[libata] wrap kmap_atomic(KM_IRQ0) with local_irq_save/restore()
authorJeff Garzik <jeff@garzik.org>
Sat, 1 Mar 2008 00:10:51 +0000 (19:10 -0500)
committerJeff Garzik <jeff@garzik.org>
Sat, 1 Mar 2008 00:10:51 +0000 (19:10 -0500)
Interrupts must be disabled if using kmap_atomic(KM_IRQ0), but that was
not the case in a few code paths coming directly from ATA driver
interrupt handlers (which use spin_lock rather than spin_lock_irqsave).

Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/libata-scsi.c

index 0562b0a49f3b2acc474c3145ee0f48911eefe349..7b1f1ee8131d2cb511989f4838bcad4eb832d4c7 100644 (file)
@@ -1694,12 +1694,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
        u8 *rbuf;
        unsigned int buflen, rc;
        struct scsi_cmnd *cmd = args->cmd;
+       unsigned long flags;
+
+       local_irq_save(flags);
 
        buflen = ata_scsi_rbuf_get(cmd, &rbuf);
        memset(rbuf, 0, buflen);
        rc = actor(args, rbuf, buflen);
        ata_scsi_rbuf_put(cmd, rbuf);
 
+       local_irq_restore(flags);
+
        if (rc == 0)
                cmd->result = SAM_STAT_GOOD;
        args->done(cmd);
@@ -2473,6 +2478,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
                        u8 *buf = NULL;
                        unsigned int buflen;
+                       unsigned long flags;
+
+                       local_irq_save(flags);
 
                        buflen = ata_scsi_rbuf_get(cmd, &buf);
 
@@ -2490,6 +2498,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                        }
 
                        ata_scsi_rbuf_put(cmd, buf);
+
+                       local_irq_restore(flags);
                }
 
                cmd->result = SAM_STAT_GOOD;