1/* 2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD. 3 * 4 * Copyright (c) 1994-1997 Justin Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * Where this Software is combined with software released under the terms of 20 * the GNU Public License ("GPL") and the terms of the GPL would require the 21 * combined work to also be released under the terms of the GPL, the terms 22 * and conditions of this License will apply in addition to those of the 23 * GPL with the exception of any terms or conditions of this License that 24 * conflict with, or are expressly prohibited by, the GPL. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $Id: aic7xxx.seq,v 1.75 1997/08/13 17:02:28 gibbs Exp $ 39 */ 40 41#include <dev/aic7xxx/aic7xxx.reg> 42#include <scsi/scsi_message.h> 43 44/* 45 * A few words on the waiting SCB list: 46 * After starting the selection hardware, we check for reconnecting targets 47 * as well as for our selection to complete just in case the reselection wins 48 * bus arbitration. The problem with this is that we must keep track of the 49 * SCB that we've already pulled from the QINFIFO and started the selection 50 * on just in case the reselection wins so that we can retry the selection at 51 * a later time. This problem cannot be resolved by holding a single entry 52 * in scratch ram since a reconnecting target can request sense and this will 53 * create yet another SCB waiting for selection. The solution used here is to 54 * use byte 27 of the SCB as a psuedo-next pointer and to thread a list 55 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, 56 * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to 57 * this list everytime a request sense occurs or after completing a non-tagged 58 * command for which a second SCB has been queued. The sequencer will 59 * automatically consume the entries. 60 */ 61 62/* 63 * We assume that the kernel driver may reset us at any time, even in the 64 * middle of a DMA, so clear DFCNTRL too. 65 */ 66reset: 67 clr SCSISIGO; /* De-assert BSY */ 68 /* Always allow reselection */ 69 mvi SCSISEQ, ENRSELI|ENAUTOATNP; 70 call clear_target_state; 71poll_for_work: 72 test SSTAT0,SELDO jnz select; 73 test SSTAT0,SELDI jnz reselect; 74 test SCSISEQ, ENSELO jnz poll_for_work; 75.if ( TWIN_CHANNEL ) 76 /* 77 * Twin channel devices cannot handle things like SELTO 78 * interrupts on the "background" channel. So, if we 79 * are selecting, keep polling the current channel util 80 * either a selection or reselection occurs. 81 */ 82 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ 83 test SSTAT0,SELDO jnz select; 84 test SSTAT0,SELDI jnz reselect; 85 test SCSISEQ, ENSELO jnz poll_for_work; 86 xor SBLKCTL,SELBUSB; /* Toggle back */ 87.endif 88 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; 89test_queue: 90 /* Has the driver posted any work for us? */ 91 test QINCNT,QCNTMASK jz poll_for_work; 92 93/* 94 * We have at least one queued SCB now and we don't have any 95 * SCBs in the list of SCBs awaiting selection. If we have 96 * any SCBs available for use, pull the tag from the QINFIFO 97 * and get to work on it. 98 */ 99.if ( SCB_PAGING ) 100 mov ALLZEROS call get_free_or_disc_scb; 101 cmp SINDEX, SCB_LIST_NULL je poll_for_work; 102.endif 103dequeue_scb: 104 mov CUR_SCBID,QINFIFO; 105.if !( SCB_PAGING ) 106 /* In the non-paging case, the SCBID == hardware SCB index */ 107 mov SCBPTR, CUR_SCBID; 108.endif 109dma_queued_scb: 110/* 111 * DMA the SCB from host ram into the current SCB location. 112 */ 113 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 114 mov CUR_SCBID call dma_scb; 115 116/* 117 * See if there is not already an active SCB for this target. This code 118 * locks out on a per target basis instead of target/lun. Although this 119 * is not ideal for devices that have multiple luns active at the same 120 * time, it is faster than looping through all SCB's looking for active 121 * commands. We also don't have enough spare SCB space for us to store the 122 * SCBID of the currently busy transaction for each target/lun making it 123 * impossible to link up the SCBs. 124 */ 125test_busy: 126 test SCB_CONTROL, TAG_ENB|ABORT_SCB jnz start_scb; 127 mvi SEQCTL, PAUSEDIS|FASTMODE; 128 mov SAVED_SCBPTR, SCBPTR; 129 mov SCB_TCL call index_untagged_scb; 130 mov ARG_1, SINDIR; /* 131 * ARG_1 should 132 * now have the SCB ID of 133 * any active, non-tagged, 134 * command for this target. 135 */ 136 cmp ARG_1, SCB_LIST_NULL je make_busy; 137.if ( SCB_PAGING ) 138 /* 139 * Put this SCB back onto the free list. It 140 * may be necessary to satisfy the search for 141 * the active SCB. 142 */ 143 mov SCBPTR, SAVED_SCBPTR; 144 call add_scb_to_free_list; 145 /* Find the active SCB */ 146 mov ALLZEROS call findSCB; 147 /* 148 * If we couldn't find it, tell the kernel. This should 149 * never happen. 150 */ 151 cmp SINDEX, SCB_LIST_NULL jne paged_busy_link; 152 mvi INTSTAT, NO_MATCH_BUSY; 153paged_busy_link: 154 /* Link us in */ 155 mov SCB_LINKED_NEXT, CUR_SCBID; 156 /* Put it back on the disconnected list */ 157 call add_scb_to_disc_list; 158 mvi SEQCTL, FASTMODE; 159 jmp poll_for_work; 160.else 161simple_busy_link: 162 mov SCBPTR, ARG_1; 163 mov SCB_LINKED_NEXT, CUR_SCBID; 164 mvi SEQCTL, FASTMODE; 165 jmp poll_for_work; 166.endif 167make_busy: 168 mov DINDIR, CUR_SCBID; 169 mov SCBPTR, SAVED_SCBPTR; 170 mvi SEQCTL, FASTMODE; 171 172start_scb: 173 /* 174 * Place us on the waiting list in case our selection 175 * doesn't win during bus arbitration. 176 */ 177 mov SCB_NEXT,WAITING_SCBH; 178 mov WAITING_SCBH, SCBPTR; 179start_waiting: 180 /* 181 * Pull the first entry off of the waiting SCB list 182 * We don't have to "test_busy" because only transactions that 183 * have passed that test can be in the WAITING_SCB list. 184 */ 185 mov SCBPTR, WAITING_SCBH; 186 call start_selection; 187 jmp poll_for_work; 188 189start_selection: 190.if ( TWIN_CHANNEL ) 191 and SINDEX,~SELBUSB,SBLKCTL;/* Clear the channel select bit */ 192 and A,SELBUSB,SCB_TCL; /* Get new channel bit */ 193 or SINDEX,A; 194 mov SBLKCTL,SINDEX; /* select channel */ 195.endif 196initialize_scsiid: 197 and A, TID, SCB_TCL; /* Get target ID */ 198 and SCSIID, OID; /* Clear old target */ 199 or SCSIID, A; 200 mvi SCSISEQ, ENSELO|ENAUTOATNO|ENRSELI|ENAUTOATNP ret; 201/* 202 * Reselection has been initiated by a target. Make a note that we've been 203 * reselected, but haven't seen an IDENTIFY message from the target yet. 204 */ 205reselect: 206 clr MSG_LEN; /* Don't have anything in the mesg buffer */ 207 mvi CLRSINT0, CLRSELDI; 208 /* XXX test for and handle ONE BIT condition */ 209 and SAVED_TCL, SELID_MASK, SELID; 210 or SEQ_FLAGS,RESELECTED; 211 jmp select2; 212 213/* 214 * After the selection, remove this SCB from the "waiting SCB" 215 * list. This is achieved by simply moving our "next" pointer into 216 * WAITING_SCBH. Our next pointer will be set to null the next time this 217 * SCB is used, so don't bother with it now. 218 */ 219select: 220 /* Turn off the selection hardware */ 221 mvi SCSISEQ, ENRSELI|ENAUTOATNP; /* 222 * ATN on parity errors 223 * for "in" phases 224 */ 225 mvi CLRSINT0, CLRSELDO; 226 mov SCBPTR, WAITING_SCBH; 227 mov WAITING_SCBH,SCB_NEXT; 228 mov SAVED_TCL, SCB_TCL; 229/* 230 * As soon as we get a successful selection, the target should go 231 * into the message out phase since we have ATN asserted. Prepare 232 * the message to send. 233 * 234 * Messages are stored in scratch RAM starting with a length byte 235 * followed by the message itself. 236 */ 237 238mk_identify: 239 and MSG_OUT,0x7,SCB_TCL; /* lun */ 240 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ 241 or MSG_OUT,A; /* or in disconnect privledge */ 242 or MSG_OUT,MSG_IDENTIFYFLAG; 243 mvi MSG_LEN, 1; 244 245/* 246 * Send a tag message if TAG_ENB is set in the SCB control block. 247 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 248 */ 249mk_tag: 250 test SCB_CONTROL,TAG_ENB jz mk_message; 251 and MSG_OUT[1],TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 252 mov MSG_OUT[2],SCB_TAG; 253 add MSG_LEN,2; /* update message length */ 254 255/* 256 * Interrupt the driver, and allow it to tweak the message buffer 257 * if it asks. 258 */ 259mk_message: 260 test SCB_CONTROL,MK_MESSAGE jz select2; 261 mvi INTSTAT,AWAITING_MSG; 262 263select2: 264 mvi CLRSINT1,CLRBUSFREE; 265 or SIMODE1, ENBUSFREE; /* 266 * We aren't expecting a 267 * bus free, so interrupt 268 * the kernel driver if it 269 * happens. 270 */ 271/* 272 * Initialize Ultra mode setting and clear the SCSI channel. 273 */ 274 or SXFRCTL0, CLRSTCNT|SPIOEN|CLRCHN; 275.if ( ULTRA ) 276ultra: 277 mvi SINDEX, ULTRA_ENB+1; 278 test SAVED_TCL, 0x80 jnz ultra_2; /* Target ID > 7 */ 279 dec SINDEX; 280ultra_2: 281 mov FUNCTION1,SAVED_TCL; 282 mov A,FUNCTION1; 283 test SINDIR, A jz ndx_dtr; 284 or SXFRCTL0, FAST20; 285.endif 286 287/* 288 * Initialize SCSIRATE with the appropriate value for this target. 289 * The SCSIRATE settings for each target are stored in an array 290 * based at TARG_SCRATCH. 291 */ 292ndx_dtr: 293 shr A,4,SAVED_TCL; 294 test SBLKCTL,SELBUSB jz ndx_dtr_2; 295 or SAVED_TCL, SELBUSB; /* Add the channel bit while we're here */ 296 or A,0x08; /* Channel B entries add 8 */ 297ndx_dtr_2: 298 add SINDEX,TARG_SCRATCH,A; 299 mov SCSIRATE,SINDIR; 300 301 302/* 303 * Main loop for information transfer phases. If BSY is false, then 304 * we have a bus free condition, expected or not. Otherwise, wait 305 * for the target to assert REQ before checking MSG, C/D and I/O 306 * for the bus phase. 307 * 308 */ 309ITloop: 310 test SSTAT1,REQINIT jz ITloop; 311 test SSTAT1, SCSIPERR jnz ITloop; 312 313 and A,PHASE_MASK,SCSISIGI; 314 mov LASTPHASE,A; 315 mov SCSISIGO,A; 316 317 cmp ALLZEROS,A je p_dataout; 318 cmp A,P_DATAIN je p_datain; 319 cmp A,P_COMMAND je p_command; 320 cmp A,P_MESGOUT je p_mesgout; 321 cmp A,P_STATUS je p_status; 322 cmp A,P_MESGIN je p_mesgin; 323 324 mvi INTSTAT,BAD_PHASE; /* unknown phase - signal driver */ 325 jmp ITloop; /* Try reading the bus again. */ 326 327await_busfree: 328 and SIMODE1, ~ENBUSFREE; 329 call clear_target_state; 330 mov NONE, SCSIDATL; /* Ack the last byte */ 331 test SSTAT1,REQINIT|BUSFREE jz .; 332 test SSTAT1, BUSFREE jnz poll_for_work; 333 mvi INTSTAT, BAD_PHASE; 334 335clear_target_state: 336 clr DFCNTRL; 337 clr SCSIRATE; /* 338 * We don't know the target we will 339 * connect to, so default to narrow 340 * transfers to avoid parity problems. 341 */ 342 and SXFRCTL0, ~FAST20; 343 mvi LASTPHASE, P_BUSFREE; 344 /* clear target specific flags */ 345 and SEQ_FLAGS,~(RESELECTED|IDENTIFY_SEEN|TAGGED_SCB|DPHASE) ret; 346 347p_dataout: 348 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET; 349 jmp data_phase_init; 350 351/* 352 * If we re-enter the data phase after going through another phase, the 353 * STCNT may have been cleared, so restore it from the residual field. 354 */ 355data_phase_reinit: 356 mvi DINDEX, STCNT; 357 mvi SCB_RESID_DCNT call bcopy_3; 358 jmp data_phase_loop; 359 360p_datain: 361 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 362data_phase_init: 363 call assert; /* 364 * Ensure entering a data 365 * phase is okay - seen identify, etc. 366 */ 367 368 test SEQ_FLAGS, DPHASE jnz data_phase_reinit; 369 370 /* 371 * Initialize the DMA address and counter from the SCB. 372 * Also set SG_COUNT and SG_NEXT in memory since we cannot 373 * modify the values in the SCB itself until we see a 374 * save data pointers message. 375 */ 376 mvi DINDEX, HADDR; 377 mvi SCB_DATAPTR call bcopy_7; 378 379 call set_stcnt_from_hcnt; 380 381 mov SG_COUNT,SCB_SGCOUNT; 382 383 mvi DINDEX, SG_NEXT; 384 mvi SCB_SGPTR call bcopy_4; 385 386data_phase_loop: 387/* Guard against overruns */ 388 test SG_COUNT, 0xff jnz data_phase_inbounds; 389/* 390 * Turn on 'Bit Bucket' mode, set the transfer count to 391 * 16meg and let the target run until it changes phase. 392 * When the transfer completes, notify the host that we 393 * had an overrun. 394 */ 395 or SXFRCTL1,BITBUCKET; 396 mvi HCNT[0], 0xff; 397 mvi HCNT[1], 0xff; 398 mvi HCNT[2], 0xff; 399 call set_stcnt_from_hcnt; 400 401data_phase_inbounds: 402/* If we are the last SG block, ensure wideodd is off. */ 403 cmp SG_COUNT,0x01 jne data_phase_wideodd; 404 and DMAPARAMS, ~WIDEODD; 405data_phase_wideodd: 406 mov DMAPARAMS call dma; 407 408/* Go tell the host about any overruns */ 409 test SXFRCTL1,BITBUCKET jnz data_phase_overrun; 410 411/* Exit if we had an underrun. dma clears SINDEX in this case. */ 412 test SINDEX,0xff jz data_phase_finish; 413 414/* 415 * Advance the scatter-gather pointers if needed 416 */ 417sg_advance: 418 dec SG_COUNT; /* one less segment to go */ 419 420 test SG_COUNT, 0xff jz data_phase_finish; /* Are we done? */ 421 422 clr A; /* add sizeof(struct scatter) */ 423 add SG_NEXT[0],SG_SIZEOF; 424 adc SG_NEXT[1],A; 425 426/* 427 * Load a struct scatter and set up the data address and length. 428 * If the working value of the SG count is nonzero, then 429 * we need to load a new set of values. 430 * 431 * This, like all DMA's, assumes little-endian host data storage. 432 */ 433sg_load: 434 mvi DINDEX, HADDR; 435 mvi SG_NEXT call bcopy_4; 436 437 mvi HCNT[0],SG_SIZEOF; 438 clr HCNT[1]; 439 clr HCNT[2]; 440 441 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 442 443 call dma_finish; 444 445/* 446 * Copy data from FIFO into SCB data pointer and data count. This assumes 447 * that the SG segments are of the form: 448 * 449 * struct ahc_dma_seg { 450 * u_int32_t addr; four bytes, little-endian order 451 * u_int32_t len; four bytes, little endian order 452 * }; 453 */ 454 mvi HADDR call dfdat_in_7; 455 456/* Load STCNT as well. It is a mirror of HCNT */ 457 call set_stcnt_from_hcnt; 458 test SSTAT1,PHASEMIS jz data_phase_loop; 459 460data_phase_finish: 461/* 462 * After a DMA finishes, save the SG and STCNT residuals back into the SCB 463 * We use STCNT instead of HCNT, since it's a reflection of how many bytes 464 * were transferred on the SCSI (as opposed to the host) bus. 465 */ 466 mov SCB_RESID_DCNT[0],STCNT[0]; 467 mov SCB_RESID_DCNT[1],STCNT[1]; 468 mov SCB_RESID_DCNT[2],STCNT[2]; 469 mov SCB_RESID_SGCNT, SG_COUNT; 470 471 /* We have seen a data phase */ 472 or SEQ_FLAGS, DPHASE; 473 474 jmp ITloop; 475 476data_phase_overrun: 477/* 478 * Turn off BITBUCKET mode and notify the host 479 */ 480 and SXFRCTL1, ~BITBUCKET; 481 mvi INTSTAT,DATA_OVERRUN; 482 jmp ITloop; 483 484/* 485 * Command phase. Set up the DMA registers and let 'er rip. 486 */ 487p_command: 488 call assert; 489 490/* 491 * Load HADDR and HCNT. 492 */ 493 mvi DINDEX, HADDR; 494 mvi SCB_CMDPTR call bcopy_5; 495 clr HCNT[1]; 496 clr HCNT[2]; 497 498 call set_stcnt_from_hcnt; 499 500 mvi (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET) call dma; 501 jmp ITloop; 502 503/* 504 * Status phase. Wait for the data byte to appear, then read it 505 * and store it into the SCB. 506 */ 507p_status: 508 call assert; 509 510 mov SCB_TARGET_STATUS, SCSIDATL; 511 jmp ITloop; 512 513/* 514 * Message out phase. If there is not an active message, but the target 515 * took us into this phase anyway, build a no-op message and send it. 516 */ 517p_mesgout: 518 test MSG_LEN, 0xff jnz p_mesgout_start; 519 mvi MSG_NOOP call mk_mesg; /* build NOP message */ 520p_mesgout_start: 521/* 522 * Set up automatic PIO transfer from MSG_OUT. Bit 3 in 523 * SXFRCTL0 (SPIOEN) is already on. 524 */ 525 mvi SINDEX,MSG_OUT; 526 mov DINDEX,MSG_LEN; 527 528/* 529 * When target asks for a byte, drop ATN if it's the last one in 530 * the message. Otherwise, keep going until the message is exhausted. 531 * ATN must be dropped *at least* 90ns before we ack the last byte, so 532 * the code is aranged to execute two instructions before the byte is 533 * transferred to give a good margin of safety 534 * 535 * Keep an eye out for a phase change, in case the target issues 536 * a MESSAGE REJECT. 537 */ 538p_mesgout_loop: 539 test SSTAT1, REQINIT jz p_mesgout_loop; 540 test SSTAT1, SCSIPERR jnz p_mesgout_loop; 541 and LASTPHASE, PHASE_MASK, SCSISIGI; 542 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 543p_mesgout_testretry: 544 test DINDEX,0xff jnz p_mesgout_dropatn; 545 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 546 jmp p_mesgout_start; 547/* 548 * If the next bus phase after ATN drops is a message out, it means 549 * that the target is requesting that the last message(s) be resent. 550 */ 551p_mesgout_dropatn: 552 cmp DINDEX,1 jne p_mesgout_outb; /* last byte? */ 553 mvi CLRSINT1,CLRATNO; /* drop ATN */ 554p_mesgout_outb: 555 dec DINDEX; 556 mov SCSIDATL,SINDIR; 557 jmp p_mesgout_loop; 558 559p_mesgout_done: 560 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 561 clr MSG_LEN; /* no active msg */ 562 jmp ITloop; 563 564/* 565 * Message in phase. Bytes are read using Automatic PIO mode. 566 */ 567p_mesgin: 568 mvi ACCUM call inb_first; /* read the 1st message byte */ 569 570 test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 571 cmp A,MSG_DISCONNECT je mesgin_disconnect; 572 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 573 cmp ALLZEROS,A je mesgin_complete; 574 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 575 cmp A,MSG_EXTENDED je mesgin_extended; 576 cmp A,MSG_MESSAGE_REJECT je mesgin_reject; 577 cmp A,MSG_NOOP je mesgin_done; 578 579rej_mesgin: 580/* 581 * We have no idea what this message in is, so we issue a message reject 582 * and hope for the best. In any case, rejection should be a rare 583 * occurrence - signal the driver when it happens. 584 */ 585 mvi INTSTAT,SEND_REJECT; /* let driver know */ 586 587 mvi MSG_MESSAGE_REJECT call mk_mesg; 588 589mesgin_done: 590 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 591 jmp ITloop; 592 593 594mesgin_complete: 595/* 596 * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO, 597 * and trigger a completion interrupt. Before doing so, check to see if there 598 * is a residual or the status byte is something other than NO_ERROR (0). In 599 * either of these conditions, we upload the SCB back to the host so it can 600 * process this information. In the case of a non zero status byte, we 601 * additionally interrupt the kernel driver synchronously, allowing it to 602 * decide if sense should be retrieved. If the kernel driver wishes to request 603 * sense, it will fill the kernel SCB with a request sense command and set 604 * RETURN_1 to SEND_SENSE. If RETURN_1 is set to SEND_SENSE we redownload 605 * the SCB, and process it as the next command by adding it to the waiting list. 606 * If the kernel driver does not wish to request sense, it need only clear 607 * RETURN_1, and the command is allowed to complete normally. We don't bother 608 * to post to the QOUTFIFO in the error cases since it would require extra 609 * work in the kernel driver to ensure that the entry was removed before the 610 * command complete code tried processing it. 611 */ 612 613/* 614 * First check for residuals 615 */ 616 test SCB_RESID_SGCNT,0xff jnz upload_scb; 617 test SCB_TARGET_STATUS,0xff jz status_ok; /* Good Status? */ 618upload_scb: 619 mvi DMAPARAMS, FIFORESET; 620 mov SCB_TAG call dma_scb; 621check_status: 622 test SCB_TARGET_STATUS,0xff jz status_ok; /* Just a residual? */ 623 mvi INTSTAT,BAD_STATUS; /* let driver know */ 624 cmp RETURN_1, SEND_SENSE jne status_ok; 625 /* This SCB becomes the next to execute as it will retrieve sense */ 626 mov SCB_LINKED_NEXT, SCB_TAG; 627 jmp dma_next_scb; 628 629status_ok: 630/* First, mark this target as free. */ 631 test SCB_CONTROL,TAG_ENB jnz complete; /* 632 * Tagged commands 633 * don't busy the 634 * target. 635 */ 636 mov SAVED_SCBPTR, SCBPTR; 637 mov SAVED_LINKPTR, SCB_LINKED_NEXT; 638 mov SCB_TCL call index_untagged_scb; 639 mov DINDIR, SAVED_LINKPTR; 640 mov SCBPTR, SAVED_SCBPTR; 641 642complete: 643 /* Post the SCB and issue an interrupt */ 644.if ( SCB_PAGING ) 645 /* 646 * Spin loop until there is space 647 * in the QOUTFIFO. 648 */ 649 cmp CMDOUTCNT, FIFODEPTH je .; 650 inc CMDOUTCNT; 651.endif 652 mov QOUTFIFO,SCB_TAG; 653 mvi INTSTAT,CMDCMPLT; 654 test SCB_CONTROL, ABORT_SCB jz dma_next_scb; 655 mvi INTSTAT, ABORT_CMDCMPLT; 656 657dma_next_scb: 658 cmp SCB_LINKED_NEXT, SCB_LIST_NULL je add_to_free_list; 659.if !( SCB_PAGING ) 660 /* Only DMA on top of ourselves if we are the SCB to download */ 661 mov A, SCB_LINKED_NEXT; 662 cmp SCB_TAG, A je dma_next_scb2; 663 call add_scb_to_free_list; 664 mov SCBPTR, A; 665 jmp add_to_waiting_list; 666.endif 667dma_next_scb2: 668 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 669 mov SCB_LINKED_NEXT call dma_scb; 670add_to_waiting_list: 671 mov SCB_NEXT,WAITING_SCBH; 672 mov WAITING_SCBH, SCBPTR; 673 /* 674 * Prepare our selection hardware before the busfree so we have a 675 * high probability of winning arbitration. 676 */ 677 call start_selection; 678 jmp await_busfree; 679add_to_free_list: 680 call add_scb_to_free_list; 681 jmp await_busfree; 682 683/* 684 * Is it an extended message? Copy the message to our message buffer and 685 * notify the host. The host will tell us whether to reject this message, 686 * respond to it with the message that the host placed in our message buffer, 687 * or simply to do nothing. 688 */ 689mesgin_extended: 690 mvi MSGIN_EXT_LEN call inb_next; 691 mov A, MSGIN_EXT_LEN; 692mesgin_extended_loop: 693 mov DINDEX call inb_next; 694 dec A; 695 cmp DINDEX, MSGIN_EXT_BYTES+3 jne mesgin_extended_loop_test; 696 dec DINDEX; /* dump by repeatedly filling the last byte */ 697mesgin_extended_loop_test: 698 test A, 0xFF jnz mesgin_extended_loop; 699mesgin_extended_intr: 700 mvi INTSTAT,EXTENDED_MSG; /* let driver know */ 701 cmp RETURN_1,SEND_REJ je rej_mesgin; 702 cmp RETURN_1,SEND_MSG jne mesgin_done; 703/* The kernel has setup a message to be sent */ 704 or SCSISIGO,ATNO,LASTPHASE; /* turn on ATNO */ 705 jmp mesgin_done; 706 707/* 708 * Is it a disconnect message? Set a flag in the SCB to remind us 709 * and await the bus going free. 710 */ 711mesgin_disconnect: 712 or SCB_CONTROL,DISCONNECTED; 713.if ( SCB_PAGING ) 714 call add_scb_to_disc_list; 715.endif 716 jmp await_busfree; 717 718/* 719 * Save data pointers message: 720 * Copying RAM values back to SCB, for Save Data Pointers message, but 721 * only if we've actually been into a data phase to change them. This 722 * protects against bogus data in scratch ram and the residual counts 723 * since they are only initialized when we go into data_in or data_out. 724 */ 725mesgin_sdptrs: 726 test SEQ_FLAGS, DPHASE jz mesgin_done; 727 mov SCB_SGCOUNT,SG_COUNT; 728 729 /* The SCB SGPTR becomes the next one we'll download */ 730 mvi DINDEX, SCB_SGPTR; 731 mvi SG_NEXT call bcopy_4; 732 733 /* The SCB DATAPTR0 becomes the current SHADDR */ 734 mvi DINDEX, SCB_DATAPTR; 735 mvi SHADDR call bcopy_4; 736 737/* 738 * Use the residual number since STCNT is corrupted by any message transfer. 739 */ 740 mvi SCB_RESID_DCNT call bcopy_3; 741 742 jmp mesgin_done; 743 744/* 745 * Restore pointers message? Data pointers are recopied from the 746 * SCB anytime we enter a data phase for the first time, so all 747 * we need to do is clear the DPHASE flag and let the data phase 748 * code do the rest. 749 */ 750mesgin_rdptrs: 751 and SEQ_FLAGS, ~DPHASE; /* 752 * We'll reload them 753 * the next time through 754 * the dataphase. 755 */ 756 jmp mesgin_done; 757 758/* 759 * Identify message? For a reconnecting target, this tells us the lun 760 * that the reconnection is for - find the correct SCB and switch to it, 761 * clearing the "disconnected" bit so we don't "find" it by accident later. 762 */ 763mesgin_identify: 764 test A,0x78 jnz rej_mesgin; /*!DiscPriv|!LUNTAR|!Reserved*/ 765 and A,0x07; /* lun in lower three bits */ 766 or SAVED_TCL,A; /* SAVED_TCL should be complete now */ 767 mov SAVED_TCL call index_untagged_scb; 768 mov ARG_1, SINDIR; 769.if ( SCB_PAGING ) 770 cmp ARG_1,SCB_LIST_NULL jne use_findSCB; 771.else 772 cmp ARG_1,SCB_LIST_NULL je snoop_tag; 773 /* Directly index the SCB */ 774 mov SCBPTR,ARG_1; 775 test SCB_CONTROL,DISCONNECTED jz not_found; 776 jmp setup_SCB; 777.endif 778/* 779 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 780 * If we get one, we use the tag returned to find the proper 781 * SCB. With SCB paging, this requires using findSCB for both tagged 782 * and non-tagged transactions since the SCB may exist in any slot. 783 * If we're not using SCB paging, we can use the tag as the direct 784 * index to the SCB. 785 */ 786snoop_tag: 787 mov NONE,SCSIDATL; /* ACK Identify MSG */ 788snoop_tag_loop: 789 test SSTAT1,REQINIT jz snoop_tag_loop; 790 test SSTAT1, SCSIPERR jnz snoop_tag_loop; 791 and LASTPHASE, PHASE_MASK, SCSISIGI; 792 cmp LASTPHASE, P_MESGIN jne not_found; 793 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 794get_tag: 795 or SEQ_FLAGS, TAGGED_SCB; 796 mvi ARG_1 call inb_next; /* tag value */ 797/* 798 * See if the tag is in range. The tag is < SCBCOUNT if we add 799 * the complement of SCBCOUNT to the incomming tag and there is 800 * no carry. 801 */ 802 add SINDEX,COMP_SCBCOUNT,ARG_1; 803 jc not_found; 804 805.if ! ( SCB_PAGING ) 806index_by_tag: 807 mov SCBPTR,ARG_1; 808 mov A, SAVED_TCL; 809 cmp SCB_TCL,A jne not_found; 810 test SCB_CONTROL,TAG_ENB jz not_found; 811 test SCB_CONTROL,DISCONNECTED jz not_found; 812.else 813/* 814 * Ensure that the SCB the tag points to is for an SCB transaction 815 * to the reconnecting target. 816 */ 817use_findSCB: 818 mov ALLZEROS call findSCB; /* Have to search */ 819 cmp SINDEX, SCB_LIST_NULL je not_found; 820.endif 821setup_SCB: 822 and SCB_CONTROL,~DISCONNECTED; 823 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 824 jmp mesgin_done; 825 826not_found: 827 mvi INTSTAT, NO_MATCH; 828 mvi MSG_BUS_DEV_RESET call mk_mesg; 829 jmp mesgin_done; 830 831/* 832 * Message reject? Let the kernel driver handle this. If we have an 833 * outstanding WDTR or SDTR negotiation, assume that it's a response from 834 * the target selecting 8bit or asynchronous transfer, otherwise just ignore 835 * it since we have no clue what it pertains to. 836 */ 837mesgin_reject: 838 mvi INTSTAT, REJECT_MSG; 839 jmp mesgin_done; 840 841/* 842 * [ ADD MORE MESSAGE HANDLING HERE ] 843 */ 844 845/* 846 * Locking the driver out, build a one-byte message passed in SINDEX 847 * if there is no active message already. SINDEX is returned intact. 848 */ 849mk_mesg: 850 mvi SEQCTL, PAUSEDIS|FASTMODE; 851 test MSG_LEN,0xff jz mk_mesg1; /* Should always succeed */ 852 853 /* 854 * Hmmm. For some reason the mesg buffer is in use. 855 * Tell the driver. It should look at SINDEX to find 856 * out what we wanted to use the buffer for and resolve 857 * the conflict. 858 */ 859 mvi SEQCTL,FASTMODE; 860 mvi INTSTAT,MSG_BUFFER_BUSY; 861 862mk_mesg1: 863 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 864 mvi MSG_LEN,1; /* length = 1 */ 865 mov MSG_OUT,SINDEX; /* 1-byte message */ 866 mvi SEQCTL,FASTMODE ret; 867 868/* 869 * Functions to read data in Automatic PIO mode. 870 * 871 * According to Adaptec's documentation, an ACK is not sent on input from 872 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 873 * latched (the usual way), then read the data byte directly off the bus 874 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 875 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 876 * spec guarantees that the target will hold the data byte on the bus until 877 * we send our ACK. 878 * 879 * The assumption here is that these are called in a particular sequence, 880 * and that REQ is already set when inb_first is called. inb_{first,next} 881 * use the same calling convention as inb. 882 */ 883 884inb_next: 885 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 886inb_next_wait: 887 /* 888 * If there is a parity error, wait for the kernel to 889 * see the interrupt and prepare our message response 890 * before continuing. 891 */ 892 test SSTAT1, REQINIT jz inb_next_wait; 893 test SSTAT1, SCSIPERR jnz inb_next_wait; 894 and LASTPHASE, PHASE_MASK, SCSISIGI; 895 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 896inb_first: 897 mov DINDEX,SINDEX; 898 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 899inb_last: 900 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 901 902mesgin_phasemis: 903/* 904 * We expected to receive another byte, but the target changed phase 905 */ 906 mvi INTSTAT, MSGIN_PHASEMIS; 907 jmp ITloop; 908 909/* 910 * DMA data transfer. HADDR and HCNT must be loaded first, and 911 * SINDEX should contain the value to load DFCNTRL with - 0x3d for 912 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared 913 * during initialization. 914 */ 915dma: 916 mov DFCNTRL,SINDEX; 917dma_loop: 918 test SSTAT0,DMADONE jnz dma_dmadone; 919 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 920dma_phasemis: 921 test SSTAT0,SDONE jnz dma_checkfifo; 922 mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */ 923 924/* 925 * We will be "done" DMAing when the transfer count goes to zero, or 926 * the target changes the phase (in light of this, it makes sense that 927 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 928 * doing a SCSI->Host transfer, the data FIFO should be flushed auto- 929 * magically on STCNT=0 or a phase change, so just wait for FIFO empty 930 * status. 931 */ 932dma_checkfifo: 933 test DFCNTRL,DIRECTION jnz dma_fifoempty; 934dma_fifoflush: 935 test DFSTATUS,FIFOEMP jz dma_fifoflush; 936 937dma_fifoempty: 938 /* Don't clobber an inprogress host data transfer */ 939 test DFSTATUS, MREQPEND jnz dma_fifoempty; 940/* 941 * Now shut the DMA enables off and make sure that the DMA enables are 942 * actually off first lest we get an ILLSADDR. 943 */ 944dma_dmadone: 945 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 946dma_halt: 947 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 948return: 949 ret; 950 951/* 952 * Assert that if we've been reselected, then we've seen an IDENTIFY 953 * message. 954 */ 955assert: 956 test SEQ_FLAGS,RESELECTED jz return; /* reselected? */ 957 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 958 959 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 960 961.if ( SCB_PAGING ) 962/* 963 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) 964 * or by the SCBIDn ARG_1. The search begins at the SCB index passed in 965 * via SINDEX. If the SCB cannot be found, SINDEX will be SCB_LIST_NULL, 966 * otherwise, SCBPTR is set to the proper SCB. 967 */ 968findSCB: 969 mov SCBPTR,SINDEX; /* switch to next SCB */ 970 mov A, ARG_1; /* Tag passed in ARG_1 */ 971 cmp SCB_TAG,A jne findSCB_loop; 972 test SCB_CONTROL,DISCONNECTED jnz foundSCB;/*should be disconnected*/ 973findSCB_loop: 974 inc SINDEX; 975 cmp SINDEX,SCBCOUNT jne findSCB; 976/* 977 * We didn't find it. If we're paging, pull an SCB and DMA down the 978 * one we want. If we aren't paging or the SCB we dma down has the 979 * abort flag set, return not found. 980 */ 981 mov ALLZEROS call get_free_or_disc_scb; 982 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 983 mov ARG_1 call dma_scb; 984 test SCB_RESID_SGCNT, 0xff jz . + 2; 985 or SCB_CONTROL, MUST_DMAUP_SCB; 986 test SCB_CONTROL, ABORT_SCB jz return; 987find_error: 988 mvi SINDEX, SCB_LIST_NULL ret; 989foundSCB: 990 test SCB_CONTROL, ABORT_SCB jnz find_error; 991rem_scb_from_disc_list: 992/* Remove this SCB from the disconnection list */ 993 cmp SCB_NEXT,SCB_LIST_NULL je unlink_prev; 994 mov SAVED_LINKPTR, SCB_PREV; 995 mov SCBPTR, SCB_NEXT; 996 mov SCB_PREV, SAVED_LINKPTR; 997 mov SCBPTR, SINDEX; 998unlink_prev: 999 cmp SCB_PREV,SCB_LIST_NULL je rHead;/* At the head of the list */ 1000 mov SAVED_LINKPTR, SCB_NEXT; 1001 mov SCBPTR, SCB_PREV; 1002 mov SCB_NEXT, SAVED_LINKPTR; 1003 mov SCBPTR, SINDEX ret; 1004rHead: 1005 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1006.else 1007 ret; 1008.endif 1009 1010set_stcnt_from_hcnt: 1011 mov STCNT[0], HCNT[0]; 1012 mov STCNT[1], HCNT[1]; 1013 mov STCNT[2], HCNT[2] ret; 1014 1015bcopy_7: 1016 mov DINDIR, SINDIR; 1017 mov DINDIR, SINDIR; 1018bcopy_5: 1019 mov DINDIR, SINDIR; 1020bcopy_4: 1021 mov DINDIR, SINDIR; 1022bcopy_3: 1023 mov DINDIR, SINDIR; 1024 mov DINDIR, SINDIR; 1025 mov DINDIR, SINDIR ret; 1026 1027dma_scb: 1028 /* 1029 * SCB index is in SINDEX. Determine the physical address in 1030 * the host where this SCB is located and load HADDR with it. 1031 */ 1032 shr DINDEX, 3, SINDEX; 1033 shl A, 5, SINDEX; 1034 add HADDR[0], A, HSCB_ADDR[0]; 1035 mov A, DINDEX; 1036 adc HADDR[1], A, HSCB_ADDR[1]; 1037 clr A; 1038 adc HADDR[2], A, HSCB_ADDR[2]; 1039 adc HADDR[3], A, HSCB_ADDR[3]; 1040 /* Setup Count */ 1041 mvi HCNT[0], 28; 1042 clr HCNT[1]; 1043 clr HCNT[2]; 1044 mov DFCNTRL, DMAPARAMS; 1045 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1046 /* Fill it with the SCB data */ 1047copy_scb_tofifo: 1048 mvi SINDEX, SCB_CONTROL; 1049 add A, 28, SINDEX; 1050copy_scb_tofifo_loop: 1051 mov DFDAT,SINDIR; 1052 mov DFDAT,SINDIR; 1053 mov DFDAT,SINDIR; 1054 mov DFDAT,SINDIR; 1055 mov DFDAT,SINDIR; 1056 mov DFDAT,SINDIR; 1057 mov DFDAT,SINDIR; 1058 cmp SINDEX, A jne copy_scb_tofifo_loop; 1059 or DFCNTRL, HDMAEN|FIFOFLUSH; 1060dma_scb_fromhost: 1061 call dma_finish; 1062 /* If we were putting the SCB, we are done */ 1063 test DMAPARAMS, DIRECTION jz return; 1064 mvi SCB_CONTROL call dfdat_in_7; 1065 call dfdat_in_7_continued; 1066 call dfdat_in_7_continued; 1067 jmp dfdat_in_7_continued; 1068dfdat_in_7: 1069 mov DINDEX,SINDEX; 1070dfdat_in_7_continued: 1071 mov DINDIR,DFDAT; 1072 mov DINDIR,DFDAT; 1073 mov DINDIR,DFDAT; 1074 mov DINDIR,DFDAT; 1075 mov DINDIR,DFDAT; 1076 mov DINDIR,DFDAT; 1077 mov DINDIR,DFDAT ret; 1078 1079/* 1080 * Wait for DMA from host memory to data FIFO to complete, then disable 1081 * DMA and wait for it to acknowledge that it's off. 1082 */ 1083dma_finish: 1084 test DFSTATUS,HDONE jz dma_finish; 1085 /* Turn off DMA */ 1086 and DFCNTRL, ~HDMAEN; 1087 test DFCNTRL, HDMAEN jnz .; 1088 ret; 1089 1090index_untagged_scb: 1091 mov DINDEX, SINDEX; 1092 shr DINDEX, 4; 1093 and DINDEX, 0x03; /* Bottom two bits of tid */ 1094 add DINDEX, SCB_BUSYTARGETS; 1095 shr A, 6, SINDEX; /* Target ID divided by 4 */ 1096 test SINDEX, SELBUSB jz index_untagged_scb2; 1097 add A, 2; /* Add 2 positions */ 1098index_untagged_scb2: 1099 mov SCBPTR, A; /* 1100 * Select the SCB with this 1101 * target's information. 1102 */ 1103 mov SINDEX, DINDEX ret; 1104 1105add_scb_to_free_list: 1106 mov SCB_NEXT, FREE_SCBH; 1107 mvi SCB_TAG, SCB_LIST_NULL; 1108 mov FREE_SCBH, SCBPTR ret; 1109 1110.if ( SCB_PAGING ) 1111get_free_or_disc_scb: 1112 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1113 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1114return_error: 1115 mvi SINDEX, SCB_LIST_NULL ret; 1116dequeue_disc_scb: 1117 mov SCBPTR, DISCONNECTED_SCBH; 1118/* 1119 * If we have a residual, then we are in the middle of some I/O 1120 * and we have to send this SCB back up to the kernel so that the 1121 * saved data pointers and residual information isn't lost. 1122 */ 1123 test SCB_CONTROL, MUST_DMAUP_SCB jz . + 3; 1124 and SCB_CONTROL, ~MUST_DMAUP_SCB; 1125 jmp dma_up_scb; 1126 test SCB_RESID_SGCNT,0xff jnz dma_up_scb; 1127 cmp SCB_LINKED_NEXT, SCB_LIST_NULL je unlink_disc_scb; 1128dma_up_scb: 1129 mvi DMAPARAMS, FIFORESET; 1130 mov SCB_TAG call dma_scb; 1131unlink_disc_scb: 1132 /* jmp instead of call since we want to return anyway */ 1133 mov SCBPTR jmp rem_scb_from_disc_list; 1134dequeue_free_scb: 1135 mov SCBPTR, FREE_SCBH; 1136 mov FREE_SCBH, SCB_NEXT ret; 1137 1138add_scb_to_disc_list: 1139/* 1140 * Link this SCB into the DISCONNECTED list. This list holds the 1141 * candidates for paging out an SCB if one is needed for a new command. 1142 * Modifying the disconnected list is a critical(pause dissabled) section. 1143 */ 1144 mvi SCB_PREV, SCB_LIST_NULL; 1145 mov SCB_NEXT, DISCONNECTED_SCBH; 1146 mov DISCONNECTED_SCBH, SCBPTR; 1147 cmp SCB_NEXT,SCB_LIST_NULL je return; 1148 mov SCBPTR,SCB_NEXT; 1149 mov SCB_PREV,DISCONNECTED_SCBH; 1150 mov SCBPTR,DISCONNECTED_SCBH ret; 1151.endif 1152