Commit a60eec02 authored by Kevin Barnett's avatar Kevin Barnett Committed by Martin K. Petersen

scsi: smartpqi: change aio sg processing

Take advantage of controller improvements.
Reviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
Reviewed-by: default avatarScott Benesh <scott.benesh@microsemi.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarKevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b2990536
...@@ -4263,48 +4263,58 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, ...@@ -4263,48 +4263,58 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info,
int i; int i;
u16 iu_length; u16 iu_length;
int sg_count; int sg_count;
unsigned int num_sg_in_iu = 0; bool chained;
unsigned int num_sg_in_iu;
unsigned int max_sg_per_iu;
struct scatterlist *sg; struct scatterlist *sg;
struct pqi_sg_descriptor *sg_descriptor; struct pqi_sg_descriptor *sg_descriptor;
sg_count = scsi_dma_map(scmd); sg_count = scsi_dma_map(scmd);
if (sg_count < 0) if (sg_count < 0)
return sg_count; return sg_count;
iu_length = offsetof(struct pqi_aio_path_request, sg_descriptors) -
PQI_REQUEST_HEADER_LENGTH;
num_sg_in_iu = 0;
if (sg_count == 0) if (sg_count == 0)
goto out; goto out;
if (sg_count <= ctrl_info->max_sg_per_iu) { sg = scsi_sglist(scmd);
sg_descriptor = &request->sg_descriptors[0]; sg_descriptor = request->sg_descriptors;
scsi_for_each_sg(scmd, sg, sg_count, i) { max_sg_per_iu = ctrl_info->max_sg_per_iu - 1;
pqi_set_sg_descriptor(sg_descriptor, sg); chained = false;
sg_descriptor++; i = 0;
}
put_unaligned_le32(CISS_SG_LAST, while (1) {
&request->sg_descriptors[sg_count - 1].flags); pqi_set_sg_descriptor(sg_descriptor, sg);
num_sg_in_iu = sg_count; if (!chained)
} else { num_sg_in_iu++;
sg_descriptor = &request->sg_descriptors[0]; i++;
put_unaligned_le64((u64)io_request->sg_chain_buffer_dma_handle, if (i == sg_count)
&sg_descriptor->address); break;
put_unaligned_le32(sg_count * sizeof(*sg_descriptor), sg_descriptor++;
&sg_descriptor->length); if (i == max_sg_per_iu) {
put_unaligned_le32(CISS_SG_CHAIN, &sg_descriptor->flags); put_unaligned_le64(
(u64)io_request->sg_chain_buffer_dma_handle,
sg_descriptor = io_request->sg_chain_buffer; &sg_descriptor->address);
scsi_for_each_sg(scmd, sg, sg_count, i) { put_unaligned_le32((sg_count - num_sg_in_iu)
pqi_set_sg_descriptor(sg_descriptor, sg); * sizeof(*sg_descriptor),
sg_descriptor++; &sg_descriptor->length);
put_unaligned_le32(CISS_SG_CHAIN,
&sg_descriptor->flags);
chained = true;
num_sg_in_iu++;
sg_descriptor = io_request->sg_chain_buffer;
} }
put_unaligned_le32(CISS_SG_LAST, sg = sg_next(sg);
&io_request->sg_chain_buffer[sg_count - 1].flags);
num_sg_in_iu = 1;
request->partial = 1;
} }
out: put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags);
iu_length = offsetof(struct pqi_aio_path_request, sg_descriptors) - request->partial = chained;
PQI_REQUEST_HEADER_LENGTH;
iu_length += num_sg_in_iu * sizeof(*sg_descriptor); iu_length += num_sg_in_iu * sizeof(*sg_descriptor);
out:
put_unaligned_le16(iu_length, &request->header.iu_length); put_unaligned_le16(iu_length, &request->header.iu_length);
request->num_sg_descriptors = num_sg_in_iu; request->num_sg_descriptors = num_sg_in_iu;
......
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