Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ming Lei and committed by
Martin K. Petersen
1194b5ce 74eb7446

+9 -13
+8 -12
drivers/usb/image/microtek.c
··· 488 488 489 489 static void mts_do_sg (struct urb* transfer) 490 490 { 491 - struct scatterlist * sg; 492 491 int status = transfer->status; 493 492 MTS_INT_INIT(); 494 493 ··· 499 500 mts_transfer_cleanup(transfer); 500 501 } 501 502 502 - sg = scsi_sglist(context->srb); 503 - context->fragment++; 503 + context->curr_sg = sg_next(context->curr_sg); 504 504 mts_int_submit_urb(transfer, 505 505 context->data_pipe, 506 - sg_virt(&sg[context->fragment]), 507 - sg[context->fragment].length, 508 - context->fragment + 1 == scsi_sg_count(context->srb) ? 506 + sg_virt(context->curr_sg), 507 + context->curr_sg->length, 508 + sg_is_last(context->curr_sg) ? 509 509 mts_data_done : mts_do_sg); 510 510 } 511 511 ··· 524 526 mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) 525 527 { 526 528 int pipe; 527 - struct scatterlist * sg; 528 - 529 + 529 530 MTS_DEBUG_GOT_HERE(); 530 531 531 532 desc->context.instance = desc; 532 533 desc->context.srb = srb; 533 - desc->context.fragment = 0; 534 534 535 535 if (!scsi_bufflen(srb)) { 536 536 desc->context.data = NULL; 537 537 desc->context.data_length = 0; 538 538 return; 539 539 } else { 540 - sg = scsi_sglist(srb); 541 - desc->context.data = sg_virt(&sg[0]); 542 - desc->context.data_length = sg[0].length; 540 + desc->context.curr_sg = scsi_sglist(srb); 541 + desc->context.data = sg_virt(desc->context.curr_sg); 542 + desc->context.data_length = desc->context.curr_sg->length; 543 543 } 544 544 545 545
+1 -1
drivers/usb/image/microtek.h
··· 21 21 void *data; 22 22 unsigned data_length; 23 23 int data_pipe; 24 - int fragment; 24 + struct scatterlist *curr_sg; 25 25 26 26 u8 *scsi_status; /* status returned from ep_response after command completion */ 27 27 };