Deleted Added
full compact
aic7xxx.seq (12137) aic7xxx.seq (13177)
1##+M#########################################################################
2# Adaptec 274x/284x/294x device driver for Linux and FreeBSD.
3#
4# Copyright (c) 1994 John Aycock
5# The University of Calgary Department of Computer Science.
6# All rights reserved.
7#
8# Modifications/enhancements:
9# Copyright (c) 1994, 1995 Justin Gibbs. All rights reserved.
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions
13# are met:
14# 1. Redistributions of source code must retain the above copyright
15# notice, this list of conditions, and the following disclaimer.
16# 2. Redistributions in binary form must reproduce the above copyright
17# notice, this list of conditions and the following disclaimer in the
18# documentation and/or other materials provided with the distribution.
19# 3. All advertising materials mentioning features or use of this software
20# must display the following acknowledgement:
21# This product includes software developed by the University of Calgary
22# Department of Computer Science and its contributors.
23# 4. Neither the name of the University nor the names of its contributors
24# may be used to endorse or promote products derived from this software
25# without specific prior written permission.
26#
27# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37# SUCH DAMAGE.
38#
39# FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other
40# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
41#
42##-M#########################################################################
1/*+M***********************************************************************
2 *Adaptec 274x/284x/294x device driver for Linux and FreeBSD.
3 *
4 *Copyright (c) 1994 John Aycock
5 * The University of Calgary Department of Computer Science.
6 * All rights reserved.
7 *
8 *Modifications/enhancements:
9 * Copyright (c) 1994, 1995 Justin Gibbs. All rights reserved.
10 *
11 *Redistribution and use in source and binary forms, with or without
12 *modification, are permitted provided that the following conditions
13 *are met:
14 *1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer.
16 *2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of Calgary
22 * Department of Computer Science and its contributors.
23 *4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 *ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 *ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 *DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 *OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 *HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 *OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 *SUCH DAMAGE.
38 *
39 *FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other
40 *optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org)
41 *
42 *-M************************************************************************/
43
43
44VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.23 1995/10/29 05:56:31 gibbs Exp $"
44VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.24 1995/11/07 05:31:28 gibbs Exp $"
45
45
46SCBMASK = 0xff
46#include "../../dev/aic7xxx/aic7xxx_reg.h"
47
47
48SCSISEQ = 0x00
49ENRSELI = 0x10
50SXFRCTL0 = 0x01
51ULTRAEN = 0x20
52SXFRCTL1 = 0x02
53SCSISIGI = 0x03
54SCSISIGO = 0x03
55SCSIRATE = 0x04
56SCSIID = 0x05
57SCSIDATL = 0x06
58STCNT = 0x08
59STCNT+0 = 0x08
60STCNT+1 = 0x09
61STCNT+2 = 0x0a
62CLRSINT0 = 0x0b
63SSTAT0 = 0x0b
64SELDO = 0x40
65SELDI = 0x20
66CLRSINT1 = 0x0c
67SSTAT1 = 0x0c
68PHASEMIS = 0x10
69SIMODE1 = 0x11
70SCSIBUSL = 0x12
71SHADDR = 0x14
72SELID = 0x19
73SBLKCTL = 0x1f
74SEQCTL = 0x60
75A = 0x64 # == ACCUM
76SINDEX = 0x65
77DINDEX = 0x66
78ALLZEROS = 0x6a
79NONE = 0x6a
80SINDIR = 0x6c
81DINDIR = 0x6d
82FUNCTION1 = 0x6e
83HADDR = 0x88
84HADDR+1 = 0x89
85HADDR+2 = 0x8a
86HADDR+3 = 0x8b
87HCNT = 0x8c
88HCNT+0 = 0x8c
89HCNT+1 = 0x8d
90HCNT+2 = 0x8e
91SCBPTR = 0x90
92INTSTAT = 0x91
93DFCNTRL = 0x93
94DFSTATUS = 0x94
95DFDAT = 0x99
96QINFIFO = 0x9b
97QINCNT = 0x9c
98QOUTFIFO = 0x9d
48/*
49 * We can't just use ACCUM in the sequencer code because it
50 * must be treated specially by the assembler, and it currently
51 * looks for the symbol 'A'. This is the only register defined
52 * the assembler's symbol space.
53 */
54A = ACCUM
99
55
100SCSICONF_A = 0x5a
101SCSICONF_B = 0x5b
56/* After starting the selection hardware, we return to the "poll_for_work"
57 * loop so that we can check for reconnecting targets as well as for our
58 * selection to complete just in case the reselection wins bus arbitration.
59 * The problem with this is that we must keep track of the SCB that we've
60 * already pulled from the QINFIFO and started the selection on just in case
61 * the reselection wins so that we can retry the selection at a later time.
62 * This problem cannot be resolved by holding a single entry in scratch
63 * ram since a reconnecting target can request sense and this will create
64 * yet another SCB waiting for selection. The solution used here is to
65 * use byte 31 of the SCB as a psuedo-next pointer and to thread a list
66 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB offsets,
67 * SCB_LIST_NULL is 0xff which is out of range. The kernel driver must
68 * add an entry to this list everytime a request sense occurs. The sequencer
69 * will automatically consume the entries.
70 */
102
71
103# The two reserved bytes at SCBARRAY+1[23] are expected to be set to
104# zero. Bit 3 in SCBARRAY+0 is used as an internal flag to indicate
105# whether or not to DMA an SCB from host ram. This flag prevents the
106# "re-fetching" of transactions that are requed because the target is
107# busy with another command. We also use bits 6 & 7 to indicate whether
108# or not to initiate SDTR or WDTR repectively when starting this command.
109#
110SCBARRAY+0 = 0xa0
111
112DISCONNECTED = 0x04
113NEEDDMA = 0x08
114NEEDSDTR = 0x10
115TAG_ENB = 0x20
116DISCENB = 0x40
117NEEDWDTR = 0x80
118
119SCBARRAY+1 = 0xa1
120SCBARRAY+2 = 0xa2
121SCBARRAY+3 = 0xa3
122SCBARRAY+4 = 0xa4
123SCBARRAY+5 = 0xa5
124SCBARRAY+6 = 0xa6
125SCBARRAY+7 = 0xa7
126SCBARRAY+8 = 0xa8
127SCBARRAY+9 = 0xa9
128SCBARRAY+10 = 0xaa
129SCBARRAY+11 = 0xab
130SCBARRAY+12 = 0xac
131SCBARRAY+13 = 0xad
132SCBARRAY+14 = 0xae
133SCBARRAY+15 = 0xaf
134SCBARRAY+16 = 0xb0
135SCBARRAY+17 = 0xb1
136SCBARRAY+18 = 0xb2
137SCBARRAY+19 = 0xb3
138SCBARRAY+20 = 0xb4
139SCBARRAY+21 = 0xb5
140SCBARRAY+22 = 0xb6
141SCBARRAY+23 = 0xb7
142SCBARRAY+24 = 0xb8
143SCBARRAY+25 = 0xb9
144SCBARRAY+26 = 0xba
145SCBARRAY+27 = 0xbb
146SCBARRAY+28 = 0xbc
147SCBARRAY+29 = 0xbd
148SCBARRAY+30 = 0xbe
149
150BAD_PHASE = 0x01 # unknown scsi bus phase
151CMDCMPLT = 0x02 # Command Complete
152SEND_REJECT = 0x11 # sending a message reject
153NO_IDENT = 0x21 # no IDENTIFY after reconnect
154NO_MATCH = 0x31 # no cmd match for reconnect
155MSG_SDTR = 0x41 # SDTR message recieved
156MSG_WDTR = 0x51 # WDTR message recieved
157MSG_REJECT = 0x61 # Reject message recieved
158BAD_STATUS = 0x71 # Bad status from target
159RESIDUAL = 0x81 # Residual byte count != 0
160ABORT_TAG = 0x91 # Sent an ABORT_TAG message
161AWAITING_MSG = 0xa1 # Kernel requested to specify
162 # a message to this target
163 # (command was null), so tell
164 # it that it can fill the
165 # message buffer.
166IMMEDDONE = 0xb1
167
168
169# The host adapter card (at least the BIOS) uses 20-2f for SCSI
170# device information, 32-33 and 5a-5f as well. As it turns out, the
171# BIOS trashes 20-2f, writing the synchronous negotiation results
172# on top of the BIOS values, so we re-use those for our per-target
173# scratchspace (actually a value that can be copied directly into
174# SCSIRATE). The kernel driver will enable synchronous negotiation
175# for all targets that have a value other than 0 in the lower four
176# bits of the target scratch space. This should work regardless of
177# whether the bios has been installed. NEEDSDTR and NEEDWDTR are the
178# fouth and sevent bits of the SCB control byte. The kernel driver
179# will set these when a WDTR or SDTR message should be sent to the
180# target the SCB's command references.
181#
182# REJBYTE contains the first byte of a MESSAGE IN message, so the driver
183# can report an intelligible error if a message is rejected.
184#
185# FLAGS's high bit is true if we are currently handling a reselect;
186# its next-highest bit is true ONLY IF we've seen an IDENTIFY message
187# from the reselecting target. If we haven't had IDENTIFY, then we have
188# no idea what the lun is, and we can't select the right SCB register
189# bank, so force a kernel panic if the target attempts a data in/out or
190# command phase instead of corrupting something. FLAGS also contains
191# configuration bits so that we can optimize for TWIN and WIDE controllers,
192# the MAX_OFFSET bit which we set when we want to negotiate for maximum sync
193# offset irregardless of what the per target scratch space says.
194#
195# Note that SG_NEXT occupies four bytes.
196#
197SYNCNEG = 0x20
198
199REJBYTE = 0x31
200DISC_DSB_A = 0x32
201DISC_DSB_B = 0x33
202
203MSG_LEN = 0x34
204MSG_START+0 = 0x35
205MSG_START+1 = 0x36
206MSG_START+2 = 0x37
207MSG_START+3 = 0x38
208MSG_START+4 = 0x39
209MSG_START+5 = 0x3a
210-MSG_START+0 = 0xcb # 2's complement of MSG_START+0
211
212ARG_1 = 0x4a # sdtr conversion args & return
213BUS_16_BIT = 0x01
214RETURN_1 = 0x4a
215
216SIGSTATE = 0x4b # value written to SCSISIGO
217
218# Linux users should use 0xc (12) for SG_SIZEOF
219SG_SIZEOF = 0x8 # sizeof(struct ahc_dma)
220#SG_SIZEOF = 0xc # sizeof(struct scatterlist)
221SCB_SIZEOF = 0x1a # sizeof SCB to DMA (26 bytes)
222
223DMAPARAMS = 0x4c # Parameters for DMA
224SG_COUNT = 0x4d # working value of SG count
225SG_NEXT = 0x4e # working value of SG pointer
226SG_NEXT+0 = 0x4e
227SG_NEXT+1 = 0x4f
228SG_NEXT+2 = 0x50
229SG_NEXT+3 = 0x51
230
231SCBCOUNT = 0x52 # the actual number of SCBs
232FLAGS = 0x53 # Device configuration flags
233TWIN_BUS = 0x01
234WIDE_BUS = 0x02
235DPHASE = 0x04
236MAX_OFFSET = 0x08
237ACTIVE_MSG = 0x20
238IDENTIFY_SEEN = 0x40
239RESELECTED = 0x80
240
241MAX_OFFSET_8BIT = 0x0f
242MAX_OFFSET_WIDE = 0x08
243
244ACTIVE_A = 0x54
245ACTIVE_B = 0x55
246SAVED_TCL = 0x56 # Temporary storage for the
247 # target/channel/lun of a
248 # reconnecting target
249# After starting the selection hardware, we return to the "poll_for_work"
250# loop so that we can check for reconnecting targets as well as for our
251# selection to complete just in case the reselection wins bus arbitration.
252# The problem with this is that we must keep track of the SCB that we've
253# already pulled from the QINFIFO and started the selection on just in case
254# the reselection wins so that we can retry the selection at a later time.
255# This problem cannot be resolved by holding a single entry in scratch
256# ram since a reconnecting target can request sense and this will create
257# yet another SCB waiting for selection. The solution used here is to
258# use byte 31 of the SCB as a psuedo-next pointer and to thread a list
259# of SCBs that are awaiting selection. Since 0-0xfe are valid SCB offsets,
260# SCB_LIST_NULL is 0xff which is out of range. The kernel driver must
261# add an entry to this list everytime a request sense occurs. The sequencer
262# will automatically consume the entries.
263
264WAITING_SCBH = 0x57 # head of list of SCBs awaiting
265 # selection
266WAITING_SCBT = 0x58 # tail of list of SCBs awaiting
267 # selection
268SCB_LIST_NULL = 0xff
269
270
271# Poll QINCNT for work - the lower bits contain
272# the number of entries in the Queue In FIFO.
273#
72/*
73 * Initialize any state idle loop state here. This code is executed on
74 * startup and after every bus free.
75 */
76start:
77 mvi SCSISEQ,ENRSELI /* Always allow reselection */
274poll_for_work:
78poll_for_work:
275 test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device?
276# For fairness, we check the other bus first, since we just finished a
277# transaction on the current channel.
278 xor SBLKCTL,0x08 # Toggle to the other bus
79 /*
80 * Are we a twin channel device?
81 * For fairness, we check the other bus first,
82 * since we just finished a transaction on the
83 * current channel.
84 */
85 test FLAGS,TWIN_BUS jz start2
86 xor SBLKCTL,SELBUSB /* Toggle to the other bus */
279 test SSTAT0,SELDI jnz reselect
87 test SSTAT0,SELDI jnz reselect
280 xor SBLKCTL,0x08 # Toggle to the original bus
88 xor SBLKCTL,SELBUSB /* Toggle to the original bus */
281start2:
282 test SSTAT0,SELDI jnz reselect
283 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting
89start2:
90 test SSTAT0,SELDI jnz reselect
91 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting
284 test QINCNT,SCBMASK jz poll_for_work
92 test QINCNT,0xff jz poll_for_work
285
93
286# We have at least one queued SCB now and we don't have any
287# SCBs in the list of SCBs awaiting selection. Set the SCB
288# pointer from the FIFO so we see the right bank of SCB
289# registers, then set SCSI options and set the initiator and
290# target SCSI IDs.
291#
94/* We have at least one queued SCB now and we don't have any
95 * SCBs in the list of SCBs awaiting selection. Set the SCB
96 * pointer from the FIFO so we see the right bank of SCB
97 * registers.
98 */
292 mov SCBPTR,QINFIFO
293
99 mov SCBPTR,QINFIFO
100
294# If the control byte of this SCB has the NEEDDMA flag set, we have
295# yet to DMA it from host memory
101/*
102 * If the control byte of this SCB has the NEEDDMA flag set, we have
103 * yet to DMA it from host memory
104 */
296
105
297test SCBARRAY+0,NEEDDMA jz test_busy
298 clr HCNT+2
299 clr HCNT+1
300 mvi HCNT+0,SCB_SIZEOF
106test SCB_CONTROL,NEEDDMA jz test_busy
107 clr HCNT2
108 clr HCNT1
109 mvi HCNT0,SCB_SIZEOF
301
302 mvi DINDEX,HADDR
110
111 mvi DINDEX,HADDR
303 mvi SCBARRAY+26 call bcopy_4
112 mvi SCB_PHYSADDR call bcopy_4
304
113
305 mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET
114 mvi DFCNTRL,0xd /* HDMAEN|DIRECTION|FIFORESET */
306
115
307# Wait for DMA from host memory to data FIFO to complete, then disable
308# DMA and wait for it to acknowledge that it's off.
309#
116/*
117 * Wait for DMA from host memory to data FIFO to complete, then disable
118 * DMA and wait for it to acknowledge that it's off.
119 */
310 call dma_finish
311
120 call dma_finish
121
312# Copy the SCB from the FIFO to the SCBARRAY
122/* Copy the SCB from the FIFO to the SCBARRAY */
313
123
314 mvi DINDEX, SCBARRAY+0
124 mvi DINDEX, SCBARRAY
315 call bcopy_5_dfdat
316 call bcopy_7_dfdat
317 call bcopy_7_dfdat
318 call bcopy_7_dfdat
319
125 call bcopy_5_dfdat
126 call bcopy_7_dfdat
127 call bcopy_7_dfdat
128 call bcopy_7_dfdat
129
320# See if there is not already an active SCB for this target. This code
321# locks out on a per target basis instead of target/lun. Although this
322# is not ideal for devices that have multiple luns active at the same
323# time, it is faster than looping through all SCB's looking for active
324# commands. It may be benificial to make findscb a more general procedure
325# to see if the added cost of the search is negligible. This code also
326# assumes that the kernel driver will clear the active flags on board
327# initialization, board reset, and a target's SELTO.
130/*
131 * See if there is not already an active SCB for this target. This code
132 * locks out on a per target basis instead of target/lun. Although this
133 * is not ideal for devices that have multiple luns active at the same
134 * time, it is faster than looping through all SCB's looking for active
135 * commands. It may be benificial to make findscb a more general procedure
136 * to see if the added cost of the search is negligible. This code also
137 * assumes that the kernel driver will clear the active flags on board
138 * initialization, board reset, and a target SELTO. Tagged commands
139 * don't set the active bits since you can have more than queue more
140 * than one command at a time. We do, however, look to see if there
141 * are any non-tagged I/Os in progress, and requeue the command if
142 * there are. Tagged and non-tagged commands cannot be mixed to a
143 * single target.
144 */
328
329test_busy:
145
146test_busy:
330 and FUNCTION1,0x70,SCBARRAY+1
147 mov FUNCTION1,SCB_TCL
331 mov A,FUNCTION1
148 mov A,FUNCTION1
332 test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel
149 test SCB_TCL,0x88 jz test_a /* Id < 8 && A channel */
333
334 test ACTIVE_B,A jnz requeue
150
151 test ACTIVE_B,A jnz requeue
335 test SCBARRAY+0,TAG_ENB jnz start_scb
336 or ACTIVE_B,A # Mark the current target as busy
152 test SCB_CONTROL,TAG_ENB jnz start_scb
153 /* Mark the current target as busy */
154 or ACTIVE_B,A
337 jmp start_scb
338
155 jmp start_scb
156
339# Place the currently active back on the queue for later processing
157/* Place the currently active SCB back on the queue for later processing */
340requeue:
341 mov QINFIFO, SCBPTR
342 jmp poll_for_work
343
158requeue:
159 mov QINFIFO, SCBPTR
160 jmp poll_for_work
161
344# Pull the first entry off of the waiting for selection list
162/*
163 * Pull the first entry off of the waiting for selection list
164 * We don't have to "test_busy" because only transactions that
165 * have passed that test can be in the waiting_scb list.
166 */
345start_waiting:
346 mov SCBPTR,WAITING_SCBH
167start_waiting:
168 mov SCBPTR,WAITING_SCBH
347 jmp start_scb
169 jmp start_scb2
348
349test_a:
170
171test_a:
350 test ACTIVE_A,A jnz requeue
351 test SCBARRAY+0,TAG_ENB jnz start_scb
352 or ACTIVE_A,A # Mark the current target as busy
172 test ACTIVE_A,A jnz requeue
173 test SCB_CONTROL,TAG_ENB jnz start_scb
174 /* Mark the current target as busy */
175 or ACTIVE_A,A
353
354start_scb:
176
177start_scb:
355 and SINDEX,0xf7,SBLKCTL #Clear the channel select bit
356 and A,0x08,SCBARRAY+1 #Get new channel bit
357 or SINDEX,A
358 mov SBLKCTL,SINDEX # select channel
359 mov SCBARRAY+1 call initialize_scsiid
178 mov SCB_NEXT_WAITING,WAITING_SCBH
179 mov WAITING_SCBH, SCBPTR
180start_scb2:
181 and SINDEX,0xf7,SBLKCTL /* Clear the channel select bit */
182 and A,0x08,SCB_TCL /* Get new channel bit */
183 or SINDEX,A
184 mov SBLKCTL,SINDEX /* select channel */
185 mov SCB_TCL call initialize_scsiid
360
186
361# Enable selection phase as an initiator, and do automatic ATN
362# after the selection. We do this now so that we can overlap the
363# rest of our work to set up this target with the arbitration and
364# selection bus phases.
365#
187/*
188 * Enable selection phase as an initiator, and do automatic ATN
189 * after the selection. We do this now so that we can overlap the
190 * rest of our work to set up this target with the arbitration and
191 * selection bus phases.
192 */
366start_selection:
193start_selection:
367 or SCSISEQ,0x48 # ENSELO|ENAUTOATNO
368 mov WAITING_SCBH, SCBPTR
369 and FLAGS,0x3f # !RESELECTING
194 mvi SCSISEQ,0x58 /* ENSELO|ENAUTOATNO|ENRSELI */
370
195
371# As soon as we get a successful selection, the target should go
372# into the message out phase since we have ATN asserted. Prepare
373# the message to send, locking out the device driver. If the device
374# driver hasn't beaten us with an ABORT or RESET message, then tack
375# on an SDTR negotiation if required.
376#
377# Messages are stored in scratch RAM starting with a flag byte (high bit
378# set means active message), one length byte, and then the message itself.
379#
196/*
197 * As soon as we get a successful selection, the target should go
198 * into the message out phase since we have ATN asserted. Prepare
199 * the message to send.
200 *
201 * Messages are stored in scratch RAM starting with a length byte
202 * followed by the message itself.
203 */
204 test SCB_CMDLEN,0xff jnz mk_identify /* 0 Length Command? */
380
205
381 test SCBARRAY+11,0xff jnz identify # 0 Length Command?
382
383# The kernel has sent us an SCB with no command attached. This implies
384# that the kernel wants to send a message of some sort to this target,
385# so we interrupt the driver, allow it to fill the message buffer, and
386# then go back into the arbitration loop
206/*
207 * The kernel has sent us an SCB with no command attached. This implies
208 * that the kernel wants to send a message of some sort to this target,
209 * so we interrupt the driver, allow it to fill the message buffer, and
210 * then go back into the arbitration loop
211 */
387 mvi INTSTAT,AWAITING_MSG
388 jmp wait_for_selection
389
212 mvi INTSTAT,AWAITING_MSG
213 jmp wait_for_selection
214
390identify:
391 and A,DISCENB,SCBARRAY+0 # mask off disconnect privledge
215mk_identify:
216 and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */
392
217
393 and SINDEX,0x7,SCBARRAY+1 # lun
394 or SINDEX,A # or in disconnect privledge
395 or SINDEX,0x80 call mk_mesg # IDENTIFY message
218 and SINDEX,0x7,SCB_TCL /* lun */
219 or SINDEX,A /* or in disconnect privledge */
220 or SINDEX,MSG_IDENTIFY call mk_mesg /* IDENTIFY message */
396
221
397 mov A,SINDEX
398 test SCBARRAY+0,0xb0 jz !message # WDTR, SDTR or TAG??
399 cmp MSG_START+0,A jne !message # did driver beat us?
222 test SCB_CONTROL,0xb0 jz !message /* WDTR, SDTR or TAG?? */
223/*
224 * Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag
225 * value
226 */
400
227
401# Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag
402# value
403
404mk_tag:
228mk_tag:
405 mvi DINDEX, MSG_START+1
406 test SCBARRAY+0,TAG_ENB jz mk_tag_done
407 and A,0x23,SCBARRAY+0
229 mvi DINDEX, MSG1
230 test SCB_CONTROL,TAG_ENB jz mk_tag_done
231 and A,0x23,SCB_CONTROL
408 mov DINDIR,A
409 mov DINDIR,SCBPTR
410
232 mov DINDIR,A
233 mov DINDIR,SCBPTR
234
411 add MSG_LEN,-MSG_START+0,DINDEX # update message length
235 add MSG_LEN,COMP_MSG0,DINDEX /* update message length */
412
413mk_tag_done:
414
236
237mk_tag_done:
238
415 mov DINDEX call mk_dtr # build DTR message if needed
239 mov DINDEX call mk_dtr /* build DTR message if needed */
416
417!message:
418wait_for_selection:
240
241!message:
242wait_for_selection:
419 test SSTAT0,SELDI jnz reselect
420 test SSTAT0,SELDO jnz select
421 jmp wait_for_selection
243 test SSTAT0,SELDO jnz select
244 test SSTAT0,SELDI jz wait_for_selection
422
245
423# Reselection has been initiated by a target. Make a note that we've been
424# reselected, but haven't seen an IDENTIFY message from the target
425# yet.
426#
246/*
247 * Reselection has been initiated by a target. Make a note that we've been
248 * reselected, but haven't seen an IDENTIFY message from the target
249 * yet.
250 */
427reselect:
251reselect:
252 clr MSG_LEN /* Don't have anything in the mesg buffer */
428 mov SELID call initialize_scsiid
253 mov SELID call initialize_scsiid
429 and FLAGS,0x3f # reselected, no IDENTIFY
430 or FLAGS,RESELECTED jmp select2
254 mvi SAVED_TCL, 0xff /*
255 * Fill with an imposible value so we
256 * don't get false hits for a tag
257 * without an identify.
258 */
259 and FLAGS,0x03 /* clear target specific flags */
260 or FLAGS,RESELECTED
261 jmp select2
431
262
432# After the selection, remove this SCB from the "waiting for selection"
433# list. This is achieved by simply moving our "next" pointer into
434# WAITING_SCBH and setting our next pointer to null so that the next
435# time this SCB is used, we don't get confused.
436#
263/*
264 * After the selection, remove this SCB from the "waiting for selection"
265 * list. This is achieved by simply moving our "next" pointer into
266 * WAITING_SCBH. Our next pointer will be set to null the next time this
267 * SCB is used, so don't bother with it now.
268 */
437select:
269select:
438 or SCBARRAY+0,NEEDDMA
439 mov WAITING_SCBH,SCBARRAY+30
440 mvi SCBARRAY+30,SCB_LIST_NULL
270 and FLAGS,0x03 /* Clear target flags */
271 or SCB_CONTROL,NEEDDMA
272
273 /*
274 * Some drives will issue a simple tag message during
275 * a tagged selection if they are immediately ready
276 * to handle the command without a disconnect. Ensure
277 * that SAVED_TCL (used in get_tag) is inialized correctly
278 * during a selection for this reason.
279 */
280 mov SAVED_TCL, SCB_TCL
281 mov WAITING_SCBH,SCB_NEXT_WAITING
441select2:
282select2:
442 call initialize_for_target
443 mvi SCSISEQ,ENRSELI
444 mvi CLRSINT0,0x60 # CLRSELDI|CLRSELDO
445 mvi CLRSINT1,0x8 # CLRBUSFREE
283/*
284 * Set CLRCHN here before the target has entered a data transfer mode -
285 * with synchronous SCSI, if you do it later, you blow away some
286 * data in the SCSI FIFO that the target has already sent to you.
287 */
288 clr SIGSTATE
446
289
447# Main loop for information transfer phases. If BSY is false, then
448# we have a bus free condition, expected or not. Otherwise, wait
449# for the target to assert REQ before checking MSG, C/D and I/O
450# for the bus phase.
451#
452# We can't simply look at the values of SCSISIGI here (if we want
453# to do synchronous data transfer), because the target won't assert
454# REQ if it's already sent us some data that we haven't acknowledged
455# yet.
456#
290 or SXFRCTL0,CLRCHN
291/*
292 * Initialize SCSIRATE with the appropriate value for this target.
293 */
294 call ndx_dtr
295 mov SCSIRATE,SINDIR
296
297 mvi SCSISEQ,ENAUTOATNP /*
298 * ATN on parity errors
299 * for "in" phases
300 */
301 mvi CLRSINT1,CLRBUSFREE
302 mvi CLRSINT0,0x60 /* CLRSELDI|CLRSELDO */
303
304/*
305 * Main loop for information transfer phases. If BSY is false, then
306 * we have a bus free condition, expected or not. Otherwise, wait
307 * for the target to assert REQ before checking MSG, C/D and I/O
308 * for the bus phase.
309 *
310 */
457ITloop:
311ITloop:
458 test SSTAT1,0x8 jnz p_busfree # BUSFREE
459 test SSTAT1,0x1 jz ITloop # REQINIT
312 test SSTAT1,BUSFREE jnz p_busfree
313 test SSTAT1,REQINIT jz ITloop
460
314
461 and A,0xe0,SCSISIGI # CDI|IOI|MSGI
315 and A,PHASE_MASK,SCSISIGI
462
463 mov A call scsisig
464 cmp ALLZEROS,A je p_dataout
316
317 mov A call scsisig
318 cmp ALLZEROS,A je p_dataout
465 cmp A,0x40 je p_datain
466 cmp A,0x80 je p_command
467 cmp A,0xc0 je p_status
468 cmp A,0xa0 je p_mesgout
469 cmp A,0xe0 je p_mesgin
319 cmp A,P_DATAIN je p_datain
320 cmp A,P_COMMAND je p_command
321 cmp A,P_MESGOUT je p_mesgout
322 cmp A,P_STATUS je p_status
323 cmp A,P_MESGIN je p_mesgin
470
324
471 mvi INTSTAT,BAD_PHASE # unknown - signal driver
325 mvi INTSTAT,BAD_PHASE /* unknown phase - signal driver */
472
473p_dataout:
326
327p_dataout:
474 mvi DMAPARAMS,0x7d # WIDEODD|SCSIEN|SDMAEN|HDMAEN|
475 # DIRECTION|FIFORESET
328 mvi DMAPARAMS,0x7d /*
329 * WIDEODD|SCSIEN|SDMAEN|HDMAEN|
330 * DIRECTION|FIFORESET
331 */
476 jmp data_phase_init
477
332 jmp data_phase_init
333
478# If we re-enter the data phase after going through another phase, the
479# STCNT may have been cleared, so restore it from the residual field.
334/*
335 * If we re-enter the data phase after going through another phase, the
336 * STCNT may have been cleared, so restore it from the residual field.
337 */
480data_phase_reinit:
481 mvi DINDEX, STCNT
338data_phase_reinit:
339 mvi DINDEX, STCNT
482 mvi SCBARRAY+15 call bcopy_3
340 mvi SCB_RESID_DCNT call bcopy_3
483 jmp data_phase_loop
484
341 jmp data_phase_loop
342
485# Reads should not use WIDEODD since it may make the last byte for a SG segment
486# go to the next segment.
487p_datain:
343p_datain:
488 mvi DMAPARAMS,0x79 # WIDEODD|SCSIEN|SDMAEN|HDMAEN|
489 # !DIRECTION|FIFORESET
344 mvi DMAPARAMS,0x79 /*
345 * WIDEODD|SCSIEN|SDMAEN|HDMAEN|
346 * !DIRECTION|FIFORESET
347 */
490data_phase_init:
491 call assert
492
493 test FLAGS, DPHASE jnz data_phase_reinit
494 call sg_scb2ram
348data_phase_init:
349 call assert
350
351 test FLAGS, DPHASE jnz data_phase_reinit
352 call sg_scb2ram
495 or FLAGS, DPHASE # We have seen a data phase
353 or FLAGS, DPHASE /* We have seen a data phase */
496
497data_phase_loop:
354
355data_phase_loop:
498# If we are the last SG block, don't set wideodd.
356/* If we are the last SG block, don't set wideodd. */
499 cmp SG_COUNT,0x01 jne data_phase_wideodd
357 cmp SG_COUNT,0x01 jne data_phase_wideodd
500 and DMAPARAMS, 0xbf # Turn off WIDEODD
358 and DMAPARAMS, 0xbf /* Turn off WIDEODD */
501data_phase_wideodd:
502 mov DMAPARAMS call dma
503
359data_phase_wideodd:
360 mov DMAPARAMS call dma
361
504# Exit if we had an underrun
505 test SSTAT0,0x04 jz data_phase_finish # underrun STCNT != 0
362/* Exit if we had an underrun */
363 test SSTAT0,SDONE jz data_phase_finish /* underrun STCNT != 0 */
506
364
507# Advance the scatter-gather pointers if needed
508#
365/*
366 * Advance the scatter-gather pointers if needed
367 */
509sg_advance:
368sg_advance:
510 dec SG_COUNT # one less segment to go
369 dec SG_COUNT /* one less segment to go */
511
370
512 test SG_COUNT, 0xff jz data_phase_finish #Are we done?
371 test SG_COUNT, 0xff jz data_phase_finish /* Are we done? */
513
372
514 clr A # add sizeof(struct scatter)
515 add SG_NEXT+0,SG_SIZEOF,SG_NEXT+0
516 adc SG_NEXT+1,A,SG_NEXT+1
517 adc SG_NEXT+2,A,SG_NEXT+2
518 adc SG_NEXT+3,A,SG_NEXT+3
373 clr A /* add sizeof(struct scatter) */
374 add SG_NEXT0,SG_SIZEOF,SG_NEXT0
375 adc SG_NEXT1,A,SG_NEXT1
376 adc SG_NEXT2,A,SG_NEXT2
377 adc SG_NEXT3,A,SG_NEXT3
519
378
520# Load a struct scatter and set up the data address and length.
521# If the working value of the SG count is nonzero, then
522# we need to load a new set of values.
523#
524# This, like all DMA's, assumes a little-endian host data storage.
525#
379/*
380 * Load a struct scatter and set up the data address and length.
381 * If the working value of the SG count is nonzero, then
382 * we need to load a new set of values.
383 *
384 * This, like all DMA's, assumes a little-endian host data storage.
385 */
526sg_load:
386sg_load:
527 clr HCNT+2
528 clr HCNT+1
529 mvi HCNT+0,SG_SIZEOF
387 clr HCNT2
388 clr HCNT1
389 mvi HCNT0,SG_SIZEOF
530
531 mvi DINDEX,HADDR
532 mvi SG_NEXT call bcopy_4
533
390
391 mvi DINDEX,HADDR
392 mvi SG_NEXT call bcopy_4
393
534 mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET
394 mvi DFCNTRL,0xd /* HDMAEN|DIRECTION|FIFORESET */
535
395
536# Wait for DMA from host memory to data FIFO to complete, then disable
537# DMA and wait for it to acknowledge that it's off.
538#
396/*
397 * Wait for DMA from host memory to data FIFO to complete, then disable
398 * DMA and wait for it to acknowledge that it's off.
399 */
539 call dma_finish
540
400 call dma_finish
401
541# Copy data from FIFO into SCB data pointer and data count. This assumes
542# that the struct scatterlist has this structure (this and sizeof(struct
543# scatterlist) == 12 are asserted in aic7xxx.c):
544#
545# struct scatterlist {
546# char *address; /* four bytes, little-endian order */
547# ... /* four bytes, ignored */
548# unsigned short length; /* two bytes, little-endian order */
549# }
550#
402/*
403 * Copy data from FIFO into SCB data pointer and data count. This assumes
404 * that the struct scatterlist has this structure (this and sizeof(struct
405 * scatterlist) == 12 are asserted in aic7xxx.c):
406 *
407 * struct scatterlist {
408 * char *address; four bytes, little-endian order
409 * ... four bytes, ignored
410 * unsigned short length; two bytes, little-endian order
411 * }
412 *
413 *
414 * Not in FreeBSD. the scatter list entry is only 8 bytes.
415 *
416 * struct ahc_dma_seg {
417 * physaddr addr; four bytes, little-endian order
418 * long len; four bytes, little endian order
419 * };
420 */
551
421
552# Not in FreeBSD. the scatter list entry is only 8 bytes.
553#
554# struct ahc_dma_seg {
555# physaddr addr; /* four bytes, little-endian order */
556# long len; /* four bytes, little endian order */
557# };
558#
559
422/*
423 * For Linux, we must throw away four bytes since there is a 32bit gap
424 * in the middle of a struct scatterlist
425 */
426#ifdef LINUX
427 call bcopy_4_dfdat
428 mov NONE,DFDAT
429 mov NONE,DFDAT
430 mov NONE,DFDAT
431 mov NONE,DFDAT
432 call bcopy_3_dfdat /* Only support 24 bit length. */
433#else
434/*
435 * For FreeBSD, just copy it wholesale
436 */
560 mvi DINDEX,HADDR
561 call bcopy_7_dfdat
437 mvi DINDEX,HADDR
438 call bcopy_7_dfdat
439#endif
562
440
563# For Linux, we must throw away four bytes since there is a 32bit gap
564# in the middle of a struct scatterlist
565# call bcopy_4_dfdat
566# mov NONE,DFDAT
567# mov NONE,DFDAT
568# mov NONE,DFDAT
569# mov NONE,DFDAT
570# call bcopy_3_dfdat #Only support 24 bit length.
571
572# Load STCNT as well. It is a mirror of HCNT
441/* Load STCNT as well. It is a mirror of HCNT */
573 mvi DINDEX,STCNT
574 mvi HCNT call bcopy_3
575 test SSTAT1,PHASEMIS jz data_phase_loop
576
577data_phase_finish:
442 mvi DINDEX,STCNT
443 mvi HCNT call bcopy_3
444 test SSTAT1,PHASEMIS jz data_phase_loop
445
446data_phase_finish:
578# After a DMA finishes, save the SG and STCNT residuals back into the SCB
579# We use STCNT instead of HCNT, since it's a reflection of how many bytes
580# were transferred on the SCSI (as opposed to the host) bus.
581#
582 mvi DINDEX,SCBARRAY+15
583 mvi STCNT call bcopy_3
584 mov SCBARRAY+18, SG_COUNT
447/*
448 * After a DMA finishes, save the SG and STCNT residuals back into the SCB
449 * We use STCNT instead of HCNT, since it's a reflection of how many bytes
450 * were transferred on the SCSI (as opposed to the host) bus.
451 */
452 mvi DINDEX,SCB_RESID_DCNT
453 mvi STCNT call bcopy_3
454 mov SCB_RESID_SGCNT, SG_COUNT
585 jmp ITloop
586
455 jmp ITloop
456
587# Command phase. Set up the DMA registers and let 'er rip - the
588# two bytes after the SCB SCSI_cmd_length are zeroed by the driver,
589# so we can copy those three bytes directly into HCNT.
590#
457/*
458 * Command phase. Set up the DMA registers and let 'er rip - the
459 * two bytes after the SCB SCSI_cmd_length are zeroed by the driver,
460 * so we can copy those three bytes directly into HCNT.
461 */
591p_command:
592 call assert
593
462p_command:
463 call assert
464
594# Load HADDR and HCNT. We can do this in one bcopy since they are neighbors
465/*
466 * Load HADDR and HCNT. We can do this in one bcopy since they are neighbors
467 */
595 mvi DINDEX,HADDR
468 mvi DINDEX,HADDR
596 mvi SCBARRAY+7 call bcopy_7
469 mvi SCB_CMDPTR call bcopy_7
597
598 mvi DINDEX,STCNT
470
471 mvi DINDEX,STCNT
599 mvi SCBARRAY+11 call bcopy_3
472 mvi SCB_CMDLEN call bcopy_3
600
601 mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN|
602 # DIRECTION|FIFORESET
603 jmp ITloop
604
473
474 mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN|
475 # DIRECTION|FIFORESET
476 jmp ITloop
477
605# Status phase. Wait for the data byte to appear, then read it
606# and store it into the SCB.
607#
478/*
479 * Status phase. Wait for the data byte to appear, then read it
480 * and store it into the SCB.
481 */
608p_status:
482p_status:
609
610 mvi SCBARRAY+14 call inb_first
483 mvi SCB_TARGET_STATUS call inb_first
611 jmp mesgin_done
612
484 jmp mesgin_done
485
613# Message out phase. If there is no active message, but the target
614# took us into this phase anyway, build a no-op message and send it.
615#
486/*
487 * Message out phase. If there is no active message, but the target
488 * took us into this phase anyway, build a no-op message and send it.
489 */
616p_mesgout:
490p_mesgout:
617 mvi 0x8 call mk_mesg # build NOP message
491 test MSG_LEN, 0xff jnz p_mesgout_start
492 mvi MSG_NOP call mk_mesg /* build NOP message */
618
493
619 clr STCNT+2
620 clr STCNT+1
621
622# Set up automatic PIO transfer from MSG_START. Bit 3 in
623# SXFRCTL0 (SPIOEN) is already on.
624#
625 mvi SINDEX,MSG_START+0
494p_mesgout_start:
495/*
496 * Set up automatic PIO transfer from MSG0. Bit 3 in
497 * SXFRCTL0 (SPIOEN) is already on.
498 */
499 mvi SINDEX,MSG0
626 mov DINDEX,MSG_LEN
627
500 mov DINDEX,MSG_LEN
501
628# When target asks for a byte, drop ATN if it's the last one in
629# the message. Otherwise, keep going until the message is exhausted.
630# (We can't use outb for this since it wants the input in SINDEX.)
631#
632# Keep an eye out for a phase change, in case the target issues
633# a MESSAGE REJECT.
634#
635p_mesgout2:
636 test SSTAT0,0x2 jz p_mesgout2 # SPIORDY
637 test SSTAT1,0x10 jnz p_mesgout6 # PHASEMIS
638
639 cmp DINDEX,1 jne p_mesgout3 # last byte?
640 mvi CLRSINT1,0x40 # CLRATNO - drop ATN
641
642# Write a byte to the SCSI bus. The AIC-7770 refuses to automatically
643# send ACKs in automatic PIO or DMA mode unless you make sure that the
644# "expected" bus phase in SCSISIGO matches the actual bus phase. This
645# behaviour is completely undocumented and caused me several days of
646# grief.
647#
648# After plugging in different drives to test with and using a longer
649# SCSI cable, I found that I/O in Automatic PIO mode ceased to function,
650# especially when transferring >1 byte. It seems to be much more stable
651# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is
652# polled for transfer completion - for both output _and_ input. The
653# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL
654# is accessed (like the documentation says it does), and that on a longer
655# cable run, the sequencer code was fast enough to loop back and see
656# an SPIORDY that hadn't dropped yet.
657#
658p_mesgout3:
659 mvi STCNT+0, 0x01
502/*
503 * When target asks for a byte, drop ATN if it's the last one in
504 * the message. Otherwise, keep going until the message is exhausted.
505 *
506 * Keep an eye out for a phase change, in case the target issues
507 * a MESSAGE REJECT.
508 */
509p_mesgout_loop:
510 test SSTAT0,SPIORDY jz p_mesgout_loop
511 cmp DINDEX,1 jne p_mesgout_outb /* last byte? */
512 mvi CLRSINT1,CLRATNO /* drop ATN */
513p_mesgout_outb:
514 test SSTAT1,PHASEMIS jnz p_mesgout_phasemis
515 dec DINDEX
660 mov SCSIDATL,SINDIR
516 mov SCSIDATL,SINDIR
661
662p_mesgout4:
517p_mesgout4:
663 test SSTAT0,0x4 jz p_mesgout4 # SDONE
664 dec DINDEX
665 test DINDEX,0xff jnz p_mesgout2
518 test DINDEX,0xff jnz p_mesgout_loop
666
519
667# If the next bus phase after ATN drops is a message out, it means
668# that the target is requesting that the last message(s) be resent.
669#
670p_mesgout5:
671 test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE
672 test SSTAT1,0x1 jz p_mesgout5 # REQINIT
520/*
521 * If the next bus phase after ATN drops is a message out, it means
522 * that the target is requesting that the last message(s) be resent.
523 */
524p_mesgout_snoop:
525 test SSTAT1,BUSFREE jnz p_mesgout_done
526 test SSTAT1,REQINIT jz p_mesgout_snoop
673
527
674 and A,0xe0,SCSISIGI # CDI|IOI|MSGI
675 cmp A,0xa0 jne p_mesgout6
676 or SINDEX,0x10,SIGSTATE # turn on ATNO
677 call scsisig # ATNO - re-assert ATN
528 test SSTAT1,PHASEMIS jnz p_mesgout_done
678
529
530 or SINDEX,0x10,SIGSTATE /* turn on ATNO */
531 call scsisig /* ATNO - re-assert ATN */
532
679 jmp ITloop
680
533 jmp ITloop
534
681p_mesgout6:
682 mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS
683 and FLAGS,0xdf # no active msg
535p_mesgout_phasemis:
536 mvi CLRSINT1,CLRATNO /* Be sure turn ATNO off */
537p_mesgout_done:
538 clr MSG_LEN /* no active msg */
684 jmp ITloop
685
539 jmp ITloop
540
686# Message in phase. Bytes are read using Automatic PIO mode, but not
687# using inb. This alleviates a race condition, namely that if ATN had
688# to be asserted under Automatic PIO mode, it had to beat the SCSI
689# circuitry sending an ACK to the target. This showed up under heavy
690# loads and really confused things, since ABORT commands wouldn't be
691# seen by the drive after an IDENTIFY message in until it had changed
692# to a data I/O phase.
693#
541/*
542 * Message in phase. Bytes are read using Automatic PIO mode.
543 */
694p_mesgin:
544p_mesgin:
695 mvi A call inb_first # read the 1st message byte
696 mvi REJBYTE,A # save it for the driver
545 mvi A call inb_first /* read the 1st message byte */
546 mov REJBYTE,A /* save it for the driver */
697
547
698 test A,0x80 jnz mesgin_identify # identify message?
699 cmp A,4 je mesgin_disconnect # disconnect?
700 cmp A,2 je mesgin_sdptrs # save data pointers?
701 cmp ALLZEROS,A je mesgin_complete # command complete?
702 cmp A,3 je mesgin_rdptrs # restore pointers code?
703 cmp A,1 je mesgin_extended # extended message?
704 cmp A,7 je mesgin_reject # message reject code?
548 test A,MSG_IDENTIFY jnz mesgin_identify
549 cmp A,MSG_DISCONNECT je mesgin_disconnect
550 cmp A,MSG_SDPTRS je mesgin_sdptrs
551 cmp ALLZEROS,A je mesgin_complete
552 cmp A,MSG_RDPTRS je mesgin_rdptrs
553 cmp A,MSG_EXTENDED je mesgin_extended
554 cmp A,MSG_REJECT je mesgin_reject
705
706rej_mesgin:
555
556rej_mesgin:
707# We have no idea what this message in is, and there's no way
708# to pass it up to the kernel, so we issue a message reject and
709# hope for the best. Since we're now using manual PIO mode to
710# read in the message, there should no longer be a race condition
711# present when we assert ATN. In any case, rejection should be a
712# rare occurrence - signal the driver when it happens.
713#
714 or SINDEX,0x10,SIGSTATE # turn on ATNO
557/*
558 * We have no idea what this message in is, and there's no way
559 * to pass it up to the kernel, so we issue a message reject and
560 * hope for the best. Since we're now using manual PIO mode to
561 * read in the message, there should no longer be a race condition
562 * present when we assert ATN. In any case, rejection should be a
563 * rare occurrence - signal the driver when it happens.
564 */
565 or SINDEX,0x10,SIGSTATE /* turn on ATNO */
715 call scsisig
566 call scsisig
716 mvi INTSTAT,SEND_REJECT # let driver know
567 mvi INTSTAT,SEND_REJECT /* let driver know */
717
568
718 mvi 0x7 call mk_mesg # MESSAGE REJECT message
569 mvi MSG_REJECT call mk_mesg
719
720mesgin_done:
570
571mesgin_done:
721 call inb_last # ack & turn auto PIO back on
572 call inb_last /*ack & turn auto PIO back on*/
722 jmp ITloop
723
724
725mesgin_complete:
573 jmp ITloop
574
575
576mesgin_complete:
726# We got a "command complete" message, so put the SCB pointer
727# into the Queue Out, and trigger a completion interrupt.
728# Check status for non zero return and interrupt driver if needed
729# This allows the driver to interpret errors only when they occur
730# instead of always uploading the scb. If the status is SCSI_CHECK,
731# the driver will download a new scb requesting sense to replace
732# the old one, modify the "waiting for selection" SCB list and set
733# RETURN_1 to 0x80. If RETURN_1 is set to 0x80 the sequencer imediately
734# jumps to main loop where it will run down the waiting SCB list.
735# If the kernel driver does not wish to request sense, it need
736# only clear RETURN_1, and the command is allowed to complete. We don't
737# bother to post to the QOUTFIFO in the error case since it would require
738# extra work in the kernel driver to ensure that the entry was removed
739# before the command complete code tried processing it.
577/*
578 * We got a "command complete" message, so put the SCB pointer
579 * into the Queue Out, and trigger a completion interrupt.
580 * Check status for non zero return and interrupt driver if needed
581 * This allows the driver to interpret errors only when they occur
582 * instead of always uploading the scb. If the status is SCSI_CHECK,
583 * the driver will download a new scb requesting sense to replace
584 * the old one, modify the "waiting for selection" SCB list and set
585 * RETURN_1 to 0x80. If RETURN_1 is set to 0x80 the sequencer imediately
586 * jumps to main loop where it will run down the waiting SCB list.
587 * If the kernel driver does not wish to request sense, it need
588 * only clear RETURN_1, and the command is allowed to complete. We don't
589 * bother to post to the QOUTFIFO in the error case since it would require
590 * extra work in the kernel driver to ensure that the entry was removed
591 * before the command complete code tried processing it.
592 *
593 * First check for residuals
594 */
595 test SCB_RESID_SGCNT,0xff jz check_status
596/*
597 * If we have a residual count, interrupt and tell the host. Other
598 * alternatives are to pause the sequencer on all command completes (yuck),
599 * dma the resid directly to the host (slick, we may have space to do it now)
600 * or have the sequencer pause itself when it encounters a non-zero resid
601 * (unecessary pause just to flag the command -yuck-, but takes one instruction
602 * and since it shouldn't happen that often is good enough for our purposes).
603 */
604resid:
605 mvi INTSTAT,RESIDUAL
740
606
741# First check for residuals
742 test SCBARRAY+18,0xff jnz resid
743
744check_status:
607check_status:
745 test SCBARRAY+14,0xff jz status_ok # 0 Status?
746 mvi INTSTAT,BAD_STATUS # let driver know
747 test RETURN_1, 0x80 jz status_ok
608 test SCB_TARGET_STATUS,0xff jz status_ok /* Good Status? */
609 mvi INTSTAT,BAD_STATUS /* let driver know */
610 cmp RETURN_1, SEND_SENSE jne status_ok
748 jmp mesgin_done
749
750status_ok:
611 jmp mesgin_done
612
613status_ok:
751# First, mark this target as free.
752 test SCBARRAY+0,TAG_ENB jnz complete # Tagged command
753 and FUNCTION1,0x70,SCBARRAY+1
614/* First, mark this target as free. */
615 test SCB_CONTROL,TAG_ENB jnz test_immediate /*
616 * Tagged commands
617 * don't busy the
618 * target.
619 */
620 mov FUNCTION1,SCB_TCL
754 mov A,FUNCTION1
621 mov A,FUNCTION1
755 test SCBARRAY+1,0x88 jz clear_a
622 test SCB_TCL,0x88 jz clear_a
756 xor ACTIVE_B,A
623 xor ACTIVE_B,A
757 jmp immediate
624 jmp test_immediate
758
759clear_a:
760 xor ACTIVE_A,A
761
625
626clear_a:
627 xor ACTIVE_A,A
628
762immediate:
763 test SCBARRAY+11,0xff jnz complete # Immediate message complete
764# Pause the sequencer until the driver gets around to handling the command
765# complete. This is so that any action that might require carefull timing
766# with the completion of this command can occur.
629test_immediate:
630 test SCB_CMDLEN,0xff jnz complete /* Immediate message complete */
631/*
632 * Pause the sequencer until the driver gets around to handling the command
633 * complete. This is so that any action that might require carefull timing
634 * with the completion of this command can occur.
635 */
767 mvi INTSTAT,IMMEDDONE
636 mvi INTSTAT,IMMEDDONE
768 jmp poll_for_work
637 jmp start
769complete:
770 mov QOUTFIFO,SCBPTR
771 mvi INTSTAT,CMDCMPLT
772 jmp mesgin_done
773
638complete:
639 mov QOUTFIFO,SCBPTR
640 mvi INTSTAT,CMDCMPLT
641 jmp mesgin_done
642
774# If we have a residual count, interrupt and tell the host. Other
775# alternatives are to pause the sequencer on all command completes (yuck),
776# dma the resid directly to the host (slick, but a ton of instructions), or
777# have the sequencer pause itself when it encounters a non-zero resid
778# (unecessary pause just to flag the command -- yuck, but takes few instructions
779# and since it shouldn't happen that often is good enough for our purposes).
780
643
781resid:
782 mvi INTSTAT,RESIDUAL
783 jmp check_status
784
785# Is it an extended message? We only support the synchronous and wide data
786# transfer request messages, which will probably be in response to
787# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -
788# apparently this can be done after any message in byte, according
789# to the SCSI-2 spec.
790#
644/*
645 * Is it an extended message? We only support the synchronous and wide data
646 * transfer request messages, which will probably be in response to
647 * WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it -
648 * apparently this can be done after any message in byte, according
649 * to the SCSI-2 spec.
650 */
791mesgin_extended:
651mesgin_extended:
792 mvi ARG_1 call inb_next # extended message length
793 mvi A call inb_next # extended message code
652 mvi ARG_1 call inb_next /* extended message length */
653 mvi A call inb_next /* extended message code */
794
654
795 cmp A,1 je p_mesginSDTR # Syncronous negotiation message
796 cmp A,3 je p_mesginWDTR # Wide negotiation message
655 cmp A,MSG_SDTR je p_mesginSDTR
656 cmp A,MSG_WDTR je p_mesginWDTR
797 jmp rej_mesgin
798
799p_mesginWDTR:
657 jmp rej_mesgin
658
659p_mesginWDTR:
800 cmp ARG_1,2 jne rej_mesgin # extended mesg length=2
801 mvi A call inb_next # Width of bus
802 mvi INTSTAT,MSG_WDTR # let driver know
803 test RETURN_1,0x80 jz mesgin_done# Do we need to send WDTR?
660 cmp ARG_1,2 jne rej_mesgin /* extended mesg length=2 */
661 mvi ARG_1 call inb_next /* Width of bus */
662 mvi INTSTAT,WDTR_MSG /* let driver know */
663 test RETURN_1,0xff jz mesgin_done /* Do we need to send WDTR? */
664 cmp RETURN_1,SEND_REJ je rej_mesgin /*
665 * Bus width was too large
666 * Reject it.
667 */
804
668
805# We didn't initiate the wide negotiation, so we must respond to the request
806 and RETURN_1,0x7f # Clear the SEND_WDTR Flag
807 or FLAGS,ACTIVE_MSG
808 mvi DINDEX,MSG_START+0
809 mvi MSG_START+0 call mk_wdtr # build WDTR message
810 or SINDEX,0x10,SIGSTATE # turn on ATNO
669/* We didn't initiate the wide negotiation, so we must respond to the request */
670 and RETURN_1,0x7f /* Clear the SEND_WDTR Flag */
671 mvi DINDEX,MSG0
672 mvi MSG0 call mk_wdtr /* build WDTR message */
673 or SINDEX,0x10,SIGSTATE /* turn on ATNO */
811 call scsisig
812 jmp mesgin_done
813
814p_mesginSDTR:
674 call scsisig
675 jmp mesgin_done
676
677p_mesginSDTR:
815 cmp ARG_1,3 jne rej_mesgin # extended mesg length=3
816 mvi ARG_1 call inb_next # xfer period
817 mvi A call inb_next # REQ/ACK offset
818 mvi INTSTAT,MSG_SDTR # call driver to convert
678 cmp ARG_1,3 jne rej_mesgin /* extended mesg length=3 */
679 mvi ARG_1 call inb_next /* xfer period */
680 mvi A call inb_next /* REQ/ACK offset */
681 mvi INTSTAT,SDTR_MSG /* call driver to convert */
819
682
820 test RETURN_1,0xc0 jz mesgin_done# Do we need to mk_sdtr or rej?
821 test RETURN_1,0x40 jnz rej_mesgin # Requested SDTR too small - rej
822 or FLAGS,ACTIVE_MSG
823 mvi DINDEX, MSG_START+0
824 mvi MSG_START+0 call mk_sdtr
825 or SINDEX,0x10,SIGSTATE # turn on ATNO
683 test RETURN_1,0xff jz mesgin_done /* Do we need to mk_sdtr/rej */
684 cmp RETURN_1,SEND_REJ je rej_mesgin /*
685 * Requested SDTR too small
686 * Reject it.
687 */
688 mvi DINDEX, MSG0
689 mvi MSG0 call mk_sdtr
690 or SINDEX,0x10,SIGSTATE /* turn on ATNO */
826 call scsisig
827 jmp mesgin_done
828
691 call scsisig
692 jmp mesgin_done
693
829# Is it a disconnect message? Set a flag in the SCB to remind us
830# and await the bus going free.
831#
694/*
695 * Is it a disconnect message? Set a flag in the SCB to remind us
696 * and await the bus going free.
697 */
832mesgin_disconnect:
698mesgin_disconnect:
833 or SCBARRAY+0,DISCONNECTED
699 or SCB_CONTROL,DISCONNECTED
834 jmp mesgin_done
835
700 jmp mesgin_done
701
836# Save data pointers message? Copy working values into the SCB,
837# usually in preparation for a disconnect.
838#
702/*
703 * Save data pointers message? Copy working values into the SCB,
704 * usually in preparation for a disconnect.
705 */
839mesgin_sdptrs:
840 call sg_ram2scb
841 jmp mesgin_done
842
706mesgin_sdptrs:
707 call sg_ram2scb
708 jmp mesgin_done
709
843# Restore pointers message? Data pointers are recopied from the
844# SCB anytime we enter a data phase for the first time, so all
845# we need to do is clear the DPHASE flag and let the data phase
846# code do the rest.
847#
710/*
711 * Restore pointers message? Data pointers are recopied from the
712 * SCB anytime we enter a data phase for the first time, so all
713 * we need to do is clear the DPHASE flag and let the data phase
714 * code do the rest.
715 */
848mesgin_rdptrs:
716mesgin_rdptrs:
849 and FLAGS,0xfb # !DPHASE we'll reload them
850 # the next time through
717 and FLAGS,0xfb /*
718 * !DPHASE we'll reload them
719 * the next time through
720 */
851 jmp mesgin_done
852
721 jmp mesgin_done
722
853# Identify message? For a reconnecting target, this tells us the lun
854# that the reconnection is for - find the correct SCB and switch to it,
855# clearing the "disconnected" bit so we don't "find" it by accident later.
856#
723/*
724 * Identify message? For a reconnecting target, this tells us the lun
725 * that the reconnection is for - find the correct SCB and switch to it,
726 * clearing the "disconnected" bit so we don't "find" it by accident later.
727 */
857mesgin_identify:
728mesgin_identify:
858 test A,0x78 jnz rej_mesgin # !DiscPriv|!LUNTAR|!Reserved
729 test A,0x78 jnz rej_mesgin /*!DiscPriv|!LUNTAR|!Reserved*/
859
730
860 and A,0x07 # lun in lower three bits
731 and A,0x07 /* lun in lower three bits */
861 or SAVED_TCL,A,SELID
862 and SAVED_TCL,0xf7
732 or SAVED_TCL,A,SELID
733 and SAVED_TCL,0xf7
863 and A,0x08,SBLKCTL # B Channel??
734 and A,SELBUSB,SBLKCTL /* B Channel?? */
864 or SAVED_TCL,A
735 or SAVED_TCL,A
865 call inb_last # ACK
866 mov ALLZEROS call findSCB
867setup_SCB:
868 and SCBARRAY+0,0xfb # clear disconnect bit in SCB
869 or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY
736 call inb_last /* ACK */
870
737
738/*
739 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
740 * If we get one, we use the tag returned to switch to the proper
741 * SCB. Otherwise, we just use the findSCB method.
742 */
743snoop_tag_loop:
744 test SSTAT1,BUSFREE jnz use_findSCB
745 test SSTAT1,REQINIT jz snoop_tag_loop
746 test SSTAT1,PHASEMIS jnz use_findSCB
747 mvi A call inb_first
748 cmp A,MSG_SIMPLE_TAG je get_tag
749use_findSCB:
750 mov ALLZEROS call findSCB /* Have to search */
751setup_SCB:
752 and SCB_CONTROL,0xfb /* clear disconnect bit in SCB */
753 or FLAGS,IDENTIFY_SEEN /* make note of IDENTIFY */
871 jmp ITloop
872get_tag:
754 jmp ITloop
755get_tag:
873 mvi A call inb_first
874 cmp A,0x20 jne return # Simple Tag message?
875 mvi A call inb_next
876 call inb_last
877 test A,0xf0 jnz abort_tag # Tag in range?
878 mov SCBPTR,A
756 mvi ARG_1 call inb_next /* tag value */
757/*
758 * See if the tag is in range. The tag is < SCBCOUNT if we add
759 * the complement of SCBCOUNT to the incomming tag and there is
760 * no carry.
761 */
762 mov A,COMP_SCBCOUNT
763 add SINDEX,A,ARG_1
764 jc abort_tag
765
766/*
767 * Ensure that the SCB the tag points to is for an SCB transaction
768 * to the reconnecting target.
769 */
770 mov SCBPTR,ARG_1
879 mov A,SAVED_TCL
771 mov A,SAVED_TCL
880 cmp SCBARRAY+1,A jne abort_tag
881 test SCBARRAY+0,TAG_ENB jz abort_tag
882 ret
772 cmp SCB_TCL,A jne abort_tag
773 test SCB_CONTROL,TAG_ENB jz abort_tag
774 call inb_last /* Ack Successful tag */
775 jmp setup_SCB
883abort_tag:
776abort_tag:
884 or SINDEX,0x10,SIGSTATE # turn on ATNO
777 or SINDEX,0x10,SIGSTATE /* turn on ATNO */
885 call scsisig
778 call scsisig
886 mvi INTSTAT,ABORT_TAG # let driver know
887 mvi 0xd call mk_mesg # ABORT TAG message
888 ret
779 mvi INTSTAT,ABORT_TAG /* let driver know */
780 mvi 0xd call mk_mesg /* ABORT TAG message */
781 jmp mesgin_done
889
782
890# Message reject? Let the kernel driver handle this. If we have an
891# outstanding WDTR or SDTR negotiation, assume that it's a response from
892# the target selecting 8bit or asynchronous transfer, otherwise just ignore
893# it since we have no clue what it pertains to.
894#
783/*
784 * Message reject? Let the kernel driver handle this. If we have an
785 * outstanding WDTR or SDTR negotiation, assume that it's a response from
786 * the target selecting 8bit or asynchronous transfer, otherwise just ignore
787 * it since we have no clue what it pertains to.
788 */
895mesgin_reject:
789mesgin_reject:
896 mvi INTSTAT, MSG_REJECT
790 mvi INTSTAT, REJECT_MSG
897 jmp mesgin_done
898
791 jmp mesgin_done
792
899# [ ADD MORE MESSAGE HANDLING HERE ]
900#
793/*
794 * [ ADD MORE MESSAGE HANDLING HERE ]
795 */
901
796
902# Bus free phase. It might be useful to interrupt the device
903# driver if we aren't expecting this. For now, make sure that
904# ATN isn't being asserted and look for a new command.
905#
797/*
798 * Bus free phase. It might be useful to interrupt the device
799 * driver if we aren't expecting this. For now, make sure that
800 * ATN isn't being asserted and look for a new command.
801 */
906p_busfree:
802p_busfree:
907 mvi CLRSINT1,0x40 # CLRATNO
908 clr SIGSTATE
803 mvi CLRSINT1,CLRATNO
909
804
910# if this is an immediate command, perform a psuedo command complete to
911# notify the driver.
912 test SCBARRAY+11,0xff jz status_ok
913 jmp poll_for_work
805/*
806 * if this is an immediate command, perform a psuedo command complete to
807 * notify the driver.
808 */
809 test SCB_CMDLEN,0xff jz status_ok
810 jmp start
914
811
915# Instead of a generic bcopy routine that requires an argument, we unroll
916# the cases that are actually used, and call them explicitly. This
917# not only reduces the overhead of doing a bcopy, but ends up saving space
918# in the program since you don't have to put the argument into the accumulator
919# before the call. Both functions expect DINDEX to contain the destination
920# address and SINDEX to contain the source address.
812/*
813 * Instead of a generic bcopy routine that requires an argument, we unroll
814 * the cases that are actually used, and call them explicitly. This
815 * not only reduces the overhead of doing a bcopy, but ends up saving space
816 * in the program since you don't have to put the argument into the accumulator
817 * before the call. Both functions expect DINDEX to contain the destination
818 * address and SINDEX to contain the source address.
819 */
921bcopy_7:
922 mov DINDIR,SINDIR
923 mov DINDIR,SINDIR
924bcopy_5:
925 mov DINDIR,SINDIR
926bcopy_4:
927 mov DINDIR,SINDIR
928bcopy_3:

