diff options
| author | Justin T. Gibbs <gibbs@FreeBSD.org> | 1995-01-16 16:31:21 +0000 |
|---|---|---|
| committer | Justin T. Gibbs <gibbs@FreeBSD.org> | 1995-01-16 16:31:21 +0000 |
| commit | 0d564039980ad935a86f4bd08e7a015101b18719 (patch) | |
| tree | 6bd668f1ae746bc724b74ab832f474eb39584dcc | |
| parent | 03b38adc657227c53577c51d2d0f00aa0c7935d8 (diff) | |
Notes
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 235 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx_asm.c | 2 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aicasm.c | 2 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm.c | 2 | ||||
| -rw-r--r-- | sys/gnu/misc/aic7xxx/aic7xxx.c | 2 | ||||
| -rw-r--r-- | sys/gnu/misc/aic7xxx/aic7xxx.seq | 235 |
6 files changed, 260 insertions, 218 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index d1ed1e1c80a9..b02c77850a1d 100644 --- a/sys/dev/aic7xxx/aic7xxx.seq +++ b/sys/dev/aic7xxx/aic7xxx.seq @@ -1,6 +1,6 @@ # @(#)aic7xxx.seq 1.32 94/11/29 jda # -# Adaptec 274x/284x/294x device driver for Linux. +# Adaptec 274x/284x/294x device driver for Linux and FreeBSD. # Copyright (c) 1994 The University of Calgary Department of Computer Science. # # This program is free software; you can redistribute it and/or modify @@ -16,8 +16,14 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# FreeBSD, Twin, Wide, 2 command per target support, and other optimizations +# provided by Justin T. Gibbs (gibbs@FreeBSD.org) +# +# $Id$ -VERSION AIC7XXX_SEQ_VERSION 1.32 +VERSION AIC7XXX_SEQ_VERSION 1.5 SCBMASK = 0x1f @@ -70,14 +76,30 @@ SCSICONF_B = 0x5b # The two reserved bytes at SCBARRAY+1[23] are expected to be set to # zero, and the reserved bit in SCBARRAY+0 is used as an internal flag # to indicate whether or not to reload scatter-gather parameters after -# a disconnect. +# a disconnect. We also use bits 6 & 7 to indicate whether or not to +# initiate SDTR or WDTR repectively when starting this command. # SCBARRAY+0 = 0xa0 + +DISCONNECTED = 0x04 +NEEDDMA = 0x08 +SG_LOAD = 0x10 +NEEDSDTR = 0x40 +NEEDWDTR = 0x80 + SCBARRAY+1 = 0xa1 SCBARRAY+2 = 0xa2 SCBARRAY+3 = 0xa3 +SCBARRAY+4 = 0xa4 +SCBARRAY+5 = 0xa5 +SCBARRAY+6 = 0xa6 SCBARRAY+7 = 0xa7 +SCBARRAY+8 = 0xa8 +SCBARRAY+9 = 0xa9 +SCBARRAY+10 = 0xaa SCBARRAY+11 = 0xab +SCBARRAY+12 = 0xac +SCBARRAY+13 = 0xad SCBARRAY+14 = 0xae SCBARRAY+15 = 0xaf SCBARRAY+16 = 0xb0 @@ -90,14 +112,16 @@ SCBARRAY+22 = 0xb6 SCBARRAY+23 = 0xb7 SCBARRAY+24 = 0xb8 SCBARRAY+25 = 0xb9 +SCBARRAY+26 = 0xba -SIGNAL_0 = 0x01 # unknown scsi bus phase -SIGNAL_1 = 0x11 # message reject -SIGNAL_2 = 0x21 # no IDENTIFY after reconnect -SIGNAL_3 = 0x31 # no cmd match for reconnect -SIGNAL_4 = 0x41 # SDTR -> SCSIRATE conversion -STATUS_ERROR = 0x51 -SIGNAL_WDTR = 0x61 +BAD_PHASE = 0x01 # unknown scsi bus phase +SEND_REJECT = 0x11 # sending a message reject +NO_IDENT = 0x21 # no IDENTIFY after reconnect +NO_MATCH = 0x31 # no cmd match for reconnect +MSG_SDTR = 0x41 # SDTR message recieved +MSG_WDTR = 0x51 # WDTR message recieved +MSG_REJECT = 0x61 # Reject message recieved +BAD_STATUS = 0x71 # Bad status from target # The host adapter card (at least the BIOS) uses 20-2f for SCSI # device information, 32-33 and 5a-5f as well. As it turns out, the @@ -107,10 +131,10 @@ SIGNAL_WDTR = 0x61 # SCSIRATE). The kernel driver will enable synchronous negotiation # for all targets that have a value other than 0 in the lower four # bits of the target scratch space. This should work irregardless of -# whether the bios has been installed. NEEDSDTR has one bit per target -# indicating if an SDTR message is needed for that device - this will -# be set initially (based on a search through the target scratch space), -# as well as after a bus reset condition. +# whether the bios has been installed. NEEDWDTR and NEEDSDTR are the top +# two bits of the SCB control byte. The kernel driver will set these +# when a WDTR or SDTR message should be sent to the target the SCB's +# command references. # # The high bit of DROPATN is set if ATN should be dropped before the ACK # when outb is called. REJBYTE contains the first byte of a MESSAGE IN @@ -133,9 +157,6 @@ REJBYTE = 0x31 DISC_DSB_A = 0x32 DISC_DSB_B = 0x33 -NEEDWDTR_A = 0x34 -NEEDWDTR_B = 0x35 - MSG_LEN = 0x36 MSG_START+0 = 0x37 MSG_START+1 = 0x38 @@ -146,13 +167,16 @@ MSG_START+5 = 0x3c -MSG_START+0 = 0xc9 # 2's complement of MSG_START+0 ARG_1 = 0x4c # sdtr conversion args & return +BUS_16_BIT = 0x01 RETURN_1 = 0x4c SIGSTATE = 0x4d # value written to SCSISIGO -NEEDSDTR_A = 0x4e # send SDTR message, 1 bit/trgt -NEEDSDTR_B = 0x4f -SG_SIZEOF = 0x8 # sizeof(struct scatterlist) +# Linux users should use 0xc (12) for SG_SIZEOF +SG_SIZEOF = 0x8 # sizeof(struct ahc_dma) +#SG_SIZEOF = 0xc # sizeof(struct scatterlist) +SCB_SIZEOF = 0x13 # sizeof SCB to DMA (19 bytes) + SG_NOLOAD = 0x50 # load SG pointer/length? SG_COUNT = 0x51 # working value of SG count SG_NEXT = 0x52 # working value of SG pointer @@ -165,7 +189,6 @@ SCBCOUNT = 0x56 # the actual number of SCBs FLAGS = 0x57 # Device configuration flags TWIN_BUS = 0x01 WIDE_BUS = 0x02 -CHECK_DTR = 0x08 SENSE = 0x10 ACTIVE_MSG = 0x20 IDENTIFY_SEEN = 0x40 @@ -189,13 +212,60 @@ start2: test SCSISIGI,0x4 jnz reselect # BSYI test QINCNT,SCBMASK jz start -# We have at least one queued SCB now. Set the SCB pointer -# from the FIFO so we see the right bank of SCB registers, -# then set SCSI options and set the initiator and target -# SCSI IDs. +# We have at least one queued SCB now. Set the SCB pointer +# from the FIFO so we see the right bank of SCB registers, +# then set SCSI options and set the initiator and target +# SCSI IDs. # mov SCBPTR,QINFIFO +# If the control byte of this SCB has the NEEDDMA flag set, we have +# yet to DMA it from host memory + +test SCBARRAY+0,NEEDDMA jz test_busy + clr HCNT+2 + clr HCNT+1 + mvi HCNT+0,SCB_SIZEOF + + mvi A,4 + mvi DINDEX,HADDR + mvi SCBARRAY+26 call bcopy + + mvi 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. +# +scb_load1: + test DFSTATUS,0x8 jz scb_load1 # HDONE + + clr DFCNTRL # disable DMA +scb_load2: + test DFCNTRL,0x8 jnz scb_load2 # HDMAENACK + +# Copy the SCB from the FIFO to the SCBARRAY + + mov SCBARRAY+0, DFDAT + mov SCBARRAY+1, DFDAT + mov SCBARRAY+2, DFDAT + mov SCBARRAY+3, DFDAT + mov SCBARRAY+4, DFDAT + mov SCBARRAY+5, DFDAT + mov SCBARRAY+6, DFDAT + mov SCBARRAY+7, DFDAT + mov SCBARRAY+8, DFDAT + mov SCBARRAY+9, DFDAT + mov SCBARRAY+10, DFDAT + mov SCBARRAY+11, DFDAT + mov SCBARRAY+12, DFDAT + mov SCBARRAY+13, DFDAT + mov SCBARRAY+14, DFDAT + mov SCBARRAY+15, DFDAT + mov SCBARRAY+16, DFDAT + mov SCBARRAY+17, DFDAT + mov SCBARRAY+18, DFDAT + and SCBARRAY+0, 0xf7 + # 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 @@ -205,6 +275,7 @@ start2: # assumes that the kernel driver will clear the active flags on board # initialization, board reset, and a target's SELTO. +test_busy: and FUNCTION1,0x70,SCBARRAY+1 mov A,FUNCTION1 test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel @@ -228,6 +299,7 @@ test_a: or ACTIVE_A,A # Mark the current target as busy start_scb: + or SCBARRAY+0,NEEDDMA and SINDEX,0x08,SCBARRAY+1 and A,WIDE_BUS,FLAGS # Wide bus? or SINDEX,A @@ -252,8 +324,8 @@ start_scb: or SINDEX,0x80 call mk_mesg # IDENTIFY message mov A,SINDEX + test SCBARRAY+0,0xc0 jz !message # WDTR or SDTR?? cmp MSG_START+0,A jne !message # did driver beat us? - test FLAGS,CHECK_DTR jz !message # Don't even bother with DTR? mvi MSG_START+1 call mk_dtr # build DTR message if needed !message: @@ -337,7 +409,7 @@ ITloop: cmp A,0xa0 je p_mesgout cmp A,0xe0 je p_mesgin - mvi INTSTAT,SIGNAL_0 # unknown - signal driver + mvi INTSTAT,BAD_PHASE # unknown - signal driver p_dataout: mvi 0 call scsisig # !CDO|!IOO|!MSGO @@ -544,8 +616,8 @@ p_mesgin: # extra work in the kernel driver to ensure that the entry was removed # before the command complete code tried processing it. - test SCBARRAY+14,0xff jz status_ok # 0 Status? - mvi INTSTAT,STATUS_ERROR # let driver know + test SCBARRAY+14,0xff jz status_ok # 0 Status? + mvi INTSTAT,BAD_STATUS # let driver know test FLAGS,SENSE jz status_ok jmp p_mesgin_done @@ -585,12 +657,13 @@ p_mesgin1: p_mesginWDTR: cmp ARG_1,2 jne p_mesginN # extended mesg length = 2 mvi A call inb_next # Width of bus - mvi INTSTAT,SIGNAL_WDTR # let driver know + mvi INTSTAT,MSG_WDTR # let driver know test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR? # We didn't initiate the wide negotiation, so we must respond to the request and RETURN_1,0x7f # Clear the SEND_WDTR Flag or FLAGS,ACTIVE_MSG + mvi DINDEX,MSG_START+0 mvi MSG_START+0 call mk_wdtr # build WDTR message or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig @@ -600,11 +673,12 @@ p_mesginSDTR: cmp ARG_1,3 jne p_mesginN # extended mesg length = 3 mvi ARG_1 call inb_next # xfer period mvi A call inb_next # REQ/ACK offset - mvi INTSTAT,SIGNAL_4 # call driver to convert + mvi INTSTAT,MSG_SDTR # call driver to convert test RETURN_1,0x80 jz p_mesgin_done# Do we need to mk_sdtr? or FLAGS,ACTIVE_MSG + mvi DINDEX, MSG_START+0 mvi MSG_START+0 call mk_sdtr or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig @@ -662,70 +736,15 @@ p_mesgin5: # required on reselect jmp p_mesgin_done -# Message reject? If we have an outstanding WDTR or SDTR negotiation, assume -# that it's a response from the target selecting 8bit or asynchronous transfer, -# otherwise just ignore it since we have no clue what it pertains to. -# -# XXX - I don't have a device that responds this way. Does this code -# actually work? +# Message reject? Let the kernel driver handle this. If we have an +# outstanding WDTR or SDTR negotiation, assume that it's a response from +# the target selecting 8bit or asynchronous transfer, otherwise just ignore +# it since we have no clue what it pertains to. # p_mesgin6: cmp A,7 jne p_mesgin7 # message reject code? - and FUNCTION1,0x70,SCSIID # outstanding SDTR message? - mov A,FUNCTION1 - - test SBLKCTL,0x08 jnz p_mesgin6_b - test SCSIID,0x80 jnz p_mesgin6_b - test NEEDWDTR_A,A jnz clear_wdtr_a - test NEEDSDTR_A,A jnz clear_sdtr_a - jmp p_mesgin_done # no - ignore rejection - -clear_sdtr_a: - call ndx_dtr # note use of asynch xfer - mov DINDEX,SINDEX - and DINDIR,0x80,SINDIR - - not A - and NEEDSDTR_A,A - jmp clear_sdtr_done - -clear_wdtr_a: - call ndx_dtr # note use of 8bit xfer - mov DINDEX,SINDEX - and DINDIR,0x7f,SINDIR - - not A - and NEEDWDTR_A,A - jmp clear_wdtr_done - -p_mesgin6_b: - test NEEDWDTR_B,A jnz clear_wdtr_b - test NEEDSDTR_B,A jnz clear_sdtr_b - jmp p_mesgin_done # no - ignore rejection - -clear_wdtr_b: - call ndx_dtr # note use of 8bit xfer - mov DINDEX,SINDEX - and DINDIR,0x7f,SINDIR - - not A - and NEEDWDTR_B,A - -clear_wdtr_done: - and SCSIRATE,0x7f # select 8bit xfer - jmp p_mesgin_done - -clear_sdtr_b: - call ndx_dtr # note use of asynch xfer - mov DINDEX,SINDEX - and DINDIR,0x80,SINDIR - - not A - and NEEDSDTR_B,A - -clear_sdtr_done: - and SCSIRATE,0xf0 # select asynch xfer + mvi INTSTAT, MSG_REJECT jmp p_mesgin_done # [ ADD MORE MESSAGE HANDLING HERE ] @@ -742,7 +761,7 @@ p_mesgin7: p_mesginN: or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig - mvi INTSTAT,SIGNAL_1 # let driver know + mvi INTSTAT,SEND_REJECT # let driver know mvi 0x7 call mk_mesg # MESSAGE REJECT message @@ -964,7 +983,7 @@ assert: test FLAGS,RESELECTED jz assert1 # reselected? test FLAGS,IDENTIFY_SEEN jnz assert1 # seen IDENTIFY? - mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic + mvi INTSTAT,NO_IDENT # no - cause a kernel panic assert1: ret @@ -1019,7 +1038,7 @@ findSCB2: mov A,SCBCOUNT cmp SINDEX,A jne findSCB1 - mvi INTSTAT,SIGNAL_3 # not found - signal kernel + mvi INTSTAT,NO_MATCH # not found - signal kernel mvi 0x6 call mk_mesg # ABORT message or SINDEX,0x10,SIGSTATE # assert ATNO @@ -1053,7 +1072,7 @@ sg_ram2scb: and SCBARRAY+0,0xef,SCBARRAY+0 test SG_NOLOAD,0x80 jz sg_ram2scb1 # reload s/g? - or SCBARRAY+0,0x10 + or SCBARRAY+0,SG_LOAD sg_ram2scb1: ret @@ -1112,10 +1131,16 @@ sg_load2: mov SCBARRAY+21,DFDAT mov SCBARRAY+22,DFDAT +# For Linux, we must throw away four bytes since there is a 32bit gap +# in the middle of a struct scatterlist +# mov NONE,DFDAT +# mov NONE,DFDAT +# mov NONE,DFDAT +# mov NONE,DFDAT + mov SCBARRAY+23,DFDAT mov SCBARRAY+24,DFDAT - mov SCBARRAY+25,DFDAT - mov NONE,DFDAT #Only support 24 bit length. + mov SCBARRAY+25,DFDAT #Only support 24 bit length. sg_load3: ret @@ -1173,19 +1198,11 @@ ndx_dtr_2: mk_dtr: mov DINDEX,SINDEX # save SINDEX - call ndx_dtr - test SCBARRAY+1,0x88 jz mk_dtr_a - test NEEDWDTR_B,A jnz mk_wdtr_16 # do we need negotiation? - test NEEDSDTR_B,A jnz mk_sdtr - ret -mk_dtr_a: - test NEEDWDTR_A,A jnz mk_wdtr_16 # do we need negotiation? - test NEEDSDTR_A,A jnz mk_sdtr - ret - -mk_wdtr_16: - mvi ARG_1,1 # 16bit wide bus + test SCBARRAY+0,NEEDWDTR jnz mk_wdtr_16bit + jmp mk_sdtr +mk_wdtr_16bit: + mvi ARG_1,BUS_16_BIT mk_wdtr: mvi DINDIR,1 # extended message mvi DINDIR,2 # extended message length = 2 diff --git a/sys/dev/aic7xxx/aic7xxx_asm.c b/sys/dev/aic7xxx/aic7xxx_asm.c index 417a352762d3..8077ac82f56c 100644 --- a/sys/dev/aic7xxx/aic7xxx_asm.c +++ b/sys/dev/aic7xxx/aic7xxx_asm.c @@ -25,6 +25,8 @@ * * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas * are token separators. + * + * $Id$ */ /* #define _POSIX_SOURCE 1 */ diff --git a/sys/dev/aic7xxx/aicasm.c b/sys/dev/aic7xxx/aicasm.c index 417a352762d3..8077ac82f56c 100644 --- a/sys/dev/aic7xxx/aicasm.c +++ b/sys/dev/aic7xxx/aicasm.c @@ -25,6 +25,8 @@ * * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas * are token separators. + * + * $Id$ */ /* #define _POSIX_SOURCE 1 */ diff --git a/sys/dev/aic7xxx/aicasm/aicasm.c b/sys/dev/aic7xxx/aicasm/aicasm.c index 417a352762d3..8077ac82f56c 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm.c +++ b/sys/dev/aic7xxx/aicasm/aicasm.c @@ -25,6 +25,8 @@ * * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas * are token separators. + * + * $Id$ */ /* #define _POSIX_SOURCE 1 */ diff --git a/sys/gnu/misc/aic7xxx/aic7xxx.c b/sys/gnu/misc/aic7xxx/aic7xxx.c index 417a352762d3..8077ac82f56c 100644 --- a/sys/gnu/misc/aic7xxx/aic7xxx.c +++ b/sys/gnu/misc/aic7xxx/aic7xxx.c @@ -25,6 +25,8 @@ * * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas * are token separators. + * + * $Id$ */ /* #define _POSIX_SOURCE 1 */ diff --git a/sys/gnu/misc/aic7xxx/aic7xxx.seq b/sys/gnu/misc/aic7xxx/aic7xxx.seq index d1ed1e1c80a9..b02c77850a1d 100644 --- a/sys/gnu/misc/aic7xxx/aic7xxx.seq +++ b/sys/gnu/misc/aic7xxx/aic7xxx.seq @@ -1,6 +1,6 @@ # @(#)aic7xxx.seq 1.32 94/11/29 jda # -# Adaptec 274x/284x/294x device driver for Linux. +# Adaptec 274x/284x/294x device driver for Linux and FreeBSD. # Copyright (c) 1994 The University of Calgary Department of Computer Science. # # This program is free software; you can redistribute it and/or modify @@ -16,8 +16,14 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# FreeBSD, Twin, Wide, 2 command per target support, and other optimizations +# provided by Justin T. Gibbs (gibbs@FreeBSD.org) +# +# $Id$ -VERSION AIC7XXX_SEQ_VERSION 1.32 +VERSION AIC7XXX_SEQ_VERSION 1.5 SCBMASK = 0x1f @@ -70,14 +76,30 @@ SCSICONF_B = 0x5b # The two reserved bytes at SCBARRAY+1[23] are expected to be set to # zero, and the reserved bit in SCBARRAY+0 is used as an internal flag # to indicate whether or not to reload scatter-gather parameters after -# a disconnect. +# a disconnect. We also use bits 6 & 7 to indicate whether or not to +# initiate SDTR or WDTR repectively when starting this command. # SCBARRAY+0 = 0xa0 + +DISCONNECTED = 0x04 +NEEDDMA = 0x08 +SG_LOAD = 0x10 +NEEDSDTR = 0x40 +NEEDWDTR = 0x80 + SCBARRAY+1 = 0xa1 SCBARRAY+2 = 0xa2 SCBARRAY+3 = 0xa3 +SCBARRAY+4 = 0xa4 +SCBARRAY+5 = 0xa5 +SCBARRAY+6 = 0xa6 SCBARRAY+7 = 0xa7 +SCBARRAY+8 = 0xa8 +SCBARRAY+9 = 0xa9 +SCBARRAY+10 = 0xaa SCBARRAY+11 = 0xab +SCBARRAY+12 = 0xac +SCBARRAY+13 = 0xad SCBARRAY+14 = 0xae SCBARRAY+15 = 0xaf SCBARRAY+16 = 0xb0 @@ -90,14 +112,16 @@ SCBARRAY+22 = 0xb6 SCBARRAY+23 = 0xb7 SCBARRAY+24 = 0xb8 SCBARRAY+25 = 0xb9 +SCBARRAY+26 = 0xba -SIGNAL_0 = 0x01 # unknown scsi bus phase -SIGNAL_1 = 0x11 # message reject -SIGNAL_2 = 0x21 # no IDENTIFY after reconnect -SIGNAL_3 = 0x31 # no cmd match for reconnect -SIGNAL_4 = 0x41 # SDTR -> SCSIRATE conversion -STATUS_ERROR = 0x51 -SIGNAL_WDTR = 0x61 +BAD_PHASE = 0x01 # unknown scsi bus phase +SEND_REJECT = 0x11 # sending a message reject +NO_IDENT = 0x21 # no IDENTIFY after reconnect +NO_MATCH = 0x31 # no cmd match for reconnect +MSG_SDTR = 0x41 # SDTR message recieved +MSG_WDTR = 0x51 # WDTR message recieved +MSG_REJECT = 0x61 # Reject message recieved +BAD_STATUS = 0x71 # Bad status from target # The host adapter card (at least the BIOS) uses 20-2f for SCSI # device information, 32-33 and 5a-5f as well. As it turns out, the @@ -107,10 +131,10 @@ SIGNAL_WDTR = 0x61 # SCSIRATE). The kernel driver will enable synchronous negotiation # for all targets that have a value other than 0 in the lower four # bits of the target scratch space. This should work irregardless of -# whether the bios has been installed. NEEDSDTR has one bit per target -# indicating if an SDTR message is needed for that device - this will -# be set initially (based on a search through the target scratch space), -# as well as after a bus reset condition. +# whether the bios has been installed. NEEDWDTR and NEEDSDTR are the top +# two bits of the SCB control byte. The kernel driver will set these +# when a WDTR or SDTR message should be sent to the target the SCB's +# command references. # # The high bit of DROPATN is set if ATN should be dropped before the ACK # when outb is called. REJBYTE contains the first byte of a MESSAGE IN @@ -133,9 +157,6 @@ REJBYTE = 0x31 DISC_DSB_A = 0x32 DISC_DSB_B = 0x33 -NEEDWDTR_A = 0x34 -NEEDWDTR_B = 0x35 - MSG_LEN = 0x36 MSG_START+0 = 0x37 MSG_START+1 = 0x38 @@ -146,13 +167,16 @@ MSG_START+5 = 0x3c -MSG_START+0 = 0xc9 # 2's complement of MSG_START+0 ARG_1 = 0x4c # sdtr conversion args & return +BUS_16_BIT = 0x01 RETURN_1 = 0x4c SIGSTATE = 0x4d # value written to SCSISIGO -NEEDSDTR_A = 0x4e # send SDTR message, 1 bit/trgt -NEEDSDTR_B = 0x4f -SG_SIZEOF = 0x8 # sizeof(struct scatterlist) +# Linux users should use 0xc (12) for SG_SIZEOF +SG_SIZEOF = 0x8 # sizeof(struct ahc_dma) +#SG_SIZEOF = 0xc # sizeof(struct scatterlist) +SCB_SIZEOF = 0x13 # sizeof SCB to DMA (19 bytes) + SG_NOLOAD = 0x50 # load SG pointer/length? SG_COUNT = 0x51 # working value of SG count SG_NEXT = 0x52 # working value of SG pointer @@ -165,7 +189,6 @@ SCBCOUNT = 0x56 # the actual number of SCBs FLAGS = 0x57 # Device configuration flags TWIN_BUS = 0x01 WIDE_BUS = 0x02 -CHECK_DTR = 0x08 SENSE = 0x10 ACTIVE_MSG = 0x20 IDENTIFY_SEEN = 0x40 @@ -189,13 +212,60 @@ start2: test SCSISIGI,0x4 jnz reselect # BSYI test QINCNT,SCBMASK jz start -# We have at least one queued SCB now. Set the SCB pointer -# from the FIFO so we see the right bank of SCB registers, -# then set SCSI options and set the initiator and target -# SCSI IDs. +# We have at least one queued SCB now. Set the SCB pointer +# from the FIFO so we see the right bank of SCB registers, +# then set SCSI options and set the initiator and target +# SCSI IDs. # mov SCBPTR,QINFIFO +# If the control byte of this SCB has the NEEDDMA flag set, we have +# yet to DMA it from host memory + +test SCBARRAY+0,NEEDDMA jz test_busy + clr HCNT+2 + clr HCNT+1 + mvi HCNT+0,SCB_SIZEOF + + mvi A,4 + mvi DINDEX,HADDR + mvi SCBARRAY+26 call bcopy + + mvi 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. +# +scb_load1: + test DFSTATUS,0x8 jz scb_load1 # HDONE + + clr DFCNTRL # disable DMA +scb_load2: + test DFCNTRL,0x8 jnz scb_load2 # HDMAENACK + +# Copy the SCB from the FIFO to the SCBARRAY + + mov SCBARRAY+0, DFDAT + mov SCBARRAY+1, DFDAT + mov SCBARRAY+2, DFDAT + mov SCBARRAY+3, DFDAT + mov SCBARRAY+4, DFDAT + mov SCBARRAY+5, DFDAT + mov SCBARRAY+6, DFDAT + mov SCBARRAY+7, DFDAT + mov SCBARRAY+8, DFDAT + mov SCBARRAY+9, DFDAT + mov SCBARRAY+10, DFDAT + mov SCBARRAY+11, DFDAT + mov SCBARRAY+12, DFDAT + mov SCBARRAY+13, DFDAT + mov SCBARRAY+14, DFDAT + mov SCBARRAY+15, DFDAT + mov SCBARRAY+16, DFDAT + mov SCBARRAY+17, DFDAT + mov SCBARRAY+18, DFDAT + and SCBARRAY+0, 0xf7 + # 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 @@ -205,6 +275,7 @@ start2: # assumes that the kernel driver will clear the active flags on board # initialization, board reset, and a target's SELTO. +test_busy: and FUNCTION1,0x70,SCBARRAY+1 mov A,FUNCTION1 test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel @@ -228,6 +299,7 @@ test_a: or ACTIVE_A,A # Mark the current target as busy start_scb: + or SCBARRAY+0,NEEDDMA and SINDEX,0x08,SCBARRAY+1 and A,WIDE_BUS,FLAGS # Wide bus? or SINDEX,A @@ -252,8 +324,8 @@ start_scb: or SINDEX,0x80 call mk_mesg # IDENTIFY message mov A,SINDEX + test SCBARRAY+0,0xc0 jz !message # WDTR or SDTR?? cmp MSG_START+0,A jne !message # did driver beat us? - test FLAGS,CHECK_DTR jz !message # Don't even bother with DTR? mvi MSG_START+1 call mk_dtr # build DTR message if needed !message: @@ -337,7 +409,7 @@ ITloop: cmp A,0xa0 je p_mesgout cmp A,0xe0 je p_mesgin - mvi INTSTAT,SIGNAL_0 # unknown - signal driver + mvi INTSTAT,BAD_PHASE # unknown - signal driver p_dataout: mvi 0 call scsisig # !CDO|!IOO|!MSGO @@ -544,8 +616,8 @@ p_mesgin: # extra work in the kernel driver to ensure that the entry was removed # before the command complete code tried processing it. - test SCBARRAY+14,0xff jz status_ok # 0 Status? - mvi INTSTAT,STATUS_ERROR # let driver know + test SCBARRAY+14,0xff jz status_ok # 0 Status? + mvi INTSTAT,BAD_STATUS # let driver know test FLAGS,SENSE jz status_ok jmp p_mesgin_done @@ -585,12 +657,13 @@ p_mesgin1: p_mesginWDTR: cmp ARG_1,2 jne p_mesginN # extended mesg length = 2 mvi A call inb_next # Width of bus - mvi INTSTAT,SIGNAL_WDTR # let driver know + mvi INTSTAT,MSG_WDTR # let driver know test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR? # We didn't initiate the wide negotiation, so we must respond to the request and RETURN_1,0x7f # Clear the SEND_WDTR Flag or FLAGS,ACTIVE_MSG + mvi DINDEX,MSG_START+0 mvi MSG_START+0 call mk_wdtr # build WDTR message or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig @@ -600,11 +673,12 @@ p_mesginSDTR: cmp ARG_1,3 jne p_mesginN # extended mesg length = 3 mvi ARG_1 call inb_next # xfer period mvi A call inb_next # REQ/ACK offset - mvi INTSTAT,SIGNAL_4 # call driver to convert + mvi INTSTAT,MSG_SDTR # call driver to convert test RETURN_1,0x80 jz p_mesgin_done# Do we need to mk_sdtr? or FLAGS,ACTIVE_MSG + mvi DINDEX, MSG_START+0 mvi MSG_START+0 call mk_sdtr or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig @@ -662,70 +736,15 @@ p_mesgin5: # required on reselect jmp p_mesgin_done -# Message reject? If we have an outstanding WDTR or SDTR negotiation, assume -# that it's a response from the target selecting 8bit or asynchronous transfer, -# otherwise just ignore it since we have no clue what it pertains to. -# -# XXX - I don't have a device that responds this way. Does this code -# actually work? +# Message reject? Let the kernel driver handle this. If we have an +# outstanding WDTR or SDTR negotiation, assume that it's a response from +# the target selecting 8bit or asynchronous transfer, otherwise just ignore +# it since we have no clue what it pertains to. # p_mesgin6: cmp A,7 jne p_mesgin7 # message reject code? - and FUNCTION1,0x70,SCSIID # outstanding SDTR message? - mov A,FUNCTION1 - - test SBLKCTL,0x08 jnz p_mesgin6_b - test SCSIID,0x80 jnz p_mesgin6_b - test NEEDWDTR_A,A jnz clear_wdtr_a - test NEEDSDTR_A,A jnz clear_sdtr_a - jmp p_mesgin_done # no - ignore rejection - -clear_sdtr_a: - call ndx_dtr # note use of asynch xfer - mov DINDEX,SINDEX - and DINDIR,0x80,SINDIR - - not A - and NEEDSDTR_A,A - jmp clear_sdtr_done - -clear_wdtr_a: - call ndx_dtr # note use of 8bit xfer - mov DINDEX,SINDEX - and DINDIR,0x7f,SINDIR - - not A - and NEEDWDTR_A,A - jmp clear_wdtr_done - -p_mesgin6_b: - test NEEDWDTR_B,A jnz clear_wdtr_b - test NEEDSDTR_B,A jnz clear_sdtr_b - jmp p_mesgin_done # no - ignore rejection - -clear_wdtr_b: - call ndx_dtr # note use of 8bit xfer - mov DINDEX,SINDEX - and DINDIR,0x7f,SINDIR - - not A - and NEEDWDTR_B,A - -clear_wdtr_done: - and SCSIRATE,0x7f # select 8bit xfer - jmp p_mesgin_done - -clear_sdtr_b: - call ndx_dtr # note use of asynch xfer - mov DINDEX,SINDEX - and DINDIR,0x80,SINDIR - - not A - and NEEDSDTR_B,A - -clear_sdtr_done: - and SCSIRATE,0xf0 # select asynch xfer + mvi INTSTAT, MSG_REJECT jmp p_mesgin_done # [ ADD MORE MESSAGE HANDLING HERE ] @@ -742,7 +761,7 @@ p_mesgin7: p_mesginN: or SINDEX,0x10,SIGSTATE # turn on ATNO call scsisig - mvi INTSTAT,SIGNAL_1 # let driver know + mvi INTSTAT,SEND_REJECT # let driver know mvi 0x7 call mk_mesg # MESSAGE REJECT message @@ -964,7 +983,7 @@ assert: test FLAGS,RESELECTED jz assert1 # reselected? test FLAGS,IDENTIFY_SEEN jnz assert1 # seen IDENTIFY? - mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic + mvi INTSTAT,NO_IDENT # no - cause a kernel panic assert1: ret @@ -1019,7 +1038,7 @@ findSCB2: mov A,SCBCOUNT cmp SINDEX,A jne findSCB1 - mvi INTSTAT,SIGNAL_3 # not found - signal kernel + mvi INTSTAT,NO_MATCH # not found - signal kernel mvi 0x6 call mk_mesg # ABORT message or SINDEX,0x10,SIGSTATE # assert ATNO @@ -1053,7 +1072,7 @@ sg_ram2scb: and SCBARRAY+0,0xef,SCBARRAY+0 test SG_NOLOAD,0x80 jz sg_ram2scb1 # reload s/g? - or SCBARRAY+0,0x10 + or SCBARRAY+0,SG_LOAD sg_ram2scb1: ret @@ -1112,10 +1131,16 @@ sg_load2: mov SCBARRAY+21,DFDAT mov SCBARRAY+22,DFDAT +# For Linux, we must throw away four bytes since there is a 32bit gap +# in the middle of a struct scatterlist +# mov NONE,DFDAT +# mov NONE,DFDAT +# mov NONE,DFDAT +# mov NONE,DFDAT + mov SCBARRAY+23,DFDAT mov SCBARRAY+24,DFDAT - mov SCBARRAY+25,DFDAT - mov NONE,DFDAT #Only support 24 bit length. + mov SCBARRAY+25,DFDAT #Only support 24 bit length. sg_load3: ret @@ -1173,19 +1198,11 @@ ndx_dtr_2: mk_dtr: mov DINDEX,SINDEX # save SINDEX - call ndx_dtr - test SCBARRAY+1,0x88 jz mk_dtr_a - test NEEDWDTR_B,A jnz mk_wdtr_16 # do we need negotiation? - test NEEDSDTR_B,A jnz mk_sdtr - ret -mk_dtr_a: - test NEEDWDTR_A,A jnz mk_wdtr_16 # do we need negotiation? - test NEEDSDTR_A,A jnz mk_sdtr - ret - -mk_wdtr_16: - mvi ARG_1,1 # 16bit wide bus + test SCBARRAY+0,NEEDWDTR jnz mk_wdtr_16bit + jmp mk_sdtr +mk_wdtr_16bit: + mvi ARG_1,BUS_16_BIT mk_wdtr: mvi DINDIR,1 # extended message mvi DINDIR,2 # extended message length = 2 |
