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