diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2010-04-30 18:09:33 +0200 |
---|---|---|
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) | |
download | kernel_goldelico_gta04-683229845f1780b10041ee7a1043fc8f10061455.zip kernel_goldelico_gta04-683229845f1780b10041ee7a1043fc8f10061455.tar.gz kernel_goldelico_gta04-683229845f1780b10041ee7a1043fc8f10061455.tar.bz2 |
[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 1e6183a8..abf33db 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) &zfcp_sysfs_adapter_attrs)) goto failed; + /* report size limit per scatter-gather segment */ + adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; + adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; + if (!zfcp_adapter_scsi_register(adapter)) return adapter; diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 7131c7d..72132c13 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -205,6 +205,7 @@ struct zfcp_adapter { struct work_struct scan_work; struct service_level service_level; struct workqueue_struct *work_queue; + struct device_dma_parameters dma_parms; }; struct zfcp_port { diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index dbfa312..aa68515 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, zfcp_qdio_zero_sbals(sbal, first, count); } -static int zfcp_qdio_fill_sbals(struct zfcp_qdio *qdio, - struct zfcp_qdio_req *q_req, - unsigned int sbtype, void *start_addr, - unsigned int total_length) -{ - struct qdio_buffer_element *sbale; - unsigned long remaining, length; - void *addr; - - /* split segment up */ - for (addr = start_addr, remaining = total_length; remaining > 0; - addr += length, remaining -= length) { - sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype); - if (!sbale) { - atomic_inc(&qdio->req_q_full); - zfcp_qdio_undo_sbals(qdio, q_req); - return -EINVAL; - } - - /* new piece must not exceed next page boundary */ - length = min(remaining, - (PAGE_SIZE - ((unsigned long)addr & - (PAGE_SIZE - 1)))); - sbale->addr = addr; - sbale->length = length; - } - return 0; -} - /** * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list * @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, int max_sbals) { struct qdio_buffer_element *sbale; - int retval, bytes = 0; + int bytes = 0; /* figure out last allowed SBAL */ 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, sbale->flags |= sbtype; for (; sg; sg = sg_next(sg)) { - retval = zfcp_qdio_fill_sbals(qdio, q_req, sbtype, - sg_virt(sg), sg->length); - if (retval < 0) - return retval; + sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype); + if (!sbale) { + atomic_inc(&qdio->req_q_full); + zfcp_qdio_undo_sbals(qdio, q_req); + return -EINVAL; + } + + sbale->addr = sg_virt(sg); + sbale->length = sg->length; + bytes += sg->length; } diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h index 8cca546..f2b5a36 100644 --- a/drivers/s390/scsi/zfcp_qdio.h +++ b/drivers/s390/scsi/zfcp_qdio.h @@ -11,6 +11,8 @@ #include <asm/qdio.h> +#define ZFCP_QDIO_SBALE_LEN PAGE_SIZE + /** * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count * @sbal: qdio buffers diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index d13eb9a..066b050 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -682,6 +682,7 @@ struct zfcp_data zfcp_data = { .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), + .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, .shost_attrs = zfcp_sysfs_shost_attrs, }, }; |