Sync Perforce IDs, add tranceiver state change support, and correct

numerous error recovery buglets.

Many thanks to Tor Egge for his assistance in diagnosing problems with
the error recovery code.

aic7xxx.c:
	Report missed bus free events using their own sequencer interrupt
	code to avoid confusion with other "bad phase" interrupts.

	Remove a delay used in debugging.  This delay could only be hit
	in certain, very extreme, error recovery scenarios.

	Handle transceiver state changes correctly.  You can now
	plug an SE device into a hot-plug LVD bus without hanging
	the controller.

	When stepping through a critical section, panic if we step
	more than a reasonable number of times.

	After a bus reset, disable bus reset interupts until we either
	our first attempt to (re)select another device, or another device
	attemps to select us.  This removes the need to busy wait in
	kernel for the scsi reset line to fall yet still ensures we
	see any reset events that impact the state of either our initiator
	or target roles.  Before this change, we had the potential of
	servicing a "storm" of reset interrupts if the reset line was
	held for a significant amount of time.

	Indicate the current sequencer address whenever we dump the
	card's state.

aic7xxx.reg:
	Transceiver state change register definitions.

	Add the missed bussfree sequencer interrupt code.

	Re-enable the scsi reset interrupt if it has been
	disabled before every attempt to (re)select a device
	and when we have been selected as a target.

	When being (re)selected, check to see if the selection
	dissappeared just after we enabled our bus free interrupt.
	If the bus has gone free again, go back to the idle loop
	and wait for another selection.

	Note two locations where we should change our behavior
	if ATN is still raised.  If ATN is raised during the
	presentation of a command complete or disconnect message,
	we should ignore the message and expect the target to put
	us in msgout phase.  We don't currently do this as it
	requires some code re-arrangement so that critical sections
	can be properly placed around our handling of these two
	events.  Otherwise, we cannot guarantee that the check of
	ATN is atomic relative to our acking of the message in
	byte (the kernel could assert ATN).

	Only set the IDENTIFY_SEEN flag after we have settled
	on the SCB for this transaction.  The kernel looks at
	this flag before assuming that SCB_TAG is valid.  This
	avoids confusion during certain types of error recovery.

	Add a critical section around findSCB.  We cannot allow
	the kernel to remove an entry from the disconnected
	list while we are traversing it.  Ditto for get_free_or_disc_scb.

aic7xxx_freebsd.c:
	Only assume that SCB_TAG is accurate if IDENTIFY_SEEN is
	set in SEQ_FLAGS.

	Fix a typo that caused us to execute some code for the
	non-SCB paging case when paging SCBs.  This only occurred
	during error recovery.
