aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 19:44:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 19:44:18 -0400
commitec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954 (patch)
treee6b0c64a51a7c0aa0efd09d4f7a80872e3b1657a /drivers/s390
parent97d2eb13a019ec09cc1a7ea2d3705c0b117b3c0d (diff)
parent590134fa78fbdbe5fea78c7ae0b2c3364bc9572f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (204 commits) [SCSI] qla4xxx: export address/port of connection (fix udev disk names) [SCSI] ipr: Fix BUG on adapter dump timeout [SCSI] megaraid_sas: Fix instance access in megasas_reset_timer [SCSI] hpsa: change confusing message to be more clear [SCSI] iscsi class: fix vlan configuration [SCSI] qla4xxx: fix data alignment and use nl helpers [SCSI] iscsi class: fix link local mispelling [SCSI] iscsi class: Replace iscsi_get_next_target_id with IDA [SCSI] aacraid: use lower snprintf() limit [SCSI] lpfc 8.3.27: Change driver version to 8.3.27 [SCSI] lpfc 8.3.27: T10 additions for SLI4 [SCSI] lpfc 8.3.27: Fix queue allocation failure recovery [SCSI] lpfc 8.3.27: Change algorithm for getting physical port name [SCSI] lpfc 8.3.27: Changed worst case mailbox timeout [SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes [SCSI] megaraid_sas: Changelog and version update [SCSI] megaraid_sas: Add driver workaround for PERC5/1068 kdump kernel panic [SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support [SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers [SCSI] megaraid_sas: Clear FUSION_IN_RESET before enabling interrupts ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio_main.c11
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c36
-rw-r--r--drivers/s390/scsi/zfcp_def.h7
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c80
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c58
-rw-r--r--drivers/s390/scsi/zfcp_qdio.h66
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c15
9 files changed, 207 insertions, 68 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 9a122280246..6547ff46941 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -160,7 +160,8 @@ again:
160 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 160 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
161 q->handler(q->irq_ptr->cdev, 161 q->handler(q->irq_ptr->cdev,
162 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 162 QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
163 0, -1, -1, q->irq_ptr->int_parm); 163 q->nr, q->first_to_kick, count,
164 q->irq_ptr->int_parm);
164 return 0; 165 return 0;
165 } 166 }
166 return count - tmp_count; 167 return count - tmp_count;
@@ -206,7 +207,8 @@ again:
206 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 207 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
207 q->handler(q->irq_ptr->cdev, 208 q->handler(q->irq_ptr->cdev,
208 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 209 QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
209 0, -1, -1, q->irq_ptr->int_parm); 210 q->nr, q->first_to_kick, count,
211 q->irq_ptr->int_parm);
210 return 0; 212 return 0;
211 } 213 }
212 WARN_ON(tmp_count); 214 WARN_ON(tmp_count);
@@ -1070,6 +1072,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
1070{ 1072{
1071 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 1073 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1072 struct qdio_q *q; 1074 struct qdio_q *q;
1075 int count;
1073 1076
1074 DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no); 1077 DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
1075 DBF_ERROR("intp :%lx", intparm); 1078 DBF_ERROR("intp :%lx", intparm);
@@ -1083,8 +1086,10 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
1083 dump_stack(); 1086 dump_stack();
1084 goto no_handler; 1087 goto no_handler;
1085 } 1088 }
1089
1090 count = sub_buf(q->first_to_check, q->first_to_kick);
1086 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 1091 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
1087 0, -1, -1, irq_ptr->int_parm); 1092 q->nr, q->first_to_kick, count, irq_ptr->int_parm);
1088no_handler: 1093no_handler:
1089 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); 1094 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
1090} 1095}
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index dd8bd670a6b..d9a46a429bc 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -381,6 +381,7 @@ static void setup_qdr(struct qdio_irq *irq_ptr,
381 int i; 381 int i;
382 382
383 irq_ptr->qdr->qfmt = qdio_init->q_format; 383 irq_ptr->qdr->qfmt = qdio_init->q_format;
384 irq_ptr->qdr->ac = qdio_init->qdr_ac;
384 irq_ptr->qdr->iqdcnt = qdio_init->no_input_qs; 385 irq_ptr->qdr->iqdcnt = qdio_init->no_input_qs;
385 irq_ptr->qdr->oqdcnt = qdio_init->no_output_qs; 386 irq_ptr->qdr->oqdcnt = qdio_init->no_output_qs;
386 irq_ptr->qdr->iqdsz = sizeof(struct qdesfmt0) / 4; /* size in words */ 387 irq_ptr->qdr->iqdsz = sizeof(struct qdesfmt0) / 4; /* size in words */
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 96d1462e0bf..967e7b70e97 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -163,6 +163,42 @@ void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req)
163 spin_unlock_irqrestore(&dbf->hba_lock, flags); 163 spin_unlock_irqrestore(&dbf->hba_lock, flags);
164} 164}
165 165
166/**
167 * zfcp_dbf_hba_def_err - trace event for deferred error messages
168 * @adapter: pointer to struct zfcp_adapter
169 * @req_id: request id which caused the deferred error message
170 * @scount: number of sbals incl. the signaling sbal
171 * @pl: array of all involved sbals
172 */
173void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
174 void **pl)
175{
176 struct zfcp_dbf *dbf = adapter->dbf;
177 struct zfcp_dbf_pay *payload = &dbf->pay_buf;
178 unsigned long flags;
179 u16 length;
180
181 if (!pl)
182 return;
183
184 spin_lock_irqsave(&dbf->pay_lock, flags);
185 memset(payload, 0, sizeof(*payload));
186
187 memcpy(payload->area, "def_err", 7);
188 payload->fsf_req_id = req_id;
189 payload->counter = 0;
190 length = min((u16)sizeof(struct qdio_buffer),
191 (u16)ZFCP_DBF_PAY_MAX_REC);
192
193 while ((char *)pl[payload->counter] && payload->counter < scount) {
194 memcpy(payload->data, (char *)pl[payload->counter], length);
195 debug_event(dbf->pay, 1, payload, zfcp_dbf_plen(length));
196 payload->counter++;
197 }
198
199 spin_unlock_irqrestore(&dbf->pay_lock, flags);
200}
201
166static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, 202static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
167 struct zfcp_adapter *adapter, 203 struct zfcp_adapter *adapter,
168 struct zfcp_port *port, 204 struct zfcp_port *port,
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 527ba48eea5..ed5d921e82c 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -72,6 +72,7 @@ struct zfcp_reqlist;
72#define ZFCP_STATUS_COMMON_NOESC 0x00200000 72#define ZFCP_STATUS_COMMON_NOESC 0x00200000
73 73
74/* adapter status */ 74/* adapter status */
75#define ZFCP_STATUS_ADAPTER_MB_ACT 0x00000001
75#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 76#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
76#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004 77#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004
77#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 78#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
@@ -314,4 +315,10 @@ struct zfcp_fsf_req {
314 void (*handler)(struct zfcp_fsf_req *); 315 void (*handler)(struct zfcp_fsf_req *);
315}; 316};
316 317
318static inline
319int zfcp_adapter_multi_buffer_active(struct zfcp_adapter *adapter)
320{
321 return atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_MB_ACT;
322}
323
317#endif /* ZFCP_DEF_H */ 324#endif /* ZFCP_DEF_H */
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 03627cfd81c..2302e1cfb76 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -53,6 +53,7 @@ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
53extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *); 53extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
54extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); 54extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
55extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); 55extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
56extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
56extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); 57extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
57extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); 58extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
58extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *); 59extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 022fb6a8cb8..e9a787e2e6a 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -936,39 +936,47 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
936 struct scatterlist *sg_resp) 936 struct scatterlist *sg_resp)
937{ 937{
938 struct zfcp_adapter *adapter = req->adapter; 938 struct zfcp_adapter *adapter = req->adapter;
939 struct zfcp_qdio *qdio = adapter->qdio;
940 struct fsf_qtcb *qtcb = req->qtcb;
939 u32 feat = adapter->adapter_features; 941 u32 feat = adapter->adapter_features;
940 int bytes;
941 942
942 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) { 943 if (zfcp_adapter_multi_buffer_active(adapter)) {
943 if (!zfcp_qdio_sg_one_sbale(sg_req) || 944 if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
944 !zfcp_qdio_sg_one_sbale(sg_resp)) 945 return -EIO;
945 return -EOPNOTSUPP; 946 if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
947 return -EIO;
946 948
947 zfcp_fsf_setup_ct_els_unchained(adapter->qdio, &req->qdio_req, 949 zfcp_qdio_set_data_div(qdio, &req->qdio_req,
948 sg_req, sg_resp); 950 zfcp_qdio_sbale_count(sg_req));
951 zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
952 zfcp_qdio_set_scount(qdio, &req->qdio_req);
949 return 0; 953 return 0;
950 } 954 }
951 955
952 /* use single, unchained SBAL if it can hold the request */ 956 /* use single, unchained SBAL if it can hold the request */
953 if (zfcp_qdio_sg_one_sbale(sg_req) && zfcp_qdio_sg_one_sbale(sg_resp)) { 957 if (zfcp_qdio_sg_one_sbale(sg_req) && zfcp_qdio_sg_one_sbale(sg_resp)) {
954 zfcp_fsf_setup_ct_els_unchained(adapter->qdio, &req->qdio_req, 958 zfcp_fsf_setup_ct_els_unchained(qdio, &req->qdio_req,
955 sg_req, sg_resp); 959 sg_req, sg_resp);
956 return 0; 960 return 0;
957 } 961 }
958 962
959 bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, sg_req); 963 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS))
960 if (bytes <= 0) 964 return -EOPNOTSUPP;
965
966 if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
961 return -EIO; 967 return -EIO;
962 zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
963 req->qtcb->bottom.support.req_buf_length = bytes;
964 zfcp_qdio_skip_to_last_sbale(&req->qdio_req);
965 968
966 bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, 969 qtcb->bottom.support.req_buf_length = zfcp_qdio_real_bytes(sg_req);
967 sg_resp); 970
968 req->qtcb->bottom.support.resp_buf_length = bytes; 971 zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
969 if (bytes <= 0) 972 zfcp_qdio_skip_to_last_sbale(qdio, &req->qdio_req);
973
974 if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
970 return -EIO; 975 return -EIO;
971 zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); 976
977 qtcb->bottom.support.resp_buf_length = zfcp_qdio_real_bytes(sg_resp);
978
979 zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
972 980
973 return 0; 981 return 0;
974} 982}
@@ -1119,7 +1127,8 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
1119 1127
1120 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 1128 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1121 1129
1122 zfcp_qdio_sbal_limit(qdio, &req->qdio_req, 2); 1130 if (!zfcp_adapter_multi_buffer_active(adapter))
1131 zfcp_qdio_sbal_limit(qdio, &req->qdio_req, 2);
1123 1132
1124 ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, timeout); 1133 ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, timeout);
1125 1134
@@ -2162,7 +2171,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
2162 struct zfcp_fsf_req *req; 2171 struct zfcp_fsf_req *req;
2163 struct fcp_cmnd *fcp_cmnd; 2172 struct fcp_cmnd *fcp_cmnd;
2164 u8 sbtype = SBAL_SFLAGS0_TYPE_READ; 2173 u8 sbtype = SBAL_SFLAGS0_TYPE_READ;
2165 int real_bytes, retval = -EIO, dix_bytes = 0; 2174 int retval = -EIO;
2166 struct scsi_device *sdev = scsi_cmnd->device; 2175 struct scsi_device *sdev = scsi_cmnd->device;
2167 struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); 2176 struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
2168 struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; 2177 struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -2207,7 +2216,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
2207 io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF; 2216 io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF;
2208 } 2217 }
2209 2218
2210 zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction); 2219 if (zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction))
2220 goto failed_scsi_cmnd;
2211 2221
2212 fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; 2222 fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
2213 zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0); 2223 zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
@@ -2215,18 +2225,22 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
2215 if (scsi_prot_sg_count(scsi_cmnd)) { 2225 if (scsi_prot_sg_count(scsi_cmnd)) {
2216 zfcp_qdio_set_data_div(qdio, &req->qdio_req, 2226 zfcp_qdio_set_data_div(qdio, &req->qdio_req,
2217 scsi_prot_sg_count(scsi_cmnd)); 2227 scsi_prot_sg_count(scsi_cmnd));
2218 dix_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, 2228 retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
2229 scsi_prot_sglist(scsi_cmnd));
2230 if (retval)
2231 goto failed_scsi_cmnd;
2232 io->prot_data_length = zfcp_qdio_real_bytes(
2219 scsi_prot_sglist(scsi_cmnd)); 2233 scsi_prot_sglist(scsi_cmnd));
2220 io->prot_data_length = dix_bytes;
2221 } 2234 }
2222 2235
2223 real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, 2236 retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
2224 scsi_sglist(scsi_cmnd)); 2237 scsi_sglist(scsi_cmnd));
2225 2238 if (unlikely(retval))
2226 if (unlikely(real_bytes < 0) || unlikely(dix_bytes < 0))
2227 goto failed_scsi_cmnd; 2239 goto failed_scsi_cmnd;
2228 2240
2229 zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); 2241 zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
2242 if (zfcp_adapter_multi_buffer_active(adapter))
2243 zfcp_qdio_set_scount(qdio, &req->qdio_req);
2230 2244
2231 retval = zfcp_fsf_req_send(req); 2245 retval = zfcp_fsf_req_send(req);
2232 if (unlikely(retval)) 2246 if (unlikely(retval))
@@ -2328,7 +2342,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
2328 struct zfcp_qdio *qdio = adapter->qdio; 2342 struct zfcp_qdio *qdio = adapter->qdio;
2329 struct zfcp_fsf_req *req = NULL; 2343 struct zfcp_fsf_req *req = NULL;
2330 struct fsf_qtcb_bottom_support *bottom; 2344 struct fsf_qtcb_bottom_support *bottom;
2331 int retval = -EIO, bytes; 2345 int retval = -EIO;
2332 u8 direction; 2346 u8 direction;
2333 2347
2334 if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) 2348 if (!(adapter->adapter_features & FSF_FEATURE_CFDC))
@@ -2361,13 +2375,17 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
2361 bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; 2375 bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
2362 bottom->option = fsf_cfdc->option; 2376 bottom->option = fsf_cfdc->option;
2363 2377
2364 bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg); 2378 retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg);
2365 2379
2366 if (bytes != ZFCP_CFDC_MAX_SIZE) { 2380 if (retval ||
2381 (zfcp_qdio_real_bytes(fsf_cfdc->sg) != ZFCP_CFDC_MAX_SIZE)) {
2367 zfcp_fsf_req_free(req); 2382 zfcp_fsf_req_free(req);
2383 retval = -EIO;
2368 goto out; 2384 goto out;
2369 } 2385 }
2370 zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); 2386 zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
2387 if (zfcp_adapter_multi_buffer_active(adapter))
2388 zfcp_qdio_set_scount(qdio, &req->qdio_req);
2371 2389
2372 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); 2390 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
2373 retval = zfcp_fsf_req_send(req); 2391 retval = zfcp_fsf_req_send(req);
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index d9c40ea73ee..df9e69f5474 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -15,6 +15,10 @@
15 15
16#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) 16#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
17 17
18static bool enable_multibuffer;
19module_param_named(datarouter, enable_multibuffer, bool, 0400);
20MODULE_PARM_DESC(datarouter, "Enable hardware data router support");
21
18static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) 22static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
19{ 23{
20 int pos; 24 int pos;
@@ -37,8 +41,11 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
37 41
38 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); 42 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
39 43
40 if (qdio_err & QDIO_ERROR_SLSB_STATE) 44 if (qdio_err & QDIO_ERROR_SLSB_STATE) {
41 zfcp_qdio_siosl(adapter); 45 zfcp_qdio_siosl(adapter);
46 zfcp_erp_adapter_shutdown(adapter, 0, id);
47 return;
48 }
42 zfcp_erp_adapter_reopen(adapter, 49 zfcp_erp_adapter_reopen(adapter,
43 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 50 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
44 ZFCP_STATUS_COMMON_ERP_FAILED, id); 51 ZFCP_STATUS_COMMON_ERP_FAILED, id);
@@ -93,9 +100,27 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
93 unsigned long parm) 100 unsigned long parm)
94{ 101{
95 struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; 102 struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
96 int sbal_idx, sbal_no; 103 struct zfcp_adapter *adapter = qdio->adapter;
104 struct qdio_buffer_element *sbale;
105 int sbal_no, sbal_idx;
106 void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
107 u64 req_id;
108 u8 scount;
97 109
98 if (unlikely(qdio_err)) { 110 if (unlikely(qdio_err)) {
111 memset(pl, 0, ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
112 if (zfcp_adapter_multi_buffer_active(adapter)) {
113 sbale = qdio->res_q[idx]->element;
114 req_id = (u64) sbale->addr;
115 scount = sbale->scount + 1; /* incl. signaling SBAL */
116
117 for (sbal_no = 0; sbal_no < scount; sbal_no++) {
118 sbal_idx = (idx + sbal_no) %
119 QDIO_MAX_BUFFERS_PER_Q;
120 pl[sbal_no] = qdio->res_q[sbal_idx];
121 }
122 zfcp_dbf_hba_def_err(adapter, req_id, scount, pl);
123 }
99 zfcp_qdio_handler_error(qdio, "qdires1", qdio_err); 124 zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
100 return; 125 return;
101 } 126 }
@@ -155,7 +180,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
155static struct qdio_buffer_element * 180static struct qdio_buffer_element *
156zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) 181zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
157{ 182{
158 if (q_req->sbale_curr == ZFCP_QDIO_LAST_SBALE_PER_SBAL) 183 if (q_req->sbale_curr == qdio->max_sbale_per_sbal - 1)
159 return zfcp_qdio_sbal_chain(qdio, q_req); 184 return zfcp_qdio_sbal_chain(qdio, q_req);
160 q_req->sbale_curr++; 185 q_req->sbale_curr++;
161 return zfcp_qdio_sbale_curr(qdio, q_req); 186 return zfcp_qdio_sbale_curr(qdio, q_req);
@@ -167,13 +192,12 @@ zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
167 * @q_req: pointer to struct zfcp_qdio_req 192 * @q_req: pointer to struct zfcp_qdio_req
168 * @sg: scatter-gather list 193 * @sg: scatter-gather list
169 * @max_sbals: upper bound for number of SBALs to be used 194 * @max_sbals: upper bound for number of SBALs to be used
170 * Returns: number of bytes, or error (negativ) 195 * Returns: zero or -EINVAL on error
171 */ 196 */
172int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, 197int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
173 struct scatterlist *sg) 198 struct scatterlist *sg)
174{ 199{
175 struct qdio_buffer_element *sbale; 200 struct qdio_buffer_element *sbale;
176 int bytes = 0;
177 201
178 /* set storage-block type for this request */ 202 /* set storage-block type for this request */
179 sbale = zfcp_qdio_sbale_req(qdio, q_req); 203 sbale = zfcp_qdio_sbale_req(qdio, q_req);
@@ -187,14 +211,10 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
187 q_req->sbal_number); 211 q_req->sbal_number);
188 return -EINVAL; 212 return -EINVAL;
189 } 213 }
190
191 sbale->addr = sg_virt(sg); 214 sbale->addr = sg_virt(sg);
192 sbale->length = sg->length; 215 sbale->length = sg->length;
193
194 bytes += sg->length;
195 } 216 }
196 217 return 0;
197 return bytes;
198} 218}
199 219
200static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) 220static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
@@ -283,6 +303,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
283 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); 303 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
284 ASCEBC(id->adapter_name, 8); 304 ASCEBC(id->adapter_name, 8);
285 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; 305 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
306 if (enable_multibuffer)
307 id->qdr_ac |= QDR_AC_MULTI_BUFFER_ENABLE;
286 id->no_input_qs = 1; 308 id->no_input_qs = 1;
287 id->no_output_qs = 1; 309 id->no_output_qs = 1;
288 id->input_handler = zfcp_qdio_int_resp; 310 id->input_handler = zfcp_qdio_int_resp;
@@ -378,6 +400,17 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
378 atomic_set_mask(ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED, 400 atomic_set_mask(ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED,
379 &qdio->adapter->status); 401 &qdio->adapter->status);
380 402
403 if (ssqd.qdioac2 & CHSC_AC2_MULTI_BUFFER_ENABLED) {
404 atomic_set_mask(ZFCP_STATUS_ADAPTER_MB_ACT, &adapter->status);
405 qdio->max_sbale_per_sbal = QDIO_MAX_ELEMENTS_PER_BUFFER;
406 } else {
407 atomic_clear_mask(ZFCP_STATUS_ADAPTER_MB_ACT, &adapter->status);
408 qdio->max_sbale_per_sbal = QDIO_MAX_ELEMENTS_PER_BUFFER - 1;
409 }
410
411 qdio->max_sbale_per_req =
412 ZFCP_QDIO_MAX_SBALS_PER_REQ * qdio->max_sbale_per_sbal
413 - 2;
381 if (qdio_activate(cdev)) 414 if (qdio_activate(cdev))
382 goto failed_qdio; 415 goto failed_qdio;
383 416
@@ -397,6 +430,11 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
397 atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); 430 atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
398 atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); 431 atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
399 432
433 if (adapter->scsi_host) {
434 adapter->scsi_host->sg_tablesize = qdio->max_sbale_per_req;
435 adapter->scsi_host->max_sectors = qdio->max_sbale_per_req * 8;
436 }
437
400 return 0; 438 return 0;
401 439
402failed_qdio: 440failed_qdio:
diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h
index 54e22ace012..8ac7f5342d2 100644
--- a/drivers/s390/scsi/zfcp_qdio.h
+++ b/drivers/s390/scsi/zfcp_qdio.h
@@ -13,20 +13,9 @@
13 13
14#define ZFCP_QDIO_SBALE_LEN PAGE_SIZE 14#define ZFCP_QDIO_SBALE_LEN PAGE_SIZE
15 15
16/* DMQ bug workaround: don't use last SBALE */
17#define ZFCP_QDIO_MAX_SBALES_PER_SBAL (QDIO_MAX_ELEMENTS_PER_BUFFER - 1)
18
19/* index of last SBALE (with respect to DMQ bug workaround) */
20#define ZFCP_QDIO_LAST_SBALE_PER_SBAL (ZFCP_QDIO_MAX_SBALES_PER_SBAL - 1)
21
22/* Max SBALS for chaining */ 16/* Max SBALS for chaining */
23#define ZFCP_QDIO_MAX_SBALS_PER_REQ 36 17#define ZFCP_QDIO_MAX_SBALS_PER_REQ 36
24 18
25/* max. number of (data buffer) SBALEs in largest SBAL chain
26 * request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
27#define ZFCP_QDIO_MAX_SBALES_PER_REQ \
28 (ZFCP_QDIO_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2)
29
30/** 19/**
31 * struct zfcp_qdio - basic qdio data structure 20 * struct zfcp_qdio - basic qdio data structure
32 * @res_q: response queue 21 * @res_q: response queue
@@ -53,6 +42,8 @@ struct zfcp_qdio {
53 atomic_t req_q_full; 42 atomic_t req_q_full;
54 wait_queue_head_t req_q_wq; 43 wait_queue_head_t req_q_wq;
55 struct zfcp_adapter *adapter; 44 struct zfcp_adapter *adapter;
45 u16 max_sbale_per_sbal;
46 u16 max_sbale_per_req;
56}; 47};
57 48
58/** 49/**
@@ -155,7 +146,7 @@ void zfcp_qdio_fill_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
155{ 146{
156 struct qdio_buffer_element *sbale; 147 struct qdio_buffer_element *sbale;
157 148
158 BUG_ON(q_req->sbale_curr == ZFCP_QDIO_LAST_SBALE_PER_SBAL); 149 BUG_ON(q_req->sbale_curr == qdio->max_sbale_per_sbal - 1);
159 q_req->sbale_curr++; 150 q_req->sbale_curr++;
160 sbale = zfcp_qdio_sbale_curr(qdio, q_req); 151 sbale = zfcp_qdio_sbale_curr(qdio, q_req);
161 sbale->addr = data; 152 sbale->addr = data;
@@ -195,9 +186,10 @@ int zfcp_qdio_sg_one_sbale(struct scatterlist *sg)
195 * @q_req: The current zfcp_qdio_req 186 * @q_req: The current zfcp_qdio_req
196 */ 187 */
197static inline 188static inline
198void zfcp_qdio_skip_to_last_sbale(struct zfcp_qdio_req *q_req) 189void zfcp_qdio_skip_to_last_sbale(struct zfcp_qdio *qdio,
190 struct zfcp_qdio_req *q_req)
199{ 191{
200 q_req->sbale_curr = ZFCP_QDIO_LAST_SBALE_PER_SBAL; 192 q_req->sbale_curr = qdio->max_sbale_per_sbal - 1;
201} 193}
202 194
203/** 195/**
@@ -228,8 +220,52 @@ void zfcp_qdio_set_data_div(struct zfcp_qdio *qdio,
228{ 220{
229 struct qdio_buffer_element *sbale; 221 struct qdio_buffer_element *sbale;
230 222
231 sbale = &qdio->req_q[q_req->sbal_first]->element[0]; 223 sbale = qdio->req_q[q_req->sbal_first]->element;
232 sbale->length = count; 224 sbale->length = count;
233} 225}
234 226
227/**
228 * zfcp_qdio_sbale_count - count sbale used
229 * @sg: pointer to struct scatterlist
230 */
231static inline
232unsigned int zfcp_qdio_sbale_count(struct scatterlist *sg)
233{
234 unsigned int count = 0;
235
236 for (; sg; sg = sg_next(sg))
237 count++;
238
239 return count;
240}
241
242/**
243 * zfcp_qdio_real_bytes - count bytes used
244 * @sg: pointer to struct scatterlist
245 */
246static inline
247unsigned int zfcp_qdio_real_bytes(struct scatterlist *sg)
248{
249 unsigned int real_bytes = 0;
250
251 for (; sg; sg = sg_next(sg))
252 real_bytes += sg->length;
253
254 return real_bytes;
255}
256
257/**
258 * zfcp_qdio_set_scount - set SBAL count value
259 * @qdio: pointer to struct zfcp_qdio
260 * @q_req: The current zfcp_qdio_req
261 */
262static inline
263void zfcp_qdio_set_scount(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
264{
265 struct qdio_buffer_element *sbale;
266
267 sbale = qdio->req_q[q_req->sbal_first]->element;
268 sbale->scount = q_req->sbal_number - 1;
269}
270
235#endif /* ZFCP_QDIO_H */ 271#endif /* ZFCP_QDIO_H */
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 7cac873c738..09126a9d62f 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -24,11 +24,8 @@ module_param_named(queue_depth, default_depth, uint, 0600);
24MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); 24MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
25 25
26static bool enable_dif; 26static bool enable_dif;
27 27module_param_named(dif, enable_dif, bool, 0400);
28#ifdef CONFIG_ZFCP_DIF
29module_param_named(dif, enable_dif, bool, 0600);
30MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support"); 28MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
31#endif
32 29
33static bool allow_lun_scan = 1; 30static bool allow_lun_scan = 1;
34module_param(allow_lun_scan, bool, 0600); 31module_param(allow_lun_scan, bool, 0600);
@@ -309,8 +306,8 @@ static struct scsi_host_template zfcp_scsi_host_template = {
309 .proc_name = "zfcp", 306 .proc_name = "zfcp",
310 .can_queue = 4096, 307 .can_queue = 4096,
311 .this_id = -1, 308 .this_id = -1,
312 .sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ, 309 .sg_tablesize = 1, /* adjusted later */
313 .max_sectors = (ZFCP_QDIO_MAX_SBALES_PER_REQ * 8), 310 .max_sectors = 8, /* adjusted later */
314 .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, 311 .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1,
315 .cmd_per_lun = 1, 312 .cmd_per_lun = 1,
316 .use_clustering = 1, 313 .use_clustering = 1,
@@ -668,9 +665,9 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
668 adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) { 665 adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) {
669 mask |= SHOST_DIX_TYPE1_PROTECTION; 666 mask |= SHOST_DIX_TYPE1_PROTECTION;
670 scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP); 667 scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP);
671 shost->sg_prot_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2; 668 shost->sg_prot_tablesize = adapter->qdio->max_sbale_per_req / 2;
672 shost->sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2; 669 shost->sg_tablesize = adapter->qdio->max_sbale_per_req / 2;
673 shost->max_sectors = ZFCP_QDIO_MAX_SBALES_PER_REQ * 8 / 2; 670 shost->max_sectors = shost->sg_tablesize * 8;
674 } 671 }
675 672
676 scsi_host_set_prot(shost, mask); 673 scsi_host_set_prot(shost, mask);