]> git.baikalelectronics.ru Git - kernel.git/commitdiff
[SCSI] aacraid: driver shutdown method
authorMark Haverkamp <markh@osdl.org>
Wed, 3 Aug 2005 22:39:01 +0000 (15:39 -0700)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 5 Aug 2005 21:51:11 +0000 (16:51 -0500)
Add in pci shutdown method so that the adapter shuts down correctly and
flushes its cache. Shutdown should also disable the adapter's interrupt
when shutdown (in particularly if the driver is rmmod'd) to prevent
spurious hardware activities.

Signed-off-by: Mark Haverkamp <markh@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rkt.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c

index ddbbb85b3a7cc29d075e278e73a8e53c6e5dcae5..6f4906ee9a5e94c4090550e78a417edd244d861b 100644 (file)
@@ -460,6 +460,7 @@ struct adapter_ops
 {
        void (*adapter_interrupt)(struct aac_dev *dev);
        void (*adapter_notify)(struct aac_dev *dev, u32 event);
+       void (*adapter_disable_int)(struct aac_dev *dev);
        int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
        int  (*adapter_check_health)(struct aac_dev *dev);
 };
@@ -994,6 +995,9 @@ struct aac_dev
 #define aac_adapter_notify(dev, event) \
        (dev)->a_ops.adapter_notify(dev, event)
 
+#define aac_adapter_disable_int(dev) \
+       (dev)->a_ops.adapter_disable_int(dev)
+
 #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
        (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
 
index b6dda99f5083ada4838380fe2b162c29a9c0d8f7..41255f7893d03e648e08fd05577c3b4f354c2cb9 100644 (file)
@@ -849,11 +849,12 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 
        return 0;
 
-out_deinit:
+ out_deinit:
        kill_proc(aac->thread_pid, SIGKILL, 0);
        wait_for_completion(&aac->aif_completion);
 
        aac_send_shutdown(aac);
+       aac_adapter_disable_int(aac);
        fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
        kfree(aac->queues);
@@ -870,6 +871,13 @@ out_deinit:
        return error;
 }
 
+static void aac_shutdown(struct pci_dev *dev)
+{
+       struct Scsi_Host *shost = pci_get_drvdata(dev);
+       struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
+       aac_send_shutdown(aac);
+}
+
 static void __devexit aac_remove_one(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
@@ -881,6 +889,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
        wait_for_completion(&aac->aif_completion);
 
        aac_send_shutdown(aac);
+       aac_adapter_disable_int(aac);
        fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
                        aac->comm_phys);
@@ -901,6 +910,7 @@ static struct pci_driver aac_pci_driver = {
        .id_table       = aac_pci_tbl,
        .probe          = aac_probe_one,
        .remove         = __devexit_p(aac_remove_one),
+       .shutdown       = aac_shutdown,
 };
 
 static int __init aac_init(void)
@@ -919,6 +929,7 @@ static int __init aac_init(void)
                printk(KERN_WARNING
                       "aacraid: unable to register \"aac\" device.\n");
        }
+
        return 0;
 }
 
index 7d68b7825137506b07af8a83e52f4302f11e31ff..557287a0b80bdbfde17a349efb9aa7666cd7d7ca 100644 (file)
@@ -87,6 +87,16 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_NONE;
 }
 
+/**
+ *     aac_rkt_disable_interrupt       -       Disable interrupts
+ *     @dev: Adapter
+ */
+
+static void aac_rkt_disable_interrupt(struct aac_dev *dev)
+{
+       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
+}
+
 /**
  *     rkt_sync_cmd    -       send a command and wait
  *     @dev: Adapter
@@ -412,10 +422,19 @@ int aac_rkt_init(struct aac_dev *dev)
         *      Fill in the function dispatch table.
         */
        dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter;
+       dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt;
        dev->a_ops.adapter_notify = aac_rkt_notify_adapter;
        dev->a_ops.adapter_sync_cmd = rkt_sync_cmd;
        dev->a_ops.adapter_check_health = aac_rkt_check_health;
 
+       /*
+        *      First clear out all interrupts.  Then enable the one's that we
+        *      can handle.
+        */
+       rkt_writeb(dev, MUnit.OIMR, 0xff);
+       rkt_writel(dev, MUnit.ODR, 0xffffffff);
+       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+
        if (aac_init_adapter(dev) == NULL)
                goto error_irq;
        /*
@@ -438,6 +457,7 @@ error_kfree:
        kfree(dev->queues);
 
 error_irq:
+       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap:
index 1ff25f49fadace646d6a1c19073527a222087f61..a8459faf87caf88facabe65a6dee10982ac481f6 100644 (file)
@@ -87,6 +87,16 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_NONE;
 }
 
+/**
+ *     aac_rx_disable_interrupt        -       Disable interrupts
+ *     @dev: Adapter
+ */
+
+static void aac_rx_disable_interrupt(struct aac_dev *dev)
+{
+       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
+}
+
 /**
  *     rx_sync_cmd     -       send a command and wait
  *     @dev: Adapter
@@ -412,10 +422,19 @@ int aac_rx_init(struct aac_dev *dev)
         *      Fill in the function dispatch table.
         */
        dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
+       dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
        dev->a_ops.adapter_notify = aac_rx_notify_adapter;
        dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
        dev->a_ops.adapter_check_health = aac_rx_check_health;
 
+       /*
+        *      First clear out all interrupts.  Then enable the one's that we
+        *      can handle.
+        */
+       rx_writeb(dev, MUnit.OIMR, 0xff);
+       rx_writel(dev, MUnit.ODR, 0xffffffff);
+       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+
        if (aac_init_adapter(dev) == NULL)
                goto error_irq;
        /*
@@ -438,6 +457,7 @@ error_kfree:
        kfree(dev->queues);
 
 error_irq:
+       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap:
index 0680249ab861600702d536bf92309e65ac23002d..3900abc5850d35e9d731f1c19840c912f63c98fe 100644 (file)
@@ -81,6 +81,16 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_NONE;
 }
 
+/**
+ *     aac_sa_disable_interrupt        -       disable interrupt
+ *     @dev: Which adapter to enable.
+ */
+
+static void aac_sa_disable_interrupt (struct aac_dev *dev)
+{
+       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
+}
+
 /**
  *     aac_sa_notify_adapter           -       handle adapter notification
  *     @dev:   Adapter that notification is for
@@ -214,9 +224,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
  
 static void aac_sa_interrupt_adapter (struct aac_dev *dev)
 {
-       u32 ret;
        sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
-                       &ret, NULL, NULL, NULL, NULL);
+                       NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -352,10 +361,18 @@ int aac_sa_init(struct aac_dev *dev)
         */
 
        dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
+       dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
        dev->a_ops.adapter_notify = aac_sa_notify_adapter;
        dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
        dev->a_ops.adapter_check_health = aac_sa_check_health;
 
+       /*
+        *      First clear out all interrupts.  Then enable the one's that 
+        *      we can handle.
+        */
+       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
+       sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | 
+                               DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
 
        if(aac_init_adapter(dev) == NULL)
                goto error_irq;
@@ -381,6 +398,7 @@ error_kfree:
        kfree(dev->queues);
 
 error_irq:
+       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap: