summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-10-09 09:48:44 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-09 09:48:44 -0400
commit91b8b3132e1870bfe3c4d3a999f13f20fc4e9726 (patch)
treeadc98107179591d18490e407da4f3e86145ccc6a
parent083958d313f886dc7d00522f2972f90f55c40041 (diff)
[libata irq-pio] use PageHighMem() to optimize the kmap_atomic() usage
as done in ide-scsi.c Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
-rw-r--r--drivers/scsi/libata-core.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 35ee35e176c0..5e750c33dd96 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2748,7 +2748,6 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
struct page *page;
unsigned int offset;
unsigned char *buf;
- unsigned long flags;
if (qc->cursect == (qc->nsect - 1))
ap->hsm_task_state = HSM_ST_LAST;
@@ -2762,14 +2761,21 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
- local_irq_save(flags);
- buf = kmap_atomic(page, KM_IRQ0);
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
- /* do the actual data transfer */
- ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
+ /* do the actual data transfer */
+ ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
- kunmap_atomic(buf, KM_IRQ0);
- local_irq_restore(flags);
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
+ }
qc->cursect++;
qc->cursg_ofs++;
@@ -2908,7 +2914,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
struct page *page;
unsigned char *buf;
unsigned int offset, count;
- unsigned long flags;
if (qc->curbytes + bytes >= qc->nbytes)
ap->hsm_task_state = HSM_ST_LAST;
@@ -2954,14 +2959,21 @@ next_sg:
DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
- local_irq_save(flags);
- buf = kmap_atomic(page, KM_IRQ0);
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
- /* do the actual data transfer */
- ata_data_xfer(ap, buf + offset, count, do_write);
+ /* do the actual data transfer */
+ ata_data_xfer(ap, buf + offset, count, do_write);
- kunmap_atomic(buf, KM_IRQ0);
- local_irq_restore(flags);
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ ata_data_xfer(ap, buf + offset, count, do_write);
+ }
bytes -= count;
qc->curbytes += count;