aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ide-scsi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 13:09:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 13:09:16 -0400
commit92d15c2ccbb3e31a3fc71ad28fdb55e1319383c0 (patch)
tree8d83c0dc3c6b935d8367e331872f242b742f0a8a /drivers/scsi/ide-scsi.c
parentf20bf6125605acbbc7eb8c9420d7221c91aa83eb (diff)
parent644bd2f048972d75eb1979b1fdca257d528ce687 (diff)
Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block: (63 commits) Fix memory leak in dm-crypt SPARC64: sg chaining support SPARC: sg chaining support PPC: sg chaining support PS3: sg chaining support IA64: sg chaining support x86-64: enable sg chaining x86-64: update pci-gart iommu to sg helpers x86-64: update nommu to sg helpers x86-64: update calgary iommu to sg helpers swiotlb: sg chaining support i386: enable sg chaining i386 dma_map_sg: convert to using sg helpers mmc: need to zero sglist on init Panic in blk_rq_map_sg() from CCISS driver remove sglist_len remove blk_queue_max_phys_segments in libata revert sg segment size ifdefs Fixup u14-34f ENABLE_SG_CHAINING qla1280: enable use_sg_chaining option ...
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;