From: Andrew Morton Date: Mon, 31 Oct 2005 22:08:53 +0000 (-0800) Subject: [PATCH] revert ide-scsi highmem cleanup X-Git-Tag: v2.6.15-rc1~18^2~42 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a717f77362d4fe044721c126c89e2a38e731a576;p=linux-2.6 [PATCH] revert ide-scsi highmem cleanup Jeff Garzik 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 Signed-off-by: Linus Torvalds --- diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 00d6a6657e..a440ea38ef 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 return; } count = min(pc->sg->length - pc->b_count, bcount); - buf = kmap_atomic(pc->sg->page, KM_IRQ0); - drive->hwif->atapi_input_bytes(drive, - buf + pc->b_count + pc->sg->offset, count); - kunmap_atomic(buf, KM_IRQ0); - bcount -= count; - pc->b_count += count; + if (PageHighMem(pc->sg->page)) { + unsigned long flags; + + local_irq_save(flags); + buf = kmap_atomic(pc->sg->page, KM_IRQ0) + + pc->sg->offset; + drive->hwif->atapi_input_bytes(drive, + buf + pc->b_count, count); + kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); + local_irq_restore(flags); + } else { + buf = page_address(pc->sg->page) + pc->sg->offset; + drive->hwif->atapi_input_bytes(drive, + buf + pc->b_count, count); + } + bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; pc->b_count = 0; @@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign return; } count = min(pc->sg->length - pc->b_count, bcount); - buf = kmap_atomic(pc->sg->page, KM_IRQ0); - drive->hwif->atapi_output_bytes(drive, - buf + pc->b_count + pc->sg->offset, count); - kunmap_atomic(buf, KM_IRQ0); - bcount -= count; - pc->b_count += count; + if (PageHighMem(pc->sg->page)) { + unsigned long flags; + + local_irq_save(flags); + buf = kmap_atomic(pc->sg->page, KM_IRQ0) + + pc->sg->offset; + drive->hwif->atapi_output_bytes(drive, + buf + pc->b_count, count); + kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); + local_irq_restore(flags); + } else { + buf = page_address(pc->sg->page) + pc->sg->offset; + drive->hwif->atapi_output_bytes(drive, + buf + pc->b_count, count); + } + bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; pc->b_count = 0;