summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq716
-rw-r--r--sys/dev/aic7xxx/aic7xxx_reg.h125
2 files changed, 485 insertions, 356 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index f67069d..cbdd497 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -39,7 +39,7 @@
*
*-M************************************************************************/
-VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.42 1996/06/09 17:29:11 gibbs Exp $"
+VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.42.2.2 1996/10/06 01:24:09 gibbs Exp $"
#if defined(__NetBSD__)
#include "../../../../dev/ic/aic7xxxreg.h"
@@ -57,7 +57,9 @@ VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.42 1996/06/09 17:29:11 gibbs Exp $
*/
A = ACCUM
-/* After starting the selection hardware, we check for reconnecting targets
+/*
+ * A few words on the waiting SCB list:
+ * After starting the selection hardware, we check for reconnecting targets
* as well as for our selection to complete just in case the reselection wins
* bus arbitration. The problem with this is that we must keep track of the
* SCB that we've already pulled from the QINFIFO and started the selection
@@ -66,10 +68,11 @@ A = ACCUM
* in scratch ram since a reconnecting target can request sense and this will
* create yet another SCB waiting for selection. The solution used here is to
* use byte 27 of the SCB as a psuedo-next pointer and to thread a list
- * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB offsets,
- * SCB_LIST_NULL is 0xff which is out of range. The kernel driver must
- * add an entry to this list everytime a request sense occurs. The sequencer
- * will automatically consume the entries.
+ * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes,
+ * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to
+ * this list everytime a request sense occurs or after completing a non-tagged
+ * command for which a second SCB has been queued. The sequencer will
+ * automatically consume the entries.
*/
/*
@@ -83,7 +86,7 @@ reset:
* We jump to start after every bus free.
*/
start:
- and FLAGS,0x0f /* clear target specific flags */
+ and FLAGS,0x07 /* clear target specific flags */
mvi SCSISEQ,ENRSELI /* Always allow reselection */
clr SCSIRATE /*
* We don't know the target we will
@@ -103,65 +106,88 @@ poll_for_work:
xor SBLKCTL,SELBUSB /* Toggle to the original bus */
start2:
test SSTAT0,SELDI jnz reselect
- cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting
+ cmp WAITING_SCBH,SCB_LIST_NULL je test_queue
+start_waiting:
+ /*
+ * Pull the first entry off of the waiting SCB list
+ * We don't have to "test_busy" because only transactions that
+ * have passed that test can be in the WAITING_SCB list.
+ */
+ mov SCBPTR,WAITING_SCBH
+ jmp start_scb2
+test_queue:
+ /* Has the driver posted any work for us? */
mov A, QCNTMASK
test QINCNT,A jz poll_for_work
/*
* We have at least one queued SCB now and we don't have any
- * SCBs in the list of SCBs awaiting selection. Set the SCB
- * pointer from the FIFO so we see the right bank of SCB
- * registers.
+ * SCBs in the list of SCBs awaiting selection. If we have
+ * any SCBs availible for use, pull the tag from the QINFIFO
+ * and get to work on it.
*/
- mov SCBPTR,QINFIFO
+ test FLAGS, PAGESCBS jz dequeue_scb
+ call get_free_or_disc_scb
+ cmp SINDEX, SCB_LIST_NULL je poll_for_work
+dequeue_scb:
+ mov CUR_SCBID,QINFIFO
+ test FLAGS, PAGESCBS jnz dma_queued_scb
+ /* In the non-paging case, the SCBID == hardware SCB index */
+ mov SCBPTR, CUR_SCBID
+dma_queued_scb:
+/*
+ * DMA the SCB from host ram into the current SCB location.
+ */
+ mvi DMAPARAMS, 0xd /* HDMAEN|DIRECTION|FIFORESET */
+ mov CUR_SCBID call dma_scb
/*
* See if there is not already an active SCB for this target. This code
* locks out on a per target basis instead of target/lun. Although this
* is not ideal for devices that have multiple luns active at the same
* time, it is faster than looping through all SCB's looking for active
- * commands. It may be benificial to make findscb a more general procedure
- * to see if the added cost of the search is negligible. This code also
- * assumes that the kernel driver will clear the active flags on board
- * initialization, board reset, and a target SELTO. Tagged commands
- * don't set the active bits since you can queue more than one command
- * at a time. We do, however, look to see if there are any non-tagged
- * I/Os in progress, and requeue the command if there are. Tagged and
- * non-tagged commands cannot be mixed to a single target.
+ * commands. We also don't have enough spare SCB space for to store the
+ * SCBID of the currently busy transaction for each target/lun making it
+ * impossible to link up the SCBs.
*/
-
test_busy:
- mov FUNCTION1,SCB_TCL
- mov A,FUNCTION1
- test SCB_TCL,0x88 jz test_a /* Id < 8 && A channel */
-
- test ACTIVE_B,A jnz requeue
- test SCB_CONTROL,TAG_ENB jnz start_scb
- /* Mark the current target as busy */
- or ACTIVE_B,A
- jmp start_scb
-
-/* Place the currently active SCB back on the queue for later processing */
-requeue:
- mov QINFIFO, SCBPTR
+ test SCB_CONTROL, TAG_ENB jnz start_scb
+ mov SAVED_SCBPTR, SCBPTR
+ call index_untagged_scb
+ mov ARG_1, SINDIR /*
+ * ARG_1 should
+ * now have the SCB ID of
+ * any active, non-tagged,
+ * command for this target.
+ */
+ cmp ARG_1, SCB_LIST_NULL je make_busy
+ test FLAGS, PAGESCBS jz simple_busy_link
+ /*
+ * Put this SCB back onto the free list. It
+ * may be necessary to satisfy the search for
+ * the active SCB.
+ */
+ call add_scb_to_free_list
+ /* Find the active SCB */
+ mov ALLZEROS call findSCB
+ /* Link us in */
+ mov SCB_LINKED_NEXT, CUR_SCBID
+ /* Put it back on the disconnected list */
+ call add_scb_to_disc_list
jmp poll_for_work
-
-/*
- * Pull the first entry off of the waiting for selection list
- * We don't have to "test_busy" because only transactions that
- * have passed that test can be in the waiting_scb list.
- */
-start_waiting:
- mov SCBPTR,WAITING_SCBH
- jmp start_scb2
-
-test_a:
- test ACTIVE_A,A jnz requeue
- test SCB_CONTROL,TAG_ENB jnz start_scb
- /* Mark the current target as busy */
- or ACTIVE_A,A
+simple_busy_link:
+ mov SCBPTR, ARG_1
+ mov SCB_LINKED_NEXT, CUR_SCBID
+ jmp poll_for_work
+make_busy:
+ mov DINDIR, CUR_SCBID
+ mov SCBPTR, SAVED_SCBPTR
start_scb:
+ /*
+ * Place us on the waiting list in case our selection
+ * doesn't win during bus arbitration.
+ */
mov SCB_NEXT,WAITING_SCBH
mov WAITING_SCBH, SCBPTR
start_scb2:
@@ -190,9 +216,8 @@ start_selection:
*/
mk_identify:
- and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */
-
and MSG0,0x7,SCB_TCL /* lun */
+ and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */
or MSG0,A /* or in disconnect privledge */
or MSG0,MSG_IDENTIFYFLAG
mvi MSG_LEN, 1
@@ -203,11 +228,9 @@ mk_identify:
*/
mk_tag:
test SCB_CONTROL,TAG_ENB jz mk_message
- mvi DINDEX, MSG1
- and DINDIR,0x23,SCB_CONTROL
- mov DINDIR,SCB_TAG
-
- add MSG_LEN,COMP_MSG0,DINDEX /* update message length */
+ and MSG1,0x23,SCB_CONTROL
+ mov MSG2,SCB_TAG
+ add MSG_LEN,2 /* update message length */
/*
* Interrupt the driver, and allow it to tweak the message buffer
@@ -224,8 +247,7 @@ wait_for_selection:
/*
* Reselection has been initiated by a target. Make a note that we've been
- * reselected, but haven't seen an IDENTIFY message from the target
- * yet.
+ * reselected, but haven't seen an IDENTIFY message from the target yet.
*/
reselect:
clr MSG_LEN /* Don't have anything in the mesg buffer */
@@ -234,43 +256,51 @@ reselect:
jmp select2
/*
- * After the selection, remove this SCB from the "waiting for selection"
+ * After the selection, remove this SCB from the "waiting SCB"
* list. This is achieved by simply moving our "next" pointer into
* WAITING_SCBH. Our next pointer will be set to null the next time this
* SCB is used, so don't bother with it now.
*/
select:
mov WAITING_SCBH,SCB_NEXT
- or FLAGS,SELECTED
select2:
/*
- * Set CLRCHN here before the target has entered a data transfer mode -
- * with synchronous SCSI, if you do it later, you blow away some
- * data in the SCSI FIFO that the target has already sent to you.
- */
- or SXFRCTL0,CLRCHN
-/*
* Initialize SCSIRATE with the appropriate value for this target.
+ * The SCSIRATE settings for each target are stored in an array
+ * based at TARG_SCRATCH.
*/
- call ndx_dtr
+ndx_dtr:
+ shr A,SCSIID,4
+ test SBLKCTL,SELBUSB jz ndx_dtr_2
+ or SAVED_TCL, SELBUSB /* Add the channel bit while we're here */
+ or A,0x08 /* Channel B entries add 8 */
+ndx_dtr_2:
+ add SINDEX,TARG_SCRATCH,A
mov SCSIRATE,SINDIR
/*
- * Initialize Ultra mode setting.
+ * Initialize Ultra mode setting and clear the SCSI channel.
*/
- mov FUNCTION1,SCSIID
- mov A,FUNCTION1
- and SINDEX,0xdf,SXFRCTL0 /* default to Ultra disabled */
- test SCSIID, 0x80 jnz ultra_b /* Target ID > 7 */
- test SBLKCTL, SELBUSB jnz ultra_b /* Second channel device */
- test ULTRA_ENB,A jz set_sxfrctl0
- or SINDEX, ULTRAEN jmp set_sxfrctl0
-ultra_b:
- test ULTRA_ENB_B,A jz set_sxfrctl0
- or SINDEX, ULTRAEN
-
+ultra:
+ and DINDEX,0xdf,SXFRCTL0 /* default to Ultra disabled */
+ /*
+ * Set CLRCHN here before the target has entered a data transfer mode -
+ * with synchronous SCSI, if you do it later, you blow away some
+ * data in the SCSI FIFO that the target has already sent to you.
+ */
+ or DINDEX, CLRCHN
+ mvi SINDEX, ULTRA_ENB_B
+ test SCSIID, 0x80 jnz ultra_2 /* Target ID > 7 */
+ test SBLKCTL, SELBUSB jnz ultra_2 /* Second channel device */
+ dec SINDEX
+ultra_2:
+ mov FUNCTION1,SCSIID
+ mov A,FUNCTION1
+ test SINDIR, A jz set_sxfrctl0
+ or DINDEX, ULTRAEN
+
set_sxfrctl0:
- mov SXFRCTL0,SINDEX
+ mov SXFRCTL0,DINDEX
mvi SCSISEQ,ENAUTOATNP /*
* ATN on parity errors
@@ -326,11 +356,31 @@ p_datain:
* !DIRECTION|FIFORESET
*/
data_phase_init:
- call assert
+ call assert /*
+ * Ensure entering a data
+ * phase is okay - seen identify, etc.
+ */
test FLAGS, DPHASE jnz data_phase_reinit
- call sg_scb2ram
- or FLAGS, DPHASE /* We have seen a data phase */
+
+ /*
+ * Initialize the DMA address and counter from the SCB.
+ * Also set SG_COUNT and SG_NEXT in memory since we cannot
+ * modify the values in the SCB itself until we see a
+ * save data pointers message.
+ */
+ mvi DINDEX, HADDR0
+ mvi SCB_DATAPTR call bcopy_7
+
+ call set_stcnt_from_hcnt
+
+ mov SG_COUNT,SCB_SGCOUNT
+
+ mvi DINDEX, SG_NEXT
+ mvi SCB_SGPTR call bcopy_4
+
+ /* We have seen a data phase */
+ or FLAGS, DPHASE
data_phase_loop:
/* Guard against overruns */
@@ -347,7 +397,7 @@ data_phase_loop:
mvi STCNT2,0xff
data_phase_inbounds:
-/* If we are the last SG block, don't set wideodd. */
+/* If we are the last SG block, ensure wideodd is off. */
cmp SG_COUNT,0x01 jne data_phase_wideodd
and DMAPARAMS, 0xbf /* Turn off WIDEODD */
data_phase_wideodd:
@@ -383,67 +433,27 @@ sg_load:
clr HCNT1
mvi HCNT0,SG_SIZEOF
- mov HADDR0,SG_NEXT0
- mov HADDR1,SG_NEXT1
- mov HADDR2,SG_NEXT2
- mov HADDR3,SG_NEXT3
+ mvi DINDEX, HADDR0
+ mvi SG_NEXT0 call bcopy_4
or DFCNTRL,0xd /* HDMAEN|DIRECTION|FIFORESET */
-/*
- * Wait for DMA from host memory to data FIFO to complete, then disable
- * DMA and wait for it to acknowledge that it's off.
- */
-dma_finish:
- test DFSTATUS,HDONE jz dma_finish
- /* Turn off DMA preserving WIDEODD */
- and DFCNTRL,WIDEODD
-dma_finish2:
- test DFCNTRL,HDMAENACK jnz dma_finish2
+ call dma_finish
/*
* Copy data from FIFO into SCB data pointer and data count. This assumes
- * that the struct scatterlist has this structure (this and sizeof(struct
- * scatterlist) == 12 are asserted in aic7xxx.c for the Linux driver):
- *
- * struct scatterlist {
- * char *address; four bytes, little-endian order
- * ... four bytes, ignored
- * unsigned short length; two bytes, little-endian order
- * }
- *
+ * that the SG segments are of the form:
*
- * In FreeBSD, the scatter list entry is only 8 bytes.
- *
* struct ahc_dma_seg {
- * physaddr addr; four bytes, little-endian order
- * long len; four bytes, little endian order
+ * u_int32_t addr; four bytes, little-endian order
+ * u_int32_t len; four bytes, little endian order
* };
*/
-
- mov HADDR0,DFDAT
- mov HADDR1,DFDAT
- mov HADDR2,DFDAT
- mov HADDR3,DFDAT
-/*
- * For Linux, we must throw away four bytes since there is a 32bit gap
- * in the middle of a struct scatterlist.
- */
-#ifdef __linux__
- mov NONE,DFDAT
- mov NONE,DFDAT
- mov NONE,DFDAT
- mov NONE,DFDAT
-#endif
- mov HCNT0,DFDAT
- mov HCNT1,DFDAT
- mov HCNT2,DFDAT
+ mvi HADDR0 call dfdat_in_7
/* Load STCNT as well. It is a mirror of HCNT */
- mov STCNT0,HCNT0
- mov STCNT1,HCNT1
- mov STCNT2,HCNT2
- test SSTAT1,PHASEMIS jz data_phase_loop
+ call set_stcnt_from_hcnt
+ test SSTAT1,PHASEMIS jz data_phase_loop
data_phase_finish:
/*
@@ -474,17 +484,12 @@ p_command:
/*
* Load HADDR and HCNT.
*/
- mov HADDR0, SCB_CMDPTR0
- mov HADDR1, SCB_CMDPTR1
- mov HADDR2, SCB_CMDPTR2
- mov HADDR3, SCB_CMDPTR3
- mov HCNT0, SCB_CMDLEN
+ mvi DINDEX, HADDR0
+ mvi SCB_CMDPTR call bcopy_5
clr HCNT1
clr HCNT2
- mov STCNT0, HCNT0
- mov STCNT1, HCNT1
- mov STCNT2, HCNT2
+ call set_stcnt_from_hcnt
mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN|
# DIRECTION|FIFORESET
@@ -505,7 +510,6 @@ p_status:
p_mesgout:
test MSG_LEN, 0xff jnz p_mesgout_start
mvi MSG_NOOP call mk_mesg /* build NOP message */
-
p_mesgout_start:
/*
* Set up automatic PIO transfer from MSG0. Bit 3 in
@@ -572,12 +576,9 @@ p_mesgin:
rej_mesgin:
/*
- * We have no idea what this message in is, and there's no way
- * to pass it up to the kernel, so we issue a message reject and
- * hope for the best. Since we're now using manual PIO mode to
- * read in the message, there should no longer be a race condition
- * present when we assert ATN. In any case, rejection should be a
- * rare occurrence - signal the driver when it happens.
+ * We have no idea what this message in is, so we issue a message reject
+ * and hope for the best. In any case, rejection should be a rare
+ * occurrence - signal the driver when it happens.
*/
or SCSISIGO,ATNO /* turn on ATNO */
mvi INTSTAT,SEND_REJECT /* let driver know */
@@ -591,40 +592,38 @@ mesgin_done:
mesgin_complete:
/*
- * We got a "command complete" message, so put the SCB_TAG into QUEUEOUT,
- * and trigger a completion interrupt. Check status for non zero return
- * and interrupt driver if needed. This allows the driver to interpret
- * errors only when they occur instead of always uploading the scb. If
- * the status is SCSI_CHECK, the driver will download a new scb requesting
- * sense to replace the old one, modify the "waiting for selection" SCB list
- * and set RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE the
- * sequencer imediately jumps to main loop where it will run down the waiting
- * SCB list and process the sense request. If the kernel driver does not
- * wish to request sense, it need only clear RETURN_1, and the command is
- * allowed to complete. We don't bother to post to the QOUTFIFO in the
- * error case since it would require extra work in the kernel driver to
- * ensure that the entry was removed before the command complete code tried
- * processing it.
- *
- * First check for residuals
+ * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO,
+ * and trigger a completion interrupt. Before doing so, check to see if there
+ * is a residual or the status byte is something other than NO_ERROR (0). In
+ * either of these conditions, we upload the SCB back to the host so it can
+ * process this information. In the case of a non zero status byte, we
+ * additionally interrupt the kernel driver synchronously, allowing it to
+ * decide if sense should be retrieved. If the kernel driver wishes to request
+ * sense, it will fill the kernel SCB with a request sense command and set
+ * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload
+ * the SCB, and process it as the next command by adding it to the waiting list.
+ * If the kernel driver does not wish to request sense, it need only clear
+ * RETURN_1, and the command is allowed to complete normally. We don't bother
+ * to post to the QOUTFIFO in the error cases since it would require extra
+ * work in the kernel driver to ensure that the entry was removed before the
+ * command complete code tried processing it.
*/
- test SCB_RESID_SGCNT,0xff jz check_status
+
/*
- * If we have a residual count, interrupt and tell the host. Other
- * alternatives are to pause the sequencer on all command completes (yuck),
- * dma the resid directly to the host (slick, we may have space to do it now)
- * or have the sequencer pause itself when it encounters a non-zero resid
- * (unecessary pause just to flag the command -yuck-, but takes one instruction
- * and since it shouldn't happen that often is good enough for our purposes).
+ * First check for residuals
*/
-resid:
- mvi INTSTAT,RESIDUAL
-
-check_status:
+ test SCB_RESID_SGCNT,0xff jnz upload_scb
test SCB_TARGET_STATUS,0xff jz status_ok /* Good Status? */
+upload_scb:
+ mvi DMAPARAMS, 0x9 /* HDMAEN | FIFORESET*/
+ mov SCB_TAG call dma_scb
+check_status:
+ test SCB_TARGET_STATUS,0xff jz status_ok /* Just a residual? */
mvi INTSTAT,BAD_STATUS /* let driver know */
cmp RETURN_1, SEND_SENSE jne status_ok
- jmp mesgin_done
+ /* This SCB becomes the next to execute as it will retrieve sense */
+ mov SCB_LINKED_NEXT, SCB_TAG
+ jmp dma_next_scb
status_ok:
/* First, mark this target as free. */
@@ -633,14 +632,11 @@ status_ok:
* don't busy the
* target.
*/
- mov FUNCTION1,SCB_TCL
- mov A,FUNCTION1
- test SCB_TCL,0x88 jz clear_a
- xor ACTIVE_B,A
- jmp test_immediate
-
-clear_a:
- xor ACTIVE_A,A
+ mov SAVED_SCBPTR, SCBPTR
+ mov SAVED_LINKPTR, SCB_LINKED_NEXT
+ call index_untagged_scb
+ mov DINDIR, SAVED_LINKPTR
+ mov SCBPTR, SAVED_SCBPTR
test_immediate:
test SCB_CMDLEN,0xff jnz complete /* Immediate message complete */
@@ -650,12 +646,33 @@ test_immediate:
* with the completion of this command can occur.
*/
mvi INTSTAT,IMMEDDONE
- jmp start
+ jmp dma_next_scb
complete:
+ test FLAGS, PAGESCBS jz complete_post
+ /* Wait for a free slot - we may need to wait only in the paging case */
+ mov A, QOUTCNT
+ cmp QFULLCNT, A je complete
+complete_post:
+ /* Post the SCB and issue an interrupt */
mov QOUTFIFO,SCB_TAG
mvi INTSTAT,CMDCMPLT
- jmp mesgin_done
+dma_next_scb:
+ cmp SCB_LINKED_NEXT, SCB_LIST_NULL je mesgin_done
+ test FLAGS, PAGESCBS jnz dma_next_scb2
+ /* Only DMA on top of ourselves if we are the SCB to download */
+ mov A, SCB_LINKED_NEXT
+ cmp SCB_TAG, A je dma_next_scb2
+ mov SCBPTR, A
+ jmp add_to_waiting_list
+dma_next_scb2:
+ mvi DMAPARAMS, 0xd /* HDMAEN|DIRECTION|FIFORESET */
+ mov SCB_TAG call dma_scb
+add_to_waiting_list:
+ mov SCB_NEXT,WAITING_SCBH
+ mov WAITING_SCBH, SCBPTR
+ or FLAGS, SCB_LISTED
+ jmp mesgin_done
/*
* Is it an extended message? Copy the message to our message buffer and
@@ -665,26 +682,14 @@ complete:
*/
mesgin_extended:
mvi MSGIN_EXT_LEN call inb_next
- mvi MSGIN_EXT_OPCODE call inb_next
mov A, MSGIN_EXT_LEN
- dec A /* Length counts the op code */
- mvi SINDEX, MSGIN_EXT_BYTE0
mesgin_extended_loop:
- test A, 0xFF jz mesgin_extended_intr
- cmp SINDEX, MSGIN_EXT_LASTBYTE je mesgin_extended_dump
- call inb_next
- dec A
-/*
- * We pass the arg to inb in SINDEX, but DINDEX is the one incremented
- * so update SINDEX with DINDEX's value before looping again.
- */
- mov DINDEX jmp mesgin_extended_loop
-mesgin_extended_dump:
-/* We have no more storage space, so dump the rest */
- test A, 0xFF jz mesgin_extended_intr
- mvi NONE call inb_next
+ mov DINDEX call inb_next
dec A
- jmp mesgin_extended_dump
+ cmp DINDEX, MSGIN_EXT_LASTBYTE jne mesgin_extended_loop_test
+ dec DINDEX /* dump by repeatedly filling the last byte */
+mesgin_extended_loop_test:
+ test A, 0xFF jnz mesgin_extended_loop
mesgin_extended_intr:
mvi INTSTAT,EXTENDED_MSG /* let driver know */
cmp RETURN_1,SEND_REJ je rej_mesgin
@@ -700,29 +705,34 @@ mesgin_extended_intr:
mesgin_disconnect:
or SCB_CONTROL,DISCONNECTED
test FLAGS, PAGESCBS jz mesgin_done
-/*
- * Link this SCB into the DISCONNECTED list. This list holds the
- * candidates for paging out an SCB if one is needed for a new command.
- * Modifying the disconnected list is a critical(pause dissabled) section.
- */
- mvi SCB_PREV, SCB_LIST_NULL
- mvi SEQCTL,0x50 /* PAUSEDIS|FASTMODE */
- mov SCB_NEXT, DISCONNECTED_SCBH
- mov DISCONNECTED_SCBH, SCBPTR
- cmp SCB_NEXT,SCB_LIST_NULL je linkdone
- mov SCBPTR,SCB_NEXT
- mov SCB_PREV,DISCONNECTED_SCBH
- mov SCBPTR,DISCONNECTED_SCBH
-linkdone:
- mvi SEQCTL,0x10 /* !PAUSEDIS|FASTMODE */
+ call add_scb_to_disc_list
+ or FLAGS, SCB_LISTED
jmp mesgin_done
/*
- * Save data pointers message? Copy working values into the SCB,
- * usually in preparation for a disconnect.
+ * Save data pointers message:
+ * Copying RAM values back to SCB, for Save Data Pointers message, but
+ * only if we've actually been into a data phase to change them. This
+ * protects against bogus data in scratch ram and the residual counts
+ * since they are only initialized when we go into data_in or data_out.
*/
mesgin_sdptrs:
- call sg_ram2scb
+ test FLAGS, DPHASE jz mesgin_done
+ mov SCB_SGCOUNT,SG_COUNT
+
+ /* The SCB SGPTR becomes the next one we'll download */
+ mvi DINDEX, SCB_SGPTR
+ mvi SG_NEXT0 call bcopy_4
+
+ /* The SCB DATAPTR0 becomes the current SHADDR */
+ mvi DINDEX, SCB_DATAPTR0
+ mvi SHADDR0 call bcopy_4
+
+/*
+ * Use the residual number since STCNT is corrupted by any message transfer.
+ */
+ mvi SCB_RESID_DCNT0 call bcopy_3
+
jmp mesgin_done
/*
@@ -745,12 +755,8 @@ mesgin_rdptrs:
*/
mesgin_identify:
test A,0x78 jnz rej_mesgin /*!DiscPriv|!LUNTAR|!Reserved*/
-
and A,0x07 /* lun in lower three bits */
- or SAVED_TCL,A,SELID
- and SAVED_TCL,0xf7
- and A,SELBUSB,SBLKCTL /* B Channel?? */
- or SAVED_TCL,A
+ or SAVED_TCL,A /* SAVED_TCL should be complete now */
call inb_last /* ACK */
/*
@@ -784,24 +790,23 @@ get_tag:
* to the reconnecting target.
*/
test FLAGS, PAGESCBS jz index_by_tag
- call inb_last /* Ack Tag */
use_findSCB:
mov ALLZEROS call findSCB /* Have to search */
setup_SCB:
and SCB_CONTROL,0xfb /* clear disconnect bit in SCB */
or FLAGS,IDENTIFY_SEEN /* make note of IDENTIFY */
+ test SCB_CONTROL,TAG_ENB jnz mesgin_done /* Ack Tag */
jmp ITloop
index_by_tag:
mov SCBPTR,ARG_1
mov A,SAVED_TCL
cmp SCB_TCL,A jne abort_tag
test SCB_CONTROL,TAG_ENB jz abort_tag
- call inb_last /* Ack Successful tag */
jmp setup_SCB
abort_tag:
or SCSISIGO,ATNO /* turn on ATNO */
- mvi INTSTAT,ABORT_TAG /* let driver know */
+abort_tag_msg:
mvi MSG_ABORT_TAG call mk_mesg /* ABORT TAG message */
jmp mesgin_done
@@ -833,6 +838,14 @@ p_busfree:
* notify the driver.
*/
test SCB_CMDLEN,0xff jz status_ok
+ test FLAGS, SCB_LISTED jnz start
+ /*
+ * This SCB didn't disconnect or have a command complete,
+ * so put it on the free queue. It was probably the
+ * result of an abort of some sort. This prevents us
+ * from "leaking" SCBs.
+ */
+ call add_scb_to_free_list
jmp start
/*
@@ -937,6 +950,7 @@ return:
*/
initialize_scsiid:
and SINDEX,0xf0 /* Get target ID */
+ mov SAVED_TCL, SINDEX /* Update the target portion of this */
and A,0x0f,SCSIID
or SINDEX,A
mov SCSIID,SINDEX ret
@@ -949,7 +963,7 @@ assert:
test FLAGS,RESELECTED jz return /* reselected? */
test FLAGS,IDENTIFY_SEEN jnz return /* seen IDENTIFY? */
- mvi INTSTAT,NO_IDENT ret /* no - cause a kernel panic */
+ mvi INTSTAT,NO_IDENT ret /* no - tell the kernel */
/*
* Locate the SCB matching the target ID/channel/lun in SAVED_TCL, and the tag
@@ -961,17 +975,42 @@ assert:
findSCB:
mov A,SAVED_TCL
mov SCBPTR,SINDEX /* switch to next SCB */
- mvi SEQCTL,0x50 /* PAUSEDIS|FASTMODE */
cmp SCB_TCL,A jne findSCB1 /* target ID/channel/lun match? */
test SCB_CONTROL,DISCONNECTED jz findSCB1 /*should be disconnected*/
test SCB_CONTROL,TAG_ENB jnz findTaggedSCB
cmp ARG_1,SCB_LIST_NULL je foundSCB
- jmp findSCB1
+findSCB1:
+ inc SINDEX
+ mov A,SCBCOUNT
+ cmp SINDEX,A jne findSCB
+/*
+ * We didn't find it. If we're paging, pull an SCB and DMA down the
+ * one we want. If we aren't paging or the SCB we dma down has the
+ * abort flag set, alert the kernel and send an abort message.
+ */
+ test FLAGS, PAGESCBS jz find_abort
+ call get_free_or_disc_scb
+ mov CUR_SCBID, ARG_1
+ cmp CUR_SCBID, SCB_LIST_NULL jne find_dma_scb
+ call index_untagged_scb
+ mov CUR_SCBID, SINDIR
+find_dma_scb:
+ mvi DMAPARAMS, 0xd /* HDMAEN|DIRECTION|FIFORESET */
+ mov CUR_SCBID call dma_scb
+ test SCB_CONTROL, ABORT_SCB jz return
+find_abort:
+ mvi INTSTAT,NO_MATCH /* not found - signal kernel */
+ or SCSISIGO,ATNO /* assert ATNO */
+ cmp ARG_1,SCB_LIST_NULL jne abort_tag_msg
+ mvi MSG_ABORT call mk_mesg
+ jmp ITloop
findTaggedSCB:
mov A, ARG_1 /* Tag passed in ARG_1 */
cmp SCB_TAG,A jne findSCB1 /* Found it? */
foundSCB:
- test FLAGS,PAGESCBS jz foundSCB_ret
+ test SCB_CONTROL, ABORT_SCB jnz find_abort
+ test FLAGS,PAGESCBS jz return
+rem_scb_from_disc_list:
/* Remove this SCB from the disconnection list */
cmp SCB_NEXT,SCB_LIST_NULL je unlink_prev
mov SAVED_LINKPTR, SCB_PREV
@@ -983,87 +1022,160 @@ unlink_prev:
mov SAVED_LINKPTR, SCB_NEXT
mov SCBPTR, SCB_PREV
mov SCB_NEXT, SAVED_LINKPTR
- mov SCBPTR, SINDEX
- mvi SEQCTL,0x10 ret /* !PAUSEDIS|FASTMODE */
+ mov SCBPTR, SINDEX ret
rHead:
- mov DISCONNECTED_SCBH,SCB_NEXT
-foundSCB_ret:
- mvi SEQCTL,0x10 ret /* !PAUSEDIS|FASTMODE */
-
-findSCB1:
- mvi SEQCTL,0x10 /* !PAUSEDIS|FASTMODE */
- inc SINDEX
- mov A,SCBCOUNT
- cmp SINDEX,A jne findSCB
+ mov DISCONNECTED_SCBH,SCB_NEXT ret
- mvi INTSTAT,NO_MATCH /* not found - signal kernel */
- cmp RETURN_1,SCB_PAGEDIN je return
- or SCSISIGO,ATNO /* assert ATNO */
- cmp ARG_1,SCB_LIST_NULL jne find_abort_tag
- mvi MSG_ABORT call mk_mesg
- jmp ITloop
-find_abort_tag:
- mvi MSG_ABORT_TAG call mk_mesg
- jmp ITloop
+set_stcnt_from_hcnt:
+ mov STCNT0, HCNT0
+ mov STCNT1, HCNT1
+ mov STCNT2, HCNT2 ret
+
+bcopy_7:
+ mov DINDIR, SINDIR
+ mov DINDIR, SINDIR
+bcopy_5:
+ mov DINDIR, SINDIR
+bcopy_4:
+ mov DINDIR, SINDIR
+bcopy_3:
+ mov DINDIR, SINDIR
+ mov DINDIR, SINDIR
+ mov DINDIR, SINDIR ret
+
+dma_scb:
+ /*
+ * SCB index is in SINDEX. Determine the physical address in
+ * the host where this SCB is located and load HADDR with it.
+ */
+ shr DINDEX, SINDEX, 3
+ shl A, SINDEX, 5
+ add HADDR0, A, HSCB_ADDR0
+ mov A, DINDEX
+ adc HADDR1, A, HSCB_ADDR1
+ clr A
+ adc HADDR2, A, HSCB_ADDR2
+ adc HADDR3, A, HSCB_ADDR3
+ /* Setup Count */
+ mvi HCNT0, 28
+ clr HCNT1
+ clr HCNT2
+ mov DFCNTRL, DMAPARAMS
+ test DMAPARAMS, DIRECTION jnz dma_scb_fromhost
+ /* Fill it with the SCB data */
+ call copy_scb_tofifo
+ mvi DFCNTRL, 0xa /* HDMAEN | FIFOFLUSH */
+dma_scb_fromhost:
+ call dma_finish
+ /* If we were putting the SCB, we are done */
+ test DMAPARAMS, DIRECTION jz return
+ mvi SCBARRAY call dfdat_in_7
+ call dfdat_in_7_continued
+ call dfdat_in_7_continued
+ jmp dfdat_in_7_continued
+dfdat_in_7:
+ mov DINDEX,SINDEX
+dfdat_in_7_continued:
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT
+ mov DINDIR,DFDAT ret
+
+copy_scb_tofifo:
+ mvi SCBARRAY call dfdat_out_7
+ call dfdat_out_7
+ call dfdat_out_7
+dfdat_out_7:
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR
+ mov DFDAT,SINDIR ret
/*
- * Make a working copy of the scatter-gather parameters from the SCB.
+ * Wait for DMA from host memory to data FIFO to complete, then disable
+ * DMA and wait for it to acknowledge that it's off.
*/
-sg_scb2ram:
- mov HADDR0, SCB_DATAPTR0
- mov HADDR1, SCB_DATAPTR1
- mov HADDR2, SCB_DATAPTR2
- mov HADDR3, SCB_DATAPTR3
- mov HCNT0, SCB_DATACNT0
- mov HCNT1, SCB_DATACNT1
- mov HCNT2, SCB_DATACNT2
-
- mov STCNT0, HCNT0
- mov STCNT1, HCNT1
- mov STCNT2, HCNT2
+dma_finish:
+ test DFSTATUS,HDONE jz dma_finish
+ /* Turn off DMA preserving WIDEODD */
+ and DFCNTRL,WIDEODD
+dma_finish2:
+ test DFCNTRL,HDMAENACK jnz dma_finish2
+ ret
- mov SG_COUNT,SCB_SGCOUNT
+index_untagged_scb:
+ shr SINDEX, SCB_TCL, 4
+ and SINDEX, 0x03 /* Bottom two bits of tid */
+ add SINDEX, SCB_ACTIVE0
+ shr A, SCB_TCL, 6 /* Target ID divided by 4 */
+ test SCB_TCL, SELBUSB jz index_untagged_scb2
+ or A, 2 /* Add 2 positions */
+index_untagged_scb2:
+ mov SCBPTR, A /*
+ * Select the SCB with this
+ * target's information.
+ */
+ mov DINDEX, SINDEX ret
- mov SG_NEXT0, SCB_SGPTR0
- mov SG_NEXT1, SCB_SGPTR1
- mov SG_NEXT2, SCB_SGPTR2
- mov SG_NEXT3, SCB_SGPTR3 ret
+get_free_or_disc_scb:
+ mov SINDEX, ALLZEROS
+ cmp FREE_SCBH, SCB_LIST_NULL jne get_free_scb
+ cmp DISCONNECTED_SCBH, SCB_LIST_NULL je return_error
+ mov SCBPTR, DISCONNECTED_SCBH
/*
- * Copying RAM values back to SCB, for Save Data Pointers message, but
- * only if we've actually been into a data phase to change them. This
- * protects against bogus data in scratch ram and the residual counts
- * since they are only initialized when we go into data_in or data_out.
+ * If we are starting a new transaction, we have to ensure that
+ * there is at least one SCB left in case a reselection wins out.
*/
-sg_ram2scb:
- test FLAGS, DPHASE jz return
- mov SCB_SGCOUNT,SG_COUNT
-
- mov SCB_SGPTR0,SG_NEXT0
- mov SCB_SGPTR1,SG_NEXT1
- mov SCB_SGPTR2,SG_NEXT2
- mov SCB_SGPTR3,SG_NEXT3
-
- mov SCB_DATAPTR0,SHADDR0
- mov SCB_DATAPTR1,SHADDR1
- mov SCB_DATAPTR2,SHADDR2
- mov SCB_DATAPTR3,SHADDR3
-
+ test FLAGS, RESELECTED jnz dequeue_disc_scb
+ cmp SCB_NEXT, SCB_LIST_NULL je return_error
+dequeue_disc_scb:
/*
- * Use the residual number since STCNT is corrupted by any message transfer
+ * If we have a residual, then we are in the middle of some I/O
+ * and we have to send this SCB back up to the kernel so that the
+ * saved data pointers and residual information isn't lost.
*/
- mov SCB_DATACNT0,SCB_RESID_DCNT0
- mov SCB_DATACNT1,SCB_RESID_DCNT1
- mov SCB_DATACNT2,SCB_RESID_DCNT2 ret
+ test SCB_RESID_SGCNT,0xff jz unlink_disc_scb
+ mvi DMAPARAMS, 0x9 /* HDMAEN | FIFORESET*/
+ mov SCB_TAG call dma_scb
+unlink_disc_scb:
+ call rem_scb_from_disc_list
+ ret
+get_free_scb:
+/*
+ * If we are starting a new transaction, we have to ensure that
+ * there is at least one SCB left in case a reselection wins out.
+ */
+ test FLAGS, RESELECTED jnz dequeue_free_scb
+ cmp SCB_NEXT, SCB_LIST_NULL jne dequeue_free_scb
+ cmp DISCONNECTED_SCBH, SCB_LIST_NULL je return_error
+dequeue_free_scb:
+ mov SCBPTR, FREE_SCBH
+ mov FREE_SCBH, SCB_NEXT ret
+return_error:
+ mvi SINDEX, SCB_LIST_NULL ret
+
+add_scb_to_free_list:
+ mov SCB_NEXT, FREE_SCBH
+ mov FREE_SCBH, SCBPTR ret
+add_scb_to_disc_list:
/*
- * Add the array base TARG_SCRATCH to the target offset (the target address
- * is in SCSIID), and return the result in SINDEX. The accumulator
- * contains the 3->8 decoding of the target ID on return.
+ * Link this SCB into the DISCONNECTED list. This list holds the
+ * candidates for paging out an SCB if one is needed for a new command.
+ * Modifying the disconnected list is a critical(pause dissabled) section.
*/
-ndx_dtr:
- shr A,SCSIID,4
- test SBLKCTL,SELBUSB jz ndx_dtr_2
- or A,0x08 /* Channel B entries add 8 */
-ndx_dtr_2:
- add SINDEX,TARG_SCRATCH,A ret
+ mvi SCB_PREV, SCB_LIST_NULL
+ mov SCB_NEXT, DISCONNECTED_SCBH
+ mov DISCONNECTED_SCBH, SCBPTR
+ cmp SCB_NEXT,SCB_LIST_NULL je return
+ mov SCBPTR,SCB_NEXT
+ mov SCB_PREV,DISCONNECTED_SCBH
+ mov SCBPTR,DISCONNECTED_SCBH ret
+
diff --git a/sys/dev/aic7xxx/aic7xxx_reg.h b/sys/dev/aic7xxx/aic7xxx_reg.h
index c4c9ad4..c48a49a 100644
--- a/sys/dev/aic7xxx/aic7xxx_reg.h
+++ b/sys/dev/aic7xxx/aic7xxx_reg.h
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx_reg.h,v 1.12 1996/06/09 17:29:12 gibbs Exp $
+ * $Id: aic7xxx_reg.h,v 1.12.2.2 1996/10/06 01:24:13 gibbs Exp $
*/
/*
@@ -408,6 +408,7 @@
#define NO_IDENT 0x21 /* no IDENTIFY after reconnect*/
#define NO_MATCH 0x31 /* no cmd match for reconnect */
#define EXTENDED_MSG 0x41 /* Extended message received */
+#define DMA_UP_SCB 0x51
#define REJECT_MSG 0x61 /* Reject message received */
#define BAD_STATUS 0x71 /* Bad status from target */
#define RESIDUAL 0x81 /* Residual byte count != 0 */
@@ -529,6 +530,7 @@
#define MK_MESSAGE 0x80
#define DISCENB 0x40
#define TAG_ENB 0x20
+#define ABORT_SCB 0x08
#define DISCONNECTED 0x04
#define SCB_TAG_TYPE 0x03
#define SCB_TCL 0x0a1
@@ -553,7 +555,7 @@
#define SCB_DATACNT0 0x0b0
#define SCB_DATACNT1 0x0b1
#define SCB_DATACNT2 0x0b2
-/* UNUSED - QUAD PADDING 0x0b3 */
+#define SCB_LINKED_NEXT 0x0b3
#define SCB_CMDPTR 0x0b4
#define SCB_CMDPTR0 0x0b4
#define SCB_CMDPTR1 0x0b5
@@ -563,6 +565,10 @@
#define SCB_TAG 0x0b9
#define SCB_NEXT 0x0ba
#define SCB_PREV 0x0bb
+#define SCB_ACTIVE0 0x0bc
+#define SCB_ACTIVE1 0x0bd
+#define SCB_ACTIVE2 0x0be
+#define SCB_ACTIVE3 0x0bf
#ifdef __linux__
#define SG_SIZEOF 0x0c /* sizeof(struct scatterlist) */
@@ -644,11 +650,10 @@
/*
* The sequencer will stick the frist byte of any rejected message here so
- * we can see what is getting thrown away. Extended messages put the
- * extended message type in REJBYTE_EXT.
+ * we can see what is getting thrown away.
*/
#define REJBYTE 0x030
-#define REJBYTE_EXT 0x031
+#define TARGID_MASK 0x031
/*
* Bit vector of targets that have disconnection disabled.
@@ -662,7 +667,7 @@
*/
#define MSG_LEN 0x034
-/* We reserve 8bytes to store outgoing messages */
+/* We reserve 6bytes to store outgoing messages */
#define MSG0 0x035
#define COMP_MSG0 0xcb /* 2's complement of MSG0 */
#define MSG1 0x036
@@ -670,92 +675,104 @@
#define MSG3 0x038
#define MSG4 0x039
#define MSG5 0x03a
-#define MSG6 0x03b
-#define MSG7 0x03c
-/*
- * These are offsets into the card's scratch ram. Some of the values are
- * specified in the AHA2742 technical reference manual and are initialized
- * by the BIOS at boot time.
- */
-#define LASTPHASE 0x03d
-#define ARG_1 0x03e
-#define RETURN_1 0x03f
+#define LASTPHASE 0x03b
+#define ARG_1 0x03c
+#define RETURN_1 0x03c
#define SEND_MSG 0x80
#define SEND_SENSE 0x40
#define SEND_REJ 0x20
#define SCB_PAGEDIN 0x10
-#define SIGSTATE 0x040
-
-#define DMAPARAMS 0x041 /* Parameters for DMA Logic */
+#define DMAPARAMS 0x03d /* Parameters for DMA Logic */
-#define SG_COUNT 0x042
-#define SG_NEXT 0x043 /* working value of SG pointer */
-#define SG_NEXT0 0x043
-#define SG_NEXT1 0x044
-#define SG_NEXT2 0x045
-#define SG_NEXT3 0x046
-
-#define SCBCOUNT 0x047 /*
+#define SCBCOUNT 0x03e /*
* Number of SCBs supported by
* this card.
*/
-#define COMP_SCBCOUNT 0x048 /*
+#define COMP_SCBCOUNT 0x03f /*
* Two's compliment of SCBCOUNT
*/
-#define QCNTMASK 0x049 /*
+#define QCNTMASK 0x040 /*
* Mask of bits to test against
* when looking at the Queue Count
* registers. Works around a bug
* on aic7850 chips.
*/
-#define FLAGS 0x04a
+#define FLAGS 0x041
#define SINGLE_BUS 0x00
#define TWIN_BUS 0x01
#define WIDE_BUS 0x02
#define PAGESCBS 0x04
+#define SCB_LISTED 0x08
#define DPHASE 0x10
-#define SELECTED 0x20
#define IDENTIFY_SEEN 0x40
#define RESELECTED 0x80
-#define SAVED_TCL 0x04b /*
+#define SAVED_TCL 0x042 /*
* Temporary storage for the
* target/channel/lun of a
* reconnecting target
*/
-#define ACTIVE_A 0x04c
-#define ACTIVE_B 0x04d
-#define WAITING_SCBH 0x04e /*
+#define SG_COUNT 0x043
+#define SG_NEXT 0x044 /* working value of SG pointer */
+#define SG_NEXT0 0x044
+#define SG_NEXT1 0x045
+#define SG_NEXT2 0x046
+#define SG_NEXT3 0x047
+
+#define WAITING_SCBH 0x048 /*
* head of list of SCBs awaiting
* selection
*/
-#define DISCONNECTED_SCBH 0x04f /*
+#define SAVED_LINKPTR 0x049
+#define SAVED_SCBPTR 0x04a
+#define ULTRA_ENB 0x04b
+#define ULTRA_ENB_B 0x04c
+
+#define MSGIN_EXT_LEN 0x04d
+#define MSGIN_EXT_OPCODE 0x04e
+#define MSGIN_EXT_BYTE0 0x04f
+#define MSGIN_EXT_BYTE1 0x050
+#define MSGIN_EXT_BYTE2 0x051 /*
+ * This location, stores the last
+ * byte of an extended message if
+ * it passes the two bytes of space
+ * we allow now. This byte isn't
+ * used for anything, it just makes
+ * the code shorter for tossing
+ * extra bytes.
+ */
+#define MSGIN_EXT_LASTBYTE 0x052 /* Used as the address for range
+ * checking, not used for storage.
+ */
+
+#define DISCONNECTED_SCBH 0x052 /*
* head of list of SCBs that are
* disconnected. Used for SCB
* paging.
*/
-#define SCB_LIST_NULL 0xff
-
-#define SAVED_LINKPTR 0x050
-#define SAVED_SCBPTR 0x051
-#define ULTRA_ENB 0x052
-#define ULTRA_ENB_B 0x053
-
-#define MSGIN_EXT_LEN 0x054
-#define MSGIN_EXT_OPCODE 0x055
-#define MSGIN_EXT_BYTE0 0x056
-#define MSGIN_EXT_BYTE1 0x057
-#define MSGIN_EXT_LASTBYTE 0x058 /*
- * We don't use this location, but
- * continue to store bytes until
- * we reach this address (avoids
- * a more complicated compare).
- * So, we can store at most 2
- * bytes for now.
+#define FREE_SCBH 0x053 /*
+ * head of list of SCBs that are
+ * not in use. Used for SCB paging.
*/
+
+#define HSCB_ADDR0 0x054
+#define HSCB_ADDR1 0x055
+#define HSCB_ADDR2 0x056
+#define HSCB_ADDR3 0x057
+
+#define CUR_SCBID 0x058
+#define QFULLCNT 0x059
+
+#define SCB_LIST_NULL 0xff
+
+/*
+ * These are offsets into the card's scratch ram. Some of the values are
+ * specified in the AHA2742 technical reference manual and are initialized
+ * by the BIOS at boot time.
+ */
#define SCSICONF 0x05a
#define RESET_SCSI 0x40
OpenPOWER on IntegriCloud