aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2006-09-14 18:04:58 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-23 12:51:57 -0400
commit5fcda4224529c4e550c917668d5e96c1d3e7039b (patch)
tree94e446cf1366c76daeef2c0d92000f6e812a0ef4
parent10d19ae5e1715c27db7009df6d59179774e7b8a1 (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>
-rw-r--r--drivers/scsi/aha152x.c53
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
266static 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
426static int registered_count=0;
427static struct Scsi_Host *aha152x_host[2];
428static struct scsi_host_template aha152x_driver_template; 429static 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
758static 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
769static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) 760static 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
914out_host_put: 904out_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 */
1460static void run(void) 1451static 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 */
1472static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) 1466static 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
3959static void __exit aha152x_exit(void) 3953static 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