home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / scsi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  28.7 KB  |  1,195 lines

  1. /*
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Van Jacobson of Lawrence Berkeley Laboratory.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)scsi.c    7.5 (Berkeley) 5/4/91
  37.  */
  38.  
  39. /*
  40.  * HP9000/3xx 98658 SCSI host adaptor driver.
  41.  */
  42. #include "scsi.h"
  43. #if NSCSI > 0
  44.  
  45. #ifndef lint
  46. static char rcsid[] = "$Header: scsi.c,v 1.4 91/01/17 12:50:18 mike Exp $";
  47. #endif
  48.  
  49. #include "sys/param.h"
  50. #include "sys/systm.h"
  51. #include "sys/buf.h"
  52. #include "device.h"
  53.  
  54. #include "scsivar.h"
  55. #include "scsireg.h"
  56. #include "dmavar.h"
  57.  
  58. #include "../include/cpu.h"
  59. #include "../hp300/isr.h"
  60.  
  61. /*
  62.  * SCSI delays
  63.  * In u-seconds, primarily for state changes on the SPC.
  64.  */
  65. #define    SCSI_CMD_WAIT    1000    /* wait per step of 'immediate' cmds */
  66. #define    SCSI_DATA_WAIT    1000    /* wait per data in/out step */
  67. #define    SCSI_INIT_WAIT    50000    /* wait per step (both) during init */
  68.  
  69. extern void isrlink();
  70. extern void _insque();
  71. extern void _remque();
  72.  
  73. int    scsiinit(), scsigo(), scsiintr(), scsixfer();
  74. void    scsistart(), scsidone(), scsifree(), scsireset();
  75. struct    driver scsidriver = {
  76.     scsiinit, "scsi", (int (*)())scsistart, scsigo, scsiintr,
  77.     (int (*)())scsidone,
  78. };
  79.  
  80. struct    scsi_softc scsi_softc[NSCSI];
  81. struct    isr scsi_isr[NSCSI];
  82.  
  83. int scsi_cmd_wait = SCSI_CMD_WAIT;
  84. int scsi_data_wait = SCSI_DATA_WAIT;
  85. int scsi_init_wait = SCSI_INIT_WAIT;
  86.  
  87. int scsi_nosync = 1;        /* inhibit sync xfers if 1 */
  88. int scsi_pridma = 0;        /* use "priority" dma */
  89.  
  90. #ifdef DEBUG
  91. int    scsi_debug = 0;
  92. #define WAITHIST
  93. #endif
  94.  
  95. #ifdef WAITHIST
  96. #define MAXWAIT    1022
  97. u_int    ixstart_wait[MAXWAIT+2];
  98. u_int    ixin_wait[MAXWAIT+2];
  99. u_int    ixout_wait[MAXWAIT+2];
  100. u_int    mxin_wait[MAXWAIT+2];
  101. u_int    mxin2_wait[MAXWAIT+2];
  102. u_int    cxin_wait[MAXWAIT+2];
  103. u_int    fxfr_wait[MAXWAIT+2];
  104. u_int    sgo_wait[MAXWAIT+2];
  105. #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]);
  106. #else
  107. #define HIST(h,w)
  108. #endif
  109.  
  110. #define    b_cylin        b_resid
  111.  
  112. static void
  113. scsiabort(hs, hd, where)
  114.     register struct scsi_softc *hs;
  115.     volatile register struct scsidevice *hd;
  116.     char *where;
  117. {
  118.     int len;
  119.     u_char junk;
  120.  
  121.     printf("scsi%d: abort from %s: phase=0x%x, ssts=0x%x, ints=0x%x\n",
  122.         hs->sc_hc->hp_unit, where, hd->scsi_psns, hd->scsi_ssts,
  123.         hd->scsi_ints);
  124.  
  125.     hd->scsi_ints = hd->scsi_ints;
  126.     hd->scsi_csr = 0;
  127.     if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
  128.         /* no longer connected to scsi target */
  129.         return;
  130.  
  131.     /* get the number of bytes remaining in current xfer + fudge */
  132.     len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
  133.  
  134.     /* for that many bus cycles, try to send an abort msg */
  135.     for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
  136.         hd->scsi_scmd = SCMD_SET_ATN;
  137.         while ((hd->scsi_psns & PSNS_REQ) == 0) {
  138.             if (! (hd->scsi_ssts & SSTS_INITIATOR))
  139.                 goto out;
  140.             DELAY(1);
  141.         }
  142.         if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
  143.             hd->scsi_scmd = SCMD_RST_ATN;
  144.         hd->scsi_pctl = hd->scsi_psns & PHASE;
  145.         if (hd->scsi_psns & PHASE_IO) {
  146.             /* one of the input phases - read & discard a byte */
  147.             hd->scsi_scmd = SCMD_SET_ACK;
  148.             if (hd->scsi_tmod == 0)
  149.                 while (hd->scsi_psns & PSNS_REQ)
  150.                     DELAY(1);
  151.             junk = hd->scsi_temp;
  152.         } else {
  153.             /* one of the output phases - send an abort msg */
  154.             hd->scsi_temp = MSG_ABORT;
  155.             hd->scsi_scmd = SCMD_SET_ACK;
  156.             if (hd->scsi_tmod == 0)
  157.                 while (hd->scsi_psns & PSNS_REQ)
  158.                     DELAY(1);
  159.         }
  160.         hd->scsi_scmd = SCMD_RST_ACK;
  161.     }
  162. out:
  163.     /*
  164.      * Either the abort was successful & the bus is disconnected or
  165.      * the device didn't listen.  If the latter, announce the problem.
  166.      * Either way, reset the card & the SPC.
  167.      */
  168.     if (len < 0 && hs)
  169.         printf("scsi%d: abort failed.  phase=0x%x, ssts=0x%x\n",
  170.             hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
  171.  
  172.     if (! ((junk = hd->scsi_ints) & INTS_RESEL)) {
  173.         hd->scsi_sctl |= SCTL_CTRLRST;
  174.         DELAY(1);
  175.         hd->scsi_sctl &=~ SCTL_CTRLRST;
  176.         hd->scsi_hconf = 0;
  177.         hd->scsi_ints = hd->scsi_ints;
  178.     }
  179. }
  180.  
  181. /*
  182.  * XXX Set/reset long delays.
  183.  *
  184.  * if delay == 0, reset default delays
  185.  * if delay < 0,  set both delays to default long initialization values
  186.  * if delay > 0,  set both delays to this value
  187.  *
  188.  * Used when a devices is expected to respond slowly (e.g. during
  189.  * initialization).
  190.  */
  191. void
  192. scsi_delay(delay)
  193.     int delay;
  194. {
  195.     static int saved_cmd_wait, saved_data_wait;
  196.  
  197.     if (delay) {
  198.         saved_cmd_wait = scsi_cmd_wait;
  199.         saved_data_wait = scsi_data_wait;
  200.         if (delay > 0)
  201.             scsi_cmd_wait = scsi_data_wait = delay;
  202.         else
  203.             scsi_cmd_wait = scsi_data_wait = scsi_init_wait;
  204.     } else {
  205.         scsi_cmd_wait = saved_cmd_wait;
  206.         scsi_data_wait = saved_data_wait;
  207.     }
  208. }
  209.  
  210. int
  211. scsiinit(hc)
  212.     register struct hp_ctlr *hc;
  213. {
  214.     register struct scsi_softc *hs = &scsi_softc[hc->hp_unit];
  215.     register struct scsidevice *hd = (struct scsidevice *)hc->hp_addr;
  216.     
  217.     if ((hd->scsi_id & ID_MASK) != SCSI_ID)
  218.         return(0);
  219.     hc->hp_ipl = SCSI_IPL(hd->scsi_csr);
  220.     hs->sc_hc = hc;
  221.     hs->sc_dq.dq_unit = hc->hp_unit;
  222.     hs->sc_dq.dq_driver = &scsidriver;
  223.     hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
  224.     scsi_isr[hc->hp_unit].isr_intr = scsiintr;
  225.     scsi_isr[hc->hp_unit].isr_ipl = hc->hp_ipl;
  226.     scsi_isr[hc->hp_unit].isr_arg = hc->hp_unit;
  227.     isrlink(&scsi_isr[hc->hp_unit]);
  228.     scsireset(hc->hp_unit);
  229.     return(1);
  230. }
  231.  
  232. void
  233. scsireset(unit)
  234.     register int unit;
  235. {
  236.     register struct scsi_softc *hs = &scsi_softc[unit];
  237.     volatile register struct scsidevice *hd =
  238.                 (struct scsidevice *)hs->sc_hc->hp_addr;
  239.     u_int i;
  240.  
  241.     if (hs->sc_flags & SCSI_ALIVE)
  242.         scsiabort(hs, hd, "reset");
  243.         
  244.     printf("scsi%d: ", unit);
  245.  
  246.     hd->scsi_id = 0xFF;
  247.     DELAY(100);
  248.     /*
  249.      * Disable interrupts then reset the FUJI chip.
  250.      */
  251.     hd->scsi_csr  = 0;
  252.     hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
  253.     hd->scsi_scmd = 0;
  254.     hd->scsi_tmod = 0;
  255.     hd->scsi_pctl = 0;
  256.     hd->scsi_temp = 0;
  257.     hd->scsi_tch  = 0;
  258.     hd->scsi_tcm  = 0;
  259.     hd->scsi_tcl  = 0;
  260.     hd->scsi_ints = 0;
  261.  
  262.     if ((hd->scsi_id & ID_WORD_DMA) == 0) {
  263.         hs->sc_flags |= SCSI_DMA32;
  264.         printf("32 bit dma, ");
  265.     }
  266.  
  267.     /* Determine Max Synchronous Transfer Rate */
  268.     if (scsi_nosync)
  269.         i = 3;
  270.     else
  271.         i = SCSI_SYNC_XFER(hd->scsi_hconf);
  272.     switch (i) {
  273.         case 0:
  274.             hs->sc_sync = TMOD_SYNC | 0x3e; /* 250 nsecs */
  275.             printf("250ns sync");
  276.             break;
  277.         case 1:
  278.             hs->sc_sync = TMOD_SYNC | 0x5e; /* 375 nsecs */
  279.             printf("375ns sync");
  280.             break;
  281.         case 2:
  282.             hs->sc_sync = TMOD_SYNC | 0x7d; /* 500 nsecs */
  283.             printf("500ns sync");
  284.             break;
  285.         case 3:
  286.             hs->sc_sync = 0;
  287.             printf("async");
  288.             break;
  289.         }
  290.  
  291.     /*
  292.      * Configure the FUJI chip with its SCSI address, all
  293.      * interrupts enabled & appropriate parity.
  294.      */
  295.     i = (~hd->scsi_hconf) & 0x7;
  296.     hs->sc_scsi_addr = 1 << i;
  297.     hd->scsi_bdid = i;
  298.     if (hd->scsi_hconf & HCONF_PARITY)
  299.         hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
  300.                 SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
  301.                 SCTL_INTR_ENAB | SCTL_PARITY_ENAB;
  302.     else {
  303.         hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
  304.                 SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
  305.                 SCTL_INTR_ENAB;
  306.         printf(", no parity");
  307.     }
  308.     hd->scsi_sctl &=~ SCTL_DISABLE;
  309.  
  310.     printf(", scsi id %d\n", i);
  311.     hs->sc_flags |= SCSI_ALIVE;
  312. }
  313.  
  314. static void
  315. scsierror(hs, hd, ints)
  316.     register struct scsi_softc *hs;
  317.     volatile register struct scsidevice *hd;
  318.     u_char ints;
  319. {
  320.     int unit = hs->sc_hc->hp_unit;
  321.     char *sep = "";
  322.  
  323.     printf("scsi%d: ", unit);
  324.     if (ints & INTS_RST) {
  325.         DELAY(100);
  326.         if (hd->scsi_hconf & HCONF_SD)
  327.             printf("spurious RST interrupt");
  328.         else
  329.             printf("hardware error - check fuse");
  330.         sep = ", ";
  331.     }
  332.     if ((ints & INTS_HARD_ERR) || hd->scsi_serr) {
  333.         if (hd->scsi_serr & SERR_SCSI_PAR) {
  334.             printf("%sparity err", sep);
  335.             sep = ", ";
  336.         }
  337.         if (hd->scsi_serr & SERR_SPC_PAR) {
  338.             printf("%sSPC parity err", sep);
  339.             sep = ", ";
  340.         }
  341.         if (hd->scsi_serr & SERR_TC_PAR) {
  342.             printf("%sTC parity err", sep);
  343.             sep = ", ";
  344.         }
  345.         if (hd->scsi_serr & SERR_PHASE_ERR) {
  346.             printf("%sphase err", sep);
  347.             sep = ", ";
  348.         }
  349.         if (hd->scsi_serr & SERR_SHORT_XFR) {
  350.             printf("%ssync short transfer err", sep);
  351.             sep = ", ";
  352.         }
  353.         if (hd->scsi_serr & SERR_OFFSET) {
  354.             printf("%ssync offset error", sep);
  355.             sep = ", ";
  356.         }
  357.     }
  358.     if (ints & INTS_TIMEOUT)
  359.         printf("%sSPC select timeout error", sep);
  360.     if (ints & INTS_SRV_REQ)
  361.         printf("%sspurious SRV_REQ interrupt", sep);
  362.     if (ints & INTS_CMD_DONE)
  363.         printf("%sspurious CMD_DONE interrupt", sep);
  364.     if (ints & INTS_DISCON)
  365.         printf("%sspurious disconnect interrupt", sep);
  366.     if (ints & INTS_RESEL)
  367.         printf("%sspurious reselect interrupt", sep);
  368.     if (ints & INTS_SEL)
  369.         printf("%sspurious select interrupt", sep);
  370.     printf("\n");
  371. }
  372.  
  373. static int
  374. issue_select(hd, target, our_addr)
  375.     volatile register struct scsidevice *hd;
  376.     u_char target, our_addr;
  377. {
  378.     if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
  379.         return (1);
  380.  
  381.     if (hd->scsi_ints & INTS_DISCON)
  382.         hd->scsi_ints = INTS_DISCON;
  383.  
  384.     hd->scsi_pctl = 0;
  385.     hd->scsi_temp = (1 << target) | our_addr;
  386.     /* select timeout is hardcoded to 2ms */
  387.     hd->scsi_tch = 0;
  388.     hd->scsi_tcm = 32;
  389.     hd->scsi_tcl = 4;
  390.  
  391.     hd->scsi_scmd = SCMD_SELECT;
  392.     return (0);
  393. }
  394.  
  395. static int
  396. wait_for_select(hd)
  397.     volatile register struct scsidevice *hd;
  398. {
  399.     u_char ints;
  400.  
  401.     while ((ints = hd->scsi_ints) == 0)
  402.         DELAY(1);
  403.     hd->scsi_ints = ints;
  404.     return (!(hd->scsi_ssts & SSTS_INITIATOR));
  405. }
  406.  
  407. static int
  408. ixfer_start(hd, len, phase, wait)
  409.     volatile register struct scsidevice *hd;
  410.     int len;
  411.     u_char phase;
  412.     register int wait;
  413. {
  414.  
  415.     hd->scsi_tch = len >> 16;
  416.     hd->scsi_tcm = len >> 8;
  417.     hd->scsi_tcl = len;
  418.     hd->scsi_pctl = phase;
  419.     hd->scsi_tmod = 0; /*XXX*/
  420.     hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
  421.  
  422.     /* wait for xfer to start or svc_req interrupt */
  423.     while ((hd->scsi_ssts & SSTS_BUSY) == 0) {
  424.         if (hd->scsi_ints || --wait < 0) {
  425. #ifdef DEBUG
  426.             if (scsi_debug)
  427.                 printf("ixfer_start fail: i%x, w%d\n",
  428.                        hd->scsi_ints, wait);
  429. #endif
  430.             HIST(ixstart_wait, wait)
  431.             return (0);
  432.         }
  433.         DELAY(1);
  434.     }
  435.     HIST(ixstart_wait, wait)
  436.     return (1);
  437. }
  438.  
  439. static int
  440. ixfer_out(hd, len, buf)
  441.     volatile register struct scsidevice *hd;
  442.     int len;
  443.     register u_char *buf;
  444. {
  445.     register int wait = scsi_data_wait;
  446.  
  447.     for (; len > 0; --len) {
  448.         while (hd->scsi_ssts & SSTS_DREG_FULL) {
  449.             if (hd->scsi_ints || --wait < 0) {
  450. #ifdef DEBUG
  451.                 if (scsi_debug)
  452.                     printf("ixfer_out fail: l%d i%x w%d\n",
  453.                            len, hd->scsi_ints, wait);
  454. #endif
  455.                 HIST(ixout_wait, wait)
  456.                 return (len);
  457.             }
  458.             DELAY(1);
  459.         }
  460.         hd->scsi_dreg = *buf++;
  461.     }
  462.     HIST(ixout_wait, wait)
  463.     return (0);
  464. }
  465.  
  466. static void
  467. ixfer_in(hd, len, buf)
  468.     volatile register struct scsidevice *hd;
  469.     int len;
  470.     register u_char *buf;
  471. {
  472.     register int wait = scsi_data_wait;
  473.  
  474.     for (; len > 0; --len) {
  475.         while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
  476.             if (hd->scsi_ints || --wait < 0) {
  477.                 while (! (hd->scsi_ssts & SSTS_DREG_EMPTY)) {
  478.                     *buf++ = hd->scsi_dreg;
  479.                     --len;
  480.                 }
  481. #ifdef DEBUG
  482.                 if (scsi_debug)
  483.                     printf("ixfer_in fail: l%d i%x w%d\n",
  484.                            len, hd->scsi_ints, wait);
  485. #endif
  486.                 HIST(ixin_wait, wait)
  487.                 return;
  488.             }
  489.             DELAY(1);
  490.         }
  491.         *buf++ = hd->scsi_dreg;
  492.     }
  493.     HIST(ixin_wait, wait)
  494. }
  495.  
  496. static int
  497. mxfer_in(hd, len, buf, phase)
  498.     volatile register struct scsidevice *hd;
  499.     register int len;
  500.     register u_char *buf;
  501.     register u_char phase;
  502. {
  503.     register int wait = scsi_cmd_wait;
  504.     register int i;
  505.  
  506.     hd->scsi_tmod = 0;
  507.     for (i = 0; i < len; ++i) {
  508.         /*
  509.          * manual sez: reset ATN before ACK is sent.
  510.          */
  511.         if (hd->scsi_psns & PSNS_ATN)
  512.             hd->scsi_scmd = SCMD_RST_ATN;
  513.         /*
  514.          * wait for the request line (which says the target
  515.          * wants to give us data).  If the phase changes while
  516.          * we're waiting, we're done.
  517.          */
  518.         while ((hd->scsi_psns & PSNS_REQ) == 0) {
  519.             if (--wait < 0) {
  520.                 HIST(mxin_wait, wait)
  521.                 return (-1);
  522.             }
  523.             if ((hd->scsi_psns & PHASE) != phase ||
  524.                 (hd->scsi_ssts & SSTS_INITIATOR) == 0)
  525.                 goto out;
  526.  
  527.             DELAY(1);
  528.         }
  529.         /*
  530.          * set ack (which says we're ready for the data, wait for
  531.          * req to go away (target says data is available), grab the
  532.          * data, then reset ack (say we've got the data).
  533.          */
  534.         hd->scsi_pctl = phase;
  535.         hd->scsi_scmd = SCMD_SET_ACK;
  536.         while (hd->scsi_psns & PSNS_REQ) {
  537.             if (--wait < 0) {
  538.                 HIST(mxin_wait, wait)
  539.                 return (-2);
  540.             }
  541.             DELAY(1);
  542.         }
  543.         *buf++ = hd->scsi_temp;
  544.         hd->scsi_scmd = SCMD_RST_ACK;
  545.     }
  546. out:
  547.     HIST(mxin_wait, wait)
  548.     /*
  549.      * Wait for manual transfer to finish.
  550.      * Avoids occasional "unexpected phase" errors in finishxfer
  551.      * formerly addressed by per-slave delays.
  552.      */
  553.     wait = scsi_cmd_wait;
  554.     while ((hd->scsi_ssts & SSTS_ACTIVE) == SSTS_INITIATOR) {
  555.         if (--wait < 0)
  556.             break;
  557.         DELAY(1);
  558.     }
  559.     HIST(mxin2_wait, wait)
  560.     return (i);
  561. }
  562.  
  563. /*
  564.  * SCSI 'immediate' command:  issue a command to some SCSI device
  565.  * and get back an 'immediate' response (i.e., do programmed xfer
  566.  * to get the response data).  'cbuf' is a buffer containing a scsi
  567.  * command of length clen bytes.  'buf' is a buffer of length 'len'
  568.  * bytes for data.  The transfer direction is determined by the device
  569.  * (i.e., by the scsi bus data xfer phase).  If 'len' is zero, the
  570.  * command must supply no data.  'xferphase' is the bus phase the
  571.  * caller expects to happen after the command is issued.  It should
  572.  * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE.
  573.  */
  574. static int
  575. scsiicmd(hs, target, cbuf, clen, buf, len, xferphase)
  576.     struct scsi_softc *hs;
  577.     int target;
  578.     u_char *cbuf;
  579.     int clen;
  580.     u_char *buf;
  581.     int len;
  582.     u_char xferphase;
  583. {
  584.     volatile register struct scsidevice *hd =
  585.                 (struct scsidevice *)hs->sc_hc->hp_addr;
  586.     u_char phase, ints;
  587.     register int wait;
  588.  
  589.     /* select the SCSI bus (it's an error if bus isn't free) */
  590.     if (issue_select(hd, target, hs->sc_scsi_addr))
  591.         return (-1);
  592.     if (wait_for_select(hd))
  593.         return (-1);
  594.     /*
  595.      * Wait for a phase change (or error) then let the device
  596.      * sequence us through the various SCSI phases.
  597.      */
  598.     hs->sc_stat[0] = 0xff;
  599.     hs->sc_msg[0] = 0xff;
  600.     phase = CMD_PHASE;
  601.     while (1) {
  602.         wait = scsi_cmd_wait;
  603.         switch (phase) {
  604.  
  605.         case CMD_PHASE:
  606.             if (ixfer_start(hd, clen, phase, wait))
  607.                 if (ixfer_out(hd, clen, cbuf))
  608.                     goto abort;
  609.             phase = xferphase;
  610.             break;
  611.  
  612.         case DATA_IN_PHASE:
  613.             if (len <= 0)
  614.                 goto abort;
  615.             wait = scsi_data_wait;
  616.             if (ixfer_start(hd, len, phase, wait) ||
  617.                 !(hd->scsi_ssts & SSTS_DREG_EMPTY))
  618.                 ixfer_in(hd, len, buf);
  619.             phase = STATUS_PHASE;
  620.             break;
  621.  
  622.         case DATA_OUT_PHASE:
  623.             if (len <= 0)
  624.                 goto abort;
  625.             wait = scsi_data_wait;
  626.             if (ixfer_start(hd, len, phase, wait)) {
  627.                 if (ixfer_out(hd, len, buf))
  628.                     goto abort;
  629.             }
  630.             phase = STATUS_PHASE;
  631.             break;
  632.  
  633.         case STATUS_PHASE:
  634.             wait = scsi_data_wait;
  635.             if (ixfer_start(hd, sizeof(hs->sc_stat), phase, wait) ||
  636.                 !(hd->scsi_ssts & SSTS_DREG_EMPTY))
  637.                 ixfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat);
  638.             phase = MESG_IN_PHASE;
  639.             break;
  640.  
  641.         case MESG_IN_PHASE:
  642.             if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait) ||
  643.                 !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
  644.                 ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
  645.                 hd->scsi_scmd = SCMD_RST_ACK;
  646.             }
  647.             phase = BUS_FREE_PHASE;
  648.             break;
  649.  
  650.         case BUS_FREE_PHASE:
  651.             goto out;
  652.  
  653.         default:
  654.             printf("scsi%d: unexpected phase %d in icmd from %d\n",
  655.                 hs->sc_hc->hp_unit, phase, target);
  656.             goto abort;
  657.         }
  658.         /* wait for last command to complete */
  659.         while ((ints = hd->scsi_ints) == 0) {
  660.             if (--wait < 0) {
  661.                 HIST(cxin_wait, wait)
  662.                 goto abort;
  663.             }
  664.             DELAY(1);
  665.         }
  666.         HIST(cxin_wait, wait)
  667.         hd->scsi_ints = ints;
  668.         if (ints & INTS_SRV_REQ)
  669.             phase = hd->scsi_psns & PHASE;
  670.         else if (ints & INTS_DISCON)
  671.             goto out;
  672.         else if ((ints & INTS_CMD_DONE) == 0) {
  673.             scsierror(hs, hd, ints);
  674.             goto abort;
  675.         }
  676.     }
  677. abort:
  678.     scsiabort(hs, hd, "icmd");
  679. out:
  680.     return (hs->sc_stat[0]);
  681. }
  682.  
  683. /*
  684.  * Finish SCSI xfer command:  After the completion interrupt from
  685.  * a read/write operation, sequence through the final phases in
  686.  * programmed i/o.  This routine is a lot like scsiicmd except we
  687.  * skip (and don't allow) the select, cmd out and data in/out phases.
  688.  */
  689. static void
  690. finishxfer(hs, hd, target)
  691.     struct scsi_softc *hs;
  692.     volatile register struct scsidevice *hd;
  693.     int target;
  694. {
  695.     u_char phase, ints;
  696.  
  697.     /*
  698.      * We specified padding xfer so we ended with either a phase
  699.      * change interrupt (normal case) or an error interrupt (handled
  700.      * elsewhere).  Reset the board dma logic then try to get the
  701.      * completion status & command done msg.  The reset confuses
  702.      * the SPC REQ/ACK logic so we have to do any status/msg input
  703.      * operations via 'manual xfer'.
  704.      */
  705.     if (hd->scsi_ssts & SSTS_BUSY) {
  706.         int wait = scsi_cmd_wait;
  707.  
  708.         /* wait for dma operation to finish */
  709.         while (hd->scsi_ssts & SSTS_BUSY) {
  710.             if (--wait < 0) {
  711. #ifdef DEBUG
  712.                 if (scsi_debug)
  713.                     printf("finishxfer fail: ssts %x\n",
  714.                            hd->scsi_ssts);
  715. #endif
  716.                 HIST(fxfr_wait, wait)
  717.                 goto abort;
  718.             }
  719.         }
  720.         HIST(fxfr_wait, wait)
  721.     }
  722.     hd->scsi_scmd |= SCMD_PROG_XFR;
  723.     hd->scsi_sctl |= SCTL_CTRLRST;
  724.     DELAY(1);
  725.     hd->scsi_sctl &=~ SCTL_CTRLRST;
  726.     hd->scsi_hconf = 0;
  727.     hs->sc_stat[0] = 0xff;
  728.     hs->sc_msg[0] = 0xff;
  729.     hd->scsi_csr = 0;
  730.     hd->scsi_ints = ints = hd->scsi_ints;
  731.     while (1) {
  732.         phase = hd->scsi_psns & PHASE;
  733.         switch (phase) {
  734.  
  735.         case STATUS_PHASE:
  736.             if (mxfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat,
  737.                      phase) <= 0)
  738.                 goto abort;
  739.             break;
  740.  
  741.         case MESG_IN_PHASE:
  742.             if (mxfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg,
  743.                      phase) < 0)
  744.                 goto abort;
  745.             break;
  746.  
  747.         case BUS_FREE_PHASE:
  748.             return;
  749.  
  750.         default:
  751.             printf("scsi%d: unexpected phase %d in finishxfer from %d\n",
  752.                 hs->sc_hc->hp_unit, phase, target);
  753.             goto abort;
  754.         }
  755.         if (ints = hd->scsi_ints) {
  756.             hd->scsi_ints = ints;
  757.             if (ints & INTS_DISCON)
  758.                 return;
  759.             else if (ints & ~(INTS_SRV_REQ|INTS_CMD_DONE)) {
  760.                 scsierror(hs, hd, ints);
  761.                 break;
  762.             }
  763.         }
  764.         if ((hd->scsi_ssts & SSTS_INITIATOR) == 0)
  765.             return;
  766.     }
  767. abort:
  768.     scsiabort(hs, hd, "finishxfer");
  769.     hs->sc_stat[0] = 0xfe;
  770. }
  771.  
  772. int
  773. scsi_test_unit_rdy(ctlr, slave, unit)
  774.     int ctlr, slave, unit;
  775. {
  776.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  777.     static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
  778.  
  779.     cdb.lun = unit;
  780.     return (scsiicmd(hs, slave, &cdb, sizeof(cdb), (u_char *)0, 0,
  781.              STATUS_PHASE));
  782. }
  783.  
  784. int
  785. scsi_request_sense(ctlr, slave, unit, buf, len)
  786.     int ctlr, slave, unit;
  787.     u_char *buf;
  788.     unsigned len;
  789. {
  790.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  791.     static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
  792.  
  793.     cdb.lun = unit;
  794.     cdb.len = len;
  795.     return (scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE));
  796. }
  797.  
  798. int
  799. scsi_immed_command(ctlr, slave, unit, cdb, buf, len, rd)
  800.     int ctlr, slave, unit;
  801.     struct scsi_fmt_cdb *cdb;
  802.     u_char *buf;
  803.     unsigned len;
  804. {
  805.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  806.  
  807.     cdb->cdb[1] |= unit << 5;
  808.     return (scsiicmd(hs, slave, cdb->cdb, cdb->len, buf, len,
  809.              rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE));
  810. }
  811.  
  812. /*
  813.  * The following routines are test-and-transfer i/o versions of read/write
  814.  * for things like reading disk labels and writing core dumps.  The
  815.  * routine scsigo should be used for normal data transfers, NOT these
  816.  * routines.
  817.  */
  818. int
  819. scsi_tt_read(ctlr, slave, unit, buf, len, blk, bshift)
  820.     int ctlr, slave, unit;
  821.     u_char *buf;
  822.     u_int len;
  823.     daddr_t blk;
  824.     int bshift;
  825. {
  826.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  827.     struct scsi_cdb10 cdb;
  828.     int stat;
  829.     int old_wait = scsi_data_wait;
  830.  
  831.     scsi_data_wait = 300000;
  832.     bzero(&cdb, sizeof(cdb));
  833.     cdb.cmd = CMD_READ_EXT;
  834.     cdb.lun = unit;
  835.     blk >>= bshift;
  836.     cdb.lbah = blk >> 24;
  837.     cdb.lbahm = blk >> 16;
  838.     cdb.lbalm = blk >> 8;
  839.     cdb.lbal = blk;
  840.     cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
  841.     cdb.lenl = len >> (DEV_BSHIFT + bshift);
  842.     stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE);
  843.     scsi_data_wait = old_wait;
  844.     return (stat);
  845. }
  846.  
  847. int
  848. scsi_tt_write(ctlr, slave, unit, buf, len, blk, bshift)
  849.     int ctlr, slave, unit;
  850.     u_char *buf;
  851.     u_int len;
  852.     daddr_t blk;
  853.     int bshift;
  854. {
  855.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  856.     struct scsi_cdb10 cdb;
  857.     int stat;
  858.     int old_wait = scsi_data_wait;
  859.  
  860.     scsi_data_wait = 300000;
  861.  
  862.     bzero(&cdb, sizeof(cdb));
  863.     cdb.cmd = CMD_WRITE_EXT;
  864.     cdb.lun = unit;
  865.     blk >>= bshift;
  866.     cdb.lbah = blk >> 24;
  867.     cdb.lbahm = blk >> 16;
  868.     cdb.lbalm = blk >> 8;
  869.     cdb.lbal = blk;
  870.     cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
  871.     cdb.lenl = len >> (DEV_BSHIFT + bshift);
  872.     stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE);
  873.     scsi_data_wait = old_wait;
  874.     return (stat);
  875. }
  876.  
  877. int
  878. scsireq(dq)
  879.     register struct devqueue *dq;
  880. {
  881.     register struct devqueue *hq;
  882.  
  883.     hq = &scsi_softc[dq->dq_ctlr].sc_sq;
  884.     insque(dq, hq->dq_back);
  885.     if (dq->dq_back == hq)
  886.         return(1);
  887.     return(0);
  888. }
  889.  
  890. int
  891. scsiustart(unit)
  892.     int unit;
  893. {
  894.     register struct scsi_softc *hs = &scsi_softc[unit];
  895.  
  896.     hs->sc_dq.dq_ctlr = DMA0 | DMA1;
  897.     if (dmareq(&hs->sc_dq))
  898.         return(1);
  899.     return(0);
  900. }
  901.  
  902. void
  903. scsistart(unit)
  904.     int unit;
  905. {
  906.     register struct devqueue *dq;
  907.     
  908.     dq = scsi_softc[unit].sc_sq.dq_forw;
  909.     (dq->dq_driver->d_go)(dq->dq_unit);
  910. }
  911.  
  912. int
  913. scsigo(ctlr, slave, unit, bp, cdb, pad)
  914.     int ctlr, slave, unit;
  915.     struct buf *bp;
  916.     struct scsi_fmt_cdb *cdb;
  917.     int pad;
  918. {
  919.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  920.     volatile register struct scsidevice *hd =
  921.                 (struct scsidevice *)hs->sc_hc->hp_addr;
  922.     int i, dmaflags;
  923.     u_char phase, ints, cmd;
  924.  
  925.     cdb->cdb[1] |= unit << 5;
  926.  
  927.     /* select the SCSI bus (it's an error if bus isn't free) */
  928.     if (issue_select(hd, slave, hs->sc_scsi_addr) || wait_for_select(hd)) {
  929.         dmafree(&hs->sc_dq);
  930.         return (1);
  931.     }
  932.     /*
  933.      * Wait for a phase change (or error) then let the device
  934.      * sequence us through command phase (we may have to take
  935.      * a msg in/out before doing the command).  If the disk has
  936.      * to do a seek, it may be a long time until we get a change
  937.      * to data phase so, in the absense of an explicit phase
  938.      * change, we assume data phase will be coming up and tell
  939.      * the SPC to start a transfer whenever it does.  We'll get
  940.      * a service required interrupt later if this assumption is
  941.      * wrong.  Otherwise we'll get a service required int when
  942.      * the transfer changes to status phase.
  943.      */
  944.     phase = CMD_PHASE;
  945.     while (1) {
  946.         register int wait = scsi_cmd_wait;
  947.  
  948.         switch (phase) {
  949.  
  950.         case CMD_PHASE:
  951.             if (ixfer_start(hd, cdb->len, phase, wait))
  952.                 if (ixfer_out(hd, cdb->len, cdb->cdb))
  953.                     goto abort;
  954.             break;
  955.  
  956.         case MESG_IN_PHASE:
  957.             if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait)||
  958.                 !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
  959.                 ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
  960.                 hd->scsi_scmd = SCMD_RST_ACK;
  961.             }
  962.             phase = BUS_FREE_PHASE;
  963.             break;
  964.  
  965.         case DATA_IN_PHASE:
  966.         case DATA_OUT_PHASE:
  967.             goto out;
  968.  
  969.         default:
  970.             printf("scsi%d: unexpected phase %d in go from %d\n",
  971.                 hs->sc_hc->hp_unit, phase, slave);
  972.             goto abort;
  973.         }
  974.         while ((ints = hd->scsi_ints) == 0) {
  975.             if (--wait < 0) {
  976.                 HIST(sgo_wait, wait)
  977.                 goto abort;
  978.             }
  979.             DELAY(1);
  980.         }
  981.         HIST(sgo_wait, wait)
  982.         hd->scsi_ints = ints;
  983.         if (ints & INTS_SRV_REQ)
  984.             phase = hd->scsi_psns & PHASE;
  985.         else if (ints & INTS_CMD_DONE)
  986.             goto out;
  987.         else {
  988.             scsierror(hs, hd, ints);
  989.             goto abort;
  990.         }
  991.     }
  992. out:
  993.     /*
  994.      * Reset the card dma logic, setup the dma channel then
  995.      * get the dio part of the card set for a dma xfer.
  996.      */
  997.     hd->scsi_hconf = 0;
  998.     cmd = CSR_IE;
  999.     dmaflags = DMAGO_NOINT;
  1000.     if (scsi_pridma)
  1001.         dmaflags |= DMAGO_PRI;
  1002.     if (bp->b_flags & B_READ)
  1003.         dmaflags |= DMAGO_READ;
  1004.     if ((hs->sc_flags & SCSI_DMA32) &&
  1005.         ((int)bp->b_un.b_addr & 3) == 0 && (bp->b_bcount & 3) == 0) {
  1006.         cmd |= CSR_DMA32;
  1007.         dmaflags |= DMAGO_LWORD;
  1008.     } else
  1009.         dmaflags |= DMAGO_WORD;
  1010.     dmago(hs->sc_dq.dq_ctlr, bp->b_un.b_addr, bp->b_bcount, dmaflags);
  1011.  
  1012.     if (bp->b_flags & B_READ) {
  1013.         cmd |= CSR_DMAIN;
  1014.         phase = DATA_IN_PHASE;
  1015.     } else
  1016.         phase = DATA_OUT_PHASE;
  1017.     /*
  1018.      * DMA enable bits must be set after size and direction bits.
  1019.      */
  1020.     hd->scsi_csr = cmd;
  1021.     hd->scsi_csr |= (CSR_DE0 << hs->sc_dq.dq_ctlr);
  1022.     /*
  1023.      * Setup the SPC for the transfer.  We don't want to take
  1024.      * first a command complete then a service required interrupt
  1025.      * at the end of the transfer so we try to disable the cmd
  1026.      * complete by setting the transfer counter to more bytes
  1027.      * than we expect.  (XXX - This strategy may have to be
  1028.      * modified to deal with devices that return variable length
  1029.      * blocks, e.g., some tape drives.)
  1030.      */
  1031.     cmd = SCMD_XFR;
  1032.     i = (unsigned)bp->b_bcount;
  1033.     if (pad) {
  1034.         cmd |= SCMD_PAD;
  1035.         /*
  1036.          * XXX - If we don't do this, the last 2 or 4 bytes
  1037.          * (depending on word/lword DMA) of a read get trashed.
  1038.          * It looks like it is necessary for the DMA to complete
  1039.          * before the SPC goes into "pad mode"???  Note: if we
  1040.          * also do this on a write, the request never completes.
  1041.          */
  1042.         if (bp->b_flags & B_READ)
  1043.             i += 2;
  1044. #ifdef DEBUG
  1045.         hs->sc_flags |= SCSI_PAD;
  1046.         if (i & 1)
  1047.             printf("scsi%d: odd byte count: %d bytes @ %d\n",
  1048.                 ctlr, i, bp->b_cylin);
  1049. #endif
  1050.     } else
  1051.         i += 4;
  1052.     hd->scsi_tch = i >> 16;
  1053.     hd->scsi_tcm = i >> 8;
  1054.     hd->scsi_tcl = i;
  1055.     hd->scsi_pctl = phase;
  1056.     hd->scsi_tmod = 0;
  1057.     hd->scsi_scmd = cmd;
  1058.     hs->sc_flags |= SCSI_IO;
  1059.     return (0);
  1060. abort:
  1061.     scsiabort(hs, hd, "go");
  1062.     dmafree(&hs->sc_dq);
  1063.     return (1);
  1064. }
  1065.  
  1066. void
  1067. scsidone(unit)
  1068.     register int unit;
  1069. {
  1070.     volatile register struct scsidevice *hd =
  1071.             (struct scsidevice *)scsi_softc[unit].sc_hc->hp_addr;
  1072.  
  1073. #ifdef DEBUG
  1074.     if (scsi_debug)
  1075.         printf("scsi%d: done called!\n");
  1076. #endif
  1077.     /* dma operation is done -- turn off card dma */
  1078.     hd->scsi_csr &=~ (CSR_DE1|CSR_DE0);
  1079. }
  1080.  
  1081. int
  1082. scsiintr(unit)
  1083.     register int unit;
  1084. {
  1085.     register struct scsi_softc *hs = &scsi_softc[unit];
  1086.     volatile register struct scsidevice *hd =
  1087.                 (struct scsidevice *)hs->sc_hc->hp_addr;
  1088.     register u_char ints;
  1089.     register struct devqueue *dq;
  1090.  
  1091.     if ((hd->scsi_csr & (CSR_IE|CSR_IR)) != (CSR_IE|CSR_IR))
  1092.         return (0);
  1093.  
  1094.     ints = hd->scsi_ints;
  1095.     if ((ints & INTS_SRV_REQ) && (hs->sc_flags & SCSI_IO)) {
  1096.         /*
  1097.          * this should be the normal i/o completion case.
  1098.          * get the status & cmd complete msg then let the
  1099.          * device driver look at what happened.
  1100.          */
  1101. #ifdef DEBUG
  1102.         int len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) |
  1103.               hd->scsi_tcl;
  1104.         if (!(hs->sc_flags & SCSI_PAD))
  1105.             len -= 4;
  1106.         hs->sc_flags &=~ SCSI_PAD;
  1107. #endif
  1108.         dq = hs->sc_sq.dq_forw;
  1109.         finishxfer(hs, hd, dq->dq_slave);
  1110.         hs->sc_flags &=~ SCSI_IO;
  1111.         dmafree(&hs->sc_dq);
  1112.         (dq->dq_driver->d_intr)(dq->dq_unit, hs->sc_stat[0]);
  1113.     } else {
  1114.         /* Something unexpected happened -- deal with it. */
  1115.         hd->scsi_ints = ints;
  1116.         hd->scsi_csr = 0;
  1117.         scsierror(hs, hd, ints);
  1118.         scsiabort(hs, hd, "intr");
  1119.         if (hs->sc_flags & SCSI_IO) {
  1120.             hs->sc_flags &=~ SCSI_IO;
  1121.             dmafree(&hs->sc_dq);
  1122.             dq = hs->sc_sq.dq_forw;
  1123.             (dq->dq_driver->d_intr)(dq->dq_unit, -1);
  1124.         }
  1125.     }
  1126.     return(1);
  1127. }
  1128.  
  1129. void
  1130. scsifree(dq)
  1131.     register struct devqueue *dq;
  1132. {
  1133.     register struct devqueue *hq;
  1134.  
  1135.     hq = &scsi_softc[dq->dq_ctlr].sc_sq;
  1136.     remque(dq);
  1137.     if ((dq = hq->dq_forw) != hq)
  1138.         (dq->dq_driver->d_start)(dq->dq_unit);
  1139. }
  1140.  
  1141. /*
  1142.  * (XXX) The following routine is needed for the SCSI tape driver
  1143.  * to read odd-size records.
  1144.  */
  1145.  
  1146. #include "st.h"
  1147. #if NST > 0
  1148. int
  1149. scsi_tt_oddio(ctlr, slave, unit, buf, len, b_flags, freedma)
  1150.     int ctlr, slave, unit, b_flags;
  1151.     u_char *buf;
  1152.     u_int len;
  1153. {
  1154.     register struct scsi_softc *hs = &scsi_softc[ctlr];
  1155.     struct scsi_cdb6 cdb;
  1156.     u_char iphase;
  1157.     int stat;
  1158.  
  1159.     /*
  1160.      * First free any DMA channel that was allocated.
  1161.      * We can't use DMA to do this transfer.
  1162.      */
  1163.     if (freedma)
  1164.         dmafree(hs->sc_dq);
  1165.     /*
  1166.      * Initialize command block
  1167.      */
  1168.     bzero(&cdb, sizeof(cdb));
  1169.     cdb.lun = unit;
  1170.     cdb.lbam = (len >> 16) & 0xff;
  1171.     cdb.lbal = (len >> 8) & 0xff;
  1172.     cdb.len = len & 0xff;
  1173.     if (buf == 0) {
  1174.         cdb.cmd = CMD_SPACE;
  1175.         cdb.lun |= 0x00;
  1176.         len = 0;
  1177.         iphase = MESG_IN_PHASE;
  1178.     } else if (b_flags & B_READ) {
  1179.         cdb.cmd = CMD_READ;
  1180.         iphase = DATA_IN_PHASE;
  1181.     } else {
  1182.         cdb.cmd = CMD_WRITE;
  1183.         iphase = DATA_OUT_PHASE;
  1184.     }
  1185.     /*
  1186.      * Perform command (with very long delays)
  1187.      */
  1188.     scsi_delay(30000000);
  1189.     stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, iphase);
  1190.     scsi_delay(0);
  1191.     return (stat);
  1192. }
  1193. #endif
  1194. #endif
  1195.