aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/scsi/scsi.h3
-rw-r--r--include/scsi/scsi_cmnd.h86
-rw-r--r--include/scsi/scsi_device.h17
-rw-r--r--include/scsi/scsi_dh.h11
-rw-r--r--include/scsi/scsi_eh.h2
-rw-r--r--include/scsi/scsi_host.h86
6 files changed, 202 insertions, 3 deletions
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 00137a7769ee..5c40cc537d4c 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -106,6 +106,7 @@
106#define VARIABLE_LENGTH_CMD 0x7f 106#define VARIABLE_LENGTH_CMD 0x7f
107#define REPORT_LUNS 0xa0 107#define REPORT_LUNS 0xa0
108#define MAINTENANCE_IN 0xa3 108#define MAINTENANCE_IN 0xa3
109#define MAINTENANCE_OUT 0xa4
109#define MOVE_MEDIUM 0xa5 110#define MOVE_MEDIUM 0xa5
110#define EXCHANGE_MEDIUM 0xa6 111#define EXCHANGE_MEDIUM 0xa6
111#define READ_12 0xa8 112#define READ_12 0xa8
@@ -125,6 +126,8 @@
125#define SAI_READ_CAPACITY_16 0x10 126#define SAI_READ_CAPACITY_16 0x10
126/* values for maintenance in */ 127/* values for maintenance in */
127#define MI_REPORT_TARGET_PGS 0x0a 128#define MI_REPORT_TARGET_PGS 0x0a
129/* values for maintenance out */
130#define MO_SET_TARGET_PGS 0x0a
128 131
129/* Values for T10/04-262r7 */ 132/* Values for T10/04-262r7 */
130#define ATA_16 0x85 /* 16-byte pass-thru */ 133#define ATA_16 0x85 /* 16-byte pass-thru */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 66c944849d6b..f9f6e793575c 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -77,6 +77,9 @@ struct scsi_cmnd {
77 int allowed; 77 int allowed;
78 int timeout_per_command; 78 int timeout_per_command;
79 79
80 unsigned char prot_op;
81 unsigned char prot_type;
82
80 unsigned short cmd_len; 83 unsigned short cmd_len;
81 enum dma_data_direction sc_data_direction; 84 enum dma_data_direction sc_data_direction;
82 85
@@ -87,6 +90,8 @@ struct scsi_cmnd {
87 90
88 /* These elements define the operation we ultimately want to perform */ 91 /* These elements define the operation we ultimately want to perform */
89 struct scsi_data_buffer sdb; 92 struct scsi_data_buffer sdb;
93 struct scsi_data_buffer *prot_sdb;
94
90 unsigned underflow; /* Return error if less than 95 unsigned underflow; /* Return error if less than
91 this amount is transferred */ 96 this amount is transferred */
92 97
@@ -208,4 +213,85 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd,
208 buf, buflen); 213 buf, buflen);
209} 214}
210 215
216/*
217 * The operations below are hints that tell the controller driver how
218 * to handle I/Os with DIF or similar types of protection information.
219 */
220enum scsi_prot_operations {
221 /* Normal I/O */
222 SCSI_PROT_NORMAL = 0,
223
224 /* OS-HBA: Protected, HBA-Target: Unprotected */
225 SCSI_PROT_READ_INSERT,
226 SCSI_PROT_WRITE_STRIP,
227
228 /* OS-HBA: Unprotected, HBA-Target: Protected */
229 SCSI_PROT_READ_STRIP,
230 SCSI_PROT_WRITE_INSERT,
231
232 /* OS-HBA: Protected, HBA-Target: Protected */
233 SCSI_PROT_READ_PASS,
234 SCSI_PROT_WRITE_PASS,
235
236 /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */
237 SCSI_PROT_READ_CONVERT,
238 SCSI_PROT_WRITE_CONVERT,
239};
240
241static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op)
242{
243 scmd->prot_op = op;
244}
245
246static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd)
247{
248 return scmd->prot_op;
249}
250
251/*
252 * The controller usually does not know anything about the target it
253 * is communicating with. However, when DIX is enabled the controller
254 * must be know target type so it can verify the protection
255 * information passed along with the I/O.
256 */
257enum scsi_prot_target_type {
258 SCSI_PROT_DIF_TYPE0 = 0,
259 SCSI_PROT_DIF_TYPE1,
260 SCSI_PROT_DIF_TYPE2,
261 SCSI_PROT_DIF_TYPE3,
262};
263
264static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type)
265{
266 scmd->prot_type = type;
267}
268
269static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd)
270{
271 return scmd->prot_type;
272}
273
274static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
275{
276 return scmd->request->sector;
277}
278
279static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
280{
281 return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0;
282}
283
284static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd)
285{
286 return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL;
287}
288
289static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)
290{
291 return cmd->prot_sdb;
292}
293
294#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \
295 for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i)
296
211#endif /* _SCSI_SCSI_CMND_H */ 297#endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 6467f78b191f..291d56a19167 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -140,7 +140,8 @@ struct scsi_device {
140 unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ 140 unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
141 unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ 141 unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */
142 unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ 142 unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
143 unsigned last_sector_bug:1; /* Always read last sector in a 1 sector read */ 143 unsigned last_sector_bug:1; /* do not use multisector accesses on
144 SD_LAST_BUGGY_SECTORS */
144 145
145 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ 146 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
146 struct list_head event_list; /* asserted events */ 147 struct list_head event_list; /* asserted events */
@@ -167,15 +168,22 @@ struct scsi_device {
167 unsigned long sdev_data[0]; 168 unsigned long sdev_data[0];
168} __attribute__((aligned(sizeof(unsigned long)))); 169} __attribute__((aligned(sizeof(unsigned long))));
169 170
171struct scsi_dh_devlist {
172 char *vendor;
173 char *model;
174};
175
170struct scsi_device_handler { 176struct scsi_device_handler {
171 /* Used by the infrastructure */ 177 /* Used by the infrastructure */
172 struct list_head list; /* list of scsi_device_handlers */ 178 struct list_head list; /* list of scsi_device_handlers */
173 struct notifier_block nb;
174 179
175 /* Filled by the hardware handler */ 180 /* Filled by the hardware handler */
176 struct module *module; 181 struct module *module;
177 const char *name; 182 const char *name;
183 const struct scsi_dh_devlist *devlist;
178 int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); 184 int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
185 int (*attach)(struct scsi_device *);
186 void (*detach)(struct scsi_device *);
179 int (*activate)(struct scsi_device *); 187 int (*activate)(struct scsi_device *);
180 int (*prep_fn)(struct scsi_device *, struct request *); 188 int (*prep_fn)(struct scsi_device *, struct request *);
181}; 189};
@@ -416,6 +424,11 @@ static inline int scsi_device_enclosure(struct scsi_device *sdev)
416 return sdev->inquiry[6] & (1<<6); 424 return sdev->inquiry[6] & (1<<6);
417} 425}
418 426
427static inline int scsi_device_protection(struct scsi_device *sdev)
428{
429 return sdev->inquiry[5] & (1<<0);
430}
431
419#define MODULE_ALIAS_SCSI_DEVICE(type) \ 432#define MODULE_ALIAS_SCSI_DEVICE(type) \
420 MODULE_ALIAS("scsi:t-" __stringify(type) "*") 433 MODULE_ALIAS("scsi:t-" __stringify(type) "*")
421#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" 434#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index 3ad2303d1a16..33efce20c26c 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -32,6 +32,7 @@ enum {
32 */ 32 */
33 SCSI_DH_DEV_FAILED, /* generic device error */ 33 SCSI_DH_DEV_FAILED, /* generic device error */
34 SCSI_DH_DEV_TEMP_BUSY, 34 SCSI_DH_DEV_TEMP_BUSY,
35 SCSI_DH_DEV_UNSUPP, /* device handler not supported */
35 SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ 36 SCSI_DH_DEVICE_MAX, /* max device blkerr definition */
36 37
37 /* 38 /*
@@ -57,6 +58,8 @@ enum {
57#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) 58#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE)
58extern int scsi_dh_activate(struct request_queue *); 59extern int scsi_dh_activate(struct request_queue *);
59extern int scsi_dh_handler_exist(const char *); 60extern int scsi_dh_handler_exist(const char *);
61extern int scsi_dh_attach(struct request_queue *, const char *);
62extern void scsi_dh_detach(struct request_queue *);
60#else 63#else
61static inline int scsi_dh_activate(struct request_queue *req) 64static inline int scsi_dh_activate(struct request_queue *req)
62{ 65{
@@ -66,4 +69,12 @@ static inline int scsi_dh_handler_exist(const char *name)
66{ 69{
67 return 0; 70 return 0;
68} 71}
72static inline int scsi_dh_attach(struct request_queue *req, const char *name)
73{
74 return SCSI_DH_NOSYS;
75}
76static inline void scsi_dh_detach(struct request_queue *q)
77{
78 return;
79}
69#endif 80#endif
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 2a9add21267d..06a8790893ef 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -74,7 +74,9 @@ struct scsi_eh_save {
74 /* saved state */ 74 /* saved state */
75 int result; 75 int result;
76 enum dma_data_direction data_direction; 76 enum dma_data_direction data_direction;
77 unsigned underflow;
77 unsigned char cmd_len; 78 unsigned char cmd_len;
79 unsigned char prot_op;
78 unsigned char *cmnd; 80 unsigned char *cmnd;
79 struct scsi_data_buffer sdb; 81 struct scsi_data_buffer sdb;
80 struct request *next_rq; 82 struct request *next_rq;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index a594bac4a77d..44a55d1bf530 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -547,7 +547,7 @@ struct Scsi_Host {
547 unsigned int host_failed; /* commands that failed. */ 547 unsigned int host_failed; /* commands that failed. */
548 unsigned int host_eh_scheduled; /* EH scheduled without command */ 548 unsigned int host_eh_scheduled; /* EH scheduled without command */
549 549
550 unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ 550 unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
551 int resetting; /* if set, it means that last_reset is a valid value */ 551 int resetting; /* if set, it means that last_reset is a valid value */
552 unsigned long last_reset; 552 unsigned long last_reset;
553 553
@@ -636,6 +636,10 @@ struct Scsi_Host {
636 */ 636 */
637 unsigned int max_host_blocked; 637 unsigned int max_host_blocked;
638 638
639 /* Protection Information */
640 unsigned int prot_capabilities;
641 unsigned char prot_guard_type;
642
639 /* 643 /*
640 * q used for scsi_tgt msgs, async events or any other requests that 644 * q used for scsi_tgt msgs, async events or any other requests that
641 * need to be processed in userspace 645 * need to be processed in userspace
@@ -756,6 +760,86 @@ extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
756extern void scsi_free_host_dev(struct scsi_device *); 760extern void scsi_free_host_dev(struct scsi_device *);
757extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); 761extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
758 762
763/*
764 * DIF defines the exchange of protection information between
765 * initiator and SBC block device.
766 *
767 * DIX defines the exchange of protection information between OS and
768 * initiator.
769 */
770enum scsi_host_prot_capabilities {
771 SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */
772 SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */
773 SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */
774
775 SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */
776 SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */
777 SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */
778 SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */
779};
780
781/*
782 * SCSI hosts which support the Data Integrity Extensions must
783 * indicate their capabilities by setting the prot_capabilities using
784 * this call.
785 */
786static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask)
787{
788 shost->prot_capabilities = mask;
789}
790
791static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)
792{
793 return shost->prot_capabilities;
794}
795
796static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type)
797{
798 switch (target_type) {
799 case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION;
800 case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION;
801 case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION;
802 }
803
804 return 0;
805}
806
807static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type)
808{
809 switch (target_type) {
810 case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION;
811 case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION;
812 case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION;
813 case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION;
814 }
815
816 return 0;
817}
818
819/*
820 * All DIX-capable initiators must support the T10-mandated CRC
821 * checksum. Controllers can optionally implement the IP checksum
822 * scheme which has much lower impact on system performance. Note
823 * that the main rationale for the checksum is to match integrity
824 * metadata with data. Detecting bit errors are a job for ECC memory
825 * and buses.
826 */
827
828enum scsi_host_guard_type {
829 SHOST_DIX_GUARD_CRC = 1 << 0,
830 SHOST_DIX_GUARD_IP = 1 << 1,
831};
832
833static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type)
834{
835 shost->prot_guard_type = type;
836}
837
838static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
839{
840 return shost->prot_guard_type;
841}
842
759/* legacy interfaces */ 843/* legacy interfaces */
760extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); 844extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
761extern void scsi_unregister(struct Scsi_Host *); 845extern void scsi_unregister(struct Scsi_Host *);