diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2006-09-14 17:04:58 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-09-23 11:51:57 -0500 |
commit | 5fcda4224529c4e550c917668d5e96c1d3e7039b (patch) | |
tree | 94e446cf1366c76daeef2c0d92000f6e812a0ef4 /drivers | |
parent | 10d19ae5e1715c27db7009df6d59179774e7b8a1 (diff) | |
download | linux-stable-5fcda4224529c4e550c917668d5e96c1d3e7039b.tar.gz linux-stable-5fcda4224529c4e550c917668d5e96c1d3e7039b.tar.bz2 linux-stable-5fcda4224529c4e550c917668d5e96c1d3e7039b.zip |
[SCSI] aha152x: remove static host array
Fix this driver not to use a static two element host array instead use
a list. This should fix panic on multiple eject reinsert of the
pcmcia version of this device.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/aha152x.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index f974869ea323..fb6a476eb873 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -253,6 +253,7 @@ #include <linux/isapnp.h> #include <linux/spinlock.h> #include <linux/workqueue.h> +#include <linux/list.h> #include <asm/semaphore.h> #include <scsi/scsicam.h> @@ -262,6 +263,8 @@ #include <scsi/scsi_transport_spi.h> #include "aha152x.h" +static LIST_HEAD(aha152x_host_list); + /* DEFINES */ @@ -423,8 +426,6 @@ MODULE_DEVICE_TABLE(isapnp, id_table); #endif /* !PCMCIA */ -static int registered_count=0; -static struct Scsi_Host *aha152x_host[2]; static struct scsi_host_template aha152x_driver_template; /* @@ -541,6 +542,7 @@ struct aha152x_hostdata { #ifdef __ISAPNP__ struct pnp_dev *pnpdev; #endif + struct list_head host_list; }; @@ -755,20 +757,9 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp) return ptr; } -static inline struct Scsi_Host *lookup_irq(int irqno) -{ - int i; - - for(i=0; i<ARRAY_SIZE(aha152x_host); i++) - if(aha152x_host[i] && aha152x_host[i]->irq==irqno) - return aha152x_host[i]; - - return NULL; -} - static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *shpnt = lookup_irq(irqno); + struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; if (!shpnt) { printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno); @@ -791,10 +782,11 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) return NULL; } - /* need to have host registered before triggering any interrupt */ - aha152x_host[registered_count] = shpnt; - memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt)); + INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list); + + /* need to have host registered before triggering any interrupt */ + list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list); shpnt->io_port = setup->io_port; shpnt->n_io_port = IO_RANGE; @@ -907,12 +899,10 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) scsi_scan_host(shpnt); - registered_count++; - return shpnt; out_host_put: - aha152x_host[registered_count]=NULL; + list_del(&HOSTDATA(shpnt)->host_list); scsi_host_put(shpnt); return NULL; @@ -937,6 +927,7 @@ void aha152x_release(struct Scsi_Host *shpnt) #endif scsi_remove_host(shpnt); + list_del(&HOSTDATA(shpnt)->host_list); scsi_host_put(shpnt); } @@ -1459,9 +1450,12 @@ static struct work_struct aha152x_tq; */ static void run(void) { - int i; - for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) { - is_complete(aha152x_host[i]); + struct aha152x_hostdata *hd; + + list_for_each_entry(hd, &aha152x_host_list, host_list) { + struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata); + + is_complete(shost); } } @@ -1471,7 +1465,7 @@ static void run(void) */ static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *shpnt = lookup_irq(irqno); + struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; unsigned long flags; unsigned char rev, dmacntrl0; @@ -3953,16 +3947,17 @@ static int __init aha152x_init(void) #endif } - return registered_count>0; + return 1; } static void __exit aha152x_exit(void) { - int i; + struct aha152x_hostdata *hd; + + list_for_each_entry(hd, &aha152x_host_list, host_list) { + struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata); - for(i=0; i<ARRAY_SIZE(setup); i++) { - aha152x_release(aha152x_host[i]); - aha152x_host[i]=NULL; + aha152x_release(shost); } } |