diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2010-04-30 12:09:33 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-02 15:42:29 -0400 |
commit | 683229845f1780b10041ee7a1043fc8f10061455 (patch) | |
tree | 88f58f214666762a71d1458a72646dd65372a1a6 /drivers/s390/scsi | |
parent | 883c98feaab708d0fc976225b146aa9307023c85 (diff) |
[SCSI] zfcp: Report scatter-gather limits to SCSI and block layer
Instead of dealing with large segments in the scatter-gather lists in
zfcp_qdio.c, report the limits to the upper layers. With these limits
in place, the code for mapping large data blocks to multiple sbales
can be removed.
Reviewed-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 4 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 45 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.h | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 1 |
5 files changed, 19 insertions, 34 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 1e6183a86ce5..abf33db647ff 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -545,6 +545,10 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
545 | &zfcp_sysfs_adapter_attrs)) | 545 | &zfcp_sysfs_adapter_attrs)) |
546 | goto failed; | 546 | goto failed; |
547 | 547 | ||
548 | /* report size limit per scatter-gather segment */ | ||
549 | adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; | ||
550 | adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; | ||
551 | |||
548 | if (!zfcp_adapter_scsi_register(adapter)) | 552 | if (!zfcp_adapter_scsi_register(adapter)) |
549 | return adapter; | 553 | return adapter; |
550 | 554 | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 7131c7db1f04..72132c13f45b 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -205,6 +205,7 @@ struct zfcp_adapter { | |||
205 | struct work_struct scan_work; | 205 | struct work_struct scan_work; |
206 | struct service_level service_level; | 206 | struct service_level service_level; |
207 | struct workqueue_struct *work_queue; | 207 | struct workqueue_struct *work_queue; |
208 | struct device_dma_parameters dma_parms; | ||
208 | }; | 209 | }; |
209 | 210 | ||
210 | struct zfcp_port { | 211 | struct zfcp_port { |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index dbfa312a7f50..aa68515abe21 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -206,35 +206,6 @@ static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio, | |||
206 | zfcp_qdio_zero_sbals(sbal, first, count); | 206 | zfcp_qdio_zero_sbals(sbal, first, count); |
207 | } | 207 | } |
208 | 208 | ||
209 | static int zfcp_qdio_fill_sbals(struct zfcp_qdio *qdio, | ||
210 | struct zfcp_qdio_req *q_req, | ||
211 | unsigned int sbtype, void *start_addr, | ||
212 | unsigned int total_length) | ||
213 | { | ||
214 | struct qdio_buffer_element *sbale; | ||
215 | unsigned long remaining, length; | ||
216 | void *addr; | ||
217 | |||
218 | /* split segment up */ | ||
219 | for (addr = start_addr, remaining = total_length; remaining > 0; | ||
220 | addr += length, remaining -= length) { | ||
221 | sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype); | ||
222 | if (!sbale) { | ||
223 | atomic_inc(&qdio->req_q_full); | ||
224 | zfcp_qdio_undo_sbals(qdio, q_req); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | /* new piece must not exceed next page boundary */ | ||
229 | length = min(remaining, | ||
230 | (PAGE_SIZE - ((unsigned long)addr & | ||
231 | (PAGE_SIZE - 1)))); | ||
232 | sbale->addr = addr; | ||
233 | sbale->length = length; | ||
234 | } | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | /** | 209 | /** |
239 | * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list | 210 | * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list |
240 | * @fsf_req: request to be processed | 211 | * @fsf_req: request to be processed |
@@ -248,7 +219,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, | |||
248 | int max_sbals) | 219 | int max_sbals) |
249 | { | 220 | { |
250 | struct qdio_buffer_element *sbale; | 221 | struct qdio_buffer_element *sbale; |
251 | int retval, bytes = 0; | 222 | int bytes = 0; |
252 | 223 | ||
253 | /* figure out last allowed SBAL */ | 224 | /* figure out last allowed SBAL */ |
254 | zfcp_qdio_sbal_limit(qdio, q_req, max_sbals); | 225 | zfcp_qdio_sbal_limit(qdio, q_req, max_sbals); |
@@ -258,10 +229,16 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, | |||
258 | sbale->flags |= sbtype; | 229 | sbale->flags |= sbtype; |
259 | 230 | ||
260 | for (; sg; sg = sg_next(sg)) { | 231 | for (; sg; sg = sg_next(sg)) { |
261 | retval = zfcp_qdio_fill_sbals(qdio, q_req, sbtype, | 232 | sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype); |
262 | sg_virt(sg), sg->length); | 233 | if (!sbale) { |
263 | if (retval < 0) | 234 | atomic_inc(&qdio->req_q_full); |
264 | return retval; | 235 | zfcp_qdio_undo_sbals(qdio, q_req); |
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | sbale->addr = sg_virt(sg); | ||
240 | sbale->length = sg->length; | ||
241 | |||
265 | bytes += sg->length; | 242 | bytes += sg->length; |
266 | } | 243 | } |
267 | 244 | ||
diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h index 8cca54631e1e..f2b5a363bb84 100644 --- a/drivers/s390/scsi/zfcp_qdio.h +++ b/drivers/s390/scsi/zfcp_qdio.h | |||
@@ -11,6 +11,8 @@ | |||
11 | 11 | ||
12 | #include <asm/qdio.h> | 12 | #include <asm/qdio.h> |
13 | 13 | ||
14 | #define ZFCP_QDIO_SBALE_LEN PAGE_SIZE | ||
15 | |||
14 | /** | 16 | /** |
15 | * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count | 17 | * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count |
16 | * @sbal: qdio buffers | 18 | * @sbal: qdio buffers |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index d13eb9a6408a..066b0507a639 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -682,6 +682,7 @@ struct zfcp_data zfcp_data = { | |||
682 | .use_clustering = 1, | 682 | .use_clustering = 1, |
683 | .sdev_attrs = zfcp_sysfs_sdev_attrs, | 683 | .sdev_attrs = zfcp_sysfs_sdev_attrs, |
684 | .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), | 684 | .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), |
685 | .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, | ||
685 | .shost_attrs = zfcp_sysfs_shost_attrs, | 686 | .shost_attrs = zfcp_sysfs_shost_attrs, |
686 | }, | 687 | }, |
687 | }; | 688 | }; |