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