This commit is contained in:
Justin T. Gibbs 2000-11-10 20:13:41 +00:00
parent aaad27fdfe
commit 72df3c5621
10 changed files with 150 additions and 58 deletions

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx.c#9 $
* $Id: //depot/src/aic7xxx/aic7xxx.c#18 $
*
* $FreeBSD$
*/
@ -617,19 +617,23 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
u_int lastphase;
lastphase = ahc_inb(ahc, LASTPHASE);
if (lastphase == P_BUSFREE) {
printf("%s:%c:%d: Missed busfree. Curphase = 0x%x\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
ahc_inb(ahc, SCSISIGI));
restart_sequencer(ahc);
return;
} else {
printf("%s:%c:%d: unknown scsi bus phase %x. "
"Attempting to continue\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
ahc_inb(ahc, SCSISIGI));
}
break;
printf("%s:%c:%d: unknown scsi bus phase %x, "
"lastphase = 0x%x. Attempting to continue\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
lastphase, ahc_inb(ahc, SCSISIGI));
break;
}
case MISSED_BUSFREE:
{
u_int lastphase;
lastphase = ahc_inb(ahc, LASTPHASE);
printf("%s:%c:%d: Missed busfree. "
"Lastphase = 0x%x, Curphase = 0x%x\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
lastphase, ahc_inb(ahc, SCSISIGI));
restart_sequencer(ahc);
return;
}
case HOST_MSG_LOOP:
{
@ -798,7 +802,6 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
case ABORT_QINSCB:
{
printf("%s: Abort QINSCB\n", ahc_name(ahc));
DELAY(10000000);
break;
}
case NO_FREE_SCB:
@ -820,18 +823,6 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
panic("for saftey");
break;
}
case SCBPTR_MISMATCH:
{
u_int scbptr;
scbptr = ahc_inb(ahc, SCBPTR);
printf("SCBPTR wrong. SCBPTR %d, tag %d, our tag %d\n",
scbptr, ahc_inb(ahc, ARG_1),
ahc->scb_data->hscbs[scbptr].tag);
ahc_dump_card_state(ahc);
panic("for safety");
break;
}
case OUT_OF_RANGE:
{
printf("%s: BTT calculation out of range\n", ahc_name(ahc));
@ -874,6 +865,7 @@ void
ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
{
u_int scb_index;
u_int status0;
u_int status;
struct scb *scb;
char cur_channel;
@ -889,8 +881,12 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
cur_channel = 'A';
intr_channel = cur_channel;
if ((ahc->features & AHC_ULTRA2) != 0)
status0 = ahc_inb(ahc, SSTAT0) & IOERR;
else
status0 = 0;
status = ahc_inb(ahc, SSTAT1);
if (status == 0) {
if (status == 0 && status0 == 0) {
if ((ahc->features & AHC_TWIN) != 0) {
/* Try the other channel */
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
@ -912,10 +908,30 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
&& (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)
scb = NULL;
if ((status & SCSIRSTI) != 0) {
if ((ahc->features & AHC_ULTRA2) != 0
&& (status0 & IOERR) != 0) {
int now_lvd;
now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
printf("%s: Transceiver State Has Changed to %s mode\n",
ahc_name(ahc), now_lvd ? "LVD" : "SE");
ahc_outb(ahc, CLRSINT0, CLRIOERR);
/*
* When transitioning to SE mode, the reset line
* glitches, triggering an arbitration bug in some
* Ultra2 controllers. This bug is cleared when we
* assert the reset line. Since a reset glitch has
* already occurred with this transition and a
* transceiver state change is handled just like
* a bus reset anyway, asserting the reset line
* ourselves is safe.
*/
ahc_reset_channel(ahc, intr_channel,
/*Initiate Reset*/now_lvd == 0);
} else if ((status & SCSIRSTI) != 0) {
printf("%s: Someone reset channel %c\n",
ahc_name(ahc), intr_channel);
ahc_reset_channel(ahc, intr_channel, /* Initiate Reset */FALSE);
ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
} else if ((status & SCSIPERR) != 0) {
/*
* Determine the bus phase and queue an appropriate message.
@ -1157,10 +1173,12 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
}
}
#define AHC_MAX_STEPS 2000
void
ahc_clear_critical_section(struct ahc_softc *ahc)
{
int stepping;
int steps;
u_int simode0;
u_int simode1;
@ -1168,6 +1186,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
return;
stepping = FALSE;
steps = 0;
simode0 = 0;
simode1 = 0;
for (;;) {
@ -1188,6 +1207,14 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
if (i == ahc->num_critical_sections)
break;
if (steps > AHC_MAX_STEPS) {
printf("%s: Infinite loop in critical section\n",
ahc_name(ahc));
ahc_dump_card_state(ahc);
panic("critical section loop");
}
steps++;
if (stepping == FALSE) {
/*
@ -3998,6 +4025,8 @@ ahc_init(struct ahc_softc *ahc)
scsi_conf = ahc_inb(ahc, SCSICONF + 1);
ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
|term|ENSTIMER|ACTNEGEN);
if ((ahc->features & AHC_ULTRA2) != 0)
ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
@ -4017,6 +4046,8 @@ ahc_init(struct ahc_softc *ahc)
ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
|term
|ENSTIMER|ACTNEGEN);
if ((ahc->features & AHC_ULTRA2) != 0)
ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
@ -5027,7 +5058,8 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
* upsetting the current bus.
*/
ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
ahc_outb(ahc, SIMODE1,
ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));
ahc_outb(ahc, SCSISEQ,
ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
if (initiate_reset)
@ -5038,7 +5070,8 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
} else {
/* Case 2: A command from this bus is active or we're idle */
ahc_clear_msg_state(ahc);
ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
ahc_outb(ahc, SIMODE1,
ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));
ahc_outb(ahc, SCSISEQ,
ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
if (initiate_reset)
@ -5603,6 +5636,10 @@ ahc_dump_card_state(struct ahc_softc *ahc)
saved_scbptr = ahc_inb(ahc, SCBPTR);
printf("%s: Dumping Card State at SEQADDR 0x%x\n",
ahc_name(ahc),
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
printf("SCB count = %d\n", ahc->scb_data->numscbs);
/* QINFIFO */
printf("QINFIFO entries: ");

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx.h#6 $
* $Id: //depot/src/aic7xxx/aic7xxx.h#13 $
*
* $FreeBSD$
*/
@ -95,6 +95,11 @@ struct scb_platform_data;
#define BUILD_TCL(scsiid, lun) \
((lun) | (((scsiid) & TID) << 4))
#ifndef AHC_TARGET_MODE
#undef AHC_TMODE_ENABLE
#define AHC_TMODE_ENABLE 0
#endif
/**************************** Driver Constants ********************************/
/*
* The maximum number of supported targets.

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx.reg#5 $
* $Id: //depot/src/aic7xxx/aic7xxx.reg#9 $
*
* $FreeBSD$
*/
@ -250,6 +250,7 @@ register CLRSINT0 {
bit CLRSELDI 0x20
bit CLRSELINGO 0x10
bit CLRSWRAP 0x08
bit CLRIOERR 0x08 /* Ultra2 Only */
bit CLRSPIORDY 0x02
}
@ -806,11 +807,11 @@ register INTSTAT {
* without honoring our ATN
* request to issue a message.
*/
mask SCBPTR_MISMATCH 0xb0|SEQINT /*
* In the SCB paging case, our
* SCBPTR is not the same as
* we originally set prior to
* download of a new scb.
mask MISSED_BUSFREE 0xb0|SEQINT /*
* The sequencer never saw
* the bus go free after
* either a command complete
* or disconnect message.
*/
mask SCB_MISMATCH 0xc0|SEQINT /*
* Downloaded SCB's tag does

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx.seq#7 $
* $Id: //depot/src/aic7xxx/aic7xxx.seq#14 $
*
* $FreeBSD$
*/
@ -112,10 +112,6 @@ dma_queued_scb:
BEGIN_CRITICAL
cmp NEXT_QUEUED_SCB, A jne abort_qinscb;
if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
if ((ahc->flags & AHC_PAGESCBS) == 0) {
cmp SCBPTR, A je . + 2;
mvi SCBPTR_MISMATCH call set_seqint;
}
cmp SCB_TAG, A je . + 2;
mvi SCB_MISMATCH call set_seqint;
}
@ -142,6 +138,16 @@ abort_qinscb:
jmp poll_for_work_loop;
start_selection:
/*
* If bus reset interrupts have been disabled (from a previous
* reset), re-enable them now. Resets are only of interest
* when we have outstanding transactions, so we can safely
* defer re-enabling the interrupt until, as an initiator,
* we start sending out transactions again.
*/
test SIMODE1, ENSCSIRST jnz . + 3;
mvi CLRSINT1, CLRSCSIRSTI;
or SIMODE1, ENSCSIRST;
if ((ahc->features & AHC_TWIN) != 0) {
and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
test SCB_SCSIID, TWIN_CHNLB jz . + 2;
@ -195,7 +201,15 @@ selection:
mvi CLRSINT1,CLRBUSFREE;
or SIMODE1, ENBUSFREE;
/*
* Guard against a bus free after (re)selection
* but prior to enabling the busfree interrupt. SELDI
* and SELDO will be cleared in that case.
*/
test SSTAT0,SELDO jnz select_out;
test SSTAT0, SELDI jnz . + 3;
and SIMODE1, ~ENBUSFREE;
jmp poll_for_work;
mvi CLRSINT0, CLRSELDI;
select_in:
if ((ahc->flags & AHC_TARGETROLE) != 0) {
@ -207,7 +221,16 @@ select_in:
* We've just been selected. Assert BSY and
* setup the phase for receiving messages
* from the target.
*
* If bus reset interrupts have been disabled (from a
* previous reset), re-enable them now. Resets are only
* of interest when we have outstanding transactions, so
* we can safely defer re-enabling the interrupt until,
* as a target, we start receiving transactions again.
*/
test SIMODE1, ENSCSIRST jnz . + 3;
mvi CLRSINT1, CLRSCSIRSTI;
or SIMODE1, ENSCSIRST;
mvi SCSISIGO, P_MESGOUT|BSYO;
/*
@ -616,7 +639,7 @@ await_busfree:
and SXFRCTL0, ~SPIOEN;
test SSTAT1,REQINIT|BUSFREE jz .;
test SSTAT1, BUSFREE jnz poll_for_work;
mvi BAD_PHASE call set_seqint;
mvi MISSED_BUSFREE call set_seqint;
}
clear_target_state:
@ -1417,6 +1440,16 @@ mesgin_complete:
* RETURN_1 to SEND_SENSE.
*/
/*
* If ATN is raised, we still want to give the target a message.
* Perhaps there was a parity error on this last message byte.
* Either way, the target should take us to message out phase
* and then attempt to complete the command again.
* XXX - Need a critical section to do this corrctly. Wait until
* we queue completions.
test SCSISIGI, ATNI jnz mesgin_done;
*/
/*
* See if we attempted to deliver a message but the target ingnored us.
*/
@ -1469,6 +1502,16 @@ if ((ahc->flags & AHC_INITIATORROLE) != 0) {
* a reselction.
*/
mesgin_disconnect:
/*
* If ATN is raised, we still want to give the target a message.
* Perhaps there was a parity error on this last message byte
* or we want to abort this command. Either way, the target
* should take us to message out phase and then attempt to
* disconnect again.
* XXX - Wait for more testing.
test SCSISIGI, ATNI jnz mesgin_done;
*/
or SCB_CONTROL,DISCONNECTED;
if ((ahc->flags & AHC_PAGESCBS) != 0) {
call add_scb_to_disc_list;
@ -1568,7 +1611,7 @@ fetch_busy_target:
mov ARG_1, SINDIR;
cmp ARG_1, SCB_LIST_NULL je snoop_tag;
if ((ahc->flags & AHC_PAGESCBS) != 0) {
mov RETURN_1 call findSCB;
mov ARG_1 call findSCB;
} else {
mov SCBPTR, RETURN_1;
}
@ -1631,13 +1674,13 @@ setup_SCB_id_lun_okay:
}
test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;
and SCB_CONTROL,~DISCONNECTED;
mvi SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */
test SCB_CONTROL, TAG_ENB jnz setup_SCB_tagged;
mov A, SCBPTR;
mvi ARG_1, SCB_LIST_NULL;
mov SAVED_SCSIID call set_busy_target;
mov SCBPTR, A;
setup_SCB_tagged:
mvi SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */
call set_transfer_settings;
/* See if the host wants to send a message upon reconnection */
test SCB_CONTROL, MK_MESSAGE jz mesgin_done;
@ -1752,6 +1795,7 @@ assert:
* removal of the found SCB from the disconnected list.
*/
if ((ahc->flags & AHC_PAGESCBS) != 0) {
BEGIN_CRITICAL
findSCB:
mov A, SINDEX; /* Tag passed in SINDEX */
cmp DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound;
@ -1773,6 +1817,7 @@ rem_scb_from_disc_list:
mov SCBPTR, SINDEX ret;
rHead:
mov DISCONNECTED_SCBH,SCB_NEXT ret;
END_CRITICAL
findSCB_notFound:
/*
* We didn't find it. Page in the SCB.
@ -1919,7 +1964,7 @@ dma_scb_tohost:
mvi CCSCBCTL, CCSCBRESET;
bmov CCSCBRAM, SCB_BASE, SCB_UPLOAD_SIZE;
or CCSCBCTL, CCSCBEN|CCSCBRESET;
cmp CCSCBCTL, CCSCBDONE|CCSCBEN jne .;
test CCSCBCTL, CCSCBDONE jz .;
} else if ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0) {
mvi CCSCBCTL, CCARREN|CCSCBRESET;
cmp CCSCBCTL, ARRDONE|CCARREN jne .;
@ -2055,6 +2100,7 @@ END_CRITICAL
if ((ahc->flags & AHC_PAGESCBS) != 0) {
get_free_or_disc_scb:
BEGIN_CRITICAL
cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
return_error:
@ -2062,14 +2108,15 @@ return_error:
mvi SINDEX, SCB_LIST_NULL ret;
dequeue_disc_scb:
mov SCBPTR, DISCONNECTED_SCBH;
dma_up_scb:
mov DISCONNECTED_SCBH, SCB_NEXT;
END_CRITICAL
mvi DMAPARAMS, FIFORESET;
mov SCB_TAG call dma_scb;
unlink_disc_scb:
mov DISCONNECTED_SCBH, SCB_NEXT ret;
mov SCB_TAG jmp dma_scb;
BEGIN_CRITICAL
dequeue_free_scb:
mov SCBPTR, FREE_SCBH;
mov FREE_SCBH, SCB_NEXT ret;
END_CRITICAL
add_scb_to_disc_list:
/*

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.c#3 $
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.c#4 $
*
* $FreeBSD$
*/

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.h#3 $
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.h#4 $
*
* $FreeBSD$
*/

View File

@ -1502,6 +1502,7 @@ ahc_timeout(void *arg)
active_scb_index = ahc_inb(ahc, SCB_TAG);
if (last_phase != P_BUSFREE
&& (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0
&& (active_scb_index < ahc->scb_data->numscbs)) {
struct scb *active_scb;
@ -1628,7 +1629,7 @@ ahc_timeout(void *arg)
* reslection, set the MK_MESSAGE flag in
* the card's copy of the SCB.
*/
if ((ahc->flags & AHC_PAGESCBS) != 0) {
if ((ahc->flags & AHC_PAGESCBS) == 0) {
ahc_outb(ahc, SCBPTR, scb->hscb->tag);
ahc_outb(ahc, SCB_CONTROL,
ahc_inb(ahc, SCB_CONTROL)

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx_inline.h#5 $
* $Id: //depot/src/aic7xxx/aic7xxx_inline.h#10 $
*
* $FreeBSD$
*/

View File

@ -1502,6 +1502,7 @@ ahc_timeout(void *arg)
active_scb_index = ahc_inb(ahc, SCB_TAG);
if (last_phase != P_BUSFREE
&& (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0
&& (active_scb_index < ahc->scb_data->numscbs)) {
struct scb *active_scb;
@ -1628,7 +1629,7 @@ ahc_timeout(void *arg)
* reslection, set the MK_MESSAGE flag in
* the card's copy of the SCB.
*/
if ((ahc->flags & AHC_PAGESCBS) != 0) {
if ((ahc->flags & AHC_PAGESCBS) == 0) {
ahc_outb(ahc, SCBPTR, scb->hscb->tag);
ahc_outb(ahc, SCB_CONTROL,
ahc_inb(ahc, SCB_CONTROL)

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/src/aic7xxx/aic7xxx_pci.c#5 $
* $Id: //depot/src/aic7xxx/aic7xxx_pci.c#8 $
*
* $FreeBSD$
*/