]> err.no Git - linux-2.6/blobdiff - drivers/scsi/ide-scsi.c
[PATCH] Clean up struct flock64 definitions
[linux-2.6] / drivers / scsi / ide-scsi.c
index d80c4c9d5a631c4997e634f9b8e5e71fa8c012c3..3d62c9bcbff76931584364de2743060f9d398d68 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/slab.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/bitops.h>
@@ -179,8 +180,18 @@ 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 = page_address(pc->sg->page) + pc->sg->offset;
-               drive->hwif->atapi_input_bytes(drive, buf + 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++;
@@ -201,8 +212,18 @@ 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 = page_address(pc->sg->page) + pc->sg->offset;
-               drive->hwif->atapi_output_bytes(drive, buf + 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++;
@@ -1006,11 +1027,13 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
                return FAILED;
        }
 
-       spin_lock_irq(&ide_lock);
+       spin_lock_irq(cmd->device->host->host_lock);
+       spin_lock(&ide_lock);
 
        if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) {
                printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");
                spin_unlock(&ide_lock);
+               spin_unlock_irq(cmd->device->host->host_lock);
                return FAILED;
        }
 
@@ -1032,16 +1055,15 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
        HWGROUP(drive)->rq = NULL;
        HWGROUP(drive)->handler = NULL;
        HWGROUP(drive)->busy = 1;               /* will set this to zero when ide reset finished */
-       spin_unlock_irq(&ide_lock);
+       spin_unlock(&ide_lock);
 
        ide_do_reset(drive);
 
        /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */
 
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
                spin_unlock_irq(cmd->device->host->host_lock);
-               schedule_timeout(HZ/20);
+               msleep(50);
                spin_lock_irq(cmd->device->host->host_lock);
        } while ( HWGROUP(drive)->handler );
 
@@ -1052,6 +1074,7 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
                ret = FAILED;
        }
 
+       spin_unlock_irq(cmd->device->host->host_lock);
        return ret;
 }