xref: /openbmc/linux/drivers/scsi/sd.h (revision 6eadc612)
1aa91696eSMartin K. Petersen #ifndef _SCSI_DISK_H
2aa91696eSMartin K. Petersen #define _SCSI_DISK_H
3aa91696eSMartin K. Petersen 
4aa91696eSMartin K. Petersen /*
5aa91696eSMartin K. Petersen  * More than enough for everybody ;)  The huge number of majors
6aa91696eSMartin K. Petersen  * is a leftover from 16bit dev_t days, we don't really need that
7aa91696eSMartin K. Petersen  * much numberspace.
8aa91696eSMartin K. Petersen  */
9aa91696eSMartin K. Petersen #define SD_MAJORS	16
10aa91696eSMartin K. Petersen 
11aa91696eSMartin K. Petersen /*
12aa91696eSMartin K. Petersen  * Time out in seconds for disks and Magneto-opticals (which are slower).
13aa91696eSMartin K. Petersen  */
14aa91696eSMartin K. Petersen #define SD_TIMEOUT		(30 * HZ)
15aa91696eSMartin K. Petersen #define SD_MOD_TIMEOUT		(75 * HZ)
167e660100SJames Bottomley /*
177e660100SJames Bottomley  * Flush timeout is a multiplier over the standard device timeout which is
187e660100SJames Bottomley  * user modifiable via sysfs but initially set to SD_TIMEOUT
197e660100SJames Bottomley  */
207e660100SJames Bottomley #define SD_FLUSH_TIMEOUT_MULTIPLIER	2
215db44863SMartin K. Petersen #define SD_WRITE_SAME_TIMEOUT	(120 * HZ)
22aa91696eSMartin K. Petersen 
23aa91696eSMartin K. Petersen /*
24aa91696eSMartin K. Petersen  * Number of allowed retries
25aa91696eSMartin K. Petersen  */
26aa91696eSMartin K. Petersen #define SD_MAX_RETRIES		5
27aa91696eSMartin K. Petersen #define SD_PASSTHROUGH_RETRIES	1
2818a4d0a2SMartin K. Petersen #define SD_MAX_MEDIUM_TIMEOUTS	2
29aa91696eSMartin K. Petersen 
30aa91696eSMartin K. Petersen /*
31aa91696eSMartin K. Petersen  * Size of the initial data buffer for mode and read capacity data
32aa91696eSMartin K. Petersen  */
33aa91696eSMartin K. Petersen #define SD_BUF_SIZE		512
34aa91696eSMartin K. Petersen 
3518351070SLinus Torvalds /*
3618351070SLinus Torvalds  * Number of sectors at the end of the device to avoid multi-sector
3718351070SLinus Torvalds  * accesses to in the case of last_sector_bug
3818351070SLinus Torvalds  */
3918351070SLinus Torvalds #define SD_LAST_BUGGY_SECTORS	8
4018351070SLinus Torvalds 
414e7392ecSMartin K. Petersen enum {
424e7392ecSMartin K. Petersen 	SD_EXT_CDB_SIZE = 32,	/* Extended CDB size */
434e7392ecSMartin K. Petersen 	SD_MEMPOOL_SIZE = 2,	/* CDB pool size */
444e7392ecSMartin K. Petersen };
454e7392ecSMartin K. Petersen 
46c98a0eb0SMartin K. Petersen enum {
47bcdb247cSMartin K. Petersen 	SD_DEF_XFER_BLOCKS = 0xffff,
48bcdb247cSMartin K. Petersen 	SD_MAX_XFER_BLOCKS = 0xffffffff,
495db44863SMartin K. Petersen 	SD_MAX_WS10_BLOCKS = 0xffff,
505db44863SMartin K. Petersen 	SD_MAX_WS16_BLOCKS = 0x7fffff,
515db44863SMartin K. Petersen };
525db44863SMartin K. Petersen 
535db44863SMartin K. Petersen enum {
54c98a0eb0SMartin K. Petersen 	SD_LBP_FULL = 0,	/* Full logical block provisioning */
55c98a0eb0SMartin K. Petersen 	SD_LBP_UNMAP,		/* Use UNMAP command */
56c98a0eb0SMartin K. Petersen 	SD_LBP_WS16,		/* Use WRITE SAME(16) with UNMAP bit */
57c98a0eb0SMartin K. Petersen 	SD_LBP_WS10,		/* Use WRITE SAME(10) with UNMAP bit */
58c98a0eb0SMartin K. Petersen 	SD_LBP_ZERO,		/* Use WRITE SAME(10) with zero payload */
59c98a0eb0SMartin K. Petersen 	SD_LBP_DISABLE,		/* Discard disabled due to failed cmd */
60c98a0eb0SMartin K. Petersen };
61c98a0eb0SMartin K. Petersen 
62aa91696eSMartin K. Petersen struct scsi_disk {
63aa91696eSMartin K. Petersen 	struct scsi_driver *driver;	/* always &sd_template */
64aa91696eSMartin K. Petersen 	struct scsi_device *device;
65aa91696eSMartin K. Petersen 	struct device	dev;
66aa91696eSMartin K. Petersen 	struct gendisk	*disk;
6789d94756SHannes Reinecke #ifdef CONFIG_BLK_DEV_ZONED
6889d94756SHannes Reinecke 	unsigned int	nr_zones;
6989d94756SHannes Reinecke 	unsigned int	zone_blocks;
7089d94756SHannes Reinecke 	unsigned int	zone_shift;
7189d94756SHannes Reinecke 	unsigned long	*zones_wlock;
7289d94756SHannes Reinecke 	unsigned int	zones_optimal_open;
7389d94756SHannes Reinecke 	unsigned int	zones_optimal_nonseq;
7489d94756SHannes Reinecke 	unsigned int	zones_max_open;
7589d94756SHannes Reinecke #endif
76409f3499SArnd Bergmann 	atomic_t	openers;
77f08bb1e0SMartin K. Petersen 	sector_t	capacity;	/* size in logical blocks */
78bcdb247cSMartin K. Petersen 	u32		max_xfer_blocks;
79ca369d51SMartin K. Petersen 	u32		opt_xfer_blocks;
80c98a0eb0SMartin K. Petersen 	u32		max_ws_blocks;
81c98a0eb0SMartin K. Petersen 	u32		max_unmap_blocks;
82c98a0eb0SMartin K. Petersen 	u32		unmap_granularity;
83c98a0eb0SMartin K. Petersen 	u32		unmap_alignment;
84aa91696eSMartin K. Petersen 	u32		index;
85526f7c79SMartin K. Petersen 	unsigned int	physical_block_size;
8618a4d0a2SMartin K. Petersen 	unsigned int	max_medium_access_timeouts;
8718a4d0a2SMartin K. Petersen 	unsigned int	medium_access_timed_out;
88aa91696eSMartin K. Petersen 	u8		media_present;
89aa91696eSMartin K. Petersen 	u8		write_prot;
90e0597d70SMartin K. Petersen 	u8		protection_type;/* Data Integrity Field */
91c98a0eb0SMartin K. Petersen 	u8		provisioning_mode;
92e0597d70SMartin K. Petersen 	unsigned	ATO : 1;	/* state of disk ATO bit */
9339c60a09SJames Bottomley 	unsigned	cache_override : 1; /* temp override of WCE,RCD */
94aa91696eSMartin K. Petersen 	unsigned	WCE : 1;	/* state of disk WCE bit */
95aa91696eSMartin K. Petersen 	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
96aa91696eSMartin K. Petersen 	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */
9770a9b873SMartin K. Petersen 	unsigned	first_scan : 1;
98c98a0eb0SMartin K. Petersen 	unsigned	lbpme : 1;
99c98a0eb0SMartin K. Petersen 	unsigned	lbprz : 1;
100c98a0eb0SMartin K. Petersen 	unsigned	lbpu : 1;
101c98a0eb0SMartin K. Petersen 	unsigned	lbpws : 1;
102c98a0eb0SMartin K. Petersen 	unsigned	lbpws10 : 1;
103c98a0eb0SMartin K. Petersen 	unsigned	lbpvpd : 1;
10466c28f97SMartin K. Petersen 	unsigned	ws10 : 1;
1055db44863SMartin K. Petersen 	unsigned	ws16 : 1;
10689d94756SHannes Reinecke 	unsigned	rc_basis: 2;
10789d94756SHannes Reinecke 	unsigned	zoned: 2;
10889d94756SHannes Reinecke 	unsigned	urswrz : 1;
1097a38dc0bSHannes Reinecke 	unsigned	ignore_medium_access_errors : 1;
110aa91696eSMartin K. Petersen };
111aa91696eSMartin K. Petersen #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
112aa91696eSMartin K. Petersen 
1135b635da1SMartin K. Petersen static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
1145b635da1SMartin K. Petersen {
1155b635da1SMartin K. Petersen 	return container_of(disk->private_data, struct scsi_disk, driver);
1165b635da1SMartin K. Petersen }
1175b635da1SMartin K. Petersen 
118aa91696eSMartin K. Petersen #define sd_printk(prefix, sdsk, fmt, a...)				\
119aa91696eSMartin K. Petersen         (sdsk)->disk ?							\
12022e0d994SHannes Reinecke 	      sdev_prefix_printk(prefix, (sdsk)->device,		\
12122e0d994SHannes Reinecke 				 (sdsk)->disk->disk_name, fmt, ##a) :	\
122aa91696eSMartin K. Petersen 	      sdev_printk(prefix, (sdsk)->device, fmt, ##a)
123aa91696eSMartin K. Petersen 
124b2bff6ceSMartin K. Petersen #define sd_first_printk(prefix, sdsk, fmt, a...)			\
125b2bff6ceSMartin K. Petersen 	do {								\
126b2bff6ceSMartin K. Petersen 		if ((sdkp)->first_scan)					\
127b2bff6ceSMartin K. Petersen 			sd_printk(prefix, sdsk, fmt, ##a);		\
128b2bff6ceSMartin K. Petersen 	} while (0)
129b2bff6ceSMartin K. Petersen 
13018a4d0a2SMartin K. Petersen static inline int scsi_medium_access_command(struct scsi_cmnd *scmd)
13118a4d0a2SMartin K. Petersen {
13218a4d0a2SMartin K. Petersen 	switch (scmd->cmnd[0]) {
13318a4d0a2SMartin K. Petersen 	case READ_6:
13418a4d0a2SMartin K. Petersen 	case READ_10:
13518a4d0a2SMartin K. Petersen 	case READ_12:
13618a4d0a2SMartin K. Petersen 	case READ_16:
13718a4d0a2SMartin K. Petersen 	case SYNCHRONIZE_CACHE:
13818a4d0a2SMartin K. Petersen 	case VERIFY:
13918a4d0a2SMartin K. Petersen 	case VERIFY_12:
14018a4d0a2SMartin K. Petersen 	case VERIFY_16:
14118a4d0a2SMartin K. Petersen 	case WRITE_6:
14218a4d0a2SMartin K. Petersen 	case WRITE_10:
14318a4d0a2SMartin K. Petersen 	case WRITE_12:
14418a4d0a2SMartin K. Petersen 	case WRITE_16:
14518a4d0a2SMartin K. Petersen 	case WRITE_SAME:
14618a4d0a2SMartin K. Petersen 	case WRITE_SAME_16:
14718a4d0a2SMartin K. Petersen 	case UNMAP:
14818a4d0a2SMartin K. Petersen 		return 1;
14918a4d0a2SMartin K. Petersen 	case VARIABLE_LENGTH_CMD:
15018a4d0a2SMartin K. Petersen 		switch (scmd->cmnd[9]) {
15118a4d0a2SMartin K. Petersen 		case READ_32:
15218a4d0a2SMartin K. Petersen 		case VERIFY_32:
15318a4d0a2SMartin K. Petersen 		case WRITE_32:
15418a4d0a2SMartin K. Petersen 		case WRITE_SAME_32:
15518a4d0a2SMartin K. Petersen 			return 1;
15618a4d0a2SMartin K. Petersen 		}
15718a4d0a2SMartin K. Petersen 	}
15818a4d0a2SMartin K. Petersen 
15918a4d0a2SMartin K. Petersen 	return 0;
16018a4d0a2SMartin K. Petersen }
16118a4d0a2SMartin K. Petersen 
162f08bb1e0SMartin K. Petersen static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks)
163f08bb1e0SMartin K. Petersen {
164f08bb1e0SMartin K. Petersen 	return blocks << (ilog2(sdev->sector_size) - 9);
165f08bb1e0SMartin K. Petersen }
166f08bb1e0SMartin K. Petersen 
1676b7e9cdeSMartin K. Petersen static inline unsigned int logical_to_bytes(struct scsi_device *sdev, sector_t blocks)
1686b7e9cdeSMartin K. Petersen {
1696b7e9cdeSMartin K. Petersen 	return blocks * sdev->sector_size;
1706b7e9cdeSMartin K. Petersen }
1716b7e9cdeSMartin K. Petersen 
1726eadc612SDamien Le Moal static inline sector_t bytes_to_logical(struct scsi_device *sdev, unsigned int bytes)
1736eadc612SDamien Le Moal {
1746eadc612SDamien Le Moal 	return bytes >> ilog2(sdev->sector_size);
1756eadc612SDamien Le Moal }
1766eadc612SDamien Le Moal 
17789d94756SHannes Reinecke static inline sector_t sectors_to_logical(struct scsi_device *sdev, sector_t sector)
17889d94756SHannes Reinecke {
17989d94756SHannes Reinecke 	return sector >> (ilog2(sdev->sector_size) - 9);
18089d94756SHannes Reinecke }
18189d94756SHannes Reinecke 
182e0597d70SMartin K. Petersen /*
183c611529eSMartin K. Petersen  * Look up the DIX operation based on whether the command is read or
184c611529eSMartin K. Petersen  * write and whether dix and dif are enabled.
185c611529eSMartin K. Petersen  */
186c611529eSMartin K. Petersen static inline unsigned int sd_prot_op(bool write, bool dix, bool dif)
187c611529eSMartin K. Petersen {
188c611529eSMartin K. Petersen 	/* Lookup table: bit 2 (write), bit 1 (dix), bit 0 (dif) */
189c611529eSMartin K. Petersen 	const unsigned int ops[] = {	/* wrt dix dif */
190c611529eSMartin K. Petersen 		SCSI_PROT_NORMAL,	/*  0	0   0  */
191c611529eSMartin K. Petersen 		SCSI_PROT_READ_STRIP,	/*  0	0   1  */
192c611529eSMartin K. Petersen 		SCSI_PROT_READ_INSERT,	/*  0	1   0  */
193c611529eSMartin K. Petersen 		SCSI_PROT_READ_PASS,	/*  0	1   1  */
194c611529eSMartin K. Petersen 		SCSI_PROT_NORMAL,	/*  1	0   0  */
195c611529eSMartin K. Petersen 		SCSI_PROT_WRITE_INSERT, /*  1	0   1  */
196c611529eSMartin K. Petersen 		SCSI_PROT_WRITE_STRIP,	/*  1	1   0  */
197c611529eSMartin K. Petersen 		SCSI_PROT_WRITE_PASS,	/*  1	1   1  */
198c611529eSMartin K. Petersen 	};
199c611529eSMartin K. Petersen 
200c611529eSMartin K. Petersen 	return ops[write << 2 | dix << 1 | dif];
201c611529eSMartin K. Petersen }
202c611529eSMartin K. Petersen 
203c611529eSMartin K. Petersen /*
204c611529eSMartin K. Petersen  * Returns a mask of the protection flags that are valid for a given DIX
205c611529eSMartin K. Petersen  * operation.
206c611529eSMartin K. Petersen  */
207c611529eSMartin K. Petersen static inline unsigned int sd_prot_flag_mask(unsigned int prot_op)
208c611529eSMartin K. Petersen {
209c611529eSMartin K. Petersen 	const unsigned int flag_mask[] = {
210c611529eSMartin K. Petersen 		[SCSI_PROT_NORMAL]		= 0,
211c611529eSMartin K. Petersen 
212c611529eSMartin K. Petersen 		[SCSI_PROT_READ_STRIP]		= SCSI_PROT_TRANSFER_PI |
213c611529eSMartin K. Petersen 						  SCSI_PROT_GUARD_CHECK |
214c611529eSMartin K. Petersen 						  SCSI_PROT_REF_CHECK |
215c611529eSMartin K. Petersen 						  SCSI_PROT_REF_INCREMENT,
216c611529eSMartin K. Petersen 
217c611529eSMartin K. Petersen 		[SCSI_PROT_READ_INSERT]		= SCSI_PROT_REF_INCREMENT |
218c611529eSMartin K. Petersen 						  SCSI_PROT_IP_CHECKSUM,
219c611529eSMartin K. Petersen 
220c611529eSMartin K. Petersen 		[SCSI_PROT_READ_PASS]		= SCSI_PROT_TRANSFER_PI |
221c611529eSMartin K. Petersen 						  SCSI_PROT_GUARD_CHECK |
222c611529eSMartin K. Petersen 						  SCSI_PROT_REF_CHECK |
223c611529eSMartin K. Petersen 						  SCSI_PROT_REF_INCREMENT |
224c611529eSMartin K. Petersen 						  SCSI_PROT_IP_CHECKSUM,
225c611529eSMartin K. Petersen 
226c611529eSMartin K. Petersen 		[SCSI_PROT_WRITE_INSERT]	= SCSI_PROT_TRANSFER_PI |
227c611529eSMartin K. Petersen 						  SCSI_PROT_REF_INCREMENT,
228c611529eSMartin K. Petersen 
229c611529eSMartin K. Petersen 		[SCSI_PROT_WRITE_STRIP]		= SCSI_PROT_GUARD_CHECK |
230c611529eSMartin K. Petersen 						  SCSI_PROT_REF_CHECK |
231c611529eSMartin K. Petersen 						  SCSI_PROT_REF_INCREMENT |
232c611529eSMartin K. Petersen 						  SCSI_PROT_IP_CHECKSUM,
233c611529eSMartin K. Petersen 
234c611529eSMartin K. Petersen 		[SCSI_PROT_WRITE_PASS]		= SCSI_PROT_TRANSFER_PI |
235c611529eSMartin K. Petersen 						  SCSI_PROT_GUARD_CHECK |
236c611529eSMartin K. Petersen 						  SCSI_PROT_REF_CHECK |
237c611529eSMartin K. Petersen 						  SCSI_PROT_REF_INCREMENT |
238c611529eSMartin K. Petersen 						  SCSI_PROT_IP_CHECKSUM,
239c611529eSMartin K. Petersen 	};
240c611529eSMartin K. Petersen 
241c611529eSMartin K. Petersen 	return flag_mask[prot_op];
242c611529eSMartin K. Petersen }
243c611529eSMartin K. Petersen 
2444c393e6eSJames Bottomley #ifdef CONFIG_BLK_DEV_INTEGRITY
245af55ff67SMartin K. Petersen 
246af55ff67SMartin K. Petersen extern void sd_dif_config_host(struct scsi_disk *);
247c611529eSMartin K. Petersen extern void sd_dif_prepare(struct scsi_cmnd *scmd);
248af55ff67SMartin K. Petersen extern void sd_dif_complete(struct scsi_cmnd *, unsigned int);
249af55ff67SMartin K. Petersen 
250af55ff67SMartin K. Petersen #else /* CONFIG_BLK_DEV_INTEGRITY */
251af55ff67SMartin K. Petersen 
2524c393e6eSJames Bottomley static inline void sd_dif_config_host(struct scsi_disk *disk)
2534c393e6eSJames Bottomley {
2544c393e6eSJames Bottomley }
255c611529eSMartin K. Petersen static inline int sd_dif_prepare(struct scsi_cmnd *scmd)
2564c393e6eSJames Bottomley {
2574c393e6eSJames Bottomley 	return 0;
2584c393e6eSJames Bottomley }
2594c393e6eSJames Bottomley static inline void sd_dif_complete(struct scsi_cmnd *cmd, unsigned int a)
2604c393e6eSJames Bottomley {
2614c393e6eSJames Bottomley }
262af55ff67SMartin K. Petersen 
263af55ff67SMartin K. Petersen #endif /* CONFIG_BLK_DEV_INTEGRITY */
264af55ff67SMartin K. Petersen 
26589d94756SHannes Reinecke static inline int sd_is_zoned(struct scsi_disk *sdkp)
26689d94756SHannes Reinecke {
26789d94756SHannes Reinecke 	return sdkp->zoned == 1 || sdkp->device->type == TYPE_ZBC;
26889d94756SHannes Reinecke }
26989d94756SHannes Reinecke 
27089d94756SHannes Reinecke #ifdef CONFIG_BLK_DEV_ZONED
27189d94756SHannes Reinecke 
27289d94756SHannes Reinecke extern int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
27389d94756SHannes Reinecke extern void sd_zbc_remove(struct scsi_disk *sdkp);
27489d94756SHannes Reinecke extern void sd_zbc_print_zones(struct scsi_disk *sdkp);
27589d94756SHannes Reinecke extern int sd_zbc_setup_write_cmnd(struct scsi_cmnd *cmd);
27689d94756SHannes Reinecke extern void sd_zbc_cancel_write_cmnd(struct scsi_cmnd *cmd);
27789d94756SHannes Reinecke extern int sd_zbc_setup_report_cmnd(struct scsi_cmnd *cmd);
27889d94756SHannes Reinecke extern int sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd);
27989d94756SHannes Reinecke extern void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
28089d94756SHannes Reinecke 			    struct scsi_sense_hdr *sshdr);
28189d94756SHannes Reinecke 
28289d94756SHannes Reinecke #else /* CONFIG_BLK_DEV_ZONED */
28389d94756SHannes Reinecke 
28489d94756SHannes Reinecke static inline int sd_zbc_read_zones(struct scsi_disk *sdkp,
28589d94756SHannes Reinecke 				    unsigned char *buf)
28689d94756SHannes Reinecke {
28789d94756SHannes Reinecke 	return 0;
28889d94756SHannes Reinecke }
28989d94756SHannes Reinecke 
29089d94756SHannes Reinecke static inline void sd_zbc_remove(struct scsi_disk *sdkp) {}
29189d94756SHannes Reinecke 
29289d94756SHannes Reinecke static inline void sd_zbc_print_zones(struct scsi_disk *sdkp) {}
29389d94756SHannes Reinecke 
29489d94756SHannes Reinecke static inline int sd_zbc_setup_write_cmnd(struct scsi_cmnd *cmd)
29589d94756SHannes Reinecke {
29689d94756SHannes Reinecke 	/* Let the drive fail requests */
29789d94756SHannes Reinecke 	return BLKPREP_OK;
29889d94756SHannes Reinecke }
29989d94756SHannes Reinecke 
30089d94756SHannes Reinecke static inline void sd_zbc_cancel_write_cmnd(struct scsi_cmnd *cmd) {}
30189d94756SHannes Reinecke 
30289d94756SHannes Reinecke static inline int sd_zbc_setup_report_cmnd(struct scsi_cmnd *cmd)
30389d94756SHannes Reinecke {
30489d94756SHannes Reinecke 	return BLKPREP_INVALID;
30589d94756SHannes Reinecke }
30689d94756SHannes Reinecke 
30789d94756SHannes Reinecke static inline int sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
30889d94756SHannes Reinecke {
30989d94756SHannes Reinecke 	return BLKPREP_INVALID;
31089d94756SHannes Reinecke }
31189d94756SHannes Reinecke 
31289d94756SHannes Reinecke static inline void sd_zbc_complete(struct scsi_cmnd *cmd,
31389d94756SHannes Reinecke 				   unsigned int good_bytes,
31489d94756SHannes Reinecke 				   struct scsi_sense_hdr *sshdr) {}
31589d94756SHannes Reinecke 
31689d94756SHannes Reinecke #endif /* CONFIG_BLK_DEV_ZONED */
31789d94756SHannes Reinecke 
318aa91696eSMartin K. Petersen #endif /* _SCSI_DISK_H */
319