patch-2.4.19 linux-2.4.19/drivers/scsi/aha152x.c

Next file: linux-2.4.19/drivers/scsi/aha152x.h
Previous file: linux-2.4.19/drivers/scsi/aacraid/linit.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/scsi/aha152x.c linux-2.4.19/drivers/scsi/aha152x.c
@@ -13,9 +13,14 @@
  * General Public License for more details.
  *
  *
- * $Id: aha152x.c,v 2.4 2000/12/16 12:53:56 fischer Exp $
+ * $Id: aha152x.c,v 2.5 2002/04/14 11:24:53 fischer Exp $
  *
  * $Log: aha152x.c,v $
+ * Revision 2.5  2002/04/14 11:24:53  fischer
+ * - isapnp support
+ * - abort fixed
+ * - 2.5 support
+ *
  * Revision 2.4  2000/12/16 12:53:56  fischer
  * - allow REQUEST SENSE to be queued
  * - handle shared PCI interrupts
@@ -222,7 +227,9 @@
 #endif
 
 #include <linux/sched.h>
+#include <asm/irq.h>
 #include <asm/io.h>
+#include <linux/version.h>
 #include <linux/blk.h>
 #include "scsi.h"
 #include "sd.h"
@@ -306,15 +313,17 @@
 
 #define DELAY_DEFAULT 1000
 
-/* possible irq range */
 #if defined(PCMCIA)
 #define IRQ_MIN 0
 #define IRQ_MAX 16
 #else
 #define IRQ_MIN 9
+#if defined(__PPC)
+#define IRQ_MAX (NR_IRQS-1)
+#else
 #define IRQ_MAX 12
 #endif
-#define IRQS    IRQ_MAX-IRQ_MIN+1
+#endif
 
 enum {
 	not_issued	= 0x0001,	/* command not yet issued */
@@ -417,7 +426,7 @@
 	char *conf;
 } setup[2];
 
-static struct Scsi_Host *aha152x_host[IRQS];
+static struct Scsi_Host *aha152x_host[2];
 
 /*
  * internal states of the host
@@ -593,6 +602,7 @@
 #define SCDONE(SCpnt)		SCDATA(SCpnt)->done
 #define SCSEM(SCpnt)		SCDATA(SCpnt)->sem
 
+#define SG_ADDRESS(buffer)	((char *) (page_address((buffer)->page)+(buffer)->offset))
 
 /* state handling */
 static void seldi_run(struct Scsi_Host *shpnt);
@@ -668,7 +678,6 @@
 
 /* possible i/o addresses for the AIC-6260; default first */
 static unsigned short ports[] = { 0x340, 0x140 };
-#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))
 
 #if !defined(SKIP_BIOSTEST)
 /* possible locations for the Adaptec BIOS; defaults first */
@@ -684,7 +693,6 @@
 	0xeb800,		/* VTech Platinum SMP */
 	0xf0000,
 };
-#define ADDRESS_COUNT (sizeof(addresses) / sizeof(unsigned int))
 
 /* signatures for various AIC-6[23]60 based controllers.
    The point in detecting signatures is to avoid useless and maybe
@@ -726,8 +734,6 @@
 	{ "DTC3520A Host Adapter BIOS", 0x318a, 26 },
 		/* DTC 3520A ISA SCSI */
 };
-
-#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
 #endif
 
 
@@ -806,7 +812,7 @@
 #if defined(PCMCIA) || !defined(MODULE)
 void aha152x_setup(char *str, int *ints)
 {
-	if(setup_count>2) {
+	if(setup_count>=ARRAY_SIZE(setup)) {
 		printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");
 		return;
 	}
@@ -849,7 +855,7 @@
 #endif
 	int count=setup_count;
 
-	get_options(str, sizeof(ints)/sizeof(int), ints);
+	get_options(str, ARRAY_SIZE(ints), ints);
 	aha152x_setup(str,ints);
 
 	return count<setup_count;
@@ -903,10 +909,10 @@
 
 #if !defined(PCMCIA)
 	int i;
-	for (i = 0; i < PORT_COUNT && (setup->io_port != ports[i]); i++)
+	for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++)
 		;
 
-	if (i == PORT_COUNT)
+	if (i == ARRAY_SIZE(ports))
 		return 0;
 #endif
 
@@ -939,12 +945,25 @@
 	return 1;
 }
 