--- 8 unchanged lines hidden (view full) ---

937 mov DINDIR,DFDAT
938bcopy_4_dfdat:
939 mov DINDIR,DFDAT
940bcopy_3_dfdat:
941 mov DINDIR,DFDAT
942 mov DINDIR,DFDAT
943 mov DINDIR,DFDAT ret
944
820bcopy_7:
821 mov DINDIR,SINDIR
822 mov DINDIR,SINDIR
823bcopy_5:
824 mov DINDIR,SINDIR
825bcopy_4:
826 mov DINDIR,SINDIR
827bcopy_3:

--- 8 unchanged lines hidden (view full) ---

836 mov DINDIR,DFDAT
837bcopy_4_dfdat:
838 mov DINDIR,DFDAT
839bcopy_3_dfdat:
840 mov DINDIR,DFDAT
841 mov DINDIR,DFDAT
842 mov DINDIR,DFDAT ret
843
945# Locking the driver out, build a one-byte message passed in SINDEX
946# if there is no active message already. SINDEX is returned intact.
947#
844/*
845 * Locking the driver out, build a one-byte message passed in SINDEX
846 * if there is no active message already. SINDEX is returned intact.
847 */
948mk_mesg:
848mk_mesg:
949 mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE
950 test FLAGS,ACTIVE_MSG jnz mk_mesg1 # active message?
849 mvi SEQCTL,0x50 /* PAUSEDIS|FASTMODE */
850 test MSG_LEN,0xff jz mk_mesg1 /* Should always succeed */
851
852 /*
853 * Hmmm. For some reason the mesg buffer is in use.
854 * Tell the driver. It should look at SINDEX to find
855 * out what we wanted to use the buffer for and resolve
856 * the conflict.
857 */
858 mvi SEQCTL,0x10 /* !PAUSEDIS|FASTMODE */
859 mvi INTSTAT,MSG_BUFFER_BUSY ret
951
860
952 or FLAGS,ACTIVE_MSG # if not, there is now
953 mvi MSG_LEN,1 # length = 1
954 mov MSG_START+0,SINDEX # 1-byte message
955
956mk_mesg1:
861mk_mesg1:
957 mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE
862 mvi MSG_LEN,1 /* length = 1 */
863 mov MSG0,SINDEX /* 1-byte message */
864 mvi SEQCTL,0x10 ret /* !PAUSEDIS|FASTMODE */
958
865
959# Carefully read data in Automatic PIO mode. I first tried this using
960# Manual PIO mode, but it gave me continual underrun errors, probably
961# indicating that I did something wrong, but I feel more secure leaving
962# Automatic PIO on all the time.
963#
964# According to Adaptec's documentation, an ACK is not sent on input from
965# the target until SCSIDATL is read from. So we wait until SCSIDATL is
966# latched (the usual way), then read the data byte directly off the bus
967# using SCSIBUSL. When we have pulled the ATN line, or we just want to
968# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
969# spec guarantees that the target will hold the data byte on the bus until
970# we send our ACK.
971#
972# The assumption here is that these are called in a particular sequence,
973# and that REQ is already set when inb_first is called. inb_{first,next}
974# use the same calling convention as inb.
975#
866/*
867 * Functions to read data in Automatic PIO mode.
868 *
869 * According to Adaptec's documentation, an ACK is not sent on input from
870 * the target until SCSIDATL is read from. So we wait until SCSIDATL is
871 * latched (the usual way), then read the data byte directly off the bus
872 * using SCSIBUSL. When we have pulled the ATN line, or we just want to
873 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
874 * spec guarantees that the target will hold the data byte on the bus until
875 * we send our ACK.
876 *
877 * The assumption here is that these are called in a particular sequence,
878 * and that REQ is already set when inb_first is called. inb_{first,next}
879 * use the same calling convention as inb.
880 */
881
882inb_next:
883 mov NONE,SCSIDATL /*dummy read from latch to ACK*/
976inb_first:
884inb_first:
977 clr STCNT+2
978 clr STCNT+1
885 test SSTAT1,PHASEMIS jnz mesgin_phasemis
886 test SSTAT0,SPIORDY jz inb_first /* wait for next byte */
979 mov DINDEX,SINDEX
887 mov DINDEX,SINDEX
980 mov DINDIR,SCSIBUSL ret # read byte directly from bus
888 mov DINDIR,SCSIBUSL ret /*read byte directly from bus*/
889inb_last:
890 mov NONE,SCSIDATL ret /*dummy read from latch to ACK*/
981
891
982inb_next:
983 mov DINDEX,SINDEX # save SINDEX
984
892
985 mvi STCNT+0,1 # xfer one byte
986 mov NONE,SCSIDATL # dummy read from latch to ACK
987inb_next1:
988 test SSTAT0,0x4 jz inb_next1 # SDONE
989inb_next2:
990 test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte
991 mov DINDIR,SCSIBUSL ret # read byte directly from bus
893mesgin_phasemis:
894/*
895 * We expected to receive another byte, but the target changed phase
896 */
897 mvi INTSTAT, MSGIN_PHASEMIS
898 jmp ITloop
992
899
993inb_last:
994 mvi STCNT+0,1 # ACK with dummy read
995 mov NONE,SCSIDATL
996inb_last1:
997 test SSTAT0,0x4 jz inb_last1 # wait for completion
998 ret
999
1000# DMA data transfer. HADDR and HCNT must be loaded first, and
1001# SINDEX should contain the value to load DFCNTRL with - 0x3d for
1002# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
1003# during initialization.
1004#
900/*
901 * DMA data transfer. HADDR and HCNT must be loaded first, and
902 * SINDEX should contain the value to load DFCNTRL with - 0x3d for
903 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared
904 * during initialization.
905 */
1005dma:
1006 mov DFCNTRL,SINDEX
1007dma1:
906dma:
907 mov DFCNTRL,SINDEX
908dma1:
1008 test SSTAT0,0x1 jnz dma3 # DMADONE
1009 test SSTAT1,0x10 jz dma1 # PHASEMIS, ie. underrun
909 test SSTAT0,DMADONE jnz dma3
910 test SSTAT1,PHASEMIS jz dma1 /* ie. underrun */
1010
911
1011# We will be "done" DMAing when the transfer count goes to zero, or
1012# the target changes the phase (in light of this, it makes sense that
1013# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are
1014# doing a SCSI->Host transfer, the data FIFO should be flushed auto-
1015# magically on STCNT=0 or a phase change, so just wait for FIFO empty
1016# status.
1017#
912/*
913 * We will be "done" DMAing when the transfer count goes to zero, or
914 * the target changes the phase (in light of this, it makes sense that
915 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are
916 * doing a SCSI->Host transfer, the data FIFO should be flushed auto-
917 * magically on STCNT=0 or a phase change, so just wait for FIFO empty
918 * status.
919 */
1018dma3:
920dma3:
1019 test SINDEX,0x4 jnz dma5 # DIRECTION
921 test SINDEX,DIRECTION jnz dma5
1020dma4:
922dma4:
1021 test DFSTATUS,0x1 jz dma4 # !FIFOEMP
923 test DFSTATUS,FIFOEMP jz dma4
1022
924
1023# Now shut the DMA enables off and make sure that the DMA enables are
1024# actually off first lest we get an ILLSADDR.
1025#
925/*
926 * Now shut the DMA enables off and make sure that the DMA enables are
927 * actually off first lest we get an ILLSADDR.
928 */
1026dma5:
929dma5:
1027 and DFCNTRL, 0x40, SINDEX # disable DMA, but maintain
1028 # WIDEODD
930 /* disable DMA, but maintain WIDEODD */
931 and A, WIDEODD, SINDEX
932 mov DFCNTRL, A
1029dma6:
933dma6:
1030 test DFCNTRL,0x38 jnz dma6 # SCSIENACK|SDMAENACK|HDMAENACK
934 test DFCNTRL,0x38 jnz dma6 /* SCSIENACK|SDMAENACK|HDMAENACK */
1031
1032 ret
1033
1034dma_finish:
935
936 ret
937
938dma_finish:
1035 test DFSTATUS,0x8 jz dma_finish # HDONE
939 test DFSTATUS,HDONE jz dma_finish
1036
940
1037 clr DFCNTRL # disable DMA
941 clr DFCNTRL /* disable DMA */
1038dma_finish2:
942dma_finish2:
1039 test DFCNTRL,0x8 jnz dma_finish2 # HDMAENACK
943 test DFCNTRL,HDMAENACK jnz dma_finish2
1040 ret
1041
944 ret
945
1042# Common SCSI initialization for selection and reselection. Expects
1043# the target SCSI ID to be in the upper four bits of SINDEX, and A's
1044# contents are stomped on return.
1045#
946/*
947 * Common SCSI initialization for selection and reselection. Expects
948 * the target SCSI ID to be in the upper four bits of SINDEX, and A's
949 * contents are stomped on return.
950 */
1046initialize_scsiid:
951initialize_scsiid:
1047 and SINDEX,0xf0 # Get target ID
952 and SINDEX,0xf0 /* Get target ID */
1048 and A,0x0f,SCSIID
1049 or SINDEX,A
1050 mov SCSIID,SINDEX ret
1051
953 and A,0x0f,SCSIID
954 or SINDEX,A
955 mov SCSIID,SINDEX ret
956
1052initialize_for_target:
1053# Set CLRCHN here before the target has entered a data transfer mode -
1054# with synchronous SCSI, if you do it later, you blow away some
1055# data in the SCSI FIFO that the target has already sent to you.
1056#
1057 clr SIGSTATE
1058
1059 or SXFRCTL0,0x02 # CLRCHN
1060
1061# Make sure that the system knows we have not been through a DATA
1062# phase.
1063 and FLAGS, 0xfb # !DPHASE
1064
1065# Initialize SCSIRATE with the appropriate value for this target.
1066#
1067 call ndx_dtr
1068 mov SCSIRATE,SINDIR ret
1069
1070# Assert that if we've been reselected, then we've seen an IDENTIFY
1071# message.
1072#
957/*
958 * Assert that if we've been reselected, then we've seen an IDENTIFY
959 * message.
960 */
1073assert:
961assert:
1074 test FLAGS,RESELECTED jz return # reselected?
1075 test FLAGS,IDENTIFY_SEEN jnz return # seen IDENTIFY?
962 test FLAGS,RESELECTED jz return /* reselected? */
963 test FLAGS,IDENTIFY_SEEN jnz return /* seen IDENTIFY? */
1076
964
1077 mvi INTSTAT,NO_IDENT ret # no - cause a kernel panic
965 mvi INTSTAT,NO_IDENT ret /* no - cause a kernel panic */
1078
966
1079# Locate the SCB matching the target ID/channel/lun in SAVED_TCL and switch
1080# the SCB to it. Have the kernel print a warning message if it can't be
1081# found, and generate an ABORT message to the target. SINDEX should be
1082# cleared on call.
1083#
967/*
968 * Locate the SCB matching the target ID/channel/lun in SAVED_TCL and switch
969 * the SCB to it. Have the kernel print a warning message if it can't be
970 * found, and generate an ABORT message to the target. SINDEX should be
971 * cleared on call.
972 */
1084findSCB:
1085 mov A,SAVED_TCL
973findSCB:
974 mov A,SAVED_TCL
1086 mov SCBPTR,SINDEX # switch to new SCB
1087 cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match?
1088 test SCBARRAY+0,DISCONNECTED jz findSCB1 # should be disconnected
1089 test SCBARRAY+0,TAG_ENB jnz get_tag
975 mov SCBPTR,SINDEX /* switch to new SCB */
976 cmp SCB_TCL,A jne findSCB1 /* target ID/channel/lun match? */
977 test SCB_CONTROL,DISCONNECTED jz findSCB1 /*should be disconnected*/
1090 ret
1091
1092findSCB1:
1093 inc SINDEX
1094 mov A,SCBCOUNT
1095 cmp SINDEX,A jne findSCB
1096
978 ret
979
980findSCB1:
981 inc SINDEX
982 mov A,SCBCOUNT
983 cmp SINDEX,A jne findSCB
984
1097 mvi INTSTAT,NO_MATCH # not found - signal kernel
1098 mvi 0x6 call mk_mesg # ABORT message
985 mvi INTSTAT,NO_MATCH /* not found - signal kernel */
986 mvi MSG_ABORT call mk_mesg /* ABORT message */
1099
987
1100 or SINDEX,0x10,SIGSTATE # assert ATNO
988 or SINDEX,0x10,SIGSTATE /* assert ATNO */
1101 call scsisig
1102 ret
989 call scsisig
990 ret
1103
1104# Make a working copy of the scatter-gather parameters from the SCB.
1105#
991/*
992 * Make a working copy of the scatter-gather parameters from the SCB.
993 */
1106sg_scb2ram:
1107 mvi DINDEX,HADDR
994sg_scb2ram:
995 mvi DINDEX,HADDR
1108 mvi SCBARRAY+19 call bcopy_7
996 mvi SCB_DATAPTR call bcopy_7
1109
1110 mvi DINDEX,STCNT
997
998 mvi DINDEX,STCNT
1111 mvi SCBARRAY+23 call bcopy_3
999 mvi SCB_DATACNT call bcopy_3
1112
1000
1113 mov SG_COUNT,SCBARRAY+2
1001 mov SG_COUNT,SCB_SGCOUNT
1114
1115 mvi DINDEX,SG_NEXT
1002
1003 mvi DINDEX,SG_NEXT
1116 mvi SCBARRAY+3 call bcopy_4
1004 mvi SCB_SGPTR call bcopy_4
1117 ret
1118
1005 ret
1006
1119# Copying RAM values back to SCB, for Save Data Pointers message, but
1120# only if we've actually been into a data phase to change them. This
1121# protects against bogus data in scratch ram and the residual counts
1122# since they are only initialized when we go into data_in or data_out.
1123#
1007/*
1008 * Copying RAM values back to SCB, for Save Data Pointers message, but
1009 * only if we've actually been into a data phase to change them. This
1010 * protects against bogus data in scratch ram and the residual counts
1011 * since they are only initialized when we go into data_in or data_out.
1012 */
1124sg_ram2scb:
1125 test FLAGS, DPHASE jz return
1013sg_ram2scb:
1014 test FLAGS, DPHASE jz return
1126 mov SCBARRAY+2,SG_COUNT
1015 mov SCB_SGCOUNT,SG_COUNT
1127
1016
1128 mvi DINDEX,SCBARRAY+3
1017 mvi DINDEX,SCB_SGPTR
1129 mvi SG_NEXT call bcopy_4
1130
1018 mvi SG_NEXT call bcopy_4
1019
1131 mvi DINDEX,SCBARRAY+19
1020 mvi DINDEX,SCB_DATAPTR
1132 mvi SHADDR call bcopy_4
1133
1021 mvi SHADDR call bcopy_4
1022
1134# Use the residual number since STCNT is corrupted by any message transfer
1135 mvi SCBARRAY+15 call bcopy_3
1023/*
1024 * Use the residual number since STCNT is corrupted by any message transfer
1025 */
1026 mvi SCB_RESID_DCNT call bcopy_3
1136 ret
1137
1027 ret
1028
1138# Add the array base SYNCNEG to the target offset (the target address
1139# is in SCSIID), and return the result in SINDEX. The accumulator
1140# contains the 3->8 decoding of the target ID on return.
1141#
1029/*
1030 * Add the array base TARG_SCRATCH to the target offset (the target address
1031 * is in SCSIID), and return the result in SINDEX. The accumulator
1032 * contains the 3->8 decoding of the target ID on return.
1033 */
1142ndx_dtr:
1143 shr A,SCSIID,4
1034ndx_dtr:
1035 shr A,SCSIID,4
1144 test SBLKCTL,0x08 jz ndx_dtr_2
1145 or A,0x08 # Channel B entries add 8
1036 test SBLKCTL,SELBUSB jz ndx_dtr_2
1037 or A,0x08 /* Channel B entries add 8 */
1146ndx_dtr_2:
1038ndx_dtr_2:
1147 add SINDEX,SYNCNEG,A
1039 add SINDEX,TARG_SCRATCH,A
1148
1040
1149 and FUNCTION1,0x70,SCSIID # 3-bit target address decode
1041 mov FUNCTION1,SCSIID /* 3-bit target address decode */
1150 mov A,FUNCTION1 ret
1151
1042 mov A,FUNCTION1 ret
1043
1152# If we need to negotiate transfer parameters, build the WDTR or SDTR message
1153# starting at the address passed in SINDEX. DINDEX is modified on return.
1154# The SCSI-II spec requires that Wide negotiation occur first and you can
1155# only negotiat one or the other at a time otherwise in the event of a message
1156# reject, you wouldn't be able to tell which message was the culpret.
1157#
1044/*
1045 * If we need to negotiate transfer parameters, build the WDTR or SDTR message
1046 * starting at the address passed in SINDEX. DINDEX is modified on return.
1047 * The SCSI-II spec requires that Wide negotiation occur first and you can
1048 * only negotiat one or the other at a time otherwise in the event of a message
1049 * reject, you wouldn't be able to tell which message was the culpret.
1050 */
1158mk_dtr:
1051mk_dtr:
1159 test SCBARRAY+0,0x90 jz return # NEEDWDTR|NEEDSDTR
1160 test SCBARRAY+0,NEEDWDTR jnz mk_wdtr_16bit
1161 or FLAGS, MAX_OFFSET # Force an offset of 15 or 8 if WIDE
1052 test SCB_CONTROL,0x90 jz return /* NEEDWDTR|NEEDSDTR */
1053 test SCB_CONTROL,NEEDWDTR jnz mk_wdtr_16bit
1054 or FLAGS, MAXOFFSET /* Force an offset of 15 or 8 if WIDE */
1162
1163mk_sdtr:
1055
1056mk_sdtr:
1164 mvi DINDIR,1 # extended message
1165 mvi DINDIR,3 # extended message length = 3
1166 mvi DINDIR,1 # SDTR code
1057 mvi DINDIR,1 /* extended message */
1058 mvi DINDIR,3 /* extended message length = 3 */
1059 mvi DINDIR,1 /* SDTR code */
1167 call sdtr_to_rate
1060 call sdtr_to_rate
1168 mov DINDIR,RETURN_1 # REQ/ACK transfer period
1169 test FLAGS, MAX_OFFSET jnz mk_sdtr_max_offset
1170 and DINDIR,0x0f,SINDIR # Sync Offset
1061 mov DINDIR,RETURN_1 /* REQ/ACK transfer period */
1062 test FLAGS, MAXOFFSET jnz mk_sdtr_max_offset
1063 and DINDIR,0x0f,SINDIR /* Sync Offset */
1171
1172mk_sdtr_done:
1064
1065mk_sdtr_done:
1173 add MSG_LEN,-MSG_START+0,DINDEX ret # update message length
1066 add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */
1174
1175mk_sdtr_max_offset:
1067
1068mk_sdtr_max_offset:
1176# We're initiating sync negotiation, so request the max offset we can (15 or 8)
1177 xor FLAGS, MAX_OFFSET
1178 test SCSIRATE, 0x80 jnz wmax_offset # Talking to a WIDE device?
1069/*
1070 * We're initiating sync negotiation, so request the max offset we can (15 or 8)
1071 */
1072 xor FLAGS, MAXOFFSET
1073
1074 /* Talking to a WIDE device? */
1075 test SCSIRATE, WIDEXFER jnz wmax_offset
1179 mvi DINDIR, MAX_OFFSET_8BIT
1180 jmp mk_sdtr_done
1181
1182wmax_offset:
1076 mvi DINDIR, MAX_OFFSET_8BIT
1077 jmp mk_sdtr_done
1078
1079wmax_offset:
1183 mvi DINDIR, MAX_OFFSET_WIDE
1080 mvi DINDIR, MAX_OFFSET_16BIT
1184 jmp mk_sdtr_done
1185
1186mk_wdtr_16bit:
1187 mvi ARG_1,BUS_16_BIT
1188mk_wdtr:
1081 jmp mk_sdtr_done
1082
1083mk_wdtr_16bit:
1084 mvi ARG_1,BUS_16_BIT
1085mk_wdtr:
1189 mvi DINDIR,1 # extended message
1190 mvi DINDIR,2 # extended message length = 2
1191 mvi DINDIR,3 # WDTR code
1192 mov DINDIR,ARG_1 # bus width
1086 mvi DINDIR,1 /* extended message */
1087 mvi DINDIR,2 /* extended message length = 2 */
1088 mvi DINDIR,3 /* WDTR code */
1089 mov DINDIR,ARG_1 /* bus width */
1193
1090
1194 add MSG_LEN,-MSG_START+0,DINDEX ret # update message length
1091 add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */
1195
1092
1196# Set SCSI bus control signal state. This also saves the last-written
1197# value into a location where the higher-level driver can read it - if
1198# it has to send an ABORT or RESET message, then it needs to know this
1199# so it can assert ATN without upsetting SCSISIGO. The new value is
1200# expected in SINDEX. Change the actual state last to avoid contention
1201# from the driver.
1202#
1093/*
1094 * Set SCSI bus control signal state. This also saves the last-written
1095 * value into a location where the higher-level driver can read it - if
1096 * it has to send an ABORT or RESET message, then it needs to know this
1097 * so it can assert ATN without upsetting SCSISIGO. The new value is
1098 * expected in SINDEX. Change the actual state last to avoid contention
1099 * from the driver.
1100 */
1203scsisig:
1204 mov SIGSTATE,SINDEX
1205 mov SCSISIGO,SINDEX ret
1206
1207sdtr_to_rate:
1101scsisig:
1102 mov SIGSTATE,SINDEX
1103 mov SCSISIGO,SINDEX ret
1104
1105sdtr_to_rate:
1208 call ndx_dtr # index scratch space for target
1106 call ndx_dtr /* index scratch space for target */
1209 shr A,SINDIR,0x4
1107 shr A,SINDIR,0x4
1210 dec SINDEX #Preserve SINDEX
1108 dec SINDEX /* Preserve SINDEX */
1211 and A,0x7
1212 clr RETURN_1
1213sdtr_to_rate_loop:
1214 test A,0x0f jz sdtr_to_rate_done
1109 and A,0x7
1110 clr RETURN_1
1111sdtr_to_rate_loop:
1112 test A,0x0f jz sdtr_to_rate_done
1215 add RETURN_1,0x18
1113 add RETURN_1,0x19
1216 dec A
1217 jmp sdtr_to_rate_loop
1218sdtr_to_rate_done:
1219 shr RETURN_1,0x2
1114 dec A
1115 jmp sdtr_to_rate_loop
1116sdtr_to_rate_done:
1117 shr RETURN_1,0x2
1220 add RETURN_1,0x18
1118 add RETURN_1,0x19
1221 test SXFRCTL0,ULTRAEN jz return
1222 shr RETURN_1,0x1
1223return:
1224 ret
1119 test SXFRCTL0,ULTRAEN jz return
1120 shr RETURN_1,0x1
1121return:
1122 ret