Skip to content

Commit

Permalink
[SCSI] aacraid: driver shutdown method
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Haverkamp authored and James Bottomley committed Aug 5, 2005
1 parent c7f4760 commit bd1aac8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 3 deletions.
4 changes: 4 additions & 0 deletions drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down Expand Up @@ -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)

Expand Down
13 changes: 12 additions & 1 deletion drivers/scsi/aacraid/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -870,6 +871,13 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -919,6 +929,7 @@ static int __init aac_init(void)
printk(KERN_WARNING
"aacraid: unable to register \"aac\" device.\n");
}

return 0;
}

Expand Down
20 changes: 20 additions & 0 deletions drivers/scsi/aacraid/rkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
/*
Expand All @@ -438,6 +457,7 @@ int aac_rkt_init(struct aac_dev *dev)
kfree(dev->queues);

error_irq:
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);

error_iounmap:
Expand Down
20 changes: 20 additions & 0 deletions drivers/scsi/aacraid/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
/*
Expand All @@ -438,6 +457,7 @@ int aac_rx_init(struct aac_dev *dev)
kfree(dev->queues);

error_irq:
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);

error_iounmap:
Expand Down
22 changes: 20 additions & 2 deletions drivers/scsi/aacraid/sa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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;
Expand All @@ -381,6 +398,7 @@ int aac_sa_init(struct aac_dev *dev)
kfree(dev->queues);

error_irq:
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);

error_iounmap:
Expand Down

0 comments on commit bd1aac8

Please sign in to comment.