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

  1. /*
  2.  * Copyright (c) 1982, 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)ct.c    7.3 (Berkeley) 5/5/91
  34.  */
  35.  
  36. /*
  37.  * CS80 tape driver
  38.  */
  39. #include <sys/param.h>
  40. #include "../dev/ctreg.h"
  41.  
  42. #include "saio.h"
  43. #include "samachdep.h"
  44.  
  45. struct    ct_iocmd ct_ioc;
  46. struct    ct_rscmd ct_rsc;
  47. struct    ct_stat ct_stat;
  48. struct    ct_ssmcmd ct_ssmc;
  49.  
  50. struct    ct_softc {
  51.     char    sc_retry;
  52.     char    sc_alive;
  53.     short    sc_punit;
  54.     int    sc_blkno;
  55. } ct_softc[NCT];
  56.  
  57. #define    CTRETRY        5
  58. #define    MTFSF        10
  59. #define    MTREW        11
  60.  
  61. struct    ctinfo {
  62.     short    hwid;
  63.     short    punit;
  64. } ctinfo[] = {
  65.     CT7946ID,    1,
  66.     CT7912PID,    1,
  67.     CT7914PID,    1,
  68.     CT9144ID,    0,
  69.     CT9145ID,    0,
  70. };
  71. int    nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]);
  72.  
  73. ctinit(unit)
  74.     register int unit;
  75. {
  76.     register struct ct_softc *rs = &ct_softc[unit];
  77.     u_char stat;
  78.     register int type;
  79.  
  80.     if (hpibrecv(unit, C_QSTAT, &stat, 1) != 1 || stat)
  81.         return (0);
  82.     if (ctident(unit) < 0)
  83.         return (0);
  84.     ct_ssmc.unit = C_SUNIT(rs->sc_punit);
  85.     ct_ssmc.cmd = C_SSM;
  86.     ct_ssmc.fefm = FEF_MASK;
  87.     ct_ssmc.refm = REF_MASK;
  88.     ct_ssmc.aefm = AEF_MASK;
  89.     ct_ssmc.iefm = IEF_MASK;
  90.     hpibsend(unit, C_CMD, &ct_ssmc, sizeof(ct_ssmc));
  91.     hpibswait(unit);
  92.     hpibrecv(unit, C_QSTAT, &stat, 1);
  93.     rs->sc_alive = 1;
  94.     return (1);
  95. }
  96.  
  97. ctident(unit)
  98.     int unit;
  99. {
  100.     struct ct_describe desc;
  101.     u_char stat, cmd[3];
  102.     char name[7];
  103.     int id, i;
  104.  
  105.     id = hpibid(unit);
  106.     if ((id & 0x200) == 0)
  107.         return(-1);
  108.     for (i = 0; i < nctinfo; i++)
  109.         if (id == ctinfo[i].hwid)
  110.             break;
  111.     if (i == nctinfo)
  112.         return(-1);
  113.     ct_softc[unit].sc_punit = ctinfo[i].punit;
  114.     id = i;
  115.  
  116.     /*
  117.      * Collect device description.
  118.      * Right now we only need this to differentiate 7945 from 7946.
  119.      * Note that we always issue the describe command to unit 0.
  120.      */
  121.     cmd[0] = C_SUNIT(0);
  122.     cmd[1] = C_SVOL(0);
  123.     cmd[2] = C_DESC;
  124.     hpibsend(unit, C_CMD, cmd, sizeof(cmd));
  125.     hpibrecv(unit, C_EXEC, &desc, 37);
  126.     hpibrecv(unit, C_QSTAT, &stat, sizeof(stat));
  127.     bzero(name, sizeof(name));
  128.     if (!stat) {
  129.         register int n = desc.d_name;
  130.         for (i = 5; i >= 0; i--) {
  131.             name[i] = (n & 0xf) + '0';
  132.             n >>= 4;
  133.         }
  134.     }
  135.     switch (ctinfo[id].hwid) {
  136.     case CT7946ID:
  137.         if (bcmp(name, "079450", 6) == 0)
  138.             id = -1;        /* not really a 7946 */
  139.         break;
  140.     default:
  141.         break;
  142.     }
  143.     return(id);
  144. }
  145.  
  146. ctopen(io)
  147.     struct iob *io;
  148. {
  149.     register int unit = io->i_unit;
  150.     register struct ct_softc *rs = &ct_softc[unit];
  151.     register int skip;
  152.  
  153.     if (hpibalive(unit) == 0)
  154.         _stop("ct controller not configured");
  155.     if (rs->sc_alive == 0)
  156.         if (ctinit(unit) == 0)
  157.             _stop("ct init failed");
  158.     ctstrategy(io, MTREW);
  159.     skip = io->i_boff;
  160.     while (skip--)
  161.         ctstrategy(io, MTFSF);
  162. }
  163.  
  164. ctclose(io)
  165.     struct iob *io;
  166. {
  167.     ctstrategy(io, MTREW);
  168. }
  169.  
  170. ctstrategy(io, func)
  171.     register struct iob *io;
  172.     register int func;
  173. {
  174.     register int unit = io->i_unit;
  175.     register struct ct_softc *rs = &ct_softc[unit];
  176.     char stat;
  177.  
  178.     rs->sc_retry = 0;
  179.     ct_ioc.unit = C_SUNIT(rs->sc_punit);
  180.     ct_ioc.saddr = C_SADDR;
  181.     ct_ioc.nop2 = C_NOP;
  182.     ct_ioc.slen = C_SLEN;
  183.     ct_ioc.nop3 = C_NOP;
  184. top:
  185.     if (func == F_READ) {
  186.         ct_ioc.cmd = C_READ;
  187.         ct_ioc.addr = rs->sc_blkno;
  188.         ct_ioc.len = io->i_cc;
  189.     }
  190.     else if (func == F_WRITE) {
  191.         ct_ioc.cmd = C_WRITE;
  192.         ct_ioc.addr = rs->sc_blkno;
  193.         ct_ioc.len = io->i_cc;
  194.     }
  195.     else if (func == MTFSF) {
  196.         ct_ioc.cmd = C_READ;
  197.         ct_ioc.addr = rs->sc_blkno;
  198.         ct_ioc.len = io->i_cc = MAXBSIZE;
  199.         io->i_ma = io->i_buf;
  200.     }
  201.     else {
  202.         ct_ioc.cmd = C_READ;
  203.         ct_ioc.addr = 0;
  204.         ct_ioc.len = 0;
  205.         rs->sc_blkno = 0;
  206.         io->i_cc = 0;
  207.     }
  208. retry:
  209.     hpibsend(unit, C_CMD, &ct_ioc, sizeof(ct_ioc));
  210.     if (func != MTREW) {
  211.         hpibswait(unit);
  212.         hpibgo(unit, C_EXEC, io->i_ma, io->i_cc,
  213.             func != F_WRITE ? F_READ : F_WRITE);
  214.         hpibswait(unit);
  215.     }
  216.     else {
  217.         while (hpibswait(unit) < 0)
  218.             ;
  219.     }
  220.     hpibrecv(unit, C_QSTAT, &stat, 1);
  221.     if (stat) {
  222.         stat = cterror(unit);
  223.         if (stat == 0)
  224.             return (-1);
  225.         if (stat == 2)
  226.             return (0);
  227.         if (++rs->sc_retry > CTRETRY)
  228.             return (-1);
  229.         else
  230.             goto retry;
  231.     }
  232.     rs->sc_blkno += CTBTOK(io->i_cc);
  233.     if (func == MTFSF)
  234.         goto top;
  235.     return (io->i_cc);
  236. }
  237.  
  238. cterror(unit)
  239.     register int unit;
  240. {
  241.     register struct ct_softc *ct = &ct_softc[unit];
  242.     char stat;
  243.  
  244.     ct_rsc.unit = C_SUNIT(ct->sc_punit);
  245.     ct_rsc.cmd = C_STATUS;
  246.     hpibsend(unit, C_CMD, &ct_rsc, sizeof(ct_rsc));
  247.     hpibrecv(unit, C_EXEC, &ct_stat, sizeof(ct_stat));
  248.     hpibrecv(unit, C_QSTAT, &stat, 1);
  249.     if (stat) {
  250.         printf("ct%d: request status fail %d\n", unit, stat);
  251.         return(0);
  252.     }
  253.     if (ct_stat.c_aef & AEF_EOF) {
  254.         /* 9145 drives don't increment block number at EOF */
  255.         if ((ct_stat.c_blk - ct->sc_blkno) == 0)
  256.             ct->sc_blkno++;
  257.         else
  258.             ct->sc_blkno = ct_stat.c_blk;
  259.         return (2);
  260.     }
  261.     printf("ct%d err: vu 0x%x, pend 0x%x, bn%d", unit,
  262.         ct_stat.c_vu, ct_stat.c_pend, ct_stat.c_blk);
  263.     printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat.c_ref,
  264.         ct_stat.c_fef, ct_stat.c_aef, ct_stat.c_ief);
  265.     return (1);
  266. }
  267.