+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 0;
+}
+
 static void swintr(int irqno, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
+	struct Scsi_Host *shpnt = lookup_irq(irqno);
 
-	if (!shpnt)
-        	printk(KERN_ERR "aha152x%d: catched software interrupt for unknown controller.\n", HOSTNO);
+	if (!shpnt) {
+        	printk(KERN_ERR "aha152x%d: catched software interrupt %d for unknown controller.\n", HOSTNO, irqno);
+		return;
+	}
 
 	HOSTDATA(shpnt)->swint++;
 
@@ -966,7 +985,7 @@
 #endif
 	tpnt->proc_name = "aha152x"; 
 
-	for (i = 0; i < IRQS; i++)
+	for (i = 0; i < ARRAY_SIZE(aha152x_host); i++)
 		aha152x_host[i] = (struct Scsi_Host *) NULL;
 
 	if (setup_count) {
@@ -981,7 +1000,7 @@
 	}
 
 #if defined(SETUP0)
-	if (setup_count < 2) {
+	if (setup_count < ARRAY_SIZE(setup)) {
 		struct aha152x_setup override = SETUP0;
 
 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
@@ -1002,7 +1021,7 @@
 #endif
 
 #if defined(SETUP1)
-	if (setup_count < 2) {
+	if (setup_count < ARRAY_SIZE(setup)) {
 		struct aha152x_setup override = SETUP1;
 
 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
@@ -1023,7 +1042,7 @@
 #endif
 
 #if defined(MODULE)
-	if (setup_count<2 && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
+	if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
 		if(aha152x[0]!=0) {
 			setup[setup_count].conf        = "";
 			setup[setup_count].io_port     = aha152x[0];
@@ -1066,7 +1085,7 @@
 			       setup[setup_count].ext_trans);
 	}
 
-	if (setup_count < 2 && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
+	if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
 		if(aha152x1[0]!=0) {
 			setup[setup_count].conf        = "";
 			setup[setup_count].io_port     = aha152x1[0];
@@ -1110,7 +1129,7 @@
 #endif
 
 #ifdef __ISAPNP__
-	while ( setup_count<2 && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
+	while ( setup_count<ARRAY_SIZE(setup) && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
 		if (dev->prepare(dev) < 0)
 			continue;
 		if (dev->active)
@@ -1145,11 +1164,11 @@
 
 
 #if defined(AUTOCONF)
-	if (setup_count < 2) {
+	if (setup_count<ARRAY_SIZE(setup)) {
 #if !defined(SKIP_BIOSTEST)
 		ok = 0;
-		for (i = 0; i < ADDRESS_COUNT && !ok; i++)
-			for (j = 0; (j < SIGNATURE_COUNT) && !ok; j++)
+		for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++)
+			for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++)
 				ok = isa_check_signature(addresses[i] + signatures[j].sig_offset,
 								signatures[j].signature, signatures[j].sig_length);
 
@@ -1162,7 +1181,7 @@
 #endif				/* !SKIP_BIOSTEST */
 
 		ok = 0;
-		for (i = 0; i < PORT_COUNT && setup_count < 2; i++) {
+		for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) {
 			if ((setup_count == 1) && (setup[0].io_port == ports[i]))
 				continue;
 
@@ -1217,7 +1236,7 @@
 	for (i=0; i<setup_count; i++) {
 		struct Scsi_Host *shpnt;
 
-		aha152x_host[setup[i].irq - IRQ_MIN] = shpnt =
+		aha152x_host[registered_count] = shpnt =
 		    scsi_register(tpnt, sizeof(struct aha152x_hostdata));
 
 		if(!shpnt) {
@@ -1341,7 +1360,7 @@
 			scsi_unregister(shpnt);
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
 			shpnt = 0;
 			continue;
 		}
@@ -1349,9 +1368,13 @@
 
 		printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO);
 		SETPORT(DMACNTRL0, SWINT|INTEN);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		spin_unlock_irq(&io_request_lock);
+#endif
 		mdelay(1000);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		spin_lock_irq(&io_request_lock);
+#endif
 		free_irq(shpnt->irq, shpnt);
 
 		if (!HOSTDATA(shpnt)->swint) {
@@ -1367,7 +1390,7 @@
 
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
 			scsi_unregister(shpnt);
 			shpnt=NULL;
 			continue;
@@ -1382,10 +1405,11 @@
 		if (request_irq(shpnt->irq, intr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt) < 0) {
 			printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO);
 
-			scsi_unregister(shpnt);
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
+			scsi_unregister(shpnt);
+			shpnt=NULL;
 			continue;
 		}
 	}
@@ -1494,7 +1518,7 @@
 	   SCp.phase            : current state of the command */
 	if (SCpnt->use_sg) {
 		SCpnt->SCp.buffer           = (struct scatterlist *) SCpnt->request_buffer;
-		SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;
+		SCpnt->SCp.ptr              = SG_ADDRESS(SCpnt->SCp.buffer);
 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
 		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
 	} else {
@@ -1584,7 +1608,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(DEBUG_LEAD "abort(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1622,9 +1645,19 @@
 
 static void timer_expired(unsigned long p)
 {
-	struct semaphore *sem = (void *)p;
+	Scsi_Cmnd	 *SCp   = (Scsi_Cmnd *)p;
+	struct semaphore *sem   = SCSEM(SCp);
+	struct Scsi_Host *shpnt = SCp->host;
+
+	/* remove command from issue queue */
+	if(remove_SC(&ISSUE_SC, SCp)) {
+		printk(KERN_INFO "aha152x: ABORT timed out - removed from issue queue\n");
+		kfree(SCp->host_scribble);
+		SCp->host_scribble=0;
+	} else {
+		printk(KERN_INFO "aha152x: ABORT timed out - not on issue queue\n");
+	}
 
-	printk(KERN_INFO "aha152x: timer expired\n");
 	up(sem);
 }
 
@@ -1645,7 +1678,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(INFO_LEAD "aha152x_device_reset(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1663,13 +1695,13 @@
 	cmnd.request_bufflen = 0;
 
 	init_timer(&timer);
-	timer.data     = (unsigned long) &sem;
+	timer.data     = (unsigned long) &cmnd;
 	timer.expires  = jiffies + 100*HZ;   /* 10s */
 	timer.function = (void (*)(unsigned long)) timer_expired;
-	add_timer(&timer);
 
 	aha152x_internal_queue(&cmnd, &sem, resetting, 0, internal_done);
 
+	add_timer(&timer);
 	down(&sem);
 
 	del_timer(&timer);
@@ -1719,7 +1751,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1878,7 +1909,7 @@
 static void run(void)
 {
 	int i;
-	for (i = 0; i < IRQS; i++) {
+	for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) {
 		struct Scsi_Host *shpnt = aha152x_host[i];
 		if (shpnt && HOSTDATA(shpnt)->service) {
 			HOSTDATA(shpnt)->service=0;
@@ -1894,10 +1925,10 @@
 
 static void intr(int irqno, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
+	struct Scsi_Host *shpnt = lookup_irq(irqno);
 
 	if (!shpnt) {
-		printk(KERN_ERR "aha152x: catched interrupt for unknown controller.\n");
+		printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
 		return;
 	}
 
@@ -2681,7 +2712,7 @@
                                		/* advance to next buffer */
                                		CURRENT_SC->SCp.buffers_residual--;
                                		CURRENT_SC->SCp.buffer++;
-                               		CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address;
+                               		CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
                                		CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 				} 
                 	}
@@ -2791,7 +2822,7 @@
 			/* advance to next buffer */
 			CURRENT_SC->SCp.buffers_residual--;
 			CURRENT_SC->SCp.buffer++;
-			CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address;
+			CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 		}
 
@@ -2821,13 +2852,13 @@
 		CURRENT_SC->resid += data_count;
 
 		if(CURRENT_SC->use_sg) {
-			data_count -= CURRENT_SC->SCp.ptr - CURRENT_SC->SCp.buffer->address;
+			data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer);
 			while(data_count>0) {
 				CURRENT_SC->SCp.buffer--;
 				CURRENT_SC->SCp.buffers_residual++;
 				data_count -= CURRENT_SC->SCp.buffer->length;
 			}
-			CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address - data_count;
+			CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count;
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count;
 		} else {
 			CURRENT_SC->SCp.ptr           -= data_count;
@@ -2955,10 +2986,9 @@
 	int pending;
 
 	DO_LOCK(flags);
-	if(HOSTDATA(shpnt)->in_intr!=0)
-	{
+	if(HOSTDATA(shpnt)->in_intr!=0) {
 		DO_UNLOCK(flags);
-		/* _error never returns.. */
+		/* aha152x_error never returns.. */
 		aha152x_error(shpnt, "bottom-half already running!?");
 	}
 	HOSTDATA(shpnt)->in_intr++;
@@ -3765,7 +3795,7 @@
 	unsigned long flags;
 	int thislength;
 
-	for (i = 0, shpnt = (struct Scsi_Host *) NULL; i < IRQS; i++)
+	for (i = 0, shpnt = (struct Scsi_Host *) NULL; i<ARRAY_SIZE(aha152x_host); i++)
 		if (aha152x_host[i] && aha152x_host[i]->host_no == hostno)
 			shpnt = aha152x_host[i];
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)