@@ -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);
The current way isn't safe for chained sgl, so use sg helper to operate sgl. Signed-off-by: Ming Lei <ming.lei@redhat.com> --- drivers/scsi/aha152x.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)