aic7xxx.seq (5326) | aic7xxx.seq (5562) |
---|---|
1# @(#)aic7xxx.seq 1.31 94/11/25 jda | 1# @(#)aic7xxx.seq 1.32 94/11/29 jda |
2# | 2# |
3# Adaptec 274x device driver for Linux. | 3# Adaptec 274x/284x/294x 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 | 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 | 20VERSION AIC7XXX_SEQ_VERSION 1.32 |
21 22SCBMASK = 0x1f 23 24SCSISEQ = 0x00 25SXFRCTL0 = 0x01 26SXFRCTL1 = 0x02 27SCSISIGI = 0x03 28SCSISIGO = 0x03 --- 63 unchanged lines hidden (view full) --- 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 | 21 22SCBMASK = 0x1f 23 24SCSISEQ = 0x00 25SXFRCTL0 = 0x01 26SXFRCTL1 = 0x02 27SCSISIGI = 0x03 28SCSISIGO = 0x03 --- 63 unchanged lines hidden (view full) --- 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 |
100SIGNAL_WDTR = 0x61 |
|
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# | 101 102# The host adapter card (at least the BIOS) uses 20-2f for SCSI 103# device information, 32-33 and 5a-5f as well. As it turns out, the 104# BIOS trashes 20-2f, writing the synchronous negotiation results 105# on top of the BIOS values, so we re-use those for our per-target 106# scratchspace (actually a value that can be copied directly into 107# SCSIRATE). The kernel driver will enable synchronous negotiation 108# for all targets that have a value other than 0 in the lower four 109# bits of the target scratch space. This should work irregardless of 110# whether the bios has been installed. NEEDSDTR has one bit per target 111# indicating if an SDTR message is needed for that device - this will 112# be set initially (based on a search through the target scratch space), 113# as well as after a bus reset condition. 114# 115# The high bit of DROPATN is set if ATN should be dropped before the ACK 116# when outb is called. REJBYTE contains the first byte of a MESSAGE IN 117# message, so the driver can report an intelligible error if a message is 118# rejected. 119# |
119# RESELECT's high bit is true if we are currently handling a reselect; | 120# FLAGS'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 | 121# its next-highest bit is true ONLY IF we've seen an IDENTIFY message 122# from the reselecting target. If we haven't had IDENTIFY, then we have 123# no idea what the lun is, and we can't select the right SCB register 124# bank, so force a kernel panic if the target attempts a data in/out or 125# command phase instead of corrupting something. 126# 127# Note that SG_NEXT occupies four bytes. 128# 129SYNCNEG = 0x20 130 131DROPATN = 0x30 132REJBYTE = 0x31 133DISC_DSB_A = 0x32 134DISC_DSB_B = 0x33 |
134RESELECT = 0x34 | |
135 | 135 |
136MSG_FLAGS = 0x35 | 136NEEDWDTR_A = 0x34 137NEEDWDTR_B = 0x35 138 |
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 --- 13 unchanged lines hidden (view full) --- 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 | 139MSG_LEN = 0x36 140MSG_START+0 = 0x37 141MSG_START+1 = 0x38 142MSG_START+2 = 0x39 143MSG_START+3 = 0x3a 144MSG_START+4 = 0x3b 145MSG_START+5 = 0x3c 146-MSG_START+0 = 0xc9 # 2's complement of MSG_START+0 --- 13 unchanged lines hidden (view full) --- 160SG_NEXT+1 = 0x53 161SG_NEXT+2 = 0x54 162SG_NEXT+3 = 0x55 163 164SCBCOUNT = 0x56 # the actual number of SCBs 165FLAGS = 0x57 # Device configuration flags 166TWIN_BUS = 0x01 167WIDE_BUS = 0x02 |
168CHECK_DTR = 0x08 169SENSE = 0x10 170ACTIVE_MSG = 0x20 171IDENTIFY_SEEN = 0x40 172RESELECTED = 0x80 |
|
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: | 173 174ACTIVE_A = 0x58 175ACTIVE_B = 0x59 176 177# Poll QINCNT for work - the lower bits contain 178# the number of entries in the Queue In FIFO. 179# 180start: |
181 test FLAGS,SENSE jnz start_sense |
|
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 --- 18 unchanged lines hidden (view full) --- 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 | 182 test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device? 183# For fairness, we check the other bus first, since we just finished a 184# transaction on the current channel. 185 xor SBLKCTL,0x08 # Toggle to the other bus 186 test SCSISIGI,0x4 jnz reselect # BSYI 187 xor SBLKCTL,0x08 # Toggle to the original bus 188start2: 189 test SCSISIGI,0x4 jnz reselect # BSYI --- 18 unchanged lines hidden (view full) --- 208 and FUNCTION1,0x70,SCBARRAY+1 209 mov A,FUNCTION1 210 test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel 211 212 test ACTIVE_B,A jnz requeue 213 or ACTIVE_B,A # Mark the current target as busy 214 jmp start_scb 215 |
216start_sense: 217# Clear the SENSE flag first, then do a normal start_scb 218 and FLAGS,0xef 219 jmp start_scb 220 |
|
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: | 221# Place the currently active back on the queue for later processing 222requeue: 223 mov QINFIFO, SCBPTR 224 jmp start 225 226test_a: 227 test ACTIVE_A,A jnz requeue 228 or ACTIVE_A,A # Mark the current target as busy 229 230start_scb: |
218 and A,0x08,SCBARRAY+1 219 mov SBLKCTL,A # select channel, !wide | 231 and SINDEX,0x08,SCBARRAY+1 232 and A,WIDE_BUS,FLAGS # Wide bus? 233 or SINDEX,A 234 mov SBLKCTL,SINDEX # select channel, bus width |
220 mov SCBARRAY+1 call initialize 221 clr SG_NOLOAD | 235 mov SCBARRAY+1 call initialize 236 clr SG_NOLOAD |
222 clr RESELECT | 237 and FLAGS,0x3f # !RESELECTING |
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? | 238 239# As soon as we get a successful selection, the target should go 240# into the message out phase since we have ATN asserted. Prepare 241# the message to send, locking out the device driver. If the device 242# driver hasn't beaten us with an ABORT or RESET message, then tack 243# on an SDTR negotiation if required. 244# 245# Messages are stored in scratch RAM starting with a flag byte (high bit 246# set means active message), one length byte, and then the message itself. 247# 248 mov SCBARRAY+1 call disconnect # disconnect ok? 249 250 and SINDEX,0x7,SCBARRAY+1 # lun 251 or SINDEX,A # return value from disconnect 252 or SINDEX,0x80 call mk_mesg # IDENTIFY message 253 254 mov A,SINDEX 255 cmp MSG_START+0,A jne !message # did driver beat us? |
241 mvi MSG_START+1 call mk_sdtr # build SDTR message if needed | 256 test FLAGS,CHECK_DTR jz !message # Don't even bother with DTR? 257 mvi MSG_START+1 call mk_dtr # build DTR 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 --- 31 unchanged lines hidden (view full) --- 281# 282reselect: 283 mvi SCSISEQ,0x10 # ENRSELI 284 285reselect1: 286 test SSTAT0,0x20 jz reselect1 # SELDI 287 mov SELID call initialize 288 | 258 259!message: 260 261# Enable selection phase as an initiator, and do automatic ATN 262# after the selection. 263# 264 mvi SCSISEQ,0x48 # ENSELO|ENAUTOATNO 265 --- 31 unchanged lines hidden (view full) --- 297# 298reselect: 299 mvi SCSISEQ,0x10 # ENRSELI 300 301reselect1: 302 test SSTAT0,0x20 jz reselect1 # SELDI 303 mov SELID call initialize 304 |
289 mvi RESELECT,0x80 # reselected, no IDENTIFY | 305 and FLAGS,0x3f # reselected, no IDENTIFY 306 or FLAGS,RESELECTED |
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 --- 192 unchanged lines hidden (view full) --- 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 | 307 308# After the [re]selection, make sure that the [re]selection enable 309# bit is off. This chip is flaky enough without extra things 310# turned on. Also clear the BUSFREE bit in SSTAT1 since we'll be 311# using it shortly. 312# 313*select: 314 clr SCSISEQ --- 192 unchanged lines hidden (view full) --- 507 and A,0xe0,SCSISIGI # CDI|IOI|MSGI 508 cmp A,0xa0 jne p_mesgout6 509 mvi 0x10 call scsisig # ATNO - re-assert ATN 510 511 jmp ITloop 512 513p_mesgout6: 514 mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS |
498 clr MSG_FLAGS # no active msg | 515 and FLAGS,0xdf # 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 --- 16 unchanged lines hidden (view full) --- 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? | 516 jmp ITloop 517 518# Message in phase. Bytes are read using Automatic PIO mode, but not 519# using inb. This alleviates a race condition, namely that if ATN had 520# to be asserted under Automatic PIO mode, it had to beat the SCSI 521# circuitry sending an ACK to the target. This showed up under heavy 522# loads and really confused things, since ABORT commands wouldn't be 523# seen by the drive after an IDENTIFY message in until it had changed --- 16 unchanged lines hidden (view full) --- 540# working on it. If the kernel driver does not wish to request sense, 541# the sequencer program counter is incremented by 1, preventing another run 542# on the current SCB and the command is allowed to complete. We don't 543# bother to post to the QOUTFIFO in the error case since it would require 544# extra work in the kernel driver to ensure that the entry was removed 545# before the command complete code tried processing it. 546 547 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 | 548 mvi INTSTAT,STATUS_ERROR # let driver know |
533 jmp start_scb | 549 test FLAGS,SENSE jz status_ok 550 jmp p_mesgin_done |
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 | 551 552status_ok: 553 554# First, mark this target as free. 555 and FUNCTION1,0x70,SCBARRAY+1 556 mov A,FUNCTION1 557 test SCBARRAY+1,0x88 jz clear_a 558 xor ACTIVE_B,A 559 jmp complete 560 561clear_a: 562 xor ACTIVE_A,A 563 564complete: 565 mov QOUTFIFO,SCBPTR 566 mvi INTSTAT,0x02 # CMDCMPLT 567 jmp p_mesgin_done 568 |
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 - | 569# Is it an extended message? We only support the synchronous and wide data 570# transfer request messages, which will probably be in response to 571# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it - |
555# apparently this can be done after any message in byte, according 556# to the SCSI-2 spec. 557# | 572# apparently this can be done after any message in byte, according 573# to the SCSI-2 spec. 574# |
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 | 575p_mesgin1: 576 cmp A,1 jne p_mesgin2 # extended message code? 577 |
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 | 578 mvi ARG_1 call inb_next # extended message length 579 mvi A call inb_next # extended message code |
568 | 580 |
581 cmp A,1 je p_mesginSDTR # Syncronous negotiation message 582 cmp A,3 je p_mesginWDTR # Wide negotiation message 583 jmp p_mesginN 584 585p_mesginWDTR: 586 cmp ARG_1,2 jne p_mesginN # extended mesg length = 2 587 mvi A call inb_next # Width of bus 588 mvi INTSTAT,SIGNAL_WDTR # let driver know 589 test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR? 590 591# We didn't initiate the wide negotiation, so we must respond to the request 592 and RETURN_1,0x7f # Clear the SEND_WDTR Flag 593 or FLAGS,ACTIVE_MSG 594 mvi MSG_START+0 call mk_wdtr # build WDTR message 595 or SINDEX,0x10,SIGSTATE # turn on ATNO 596 call scsisig 597 jmp p_mesgin_done 598 599p_mesginSDTR: 600 cmp ARG_1,3 jne p_mesginN # extended mesg length = 3 |
|
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 | 601 mvi ARG_1 call inb_next # xfer period 602 mvi A call inb_next # REQ/ACK offset 603 mvi INTSTAT,SIGNAL_4 # call driver to convert 604 |
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 | 605 test RETURN_1,0x80 jz p_mesgin_done# Do we need to mk_sdtr? |
580 | 606 |
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 | 607 or FLAGS,ACTIVE_MSG 608 mvi MSG_START+0 call mk_sdtr 609 or SINDEX,0x10,SIGSTATE # turn on ATNO 610 call scsisig |
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 --- 29 unchanged lines hidden (view full) --- 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# | 611 jmp p_mesgin_done 612 613# Is it a disconnect message? Set a flag in the SCB to remind us 614# and await the bus going free. 615# 616p_mesgin2: 617 cmp A,4 jne p_mesgin3 # disconnect code? 618 --- 29 unchanged lines hidden (view full) --- 648 test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved 649 650 mov A call findSCB # switch to correct SCB 651 652# If a active message is present after calling findSCB, then either it 653# or the driver is trying to abort the command. Either way, something 654# untoward has happened and we should just leave it alone. 655# |
641 test MSG_FLAGS,0x80 jnz p_mesgin_done | 656 test FLAGS,ACTIVE_MSG jnz p_mesgin_done |
642 643 and SCBARRAY+0,0xfb # clear disconnect bit in SCB | 657 658 and SCBARRAY+0,0xfb # clear disconnect bit in SCB |
644 mvi RESELECT,0xc0 # make note of IDENTIFY | 659 or FLAGS,0xc0 # make note of IDENTIFY |
645 646 call sg_scb2ram # implied restore pointers 647 # required on reselect 648 jmp p_mesgin_done 649 | 660 661 call sg_scb2ram # implied restore pointers 662 # required on reselect 663 jmp p_mesgin_done 664 |
650# Message reject? If we have an outstanding SDTR negotiation, assume 651# that it's a response from the target selecting asynchronous transfer, | 665# Message reject? If we have an outstanding WDTR or SDTR negotiation, assume 666# that it's a response from the target selecting 8bit or 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 | 667# otherwise just ignore it since we have no clue what it pertains to. 668# 669# XXX - I don't have a device that responds this way. Does this code 670# actually work? 671# 672p_mesgin6: 673 cmp A,7 jne p_mesgin7 # message reject code? 674 675 and FUNCTION1,0x70,SCSIID # outstanding SDTR message? 676 mov A,FUNCTION1 677 678 test SBLKCTL,0x08 jnz p_mesgin6_b 679 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 | 680 test NEEDWDTR_A,A jnz clear_wdtr_a 681 test NEEDSDTR_A,A jnz clear_sdtr_a 682 jmp p_mesgin_done # no - ignore rejection 683 684clear_sdtr_a: 685 call ndx_dtr # note use of asynch xfer |
667 mov DINDEX,SINDEX | 686 mov DINDEX,SINDEX |
668 clr DINDIR | 687 and DINDIR,0x80,SINDIR |
669 670 not A 671 and NEEDSDTR_A,A | 688 689 not A 690 and NEEDSDTR_A,A |
672 jmp p_mesgin6_done | 691 jmp clear_sdtr_done |
673 | 692 |
693clear_wdtr_a: 694 call ndx_dtr # note use of 8bit xfer 695 mov DINDEX,SINDEX 696 and DINDIR,0x7f,SINDIR 697 698 not A 699 and NEEDWDTR_A,A 700 jmp clear_wdtr_done 701 |
|
674p_mesgin6_b: | 702p_mesgin6_b: |
675 test NEEDSDTR_B,A jz p_mesgin_done # no - ignore rejection 676 call ndx_sdtr # note use of asynch xfer | 703 test NEEDWDTR_B,A jnz clear_wdtr_b 704 test NEEDSDTR_B,A jnz clear_sdtr_b 705 jmp p_mesgin_done # no - ignore rejection 706 707clear_wdtr_b: 708 call ndx_dtr # note use of 8bit xfer |
677 mov DINDEX,SINDEX | 709 mov DINDEX,SINDEX |
678 clr DINDIR | 710 and DINDIR,0x7f,SINDIR |
679 680 not A | 711 712 not A |
713 and NEEDWDTR_B,A 714 715clear_wdtr_done: 716 and SCSIRATE,0x7f # select 8bit xfer 717 jmp p_mesgin_done 718 719clear_sdtr_b: 720 call ndx_dtr # note use of asynch xfer 721 mov DINDEX,SINDEX 722 and DINDIR,0x80,SINDIR 723 724 not A |
|
681 and NEEDSDTR_B,A 682 | 725 and NEEDSDTR_B,A 726 |
683p_mesgin6_done: 684 685 clr SCSIRATE # select asynch xfer | 727clear_sdtr_done: 728 and SCSIRATE,0xf0 # 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 --- 32 unchanged lines hidden (view full) --- 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 | 729 jmp p_mesgin_done 730 731# [ ADD MORE MESSAGE HANDLING HERE ] 732# 733p_mesgin7: 734 735# We have no idea what this message in is, and there's no way 736# to pass it up to the kernel, so we issue a message reject and --- 32 unchanged lines hidden (view full) --- 769 cmp ALLZEROS,A jne bcopy 770 ret 771 772# Locking the driver out, build a one-byte message passed in SINDEX 773# if there is no active message already. SINDEX is returned intact. 774# 775mk_mesg: 776 mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE |
734 test MSG_FLAGS,0x80 jnz mk_mesg1 # active message? | 777 test FLAGS,ACTIVE_MSG jnz mk_mesg1 # active message? |
735 | 778 |
736 mvi MSG_FLAGS,0x80 # if not, there is now | 779 or FLAGS,ACTIVE_MSG # 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 --- 89 unchanged lines hidden (view full) --- 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: | 780 mvi MSG_LEN,1 # length = 1 781 mov MSG_START+0,SINDEX # 1-byte message 782 783mk_mesg1: 784 mvi SEQCTL,0x10 # !PAUSEDIS|FASTMODE 785 ret 786 787# Input byte in Automatic PIO mode. The address to store the byte --- 89 unchanged lines hidden (view full) --- 877# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are 878# doing a SCSI->Host transfer, the data FIFO should be flushed auto- 879# magically on STCNT=0 or a phase change, so just wait for FIFO empty 880# status. 881# 882dma3: 883 test SINDEX,0x4 jnz dma5 # DIRECTION 884dma4: |
842 test DFSTATUS,0x1 jz dma4 # FIFOEMP | 885 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 --- 17 unchanged lines hidden (view full) --- 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: | 886 887# Now shut the DMA enables off, and copy STCNT (ie. the underrun 888# amount, if any) to the SCB registers; SG_COUNT will get copied to 889# the SCB's residual S/G count field after sg_advance is called. Make 890# sure that the DMA enables are actually off first lest we get an ILLSADDR. 891# 892dma5: 893 clr DFCNTRL # disable DMA --- 17 unchanged lines hidden (view full) --- 911 test FLAGS,WIDE_BUS jnz initialize_wide 912 and A,0x7,SCSICONF_A # SCSI_ID_A[210] 913 jmp initialize_2 914initialize_b: 915 and A,0x7,SCSICONF_B # SCSI_ID_B[210] 916 mvi SCSICONF_B jmp initialize_2 917 918initialize_wide: |
876 and A, 0xf,SCSICONF_B | 919 and A,0x0f,SCSICONF_B # SCSI_ID_B[210] |
877 878initialize_2: 879 or SCSIID,A 880 881# Esundry initialization. 882# 883 clr DROPATN 884 clr SIGSTATE --- 10 unchanged lines hidden (view full) --- 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] | 920 921initialize_2: 922 or SCSIID,A 923 924# Esundry initialization. 925# 926 clr DROPATN 927 clr SIGSTATE --- 10 unchanged lines hidden (view full) --- 938 939# Set SCSI bus parity checking and the selection timeout value, 940# and enable the hardware selection timer. Set the SELTO interrupt 941# to signal the driver. 942# 943# STPWEN is 7870-specific, enabling an external termination power source. 944# 945 and A,0x38,SINDIR # PARITY_ENB|SEL_TIM[10] |
903 or SXFRCTL1,0x7,A # ENSTIMER|ACTNEGEN|STPWEN | 946 or SXFRCTL1,0x7,A # ENSTIMER|ACTBEGEB|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# | 947 mvi SIMODE1,0x84 # ENSELTIMO|ENSCSIPERR 948 949# Initialize scatter-gather pointers by setting up the working copy 950# in scratch RAM. 951# 952 call sg_scb2ram 953 954# Initialize SCSIRATE with the appropriate value for this target. 955# |
913 call ndx_sdtr | 956 call ndx_dtr |
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: | 957 mov SCSIRATE,SINDIR 958 ret 959 960# Assert that if we've been reselected, then we've seen an IDENTIFY 961# message. 962# 963assert: |
921 test RESELECT,0x80 jz assert1 # reselected? 922 test RESELECT,0x40 jnz assert1 # seen IDENTIFY? | 964 test FLAGS,RESELECTED jz assert1 # reselected? 965 test FLAGS,IDENTIFY_SEEN 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 --- 175 unchanged lines hidden (view full) --- 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# | 966 967 mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic 968 969assert1: 970 ret 971 972# Find out if disconnection is ok from the information the BIOS has left 973# us. The tcl from SCBARRAY+1 should be in SINDEX; A will --- 175 unchanged lines hidden (view full) --- 1149 mvi SG_NOLOAD,0x80 # don't reload s/g next time 1150sg_advance2: 1151 ret 1152 1153# Add the array base SYNCNEG to the target offset (the target address 1154# is in SCSIID), and return the result in SINDEX. The accumulator 1155# contains the 3->8 decoding of the target ID on return. 1156# |
1114ndx_sdtr: | 1157ndx_dtr: |
1115 shr A,SCSIID,4 | 1158 shr A,SCSIID,4 |
1116 test SBLKCTL,0x08 jz ndx_sdtr_2 | 1159 test SBLKCTL,0x08 jz ndx_dtr_2 |
1117 or A,0x08 # Channel B entries add 8 | 1160 or A,0x08 # Channel B entries add 8 |
1118ndx_sdtr_2: | 1161ndx_dtr_2: |
1119 add SINDEX,SYNCNEG,A 1120 1121 and FUNCTION1,0x70,SCSIID # 3-bit target address decode 1122 mov A,FUNCTION1 ret 1123 | 1162 add SINDEX,SYNCNEG,A 1163 1164 and FUNCTION1,0x70,SCSIID # 3-bit target address decode 1165 mov A,FUNCTION1 ret 1166 |
1124# If we need to negotiate transfer parameters, build the SDTR message | 1167# If we need to negotiate transfer parameters, build the WDTR or SDTR message |
1125# starting at the address passed in SINDEX. DINDEX is modified on return. | 1168# starting at the address passed in SINDEX. DINDEX is modified on return. |
1169# The SCSI-II spec requires that Wide negotiation occur first and you can 1170# only negotiat one or the other at a time otherwise in the event of a message 1171# reject, you wouldn't be able to tell which message was the culpret. |
|
1126# | 1172# |
1127mk_sdtr: | 1173mk_dtr: |
1128 mov DINDEX,SINDEX # save SINDEX 1129 | 1174 mov DINDEX,SINDEX # save SINDEX 1175 |
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? | 1176 call ndx_dtr 1177 test SCBARRAY+1,0x88 jz mk_dtr_a 1178 test NEEDWDTR_B,A jnz mk_wdtr_16 # do we need negotiation? 1179 test NEEDSDTR_B,A jnz mk_sdtr |
1133 ret | 1180 ret |
1134mk_sdtr1_a: 1135 test NEEDSDTR_A,A jnz mk_sdtr1 # do we need negotiation? | 1181mk_dtr_a: 1182 test NEEDWDTR_A,A jnz mk_wdtr_16 # do we need negotiation? 1183 test NEEDSDTR_A,A jnz mk_sdtr |
1136 ret 1137 | 1184 ret 1185 |
1138mk_sdtr1: | 1186mk_wdtr_16: 1187 mvi ARG_1,1 # 16bit wide bus 1188 1189mk_wdtr: |
1139 mvi DINDIR,1 # extended message | 1190 mvi DINDIR,1 # extended message |
1191 mvi DINDIR,2 # extended message length = 2 1192 mvi DINDIR,3 # WDTR code 1193 mov DINDIR,ARG_1 # bus width 1194 1195 add MSG_LEN,-MSG_START+0,DINDEX # update message length 1196 ret 1197 1198mk_sdtr: 1199 mvi DINDIR,1 # extended message |
|
1140 mvi DINDIR,3 # extended message length = 3 1141 mvi DINDIR,1 # SDTR code | 1200 mvi DINDIR,3 # extended message length = 3 1201 mvi DINDIR,1 # SDTR code |
1142 mvi DINDIR,25 # REQ/ACK transfer period 1143 mvi DINDIR,15 # REQ/ACK offset | 1202 call sdtr_to_rate 1203 mov DINDIR,RETURN_1 # REQ/ACK transfer period 1204 and DINDIR,0xf,SINDIR # Sync Offset |
1144 1145 add MSG_LEN,-MSG_START+0,DINDEX # update message length 1146 ret 1147 | 1205 1206 add MSG_LEN,-MSG_START+0,DINDEX # update message length 1207 ret 1208 |
1209# Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag 1210# value 1211 1212#mk_tag: 1213# test SCBARRAY+0,0x10 jz mk_tag_done # Tag Enabled? 1214# and A,0x03,SCBARRYA+0 1215# or A,0x20 1216# mov DINDIR,A 1217# mov DINDIR,SCBPTR 1218# 1219# add MSG_LEN,-MSG_START+0,DINDEX # update message length 1220 1221#mk_tag_done: 1222# ret 1223 1224 |
|
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 | 1225# Set SCSI bus control signal state. This also saves the last-written 1226# value into a location where the higher-level driver can read it - if 1227# it has to send an ABORT or RESET message, then it needs to know this 1228# so it can assert ATN without upsetting SCSISIGO. The new value is 1229# expected in SINDEX. Change the actual state last to avoid contention 1230# from the driver. 1231# 1232scsisig: 1233 mov SIGSTATE,SINDEX 1234 mov SCSISIGO,SINDEX ret |
1235 1236sdtr_to_rate: 1237 call ndx_dtr # index scratch space for target 1238 shr A,SINDIR,0x4 1239 dec SINDEX #Preserve SINDEX 1240 and A,0x7 1241 clr RETURN_1 1242sdtr_to_rate_loop: 1243 test A,0x0f jz sdtr_to_rate_done 1244 add RETURN_1,0x18 1245 dec A 1246 jmp sdtr_to_rate_loop 1247sdtr_to_rate_done: 1248 shr RETURN_1,0x2 1249 add RETURN_1,0x18 ret |
|