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 *-M************************************************************************/ 41 42#include <dev/aic7xxx/aic7xxx.reg> 43#include <scsi/scsi_message.h> 44 45/* 46 * A few words on the waiting SCB list: 47 * After starting the selection hardware, we check for reconnecting targets 48 * as well as for our selection to complete just in case the reselection wins 49 * bus arbitration. The problem with this is that we must keep track of the 50 * SCB that we've already pulled from the QINFIFO and started the selection 51 * on just in case the reselection wins so that we can retry the selection at 52 * a later time. This problem cannot be resolved by holding a single entry 53 * in scratch ram since a reconnecting target can request sense and this will 54 * create yet another SCB waiting for selection. The solution used here is to 55 * use byte 27 of the SCB as a psuedo-next pointer and to thread a list 56 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, 57 * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to 58 * this list everytime a request sense occurs or after completing a non-tagged 59 * command for which a second SCB has been queued. The sequencer will 60 * automatically consume the entries. 61 */ 62 63/* 64 * We assume that the kernel driver may reset us at any time, even in the 65 * middle of a DMA, so clear DFCNTRL too. 66 */ 67reset: 68 clr SCSISIGO; /* De-assert BSY */ 69 /* Always allow reselection */ 70 mvi SCSISEQ, ENRSELI|ENAUTOATNP; 71 call clear_target_state; 72poll_for_work: 73 test SSTAT0,SELDI|SELDO jnz selection; 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,SELDI|SELDO jnz selection; 84 test SCSISEQ, ENSELO jnz poll_for_work; 85 xor SBLKCTL,SELBUSB; /* Toggle back */ 86.endif 87 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; 88test_queue: 89 /* Has the driver posted any work for us? */ 90 mov A, QCNTMASK; 91 test QINCNT,A 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.endif 161simple_busy_link: 162 mov SCBPTR, ARG_1; 163 mov SCB_LINKED_NEXT, CUR_SCBID; 164 mvi SEQCTL, FASTMODE; 165 jmp poll_for_work; 166make_busy: 167 mov DINDIR, CUR_SCBID; 168 mov SCBPTR, SAVED_SCBPTR; 169 mvi SEQCTL, FASTMODE; 170 171start_scb: 172 /* 173 * Place us on the waiting list in case our selection 174 * doesn't win during bus arbitration. 175 */ 176 mov SCB_NEXT,WAITING_SCBH; 177 mov WAITING_SCBH, SCBPTR; 178start_waiting: 179 /* 180 * Pull the first entry off of the waiting SCB list 181 * We don't have to "test_busy" because only transactions that 182 * have passed that test can be in the WAITING_SCB list. 183 */ 184 mov SCBPTR, WAITING_SCBH; 185 call start_selection; 186 jmp poll_for_work; 187 188start_selection: 189.if ( TWIN_CHANNEL ) 190 and SINDEX,~SELBUSB,SBLKCTL;/* Clear the channel select bit */ 191 and A,SELBUSB,SCB_TCL; /* Get new channel bit */ 192 or SINDEX,A; 193 mov SBLKCTL,SINDEX; /* select channel */ 194.endif 195initialize_scsiid: 196 and A, TID, SCB_TCL; /* Get target ID */ 197 and SCSIID, OID; /* Clear old target */ 198 or SCSIID, A; 199 mvi SCSISEQ, ENSELO|ENAUTOATNO|ENRSELI|ENAUTOATNP ret; 200/* 201 * Reselection has been initiated by a target. Make a note that we've been 202 * reselected, but haven't seen an IDENTIFY message from the target yet. 203 */ 204selection: 205 test SSTAT0, SELDI jz select; 206reselect: 207 clr MSG_LEN; /* Don't have anything in the mesg buffer */ 208 mvi CLRSINT0, CLRSELDI; 209 /* XXX test for and handle ONE BIT condition */ 210 and SAVED_TCL, SELID_MASK, SELID; 211 or SEQ_FLAGS,RESELECTED; 212 jmp select2; 213 214/* 215 * After the selection, remove this SCB from the "waiting SCB" 216 * list. This is achieved by simply moving our "next" pointer into 217 * WAITING_SCBH. Our next pointer will be set to null the next time this 218 * SCB is used, so don't bother with it now. 219 */ 220select: 221 /* Turn off the selection hardware */ 222 mvi SCSISEQ, ENRSELI|ENAUTOATNP; /* 223 * ATN on parity errors 224 * for "in" phases 225 */ 226 mvi CLRSINT0, CLRSELDO; 227 mov SCBPTR, WAITING_SCBH; 228 mov WAITING_SCBH,SCB_NEXT; 229 mov SAVED_TCL, SCB_TCL; 230/* 231 * As soon as we get a successful selection, the target should go 232 * into the message out phase since we have ATN asserted. Prepare 233 * the message to send. 234 * 235 * Messages are stored in scratch RAM starting with a length byte 236 * followed by the message itself. 237 */ 238 239mk_identify: 240 and MSG_OUT,0x7,SCB_TCL; /* lun */ 241 and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ 242 or MSG_OUT,A; /* or in disconnect privledge */ 243 or MSG_OUT,MSG_IDENTIFYFLAG; 244 mvi MSG_LEN, 1; 245 246/* 247 * Send a tag message if TAG_ENB is set in the SCB control block. 248 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 249 */ 250mk_tag: 251 test SCB_CONTROL,TAG_ENB jz mk_message; 252 and MSG_OUT[1],TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 253 mov MSG_OUT[2],SCB_TAG; 254 add MSG_LEN,2; /* update message length */ 255 256/* 257 * Interrupt the driver, and allow it to tweak the message buffer 258 * if it asks. 259 */ 260mk_message: 261 test SCB_CONTROL,MK_MESSAGE jz select2; 262 mvi INTSTAT,AWAITING_MSG; 263 264select2: 265 mvi CLRSINT1,CLRBUSFREE; 266 or SIMODE1, ENBUSFREE; /* 267 * We aren't expecting a 268 * bus free, so interrupt 269 * the kernel driver if it 270 * happens. 271 */ 272/* 273 * Initialize Ultra mode setting and clear the SCSI channel. 274 */ 275 or SXFRCTL0, CLRSTCNT|SPIOEN|CLRCHN; 276.if ( ULTRA ) 277ultra: 278 mvi SINDEX, ULTRA_ENB+1; 279 test SAVED_TCL, 0x80 jnz ultra_2; /* Target ID > 7 */ 280 dec SINDEX; 281ultra_2: 282 mov FUNCTION1,SAVED_TCL; 283 mov A,FUNCTION1; 284 test SINDIR, A jz ndx_dtr; 285 or SXFRCTL0, FAST20; 286.endif 287 288/* 289 * Initialize SCSIRATE with the appropriate value for this target. 290 * The SCSIRATE settings for each target are stored in an array 291 * based at TARG_SCRATCH. 292 */ 293ndx_dtr: 294 shr A,4,SAVED_TCL; 295 test SBLKCTL,SELBUSB jz ndx_dtr_2; 296 or SAVED_TCL, SELBUSB; /* Add the channel bit while we're here */ 297 or A,0x08; /* Channel B entries add 8 */ 298ndx_dtr_2: 299 add SINDEX,TARG_SCRATCH,A; 300 mov SCSIRATE,SINDIR; 301 302 303/* 304 * Main loop for information transfer phases. If BSY is false, then 305 * we have a bus free condition, expected or not. Otherwise, wait 306 * for the target to assert REQ before checking MSG, C/D and I/O 307 * for the bus phase. 308 * 309 */ 310ITloop: 311 test SSTAT1,REQINIT jz 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 mov NONE, SCSIDATL; /* Ack the last byte */ 330 call clear_target_state; 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 and LASTPHASE, PHASE_MASK, SCSISIGI; 541 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 542/* 543 * If the next bus phase after ATN drops is a message out, it means 544 * that the target is requesting that the last message(s) be resent. 545 */ 546p_mesgout_dropatn: 547 cmp DINDEX,1 jne p_mesgout_testretry;/* last byte? */ 548 mvi CLRSINT1,CLRATNO; /* drop ATN */ 549p_mesgout_testretry: 550 test DINDEX,0xff jnz p_mesgout_outb; 551 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */ 552 jmp p_mesgout_start; 553p_mesgout_outb: 554 dec DINDEX; 555 mov SCSIDATL,SINDIR; 556 jmp p_mesgout_loop; 557 558p_mesgout_done: 559 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 560 clr MSG_LEN; /* no active msg */ 561 jmp ITloop; 562 563/* 564 * Message in phase. Bytes are read using Automatic PIO mode. 565 */ 566p_mesgin: 567 mvi ACCUM call inb_first; /* read the 1st message byte */ 568 mov REJBYTE,A; /* save it for the driver */ 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 mov QOUTFIFO,SCB_TAG; 645 mvi INTSTAT,CMDCMPLT; 646 test SCB_CONTROL, ABORT_SCB jz dma_next_scb; 647 mvi INTSTAT, ABORT_CMDCMPLT; 648 649dma_next_scb: 650 cmp SCB_LINKED_NEXT, SCB_LIST_NULL je add_to_free_list; 651.if !( SCB_PAGING ) 652 /* Only DMA on top of ourselves if we are the SCB to download */ 653 mov A, SCB_LINKED_NEXT; 654 cmp SCB_TAG, A je dma_next_scb2; 655 mov SCBPTR, A; 656 jmp add_to_waiting_list; 657.endif 658dma_next_scb2: 659 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 660 mov SCB_LINKED_NEXT call dma_scb; 661add_to_waiting_list: 662 mov SCB_NEXT,WAITING_SCBH; 663 mov WAITING_SCBH, SCBPTR; 664 /* 665 * Prepare our selection hardware before the busfree so we have a 666 * high probability of winning arbitration. 667 */ 668 call start_selection; 669 jmp await_busfree; 670add_to_free_list: 671 call add_scb_to_free_list; 672 jmp await_busfree; 673 674/* 675 * Is it an extended message? Copy the message to our message buffer and 676 * notify the host. The host will tell us whether to reject this message, 677 * respond to it with the message that the host placed in our message buffer, 678 * or simply to do nothing. 679 */ 680mesgin_extended: 681 mvi MSGIN_EXT_LEN call inb_next; 682 mov A, MSGIN_EXT_LEN; 683mesgin_extended_loop: 684 mov DINDEX call inb_next; 685 dec A; 686 cmp DINDEX, MSGIN_EXT_BYTES+3 jne mesgin_extended_loop_test; 687 dec DINDEX; /* dump by repeatedly filling the last byte */ 688mesgin_extended_loop_test: 689 test A, 0xFF jnz mesgin_extended_loop; 690mesgin_extended_intr: 691 mvi INTSTAT,EXTENDED_MSG; /* let driver know */ 692 cmp RETURN_1,SEND_REJ je rej_mesgin; 693 cmp RETURN_1,SEND_MSG jne mesgin_done; 694/* The kernel has setup a message to be sent */ 695 or SCSISIGO,ATNO,LASTPHASE; /* turn on ATNO */ 696 jmp mesgin_done; 697 698/* 699 * Is it a disconnect message? Set a flag in the SCB to remind us 700 * and await the bus going free. 701 */ 702mesgin_disconnect: 703 or SCB_CONTROL,DISCONNECTED; 704.if ( SCB_PAGING ) 705 call add_scb_to_disc_list; 706.endif 707 jmp await_busfree; 708 709/* 710 * Save data pointers message: 711 * Copying RAM values back to SCB, for Save Data Pointers message, but 712 * only if we've actually been into a data phase to change them. This 713 * protects against bogus data in scratch ram and the residual counts 714 * since they are only initialized when we go into data_in or data_out. 715 */ 716mesgin_sdptrs: 717 test SEQ_FLAGS, DPHASE jz mesgin_done; 718 mov SCB_SGCOUNT,SG_COUNT; 719 720 /* The SCB SGPTR becomes the next one we'll download */ 721 mvi DINDEX, SCB_SGPTR; 722 mvi SG_NEXT call bcopy_4; 723 724 /* The SCB DATAPTR0 becomes the current SHADDR */ 725 mvi DINDEX, SCB_DATAPTR; 726 mvi SHADDR call bcopy_4; 727 728/* 729 * Use the residual number since STCNT is corrupted by any message transfer. 730 */ 731 mvi SCB_RESID_DCNT call bcopy_3; 732 733 jmp mesgin_done; 734 735/* 736 * Restore pointers message? Data pointers are recopied from the 737 * SCB anytime we enter a data phase for the first time, so all 738 * we need to do is clear the DPHASE flag and let the data phase 739 * code do the rest. 740 */ 741mesgin_rdptrs: 742 and SEQ_FLAGS, ~DPHASE; /* 743 * We'll reload them 744 * the next time through 745 * the dataphase. 746 */ 747 jmp mesgin_done; 748 749/* 750 * Identify message? For a reconnecting target, this tells us the lun 751 * that the reconnection is for - find the correct SCB and switch to it, 752 * clearing the "disconnected" bit so we don't "find" it by accident later. 753 */ 754mesgin_identify: 755 test A,0x78 jnz rej_mesgin; /*!DiscPriv|!LUNTAR|!Reserved*/ 756 and A,0x07; /* lun in lower three bits */ 757 or SAVED_TCL,A; /* SAVED_TCL should be complete now */ 758 mov SAVED_TCL call index_untagged_scb; 759 mov ARG_1, SINDIR; 760 /* XXX Directly index in the non paging case */ 761 cmp ARG_1,SCB_LIST_NULL jne use_findSCB; 762/* 763 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 764 * If we get one, we use the tag returned to find the proper 765 * SCB. With SCB paging, this requires using findSCB for both tagged 766 * and non-tagged transactions since the SCB may exist in any slot. 767 * If we're not using SCB paging, we can use the tag as the direct 768 * index to the SCB. 769 */ 770 mov NONE,SCSIDATL; /* ACK Identify MSG */ 771snoop_tag_loop: 772 test SSTAT1,REQINIT jz snoop_tag_loop; 773 and LASTPHASE, PHASE_MASK, SCSISIGI; 774 cmp LASTPHASE, P_MESGIN jne not_found; 775 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 776get_tag: 777 or SEQ_FLAGS, TAGGED_SCB; 778 mvi ARG_1 call inb_next; /* tag value */ 779/* 780 * See if the tag is in range. The tag is < SCBCOUNT if we add 781 * the complement of SCBCOUNT to the incomming tag and there is 782 * no carry. 783 */ 784 mov A,COMP_SCBCOUNT; 785 add SINDEX,A,ARG_1; 786 jc not_found; 787 788.if ! ( SCB_PAGING ) 789 jmp index_by_tag; 790.endif 791/* 792 * Ensure that the SCB the tag points to is for an SCB transaction 793 * to the reconnecting target. 794 */ 795use_findSCB: 796 mov ALLZEROS call findSCB; /* Have to search */ 797 cmp SINDEX, SCB_LIST_NULL je not_found; 798setup_SCB: 799 and SCB_CONTROL,~DISCONNECTED; 800 or SEQ_FLAGS,IDENTIFY_SEEN; /* make note of IDENTIFY */ 801 jmp mesgin_done; 802index_by_tag: 803 mov SCBPTR,ARG_1; 804 mov A, SAVED_TCL; 805 cmp SCB_TCL,A jne not_found; 806 test SCB_CONTROL,TAG_ENB jz not_found; 807 test SCB_CONTROL,DISCONNECTED jz not_found; 808 jmp setup_SCB; 809 810not_found: 811 mvi INTSTAT, NO_MATCH; 812send_abort_msg: 813 test SEQ_FLAGS, TAGGED_SCB jnz send_abort_tag_msg; 814 mvi MSG_ABORT call mk_mesg; 815 jmp send_abort_done; 816send_abort_tag_msg: 817 mvi MSG_ABORT_TAG call mk_mesg; /* ABORT TAG message */ 818send_abort_done: 819 /* If we don't have the tag ID yet, we're "looking ahead" at state 820 * that hasn't been processed, so don't ack. 821 */ 822 cmp ARG_1, SCB_LIST_NULL je ITloop; 823 jmp mesgin_done; 824 825/* 826 * Message reject? Let the kernel driver handle this. If we have an 827 * outstanding WDTR or SDTR negotiation, assume that it's a response from 828 * the target selecting 8bit or asynchronous transfer, otherwise just ignore 829 * it since we have no clue what it pertains to. 830 */ 831mesgin_reject: 832 mvi INTSTAT, REJECT_MSG; 833 jmp mesgin_done; 834 835/* 836 * [ ADD MORE MESSAGE HANDLING HERE ] 837 */ 838 839/* 840 * Locking the driver out, build a one-byte message passed in SINDEX 841 * if there is no active message already. SINDEX is returned intact. 842 */ 843mk_mesg: 844 mvi SEQCTL, PAUSEDIS|FASTMODE; 845 test MSG_LEN,0xff jz mk_mesg1; /* Should always succeed */ 846 847 /* 848 * Hmmm. For some reason the mesg buffer is in use. 849 * Tell the driver. It should look at SINDEX to find 850 * out what we wanted to use the buffer for and resolve 851 * the conflict. 852 */ 853 mvi SEQCTL,FASTMODE; 854 mvi INTSTAT,MSG_BUFFER_BUSY; 855 856mk_mesg1: 857 or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */ 858 mvi MSG_LEN,1; /* length = 1 */ 859 mov MSG_OUT,SINDEX; /* 1-byte message */ 860 mvi SEQCTL,FASTMODE ret; 861 862/* 863 * Functions to read data in Automatic PIO mode. 864 * 865 * According to Adaptec's documentation, an ACK is not sent on input from 866 * the target until SCSIDATL is read from. So we wait until SCSIDATL is 867 * latched (the usual way), then read the data byte directly off the bus 868 * using SCSIBUSL. When we have pulled the ATN line, or we just want to 869 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 870 * spec guarantees that the target will hold the data byte on the bus until 871 * we send our ACK. 872 * 873 * The assumption here is that these are called in a particular sequence, 874 * and that REQ is already set when inb_first is called. inb_{first,next} 875 * use the same calling convention as inb. 876 */ 877 878inb_next: 879 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 880inb_next_wait: 881 /* 882 * If there is a parity error, wait for the kernel to 883 * see the interrupt and prepare our message response 884 * before continuing. 885 */ 886 test SSTAT1, REQINIT jz inb_next_wait; 887 test SSTAT1, SCSIPERR jnz inb_next_wait; 888 and LASTPHASE, PHASE_MASK, SCSISIGI; 889 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 890inb_first: 891 mov DINDEX,SINDEX; 892 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 893inb_last: 894 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 895 896mesgin_phasemis: 897/* 898 * We expected to receive another byte, but the target changed phase 899 */ 900 mvi INTSTAT, MSGIN_PHASEMIS; 901 jmp ITloop; 902 903/* 904 * DMA data transfer. HADDR and HCNT must be loaded first, and 905 * SINDEX should contain the value to load DFCNTRL with - 0x3d for 906 * host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared 907 * during initialization. 908 */ 909dma: 910 mov DFCNTRL,SINDEX; 911dma_loop: 912 test SSTAT0,DMADONE jnz dma_dmadone; 913 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 914dma_phasemis: 915 test SSTAT0,SDONE jnz dma_checkfifo; 916 mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */ 917 918/* 919 * We will be "done" DMAing when the transfer count goes to zero, or 920 * the target changes the phase (in light of this, it makes sense that 921 * the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 922 * doing a SCSI->Host transfer, the data FIFO should be flushed auto- 923 * magically on STCNT=0 or a phase change, so just wait for FIFO empty 924 * status. 925 */ 926dma_checkfifo: 927 test DFCNTRL,DIRECTION jnz dma_fifoempty; 928dma_fifoflush: 929 test DFSTATUS,FIFOEMP jz dma_fifoflush; 930 931dma_fifoempty: 932 /* Don't clobber an inprogress host data transfer */ 933 test DFSTATUS, MREQPEND jnz dma_fifoempty; 934/* 935 * Now shut the DMA enables off and make sure that the DMA enables are 936 * actually off first lest we get an ILLSADDR. 937 */ 938dma_dmadone: 939 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 940dma_halt: 941 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 942return: 943 ret; 944 945/* 946 * Assert that if we've been reselected, then we've seen an IDENTIFY 947 * message. 948 */ 949assert: 950 test SEQ_FLAGS,RESELECTED jz return; /* reselected? */ 951 test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */ 952 953 mvi INTSTAT,NO_IDENT ret; /* no - tell the kernel */ 954 955/* 956 * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL) 957 * or by the SCBIDn ARG_1. The search begins at the SCB index passed in 958 * via SINDEX. If the SCB cannot be found, SINDEX will be SCB_LIST_NULL, 959 * otherwise, SCBPTR is set to the proper SCB. 960 */ 961findSCB: 962 mov SCBPTR,SINDEX; /* switch to next SCB */ 963 mov A, ARG_1; /* Tag passed in ARG_1 */ 964 cmp SCB_TAG,A jne findSCB_loop; 965 test SCB_CONTROL,DISCONNECTED jnz foundSCB;/*should be disconnected*/ 966findSCB_loop: 967 inc SINDEX; 968 mov A,SCBCOUNT; 969 cmp SINDEX,A jne findSCB; 970/* 971 * We didn't find it. If we're paging, pull an SCB and DMA down the 972 * one we want. If we aren't paging or the SCB we dma down has the 973 * abort flag set, return not found. 974 */ 975.if ( SCB_PAGING ) 976 mov ALLZEROS call get_free_or_disc_scb; 977 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 978 mov ARG_1 call dma_scb; 979 test SCB_CONTROL, ABORT_SCB jz return; 980.endif 981find_error: 982 mvi SINDEX, SCB_LIST_NULL ret; 983foundSCB: 984 test SCB_CONTROL, ABORT_SCB jnz find_error; 985.if ( SCB_PAGING ) 986rem_scb_from_disc_list: 987/* Remove this SCB from the disconnection list */ 988 cmp SCB_NEXT,SCB_LIST_NULL je unlink_prev; 989 mov SAVED_LINKPTR, SCB_PREV; 990 mov SCBPTR, SCB_NEXT; 991 mov SCB_PREV, SAVED_LINKPTR; 992 mov SCBPTR, SINDEX; 993unlink_prev: 994 cmp SCB_PREV,SCB_LIST_NULL je rHead;/* At the head of the list */ 995 mov SAVED_LINKPTR, SCB_NEXT; 996 mov SCBPTR, SCB_PREV; 997 mov SCB_NEXT, SAVED_LINKPTR; 998 mov SCBPTR, SINDEX ret; 999rHead: 1000 mov DISCONNECTED_SCBH,SCB_NEXT ret; 1001.else 1002 ret; 1003.endif 1004 1005set_stcnt_from_hcnt: 1006 mov STCNT[0], HCNT[0]; 1007 mov STCNT[1], HCNT[1]; 1008 mov STCNT[2], HCNT[2] ret; 1009 1010bcopy_7: 1011 mov DINDIR, SINDIR; 1012 mov DINDIR, SINDIR; 1013bcopy_5: 1014 mov DINDIR, SINDIR; 1015bcopy_4: 1016 mov DINDIR, SINDIR; 1017bcopy_3: 1018 mov DINDIR, SINDIR; 1019 mov DINDIR, SINDIR; 1020 mov DINDIR, SINDIR ret; 1021 1022dma_scb: 1023 /* 1024 * SCB index is in SINDEX. Determine the physical address in 1025 * the host where this SCB is located and load HADDR with it. 1026 */ 1027 shr DINDEX, 3, SINDEX; 1028 shl A, 5, SINDEX; 1029 add HADDR[0], A, HSCB_ADDR[0]; 1030 mov A, DINDEX; 1031 adc HADDR[1], A, HSCB_ADDR[1]; 1032 clr A; 1033 adc HADDR[2], A, HSCB_ADDR[2]; 1034 adc HADDR[3], A, HSCB_ADDR[3]; 1035 /* Setup Count */ 1036 mvi HCNT[0], 28; 1037 clr HCNT[1]; 1038 clr HCNT[2]; 1039 mov DFCNTRL, DMAPARAMS; 1040 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 1041 /* Fill it with the SCB data */ 1042 call copy_scb_tofifo; 1043 or DFCNTRL, HDMAEN|FIFOFLUSH; 1044dma_scb_fromhost: 1045 call dma_finish; 1046 /* If we were putting the SCB, we are done */ 1047 test DMAPARAMS, DIRECTION jz return; 1048 mvi SCB_CONTROL call dfdat_in_7; 1049 call dfdat_in_7_continued; 1050 call dfdat_in_7_continued; 1051 jmp dfdat_in_7_continued; 1052dfdat_in_7: 1053 mov DINDEX,SINDEX; 1054dfdat_in_7_continued: 1055 mov DINDIR,DFDAT; 1056 mov DINDIR,DFDAT; 1057 mov DINDIR,DFDAT; 1058 mov DINDIR,DFDAT; 1059 mov DINDIR,DFDAT; 1060 mov DINDIR,DFDAT; 1061 mov DINDIR,DFDAT ret; 1062 1063copy_scb_tofifo: 1064 mvi SCB_CONTROL call dfdat_out_7; 1065 call dfdat_out_7; 1066 call dfdat_out_7; 1067dfdat_out_7: 1068 mov DFDAT,SINDIR; 1069 mov DFDAT,SINDIR; 1070 mov DFDAT,SINDIR; 1071 mov DFDAT,SINDIR; 1072 mov DFDAT,SINDIR; 1073 mov DFDAT,SINDIR; 1074 mov DFDAT,SINDIR ret; 1075 1076/* 1077 * Wait for DMA from host memory to data FIFO to complete, then disable 1078 * DMA and wait for it to acknowledge that it's off. 1079 */ 1080dma_finish: 1081 test DFSTATUS,HDONE jz dma_finish; 1082 /* Turn off DMA */ 1083 and DFCNTRL, ~HDMAEN; 1084 test DFCNTRL, HDMAEN jnz .; 1085 ret; 1086 1087index_untagged_scb: 1088 mov DINDEX, SINDEX; 1089 shr DINDEX, 4; 1090 and DINDEX, 0x03; /* Bottom two bits of tid */ 1091 add DINDEX, SCB_BUSYTARGETS; 1092 shr A, 6, SINDEX; /* Target ID divided by 4 */ 1093 test SINDEX, SELBUSB jz index_untagged_scb2; 1094 add A, 2; /* Add 2 positions */ 1095index_untagged_scb2: 1096 mov SCBPTR, A; /* 1097 * Select the SCB with this 1098 * target's information. 1099 */ 1100 mov SINDEX, DINDEX ret; 1101 1102add_scb_to_free_list: 1103 mov SCB_NEXT, FREE_SCBH; 1104 mvi SCB_TAG, SCB_LIST_NULL; 1105 mov FREE_SCBH, SCBPTR ret; 1106 1107.if ( SCB_PAGING ) 1108get_free_or_disc_scb: 1109 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 1110 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 1111return_error: 1112 mvi SINDEX, SCB_LIST_NULL ret; 1113dequeue_disc_scb: 1114 mov SCBPTR, DISCONNECTED_SCBH; 1115/* 1116 * If we have a residual, then we are in the middle of some I/O 1117 * and we have to send this SCB back up to the kernel so that the 1118 * saved data pointers and residual information isn't lost. 1119 */ 1120 test SCB_RESID_SGCNT,0xff jnz dma_up_scb; 1121 cmp SCB_LINKED_NEXT, SCB_LIST_NULL je unlink_disc_scb; 1122dma_up_scb: 1123 mvi DMAPARAMS, FIFORESET; 1124 mov SCB_TAG call dma_scb; 1125unlink_disc_scb: 1126 /* jmp instead of call since we want to return anyway */ 1127 mov SCBPTR jmp rem_scb_from_disc_list; 1128dequeue_free_scb: 1129 mov SCBPTR, FREE_SCBH; 1130 mov FREE_SCBH, SCB_NEXT ret; 1131 1132add_scb_to_disc_list: 1133/* 1134 * Link this SCB into the DISCONNECTED list. This list holds the 1135 * candidates for paging out an SCB if one is needed for a new command. 1136 * Modifying the disconnected list is a critical(pause dissabled) section. 1137 */ 1138 mvi SCB_PREV, SCB_LIST_NULL; 1139 mov SCB_NEXT, DISCONNECTED_SCBH; 1140 mov DISCONNECTED_SCBH, SCBPTR; 1141 cmp SCB_NEXT,SCB_LIST_NULL je return; 1142 mov SCBPTR,SCB_NEXT; 1143 mov SCB_PREV,DISCONNECTED_SCBH; 1144 mov SCBPTR,DISCONNECTED_SCBH ret; 1145.endif 1146