diff options
author | Kevin Barnett <kevin.barnett@microsemi.com> | 2016-08-31 15:54:11 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-09-02 06:21:37 -0400 |
commit | a60eec0251fe1bfc0cd549c073591e6657761158 (patch) | |
tree | 77ee5da669f12556439fda67e80d9fc8e7e9ac37 | |
parent | b2990536f44752e54dc300a2f98253519adfe649 (diff) |
scsi: smartpqi: change aio sg processing
Take advantage of controller improvements.
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi_init.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 906f1aaf7cd2..418f63670d71 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c | |||
@@ -4263,48 +4263,58 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, | |||
4263 | int i; | 4263 | int i; |
4264 | u16 iu_length; | 4264 | u16 iu_length; |
4265 | int sg_count; | 4265 | int sg_count; |
4266 | unsigned int num_sg_in_iu = 0; | 4266 | bool chained; |
4267 | unsigned int num_sg_in_iu; | ||
4268 | unsigned int max_sg_per_iu; | ||
4267 | struct scatterlist *sg; | 4269 | struct scatterlist *sg; |
4268 | struct pqi_sg_descriptor *sg_descriptor; | 4270 | struct pqi_sg_descriptor *sg_descriptor; |
4269 | 4271 | ||
4270 | sg_count = scsi_dma_map(scmd); | 4272 | sg_count = scsi_dma_map(scmd); |
4271 | if (sg_count < 0) | 4273 | if (sg_count < 0) |
4272 | return sg_count; | 4274 | return sg_count; |
4275 | |||
4276 | iu_length = offsetof(struct pqi_aio_path_request, sg_descriptors) - | ||
4277 | PQI_REQUEST_HEADER_LENGTH; | ||
4278 | num_sg_in_iu = 0; | ||
4279 | |||
4273 | if (sg_count == 0) | 4280 | if (sg_count == 0) |
4274 | goto out; | 4281 | goto out; |
4275 | 4282 | ||
4276 | if (sg_count <= ctrl_info->max_sg_per_iu) { | 4283 | sg = scsi_sglist(scmd); |
4277 | sg_descriptor = &request->sg_descriptors[0]; | 4284 | sg_descriptor = request->sg_descriptors; |
4278 | scsi_for_each_sg(scmd, sg, sg_count, i) { | 4285 | max_sg_per_iu = ctrl_info->max_sg_per_iu - 1; |
4279 | pqi_set_sg_descriptor(sg_descriptor, sg); | 4286 | chained = false; |
4280 | sg_descriptor++; | 4287 | i = 0; |
4281 | } | 4288 | |
4282 | put_unaligned_le32(CISS_SG_LAST, | 4289 | while (1) { |
4283 | &request->sg_descriptors[sg_count - 1].flags); | 4290 | pqi_set_sg_descriptor(sg_descriptor, sg); |
4284 | num_sg_in_iu = sg_count; | 4291 | if (!chained) |
4285 | } else { | 4292 | num_sg_in_iu++; |
4286 | sg_descriptor = &request->sg_descriptors[0]; | 4293 | i++; |
4287 | put_unaligned_le64((u64)io_request->sg_chain_buffer_dma_handle, | 4294 | if (i == sg_count) |
4288 | &sg_descriptor->address); | 4295 | break; |
4289 | put_unaligned_le32(sg_count * sizeof(*sg_descriptor), | 4296 | sg_descriptor++; |
4290 | &sg_descriptor->length); | 4297 | if (i == max_sg_per_iu) { |
4291 | put_unaligned_le32(CISS_SG_CHAIN, &sg_descriptor->flags); | 4298 | put_unaligned_le64( |
4292 | 4299 | (u64)io_request->sg_chain_buffer_dma_handle, | |
4293 | sg_descriptor = io_request->sg_chain_buffer; | 4300 | &sg_descriptor->address); |
4294 | scsi_for_each_sg(scmd, sg, sg_count, i) { | 4301 | put_unaligned_le32((sg_count - num_sg_in_iu) |
4295 | pqi_set_sg_descriptor(sg_descriptor, sg); | 4302 | * sizeof(*sg_descriptor), |
4296 | sg_descriptor++; | 4303 | &sg_descriptor->length); |
4304 | put_unaligned_le32(CISS_SG_CHAIN, | ||
4305 | &sg_descriptor->flags); | ||
4306 | chained = true; | ||
4307 | num_sg_in_iu++; | ||
4308 | sg_descriptor = io_request->sg_chain_buffer; | ||
4297 | } | 4309 | } |
4298 | put_unaligned_le32(CISS_SG_LAST, | 4310 | sg = sg_next(sg); |
4299 | &io_request->sg_chain_buffer[sg_count - 1].flags); | ||
4300 | num_sg_in_iu = 1; | ||
4301 | request->partial = 1; | ||
4302 | } | 4311 | } |
4303 | 4312 | ||
4304 | out: | 4313 | put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); |
4305 | iu_length = offsetof(struct pqi_aio_path_request, sg_descriptors) - | 4314 | request->partial = chained; |
4306 | PQI_REQUEST_HEADER_LENGTH; | ||
4307 | iu_length += num_sg_in_iu * sizeof(*sg_descriptor); | 4315 | iu_length += num_sg_in_iu * sizeof(*sg_descriptor); |
4316 | |||
4317 | out: | ||
4308 | put_unaligned_le16(iu_length, &request->header.iu_length); | 4318 | put_unaligned_le16(iu_length, &request->header.iu_length); |
4309 | request->num_sg_descriptors = num_sg_in_iu; | 4319 | request->num_sg_descriptors = num_sg_in_iu; |
4310 | 4320 | ||