Use the scatterlist iterators and remove direct indexing of the
scatterlist array.

This way allows us to pre-allocate one small scatterlist, which can be
chained with one runtime allocated scatterlist if the pre-allocated one
isn't enough for the whole request.

Signed-off-by: Ming Lei <ming....@redhat.com>
---
 drivers/scsi/aha152x.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 97872838b983..bc9d12aa7880 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -2033,7 +2033,7 @@ static void datai_run(struct Scsi_Host *shpnt)
                                    CURRENT_SC->SCp.buffers_residual > 0) {
                                        /* advance to next buffer */
                                        CURRENT_SC->SCp.buffers_residual--;
-                                       CURRENT_SC->SCp.buffer++;
+                                       CURRENT_SC->SCp.buffer = 
sg_next(CURRENT_SC->SCp.buffer);
                                        CURRENT_SC->SCp.ptr           = 
SG_ADDRESS(CURRENT_SC->SCp.buffer);
                                        CURRENT_SC->SCp.this_residual = 
CURRENT_SC->SCp.buffer->length;
                                }
@@ -2139,7 +2139,7 @@ static void datao_run(struct Scsi_Host *shpnt)
                if(CURRENT_SC->SCp.this_residual==0 && 
CURRENT_SC->SCp.buffers_residual>0) {
                        /* advance to next buffer */
                        CURRENT_SC->SCp.buffers_residual--;
-                       CURRENT_SC->SCp.buffer++;
+                       CURRENT_SC->SCp.buffer = 
sg_next(CURRENT_SC->SCp.buffer);
                        CURRENT_SC->SCp.ptr           = 
SG_ADDRESS(CURRENT_SC->SCp.buffer);
                        CURRENT_SC->SCp.this_residual = 
CURRENT_SC->SCp.buffer->length;
                }
@@ -2160,20 +2160,29 @@ static void datao_end(struct Scsi_Host *shpnt)
        if(TESTLO(DMASTAT, DFIFOEMP)) {
                int data_count = (DATA_LEN - scsi_get_resid(CURRENT_SC)) -
                        GETSTCNT();
+               struct scatterlist *sg = scsi_sglist(CURRENT_SC);
+               int left, i = 0;
 
                CMD_INC_RESID(CURRENT_SC, data_count);
 
                data_count -= CURRENT_SC->SCp.ptr -
                        SG_ADDRESS(CURRENT_SC->SCp.buffer);
-               while(data_count>0) {
-                       CURRENT_SC->SCp.buffer--;
-                       CURRENT_SC->SCp.buffers_residual++;
-                       data_count -= CURRENT_SC->SCp.buffer->length;
+
+               left = CURRENT_SC->transfersize - data_count;
+               for (i = 0; left > 0 && !sg_is_last(sg); i++, sg = sg_next(sg)) 
{
+                       if (left < sg->length)
+                               break;
+                       left -= sg->length;
+               }
+
+               if (data_count > 0) {
+                       CURRENT_SC->SCp.buffers_residual += i;
+                       CURRENT_SC->SCp.buffer = sg;
+
+                       CURRENT_SC->SCp.ptr = 
SG_ADDRESS(CURRENT_SC->SCp.buffer) + left;
+                       CURRENT_SC->SCp.this_residual = 
CURRENT_SC->SCp.buffer->length -
+                               left;
                }
-               CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) -
-                       data_count;
-               CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length +
-                       data_count;
        }
 
        SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
-- 
2.20.1

Reply via email to