Deleted Added
full compact
aic7xxx.seq (72640) aic7xxx.seq (72811)
1/*
2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2001 Justin Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2001 Justin Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/src/aic7xxx/aic7xxx.seq#19 $
31 * $Id: //depot/src/aic7xxx/aic7xxx.seq#20 $
32 *
32 *
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.seq 72640 2001-02-18 10:25:42Z asmodai $
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.seq 72811 2001-02-21 20:50:36Z gibbs $
34 */
35
36#include "aic7xxx.reg"
37#include "scsi_message.h"
38
39/*
40 * A few words on the waiting SCB list:
41 * After starting the selection hardware, we check for reconnecting targets

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

62 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;
63 and SIMODE1, ~ENBUSFREE;
64poll_for_work:
65 call clear_target_state;
66 and SXFRCTL0, ~SPIOEN;
67 if ((ahc->features & AHC_ULTRA2) != 0) {
68 clr SCSIBUSL;
69 }
34 */
35
36#include "aic7xxx.reg"
37#include "scsi_message.h"
38
39/*
40 * A few words on the waiting SCB list:
41 * After starting the selection hardware, we check for reconnecting targets

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

62 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;
63 and SIMODE1, ~ENBUSFREE;
64poll_for_work:
65 call clear_target_state;
66 and SXFRCTL0, ~SPIOEN;
67 if ((ahc->features & AHC_ULTRA2) != 0) {
68 clr SCSIBUSL;
69 }
70poll_for_work_loop:
71 test SSTAT0, SELDO|SELDI jnz selection;
72 test SCSISEQ, ENSELO jnz poll_for_work_loop;
70 test SCSISEQ, ENSELO jnz poll_for_selection;
73 if ((ahc->features & AHC_TWIN) != 0) {
71 if ((ahc->features & AHC_TWIN) != 0) {
74 /*
75 * Twin channel devices cannot handle things like SELTO
76 * interrupts on the "background" channel. So, if we
77 * are selecting, keep polling the current channel util
78 * either a selection or reselection occurs.
79 */
80 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
72 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
81 test SSTAT0, SELDO|SELDI jnz selection;
82 xor SBLKCTL,SELBUSB; /* Toggle back */
73 test SCSISEQ, ENSELO jnz poll_for_selection;
83 }
84 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
74 }
75 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
76poll_for_work_loop:
77 if ((ahc->features & AHC_TWIN) != 0) {
78 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
79 }
80 test SSTAT0, SELDO|SELDI jnz selection;
85test_queue:
86 /* Has the driver posted any work for us? */
87BEGIN_CRITICAL
88 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
89 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
90 } else {
91 mov A, QINPOS;
92 cmp KERNEL_QINPOS, A je poll_for_work_loop;

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

134 }
135END_CRITICAL
136start_waiting:
137 /*
138 * Start the first entry on the waiting SCB list.
139 */
140 mov SCBPTR, WAITING_SCBH;
141 call start_selection;
81test_queue:
82 /* Has the driver posted any work for us? */
83BEGIN_CRITICAL
84 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
85 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
86 } else {
87 mov A, QINPOS;
88 cmp KERNEL_QINPOS, A je poll_for_work_loop;

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

130 }
131END_CRITICAL
132start_waiting:
133 /*
134 * Start the first entry on the waiting SCB list.
135 */
136 mov SCBPTR, WAITING_SCBH;
137 call start_selection;
142 jmp poll_for_work_loop;
143
138
144abort_qinscb:
145 call add_scb_to_free_list;
146 jmp poll_for_work_loop;
147
148start_selection:
139poll_for_selection:
149 /*
140 /*
150 * If bus reset interrupts have been disabled (from a previous
151 * reset), re-enable them now. Resets are only of interest
152 * when we have outstanding transactions, so we can safely
153 * defer re-enabling the interrupt until, as an initiator,
154 * we start sending out transactions again.
141 * Twin channel devices cannot handle things like SELTO
142 * interrupts on the "background" channel. So, while
143 * selecting, keep polling the current channel until
144 * either a selection or reselection occurs.
155 */
145 */
156 test SIMODE1, ENSCSIRST jnz . + 3;
157 mvi CLRSINT1, CLRSCSIRSTI;
158 or SIMODE1, ENSCSIRST;
159 if ((ahc->features & AHC_TWIN) != 0) {
160 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
161 test SCB_SCSIID, TWIN_CHNLB jz . + 2;
162 or SINDEX, SELBUSB;
163 mov SBLKCTL,SINDEX; /* select channel */
164 }
165initialize_scsiid:
166 if ((ahc->features & AHC_ULTRA2) != 0) {
167 mov SCSIID_ULTRA2, SCB_SCSIID;
168 } else if ((ahc->features & AHC_TWIN) != 0) {
169 and SCSIID, TWIN_TID|OID, SCB_SCSIID;
170 } else {
171 mov SCSIID, SCB_SCSIID;
172 }
173 if ((ahc->flags & AHC_TARGETROLE) != 0) {
174 mov SINDEX, SCSISEQ_TEMPLATE;
175 test SCB_CONTROL, TARGET_SCB jz . + 2;
176 or SINDEX, TEMODE;
177 mov SCSISEQ, SINDEX ret;
178 } else {
179 mov SCSISEQ, SCSISEQ_TEMPLATE ret;
180 }
146 test SSTAT0, SELDO|SELDI jz poll_for_selection;
181
147
182/*
183 * Initialize transfer settings and clear the SCSI channel.
184 * SINDEX should contain any additional bit's the client wants
185 * set in SXFRCTL0. We also assume that the current SCB is
186 * a valid SCB for the target we wish to talk to.
187 */
188initialize_channel:
189 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;
190set_transfer_settings:
191 if ((ahc->features & AHC_ULTRA) != 0) {
192 test SCB_CONTROL, ULTRAENB jz . + 2;
193 or SXFRCTL0, FAST20;
194 }
195 /*
196 * Initialize SCSIRATE with the appropriate value for this target.
197 */
198 if ((ahc->features & AHC_ULTRA2) != 0) {
199 bmov SCSIRATE, SCB_SCSIRATE, 2 ret;
200 } else {
201 mov SCSIRATE, SCB_SCSIRATE ret;
202 }
203
204selection:
205 /*
206 * We aren't expecting a bus free, so interrupt
207 * the kernel driver if it happens.
208 */
209 mvi CLRSINT1,CLRBUSFREE;
210 or SIMODE1, ENBUSFREE;
211

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

