1/* 2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD. 3 * 4 * Copyright (c) 1994-1999 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 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * Where this Software is combined with software released under the terms of 17 * the GNU General Public License (GPL) and the terms of the GPL would require the 18 * combined work to also be released under the terms of the GPL, the terms 19 * and conditions of this License will apply in addition to those of the 20 * GPL with the exception of any terms or conditions of this License that 21 * conflict with, or are expressly prohibited by, the GPL. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * $Id: aic7xxx.seq,v 1.77 1998/06/28 02:58:57 gibbs Exp $ 36 */ 37 38#include "aic7xxx.reg" 39#include "scsi_message.h" 40 41/* 42 * A few words on the waiting SCB list: 43 * After starting the selection hardware, we check for reconnecting targets 44 * as well as for our selection to complete just in case the reselection wins 45 * bus arbitration. The problem with this is that we must keep track of the 46 * SCB that we've already pulled from the QINFIFO and started the selection 47 * on just in case the reselection wins so that we can retry the selection at 48 * a later time. This problem cannot be resolved by holding a single entry 49 * in scratch ram since a reconnecting target can request sense and this will 50 * create yet another SCB waiting for selection. The solution used here is to 51 * use byte 27 of the SCB as a pseudo-next pointer and to thread a list 52 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, 53 * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to 54 * this list everytime a request sense occurs or after completing a non-tagged 55 * command for which a second SCB has been queued. The sequencer will 56 * automatically consume the entries. 57 */ 58 59reset: 60 clr SCSISIGO; /* De-assert BSY */ 61 and SXFRCTL1, ~BITBUCKET; 62 /* Always allow reselection */ 63 mvi SCSISEQ, ENRSELI|ENAUTOATNP; 64 65 if ((p->features & AHC_CMD_CHAN) != 0) { 66 /* Ensure that no DMA operations are in progress */ 67 clr CCSGCTL; 68 clr CCSCBCTL; 69 } 70 71 call clear_target_state; 72poll_for_work: 73 and SXFRCTL0, ~SPIOEN; 74 if ((p->features & AHC_QUEUE_REGS) == 0) { 75 mov A, QINPOS; 76 } 77poll_for_work_loop: 78 if ((p->features & AHC_QUEUE_REGS) == 0) { 79 and SEQCTL, ~PAUSEDIS; 80 } 81 test SSTAT0, SELDO|SELDI jnz selection; 82 test SCSISEQ, ENSELO jnz poll_for_work; 83 if ((p->features & AHC_TWIN) != 0) { 84 /* 85 * Twin channel devices cannot handle things like SELTO 86 * interrupts on the "background" channel. So, if we 87 * are selecting, keep polling the current channel util 88 * either a selection or reselection occurs. 89 */ 90 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ 91 test SSTAT0, SELDO|SELDI jnz selection; 92 test SCSISEQ, ENSELO jnz poll_for_work; 93 xor SBLKCTL,SELBUSB; /* Toggle back */ 94 } 95 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; 96test_queue: 97 /* Has the driver posted any work for us? */ 98 if ((p->features & AHC_QUEUE_REGS) != 0) { 99 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop; 100 mov NONE, SNSCB_QOFF; 101 inc QINPOS; 102 } else { 103 or SEQCTL, PAUSEDIS; 104 cmp KERNEL_QINPOS, A je poll_for_work_loop; 105 inc QINPOS; 106 and SEQCTL, ~PAUSEDIS; 107 } 108 109/* 110 * We have at least one queued SCB now and we don't have any 111 * SCBs in the list of SCBs awaiting selection. If we have 112 * any SCBs available for use, pull the tag from the QINFIFO 113 * and get to work on it. 114 */ 115 if ((p->flags & AHC_PAGESCBS) != 0) { 116 mov ALLZEROS call get_free_or_disc_scb; 117 } 118 119dequeue_scb: 120 add A, -1, QINPOS; 121 mvi QINFIFO_OFFSET call fetch_byte; 122 123 if ((p->flags & AHC_PAGESCBS) == 0) { 124 /* In the non-paging case, the SCBID == hardware SCB index */ 125 mov SCBPTR, RETURN_2; 126 } 127dma_queued_scb: 128/* 129 * DMA the SCB from host ram into the current SCB location. 130 */ 131 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 132 mov RETURN_2 call dma_scb; 133 134/* 135 * Preset the residual fields in case we never go through a data phase. 136 * This isn't done by the host so we can avoid a DMA to clear these 137 * fields for the normal case of I/O that completes without underrun 138 * or overrun conditions. 139 */ 140 if ((p->features & AHC_CMD_CHAN) != 0) { 141 bmov SCB_RESID_DCNT, SCB_DATACNT, 3; 142 } else { 143 mov SCB_RESID_DCNT[0],SCB_DATACNT[0]; 144 mov SCB_RESID_DCNT[1],SCB_DATACNT[1]; 145 mov SCB_RESID_DCNT[2],SCB_DATACNT[2]; 146 } 147 mov SCB_RESID_SGCNT, SCB_SGCOUNT; 148 149start_scb: 150 /* 151 * Place us on the waiting list in case our selection 152 * doesn't win during bus arbitration. 153 */ 154 mov SCB_NEXT,WAITING_SCBH; 155 mov WAITING_SCBH, SCBPTR; 156start_waiting: 157 /* 158 * Pull the first entry off of the waiting SCB list. 159 */ 160 mov SCBPTR, WAITING_SCBH; 161 call start_selection; 162 jmp poll_for_work; 163 164start_selection: 165 if ((p->features & AHC_TWIN) != 0) { 166 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */ 167 and A,SELBUSB,SCB_TCL; /* Get new channel bit */ 168 or SINDEX,A; 169 mov SBLKCTL,SINDEX; /* select channel */ 170 } 171initialize_scsiid: 172 if ((p->features & AHC_ULTRA2) != 0) { 173 and A, TID, SCB_TCL; /* Get target ID */ 174 and SCSIID_ULTRA2, OID; /* Clear old target */ 175 or SCSIID_ULTRA2, A; 176 } else { 177 and A, TID, SCB_TCL; /* Get target ID */ 178 and SCSIID, OID; /* Clear old target */ 179 or SCSIID, A; 180 } 181 mov SCSIDATL, ALLZEROS; /* clear out the latched */ 182 /* data register, this */ 183 /* fixes a bug on some */ 184 /* controllers where the */ 185 /* last byte written to */ 186 /* this register can leak */ 187 /* onto the data bus at */ 188 /* bad times, such as during */ 189 /* selection timeouts */ 190 mvi SCSISEQ, ENSELO|ENAUTOATNO|ENRSELI|ENAUTOATNP ret; 191 192/* 193 * Initialize Ultra mode setting and clear the SCSI channel. 194 * SINDEX should contain any additional bit's the client wants 195 * set in SXFRCTL0. 196 */ 197initialize_channel: 198 or SXFRCTL0, CLRSTCNT|CLRCHN, SINDEX; 199 if ((p->features & AHC_ULTRA) != 0) { 200ultra: 201 mvi SINDEX, ULTRA_ENB+1; 202 test SAVED_TCL, 0x80 jnz ultra_2; /* Target ID > 7 */ 203 dec SINDEX; 204ultra_2: 205 mov FUNCTION1,SAVED_TCL; 206 mov A,FUNCTION1; 207 test SINDIR, A jz ndx_dtr; 208 or SXFRCTL0, FAST20; 209 } 210/* 211 * Initialize SCSIRATE with the appropriate value for this target. 212 * The SCSIRATE settings for each target are stored in an array 213 * based at TARG_SCSIRATE. 214 */ 215ndx_dtr: 216 shr A,4,SAVED_TCL; 217 if ((p->features & AHC_TWIN) != 0) { 218 test SBLKCTL,SELBUSB jz ndx_dtr_2; 219 or SAVED_TCL, SELBUSB; 220 or A,0x08; /* Channel B entries add 8 */ 221ndx_dtr_2: 222 } 223 224 if ((p->features & AHC_ULTRA2) != 0) { 225 add SINDEX, TARG_OFFSET, A; 226 mov SCSIOFFSET, SINDIR; 227 } 228 229 add SINDEX,TARG_SCSIRATE,A; 230 mov SCSIRATE,SINDIR ret; 231 232 233selection: 234 test SSTAT0,SELDO jnz select_out; 235/* 236 * Reselection has been initiated by a target. Make a note that we've been 237 * reselected, but haven't seen an IDENTIFY message from the target yet. 238 */ 239initiator_reselect: 240 mvi CLRSINT0, CLRSELDI; 241 /* XXX test for and handle ONE BIT condition */ 242 and SAVED_TCL, SELID_MASK, SELID; 243 mvi CLRSINT1,CLRBUSFREE; 244 or SIMODE1, ENBUSFREE; /* 245 * We aren't expecting a 246 * bus free, so interrupt 247 * the kernel driver if it 248 * happens. 249 */ 250 mvi SPIOEN call initialize_channel; 251 mvi MSG_OUT, MSG_NOOP; /* No message to send */ 252 jmp ITloop; 253 254/* 255 * After the selection, remove this SCB from the "waiting SCB" 256 * list. This is achieved by simply moving our "next" pointer into 257 * WAITING_SCBH. Our next pointer will be set to null the next time this 258 * SCB is used, so don't bother with it now. 259 */ 260select_out: 261 /* Turn off the selection hardware */ 262 mvi SCSISEQ, ENRSELI|ENAUTOATNP; /* 263 * ATN on parity errors 264 * for "in" phases 265 */ 266 mvi CLRSINT0, CLRSELDO; 267 mov SCBPTR, WAITING_SCBH; 268 mov WAITING_SCBH,SCB_NEXT; 269 mov SAVED_TCL, SCB_TCL; 270 mvi CLRSINT1,CLRBUSFREE; 271 or SIMODE1, ENBUSFREE; /* 272 * We aren't expecting a 273 * bus free, so interrupt 274 * the kernel driver if it 275 * happens. 276 */ 277 mvi SPIOEN call initialize_channel; 278/* 279 * As soon as we get a successful selection, the target should go 280 * into the message out phase since we have ATN asserted. 281 */ 282 mvi MSG_OUT, MSG_IDENTIFYFLAG; 283 or SEQ_FLAGS, IDENTIFY_SEEN; 284 285/* 286 * Main loop for information transfer phases. Wait for the target 287 * to assert REQ before checking MSG, C/D and I/O for the bus phase. 288 */ 289ITloop: 290 call phase_lock; 291 292 mov A, LASTPHASE; 293 294 test A, ~P_DATAIN jz p_data; 295 cmp A,P_COMMAND je p_command; 296 cmp A,P_MESGOUT je p_mesgout; 297 cmp A,P_STATUS je p_status; 298 cmp A,P_MESGIN je p_mesgin; 299 300 mvi INTSTAT,BAD_PHASE; /* unknown phase - signal driver */ 301 jmp ITloop; /* Try reading the bus again. */ 302 303await_busfree: 304 and SIMODE1, ~ENBUSFREE; 305 call clear_target_state; 306 mov NONE, SCSIDATL; /* Ack the last byte */ 307 and SXFRCTL0, ~SPIOEN; 308 test SSTAT1,REQINIT|BUSFREE jz .; 309 test SSTAT1, BUSFREE jnz poll_for_work; 310 mvi INTSTAT, BAD_PHASE; 311 312clear_target_state: 313 /* 314 * We assume that the kernel driver may reset us 315 * at any time, even in the middle of a DMA, so 316 * clear DFCNTRL too. 317 */ 318 clr DFCNTRL; 319 320 /* 321 * We don't know the target we will connect to, 322 * so default to narrow transfers to avoid 323 * parity problems. 324 */ 325 if ((p->features & AHC_ULTRA2) != 0) { 326 bmov SCSIRATE, ALLZEROS, 2; 327 } else { 328 clr SCSIRATE; 329 and SXFRCTL0, ~(FAST20); 330 } 331 mvi LASTPHASE, P_BUSFREE; 332 /* clear target specific flags */ 333 clr SEQ_FLAGS ret; 334 335 336data_phase_reinit: 337/* 338 * If we re-enter the data phase after going through another phase, the 339 * STCNT may have been cleared, so restore it from the residual field. 340 * On Ultra2, we have to put it into the HCNT field because we have to 341 * drop the data down into the shadow layer via the preload ability. 342 */ 343 if ((p->features & AHC_ULTRA2) != 0) { 344 bmov HADDR, SHADDR, 4; 345 bmov HCNT, SCB_RESID_DCNT, 3; 346 } 347 if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 348 bmov STCNT, SCB_RESID_DCNT, 3; 349 } 350 if ((p->features & AHC_CMD_CHAN) == 0) { 351 mvi DINDEX, STCNT; 352 mvi SCB_RESID_DCNT call bcopy_3; 353 } 354 jmp data_phase_loop; 355p_data: 356 if ((p->features & AHC_ULTRA2) != 0) { 357 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; 358 } else { 359 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 360 } 361 test LASTPHASE, IOI jnz . + 2; 362 or DMAPARAMS, DIRECTION; 363 call assert; /* 364 * Ensure entering a data 365 * phase is okay - seen identify, etc. 366 */ 367 if ((p->features & AHC_CMD_CHAN) != 0) { 368 mvi CCSGADDR, CCSGADDR_MAX; 369 } 370 371 test SEQ_FLAGS, DPHASE jnz data_phase_reinit; 372 or SEQ_FLAGS, DPHASE; /* we've seen a data phase */ 373 /* 374 * Initialize the DMA address and counter from the SCB. 375 * Also set SG_COUNT and SG_NEXT in memory since we cannot 376 * modify the values in the SCB itself until we see a 377 * save data pointers message. 378 */ 379 if ((p->features & AHC_CMD_CHAN) != 0) { 380 bmov HADDR, SCB_DATAPTR, 7; 381 bmov SG_COUNT, SCB_SGCOUNT, 5; 382 if ((p->features & AHC_ULTRA2) == 0) { 383 bmov STCNT, HCNT, 3; 384 } 385 } else { 386 mvi DINDEX, HADDR; 387 mvi SCB_DATAPTR call bcopy_7; 388 call set_stcnt_from_hcnt; 389 mvi DINDEX, SG_COUNT; 390 mvi SCB_SGCOUNT call bcopy_5; 391 } 392data_phase_loop: 393 /* Guard against overruns */ 394 test SG_COUNT, 0xff jnz data_phase_inbounds; 395/* 396 * Turn on 'Bit Bucket' mode, set the transfer count to 397 * 16meg and let the target run until it changes phase. 398 * When the transfer completes, notify the host that we 399 * had an overrun. 400 */ 401 or SXFRCTL1,BITBUCKET; 402 and DMAPARAMS, ~(HDMAEN|SDMAEN); 403 if ((p->features & AHC_ULTRA2) != 0) { 404 bmov HCNT, ALLONES, 3; 405 } 406 if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 407 bmov STCNT, ALLONES, 3; 408 } 409 if ((p->features & AHC_CMD_CHAN) == 0) { 410 mvi STCNT[0], 0xFF; 411 mvi STCNT[1], 0xFF; 412 mvi STCNT[2], 0xFF; 413 } 414 415data_phase_inbounds: 416/* If we are the last SG block, tell the hardware. */ 417 if ((p->features & AHC_ULTRA2) != 0) { 418 shl A, 2, SG_COUNT; 419 cmp SG_COUNT,0x01 jne data_phase_wideodd; 420 or A, LAST_SEG; 421 } else { 422 cmp SG_COUNT,0x01 jne data_phase_wideodd; 423 and DMAPARAMS, ~WIDEODD; 424 } 425data_phase_wideodd: 426 if ((p->features & AHC_ULTRA2) != 0) { 427 mov SG_CACHEPTR, A; 428 mov DFCNTRL, DMAPARAMS; /* start the operation */ 429 test SXFRCTL1, BITBUCKET jnz data_phase_overrun; 430u2_preload_wait: 431 test SSTAT1, PHASEMIS jnz u2_phasemis; 432 test DFSTATUS, PRELOAD_AVAIL jz u2_preload_wait; 433 } else { 434 mov DMAPARAMS call dma; 435data_phase_dma_done: 436/* Go tell the host about any overruns */ 437 test SXFRCTL1,BITBUCKET jnz data_phase_overrun; 438 439/* Exit if we had an underrun. dma clears SINDEX in this case. */ 440 test SINDEX,0xff jz data_phase_finish; 441 } 442/* 443 * Advance the scatter-gather pointers 444 */ 445sg_advance: 446 if ((p->features & AHC_ULTRA2) != 0) { 447 cmp SG_COUNT, 0x01 je u2_data_phase_finish; 448 } else { 449 dec SG_COUNT; 450 test SG_COUNT, 0xff jz data_phase_finish; 451 } 452 453 if ((p->features & AHC_CMD_CHAN) != 0) { 454 455 /* 456 * Do we have any prefetch left??? 457 */ 458 cmp CCSGADDR, CCSGADDR_MAX jne prefetch_avail; 459 460 /* 461 * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes. 462 */ 463 add A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT; 464 mvi A, CCSGADDR_MAX; 465 jc . + 2; 466 shl A, 3, SG_COUNT; 467 mov CCHCNT, A; 468 bmov CCHADDR, SG_NEXT, 4; 469 mvi CCSGCTL, CCSGEN|CCSGRESET; 470 test CCSGCTL, CCSGDONE jz .; 471 and CCSGCTL, ~CCSGEN; 472 test CCSGCTL, CCSGEN jnz .; 473 mvi CCSGCTL, CCSGRESET; 474prefetch_avail: 475 bmov HADDR, CCSGRAM, 8; 476 if ((p->features & AHC_ULTRA2) == 0) { 477 bmov STCNT, HCNT, 3; 478 } else { 479 dec SG_COUNT; 480 } 481 } else { 482 mvi DINDEX, HADDR; 483 mvi SG_NEXT call bcopy_4; 484 485 mvi HCNT[0],SG_SIZEOF; 486 clr HCNT[1]; 487 clr HCNT[2]; 488 489 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 490 491 call dma_finish; 492 493/* 494 * Copy data from FIFO into SCB data pointer and data count. 495 * This assumes that the SG segments are of the form: 496 * struct ahc_dma_seg { 497 * u_int32_t addr; four bytes, little-endian order 498 * u_int32_t len; four bytes, little endian order 499 * }; 500 */ 501 mvi DINDEX, HADDR; 502 call dfdat_in_7; 503 call set_stcnt_from_hcnt; 504 } 505/* Advance the SG pointer */ 506 clr A; /* add sizeof(struct scatter) */ 507 add SG_NEXT[0],SG_SIZEOF; 508 adc SG_NEXT[1],A; 509 510 if ((p->features & AHC_ULTRA2) != 0) { 511 jmp data_phase_loop; 512 } else { 513 test SSTAT1, REQINIT jz .; 514 test SSTAT1,PHASEMIS jz data_phase_loop; 515 } 516 517 518/* 519 * We've loaded all of our segments into the preload layer. Now, we simply 520 * have to wait for it to finish or for us to get a phasemis. And, since 521 * we'll get a phasemis if we do finish, all we really need to do is wait 522 * for a phasemis then check if we did actually complete all the segments. 523 */ 524 if ((p->features & AHC_ULTRA2) != 0) { 525u2_data_phase_finish: 526 test SSTAT1, PHASEMIS jnz u2_phasemis; 527 test SG_CACHEPTR, LAST_SEG_DONE jz u2_data_phase_finish; 528 clr SG_COUNT; 529 test SSTAT1, REQINIT jz .; 530 test SSTAT1, PHASEMIS jz data_phase_loop; 531u2_phasemis: 532 call ultra2_dmafinish; 533 test SG_CACHEPTR, LAST_SEG_DONE jnz data_phase_finish; 534 test SSTAT2, SHVALID jnz u2_fixup_residual; 535 mvi INTSTAT, SEQ_SG_FIXUP; 536 jmp data_phase_finish; 537u2_fixup_residual: 538 shr ARG_1, 2, SG_CACHEPTR; 539u2_phasemis_loop: 540 and A, 0x3f, SG_COUNT; 541 cmp ARG_1, A je data_phase_finish; 542/* 543 * Subtract SG_SIZEOF from the SG_NEXT pointer and add 1 to the SG_COUNT 544 */ 545 clr A; 546 add SG_NEXT[0], -SG_SIZEOF; 547 adc SG_NEXT[1], 0xff; 548 inc SG_COUNT; 549 jmp u2_phasemis_loop; 550 } 551 552data_phase_finish: 553/* 554 * After a DMA finishes, save the SG and STCNT residuals back into the SCB 555 * We use STCNT instead of HCNT, since it's a reflection of how many bytes 556 * were transferred on the SCSI (as opposed to the host) bus. 557 */ 558 if ((p->features & AHC_CMD_CHAN) != 0) { 559 bmov SCB_RESID_DCNT, STCNT, 3; 560 mov SCB_RESID_SGCNT, SG_COUNT; 561 if ((p->features & AHC_ULTRA2) != 0) { 562 or SXFRCTL0, CLRSTCNT|CLRCHN; 563 } 564 } else { 565 mov SCB_RESID_DCNT[0],STCNT[0]; 566 mov SCB_RESID_DCNT[1],STCNT[1]; 567 mov SCB_RESID_DCNT[2],STCNT[2]; 568 mov SCB_RESID_SGCNT, SG_COUNT; 569 } 570 571 jmp ITloop; 572 573data_phase_overrun: 574/* 575 * Turn off BITBUCKET mode and notify the host 576 */ 577 if ((p->features & AHC_ULTRA2) != 0) { 578/* 579 * Wait for the target to quit transferring data on the SCSI bus 580 */ 581 test SSTAT1, PHASEMIS jz .; 582 call ultra2_dmafinish; 583 } 584 and SXFRCTL1, ~BITBUCKET; 585 mvi INTSTAT,DATA_OVERRUN; 586 jmp ITloop; 587 588 589 590 591/* 592 * Actually turn off the DMA hardware, save our current position into the 593 * proper residual variables, wait for the next REQ signal, then jump to 594 * the ITloop. Jumping to the ITloop ensures that if we happen to get 595 * brought into the data phase again (or are still in it after our last 596 * segment) that we will properly signal an overrun to the kernel. 597 */ 598 if ((p->features & AHC_ULTRA2) != 0) { 599ultra2_dmafinish: 600 test DFCNTRL, DIRECTION jnz ultra2_dmahalt; 601 and DFCNTRL, ~SCSIEN; 602 test DFCNTRL, SCSIEN jnz .; 603 if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) { 604 or DFCNTRL, FIFOFLUSH; 605 } 606ultra2_dmafifoflush: 607 if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) { 608 /* 609 * hardware bug alert! This needless set of jumps 610 * works around a glitch in the silicon. When the 611 * PCI DMA fifo goes empty, but there is still SCSI 612 * data to be flushed into the PCI DMA fifo (and from 613 * there on into main memory), the FIFOEMP bit will 614 * come on between the time when the PCI DMA buffer 615 * went empty and the next bit of data is copied from 616 * the SCSI fifo into the PCI fifo. It should only 617 * come on when both FIFOs (meaning the entire FIFO 618 * chain) are emtpy. Since it can take up to 4 cycles 619 * for new data to be copied from the SCSI fifo into 620 * the PCI fifo, testing for FIFOEMP status for 4 621 * extra times gives the needed time for any 622 * remaining SCSI fifo data to be put in the PCI fifo 623 * before we declare it *truly* empty. 624 */ 625 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 626 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 627 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 628 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 629 } 630 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 631 test DFSTATUS, MREQPEND jnz .; 632ultra2_dmahalt: 633 and DFCNTRL, ~(HDMAEN|SCSIEN); 634 test DFCNTRL, (HDMAEN|SCSIEN) jnz .; 635 ret; 636 } 637 638/* 639 * Command phase. Set up the DMA registers and let 'er rip. 640 */ 641p_command: 642 call assert; 643 644/* 645 * Load HADDR and HCNT. 646 */ 647 if ((p->features & AHC_CMD_CHAN) != 0) { 648 bmov HADDR, SCB_CMDPTR, 5; 649 bmov HCNT[1], ALLZEROS, 2; 650 if ((p->features & AHC_ULTRA2) == 0) { 651 bmov STCNT, HCNT, 3; 652 } 653 } else { 654 mvi DINDEX, HADDR; 655 mvi SCB_CMDPTR call bcopy_5; 656 clr HCNT[1]; 657 clr HCNT[2]; 658 call set_stcnt_from_hcnt; 659 } 660 661 if ((p->features & AHC_ULTRA2) == 0) { 662 mvi (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET) call dma; 663 } else { 664 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION); 665 test SSTAT0, SDONE jnz .; 666p_command_dma_loop: 667 test SSTAT0, SDONE jnz p_command_ultra2_dma_done; 668 test SSTAT1,PHASEMIS jz p_command_dma_loop; /* ie. underrun */ 669p_command_ultra2_dma_done: 670 test SCSISIGI, REQI jz p_command_ultra2_shutdown; 671 test SSTAT1, (PHASEMIS|REQINIT) jz p_command_ultra2_dma_done; 672p_command_ultra2_shutdown: 673 and DFCNTRL, ~(HDMAEN|SCSIEN); 674 test DFCNTRL, (HDMAEN|SCSIEN) jnz .; 675 or SXFRCTL0, CLRSTCNT|CLRCHN; 676 } 677 jmp ITloop; 678 679/* 680 * Status phase. Wait for the data byte to appear, then read it 681 * and store it into the SCB. 682 */ 683p_status: 684 call assert; 685 686 mov SCB_TARGET_STATUS, SCSIDATL; 687 jmp ITloop; 688 689/* 690 * Message out phase. If MSG_OUT is 0x80, build I full indentify message 691 * sequence and send it to the target. In addition, if the MK_MESSAGE bit 692 * is set in the SCB_CONTROL byte, interrupt the host and allow it to send 693 * it's own message. 694 * 695 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. 696 * This is done to allow the hsot to send messages outside of an identify 697 * sequence while protecting the seqencer from testing the MK_MESSAGE bit 698 * on an SCB that might not be for the current nexus. (For example, a 699 * BDR message in responce to a bad reselection would leave us pointed to 700 * an SCB that doesn't have anything to do with the current target). 701 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, 702 * bus device reset). 703 * 704 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, 705 * in case the target decides to put us in this phase for some strange 706 * reason. 707 */ 708p_mesgout_retry: 709 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 710p_mesgout: 711 mov SINDEX, MSG_OUT; 712 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; 713p_mesgout_identify: 714 if ((p->features & AHC_WIDE) != 0) { 715 and SINDEX,0xf,SCB_TCL; /* lun */ 716 } else { 717 and SINDEX,0x7,SCB_TCL; /* lun */ 718 } 719 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ 720 or SINDEX,A; /* or in disconnect privledge */ 721 or SINDEX,MSG_IDENTIFYFLAG; 722p_mesgout_mk_message: 723 test SCB_CONTROL,MK_MESSAGE jz p_mesgout_tag; 724 mov SCSIDATL, SINDEX; /* Send the last byte */ 725 jmp p_mesgout_from_host + 1;/* Skip HOST_MSG test */ 726/* 727 * Send a tag message if TAG_ENB is set in the SCB control block. 728 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 729 */ 730p_mesgout_tag: 731 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; 732 mov SCSIDATL, SINDEX; /* Send the identify message */ 733 call phase_lock; 734 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 735 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 736 call phase_lock; 737 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 738 mov SCB_TAG jmp p_mesgout_onebyte; 739/* 740 * Interrupt the driver, and allow it to send a message 741 * if it asks. 742 */ 743p_mesgout_from_host: 744 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; 745 mvi INTSTAT,AWAITING_MSG; 746 nop; 747 /* 748 * Did the host detect a phase change? 749 */ 750 cmp RETURN_1, MSGOUT_PHASEMIS je p_mesgout_done; 751 752p_mesgout_onebyte: 753 mvi CLRSINT1, CLRATNO; 754 mov SCSIDATL, SINDEX; 755 756/* 757 * If the next bus phase after ATN drops is a message out, it means 758 * that the target is requesting that the last message(s) be resent. 759 */ 760 call phase_lock; 761 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; 762 763p_mesgout_done: 764 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 765 mov LAST_MSG, MSG_OUT; 766 cmp MSG_OUT, MSG_IDENTIFYFLAG jne . + 2; 767 and SCB_CONTROL, ~MK_MESSAGE; 768 mvi MSG_OUT, MSG_NOOP; /* No message left */ 769 jmp ITloop; 770 771/* 772 * Message in phase. Bytes are read using Automatic PIO mode. 773 */ 774p_mesgin: 775 mvi ACCUM call inb_first; /* read the 1st message byte */ 776 777 test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 778 cmp A,MSG_DISCONNECT je mesgin_disconnect; 779 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 780 cmp ALLZEROS,A je mesgin_complete; 781 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 782 cmp A,MSG_EXTENDED je mesgin_extended; 783 cmp A,MSG_MESSAGE_REJECT je mesgin_reject; 784 cmp A,MSG_NOOP je mesgin_done; 785 cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_wide_residue; 786 787rej_mesgin: 788/* 789 * We have no idea what this message in is, so we issue a message reject 790 * and hope for the best. In any case, rejection should be a rare 791 * occurrence - signal the driver when it happens. 792 */ 793 mvi INTSTAT,SEND_REJECT; /* let driver know */ 794 795 mvi MSG_MESSAGE_REJECT call mk_mesg; 796 797mesgin_done: 798 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 799 jmp ITloop; 800 801 802mesgin_complete: 803/* 804 * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO, 805 * and trigger a completion interrupt. Before doing so, check to see if there 806 * is a residual or the status byte is something other than STATUS_GOOD (0). 807 * In either of these conditions, we upload the SCB back to the host so it can 808 * process this information. In the case of a non zero status byte, we 809 * additionally interrupt the kernel driver synchronously, allowing it to 810 * decide if sense should be retrieved. If the kernel driver wishes to request 811 * sense, it will fill the kernel SCB with a request sense command and set 812 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload 813 * the SCB, and process it as the next command by adding it to the waiting list. 814 * If the kernel driver does not wish to request sense, it need only clear 815 * RETURN_1, and the command is allowed to complete normally. We don't bother 816 * to post to the QOUTFIFO in the error cases since it would require extra 817 * work in the kernel driver to ensure that the entry was removed before the 818 * command complete code tried processing it. 819 */ 820 821/* 822 * First check for residuals 823 */ 824 test SCB_RESID_SGCNT,0xff jnz upload_scb; 825 test SCB_TARGET_STATUS,0xff jz complete; /* Good Status? */ 826upload_scb: 827 mvi DMAPARAMS, FIFORESET; 828 mov SCB_TAG call dma_scb; 829check_status: 830 test SCB_TARGET_STATUS,0xff jz complete; /* Just a residual? */ 831 mvi INTSTAT,BAD_STATUS; /* let driver know */ 832 nop; 833 cmp RETURN_1, SEND_SENSE jne complete; 834 /* This SCB becomes the next to execute as it will retrieve sense */ 835 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 836 mov SCB_TAG call dma_scb; 837add_to_waiting_list: 838 mov SCB_NEXT,WAITING_SCBH; 839 mov WAITING_SCBH, SCBPTR; 840 /* 841 * Prepare our selection hardware before the busfree so we have a 842 * high probability of winning arbitration. 843 */ 844 call start_selection; 845 jmp await_busfree; 846 847complete: 848 /* If we are untagged, clear our address up in host ram */ 849 test SCB_CONTROL, TAG_ENB jnz complete_post; 850 mov A, SAVED_TCL; 851 mvi UNTAGGEDSCB_OFFSET call post_byte_setup; 852 mvi SCB_LIST_NULL call post_byte; 853 854complete_post: 855 /* Post the SCB and issue an interrupt */ 856 if ((p->features & AHC_QUEUE_REGS) != 0) { 857 mov A, SDSCB_QOFF; 858 } else { 859 mov A, QOUTPOS; 860 } 861 mvi QOUTFIFO_OFFSET call post_byte_setup; 862 mov SCB_TAG call post_byte; 863 if ((p->features & AHC_QUEUE_REGS) == 0) { 864 inc QOUTPOS; 865 } 866 mvi INTSTAT,CMDCMPLT; 867 868add_to_free_list: 869 call add_scb_to_free_list; 870 jmp await_busfree; 871 872/* 873 * Is it an extended message? Copy the message to our message buffer and 874 * notify the host. The host will tell us whether to reject this message, 875 * respond to it with the message that the host placed in our message buffer, 876 * or simply to do nothing. 877 */ 878mesgin_extended: 879 mvi INTSTAT,EXTENDED_MSG; /* let driver know */ 880 jmp ITloop; 881 882/* 883 * Is it a disconnect message? Set a flag in the SCB to remind us 884 * and await the bus going free. 885 */ 886mesgin_disconnect: 887 or SCB_CONTROL,DISCONNECTED; 888 call add_scb_to_disc_list; 889 jmp await_busfree; 890 891/* 892 * Save data pointers message: 893 * Copying RAM values back to SCB, for Save Data Pointers message, but 894 * only if we've actually been into a data phase to change them. This 895 * protects against bogus data in scratch ram and the residual counts 896 * since they are only initialized when we go into data_in or data_out. 897 */ 898mesgin_sdptrs: 899 test SEQ_FLAGS, DPHASE jz mesgin_done; 900 /* 901 * The SCB SGPTR becomes the next one we'll download, 902 * and the SCB DATAPTR becomes the current SHADDR. 903 * Use the residual number since STCNT is corrupted by 904 * any message transfer. 905 */ 906 if ((p->features & AHC_CMD_CHAN) != 0) { 907 bmov SCB_SGCOUNT, SG_COUNT, 5; 908 bmov SCB_DATAPTR, SHADDR, 4; 909 bmov SCB_DATACNT, SCB_RESID_DCNT, 3; 910 } else { 911 mvi DINDEX, SCB_SGCOUNT; 912 mvi SG_COUNT call bcopy_5; 913 mvi DINDEX, SCB_DATAPTR; 914 mvi SHADDR call bcopy_4; 915 mvi SCB_RESID_DCNT call bcopy_3; 916 } 917 jmp mesgin_done; 918 919/* 920 * Restore pointers message? Data pointers are recopied from the 921 * SCB anytime we enter a data phase for the first time, so all 922 * we need to do is clear the DPHASE flag and let the data phase 923 * code do the rest. 924 */ 925mesgin_rdptrs: 926 and SEQ_FLAGS, ~DPHASE; /* 927 * We'll reload them 928 * the next time through 929 * the dataphase. 930 */ 931 jmp mesgin_done; 932 933/* 934 * Identify message? For a reconnecting target, this tells us the lun 935 * that the reconnection is for - find the correct SCB and switch to it, 936 * clearing the "disconnected" bit so we don't "find" it by accident later. 937 */ 938mesgin_identify: 939 940 if ((p->features & AHC_WIDE) != 0) { 941 and A,0x0f; /* lun in lower four bits */ 942 } else { 943 and A,0x07; /* lun in lower three bits */ 944 } 945 or SAVED_TCL,A; /* SAVED_TCL should be complete now */ 946 947 mvi ARG_2, SCB_LIST_NULL; /* SCBID of prev SCB in disc List */ 948 call get_untagged_SCBID; 949 cmp ARG_1, SCB_LIST_NULL je snoop_tag; 950 if ((p->flags & AHC_PAGESCBS) != 0) { 951 test SEQ_FLAGS, SCBPTR_VALID jz use_retrieveSCB; 952 } 953 /* 954 * If the SCB was found in the disconnected list (as is 955 * always the case in non-paging scenarios), SCBPTR is already 956 * set to the correct SCB. So, simply setup the SCB and get 957 * on with things. 958 */ 959 mov SCBPTR call rem_scb_from_disc_list; 960 jmp setup_SCB; 961/* 962 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 963 * If we get one, we use the tag returned to find the proper 964 * SCB. With SCB paging, this requires using search for both tagged 965 * and non-tagged transactions since the SCB may exist in any slot. 966 * If we're not using SCB paging, we can use the tag as the direct 967 * index to the SCB. 968 */ 969snoop_tag: 970 mov NONE,SCSIDATL; /* ACK Identify MSG */ 971snoop_tag_loop: 972 call phase_lock; 973 cmp LASTPHASE, P_MESGIN jne not_found; 974 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 975get_tag: 976 mvi ARG_1 call inb_next; /* tag value */ 977 978use_retrieveSCB: 979 call retrieveSCB; 980setup_SCB: 981 mov A, SAVED_TCL; 982 cmp SCB_TCL, A jne not_found_cleanup_scb; 983 test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb; 984 and SCB_CONTROL,~DISCONNECTED; 985 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 986 /* See if the host wants to send a message upon reconnection */ 987 test SCB_CONTROL, MK_MESSAGE jz mesgin_done; 988 and SCB_CONTROL, ~MK_MESSAGE; 989 mvi HOST_MSG call mk_mesg; 990 jmp mesgin_done; 991 992not_found_cleanup_scb: 993 test SCB_CONTROL, DISCONNECTED jz . + 3; 994 call add_scb_to_disc_list; 995 jmp not_found; 996 call add_scb_to_free_list; 997not_found: 998 mvi INTSTAT, NO_MATCH; 999 mvi MSG_BUS_DEV_RESET call mk_mesg; 1000 jmp mesgin_done; 1001 1002/* 1003 * Message reject? Let the kernel driver handle this. If we have an 1004 * outstanding WDTR or SDTR negotiation, assume that it's a response from 1005 * the target selecting 8bit or asynchronous transfer, otherwise just ignore 1006 * it since we have no clue what it pertains to. 1007 */ 1008mesgin_reject: 1009 mvi INTSTAT, REJECT_MSG; 1010 jmp mesgin_done; 1011 1012/* 1013 * Wide Residue. We handle the simple cases, but pass of the one hard case 1014 * to the kernel (when the residue byte happened to cause us to advance our 1015 * sg element array, so we know have to back that advance out). 1016 */ 1017mesgin_wide_residue: 1018 mvi ARG_1 call inb_next; /* ACK the wide_residue and get */ 1019 /* the size byte */ 1020/* 1021 * In order for this to be reliable, we have to do all sorts of horrible 1022 * magic in terms of resetting the datafifo and reloading the shadow layer 1023 * with the correct new values (so that a subsequent save data pointers 1024 * message will do the right thing). We let the kernel do that work. 1025 */ 1026 mvi INTSTAT, WIDE_RESIDUE; 1027 jmp mesgin_done; 1028 1029/* 1030 * [ ADD MORE MESSAGE HANDLING HERE ] 1031 */ 1032 1033/* 1034 * Locking the driver out, build a one-byte message passed in SINDEX 1035 * if there is no active message already. SINDEX is returned intact. 1036 */ 1037mk_mesg: 1038 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 1039 mov MSG_OUT,SINDEX ret; 1040 1041/* 1042 * Functions to read data in Automatic PIO mode. 1043 * 1044 * According to Adaptec's documentation, an ACK is not sent on input from 1045 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 1046 * latched (the usual way), then read the data byte directly off the bus 1047 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 1048 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 1049 * spec guarantees that the target will hold the data byte on the bus until 1050 * we send our ACK. 1051 * 1052 * The assumption here is that these are called in a particular sequence, 1053 * and that REQ is already set when inb_first is called. inb_{first,next} 1054 * use the same calling convention as inb. 1055 */ 1056 1057inb_next: 1058 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1059inb_next_wait: 1060 /* 1061 * If there is a parity error, wait for the kernel to 1062 * see the interrupt and prepare our message response 1063 * before continuing. 1064 */ 1065 test SSTAT1, REQINIT jz inb_next_wait; 1066 test SSTAT1, SCSIPERR jnz .; 1067 and LASTPHASE, PHASE_MASK, SCSISIGI; 1068 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 1069inb_first: 1070 mov DINDEX,SINDEX; 1071 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 1072inb_last: 1073 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 1074 1075 1076mesgin_phasemis: 1077/* 1078 * We expected to receive another byte, but the target changed phase 1079 */ 1080 mvi INTSTAT, MSGIN_PHASEMIS; 1081 jmp ITloop; 1082 1083/* 1084 * DMA data transfer. HADDR and HCNT must be loaded first, and 1085 * SINDEX should contain the value to load DFCNTRL with - 0x3d for 1086 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared 1087 * during initialization. 1088 */ 1089if ((p->features & AHC_ULTRA2) == 0) { 1090dma: 1091 mov DFCNTRL,SINDEX; 1092dma_loop: 1093 test SSTAT0,DMADONE jnz dma_dmadone; 1094 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 1095dma_phasemis: 1096 test SSTAT0,SDONE jnz dma_checkfifo; 1097 mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */ 1098 1099/* 1100 * We will be "done" DMAing when the transfer count goes to zero, or 1101 * the target changes the phase (in light of this, it makes sense that 1102 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 1103 * doing a SCSI->Host transfer, the data FIFO should be flushed auto- 1104 * magically on STCNT=0 or a phase change, so just wait for FIFO empty 1105 * status. 1106 */ 1107dma_checkfifo: 1108 test DFCNTRL,DIRECTION jnz dma_fifoempty; 1109dma_fifoflush: 1110 test DFSTATUS,FIFOEMP jz dma_fifoflush; 1111 1112dma_fifoempty: 1113 /* Don't clobber an inprogress host data transfer */ 1114 test DFSTATUS, MREQPEND jnz dma_fifoempty; 1115/* 1116 * Now shut the DMA enables off and make sure that the DMA enables are 1117 * actually off first lest we get an ILLSADDR. 1118 */ 1119dma_dmadone: 1120 cmp LASTPHASE, P_COMMAND je dma_await_nreq; 1121 test SCSIRATE, 0x0f jnz dma_shutdown; 1122dma_await_nreq: 1123 test SCSISIGI, REQI jz dma_shutdown; 1124 test SSTAT1, (PHASEMIS|REQINIT) jz dma_await_nreq; 1125dma_shutdown: 1126 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1127dma_halt: 1128 /* 1129 * Some revisions of the aic7880 have a problem where, if the 1130 * data fifo is full, but the PCI input latch is not empty, 1131 * HDMAEN cannot be cleared. The fix used here is to attempt 1132 * to drain the data fifo until there is space for the input 1133 * latch to drain and HDMAEN de-asserts. 1134 */ 1135 if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) { 1136 mov NONE, DFDAT; 1137 } 1138 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 1139} 1140return: 1141 ret; 1142 1143/* 1144 * Assert that if we've been reselected, then we've seen an IDENTIFY 1145 * message. 1146 */ 1147assert: 1148 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 1149 1150 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 1151 1152/* 1153 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) 1154 * or by the SCBID ARG_1. The search begins at the SCB index passed in 1155 * via SINDEX which is an SCB that must be on the disconnected list. If 1156 * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR 1157 * is set to the proper SCB. 1158 */ 1159findSCB: 1160 mov SCBPTR,SINDEX; /* Initialize SCBPTR */ 1161 cmp ARG_1, SCB_LIST_NULL jne findSCB_by_SCBID; 1162 mov A, SAVED_TCL; 1163 mvi SCB_TCL jmp findSCB_loop; /* &SCB_TCL -> SINDEX */ 1164findSCB_by_SCBID: 1165 mov A, ARG_1; /* Tag passed in ARG_1 */ 1166 mvi SCB_TAG jmp findSCB_loop; /* &SCB_TAG -> SINDEX */ 1167findSCB_next: 1168 mov ARG_2, SCBPTR; 1169 cmp SCB_NEXT, SCB_LIST_NULL je notFound; 1170 mov SCBPTR,SCB_NEXT; 1171 dec SINDEX; /* Last comparison moved us too far */ 1172findSCB_loop: 1173 cmp SINDIR, A jne findSCB_next; 1174 mov SINDEX, SCBPTR ret; 1175notFound: 1176 mvi SINDEX, SCB_LIST_NULL ret; 1177 1178/* 1179 * Retrieve an SCB by SCBID first searching the disconnected list falling 1180 * back to DMA'ing the SCB down from the host. This routine assumes that 1181 * ARG_1 is the SCBID of interrest and that SINDEX is the position in the 1182 * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, 1183 * we go directly to the host for the SCB. 1184 */ 1185retrieveSCB: 1186 test SEQ_FLAGS, SCBPTR_VALID jz retrieve_from_host; 1187 mov SCBPTR call findSCB; /* Continue the search */ 1188 cmp SINDEX, SCB_LIST_NULL je retrieve_from_host; 1189 1190/* 1191 * This routine expects SINDEX to contain the index of the SCB to be 1192 * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the 1193 * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL 1194 * if it is at the head. 1195 */ 1196rem_scb_from_disc_list: 1197/* Remove this SCB from the disconnection list */ 1198 cmp ARG_2, SCB_LIST_NULL je rHead; 1199 mov DINDEX, SCB_NEXT; 1200 mov SCBPTR, ARG_2; 1201 mov SCB_NEXT, DINDEX; 1202 mov SCBPTR, SINDEX ret; 1203rHead: 1204 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1205 1206retrieve_from_host: 1207/* 1208 * We didn't find it. Pull an SCB and DMA down the one we want. 1209 * We should never get here in the non-paging case. 1210 */ 1211 mov ALLZEROS call get_free_or_disc_scb; 1212 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1213 /* Jump instead of call as we want to return anyway */ 1214 mov ARG_1 jmp dma_scb; 1215 1216/* 1217 * Determine whether a target is using tagged or non-tagged transactions 1218 * by first looking for a matching transaction based on the TCL and if 1219 * that fails, looking up this device in the host's untagged SCB array. 1220 * The TCL to search for is assumed to be in SAVED_TCL. The value is 1221 * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged). 1222 * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information 1223 * in an SCB instead of having to go to the host. 1224 */ 1225get_untagged_SCBID: 1226 cmp DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host; 1227 mvi ARG_1, SCB_LIST_NULL; 1228 mov DISCONNECTED_SCBH call findSCB; 1229 cmp SINDEX, SCB_LIST_NULL je get_SCBID_from_host; 1230 or SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */ 1231 test SCB_CONTROL, TAG_ENB jnz . + 2; 1232 mov ARG_1, SCB_TAG ret; 1233 mvi ARG_1, SCB_LIST_NULL ret; 1234 1235/* 1236 * Fetch a byte from host memory given an index of (A + (256 * SINDEX)) 1237 * and a base address of SCBID_ADDR. The byte is returned in RETURN_2. 1238 */ 1239fetch_byte: 1240 mov ARG_2, SINDEX; 1241 if ((p->features & AHC_CMD_CHAN) != 0) { 1242 mvi DINDEX, CCHADDR; 1243 mvi SCBID_ADDR call set_1byte_addr; 1244 mvi CCHCNT, 1; 1245 mvi CCSGCTL, CCSGEN|CCSGRESET; 1246 test CCSGCTL, CCSGDONE jz .; 1247 mvi CCSGCTL, CCSGRESET; 1248 bmov RETURN_2, CCSGRAM, 1 ret; 1249 } else { 1250 mvi DINDEX, HADDR; 1251 mvi SCBID_ADDR call set_1byte_addr; 1252 mvi HCNT[0], 1; 1253 clr HCNT[1]; 1254 clr HCNT[2]; 1255 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 1256 call dma_finish; 1257 mov RETURN_2, DFDAT ret; 1258 } 1259 1260/* 1261 * Prepare the hardware to post a byte to host memory given an 1262 * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR. 1263 */ 1264post_byte_setup: 1265 mov ARG_2, SINDEX; 1266 if ((p->features & AHC_CMD_CHAN) != 0) { 1267 mvi DINDEX, CCHADDR; 1268 mvi SCBID_ADDR call set_1byte_addr; 1269 mvi CCHCNT, 1; 1270 mvi CCSCBCTL, CCSCBRESET ret; 1271 } else { 1272 mvi DINDEX, HADDR; 1273 mvi SCBID_ADDR call set_1byte_addr; 1274 mvi HCNT[0], 1; 1275 clr HCNT[1]; 1276 clr HCNT[2]; 1277 mvi DFCNTRL, FIFORESET ret; 1278 } 1279 1280post_byte: 1281 if ((p->features & AHC_CMD_CHAN) != 0) { 1282 bmov CCSCBRAM, SINDEX, 1; 1283 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1284 test CCSCBCTL, CCSCBDONE jz .; 1285 clr CCSCBCTL ret; 1286 } else { 1287 mov DFDAT, SINDEX; 1288 or DFCNTRL, HDMAEN|FIFOFLUSH; 1289 jmp dma_finish; 1290 } 1291 1292get_SCBID_from_host: 1293 mov A, SAVED_TCL; 1294 mvi UNTAGGEDSCB_OFFSET call fetch_byte; 1295 mov RETURN_1, RETURN_2 ret; 1296 1297phase_lock: 1298 test SSTAT1, REQINIT jz phase_lock; 1299 test SSTAT1, SCSIPERR jnz phase_lock; 1300 and SCSISIGO, PHASE_MASK, SCSISIGI; 1301 and LASTPHASE, PHASE_MASK, SCSISIGI ret; 1302 1303if ((p->features & AHC_CMD_CHAN) == 0) { 1304set_stcnt_from_hcnt: 1305 mov STCNT[0], HCNT[0]; 1306 mov STCNT[1], HCNT[1]; 1307 mov STCNT[2], HCNT[2] ret; 1308 1309bcopy_7: 1310 mov DINDIR, SINDIR; 1311 mov DINDIR, SINDIR; 1312bcopy_5: 1313 mov DINDIR, SINDIR; 1314bcopy_4: 1315 mov DINDIR, SINDIR; 1316bcopy_3: 1317 mov DINDIR, SINDIR; 1318 mov DINDIR, SINDIR; 1319 mov DINDIR, SINDIR ret; 1320} 1321 1322/* 1323 * Setup addr assuming that A is an index into 1324 * an array of 32byte objects, SINDEX contains 1325 * the base address of that array, and DINDEX 1326 * contains the base address of the location 1327 * to store the indexed address. 1328 */ 1329set_32byte_addr: 1330 shr ARG_2, 3, A; 1331 shl A, 5; 1332/* 1333 * Setup addr assuming that A + (ARG_1 * 256) is an 1334 * index into an array of 1byte objects, SINDEX contains 1335 * the base address of that array, and DINDEX contains 1336 * the base address of the location to store the computed 1337 * address. 1338 */ 1339set_1byte_addr: 1340 add DINDIR, A, SINDIR; 1341 mov A, ARG_2; 1342 adc DINDIR, A, SINDIR; 1343 clr A; 1344 adc DINDIR, A, SINDIR; 1345 adc DINDIR, A, SINDIR ret; 1346 1347/* 1348 * Either post or fetch and SCB from host memory based on the 1349 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. 1350 */ 1351dma_scb: 1352 mov A, SINDEX; 1353 if ((p->features & AHC_CMD_CHAN) != 0) { 1354 mvi DINDEX, CCHADDR; 1355 mvi HSCB_ADDR call set_32byte_addr; 1356 mov CCSCBPTR, SCBPTR; 1357 mvi CCHCNT, 32; 1358 test DMAPARAMS, DIRECTION jz dma_scb_tohost; 1359 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET; 1360 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .; 1361 jmp dma_scb_finish; 1362dma_scb_tohost: 1363 if ((p->features & AHC_ULTRA2) == 0) { 1364 mvi CCSCBCTL, CCSCBRESET; 1365 bmov CCSCBRAM, SCB_CONTROL, 32; 1366 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1367 test CCSCBCTL, CCSCBDONE jz .; 1368 } 1369 if ((p->features & AHC_ULTRA2) != 0) { 1370 if ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0) { 1371 mvi CCSCBCTL, CCARREN|CCSCBRESET; 1372 cmp CCSCBCTL, ARRDONE|CCARREN jne .; 1373 mvi CCHCNT, 32; 1374 mvi CCSCBCTL, CCSCBEN|CCSCBRESET; 1375 cmp CCSCBCTL, CCSCBDONE|CCSCBEN jne .; 1376 } else { 1377 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET; 1378 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .; 1379 } 1380 } 1381dma_scb_finish: 1382 clr CCSCBCTL; 1383 test CCSCBCTL, CCARREN|CCSCBEN jnz .; 1384 ret; 1385 } 1386 if ((p->features & AHC_CMD_CHAN) == 0) { 1387 mvi DINDEX, HADDR; 1388 mvi HSCB_ADDR call set_32byte_addr; 1389 mvi HCNT[0], 32; 1390 clr HCNT[1]; 1391 clr HCNT[2]; 1392 mov DFCNTRL, DMAPARAMS; 1393 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1394 /* Fill it with the SCB data */ 1395copy_scb_tofifo: 1396 mvi SINDEX, SCB_CONTROL; 1397 add A, 32, SINDEX; 1398copy_scb_tofifo_loop: 1399 mov DFDAT,SINDIR; 1400 mov DFDAT,SINDIR; 1401 mov DFDAT,SINDIR; 1402 mov DFDAT,SINDIR; 1403 mov DFDAT,SINDIR; 1404 mov DFDAT,SINDIR; 1405 mov DFDAT,SINDIR; 1406 mov DFDAT,SINDIR; 1407 cmp SINDEX, A jne copy_scb_tofifo_loop; 1408 or DFCNTRL, HDMAEN|FIFOFLUSH; 1409 jmp dma_finish; 1410dma_scb_fromhost: 1411 mvi DINDEX, SCB_CONTROL; 1412 if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) { 1413 /* 1414 * Set the A to -24. It it hits 0, then we let 1415 * our code fall through to dfdat_in_8 to complete 1416 * the last of the copy. 1417 * 1418 * Also, things happen 8 bytes at a time in this 1419 * case, so we may need to drain the fifo at most 1420 * 3 times to keep things flowing 1421 */ 1422 mvi A, -24; 1423dma_scb_hang_fifo: 1424 /* Wait for the first bit of data to hit the fifo */ 1425 test DFSTATUS, FIFOEMP jnz .; 1426dma_scb_hang_wait: 1427 /* OK, now they've started to transfer into the fifo, 1428 * so wait for them to stop trying to transfer any 1429 * more data. 1430 */ 1431 test DFSTATUS, MREQPEND jnz .; 1432 /* 1433 * OK, they started, then they stopped, now see if they 1434 * managed to complete the job before stopping. Try 1435 * it multiple times to give the chip a few cycles to 1436 * set the flag if it did complete. 1437 */ 1438 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 1439 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 1440 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 1441 /* 1442 * Too bad, the chip didn't complete the DMA, but there 1443 * aren't any more memory requests pending, so that 1444 * means it stopped part way through and hung. That's 1445 * our bug, so now we drain what data there is in the 1446 * fifo in order to get things going again. 1447 */ 1448dma_scb_hang_empty_fifo: 1449 call dfdat_in_8; 1450 add A, 8; 1451 add SINDEX, A, HCNT; 1452 /* 1453 * If there are another 8 bytes of data waiting in the 1454 * fifo, then the carry bit will be set as a result 1455 * of the above add command (unless A is non-negative, 1456 * in which case the carry bit won't be set). 1457 */ 1458 jc dma_scb_hang_empty_fifo; 1459 /* 1460 * We've emptied the fifo now, but we wouldn't have got 1461 * here if the memory transfer hadn't stopped part way 1462 * through, so go back up to the beginning of the 1463 * loop and start over. When it succeeds in getting 1464 * all the data down, HDONE will be set and we'll 1465 * jump to the code just below here. 1466 */ 1467 jmp dma_scb_hang_fifo; 1468dma_scb_hang_dma_done: 1469 and DFCNTRL, ~HDMAEN; 1470 test DFCNTRL, HDMAEN jnz .; 1471 call dfdat_in_8; 1472 add A, 8; 1473 cmp A, 8 jne . - 2; 1474 ret; 1475 } else { 1476 call dma_finish; 1477 call dfdat_in_8; 1478 call dfdat_in_8; 1479 call dfdat_in_8; 1480 } 1481dfdat_in_8: 1482 mov DINDIR,DFDAT; 1483dfdat_in_7: 1484 mov DINDIR,DFDAT; 1485 mov DINDIR,DFDAT; 1486 mov DINDIR,DFDAT; 1487 mov DINDIR,DFDAT; 1488 mov DINDIR,DFDAT; 1489 mov DINDIR,DFDAT; 1490 mov DINDIR,DFDAT ret; 1491 } 1492 1493 1494/* 1495 * Wait for DMA from host memory to data FIFO to complete, then disable 1496 * DMA and wait for it to acknowledge that it's off. 1497 */ 1498if ((p->features & AHC_CMD_CHAN) == 0) { 1499dma_finish: 1500 test DFSTATUS,HDONE jz dma_finish; 1501 /* Turn off DMA */ 1502 and DFCNTRL, ~HDMAEN; 1503 test DFCNTRL, HDMAEN jnz .; 1504 ret; 1505} 1506 1507add_scb_to_free_list: 1508 if ((p->flags & AHC_PAGESCBS) != 0) { 1509 mov SCB_NEXT, FREE_SCBH; 1510 mov FREE_SCBH, SCBPTR; 1511 } 1512 mvi SCB_TAG, SCB_LIST_NULL ret; 1513 1514if ((p->flags & AHC_PAGESCBS) != 0) { 1515get_free_or_disc_scb: 1516 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1517 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1518return_error: 1519 mvi SINDEX, SCB_LIST_NULL ret; 1520dequeue_disc_scb: 1521 mov SCBPTR, DISCONNECTED_SCBH; 1522dma_up_scb: 1523 mvi DMAPARAMS, FIFORESET; 1524 mov SCB_TAG call dma_scb; 1525unlink_disc_scb: 1526 mov DISCONNECTED_SCBH, SCB_NEXT ret; 1527dequeue_free_scb: 1528 mov SCBPTR, FREE_SCBH; 1529 mov FREE_SCBH, SCB_NEXT ret; 1530} 1531 1532add_scb_to_disc_list: 1533/* 1534 * Link this SCB into the DISCONNECTED list. This list holds the 1535 * candidates for paging out an SCB if one is needed for a new command. 1536 * Modifying the disconnected list is a critical(pause dissabled) section. 1537 */ 1538 mov SCB_NEXT, DISCONNECTED_SCBH; 1539 mov DISCONNECTED_SCBH, SCBPTR ret; 1540