mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 17:32:43 +00:00
Clean up a few nits in the aic7xxx driver:
1) Make the driver "quiet" by sticking most boot messages behind bootverbose conditionals. This means that you won't see the sync and wide negotiation, but you will find out if they fail. 2) Add support to the 93cx6 serial eeprom code to read at an abitrary offset. This is needed so that we can access the second half of the eeprom on 3940 cards where the second channel's config is stored. 3) Add flags argument to ahcprobe(). This is used by the pci probe code to tell the generic driver that an adapter should be treated as a channel B device as well as notify it of the presence of external SCB SRAM. These are needed for some motherboard implementations of the aic7870 and for the 3940 controllers. 4) Print "Channel A"/"Channel B" instead of "Single Channel" for the two busses of the 3940. I received many reports of confusion about how the 3940 was probed since most people belived that only one ahc entry was needed. This will hopefully make it clearer. 5) Walk the SCBs to determine just how many their are if external SCB ram is detected. 6) Hard code that external SCB ram is present for the 3940 since it doesn't use the documented reporting facility for reporting the SRAM. :( 255 commands per channel are supported on the 3940. 7) Read the seeprom starting at addres 32 for the second channel of the 3940 so we get the right info for that channel. 8) Clean up printing of the "Disabling tagged queuing message". 9) Queue timeouts if they occur while we are handling a timeout. The code was totally unprotected in this scenario. Reviewed by: Timeout code reviewed by David Greenman <davidg>
This commit is contained in:
parent
0be4f315f7
commit
67f06b6142
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10569
@ -18,7 +18,7 @@
|
||||
* 4. Modifications may be freely made to this file if the above conditions
|
||||
* are met.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: 93cx6.c,v 1.1 1995/07/04 21:16:11 gibbs Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -82,6 +82,7 @@ struct seeprom_cmd {
|
||||
*/
|
||||
int read_seeprom (u_long offset,
|
||||
u_short *buf,
|
||||
u_int start_addr,
|
||||
int count,
|
||||
u_short CS, /* chip select */
|
||||
u_short CK, /* clock */
|
||||
@ -98,7 +99,7 @@ int read_seeprom (u_long offset,
|
||||
* Read the requested registers of the seeprom. The loop
|
||||
* will range from 0 to count-1.
|
||||
*/
|
||||
for (k = 0; k < count; k = k + 1) {
|
||||
for (k = start_addr; k < count + start_addr; k = k + 1) {
|
||||
/* Send chip select for one clock cycle. */
|
||||
outb(offset, MS | CK | CS);
|
||||
CLOCK_PULSE(offset, RDY);
|
||||
@ -144,9 +145,10 @@ int read_seeprom (u_long offset,
|
||||
CLOCK_PULSE(offset, RDY);
|
||||
temp = temp ^ CK;
|
||||
if (inb(offset) & DI)
|
||||
buf[k] = (buf[k] << 1) | 0x1;
|
||||
buf[k - start_addr] =
|
||||
(buf[k - start_addr] << 1) | 0x1;
|
||||
else
|
||||
buf[k] = (buf[k] << 1);
|
||||
buf[k - start_addr] = (buf[k - start_addr]<< 1);
|
||||
outb(offset, temp);
|
||||
CLOCK_PULSE(offset, RDY);
|
||||
}
|
||||
@ -159,7 +161,6 @@ int read_seeprom (u_long offset,
|
||||
outb(offset, MS);
|
||||
CLOCK_PULSE(offset, RDY);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf ("Serial EEPROM:");
|
||||
for (k = 0; k < count; k = k + 1) {
|
||||
|
@ -20,7 +20,7 @@
|
||||
* 4. Modifications may be freely made to this file if the above conditions
|
||||
* are met.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: 93cx6.h,v 1.1 1995/07/04 21:16:12 gibbs Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -43,6 +43,7 @@
|
||||
*/
|
||||
int read_seeprom (u_long offset,
|
||||
u_short *buf,
|
||||
u_int start_addr,
|
||||
int count,
|
||||
u_short CS,
|
||||
u_short CK,
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Product specific probe and attach routines can be found in:
|
||||
* i386/isa/aic7770.c 27/284X and aic7770 motherboard controllers
|
||||
* /pci/aic7870.c 294x and aic7870 motherboard controllers
|
||||
* /pci/aic7870.c 3940, 2940, aic7870 and aic7850 controllers
|
||||
*
|
||||
* Portions of this driver are based on the FreeBSD 1742 Driver:
|
||||
*
|
||||
@ -24,7 +24,7 @@
|
||||
*
|
||||
* commenced: Sun Sep 27 18:14:01 PDT 1992
|
||||
*
|
||||
* $Id: aic7xxx.c,v 1.36 1995/08/15 08:54:21 gibbs Exp $
|
||||
* $Id: aic7xxx.c,v 1.37 1995/08/23 23:03:17 gibbs Exp $
|
||||
*/
|
||||
/*
|
||||
* TODO:
|
||||
@ -62,6 +62,7 @@ void ahc_loadseq __P((u_long iobase));
|
||||
int32 ahc_scsi_cmd();
|
||||
timeout_t ahc_timeout;
|
||||
void ahc_done __P((int unit, struct scb *scbp));
|
||||
void ahc_timeout_done __P((int unit, struct scb *scbp));
|
||||
struct scb *ahc_get_scb __P((int unit, int flags));
|
||||
void ahc_free_scb();
|
||||
void ahc_scb_timeout __P((int unit, struct ahc_data *ahc, struct scb *scb));
|
||||
@ -778,10 +779,11 @@ static int ahc_num_syncrates =
|
||||
*/
|
||||
|
||||
int
|
||||
ahcprobe(unit, iobase, type)
|
||||
ahcprobe(unit, iobase, type, flags)
|
||||
int unit;
|
||||
u_long iobase;
|
||||
ahc_type type;
|
||||
ahc_flag flags;
|
||||
{
|
||||
|
||||
/*
|
||||
@ -812,6 +814,7 @@ ahcprobe(unit, iobase, type)
|
||||
ahcdata[unit] = ahc;
|
||||
ahc->baseport = iobase;
|
||||
ahc->type = type;
|
||||
ahc->flags = flags;
|
||||
|
||||
/*
|
||||
* Try to initialize a unit at this location
|
||||
@ -844,22 +847,20 @@ void ahc_scsirate(scsirate, period, offset, unit, target )
|
||||
|
||||
if ((ahc_syncrates[i].period - period) >= 0) {
|
||||
*scsirate = (ahc_syncrates[i].sxfr) | (offset & 0x0f);
|
||||
printf("ahc%d: target %d synchronous at %sMB/s, "
|
||||
"offset = 0x%x\n", unit, target,
|
||||
ahc_syncrates[i].rate, offset );
|
||||
/* XXX Conditional on bootverbose??? */
|
||||
#ifdef AHC_DEBUG
|
||||
#endif /* AHC_DEBUG */
|
||||
if(bootverbose) {
|
||||
printf("ahc%d: target %d synchronous at %sMB/s,"
|
||||
" offset = 0x%x\n", unit, target,
|
||||
ahc_syncrates[i].rate, offset );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Default to asyncronous transfers. Also reject this SDTR request. */
|
||||
*scsirate = 0;
|
||||
printf("ahc%d: target %d using asyncronous transfers\n",
|
||||
unit, target );
|
||||
#ifdef AHC_DEBUG
|
||||
#endif /* AHC_DEBUG */
|
||||
|
||||
if(bootverbose) {
|
||||
printf("ahc%d: target %d using asyncronous transfers\n",
|
||||
unit, target );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -898,7 +899,8 @@ ahc_attach(unit)
|
||||
/*
|
||||
* ask the adapter what subunits are present
|
||||
*/
|
||||
printf("ahc%d: Probing channel A\n", unit);
|
||||
if(bootverbose)
|
||||
printf("ahc%d: Probing channel A\n", unit);
|
||||
scsi_attachdevs(scbus);
|
||||
scbus = NULL; /* Upper-level SCSI code owns this now */
|
||||
if(ahc->type & AHC_TWIN) {
|
||||
@ -913,7 +915,8 @@ ahc_attach(unit)
|
||||
scbus->adapter_link = &ahc->sc_link_b;
|
||||
if(ahc->type & AHC_WIDE)
|
||||
scbus->maxtarg = 15;
|
||||
printf("ahc%d: Probing Channel B\n", unit);
|
||||
if(bootverbose)
|
||||
printf("ahc%d: Probing Channel B\n", unit);
|
||||
scsi_attachdevs(scbus);
|
||||
scbus = NULL; /* Upper-level SCSI code owns this now */
|
||||
}
|
||||
@ -1050,17 +1053,18 @@ ahcintr(unit)
|
||||
case SEND_REJECT:
|
||||
{
|
||||
u_char rejbyte = inb(HA_REJBYTE + iobase);
|
||||
printf("ahc%d:%c:%d: Warning - message "
|
||||
"rejected by target: 0x%x\n",
|
||||
unit, channel, target, rejbyte);
|
||||
if(( rejbyte & 0xf0) == 0x20) {
|
||||
/* Tagged Message */
|
||||
printf("ahc%d:%c:%d: Tagged message "
|
||||
printf("\nahc%d:%c:%d: Tagged message "
|
||||
"rejected. Disabling tagged "
|
||||
"commands for this target.\n",
|
||||
unit, channel, target);
|
||||
ahc->tagenable &= ~targ_mask;
|
||||
}
|
||||
else
|
||||
printf("ahc%d:%c:%d: Warning - message "
|
||||
"rejected by target: 0x%x\n",
|
||||
unit, channel, target, rejbyte);
|
||||
break;
|
||||
}
|
||||
case NO_IDENT:
|
||||
@ -1168,22 +1172,24 @@ ahcintr(unit)
|
||||
switch(bus_width)
|
||||
{
|
||||
case BUS_8_BIT:
|
||||
scratch &= 0x7f;
|
||||
break;
|
||||
scratch &= 0x7f;
|
||||
break;
|
||||
case BUS_16_BIT:
|
||||
if(bootverbose)
|
||||
printf("ahc%d: target "
|
||||
"%d using 16Bit "
|
||||
"transfers\n",
|
||||
unit, target);
|
||||
scratch |= 0x80;
|
||||
break;
|
||||
scratch |= 0x80;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Send our own WDTR in reply
|
||||
*/
|
||||
printf("Will Send WDTR!!\n");
|
||||
switch(bus_width)
|
||||
{
|
||||
case BUS_8_BIT:
|
||||
@ -1193,12 +1199,15 @@ ahcintr(unit)
|
||||
/* Negotiate 16_BITS */
|
||||
bus_width = BUS_16_BIT;
|
||||
case BUS_16_BIT:
|
||||
if(bootverbose)
|
||||
printf("ahc%d: target "
|
||||
"%d using 16Bit "
|
||||
"transfers\n",
|
||||
unit, target);
|
||||
scratch |= 0x80;
|
||||
break;
|
||||
scratch |= 0x80;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
outb(HA_RETURN_1 + iobase,
|
||||
bus_width | SEND_WDTR);
|
||||
@ -1745,7 +1754,7 @@ ahc_init(unit)
|
||||
struct ahc_data *ahc = ahcdata[unit];
|
||||
u_long iobase = ahc->baseport;
|
||||
u_char scsi_conf, sblkctl, i, host_id;
|
||||
int intdef, max_targ = 16, wait, have_seeprom = 0;
|
||||
int intdef, max_targ = 15, wait, have_seeprom = 0;
|
||||
int bios_disabled = 0;
|
||||
struct seeprom_config sc;
|
||||
/*
|
||||
@ -1758,7 +1767,8 @@ ahc_init(unit)
|
||||
printf("ahc%d: scb %d bytes; ahc_dma %d bytes\n",
|
||||
unit, sizeof(struct scb), sizeof(struct ahc_dma_seg));
|
||||
#endif /* AHC_DEBUG */
|
||||
printf("ahc%d: reading board settings\n", unit);
|
||||
if(bootverbose)
|
||||
printf("ahc%d: reading board settings\n", unit);
|
||||
|
||||
/* Save the IRQ type before we do a chip reset */
|
||||
|
||||
@ -1809,17 +1819,19 @@ ahc_init(unit)
|
||||
case AHC_394:
|
||||
case AHC_294:
|
||||
host_id = 0x07; /* default to SCSI ID 7 for 7850 */
|
||||
if (ahc->type != AHC_AIC7850) {
|
||||
if (ahc->type & AHC_AIC7870) {
|
||||
unsigned short *scarray = (u_short *)≻
|
||||
unsigned short checksum = 0;
|
||||
|
||||
printf("ahc%d: Reading SEEPROM...", unit);
|
||||
if(bootverbose)
|
||||
printf("ahc%d: Reading SEEPROM...", unit);
|
||||
have_seeprom = enable_seeprom (iobase + SEECTL,
|
||||
SEECS, SEECK, SEEDO, SEEDI, SEERDY, SEEMS);
|
||||
if (have_seeprom) {
|
||||
have_seeprom = read_seeprom (iobase + SEECTL,
|
||||
(u_short *)&sc, sizeof(sc)/2, SEECS,
|
||||
SEECK, SEEDO, SEEDI, SEERDY, SEEMS);
|
||||
(u_short *)&sc, ahc->flags & AHC_CHNLB,
|
||||
sizeof(sc)/2, SEECS, SEECK, SEEDO,
|
||||
SEEDI, SEERDY, SEEMS);
|
||||
release_seeprom (iobase + SEECTL, SEECS, SEECK,
|
||||
SEEDO, SEEDI, SEERDY, SEEMS);
|
||||
if (have_seeprom) {
|
||||
@ -1831,7 +1843,8 @@ ahc_init(unit)
|
||||
have_seeprom = 0;
|
||||
}
|
||||
else {
|
||||
printf("done.\n");
|
||||
if(bootverbose)
|
||||
printf("done.\n");
|
||||
host_id = (sc.brtime_id & CFSCSIID);
|
||||
}
|
||||
}
|
||||
@ -1843,18 +1856,16 @@ ahc_init(unit)
|
||||
}
|
||||
}
|
||||
ahc->maxscbs = 0x10;
|
||||
if(ahc->type == AHC_AIC7850){
|
||||
if(ahc->type == AHC_394)
|
||||
printf("ahc%d: 3940 ", unit);
|
||||
else if(ahc->type == AHC_294)
|
||||
printf("ahc%d: 2940 ", unit);
|
||||
else if(ahc->type == AHC_AIC7850){
|
||||
printf("ahc%d: aic7850 ", unit);
|
||||
ahc->maxscbs = 0x03;
|
||||
}
|
||||
else if(ahc->type == AHC_AIC7870)
|
||||
printf("ahc%d: aic7870 ", unit);
|
||||
else if(ahc->type == AHC_394){
|
||||
printf("ahc%d: 3940 ", unit);
|
||||
/* XXX Test this! ahc->maxscbs = 0xff; */
|
||||
}
|
||||
else
|
||||
printf("ahc%d: 2940 ", unit);
|
||||
printf("ahc%d: aic7870 ", unit);
|
||||
outb(DSPCISTATUS + iobase, 0xc0 /* DFTHRSH == 100% */);
|
||||
/*
|
||||
* XXX Use SCSI ID from SEEPROM if we have it; otherwise
|
||||
@ -1871,12 +1882,22 @@ ahc_init(unit)
|
||||
switch ( (sblkctl = inb(SBLKCTL + iobase) & 0x0a) ) {
|
||||
case 0:
|
||||
ahc->our_id = (inb(HA_SCSICONF + iobase) & HSCSIID);
|
||||
printf("Single Channel, SCSI Id=%d, ", ahc->our_id);
|
||||
if(ahc->type == AHC_394)
|
||||
printf("Channel %c, SCSI Id=%d, ",
|
||||
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
||||
ahc->our_id);
|
||||
else
|
||||
printf("Single Channel, SCSI Id=%d, ", ahc->our_id);
|
||||
outb(HA_FLAGS + iobase, SINGLE_BUS);
|
||||
break;
|
||||
case 2:
|
||||
ahc->our_id = (inb(HA_SCSICONF + 1 + iobase) & HWSCSIID);
|
||||
printf("Wide Channel, SCSI Id=%d, ", ahc->our_id);
|
||||
if(ahc->type == AHC_394)
|
||||
printf("Wide Channel %c, SCSI Id=%d, ",
|
||||
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
||||
ahc->our_id);
|
||||
else
|
||||
printf("Wide Channel, SCSI Id=%d, ", ahc->our_id);
|
||||
ahc->type |= AHC_WIDE;
|
||||
outb(HA_FLAGS + iobase, WIDE_BUS);
|
||||
break;
|
||||
@ -1930,9 +1951,27 @@ ahc_init(unit)
|
||||
printf("aic7850, ");
|
||||
else
|
||||
printf("aic7870, ");
|
||||
if(ahc->flags & AHC_EXTSCB) {
|
||||
/*
|
||||
* This adapter has external SCB memory.
|
||||
* Walk the SCBs to determine how many there are.
|
||||
*/
|
||||
for(i = 0; i < AHC_SCB_MAX; i++) {
|
||||
outb(SCBPTR + iobase, i);
|
||||
outb(SCBARRAY + iobase, 0xaa);
|
||||
if(inb(SCBARRAY + iobase) == 0xaa){
|
||||
outb(SCBARRAY + iobase, 0x55);
|
||||
if(inb(SCBARRAY + iobase) == 0x55) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
ahc->maxscbs = i;
|
||||
}
|
||||
printf("%d SCBs\n", ahc->maxscbs);
|
||||
|
||||
if(!(ahc->type & AHC_AIC78X0)) {
|
||||
if(!(ahc->type & AHC_AIC78X0) && bootverbose) {
|
||||
if(ahc->pause & IRQMS)
|
||||
printf("ahc%d: Using Level Sensitive Interrupts\n",
|
||||
unit);
|
||||
@ -1942,7 +1981,7 @@ ahc_init(unit)
|
||||
}
|
||||
if(!(ahc->type & AHC_AIC78X0)){
|
||||
/*
|
||||
* The 294x cards are PCI, so we get their interrupt from the PCI
|
||||
* The AIC78X0 cards are PCI, so we get their interrupt from the PCI
|
||||
* BIOS.
|
||||
*/
|
||||
|
||||
@ -1986,7 +2025,7 @@ ahc_init(unit)
|
||||
|
||||
/* Reset the bus */
|
||||
outb(SCSISEQ + iobase, SCSIRSTO);
|
||||
DELAY(10000);
|
||||
DELAY(1000);
|
||||
outb(SCSISEQ + iobase, 0);
|
||||
|
||||
/* Select Channel A */
|
||||
@ -1999,7 +2038,7 @@ ahc_init(unit)
|
||||
|
||||
/* Reset the bus */
|
||||
outb(SCSISEQ + iobase, SCSIRSTO);
|
||||
DELAY(10000);
|
||||
DELAY(1000);
|
||||
outb(SCSISEQ + iobase, 0);
|
||||
|
||||
/*
|
||||
@ -2026,9 +2065,9 @@ ahc_init(unit)
|
||||
ahc->discenable = ~(inw(HA_DISC_DSB + iobase));
|
||||
|
||||
if(!(ahc->type & AHC_WIDE))
|
||||
max_targ = 8;
|
||||
max_targ = 7;
|
||||
|
||||
for(i = 0; i < max_targ; i++){
|
||||
for(i = 0; i <= max_targ; i++){
|
||||
u_char target_settings;
|
||||
if (have_seeprom) {
|
||||
target_settings = (sc.device_flags[i] & CFXFER) << 4;
|
||||
@ -2113,9 +2152,11 @@ ahc_init(unit)
|
||||
* difference when doing many small block transfers.
|
||||
*/
|
||||
|
||||
printf("ahc%d: Downloading Sequencer Program...", unit);
|
||||
if(bootverbose)
|
||||
printf("ahc%d: Downloading Sequencer Program...", unit);
|
||||
ahc_loadseq(iobase);
|
||||
printf("Done\n");
|
||||
if(bootverbose)
|
||||
printf("Done\n");
|
||||
|
||||
outb(SEQCTL + iobase, FASTMODE);
|
||||
if (!(ahc->type & AHC_AIC78X0))
|
||||
@ -2668,37 +2709,57 @@ ahc_scb_timeout(unit, ahc, scb)
|
||||
void
|
||||
ahc_timeout(void *arg1)
|
||||
{
|
||||
struct scb *scb = (struct scb *)arg1;
|
||||
int unit;
|
||||
struct ahc_data *ahc;
|
||||
int s = splbio();
|
||||
struct scb *scb = (struct scb *)arg1;
|
||||
int unit;
|
||||
struct ahc_data *ahc;
|
||||
int s, h;
|
||||
s = splbio();
|
||||
|
||||
unit = scb->xs->sc_link->adapter_unit;
|
||||
ahc = ahcdata[unit];
|
||||
printf("ahc%d: target %d, lun %d (%s%d) timed out\n", unit
|
||||
,scb->xs->sc_link->target
|
||||
,scb->xs->sc_link->lun
|
||||
,scb->xs->sc_link->device->name
|
||||
,scb->xs->sc_link->dev_unit);
|
||||
unit = scb->xs->sc_link->adapter_unit;
|
||||
ahc = ahcdata[unit];
|
||||
printf("ahc%d: target %d, lun %d (%s%d) timed out\n", unit
|
||||
,scb->xs->sc_link->target
|
||||
,scb->xs->sc_link->lun
|
||||
,scb->xs->sc_link->device->name
|
||||
,scb->xs->sc_link->dev_unit);
|
||||
h = splhigh();
|
||||
if(ahc->in_timeout){
|
||||
scb->next = ahc->timedout_scb;
|
||||
ahc->timedout_scb = scb;
|
||||
splx(h);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
else
|
||||
ahc->in_timeout = 1;
|
||||
splx(h);
|
||||
while(scb) {
|
||||
#ifdef SCSIDEBUG
|
||||
show_scsi_cmd(scb->xs);
|
||||
show_scsi_cmd(scb->xs);
|
||||
#endif
|
||||
#ifdef AHC_DEBUG
|
||||
if (ahc_debug & AHC_SHOWSCBS)
|
||||
ahc_print_active_scb(ahc);
|
||||
if (ahc_debug & AHC_SHOWSCBS)
|
||||
ahc_print_active_scb(ahc);
|
||||
#endif /*AHC_DEBUG */
|
||||
|
||||
/*
|
||||
* If it's immediate, don't try to abort it
|
||||
*/
|
||||
if (scb->flags & SCB_IMMED) {
|
||||
scb->xs->retries = 0; /* I MEAN IT ! */
|
||||
ahc_done(unit, scb);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
/* abort the operation that has timed out */
|
||||
ahc_scb_timeout( unit, ahc, scb );
|
||||
/*
|
||||
* If it's immediate, don't try to abort it
|
||||
*/
|
||||
if (scb->flags & SCB_IMMED) {
|
||||
scb->xs->retries = 0; /* I MEAN IT ! */
|
||||
ahc_timeout_done(unit, scb);
|
||||
}
|
||||
else {
|
||||
/* abort the operation that has timed out */
|
||||
ahc_scb_timeout( unit, ahc, scb );
|
||||
}
|
||||
h = splhigh();
|
||||
scb = ahc->timedout_scb;
|
||||
if(scb)
|
||||
ahc->timedout_scb = scb->next;
|
||||
splx(h);
|
||||
}
|
||||
ahc->in_timeout = 0;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
@ -2743,7 +2804,7 @@ ahc_reset_device(unit, ahc, target, channel, timedout_scb, xs_error)
|
||||
scbp->xs->error |= xs_error;
|
||||
if(scbp->position != timedout_scb)
|
||||
untimeout(ahc_timeout, (caddr_t)scbp);
|
||||
ahc_done (unit, scbp);
|
||||
ahc_timeout_done (unit, scbp);
|
||||
outb(SCBPTR + iobase, scbp->position);
|
||||
outb(SCBARRAY + iobase, SCB_NEEDDMA);
|
||||
i--;
|
||||
@ -2800,7 +2861,7 @@ ahc_reset_device(unit, ahc, target, channel, timedout_scb, xs_error)
|
||||
scbp->xs->error |= xs_error;
|
||||
if(scbp->position != timedout_scb)
|
||||
untimeout(ahc_timeout, (caddr_t)scbp);
|
||||
ahc_done (unit, scbp);
|
||||
ahc_timeout_done (unit, scbp);
|
||||
found++;
|
||||
}
|
||||
}
|
||||
@ -2863,7 +2924,7 @@ ahc_abort_wscb (unit, scbp, prev, iobase, timedout_scb, xs_error)
|
||||
scbp->xs->error |= xs_error;
|
||||
if(scbp->position != timedout_scb)
|
||||
untimeout(ahc_timeout, (caddr_t)scbp);
|
||||
ahc_done (unit, scbp);
|
||||
ahc_timeout_done (unit, scbp);
|
||||
return next;
|
||||
}
|
||||
|
||||
@ -2993,3 +3054,28 @@ ahc_match_scb (scb, target, channel)
|
||||
return ((chan == channel) && (targ == target));
|
||||
}
|
||||
|
||||
void
|
||||
ahc_timeout_done (unit, scbp)
|
||||
int unit;
|
||||
struct scb *scbp;
|
||||
{
|
||||
struct ahc_data *ahc = ahcdata[unit];
|
||||
struct scb **prev_scb;
|
||||
struct scb *cur_scb;
|
||||
int h;
|
||||
|
||||
h = splhigh();
|
||||
prev_scb = &ahc->timedout_scb;
|
||||
cur_scb = ahc->timedout_scb;
|
||||
|
||||
while(cur_scb) {
|
||||
if(cur_scb == scbp) {
|
||||
*prev_scb = cur_scb->next;
|
||||
break;
|
||||
}
|
||||
prev_scb = &cur_scb->next;
|
||||
cur_scb = cur_scb->next;
|
||||
}
|
||||
splx(h);
|
||||
ahc_done(unit, scbp);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* 4. Modifications may be freely made to this file if the above conditions
|
||||
* are met.
|
||||
*
|
||||
* $Id: aic7xxx.h,v 1.11 1995/07/04 21:14:45 gibbs Exp $
|
||||
* $Id: aic7xxx.h,v 1.12 1995/08/05 17:32:55 gibbs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _AIC7XXX_H_
|
||||
@ -30,13 +30,17 @@
|
||||
|
||||
#define AHC_NSEG 256 /* number of dma segments supported */
|
||||
|
||||
#define AHC_SCB_MAX 16 /*
|
||||
* Up to 16 SCBs on some types of aic7xxx based
|
||||
* boards. The aic7770 family only have 4
|
||||
#define AHC_SCB_MAX 255 /*
|
||||
* Up to 255 SCBs on some types of aic7xxx
|
||||
* based boards. The aic7870 have 16 internal
|
||||
* SCBs, but external SRAM bumps this to 255.
|
||||
* The aic7770 family have only 4, and the
|
||||
* aic7850 have only 3.
|
||||
*/
|
||||
|
||||
/* #define AHCDEBUG */
|
||||
|
||||
extern int bootverbose;
|
||||
typedef unsigned long int physaddr;
|
||||
extern int ahc_unit;
|
||||
|
||||
@ -59,6 +63,18 @@ typedef enum {
|
||||
AHC_394 = 0x840 /* Twin Channel PCI Controller */
|
||||
}ahc_type;
|
||||
|
||||
typedef enum {
|
||||
AHC_FNONE = 0x00,
|
||||
AHC_INIT = 0x01,
|
||||
AHC_RUNNING = 0x02,
|
||||
AHC_EXTSCB = 0x10, /* External SCBs present */
|
||||
AHC_CHNLB = 0x20, /*
|
||||
* Second controller on 3940
|
||||
* Also encodes the offset in the
|
||||
* SEEPROM for CHNLB info (32)
|
||||
*/
|
||||
}ahc_flag;
|
||||
|
||||
/*
|
||||
* The driver keeps up to MAX_SCB scb structures per card in memory. Only the
|
||||
* first 26 bytes of the structure are valid for the hardware, the rest used
|
||||
@ -127,12 +143,12 @@ struct scb {
|
||||
|
||||
struct ahc_data {
|
||||
ahc_type type;
|
||||
int flags;
|
||||
#define AHC_INIT 0x01
|
||||
#define AHC_RUNNING 0x02
|
||||
ahc_flag flags;
|
||||
u_long baseport;
|
||||
struct scb *scbarray[AHC_SCB_MAX]; /* Mirror boards scbarray */
|
||||
struct scb *free_scb;
|
||||
struct scb *timedout_scb;
|
||||
int in_timeout;
|
||||
int our_id; /* our scsi id */
|
||||
int our_id_b; /* B channel scsi id */
|
||||
int vect;
|
||||
@ -156,7 +172,7 @@ struct ahc_data {
|
||||
|
||||
extern struct ahc_data *ahcdata[NAHC];
|
||||
|
||||
int ahcprobe __P((int unit, u_long io_base, ahc_type type));
|
||||
int ahcprobe __P((int unit, u_long io_base, ahc_type type, ahc_flag flags));
|
||||
int ahc_attach __P((int unit));
|
||||
int ahcintr();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user