aic7xxx.seq revision 63944
1272343Sngie/* 2272343Sngie * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD. 3272343Sngie * 4272343Sngie * Copyright (c) 1994-2000 Justin Gibbs. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions, and the following disclaimer, 12272343Sngie * without modification. 13272343Sngie * 2. The name of the author may not be used to endorse or promote products 14272343Sngie * derived from this software without specific prior written permission. 15272343Sngie * 16272343Sngie * Alternatively, this software may be distributed under the terms of the 17272343Sngie * GNU Public License ("GPL"). 18272343Sngie * 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20272343Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21272343Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22272343Sngie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23272343Sngie * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25272343Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27272343Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28272343Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29272343Sngie * SUCH DAMAGE. 30272343Sngie * 31272343Sngie * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.seq 63944 2000-07-27 23:17:52Z gibbs $ 32272343Sngie */ 33272343Sngie 34272343Sngie#include <dev/aic7xxx/aic7xxx.reg> 35272343Sngie#include <cam/scsi/scsi_message.h> 36272343Sngie 37272343Sngie/* 38272343Sngie * A few words on the waiting SCB list: 39272343Sngie * After starting the selection hardware, we check for reconnecting targets 40272343Sngie * as well as for our selection to complete just in case the reselection wins 41272343Sngie * bus arbitration. The problem with this is that we must keep track of the 42272343Sngie * SCB that we've already pulled from the QINFIFO and started the selection 43272343Sngie * on just in case the reselection wins so that we can retry the selection at 44272343Sngie * a later time. This problem cannot be resolved by holding a single entry 45272343Sngie * in scratch ram since a reconnecting target can request sense and this will 46272343Sngie * create yet another SCB waiting for selection. The solution used here is to 47272343Sngie * use byte 27 of the SCB as a psuedo-next pointer and to thread a list 48272343Sngie * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, 49272343Sngie * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to 50272343Sngie * this list everytime a request sense occurs or after completing a non-tagged 51272343Sngie * command for which a second SCB has been queued. The sequencer will 52272343Sngie * automatically consume the entries. 53272343Sngie */ 54272343Sngie 55272343Sngiereset: 56272343Sngie clr SCSISIGO; /* De-assert BSY */ 57272343Sngie mvi MSG_OUT, MSG_NOOP; /* No message to send */ 58272343Sngie and SXFRCTL1, ~BITBUCKET; 59272343Sngie /* Always allow reselection */ 60272343Sngie and SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ_TEMPLATE; 61272343Sngie if ((ahc->features & AHC_CMD_CHAN) != 0) { 62272343Sngie /* Ensure that no DMA operations are in progress */ 63272343Sngie clr CCSGCTL; 64272343Sngie clr CCSCBCTL; 65272343Sngie } 66272343Sngie 67272343Sngiepoll_for_work: 68272343Sngie call clear_target_state; 69272343Sngie and SXFRCTL0, ~SPIOEN; 70272343Sngie if ((ahc->features & AHC_QUEUE_REGS) == 0) { 71272343Sngie mov A, QINPOS; 72272343Sngie } 73272343Sngiepoll_for_work_loop: 74272343Sngie test SSTAT0, SELDO|SELDI jnz selection; 75272343Sngie test SCSISEQ, ENSELO jnz poll_for_work_loop; 76272343Sngie if ((ahc->features & AHC_TWIN) != 0) { 77272343Sngie /* 78272343Sngie * Twin channel devices cannot handle things like SELTO 79272343Sngie * interrupts on the "background" channel. So, if we 80272343Sngie * are selecting, keep polling the current channel util 81272343Sngie * either a selection or reselection occurs. 82272343Sngie */ 83272343Sngie xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ 84272343Sngie test SSTAT0, SELDO|SELDI jnz selection; 85272343Sngie test SCSISEQ, ENSELO jnz poll_for_work_loop; 86272343Sngie } 87272343Sngie cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; 88272343Sngietest_queue: 89272343Sngie /* Has the driver posted any work for us? */ 90272343Sngie if ((ahc->features & AHC_QUEUE_REGS) != 0) { 91272343Sngie test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop; 92272343Sngie mov NONE, SNSCB_QOFF; 93272343Sngie inc QINPOS; 94272343Sngie } else { 95272343Sngie cmp KERNEL_QINPOS, A je poll_for_work_loop; 96272343Sngie inc QINPOS; 97272343Sngie } 98272343Sngie 99272343Sngie /* 100272343Sngie * We have at least one queued SCB now and we don't have any 101272343Sngie * SCBs in the list of SCBs awaiting selection. Pull the tag 102272343Sngie * from the QINFIFO and get to work on it. 103272343Sngie */ 104272343Sngie if ((ahc->flags & AHC_PAGESCBS) != 0) { 105272343Sngie mov ALLZEROS call get_free_or_disc_scb; 106272343Sngie } 107272343Sngie 108272343Sngiedequeue_scb: 109272343Sngie add A, -1, QINPOS; 110272343Sngie mvi QINFIFO_OFFSET call fetch_byte; 111272343Sngie 112272343Sngie if ((ahc->flags & AHC_PAGESCBS) == 0) { 113272343Sngie /* In the non-paging case, the SCBID == hardware SCB index */ 114272343Sngie mov SCBPTR, RETURN_2; 115272343Sngie } 116272343Sngiedma_queued_scb: 117272343Sngie /* 118272343Sngie * DMA the SCB from host ram into the current SCB location. 119272343Sngie */ 120272343Sngie mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 121272343Sngie mov RETURN_2 call dma_scb; 122272343Sngie 123272343Sngiestart_scb: 124272343Sngie /* 125272343Sngie * Place us on the waiting list in case our selection 126272343Sngie * doesn't win during bus arbitration. 127272343Sngie */ 128272343Sngie mov SCB_NEXT,WAITING_SCBH; 129272343Sngie mov WAITING_SCBH, SCBPTR; 130272343Sngiestart_waiting: 131272343Sngie /* 132272343Sngie * Start the first entry on the waiting SCB list. 133272343Sngie */ 134272343Sngie mov SCBPTR, WAITING_SCBH; 135272343Sngie call start_selection; 136272343Sngie jmp poll_for_work; 137272343Sngie 138272343Sngiestart_selection: 139272343Sngie if ((ahc->features & AHC_TWIN) != 0) { 140272343Sngie and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */ 141272343Sngie test SCB_SCSIID, TWIN_CHNLB jz . + 2; 142272343Sngie or SINDEX, SELBUSB; 143272343Sngie mov SBLKCTL,SINDEX; /* select channel */ 144272343Sngie } 145272343Sngieinitialize_scsiid: 146272343Sngie if ((ahc->features & AHC_ULTRA2) != 0) { 147272343Sngie mov SCSIID_ULTRA2, SCB_SCSIID; 148272343Sngie } else if ((ahc->features & AHC_TWIN) != 0) { 149272343Sngie and SCSIID, TWIN_TID|OID, SCB_SCSIID; 150272343Sngie } else { 151272343Sngie mov SCSIID, SCB_SCSIID; 152272343Sngie } 153272343Sngie if ((ahc->flags & AHC_TARGETMODE) != 0) { 154272343Sngie mov SINDEX, SCSISEQ_TEMPLATE; 155272343Sngie test SCB_CONTROL, TARGET_SCB jz . + 2; 156272343Sngie or SINDEX, TEMODE; 157272343Sngie mov SCSISEQ, SINDEX ret; 158272343Sngie } else { 159272343Sngie mov SCSISEQ, SCSISEQ_TEMPLATE ret; 160272343Sngie } 161272343Sngie 162272343Sngie/* 163272343Sngie * Initialize transfer settings and clear the SCSI channel. 164272343Sngie * SINDEX should contain any additional bit's the client wants 165272343Sngie * set in SXFRCTL0. We also assume that the current SCB is 166272343Sngie * a valid SCB for the target we wish to talk to. 167272343Sngie */ 168272343Sngieinitialize_channel: 169272343Sngie or SXFRCTL0, CLRSTCNT|CLRCHN, SINDEX; 170272343Sngieset_transfer_settings: 171272343Sngie if ((ahc->features & AHC_ULTRA) != 0) { 172272343Sngie test SCB_CONTROL, ULTRAENB jz . + 2; 173272343Sngie or SXFRCTL0, FAST20; 174272343Sngie } 175272343Sngie /* 176272343Sngie * Initialize SCSIRATE with the appropriate value for this target. 177272343Sngie */ 178272343Sngie if ((ahc->features & AHC_ULTRA2) != 0) { 179272343Sngie bmov SCSIRATE, SCB_SCSIRATE, 2 ret; 180272343Sngie } else { 181272343Sngie mov SCSIRATE, SCB_SCSIRATE ret; 182 } 183 184selection: 185 /* 186 * We aren't expecting a bus free, so interrupt 187 * the kernel driver if it happens. 188 */ 189 mvi CLRSINT1,CLRBUSFREE; 190 or SIMODE1, ENBUSFREE; 191 192 test SSTAT0,SELDO jnz select_out; 193 mvi CLRSINT0, CLRSELDI; 194select_in: 195 if ((ahc->flags & AHC_TARGETMODE) != 0) { 196 if ((ahc->flags & AHC_INITIATORMODE) != 0) { 197 test SSTAT0, TARGET jz initiator_reselect; 198 } 199 200 /* 201 * We've just been selected. Assert BSY and 202 * setup the phase for receiving messages 203 * from the target. 204 */ 205 mvi SCSISIGO, P_MESGOUT|BSYO; 206 207 /* 208 * Setup the DMA for sending the identify and 209 * command information. 210 */ 211 or SEQ_FLAGS, CMDPHASE_PENDING; 212 213 mov A, TQINPOS; 214 if ((ahc->features & AHC_CMD_CHAN) != 0) { 215 mvi DINDEX, CCHADDR; 216 mvi SHARED_DATA_ADDR call set_32byte_addr; 217 mvi CCSCBCTL, CCSCBRESET; 218 } else { 219 mvi DINDEX, HADDR; 220 mvi SHARED_DATA_ADDR call set_32byte_addr; 221 mvi DFCNTRL, FIFORESET; 222 } 223 224 /* Initiator that selected us */ 225 and SAVED_SCSIID, SELID_MASK, SELID; 226 /* The Target ID we were selected at */ 227 if ((ahc->features & AHC_MULTI_TID) != 0) { 228 and A, OID, TARGIDIN; 229 } else if ((ahc->features & AHC_ULTRA2) != 0) { 230 and A, OID, SCSIID_ULTRA2; 231 } else { 232 and A, OID, SCSIID; 233 } 234 or SAVED_SCSIID, A; 235 if ((ahc->features & AHC_TWIN) != 0) { 236 test SBLKCTL, SELBUSB jz . + 2; 237 or SAVED_SCSIID, TWIN_CHNLB; 238 } 239 if ((ahc->features & AHC_CMD_CHAN) != 0) { 240 mov CCSCBRAM, SAVED_SCSIID; 241 } else { 242 mov DFDAT, SAVED_SCSIID; 243 } 244 245 /* 246 * If ATN isn't asserted, the target isn't interested 247 * in talking to us. Go directly to bus free. 248 * XXX SCSI-1 may require us to assume lun 0 if 249 * ATN is false. 250 */ 251 test SCSISIGI, ATNI jz target_busfree; 252 253 /* 254 * Watch ATN closely now as we pull in messages from the 255 * initiator. We follow the guidlines from section 6.5 256 * of the SCSI-2 spec for what messages are allowed when. 257 */ 258 call target_inb; 259 260 /* 261 * Our first message must be one of IDENTIFY, ABORT, or 262 * BUS_DEVICE_RESET. 263 */ 264 test DINDEX, MSG_IDENTIFYFLAG jz host_target_message_loop; 265 /* Store for host */ 266 if ((ahc->features & AHC_CMD_CHAN) != 0) { 267 mov CCSCBRAM, DINDEX; 268 } else { 269 mov DFDAT, DINDEX; 270 } 271 272 /* Remember for disconnection decision */ 273 test DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2; 274 /* XXX Honor per target settings too */ 275 or SEQ_FLAGS, NO_DISCONNECT; 276 277 test SCSISIGI, ATNI jz ident_messages_done; 278 call target_inb; 279 /* 280 * If this is a tagged request, the tagged message must 281 * immediately follow the identify. We test for a valid 282 * tag message by seeing if it is >= MSG_SIMPLE_Q_TAG and 283 * < MSG_IGN_WIDE_RESIDUE. 284 */ 285 add A, -MSG_SIMPLE_Q_TAG, DINDEX; 286 jnc ident_messages_done; 287 add A, -MSG_IGN_WIDE_RESIDUE, DINDEX; 288 jc ident_messages_done; 289 /* Store for host */ 290 if ((ahc->features & AHC_CMD_CHAN) != 0) { 291 mov CCSCBRAM, DINDEX; 292 } else { 293 mov DFDAT, DINDEX; 294 } 295 296 /* 297 * If the initiator doesn't feel like providing a tag number, 298 * we've got a failed selection and must transition to bus 299 * free. 300 */ 301 test SCSISIGI, ATNI jz target_busfree; 302 303 /* 304 * Store the tag for the host. 305 */ 306 call target_inb; 307 if ((ahc->features & AHC_CMD_CHAN) != 0) { 308 mov CCSCBRAM, DINDEX; 309 } else { 310 mov DFDAT, DINDEX; 311 } 312 mov INITIATOR_TAG, DINDEX; 313 or SEQ_FLAGS, TARGET_CMD_IS_TAGGED; 314 test SCSISIGI, ATNI jz . + 2; 315 /* Initiator still wants to give us messages */ 316 call target_inb; 317 jmp ident_messages_done; 318 319 /* 320 * Pushed message loop to allow the kernel to 321 * run it's own target mode message state engine. 322 */ 323host_target_message_loop: 324 mvi INTSTAT, HOST_MSG_LOOP; 325 nop; 326 cmp RETURN_1, EXIT_MSG_LOOP je target_ITloop; 327 test SSTAT0, SPIORDY jz .; 328 jmp host_target_message_loop; 329 330ident_messages_done: 331 /* If ring buffer is full, return busy or queue full */ 332 if ((ahc->features & AHC_HS_MAILBOX) != 0) { 333 and A, HOST_TQINPOS, HS_MAILBOX; 334 } else { 335 mov A, KERNEL_TQINPOS; 336 } 337 cmp TQINPOS, A jne tqinfifo_has_space; 338 mvi P_STATUS|BSYO call change_phase; 339 test SEQ_FLAGS, TARGET_CMD_IS_TAGGED jnz . + 3; 340 mvi STATUS_QUEUE_FULL call target_outb; 341 jmp target_busfree_wait; 342 mvi STATUS_BUSY call target_outb; 343 jmp target_busfree_wait; 344tqinfifo_has_space: 345 /* Terminate the ident list */ 346 if ((ahc->features & AHC_CMD_CHAN) != 0) { 347 mvi CCSCBRAM, SCB_LIST_NULL; 348 } else { 349 mvi DFDAT, SCB_LIST_NULL; 350 } 351 or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN; 352 test SCSISIGI, ATNI jnz target_mesgout_pending; 353 jmp target_ITloop; 354 355/* 356 * We carefully toggle SPIOEN to allow us to return the 357 * message byte we receive so it can be checked prior to 358 * driving REQ on the bus for the next byte. 359 */ 360target_inb: 361 /* 362 * Drive REQ on the bus by enabling SCSI PIO. 363 */ 364 or SXFRCTL0, SPIOEN; 365 /* Wait for the byte */ 366 test SSTAT0, SPIORDY jz .; 367 /* Prevent our read from triggering another REQ */ 368 and SXFRCTL0, ~SPIOEN; 369 /* Save latched contents */ 370 mov DINDEX, SCSIDATL ret; 371 } 372 373if ((ahc->flags & AHC_INITIATORMODE) != 0) { 374/* 375 * Reselection has been initiated by a target. Make a note that we've been 376 * reselected, but haven't seen an IDENTIFY message from the target yet. 377 */ 378initiator_reselect: 379 /* XXX test for and handle ONE BIT condition */ 380 and SAVED_SCSIID, SELID_MASK, SELID; 381 if ((ahc->features & AHC_ULTRA2) != 0) { 382 and A, OID, SCSIID_ULTRA2; 383 } else { 384 and A, OID, SCSIID; 385 } 386 or SAVED_SCSIID, A; 387 if ((ahc->features & AHC_TWIN) != 0) { 388 test SBLKCTL, SELBUSB jz . + 2; 389 or SAVED_SCSIID, TWIN_CHNLB; 390 } 391 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; 392 jmp ITloop; 393} 394 395/* 396 * After the selection, remove this SCB from the "waiting SCB" 397 * list. This is achieved by simply moving our "next" pointer into 398 * WAITING_SCBH. Our next pointer will be set to null the next time this 399 * SCB is used, so don't bother with it now. 400 */ 401select_out: 402 /* Turn off the selection hardware */ 403 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ; 404 mvi CLRSINT0, CLRSELDO; 405 mov SCBPTR, WAITING_SCBH; 406 mov WAITING_SCBH,SCB_NEXT; 407 mov SAVED_SCSIID, SCB_SCSIID; 408 mov SAVED_LUN, SCB_LUN; 409 mvi SPIOEN call initialize_channel; 410 if ((ahc->flags & AHC_TARGETMODE) != 0) { 411 test SSTAT0, TARGET jz initiator_select; 412 413 /* 414 * We've just re-selected an initiator. 415 * Assert BSY and setup the phase for 416 * sending our identify messages. 417 */ 418 mvi P_MESGIN|BSYO call change_phase; 419 420 /* 421 * Start out with a simple identify message. 422 */ 423 or SCB_LUN, MSG_IDENTIFYFLAG call target_outb; 424 425 /* 426 * If we are the result of a tagged command, send 427 * a simple Q tag and the tag id. 428 */ 429 test SCB_CONTROL, TAG_ENB jz . + 3; 430 mvi MSG_SIMPLE_Q_TAG call target_outb; 431 mov SCB_TARGET_INFO[SCB_INITIATOR_TAG] call target_outb; 432target_synccmd: 433 /* 434 * Now determine what phases the host wants us 435 * to go through. 436 */ 437 mov SEQ_FLAGS, SCB_TARGET_INFO[SCB_TARGET_PHASES]; 438 439target_ITloop: 440 /* 441 * Start honoring ATN signals now that 442 * we properly identified ourselves. 443 */ 444 test SCSISIGI, ATNI jnz target_mesgout; 445 test SEQ_FLAGS, CMDPHASE_PENDING jnz target_cmdphase; 446 test SEQ_FLAGS, DPHASE_PENDING jnz target_dphase; 447 test SEQ_FLAGS, SPHASE_PENDING jnz target_sphase; 448 449 /* 450 * No more work to do. Either disconnect or not depending 451 * on the state of NO_DISCONNECT. 452 */ 453 test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; 454 if ((ahc->flags & AHC_PAGESCBS) != 0) { 455 mov ALLZEROS call get_free_or_disc_scb; 456 } 457 mov RETURN_1, ALLZEROS; 458 call complete_target_cmd; 459 cmp RETURN_1, CONT_MSG_LOOP jne .; 460 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 461 mov SCB_TAG call dma_scb; 462 jmp target_synccmd; 463 464target_mesgout: 465 mvi SCSISIGO, P_MESGOUT|BSYO; 466target_mesgout_continue: 467 call target_inb; 468target_mesgout_pending: 469 /* Local Processing goes here... */ 470 jmp host_target_message_loop; 471 472target_disconnect: 473 mvi P_MESGIN|BSYO call change_phase; 474 test SEQ_FLAGS, DPHASE jz . + 2; 475 mvi MSG_SAVEDATAPOINTER call target_outb; 476 mvi MSG_DISCONNECT call target_outb; 477 478target_busfree_wait: 479 /* Wait for preceeding I/O session to complete. */ 480 test SCSISIGI, ACKI jnz .; 481target_busfree: 482 and SIMODE1, ~ENBUSFREE; 483 clr SCSISIGO; 484 mvi LASTPHASE, P_BUSFREE; 485 call complete_target_cmd; 486 jmp poll_for_work; 487 488target_cmdphase: 489 mvi P_COMMAND|BSYO call change_phase; 490 call target_inb; 491 mov A, DINDEX; 492 /* Store for host */ 493 if ((ahc->features & AHC_CMD_CHAN) != 0) { 494 mov CCSCBRAM, A; 495 } else { 496 mov DFDAT, A; 497 } 498 499 /* 500 * Determine the number of bytes to read 501 * based on the command group code via table lookup. 502 * We reuse the first 8 bytes of the TARG_SCSIRATE 503 * BIOS array for this table. Count is one less than 504 * the total for the command since we've already fetched 505 * the first byte. 506 */ 507 shr A, CMD_GROUP_CODE_SHIFT; 508 add SINDEX, TARG_SCSIRATE, A; 509 mov A, SINDIR; 510 511 test A, 0xFF jz command_phase_done; 512command_loop: 513 or SXFRCTL0, SPIOEN; 514 test SSTAT0, SPIORDY jz .; 515 cmp A, 1 jne . + 2; 516 and SXFRCTL0, ~SPIOEN; /* Last Byte */ 517 if ((ahc->features & AHC_CMD_CHAN) != 0) { 518 mov CCSCBRAM, SCSIDATL; 519 } else { 520 mov DFDAT, SCSIDATL; 521 } 522 dec A; 523 test A, 0xFF jnz command_loop; 524 525command_phase_done: 526 and SEQ_FLAGS, ~CMDPHASE_PENDING; 527 jmp target_ITloop; 528 529target_dphase: 530 /* 531 * Data phases on the bus are from the 532 * perspective of the initiator. The dma 533 * code looks at LASTPHASE to determine the 534 * data direction of the DMA. Toggle it for 535 * target transfers. 536 */ 537 xor LASTPHASE, IOI, SCB_TARGET_INFO[SCB_TARGET_DATA_DIR]; 538 or SCB_TARGET_INFO[SCB_TARGET_DATA_DIR], BSYO 539 call change_phase; 540 jmp p_data; 541 542target_sphase: 543 mvi P_STATUS|BSYO call change_phase; 544 mvi LASTPHASE, P_STATUS; 545 mov SCB_TARGET_INFO[SCB_TARGET_STATUS] call target_outb; 546 /* XXX Watch for ATN or parity errors??? */ 547 mvi SCSISIGO, P_MESGIN|BSYO; 548 /* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */ 549 mov ALLZEROS call target_outb; 550 jmp target_busfree_wait; 551 552complete_target_cmd: 553 test SEQ_FLAGS, TARG_CMD_PENDING jnz . + 2; 554 mov SCB_TAG jmp complete_post; 555 if ((ahc->features & AHC_CMD_CHAN) != 0) { 556 /* Set the valid byte */ 557 mvi CCSCBADDR, 24; 558 mov CCSCBRAM, ALLONES; 559 mvi CCHCNT, 28; 560 or CCSCBCTL, CCSCBEN|CCSCBRESET; 561 test CCSCBCTL, CCSCBDONE jz .; 562 clr CCSCBCTL; 563 } else { 564 /* Set the valid byte */ 565 or DFCNTRL, FIFORESET; 566 mvi DFWADDR, 3; /* Third 64bit word or byte 24 */ 567 mov DFDAT, ALLONES; 568 mvi 28 call set_hcnt; 569 or DFCNTRL, HDMAEN|FIFOFLUSH; 570 call dma_finish; 571 } 572 inc TQINPOS; 573 mvi INTSTAT,CMDCMPLT ret; 574 } 575 576if ((ahc->flags & AHC_INITIATORMODE) != 0) { 577initiator_select: 578 /* 579 * As soon as we get a successful selection, the target 580 * should go into the message out phase since we have ATN 581 * asserted. 582 */ 583 mvi MSG_OUT, MSG_IDENTIFYFLAG; 584 or SEQ_FLAGS, IDENTIFY_SEEN; 585 586 /* 587 * Main loop for information transfer phases. Wait for the 588 * target to assert REQ before checking MSG, C/D and I/O for 589 * the bus phase. 590 */ 591mesgin_phasemis: 592ITloop: 593 call phase_lock; 594 595 mov A, LASTPHASE; 596 597 test A, ~P_DATAIN jz p_data; 598 cmp A,P_COMMAND je p_command; 599 cmp A,P_MESGOUT je p_mesgout; 600 cmp A,P_STATUS je p_status; 601 cmp A,P_MESGIN je p_mesgin; 602 603 mvi INTSTAT,BAD_PHASE; 604 jmp ITloop; /* Try reading the bus again. */ 605 606await_busfree: 607 and SIMODE1, ~ENBUSFREE; 608 mov NONE, SCSIDATL; /* Ack the last byte */ 609 and SXFRCTL0, ~SPIOEN; 610 test SSTAT1,REQINIT|BUSFREE jz .; 611 test SSTAT1, BUSFREE jnz poll_for_work; 612 mvi INTSTAT, BAD_PHASE; 613} 614 615clear_target_state: 616 /* 617 * We assume that the kernel driver may reset us 618 * at any time, even in the middle of a DMA, so 619 * clear DFCNTRL too. 620 */ 621 clr DFCNTRL; 622 mvi SXFRCTL0, CLRSTCNT|CLRCHN; 623 624 /* 625 * We don't know the target we will connect to, 626 * so default to narrow transfers to avoid 627 * parity problems. 628 */ 629 if ((ahc->features & AHC_ULTRA2) != 0) { 630 bmov SCSIRATE, ALLZEROS, 2; 631 } else { 632 clr SCSIRATE; 633 if ((ahc->features & AHC_ULTRA) != 0) { 634 and SXFRCTL0, ~(FAST20); 635 } 636 } 637 mvi LASTPHASE, P_BUSFREE; 638 /* clear target specific flags */ 639 clr SEQ_FLAGS ret; 640 641sg_advance: 642 clr A; /* add sizeof(struct scatter) */ 643 add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; 644 adc SCB_RESIDUAL_SGPTR[1],A; 645 adc SCB_RESIDUAL_SGPTR[2],A; 646 adc SCB_RESIDUAL_SGPTR[3],A ret; 647 648idle_loop: 649 if ((ahc->features & AHC_CMD_CHAN) != 0) { 650 /* Did we just finish fetching segs? */ 651 cmp CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete; 652 653 /* Are we actively fetching segments? */ 654 test CCSGCTL, CCSGEN jnz return; 655 656 /* 657 * Do we need any more segments? 658 */ 659 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return; 660 661 /* 662 * Do we have any prefetch left??? 663 */ 664 cmp CCSGADDR, CCSGADDR_MAX jne idle_sg_avail; 665 666 /* 667 * Need to fetch segments, but we can only do that 668 * if the command channel is completely idle. Make 669 * sure we don't have an SCB prefetch going on. 670 */ 671 test CCSCBCTL, CCSCBEN jnz return; 672 673 /* 674 * The kernel allocates S/G space so that it is 128 byte 675 * aligned and ends on a 128 byte boundary. We fetch 676 * up to the next 128 byte boundary so we don't attempt 677 * to read a non-existent page. 678 */ 679 mvi CCHCNT, CCSGADDR_MAX; 680 and CCHADDR[0], ~(CCSGADDR_MAX - 1), SCB_RESIDUAL_SGPTR; 681 bmov CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3; 682 mvi CCSGCTL, CCSGEN|CCSGRESET ret; 683idle_sgfetch_complete: 684 clr CCSGCTL; 685 test CCSGCTL, CCSGEN jnz .; 686 and CCSGADDR, (CCSGADDR_MAX - 1), SCB_RESIDUAL_SGPTR; 687idle_sg_avail: 688 if ((ahc->features & AHC_ULTRA2) != 0) { 689 /* Does the hardware have space for another SG entry? */ 690 test DFSTATUS, PRELOAD_AVAIL jz return; 691 bmov HADDR, CCSGRAM, 4; 692 bmov SINDEX, CCSGRAM, 1; 693 test SINDEX, 0x1 jz . + 2; 694 xor DATA_COUNT_ODD, 0x1; 695 bmov HCNT[0], SINDEX, 1; 696 bmov HCNT[1], CCSGRAM, 2; 697 bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; 698 call sg_advance; 699 mov SINDEX, SCB_RESIDUAL_SGPTR[0]; 700 test DATA_COUNT_ODD, 0x1 jz . + 2; 701 or SINDEX, ODD_SEG; 702 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; 703 or SINDEX, LAST_SEG; 704 mov SG_CACHE_PRE, SINDEX; 705 /* Load the segment by writing DFCNTRL again */ 706 mov DFCNTRL, DMAPARAMS; 707 } 708 ret; 709 } 710 711/* 712 * If we re-enter the data phase after going through another phase, the 713 * STCNT may have been cleared, so restore it from the residual field. 714 */ 715data_phase_reinit: 716 if ((ahc->features & AHC_ULTRA2) != 0) { 717 /* 718 * The preload circuitry requires us to 719 * reload the address too, so pull it from 720 * the shaddow address. 721 */ 722 bmov HADDR, SHADDR, 4; 723 bmov HCNT, SCB_RESIDUAL_DATACNT, 3; 724 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 725 bmov STCNT, SCB_RESIDUAL_DATACNT, 3; 726 } else { 727 mvi DINDEX, STCNT; 728 mvi SCB_RESIDUAL_DATACNT call bcopy_3; 729 } 730 and DATA_COUNT_ODD, 0x1, SCB_RESIDUAL_DATACNT[0]; 731 jmp data_phase_loop; 732 733p_data: 734 if ((ahc->features & AHC_ULTRA2) != 0) { 735 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; 736 } else { 737 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 738 } 739 test LASTPHASE, IOI jnz . + 2; 740 or DMAPARAMS, DIRECTION; 741 call assert; /* 742 * Ensure entering a data 743 * phase is okay - seen identify, etc. 744 */ 745 if ((ahc->features & AHC_CMD_CHAN) != 0) { 746 /* We don't have any valid S/G elements */ 747 mvi CCSGADDR, CCSGADDR_MAX; 748 } 749 test SEQ_FLAGS, DPHASE jnz data_phase_reinit; 750 751 /* We have seen a data phase */ 752 or SEQ_FLAGS, DPHASE; 753 754 /* 755 * Initialize the DMA address and counter from the SCB. 756 * Also set SCB_RESIDUAL_SGPTR, including the LAST_SEG 757 * flag in the highest byte of the data count. We cannot 758 * modify the saved values in the SCB until we see a save 759 * data pointers message. 760 */ 761 if ((ahc->features & AHC_CMD_CHAN) != 0) { 762 bmov HADDR, SCB_DATAPTR, 7; 763 bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; 764 } else { 765 mvi DINDEX, HADDR; 766 mvi SCB_DATAPTR call bcopy_7; 767 mvi DINDEX, SCB_RESIDUAL_DATACNT + 3; 768 mvi SCB_DATACNT + 3 call bcopy_5; 769 } 770 and SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID; 771 and DATA_COUNT_ODD, 0x1, SCB_DATACNT[0]; 772 773 if ((ahc->features & AHC_ULTRA2) == 0) { 774 if ((ahc->features & AHC_CMD_CHAN) != 0) { 775 bmov STCNT, HCNT, 3; 776 } else { 777 call set_stcnt_from_hcnt; 778 } 779 } 780 781data_phase_loop: 782 /* Guard against overruns */ 783 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_inbounds; 784 785 /* 786 * Turn on 'Bit Bucket' mode, set the transfer count to 787 * 16meg and let the target run until it changes phase. 788 * When the transfer completes, notify the host that we 789 * had an overrun. 790 */ 791 or SXFRCTL1,BITBUCKET; 792 and DMAPARAMS, ~(HDMAEN|SDMAEN); 793 if ((ahc->features & AHC_ULTRA2) != 0) { 794 bmov HCNT, ALLONES, 3; 795 or SXFRCTL0, CLRCHN; /* Ensure FIFO empty */ 796 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 797 bmov STCNT, ALLONES, 3; 798 } else { 799 mvi STCNT[0], 0xFF; 800 mvi STCNT[1], 0xFF; 801 mvi STCNT[2], 0xFF; 802 } 803data_phase_inbounds: 804 if ((ahc->features & AHC_ULTRA2) != 0) { 805 mov SINDEX, SCB_RESIDUAL_SGPTR[0]; 806 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; 807 or SINDEX, LAST_SEG; 808 test DATA_COUNT_ODD, 0x1 jz . + 2; 809 or SINDEX, ODD_SEG; 810 mov SG_CACHE_PRE, SINDEX; 811 mov DFCNTRL, DMAPARAMS; 812ultra2_dma_loop: 813 call idle_loop; 814 /* 815 * The transfer is complete if either the last segment 816 * completes or the target changes phase. 817 */ 818 test SG_CACHE_SHADOW, LAST_SEG_DONE jnz ultra2_dmafinish; 819 test SSTAT1,PHASEMIS jz ultra2_dma_loop; 820 821ultra2_dmafinish: 822 test DFCNTRL, DIRECTION jnz ultra2_dmafifoempty; 823 and DFCNTRL, ~SCSIEN; 824 test DFCNTRL, SCSIEN jnz .; 825 if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) { 826 test DFSTATUS, FIFOEMP jnz ultra2_dmafifoempty; 827 } 828ultra2_dmafifoflush: 829 if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) { 830 /* 831 * On Rev A of the aic7890, the autoflush 832 * features doesn't function correctly. 833 * Perform an explicit manual flush. During 834 * a manual flush, the FIFOEMP bit becomes 835 * true every time the PCI FIFO empties 836 * regardless of the state of the SCSI FIFO. 837 * It can take up to 4 clock cycles for the 838 * SCSI FIFO to get data into the PCI FIFO 839 * and for FIFOEMP to de-assert. Here we 840 * guard against this condition by making 841 * sure the FIFOEMP bit stays on for 5 full 842 * clock cycles. 843 */ 844 or DFCNTRL, FIFOFLUSH; 845 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 846 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 847 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 848 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 849 } 850 test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; 851ultra2_dmafifoempty: 852 /* Don't clobber an inprogress host data transfer */ 853 test DFSTATUS, MREQPEND jnz ultra2_dmafifoempty; 854ultra2_dmahalt: 855 and DFCNTRL, ~(SCSIEN|HDMAEN); 856 test DFCNTRL, HDMAEN jnz .; 857 858 test SXFRCTL1,BITBUCKET jnz data_phase_finish; 859 860 /* 861 * If, by chance, we stopped before being able 862 * to fetch additional segments for this transfer, 863 * yet the last S/G was completely exhausted, 864 * call our idle loop until it is able to load 865 * another segment. This will allow us to immediately 866 * pickup on the next segment on the next data phase. 867 * 868 * If we happened to stop on the last segment, then 869 * our residual information is still correct from 870 * the idle loop and there is no need to perform 871 * any fixups. Just jump to data_phase_finish. 872 */ 873ultra2_ensure_sg: 874 test SG_CACHE_SHADOW, LAST_SEG jz ultra2_shvalid; 875 /* Record if we've consumed all S/G entries */ 876 test SG_CACHE_SHADOW, LAST_SEG_DONE jz data_phase_finish; 877 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL; 878 jmp data_phase_finish; 879 880ultra2_shvalid: 881 test SSTAT2, SHVALID jnz sgptr_fixup; 882 call idle_loop; 883 jmp ultra2_ensure_sg; 884 885sgptr_fixup: 886 /* 887 * Fixup the residual next S/G pointer. The S/G preload 888 * feature of the chip allows us to load two elements 889 * in addition to the currently active element. We 890 * store the bottom byte of the next S/G pointer in 891 * the SG_CACEPTR register so we can restore the 892 * correct value when the DMA completes. If the next 893 * sg ptr value has advanced to the point where higher 894 * bytes in the address have been affected, fix them 895 * too. 896 */ 897 test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; 898 test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; 899 add SCB_RESIDUAL_SGPTR[1], -1; 900 adc SCB_RESIDUAL_SGPTR[2], -1; 901 adc SCB_RESIDUAL_SGPTR[3], -1; 902sgptr_fixup_done: 903 and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; 904 clr DATA_COUNT_ODD; 905 test SG_CACHE_SHADOW, ODD_SEG jz . + 2; 906 or DATA_COUNT_ODD, 0x1; 907 clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ 908 } else { 909 /* If we are the last SG block, tell the hardware. */ 910 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz dma_mid_sg; 911 if ((ahc->flags & AHC_TARGETMODE) != 0) { 912 test SSTAT0, TARGET jz dma_last_sg; 913 if ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0) { 914 test DMAPARAMS, DIRECTION jz dma_mid_sg; 915 } 916 } 917dma_last_sg: 918 and DMAPARAMS, ~WIDEODD; 919dma_mid_sg: 920 /* Start DMA data transfer. */ 921 mov DFCNTRL, DMAPARAMS; 922dma_loop: 923 if ((ahc->features & AHC_CMD_CHAN) != 0) { 924 call idle_loop; 925 } 926 test SSTAT0,DMADONE jnz dma_dmadone; 927 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 928dma_phasemis: 929 /* 930 * We will be "done" DMAing when the transfer count goes to 931 * zero, or the target changes the phase (in light of this, 932 * it makes sense that the DMA circuitry doesn't ACK when 933 * PHASEMIS is active). If we are doing a SCSI->Host transfer, 934 * the data FIFO should be flushed auto-magically on STCNT=0 935 * or a phase change, so just wait for FIFO empty status. 936 */ 937dma_checkfifo: 938 test DFCNTRL,DIRECTION jnz dma_fifoempty; 939dma_fifoflush: 940 test DFSTATUS,FIFOEMP jz dma_fifoflush; 941dma_fifoempty: 942 /* Don't clobber an inprogress host data transfer */ 943 test DFSTATUS, MREQPEND jnz dma_fifoempty; 944 945 /* 946 * Now shut off the DMA and make sure that the DMA 947 * hardware has actually stopped. Touching the DMA 948 * counters, etc. while a DMA is active will result 949 * in an ILLSADDR exception. 950 */ 951dma_dmadone: 952 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 953dma_halt: 954 /* 955 * Some revisions of the aic7880 have a problem where, if the 956 * data fifo is full, but the PCI input latch is not empty, 957 * HDMAEN cannot be cleared. The fix used here is to drain 958 * the prefetched but unused data from the data fifo until 959 * there is space for the input latch to drain. 960 */ 961 mov NONE, DFDAT; 962 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 963 964 /* See if we have completed this last segment */ 965 test STCNT[0], 0xff jnz data_phase_finish; 966 test STCNT[1], 0xff jnz data_phase_finish; 967 test STCNT[2], 0xff jnz data_phase_finish; 968 969 /* 970 * Advance the scatter-gather pointers if needed 971 */ 972 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz sg_load; 973 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL; 974 jmp data_phase_finish; 975sg_load: 976 /* 977 * Load the next SG element's data address and length 978 * into the DMA engine. If we don't have hardware 979 * to perform a prefetch, we'll have to fetch the 980 * segment from host memory first. 981 */ 982 if ((ahc->features & AHC_CMD_CHAN) != 0) { 983 /* Wait for the idle loop to complete */ 984 test CCSGCTL, CCSGEN jz . + 3; 985 call idle_loop; 986 test CCSGCTL, CCSGEN jnz . - 1; 987 bmov HADDR, CCSGRAM, 7; 988 bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; 989 bmov STCNT, HCNT, 3; 990 } else { 991 mvi DINDEX, HADDR; 992 mvi SCB_RESIDUAL_SGPTR call bcopy_4; 993 994 mvi SG_SIZEOF call set_hcnt; 995 996 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 997 998 call dma_finish; 999 1000 mvi HADDR call dfdat_in_7; 1001 mov SCB_RESIDUAL_DATACNT[3], DFDAT; 1002 call set_stcnt_from_hcnt; 1003 } 1004 1005 /* Track odd'ness */ 1006 test HCNT[0], 0x1 jz . + 2; 1007 xor DATA_COUNT_ODD, 0x1; 1008 1009 /* Point to the new next sg in memory */ 1010 call sg_advance; 1011 1012 if ((ahc->flags & AHC_TARGETMODE) != 0) { 1013 test SSTAT0, TARGET jnz data_phase_loop; 1014 } 1015 } 1016data_phase_finish: 1017 /* 1018 * If the target has left us in data phase, loop through 1019 * the dma code again. In the case of ULTRA2 adapters, 1020 * we should only loop if there is a data overrun. For 1021 * all other adapters, we'll loop after each S/G element 1022 * is loaded as well as if there is an overrun. 1023 */ 1024 if ((ahc->flags & AHC_TARGETMODE) != 0) { 1025 test SSTAT0, TARGET jnz data_phase_done; 1026 } 1027 if ((ahc->flags & AHC_INITIATORMODE) != 0) { 1028 test SSTAT1, REQINIT jz .; 1029 test SSTAT1,PHASEMIS jz data_phase_loop; 1030 1031 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1032 /* Kill off any pending prefetch */ 1033 clr CCSGCTL; 1034 test CCSGCTL, CCSGEN jnz .; 1035 } 1036 1037 /* 1038 * Turn off BITBUCKET mode and notify the host 1039 * in the event of an overrun. 1040 */ 1041 test SXFRCTL1,BITBUCKET jz data_phase_done; 1042 and SXFRCTL1, ~BITBUCKET; 1043 mvi INTSTAT,DATA_OVERRUN; 1044 jmp ITloop; 1045 } 1046 1047data_phase_done: 1048 /* 1049 * After a DMA finishes, save the SG and STCNT residuals back into 1050 * the SCB. We use STCNT instead of HCNT, since it's a reflection 1051 * of how many bytes were transferred on the SCSI (as opposed to the 1052 * host) bus. 1053 */ 1054 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1055 /* Kill off any pending prefetch */ 1056 clr CCSGCTL; 1057 test CCSGCTL, CCSGEN jnz .; 1058 1059 bmov SCB_RESIDUAL_DATACNT, STCNT, 3; 1060 } else { 1061 mov SCB_RESIDUAL_DATACNT[0],STCNT[0]; 1062 mov SCB_RESIDUAL_DATACNT[1],STCNT[1]; 1063 mov SCB_RESIDUAL_DATACNT[2],STCNT[2]; 1064 } 1065 1066 /* 1067 * Since we've been through a data phase, the SCB_RESID* fields 1068 * are now initialized. Clear the full residual flag. 1069 */ 1070 and SCB_SGPTR[0], ~SG_FULL_RESID; 1071 1072 if ((ahc->features & AHC_ULTRA2) != 0) { 1073 /* Clear the channel in case we return to data phase later */ 1074 or SXFRCTL0, CLRSTCNT|CLRCHN; 1075 } 1076 1077 if ((ahc->flags & AHC_TARGETMODE) != 0) { 1078 test SEQ_FLAGS, DPHASE_PENDING jz ITloop; 1079 and SEQ_FLAGS, ~DPHASE_PENDING; 1080 /* 1081 * For data-in phases, wait for any pending acks from the 1082 * initiator before changing phase. 1083 */ 1084 test DFCNTRL, DIRECTION jz target_ITloop; 1085 test SSTAT1, REQINIT jnz .; 1086 jmp target_ITloop; 1087 } else { 1088 jmp ITloop; 1089 } 1090 1091if ((ahc->flags & AHC_INITIATORMODE) != 0) { 1092/* 1093 * Command phase. Set up the DMA registers and let 'er rip. 1094 */ 1095p_command: 1096 call assert; 1097 1098 if ((ahc->features & AHC_ULTRA2) != 0) { 1099 bmov HCNT[0], SCB_CDB_LEN, 1; 1100 bmov HCNT[1], ALLZEROS, 2; 1101 mvi SG_CACHE_PRE, LAST_SEG; 1102 } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 1103 bmov STCNT[0], SCB_CDB_LEN, 1; 1104 bmov STCNT[1], ALLZEROS, 2; 1105 } else { 1106 mov STCNT[0], SCB_CDB_LEN; 1107 clr STCNT[1]; 1108 clr STCNT[2]; 1109 } 1110 add NONE, -13, SCB_CDB_LEN; 1111 mvi SCB_CDB_STORE jnc p_command_embedded; 1112p_command_from_host: 1113 if ((ahc->features & AHC_ULTRA2) != 0) { 1114 bmov HADDR[0], SCB_CDB_PTR, 4; 1115 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION); 1116 } else { 1117 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1118 bmov HADDR[0], SCB_CDB_PTR, 4; 1119 bmov HCNT[0], STCNT[0], 3; 1120 } else { 1121 mvi DINDEX, HADDR; 1122 mvi SCB_CDB_PTR call bcopy_5; 1123 call clear_hcnt; 1124 } 1125 mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); 1126 } 1127 jmp p_command_loop; 1128p_command_embedded: 1129 /* 1130 * The data fifo seems to require 4 byte alligned 1131 * transfers from the sequencer. Force this to 1132 * be the case by clearing HADDR[0] even though 1133 * we aren't going to touch host memeory. 1134 */ 1135 clr HADDR[0]; 1136 if ((ahc->features & AHC_ULTRA2) != 0) { 1137 mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION); 1138 } else { 1139 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); 1140 } 1141 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1142 bmov DFDAT, SCB_CDB_STORE, 12; 1143 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 1144 or DFCNTRL, FIFOFLUSH; 1145 } 1146 } else { 1147 call copy_to_fifo_6; 1148 call copy_to_fifo_6; 1149 or DFCNTRL, FIFOFLUSH; 1150 } 1151p_command_loop: 1152 test SSTAT0, SDONE jnz . + 2; 1153 test SSTAT1, PHASEMIS jz p_command_loop; 1154 /* 1155 * Wait for our ACK to go-away on it's own 1156 * instead of being killed by SCSIEN getting cleared. 1157 */ 1158 test SCSISIGI, ACKI jnz .; 1159 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1160 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; 1161 jmp ITloop; 1162 1163/* 1164 * Status phase. Wait for the data byte to appear, then read it 1165 * and store it into the SCB. 1166 */ 1167p_status: 1168 call assert; 1169 1170 mov SCB_SCSI_STATUS, SCSIDATL; 1171 jmp ITloop; 1172 1173/* 1174 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full 1175 * indentify message sequence and send it to the target. The host may 1176 * override this behavior by setting the MK_MESSAGE bit in the SCB 1177 * control byte. This will cause us to interrupt the host and allow 1178 * it to handle the message phase completely on its own. If the bit 1179 * associated with this target is set, we will also interrupt the host, 1180 * thereby allowing it to send a message on the next selection regardless 1181 * of the transaction being sent. 1182 * 1183 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. 1184 * This is done to allow the host to send messages outside of an identify 1185 * sequence while protecting the seqencer from testing the MK_MESSAGE bit 1186 * on an SCB that might not be for the current nexus. (For example, a 1187 * BDR message in responce to a bad reselection would leave us pointed to 1188 * an SCB that doesn't have anything to do with the current target). 1189 * 1190 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, 1191 * bus device reset). 1192 * 1193 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, 1194 * in case the target decides to put us in this phase for some strange 1195 * reason. 1196 */ 1197p_mesgout_retry: 1198 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 1199p_mesgout: 1200 mov SINDEX, MSG_OUT; 1201 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; 1202 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; 1203 mov FUNCTION1, SCB_SCSIID; 1204 mov A, FUNCTION1; 1205 mov SINDEX, TARGET_MSG_REQUEST[0]; 1206 if ((ahc->features & AHC_TWIN) != 0) { 1207 /* Second Channel uses high byte bits */ 1208 test SCB_SCSIID, TWIN_CHNLB jz . + 2; 1209 mov SINDEX, TARGET_MSG_REQUEST[1]; 1210 } else if ((ahc->features & AHC_WIDE) != 0) { 1211 test SCB_SCSIID, 0x80 jz . + 2; /* target > 7 */ 1212 mov SINDEX, TARGET_MSG_REQUEST[1]; 1213 } 1214 test SINDEX, A jnz host_message_loop; 1215p_mesgout_identify: 1216 or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; 1217 test SCB_CONTROL, DISCENB jnz . + 2; 1218 and SINDEX, ~DISCENB; 1219/* 1220 * Send a tag message if TAG_ENB is set in the SCB control block. 1221 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 1222 */ 1223p_mesgout_tag: 1224 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; 1225 mov SCSIDATL, SINDEX; /* Send the identify message */ 1226 call phase_lock; 1227 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1228 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 1229 call phase_lock; 1230 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1231 mov SCB_TAG jmp p_mesgout_onebyte; 1232/* 1233 * Interrupt the driver, and allow it to handle this message 1234 * phase and any required retries. 1235 */ 1236p_mesgout_from_host: 1237 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; 1238 jmp host_message_loop; 1239 1240p_mesgout_onebyte: 1241 mvi CLRSINT1, CLRATNO; 1242 mov SCSIDATL, SINDEX; 1243 1244/* 1245 * If the next bus phase after ATN drops is message out, it means 1246 * that the target is requesting that the last message(s) be resent. 1247 */ 1248 call phase_lock; 1249 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; 1250 1251p_mesgout_done: 1252 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 1253 mov LAST_MSG, MSG_OUT; 1254 mvi MSG_OUT, MSG_NOOP; /* No message left */ 1255 jmp ITloop; 1256 1257/* 1258 * Message in phase. Bytes are read using Automatic PIO mode. 1259 */ 1260p_mesgin: 1261 mvi ACCUM call inb_first; /* read the 1st message byte */ 1262 1263 test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 1264 cmp A,MSG_DISCONNECT je mesgin_disconnect; 1265 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 1266 cmp ALLZEROS,A je mesgin_complete; 1267 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 1268 cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; 1269 cmp A,MSG_NOOP je mesgin_done; 1270 1271/* 1272 * Pushed message loop to allow the kernel to 1273 * run it's own message state engine. To avoid an 1274 * extra nop instruction after signaling the kernel, 1275 * we perform the phase_lock before checking to see 1276 * if we should exit the loop and skip the phase_lock 1277 * in the ITloop. Performing back to back phase_locks 1278 * shouldn't hurt, but why do it twice... 1279 */ 1280host_message_loop: 1281 nop; 1282 mvi INTSTAT, HOST_MSG_LOOP; 1283 call phase_lock; 1284 cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1; 1285 jmp host_message_loop; 1286 1287mesgin_ign_wide_residue: 1288if ((ahc->features & AHC_WIDE) != 0) { 1289 test SCSIRATE, WIDEXFER jz mesgin_reject; 1290 /* Pull the residue byte */ 1291 mvi ARG_1 call inb_next; 1292 cmp ARG_1, 0x01 jne mesgin_reject; 1293 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; 1294 test DATA_COUNT_ODD, 0x1 jz mesgin_done; 1295 mvi INTSTAT, IGN_WIDE_RES; 1296 jmp mesgin_done; 1297} 1298 1299mesgin_reject: 1300 mvi MSG_MESSAGE_REJECT call mk_mesg; 1301mesgin_done: 1302 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1303 jmp ITloop; 1304 1305mesgin_complete: 1306/* 1307 * We received a "command complete" message. Put the SCB_TAG into the QOUTFIFO, 1308 * and trigger a completion interrupt. Before doing so, check to see if there 1309 * is a residual or the status byte is something other than STATUS_GOOD (0). 1310 * In either of these conditions, we upload the SCB back to the host so it can 1311 * process this information. In the case of a non zero status byte, we 1312 * additionally interrupt the kernel driver synchronously, allowing it to 1313 * decide if sense should be retrieved. If the kernel driver wishes to request 1314 * sense, it will fill the kernel SCB with a request sense command and set 1315 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload 1316 * the SCB, and process it as the next command by adding it to the waiting list. 1317 * If the kernel driver does not wish to request sense, it need only clear 1318 * RETURN_1, and the command is allowed to complete normally. We don't bother 1319 * to post to the QOUTFIFO in the error cases since it would require extra 1320 * work in the kernel driver to ensure that the entry was removed before the 1321 * command complete code tried processing it. 1322 */ 1323 1324/* 1325 * First check for residuals 1326 */ 1327 test SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */ 1328 test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ 1329 test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; 1330check_status: 1331 test SCB_SCSI_STATUS,0xff jz complete; /* Good Status? */ 1332upload_scb: 1333 or SCB_SGPTR, SG_RESID_VALID; 1334 mvi DMAPARAMS, FIFORESET; 1335 mov SCB_TAG call dma_scb; 1336 test SCB_SCSI_STATUS, 0xff jz complete; /* Just a residual? */ 1337 mvi INTSTAT, BAD_STATUS; /* let driver know */ 1338 /* 1339 * Prepare to DMA this SCB in case we are told to retrieve sense. 1340 * Fills a delay slot after the INTSTAT as well. 1341 */ 1342 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1343 cmp RETURN_1, SEND_SENSE jne complete; 1344 mov SCB_TAG call dma_scb; 1345add_to_waiting_list: 1346 mov SCB_NEXT,WAITING_SCBH; 1347 mov WAITING_SCBH, SCBPTR; 1348 /* 1349 * Prepare our selection hardware before the busfree so we have a 1350 * high probability of winning arbitration. 1351 */ 1352 call start_selection; 1353 jmp await_busfree; 1354 1355complete: 1356 mov SCB_TAG call complete_post; 1357 jmp await_busfree; 1358} 1359 1360complete_post: 1361 /* Post the SCBID in SINDEX and issue an interrupt */ 1362 call add_scb_to_free_list; 1363 mov ARG_1, SINDEX; 1364 if ((ahc->features & AHC_QUEUE_REGS) != 0) { 1365 mov A, SDSCB_QOFF; 1366 } else { 1367 mov A, QOUTPOS; 1368 } 1369 mvi QOUTFIFO_OFFSET call post_byte_setup; 1370 mov ARG_1 call post_byte; 1371 if ((ahc->features & AHC_QUEUE_REGS) == 0) { 1372 inc QOUTPOS; 1373 } 1374 mvi INTSTAT,CMDCMPLT ret; 1375 1376if ((ahc->flags & AHC_INITIATORMODE) != 0) { 1377/* 1378 * Is it a disconnect message? Set a flag in the SCB to remind us 1379 * and await the bus going free. If this is an untagged transaction 1380 * store the SCB id for it in our untagged target table for lookup on 1381 * a reselction. 1382 */ 1383mesgin_disconnect: 1384 or SCB_CONTROL,DISCONNECTED; 1385 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1386 call add_scb_to_disc_list; 1387 } 1388 test SCB_CONTROL, TAG_ENB jnz await_busfree; 1389 mov ARG_1, SCB_TAG; 1390 mov SAVED_LUN, SCB_LUN; 1391 mov SCB_SCSIID call index_busy_target; 1392 mov DINDIR, ARG_1; 1393 jmp await_busfree; 1394 1395/* 1396 * Save data pointers message: 1397 * Copying RAM values back to SCB, for Save Data Pointers message, but 1398 * only if we've actually been into a data phase to change them. This 1399 * protects against bogus data in scratch ram and the residual counts 1400 * since they are only initialized when we go into data_in or data_out. 1401 */ 1402mesgin_sdptrs: 1403 test SEQ_FLAGS, DPHASE jz mesgin_done; 1404 1405 /* 1406 * The SCB_SGPTR becomes the next one we'll download, 1407 * and the SCB_DATAPTR becomes the current SHADDR. 1408 * Use the residual number since STCNT is corrupted by 1409 * any message transfer. 1410 */ 1411 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1412 bmov SCB_DATAPTR, SHADDR, 4; 1413 bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8; 1414 } else { 1415 mvi DINDEX, SCB_DATAPTR; 1416 mvi SHADDR call bcopy_4; 1417 mvi SCB_RESIDUAL_DATACNT call bcopy_8; 1418 } 1419 jmp mesgin_done; 1420 1421/* 1422 * Restore pointers message? Data pointers are recopied from the 1423 * SCB anytime we enter a data phase for the first time, so all 1424 * we need to do is clear the DPHASE flag and let the data phase 1425 * code do the rest. 1426 */ 1427mesgin_rdptrs: 1428 and SEQ_FLAGS, ~DPHASE; /* 1429 * We'll reload them 1430 * the next time through 1431 * the dataphase. 1432 */ 1433 jmp mesgin_done; 1434 1435/* 1436 * Index into our Busy Target table. SINDEX and DINDEX are modified 1437 * upon return. SCBPTR may be modified by this action. 1438 */ 1439index_busy_target: 1440 if ((ahc->features & AHC_SCB_BTT) != 0) { 1441 mov SCBPTR, SAVED_LUN; 1442 add SINDEX, SCB_64_BTT; 1443 } else { 1444 shr SINDEX, 4; 1445 add SINDEX, BUSY_TARGETS; 1446 } 1447 mov DINDEX, SINDEX ret; 1448 1449/* 1450 * Identify message? For a reconnecting target, this tells us the lun 1451 * that the reconnection is for - find the correct SCB and switch to it, 1452 * clearing the "disconnected" bit so we don't "find" it by accident later. 1453 */ 1454mesgin_identify: 1455 and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; 1456 /* 1457 * Determine whether a target is using tagged or non-tagged 1458 * transactions by first looking at the transaction stored in 1459 * the busy target array. If there is no untagged transaction 1460 * for this target or the transaction is for a different lun, then 1461 * this must be an untagged transaction. 1462 */ 1463 mov SAVED_SCSIID call index_busy_target; 1464 mov A, SINDIR; 1465 cmp A, SCB_LIST_NULL je snoop_tag; 1466 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1467 mov A call findSCB; 1468 } else { 1469 mov SCBPTR, A; 1470 } 1471 if ((ahc->features & AHC_SCB_BTT) != 0) { 1472 jmp setup_SCB_id_lun_okay; 1473 } else { 1474 mov A, SCB_LUN; 1475 cmp SAVED_LUN, A je setup_SCB_id_lun_okay; 1476 } 1477 1478/* 1479 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 1480 * If we get one, we use the tag returned to find the proper 1481 * SCB. With SCB paging, we must search for non-tagged 1482 * transactions since the SCB may exist in any slot. If we're not 1483 * using SCB paging, we can use the tag as the direct index to the 1484 * SCB. 1485 */ 1486snoop_tag: 1487 mov NONE,SCSIDATL; /* ACK Identify MSG */ 1488snoop_tag_loop: 1489 call phase_lock; 1490 cmp LASTPHASE, P_MESGIN jne not_found; 1491 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 1492get_tag: 1493 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1494 mvi ARG_1 call inb_next; /* tag value */ 1495 mov ARG_1 call findSCB; 1496 } else { 1497 mvi SCBPTR call inb_next; /* tag value */ 1498 } 1499 1500/* 1501 * Ensure that the SCB the tag points to is for 1502 * an SCB transaction to the reconnecting target. 1503 */ 1504setup_SCB: 1505 mov A, SAVED_SCSIID; 1506 cmp SCB_SCSIID, A jne not_found; 1507 mov A, SAVED_LUN; 1508 cmp SCB_LUN, A jne not_found; 1509setup_SCB_id_lun_okay: 1510 test SCB_CONTROL,DISCONNECTED jz not_found; 1511 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1512 mov SCBPTR call rem_scb_from_disc_list; 1513 } 1514 and SCB_CONTROL,~DISCONNECTED; 1515 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 1516 test SCB_CONTROL, TAG_ENB jnz setup_SCB_tagged; 1517 mov A, SCBPTR; 1518 mov SAVED_SCSIID call index_busy_target; 1519 mvi DINDIR, SCB_LIST_NULL; 1520 mov SCBPTR, A; 1521setup_SCB_tagged: 1522 call set_transfer_settings; 1523 /* See if the host wants to send a message upon reconnection */ 1524 test SCB_CONTROL, MK_MESSAGE jz mesgin_done; 1525 and SCB_CONTROL, ~MK_MESSAGE; 1526 mvi HOST_MSG call mk_mesg; 1527 jmp mesgin_done; 1528 1529not_found: 1530 mvi INTSTAT, NO_MATCH; 1531 jmp mesgin_done; 1532 1533mk_mesg: 1534 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 1535 mov MSG_OUT,SINDEX ret; 1536 1537/* 1538 * Functions to read data in Automatic PIO mode. 1539 * 1540 * According to Adaptec's documentation, an ACK is not sent on input from 1541 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 1542 * latched (the usual way), then read the data byte directly off the bus 1543 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 1544 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 1545 * spec guarantees that the target will hold the data byte on the bus until 1546 * we send our ACK. 1547 * 1548 * The assumption here is that these are called in a particular sequence, 1549 * and that REQ is already set when inb_first is called. inb_{first,next} 1550 * use the same calling convention as inb. 1551 */ 1552inb_next_wait_perr: 1553 mvi INTSTAT, PERR_DETECTED; 1554 jmp inb_next_wait; 1555inb_next: 1556 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1557inb_next_wait: 1558 /* 1559 * If there is a parity error, wait for the kernel to 1560 * see the interrupt and prepare our message response 1561 * before continuing. 1562 */ 1563 test SSTAT1, REQINIT jz inb_next_wait; 1564 test SSTAT1, SCSIPERR jnz inb_next_wait_perr; 1565inb_next_check_phase: 1566 and LASTPHASE, PHASE_MASK, SCSISIGI; 1567 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 1568inb_first: 1569 mov DINDEX,SINDEX; 1570 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 1571inb_last: 1572 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 1573} 1574 1575if ((ahc->flags & AHC_TARGETMODE) != 0) { 1576/* 1577 * Change to a new phase. If we are changing the state of the I/O signal, 1578 * from out to in, wait an additional data release delay before continuing. 1579 */ 1580change_phase: 1581 /* Wait for preceeding I/O session to complete. */ 1582 test SCSISIGI, ACKI jnz .; 1583 1584 /* Change the phase */ 1585 and DINDEX, IOI, SCSISIGI; 1586 mov SCSISIGO, SINDEX; 1587 and A, IOI, SINDEX; 1588 1589 /* 1590 * If the data direction has changed, from 1591 * out (initiator driving) to in (target driving), 1592 * we must wait at least a data release delay plus 1593 * the normal bus settle delay. [SCSI III SPI 10.11.0] 1594 */ 1595 cmp DINDEX, A je change_phase_wait; 1596 test SINDEX, IOI jz change_phase_wait; 1597 call change_phase_wait; 1598change_phase_wait: 1599 nop; 1600 nop; 1601 nop; 1602 nop ret; 1603 1604/* 1605 * Send a byte to an initiator in Automatic PIO mode. 1606 */ 1607target_outb: 1608 or SXFRCTL0, SPIOEN; 1609 test SSTAT0, SPIORDY jz .; 1610 mov SCSIDATL, SINDEX; 1611 test SSTAT0, SPIORDY jz .; 1612 and SXFRCTL0, ~SPIOEN ret; 1613} 1614 1615 1616/* 1617 * Assert that if we've been reselected, then we've seen an IDENTIFY 1618 * message. 1619 */ 1620assert: 1621 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 1622 1623 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 1624 1625/* 1626 * Locate a disconnected SCB by SCBID. Upon return, SCBPTR and SINDEX will 1627 * be set to the position of the SCB. If the SCB cannot be found locally, 1628 * it will be paged in from host memory. RETURN_2 stores the address of the 1629 * preceding SCB in the disconnected list which can be used to speed up 1630 * removal of the found SCB from the disconnected list. 1631 */ 1632findSCB: 1633 mov SCBPTR, DISCONNECTED_SCBH; /* Initialize SCBPTR */ 1634 mov A, SINDEX; /* Tag passed in SINDEX */ 1635 mvi RETURN_2, SCB_LIST_NULL; /* Head of list */ 1636 jmp findSCB_loop; 1637findSCB_next: 1638 mov RETURN_2, SCBPTR; 1639 cmp SCB_NEXT, SCB_LIST_NULL je findSCB_notFound; 1640 mov SCBPTR,SCB_NEXT; 1641findSCB_loop: 1642 cmp SCB_TAG, A jne findSCB_next; 1643 mov SINDEX, SCBPTR ret; 1644findSCB_notFound: 1645 /* 1646 * We didn't find it. Page in the SCB and make it look 1647 * like it was at the head of the appropriate scb list. 1648 */ 1649 mov ARG_1, A; /* Save tag */ 1650 mov ALLZEROS call get_free_or_disc_scb; 1651 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 1652 mov ARG_1 call dma_scb; 1653 mvi RETURN_2, SCB_LIST_NULL; /* Head of list */ 1654 /* Jump instead of call as we want to return anyway */ 1655 test SCB_CONTROL, DISCONNECTED jnz add_scb_to_disc_list; 1656 jmp add_scb_to_free_list; 1657 1658/* 1659 * This routine expects SINDEX to contain the index of the SCB to be 1660 * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the 1661 * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL 1662 * if it is at the head. 1663 */ 1664rem_scb_from_disc_list: 1665/* Remove this SCB from the disconnection list */ 1666 cmp ARG_2, SCB_LIST_NULL je rHead; 1667 mov DINDEX, SCB_NEXT; 1668 mov SCBPTR, ARG_2; 1669 mov SCB_NEXT, DINDEX; 1670 mov SCBPTR, SINDEX ret; 1671rHead: 1672 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1673 1674/* 1675 * Fetch a byte from host memory given an index of (A + (256 * SINDEX)) 1676 * and a base address of SHARED_DATA_ADDR. The byte is returned in RETURN_2. 1677 */ 1678fetch_byte: 1679 mov ARG_2, SINDEX; 1680 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1681 mvi DINDEX, CCHADDR; 1682 mvi SHARED_DATA_ADDR call set_1byte_addr; 1683 mvi CCHCNT, 1; 1684 mvi CCSGCTL, CCSGEN|CCSGRESET; 1685 test CCSGCTL, CCSGDONE jz .; 1686 mvi CCSGCTL, CCSGRESET; 1687 bmov RETURN_2, CCSGRAM, 1 ret; 1688 } else { 1689 mvi DINDEX, HADDR; 1690 mvi SHARED_DATA_ADDR call set_1byte_addr; 1691 mvi 1 call set_hcnt; 1692 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 1693 call dma_finish; 1694 mov RETURN_2, DFDAT ret; 1695 } 1696 1697/* 1698 * Prepare the hardware to post a byte to host memory given an 1699 * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR. 1700 */ 1701post_byte_setup: 1702 mov ARG_2, SINDEX; 1703 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1704 mvi DINDEX, CCHADDR; 1705 mvi SHARED_DATA_ADDR call set_1byte_addr; 1706 mvi CCHCNT, 1; 1707 mvi CCSCBCTL, CCSCBRESET ret; 1708 } else { 1709 mvi DINDEX, HADDR; 1710 mvi SHARED_DATA_ADDR call set_1byte_addr; 1711 mvi 1 call set_hcnt; 1712 mvi DFCNTRL, FIFORESET ret; 1713 } 1714 1715post_byte: 1716 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1717 bmov CCSCBRAM, SINDEX, 1; 1718 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1719 test CCSCBCTL, CCSCBDONE jz .; 1720 clr CCSCBCTL ret; 1721 } else { 1722 mov DFDAT, SINDEX; 1723 or DFCNTRL, HDMAEN|FIFOFLUSH; 1724 jmp dma_finish; 1725 } 1726 1727get_SCBID_from_host: 1728 mov A, SAVED_LUN; 1729 shr SINDEX, 4, SAVED_SCSIID; 1730 call fetch_byte; 1731 mov RETURN_1, RETURN_2 ret; 1732 1733phase_lock_perr: 1734 mvi INTSTAT, PERR_DETECTED; 1735phase_lock: 1736 /* 1737 * If there is a parity error, wait for the kernel to 1738 * see the interrupt and prepare our message response 1739 * before continuing. 1740 */ 1741 test SSTAT1, REQINIT jz phase_lock; 1742 test SSTAT1, SCSIPERR jnz phase_lock_perr; 1743phase_lock_latch_phase: 1744 and SCSISIGO, PHASE_MASK, SCSISIGI; 1745 and LASTPHASE, PHASE_MASK, SCSISIGI ret; 1746 1747if ((ahc->features & AHC_CMD_CHAN) == 0) { 1748set_hcnt: 1749 mov HCNT[0], SINDEX; 1750clear_hcnt: 1751 clr HCNT[1]; 1752 clr HCNT[2] ret; 1753 1754set_stcnt_from_hcnt: 1755 mov STCNT[0], HCNT[0]; 1756 mov STCNT[1], HCNT[1]; 1757 mov STCNT[2], HCNT[2] ret; 1758 1759bcopy_8: 1760 mov DINDIR, SINDIR; 1761bcopy_7: 1762 mov DINDIR, SINDIR; 1763 mov DINDIR, SINDIR; 1764bcopy_5: 1765 mov DINDIR, SINDIR; 1766bcopy_4: 1767 mov DINDIR, SINDIR; 1768bcopy_3: 1769 mov DINDIR, SINDIR; 1770 mov DINDIR, SINDIR; 1771 mov DINDIR, SINDIR ret; 1772} 1773 1774if ((ahc->flags & AHC_TARGETMODE) != 0) { 1775/* 1776 * Setup addr assuming that A is an index into 1777 * an array of 32byte objects, SINDEX contains 1778 * the base address of that array, and DINDEX 1779 * contains the base address of the location 1780 * to store the indexed address. 1781 */ 1782set_32byte_addr: 1783 shr ARG_2, 3, A; 1784 shl A, 5; 1785 jmp set_1byte_addr; 1786} 1787 1788/* 1789 * Setup addr assuming that A is an index into 1790 * an array of 64byte objects, SINDEX contains 1791 * the base address of that array, and DINDEX 1792 * contains the base address of the location 1793 * to store the indexed address. 1794 */ 1795set_64byte_addr: 1796 shr ARG_2, 2, A; 1797 shl A, 6; 1798 1799/* 1800 * Setup addr assuming that A + (ARG_2 * 256) is an 1801 * index into an array of 1byte objects, SINDEX contains 1802 * the base address of that array, and DINDEX contains 1803 * the base address of the location to store the computed 1804 * address. 1805 */ 1806set_1byte_addr: 1807 add DINDIR, A, SINDIR; 1808 mov A, ARG_2; 1809 adc DINDIR, A, SINDIR; 1810 clr A; 1811 adc DINDIR, A, SINDIR; 1812 adc DINDIR, A, SINDIR ret; 1813 1814/* 1815 * Either post or fetch and SCB from host memory based on the 1816 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. 1817 */ 1818dma_scb: 1819 mov A, SINDEX; 1820 if ((ahc->features & AHC_CMD_CHAN) != 0) { 1821 mvi DINDEX, CCHADDR; 1822 mvi HSCB_ADDR call set_64byte_addr; 1823 mov CCSCBPTR, SCBPTR; 1824 test DMAPARAMS, DIRECTION jz dma_scb_tohost; 1825 mvi CCHCNT, SCB_64BYTE_SIZE; 1826 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET; 1827 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .; 1828 jmp dma_scb_finish; 1829dma_scb_tohost: 1830 mvi CCHCNT, SCB_32BYTE_SIZE; 1831 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 1832 mvi CCSCBCTL, CCSCBRESET; 1833 bmov CCSCBRAM, SCB_CONTROL, SCB_32BYTE_SIZE; 1834 or CCSCBCTL, CCSCBEN|CCSCBRESET; 1835 test CCSCBCTL, CCSCBDONE jz .; 1836 } else { 1837 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET; 1838 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .; 1839 } 1840dma_scb_finish: 1841 clr CCSCBCTL; 1842 test CCSCBCTL, CCARREN|CCSCBEN jnz .; 1843 ret; 1844 } else { 1845 mvi DINDEX, HADDR; 1846 mvi HSCB_ADDR call set_64byte_addr; 1847 mvi SCB_32BYTE_SIZE call set_hcnt; 1848 mov DFCNTRL, DMAPARAMS; 1849 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1850 /* Fill it with the SCB data */ 1851copy_scb_tofifo: 1852 mvi SINDEX, SCB_CONTROL; 1853 add A, SCB_32BYTE_SIZE, SINDEX; 1854copy_scb_tofifo_loop: 1855 call copy_to_fifo_6; 1856 cmp SINDEX, A jne copy_scb_tofifo_loop; 1857 or DFCNTRL, HDMAEN|FIFOFLUSH; 1858dma_scb_fromhost: 1859 call dma_finish; 1860 /* If we were putting the SCB, we are done */ 1861 test DMAPARAMS, DIRECTION jz return; 1862 mvi SCB_CONTROL call dfdat_in_7; 1863 call dfdat_in_7_continued; 1864 call dfdat_in_7_continued; 1865 call dfdat_in_7_continued; 1866 jmp dfdat_in_2_continued; 1867dfdat_in_7: 1868 mov DINDEX,SINDEX; 1869dfdat_in_7_continued: 1870 mov DINDIR,DFDAT; 1871 mov DINDIR,DFDAT; 1872 mov DINDIR,DFDAT; 1873 mov DINDIR,DFDAT; 1874 mov DINDIR,DFDAT; 1875dfdat_in_2_continued: 1876 mov DINDIR,DFDAT; 1877 mov DINDIR,DFDAT ret; 1878 } 1879 1880copy_to_fifo_6: 1881 mov DFDAT,SINDIR; 1882copy_to_fifo_5: 1883 mov DFDAT,SINDIR; 1884copy_to_fifo_4: 1885 mov DFDAT,SINDIR; 1886 mov DFDAT,SINDIR; 1887 mov DFDAT,SINDIR; 1888 mov DFDAT,SINDIR ret; 1889 1890/* 1891 * Wait for DMA from host memory to data FIFO to complete, then disable 1892 * DMA and wait for it to acknowledge that it's off. 1893 */ 1894dma_finish: 1895 test DFSTATUS,HDONE jz dma_finish; 1896 /* Turn off DMA */ 1897 and DFCNTRL, ~HDMAEN; 1898 test DFCNTRL, HDMAEN jnz .; 1899 ret; 1900 1901add_scb_to_free_list: 1902 if ((ahc->flags & AHC_PAGESCBS) != 0) { 1903 mov SCB_NEXT, FREE_SCBH; 1904 mvi SCB_TAG, SCB_LIST_NULL; 1905 mov FREE_SCBH, SCBPTR ret; 1906 } else { 1907 mvi SCB_TAG, SCB_LIST_NULL ret; 1908 } 1909 1910if ((ahc->flags & AHC_PAGESCBS) != 0) { 1911get_free_or_disc_scb: 1912 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1913 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1914return_error: 1915 mvi SINDEX, SCB_LIST_NULL ret; 1916dequeue_disc_scb: 1917 mov SCBPTR, DISCONNECTED_SCBH; 1918dma_up_scb: 1919 mvi DMAPARAMS, FIFORESET; 1920 mov SCB_TAG call dma_scb; 1921unlink_disc_scb: 1922 mov DISCONNECTED_SCBH, SCB_NEXT ret; 1923dequeue_free_scb: 1924 mov SCBPTR, FREE_SCBH; 1925 mov FREE_SCBH, SCB_NEXT ret; 1926} 1927 1928add_scb_to_disc_list: 1929/* 1930 * Link this SCB into the DISCONNECTED list. This list holds the 1931 * candidates for paging out an SCB if one is needed for a new command. 1932 * Modifying the disconnected list is a critical(pause dissabled) section. 1933 */ 1934 mov SCB_NEXT, DISCONNECTED_SCBH; 1935 mov DISCONNECTED_SCBH, SCBPTR ret; 1936return: 1937 ret; 1938