diff options
author | Andrew Morton <akpm@osdl.org> | 2005-10-31 17:08:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-31 17:22:04 -0500 |
commit | a717f77362d4fe044721c126c89e2a38e731a576 (patch) | |
tree | b899e97f5c73a1679613903a1c378352a0997749 /drivers | |
parent | f2c84c0e84bfa637a7161eac10157cf3b05b4a73 (diff) |
[PATCH] revert ide-scsi highmem cleanup
Jeff Garzik <jgarzik@pobox.com> points out that this was wrong: we need to
disable local interrupts while holding KM_IRQ0 due to IRQ sharing.
And holding interrupts off during a big PIO opration is expensive, so we only
want to do that if we know the page was highmem.
So revert commit 17fd47ab4d33e764216b87006d8118fa050b4c92
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/ide-scsi.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 00d6a6657ebc..a440ea38efaa 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -180,12 +180,22 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne | |||
180 | return; | 180 | return; |
181 | } | 181 | } |
182 | count = min(pc->sg->length - pc->b_count, bcount); | 182 | count = min(pc->sg->length - pc->b_count, bcount); |
183 | buf = kmap_atomic(pc->sg->page, KM_IRQ0); | 183 | if (PageHighMem(pc->sg->page)) { |
184 | drive->hwif->atapi_input_bytes(drive, | 184 | unsigned long flags; |
185 | buf + pc->b_count + pc->sg->offset, count); | 185 | |
186 | kunmap_atomic(buf, KM_IRQ0); | 186 | local_irq_save(flags); |
187 | bcount -= count; | 187 | buf = kmap_atomic(pc->sg->page, KM_IRQ0) + |
188 | pc->b_count += count; | 188 | pc->sg->offset; |
189 | drive->hwif->atapi_input_bytes(drive, | ||
190 | buf + pc->b_count, count); | ||
191 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
192 | local_irq_restore(flags); | ||
193 | } else { | ||
194 | buf = page_address(pc->sg->page) + pc->sg->offset; | ||
195 | drive->hwif->atapi_input_bytes(drive, | ||
196 | buf + pc->b_count, count); | ||
197 | } | ||
198 | bcount -= count; pc->b_count += count; | ||
189 | if (pc->b_count == pc->sg->length) { | 199 | if (pc->b_count == pc->sg->length) { |
190 | pc->sg++; | 200 | pc->sg++; |
191 | pc->b_count = 0; | 201 | pc->b_count = 0; |
@@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign | |||
205 | return; | 215 | return; |
206 | } | 216 | } |
207 | count = min(pc->sg->length - pc->b_count, bcount); | 217 | count = min(pc->sg->length - pc->b_count, bcount); |
208 | buf = kmap_atomic(pc->sg->page, KM_IRQ0); | 218 | if (PageHighMem(pc->sg->page)) { |
209 | drive->hwif->atapi_output_bytes(drive, | 219 | unsigned long flags; |
210 | buf + pc->b_count + pc->sg->offset, count); | 220 | |
211 | kunmap_atomic(buf, KM_IRQ0); | 221 | local_irq_save(flags); |
212 | bcount -= count; | 222 | buf = kmap_atomic(pc->sg->page, KM_IRQ0) + |
213 | pc->b_count += count; | 223 | pc->sg->offset; |
224 | drive->hwif->atapi_output_bytes(drive, | ||
225 | buf + pc->b_count, count); | ||
226 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
227 | local_irq_restore(flags); | ||
228 | } else { | ||
229 | buf = page_address(pc->sg->page) + pc->sg->offset; | ||
230 | drive->hwif->atapi_output_bytes(drive, | ||
231 | buf + pc->b_count, count); | ||
232 | } | ||
233 | bcount -= count; pc->b_count += count; | ||
214 | if (pc->b_count == pc->sg->length) { | 234 | if (pc->b_count == pc->sg->length) { |
215 | pc->sg++; | 235 | pc->sg++; |
216 | pc->b_count = 0; | 236 | pc->b_count = 0; |