Commit 83d8dc13 authored by Jürgen E. Fischer's avatar Jürgen E. Fischer Committed by Linus Torvalds

[PATCH] aha152x driver

Patch to the aha152x driver, which makes it work under 2.5.
parent 1a86c1cb
......@@ -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 @@ static struct aha152x_setup {
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 @@ struct aha152x_scdata {
#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 @@ static void disp_enintr(struct Scsi_Host *shpnt);
/* 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 @@ static unsigned int addresses[] =
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 @@ static struct signature {
{ "DTC3520A Host Adapter BIOS", 0x318a, 26 },
/* DTC 3520A ISA SCSI */
};
#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
#endif
......@@ -806,7 +812,7 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp)
#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 @@ static int __init do_setup(char *str)
#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 @@ static int checksetup(struct aha152x_setup *setup)
#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 @@ static int checksetup(struct aha152x_setup *setup)
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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
}
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
#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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
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 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
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,7 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO);
SETPORT(DMACNTRL0, SWINT|INTEN);
spin_unlock_irq(shpnt->host_lock);
mdelay(1000);
spin_lock_irq(shpnt->host_lock);
free_irq(shpnt->irq, shpnt);
if (!HOSTDATA(shpnt)->swint) {
......@@ -1367,7 +1384,7 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
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 +1399,11 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
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 +1512,7 @@ int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, S
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 +1602,6 @@ int aha152x_abort(Scsi_Cmnd *SCpnt)
if(HOSTDATA(shpnt)->debug & debug_eh) {
printk(DEBUG_LEAD "abort(%p)", CMDINFO(SCpnt), SCpnt);
show_queues(shpnt);
mdelay(1000);
}
#endif
......@@ -1622,9 +1639,19 @@ int aha152x_abort(Scsi_Cmnd *SCpnt)
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 +1672,6 @@ int aha152x_device_reset(Scsi_Cmnd * SCpnt)
if(HOSTDATA(shpnt)->debug & debug_eh) {
printk(INFO_LEAD "aha152x_device_reset(%p)", CMDINFO(SCpnt), SCpnt);
show_queues(shpnt);
mdelay(1000);
}
#endif
......@@ -1663,13 +1689,13 @@ int aha152x_device_reset(Scsi_Cmnd * SCpnt)
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 +1745,6 @@ int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
if(HOSTDATA(shpnt)->debug & debug_eh) {
printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt);
show_queues(shpnt);
mdelay(1000);
}
#endif
......@@ -1878,7 +1903,7 @@ static struct tq_struct aha152x_tq;
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 +1919,10 @@ static void run(void)
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 +2706,7 @@ static void datai_run(struct Scsi_Host *shpnt)
/* 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 +2816,7 @@ static void datao_run(struct Scsi_Host *shpnt)
/* 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 +2846,13 @@ static void datao_end(struct Scsi_Host *shpnt)
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 +2980,9 @@ static void is_complete(struct Scsi_Host *shpnt)
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 +3789,7 @@ int aha152x_proc_info(char *buffer, char **start,
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];
......
......@@ -2,7 +2,7 @@
#define _AHA152X_H
/*
* $Id: aha152x.h,v 2.4 2000/12/16 12:48:48 fischer Exp $
* $Id: aha152x.h,v 2.5 2002/04/14 11:24:12 fischer Exp $
*/
#if defined(__KERNEL__)
......@@ -27,7 +27,7 @@ int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int
(unless we support more than 1 cmd_per_lun this should do) */
#define AHA152X_MAXQUEUE 7
#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.4 $"
#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.5 $"
/* Initial value of Scsi_Host entry */
#define AHA152X { proc_name: "aha152x", \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment