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