diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2006-09-14 18:04:58 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-09-23 12:51:57 -0400 |
commit | 5fcda4224529c4e550c917668d5e96c1d3e7039b (patch) | |
tree | 94e446cf1366c76daeef2c0d92000f6e812a0ef4 /drivers | |
parent | 10d19ae5e1715c27db7009df6d59179774e7b8a1 (diff) |
[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 @@ | |||
253 | #include <linux/isapnp.h> | 253 | #include <linux/isapnp.h> |
254 | #include <linux/spinlock.h> | 254 | #include <linux/spinlock.h> |
255 | #include <linux/workqueue.h> | 255 | #include <linux/workqueue.h> |
256 | #include <linux/list.h> | ||
256 | #include <asm/semaphore.h> | 257 | #include <asm/semaphore.h> |
257 | #include <scsi/scsicam.h> | 258 | #include <scsi/scsicam.h> |
258 | 259 | ||
@@ -262,6 +263,8 @@ | |||
262 | #include <scsi/scsi_transport_spi.h> | 263 | #include <scsi/scsi_transport_spi.h> |
263 | #include "aha152x.h" | 264 | #include "aha152x.h" |
264 | 265 | ||
266 | static LIST_HEAD(aha152x_host_list); | ||
267 | |||
265 | 268 | ||
266 | /* DEFINES */ | 269 | /* DEFINES */ |
267 | 270 | ||
@@ -423,8 +426,6 @@ MODULE_DEVICE_TABLE(isapnp, id_table); | |||
423 | 426 | ||
424 | #endif /* !PCMCIA */ | 427 | #endif /* !PCMCIA */ |
425 | 428 | ||
426 | static int registered_count=0; | ||
427 | static struct Scsi_Host *aha152x_host[2]; | ||
428 | static struct scsi_host_template aha152x_driver_template; | 429 | static struct scsi_host_template aha152x_driver_template; |
429 | 430 | ||
430 | /* | 431 | /* |
@@ -541,6 +542,7 @@ struct aha152x_hostdata { | |||
541 | #ifdef __ISAPNP__ | 542 | #ifdef __ISAPNP__ |
542 | struct pnp_dev *pnpdev; | 543 | struct pnp_dev *pnpdev; |
543 | #endif | 544 | #endif |
545 | struct list_head host_list; | ||
544 | }; | 546 | }; |
545 | 547 | ||
546 | 548 | ||
@@ -755,20 +757,9 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp) | |||
755 | return ptr; | 757 | return ptr; |
756 | } | 758 | } |
757 | 759 | ||
758 | static inline struct Scsi_Host *lookup_irq(int irqno) | ||
759 | { | ||
760 | int i; | ||
761 | |||
762 | for(i=0; i<ARRAY_SIZE(aha152x_host); i++) | ||
763 | if(aha152x_host[i] && aha152x_host[i]->irq==irqno) | ||
764 | return aha152x_host[i]; | ||
765 | |||
766 | return NULL; | ||
767 | } | ||
768 | |||
769 | static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) | 760 | static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) |
770 | { | 761 | { |
771 | struct Scsi_Host *shpnt = lookup_irq(irqno); | 762 | struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; |
772 | 763 | ||
773 | if (!shpnt) { | 764 | if (!shpnt) { |
774 | printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno); | 765 | 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) | |||
791 | return NULL; | 782 | return NULL; |
792 | } | 783 | } |
793 | 784 | ||
794 | /* need to have host registered before triggering any interrupt */ | ||
795 | aha152x_host[registered_count] = shpnt; | ||
796 | |||
797 | memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt)); | 785 | memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt)); |
786 | INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list); | ||
787 | |||
788 | /* need to have host registered before triggering any interrupt */ | ||
789 | list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list); | ||
798 | 790 | ||
799 | shpnt->io_port = setup->io_port; | 791 | shpnt->io_port = setup->io_port; |
800 | shpnt->n_io_port = IO_RANGE; | 792 | shpnt->n_io_port = IO_RANGE; |
@@ -907,12 +899,10 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) | |||
907 | 899 | ||
908 | scsi_scan_host(shpnt); | 900 | scsi_scan_host(shpnt); |
909 | 901 | ||
910 | registered_count++; | ||
911 | |||
912 | return shpnt; | 902 | return shpnt; |
913 | 903 | ||
914 | out_host_put: | 904 | out_host_put: |
915 | aha152x_host[registered_count]=NULL; | 905 | list_del(&HOSTDATA(shpnt)->host_list); |
916 | scsi_host_put(shpnt); | 906 | scsi_host_put(shpnt); |
917 | 907 | ||
918 | return NULL; | 908 | return NULL; |
@@ -937,6 +927,7 @@ void aha152x_release(struct Scsi_Host *shpnt) | |||
937 | #endif | 927 | #endif |
938 | 928 | ||
939 | scsi_remove_host(shpnt); | 929 | scsi_remove_host(shpnt); |
930 | list_del(&HOSTDATA(shpnt)->host_list); | ||
940 | scsi_host_put(shpnt); | 931 | scsi_host_put(shpnt); |
941 | } | 932 | } |
942 | 933 | ||
@@ -1459,9 +1450,12 @@ static struct work_struct aha152x_tq; | |||
1459 | */ | 1450 | */ |
1460 | static void run(void) | 1451 | static void run(void) |
1461 | { | 1452 | { |
1462 | int i; | 1453 | struct aha152x_hostdata *hd; |
1463 | for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) { | 1454 | |
1464 | is_complete(aha152x_host[i]); | 1455 | list_for_each_entry(hd, &aha152x_host_list, host_list) { |
1456 | struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata); | ||
1457 | |||
1458 | is_complete(shost); | ||
1465 | } | 1459 | } |
1466 | } | 1460 | } |
1467 | 1461 | ||
@@ -1471,7 +1465,7 @@ static void run(void) | |||
1471 | */ | 1465 | */ |
1472 | static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) | 1466 | static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) |
1473 | { | 1467 | { |
1474 | struct Scsi_Host *shpnt = lookup_irq(irqno); | 1468 | struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; |
1475 | unsigned long flags; | 1469 | unsigned long flags; |
1476 | unsigned char rev, dmacntrl0; | 1470 | unsigned char rev, dmacntrl0; |
1477 | 1471 | ||
@@ -3953,16 +3947,17 @@ static int __init aha152x_init(void) | |||
3953 | #endif | 3947 | #endif |
3954 | } | 3948 | } |
3955 | 3949 | ||
3956 | return registered_count>0; | 3950 | return 1; |
3957 | } | 3951 | } |
3958 | 3952 | ||
3959 | static void __exit aha152x_exit(void) | 3953 | static void __exit aha152x_exit(void) |
3960 | { | 3954 | { |
3961 | int i; | 3955 | struct aha152x_hostdata *hd; |
3956 | |||
3957 | list_for_each_entry(hd, &aha152x_host_list, host_list) { | ||
3958 | struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata); | ||
3962 | 3959 | ||
3963 | for(i=0; i<ARRAY_SIZE(setup); i++) { | 3960 | aha152x_release(shost); |
3964 | aha152x_release(aha152x_host[i]); | ||
3965 | aha152x_host[i]=NULL; | ||
3966 | } | 3961 | } |
3967 | } | 3962 | } |
3968 | 3963 | ||