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 --- |