mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-02 12:20:51 +00:00
Honor the CHANNEL_B_PRIMARY bit of the BIOSCTRL register and probe
channel B first as approriate. Only reset the SCSI bus if the RESET_SCSI bit of SCSICONF is set. This makes the aic7xxx driver honor all of the configuration settings availible in SCSI-Select or the ECU. Fix a benign bug in the reset code that caused us to always wait a full second after the chip reset. This should shave some time off the probe. Bug found by pedrosal@nce.ufrj.br (Pedro Salenbauch) It seems that only the top three sync rates are doubled when in ultra mode, so update the syncrates table as appropriate. Found by "Dan Willis" <dan@plutotech.com> and his SCSI bus analyzer
This commit is contained in:
parent
2f17ee3208
commit
efaafa27d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15711
@ -31,7 +31,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: aic7xxx.c,v 1.64 1996/04/23 04:47:02 gibbs Exp $
|
* $Id: aic7xxx.c,v 1.65 1996/04/28 19:21:19 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
@ -288,11 +288,11 @@ static struct {
|
|||||||
{ 0x100, 50, "20.0" },
|
{ 0x100, 50, "20.0" },
|
||||||
{ 0x110, 62, "16.0" },
|
{ 0x110, 62, "16.0" },
|
||||||
{ 0x120, 75, "13.4" },
|
{ 0x120, 75, "13.4" },
|
||||||
{ 0x130, 87, "11.4" },
|
{ 0x130, 175, "5.7" },
|
||||||
{ 0x140, 100, "10.0" },
|
{ 0x140, 200, "5.0" },
|
||||||
{ 0x150, 112, "8.8" },
|
{ 0x150, 225, "4.4" },
|
||||||
{ 0x160, 125, "8.0" },
|
{ 0x160, 250, "4.0" },
|
||||||
{ 0x170, 137, "7.2" },
|
{ 0x170, 275, "3.6" },
|
||||||
{ 0x000, 100, "10.0" },
|
{ 0x000, 100, "10.0" },
|
||||||
{ 0x010, 125, "8.0" },
|
{ 0x010, 125, "8.0" },
|
||||||
{ 0x020, 150, "6.67" },
|
{ 0x020, 150, "6.67" },
|
||||||
@ -367,16 +367,14 @@ ahc_reset(iobase)
|
|||||||
|
|
||||||
/* Retain the IRQ type accross the chip reset */
|
/* Retain the IRQ type accross the chip reset */
|
||||||
hcntrl = (inb(HCNTRL + iobase) & IRQMS) | INTEN;
|
hcntrl = (inb(HCNTRL + iobase) & IRQMS) | INTEN;
|
||||||
|
|
||||||
outb(HCNTRL + iobase, CHIPRST | PAUSE);
|
outb(HCNTRL + iobase, CHIPRST | PAUSE);
|
||||||
/*
|
/*
|
||||||
* Ensure that the reset has finished
|
* Ensure that the reset has finished
|
||||||
*/
|
*/
|
||||||
wait = 1000;
|
wait = 1000;
|
||||||
while (wait--) {
|
while (--wait && !(inb(HCNTRL + iobase) & CHIPRSTACK))
|
||||||
DELAY(1000);
|
DELAY(1000);
|
||||||
if(!(inb(HCNTRL + iobase) & CHIPRST))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(wait == 0) {
|
if(wait == 0) {
|
||||||
printf("ahc at 0x%lx: WARNING - Failed chip reset! "
|
printf("ahc at 0x%lx: WARNING - Failed chip reset! "
|
||||||
"Trying to initialize anyway.\n", iobase);
|
"Trying to initialize anyway.\n", iobase);
|
||||||
@ -405,14 +403,8 @@ ahc_scsirate(ahc, scsirate, period, offset, target )
|
|||||||
* enabled and vice-versa.
|
* enabled and vice-versa.
|
||||||
*/
|
*/
|
||||||
if (ahc->type & AHC_ULTRA) {
|
if (ahc->type & AHC_ULTRA) {
|
||||||
if (!(ahc_syncrates[i].sxfr & ULTRA_SXFR)) {
|
if (!(ahc_syncrates[i].sxfr & ULTRA_SXFR))
|
||||||
printf("ahc%d: target %d requests "
|
|
||||||
"%sMHz transfers, but adapter "
|
|
||||||
"in Ultra mode can only sync at "
|
|
||||||
"7.2MHz or above\n", ahc->unit,
|
|
||||||
target, ahc_syncrates[i].rate);
|
|
||||||
break; /* Use Async */
|
break; /* Use Async */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ahc_syncrates[i].sxfr & ULTRA_SXFR) {
|
if (ahc_syncrates[i].sxfr & ULTRA_SXFR) {
|
||||||
@ -454,7 +446,7 @@ ahc_attach(ahc)
|
|||||||
struct scsibus_data *scbus;
|
struct scsibus_data *scbus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill in the prototype scsi_link.
|
* fill in the prototype scsi_links.
|
||||||
*/
|
*/
|
||||||
ahc->sc_link.adapter_unit = ahc->unit;
|
ahc->sc_link.adapter_unit = ahc->unit;
|
||||||
ahc->sc_link.adapter_targ = ahc->our_id;
|
ahc->sc_link.adapter_targ = ahc->our_id;
|
||||||
@ -465,6 +457,14 @@ ahc_attach(ahc)
|
|||||||
ahc->sc_link.flags = DEBUGLEVEL;
|
ahc->sc_link.flags = DEBUGLEVEL;
|
||||||
ahc->sc_link.fordriver = 0;
|
ahc->sc_link.fordriver = 0;
|
||||||
|
|
||||||
|
if(ahc->type & AHC_TWIN) {
|
||||||
|
/* Configure the second scsi bus */
|
||||||
|
ahc->sc_link_b = ahc->sc_link;
|
||||||
|
ahc->sc_link_b.adapter_targ = ahc->our_id_b;
|
||||||
|
ahc->sc_link_b.adapter_bus = 1;
|
||||||
|
ahc->sc_link_b.fordriver = (void *)SELBUSB;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the scsibus_data area for the upperlevel
|
* Prepare the scsibus_data area for the upperlevel
|
||||||
* scsi code.
|
* scsi code.
|
||||||
@ -472,7 +472,8 @@ ahc_attach(ahc)
|
|||||||
scbus = scsi_alloc_bus();
|
scbus = scsi_alloc_bus();
|
||||||
if(!scbus)
|
if(!scbus)
|
||||||
return 0;
|
return 0;
|
||||||
scbus->adapter_link = &ahc->sc_link;
|
scbus->adapter_link = (ahc->flags & AHC_CHANNEL_B_PRIMARY) ?
|
||||||
|
&ahc->sc_link_b : &ahc->sc_link;
|
||||||
if(ahc->type & AHC_WIDE)
|
if(ahc->type & AHC_WIDE)
|
||||||
scbus->maxtarg = 15;
|
scbus->maxtarg = 15;
|
||||||
|
|
||||||
@ -480,23 +481,22 @@ ahc_attach(ahc)
|
|||||||
* ask the adapter what subunits are present
|
* ask the adapter what subunits are present
|
||||||
*/
|
*/
|
||||||
if(bootverbose)
|
if(bootverbose)
|
||||||
printf("ahc%d: Probing channel A\n", ahc->unit);
|
printf("ahc%d: Probing channel %c\n", ahc->unit,
|
||||||
|
(ahc->flags & AHC_CHANNEL_B_PRIMARY) ? 'B' : 'A');
|
||||||
scsi_attachdevs(scbus);
|
scsi_attachdevs(scbus);
|
||||||
scbus = NULL; /* Upper-level SCSI code owns this now */
|
scbus = NULL; /* Upper-level SCSI code owns this now */
|
||||||
|
|
||||||
if(ahc->type & AHC_TWIN) {
|
if(ahc->type & AHC_TWIN) {
|
||||||
/* Configure the second scsi bus */
|
|
||||||
ahc->sc_link_b = ahc->sc_link;
|
|
||||||
ahc->sc_link_b.adapter_targ = ahc->our_id_b;
|
|
||||||
ahc->sc_link_b.adapter_bus = 1;
|
|
||||||
ahc->sc_link_b.fordriver = (void *)SELBUSB;
|
|
||||||
scbus = scsi_alloc_bus();
|
scbus = scsi_alloc_bus();
|
||||||
if(!scbus)
|
if(!scbus)
|
||||||
return 0;
|
return 0;
|
||||||
scbus->adapter_link = &ahc->sc_link_b;
|
scbus->adapter_link = (ahc->flags & AHC_CHANNEL_B_PRIMARY) ?
|
||||||
|
&ahc->sc_link : &ahc->sc_link_b;
|
||||||
if(ahc->type & AHC_WIDE)
|
if(ahc->type & AHC_WIDE)
|
||||||
scbus->maxtarg = 15;
|
scbus->maxtarg = 15;
|
||||||
if(bootverbose)
|
if(bootverbose)
|
||||||
printf("ahc%d: Probing Channel B\n", ahc->unit);
|
printf("ahc%d: Probing Channel %c\n", ahc->unit,
|
||||||
|
(ahc->flags & AHC_CHANNEL_B_PRIMARY) ? 'A': 'B');
|
||||||
scsi_attachdevs(scbus);
|
scsi_attachdevs(scbus);
|
||||||
scbus = NULL; /* Upper-level SCSI code owns this now */
|
scbus = NULL; /* Upper-level SCSI code owns this now */
|
||||||
}
|
}
|
||||||
@ -798,6 +798,9 @@ ahc_intr(arg)
|
|||||||
case NO_MATCH:
|
case NO_MATCH:
|
||||||
if(ahc->flags & AHC_PAGESCBS) {
|
if(ahc->flags & AHC_PAGESCBS) {
|
||||||
/* SCB Page-in request */
|
/* SCB Page-in request */
|
||||||
|
u_char tag;
|
||||||
|
u_char next;
|
||||||
|
u_char disc_scb;
|
||||||
struct scb *outscb;
|
struct scb *outscb;
|
||||||
u_char arg_1 = inb(ARG_1 + iobase);
|
u_char arg_1 = inb(ARG_1 + iobase);
|
||||||
if(arg_1 == SCB_LIST_NULL) {
|
if(arg_1 == SCB_LIST_NULL) {
|
||||||
@ -812,8 +815,9 @@ ahc_intr(arg)
|
|||||||
/*
|
/*
|
||||||
* Now to pick the SCB to page out.
|
* Now to pick the SCB to page out.
|
||||||
* Either take a free SCB, an assigned SCB,
|
* Either take a free SCB, an assigned SCB,
|
||||||
* an SCB that just completed or the first
|
* an SCB that just completed, the first
|
||||||
* one on the disconnected SCB list.
|
* one on the disconnected SCB list, or
|
||||||
|
* as a last resort a queued SCB.
|
||||||
*/
|
*/
|
||||||
if(ahc->free_scbs.stqh_first) {
|
if(ahc->free_scbs.stqh_first) {
|
||||||
outscb = ahc->free_scbs.stqh_first;
|
outscb = ahc->free_scbs.stqh_first;
|
||||||
@ -826,8 +830,9 @@ ahc_intr(arg)
|
|||||||
outb(SCBPTR + iobase, scb->position);
|
outb(SCBPTR + iobase, scb->position);
|
||||||
ahc_send_scb(ahc, scb);
|
ahc_send_scb(ahc, scb);
|
||||||
scb->flags &= ~SCB_PAGED_OUT;
|
scb->flags &= ~SCB_PAGED_OUT;
|
||||||
|
goto pagein_done;
|
||||||
}
|
}
|
||||||
else if(ahc->assigned_scbs.stqh_first) {
|
if(ahc->assigned_scbs.stqh_first) {
|
||||||
outscb = ahc->assigned_scbs.stqh_first;
|
outscb = ahc->assigned_scbs.stqh_first;
|
||||||
STAILQ_REMOVE_HEAD(&ahc->assigned_scbs,
|
STAILQ_REMOVE_HEAD(&ahc->assigned_scbs,
|
||||||
links);
|
links);
|
||||||
@ -839,8 +844,9 @@ ahc_intr(arg)
|
|||||||
outb(SCBPTR + iobase, scb->position);
|
outb(SCBPTR + iobase, scb->position);
|
||||||
ahc_send_scb(ahc, scb);
|
ahc_send_scb(ahc, scb);
|
||||||
scb->flags &= ~SCB_PAGED_OUT;
|
scb->flags &= ~SCB_PAGED_OUT;
|
||||||
|
goto pagein_done;
|
||||||
}
|
}
|
||||||
else if(intstat & CMDCMPLT) {
|
if(intstat & CMDCMPLT) {
|
||||||
int scb_index;
|
int scb_index;
|
||||||
|
|
||||||
printf("PIC\n");
|
printf("PIC\n");
|
||||||
@ -854,7 +860,7 @@ ahc_intr(arg)
|
|||||||
printf("ahc%d: WARNING "
|
printf("ahc%d: WARNING "
|
||||||
"no command for scb %d (cmdcmplt)\n",
|
"no command for scb %d (cmdcmplt)\n",
|
||||||
ahc->unit, scb_index );
|
ahc->unit, scb_index );
|
||||||
goto use_disconnected_scb;
|
/* Fall through in hopes of finding another SCB */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scb->position = outscb->position;
|
scb->position = outscb->position;
|
||||||
@ -864,18 +870,11 @@ ahc_intr(arg)
|
|||||||
scb->flags &= ~SCB_PAGED_OUT;
|
scb->flags &= ~SCB_PAGED_OUT;
|
||||||
untimeout(ahc_timeout, (caddr_t)outscb);
|
untimeout(ahc_timeout, (caddr_t)outscb);
|
||||||
ahc_done(ahc, outscb);
|
ahc_done(ahc, outscb);
|
||||||
|
goto pagein_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
disc_scb = inb(DISCONNECTED_SCBH + iobase);
|
||||||
u_char tag;
|
if(disc_scb != SCB_LIST_NULL) {
|
||||||
u_char next;
|
|
||||||
u_char disc_scb;
|
|
||||||
use_disconnected_scb:
|
|
||||||
disc_scb =
|
|
||||||
inb(DISCONNECTED_SCBH + iobase);
|
|
||||||
if(disc_scb == SCB_LIST_NULL)
|
|
||||||
panic("Page-in request with no "
|
|
||||||
"candidates");
|
|
||||||
outb(SCBPTR + iobase, disc_scb);
|
outb(SCBPTR + iobase, disc_scb);
|
||||||
tag = inb(SCB_TAG + iobase);
|
tag = inb(SCB_TAG + iobase);
|
||||||
outscb = ahc->scbarray[tag];
|
outscb = ahc->scbarray[tag];
|
||||||
@ -889,6 +888,52 @@ ahc_intr(arg)
|
|||||||
outb(DISCONNECTED_SCBH + iobase, next);
|
outb(DISCONNECTED_SCBH + iobase, next);
|
||||||
ahc_page_scb(ahc, outscb, scb);
|
ahc_page_scb(ahc, outscb, scb);
|
||||||
}
|
}
|
||||||
|
else if(inb(QINCNT + iobase) & ahc->qcntmask) {
|
||||||
|
/* Pull one of our queued commands as a last resort */
|
||||||
|
disc_scb = inb(QINFIFO + iobase);
|
||||||
|
outb(SCBPTR + iobase, disc_scb);
|
||||||
|
tag = inb(SCB_TAG + iobase);
|
||||||
|
outscb = ahc->scbarray[tag];
|
||||||
|
if((outscb->control & 0x23) != TAG_ENB) {
|
||||||
|
/*
|
||||||
|
* This is not a simple tagged command
|
||||||
|
* so its position in the queue
|
||||||
|
* matters. Take the command at the
|
||||||
|
* end of the queue instead.
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
int saved_queue[AHC_SCB_MAX];
|
||||||
|
int queued = inb(QINCNT + iobase) & ahc->qcntmask;
|
||||||
|
|
||||||
|
/* Count the command we removed already */
|
||||||
|
saved_queue[0] = disc_scb;
|
||||||
|
queued++;
|
||||||
|
|
||||||
|
/* Empty the input queue */
|
||||||
|
for (i = 1; i < queued; i++)
|
||||||
|
saved_queue[i] = inb(QINFIFO + iobase);
|
||||||
|
|
||||||
|
/* Put everyone back put the last entry */
|
||||||
|
queued--;
|
||||||
|
for (i = 0; i < queued; i++)
|
||||||
|
outb (QINFIFO + iobase, saved_queue[i]);
|
||||||
|
|
||||||
|
outb(SCBPTR + iobase, saved_queue[queued]);
|
||||||
|
tag = inb(SCB_TAG + iobase);
|
||||||
|
outscb = ahc->scbarray[tag];
|
||||||
|
}
|
||||||
|
untimeout(ahc_timeout, (caddr_t)outscb);
|
||||||
|
scb->position = outscb->position;
|
||||||
|
outscb->position = SCB_LIST_NULL;
|
||||||
|
STAILQ_INSERT_HEAD(&ahc->waiting_scbs,
|
||||||
|
outscb, links);
|
||||||
|
outscb->flags = SCB_WAITINGQ;
|
||||||
|
ahc_send_scb(ahc, scb);
|
||||||
|
scb->flags &= ~SCB_PAGED_OUT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
panic("Page-in request with no candidates");
|
||||||
|
pagein_done:
|
||||||
outb(RETURN_1 + iobase, SCB_PAGEDIN);
|
outb(RETURN_1 + iobase, SCB_PAGEDIN);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1645,6 +1690,7 @@ ahc_init(ahc)
|
|||||||
switch ( (sblkctl = inb(SBLKCTL + iobase) & 0x0a) ) {
|
switch ( (sblkctl = inb(SBLKCTL + iobase) & 0x0a) ) {
|
||||||
case 0:
|
case 0:
|
||||||
ahc->our_id = (inb(SCSICONF + iobase) & HSCSIID);
|
ahc->our_id = (inb(SCSICONF + iobase) & HSCSIID);
|
||||||
|
ahc->flags &= ~AHC_CHANNEL_B_PRIMARY;
|
||||||
if(ahc->type == AHC_394)
|
if(ahc->type == AHC_394)
|
||||||
printf("Channel %c, SCSI Id=%d, ",
|
printf("Channel %c, SCSI Id=%d, ",
|
||||||
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
||||||
@ -1655,6 +1701,7 @@ ahc_init(ahc)
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ahc->our_id = (inb(SCSICONF + 1 + iobase) & HWSCSIID);
|
ahc->our_id = (inb(SCSICONF + 1 + iobase) & HWSCSIID);
|
||||||
|
ahc->flags &= ~AHC_CHANNEL_B_PRIMARY;
|
||||||
if(ahc->type == AHC_394)
|
if(ahc->type == AHC_394)
|
||||||
printf("Wide Channel %c, SCSI Id=%d, ",
|
printf("Wide Channel %c, SCSI Id=%d, ",
|
||||||
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
ahc->flags & AHC_CHNLB ? 'B' : 'A',
|
||||||
@ -1733,15 +1780,46 @@ ahc_init(ahc)
|
|||||||
* so set those values first
|
* so set those values first
|
||||||
*/
|
*/
|
||||||
outb(SCSIID + iobase, ahc->our_id_b);
|
outb(SCSIID + iobase, ahc->our_id_b);
|
||||||
scsi_conf = inb(SCSICONF + 1 + iobase) & (ENSPCHK|STIMESEL);
|
scsi_conf = inb(SCSICONF + 1 + iobase);
|
||||||
outb(SXFRCTL1 + iobase, scsi_conf|ENSTIMER|ACTNEGEN|STPWEN);
|
outb(SXFRCTL1 + iobase, (scsi_conf & (ENSPCHK|STIMESEL))
|
||||||
|
| ENSTIMER|ACTNEGEN|STPWEN);
|
||||||
outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
|
outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
|
||||||
if(ahc->type & AHC_ULTRA)
|
if(ahc->type & AHC_ULTRA)
|
||||||
outb(SXFRCTL0 + iobase, DFON|SPIOEN|ULTRAEN);
|
outb(SXFRCTL0 + iobase, DFON|SPIOEN|ULTRAEN);
|
||||||
else
|
else
|
||||||
outb(SXFRCTL0 + iobase, DFON|SPIOEN);
|
outb(SXFRCTL0 + iobase, DFON|SPIOEN);
|
||||||
|
|
||||||
|
if(scsi_conf & RESET_SCSI) {
|
||||||
|
/* Reset the bus */
|
||||||
|
if(bootverbose)
|
||||||
|
printf("Reseting Channel B\n");
|
||||||
|
outb(SCSISEQ + iobase, SCSIRSTO);
|
||||||
|
DELAY(1000);
|
||||||
|
outb(SCSISEQ + iobase, 0);
|
||||||
|
|
||||||
|
/* Ensure we don't get a RSTI interrupt from this */
|
||||||
|
outb(CLRSINT1 + iobase, CLRSCSIRSTI);
|
||||||
|
outb(CLRINT + iobase, CLRSCSIINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select Channel A */
|
||||||
|
outb(SBLKCTL + iobase, 0);
|
||||||
|
}
|
||||||
|
outb(SCSIID + iobase, ahc->our_id);
|
||||||
|
scsi_conf = inb(SCSICONF + iobase);
|
||||||
|
outb(SXFRCTL1 + iobase, (scsi_conf & (ENSPCHK|STIMESEL))
|
||||||
|
| ENSTIMER|ACTNEGEN|STPWEN);
|
||||||
|
outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
|
||||||
|
if(ahc->type & AHC_ULTRA)
|
||||||
|
outb(SXFRCTL0 + iobase, DFON|SPIOEN|ULTRAEN);
|
||||||
|
else
|
||||||
|
outb(SXFRCTL0 + iobase, DFON|SPIOEN);
|
||||||
|
|
||||||
|
if(scsi_conf & RESET_SCSI) {
|
||||||
/* Reset the bus */
|
/* Reset the bus */
|
||||||
|
if(bootverbose)
|
||||||
|
printf("Reseting Channel A\n");
|
||||||
|
|
||||||
outb(SCSISEQ + iobase, SCSIRSTO);
|
outb(SCSISEQ + iobase, SCSIRSTO);
|
||||||
DELAY(1000);
|
DELAY(1000);
|
||||||
outb(SCSISEQ + iobase, 0);
|
outb(SCSISEQ + iobase, 0);
|
||||||
@ -1749,27 +1827,7 @@ ahc_init(ahc)
|
|||||||
/* Ensure we don't get a RSTI interrupt from this */
|
/* Ensure we don't get a RSTI interrupt from this */
|
||||||
outb(CLRSINT1 + iobase, CLRSCSIRSTI);
|
outb(CLRSINT1 + iobase, CLRSCSIRSTI);
|
||||||
outb(CLRINT + iobase, CLRSCSIINT);
|
outb(CLRINT + iobase, CLRSCSIINT);
|
||||||
|
|
||||||
/* Select Channel A */
|
|
||||||
outb(SBLKCTL + iobase, 0);
|
|
||||||
}
|
}
|
||||||
outb(SCSIID + iobase, ahc->our_id);
|
|
||||||
scsi_conf = inb(SCSICONF + iobase) & (ENSPCHK|STIMESEL);
|
|
||||||
outb(SXFRCTL1 + iobase, scsi_conf|ENSTIMER|ACTNEGEN|STPWEN);
|
|
||||||
outb(SIMODE1 + iobase, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
|
|
||||||
if(ahc->type & AHC_ULTRA)
|
|
||||||
outb(SXFRCTL0 + iobase, DFON|SPIOEN|ULTRAEN);
|
|
||||||
else
|
|
||||||
outb(SXFRCTL0 + iobase, DFON|SPIOEN);
|
|
||||||
|
|
||||||
/* Reset the bus */
|
|
||||||
outb(SCSISEQ + iobase, SCSIRSTO);
|
|
||||||
DELAY(1000);
|
|
||||||
outb(SCSISEQ + iobase, 0);
|
|
||||||
|
|
||||||
/* Ensure we don't get a RSTI interrupt from this */
|
|
||||||
outb(CLRSINT1 + iobase, CLRSCSIRSTI);
|
|
||||||
outb(CLRINT + iobase, CLRSCSIINT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look at the information that board initialization or
|
* Look at the information that board initialization or
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: aic7xxx.h,v 1.25 1996/04/20 21:29:27 gibbs Exp $
|
* $Id: aic7xxx.h,v 1.26 1996/04/28 19:21:20 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _AIC7XXX_H_
|
#ifndef _AIC7XXX_H_
|
||||||
@ -77,27 +77,47 @@ typedef enum {
|
|||||||
}ahc_type;
|
}ahc_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AHC_FNONE = 0x00,
|
AHC_FNONE = 0x00,
|
||||||
AHC_INIT = 0x01,
|
AHC_INIT = 0x01,
|
||||||
AHC_RUNNING = 0x02,
|
AHC_RUNNING = 0x02,
|
||||||
AHC_PAGESCBS = 0x04, /* Enable SCB paging */
|
AHC_PAGESCBS = 0x04, /* Enable SCB paging */
|
||||||
AHC_USEDEFAULTS = 0x10, /*
|
AHC_CHANNEL_B_PRIMARY = 0x08, /*
|
||||||
|
* On twin channel adapters, probe
|
||||||
|
* channel B first since it is the
|
||||||
|
* primary bus.
|
||||||
|
*/
|
||||||
|
AHC_USEDEFAULTS = 0x10, /*
|
||||||
* For cards without an seeprom
|
* For cards without an seeprom
|
||||||
* or a BIOS to initialize the chip's
|
* or a BIOS to initialize the chip's
|
||||||
* SRAM, we use the default chip and
|
* SRAM, we use the default target
|
||||||
* target settings.
|
* settings.
|
||||||
*/
|
*/
|
||||||
AHC_CHNLB = 0x20, /*
|
AHC_CHNLB = 0x20, /*
|
||||||
* Second controller on 3940
|
* Second controller on 3940
|
||||||
* Also encodes the offset in the
|
* Also encodes the offset in the
|
||||||
* SEEPROM for CHNLB info (32)
|
* SEEPROM for CHNLB info (32)
|
||||||
*/
|
*/
|
||||||
}ahc_flag;
|
}ahc_flag;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCB_FREE = 0x000,
|
||||||
|
SCB_ACTIVE = 0x001,
|
||||||
|
SCB_ABORTED = 0x002,
|
||||||
|
SCB_DEVICE_RESET = 0x004,
|
||||||
|
SCB_IMMED = 0x008,
|
||||||
|
SCB_SENSE = 0x010,
|
||||||
|
SCB_TIMEDOUT = 0x020,
|
||||||
|
SCB_QUEUED_FOR_DONE = 0x040,
|
||||||
|
SCB_PAGED_OUT = 0x080,
|
||||||
|
SCB_WAITINGQ = 0x100,
|
||||||
|
SCB_ASSIGNEDQ = 0x200,
|
||||||
|
SCB_SENTORDEREDTAG = 0x400
|
||||||
|
}scb_flag;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The driver keeps up to MAX_SCB scb structures per card in memory. Only the
|
* The driver keeps up to MAX_SCB scb structures per card in memory. Only the
|
||||||
* first 26 bytes of the structure need to be transfered to the card during
|
* first 28 bytes of the structure need to be transfered to the card during
|
||||||
* normal operation. The fields starting at byte 32 are used for kernel level
|
* normal operation. The fields starting at byte 28 are used for kernel level
|
||||||
* bookkeeping.
|
* bookkeeping.
|
||||||
*/
|
*/
|
||||||
struct scb {
|
struct scb {
|
||||||
@ -131,19 +151,7 @@ struct scb {
|
|||||||
/*-----------------end of hardware supported fields----------------*/
|
/*-----------------end of hardware supported fields----------------*/
|
||||||
STAILQ_ENTRY(scb) links; /* for chaining */
|
STAILQ_ENTRY(scb) links; /* for chaining */
|
||||||
struct scsi_xfer *xs; /* the scsi_xfer for this cmd */
|
struct scsi_xfer *xs; /* the scsi_xfer for this cmd */
|
||||||
int flags;
|
scb_flag flags;
|
||||||
#define SCB_FREE 0x000
|
|
||||||
#define SCB_ACTIVE 0x001
|
|
||||||
#define SCB_ABORTED 0x002
|
|
||||||
#define SCB_DEVICE_RESET 0x004
|
|
||||||
#define SCB_IMMED 0x008
|
|
||||||
#define SCB_SENSE 0x010
|
|
||||||
#define SCB_TIMEDOUT 0x020
|
|
||||||
#define SCB_QUEUED_FOR_DONE 0x040
|
|
||||||
#define SCB_PAGED_OUT 0x080
|
|
||||||
#define SCB_WAITINGQ 0x100
|
|
||||||
#define SCB_ASSIGNEDQ 0x200
|
|
||||||
#define SCB_SENTORDEREDTAG 0x400
|
|
||||||
u_char position; /* Position in card's scbarray */
|
u_char position; /* Position in card's scbarray */
|
||||||
struct ahc_dma_seg ahc_dma[AHC_NSEG] __attribute__ ((packed));
|
struct ahc_dma_seg ahc_dma[AHC_NSEG] __attribute__ ((packed));
|
||||||
struct scsi_sense sense_cmd; /* SCSI command block */
|
struct scsi_sense sense_cmd; /* SCSI command block */
|
||||||
|
Loading…
Reference in New Issue
Block a user