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