aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Barnett <kevin.barnett@microsemi.com>2016-08-31 15:54:11 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-09-02 06:21:37 -0400
commita60eec0251fe1bfc0cd549c073591e6657761158 (patch)
tree77ee5da669f12556439fda67e80d9fc8e7e9ac37
parentb2990536f44752e54dc300a2f98253519adfe649 (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.c68
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
4304out: 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
4317out:
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