aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2019-06-17 21:37:48 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-06-20 15:21:32 -0400
commit1194b5ce57d27c2ad49ed26f8cec98757c7c23ec (patch)
treece74be24a12b0c7139534ba271df8cfcb6767be3
parent74eb7446eda5e348dbb90981e91e9caf54f2fde4 (diff)
scsi: usb: image: microtek: use sg helper to iterate over scatterlist
Unlike the legacy I/O path, scsi-mq preallocates a large array to hold the scatterlist for each request. This static allocation can consume substantial amounts of memory on modern controllers which support a large number of concurrently outstanding requests. To facilitate a switch to a smaller static allocation combined with a dynamic allocation for requests that need it, we need to make sure all SCSI drivers handle chained scatterlists correctly. Convert remaining drivers that directly dereference the scatterlist array to using the iterator functions. [mkp: clarified commit message] Cc: Oliver Neukum <oliver@neukum.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: linux-usb@vger.kernel.org Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/usb/image/microtek.c20
-rw-r--r--drivers/usb/image/microtek.h2
2 files changed, 9 insertions, 13 deletions
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 607be1f4fe27..0a57c2cc8e5a 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -488,7 +488,6 @@ static void mts_command_done( struct urb *transfer )
488 488
489static void mts_do_sg (struct urb* transfer) 489static void mts_do_sg (struct urb* transfer)
490{ 490{
491 struct scatterlist * sg;
492 int status = transfer->status; 491 int status = transfer->status;
493 MTS_INT_INIT(); 492 MTS_INT_INIT();
494 493
@@ -500,13 +499,12 @@ static void mts_do_sg (struct urb* transfer)
500 mts_transfer_cleanup(transfer); 499 mts_transfer_cleanup(transfer);
501 } 500 }
502 501
503 sg = scsi_sglist(context->srb); 502 context->curr_sg = sg_next(context->curr_sg);
504 context->fragment++;
505 mts_int_submit_urb(transfer, 503 mts_int_submit_urb(transfer,
506 context->data_pipe, 504 context->data_pipe,
507 sg_virt(&sg[context->fragment]), 505 sg_virt(context->curr_sg),
508 sg[context->fragment].length, 506 context->curr_sg->length,
509 context->fragment + 1 == scsi_sg_count(context->srb) ? 507 sg_is_last(context->curr_sg) ?
510 mts_data_done : mts_do_sg); 508 mts_data_done : mts_do_sg);
511} 509}
512 510
@@ -526,22 +524,20 @@ static void
526mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) 524mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
527{ 525{
528 int pipe; 526 int pipe;
529 struct scatterlist * sg; 527
530
531 MTS_DEBUG_GOT_HERE(); 528 MTS_DEBUG_GOT_HERE();
532 529
533 desc->context.instance = desc; 530 desc->context.instance = desc;
534 desc->context.srb = srb; 531 desc->context.srb = srb;
535 desc->context.fragment = 0;
536 532
537 if (!scsi_bufflen(srb)) { 533 if (!scsi_bufflen(srb)) {
538 desc->context.data = NULL; 534 desc->context.data = NULL;
539 desc->context.data_length = 0; 535 desc->context.data_length = 0;
540 return; 536 return;
541 } else { 537 } else {
542 sg = scsi_sglist(srb); 538 desc->context.curr_sg = scsi_sglist(srb);
543 desc->context.data = sg_virt(&sg[0]); 539 desc->context.data = sg_virt(desc->context.curr_sg);
544 desc->context.data_length = sg[0].length; 540 desc->context.data_length = desc->context.curr_sg->length;
545 } 541 }
546 542
547 543
diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h
index 66685e59241a..7bd5f4639c4a 100644
--- a/drivers/usb/image/microtek.h
+++ b/drivers/usb/image/microtek.h
@@ -21,7 +21,7 @@ struct mts_transfer_context
21 void *data; 21 void *data;
22 unsigned data_length; 22 unsigned data_length;
23 int data_pipe; 23 int data_pipe;
24 int fragment; 24 struct scatterlist *curr_sg;
25 25
26 u8 *scsi_status; /* status returned from ep_response after command completion */ 26 u8 *scsi_status; /* status returned from ep_response after command completion */
27}; 27};