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
- Lines: 430
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/scsi/aha152x.c
- Orig date:
Fri Nov 9 14:05:06 2001
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)