380 if ((ahc->features & AHC_CMD_CHAN) != 0) {
381 mvi CCSCBRAM, SCB_LIST_NULL;
382 } else {
383 mvi DFDAT, SCB_LIST_NULL;
384 }
385 or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN;
386 test SCSISIGI, ATNI jnz target_mesgout_pending;
387 jmp target_ITloop;
148selection:
149 /*
150 * We aren't expecting a bus free, so interrupt
151 * the kernel driver if it happens.
152 */
153 mvi CLRSINT1,CLRBUSFREE;
154 or SIMODE1, ENBUSFREE;
155

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

324 if ((ahc->features & AHC_CMD_CHAN) != 0) {
325 mvi CCSCBRAM, SCB_LIST_NULL;
326 } else {
327 mvi DFDAT, SCB_LIST_NULL;
328 }
329 or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN;
330 test SCSISIGI, ATNI jnz target_mesgout_pending;
331 jmp target_ITloop;
388
389/*
390 * We carefully toggle SPIOEN to allow us to return the
391 * message byte we receive so it can be checked prior to
392 * driving REQ on the bus for the next byte.
393 */
394target_inb:
395 /*
396 * Drive REQ on the bus by enabling SCSI PIO.
397 */
398 or SXFRCTL0, SPIOEN;
399 /* Wait for the byte */
400 test SSTAT0, SPIORDY jz .;
401 /* Prevent our read from triggering another REQ */
402 and SXFRCTL0, ~SPIOEN;
403 /* Save latched contents */
404 mov DINDEX, SCSIDATL ret;
405 }
406
407if ((ahc->flags & AHC_INITIATORROLE) != 0) {
408/*
409 * Reselection has been initiated by a target. Make a note that we've been
410 * reselected, but haven't seen an IDENTIFY message from the target yet.
411 */
412initiator_reselect:

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

422 if ((ahc->features & AHC_TWIN) != 0) {
423 test SBLKCTL, SELBUSB jz . + 2;
424 or SAVED_SCSIID, TWIN_CHNLB;
425 }
426 mvi CLRSINT0, CLRSELDI;
427 jmp ITloop;
428}
429
332 }
333
334if ((ahc->flags & AHC_INITIATORROLE) != 0) {
335/*
336 * Reselection has been initiated by a target. Make a note that we've been
337 * reselected, but haven't seen an IDENTIFY message from the target yet.
338 */
339initiator_reselect:

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

349 if ((ahc->features & AHC_TWIN) != 0) {
350 test SBLKCTL, SELBUSB jz . + 2;
351 or SAVED_SCSIID, TWIN_CHNLB;
352 }
353 mvi CLRSINT0, CLRSELDI;
354 jmp ITloop;
355}
356
357abort_qinscb:
358 call add_scb_to_free_list;
359 jmp poll_for_work_loop;
360
361start_selection:
362 /*
363 * If bus reset interrupts have been disabled (from a previous
364 * reset), re-enable them now. Resets are only of interest
365 * when we have outstanding transactions, so we can safely
366 * defer re-enabling the interrupt until, as an initiator,
367 * we start sending out transactions again.
368 */
369 test SIMODE1, ENSCSIRST jnz . + 3;
370 mvi CLRSINT1, CLRSCSIRSTI;
371 or SIMODE1, ENSCSIRST;
372 if ((ahc->features & AHC_TWIN) != 0) {
373 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
374 test SCB_SCSIID, TWIN_CHNLB jz . + 2;
375 or SINDEX, SELBUSB;
376 mov SBLKCTL,SINDEX; /* select channel */
377 }
378initialize_scsiid:
379 if ((ahc->features & AHC_ULTRA2) != 0) {
380 mov SCSIID_ULTRA2, SCB_SCSIID;
381 } else if ((ahc->features & AHC_TWIN) != 0) {
382 and SCSIID, TWIN_TID|OID, SCB_SCSIID;
383 } else {
384 mov SCSIID, SCB_SCSIID;
385 }
386 if ((ahc->flags & AHC_TARGETROLE) != 0) {
387 mov SINDEX, SCSISEQ_TEMPLATE;
388 test SCB_CONTROL, TARGET_SCB jz . + 2;
389 or SINDEX, TEMODE;
390 mov SCSISEQ, SINDEX ret;
391 } else {
392 mov SCSISEQ, SCSISEQ_TEMPLATE ret;
393 }
394
430/*
395/*
396 * Initialize transfer settings and clear the SCSI channel.
397 * SINDEX should contain any additional bit's the client wants
398 * set in SXFRCTL0. We also assume that the current SCB is
399 * a valid SCB for the target we wish to talk to.
400 */
401initialize_channel:
402 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;
403set_transfer_settings:
404 if ((ahc->features & AHC_ULTRA) != 0) {
405 test SCB_CONTROL, ULTRAENB jz . + 2;
406 or SXFRCTL0, FAST20;
407 }
408 /*
409 * Initialize SCSIRATE with the appropriate value for this target.
410 */
411 if ((ahc->features & AHC_ULTRA2) != 0) {
412 bmov SCSIRATE, SCB_SCSIRATE, 2 ret;
413 } else {
414 mov SCSIRATE, SCB_SCSIRATE ret;
415 }
416
417if ((ahc->flags & AHC_TARGETROLE) != 0) {
418/*
419 * We carefully toggle SPIOEN to allow us to return the
420 * message byte we receive so it can be checked prior to
421 * driving REQ on the bus for the next byte.
422 */
423target_inb:
424 /*
425 * Drive REQ on the bus by enabling SCSI PIO.
426 */
427 or SXFRCTL0, SPIOEN;
428 /* Wait for the byte */
429 test SSTAT0, SPIORDY jz .;
430 /* Prevent our read from triggering another REQ */
431 and SXFRCTL0, ~SPIOEN;
432 /* Save latched contents */
433 mov DINDEX, SCSIDATL ret;
434}
435
436/*
431 * After the selection, remove this SCB from the "waiting SCB"
432 * list. This is achieved by simply moving our "next" pointer into
433 * WAITING_SCBH. Our next pointer will be set to null the next time this
434 * SCB is used, so don't bother with it now.
435 */
436select_out:
437 /* Turn off the selection hardware */
438 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;

--- 1736 unchanged lines hidden ---
437 * After the selection, remove this SCB from the "waiting SCB"
438 * list. This is achieved by simply moving our "next" pointer into
439 * WAITING_SCBH. Our next pointer will be set to null the next time this
440 * SCB is used, so don't bother with it now.
441 */
442select_out:
443 /* Turn off the selection hardware */
444 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;

--- 1736 unchanged lines hidden ---