aic7xxx.seq revision 47158
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 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.87 1999/03/23 07:24:28 gibbs Exp $ 36 */ 37 38#include <dev/aic7xxx/aic7xxx.reg> 39#include <cam/scsi/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 psuedo-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 and SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ_TEMPLATE; 64 65 if ((ahc->features & AHC_CMD_CHAN) != 0) { 66 /* Ensure that no DMA operations are in progress */ 67 clr CCSGCTL; 68 clr CCSCBCTL; 69 } 70 71poll_for_work: 72 call clear_target_state; 73 and SXFRCTL0, ~SPIOEN; 74 if ((ahc->features & AHC_QUEUE_REGS) == 0) { 75 mov A, QINPOS; 76 } 77poll_for_work_loop: 78 if ((ahc->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 ((ahc->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 ((ahc->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 ((ahc->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 ((ahc->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 ((ahc->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 ((ahc->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 mov SINDEX, SCSISEQ_TEMPLATE; 173 if ((ahc->flags & AHC_TARGETMODE) != 0) { 174 test SCB_CONTROL, TARGET_SCB jz . + 4; 175 if ((ahc->features & AHC_ULTRA2) != 0) { 176 mov SCSIID_ULTRA2, SCB_CMDPTR[2]; 177 } else { 178 mov SCSIID, SCB_CMDPTR[2]; 179 } 180 or SINDEX, TEMODE; 181 jmp initialize_scsiid_fini; 182 } 183 if ((ahc->features & AHC_ULTRA2) != 0) { 184 and A, TID, SCB_TCL; /* Get target ID */ 185 and SCSIID_ULTRA2, OID; /* Clear old target */ 186 or SCSIID_ULTRA2, A; 187 } else { 188 and A, TID, SCB_TCL; /* Get target ID */ 189 and SCSIID, OID; /* Clear old target */ 190 or SCSIID, A; 191 } 192initialize_scsiid_fini: 193 mov SCSISEQ, SINDEX ret; 194 195/* 196 * Initialize transfer settings and clear the SCSI channel. 197 * SINDEX should contain any additional bit's the client wants 198 * set in SXFRCTL0. We also assume that the current SCB is 199 * a valid SCB for the target we wish to talk to. 200 */ 201initialize_channel: 202 or SXFRCTL0, CLRSTCNT|CLRCHN, SINDEX; 203set_transfer_settings: 204 if ((ahc->features & AHC_ULTRA) != 0) { 205 test SCB_CONTROL, ULTRAENB jz . + 2; 206 or SXFRCTL0, FAST20; 207 } 208/* 209 * Initialize SCSIRATE with the appropriate value for this target. 210 */ 211 if ((ahc->features & AHC_ULTRA2) != 0) { 212 bmov SCSIRATE, SCB_SCSIRATE, 2 ret; 213 } else { 214 mov SCSIRATE, SCB_SCSIRATE ret; 215 } 216 217selection: 218 test SSTAT0,SELDO jnz select_out; 219 mvi CLRSINT0, CLRSELDI; 220select_in: 221 if ((ahc->flags & AHC_TARGETMODE) != 0) { 222 if ((ahc->flags & AHC_INITIATORMODE) != 0) { 223 test SSTAT0, TARGET jz initiator_reselect; 224 } 225 226 /* 227 * We've just been selected. Assert BSY and 228 * setup the phase for receiving messages 229 * from the target. 230 */ 231 mvi SCSISIGO, P_MESGOUT|BSYO; 232 mvi CLRSINT1, CLRBUSFREE; 233 234 /* 235 * Setup the DMA for sending the identify and 236 * command information. 237 */ 238 or SEQ_FLAGS, CMDPHASE_PENDING; 239 240 mov A, TQINPOS; 241 if ((ahc->features & AHC_CMD_CHAN) != 0) { 242 mvi DINDEX, CCHADDR; 243 mvi TMODE_CMDADDR call set_32byte_addr; 244 mvi CCSCBCTL, CCSCBRESET; 245 } else { 246 mvi DINDEX, HADDR; 247 mvi TMODE_CMDADDR call set_32byte_addr; 248 mvi DFCNTRL, FIFORESET; 249 } 250 251 /* Initiator that selected us */ 252 and SAVED_TCL, SELID_MASK, SELID; 253 if ((ahc->features & AHC_CMD_CHAN) != 0) { 254 mov CCSCBRAM, SAVED_TCL; 255 } else { 256 mov DFDAT, SAVED_TCL; 257 } 258 259 /* The Target ID we were selected at */ 260 if ((ahc->features & AHC_CMD_CHAN) != 0) { 261 if ((ahc->features & AHC_MULTI_TID) != 0) { 262 and CCSCBRAM, OID, TARGIDIN; 263 } else if ((ahc->features & AHC_ULTRA2) != 0) { 264 and CCSCBRAM, OID, SCSIID_ULTRA2; 265 } else { 266 and CCSCBRAM, OID, SCSIID; 267 } 268 } else { 269 if ((ahc->features & AHC_MULTI_TID) != 0) { 270 and DFDAT, OID, TARGIDIN; 271 } else if ((ahc->features & AHC_ULTRA2) != 0) { 272 and DFDAT, OID, SCSIID_ULTRA2; 273 } else { 274 and DFDAT, OID, SCSIID; 275 } 276 } 277 278 /* No tag yet */ 279 mvi INITIATOR_TAG, SCB_LIST_NULL; 280 281 /* 282 * If ATN isn't asserted, the target isn't interested 283 * in talking to us. Go directly to bus free. 284 */ 285 test SCSISIGI, ATNI jz target_busfree; 286 287 /* 288 * Watch ATN closely now as we pull in messages from the 289 * initiator. We follow the guidlines from section 6.5 290 * of the SCSI-2 spec for what messages are allowed when. 291 */ 292 call target_inb; 293 294 /* 295 * Our first message must be one of IDENTIFY, ABORT, or 296 * BUS_DEVICE_RESET. 297 */ 298 /* XXX May need to be more lax here for older initiators... */ 299 test DINDEX, MSG_IDENTIFYFLAG jz host_target_message_loop; 300 /* Store for host */ 301 if ((ahc->features & AHC_CMD_CHAN) != 0) { 302 mov CCSCBRAM, DINDEX; 303 } else { 304 mov DFDAT, DINDEX; 305 } 306 307 /* Remember for disconnection decision */ 308 test DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2; 309 /* XXX Honor per target settings too */ 310 or SEQ_FLAGS, NO_DISCONNECT; 311 312 test SCSISIGI, ATNI jz ident_messages_done; 313 call target_inb; 314 /* 315 * If this is a tagged request, the tagged message must 316 * immediately follow the identify. We test for a valid 317 * tag message by seeing if it is >= MSG_SIMPLE_Q_TAG and 318 * < MSG_IGN_WIDE_RESIDUE. 319 */ 320 add A, -MSG_SIMPLE_Q_TAG, DINDEX; 321 jnc ident_messages_done; 322 add A, -MSG_IGN_WIDE_RESIDUE, DINDEX; 323 jc ident_messages_done; 324 /* Store for host */ 325 if ((ahc->features & AHC_CMD_CHAN) != 0) { 326 mov CCSCBRAM, DINDEX; 327 } else { 328 mov DFDAT, DINDEX; 329 } 330 331 /* 332 * If the initiator doesn't feel like providing a tag number, 333 * we've got a failed selection and must transition to bus 334 * free. 335 */ 336 test SCSISIGI, ATNI jz target_busfree; 337 338 /* 339 * Store the tag for the host. 340 */ 341 call target_inb; 342 if ((ahc->features & AHC_CMD_CHAN) != 0) { 343 mov CCSCBRAM, DINDEX; 344 } else { 345 mov DFDAT, DINDEX; 346 } 347 mov INITIATOR_TAG, DINDEX; 348 jmp ident_messages_done; 349 350 /* 351 * Pushed message loop to allow the kernel to 352 * run it's own target mode message state engine. 353 */ 354host_target_message_loop: 355 mvi INTSTAT, HOST_MSG_LOOP; 356 nop; 357 cmp RETURN_1, EXIT_MSG_LOOP je target_ITloop; 358 test SSTAT0, SPIORDY jz .; 359 jmp host_target_message_loop; 360 361ident_messages_done: 362 /* If ring buffer is full, return busy or queue full */ 363 mov A, KERNEL_TQINPOS; 364 cmp TQINPOS, A jne tqinfifo_has_space; 365 mvi P_STATUS|BSYO call change_phase; 366 cmp INITIATOR_TAG, SCB_LIST_NULL je . + 3; 367 mvi STATUS_QUEUE_FULL call target_outb; 368 jmp target_busfree_wait; 369 mvi STATUS_BUSY call target_outb; 370 jmp target_busfree_wait; 371tqinfifo_has_space: 372 /* Terminate the ident list */ 373 if ((ahc->features & AHC_CMD_CHAN) != 0) { 374 mvi CCSCBRAM, SCB_LIST_NULL; 375 } else { 376 mvi DFDAT, SCB_LIST_NULL; 377 } 378 or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN; 379 test SCSISIGI, ATNI jnz target_mesgout_pending_msg; 380 jmp target_ITloop; 381 382/* 383 * We carefully toggle SPIOEN to allow us to return the 384 * message byte we receive so it can be checked prior to 385 * driving REQ on the bus for the next byte. 386 */ 387target_inb: 388 /* 389 * Drive REQ on the bus by enabling SCSI PIO. 390 */ 391 or SXFRCTL0, SPIOEN; 392 /* Wait for the byte */ 393 test SSTAT0, SPIORDY jz .; 394 /* Prevent our read from triggering another REQ */ 395 and SXFRCTL0, ~SPIOEN; 396 /* Save latched contents */ 397 mov DINDEX, SCSIDATL ret; 398 } 399 400if ((ahc->flags & AHC_INITIATORMODE) != 0) { 401/* 402 * Reselection has been initiated by a target. Make a note that we've been 403 * reselected, but haven't seen an IDENTIFY message from the target yet. 404 */ 405initiator_reselect: 406 /* XXX test for and handle ONE BIT condition */ 407 and SAVED_TCL, SELID_MASK, SELID; 408 if ((ahc->features & AHC_TWIN) != 0) { 409 test SBLKCTL, SELBUSB jz . + 2; 410 or SAVED_TCL, SELBUSB; 411 } 412 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; 413 mvi CLRSINT1,CLRBUSFREE; 414 or SIMODE1, ENBUSFREE; /* 415 * We aren't expecting a 416 * bus free, so interrupt 417 * the kernel driver if it 418 * happens. 419 */ 420 mvi MSG_OUT, MSG_NOOP; /* No message to send */ 421 jmp ITloop; 422} 423 424/* 425 * After the selection, remove this SCB from the "waiting SCB" 426 * list. This is achieved by simply moving our "next" pointer into 427 * WAITING_SCBH. Our next pointer will be set to null the next time this 428 * SCB is used, so don't bother with it now. 429 */ 430select_out: 431 /* Turn off the selection hardware */ 432 and SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ_TEMPLATE; 433 mvi CLRSINT0, CLRSELDO; 434 mov SCBPTR, WAITING_SCBH; 435 mov WAITING_SCBH,SCB_NEXT; 436 mov SAVED_TCL, SCB_TCL; 437 if ((ahc->flags & AHC_TARGETMODE) != 0) { 438 test SSTAT0, TARGET jz initiator_select; 439 440 /* 441 * We've just re-selected an initiator. 442 * Assert BSY and setup the phase for 443 * sending our identify messages. 444 */ 445 mvi P_MESGIN|BSYO call change_phase; 446 mvi CLRSINT1,CLRBUSFREE; 447 448 /* 449 * Start out with a simple identify message. 450 */ 451 and A, LID, SCB_TCL; 452 or A, MSG_IDENTIFYFLAG call target_outb; 453 454 /* 455 * If we are the result of a tagged command, send 456 * a simple Q tag and the tag id. 457 */ 458 test SCB_CONTROL, TAG_ENB jz . + 3; 459 mvi MSG_SIMPLE_Q_TAG call target_outb; 460 mov SCB_INITIATOR_TAG call target_outb; 461 mov INITIATOR_TAG, SCB_INITIATOR_TAG; 462target_synccmd: 463 /* 464 * Now determine what phases the host wants us 465 * to go through. 466 */ 467 mov SEQ_FLAGS, SCB_TARGET_PHASES; 468 469 470target_ITloop: 471 /* 472 * Start honoring ATN signals now that 473 * we properly identified ourselves. 474 */ 475 test SCSISIGI, ATNI jnz target_mesgout; 476 test SEQ_FLAGS, CMDPHASE_PENDING jnz target_cmdphase; 477 test SEQ_FLAGS, DPHASE_PENDING jnz target_dphase; 478 test SEQ_FLAGS, SPHASE_PENDING jnz target_sphase; 479 480 /* 481 * No more work to do. Either disconnect or not depending 482 * on the state of NO_DISCONNECT. 483 */ 484 test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; 485 if ((ahc->flags & AHC_PAGESCBS) != 0) { 486 mov ALLZEROS call get_free_or_disc_scb; 487 } 488 mov RETURN_1, ALLZEROS; 489 call complete_target_cmd; 490 cmp RETURN_1, CONT_MSG_LOOP jne .; 491 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 492 mov SCB_TAG call dma_scb; 493 jmp target_synccmd; 494 495target_mesgout: 496 mvi SCSISIGO, P_MESGOUT|BSYO; 497 call target_inb; 498 /* Local Processing goes here... */ 499target_mesgout_pending_msg: 500 jmp host_target_message_loop; 501 502target_disconnect: 503 mvi P_MESGIN|BSYO call change_phase; 504 test SEQ_FLAGS, DPHASE jz . + 2; 505 mvi MSG_SAVEDATAPOINTER call target_outb; 506 mvi MSG_DISCONNECT call target_outb; 507 508target_busfree_wait: 509 /* Wait for preceeding I/O session to complete. */ 510 test SCSISIGI, ACKI jnz .; 511target_busfree: 512 clr SCSISIGO; 513 call complete_target_cmd; 514 jmp poll_for_work; 515 516target_cmdphase: 517 mvi P_COMMAND|BSYO call change_phase; 518 call target_inb; 519 mov A, DINDEX; 520 /* Store for host */ 521 if ((ahc->features & AHC_CMD_CHAN) != 0) { 522 mov CCSCBRAM, A; 523 } else { 524 mov DFDAT, A; 525 } 526 527 /* 528 * Determine the number of bytes to read 529 * based on the command group code via table lookup. 530 * We reuse the first 8 bytes of the TARG_SCSIRATE 531 * BIOS array for this table. Count is one less than 532 * the total for the command since we've already fetched 533 * the first byte. 534 */ 535 shr A, CMD_GROUP_CODE_SHIFT; 536 add SINDEX, TARG_SCSIRATE, A; 537 mov A, SINDIR; 538 539 test A, 0xFF jz command_phase_done; 540command_loop: 541 or SXFRCTL0, SPIOEN; 542 test SSTAT0, SPIORDY jz .; 543 cmp A, 1 jne . + 2; 544 and SXFRCTL0, ~SPIOEN; /* Last Byte */ 545 if ((ahc->features & AHC_CMD_CHAN) != 0) { 546 mov CCSCBRAM, SCSIDATL; 547 } else { 548 mov DFDAT, SCSIDATL; 549 } 550 dec A; 551 test A, 0xFF jnz command_loop; 552 553command_phase_done: 554 and SEQ_FLAGS, ~CMDPHASE_PENDING; 555 jmp target_ITloop; 556 557target_dphase: 558 /* 559 * Data direction flags are from the 560 * perspective of the initiator. 561 */ 562 test SCB_TARGET_PHASES[1], TARGET_DATA_IN jz . + 4; 563 mvi LASTPHASE, P_DATAOUT; 564 mvi P_DATAIN|BSYO call change_phase; 565 jmp . + 3; 566 mvi LASTPHASE, P_DATAIN; 567 mvi P_DATAOUT|BSYO call change_phase; 568 mov ALLZEROS call initialize_channel; 569 jmp p_data; 570 571target_sphase: 572 mvi P_STATUS|BSYO call change_phase; 573 mvi LASTPHASE, P_STATUS; 574 mov SCB_TARGET_STATUS call target_outb; 575 /* XXX Watch for ATN or parity errors??? */ 576 mvi SCSISIGO, P_MESGIN|BSYO; 577 /* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */ 578 mov ALLZEROS call target_outb; 579 jmp target_busfree_wait; 580 581complete_target_cmd: 582 test SEQ_FLAGS, TARG_CMD_PENDING jnz . + 2; 583 mov SCB_TAG jmp complete_post; 584 if ((ahc->features & AHC_CMD_CHAN) != 0) { 585 /* Set the valid byte */ 586 mvi CCSCBADDR, 24; 587 mov CCSCBRAM, ALLONES; 588 mvi CCHCNT, 28; 589 or CCSCBCTL, CCSCBEN|CCSCBRESET; 590 test CCSCBCTL, CCSCBDONE jz .; 591 clr CCSCBCTL; 592 } else { 593 /* Set the valid byte */ 594 or DFCNTRL, FIFORESET; 595 mvi DFWADDR, 3; /* Third 64bit word or byte 24 */ 596 mov DFDAT, ALLONES; 597 mvi HCNT[0], 28; 598 clr HCNT[1]; 599 clr HCNT[2]; 600 or DFCNTRL, HDMAEN|FIFOFLUSH; 601 call dma_finish; 602 } 603 inc TQINPOS; 604 mvi INTSTAT,CMDCMPLT ret; 605 } 606 607if ((ahc->flags & AHC_INITIATORMODE) != 0) { 608initiator_select: 609 mvi SPIOEN call initialize_channel; 610 611 /* 612 * We aren't expecting a bus free, so interrupt 613 * the kernel driver if it happens. 614 */ 615 mvi CLRSINT1,CLRBUSFREE; 616 or SIMODE1, ENBUSFREE; 617 618 /* 619 * As soon as we get a successful selection, the target 620 * should go into the message out phase since we have ATN 621 * asserted. 622 */ 623 mvi MSG_OUT, MSG_IDENTIFYFLAG; 624 or SEQ_FLAGS, IDENTIFY_SEEN; 625 626 /* 627 * Main loop for information transfer phases. Wait for the 628 * target to assert REQ before checking MSG, C/D and I/O for 629 * the bus phase. 630 */ 631ITloop: 632 call phase_lock; 633 634 mov A, LASTPHASE; 635 636 test A, ~P_DATAIN jz p_data; 637 cmp A,P_COMMAND je p_command; 638 cmp A,P_MESGOUT je p_mesgout; 639 cmp A,P_STATUS je p_status; 640 cmp A,P_MESGIN je p_mesgin; 641 642 mvi INTSTAT,BAD_PHASE; 643 jmp ITloop; /* Try reading the bus again. */ 644 645await_busfree: 646 and SIMODE1, ~ENBUSFREE; 647 mov NONE, SCSIDATL; /* Ack the last byte */ 648 and SXFRCTL0, ~SPIOEN; 649 test SSTAT1,REQINIT|BUSFREE jz .; 650 test SSTAT1, BUSFREE jnz poll_for_work; 651 mvi INTSTAT, BAD_PHASE; 652} 653 654clear_target_state: 655 /* 656 * We assume that the kernel driver may reset us 657 * at any time, even in the middle of a DMA, so 658 * clear DFCNTRL too. 659 */ 660 clr DFCNTRL; 661 662 /* 663 * We don't know the target we will connect to, 664 * so default to narrow transfers to avoid 665 * parity problems. 666 */ 667 if ((ahc->features & AHC_ULTRA2) != 0) { 668 bmov SCSIRATE, ALLZEROS, 2; 669 } else { 670 clr SCSIRATE; 671 and SXFRCTL0, ~(FAST20); 672 } 673 mvi LASTPHASE, P_BUSFREE; 674 /* clear target specific flags */ 675 clr SEQ_FLAGS ret; 676 677/* 678 * If we re-enter the data phase after going through another phase, the 679 * STCNT may have been cleared, so restore it from the residual field. 680 */ 681data_phase_reinit: 682 if ((ahc->features & AHC_CMD_CHAN) != 0) { 683 bmov STCNT, SCB_RESID_DCNT, 3; 684 } else { 685 mvi DINDEX, STCNT; 686 mvi SCB_RESID_DCNT call bcopy_3; 687 } 688 and DATA_COUNT_ODD, 0x1, SCB_RESID_DCNT[0]; 689 jmp data_phase_loop; 690 691p_data: 692 if ((ahc->features & AHC_ULTRA2) != 0) { 693 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; 694 } else { 695 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 696 } 697 test LASTPHASE, IOI jnz . + 2; 698 or DMAPARAMS, DIRECTION; 699 call assert; /* 700 * Ensure entering a data 701 * phase is okay - seen identify, etc. 702 */ 703 if ((ahc->features & AHC_CMD_CHAN) != 0) { 704 mvi CCSGADDR, CCSGADDR_MAX; 705 } 706 test SEQ_FLAGS, DPHASE jnz data_phase_reinit; 707 708 /* We have seen a data phase */ 709 or SEQ_FLAGS, DPHASE; 710 711 /* 712 * Initialize the DMA address and counter from the SCB. 713 * Also set SG_COUNT and SG_NEXT in memory since we cannot 714 * modify the values in the SCB itself until we see a 715 * save data pointers message. 716 */ 717 if ((ahc->features & AHC_CMD_CHAN) != 0) { 718 bmov HADDR, SCB_DATAPTR, 7; 719 } else { 720 mvi DINDEX, HADDR; 721 mvi SCB_DATAPTR call bcopy_7; 722 } 723 and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0]; 724 725 if ((ahc->features & AHC_ULTRA2) == 0) { 726 if ((ahc->features & AHC_CMD_CHAN) != 0) { 727 bmov STCNT, HCNT, 3; 728 } else { 729 call set_stcnt_from_hcnt; 730 } 731 } 732 733 if ((ahc->features & AHC_CMD_CHAN) != 0) { 734 bmov SG_COUNT, SCB_SGCOUNT, 5; 735 } else { 736 mvi DINDEX, SG_COUNT; 737 mvi SCB_SGCOUNT call bcopy_5; 738 } 739 740data_phase_loop: 741/* Guard against overruns */ 742 test SG_COUNT, 0xff jnz data_phase_inbounds; 743/* 744 * Turn on 'Bit Bucket' mode, set the transfer count to 745 * 16meg and let the target run until it changes phase. 746 * When the transfer completes, notify the host that we 747 * had an overrun. 748 */ 749 or SXFRCTL1,BITBUCKET; 750 and DMAPARAMS, ~(HDMAEN|SDMAEN); 751 if ((ahc->features & AHC_ULTRA2) != 0) { 752 bmov HCNT, ALLONES, 3; 753 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 754 bmov STCNT, ALLONES, 3; 755 } else { 756 mvi STCNT[0], 0xFF; 757 mvi STCNT[1], 0xFF; 758 mvi STCNT[2], 0xFF; 759 } 760data_phase_inbounds: 761/* If we are the last SG block, tell the hardware. */ 762 cmp SG_COUNT,0x01 jne data_phase_wideodd; 763 if ((ahc->features & AHC_ULTRA2) != 0) { 764 or SG_CACHEPTR, LAST_SEG; 765 } else { 766 and DMAPARAMS, ~WIDEODD; 767 } 768data_phase_wideodd: 769 if ((ahc->features & AHC_ULTRA2) != 0) { 770 mov SINDEX, ALLONES; 771 mov DFCNTRL, DMAPARAMS; 772 test SSTAT0, SDONE jnz .;/* Wait for preload to complete */ 773data_phase_dma_loop: 774 test SSTAT0, SDONE jnz data_phase_dma_done; 775 test SSTAT1,PHASEMIS jz data_phase_dma_loop; /* ie. underrun */ 776data_phase_dma_phasemis: 777 test SSTAT0,SDONE jnz . + 2; 778 mov SINDEX,ALLZEROS; /* Remeber the phasemiss */ 779 } else { 780 mov DMAPARAMS call dma; 781 } 782 783data_phase_dma_done: 784/* Go tell the host about any overruns */ 785 test SXFRCTL1,BITBUCKET jnz data_phase_overrun; 786 787/* Exit if we had an underrun. dma clears SINDEX in this case. */ 788 test SINDEX,0xff jz data_phase_finish; 789 790/* 791 * Advance the scatter-gather pointers if needed 792 */ 793sg_advance: 794 dec SG_COUNT; /* one less segment to go */ 795 796 test SG_COUNT, 0xff jz data_phase_finish; /* Are we done? */ 797/* 798 * Load a struct scatter and set up the data address and length. 799 * If the working value of the SG count is nonzero, then 800 * we need to load a new set of values. 801 * 802 * This, like all DMA's, assumes little-endian host data storage. 803 */ 804sg_load: 805 if ((ahc->features & AHC_CMD_CHAN) != 0) { 806 /* 807 * Do we have any prefetch left??? 808 */ 809 cmp CCSGADDR, CCSGADDR_MAX jne prefetched_segs_avail; 810 811 /* 812 * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes. 813 */ 814 add A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT; 815 mvi A, CCSGADDR_MAX; 816 jc . + 2; 817 shl A, 3, SG_COUNT; 818 mov CCHCNT, A; 819 bmov CCHADDR, SG_NEXT, 4; 820 mvi CCSGCTL, CCSGEN|CCSGRESET; 821 test CCSGCTL, CCSGDONE jz .; 822 and CCSGCTL, ~CCSGEN; 823 test CCSGCTL, CCSGEN jnz .; 824 mvi CCSGCTL, CCSGRESET; 825prefetched_segs_avail: 826 bmov HADDR, CCSGRAM, 8; 827 } else { 828 mvi DINDEX, HADDR; 829 mvi SG_NEXT call bcopy_4; 830 831 mvi HCNT[0],SG_SIZEOF; 832 clr HCNT[1]; 833 clr HCNT[2]; 834 835 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 836 837 call dma_finish; 838 839 /* 840 * Copy data from FIFO into SCB data pointer and data count. 841 * This assumes that the SG segments are of the form: 842 * struct ahc_dma_seg { 843 * u_int32_t addr; four bytes, little-endian order 844 * u_int32_t len; four bytes, little endian order 845 * }; 846 */ 847 mvi HADDR call dfdat_in_7; 848 } 849 850 /* Track odd'ness */ 851 test HCNT[0], 0x1 jz . + 2; 852 xor DATA_COUNT_ODD, 0x1; 853 854 if ((ahc->features & AHC_ULTRA2) == 0) { 855 /* Load STCNT as well. It is a mirror of HCNT */ 856 if ((ahc->features & AHC_CMD_CHAN) != 0) { 857 bmov STCNT, HCNT, 3; 858 } else { 859 call set_stcnt_from_hcnt; 860 } 861 } 862 863/* Advance the SG pointer */ 864 clr A; /* add sizeof(struct scatter) */ 865 add SG_NEXT[0],SG_SIZEOF; 866 adc SG_NEXT[1],A; 867 868 if ((ahc->flags & AHC_TARGETMODE) != 0) { 869 test SSTAT0, TARGET jnz data_phase_loop; 870 } 871 test SSTAT1, REQINIT jz .; 872 test SSTAT1,PHASEMIS jz data_phase_loop; 873 874 /* Ensure the last seg is visable at the shaddow layer */ 875 if ((ahc->features & AHC_ULTRA2) != 0) { 876 or DFCNTRL, PRELOADEN; 877 } 878 879data_phase_finish: 880 if ((ahc->features & AHC_ULTRA2) != 0) { 881 call ultra2_dmafinish; 882 } 883/* 884 * After a DMA finishes, save the SG and STCNT residuals back into the SCB 885 * We use STCNT instead of HCNT, since it's a reflection of how many bytes 886 * were transferred on the SCSI (as opposed to the host) bus. 887 */ 888 if ((ahc->features & AHC_CMD_CHAN) != 0) { 889 bmov SCB_RESID_DCNT, STCNT, 3; 890 } else { 891 mov SCB_RESID_DCNT[0],STCNT[0]; 892 mov SCB_RESID_DCNT[1],STCNT[1]; 893 mov SCB_RESID_DCNT[2],STCNT[2]; 894 } 895 mov SCB_RESID_SGCNT, SG_COUNT; 896 897 if ((ahc->features & AHC_ULTRA2) != 0) { 898 or SXFRCTL0, CLRSTCNT|CLRCHN; 899 } 900 901 if ((ahc->flags & AHC_TARGETMODE) != 0) { 902 test SEQ_FLAGS, DPHASE_PENDING jz ITloop; 903 and SEQ_FLAGS, ~DPHASE_PENDING; 904 /* 905 * For data-in phases, wait for any pending acks from the 906 * initiator before changing phase. 907 */ 908 test DFCNTRL, DIRECTION jz target_ITloop; 909 test SSTAT1, REQINIT jnz .; 910 jmp target_ITloop; 911 } 912 jmp ITloop; 913 914data_phase_overrun: 915 if ((ahc->features & AHC_ULTRA2) != 0) { 916 call ultra2_dmafinish; 917 or SXFRCTL0, CLRSTCNT|CLRCHN; 918 } 919/* 920 * Turn off BITBUCKET mode and notify the host 921 */ 922 and SXFRCTL1, ~BITBUCKET; 923 mvi INTSTAT,DATA_OVERRUN; 924 jmp ITloop; 925 926ultra2_dmafinish: 927 if ((ahc->features & AHC_ULTRA2) != 0) { 928 test DFCNTRL, DIRECTION jnz ultra2_dmahalt; 929 and DFCNTRL, ~SCSIEN; 930 test DFCNTRL, SCSIEN jnz .; 931 or DFCNTRL, FIFOFLUSH; 932 test DFSTATUS, FIFOEMP jz . - 1; 933ultra2_dmahalt: 934 and DFCNTRL, ~(SCSIEN|HDMAEN); 935 test DFCNTRL, HDMAEN jnz .; 936 ret; 937 } 938 939if ((ahc->flags & AHC_INITIATORMODE) != 0) { 940/* 941 * Command phase. Set up the DMA registers and let 'er rip. 942 */ 943p_command: 944 call assert; 945 946 if ((ahc->features & AHC_CMD_CHAN) != 0) { 947 mov HCNT[0], SCB_CMDLEN; 948 bmov HCNT[1], ALLZEROS, 2; 949 if ((ahc->features & AHC_ULTRA2) == 0) { 950 bmov STCNT, HCNT, 3; 951 } 952 add NONE, -17, SCB_CMDLEN; 953 jc dma_cmd_data; 954 if ((ahc->features & AHC_ULTRA2) != 0) { 955 mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION); 956 } else { 957 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); 958 } 959 bmov DFDAT, SCB_CMDSTORE, 16; 960 jmp cmd_loop; 961dma_cmd_data: 962 bmov HADDR, SCB_CMDPTR, 4; 963 } else { 964 mvi DINDEX, HADDR; 965 mvi SCB_CMDPTR call bcopy_5; 966 clr HCNT[1]; 967 clr HCNT[2]; 968 } 969 970 if ((ahc->features & AHC_ULTRA2) == 0) { 971 if ((ahc->features & AHC_CMD_CHAN) == 0) { 972 call set_stcnt_from_hcnt; 973 } 974 mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); 975 } else { 976 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION); 977 } 978cmd_loop: 979 test SSTAT0, SDONE jnz . + 2; 980 test SSTAT1, PHASEMIS jz cmd_loop; 981 and DFCNTRL, ~(SCSIEN|HDMAEN|SDMAEN); 982 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; 983 jmp ITloop; 984 985/* 986 * Status phase. Wait for the data byte to appear, then read it 987 * and store it into the SCB. 988 */ 989p_status: 990 call assert; 991 992 mov SCB_TARGET_STATUS, SCSIDATL; 993 jmp ITloop; 994 995/* 996 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full 997 * indentify message sequence and send it to the target. The host may 998 * override this behavior by setting the MK_MESSAGE bit in the SCB 999 * control byte. This will cause us to interrupt the host and allow 1000 * it to handle the message phase completely on its own. If the bit 1001 * associated with this target is set, we will also interrupt the host, 1002 * thereby allowing it to send a message on the next selection regardless 1003 * of the transaction being sent. 1004 * 1005 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. 1006 * This is done to allow the host to send messages outside of an identify 1007 * sequence while protecting the seqencer from testing the MK_MESSAGE bit 1008 * on an SCB that might not be for the current nexus. (For example, a 1009 * BDR message in responce to a bad reselection would leave us pointed to 1010 * an SCB that doesn't have anything to do with the current target). 1011 * 1012 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, 1013 * bus device reset). 1014 * 1015 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, 1016 * in case the target decides to put us in this phase for some strange 1017 * reason. 1018 */ 1019p_mesgout_retry: 1020 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 1021p_mesgout: 1022 mov SINDEX, MSG_OUT; 1023 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; 1024 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; 1025 mov FUNCTION1, SCB_TCL; 1026 mov A, FUNCTION1; 1027 mov SINDEX, TARGET_MSG_REQUEST[0]; 1028 if ((ahc->features & AHC_HS_MAILBOX) != 0) { 1029 /* 1030 * Work around a pausing bug in at least the aic7890. 1031 * If the host needs to update the TARGET_MSG_REQUEST 1032 * bit field, it will set the HS_MAILBOX to 1. In 1033 * response, we pause with a specific interrupt code 1034 * asking for the mask to be updated before we continue. 1035 * Ugh. 1036 */ 1037 test HS_MAILBOX, 0xF0 jz . + 2; 1038 mvi INTSTAT, UPDATE_TMSG_REQ; 1039 } 1040 if ((ahc->features & AHC_TWIN) != 0) { 1041 /* Second Channel uses high byte bits */ 1042 test SCB_TCL, SELBUSB jz . + 2; 1043 mov SINDEX, TARGET_MSG_REQUEST[1]; 1044 } else if ((ahc->features & AHC_WIDE) != 0) { 1045 test SCB_TCL, 0x80 jz . + 2; /* target > 7 */ 1046 mov SINDEX, TARGET_MSG_REQUEST[1]; 1047 } 1048 test SINDEX, A jnz host_message_loop; 1049p_mesgout_identify: 1050 and SINDEX,LID,SCB_TCL; /* lun */ 1051 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ 1052 or SINDEX,A; /* or in disconnect privledge */ 1053 or SINDEX,MSG_IDENTIFYFLAG; 1054/* 1055 * Send a tag message if TAG_ENB is set in the SCB control block. 1056 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 1057 */ 1058p_mesgout_tag: 1059 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; 1060 mov SCSIDATL, SINDEX; /* Send the identify message */ 1061 call phase_lock; 1062 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1063 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 1064 call phase_lock; 1065 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1066 mov SCB_TAG jmp p_mesgout_onebyte; 1067/* 1068 * Interrupt the driver, and allow it to handle this message 1069 * phase and any required retries. 1070 */ 1071p_mesgout_from_host: 1072 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; 1073 jmp host_message_loop; 1074 1075p_mesgout_onebyte: 1076 mvi CLRSINT1, CLRATNO; 1077 mov SCSIDATL, SINDEX; 1078 1079/* 1080 * If the next bus phase after ATN drops is message out, it means 1081 * that the target is requesting that the last message(s) be resent. 1082 */ 1083 call phase_lock; 1084 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; 1085 1086p_mesgout_done: 1087 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 1088 mov LAST_MSG, MSG_OUT; 1089 mvi MSG_OUT, MSG_NOOP; /* No message left */ 1090 jmp ITloop; 1091 1092/* 1093 * Message in phase. Bytes are read using Automatic PIO mode. 1094 */ 1095p_mesgin: 1096 mvi ACCUM call inb_first; /* read the 1st message byte */ 1097 1098 test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 1099 cmp A,MSG_DISCONNECT je mesgin_disconnect; 1100 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 1101 cmp ALLZEROS,A je mesgin_complete; 1102 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 1103 cmp A,MSG_NOOP je mesgin_done; 1104 1105/* 1106 * Pushed message loop to allow the kernel to 1107 * RUN IT's own message state engine. To avoid an 1108 * extra nop instruction after signaling the kernel, 1109 * we perform the phase_lock before checking to see 1110 * if we should exit the loop and skip the phase_lock 1111 * in the ITloop. Performing back to back phase_locks 1112 * shouldn't hurt, but why do it twice... 1113 */ 1114host_message_loop: 1115 mvi INTSTAT, HOST_MSG_LOOP; 1116 call phase_lock; 1117 cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1; 1118 jmp host_message_loop; 1119 1120mesgin_done: 1121 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1122 jmp ITloop; 1123 1124 1125mesgin_complete: 1126/* 1127 * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO, 1128 * and trigger a completion interrupt. Before doing so, check to see if there 1129 * is a residual or the status byte is something other than STATUS_GOOD (0). 1130 * In either of these conditions, we upload the SCB back to the host so it can 1131 * process this information. In the case of a non zero status byte, we 1132 * additionally interrupt the kernel driver synchronously, allowing it to 1133 * decide if sense should be retrieved. If the kernel driver wishes to request 1134 * sense, it will fill the kernel SCB with a request sense command and set 1135 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload 1136 * the SCB, and process it as the next command by adding it to the waiting list. 1137 * If the kernel driver does not wish to request sense, it need only clear 1138 * RETURN_1, and the command is allowed to complete normally. We don't bother 1139 * to post to the QOUTFIFO in the error cases since it would require extra 1140 * work in the kernel driver to ensure that the entry was removed before the 1141 * command complete code tried processing it. 1142 */ 1143 1144/* 1145 * First check for residuals 1146 */ 1147 test SCB_RESID_SGCNT,0xff jnz upload_scb; 1148 test SCB_TARGET_STATUS,0xff jz complete; /* Good Status? */ 1149upload_scb: 1150 mvi DMAPARAMS, FIFORESET; 1151 mov SCB_TAG call dma_scb; 1152check_status: 1153 test SCB_TARGET_STATUS,0xff jz complete; /* Just a residual? */ 1154 mvi INTSTAT,BAD_STATUS; /* let driver know */ 1155 nop; 1156 cmp RETURN_1, SEND_SENSE jne complete; 1157 /* This SCB becomes the next to execute as it will retrieve sense */ 1158 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1159 mov SCB_TAG call dma_scb; 1160add_to_waiting_list: 1161 mov SCB_NEXT,WAITING_SCBH; 1162 mov WAITING_SCBH, SCBPTR; 1163 /* 1164 * Prepare our selection hardware before the busfree so we have a 1165 * high probability of winning arbitration. 1166 */ 1167 call start_selection; 1168 jmp await_busfree; 1169 1170complete: 1171 /* If we are untagged, clear our address up in host ram */ 1172 test SCB_CONTROL, TAG_ENB jnz complete_queue; 1173 mov A, SAVED_TCL; 1174 mvi UNTAGGEDSCB_OFFSET call post_byte_setup; 1175 mvi SCB_LIST_NULL call post_byte; 1176 1177complete_queue: 1178 mov SCB_TAG call complete_post; 1179 jmp await_busfree; 1180} 1181 1182complete_post: 1183 /* Post the SCBID in SINDEX and issue an interrupt */ 1184 call add_scb_to_free_list; 1185 mov ARG_1, SINDEX; 1186 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 1187 mov A, SDSCB_QOFF; 1188 } else { 1189 mov A, QOUTPOS; 1190 } 1191 mvi QOUTFIFO_OFFSET call post_byte_setup; 1192 mov ARG_1 call post_byte; 1193 if ((ahc->features & AHC_QUEUE_REGS) == 0) { 1194 inc QOUTPOS; 1195 } 1196 mvi INTSTAT,CMDCMPLT ret; 1197 1198if ((ahc->flags & AHC_INITIATORMODE) != 0) { 1199/* 1200 * Is it a disconnect message? Set a flag in the SCB to remind us 1201 * and await the bus going free. 1202 */ 1203mesgin_disconnect: 1204 or SCB_CONTROL,DISCONNECTED; 1205 call add_scb_to_disc_list; 1206 jmp await_busfree; 1207 1208/* 1209 * Save data pointers message: 1210 * Copying RAM values back to SCB, for Save Data Pointers message, but 1211 * only if we've actually been into a data phase to change them. This 1212 * protects against bogus data in scratch ram and the residual counts 1213 * since they are only initialized when we go into data_in or data_out. 1214 */ 1215mesgin_sdptrs: 1216 test SEQ_FLAGS, DPHASE jz mesgin_done; 1217 1218 /* 1219 * The SCB SGPTR becomes the next one we'll download, 1220 * and the SCB DATAPTR becomes the current SHADDR. 1221 * Use the residual number since STCNT is corrupted by 1222 * any message transfer. 1223 */ 1224 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1225 bmov SCB_SGCOUNT, SG_COUNT, 5; 1226 bmov SCB_DATAPTR, SHADDR, 4; 1227 bmov SCB_DATACNT, SCB_RESID_DCNT, 3; 1228 } else { 1229 mvi DINDEX, SCB_SGCOUNT; 1230 mvi SG_COUNT call bcopy_5; 1231 1232 mvi DINDEX, SCB_DATAPTR; 1233 mvi SHADDR call bcopy_4; 1234 mvi SCB_RESID_DCNT call bcopy_3; 1235 } 1236 jmp mesgin_done; 1237 1238/* 1239 * Restore pointers message? Data pointers are recopied from the 1240 * SCB anytime we enter a data phase for the first time, so all 1241 * we need to do is clear the DPHASE flag and let the data phase 1242 * code do the rest. 1243 */ 1244mesgin_rdptrs: 1245 and SEQ_FLAGS, ~DPHASE; /* 1246 * We'll reload them 1247 * the next time through 1248 * the dataphase. 1249 */ 1250 jmp mesgin_done; 1251 1252/* 1253 * Identify message? For a reconnecting target, this tells us the lun 1254 * that the reconnection is for - find the correct SCB and switch to it, 1255 * clearing the "disconnected" bit so we don't "find" it by accident later. 1256 */ 1257mesgin_identify: 1258 1259 if ((ahc->features & AHC_WIDE) != 0) { 1260 and A,0x0f; /* lun in lower four bits */ 1261 } else { 1262 and A,0x07; /* lun in lower three bits */ 1263 } 1264 or SAVED_TCL,A; /* SAVED_TCL should be complete now */ 1265 1266 mvi ARG_2, SCB_LIST_NULL; /* SCBID of prev SCB in disc List */ 1267 call get_untagged_SCBID; 1268 cmp ARG_1, SCB_LIST_NULL je snoop_tag; 1269 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1270 test SEQ_FLAGS, SCBPTR_VALID jz use_retrieveSCB; 1271 } 1272 /* 1273 * If the SCB was found in the disconnected list (as is 1274 * always the case in non-paging scenarios), SCBPTR is already 1275 * set to the correct SCB. So, simply setup the SCB and get 1276 * on with things. 1277 */ 1278 call rem_scb_from_disc_list; 1279 jmp setup_SCB; 1280/* 1281 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 1282 * If we get one, we use the tag returned to find the proper 1283 * SCB. With SCB paging, this requires using search for both tagged 1284 * and non-tagged transactions since the SCB may exist in any slot. 1285 * If we're not using SCB paging, we can use the tag as the direct 1286 * index to the SCB. 1287 */ 1288snoop_tag: 1289 mov NONE,SCSIDATL; /* ACK Identify MSG */ 1290snoop_tag_loop: 1291 call phase_lock; 1292 cmp LASTPHASE, P_MESGIN jne not_found; 1293 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 1294get_tag: 1295 mvi ARG_1 call inb_next; /* tag value */ 1296 1297 /* 1298 * Ensure that the SCB the tag points to is for 1299 * an SCB transaction to the reconnecting target. 1300 */ 1301use_retrieveSCB: 1302 call retrieveSCB; 1303setup_SCB: 1304 mov A, SAVED_TCL; 1305 cmp SCB_TCL, A jne not_found_cleanup_scb; 1306 test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb; 1307 and SCB_CONTROL,~DISCONNECTED; 1308 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 1309 call set_transfer_settings; 1310 /* See if the host wants to send a message upon reconnection */ 1311 test SCB_CONTROL, MK_MESSAGE jz mesgin_done; 1312 and SCB_CONTROL, ~MK_MESSAGE; 1313 mvi HOST_MSG call mk_mesg; 1314 jmp mesgin_done; 1315 1316not_found_cleanup_scb: 1317 test SCB_CONTROL, DISCONNECTED jz . + 3; 1318 call add_scb_to_disc_list; 1319 jmp not_found; 1320 call add_scb_to_free_list; 1321not_found: 1322 mvi INTSTAT, NO_MATCH; 1323 jmp mesgin_done; 1324 1325/* 1326 * [ ADD MORE MESSAGE HANDLING HERE ] 1327 */ 1328 1329/* 1330 * Locking the driver out, build a one-byte message passed in SINDEX 1331 * if there is no active message already. SINDEX is returned intact. 1332 */ 1333mk_mesg: 1334 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 1335 mov MSG_OUT,SINDEX ret; 1336 1337/* 1338 * Functions to read data in Automatic PIO mode. 1339 * 1340 * According to Adaptec's documentation, an ACK is not sent on input from 1341 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 1342 * latched (the usual way), then read the data byte directly off the bus 1343 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 1344 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 1345 * spec guarantees that the target will hold the data byte on the bus until 1346 * we send our ACK. 1347 * 1348 * The assumption here is that these are called in a particular sequence, 1349 * and that REQ is already set when inb_first is called. inb_{first,next} 1350 * use the same calling convention as inb. 1351 */ 1352 1353inb_next: 1354 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1355inb_next_wait: 1356 /* 1357 * If there is a parity error, wait for the kernel to 1358 * see the interrupt and prepare our message response 1359 * before continuing. 1360 */ 1361 test SSTAT1, REQINIT jz inb_next_wait; 1362 test SSTAT1, SCSIPERR jnz inb_next_wait; 1363 and LASTPHASE, PHASE_MASK, SCSISIGI; 1364 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 1365inb_first: 1366 mov DINDEX,SINDEX; 1367 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 1368inb_last: 1369 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 1370} 1371 1372if ((ahc->flags & AHC_TARGETMODE) != 0) { 1373/* 1374 * Change to a new phase. If we are changing the state of the I/O signal, 1375 * from out to in, wait an additional data release delay before continuing. 1376 */ 1377change_phase: 1378 /* Wait for preceeding I/O session to complete. */ 1379 test SCSISIGI, ACKI jnz .; 1380 1381 /* Change the phase */ 1382 and DINDEX, IOI, SCSISIGI; 1383 mov SCSISIGO, SINDEX; 1384 and A, IOI, SINDEX; 1385 1386 /* 1387 * If the data direction has changed, from 1388 * out (initiator driving) to in (target driving), 1389 * we must waitat least a data release delay plus 1390 * the normal bus settle delay. [SCSI III SPI 10.11.0] 1391 */ 1392 cmp DINDEX, A je change_phase_wait; 1393 test SINDEX, IOI jz change_phase_wait; 1394 call change_phase_wait; 1395change_phase_wait: 1396 nop; 1397 nop; 1398 nop; 1399 nop ret; 1400 1401/* 1402 * Send a byte to an initiator in Automatic PIO mode. 1403 */ 1404target_outb: 1405 or SXFRCTL0, SPIOEN; 1406 test SSTAT0, SPIORDY jz .; 1407 mov SCSIDATL, SINDEX; 1408 test SSTAT0, SPIORDY jz .; 1409 and SXFRCTL0, ~SPIOEN ret; 1410} 1411 1412mesgin_phasemis: 1413/* 1414 * We expected to receive another byte, but the target changed phase 1415 */ 1416 mvi INTSTAT, MSGIN_PHASEMIS; 1417 jmp ITloop; 1418 1419/* 1420 * DMA data transfer. HADDR and HCNT must be loaded first, and 1421 * SINDEX should contain the value to load DFCNTRL with - 0x3d for 1422 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared 1423 * during initialization. 1424 */ 1425dma: 1426 mov DFCNTRL,SINDEX; 1427dma_loop: 1428 test SSTAT0,DMADONE jnz dma_dmadone; 1429 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 1430dma_phasemis: 1431 test SSTAT0,SDONE jnz dma_checkfifo; 1432 mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */ 1433 1434/* 1435 * We will be "done" DMAing when the transfer count goes to zero, or 1436 * the target changes the phase (in light of this, it makes sense that 1437 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 1438 * doing a SCSI->Host transfer, the data FIFO should be flushed auto- 1439 * magically on STCNT=0 or a phase change, so just wait for FIFO empty 1440 * status. 1441 */ 1442dma_checkfifo: 1443 test DFCNTRL,DIRECTION jnz dma_fifoempty; 1444dma_fifoflush: 1445 test DFSTATUS,FIFOEMP jz dma_fifoflush; 1446 1447dma_fifoempty: 1448 /* Don't clobber an inprogress host data transfer */ 1449 test DFSTATUS, MREQPEND jnz dma_fifoempty; 1450/* 1451 * Now shut the DMA enables off and make sure that the DMA enables are 1452 * actually off first lest we get an ILLSADDR. 1453 */ 1454dma_dmadone: 1455 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1456dma_halt: 1457 /* 1458 * Some revisions of the aic7880 have a problem where, if the 1459 * data fifo is full, but the PCI input latch is not empty, 1460 * HDMAEN cannot be cleared. The fix used here is to attempt 1461 * to drain the data fifo until there is space for the input 1462 * latch to drain and HDMAEN de-asserts. 1463 */ 1464 if ((ahc->features & AHC_ULTRA2) == 0) { 1465 mov NONE, DFDAT; 1466 } 1467 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 1468return: 1469 ret; 1470 1471/* 1472 * Assert that if we've been reselected, then we've seen an IDENTIFY 1473 * message. 1474 */ 1475assert: 1476 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 1477 1478 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 1479 1480/* 1481 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) 1482 * or by the SCBID ARG_1. The search begins at the SCB index passed in 1483 * via SINDEX which is an SCB that must be on the disconnected list. If 1484 * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR 1485 * is set to the proper SCB. 1486 */ 1487findSCB: 1488 mov SCBPTR,SINDEX; /* Initialize SCBPTR */ 1489 cmp ARG_1, SCB_LIST_NULL jne findSCB_by_SCBID; 1490 mov A, SAVED_TCL; 1491 mvi SCB_TCL jmp findSCB_loop; /* &SCB_TCL -> SINDEX */ 1492findSCB_by_SCBID: 1493 mov A, ARG_1; /* Tag passed in ARG_1 */ 1494 mvi SCB_TAG jmp findSCB_loop; /* &SCB_TAG -> SINDEX */ 1495findSCB_next: 1496 mov ARG_2, SCBPTR; 1497 cmp SCB_NEXT, SCB_LIST_NULL je notFound; 1498 mov SCBPTR,SCB_NEXT; 1499 dec SINDEX; /* Last comparison moved us too far */ 1500findSCB_loop: 1501 cmp SINDIR, A jne findSCB_next; 1502 mov SINDEX, SCBPTR ret; 1503notFound: 1504 mvi SINDEX, SCB_LIST_NULL ret; 1505 1506/* 1507 * Retrieve an SCB by SCBID first searching the disconnected list falling 1508 * back to DMA'ing the SCB down from the host. This routine assumes that 1509 * ARG_1 is the SCBID of interrest and that SINDEX is the position in the 1510 * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, 1511 * we go directly to the host for the SCB. 1512 */ 1513retrieveSCB: 1514 test SEQ_FLAGS, SCBPTR_VALID jz retrieve_from_host; 1515 mov SCBPTR call findSCB; /* Continue the search */ 1516 cmp SINDEX, SCB_LIST_NULL je retrieve_from_host; 1517 1518/* 1519 * This routine expects SINDEX to contain the index of the SCB to be 1520 * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the 1521 * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL 1522 * if it is at the head. 1523 */ 1524rem_scb_from_disc_list: 1525/* Remove this SCB from the disconnection list */ 1526 cmp ARG_2, SCB_LIST_NULL je rHead; 1527 mov DINDEX, SCB_NEXT; 1528 mov SCBPTR, ARG_2; 1529 mov SCB_NEXT, DINDEX; 1530 mov SCBPTR, SINDEX ret; 1531rHead: 1532 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1533 1534retrieve_from_host: 1535/* 1536 * We didn't find it. Pull an SCB and DMA down the one we want. 1537 * We should never get here in the non-paging case. 1538 */ 1539 mov ALLZEROS call get_free_or_disc_scb; 1540 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1541 /* Jump instead of call as we want to return anyway */ 1542 mov ARG_1 jmp dma_scb; 1543 1544/* 1545 * Determine whether a target is using tagged or non-tagged transactions 1546 * by first looking for a matching transaction based on the TCL and if 1547 * that fails, looking up this device in the host's untagged SCB array. 1548 * The TCL to search for is assumed to be in SAVED_TCL. The value is 1549 * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged). 1550 * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information 1551 * in an SCB instead of having to go to the host. 1552 */ 1553get_untagged_SCBID: 1554 cmp DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host; 1555 mvi ARG_1, SCB_LIST_NULL; 1556 mov DISCONNECTED_SCBH call findSCB; 1557 cmp SINDEX, SCB_LIST_NULL je get_SCBID_from_host; 1558 or SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */ 1559 test SCB_CONTROL, TAG_ENB jnz . + 2; 1560 mov ARG_1, SCB_TAG ret; 1561 mvi ARG_1, SCB_LIST_NULL ret; 1562 1563/* 1564 * Fetch a byte from host memory given an index of (A + (256 * SINDEX)) 1565 * and a base address of SCBID_ADDR. The byte is returned in RETURN_2. 1566 */ 1567fetch_byte: 1568 mov ARG_2, SINDEX; 1569 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1570 mvi DINDEX, CCHADDR; 1571 mvi SCBID_ADDR call set_1byte_addr; 1572 mvi CCHCNT, 1; 1573 mvi CCSGCTL, CCSGEN|CCSGRESET; 1574 test CCSGCTL, CCSGDONE jz .; 1575 mvi CCSGCTL, CCSGRESET; 1576 bmov RETURN_2, CCSGRAM, 1 ret; 1577 } else { 1578 mvi DINDEX, HADDR; 1579 mvi SCBID_ADDR call set_1byte_addr; 1580 mvi HCNT[0], 1; 1581 clr HCNT[1]; 1582 clr HCNT[2]; 1583 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 1584 call dma_finish; 1585 mov RETURN_2, DFDAT ret; 1586 } 1587 1588/* 1589 * Prepare the hardware to post a byte to host memory given an 1590 * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR. 1591 */ 1592post_byte_setup: 1593 mov ARG_2, SINDEX; 1594 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1595 mvi DINDEX, CCHADDR; 1596 mvi SCBID_ADDR call set_1byte_addr; 1597 mvi CCHCNT, 1; 1598 mvi CCSCBCTL, CCSCBRESET ret; 1599 } else { 1600 mvi DINDEX, HADDR; 1601 mvi SCBID_ADDR call set_1byte_addr; 1602 mvi HCNT[0], 1; 1603 clr HCNT[1]; 1604 clr HCNT[2]; 1605 mvi DFCNTRL, FIFORESET ret; 1606 } 1607 1608post_byte: 1609 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1610 bmov CCSCBRAM, SINDEX, 1; 1611 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1612 test CCSCBCTL, CCSCBDONE jz .; 1613 clr CCSCBCTL ret; 1614 } else { 1615 mov DFDAT, SINDEX; 1616 or DFCNTRL, HDMAEN|FIFOFLUSH; 1617 jmp dma_finish; 1618 } 1619 1620get_SCBID_from_host: 1621 mov A, SAVED_TCL; 1622 mvi UNTAGGEDSCB_OFFSET call fetch_byte; 1623 mov RETURN_1, RETURN_2 ret; 1624 1625phase_lock: 1626 test SSTAT1, REQINIT jz phase_lock; 1627 test SSTAT1, SCSIPERR jnz phase_lock; 1628 and SCSISIGO, PHASE_MASK, SCSISIGI; 1629 and LASTPHASE, PHASE_MASK, SCSISIGI ret; 1630 1631if ((ahc->features & AHC_CMD_CHAN) == 0) { 1632set_stcnt_from_hcnt: 1633 mov STCNT[0], HCNT[0]; 1634 mov STCNT[1], HCNT[1]; 1635 mov STCNT[2], HCNT[2] ret; 1636 1637bcopy_7: 1638 mov DINDIR, SINDIR; 1639 mov DINDIR, SINDIR; 1640bcopy_5: 1641 mov DINDIR, SINDIR; 1642bcopy_4: 1643 mov DINDIR, SINDIR; 1644bcopy_3: 1645 mov DINDIR, SINDIR; 1646 mov DINDIR, SINDIR; 1647 mov DINDIR, SINDIR ret; 1648} 1649 1650if ((ahc->flags & AHC_TARGETMODE) != 0) { 1651/* 1652 * Setup addr assuming that A is an index into 1653 * an array of 32byte objects, SINDEX contains 1654 * the base address of that array, and DINDEX 1655 * contains the base address of the location 1656 * to store the indexed address. 1657 */ 1658set_32byte_addr: 1659 shr ARG_2, 3, A; 1660 shl A, 5; 1661 jmp set_1byte_addr; 1662} 1663 1664/* 1665 * Setup addr assuming that A is an index into 1666 * an array of 64byte objects, SINDEX contains 1667 * the base address of that array, and DINDEX 1668 * contains the base address of the location 1669 * to store the indexed address. 1670 */ 1671set_64byte_addr: 1672 shr ARG_2, 2, A; 1673 shl A, 6; 1674 1675/* 1676 * Setup addr assuming that A + (ARG_1 * 256) is an 1677 * index into an array of 1byte objects, SINDEX contains 1678 * the base address of that array, and DINDEX contains 1679 * the base address of the location to store the computed 1680 * address. 1681 */ 1682set_1byte_addr: 1683 add DINDIR, A, SINDIR; 1684 mov A, ARG_2; 1685 adc DINDIR, A, SINDIR; 1686 clr A; 1687 adc DINDIR, A, SINDIR; 1688 adc DINDIR, A, SINDIR ret; 1689 1690/* 1691 * Either post or fetch and SCB from host memory based on the 1692 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. 1693 */ 1694dma_scb: 1695 mov A, SINDEX; 1696 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1697 mvi DINDEX, CCHADDR; 1698 mvi HSCB_ADDR call set_64byte_addr; 1699 mov CCSCBPTR, SCBPTR; 1700 test DMAPARAMS, DIRECTION jz dma_scb_tohost; 1701 mvi CCHCNT, SCB_64BYTE_SIZE; 1702 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET; 1703 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .; 1704 jmp dma_scb_finish; 1705dma_scb_tohost: 1706 mvi CCHCNT, SCB_32BYTE_SIZE; 1707 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 1708 mvi CCSCBCTL, CCSCBRESET; 1709 bmov CCSCBRAM, SCB_CONTROL, SCB_32BYTE_SIZE; 1710 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1711 test CCSCBCTL, CCSCBDONE jz .; 1712 } else { 1713 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET; 1714 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .; 1715 } 1716dma_scb_finish: 1717 clr CCSCBCTL; 1718 test CCSCBCTL, CCARREN|CCSCBEN jnz .; 1719 ret; 1720 } else { 1721 mvi DINDEX, HADDR; 1722 mvi HSCB_ADDR call set_64byte_addr; 1723 mvi HCNT[0], SCB_32BYTE_SIZE; 1724 clr HCNT[1]; 1725 clr HCNT[2]; 1726 mov DFCNTRL, DMAPARAMS; 1727 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1728 /* Fill it with the SCB data */ 1729copy_scb_tofifo: 1730 mvi SINDEX, SCB_CONTROL; 1731 add A, SCB_32BYTE_SIZE, SINDEX; 1732copy_scb_tofifo_loop: 1733 mov DFDAT,SINDIR; 1734 mov DFDAT,SINDIR; 1735 mov DFDAT,SINDIR; 1736 mov DFDAT,SINDIR; 1737 mov DFDAT,SINDIR; 1738 mov DFDAT,SINDIR; 1739 mov DFDAT,SINDIR; 1740 cmp SINDEX, A jne copy_scb_tofifo_loop; 1741 or DFCNTRL, HDMAEN|FIFOFLUSH; 1742dma_scb_fromhost: 1743 call dma_finish; 1744 /* If we were putting the SCB, we are done */ 1745 test DMAPARAMS, DIRECTION jz return; 1746 mvi SCB_CONTROL call dfdat_in_7; 1747 call dfdat_in_7_continued; 1748 call dfdat_in_7_continued; 1749 jmp dfdat_in_7_continued; 1750dfdat_in_7: 1751 mov DINDEX,SINDEX; 1752dfdat_in_7_continued: 1753 mov DINDIR,DFDAT; 1754 mov DINDIR,DFDAT; 1755 mov DINDIR,DFDAT; 1756 mov DINDIR,DFDAT; 1757 mov DINDIR,DFDAT; 1758 mov DINDIR,DFDAT; 1759 mov DINDIR,DFDAT ret; 1760 } 1761 1762 1763/* 1764 * Wait for DMA from host memory to data FIFO to complete, then disable 1765 * DMA and wait for it to acknowledge that it's off. 1766 */ 1767dma_finish: 1768 test DFSTATUS,HDONE jz dma_finish; 1769 /* Turn off DMA */ 1770 and DFCNTRL, ~HDMAEN; 1771 test DFCNTRL, HDMAEN jnz .; 1772 ret; 1773 1774add_scb_to_free_list: 1775 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1776 mov SCB_NEXT, FREE_SCBH; 1777 mov FREE_SCBH, SCBPTR; 1778 } 1779 mvi SCB_TAG, SCB_LIST_NULL ret; 1780 1781if ((ahc->flags & AHC_PAGESCBS) != 0) { 1782get_free_or_disc_scb: 1783 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1784 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1785return_error: 1786 mvi SINDEX, SCB_LIST_NULL ret; 1787dequeue_disc_scb: 1788 mov SCBPTR, DISCONNECTED_SCBH; 1789dma_up_scb: 1790 mvi DMAPARAMS, FIFORESET; 1791 mov SCB_TAG call dma_scb; 1792unlink_disc_scb: 1793 mov DISCONNECTED_SCBH, SCB_NEXT ret; 1794dequeue_free_scb: 1795 mov SCBPTR, FREE_SCBH; 1796 mov FREE_SCBH, SCB_NEXT ret; 1797} 1798 1799add_scb_to_disc_list: 1800/* 1801 * Link this SCB into the DISCONNECTED list. This list holds the 1802 * candidates for paging out an SCB if one is needed for a new command. 1803 * Modifying the disconnected list is a critical(pause dissabled) section. 1804 */ 1805 mov SCB_NEXT, DISCONNECTED_SCBH; 1806 mov DISCONNECTED_SCBH, SCBPTR ret; 1807