diff options
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 35 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 3 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 57 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.h | 112 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 97 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 20 |
7 files changed, 156 insertions, 169 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index fe818cd29dc..21e5316e500 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -870,8 +870,9 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, | |||
870 | struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf; | 870 | struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf; |
871 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | 871 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; |
872 | unsigned long flags; | 872 | unsigned long flags; |
873 | struct fcp_rsp_iu *fcp_rsp; | 873 | struct fcp_resp_with_ext *fcp_rsp; |
874 | char *fcp_rsp_info = NULL, *fcp_sns_info = NULL; | 874 | struct fcp_resp_rsp_info *fcp_rsp_info = NULL; |
875 | char *fcp_sns_info = NULL; | ||
875 | int offset = 0, buflen = 0; | 876 | int offset = 0, buflen = 0; |
876 | 877 | ||
877 | spin_lock_irqsave(&dbf->scsi_lock, flags); | 878 | spin_lock_irqsave(&dbf->scsi_lock, flags); |
@@ -895,20 +896,22 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, | |||
895 | rec->scsi_allowed = scsi_cmnd->allowed; | 896 | rec->scsi_allowed = scsi_cmnd->allowed; |
896 | } | 897 | } |
897 | if (fsf_req != NULL) { | 898 | if (fsf_req != NULL) { |
898 | fcp_rsp = (struct fcp_rsp_iu *) | 899 | fcp_rsp = (struct fcp_resp_with_ext *) |
899 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | 900 | &(fsf_req->qtcb->bottom.io.fcp_rsp); |
900 | fcp_rsp_info = (unsigned char *) &fcp_rsp[1]; | 901 | fcp_rsp_info = (struct fcp_resp_rsp_info *) |
901 | fcp_sns_info = | 902 | &fcp_rsp[1]; |
902 | zfcp_get_fcp_sns_info_ptr(fcp_rsp); | 903 | fcp_sns_info = (char *) &fcp_rsp[1]; |
903 | 904 | if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) | |
904 | rec->rsp_validity = fcp_rsp->validity.value; | 905 | fcp_sns_info += fcp_rsp->ext.fr_sns_len; |
905 | rec->rsp_scsi_status = fcp_rsp->scsi_status; | 906 | |
906 | rec->rsp_resid = fcp_rsp->fcp_resid; | 907 | rec->rsp_validity = fcp_rsp->resp.fr_flags; |
907 | if (fcp_rsp->validity.bits.fcp_rsp_len_valid) | 908 | rec->rsp_scsi_status = fcp_rsp->resp.fr_status; |
908 | rec->rsp_code = *(fcp_rsp_info + 3); | 909 | rec->rsp_resid = fcp_rsp->ext.fr_resid; |
909 | if (fcp_rsp->validity.bits.fcp_sns_len_valid) { | 910 | if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) |
910 | buflen = min((int)fcp_rsp->fcp_sns_len, | 911 | rec->rsp_code = fcp_rsp_info->rsp_code; |
911 | ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); | 912 | if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { |
913 | buflen = min(fcp_rsp->ext.fr_sns_len, | ||
914 | (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); | ||
912 | rec->sns_info_len = buflen; | 915 | rec->sns_info_len = buflen; |
913 | memcpy(rec->sns_info, fcp_sns_info, | 916 | memcpy(rec->sns_info, fcp_sns_info, |
914 | min(buflen, | 917 | min(buflen, |
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 6b1461e8f84..c3e25702df5 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #ifndef ZFCP_DBF_H | 22 | #ifndef ZFCP_DBF_H |
23 | #define ZFCP_DBF_H | 23 | #define ZFCP_DBF_H |
24 | 24 | ||
25 | #include <scsi/fc/fc_fcp.h> | ||
25 | #include "zfcp_ext.h" | 26 | #include "zfcp_ext.h" |
26 | #include "zfcp_fsf.h" | 27 | #include "zfcp_fsf.h" |
27 | #include "zfcp_def.h" | 28 | #include "zfcp_def.h" |
@@ -343,7 +344,7 @@ static inline | |||
343 | void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | 344 | void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, |
344 | struct scsi_cmnd *scsi_cmnd) | 345 | struct scsi_cmnd *scsi_cmnd) |
345 | { | 346 | { |
346 | zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, | 347 | zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1, |
347 | unit->port->adapter->dbf, scsi_cmnd, NULL, 0); | 348 | unit->port->adapter->dbf, scsi_cmnd, NULL, 0); |
348 | } | 349 | } |
349 | 350 | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 08fa31302f7..0317e7f2085 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -73,65 +73,8 @@ | |||
73 | 73 | ||
74 | /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ | 74 | /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ |
75 | 75 | ||
76 | /* task attribute values in FCP-2 FCP_CMND IU */ | ||
77 | #define SIMPLE_Q 0 | ||
78 | #define HEAD_OF_Q 1 | ||
79 | #define ORDERED_Q 2 | ||
80 | #define ACA_Q 4 | ||
81 | #define UNTAGGED 5 | ||
82 | |||
83 | /* task management flags in FCP-2 FCP_CMND IU */ | ||
84 | #define FCP_CLEAR_ACA 0x40 | ||
85 | #define FCP_TARGET_RESET 0x20 | ||
86 | #define FCP_LOGICAL_UNIT_RESET 0x10 | ||
87 | #define FCP_CLEAR_TASK_SET 0x04 | ||
88 | #define FCP_ABORT_TASK_SET 0x02 | ||
89 | |||
90 | #define FCP_CDB_LENGTH 16 | ||
91 | |||
92 | #define ZFCP_DID_MASK 0x00FFFFFF | 76 | #define ZFCP_DID_MASK 0x00FFFFFF |
93 | 77 | ||
94 | /* FCP(-2) FCP_CMND IU */ | ||
95 | struct fcp_cmnd_iu { | ||
96 | u64 fcp_lun; /* FCP logical unit number */ | ||
97 | u8 crn; /* command reference number */ | ||
98 | u8 reserved0:5; /* reserved */ | ||
99 | u8 task_attribute:3; /* task attribute */ | ||
100 | u8 task_management_flags; /* task management flags */ | ||
101 | u8 add_fcp_cdb_length:6; /* additional FCP_CDB length */ | ||
102 | u8 rddata:1; /* read data */ | ||
103 | u8 wddata:1; /* write data */ | ||
104 | u8 fcp_cdb[FCP_CDB_LENGTH]; | ||
105 | } __attribute__((packed)); | ||
106 | |||
107 | /* FCP(-2) FCP_RSP IU */ | ||
108 | struct fcp_rsp_iu { | ||
109 | u8 reserved0[10]; | ||
110 | union { | ||
111 | struct { | ||
112 | u8 reserved1:3; | ||
113 | u8 fcp_conf_req:1; | ||
114 | u8 fcp_resid_under:1; | ||
115 | u8 fcp_resid_over:1; | ||
116 | u8 fcp_sns_len_valid:1; | ||
117 | u8 fcp_rsp_len_valid:1; | ||
118 | } bits; | ||
119 | u8 value; | ||
120 | } validity; | ||
121 | u8 scsi_status; | ||
122 | u32 fcp_resid; | ||
123 | u32 fcp_sns_len; | ||
124 | u32 fcp_rsp_len; | ||
125 | } __attribute__((packed)); | ||
126 | |||
127 | |||
128 | #define RSP_CODE_GOOD 0 | ||
129 | #define RSP_CODE_LENGTH_MISMATCH 1 | ||
130 | #define RSP_CODE_FIELD_INVALID 2 | ||
131 | #define RSP_CODE_RO_MISMATCH 3 | ||
132 | #define RSP_CODE_TASKMAN_UNSUPP 4 | ||
133 | #define RSP_CODE_TASKMAN_FAILED 5 | ||
134 | |||
135 | /* see fc-fs */ | 78 | /* see fc-fs */ |
136 | #define LS_RSCN 0x61 | 79 | #define LS_RSCN 0x61 |
137 | #define LS_LOGO 0x05 | 80 | #define LS_LOGO 0x05 |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index d372146af38..3832fe0ae2e 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -154,7 +154,6 @@ extern void zfcp_qdio_close(struct zfcp_qdio *); | |||
154 | extern struct zfcp_data zfcp_data; | 154 | extern struct zfcp_data zfcp_data; |
155 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); | 155 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); |
156 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); | 156 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); |
157 | extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); | ||
158 | extern struct fc_function_template zfcp_transport_functions; | 157 | extern struct fc_function_template zfcp_transport_functions; |
159 | extern void zfcp_scsi_rport_work(struct work_struct *); | 158 | extern void zfcp_scsi_rport_work(struct work_struct *); |
160 | extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); | 159 | extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); |
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h new file mode 100644 index 00000000000..814fc2d2525 --- /dev/null +++ b/drivers/s390/scsi/zfcp_fc.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * zfcp device driver | ||
3 | * | ||
4 | * Fibre Channel related definitions and inline functions for the zfcp | ||
5 | * device driver | ||
6 | * | ||
7 | * Copyright IBM Corporation 2009 | ||
8 | */ | ||
9 | |||
10 | #ifndef ZFCP_FC_H | ||
11 | #define ZFCP_FC_H | ||
12 | |||
13 | #include <scsi/fc/fc_fcp.h> | ||
14 | #include <scsi/scsi_cmnd.h> | ||
15 | #include <scsi/scsi_tcq.h> | ||
16 | |||
17 | /** | ||
18 | * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd | ||
19 | * @fcp: fcp_cmnd to setup | ||
20 | * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB | ||
21 | */ | ||
22 | static inline | ||
23 | void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi) | ||
24 | { | ||
25 | char tag[2]; | ||
26 | |||
27 | int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun); | ||
28 | |||
29 | if (scsi_populate_tag_msg(scsi, tag)) { | ||
30 | switch (tag[0]) { | ||
31 | case MSG_ORDERED_TAG: | ||
32 | fcp->fc_pri_ta |= FCP_PTA_ORDERED; | ||
33 | break; | ||
34 | case MSG_SIMPLE_TAG: | ||
35 | fcp->fc_pri_ta |= FCP_PTA_SIMPLE; | ||
36 | break; | ||
37 | }; | ||
38 | } else | ||
39 | fcp->fc_pri_ta = FCP_PTA_SIMPLE; | ||
40 | |||
41 | if (scsi->sc_data_direction == DMA_FROM_DEVICE) | ||
42 | fcp->fc_flags |= FCP_CFL_RDDATA; | ||
43 | if (scsi->sc_data_direction == DMA_TO_DEVICE) | ||
44 | fcp->fc_flags |= FCP_CFL_WRDATA; | ||
45 | |||
46 | memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len); | ||
47 | |||
48 | fcp->fc_dl = scsi_bufflen(scsi); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * zfcp_fc_fcp_tm - setup FCP command as task management command | ||
53 | * @fcp: fcp_cmnd to setup | ||
54 | * @dev: scsi_device where to send the task management command | ||
55 | * @tm: task management flags to setup tm command | ||
56 | */ | ||
57 | static inline | ||
58 | void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags) | ||
59 | { | ||
60 | int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun); | ||
61 | fcp->fc_tm_flags |= tm_flags; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly | ||
66 | * @fcp_rsp: FCP RSP IU to evaluate | ||
67 | * @scsi: SCSI command where to update status and sense buffer | ||
68 | */ | ||
69 | static inline | ||
70 | void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp, | ||
71 | struct scsi_cmnd *scsi) | ||
72 | { | ||
73 | struct fcp_resp_rsp_info *rsp_info; | ||
74 | char *sense; | ||
75 | u32 sense_len, resid; | ||
76 | u8 rsp_flags; | ||
77 | |||
78 | set_msg_byte(scsi, COMMAND_COMPLETE); | ||
79 | scsi->result |= fcp_rsp->resp.fr_status; | ||
80 | |||
81 | rsp_flags = fcp_rsp->resp.fr_flags; | ||
82 | |||
83 | if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) { | ||
84 | rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; | ||
85 | if (rsp_info->rsp_code == FCP_TMF_CMPL) | ||
86 | set_host_byte(scsi, DID_OK); | ||
87 | else { | ||
88 | set_host_byte(scsi, DID_ERROR); | ||
89 | return; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) { | ||
94 | sense = (char *) &fcp_rsp[1]; | ||
95 | if (rsp_flags & FCP_RSP_LEN_VAL) | ||
96 | sense += fcp_rsp->ext.fr_sns_len; | ||
97 | sense_len = min(fcp_rsp->ext.fr_sns_len, | ||
98 | (u32) SCSI_SENSE_BUFFERSIZE); | ||
99 | memcpy(scsi->sense_buffer, sense, sense_len); | ||
100 | } | ||
101 | |||
102 | if (unlikely(rsp_flags & FCP_RESID_UNDER)) { | ||
103 | resid = fcp_rsp->ext.fr_resid; | ||
104 | scsi_set_resid(scsi, resid); | ||
105 | if (scsi_bufflen(scsi) - resid < scsi->underflow && | ||
106 | !(rsp_flags & FCP_SNS_LEN_VAL) && | ||
107 | fcp_rsp->resp.fr_status == SAM_STAT_GOOD) | ||
108 | set_host_byte(scsi, DID_ERROR); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | #endif | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index b6f12c826b7..5f4cd03797e 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/blktrace_api.h> | 12 | #include <linux/blktrace_api.h> |
13 | #include "zfcp_ext.h" | 13 | #include "zfcp_ext.h" |
14 | #include "zfcp_fc.h" | ||
14 | #include "zfcp_dbf.h" | 15 | #include "zfcp_dbf.h" |
15 | 16 | ||
16 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 17 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
@@ -2159,10 +2160,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) | |||
2159 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2160 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
2160 | { | 2161 | { |
2161 | struct scsi_cmnd *scpnt; | 2162 | struct scsi_cmnd *scpnt; |
2162 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2163 | struct fcp_resp_with_ext *fcp_rsp; |
2163 | &(req->qtcb->bottom.io.fcp_rsp); | ||
2164 | u32 sns_len; | ||
2165 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | ||
2166 | unsigned long flags; | 2164 | unsigned long flags; |
2167 | 2165 | ||
2168 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2166 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
@@ -2183,37 +2181,11 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |||
2183 | goto skip_fsfstatus; | 2181 | goto skip_fsfstatus; |
2184 | } | 2182 | } |
2185 | 2183 | ||
2186 | set_msg_byte(scpnt, COMMAND_COMPLETE); | 2184 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; |
2187 | 2185 | zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); | |
2188 | scpnt->result |= fcp_rsp_iu->scsi_status; | ||
2189 | 2186 | ||
2190 | zfcp_fsf_req_trace(req, scpnt); | 2187 | zfcp_fsf_req_trace(req, scpnt); |
2191 | 2188 | ||
2192 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { | ||
2193 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) | ||
2194 | set_host_byte(scpnt, DID_OK); | ||
2195 | else { | ||
2196 | set_host_byte(scpnt, DID_ERROR); | ||
2197 | goto skip_fsfstatus; | ||
2198 | } | ||
2199 | } | ||
2200 | |||
2201 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) { | ||
2202 | sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) + | ||
2203 | fcp_rsp_iu->fcp_rsp_len; | ||
2204 | sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE); | ||
2205 | sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len); | ||
2206 | |||
2207 | memcpy(scpnt->sense_buffer, | ||
2208 | zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len); | ||
2209 | } | ||
2210 | |||
2211 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) { | ||
2212 | scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); | ||
2213 | if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < | ||
2214 | scpnt->underflow) | ||
2215 | set_host_byte(scpnt, DID_ERROR); | ||
2216 | } | ||
2217 | skip_fsfstatus: | 2189 | skip_fsfstatus: |
2218 | if (scpnt->result != 0) | 2190 | if (scpnt->result != 0) |
2219 | zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req); | 2191 | zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req); |
@@ -2235,11 +2207,13 @@ skip_fsfstatus: | |||
2235 | 2207 | ||
2236 | static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) | 2208 | static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) |
2237 | { | 2209 | { |
2238 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2210 | struct fcp_resp_with_ext *fcp_rsp; |
2239 | &(req->qtcb->bottom.io.fcp_rsp); | 2211 | struct fcp_resp_rsp_info *rsp_info; |
2240 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | ||
2241 | 2212 | ||
2242 | if ((fcp_rsp_info[3] != RSP_CODE_GOOD) || | 2213 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; |
2214 | rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; | ||
2215 | |||
2216 | if ((rsp_info->rsp_code != FCP_TMF_CMPL) || | ||
2243 | (req->status & ZFCP_STATUS_FSFREQ_ERROR)) | 2217 | (req->status & ZFCP_STATUS_FSFREQ_ERROR)) |
2244 | req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; | 2218 | req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; |
2245 | } | 2219 | } |
@@ -2324,20 +2298,6 @@ skip_fsfstatus: | |||
2324 | } | 2298 | } |
2325 | } | 2299 | } |
2326 | 2300 | ||
2327 | static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl) | ||
2328 | { | ||
2329 | u32 *fcp_dl_ptr; | ||
2330 | |||
2331 | /* | ||
2332 | * fcp_dl_addr = start address of fcp_cmnd structure + | ||
2333 | * size of fixed part + size of dynamically sized add_dcp_cdb field | ||
2334 | * SEE FCP-2 documentation | ||
2335 | */ | ||
2336 | fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] + | ||
2337 | (fcp_cmd->add_fcp_cdb_length << 2)); | ||
2338 | *fcp_dl_ptr = fcp_dl; | ||
2339 | } | ||
2340 | |||
2341 | /** | 2301 | /** |
2342 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) | 2302 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) |
2343 | * @unit: unit where command is sent to | 2303 | * @unit: unit where command is sent to |
@@ -2347,7 +2307,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2347 | struct scsi_cmnd *scsi_cmnd) | 2307 | struct scsi_cmnd *scsi_cmnd) |
2348 | { | 2308 | { |
2349 | struct zfcp_fsf_req *req; | 2309 | struct zfcp_fsf_req *req; |
2350 | struct fcp_cmnd_iu *fcp_cmnd_iu; | 2310 | struct fcp_cmnd *fcp_cmnd; |
2351 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; | 2311 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; |
2352 | int real_bytes, retval = -EIO; | 2312 | int real_bytes, retval = -EIO; |
2353 | struct zfcp_adapter *adapter = unit->port->adapter; | 2313 | struct zfcp_adapter *adapter = unit->port->adapter; |
@@ -2379,16 +2339,14 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2379 | req->qtcb->header.lun_handle = unit->handle; | 2339 | req->qtcb->header.lun_handle = unit->handle; |
2380 | req->qtcb->header.port_handle = unit->port->handle; | 2340 | req->qtcb->header.port_handle = unit->port->handle; |
2381 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2341 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; |
2342 | req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; | ||
2382 | 2343 | ||
2383 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; | 2344 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; |
2384 | 2345 | ||
2385 | fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd); | ||
2386 | fcp_cmnd_iu->fcp_lun = unit->fcp_lun; | ||
2387 | /* | 2346 | /* |
2388 | * set depending on data direction: | 2347 | * set depending on data direction: |
2389 | * data direction bits in SBALE (SB Type) | 2348 | * data direction bits in SBALE (SB Type) |
2390 | * data direction bits in QTCB | 2349 | * data direction bits in QTCB |
2391 | * data direction bits in FCP_CMND IU | ||
2392 | */ | 2350 | */ |
2393 | switch (scsi_cmnd->sc_data_direction) { | 2351 | switch (scsi_cmnd->sc_data_direction) { |
2394 | case DMA_NONE: | 2352 | case DMA_NONE: |
@@ -2396,32 +2354,17 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2396 | break; | 2354 | break; |
2397 | case DMA_FROM_DEVICE: | 2355 | case DMA_FROM_DEVICE: |
2398 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; | 2356 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; |
2399 | fcp_cmnd_iu->rddata = 1; | ||
2400 | break; | 2357 | break; |
2401 | case DMA_TO_DEVICE: | 2358 | case DMA_TO_DEVICE: |
2402 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; | 2359 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; |
2403 | sbtype = SBAL_FLAGS0_TYPE_WRITE; | 2360 | sbtype = SBAL_FLAGS0_TYPE_WRITE; |
2404 | fcp_cmnd_iu->wddata = 1; | ||
2405 | break; | 2361 | break; |
2406 | case DMA_BIDIRECTIONAL: | 2362 | case DMA_BIDIRECTIONAL: |
2407 | goto failed_scsi_cmnd; | 2363 | goto failed_scsi_cmnd; |
2408 | } | 2364 | } |
2409 | 2365 | ||
2410 | if (likely((scsi_cmnd->device->simple_tags) || | 2366 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; |
2411 | ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) && | 2367 | zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); |
2412 | (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED)))) | ||
2413 | fcp_cmnd_iu->task_attribute = SIMPLE_Q; | ||
2414 | else | ||
2415 | fcp_cmnd_iu->task_attribute = UNTAGGED; | ||
2416 | |||
2417 | if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) | ||
2418 | fcp_cmnd_iu->add_fcp_cdb_length = | ||
2419 | (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2; | ||
2420 | |||
2421 | memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); | ||
2422 | |||
2423 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | ||
2424 | fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32); | ||
2425 | 2368 | ||
2426 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype, | 2369 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype, |
2427 | scsi_sglist(scsi_cmnd), | 2370 | scsi_sglist(scsi_cmnd), |
@@ -2439,8 +2382,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2439 | goto failed_scsi_cmnd; | 2382 | goto failed_scsi_cmnd; |
2440 | } | 2383 | } |
2441 | 2384 | ||
2442 | zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes); | ||
2443 | |||
2444 | retval = zfcp_fsf_req_send(req); | 2385 | retval = zfcp_fsf_req_send(req); |
2445 | if (unlikely(retval)) | 2386 | if (unlikely(retval)) |
2446 | goto failed_scsi_cmnd; | 2387 | goto failed_scsi_cmnd; |
@@ -2466,7 +2407,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2466 | { | 2407 | { |
2467 | struct qdio_buffer_element *sbale; | 2408 | struct qdio_buffer_element *sbale; |
2468 | struct zfcp_fsf_req *req = NULL; | 2409 | struct zfcp_fsf_req *req = NULL; |
2469 | struct fcp_cmnd_iu *fcp_cmnd_iu; | 2410 | struct fcp_cmnd *fcp_cmnd; |
2470 | struct zfcp_qdio *qdio = unit->port->adapter->qdio; | 2411 | struct zfcp_qdio *qdio = unit->port->adapter->qdio; |
2471 | 2412 | ||
2472 | if (unlikely(!(atomic_read(&unit->status) & | 2413 | if (unlikely(!(atomic_read(&unit->status) & |
@@ -2492,16 +2433,14 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2492 | req->qtcb->header.port_handle = unit->port->handle; | 2433 | req->qtcb->header.port_handle = unit->port->handle; |
2493 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; | 2434 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; |
2494 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2435 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; |
2495 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | 2436 | req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; |
2496 | sizeof(u32); | ||
2497 | 2437 | ||
2498 | sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req); | 2438 | sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req); |
2499 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; | 2439 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; |
2500 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 2440 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
2501 | 2441 | ||
2502 | fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd; | 2442 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; |
2503 | fcp_cmnd_iu->fcp_lun = unit->fcp_lun; | 2443 | zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags); |
2504 | fcp_cmnd_iu->task_management_flags = tm_flags; | ||
2505 | 2444 | ||
2506 | zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); | 2445 | zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); |
2507 | if (!zfcp_fsf_req_send(req)) | 2446 | if (!zfcp_fsf_req_send(req)) |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 0ecec9c1b49..3d168410036 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -9,6 +9,8 @@ | |||
9 | #define KMSG_COMPONENT "zfcp" | 9 | #define KMSG_COMPONENT "zfcp" |
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
11 | 11 | ||
12 | #include <linux/types.h> | ||
13 | #include <scsi/fc/fc_fcp.h> | ||
12 | #include <asm/atomic.h> | 14 | #include <asm/atomic.h> |
13 | #include "zfcp_ext.h" | 15 | #include "zfcp_ext.h" |
14 | #include "zfcp_dbf.h" | 16 | #include "zfcp_dbf.h" |
@@ -17,18 +19,6 @@ static unsigned int default_depth = 32; | |||
17 | module_param_named(queue_depth, default_depth, uint, 0600); | 19 | module_param_named(queue_depth, default_depth, uint, 0600); |
18 | MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); | 20 | MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); |
19 | 21 | ||
20 | /* Find start of Sense Information in FCP response unit*/ | ||
21 | char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) | ||
22 | { | ||
23 | char *fcp_sns_info_ptr; | ||
24 | |||
25 | fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1]; | ||
26 | if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid) | ||
27 | fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len; | ||
28 | |||
29 | return fcp_sns_info_ptr; | ||
30 | } | ||
31 | |||
32 | static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, | 22 | static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, |
33 | int reason) | 23 | int reason) |
34 | { | 24 | { |
@@ -283,12 +273,12 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
283 | 273 | ||
284 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | 274 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) |
285 | { | 275 | { |
286 | return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET); | 276 | return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET); |
287 | } | 277 | } |
288 | 278 | ||
289 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) | 279 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) |
290 | { | 280 | { |
291 | return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET); | 281 | return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET); |
292 | } | 282 | } |
293 | 283 | ||
294 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | 284 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) |
@@ -325,7 +315,7 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
325 | adapter->scsi_host->max_lun = 1; | 315 | adapter->scsi_host->max_lun = 1; |
326 | adapter->scsi_host->max_channel = 0; | 316 | adapter->scsi_host->max_channel = 0; |
327 | adapter->scsi_host->unique_id = dev_id.devno; | 317 | adapter->scsi_host->unique_id = dev_id.devno; |
328 | adapter->scsi_host->max_cmd_len = 255; | 318 | adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ |
329 | adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; | 319 | adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; |
330 | 320 | ||
331 | adapter->scsi_host->hostdata[0] = (unsigned long) adapter; | 321 | adapter->scsi_host->hostdata[0] = (unsigned long) adapter; |