home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / kernel-s / v1.1 / scsi / 274x / aha274x / aha274x.seq < prev    next >
Text File  |  1995-10-10  |  29KB  |  1,014 lines

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