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 | |
| 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>
| -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; |
