Use the new adapter_softc field in the scsi_link structure so that

this driver no longer needs to maintain an array of configured units.

Pass "softc" pointers instead of unit numbers to many functions that
did a conversion for unit->softc anyway.
This commit is contained in:
Justin T. Gibbs 1996-01-07 19:20:59 +00:00
parent a8ce2e68d7
commit b3b779573c
1 changed files with 66 additions and 79 deletions

View File

@ -14,7 +14,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
* $Id: aha1742.c,v 1.45 1995/12/14 23:26:53 bde Exp $
* $Id: aha1742.c,v 1.46 1996/01/04 21:10:39 wollman Exp $
*/
#include <sys/types.h>
@ -246,7 +246,7 @@ struct ecb {
physaddr hashkey; /* physaddr of this struct */
};
static struct ahb_data {
struct ahb_data {
int unit;
int flags;
#define AHB_INIT 0x01;
@ -258,34 +258,36 @@ static struct ahb_data {
struct ecb *immed_ecb; /* an outstanding immediete command */
struct scsi_link sc_link;
int numecbs;
} *ahbdata[NAHB];
};
static u_int32 ahb_adapter_info __P((int unit));
static struct ahb_data *
ahb_alloc __P((int unit, u_long iobase, int irq));
static int ahb_attach __P((struct eisa_device *dev));
static int ahb_bus_attach __P((struct ahb_data *ahb));
static void ahb_done __P((int unit, struct ecb *ecb, int state));
static void ahb_done __P((struct ahb_data *ahb, struct ecb *ecb, int state));
static void ahb_free __P((struct ahb_data *ahb));
static void ahb_free_ecb __P((int unit, struct ecb *ecb, int flags));
static void ahb_free_ecb __P((struct ahb_data* ahb, struct ecb *ecb,
int flags));
static struct ecb *
ahb_get_ecb __P((int unit, int flags));
ahb_get_ecb __P((struct ahb_data* ahb, int flags));
static struct ecb *
ahb_ecb_phys_kv __P((struct ahb_data *ahb, physaddr ecb_phys));
static int ahb_init __P((int unit));
static int ahb_init __P((struct ahb_data *ahb));
static void ahbintr __P((void *arg));
static char *ahbmatch __P((eisa_id_t type));
static void ahbminphys __P((struct buf *bp));
static int ahb_poll __P((int unit, int wait));
static int ahb_poll __P((struct ahb_data *ahb, int wait));
#ifdef AHBDEBUG
static void ahb_print_active_ecb __P((int unit));
static void ahb_print_active_ecb __P((struct ahb_data *ahb));
static void ahb_print_ecb __P((struct ecb *ecb));
#endif
static int ahbprobe __P((void));
static int ahb_reset __P((u_long port));
static int32 ahb_scsi_cmd __P((struct scsi_xfer *xs));
static void ahb_send_immed __P((int unit, int target, u_long cmd));
static void ahb_send_mbox __P((int unit, int opcode, int target,
static void ahb_send_immed __P((struct ahb_data *ahb, int target,
u_long cmd));
static void ahb_send_mbox __P((struct ahb_data *ahb, int opcode, int target,
struct ecb *ecb));
static timeout_t
ahb_timeout;
@ -366,9 +368,9 @@ main()
* Function to send a command out through a mailbox
*/
static void
ahb_send_mbox(int unit, int opcode, int target, struct ecb *ecb)
ahb_send_mbox(struct ahb_data* ahb, int opcode, int target, struct ecb *ecb)
{
int port = ahbdata[unit]->baseport;
int port = ahb->baseport;
int wait = 300; /* 3ms should be enough */
int stport = port + G2STAT;
int s = splbio();
@ -380,7 +382,7 @@ ahb_send_mbox(int unit, int opcode, int target, struct ecb *ecb)
DELAY(10);
}
if (wait == 0) {
printf("ahb%d: board not responding\n", unit);
printf("ahb%d: board not responding\n", ahb->unit);
Debugger("aha1742");
fatal_if_no_DDB();
}
@ -394,9 +396,8 @@ ahb_send_mbox(int unit, int opcode, int target, struct ecb *ecb)
* Function to poll for command completion when in poll mode
*/
static int
ahb_poll(int unit, int wait)
ahb_poll(struct ahb_data *ahb, int wait)
{ /* in msec */
struct ahb_data *ahb = ahbdata[unit];
int port = ahb->baseport;
int stport = port + G2STAT;
@ -406,7 +407,7 @@ ahb_poll(int unit, int wait)
break;
DELAY(1000);
} if (wait == 0) {
printf("ahb%d: board not responding\n", unit);
printf("ahb%d: board not responding\n", ahb->unit);
return (EIO);
}
if (cheat != ahb_ecb_phys_kv(ahb, inl(port + MBOXIN0))) {
@ -424,9 +425,9 @@ ahb_poll(int unit, int wait)
* Function to send an immediate type command to the adapter
*/
static void
ahb_send_immed(int unit, int target, u_long cmd)
ahb_send_immed(struct ahb_data *ahb, int target, u_long cmd)
{
int port = ahbdata[unit]->baseport;
int port = ahb->baseport;
int s = splbio();
int stport = port + G2STAT;
int wait = 100; /* 1 ms enough? */
@ -437,7 +438,7 @@ ahb_send_immed(int unit, int target, u_long cmd)
break;
DELAY(10);
} if (wait == 0) {
printf("ahb%d: board not responding\n", unit);
printf("ahb%d: board not responding\n", ahb->unit);
Debugger("aha1742");
fatal_if_no_DDB();
}
@ -516,25 +517,15 @@ ahb_alloc(unit, iobase, irq)
{
struct ahb_data *ahb;
if (unit >= NAHB) {
printf("ahb: unit number (%d) too high\n", unit);
return NULL;
}
/*
* Allocate a storage area for us
*/
if (ahbdata[unit]) {
printf("ahb%d: memory already allocated\n", unit);
return NULL;
}
ahb = malloc(sizeof(struct ahb_data), M_TEMP, M_NOWAIT);
if (!ahb) {
printf("ahb%d: cannot malloc!\n", unit);
return NULL;
}
bzero(ahb, sizeof(struct ahb_data));
ahbdata[unit] = ahb;
ahb->unit = unit;
ahb->baseport = iobase;
ahb->vect = irq;
@ -546,7 +537,6 @@ static void
ahb_free(ahb)
struct ahb_data *ahb;
{
ahbdata[ahb->unit] = NULL;
free(ahb, M_DEVBUF);
return;
}
@ -633,7 +623,7 @@ ahb_attach(e_dev)
* Now that we know we own the resources we need, do the full
* card initialization.
*/
if(ahb_init(unit)){
if(ahb_init(ahb)){
ahb_free(ahb);
/*
* The board's IRQ line will not be left enabled
@ -659,13 +649,12 @@ static int
ahb_bus_attach(ahb)
struct ahb_data *ahb;
{
int unit = ahb->unit;
struct scsibus_data *scbus;
/*
* fill in the prototype scsi_link.
*/
ahb->sc_link.adapter_unit = unit;
ahb->sc_link.adapter_unit = ahb->unit;
ahb->sc_link.adapter_targ = ahb->our_id;
ahb->sc_link.adapter = &ahb_switch;
ahb->sc_link.device = &ahb_dev;
@ -715,7 +704,6 @@ ahbintr(arg)
int unit;
ahb = (struct ahb_data *)arg;
unit = ahb->unit;
port = ahb->baseport;
#ifdef AHBDEBUG
@ -755,13 +743,13 @@ ahbintr(arg)
case AHB_ASN: /* for target mode */
printf("ahb%d: "
"Unexpected ASN interrupt(0x%lx)\n",
unit, mboxval);
ahb->unit, mboxval);
ecb = 0;
break;
case AHB_HW_ERR:
printf("ahb%d: "
"Hardware error interrupt(0x%lx)\n",
unit, mboxval);
ahb->unit, mboxval);
ecb = 0;
break;
case AHB_ECB_RECOVERED:
@ -771,7 +759,8 @@ ahbintr(arg)
ecb = ahb_ecb_phys_kv(ahb, mboxval);
break;
default:
printf(" Unknown return from ahb%d(%x)\n", unit, ahbstat);
printf(" Unknown return from ahb%d(%x)\n",
ahb->unit, ahbstat);
ecb = 0;
}
} if (ecb) {
@ -783,7 +772,7 @@ ahbintr(arg)
printf("<int ecb(%x)>", ecb);
#endif /*AHBDEBUG */
untimeout(ahb_timeout, (caddr_t)ecb);
ahb_done(unit, ecb, ((stat == AHB_ECB_OK) ? SUCCESS : FAIL));
ahb_done(ahb, ecb, ((stat == AHB_ECB_OK) ? SUCCESS : FAIL));
}
}
}
@ -794,8 +783,9 @@ ahbintr(arg)
* went.
*/
static void
ahb_done(unit, ecb, state)
int unit, state;
ahb_done(ahb, ecb, state)
struct ahb_data *ahb;
int state;
struct ecb *ecb;
{
struct ahb_ecb_status *stat = &ecb->ecb_status;
@ -869,7 +859,7 @@ ahb_done(unit, ecb, state)
}
}
done: xs->flags |= ITSDONE;
ahb_free_ecb(unit, ecb, xs->flags);
ahb_free_ecb(ahb, ecb, xs->flags);
scsi_done(xs);
}
@ -878,12 +868,12 @@ done: xs->flags |= ITSDONE;
* free list.
*/
static void
ahb_free_ecb(unit, ecb, flags)
int unit, flags;
ahb_free_ecb(ahb, ecb, flags)
struct ahb_data *ahb;
int flags;
struct ecb *ecb;
{
unsigned int opri = 0;
struct ahb_data *ahb = ahbdata[unit];
if (!(flags & SCSI_NOMASK))
opri = splbio();
@ -909,10 +899,10 @@ ahb_free_ecb(unit, ecb, flags)
* otherwise either return an error or sleep
*/
static struct ecb *
ahb_get_ecb(unit, flags)
int unit, flags;
ahb_get_ecb(ahb, flags)
struct ahb_data *ahb;
int flags;
{
struct ahb_data *ahb = ahbdata[unit];
unsigned opri = 0;
struct ecb *ecbp;
int hashnum;
@ -940,7 +930,7 @@ ahb_get_ecb(unit, flags)
ecbp->nexthash = ahb->ecbhash[hashnum];
ahb->ecbhash[hashnum] = ecbp;
} else {
printf("ahb%d: Can't malloc ECB\n", unit);
printf("ahb%d: Can't malloc ECB\n", ahb->unit);
}
break;
} else {
@ -987,11 +977,10 @@ ahb_ecb_phys_kv(ahb, ecb_phys)
* Start the board, ready for normal operation
*/
static int
ahb_init(unit)
int unit;
ahb_init(ahb)
struct ahb_data *ahb;
{
u_char intdef;
struct ahb_data *ahb = ahbdata[unit];
int port = ahb->baseport;
/*
@ -1039,11 +1028,11 @@ ahb_scsi_cmd(xs)
int seg; /* scatter gather seg being worked on */
int thiskv;
physaddr thisphys, nextphys;
int unit = xs->sc_link->adapter_unit;
int bytes_this_seg, bytes_this_page, datalen, flags;
struct ahb_data *ahb = ahbdata[unit];
struct ahb_data *ahb;
int s;
ahb = (struct ahb_data *)xs->sc_link->adapter_softc;
SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahb_scsi_cmd\n"));
/*
* get a ecb (mbox-out) to use. If the transfer
@ -1054,14 +1043,14 @@ ahb_scsi_cmd(xs)
if (xs->bp)
flags |= (SCSI_NOSLEEP); /* just to be sure */
if (flags & ITSDONE) {
printf("ahb%d: Already done?", unit);
printf("ahb%d: Already done?", ahb->unit);
xs->flags &= ~ITSDONE;
}
if (!(flags & INUSE)) {
printf("ahb%d: Not in use?", unit);
printf("ahb%d: Not in use?", ahb->unit);
xs->flags |= INUSE;
}
if (!(ecb = ahb_get_ecb(unit, flags))) {
if (!(ecb = ahb_get_ecb(ahb, flags))) {
xs->error = XS_DRIVER_STUFFUP;
return (TRY_AGAIN_LATER);
}
@ -1082,18 +1071,18 @@ ahb_scsi_cmd(xs)
ahb->immed_ecb = ecb;
if (!(flags & SCSI_NOMASK)) {
s = splbio();
ahb_send_immed(unit, xs->sc_link->target, AHB_TARG_RESET);
ahb_send_immed(ahb, xs->sc_link->target, AHB_TARG_RESET);
timeout(ahb_timeout, (caddr_t)ecb, (xs->timeout * hz) / 1000);
splx(s);
return (SUCCESSFULLY_QUEUED);
} else {
ahb_send_immed(unit, xs->sc_link->target, AHB_TARG_RESET);
ahb_send_immed(ahb, xs->sc_link->target, AHB_TARG_RESET);
/*
* If we can't use interrupts, poll on completion
*/
SC_DEBUG(xs->sc_link, SDEV_DB3, ("wait\n"));
if (ahb_poll(unit, xs->timeout)) {
ahb_free_ecb(unit, ecb, flags);
if (ahb_poll(ahb, xs->timeout)) {
ahb_free_ecb(ahb, ecb, flags);
xs->error = XS_TIMEOUT;
return (HAD_ERROR);
}
@ -1194,9 +1183,9 @@ ahb_scsi_cmd(xs)
SC_DEBUGN(xs->sc_link, SDEV_DB4, ("\n"));
if (datalen) { /* there's still data, must have run out of segs! */
printf("ahb_scsi_cmd%d: more than %d DMA segs\n",
unit, AHB_NSEG);
ahb->unit, AHB_NSEG);
xs->error = XS_DRIVER_STUFFUP;
ahb_free_ecb(unit, ecb, flags);
ahb_free_ecb(ahb, ecb, flags);
return (HAD_ERROR);
}
} else { /* No data xfer, use non S/G values */
@ -1212,7 +1201,7 @@ ahb_scsi_cmd(xs)
*/
if (!(flags & SCSI_NOMASK)) {
s = splbio();
ahb_send_mbox(unit, OP_START_ECB, xs->sc_link->target, ecb);
ahb_send_mbox(ahb, OP_START_ECB, xs->sc_link->target, ecb);
timeout(ahb_timeout, (caddr_t)ecb, (xs->timeout * hz) / 1000);
splx(s);
SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_sent\n"));
@ -1221,16 +1210,16 @@ ahb_scsi_cmd(xs)
/*
* If we can't use interrupts, poll on completion
*/
ahb_send_mbox(unit, OP_START_ECB, xs->sc_link->target, ecb);
ahb_send_mbox(ahb, OP_START_ECB, xs->sc_link->target, ecb);
SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_wait\n"));
do {
if (ahb_poll(unit, xs->timeout)) {
if (ahb_poll(ahb, xs->timeout)) {
if (!(xs->flags & SCSI_SILENT))
printf("cmd fail\n");
ahb_send_mbox(unit, OP_ABORT_ECB, xs->sc_link->target, ecb);
if (ahb_poll(unit, 2000)) {
ahb_send_mbox(ahb, OP_ABORT_ECB, xs->sc_link->target, ecb);
if (ahb_poll(ahb, 2000)) {
printf("abort failed in wait\n");
ahb_free_ecb(unit, ecb, flags);
ahb_free_ecb(ahb, ecb, flags);
}
xs->error = XS_DRIVER_STUFFUP;
return (HAD_ERROR);
@ -1246,13 +1235,11 @@ static void
ahb_timeout(void *arg1)
{
struct ecb * ecb = (struct ecb *)arg1;
int unit;
struct ahb_data *ahb;
int s = splbio();
unit = ecb->xs->sc_link->adapter_unit;
ahb = ahbdata[unit];
printf("ahb%d:%d:%d (%s%d) timed out ", unit
ahb = ecb->xs->sc_link->adapter_softc;
printf("ahb%d:%d:%d (%s%d) timed out ", ahb->unit
,ecb->xs->sc_link->target
,ecb->xs->sc_link->lun
,ecb->xs->sc_link->device->name
@ -1260,7 +1247,7 @@ ahb_timeout(void *arg1)
#ifdef AHBDEBUG
if (ahb_debug & AHB_SHOWECBS)
ahb_print_active_ecb(unit);
ahb_print_active_ecb(ahb);
#endif /*AHBDEBUG */
/*
@ -1269,7 +1256,7 @@ ahb_timeout(void *arg1)
if (ecb->flags & ECB_IMMED) {
ecb->xs->retries = 0; /* I MEAN IT ! */
ecb->flags |= ECB_IMMED_FAIL;
ahb_done(unit, ecb, FAIL);
ahb_done(ahb, ecb, FAIL);
splx(s);
return;
}
@ -1285,10 +1272,10 @@ ahb_timeout(void *arg1)
printf("AGAIN");
ecb->xs->retries = 0; /* I MEAN IT ! */
ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST;
ahb_done(unit, ecb, FAIL);
ahb_done(ahb, ecb, FAIL);
} else { /* abort the operation that has timed out */
printf("\n");
ahb_send_mbox(unit, OP_ABORT_ECB, ecb->xs->sc_link->target, ecb);
ahb_send_mbox(ahb, OP_ABORT_ECB, ecb->xs->sc_link->target, ecb);
/* 2 secs for the abort */
timeout(ahb_timeout, (caddr_t)ecb, 2 * hz);
ecb->flags = ECB_ABORTED;
@ -1315,9 +1302,9 @@ ahb_print_ecb(ecb)
}
static void
ahb_print_active_ecb(int unit)
ahb_print_active_ecb(ahb)
struct ahb_data *ahb;
{
struct ahb_data *ahb = ahbdata[unit];
struct ecb *ecb;
int i = 0;