Commit 68322984 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[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: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 883c98fe
...@@ -545,6 +545,10 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) ...@@ -545,6 +545,10 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
&zfcp_sysfs_adapter_attrs)) &zfcp_sysfs_adapter_attrs))
goto failed; 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)) if (!zfcp_adapter_scsi_register(adapter))
return adapter; return adapter;
......
...@@ -205,6 +205,7 @@ struct zfcp_adapter { ...@@ -205,6 +205,7 @@ struct zfcp_adapter {
struct work_struct scan_work; struct work_struct scan_work;
struct service_level service_level; struct service_level service_level;
struct workqueue_struct *work_queue; struct workqueue_struct *work_queue;
struct device_dma_parameters dma_parms;
}; };
struct zfcp_port { struct zfcp_port {
......
...@@ -206,35 +206,6 @@ static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio, ...@@ -206,35 +206,6 @@ static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio,
zfcp_qdio_zero_sbals(sbal, first, count); 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 * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list
* @fsf_req: request to be processed * @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,7 +219,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
int max_sbals) int max_sbals)
{ {
struct qdio_buffer_element *sbale; struct qdio_buffer_element *sbale;
int retval, bytes = 0; int bytes = 0;
/* figure out last allowed SBAL */ /* figure out last allowed SBAL */
zfcp_qdio_sbal_limit(qdio, q_req, max_sbals); 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,10 +229,16 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
sbale->flags |= sbtype; sbale->flags |= sbtype;
for (; sg; sg = sg_next(sg)) { for (; sg; sg = sg_next(sg)) {
retval = zfcp_qdio_fill_sbals(qdio, q_req, sbtype, sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype);
sg_virt(sg), sg->length); if (!sbale) {
if (retval < 0) atomic_inc(&qdio->req_q_full);
return retval; zfcp_qdio_undo_sbals(qdio, q_req);
return -EINVAL;
}
sbale->addr = sg_virt(sg);
sbale->length = sg->length;
bytes += sg->length; bytes += sg->length;
} }
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <asm/qdio.h> #include <asm/qdio.h>
#define ZFCP_QDIO_SBALE_LEN PAGE_SIZE
/** /**
* struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count
* @sbal: qdio buffers * @sbal: qdio buffers
......
...@@ -682,6 +682,7 @@ struct zfcp_data zfcp_data = { ...@@ -682,6 +682,7 @@ struct zfcp_data zfcp_data = {
.use_clustering = 1, .use_clustering = 1,
.sdev_attrs = zfcp_sysfs_sdev_attrs, .sdev_attrs = zfcp_sysfs_sdev_attrs,
.max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8),
.dma_boundary = ZFCP_QDIO_SBALE_LEN - 1,
.shost_attrs = zfcp_sysfs_shost_attrs, .shost_attrs = zfcp_sysfs_shost_attrs,
}, },
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment