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 * $FreeBSD$ 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_ULTRA2) != 0) { 683 /* 684 * The preload circuitry requires us to 685 * reload the address too, so pull it from 686 * the shaddow address. 687 */ 688 bmov HADDR, SHADDR, 4; 689 bmov HCNT, SCB_RESID_DCNT, 3; 690 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 691 bmov STCNT, SCB_RESID_DCNT, 3; 692 } else { 693 mvi DINDEX, STCNT; 694 mvi SCB_RESID_DCNT call bcopy_3; 695 } 696 and DATA_COUNT_ODD, 0x1, SCB_RESID_DCNT[0]; 697 jmp data_phase_loop; 698 699p_data: 700 if ((ahc->features & AHC_ULTRA2) != 0) { 701 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; 702 } else { 703 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 704 } 705 test LASTPHASE, IOI jnz . + 2; 706 or DMAPARAMS, DIRECTION; 707 call assert; /* 708 * Ensure entering a data 709 * phase is okay - seen identify, etc. 710 */ 711 if ((ahc->features & AHC_CMD_CHAN) != 0) { 712 mvi CCSGADDR, CCSGADDR_MAX; 713 } 714 test SEQ_FLAGS, DPHASE jnz data_phase_reinit; 715 716 /* We have seen a data phase */ 717 or SEQ_FLAGS, DPHASE; 718 719 /* 720 * Initialize the DMA address and counter from the SCB. 721 * Also set SG_COUNT and SG_NEXT in memory since we cannot 722 * modify the values in the SCB itself until we see a 723 * save data pointers message. 724 */ 725 if ((ahc->features & AHC_CMD_CHAN) != 0) { 726 bmov HADDR, SCB_DATAPTR, 7; 727 } else { 728 mvi DINDEX, HADDR; 729 mvi SCB_DATAPTR call bcopy_7; 730 } 731 and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0]; 732 733 if ((ahc->features & AHC_ULTRA2) == 0) { 734 if ((ahc->features & AHC_CMD_CHAN) != 0) { 735 bmov STCNT, HCNT, 3; 736 } else { 737 call set_stcnt_from_hcnt; 738 } 739 } 740 741 if ((ahc->features & AHC_CMD_CHAN) != 0) { 742 bmov SG_COUNT, SCB_SGCOUNT, 5; 743 } else { 744 mvi DINDEX, SG_COUNT; 745 mvi SCB_SGCOUNT call bcopy_5; 746 } 747 748data_phase_loop: 749/* Guard against overruns */ 750 test SG_COUNT, 0xff jnz data_phase_inbounds; 751/* 752 * Turn on 'Bit Bucket' mode, set the transfer count to 753 * 16meg and let the target run until it changes phase. 754 * When the transfer completes, notify the host that we 755 * had an overrun. 756 */ 757 or SXFRCTL1,BITBUCKET; 758 and DMAPARAMS, ~(HDMAEN|SDMAEN); 759 if ((ahc->features & AHC_ULTRA2) != 0) { 760 bmov HCNT, ALLONES, 3; 761 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 762 bmov STCNT, ALLONES, 3; 763 } else { 764 mvi STCNT[0], 0xFF; 765 mvi STCNT[1], 0xFF; 766 mvi STCNT[2], 0xFF; 767 } 768data_phase_inbounds: 769/* If we are the last SG block, tell the hardware. */ 770 cmp SG_COUNT,0x01 jne data_phase_wideodd; 771 if ((ahc->features & AHC_ULTRA2) != 0) { 772 or SG_CACHEPTR, LAST_SEG; 773 } else { 774 and DMAPARAMS, ~WIDEODD; 775 } 776data_phase_wideodd: 777 if ((ahc->features & AHC_ULTRA2) != 0) { 778 mov SINDEX, ALLONES; 779 mov DFCNTRL, DMAPARAMS; 780 test SSTAT0, SDONE jnz .;/* Wait for preload to complete */ 781data_phase_dma_loop: 782 test SSTAT0, SDONE jnz data_phase_dma_done; 783 test SSTAT1,PHASEMIS jz data_phase_dma_loop; /* ie. underrun */ 784data_phase_dma_phasemis: 785 test SSTAT0,SDONE jnz . + 2; 786 mov SINDEX,ALLZEROS; /* Remeber the phasemiss */ 787 } else { 788 mov DMAPARAMS call dma; 789 } 790 791data_phase_dma_done: 792/* Go tell the host about any overruns */ 793 test SXFRCTL1,BITBUCKET jnz data_phase_overrun; 794 795/* Exit if we had an underrun. dma clears SINDEX in this case. */ 796 test SINDEX,0xff jz data_phase_finish; 797 798/* 799 * Advance the scatter-gather pointers if needed 800 */ 801sg_advance: 802 dec SG_COUNT; /* one less segment to go */ 803 804 test SG_COUNT, 0xff jz data_phase_finish; /* Are we done? */ 805/* 806 * Load a struct scatter and set up the data address and length. 807 * If the working value of the SG count is nonzero, then 808 * we need to load a new set of values. 809 * 810 * This, like all DMA's, assumes little-endian host data storage. 811 */ 812sg_load: 813 if ((ahc->features & AHC_CMD_CHAN) != 0) { 814 /* 815 * Do we have any prefetch left??? 816 */ 817 cmp CCSGADDR, CCSGADDR_MAX jne prefetched_segs_avail; 818 819 /* 820 * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes. 821 */ 822 add A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT; 823 mvi A, CCSGADDR_MAX; 824 jc . + 2; 825 shl A, 3, SG_COUNT; 826 mov CCHCNT, A; 827 bmov CCHADDR, SG_NEXT, 4; 828 mvi CCSGCTL, CCSGEN|CCSGRESET; 829 test CCSGCTL, CCSGDONE jz .; 830 and CCSGCTL, ~CCSGEN; 831 test CCSGCTL, CCSGEN jnz .; 832 mvi CCSGCTL, CCSGRESET; 833prefetched_segs_avail: 834 bmov HADDR, CCSGRAM, 8; 835 } else { 836 mvi DINDEX, HADDR; 837 mvi SG_NEXT call bcopy_4; 838 839 mvi HCNT[0],SG_SIZEOF; 840 clr HCNT[1]; 841 clr HCNT[2]; 842 843 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 844 845 call dma_finish; 846 847 /* 848 * Copy data from FIFO into SCB data pointer and data count. 849 * This assumes that the SG segments are of the form: 850 * struct ahc_dma_seg { 851 * u_int32_t addr; four bytes, little-endian order 852 * u_int32_t len; four bytes, little endian order 853 * }; 854 */ 855 mvi HADDR call dfdat_in_7; 856 } 857 858 /* Track odd'ness */ 859 test HCNT[0], 0x1 jz . + 2; 860 xor DATA_COUNT_ODD, 0x1; 861 862 if ((ahc->features & AHC_ULTRA2) == 0) { 863 /* Load STCNT as well. It is a mirror of HCNT */ 864 if ((ahc->features & AHC_CMD_CHAN) != 0) { 865 bmov STCNT, HCNT, 3; 866 } else { 867 call set_stcnt_from_hcnt; 868 } 869 } 870 871/* Advance the SG pointer */ 872 clr A; /* add sizeof(struct scatter) */ 873 add SG_NEXT[0],SG_SIZEOF; 874 adc SG_NEXT[1],A; 875 876 if ((ahc->flags & AHC_TARGETMODE) != 0) { 877 test SSTAT0, TARGET jnz data_phase_loop; 878 } 879 test SSTAT1, REQINIT jz .; 880 test SSTAT1,PHASEMIS jz data_phase_loop; 881 882 /* Ensure the last seg is visable at the shaddow layer */ 883 if ((ahc->features & AHC_ULTRA2) != 0) { 884 or DFCNTRL, PRELOADEN; 885 } 886 887data_phase_finish: 888 if ((ahc->features & AHC_ULTRA2) != 0) { 889 call ultra2_dmafinish; 890 } 891/* 892 * After a DMA finishes, save the SG and STCNT residuals back into the SCB 893 * We use STCNT instead of HCNT, since it's a reflection of how many bytes 894 * were transferred on the SCSI (as opposed to the host) bus. 895 */ 896 if ((ahc->features & AHC_CMD_CHAN) != 0) { 897 bmov SCB_RESID_DCNT, STCNT, 3; 898 } else { 899 mov SCB_RESID_DCNT[0],STCNT[0]; 900 mov SCB_RESID_DCNT[1],STCNT[1]; 901 mov SCB_RESID_DCNT[2],STCNT[2]; 902 } 903 mov SCB_RESID_SGCNT, SG_COUNT; 904 905 if ((ahc->features & AHC_ULTRA2) != 0) { 906 or SXFRCTL0, CLRSTCNT|CLRCHN; 907 } 908 909 if ((ahc->flags & AHC_TARGETMODE) != 0) { 910 test SEQ_FLAGS, DPHASE_PENDING jz ITloop; 911 and SEQ_FLAGS, ~DPHASE_PENDING; 912 /* 913 * For data-in phases, wait for any pending acks from the 914 * initiator before changing phase. 915 */ 916 test DFCNTRL, DIRECTION jz target_ITloop; 917 test SSTAT1, REQINIT jnz .; 918 jmp target_ITloop; 919 } 920 jmp ITloop; 921 922data_phase_overrun: 923 if ((ahc->features & AHC_ULTRA2) != 0) { 924 call ultra2_dmafinish; 925 or SXFRCTL0, CLRSTCNT|CLRCHN; 926 } 927/* 928 * Turn off BITBUCKET mode and notify the host 929 */ 930 and SXFRCTL1, ~BITBUCKET; 931 mvi INTSTAT,DATA_OVERRUN; 932 jmp ITloop; 933 934ultra2_dmafinish: 935 if ((ahc->features & AHC_ULTRA2) != 0) { 936 test DFCNTRL, DIRECTION jnz ultra2_dmahalt; 937 and DFCNTRL, ~SCSIEN; 938 test DFCNTRL, SCSIEN jnz .; 939ultra2_dmafifoflush: 940 or DFCNTRL, FIFOFLUSH; 941 /* 942 * The FIFOEMP status bit on the Ultra2 class 943 * of controllers seems to be a bit flaky. 944 * It appears that if the FIFO is full and the 945 * transfer ends with some data in the REQ/ACK 946 * FIFO, FIFOEMP will fall temporarily 947 * as the data is transferred to the PCI bus. 948 * This glitch lasts for fewer than 5 clock cycles, 949 * so we work around the problem by ensuring the 950 * status bit stays false through a full glitch 951 * window. 952 */ 953 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 954 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 955 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 956 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 957 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 958 959ultra2_dmafifoempty: 960 /* Don't clobber an inprogress host data transfer */ 961 test DFSTATUS, MREQPEND jnz ultra2_dmafifoempty; 962 963ultra2_dmahalt: 964 and DFCNTRL, ~(SCSIEN|HDMAEN); 965 test DFCNTRL, HDMAEN jnz .; 966 ret; 967 } 968 969if ((ahc->flags & AHC_INITIATORMODE) != 0) { 970/* 971 * Command phase. Set up the DMA registers and let 'er rip. 972 */ 973p_command: 974 call assert; 975 976 if ((ahc->features & AHC_CMD_CHAN) != 0) { 977 mov HCNT[0], SCB_CMDLEN; 978 bmov HCNT[1], ALLZEROS, 2; 979 if ((ahc->features & AHC_ULTRA2) == 0) { 980 bmov STCNT, HCNT, 3; 981 } 982 add NONE, -17, SCB_CMDLEN; 983 jc dma_cmd_data; 984 if ((ahc->features & AHC_ULTRA2) != 0) { 985 mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION); 986 } else { 987 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); 988 } 989 bmov DFDAT, SCB_CMDSTORE, 16; 990 jmp cmd_loop; 991dma_cmd_data: 992 bmov HADDR, SCB_CMDPTR, 4; 993 } else { 994 mvi DINDEX, HADDR; 995 mvi SCB_CMDPTR call bcopy_5; 996 clr HCNT[1]; 997 clr HCNT[2]; 998 } 999 1000 if ((ahc->features & AHC_ULTRA2) == 0) { 1001 if ((ahc->features & AHC_CMD_CHAN) == 0) { 1002 call set_stcnt_from_hcnt; 1003 } 1004 mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); 1005 } else { 1006 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION); 1007 } 1008cmd_loop: 1009 test SSTAT0, SDONE jnz . + 2; 1010 test SSTAT1, PHASEMIS jz cmd_loop; 1011 and DFCNTRL, ~(SCSIEN|HDMAEN|SDMAEN); 1012 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; 1013 jmp ITloop; 1014 1015/* 1016 * Status phase. Wait for the data byte to appear, then read it 1017 * and store it into the SCB. 1018 */ 1019p_status: 1020 call assert; 1021 1022 mov SCB_TARGET_STATUS, SCSIDATL; 1023 jmp ITloop; 1024 1025/* 1026 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full 1027 * indentify message sequence and send it to the target. The host may 1028 * override this behavior by setting the MK_MESSAGE bit in the SCB 1029 * control byte. This will cause us to interrupt the host and allow 1030 * it to handle the message phase completely on its own. If the bit 1031 * associated with this target is set, we will also interrupt the host, 1032 * thereby allowing it to send a message on the next selection regardless 1033 * of the transaction being sent. 1034 * 1035 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. 1036 * This is done to allow the host to send messages outside of an identify 1037 * sequence while protecting the seqencer from testing the MK_MESSAGE bit 1038 * on an SCB that might not be for the current nexus. (For example, a 1039 * BDR message in responce to a bad reselection would leave us pointed to 1040 * an SCB that doesn't have anything to do with the current target). 1041 * 1042 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, 1043 * bus device reset). 1044 * 1045 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, 1046 * in case the target decides to put us in this phase for some strange 1047 * reason. 1048 */ 1049p_mesgout_retry: 1050 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 1051p_mesgout: 1052 mov SINDEX, MSG_OUT; 1053 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; 1054 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; 1055 mov FUNCTION1, SCB_TCL; 1056 mov A, FUNCTION1; 1057 if ((ahc->features & AHC_HS_MAILBOX) != 0) { 1058 /* 1059 * Work around a pausing bug in at least the aic7890. 1060 * If the host needs to update the TARGET_MSG_REQUEST 1061 * bit field, it will set the HS_MAILBOX to 1. In 1062 * response, we pause with a specific interrupt code 1063 * asking for the mask to be updated before we continue. 1064 * Ugh. 1065 */ 1066 test HS_MAILBOX, 0xF0 jz . + 2; 1067 mvi INTSTAT, UPDATE_TMSG_REQ; 1068 nop; 1069 } 1070 mov SINDEX, TARGET_MSG_REQUEST[0]; 1071 if ((ahc->features & AHC_TWIN) != 0) { 1072 /* Second Channel uses high byte bits */ 1073 test SCB_TCL, SELBUSB jz . + 2; 1074 mov SINDEX, TARGET_MSG_REQUEST[1]; 1075 } else if ((ahc->features & AHC_WIDE) != 0) { 1076 test SCB_TCL, 0x80 jz . + 2; /* target > 7 */ 1077 mov SINDEX, TARGET_MSG_REQUEST[1]; 1078 } 1079 test SINDEX, A jnz host_message_loop; 1080p_mesgout_identify: 1081 and SINDEX,LID,SCB_TCL; /* lun */ 1082 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ 1083 or SINDEX,A; /* or in disconnect privledge */ 1084 or SINDEX,MSG_IDENTIFYFLAG; 1085/* 1086 * Send a tag message if TAG_ENB is set in the SCB control block. 1087 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 1088 */ 1089p_mesgout_tag: 1090 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; 1091 mov SCSIDATL, SINDEX; /* Send the identify message */ 1092 call phase_lock; 1093 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1094 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 1095 call phase_lock; 1096 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1097 mov SCB_TAG jmp p_mesgout_onebyte; 1098/* 1099 * Interrupt the driver, and allow it to handle this message 1100 * phase and any required retries. 1101 */ 1102p_mesgout_from_host: 1103 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; 1104 jmp host_message_loop; 1105 1106p_mesgout_onebyte: 1107 mvi CLRSINT1, CLRATNO; 1108 mov SCSIDATL, SINDEX; 1109 1110/* 1111 * If the next bus phase after ATN drops is message out, it means 1112 * that the target is requesting that the last message(s) be resent. 1113 */ 1114 call phase_lock; 1115 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; 1116 1117p_mesgout_done: 1118 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 1119 mov LAST_MSG, MSG_OUT; 1120 mvi MSG_OUT, MSG_NOOP; /* No message left */ 1121 jmp ITloop; 1122 1123/* 1124 * Message in phase. Bytes are read using Automatic PIO mode. 1125 */ 1126p_mesgin: 1127 mvi ACCUM call inb_first; /* read the 1st message byte */ 1128 1129 test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 1130 cmp A,MSG_DISCONNECT je mesgin_disconnect; 1131 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 1132 cmp ALLZEROS,A je mesgin_complete; 1133 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 1134 cmp A,MSG_NOOP je mesgin_done; 1135 1136/* 1137 * Pushed message loop to allow the kernel to 1138 * RUN IT's own message state engine. To avoid an 1139 * extra nop instruction after signaling the kernel, 1140 * we perform the phase_lock before checking to see 1141 * if we should exit the loop and skip the phase_lock 1142 * in the ITloop. Performing back to back phase_locks 1143 * shouldn't hurt, but why do it twice... 1144 */ 1145host_message_loop: 1146 mvi INTSTAT, HOST_MSG_LOOP; 1147 call phase_lock; 1148 cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1; 1149 jmp host_message_loop; 1150 1151mesgin_done: 1152 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1153 jmp ITloop; 1154 1155 1156mesgin_complete: 1157/* 1158 * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO, 1159 * and trigger a completion interrupt. Before doing so, check to see if there 1160 * is a residual or the status byte is something other than STATUS_GOOD (0). 1161 * In either of these conditions, we upload the SCB back to the host so it can 1162 * process this information. In the case of a non zero status byte, we 1163 * additionally interrupt the kernel driver synchronously, allowing it to 1164 * decide if sense should be retrieved. If the kernel driver wishes to request 1165 * sense, it will fill the kernel SCB with a request sense command and set 1166 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload 1167 * the SCB, and process it as the next command by adding it to the waiting list. 1168 * If the kernel driver does not wish to request sense, it need only clear 1169 * RETURN_1, and the command is allowed to complete normally. We don't bother 1170 * to post to the QOUTFIFO in the error cases since it would require extra 1171 * work in the kernel driver to ensure that the entry was removed before the 1172 * command complete code tried processing it. 1173 */ 1174 1175/* 1176 * First check for residuals 1177 */ 1178 test SCB_RESID_SGCNT,0xff jnz upload_scb; 1179 test SCB_TARGET_STATUS,0xff jz complete; /* Good Status? */ 1180upload_scb: 1181 mvi DMAPARAMS, FIFORESET; 1182 mov SCB_TAG call dma_scb; 1183check_status: 1184 test SCB_TARGET_STATUS,0xff jz complete; /* Just a residual? */ 1185 mvi INTSTAT,BAD_STATUS; /* let driver know */ 1186 nop; 1187 cmp RETURN_1, SEND_SENSE jne complete; 1188 /* This SCB becomes the next to execute as it will retrieve sense */ 1189 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1190 mov SCB_TAG call dma_scb; 1191add_to_waiting_list: 1192 mov SCB_NEXT,WAITING_SCBH; 1193 mov WAITING_SCBH, SCBPTR; 1194 /* 1195 * Prepare our selection hardware before the busfree so we have a 1196 * high probability of winning arbitration. 1197 */ 1198 call start_selection; 1199 jmp await_busfree; 1200 1201complete: 1202 /* If we are untagged, clear our address up in host ram */ 1203 test SCB_CONTROL, TAG_ENB jnz complete_queue; 1204 mov A, SAVED_TCL; 1205 mvi UNTAGGEDSCB_OFFSET call post_byte_setup; 1206 mvi SCB_LIST_NULL call post_byte; 1207 1208complete_queue: 1209 mov SCB_TAG call complete_post; 1210 jmp await_busfree; 1211} 1212 1213complete_post: 1214 /* Post the SCBID in SINDEX and issue an interrupt */ 1215 call add_scb_to_free_list; 1216 mov ARG_1, SINDEX; 1217 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 1218 mov A, SDSCB_QOFF; 1219 } else { 1220 mov A, QOUTPOS; 1221 } 1222 mvi QOUTFIFO_OFFSET call post_byte_setup; 1223 mov ARG_1 call post_byte; 1224 if ((ahc->features & AHC_QUEUE_REGS) == 0) { 1225 inc QOUTPOS; 1226 } 1227 mvi INTSTAT,CMDCMPLT ret; 1228 1229if ((ahc->flags & AHC_INITIATORMODE) != 0) { 1230/* 1231 * Is it a disconnect message? Set a flag in the SCB to remind us 1232 * and await the bus going free. 1233 */ 1234mesgin_disconnect: 1235 or SCB_CONTROL,DISCONNECTED; 1236 call add_scb_to_disc_list; 1237 jmp await_busfree; 1238 1239/* 1240 * Save data pointers message: 1241 * Copying RAM values back to SCB, for Save Data Pointers message, but 1242 * only if we've actually been into a data phase to change them. This 1243 * protects against bogus data in scratch ram and the residual counts 1244 * since they are only initialized when we go into data_in or data_out. 1245 */ 1246mesgin_sdptrs: 1247 test SEQ_FLAGS, DPHASE jz mesgin_done; 1248 1249 /* 1250 * The SCB SGPTR becomes the next one we'll download, 1251 * and the SCB DATAPTR becomes the current SHADDR. 1252 * Use the residual number since STCNT is corrupted by 1253 * any message transfer. 1254 */ 1255 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1256 bmov SCB_SGCOUNT, SG_COUNT, 5; 1257 bmov SCB_DATAPTR, SHADDR, 4; 1258 bmov SCB_DATACNT, SCB_RESID_DCNT, 3; 1259 } else { 1260 mvi DINDEX, SCB_SGCOUNT; 1261 mvi SG_COUNT call bcopy_5; 1262 1263 mvi DINDEX, SCB_DATAPTR; 1264 mvi SHADDR call bcopy_4; 1265 mvi SCB_RESID_DCNT call bcopy_3; 1266 } 1267 jmp mesgin_done; 1268 1269/* 1270 * Restore pointers message? Data pointers are recopied from the 1271 * SCB anytime we enter a data phase for the first time, so all 1272 * we need to do is clear the DPHASE flag and let the data phase 1273 * code do the rest. 1274 */ 1275mesgin_rdptrs: 1276 and SEQ_FLAGS, ~DPHASE; /* 1277 * We'll reload them 1278 * the next time through 1279 * the dataphase. 1280 */ 1281 jmp mesgin_done; 1282 1283/* 1284 * Identify message? For a reconnecting target, this tells us the lun 1285 * that the reconnection is for - find the correct SCB and switch to it, 1286 * clearing the "disconnected" bit so we don't "find" it by accident later. 1287 */ 1288mesgin_identify: 1289 1290 if ((ahc->features & AHC_WIDE) != 0) { 1291 and A,0x0f; /* lun in lower four bits */ 1292 } else { 1293 and A,0x07; /* lun in lower three bits */ 1294 } 1295 or SAVED_TCL,A; /* SAVED_TCL should be complete now */ 1296 1297 mvi ARG_2, SCB_LIST_NULL; /* SCBID of prev SCB in disc List */ 1298 call get_untagged_SCBID; 1299 cmp ARG_1, SCB_LIST_NULL je snoop_tag; 1300 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1301 test SEQ_FLAGS, SCBPTR_VALID jz use_retrieveSCB; 1302 } 1303 /* 1304 * If the SCB was found in the disconnected list (as is 1305 * always the case in non-paging scenarios), SCBPTR is already 1306 * set to the correct SCB. So, simply setup the SCB and get 1307 * on with things. 1308 */ 1309 call rem_scb_from_disc_list; 1310 jmp setup_SCB; 1311/* 1312 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 1313 * If we get one, we use the tag returned to find the proper 1314 * SCB. With SCB paging, this requires using search for both tagged 1315 * and non-tagged transactions since the SCB may exist in any slot. 1316 * If we're not using SCB paging, we can use the tag as the direct 1317 * index to the SCB. 1318 */ 1319snoop_tag: 1320 mov NONE,SCSIDATL; /* ACK Identify MSG */ 1321snoop_tag_loop: 1322 call phase_lock; 1323 cmp LASTPHASE, P_MESGIN jne not_found; 1324 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 1325get_tag: 1326 mvi ARG_1 call inb_next; /* tag value */ 1327 1328 /* 1329 * Ensure that the SCB the tag points to is for 1330 * an SCB transaction to the reconnecting target. 1331 */ 1332use_retrieveSCB: 1333 call retrieveSCB; 1334setup_SCB: 1335 mov A, SAVED_TCL; 1336 cmp SCB_TCL, A jne not_found_cleanup_scb; 1337 test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb; 1338 and SCB_CONTROL,~DISCONNECTED; 1339 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 1340 call set_transfer_settings; 1341 /* See if the host wants to send a message upon reconnection */ 1342 test SCB_CONTROL, MK_MESSAGE jz mesgin_done; 1343 and SCB_CONTROL, ~MK_MESSAGE; 1344 mvi HOST_MSG call mk_mesg; 1345 jmp mesgin_done; 1346 1347not_found_cleanup_scb: 1348 test SCB_CONTROL, DISCONNECTED jz . + 3; 1349 call add_scb_to_disc_list; 1350 jmp not_found; 1351 call add_scb_to_free_list; 1352not_found: 1353 mvi INTSTAT, NO_MATCH; 1354 jmp mesgin_done; 1355 1356/* 1357 * [ ADD MORE MESSAGE HANDLING HERE ] 1358 */ 1359 1360/* 1361 * Locking the driver out, build a one-byte message passed in SINDEX 1362 * if there is no active message already. SINDEX is returned intact. 1363 */ 1364mk_mesg: 1365 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 1366 mov MSG_OUT,SINDEX ret; 1367 1368/* 1369 * Functions to read data in Automatic PIO mode. 1370 * 1371 * According to Adaptec's documentation, an ACK is not sent on input from 1372 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 1373 * latched (the usual way), then read the data byte directly off the bus 1374 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 1375 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 1376 * spec guarantees that the target will hold the data byte on the bus until 1377 * we send our ACK. 1378 * 1379 * The assumption here is that these are called in a particular sequence, 1380 * and that REQ is already set when inb_first is called. inb_{first,next} 1381 * use the same calling convention as inb. 1382 */ 1383 1384inb_next: 1385 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1386inb_next_wait: 1387 /* 1388 * If there is a parity error, wait for the kernel to 1389 * see the interrupt and prepare our message response 1390 * before continuing. 1391 */ 1392 test SSTAT1, REQINIT jz inb_next_wait; 1393 test SSTAT1, SCSIPERR jnz inb_next_wait; 1394 and LASTPHASE, PHASE_MASK, SCSISIGI; 1395 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 1396inb_first: 1397 mov DINDEX,SINDEX; 1398 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 1399inb_last: 1400 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 1401} 1402 1403if ((ahc->flags & AHC_TARGETMODE) != 0) { 1404/* 1405 * Change to a new phase. If we are changing the state of the I/O signal, 1406 * from out to in, wait an additional data release delay before continuing. 1407 */ 1408change_phase: 1409 /* Wait for preceeding I/O session to complete. */ 1410 test SCSISIGI, ACKI jnz .; 1411 1412 /* Change the phase */ 1413 and DINDEX, IOI, SCSISIGI; 1414 mov SCSISIGO, SINDEX; 1415 and A, IOI, SINDEX; 1416 1417 /* 1418 * If the data direction has changed, from 1419 * out (initiator driving) to in (target driving), 1420 * we must waitat least a data release delay plus 1421 * the normal bus settle delay. [SCSI III SPI 10.11.0] 1422 */ 1423 cmp DINDEX, A je change_phase_wait; 1424 test SINDEX, IOI jz change_phase_wait; 1425 call change_phase_wait; 1426change_phase_wait: 1427 nop; 1428 nop; 1429 nop; 1430 nop ret; 1431 1432/* 1433 * Send a byte to an initiator in Automatic PIO mode. 1434 */ 1435target_outb: 1436 or SXFRCTL0, SPIOEN; 1437 test SSTAT0, SPIORDY jz .; 1438 mov SCSIDATL, SINDEX; 1439 test SSTAT0, SPIORDY jz .; 1440 and SXFRCTL0, ~SPIOEN ret; 1441} 1442 1443mesgin_phasemis: 1444/* 1445 * We expected to receive another byte, but the target changed phase 1446 */ 1447 mvi INTSTAT, MSGIN_PHASEMIS; 1448 jmp ITloop; 1449 1450/* 1451 * DMA data transfer. HADDR and HCNT must be loaded first, and 1452 * SINDEX should contain the value to load DFCNTRL with - 0x3d for 1453 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared 1454 * during initialization. 1455 */ 1456dma: 1457 mov DFCNTRL,SINDEX; 1458dma_loop: 1459 test SSTAT0,DMADONE jnz dma_dmadone; 1460 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 1461dma_phasemis: 1462 test SSTAT0,SDONE jnz dma_checkfifo; 1463 mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */ 1464 1465/* 1466 * We will be "done" DMAing when the transfer count goes to zero, or 1467 * the target changes the phase (in light of this, it makes sense that 1468 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 1469 * doing a SCSI->Host transfer, the data FIFO should be flushed auto- 1470 * magically on STCNT=0 or a phase change, so just wait for FIFO empty 1471 * status. 1472 */ 1473dma_checkfifo: 1474 test DFCNTRL,DIRECTION jnz dma_fifoempty; 1475dma_fifoflush: 1476 test DFSTATUS,FIFOEMP jz dma_fifoflush; 1477 1478dma_fifoempty: 1479 /* Don't clobber an inprogress host data transfer */ 1480 test DFSTATUS, MREQPEND jnz dma_fifoempty; 1481/* 1482 * Now shut the DMA enables off and make sure that the DMA enables are 1483 * actually off first lest we get an ILLSADDR. 1484 */ 1485dma_dmadone: 1486 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1487dma_halt: 1488 /* 1489 * Some revisions of the aic7880 have a problem where, if the 1490 * data fifo is full, but the PCI input latch is not empty, 1491 * HDMAEN cannot be cleared. The fix used here is to attempt 1492 * to drain the data fifo until there is space for the input 1493 * latch to drain and HDMAEN de-asserts. 1494 */ 1495 if ((ahc->features & AHC_ULTRA2) == 0) { 1496 mov NONE, DFDAT; 1497 } 1498 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 1499return: 1500 ret; 1501 1502/* 1503 * Assert that if we've been reselected, then we've seen an IDENTIFY 1504 * message. 1505 */ 1506assert: 1507 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 1508 1509 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 1510 1511/* 1512 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) 1513 * or by the SCBID ARG_1. The search begins at the SCB index passed in 1514 * via SINDEX which is an SCB that must be on the disconnected list. If 1515 * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR 1516 * is set to the proper SCB. 1517 */ 1518findSCB: 1519 mov SCBPTR,SINDEX; /* Initialize SCBPTR */ 1520 cmp ARG_1, SCB_LIST_NULL jne findSCB_by_SCBID; 1521 mov A, SAVED_TCL; 1522 mvi SCB_TCL jmp findSCB_loop; /* &SCB_TCL -> SINDEX */ 1523findSCB_by_SCBID: 1524 mov A, ARG_1; /* Tag passed in ARG_1 */ 1525 mvi SCB_TAG jmp findSCB_loop; /* &SCB_TAG -> SINDEX */ 1526findSCB_next: 1527 mov ARG_2, SCBPTR; 1528 cmp SCB_NEXT, SCB_LIST_NULL je notFound; 1529 mov SCBPTR,SCB_NEXT; 1530 dec SINDEX; /* Last comparison moved us too far */ 1531findSCB_loop: 1532 cmp SINDIR, A jne findSCB_next; 1533 mov SINDEX, SCBPTR ret; 1534notFound: 1535 mvi SINDEX, SCB_LIST_NULL ret; 1536 1537/* 1538 * Retrieve an SCB by SCBID first searching the disconnected list falling 1539 * back to DMA'ing the SCB down from the host. This routine assumes that 1540 * ARG_1 is the SCBID of interrest and that SINDEX is the position in the 1541 * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, 1542 * we go directly to the host for the SCB. 1543 */ 1544retrieveSCB: 1545 test SEQ_FLAGS, SCBPTR_VALID jz retrieve_from_host; 1546 mov SCBPTR call findSCB; /* Continue the search */ 1547 cmp SINDEX, SCB_LIST_NULL je retrieve_from_host; 1548 1549/* 1550 * This routine expects SINDEX to contain the index of the SCB to be 1551 * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the 1552 * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL 1553 * if it is at the head. 1554 */ 1555rem_scb_from_disc_list: 1556/* Remove this SCB from the disconnection list */ 1557 cmp ARG_2, SCB_LIST_NULL je rHead; 1558 mov DINDEX, SCB_NEXT; 1559 mov SCBPTR, ARG_2; 1560 mov SCB_NEXT, DINDEX; 1561 mov SCBPTR, SINDEX ret; 1562rHead: 1563 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1564 1565retrieve_from_host: 1566/* 1567 * We didn't find it. Pull an SCB and DMA down the one we want. 1568 * We should never get here in the non-paging case. 1569 */ 1570 mov ALLZEROS call get_free_or_disc_scb; 1571 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1572 /* Jump instead of call as we want to return anyway */ 1573 mov ARG_1 jmp dma_scb; 1574 1575/* 1576 * Determine whether a target is using tagged or non-tagged transactions 1577 * by first looking for a matching transaction based on the TCL and if 1578 * that fails, looking up this device in the host's untagged SCB array. 1579 * The TCL to search for is assumed to be in SAVED_TCL. The value is 1580 * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged). 1581 * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information 1582 * in an SCB instead of having to go to the host. 1583 */ 1584get_untagged_SCBID: 1585 cmp DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host; 1586 mvi ARG_1, SCB_LIST_NULL; 1587 mov DISCONNECTED_SCBH call findSCB; 1588 cmp SINDEX, SCB_LIST_NULL je get_SCBID_from_host; 1589 or SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */ 1590 test SCB_CONTROL, TAG_ENB jnz . + 2; 1591 mov ARG_1, SCB_TAG ret; 1592 mvi ARG_1, SCB_LIST_NULL ret; 1593 1594/* 1595 * Fetch a byte from host memory given an index of (A + (256 * SINDEX)) 1596 * and a base address of SCBID_ADDR. The byte is returned in RETURN_2. 1597 */ 1598fetch_byte: 1599 mov ARG_2, SINDEX; 1600 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1601 mvi DINDEX, CCHADDR; 1602 mvi SCBID_ADDR call set_1byte_addr; 1603 mvi CCHCNT, 1; 1604 mvi CCSGCTL, CCSGEN|CCSGRESET; 1605 test CCSGCTL, CCSGDONE jz .; 1606 mvi CCSGCTL, CCSGRESET; 1607 bmov RETURN_2, CCSGRAM, 1 ret; 1608 } else { 1609 mvi DINDEX, HADDR; 1610 mvi SCBID_ADDR call set_1byte_addr; 1611 mvi HCNT[0], 1; 1612 clr HCNT[1]; 1613 clr HCNT[2]; 1614 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 1615 call dma_finish; 1616 mov RETURN_2, DFDAT ret; 1617 } 1618 1619/* 1620 * Prepare the hardware to post a byte to host memory given an 1621 * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR. 1622 */ 1623post_byte_setup: 1624 mov ARG_2, SINDEX; 1625 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1626 mvi DINDEX, CCHADDR; 1627 mvi SCBID_ADDR call set_1byte_addr; 1628 mvi CCHCNT, 1; 1629 mvi CCSCBCTL, CCSCBRESET ret; 1630 } else { 1631 mvi DINDEX, HADDR; 1632 mvi SCBID_ADDR call set_1byte_addr; 1633 mvi HCNT[0], 1; 1634 clr HCNT[1]; 1635 clr HCNT[2]; 1636 mvi DFCNTRL, FIFORESET ret; 1637 } 1638 1639post_byte: 1640 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1641 bmov CCSCBRAM, SINDEX, 1; 1642 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1643 test CCSCBCTL, CCSCBDONE jz .; 1644 clr CCSCBCTL ret; 1645 } else { 1646 mov DFDAT, SINDEX; 1647 or DFCNTRL, HDMAEN|FIFOFLUSH; 1648 jmp dma_finish; 1649 } 1650 1651get_SCBID_from_host: 1652 mov A, SAVED_TCL; 1653 mvi UNTAGGEDSCB_OFFSET call fetch_byte; 1654 mov RETURN_1, RETURN_2 ret; 1655 1656phase_lock: 1657 test SSTAT1, REQINIT jz phase_lock; 1658 test SSTAT1, SCSIPERR jnz phase_lock; 1659 and SCSISIGO, PHASE_MASK, SCSISIGI; 1660 and LASTPHASE, PHASE_MASK, SCSISIGI ret; 1661 1662if ((ahc->features & AHC_CMD_CHAN) == 0) { 1663set_stcnt_from_hcnt: 1664 mov STCNT[0], HCNT[0]; 1665 mov STCNT[1], HCNT[1]; 1666 mov STCNT[2], HCNT[2] ret; 1667 1668bcopy_7: 1669 mov DINDIR, SINDIR; 1670 mov DINDIR, SINDIR; 1671bcopy_5: 1672 mov DINDIR, SINDIR; 1673bcopy_4: 1674 mov DINDIR, SINDIR; 1675bcopy_3: 1676 mov DINDIR, SINDIR; 1677 mov DINDIR, SINDIR; 1678 mov DINDIR, SINDIR ret; 1679} 1680 1681if ((ahc->flags & AHC_TARGETMODE) != 0) { 1682/* 1683 * Setup addr assuming that A is an index into 1684 * an array of 32byte objects, SINDEX contains 1685 * the base address of that array, and DINDEX 1686 * contains the base address of the location 1687 * to store the indexed address. 1688 */ 1689set_32byte_addr: 1690 shr ARG_2, 3, A; 1691 shl A, 5; 1692 jmp set_1byte_addr; 1693} 1694 1695/* 1696 * Setup addr assuming that A is an index into 1697 * an array of 64byte objects, SINDEX contains 1698 * the base address of that array, and DINDEX 1699 * contains the base address of the location 1700 * to store the indexed address. 1701 */ 1702set_64byte_addr: 1703 shr ARG_2, 2, A; 1704 shl A, 6; 1705 1706/* 1707 * Setup addr assuming that A + (ARG_1 * 256) is an 1708 * index into an array of 1byte objects, SINDEX contains 1709 * the base address of that array, and DINDEX contains 1710 * the base address of the location to store the computed 1711 * address. 1712 */ 1713set_1byte_addr: 1714 add DINDIR, A, SINDIR; 1715 mov A, ARG_2; 1716 adc DINDIR, A, SINDIR; 1717 clr A; 1718 adc DINDIR, A, SINDIR; 1719 adc DINDIR, A, SINDIR ret; 1720 1721/* 1722 * Either post or fetch and SCB from host memory based on the 1723 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. 1724 */ 1725dma_scb: 1726 mov A, SINDEX; 1727 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1728 mvi DINDEX, CCHADDR; 1729 mvi HSCB_ADDR call set_64byte_addr; 1730 mov CCSCBPTR, SCBPTR; 1731 test DMAPARAMS, DIRECTION jz dma_scb_tohost; 1732 mvi CCHCNT, SCB_64BYTE_SIZE; 1733 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET; 1734 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .; 1735 jmp dma_scb_finish; 1736dma_scb_tohost: 1737 mvi CCHCNT, SCB_32BYTE_SIZE; 1738 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 1739 mvi CCSCBCTL, CCSCBRESET; 1740 bmov CCSCBRAM, SCB_CONTROL, SCB_32BYTE_SIZE; 1741 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1742 test CCSCBCTL, CCSCBDONE jz .; 1743 } else { 1744 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET; 1745 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .; 1746 } 1747dma_scb_finish: 1748 clr CCSCBCTL; 1749 test CCSCBCTL, CCARREN|CCSCBEN jnz .; 1750 ret; 1751 } else { 1752 mvi DINDEX, HADDR; 1753 mvi HSCB_ADDR call set_64byte_addr; 1754 mvi HCNT[0], SCB_32BYTE_SIZE; 1755 clr HCNT[1]; 1756 clr HCNT[2]; 1757 mov DFCNTRL, DMAPARAMS; 1758 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1759 /* Fill it with the SCB data */ 1760copy_scb_tofifo: 1761 mvi SINDEX, SCB_CONTROL; 1762 add A, SCB_32BYTE_SIZE, SINDEX; 1763copy_scb_tofifo_loop: 1764 mov DFDAT,SINDIR; 1765 mov DFDAT,SINDIR; 1766 mov DFDAT,SINDIR; 1767 mov DFDAT,SINDIR; 1768 mov DFDAT,SINDIR; 1769 mov DFDAT,SINDIR; 1770 mov DFDAT,SINDIR; 1771 cmp SINDEX, A jne copy_scb_tofifo_loop; 1772 or DFCNTRL, HDMAEN|FIFOFLUSH; 1773dma_scb_fromhost: 1774 call dma_finish; 1775 /* If we were putting the SCB, we are done */ 1776 test DMAPARAMS, DIRECTION jz return; 1777 mvi SCB_CONTROL call dfdat_in_7; 1778 call dfdat_in_7_continued; 1779 call dfdat_in_7_continued; 1780 jmp dfdat_in_7_continued; 1781dfdat_in_7: 1782 mov DINDEX,SINDEX; 1783dfdat_in_7_continued: 1784 mov DINDIR,DFDAT; 1785 mov DINDIR,DFDAT; 1786 mov DINDIR,DFDAT; 1787 mov DINDIR,DFDAT; 1788 mov DINDIR,DFDAT; 1789 mov DINDIR,DFDAT; 1790 mov DINDIR,DFDAT ret; 1791 } 1792 1793 1794/* 1795 * Wait for DMA from host memory to data FIFO to complete, then disable 1796 * DMA and wait for it to acknowledge that it's off. 1797 */ 1798dma_finish: 1799 test DFSTATUS,HDONE jz dma_finish; 1800 /* Turn off DMA */ 1801 and DFCNTRL, ~HDMAEN; 1802 test DFCNTRL, HDMAEN jnz .; 1803 ret; 1804 1805add_scb_to_free_list: 1806 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1807 mov SCB_NEXT, FREE_SCBH; 1808 mov FREE_SCBH, SCBPTR; 1809 } 1810 mvi SCB_TAG, SCB_LIST_NULL ret; 1811 1812if ((ahc->flags & AHC_PAGESCBS) != 0) { 1813get_free_or_disc_scb: 1814 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1815 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1816return_error: 1817 mvi SINDEX, SCB_LIST_NULL ret; 1818dequeue_disc_scb: 1819 mov SCBPTR, DISCONNECTED_SCBH; 1820dma_up_scb: 1821 mvi DMAPARAMS, FIFORESET; 1822 mov SCB_TAG call dma_scb; 1823unlink_disc_scb: 1824 mov DISCONNECTED_SCBH, SCB_NEXT ret; 1825dequeue_free_scb: 1826 mov SCBPTR, FREE_SCBH; 1827 mov FREE_SCBH, SCB_NEXT ret; 1828} 1829 1830add_scb_to_disc_list: 1831/* 1832 * Link this SCB into the DISCONNECTED list. This list holds the 1833 * candidates for paging out an SCB if one is needed for a new command. 1834 * Modifying the disconnected list is a critical(pause dissabled) section. 1835 */ 1836 mov SCB_NEXT, DISCONNECTED_SCBH; 1837 mov DISCONNECTED_SCBH, SCBPTR ret; 1838