aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ide-scsi.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-10-16 05:20:52 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 05:20:52 -0400
commitd274a9878bcd028712ea4f3d96db72b63d3eba4d (patch)
tree156c237e5fa38e86e3caa57f8bdac07aef0da94d /drivers/scsi/ide-scsi.c
parent2f08fe5221b79aa1e240aa3938e9de6ab0baf1d3 (diff)
ide-scsi: sg chaining support
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
-rw-r--r--drivers/scsi/ide-scsi.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d81bb076a15a..d297f64cd432 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -70,6 +70,7 @@ typedef struct idescsi_pc_s {
70 u8 *buffer; /* Data buffer */ 70 u8 *buffer; /* Data buffer */
71 u8 *current_position; /* Pointer into the above buffer */ 71 u8 *current_position; /* Pointer into the above buffer */
72 struct scatterlist *sg; /* Scatter gather table */ 72 struct scatterlist *sg; /* Scatter gather table */
73 struct scatterlist *last_sg; /* Last sg element */
73 int b_count; /* Bytes transferred from current entry */ 74 int b_count; /* Bytes transferred from current entry */
74 struct scsi_cmnd *scsi_cmd; /* SCSI command */ 75 struct scsi_cmnd *scsi_cmd; /* SCSI command */
75 void (*done)(struct scsi_cmnd *); /* Scsi completion routine */ 76 void (*done)(struct scsi_cmnd *); /* Scsi completion routine */
@@ -173,12 +174,6 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
173 char *buf; 174 char *buf;
174 175
175 while (bcount) { 176 while (bcount) {
176 if (pc->sg - scsi_sglist(pc->scsi_cmd) >
177 scsi_sg_count(pc->scsi_cmd)) {
178 printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
179 idescsi_discard_data (drive, bcount);
180 return;
181 }
182 count = min(pc->sg->length - pc->b_count, bcount); 177 count = min(pc->sg->length - pc->b_count, bcount);
183 if (PageHighMem(pc->sg->page)) { 178 if (PageHighMem(pc->sg->page)) {
184 unsigned long flags; 179 unsigned long flags;
@@ -197,10 +192,17 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
197 } 192 }
198 bcount -= count; pc->b_count += count; 193 bcount -= count; pc->b_count += count;
199 if (pc->b_count == pc->sg->length) { 194 if (pc->b_count == pc->sg->length) {
200 pc->sg++; 195 if (pc->sg == pc->last_sg)
196 break;
197 pc->sg = sg_next(pc->sg);
201 pc->b_count = 0; 198 pc->b_count = 0;
202 } 199 }
203 } 200 }
201
202 if (bcount) {
203 printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
204 idescsi_discard_data (drive, bcount);
205 }
204} 206}
205 207
206static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) 208static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
@@ -209,12 +211,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
209 char *buf; 211 char *buf;
210 212
211 while (bcount) { 213 while (bcount) {
212 if (pc->sg - scsi_sglist(pc->scsi_cmd) >
213 scsi_sg_count(pc->scsi_cmd)) {
214 printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
215 idescsi_output_zeros (drive, bcount);
216 return;
217 }
218 count = min(pc->sg->length - pc->b_count, bcount); 214 count = min(pc->sg->length - pc->b_count, bcount);
219 if (PageHighMem(pc->sg->page)) { 215 if (PageHighMem(pc->sg->page)) {
220 unsigned long flags; 216 unsigned long flags;
@@ -233,10 +229,17 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
233 } 229 }
234 bcount -= count; pc->b_count += count; 230 bcount -= count; pc->b_count += count;
235 if (pc->b_count == pc->sg->length) { 231 if (pc->b_count == pc->sg->length) {
236 pc->sg++; 232 if (pc->sg == pc->last_sg)
233 break;
234 pc->sg = sg_next(pc->sg);
237 pc->b_count = 0; 235 pc->b_count = 0;
238 } 236 }
239 } 237 }
238
239 if (bcount) {
240 printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
241 idescsi_output_zeros (drive, bcount);
242 }
240} 243}
241 244
242static void hexdump(u8 *x, int len) 245static void hexdump(u8 *x, int len)
@@ -804,6 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
804 memcpy (pc->c, cmd->cmnd, cmd->cmd_len); 807 memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
805 pc->buffer = NULL; 808 pc->buffer = NULL;
806 pc->sg = scsi_sglist(cmd); 809 pc->sg = scsi_sglist(cmd);
810 pc->last_sg = sg_last(pc->sg, cmd->use_sg);
807 pc->b_count = 0; 811 pc->b_count = 0;
808 pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); 812 pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd);
809 pc->scsi_cmd = cmd; 813 pc->scsi_cmd = cmd;