home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / stand / rd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-05  |  7.6 KB  |  277 lines

  1. /*
  2.  * Copyright (c) 1988 University of Utah.
  3.  * Copyright (c) 1982, 1990 The Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * This code is derived from software contributed to Berkeley by
  7.  * the Systems Programming Group of the University of Utah Computer
  8.  * Science Department.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  * from: Utah $Hdr: rd.c 1.14 89/02/27$
  39.  *
  40.  *    @(#)rd.c    7.3 (Berkeley) 5/5/91
  41.  */
  42.  
  43. /*
  44.  * CS80/SS80 disk driver
  45.  */
  46. #include <sys/param.h>
  47. #include "saio.h"
  48. #include "samachdep.h"
  49.  
  50. #include "../dev/rdreg.h"
  51.  
  52. struct    rd_iocmd rd_ioc;
  53. struct    rd_rscmd rd_rsc;
  54. struct    rd_stat rd_stat;
  55. struct    rd_ssmcmd rd_ssmc;
  56.  
  57. struct    rd_softc {
  58.     char    sc_retry;
  59.     char    sc_alive;
  60.     short    sc_type;
  61. } rd_softc[NRD];
  62.  
  63. #define    RDRETRY        5
  64.  
  65. int rdcyloff[][8] = {
  66.     { 1, 143, 0, 143, 0,   0,   323, 503, },    /* 7945A */
  67.     { 1, 167, 0, 0,   0,   0,   0,   0,   },    /* 9134D */
  68.     { 0, 0,   0, 0,   0,   0,   0,   0,   },    /* 9122S */
  69.     { 0, 71,  0, 221, 292, 542, 221, 0,   },    /* 7912P */
  70.     { 1, 72,  0, 72,  362, 802, 252, 362, },    /* 7914P */
  71.     { 1, 28,  0, 140, 167, 444, 140, 721, },    /* 7933H */
  72.     { 1, 200, 0, 200, 0,   0,   450, 600, },    /* 9134L */
  73.     { 1, 105, 0, 105, 380, 736, 265, 380, },    /* 7957A */
  74.     { 1, 65,  0, 65,  257, 657, 193, 257, },    /* 7958A */
  75.     { 1, 128, 0, 128, 518, 918, 388, 518, },    /* 7957B */
  76.     { 1, 44,  0, 44,  174, 496, 131, 174, },    /* 7958B */
  77.     { 1, 44,  0, 44,  218, 918, 174, 218, },    /* 7959B */
  78.     { 1, 20,  0, 98,  117, 256, 98,  397, },    /* 7936H */
  79.     { 1, 11,  0, 53,  63,  217, 53,  371, },    /* 7937H */
  80. };
  81.  
  82. struct rdinfo {
  83.     int    nbpc;
  84.     int    hwid;
  85.     int    *cyloff;
  86. } rdinfo[] = {
  87.     NRD7945ABPT*NRD7945ATRK, RD7946AID, rdcyloff[0],
  88.     NRD9134DBPT*NRD9134DTRK, RD9134DID, rdcyloff[1],
  89.     NRD9122SBPT*NRD9122STRK, RD9134LID, rdcyloff[2],
  90.     NRD7912PBPT*NRD7912PTRK, RD7912PID, rdcyloff[3],
  91.     NRD7914PBPT*NRD7914PTRK, RD7914PID, rdcyloff[4],
  92.     NRD7958ABPT*NRD7958ATRK, RD7958AID, rdcyloff[8],
  93.     NRD7957ABPT*NRD7957ATRK, RD7957AID, rdcyloff[7],
  94.     NRD7933HBPT*NRD7933HTRK, RD7933HID, rdcyloff[5],
  95.     NRD9134LBPT*NRD9134LTRK, RD9134LID, rdcyloff[6],
  96.     NRD7936HBPT*NRD7936HTRK, RD7936HID, rdcyloff[12],
  97.     NRD7937HBPT*NRD7937HTRK, RD7937HID, rdcyloff[13],
  98.     NRD7914PBPT*NRD7914PTRK, RD7914CTID,rdcyloff[4],
  99.     NRD7945ABPT*NRD7945ATRK, RD7946AID, rdcyloff[0],
  100.     NRD9122SBPT*NRD9122STRK, RD9134LID, rdcyloff[2],
  101.     NRD7957BBPT*NRD7957BTRK, RD7957BID, rdcyloff[9],
  102.     NRD7958BBPT*NRD7958BTRK, RD7958BID, rdcyloff[10],
  103.     NRD7959BBPT*NRD7959BTRK, RD7959BID, rdcyloff[11],
  104. };
  105. int    nrdinfo = sizeof(rdinfo) / sizeof(rdinfo[0]);
  106.                     
  107. rdinit(unit)
  108.     register int unit;
  109. {
  110.     register struct rd_softc *rs;
  111.     u_char stat;
  112.  
  113.     if (unit > NRD)
  114.         return (0);
  115.     rs = &rd_softc[unit];
  116.     rs->sc_type = rdident(unit);
  117.     if (rs->sc_type < 0)
  118.         return (0);
  119.     rs->sc_alive = 1;
  120.     return (1);
  121. }
  122.  
  123. rdreset(unit)
  124. {
  125.     u_char stat;
  126.  
  127.     rd_ssmc.c_unit = C_SUNIT(0);
  128.     rd_ssmc.c_cmd = C_SSM;
  129.     rd_ssmc.c_refm = REF_MASK;
  130.     rd_ssmc.c_fefm = FEF_MASK;
  131.     rd_ssmc.c_aefm = AEF_MASK;
  132.     rd_ssmc.c_iefm = IEF_MASK;
  133.     hpibsend(unit, C_CMD, &rd_ssmc, sizeof(rd_ssmc));
  134.     hpibswait(unit);
  135.     hpibrecv(unit, C_QSTAT, &stat, 1);
  136. }
  137.  
  138. rdident(unit)
  139. {
  140.     struct rd_describe desc;
  141.     u_char stat, cmd[3];
  142.     char name[7];
  143.     register int id, i;
  144.  
  145.     id = hpibid(unit);
  146.     if ((id & 0x200) == 0)
  147.         return(-1);
  148.     for (i = 0; i < nrdinfo; i++)
  149.         if (id == rdinfo[i].hwid)
  150.             break;
  151.     if (i == nrdinfo)
  152.         return(-1);
  153.     id = i;
  154.     rdreset(unit);
  155.     cmd[0] = C_SUNIT(0);
  156.     cmd[1] = C_SVOL(0);
  157.     cmd[2] = C_DESC;
  158.     hpibsend(unit, C_CMD, cmd, sizeof(cmd));
  159.     hpibrecv(unit, C_EXEC, &desc, 37);
  160.     hpibrecv(unit, C_QSTAT, &stat, sizeof(stat));
  161.     bzero(name, sizeof(name));
  162.     if (!stat) {
  163.         register int n = desc.d_name;
  164.         for (i = 5; i >= 0; i--) {
  165.             name[i] = (n & 0xf) + '0';
  166.             n >>= 4;
  167.         }
  168.     }
  169.     /*
  170.      * Take care of a couple of anomolies:
  171.      * 1. 7945A and 7946A both return same HW id
  172.      * 2. 9122S and 9134D both return same HW id
  173.      * 3. 9122D and 9134L both return same HW id
  174.      */
  175.     switch (rdinfo[id].hwid) {
  176.     case RD7946AID:
  177.         if (bcmp(name, "079450", 6) == 0)
  178.             id = RD7945A;
  179.         else
  180.             id = RD7946A;
  181.         break;
  182.  
  183.     case RD9134LID:
  184.         if (bcmp(name, "091340", 6) == 0)
  185.             id = RD9134L;
  186.         else
  187.             id = RD9122D;
  188.         break;
  189.  
  190.     case RD9134DID:
  191.         if (bcmp(name, "091220", 6) == 0)
  192.             id = RD9122S;
  193.         else
  194.             id = RD9134D;
  195.         break;
  196.     }
  197.     return(id);
  198. }
  199.  
  200. rdopen(io)
  201.     struct iob *io;
  202. {
  203.     register int unit = io->i_unit;
  204.     register struct rd_softc *rs = &rd_softc[unit];
  205.     struct rdinfo *ri;
  206.  
  207.     if (hpibalive(unit) == 0)
  208.         _stop("rd controller not configured");
  209.     if (rs->sc_alive == 0)
  210.         if (rdinit(unit) == 0)
  211.             _stop("rd init failed");
  212.     if (io->i_boff < 0 || io->i_boff > 7)
  213.         _stop("rd bad minor");
  214.     ri = &rdinfo[rs->sc_type];
  215.     io->i_boff = ri->cyloff[io->i_boff] * ri->nbpc;
  216. }
  217.  
  218. rdstrategy(io, func)
  219.     register struct iob *io;
  220.     register int func;
  221. {
  222.     register int unit = io->i_unit;
  223.     register struct rd_softc *rs = &rd_softc[unit];
  224.     char stat;
  225.  
  226.     rs->sc_retry = 0;
  227.     rd_ioc.c_unit = C_SUNIT(0);
  228.     rd_ioc.c_volume = C_SVOL(0);
  229.     rd_ioc.c_saddr = C_SADDR;
  230.     rd_ioc.c_hiaddr = 0;
  231.     rd_ioc.c_addr = RDBTOS(io->i_bn);
  232.     rd_ioc.c_nop2 = C_NOP;
  233.     rd_ioc.c_slen = C_SLEN;
  234.     rd_ioc.c_len = io->i_cc;
  235.     rd_ioc.c_cmd = func == F_READ ? C_READ : C_WRITE;
  236. retry:
  237.     hpibsend(unit, C_CMD, &rd_ioc.c_unit, sizeof(rd_ioc)-2);
  238.     hpibswait(unit);
  239.     hpibgo(unit, C_EXEC, io->i_ma, io->i_cc, func);
  240.     hpibswait(unit);
  241.     hpibrecv(unit, C_QSTAT, &stat, 1);
  242.     if (stat) {
  243.         if (rderror(unit) == 0)
  244.             return(-1);
  245.         if (++rs->sc_retry > RDRETRY)
  246.             return(-1);
  247.         else
  248.             goto retry;
  249.     }
  250.     return(io->i_cc);
  251. }
  252.  
  253. rderror(unit)
  254.     register int unit;
  255. {
  256.     register struct rd_softc *rd = &rd_softc[unit];
  257.     char stat;
  258.  
  259.     rd_rsc.c_unit = C_SUNIT(0);
  260.     rd_rsc.c_sram = C_SRAM;
  261.     rd_rsc.c_ram = C_RAM;
  262.     rd_rsc.c_cmd = C_STATUS;
  263.     hpibsend(unit, C_CMD, &rd_rsc, sizeof(rd_rsc));
  264.     hpibrecv(unit, C_EXEC, &rd_stat, sizeof(rd_stat));
  265.     hpibrecv(unit, C_QSTAT, &stat, 1);
  266.     if (stat) {
  267.         printf("rd(%d,?): request status fail %d\n", unit, stat);
  268.         return(0);
  269.     }
  270.     printf("rd(%d,?) err: vu 0x%x", unit, rd_stat.c_vu);
  271.     if ((rd_stat.c_aef & AEF_UD) || (rd_stat.c_ief & (IEF_MD|IEF_RD)))
  272.         printf(", block %d", rd_stat.c_blk);
  273.     printf(", R0x%x F0x%x A0x%x I0x%x\n",
  274.            rd_stat.c_ref, rd_stat.c_fef, rd_stat.c_aef, rd_stat.c_ief);
  275.     return(1);
  276. }
  277.