aic7xxx.seq
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:46k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
  3.  *
  4.  * Copyright (c) 1994-1999 Justin Gibbs.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions, and the following disclaimer,
  12.  *    without modification, immediately at the beginning of the file.
  13.  * 2. The name of the author may not be used to endorse or promote products
  14.  *    derived from this software without specific prior written permission.
  15.  *
  16.  * Where this Software is combined with software released under the terms of 
  17.  * the GNU General Public License (GPL) and the terms of the GPL would require the 
  18.  * combined work to also be released under the terms of the GPL, the terms
  19.  * and conditions of this License will apply in addition to those of the
  20.  * GPL with the exception of any terms or conditions of this License that
  21.  * conflict with, or are expressly prohibited by, the GPL.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  27.  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  *
  35.  * $Id: aic7xxx.seq,v 1.77 1998/06/28 02:58:57 gibbs Exp $
  36.  */
  37. #include "aic7xxx.reg"
  38. #include "scsi_message.h"
  39. /*
  40.  * A few words on the waiting SCB list:
  41.  * After starting the selection hardware, we check for reconnecting targets
  42.  * as well as for our selection to complete just in case the reselection wins
  43.  * bus arbitration.  The problem with this is that we must keep track of the
  44.  * SCB that we've already pulled from the QINFIFO and started the selection
  45.  * on just in case the reselection wins so that we can retry the selection at
  46.  * a later time.  This problem cannot be resolved by holding a single entry
  47.  * in scratch ram since a reconnecting target can request sense and this will
  48.  * create yet another SCB waiting for selection.  The solution used here is to 
  49.  * use byte 27 of the SCB as a pseudo-next pointer and to thread a list
  50.  * of SCBs that are awaiting selection.  Since 0-0xfe are valid SCB indexes, 
  51.  * SCB_LIST_NULL is 0xff which is out of range.  An entry is also added to
  52.  * this list everytime a request sense occurs or after completing a non-tagged
  53.  * command for which a second SCB has been queued.  The sequencer will
  54.  * automatically consume the entries.
  55.  */
  56. reset:
  57. clr SCSISIGO; /* De-assert BSY */
  58. and SXFRCTL1, ~BITBUCKET;
  59. /* Always allow reselection */
  60. mvi SCSISEQ, ENRSELI|ENAUTOATNP;
  61. if ((p->features & AHC_CMD_CHAN) != 0) {
  62. /* Ensure that no DMA operations are in progress */
  63. clr CCSGCTL;
  64. clr CCSCBCTL;
  65. }
  66. call clear_target_state;
  67. poll_for_work:
  68. and SXFRCTL0, ~SPIOEN;
  69. if ((p->features & AHC_QUEUE_REGS) == 0) {
  70. mov A, QINPOS;
  71. }
  72. poll_for_work_loop:
  73. if ((p->features & AHC_QUEUE_REGS) == 0) {
  74. and SEQCTL, ~PAUSEDIS;
  75. }
  76. test SSTAT0, SELDO|SELDI jnz selection;
  77. test SCSISEQ, ENSELO jnz poll_for_work;
  78. if ((p->features & AHC_TWIN) != 0) {
  79. /*
  80.  * Twin channel devices cannot handle things like SELTO
  81.  * interrupts on the "background" channel.  So, if we
  82.  * are selecting, keep polling the current channel util
  83.  * either a selection or reselection occurs.
  84.  */
  85. xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
  86. test SSTAT0, SELDO|SELDI jnz selection;
  87. test SCSISEQ, ENSELO jnz poll_for_work;
  88. xor SBLKCTL,SELBUSB; /* Toggle back */
  89. }
  90. cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
  91. test_queue:
  92. /* Has the driver posted any work for us? */
  93. if ((p->features & AHC_QUEUE_REGS) != 0) {
  94. test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
  95. mov NONE, SNSCB_QOFF;
  96. inc QINPOS;
  97. } else {
  98. or SEQCTL, PAUSEDIS;
  99. cmp KERNEL_QINPOS, A je poll_for_work_loop;
  100. inc QINPOS;
  101. and SEQCTL, ~PAUSEDIS;
  102. }
  103. /*
  104.  * We have at least one queued SCB now and we don't have any 
  105.  * SCBs in the list of SCBs awaiting selection.  If we have
  106.  * any SCBs available for use, pull the tag from the QINFIFO
  107.  * and get to work on it.
  108.  */
  109. if ((p->flags & AHC_PAGESCBS) != 0) {
  110. mov ALLZEROS call get_free_or_disc_scb;
  111. }
  112. dequeue_scb:
  113. add A, -1, QINPOS;
  114. mvi QINFIFO_OFFSET call fetch_byte;
  115. if ((p->flags & AHC_PAGESCBS) == 0) {
  116. /* In the non-paging case, the SCBID == hardware SCB index */
  117. mov SCBPTR, RETURN_2;
  118. }
  119. dma_queued_scb:
  120. /*
  121.  * DMA the SCB from host ram into the current SCB location.
  122.  */
  123. mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
  124. mov RETURN_2  call dma_scb;
  125. /*
  126.  * Preset the residual fields in case we never go through a data phase.
  127.  * This isn't done by the host so we can avoid a DMA to clear these
  128.  * fields for the normal case of I/O that completes without underrun
  129.  * or overrun conditions.
  130.  */
  131. if ((p->features & AHC_CMD_CHAN) != 0) {
  132. bmov    SCB_RESID_DCNT, SCB_DATACNT, 3;
  133. } else {
  134. mov     SCB_RESID_DCNT[0],SCB_DATACNT[0];
  135. mov     SCB_RESID_DCNT[1],SCB_DATACNT[1];
  136. mov     SCB_RESID_DCNT[2],SCB_DATACNT[2];
  137. }
  138. mov     SCB_RESID_SGCNT, SCB_SGCOUNT;
  139. start_scb:
  140. /*
  141.  * Place us on the waiting list in case our selection
  142.  * doesn't win during bus arbitration.
  143.  */
  144. mov SCB_NEXT,WAITING_SCBH;
  145. mov WAITING_SCBH, SCBPTR;
  146. start_waiting:
  147. /*
  148.  * Pull the first entry off of the waiting SCB list.
  149.  */
  150. mov SCBPTR, WAITING_SCBH;
  151. call start_selection;
  152. jmp poll_for_work;
  153. start_selection:
  154. if ((p->features & AHC_TWIN) != 0) {
  155. and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
  156. and A,SELBUSB,SCB_TCL; /* Get new channel bit */
  157. or SINDEX,A;
  158. mov SBLKCTL,SINDEX; /* select channel */
  159. }
  160. initialize_scsiid:
  161. if ((p->features & AHC_ULTRA2) != 0) {
  162. and A, TID, SCB_TCL; /* Get target ID */
  163. and SCSIID_ULTRA2, OID; /* Clear old target */
  164. or SCSIID_ULTRA2, A;
  165. } else {
  166. and A, TID, SCB_TCL; /* Get target ID */
  167. and SCSIID, OID; /* Clear old target */
  168. or SCSIID, A;
  169. }
  170. mov SCSIDATL, ALLZEROS; /* clear out the latched */
  171. /* data register, this */
  172. /* fixes a bug on some */
  173. /* controllers where the */
  174. /* last byte written to */
  175. /* this register can leak */
  176. /* onto the data bus at */
  177. /* bad times, such as during */
  178. /* selection timeouts */
  179. mvi SCSISEQ, ENSELO|ENAUTOATNO|ENRSELI|ENAUTOATNP ret;
  180. /*
  181.  * Initialize Ultra mode setting and clear the SCSI channel.
  182.  * SINDEX should contain any additional bit's the client wants
  183.  * set in SXFRCTL0.
  184.  */
  185. initialize_channel:
  186. or SXFRCTL0, CLRSTCNT|CLRCHN, SINDEX;
  187. if ((p->features & AHC_ULTRA) != 0) {
  188. ultra:
  189. mvi SINDEX, ULTRA_ENB+1;
  190. test SAVED_TCL, 0x80 jnz ultra_2; /* Target ID > 7 */
  191. dec SINDEX;
  192. ultra_2:
  193. mov     FUNCTION1,SAVED_TCL;
  194. mov     A,FUNCTION1;
  195. test SINDIR, A jz ndx_dtr;
  196. or SXFRCTL0, FAST20;
  197. /*
  198.  * Initialize SCSIRATE with the appropriate value for this target.
  199.  * The SCSIRATE settings for each target are stored in an array
  200.  * based at TARG_SCSIRATE.
  201.  */
  202. ndx_dtr:
  203. shr A,4,SAVED_TCL;
  204. if ((p->features & AHC_TWIN) != 0) {
  205. test SBLKCTL,SELBUSB jz ndx_dtr_2;
  206. or SAVED_TCL, SELBUSB; 
  207. or A,0x08; /* Channel B entries add 8 */
  208. ndx_dtr_2:
  209. }
  210. if ((p->features & AHC_ULTRA2) != 0) {
  211. add SINDEX, TARG_OFFSET, A;
  212. mov SCSIOFFSET, SINDIR;
  213. }
  214. add SINDEX,TARG_SCSIRATE,A;
  215. mov SCSIRATE,SINDIR ret;
  216. selection:
  217. test SSTAT0,SELDO jnz select_out;
  218. /*
  219.  * Reselection has been initiated by a target. Make a note that we've been
  220.  * reselected, but haven't seen an IDENTIFY message from the target yet.
  221.  */
  222. initiator_reselect:
  223. mvi CLRSINT0, CLRSELDI;
  224. /* XXX test for and handle ONE BIT condition */
  225. and SAVED_TCL, SELID_MASK, SELID;
  226. mvi CLRSINT1,CLRBUSFREE;
  227. or SIMODE1, ENBUSFREE; /*
  228.  * We aren't expecting a
  229.  * bus free, so interrupt
  230.  * the kernel driver if it
  231.  * happens.
  232.  */
  233. mvi SPIOEN call initialize_channel;
  234. mvi MSG_OUT, MSG_NOOP; /* No message to send */
  235. jmp ITloop;
  236. /*
  237.  * After the selection, remove this SCB from the "waiting SCB"
  238.  * list.  This is achieved by simply moving our "next" pointer into
  239.  * WAITING_SCBH.  Our next pointer will be set to null the next time this
  240.  * SCB is used, so don't bother with it now.
  241.  */
  242. select_out:
  243. /* Turn off the selection hardware */
  244. mvi SCSISEQ, ENRSELI|ENAUTOATNP; /*
  245.  * ATN on parity errors
  246.  * for "in" phases
  247.  */
  248. mvi CLRSINT0, CLRSELDO;
  249. mov SCBPTR, WAITING_SCBH;
  250. mov WAITING_SCBH,SCB_NEXT;
  251. mov SAVED_TCL, SCB_TCL;
  252. mvi CLRSINT1,CLRBUSFREE;
  253. or SIMODE1, ENBUSFREE; /*
  254.  * We aren't expecting a
  255.  * bus free, so interrupt
  256.  * the kernel driver if it
  257.  * happens.
  258.  */
  259. mvi SPIOEN call initialize_channel;
  260. /*
  261.  * As soon as we get a successful selection, the target should go
  262.  * into the message out phase since we have ATN asserted.
  263.  */
  264. mvi MSG_OUT, MSG_IDENTIFYFLAG;
  265. or SEQ_FLAGS, IDENTIFY_SEEN;
  266. /*
  267.  * Main loop for information transfer phases.  Wait for the target
  268.  * to assert REQ before checking MSG, C/D and I/O for the bus phase.
  269.  */
  270. ITloop:
  271. call phase_lock;
  272. mov A, LASTPHASE;
  273. test A, ~P_DATAIN jz p_data;
  274. cmp A,P_COMMAND je p_command;
  275. cmp A,P_MESGOUT je p_mesgout;
  276. cmp A,P_STATUS je p_status;
  277. cmp A,P_MESGIN je p_mesgin;
  278. mvi INTSTAT,BAD_PHASE; /* unknown phase - signal driver */
  279. jmp ITloop; /* Try reading the bus again. */
  280. await_busfree:
  281. and SIMODE1, ~ENBUSFREE;
  282. call clear_target_state;
  283. mov NONE, SCSIDATL; /* Ack the last byte */
  284. and SXFRCTL0, ~SPIOEN;
  285. test SSTAT1,REQINIT|BUSFREE jz .;
  286. test SSTAT1, BUSFREE jnz poll_for_work;
  287. mvi INTSTAT, BAD_PHASE;
  288. clear_target_state:
  289. /*
  290.  * We assume that the kernel driver may reset us
  291.  * at any time, even in the middle of a DMA, so
  292.  * clear DFCNTRL too.
  293.  */
  294. clr DFCNTRL;
  295. /*
  296.  * We don't know the target we will connect to,
  297.  * so default to narrow transfers to avoid
  298.  * parity problems.
  299.  */
  300. if ((p->features & AHC_ULTRA2) != 0) {
  301. bmov    SCSIRATE, ALLZEROS, 2;
  302. } else {
  303. clr     SCSIRATE;
  304. and     SXFRCTL0, ~(FAST20);
  305. }
  306. mvi LASTPHASE, P_BUSFREE;
  307. /* clear target specific flags */
  308. clr SEQ_FLAGS ret;
  309. data_phase_reinit:
  310. /*
  311.  * If we re-enter the data phase after going through another phase, the
  312.  * STCNT may have been cleared, so restore it from the residual field.
  313.  * On Ultra2, we have to put it into the HCNT field because we have to
  314.  * drop the data down into the shadow layer via the preload ability.
  315.  */
  316.   if ((p->features & AHC_ULTRA2) != 0) {
  317. bmov HADDR, SHADDR, 4;
  318. bmov    HCNT, SCB_RESID_DCNT, 3;
  319. }
  320. if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
  321. bmov    STCNT, SCB_RESID_DCNT, 3;
  322. }
  323. if ((p->features & AHC_CMD_CHAN) == 0) {
  324. mvi DINDEX, STCNT;
  325. mvi SCB_RESID_DCNT call bcopy_3;
  326. }
  327. jmp data_phase_loop;
  328. p_data:
  329.   if ((p->features & AHC_ULTRA2) != 0) {
  330. mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN;
  331. } else {
  332. mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;
  333. }
  334. test LASTPHASE, IOI jnz . + 2;
  335. or DMAPARAMS, DIRECTION;
  336. call assert; /*
  337.  * Ensure entering a data
  338.  * phase is okay - seen identify, etc.
  339.  */
  340. if ((p->features & AHC_CMD_CHAN) != 0) {
  341. mvi CCSGADDR, CCSGADDR_MAX;
  342. }
  343. test SEQ_FLAGS, DPHASE jnz data_phase_reinit;
  344. or SEQ_FLAGS, DPHASE; /* we've seen a data phase */
  345. /*
  346.  * Initialize the DMA address and counter from the SCB.
  347.  * Also set SG_COUNT and SG_NEXT in memory since we cannot
  348.  * modify the values in the SCB itself until we see a
  349.  * save data pointers message.
  350.  */
  351. if ((p->features & AHC_CMD_CHAN) != 0) {
  352. bmov HADDR, SCB_DATAPTR, 7;
  353. bmov    SG_COUNT, SCB_SGCOUNT, 5;
  354. if ((p->features & AHC_ULTRA2) == 0) {
  355. bmov    STCNT, HCNT, 3;
  356. }
  357. } else {
  358. mvi DINDEX, HADDR;
  359. mvi SCB_DATAPTR call bcopy_7;
  360. call set_stcnt_from_hcnt;
  361. mvi DINDEX, SG_COUNT;
  362. mvi SCB_SGCOUNT call bcopy_5;
  363. }
  364. data_phase_loop:
  365. /* Guard against overruns */
  366. test SG_COUNT, 0xff jnz data_phase_inbounds;
  367. /*
  368.  * Turn on 'Bit Bucket' mode, set the transfer count to
  369.  * 16meg and let the target run until it changes phase.
  370.  * When the transfer completes, notify the host that we
  371.  * had an overrun.
  372.  */
  373. or SXFRCTL1,BITBUCKET;
  374. and DMAPARAMS, ~(HDMAEN|SDMAEN);
  375. if ((p->features & AHC_ULTRA2) != 0) {
  376. bmov HCNT, ALLONES, 3;
  377. }
  378. if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
  379. bmov STCNT, ALLONES, 3;
  380. }
  381. if ((p->features & AHC_CMD_CHAN) == 0) {
  382. mvi STCNT[0], 0xFF;
  383. mvi STCNT[1], 0xFF;
  384. mvi STCNT[2], 0xFF;
  385. }
  386. data_phase_inbounds:
  387. /* If we are the last SG block, tell the hardware. */
  388. if ((p->features & AHC_ULTRA2) != 0) {
  389. shl A, 2, SG_COUNT;
  390. cmp SG_COUNT,0x01 jne data_phase_wideodd;
  391. or A, LAST_SEG;
  392. } else {
  393. cmp SG_COUNT,0x01 jne data_phase_wideodd;
  394. and DMAPARAMS, ~WIDEODD;
  395. }
  396. data_phase_wideodd:
  397. if ((p->features & AHC_ULTRA2) != 0) {
  398. mov SG_CACHEPTR, A;
  399. mov DFCNTRL, DMAPARAMS; /* start the operation */
  400. test SXFRCTL1, BITBUCKET jnz data_phase_overrun;
  401. u2_preload_wait:
  402. test SSTAT1, PHASEMIS jnz u2_phasemis;
  403. test DFSTATUS, PRELOAD_AVAIL jz u2_preload_wait;
  404. } else {
  405. mov DMAPARAMS  call dma;
  406. data_phase_dma_done:
  407. /* Go tell the host about any overruns */
  408. test SXFRCTL1,BITBUCKET jnz data_phase_overrun;
  409. /* Exit if we had an underrun.  dma clears SINDEX in this case. */
  410. test SINDEX,0xff jz data_phase_finish;
  411. }
  412. /*
  413.  * Advance the scatter-gather pointers 
  414.  */
  415. sg_advance:
  416. if ((p->features & AHC_ULTRA2) != 0) {
  417. cmp SG_COUNT, 0x01 je u2_data_phase_finish;
  418. } else {
  419. dec SG_COUNT;
  420. test SG_COUNT, 0xff jz data_phase_finish;
  421. }
  422. if ((p->features & AHC_CMD_CHAN) != 0) {
  423. /*
  424.  * Do we have any prefetch left???
  425.  */
  426. cmp CCSGADDR, CCSGADDR_MAX jne prefetch_avail;
  427. /*
  428.  * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes.
  429.  */
  430. add A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT;
  431. mvi A, CCSGADDR_MAX;
  432. jc . + 2;
  433. shl A, 3, SG_COUNT;
  434. mov CCHCNT, A;
  435. bmov CCHADDR, SG_NEXT, 4;
  436. mvi CCSGCTL, CCSGEN|CCSGRESET;
  437. test CCSGCTL, CCSGDONE jz .;
  438. and CCSGCTL, ~CCSGEN;
  439. test CCSGCTL, CCSGEN jnz .;
  440. mvi CCSGCTL, CCSGRESET;
  441. prefetch_avail:
  442. bmov  HADDR, CCSGRAM, 8;
  443. if ((p->features & AHC_ULTRA2) == 0) {
  444. bmov    STCNT, HCNT, 3;
  445. } else {
  446. dec SG_COUNT;
  447. }
  448. } else {
  449. mvi DINDEX, HADDR;
  450. mvi SG_NEXT call bcopy_4;
  451. mvi HCNT[0],SG_SIZEOF;
  452. clr HCNT[1];
  453. clr HCNT[2];
  454. or DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
  455. call dma_finish;
  456. /*
  457.  * Copy data from FIFO into SCB data pointer and data count.
  458.  * This assumes that the SG segments are of the form:
  459.  * struct ahc_dma_seg {
  460.  * u_int32_t addr; four bytes, little-endian order
  461.  * u_int32_t len; four bytes, little endian order
  462.  * };
  463.  */
  464.   mvi DINDEX, HADDR;
  465. call dfdat_in_7;
  466. call set_stcnt_from_hcnt;
  467. }
  468. /* Advance the SG pointer */
  469. clr A; /* add sizeof(struct scatter) */
  470. add SG_NEXT[0],SG_SIZEOF;
  471. adc SG_NEXT[1],A;
  472. if ((p->features & AHC_ULTRA2) != 0) {
  473. jmp data_phase_loop;
  474. } else {
  475. test    SSTAT1, REQINIT jz .;
  476. test SSTAT1,PHASEMIS jz data_phase_loop;
  477. }
  478. /*
  479.  * We've loaded all of our segments into the preload layer.  Now, we simply
  480.  * have to wait for it to finish or for us to get a phasemis.  And, since
  481.  * we'll get a phasemis if we do finish, all we really need to do is wait
  482.  * for a phasemis then check if we did actually complete all the segments.
  483.  */
  484. if ((p->features & AHC_ULTRA2) != 0) {
  485. u2_data_phase_finish:
  486. test SSTAT1, PHASEMIS jnz u2_phasemis;
  487. test SG_CACHEPTR, LAST_SEG_DONE jz u2_data_phase_finish;
  488. clr SG_COUNT;
  489. test SSTAT1, REQINIT jz .;
  490. test SSTAT1, PHASEMIS jz data_phase_loop;
  491. u2_phasemis:
  492. call ultra2_dmafinish;
  493. test SG_CACHEPTR, LAST_SEG_DONE jnz data_phase_finish;
  494. test SSTAT2, SHVALID jnz u2_fixup_residual;
  495. mvi INTSTAT, SEQ_SG_FIXUP;
  496. jmp data_phase_finish;
  497. u2_fixup_residual:
  498. shr ARG_1, 2, SG_CACHEPTR;
  499. u2_phasemis_loop:
  500. and A, 0x3f, SG_COUNT;
  501. cmp ARG_1, A je data_phase_finish;
  502. /*
  503.  * Subtract SG_SIZEOF from the SG_NEXT pointer and add 1 to the SG_COUNT
  504.  */
  505.   clr A;
  506. add SG_NEXT[0], -SG_SIZEOF;
  507. adc SG_NEXT[1], 0xff;
  508. inc SG_COUNT;
  509. jmp u2_phasemis_loop;
  510. }
  511. data_phase_finish:
  512. /*
  513.  * After a DMA finishes, save the SG and STCNT residuals back into the SCB
  514.  * We use STCNT instead of HCNT, since it's a reflection of how many bytes 
  515.  * were transferred on the SCSI (as opposed to the host) bus.
  516.  */
  517. if ((p->features & AHC_CMD_CHAN) != 0) {
  518. bmov    SCB_RESID_DCNT, STCNT, 3;
  519. mov SCB_RESID_SGCNT, SG_COUNT;
  520. if ((p->features & AHC_ULTRA2) != 0) {
  521. or SXFRCTL0, CLRSTCNT|CLRCHN;
  522. }
  523. } else {
  524. mov SCB_RESID_DCNT[0],STCNT[0];
  525. mov SCB_RESID_DCNT[1],STCNT[1];
  526. mov SCB_RESID_DCNT[2],STCNT[2];
  527. mov SCB_RESID_SGCNT, SG_COUNT;
  528. }
  529. jmp ITloop;
  530. data_phase_overrun:
  531. /*
  532.  * Turn off BITBUCKET mode and notify the host
  533.  */
  534. if ((p->features & AHC_ULTRA2) != 0) {
  535. /*
  536.  * Wait for the target to quit transferring data on the SCSI bus
  537.  */
  538.   test SSTAT1, PHASEMIS jz .;
  539. call ultra2_dmafinish;
  540. }
  541. and SXFRCTL1, ~BITBUCKET;
  542. mvi INTSTAT,DATA_OVERRUN;
  543. jmp ITloop;
  544. /*
  545.  * Actually turn off the DMA hardware, save our current position into the
  546.  * proper residual variables, wait for the next REQ signal, then jump to
  547.  * the ITloop.  Jumping to the ITloop ensures that if we happen to get
  548.  * brought into the data phase again (or are still in it after our last
  549.  * segment) that we will properly signal an overrun to the kernel.
  550.  */
  551. if ((p->features & AHC_ULTRA2) != 0) {
  552. ultra2_dmafinish:
  553. test DFCNTRL, DIRECTION jnz ultra2_dmahalt;
  554. and DFCNTRL, ~SCSIEN;
  555. test DFCNTRL, SCSIEN jnz .;
  556. if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) {
  557. or DFCNTRL, FIFOFLUSH;
  558. }
  559. ultra2_dmafifoflush:
  560. if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) {
  561. /*
  562.  * hardware bug alert!  This needless set of jumps
  563.  * works around a glitch in the silicon.  When the
  564.  * PCI DMA fifo goes empty, but there is still SCSI
  565.  * data to be flushed into the PCI DMA fifo (and from
  566.  * there on into main memory), the FIFOEMP bit will
  567.  * come on between the time when the PCI DMA buffer
  568.  * went empty and the next bit of data is copied from
  569.  * the SCSI fifo into the PCI fifo.  It should only
  570.  * come on when both FIFOs (meaning the entire FIFO
  571.  * chain) are emtpy.  Since it can take up to 4 cycles
  572.  * for new data to be copied from the SCSI fifo into
  573.  * the PCI fifo, testing for FIFOEMP status for 4
  574.  * extra times gives the needed time for any
  575.  * remaining SCSI fifo data to be put in the PCI fifo
  576.  * before we declare it *truly* empty.
  577.  */
  578. test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
  579. test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
  580. test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
  581. test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
  582. }
  583. test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
  584. test DFSTATUS, MREQPEND jnz .;
  585. ultra2_dmahalt:
  586. and     DFCNTRL, ~(HDMAEN|SCSIEN);
  587. test DFCNTRL, (HDMAEN|SCSIEN) jnz .;
  588. ret;
  589. }
  590. /*
  591.  * Command phase.  Set up the DMA registers and let 'er rip.
  592.  */
  593. p_command:
  594. call assert;
  595. /*
  596.  * Load HADDR and HCNT.
  597.  */
  598. if ((p->features & AHC_CMD_CHAN) != 0) {
  599. bmov HADDR, SCB_CMDPTR, 5;
  600. bmov HCNT[1], ALLZEROS, 2;
  601. if ((p->features & AHC_ULTRA2) == 0) {
  602. bmov STCNT, HCNT, 3;
  603. }
  604. } else {
  605. mvi DINDEX, HADDR;
  606. mvi SCB_CMDPTR call bcopy_5;
  607. clr HCNT[1];
  608. clr HCNT[2];
  609. call set_stcnt_from_hcnt;
  610. }
  611. if ((p->features & AHC_ULTRA2) == 0) {
  612. mvi (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET) call dma;
  613. } else {
  614. mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION);
  615. test SSTAT0, SDONE jnz .;
  616. p_command_dma_loop:
  617. test SSTAT0, SDONE jnz p_command_ultra2_dma_done;
  618. test SSTAT1,PHASEMIS jz p_command_dma_loop; /* ie. underrun */
  619. p_command_ultra2_dma_done:
  620. test SCSISIGI, REQI jz p_command_ultra2_shutdown;
  621. test SSTAT1, (PHASEMIS|REQINIT) jz p_command_ultra2_dma_done;
  622. p_command_ultra2_shutdown:
  623. and     DFCNTRL, ~(HDMAEN|SCSIEN);
  624. test DFCNTRL, (HDMAEN|SCSIEN) jnz .;
  625. or SXFRCTL0, CLRSTCNT|CLRCHN;
  626. }
  627. jmp ITloop;
  628. /*
  629.  * Status phase.  Wait for the data byte to appear, then read it
  630.  * and store it into the SCB.
  631.  */
  632. p_status:
  633. call assert;
  634. mov SCB_TARGET_STATUS, SCSIDATL;
  635. jmp ITloop;
  636. /*
  637.  * Message out phase.  If MSG_OUT is 0x80, build I full indentify message
  638.  * sequence and send it to the target.  In addition, if the MK_MESSAGE bit
  639.  * is set in the SCB_CONTROL byte, interrupt the host and allow it to send
  640.  * it's own message.
  641.  * 
  642.  * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
  643.  * This is done to allow the hsot to send messages outside of an identify
  644.  * sequence while protecting the seqencer from testing the MK_MESSAGE bit
  645.  * on an SCB that might not be for the current nexus. (For example, a
  646.  * BDR message in responce to a bad reselection would leave us pointed to
  647.  * an SCB that doesn't have anything to do with the current target).
  648.  * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag,
  649.  * bus device reset).
  650.  *
  651.  * When there are no messages to send, MSG_OUT should be set to MSG_NOOP,
  652.  * in case the target decides to put us in this phase for some strange
  653.  * reason.
  654.  */
  655. p_mesgout_retry:
  656. or      SCSISIGO,ATNO,LASTPHASE;/* turn on ATN for the retry */
  657. p_mesgout:
  658. mov SINDEX, MSG_OUT;
  659. cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
  660. p_mesgout_identify:
  661. if ((p->features & AHC_WIDE) != 0) {
  662. and SINDEX,0xf,SCB_TCL; /* lun */
  663. } else {
  664. and SINDEX,0x7,SCB_TCL; /* lun */
  665. }
  666. and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */
  667. or SINDEX,A; /* or in disconnect privledge */
  668. or SINDEX,MSG_IDENTIFYFLAG;
  669. p_mesgout_mk_message:
  670. test SCB_CONTROL,MK_MESSAGE  jz p_mesgout_tag;
  671. mov SCSIDATL, SINDEX; /* Send the last byte */
  672. jmp p_mesgout_from_host + 1;/* Skip HOST_MSG test */
  673. /*
  674.  * Send a tag message if TAG_ENB is set in the SCB control block.
  675.  * Use SCB_TAG (the position in the kernel's SCB array) as the tag value.
  676.  */
  677. p_mesgout_tag:
  678. test SCB_CONTROL,TAG_ENB jz  p_mesgout_onebyte;
  679. mov SCSIDATL, SINDEX; /* Send the identify message */
  680. call phase_lock;
  681. cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
  682. and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;
  683. call phase_lock;
  684. cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
  685. mov SCB_TAG jmp p_mesgout_onebyte;
  686. /*
  687.  * Interrupt the driver, and allow it to send a message
  688.  * if it asks.
  689.  */
  690. p_mesgout_from_host:
  691. cmp SINDEX, HOST_MSG jne p_mesgout_onebyte;
  692. mvi     INTSTAT,AWAITING_MSG;
  693. nop;
  694. /*
  695.  * Did the host detect a phase change?
  696.  */
  697. cmp RETURN_1, MSGOUT_PHASEMIS je p_mesgout_done;
  698. p_mesgout_onebyte:
  699. mvi CLRSINT1, CLRATNO;
  700. mov SCSIDATL, SINDEX;
  701. /*
  702.  * If the next bus phase after ATN drops is a message out, it means
  703.  * that the target is requesting that the last message(s) be resent.
  704.  */
  705. call phase_lock;
  706. cmp     LASTPHASE, P_MESGOUT    je p_mesgout_retry;
  707. p_mesgout_done:
  708. mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */
  709. mov LAST_MSG, MSG_OUT;
  710. cmp MSG_OUT, MSG_IDENTIFYFLAG jne . + 2;
  711. and SCB_CONTROL, ~MK_MESSAGE;
  712. mvi MSG_OUT, MSG_NOOP; /* No message left */
  713. jmp ITloop;
  714. /*
  715.  * Message in phase.  Bytes are read using Automatic PIO mode.
  716.  */
  717. p_mesgin:
  718. mvi ACCUM call inb_first; /* read the 1st message byte */
  719. test A,MSG_IDENTIFYFLAG jnz mesgin_identify;
  720. cmp A,MSG_DISCONNECT je mesgin_disconnect;
  721. cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs;
  722. cmp ALLZEROS,A je mesgin_complete;
  723. cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs;
  724. cmp A,MSG_EXTENDED je mesgin_extended;
  725. cmp A,MSG_MESSAGE_REJECT je mesgin_reject;
  726. cmp A,MSG_NOOP je mesgin_done;
  727. cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_wide_residue;
  728. rej_mesgin:
  729. /*
  730.  * We have no idea what this message in is, so we issue a message reject
  731.  * and hope for the best.  In any case, rejection should be a rare
  732.  * occurrence - signal the driver when it happens.
  733.  */
  734. mvi INTSTAT,SEND_REJECT; /* let driver know */
  735. mvi MSG_MESSAGE_REJECT call mk_mesg;
  736. mesgin_done:
  737. mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
  738. jmp ITloop;
  739. mesgin_complete:
  740. /*
  741.  * We got a "command complete" message, so put the SCB_TAG into the QOUTFIFO,
  742.  * and trigger a completion interrupt.  Before doing so, check to see if there
  743.  * is a residual or the status byte is something other than STATUS_GOOD (0).
  744.  * In either of these conditions, we upload the SCB back to the host so it can
  745.  * process this information.  In the case of a non zero status byte, we 
  746.  * additionally interrupt the kernel driver synchronously, allowing it to
  747.  * decide if sense should be retrieved.  If the kernel driver wishes to request
  748.  * sense, it will fill the kernel SCB with a request sense command and set
  749.  * RETURN_1 to SEND_SENSE.  If RETURN_1 is set to SEND_SENSE we redownload
  750.  * the SCB, and process it as the next command by adding it to the waiting list.
  751.  * If the kernel driver does not wish to request sense, it need only clear
  752.  * RETURN_1, and the command is allowed to complete normally.  We don't bother
  753.  * to post to the QOUTFIFO in the error cases since it would require extra
  754.  * work in the kernel driver to ensure that the entry was removed before the
  755.  * command complete code tried processing it.
  756.  */
  757. /*
  758.  * First check for residuals
  759.  */
  760. test SCB_RESID_SGCNT,0xff jnz upload_scb;
  761. test SCB_TARGET_STATUS,0xff jz complete; /* Good Status? */
  762. upload_scb:
  763. mvi DMAPARAMS, FIFORESET;
  764. mov SCB_TAG call dma_scb;
  765. check_status:
  766. test SCB_TARGET_STATUS,0xff jz complete; /* Just a residual? */
  767. mvi INTSTAT,BAD_STATUS; /* let driver know */
  768. nop;
  769. cmp RETURN_1, SEND_SENSE jne complete;
  770. /* This SCB becomes the next to execute as it will retrieve sense */
  771. mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
  772. mov SCB_TAG call dma_scb;
  773. add_to_waiting_list:
  774. mov SCB_NEXT,WAITING_SCBH;
  775. mov WAITING_SCBH, SCBPTR;
  776. /*
  777.  * Prepare our selection hardware before the busfree so we have a
  778.  * high probability of winning arbitration.
  779.  */
  780. call start_selection;
  781. jmp await_busfree;
  782. complete:
  783. /* If we are untagged, clear our address up in host ram */
  784. test SCB_CONTROL, TAG_ENB jnz complete_post;
  785. mov A, SAVED_TCL;
  786. mvi UNTAGGEDSCB_OFFSET call post_byte_setup;
  787. mvi SCB_LIST_NULL call post_byte;
  788. complete_post:
  789. /* Post the SCB and issue an interrupt */
  790. if ((p->features & AHC_QUEUE_REGS) != 0) {
  791. mov A, SDSCB_QOFF;
  792. } else {
  793. mov A, QOUTPOS;
  794. }
  795. mvi QOUTFIFO_OFFSET call post_byte_setup;
  796. mov SCB_TAG call post_byte;
  797. if ((p->features & AHC_QUEUE_REGS) == 0) {
  798. inc  QOUTPOS;
  799. }
  800. mvi INTSTAT,CMDCMPLT;
  801. add_to_free_list:
  802. call add_scb_to_free_list;
  803. jmp await_busfree;
  804. /*
  805.  * Is it an extended message?  Copy the message to our message buffer and
  806.  * notify the host.  The host will tell us whether to reject this message,
  807.  * respond to it with the message that the host placed in our message buffer,
  808.  * or simply to do nothing.
  809.  */
  810. mesgin_extended:
  811. mvi INTSTAT,EXTENDED_MSG; /* let driver know */
  812. jmp ITloop;
  813. /*
  814.  * Is it a disconnect message?  Set a flag in the SCB to remind us
  815.  * and await the bus going free.
  816.  */
  817. mesgin_disconnect:
  818. or SCB_CONTROL,DISCONNECTED;
  819. call add_scb_to_disc_list;
  820. jmp await_busfree;
  821. /*
  822.  * Save data pointers message:
  823.  * Copying RAM values back to SCB, for Save Data Pointers message, but
  824.  * only if we've actually been into a data phase to change them.  This
  825.  * protects against bogus data in scratch ram and the residual counts
  826.  * since they are only initialized when we go into data_in or data_out.
  827.  */
  828. mesgin_sdptrs:
  829. test SEQ_FLAGS, DPHASE jz mesgin_done;
  830. /*
  831.  * The SCB SGPTR becomes the next one we'll download,
  832.  * and the SCB DATAPTR becomes the current SHADDR.
  833.  * Use the residual number since STCNT is corrupted by
  834.  * any message transfer.
  835.  */
  836. if ((p->features & AHC_CMD_CHAN) != 0) {
  837. bmov    SCB_SGCOUNT, SG_COUNT, 5;
  838. bmov    SCB_DATAPTR, SHADDR, 4;
  839. bmov    SCB_DATACNT, SCB_RESID_DCNT, 3;
  840. } else {
  841. mvi DINDEX, SCB_SGCOUNT;
  842. mvi SG_COUNT call bcopy_5;
  843. mvi DINDEX, SCB_DATAPTR;
  844. mvi SHADDR call bcopy_4;
  845. mvi SCB_RESID_DCNT call bcopy_3;
  846. }
  847. jmp mesgin_done;
  848. /*
  849.  * Restore pointers message?  Data pointers are recopied from the
  850.  * SCB anytime we enter a data phase for the first time, so all
  851.  * we need to do is clear the DPHASE flag and let the data phase
  852.  * code do the rest.
  853.  */
  854. mesgin_rdptrs:
  855. and SEQ_FLAGS, ~DPHASE; /*
  856.  * We'll reload them
  857.  * the next time through
  858.  * the dataphase.
  859.  */
  860. jmp mesgin_done;
  861. /*
  862.  * Identify message?  For a reconnecting target, this tells us the lun
  863.  * that the reconnection is for - find the correct SCB and switch to it,
  864.  * clearing the "disconnected" bit so we don't "find" it by accident later.
  865.  */
  866. mesgin_identify:
  867. if ((p->features & AHC_WIDE) != 0) {
  868. and A,0x0f; /* lun in lower four bits */
  869. } else {
  870. and A,0x07; /* lun in lower three bits */
  871. }
  872. or      SAVED_TCL,A; /* SAVED_TCL should be complete now */
  873. mvi     ARG_2, SCB_LIST_NULL;   /* SCBID of prev SCB in disc List */
  874. call get_untagged_SCBID;
  875. cmp ARG_1, SCB_LIST_NULL je snoop_tag;
  876. if ((p->flags & AHC_PAGESCBS) != 0) {
  877. test SEQ_FLAGS, SCBPTR_VALID jz use_retrieveSCB;
  878. }
  879. /*
  880.  * If the SCB was found in the disconnected list (as is
  881.  * always the case in non-paging scenarios), SCBPTR is already
  882.  * set to the correct SCB.  So, simply setup the SCB and get
  883.  * on with things.
  884.  */
  885. mov SCBPTR call rem_scb_from_disc_list;
  886. jmp setup_SCB;
  887. /*
  888.  * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
  889.  * If we get one, we use the tag returned to find the proper
  890.  * SCB.  With SCB paging, this requires using search for both tagged
  891.  * and non-tagged transactions since the SCB may exist in any slot.
  892.  * If we're not using SCB paging, we can use the tag as the direct
  893.  * index to the SCB.
  894.  */
  895. snoop_tag:
  896. mov NONE,SCSIDATL; /* ACK Identify MSG */
  897. snoop_tag_loop:
  898. call phase_lock;
  899. cmp LASTPHASE, P_MESGIN jne not_found;
  900. cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found;
  901. get_tag:
  902. mvi ARG_1 call inb_next; /* tag value */
  903. use_retrieveSCB:
  904. call retrieveSCB;
  905. setup_SCB:
  906. mov A, SAVED_TCL;
  907. cmp SCB_TCL, A jne not_found_cleanup_scb;
  908. test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;
  909. and SCB_CONTROL,~DISCONNECTED;
  910. or SEQ_FLAGS,IDENTIFY_SEEN;   /* make note of IDENTIFY */
  911. /* See if the host wants to send a message upon reconnection */
  912. test SCB_CONTROL, MK_MESSAGE jz mesgin_done;
  913. and SCB_CONTROL, ~MK_MESSAGE;
  914. mvi HOST_MSG call mk_mesg;
  915. jmp mesgin_done;
  916. not_found_cleanup_scb:
  917. test SCB_CONTROL, DISCONNECTED jz . + 3;
  918. call add_scb_to_disc_list;
  919. jmp not_found;
  920. call add_scb_to_free_list;
  921. not_found:
  922. mvi INTSTAT, NO_MATCH;
  923. mvi MSG_BUS_DEV_RESET call mk_mesg;
  924. jmp mesgin_done;
  925. /*
  926.  * Message reject?  Let the kernel driver handle this.  If we have an 
  927.  * outstanding WDTR or SDTR negotiation, assume that it's a response from 
  928.  * the target selecting 8bit or asynchronous transfer, otherwise just ignore 
  929.  * it since we have no clue what it pertains to.
  930.  */
  931. mesgin_reject:
  932. mvi INTSTAT, REJECT_MSG;
  933. jmp mesgin_done;
  934. /*
  935.  * Wide Residue.  We handle the simple cases, but pass of the one hard case
  936.  * to the kernel (when the residue byte happened to cause us to advance our
  937.  * sg element array, so we know have to back that advance out).
  938.  */
  939. mesgin_wide_residue:
  940. mvi ARG_1 call inb_next; /* ACK the wide_residue and get */
  941.        /* the size byte */
  942. /*
  943.  * In order for this to be reliable, we have to do all sorts of horrible
  944.  * magic in terms of resetting the datafifo and reloading the shadow layer
  945.  * with the correct new values (so that a subsequent save data pointers
  946.  * message will do the right thing).  We let the kernel do that work.
  947.  */
  948.   mvi INTSTAT, WIDE_RESIDUE;
  949. jmp mesgin_done;
  950. /*
  951.  * [ ADD MORE MESSAGE HANDLING HERE ]
  952.  */
  953. /*
  954.  * Locking the driver out, build a one-byte message passed in SINDEX
  955.  * if there is no active message already.  SINDEX is returned intact.
  956.  */
  957. mk_mesg:
  958. or SCSISIGO,ATNO,LASTPHASE;/* turn on ATNO */
  959. mov MSG_OUT,SINDEX ret;
  960. /*
  961.  * Functions to read data in Automatic PIO mode.
  962.  *
  963.  * According to Adaptec's documentation, an ACK is not sent on input from
  964.  * the target until SCSIDATL is read from.  So we wait until SCSIDATL is
  965.  * latched (the usual way), then read the data byte directly off the bus
  966.  * using SCSIBUSL.  When we have pulled the ATN line, or we just want to
  967.  * acknowledge the byte, then we do a dummy read from SCISDATL.  The SCSI
  968.  * spec guarantees that the target will hold the data byte on the bus until
  969.  * we send our ACK.
  970.  *
  971.  * The assumption here is that these are called in a particular sequence,
  972.  * and that REQ is already set when inb_first is called.  inb_{first,next}
  973.  * use the same calling convention as inb.
  974.  */
  975. inb_next:
  976. mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
  977. inb_next_wait:
  978. /*
  979.  * If there is a parity error, wait for the kernel to
  980.  * see the interrupt and prepare our message response
  981.  * before continuing.
  982.  */
  983. test SSTAT1, REQINIT jz inb_next_wait;
  984. test SSTAT1, SCSIPERR jnz .;
  985. and LASTPHASE, PHASE_MASK, SCSISIGI;
  986. cmp LASTPHASE, P_MESGIN jne mesgin_phasemis;
  987. inb_first:
  988. mov DINDEX,SINDEX;
  989. mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/
  990. inb_last:
  991. mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/
  992. mesgin_phasemis:
  993. /*
  994.  * We expected to receive another byte, but the target changed phase
  995.  */
  996. mvi INTSTAT, MSGIN_PHASEMIS;
  997. jmp ITloop;
  998. /*
  999.  * DMA data transfer.  HADDR and HCNT must be loaded first, and
  1000.  * SINDEX should contain the value to load DFCNTRL with - 0x3d for
  1001.  * host->scsi, or 0x39 for scsi->host.  The SCSI channel is cleared
  1002.  * during initialization.
  1003.  */
  1004. if ((p->features & AHC_ULTRA2) == 0) {
  1005. dma:
  1006. mov DFCNTRL,SINDEX;
  1007. dma_loop:
  1008. test SSTAT0,DMADONE jnz dma_dmadone;
  1009. test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */
  1010. dma_phasemis:
  1011. test SSTAT0,SDONE jnz dma_checkfifo;
  1012. mov SINDEX,ALLZEROS; /* Notify caller of phasemiss */
  1013. /*
  1014.  * We will be "done" DMAing when the transfer count goes to zero, or
  1015.  * the target changes the phase (in light of this, it makes sense that
  1016.  * the DMA circuitry doesn't ACK when PHASEMIS is active).  If we are
  1017.  * doing a SCSI->Host transfer, the data FIFO should be flushed auto-
  1018.  * magically on STCNT=0 or a phase change, so just wait for FIFO empty
  1019.  * status.
  1020.  */
  1021. dma_checkfifo:
  1022. test DFCNTRL,DIRECTION jnz dma_fifoempty;
  1023. dma_fifoflush:
  1024. test DFSTATUS,FIFOEMP jz dma_fifoflush;
  1025. dma_fifoempty:
  1026. /* Don't clobber an inprogress host data transfer */
  1027. test DFSTATUS, MREQPEND jnz dma_fifoempty;
  1028. /*
  1029.  * Now shut the DMA enables off and make sure that the DMA enables are 
  1030.  * actually off first lest we get an ILLSADDR.
  1031.  */
  1032. dma_dmadone:
  1033. cmp LASTPHASE, P_COMMAND je dma_await_nreq;
  1034. test SCSIRATE, 0x0f jnz dma_shutdown;
  1035. dma_await_nreq:
  1036. test SCSISIGI, REQI jz dma_shutdown;
  1037. test SSTAT1, (PHASEMIS|REQINIT) jz dma_await_nreq;
  1038. dma_shutdown:
  1039. and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
  1040. dma_halt:
  1041. /*
  1042.  * Some revisions of the aic7880 have a problem where, if the
  1043.  * data fifo is full, but the PCI input latch is not empty, 
  1044.  * HDMAEN cannot be cleared.  The fix used here is to attempt
  1045.  * to drain the data fifo until there is space for the input
  1046.  * latch to drain and HDMAEN de-asserts.
  1047.  */
  1048. if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) {
  1049. mov NONE, DFDAT;
  1050. }
  1051. test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt;
  1052. }
  1053. return:
  1054. ret;
  1055. /*
  1056.  * Assert that if we've been reselected, then we've seen an IDENTIFY
  1057.  * message.
  1058.  */
  1059. assert:
  1060. test SEQ_FLAGS,IDENTIFY_SEEN jnz return; /* seen IDENTIFY? */
  1061. mvi INTSTAT,NO_IDENT  ret; /* no - tell the kernel */
  1062. /*
  1063.  * Locate a disconnected SCB either by SAVED_TCL (ARG_1 is SCB_LIST_NULL)
  1064.  * or by the SCBID ARG_1.  The search begins at the SCB index passed in
  1065.  * via SINDEX which is an SCB that must be on the disconnected list.  If
  1066.  * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR
  1067.  * is set to the proper SCB.
  1068.  */
  1069. findSCB:
  1070. mov SCBPTR,SINDEX; /* Initialize SCBPTR */
  1071. cmp ARG_1, SCB_LIST_NULL jne findSCB_by_SCBID;
  1072. mov A, SAVED_TCL;
  1073. mvi SCB_TCL jmp findSCB_loop; /* &SCB_TCL -> SINDEX */
  1074. findSCB_by_SCBID:
  1075. mov A, ARG_1; /* Tag passed in ARG_1 */
  1076. mvi SCB_TAG jmp findSCB_loop; /* &SCB_TAG -> SINDEX */
  1077. findSCB_next:
  1078. mov     ARG_2, SCBPTR;
  1079. cmp SCB_NEXT, SCB_LIST_NULL je notFound;
  1080. mov SCBPTR,SCB_NEXT;
  1081. dec SINDEX; /* Last comparison moved us too far */
  1082. findSCB_loop:
  1083. cmp SINDIR, A jne findSCB_next;
  1084. mov SINDEX, SCBPTR  ret;
  1085. notFound:
  1086. mvi SINDEX, SCB_LIST_NULL ret;
  1087. /*
  1088.  * Retrieve an SCB by SCBID first searching the disconnected list falling
  1089.  * back to DMA'ing the SCB down from the host.  This routine assumes that
  1090.  * ARG_1 is the SCBID of interrest and that SINDEX is the position in the
  1091.  * disconnected list to start the search from.  If SINDEX is SCB_LIST_NULL,
  1092.  * we go directly to the host for the SCB.
  1093.  */
  1094. retrieveSCB:
  1095. test SEQ_FLAGS, SCBPTR_VALID jz retrieve_from_host;
  1096. mov SCBPTR call findSCB; /* Continue the search */
  1097. cmp SINDEX, SCB_LIST_NULL je retrieve_from_host;
  1098. /*
  1099.  * This routine expects SINDEX to contain the index of the SCB to be
  1100.  * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the
  1101.  * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL
  1102.  * if it is at the head.
  1103.  */
  1104. rem_scb_from_disc_list:
  1105. /* Remove this SCB from the disconnection list */
  1106. cmp     ARG_2, SCB_LIST_NULL    je rHead;
  1107. mov DINDEX, SCB_NEXT;
  1108. mov SCBPTR, ARG_2;
  1109. mov SCB_NEXT, DINDEX;
  1110. mov SCBPTR, SINDEX ret;
  1111. rHead:
  1112. mov DISCONNECTED_SCBH,SCB_NEXT ret;
  1113. retrieve_from_host:
  1114. /*
  1115.  * We didn't find it.  Pull an SCB and DMA down the one we want.
  1116.  * We should never get here in the non-paging case.
  1117.  */
  1118. mov ALLZEROS call get_free_or_disc_scb;
  1119. mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
  1120. /* Jump instead of call as we want to return anyway */
  1121. mov ARG_1 jmp dma_scb;
  1122. /*
  1123.  * Determine whether a target is using tagged or non-tagged transactions
  1124.  * by first looking for a matching transaction based on the TCL and if
  1125.  * that fails, looking up this device in the host's untagged SCB array.
  1126.  * The TCL to search for is assumed to be in SAVED_TCL.  The value is
  1127.  * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged).
  1128.  * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information
  1129.  * in an SCB instead of having to go to the host.
  1130.  */
  1131. get_untagged_SCBID:
  1132. cmp DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host;
  1133. mvi ARG_1, SCB_LIST_NULL;
  1134. mov DISCONNECTED_SCBH call findSCB;
  1135. cmp SINDEX, SCB_LIST_NULL je get_SCBID_from_host;
  1136. or SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */
  1137. test SCB_CONTROL, TAG_ENB jnz . + 2;
  1138. mov ARG_1, SCB_TAG ret;
  1139. mvi ARG_1, SCB_LIST_NULL ret;
  1140. /*
  1141.  * Fetch a byte from host memory given an index of (A + (256 * SINDEX))
  1142.  * and a base address of SCBID_ADDR.  The byte is returned in RETURN_2.
  1143.  */
  1144. fetch_byte:
  1145. mov ARG_2, SINDEX;
  1146. if ((p->features & AHC_CMD_CHAN) != 0) {
  1147. mvi DINDEX, CCHADDR;
  1148. mvi SCBID_ADDR call set_1byte_addr;
  1149. mvi CCHCNT, 1;
  1150. mvi CCSGCTL, CCSGEN|CCSGRESET;
  1151. test CCSGCTL, CCSGDONE jz .;
  1152. mvi CCSGCTL, CCSGRESET;
  1153. bmov RETURN_2, CCSGRAM, 1 ret;
  1154. } else {
  1155. mvi DINDEX, HADDR;
  1156. mvi SCBID_ADDR call set_1byte_addr;
  1157. mvi HCNT[0], 1;
  1158. clr HCNT[1];
  1159. clr HCNT[2];
  1160. mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
  1161. call dma_finish;
  1162. mov RETURN_2, DFDAT ret;
  1163. }
  1164. /*
  1165.  * Prepare the hardware to post a byte to host memory given an
  1166.  * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR.
  1167.  */
  1168. post_byte_setup:
  1169. mov ARG_2, SINDEX;
  1170. if ((p->features & AHC_CMD_CHAN) != 0) {
  1171. mvi DINDEX, CCHADDR;
  1172. mvi SCBID_ADDR call set_1byte_addr;
  1173. mvi CCHCNT, 1;
  1174. mvi CCSCBCTL, CCSCBRESET ret;
  1175. } else {
  1176. mvi DINDEX, HADDR;
  1177. mvi SCBID_ADDR call set_1byte_addr;
  1178. mvi HCNT[0], 1;
  1179. clr HCNT[1];
  1180. clr HCNT[2];
  1181. mvi DFCNTRL, FIFORESET ret;
  1182. }
  1183. post_byte:
  1184. if ((p->features & AHC_CMD_CHAN) != 0) {
  1185. bmov CCSCBRAM, SINDEX, 1;
  1186. or CCSCBCTL, CCSCBEN|CCSCBRESET;
  1187. test CCSCBCTL, CCSCBDONE jz .;
  1188. clr CCSCBCTL ret;
  1189. } else {
  1190. mov DFDAT, SINDEX;
  1191. or DFCNTRL, HDMAEN|FIFOFLUSH;
  1192. jmp dma_finish;
  1193. }
  1194. get_SCBID_from_host:
  1195. mov A, SAVED_TCL;
  1196. mvi UNTAGGEDSCB_OFFSET call fetch_byte;
  1197. mov RETURN_1,  RETURN_2 ret;
  1198. phase_lock:     
  1199. test SSTAT1, REQINIT jz phase_lock;
  1200. test SSTAT1, SCSIPERR jnz phase_lock;
  1201. and SCSISIGO, PHASE_MASK, SCSISIGI;
  1202. and LASTPHASE, PHASE_MASK, SCSISIGI ret;
  1203. if ((p->features & AHC_CMD_CHAN) == 0) {
  1204. set_stcnt_from_hcnt:
  1205. mov STCNT[0], HCNT[0];
  1206. mov STCNT[1], HCNT[1];
  1207. mov STCNT[2], HCNT[2] ret;
  1208. bcopy_7:
  1209. mov DINDIR, SINDIR;
  1210. mov DINDIR, SINDIR;
  1211. bcopy_5:
  1212. mov DINDIR, SINDIR;
  1213. bcopy_4:
  1214. mov DINDIR, SINDIR;
  1215. bcopy_3:
  1216. mov DINDIR, SINDIR;
  1217. mov DINDIR, SINDIR;
  1218. mov DINDIR, SINDIR ret;
  1219. }
  1220. /*
  1221.  * Setup addr assuming that A is an index into
  1222.  * an array of 32byte objects, SINDEX contains
  1223.  * the base address of that array, and DINDEX
  1224.  * contains the base address of the location
  1225.  * to store the indexed address.
  1226.  */
  1227. set_32byte_addr:
  1228. shr ARG_2, 3, A;
  1229. shl A, 5;
  1230. /*
  1231.  * Setup addr assuming that A + (ARG_1 * 256) is an
  1232.  * index into an array of 1byte objects, SINDEX contains
  1233.  * the base address of that array, and DINDEX contains
  1234.  * the base address of the location to store the computed
  1235.  * address.
  1236.  */
  1237. set_1byte_addr:
  1238. add DINDIR, A, SINDIR;
  1239. mov A, ARG_2;
  1240. adc DINDIR, A, SINDIR;
  1241. clr A;
  1242. adc DINDIR, A, SINDIR;
  1243. adc DINDIR, A, SINDIR ret;
  1244. /*
  1245.  * Either post or fetch and SCB from host memory based on the
  1246.  * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX.
  1247.  */
  1248. dma_scb:
  1249. mov A, SINDEX;
  1250. if ((p->features & AHC_CMD_CHAN) != 0) {
  1251. mvi DINDEX, CCHADDR;
  1252. mvi HSCB_ADDR call set_32byte_addr;
  1253. mov CCSCBPTR, SCBPTR;
  1254. mvi CCHCNT, 32;
  1255. test DMAPARAMS, DIRECTION jz dma_scb_tohost;
  1256. mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET;
  1257. cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;
  1258. jmp dma_scb_finish;
  1259. dma_scb_tohost:
  1260. if ((p->features & AHC_ULTRA2) == 0) {
  1261. mvi CCSCBCTL, CCSCBRESET;
  1262. bmov CCSCBRAM, SCB_CONTROL, 32;
  1263. or CCSCBCTL, CCSCBEN|CCSCBRESET;
  1264. test CCSCBCTL, CCSCBDONE jz .;
  1265. }
  1266. if ((p->features & AHC_ULTRA2) != 0) {
  1267. if ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0) {
  1268. mvi     CCSCBCTL, CCARREN|CCSCBRESET;
  1269. cmp     CCSCBCTL, ARRDONE|CCARREN jne .;
  1270.                          mvi     CCHCNT, 32;
  1271. mvi     CCSCBCTL, CCSCBEN|CCSCBRESET;
  1272. cmp     CCSCBCTL, CCSCBDONE|CCSCBEN jne .;
  1273. } else {
  1274. mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET;
  1275. cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .;
  1276. }
  1277. }
  1278. dma_scb_finish:
  1279. clr CCSCBCTL;
  1280. test CCSCBCTL, CCARREN|CCSCBEN jnz .;
  1281. ret;
  1282. }
  1283. if ((p->features & AHC_CMD_CHAN) == 0) {
  1284. mvi DINDEX, HADDR;
  1285. mvi HSCB_ADDR call set_32byte_addr;
  1286. mvi HCNT[0], 32;
  1287. clr HCNT[1];
  1288. clr HCNT[2];
  1289. mov DFCNTRL, DMAPARAMS;
  1290. test DMAPARAMS, DIRECTION jnz dma_scb_fromhost;
  1291. /* Fill it with the SCB data */
  1292. copy_scb_tofifo:
  1293. mvi SINDEX, SCB_CONTROL;
  1294. add A, 32, SINDEX;
  1295. copy_scb_tofifo_loop:
  1296. mov DFDAT,SINDIR;
  1297. mov DFDAT,SINDIR;
  1298. mov DFDAT,SINDIR;
  1299. mov DFDAT,SINDIR;
  1300. mov DFDAT,SINDIR;
  1301. mov DFDAT,SINDIR;
  1302. mov DFDAT,SINDIR;
  1303. mov DFDAT,SINDIR;
  1304. cmp SINDEX, A jne copy_scb_tofifo_loop;
  1305. or DFCNTRL, HDMAEN|FIFOFLUSH;
  1306. jmp dma_finish;
  1307. dma_scb_fromhost:
  1308. mvi DINDEX, SCB_CONTROL;
  1309. if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) {
  1310. /*
  1311.  * Set the A to -24.  It it hits 0, then we let
  1312.  * our code fall through to dfdat_in_8 to complete
  1313.  * the last of the copy.
  1314.  *
  1315.  * Also, things happen 8 bytes at a time in this
  1316.  * case, so we may need to drain the fifo at most
  1317.  * 3 times to keep things flowing
  1318.  */
  1319. mvi A, -24;
  1320. dma_scb_hang_fifo:
  1321. /* Wait for the first bit of data to hit the fifo */
  1322. test DFSTATUS, FIFOEMP jnz .;
  1323. dma_scb_hang_wait:
  1324. /* OK, now they've started to transfer into the fifo,
  1325.  * so wait for them to stop trying to transfer any
  1326.  * more data.
  1327.  */
  1328. test DFSTATUS, MREQPEND jnz .;
  1329. /*
  1330.  * OK, they started, then they stopped, now see if they
  1331.  * managed to complete the job before stopping.  Try
  1332.  * it multiple times to give the chip a few cycles to
  1333.  * set the flag if it did complete.
  1334.  */
  1335. test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
  1336. test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
  1337. test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
  1338. /*
  1339.  * Too bad, the chip didn't complete the DMA, but there
  1340.  * aren't any more memory requests pending, so that
  1341.  * means it stopped part way through and hung.  That's
  1342.  * our bug, so now we drain what data there is in the
  1343.  * fifo in order to get things going again.
  1344.  */
  1345. dma_scb_hang_empty_fifo:
  1346. call dfdat_in_8;
  1347. add A, 8;
  1348. add SINDEX, A, HCNT;
  1349. /*
  1350.  * If there are another 8 bytes of data waiting in the
  1351.  * fifo, then the carry bit will be set as a result
  1352.  * of the above add command (unless A is non-negative,
  1353.  * in which case the carry bit won't be set).
  1354.  */
  1355. jc dma_scb_hang_empty_fifo;
  1356. /*
  1357.  * We've emptied the fifo now, but we wouldn't have got
  1358.  * here if the memory transfer hadn't stopped part way
  1359.  * through, so go back up to the beginning of the
  1360.  * loop and start over.  When it succeeds in getting
  1361.  * all the data down, HDONE will be set and we'll
  1362.  * jump to the code just below here.
  1363.  */
  1364. jmp dma_scb_hang_fifo;
  1365. dma_scb_hang_dma_done:
  1366. and DFCNTRL, ~HDMAEN;
  1367. test DFCNTRL, HDMAEN jnz .;
  1368. call dfdat_in_8;
  1369. add A, 8;
  1370. cmp A, 8 jne . - 2;
  1371. ret;
  1372. } else {
  1373. call dma_finish;
  1374. call dfdat_in_8;
  1375. call dfdat_in_8;
  1376. call dfdat_in_8;
  1377. }
  1378. dfdat_in_8:
  1379. mov DINDIR,DFDAT;
  1380. dfdat_in_7:
  1381. mov DINDIR,DFDAT;
  1382. mov DINDIR,DFDAT;
  1383. mov DINDIR,DFDAT;
  1384. mov DINDIR,DFDAT;
  1385. mov DINDIR,DFDAT;
  1386. mov DINDIR,DFDAT;
  1387. mov DINDIR,DFDAT ret;
  1388. }
  1389. /*
  1390.  * Wait for DMA from host memory to data FIFO to complete, then disable
  1391.  * DMA and wait for it to acknowledge that it's off.
  1392.  */
  1393. if ((p->features & AHC_CMD_CHAN) == 0) {
  1394. dma_finish:
  1395. test DFSTATUS,HDONE jz dma_finish;
  1396. /* Turn off DMA */
  1397. and DFCNTRL, ~HDMAEN;
  1398. test DFCNTRL, HDMAEN jnz .;
  1399. ret;
  1400. }
  1401. add_scb_to_free_list:
  1402. if ((p->flags & AHC_PAGESCBS) != 0) {
  1403. mov SCB_NEXT, FREE_SCBH;
  1404. mov FREE_SCBH, SCBPTR;
  1405. }
  1406. mvi SCB_TAG, SCB_LIST_NULL ret;
  1407. if ((p->flags & AHC_PAGESCBS) != 0) {
  1408. get_free_or_disc_scb:
  1409. cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
  1410. cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
  1411. return_error:
  1412. mvi SINDEX, SCB_LIST_NULL ret;
  1413. dequeue_disc_scb:
  1414. mov SCBPTR, DISCONNECTED_SCBH;
  1415. dma_up_scb:
  1416. mvi DMAPARAMS, FIFORESET;
  1417. mov SCB_TAG call dma_scb;
  1418. unlink_disc_scb:
  1419. mov DISCONNECTED_SCBH, SCB_NEXT ret;
  1420. dequeue_free_scb:
  1421. mov SCBPTR, FREE_SCBH;
  1422. mov FREE_SCBH, SCB_NEXT ret;
  1423. }
  1424. add_scb_to_disc_list:
  1425. /*
  1426.  * Link this SCB into the DISCONNECTED list.  This list holds the
  1427.  * candidates for paging out an SCB if one is needed for a new command.
  1428.  * Modifying the disconnected list is a critical(pause dissabled) section.
  1429.  */
  1430. mov SCB_NEXT, DISCONNECTED_SCBH;
  1431. mov DISCONNECTED_SCBH, SCBPTR ret;