Commit ed36188d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[PATCH] aha152x pcmcia updates

(1) use new pcmcia_register_driver() & co API
(2) use scsi_add_host & co.  This needed some restructuring in aha152x.c
(3) add a bunch of missing statics to aha152x.c
(4) move prototypes for functions used by aha152x_stub.c to aha152x.h
parent a80bc2d3
...@@ -404,25 +404,11 @@ MODULE_DEVICE_TABLE(isapnp, id_table); ...@@ -404,25 +404,11 @@ MODULE_DEVICE_TABLE(isapnp, id_table);
#endif /* ISAPNP */ #endif /* ISAPNP */
/* set by aha152x_setup according to the command line */ /* set by aha152x_setup according to the command line */
static int setup_count = 0; static int setup_count;
static int registered_count = 0; static int registered_count;
static struct aha152x_setup { static struct aha152x_setup setup[2];
int io_port;
int irq;
int scsiid;
int reconnect;
int parity;
int synchronous;
int delay;
int ext_trans;
int tc1550;
#if defined(AHA152X_DEBUG)
int debug;
#endif
char *conf;
} setup[2];
static struct Scsi_Host *aha152x_host[2]; static struct Scsi_Host *aha152x_host[2];
static Scsi_Host_Template aha152x_driver_template;
/* /*
* internal states of the host * internal states of the host
...@@ -806,7 +792,7 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp) ...@@ -806,7 +792,7 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp)
} }
#if defined(PCMCIA) || !defined(MODULE) #if defined(PCMCIA) || !defined(MODULE)
void aha152x_setup(char *str, int *ints) static void aha152x_setup(char *str, int *ints)
{ {
if(setup_count>=ARRAY_SIZE(setup)) { if(setup_count>=ARRAY_SIZE(setup)) {
printk(KERN_ERR "aha152x: you can only configure up to two controllers\n"); printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");
...@@ -832,10 +818,8 @@ void aha152x_setup(char *str, int *ints) ...@@ -832,10 +818,8 @@ void aha152x_setup(char *str, int *ints)
printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
"[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n"); "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
#endif #endif
return;
} else { } else {
setup_count++; setup_count++;
return;
} }
} }
#endif #endif
...@@ -970,7 +954,142 @@ static void swintr(int irqno, void *dev_id, struct pt_regs *regs) ...@@ -970,7 +954,142 @@ static void swintr(int irqno, void *dev_id, struct pt_regs *regs)
static struct pnp_dev *pnpdev[2]; static struct pnp_dev *pnpdev[2];
static int num_pnpdevs; static int num_pnpdevs;
#endif #endif
int aha152x_detect(Scsi_Host_Template * tpnt)
struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
{
struct Scsi_Host *shost, *shpnt;
struct aha152x_hostdata *aha;
/* XXX: shpnt is needed for some broken macros */
shost = shpnt = scsi_register(&aha152x_driver_template,
sizeof(struct aha152x_hostdata));
if (!shost) {
printk(KERN_ERR "aha152x: scsi_register failed\n");
return NULL;
}
aha = (struct aha152x_hostdata *)&shost->hostdata;
memset(aha, 0, sizeof(*aha));
shost->io_port = setup->io_port;
shost->n_io_port = IO_RANGE;
shost->irq = setup->irq;
if (!setup->tc1550) {
aha->io_port0 = setup->io_port;
aha->io_port1 = setup->io_port;
} else {
aha->io_port0 = setup->io_port+0x10;
aha->io_port1 = setup->io_port-0x10;
}
spin_lock_init(&aha->lock);
aha->reconnect = setup->reconnect;
aha->synchronous = setup->synchronous;
aha->parity = setup->parity;
aha->delay = setup->delay;
aha->ext_trans = setup->ext_trans;
#if defined(AHA152X_DEBUG)
aha->debug = setup->debug;
#endif
SETPORT(SCSIID, setup->scsiid << 4);
shost->this_id = setup->scsiid;
if (setup->reconnect)
shost->can_queue = AHA152X_MAXQUEUE;
/* RESET OUT */
printk("aha152x: resetting bus...\n");
SETPORT(SCSISEQ, SCSIRSTO);
mdelay(256);
SETPORT(SCSISEQ, 0);
mdelay(DELAY);
reset_ports(shost);
printk(KERN_INFO
"aha152x%d%s: "
"vital data: rev=%x, "
"io=0x%03lx (0x%03lx/0x%03lx), "
"irq=%d, "
"scsiid=%d, "
"reconnect=%s, "
"parity=%s, "
"synchronous=%s, "
"delay=%d, "
"extended translation=%s\n",
shost->host_no, setup->tc1550 ? " (tc1550 mode)" : "",
GETPORT(REV) & 0x7,
shost->io_port, aha->io_port0, aha->io_port1,
shost->irq,
shost->this_id,
aha->reconnect ? "enabled" : "disabled",
aha->parity ? "enabled" : "disabled",
aha->synchronous ? "enabled" : "disabled",
aha->delay,
aha->ext_trans ? "enabled" : "disabled");
if (!request_region(shost->io_port, IO_RANGE, "aha152x"))
goto out_unregister;
/* not expecting any interrupts */
SETPORT(SIMODE0, 0);
SETPORT(SIMODE1, 0);
if (request_irq(shost->irq, swintr, SA_INTERRUPT|SA_SHIRQ,
"aha152x", shost) < 0) {
printk(KERN_ERR "aha152x%d: driver needs an IRQ.\n", shost->host_no);
goto out_release_region;
}
aha->swint = 0;
printk(KERN_INFO "aha152x%d: trying software interrupt, ",
shost->host_no);
SETPORT(DMACNTRL0, SWINT|INTEN);
mdelay(1000);
free_irq(shost->irq, shost);
if (!aha->swint) {
if (TESTHI(DMASTAT, INTSTAT)) {
printk("lost.\n");
} else {
printk("failed.\n");
}
SETPORT(DMACNTRL0, INTEN);
printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong. "
"Please verify.\n", shost->host_no, shost->irq);
goto out_release_region;
}
printk("ok.\n");
/* clear interrupts */
SETPORT(SSTAT0, 0x7f);
SETPORT(SSTAT1, 0xef);
if (request_irq(shost->irq, intr, SA_INTERRUPT|SA_SHIRQ,
"aha152x", shost) < 0) {
printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n",
shost->host_no);
goto out_release_region;
}
aha152x_host[registered_count] = shost;
return shost; /* the pcmcia stub needs the return value; */
out_release_region:
release_region(shost->io_port, IO_RANGE);
out_unregister:
scsi_unregister(shost);
return NULL;
}
static int aha152x_detect(Scsi_Host_Template * tpnt)
{ {
int i, j, ok; int i, j, ok;
#if defined(AUTOCONF) #if defined(AUTOCONF)
...@@ -979,10 +1098,6 @@ int aha152x_detect(Scsi_Host_Template * tpnt) ...@@ -979,10 +1098,6 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
struct pnp_dev *dev = NULL; struct pnp_dev *dev = NULL;
#endif #endif
#endif #endif
tpnt->proc_name = "aha152x";
for (i = 0; i < ARRAY_SIZE(aha152x_host); i++)
aha152x_host[i] = (struct Scsi_Host *) NULL;
if (setup_count) { if (setup_count) {
printk(KERN_INFO "aha152x: processing commandline: "); printk(KERN_INFO "aha152x: processing commandline: ");
...@@ -1231,185 +1346,16 @@ int aha152x_detect(Scsi_Host_Template * tpnt) ...@@ -1231,185 +1346,16 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
printk("detected %d controller(s)\n", setup_count); printk("detected %d controller(s)\n", setup_count);
for (i=0; i<setup_count; i++) { for (i=0; i<setup_count; i++) {
struct Scsi_Host *shpnt; aha152x_probe_one(&setup[i]);
if (aha152x_host[registered_count])
aha152x_host[registered_count] = shpnt =
scsi_register(tpnt, sizeof(struct aha152x_hostdata));
if(!shpnt) {
printk(KERN_ERR "aha152x: scsi_register failed\n");
continue;
}
registered_count++; registered_count++;
shpnt->io_port = setup[i].io_port;
shpnt->n_io_port = IO_RANGE;
shpnt->irq = setup[i].irq;
if(!setup[i].tc1550) {
HOSTIOPORT0 = setup[i].io_port;
HOSTIOPORT1 = setup[i].io_port;
} else {
HOSTIOPORT0 = setup[i].io_port+0x10;
HOSTIOPORT1 = setup[i].io_port-0x10;
}
ISSUE_SC = 0;
CURRENT_SC = 0;
DONE_SC = 0;
DISCONNECTED_SC = 0;
QLOCK = SPIN_LOCK_UNLOCKED;
STATE = 0;
PREVSTATE = 0;
LASTSTATE = 0;
MSGILEN = 0;
MSGOLEN = 0;
RECONNECT = setup[i].reconnect;
SYNCHRONOUS = setup[i].synchronous;
PARITY = setup[i].parity;
DELAY = setup[i].delay;
EXT_TRANS = setup[i].ext_trans;
#if defined(AHA152X_DEBUG)
HOSTDATA(shpnt)->debug = setup[i].debug;
#endif
HOSTDATA(shpnt)->in_intr = 0;
HOSTDATA(shpnt)->commands = 0;
#if defined(AHA152X_STAT)
HOSTDATA(shpnt)->total_commands=0;
HOSTDATA(shpnt)->disconnections=0;
HOSTDATA(shpnt)->busfree_without_any_action=0;
HOSTDATA(shpnt)->busfree_without_old_command=0;
HOSTDATA(shpnt)->busfree_without_new_command=0;
HOSTDATA(shpnt)->busfree_without_done_command=0;
HOSTDATA(shpnt)->busfree_with_check_condition=0;
for (j = idle; j<maxstate; j++) {
HOSTDATA(shpnt)->count[j]=0;
HOSTDATA(shpnt)->count_trans[j]=0;
HOSTDATA(shpnt)->time[j]=0;
}
#endif
for (j = 0; j < 8; j++) {
HOSTDATA(shpnt)->syncrate[j] = 0;
HOSTDATA(shpnt)->syncneg[j] = 0;
}
SETPORT(SCSIID, setup[i].scsiid << 4);
shpnt->this_id = setup[i].scsiid;
if (setup[i].reconnect)
shpnt->can_queue = AHA152X_MAXQUEUE;
/* RESET OUT */
printk("aha152x: resetting bus...\n");
SETPORT(SCSISEQ, SCSIRSTO);
mdelay(256);
SETPORT(SCSISEQ, 0);
mdelay(DELAY);
reset_ports(shpnt);
printk(KERN_INFO
"aha152x%d%s: "
"vital data: rev=%x, "
"io=0x%03lx (0x%03lx/0x%03lx), "
"irq=%d, "
"scsiid=%d, "
"reconnect=%s, "
"parity=%s, "
"synchronous=%s, "
"delay=%d, "
"extended translation=%s\n",
HOSTNO, setup[i].tc1550 ? " (tc1550 mode)" : "",
GETPORT(REV) & 0x7,
shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,
shpnt->irq,
shpnt->this_id,
RECONNECT ? "enabled" : "disabled",
PARITY ? "enabled" : "disabled",
SYNCHRONOUS ? "enabled" : "disabled",
DELAY,
EXT_TRANS ? "enabled" : "disabled");
request_region(shpnt->io_port, IO_RANGE, "aha152x");
/* not expecting any interrupts */
SETPORT(SIMODE0, 0);
SETPORT(SIMODE1, 0);
ok = request_irq(shpnt->irq, swintr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt);
if (ok < 0) {
if (ok==-EINVAL)
printk(KERN_ERR "aha152x%d: bad IRQ %d.\n", HOSTNO, shpnt->irq);
else if(ok==-EBUSY)
printk(KERN_ERR "aha152x%d: IRQ %d already in use.\n", HOSTNO, shpnt->irq);
else
printk(KERN_ERR "aha152x%d: Unexpected error code %d on requesting IRQ %d.\n", HOSTNO, ok, shpnt->irq);
printk(KERN_ERR "aha152x%d: driver needs an IRQ.\n", HOSTNO);
scsi_unregister(shpnt);
registered_count--;
release_region(shpnt->io_port, IO_RANGE);
aha152x_host[registered_count] = 0;
shpnt = 0;
continue;
}
HOSTDATA(shpnt)->swint = 0;
printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO);
SETPORT(DMACNTRL0, SWINT|INTEN);
mdelay(1000);
free_irq(shpnt->irq, shpnt);
if (!HOSTDATA(shpnt)->swint) {
if (TESTHI(DMASTAT, INTSTAT)) {
printk("lost.\n");
} else {
printk("failed.\n");
}
SETPORT(DMACNTRL0, INTEN);
printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong. Please verify.\n", HOSTNO, shpnt->irq);
registered_count--;
release_region(shpnt->io_port, IO_RANGE);
aha152x_host[registered_count] = 0;
scsi_unregister(shpnt);
shpnt=NULL;
continue;
}
printk("ok.\n");
/* clear interrupts */
SETPORT(SSTAT0, 0x7f);
SETPORT(SSTAT1, 0xef);
if (request_irq(shpnt->irq, intr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt) < 0) {
printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO);
registered_count--;
release_region(shpnt->io_port, IO_RANGE);
aha152x_host[registered_count] = 0;
scsi_unregister(shpnt);
shpnt=NULL;
continue;
}
} }
return registered_count>0; return registered_count>0;
} }
int aha152x_release(struct Scsi_Host *shpnt) static int aha152x_release(struct Scsi_Host *shpnt)
{ {
if (shpnt->irq) if (shpnt->irq)
free_irq(shpnt->irq, shpnt); free_irq(shpnt->irq, shpnt);
...@@ -1471,7 +1417,7 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt) ...@@ -1471,7 +1417,7 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt)
/* /*
* Queue a command and setup interrupts for a free bus. * Queue a command and setup interrupts for a free bus.
*/ */
int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, Scsi_Cmnd *done_SC, void (*done)(Scsi_Cmnd *)) static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, Scsi_Cmnd *done_SC, void (*done)(Scsi_Cmnd *))
{ {
struct Scsi_Host *shpnt = SCpnt->device->host; struct Scsi_Host *shpnt = SCpnt->device->host;
unsigned long flags; unsigned long flags;
...@@ -1540,7 +1486,7 @@ int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, S ...@@ -1540,7 +1486,7 @@ int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, S
return 0; return 0;
} }
int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{ {
#if 0 #if 0
if(*SCpnt->cmnd == REQUEST_SENSE) { if(*SCpnt->cmnd == REQUEST_SENSE) {
...@@ -1559,7 +1505,7 @@ int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -1559,7 +1505,7 @@ int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
* run a command * run a command
* *
*/ */
void internal_done(Scsi_Cmnd *SCpnt) static void internal_done(Scsi_Cmnd *SCpnt)
{ {
#if 0 #if 0
struct Scsi_Host *shpnt = SCpnt->host; struct Scsi_Host *shpnt = SCpnt->host;
...@@ -1570,7 +1516,7 @@ void internal_done(Scsi_Cmnd *SCpnt) ...@@ -1570,7 +1516,7 @@ void internal_done(Scsi_Cmnd *SCpnt)
up(SCSEM(SCpnt)); up(SCSEM(SCpnt));
} }
int aha152x_command(Scsi_Cmnd * SCpnt) static int aha152x_command(Scsi_Cmnd * SCpnt)
{ {
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
...@@ -1584,7 +1530,7 @@ int aha152x_command(Scsi_Cmnd * SCpnt) ...@@ -1584,7 +1530,7 @@ int aha152x_command(Scsi_Cmnd * SCpnt)
* Abort a command * Abort a command
* *
*/ */
int aha152x_abort(Scsi_Cmnd *SCpnt) static int aha152x_abort(Scsi_Cmnd *SCpnt)
{ {
struct Scsi_Host *shpnt = SCpnt->device->host; struct Scsi_Host *shpnt = SCpnt->device->host;
Scsi_Cmnd *ptr; Scsi_Cmnd *ptr;
...@@ -1658,7 +1604,7 @@ static void timer_expired(unsigned long p) ...@@ -1658,7 +1604,7 @@ static void timer_expired(unsigned long p)
* FIXME: never seen this live. might lockup... * FIXME: never seen this live. might lockup...
* *
*/ */
int aha152x_device_reset(Scsi_Cmnd * SCpnt) static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
{ {
struct Scsi_Host *shpnt = SCpnt->device->host; struct Scsi_Host *shpnt = SCpnt->device->host;
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
...@@ -1716,7 +1662,7 @@ int aha152x_device_reset(Scsi_Cmnd * SCpnt) ...@@ -1716,7 +1662,7 @@ int aha152x_device_reset(Scsi_Cmnd * SCpnt)
return ret; return ret;
} }
void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs) static void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs)
{ {
Scsi_Cmnd *ptr; Scsi_Cmnd *ptr;
unsigned long flags; unsigned long flags;
...@@ -1745,7 +1691,7 @@ void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs) ...@@ -1745,7 +1691,7 @@ void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs)
* Reset the bus * Reset the bus
* *
*/ */
int aha152x_bus_reset(Scsi_Cmnd *SCpnt) static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
{ {
struct Scsi_Host *shpnt = SCpnt->device->host; struct Scsi_Host *shpnt = SCpnt->device->host;
unsigned long flags; unsigned long flags;
...@@ -1840,7 +1786,7 @@ int aha152x_host_reset(Scsi_Cmnd * SCpnt) ...@@ -1840,7 +1786,7 @@ int aha152x_host_reset(Scsi_Cmnd * SCpnt)
* Return the "logical geometry" * Return the "logical geometry"
* *
*/ */
int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev, static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *info_array) sector_t capacity, int *info_array)
{ {
struct Scsi_Host *shpnt = sdev->host; struct Scsi_Host *shpnt = sdev->host;
...@@ -3741,7 +3687,7 @@ static int get_ports(struct Scsi_Host *shpnt, char *pos) ...@@ -3741,7 +3687,7 @@ static int get_ports(struct Scsi_Host *shpnt, char *pos)
return (pos - start); return (pos - start);
} }
int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt) static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
{ {
if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0) if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0)
return -EINVAL; return -EINVAL;
...@@ -3788,7 +3734,7 @@ int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt) ...@@ -3788,7 +3734,7 @@ int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
#define SPRINTF(args...) \ #define SPRINTF(args...) \
do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0) do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
int aha152x_proc_info(char *buffer, char **start, static int aha152x_proc_info(char *buffer, char **start,
off_t offset, int length, int hostno, int inout) off_t offset, int length, int hostno, int inout)
{ {
int i; int i;
...@@ -3932,7 +3878,7 @@ int aha152x_proc_info(char *buffer, char **start, ...@@ -3932,7 +3878,7 @@ int aha152x_proc_info(char *buffer, char **start,
return thislength < length ? thislength : length; return thislength < length ? thislength : length;
} }
Scsi_Host_Template aha152x_driver_template = { static Scsi_Host_Template aha152x_driver_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = AHA152X_REVID, .name = AHA152X_REVID,
.proc_name = "aha152x", .proc_name = "aha152x",
...@@ -3954,6 +3900,6 @@ Scsi_Host_Template aha152x_driver_template = { ...@@ -3954,6 +3900,6 @@ Scsi_Host_Template aha152x_driver_template = {
}; };
#ifndef PCMCIA #ifndef PCMCIA
#define driver_templace aha152x_driver_template #define driver_template aha152x_driver_template
#include "scsi_module.c" #include "scsi_module.c"
#endif #endif
...@@ -313,4 +313,24 @@ enum { ...@@ -313,4 +313,24 @@ enum {
}; };
#endif #endif
/* for the pcmcia stub */
struct aha152x_setup {
int io_port;
int irq;
int scsiid;
int reconnect;
int parity;
int synchronous;
int delay;
int ext_trans;
int tc1550;
#if defined(AHA152X_DEBUG)
int debug;
#endif
char *conf;
};
struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *);
int aha152x_host_reset(struct scsi_cmnd *);
#endif /* _AHA152X_H */ #endif /* _AHA152X_H */
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include "aha152x.h"
#include <pcmcia/version.h> #include <pcmcia/version.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
...@@ -102,8 +103,6 @@ typedef struct scsi_info_t { ...@@ -102,8 +103,6 @@ typedef struct scsi_info_t {
dev_node_t node[8]; dev_node_t node[8];
} scsi_info_t; } scsi_info_t;
extern void aha152x_setup(char *str, int *ints);
static void aha152x_release_cs(u_long arg); static void aha152x_release_cs(u_long arg);
static int aha152x_event(event_t event, int priority, static int aha152x_event(event_t event, int priority,
event_callback_args_t *args); event_callback_args_t *args);
...@@ -111,11 +110,7 @@ static int aha152x_event(event_t event, int priority, ...@@ -111,11 +110,7 @@ static int aha152x_event(event_t event, int priority,
static dev_link_t *aha152x_attach(void); static dev_link_t *aha152x_attach(void);
static void aha152x_detach(dev_link_t *); static void aha152x_detach(dev_link_t *);
#define driver_template aha152x_driver_template static dev_link_t *dev_list;
extern Scsi_Host_Template aha152x_driver_template;
static dev_link_t *dev_list = NULL;
static dev_info_t dev_info = "aha152x_cs"; static dev_info_t dev_info = "aha152x_cs";
/*====================================================================*/ /*====================================================================*/
...@@ -227,11 +222,12 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -227,11 +222,12 @@ static void aha152x_config_cs(dev_link_t *link)
{ {
client_handle_t handle = link->handle; client_handle_t handle = link->handle;
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
struct aha152x_setup s;
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
int i, last_ret, last_fn, ints[8]; int i, last_ret, last_fn;
u_char tuple_data[64]; u_char tuple_data[64];
Scsi_Device *dev; struct scsi_device *dev;
dev_node_t *node, **tail; dev_node_t *node, **tail;
struct Scsi_Host *host; struct Scsi_Host *host;
...@@ -247,7 +243,6 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -247,7 +243,6 @@ static void aha152x_config_cs(dev_link_t *link)
link->conf.ConfigBase = parse.config.base; link->conf.ConfigBase = parse.config.base;
/* Configure card */ /* Configure card */
driver_template.module = &__this_module;
link->state |= DEV_CONFIG; link->state |= DEV_CONFIG;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
...@@ -278,27 +273,30 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -278,27 +273,30 @@ static void aha152x_config_cs(dev_link_t *link)
release_region(link->io.BasePort1, link->io.NumPorts1); release_region(link->io.BasePort1, link->io.NumPorts1);
/* Set configuration options for the aha152x driver */ /* Set configuration options for the aha152x driver */
ints[0] = 7; memset(&s, 0, sizeof(s));
ints[1] = link->io.BasePort1; s.conf = "PCMCIA setup";
ints[2] = link->irq.AssignedIRQ; s.io_port = link->io.BasePort1;
ints[3] = host_id; s.irq = link->irq.AssignedIRQ;
ints[4] = reconnect; s.scsiid = host_id;
ints[5] = parity; s.reconnect = reconnect;
ints[6] = synchronous; s.parity = parity;
ints[7] = reset_delay; s.synchronous = synchronous;
if (ext_trans) { s.delay = reset_delay;
ints[8] = ext_trans; ints[0] = 8; if (ext_trans)
} s.ext_trans = ext_trans;
aha152x_setup("PCMCIA setup", ints);
scsi_register_host(&driver_template);
tail = &link->dev; tail = &link->dev;
info->ndev = 0; info->ndev = 0;
for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host)) host = aha152x_probe_one(&s);
if (host->hostt == &driver_template) if (host == NULL) {
list_for_each_entry (dev, &host->my_devices, siblings) { printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
goto cs_failed;
}
scsi_add_host(host, NULL);
list_for_each_entry(dev, &host->my_devices, siblings) {
u_long arg[2], id; u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
...@@ -329,10 +327,8 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -329,10 +327,8 @@ static void aha152x_config_cs(dev_link_t *link)
info->ndev++; info->ndev++;
info->host = dev->host; info->host = dev->host;
} }
*tail = NULL;
if (info->ndev == 0)
printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
*tail = NULL;
link->state &= ~DEV_CONFIG_PENDING; link->state &= ~DEV_CONFIG_PENDING;
return; return;
...@@ -340,28 +336,14 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -340,28 +336,14 @@ static void aha152x_config_cs(dev_link_t *link)
cs_error(link->handle, last_fn, last_ret); cs_error(link->handle, last_fn, last_ret);
aha152x_release_cs((u_long)link); aha152x_release_cs((u_long)link);
return; return;
}
} /* aha152x_config_cs */
/*====================================================================*/
static void aha152x_release_cs(u_long arg) static void aha152x_release_cs(u_long arg)
{ {
dev_link_t *link = (dev_link_t *)arg; dev_link_t *link = (dev_link_t *)arg;
scsi_info_t *info = link->priv;
DEBUG(0, "aha152x_release_cs(0x%p)\n", link); scsi_remove_host(info->host);
#warning This does not protect you. You need some real fix for your races.
#if 0
if (GET_USE_COUNT(driver_template.module) != 0) {
DEBUG(1, "aha152x_cs: release postponed, "
"device still open\n");
link->state |= DEV_STALE_CONFIG;
return;
}
#endif
scsi_unregister_host(&driver_template);
link->dev = NULL; link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseConfiguration, link->handle);
...@@ -369,12 +351,11 @@ static void aha152x_release_cs(u_long arg) ...@@ -369,12 +351,11 @@ static void aha152x_release_cs(u_long arg)
CardServices(ReleaseIRQ, link->handle, &link->irq); CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
scsi_unregister(info->host);
if (link->state & DEV_STALE_LINK) if (link->state & DEV_STALE_LINK)
aha152x_detach(link); aha152x_detach(link);
}
} /* aha152x_release_cs */
/*====================================================================*/
static int aha152x_event(event_t event, int priority, static int aha152x_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
...@@ -414,26 +395,27 @@ static int aha152x_event(event_t event, int priority, ...@@ -414,26 +395,27 @@ static int aha152x_event(event_t event, int priority,
break; break;
} }
return 0; return 0;
} /* aha152x_event */ }
/*====================================================================*/ static struct pcmcia_driver aha152x_cs_driver = {
.owner = THIS_MODULE,
.drv = {
.name = "aha152x_cs",
},
.attach = aha152x_attach,
.detach = aha152x_detach,
};
static int __init init_aha152x_cs(void) { static int __init init_aha152x_cs(void)
servinfo_t serv; {
DEBUG(0, "%s\n", version); return pcmcia_register_driver(&aha152x_cs_driver);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "aha152x_cs: Card Services release "
"does not match!\n");
return -1;
}
register_pccard_driver(&dev_info, &aha152x_attach, &aha152x_detach);
return 0;
} }
static void __exit exit_aha152x_cs(void) { static void __exit exit_aha152x_cs(void)
DEBUG(0, "aha152x_cs: unloading\n"); {
unregister_pccard_driver(&dev_info); pcmcia_unregister_driver(&aha152x_cs_driver);
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) while (dev_list != NULL)
aha152x_detach(dev_list); aha152x_detach(dev_list);
} }
......
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