aic7xxx.seq revision 7700
1# @(#)aic7xxx.seq 1.32 94/11/29 jda 2# 3# Adaptec 274x/284x/294x device driver for Linux and FreeBSD. 4# Copyright (c) 1994 The University of Calgary Department of Computer Science. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19# 20 21# FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other 22# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org) 23# 24 25VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.12 1995/04/01 19:51:40 gibbs Exp $" 26 27SCBMASK = 0x1f 28 29SCSISEQ = 0x00 30SXFRCTL0 = 0x01 31SXFRCTL1 = 0x02 32SCSISIGI = 0x03 33SCSISIGO = 0x03 34SCSIRATE = 0x04 35SCSIID = 0x05 36SCSIDATL = 0x06 37STCNT = 0x08 38STCNT+0 = 0x08 39STCNT+1 = 0x09 40STCNT+2 = 0x0a 41SSTAT0 = 0x0b 42CLRSINT1 = 0x0c 43SSTAT1 = 0x0c 44SIMODE1 = 0x11 45SCSIBUSL = 0x12 46SHADDR = 0x14 47SELID = 0x19 48SBLKCTL = 0x1f 49SEQCTL = 0x60 50A = 0x64 # == ACCUM 51SINDEX = 0x65 52DINDEX = 0x66 53ALLZEROS = 0x6a 54NONE = 0x6a 55SINDIR = 0x6c 56DINDIR = 0x6d 57FUNCTION1 = 0x6e 58HADDR = 0x88 59HADDR+1 = 0x89 60HADDR+2 = 0x8a 61HADDR+3 = 0x8b 62HCNT = 0x8c 63HCNT+0 = 0x8c 64HCNT+1 = 0x8d 65HCNT+2 = 0x8e 66SCBPTR = 0x90 67INTSTAT = 0x91 68DFCNTRL = 0x93 69DFSTATUS = 0x94 70DFDAT = 0x99 71QINFIFO = 0x9b 72QINCNT = 0x9c 73QOUTFIFO = 0x9d 74 75SCSICONF_A = 0x5a 76SCSICONF_B = 0x5b 77 78# The two reserved bytes at SCBARRAY+1[23] are expected to be set to 79# zero, and the reserved bit in SCBARRAY+0 is used as an internal flag 80# to indicate whether or not to reload scatter-gather parameters after 81# a disconnect. We also use bits 6 & 7 to indicate whether or not to 82# initiate SDTR or WDTR repectively when starting this command. 83# 84SCBARRAY+0 = 0xa0 85 86DISCONNECTED = 0x04 87NEEDDMA = 0x08 88SG_LOAD = 0x10 89TAG_ENB = 0x20 90NEEDSDTR = 0x40 91NEEDWDTR = 0x80 92 93SCBARRAY+1 = 0xa1 94SCBARRAY+2 = 0xa2 95SCBARRAY+3 = 0xa3 96SCBARRAY+4 = 0xa4 97SCBARRAY+5 = 0xa5 98SCBARRAY+6 = 0xa6 99SCBARRAY+7 = 0xa7 100SCBARRAY+8 = 0xa8 101SCBARRAY+9 = 0xa9 102SCBARRAY+10 = 0xaa 103SCBARRAY+11 = 0xab 104SCBARRAY+12 = 0xac 105SCBARRAY+13 = 0xad 106SCBARRAY+14 = 0xae 107SCBARRAY+15 = 0xaf 108SCBARRAY+16 = 0xb0 109SCBARRAY+17 = 0xb1 110SCBARRAY+18 = 0xb2 111SCBARRAY+19 = 0xb3 112SCBARRAY+20 = 0xb4 113SCBARRAY+21 = 0xb5 114SCBARRAY+22 = 0xb6 115SCBARRAY+23 = 0xb7 116SCBARRAY+24 = 0xb8 117SCBARRAY+25 = 0xb9 118SCBARRAY+26 = 0xba 119SCBARRAY+27 = 0xbb 120SCBARRAY+28 = 0xbc 121SCBARRAY+29 = 0xbd 122 123BAD_PHASE = 0x01 # unknown scsi bus phase 124CMDCMPLT = 0x02 125SEND_REJECT = 0x11 # sending a message reject 126NO_IDENT = 0x21 # no IDENTIFY after reconnect 127NO_MATCH = 0x31 # no cmd match for reconnect 128MSG_SDTR = 0x41 # SDTR message recieved 129MSG_WDTR = 0x51 # WDTR message recieved 130MSG_REJECT = 0x61 # Reject message recieved 131BAD_STATUS = 0x71 # Bad status from target 132RESIDUAL = 0x81 # Residual byte count != 0 133ABORT_TAG = 0x91 # Sent an ABORT_TAG message 134 135# The host adapter card (at least the BIOS) uses 20-2f for SCSI 136# device information, 32-33 and 5a-5f as well. As it turns out, the 137# BIOS trashes 20-2f, writing the synchronous negotiation results 138# on top of the BIOS values, so we re-use those for our per-target 139# scratchspace (actually a value that can be copied directly into 140# SCSIRATE). The kernel driver will enable synchronous negotiation 141# for all targets that have a value other than 0 in the lower four 142# bits of the target scratch space. This should work irregardless of 143# whether the bios has been installed. NEEDWDTR and NEEDSDTR are the top 144# two bits of the SCB control byte. The kernel driver will set these 145# when a WDTR or SDTR message should be sent to the target the SCB's 146# command references. 147# 148# The high bit of DROPATN is set if ATN should be dropped before the ACK 149# when outb is called. REJBYTE contains the first byte of a MESSAGE IN 150# message, so the driver can report an intelligible error if a message is 151# rejected. 152# 153# FLAGS's high bit is true if we are currently handling a reselect; 154# its next-highest bit is true ONLY IF we've seen an IDENTIFY message 155# from the reselecting target. If we haven't had IDENTIFY, then we have 156# no idea what the lun is, and we can't select the right SCB register 157# bank, so force a kernel panic if the target attempts a data in/out or 158# command phase instead of corrupting something. 159# 160# Note that SG_NEXT occupies four bytes. 161# 162SYNCNEG = 0x20 163 164DROPATN = 0x30 165REJBYTE = 0x31 166DISC_DSB_A = 0x32 167DISC_DSB_B = 0x33 168 169MSG_LEN = 0x34 170MSG_START+0 = 0x35 171MSG_START+1 = 0x36 172MSG_START+2 = 0x37 173MSG_START+3 = 0x38 174MSG_START+4 = 0x39 175MSG_START+5 = 0x3a 176-MSG_START+0 = 0xcb # 2's complement of MSG_START+0 177 178ARG_1 = 0x4a # sdtr conversion args & return 179BUS_16_BIT = 0x01 180RETURN_1 = 0x4a 181 182SIGSTATE = 0x4b # value written to SCSISIGO 183 184# Linux users should use 0xc (12) for SG_SIZEOF 185SG_SIZEOF = 0x8 # sizeof(struct ahc_dma) 186#SG_SIZEOF = 0xc # sizeof(struct scatterlist) 187SCB_SIZEOF = 0x13 # sizeof SCB to DMA (19 bytes) 188 189SG_NOLOAD = 0x4c # load SG pointer/length? 190SG_COUNT = 0x4d # working value of SG count 191SG_NEXT = 0x4e # working value of SG pointer 192SG_NEXT+0 = 0x4e 193SG_NEXT+1 = 0x4f 194SG_NEXT+2 = 0x50 195SG_NEXT+3 = 0x51 196 197SCBCOUNT = 0x52 # the actual number of SCBs 198FLAGS = 0x53 # Device configuration flags 199TWIN_BUS = 0x01 200WIDE_BUS = 0x02 201MAX_SYNC = 0x08 202SENSE = 0x10 203ACTIVE_MSG = 0x20 204IDENTIFY_SEEN = 0x40 205RESELECTED = 0x80 206 207ACTIVE_A = 0x54 208ACTIVE_B = 0x55 209SAVED_TCL = 0x56 210# Poll QINCNT for work - the lower bits contain 211# the number of entries in the Queue In FIFO. 212# 213start: 214 test FLAGS,SENSE jnz start_sense 215start_nosense: 216 test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device? 217# For fairness, we check the other bus first, since we just finished a 218# transaction on the current channel. 219 xor SBLKCTL,0x08 # Toggle to the other bus 220 test SCSISIGI,0x4 jnz reselect # BSYI 221 xor SBLKCTL,0x08 # Toggle to the original bus 222start2: 223 test SCSISIGI,0x4 jnz reselect # BSYI 224 test QINCNT,SCBMASK jz start_nosense 225 226# We have at least one queued SCB now. Set the SCB pointer 227# from the FIFO so we see the right bank of SCB registers, 228# then set SCSI options and set the initiator and target 229# SCSI IDs. 230# 231 mov SCBPTR,QINFIFO 232 233# If the control byte of this SCB has the NEEDDMA flag set, we have 234# yet to DMA it from host memory 235 236test SCBARRAY+0,NEEDDMA jz test_busy 237 clr HCNT+2 238 clr HCNT+1 239 mvi HCNT+0,SCB_SIZEOF 240 241 mvi DINDEX,HADDR 242 mvi SCBARRAY+26 call bcopy_4 243 244 mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET 245 246# Wait for DMA from host memory to data FIFO to complete, then disable 247# DMA and wait for it to acknowledge that it's off. 248# 249 call dma_finish 250 251# Copy the SCB from the FIFO to the SCBARRAY 252 253 mvi DINDEX, SCBARRAY+0 254 call bcopy_3_dfdat 255 call bcopy_4_dfdat 256 call bcopy_4_dfdat 257 call bcopy_4_dfdat 258 call bcopy_4_dfdat 259 260# See if there is not already an active SCB for this target. This code 261# locks out on a per target basis instead of target/lun. Although this 262# is not ideal for devices that have multiple luns active at the same 263# time, it is faster than looping through all SCB's looking for active 264# commands. It may be benificial to make findscb a more general procedure 265# to see if the added cost of the search is negligible. This code also 266# assumes that the kernel driver will clear the active flags on board 267# initialization, board reset, and a target's SELTO. 268 269test_busy: 270 test SCBARRAY+0,0x20 jnz start_scb 271 and FUNCTION1,0x70,SCBARRAY+1 272 mov A,FUNCTION1 273 test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel 274 275 test ACTIVE_B,A jnz requeue 276 or ACTIVE_B,A # Mark the current target as busy 277 jmp start_scb 278 279start_sense: 280# Clear the SENSE flag first, then do a normal start_scb 281 and FLAGS,0xef 282 jmp start_scb 283 284# Place the currently active back on the queue for later processing 285requeue: 286 mov QINFIFO, SCBPTR 287 jmp start_nosense 288 289test_a: 290 test ACTIVE_A,A jnz requeue 291 or ACTIVE_A,A # Mark the current target as busy 292 293start_scb: 294 or SCBARRAY+0,NEEDDMA 295 and SINDEX,0xf7,SBLKCTL #Clear the channel select bit 296 and A,0x08,SCBARRAY+1 #Get new channel bit 297 or SINDEX,A 298 mov SBLKCTL,SINDEX # select channel 299 mov SCBARRAY+1 call initialize 300 clr SG_NOLOAD 301 and FLAGS,0x3f # !RESELECTING 302 303# As soon as we get a successful selection, the target should go 304# into the message out phase since we have ATN asserted. Prepare 305# the message to send, locking out the device driver. If the device 306# driver hasn't beaten us with an ABORT or RESET message, then tack 307# on an SDTR negotiation if required. 308# 309# Messages are stored in scratch RAM starting with a flag byte (high bit 310# set means active message), one length byte, and then the message itself. 311# 312 mov SCBARRAY+1 call disconnect # disconnect ok? 313 314 and SINDEX,0x7,SCBARRAY+1 # lun 315 or SINDEX,A # return value from disconnect 316 or SINDEX,0x80 call mk_mesg # IDENTIFY message 317 318 mov A,SINDEX 319 test SCBARRAY+0,0xe0 jz !message # WDTR, SDTR or TAG?? 320 cmp MSG_START+0,A jne !message # did driver beat us? 321 322# Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag 323# value 324 325mk_tag: 326 mvi DINDEX, MSG_START+1 327 test SCBARRAY+0,TAG_ENB jz mk_tag_done 328 and A,0x23,SCBARRAY+0 329 mov DINDIR,A 330 mov DINDIR,SCBPTR 331 332 add MSG_LEN,-MSG_START+0,DINDEX # update message length 333 334mk_tag_done: 335 336 mov DINDEX call mk_dtr # build DTR message if needed 337 338!message: 339 340# Enable selection phase as an initiator, and do automatic ATN 341# after the selection. 342# 343 mvi SCSISEQ,0x48 # ENSELO|ENAUTOATNO 344 345# Wait for successful arbitration. The AIC-7770 documentation says 346# that SELINGO indicates successful arbitration, and that it should 347# be used to look for SELDO. However, if the sequencer is paused at 348# just the right time - a parallel fsck(8) on two drives did it for 349# me - then SELINGO can flip back to false before we've seen it. This 350# makes the sequencer sit in the arbitration loop forever. This is 351# Not Good. 352# 353# Therefore, I've added a check in the arbitration loop for SELDO 354# too. This could arguably be made a critical section by disabling 355# pauses, but I don't want to make a potentially infinite loop a CS. 356# I suppose you could fold it into the select loop, too, but since 357# I've been hunting this bug for four days it's kinda like a trophy. 358# 359arbitrate: 360 test SSTAT0,0x40 jnz *select # SELDO 361 test SSTAT0,0x10 jz arbitrate # SELINGO 362 363# Wait for a successful selection. If the hardware selection 364# timer goes off, then the driver gets the interrupt, so we don't 365# need to worry about it. 366# 367select: 368 test SSTAT0,0x40 jz select # SELDO 369 jmp *select 370 371# Reselection is being initiated by a target - we've seen the BSY 372# line driven active, and we didn't do it! Enable the reselection 373# hardware, and wait for it to finish. Make a note that we've been 374# reselected, but haven't seen an IDENTIFY message from the target 375# yet. 376# 377reselect: 378 mvi SCSISEQ,0x10 # ENRSELI 379 380reselect1: 381 test SSTAT0,0x20 jz reselect1 # SELDI 382 mov SELID call initialize 383 384 and FLAGS,0x3f # reselected, no IDENTIFY 385 or FLAGS,RESELECTED 386 387# After the [re]selection, make sure that the [re]selection enable 388# bit is off. This chip is flaky enough without extra things 389# turned on. Also clear the BUSFREE bit in SSTAT1 since we'll be 390# using it shortly. 391# 392*select: 393 clr SCSISEQ 394 mvi CLRSINT1,0x8 # CLRBUSFREE 395 396# Main loop for information transfer phases. If BSY is false, then 397# we have a bus free condition, expected or not. Otherwise, wait 398# for the target to assert REQ before checking MSG, C/D and I/O 399# for the bus phase. 400# 401# We can't simply look at the values of SCSISIGI here (if we want 402# to do synchronous data transfer), because the target won't assert 403# REQ if it's already sent us some data that we haven't acknowledged 404# yet. 405# 406ITloop: 407 test SSTAT1,0x8 jnz p_busfree # BUSFREE 408 test SSTAT1,0x1 jz ITloop # REQINIT 409 410 and A,0xe0,SCSISIGI # CDI|IOI|MSGI 411 412 cmp ALLZEROS,A je p_dataout 413 cmp A,0x40 je p_datain 414 cmp A,0x80 je p_command 415 cmp A,0xc0 je p_status 416 cmp A,0xa0 je p_mesgout 417 cmp A,0xe0 je p_mesgin 418 419 mvi INTSTAT,BAD_PHASE # unknown - signal driver 420 421p_dataout: 422 mvi 0 call scsisig # !CDO|!IOO|!MSGO 423 call assert 424 call sg_load 425 426 mvi DINDEX,HADDR 427 mvi SCBARRAY+19 call bcopy_4 428 429# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR 430 mvi SCBARRAY+23 call bcopy_3 431 432 mvi DINDEX,STCNT 433 mvi SCBARRAY+23 call bcopy_3 434 435# If we are the last SG block, don't set wideodd. 436 test SCBARRAY+18,0xff jnz p_dataout_wideodd 437 mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| 438 # DIRECTION|FIFORESET 439 jmp p_dataout_rest 440 441p_dataout_wideodd: 442 mvi 0xbd call dma # WIDEODD|SCSIEN|SDMAEN|HDMAEN| 443 # DIRECTION|FIFORESET 444 445p_dataout_rest: 446# After a DMA finishes, save the final transfer pointer and count 447# back into the SCB, in case a device disconnects in the middle of 448# a transfer. Use SHADDR and STCNT instead of HADDR and HCNT, since 449# it's a reflection of how many bytes were transferred on the SCSI 450# (as opposed to the host) bus. 451# 452 mvi DINDEX,SCBARRAY+23 453 mvi STCNT call bcopy_3 454 455 mvi DINDEX,SCBARRAY+19 456 mvi SHADDR call bcopy_4 457 458 call sg_advance 459 mov SCBARRAY+18,SG_COUNT # residual S/G count 460 461 jmp ITloop 462 463p_datain: 464 mvi 0x40 call scsisig # !CDO|IOO|!MSGO 465 call assert 466 call sg_load 467 468 mvi DINDEX,HADDR 469 mvi SCBARRAY+19 call bcopy_4 470 471# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR 472 mvi SCBARRAY+23 call bcopy_3 473 474 mvi DINDEX,STCNT 475 mvi SCBARRAY+23 call bcopy_3 476 477# If we are the last SG block, don't set wideodd. 478 test SCBARRAY+18,0xff jnz p_datain_wideodd 479 mvi 0x39 call dma # SCSIEN|SDMAEN|HDMAEN| 480 # !DIRECTION|FIFORESET 481 jmp p_datain_rest 482p_datain_wideodd: 483 mvi 0xb9 call dma # WIDEODD|SCSIEN|SDMAEN|HDMAEN| 484 # !DIRECTION|FIFORESET 485p_datain_rest: 486 mvi DINDEX,SCBARRAY+23 487 mvi STCNT call bcopy_3 488 489 mvi DINDEX,SCBARRAY+19 490 mvi SHADDR call bcopy_4 491 492 call sg_advance 493 mov SCBARRAY+18,SG_COUNT # residual S/G count 494 495 jmp ITloop 496 497# Command phase. Set up the DMA registers and let 'er rip - the 498# two bytes after the SCB SCSI_cmd_length are zeroed by the driver, 499# so we can copy those three bytes directly into HCNT. 500# 501p_command: 502 mvi 0x80 call scsisig # CDO|!IOO|!MSGO 503 call assert 504 505 mvi DINDEX,HADDR 506 mvi SCBARRAY+7 call bcopy_4 507 508# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR 509 mvi SCBARRAY+11 call bcopy_3 510 511 mvi DINDEX,STCNT 512 mvi SCBARRAY+11 call bcopy_3 513 514 mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| 515 # DIRECTION|FIFORESET 516 jmp ITloop 517 518# Status phase. Wait for the data byte to appear, then read it 519# and store it into the SCB. 520# 521p_status: 522 mvi 0xc0 call scsisig # CDO|IOO|!MSGO 523 524 mvi SCBARRAY+14 call inb_first 525 jmp p_mesgin_done 526 527# Message out phase. If there is no active message, but the target 528# took us into this phase anyway, build a no-op message and send it. 529# 530p_mesgout: 531 mvi 0xa0 call scsisig # CDO|!IOO|MSGO 532 mvi 0x8 call mk_mesg # build NOP message 533 534 clr STCNT+2 535 clr STCNT+1 536 537# Set up automatic PIO transfer from MSG_START. Bit 3 in 538# SXFRCTL0 (SPIOEN) is already on. 539# 540 mvi SINDEX,MSG_START+0 541 mov DINDEX,MSG_LEN 542 543# When target asks for a byte, drop ATN if it's the last one in 544# the message. Otherwise, keep going until the message is exhausted. 545# (We can't use outb for this since it wants the input in SINDEX.) 546# 547# Keep an eye out for a phase change, in case the target issues 548# a MESSAGE REJECT. 549# 550p_mesgout2: 551 test SSTAT0,0x2 jz p_mesgout2 # SPIORDY 552 test SSTAT1,0x10 jnz p_mesgout6 # PHASEMIS 553 554 cmp DINDEX,1 jne p_mesgout3 # last byte? 555 mvi CLRSINT1,0x40 # CLRATNO - drop ATN 556 557# Write a byte to the SCSI bus. The AIC-7770 refuses to automatically 558# send ACKs in automatic PIO or DMA mode unless you make sure that the 559# "expected" bus phase in SCSISIGO matches the actual bus phase. This 560# behaviour is completely undocumented and caused me several days of 561# grief. 562# 563# After plugging in different drives to test with and using a longer 564# SCSI cable, I found that I/O in Automatic PIO mode ceased to function, 565# especially when transferring >1 byte. It seems to be much more stable 566# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is 567# polled for transfer completion - for both output _and_ input. The 568# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL 569# is accessed (like the documentation says it does), and that on a longer 570# cable run, the sequencer code was fast enough to loop back and see 571# an SPIORDY that hadn't dropped yet. 572# 573p_mesgout3: 574 mvi STCNT+0, 0x01 575 mov SCSIDATL,SINDIR 576 577p_mesgout4: 578 test SSTAT0,0x4 jz p_mesgout4 # SDONE 579 dec DINDEX 580 test DINDEX,0xff jnz p_mesgout2 581 582# If the next bus phase after ATN drops is a message out, it means 583# that the target is requesting that the last message(s) be resent. 584# 585p_mesgout5: 586 test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE 587 test SSTAT1,0x1 jz p_mesgout5 # REQINIT 588 589 and A,0xe0,SCSISIGI # CDI|IOI|MSGI 590 cmp A,0xa0 jne p_mesgout6 591 mvi 0x10 call scsisig # ATNO - re-assert ATN 592 593 jmp ITloop 594 595p_mesgout6: 596 mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS 597 and FLAGS,0xdf # no active msg 598 jmp ITloop 599 600# Message in phase. Bytes are read using Automatic PIO mode, but not 601# using inb. This alleviates a race condition, namely that if ATN had 602# to be asserted under Automatic PIO mode, it had to beat the SCSI 603# circuitry sending an ACK to the target. This showed up under heavy 604# loads and really confused things, since ABORT commands wouldn't be 605# seen by the drive after an IDENTIFY message in until it had changed 606# to a data I/O phase. 607# 608p_mesgin: 609 mvi 0xe0 call scsisig # CDO|IOO|MSGO 610 mvi A call inb_first # read the 1st message byte 611 mvi REJBYTE,A # save it for the driver 612 613 cmp ALLZEROS,A jne p_mesgin1 614 615# We got a "command complete" message, so put the SCB pointer 616# into the Queue Out, and trigger a completion interrupt. 617# Check status for non zero return and interrupt driver if needed 618# This allows the driver to interpret errors only when they occur 619# instead of always uploading the scb. If the status is SCSI_CHECK, 620# the driver will download a new scb requesting sense, to replace 621# the old one and set the SENSE sequencer flag. If the sense flag is 622# set, the sequencer imediately jumps to start working on the sense 623# command. If the kernel driver does not wish to request sense, it need 624# do nothing, and the command is allowed to complete. We don't 625# bother to post to the QOUTFIFO in the error case since it would require 626# extra work in the kernel driver to ensure that the entry was removed 627# before the command complete code tried processing it. 628 629# First check for residuals 630 test SCBARRAY+15,0xff jnz resid 631 test SCBARRAY+16,0xff jnz resid 632 test SCBARRAY+17,0xff jnz resid 633 634check_status: 635 test SCBARRAY+14,0xff jz status_ok # 0 Status? 636 mvi INTSTAT,BAD_STATUS # let driver know 637 test FLAGS,SENSE jz status_ok 638 jmp p_mesgin_done 639 640status_ok: 641# First, mark this target as free. 642 test SCBARRAY+0,0x20 jnz complete # Tagged command 643 and FUNCTION1,0x70,SCBARRAY+1 644 mov A,FUNCTION1 645 test SCBARRAY+1,0x88 jz clear_a 646 xor ACTIVE_B,A 647 jmp complete 648 649clear_a: 650 xor ACTIVE_A,A 651 652complete: 653 mov QOUTFIFO,SCBPTR 654 mvi INTSTAT,CMDCMPLT 655 jmp p_mesgin_done 656 657# If we have a residual count, interrupt and tell the host. Other 658# alternatives are to pause the sequencer on all command completes (yuck), 659# dma the resid directly to the host (slick, but a ton of instructions), or 660# have the sequencer pause itself when it encounters a non-zero resid 661# (unecessary pause just to flag the command -- yuck, but takes few instructions 662# and since it shouldn't happen that often is good enough for our purposes). 663 664resid: 665 mvi INTSTAT,RESIDUAL 666 jmp check_status 667 668# Is it an extended message? We only support the synchronous and wide data 669# transfer request messages, which will probably be in response to 670# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it - 671# apparently this can be done after any message in byte, according 672# to the SCSI-2 spec. 673# 674p_mesgin1: 675 cmp A,1 jne p_mesgin2 # extended message code? 676 677 mvi ARG_1 call inb_next # extended message length 678 mvi A call inb_next # extended message code 679 680 cmp A,1 je p_mesginSDTR # Syncronous negotiation message 681 cmp A,3 je p_mesginWDTR # Wide negotiation message 682 jmp p_mesginN 683 684p_mesginWDTR: 685 cmp ARG_1,2 jne p_mesginN # extended mesg length = 2 686 mvi A call inb_next # Width of bus 687 mvi INTSTAT,MSG_WDTR # let driver know 688 test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR? 689 690# We didn't initiate the wide negotiation, so we must respond to the request 691 and RETURN_1,0x7f # Clear the SEND_WDTR Flag 692 or FLAGS,ACTIVE_MSG 693 mvi DINDEX,MSG_START+0 694 mvi MSG_START+0 call mk_wdtr # build WDTR message 695 or SINDEX,0x10,SIGSTATE # turn on ATNO 696 call scsisig 697 jmp p_mesgin_done 698 699p_mesginSDTR: 700 cmp ARG_1,3 jne p_mesginN # extended mesg length = 3 701 mvi ARG_1 call inb_next # xfer period 702 mvi A call inb_next # REQ/ACK offset 703 mvi INTSTAT,MSG_SDTR # call driver to convert 704 705 test RETURN_1,0x80 jz p_mesgin_done# Do we need to mk_sdtr? 706 707 or FLAGS,ACTIVE_MSG 708 mvi DINDEX, MSG_START+0 709 mvi MSG_START+0 call mk_sdtr 710 or SINDEX,0x10,SIGSTATE # turn on ATNO 711 call scsisig 712 jmp p_mesgin_done 713 714# Is it a disconnect message? Set a flag in the SCB to remind us 715# and await the bus going free. 716# 717p_mesgin2: 718 cmp A,4 jne p_mesgin3 # disconnect code? 719 720 or SCBARRAY+0,0x4 # set "disconnected" bit 721 jmp p_mesgin_done 722 723# Save data pointers message? Copy working values into the SCB, 724# usually in preparation for a disconnect. 725# 726p_mesgin3: 727 cmp A,2 jne p_mesgin4 # save data pointers code? 728 729 call sg_ram2scb 730 jmp p_mesgin_done 731 732# Restore pointers message? Data pointers are recopied from the 733# SCB anyway at the start of any DMA operation, so the only thing 734# to copy is the scatter-gather values. 735# 736p_mesgin4: 737 cmp A,3 jne p_mesgin5 # restore pointers code? 738 739 call sg_scb2ram 740 jmp p_mesgin_done 741 742# Identify message? For a reconnecting target, this tells us the lun 743# that the reconnection is for - find the correct SCB and switch to it, 744# clearing the "disconnected" bit so we don't "find" it by accident later. 745# 746p_mesgin5: 747 test A,0x80 jz p_mesgin6 # identify message? 748 749 test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved 750 751 and A,0x07 # lun in lower three bits 752 or SAVED_TCL,A,SELID 753 and SAVED_TCL,0xf7 754 and A,0x08,SBLKCTL # B Channel?? 755 or SAVED_TCL,A 756 call inb_last # ACK 757 mov ALLZEROS call findSCB 758setup_SCB: 759 and SCBARRAY+0,0xfb # clear disconnect bit in SCB 760 or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY 761 762 call sg_scb2ram # implied restore pointers 763 # required on reselect 764 jmp ITloop 765get_tag: 766 mvi A call inb_first 767 cmp A,0x20 jne return # Simple Tag message? 768 mvi A call inb_next 769 call inb_last 770 test A,0xf0 jnz abort_tag # Tag in range? 771 mov SCBPTR,A 772 mov A,SAVED_TCL 773 cmp SCBARRAY+1,A jne abort_tag 774 test SCBARRAY+0,TAG_ENB jz abort_tag 775 ret 776abort_tag: 777 or SINDEX,0x10,SIGSTATE # turn on ATNO 778 call scsisig 779 mvi INTSTAT,ABORT_TAG # let driver know 780 mvi 0xd call mk_mesg # ABORT TAG message 781 ret 782 783# Message reject? Let the kernel driver handle this. If we have an 784# outstanding WDTR or SDTR negotiation, assume that it's a response from 785# the target selecting 8bit or asynchronous transfer, otherwise just ignore 786# it since we have no clue what it pertains to. 787# 788p_mesgin6: 789 cmp A,7 jne p_mesgin7 # message reject code? 790 791 mvi INTSTAT, MSG_REJECT 792 jmp p_mesgin_done 793 794# [ ADD MORE MESSAGE HANDLING HERE ] 795# 796p_mesgin7: 797 798# We have no idea what this message in is, and there's no way 799# to pass it up to the kernel, so we issue a message reject and 800# hope for the best. Since we're now using manual PIO mode to 801# read in the message, there should no longer be a race condition 802# present when we assert ATN. In any case, rejection should be a 803# rare occurrence - signal the driver when it happens. 804# 805p_mesginN: 806 or SINDEX,0x10,SIGSTATE # turn on ATNO 807 call scsisig 808 mvi INTSTAT,SEND_REJECT # let driver know 809 810 mvi 0x7 call mk_mesg # MESSAGE REJECT message 811 812p_mesgin_done: 813 call inb_last # ack & turn auto PIO back on 814 jmp ITloop 815 816 817# Bus free phase. It might be useful to interrupt the device 818# driver if we aren't expecting this. For now, make sure that 819# ATN isn't being asserted and look for a new command. 820# 821p_busfree: 822 mvi CLRSINT1,0x40 # CLRATNO 823 clr SIGSTATE 824 jmp start 825 826# Instead of a generic bcopy routine that requires an argument, we unroll 827# the two cases that are actually used, and call them explicitly. This 828# not only reduces the overhead of doing a bcopy by 2/3rds, but ends up 829# saving space in the program since you don't have to put the argument 830# into the accumulator before the call. Both functions expect DINDEX to 831# contain the destination address and SINDEX to contain the source 832# address. 833bcopy_3: 834 mov DINDIR,SINDIR 835 mov DINDIR,SINDIR 836 mov DINDIR,SINDIR ret 837 838bcopy_4: 839 mov DINDIR,SINDIR 840 mov DINDIR,SINDIR 841 mov DINDIR,SINDIR 842 mov DINDIR,SINDIR ret 843 844bcopy_3_dfdat: 845 mov DINDIR,DFDAT 846 mov DINDIR,DFDAT 847 mov DINDIR,DFDAT ret 848 849bcopy_4_dfdat: 850 mov DINDIR,DFDAT 851 mov DINDIR,DFDAT 852 mov DINDIR,DFDAT 853 mov DINDIR,DFDAT ret 854 855# Locking the driver out, build a one-byte message passed in SINDEX 856# if there is no active message already. SINDEX is returned intact. 857# 858mk_mesg: 859 mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE 860 test FLAGS,ACTIVE_MSG jnz mk_mesg1 # active message? 861 862 or FLAGS,ACTIVE_MSG # if not, there is now 863 mvi MSG_LEN,1 # length = 1 864 mov MSG_START+0,SINDEX # 1-byte message 865 866mk_mesg1: 867 mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE 868 869# Carefully read data in Automatic PIO mode. I first tried this using 870# Manual PIO mode, but it gave me continual underrun errors, probably 871# indicating that I did something wrong, but I feel more secure leaving 872# Automatic PIO on all the time. 873# 874# According to Adaptec's documentation, an ACK is not sent on input from 875# the target until SCSIDATL is read from. So we wait until SCSIDATL is 876# latched (the usual way), then read the data byte directly off the bus 877# using SCSIBUSL. When we have pulled the ATN line, or we just want to 878# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 879# spec guarantees that the target will hold the data byte on the bus until 880# we send our ACK. 881# 882# The assumption here is that these are called in a particular sequence, 883# and that REQ is already set when inb_first is called. inb_{first,next} 884# use the same calling convention as inb. 885# 886inb_first: 887 clr STCNT+2 888 clr STCNT+1 889 mov DINDEX,SINDEX 890 mov DINDIR,SCSIBUSL ret # read byte directly from bus 891 892inb_next: 893 mov DINDEX,SINDEX # save SINDEX 894 895 mvi STCNT+0,1 # xfer one byte 896 mov NONE,SCSIDATL # dummy read from latch to ACK 897inb_next1: 898 test SSTAT0,0x4 jz inb_next1 # SDONE 899inb_next2: 900 test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte 901 mov DINDIR,SCSIBUSL ret # read byte directly from bus 902 903inb_last: 904 mvi STCNT+0,1 # ACK with dummy read 905 mov NONE,SCSIDATL 906inb_last1: 907 test SSTAT0,0x4 jz inb_last1 # wait for completion 908 ret 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 917dma1: 918dma2: 919 test SSTAT0,0x1 jnz dma3 # DMADONE 920 test SSTAT1,0x10 jz dma1 # PHASEMIS, ie. underrun 921 922# We will be "done" DMAing when the transfer count goes to zero, or 923# the target changes the phase (in light of this, it makes sense that 924# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 925# doing a SCSI->Host transfer, the data FIFO should be flushed auto- 926# magically on STCNT=0 or a phase change, so just wait for FIFO empty 927# status. 928# 929dma3: 930 test SINDEX,0x4 jnz dma5 # DIRECTION 931dma4: 932 test DFSTATUS,0x1 jz dma4 # !FIFOEMP 933 934# Now shut the DMA enables off, and copy STCNT (ie. the underrun 935# amount, if any) to the SCB registers; SG_COUNT will get copied to 936# the SCB's residual S/G count field after sg_advance is called. Make 937# sure that the DMA enables are actually off first lest we get an ILLSADDR. 938# 939dma5: 940 clr DFCNTRL # disable DMA 941dma6: 942 test DFCNTRL,0x38 jnz dma6 # SCSIENACK|SDMAENACK|HDMAENACK 943 944 mvi DINDEX,SCBARRAY+15 945 mvi STCNT call bcopy_3 946 947 ret 948 949dma_finish: 950 test DFSTATUS,0x8 jz dma_finish # HDONE 951 952 clr DFCNTRL # disable DMA 953dma_finish2: 954 test DFCNTRL,0x8 jnz dma_finish2 # HDMAENACK 955 ret 956 957# Common SCSI initialization for selection and reselection. Expects 958# the target SCSI ID to be in the upper four bits of SINDEX, and A's 959# contents are stomped on return. 960# 961initialize: 962 and SINDEX,0xf0 # Get target ID 963 and A,0x0f,SCSIID 964 or SINDEX,A 965 mov SCSIID,SINDEX 966 967# Esundry initialization. 968# 969 clr DROPATN 970 clr SIGSTATE 971 972# Turn on Automatic PIO mode now, before we expect to see a REQ 973# from the target. It shouldn't hurt anything to leave it on. Set 974# CLRCHN here before the target has entered a data transfer mode - 975# with synchronous SCSI, if you do it later, you blow away some 976# data in the SCSI FIFO that the target has already sent to you. 977# 978 mvi SXFRCTL0,0x8a # DFON|SPIOEN|CLRCHN 979 980# Initialize scatter-gather pointers by setting up the working copy 981# in scratch RAM. 982# 983 call sg_scb2ram 984 985# Initialize SCSIRATE with the appropriate value for this target. 986# 987 call ndx_dtr 988 mov SCSIRATE,SINDIR ret 989 990# Assert that if we've been reselected, then we've seen an IDENTIFY 991# message. 992# 993assert: 994 test FLAGS,RESELECTED jz return # reselected? 995 test FLAGS,IDENTIFY_SEEN jnz return # seen IDENTIFY? 996 997 mvi INTSTAT,NO_IDENT ret # no - cause a kernel panic 998 999# Find out if disconnection is ok from the information the BIOS has left 1000# us. The tcl from SCBARRAY+1 should be in SINDEX; A will 1001# contain either 0x40 (disconnection ok) or 0x00 (disconnection not ok) 1002# on exit. 1003# 1004# To allow for wide or twin busses, we check the upper bit of the target ID 1005# and the channel ID and look at the appropriate disconnect register. 1006# 1007disconnect: 1008 and FUNCTION1,0x70,SINDEX # strip off extra just in case 1009 mov A,FUNCTION1 1010 test SINDEX, 0x88 jz disconnect_a 1011 1012 test DISC_DSB_B,A jz disconnect1 # bit nonzero if DISabled 1013 clr A ret 1014 1015disconnect_a: 1016 test DISC_DSB_A,A jz disconnect1 # bit nonzero if DISabled 1017 clr A ret 1018 1019disconnect1: 1020 mvi A,0x40 ret 1021 1022# Locate the SCB matching the target ID/channel/lun in SAVED_TCL and switch 1023# the SCB to it. Have the kernel print a warning message if it can't be 1024# found, and generate an ABORT message to the target. SINDEX should be 1025# cleared on call. 1026# 1027findSCB: 1028 mov A,SAVED_TCL 1029 mov SCBPTR,SINDEX # switch to new SCB 1030 cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match? 1031 test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected 1032 test SCBARRAY+0,TAG_ENB jnz get_tag 1033 ret 1034 1035findSCB1: 1036 inc SINDEX 1037 mov A,SCBCOUNT 1038 cmp SINDEX,A jne findSCB 1039 1040 mvi INTSTAT,NO_MATCH # not found - signal kernel 1041 mvi 0x6 call mk_mesg # ABORT message 1042 1043 or SINDEX,0x10,SIGSTATE # assert ATNO 1044 call scsisig 1045 ret 1046 1047# Make a working copy of the scatter-gather parameters in the SCB. 1048# 1049sg_scb2ram: 1050 mov SG_COUNT,SCBARRAY+2 1051 1052 mvi DINDEX,SG_NEXT 1053 mvi SCBARRAY+3 call bcopy_4 1054 1055 mvi SG_NOLOAD,0x80 1056 test SCBARRAY+0,0x10 jnz return # don't reload s/g? 1057 clr SG_NOLOAD ret 1058 1059# Copying RAM values back to SCB, for Save Data Pointers message. 1060# 1061sg_ram2scb: 1062 mov SCBARRAY+2,SG_COUNT 1063 1064 mvi DINDEX,SCBARRAY+3 1065 mvi SG_NEXT call bcopy_4 1066 1067 and SCBARRAY+0,0xef,SCBARRAY+0 1068 test SG_NOLOAD,0x80 jz return # reload s/g? 1069 or SCBARRAY+0,SG_LOAD ret 1070 1071# Load a struct scatter if needed and set up the data address and 1072# length. If the working value of the SG count is nonzero, then 1073# we need to load a new set of values. 1074# 1075# This, like the above DMA, assumes a little-endian host data storage. 1076# 1077sg_load: 1078 test SG_COUNT,0xff jz return # SG being used? 1079 test SG_NOLOAD,0x80 jnz return # don't reload s/g? 1080 1081 clr HCNT+2 1082 clr HCNT+1 1083 mvi HCNT+0,SG_SIZEOF 1084 1085 mvi DINDEX,HADDR 1086 mvi SG_NEXT call bcopy_4 1087 1088 mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET 1089 1090# Wait for DMA from host memory to data FIFO to complete, then disable 1091# DMA and wait for it to acknowledge that it's off. 1092# 1093 1094 call dma_finish 1095 1096# Copy data from FIFO into SCB data pointer and data count. This assumes 1097# that the struct scatterlist has this structure (this and sizeof(struct 1098# scatterlist) == 12 are asserted in aic7xxx.c): 1099# 1100# struct scatterlist { 1101# char *address; /* four bytes, little-endian order */ 1102# ... /* four bytes, ignored */ 1103# unsigned short length; /* two bytes, little-endian order */ 1104# } 1105# 1106 1107# Not in FreeBSD. the scatter list entry is only 8 bytes. 1108# 1109# struct ahc_dma_seg { 1110# physaddr addr; /* four bytes, little-endian order */ 1111# long len; /* four bytes, little endian order */ 1112# }; 1113# 1114 1115 mvi DINDEX, SCBARRAY+19 1116 call bcopy_4_dfdat 1117 1118# For Linux, we must throw away four bytes since there is a 32bit gap 1119# in the middle of a struct scatterlist 1120# mov NONE,DFDAT 1121# mov NONE,DFDAT 1122# mov NONE,DFDAT 1123# mov NONE,DFDAT 1124 1125 call bcopy_3_dfdat #Only support 24 bit length. 1126 ret 1127 1128# Advance the scatter-gather pointers only IF NEEDED. If SG is enabled, 1129# and the SCSI transfer count is zero (note that this should be called 1130# right after a DMA finishes), then move the working copies of the SG 1131# pointer/length along. If the SCSI transfer count is not zero, then 1132# presumably the target is disconnecting - do not reload the SG values 1133# next time. 1134# 1135sg_advance: 1136 test SG_COUNT,0xff jz return # s/g enabled? 1137 1138 test STCNT+0,0xff jnz sg_advance1 # SCSI transfer count nonzero? 1139 test STCNT+1,0xff jnz sg_advance1 1140 test STCNT+2,0xff jnz sg_advance1 1141 1142 clr SG_NOLOAD # reload s/g next time 1143 dec SG_COUNT # one less segment to go 1144 1145 clr A # add sizeof(struct scatter) 1146 add SG_NEXT+0,SG_SIZEOF,SG_NEXT+0 1147 adc SG_NEXT+1,A,SG_NEXT+1 1148 adc SG_NEXT+2,A,SG_NEXT+2 1149 adc SG_NEXT+3,A,SG_NEXT+3 ret 1150 1151sg_advance1: 1152 mvi SG_NOLOAD,0x80 ret # don't reload s/g next time 1153 1154# Add the array base SYNCNEG to the target offset (the target address 1155# is in SCSIID), and return the result in SINDEX. The accumulator 1156# contains the 3->8 decoding of the target ID on return. 1157# 1158ndx_dtr: 1159 shr A,SCSIID,4 1160 test SBLKCTL,0x08 jz ndx_dtr_2 1161 or A,0x08 # Channel B entries add 8 1162ndx_dtr_2: 1163 add SINDEX,SYNCNEG,A 1164 1165 and FUNCTION1,0x70,SCSIID # 3-bit target address decode 1166 mov A,FUNCTION1 ret 1167 1168# If we need to negotiate transfer parameters, build the WDTR or SDTR message 1169# starting at the address passed in SINDEX. DINDEX is modified on return. 1170# The SCSI-II spec requires that Wide negotiation occur first and you can 1171# only negotiat one or the other at a time otherwise in the event of a message 1172# reject, you wouldn't be able to tell which message was the culpret. 1173# 1174mk_dtr: 1175 test SCBARRAY+0,0xc0 jz return # NEEDWDTR|NEEDSDTR 1176 test SCBARRAY+0,NEEDWDTR jnz mk_wdtr_16bit 1177 or FLAGS, MAX_SYNC # Force an offset of 15 1178 1179mk_sdtr: 1180 mvi DINDIR,1 # extended message 1181 mvi DINDIR,3 # extended message length = 3 1182 mvi DINDIR,1 # SDTR code 1183 call sdtr_to_rate 1184 mov DINDIR,RETURN_1 # REQ/ACK transfer period 1185 test FLAGS, MAX_SYNC jnz mk_sdtr_max_sync 1186 and DINDIR,0xf,SINDIR # Sync Offset 1187 1188mk_sdtr_done: 1189 add MSG_LEN,-MSG_START+0,DINDEX ret # update message length 1190 1191mk_sdtr_max_sync: 1192# We're initiating sync negotiation, so request the max offset we can (15) 1193 mvi DINDIR, 0x0f 1194 xor FLAGS, MAX_SYNC 1195 jmp mk_sdtr_done 1196 1197mk_wdtr_16bit: 1198 mvi ARG_1,BUS_16_BIT 1199mk_wdtr: 1200 mvi DINDIR,1 # extended message 1201 mvi DINDIR,2 # extended message length = 2 1202 mvi DINDIR,3 # WDTR code 1203 mov DINDIR,ARG_1 # bus width 1204 1205 add MSG_LEN,-MSG_START+0,DINDEX ret # update message length 1206 1207# Set SCSI bus control signal state. This also saves the last-written 1208# value into a location where the higher-level driver can read it - if 1209# it has to send an ABORT or RESET message, then it needs to know this 1210# so it can assert ATN without upsetting SCSISIGO. The new value is 1211# expected in SINDEX. Change the actual state last to avoid contention 1212# from the driver. 1213# 1214scsisig: 1215 mov SIGSTATE,SINDEX 1216 mov SCSISIGO,SINDEX ret 1217 1218sdtr_to_rate: 1219 call ndx_dtr # index scratch space for target 1220 shr A,SINDIR,0x4 1221 dec SINDEX #Preserve SINDEX 1222 and A,0x7 1223 clr RETURN_1 1224sdtr_to_rate_loop: 1225 test A,0x0f jz sdtr_to_rate_done 1226 add RETURN_1,0x18 1227 dec A 1228 jmp sdtr_to_rate_loop 1229sdtr_to_rate_done: 1230 shr RETURN_1,0x2 1231 add RETURN_1,0x18 ret 1232 1233return: 1234 ret 1235