home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / nhpib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  8.6 KB  |  349 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.  *    @(#)nhpib.c    7.4 (Berkeley) 5/7/91
  34.  */
  35.  
  36. /*
  37.  * Internal/98624 HPIB driver
  38.  */
  39. #include "hpib.h"
  40. #if NHPIB > 0
  41.  
  42. #include "sys/param.h"
  43. #include "sys/systm.h"
  44. #include "sys/buf.h"
  45.  
  46. #include "device.h"
  47. #include "nhpibreg.h"
  48. #include "hpibvar.h"
  49. #include "dmavar.h"
  50.  
  51. nhpibtype(hc)
  52.     register struct hp_ctlr *hc;
  53. {
  54.     register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
  55.     register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr;
  56.  
  57.     if (hc->hp_addr == internalhpib) {
  58.         hs->sc_type = HPIBA;
  59.         hs->sc_ba = HPIBA_BA;
  60.         hc->hp_ipl = HPIBA_IPL;
  61.     }
  62.     else if (hd->hpib_cid == HPIBB) {
  63.         hs->sc_type = HPIBB;
  64.         hs->sc_ba = hd->hpib_csa & CSA_BA;
  65.         hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
  66.     }
  67.     else
  68.         return(0);
  69.     return(1);
  70. }
  71.  
  72. nhpibreset(unit)
  73. {
  74.     register struct hpib_softc *hs = &hpib_softc[unit];
  75.     register struct nhpibdevice *hd;
  76.  
  77.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  78.     hd->hpib_acr = AUX_SSWRST;
  79.     hd->hpib_ar = hs->sc_ba;
  80.     hd->hpib_lim = LIS_ERR;
  81.     hd->hpib_mim = 0;
  82.     hd->hpib_acr = AUX_CDAI;
  83.     hd->hpib_acr = AUX_CSHDW;
  84.     hd->hpib_acr = AUX_SSTD1;
  85.     hd->hpib_acr = AUX_SVSTD1;
  86.     hd->hpib_acr = AUX_CPP;
  87.     hd->hpib_acr = AUX_CHDFA;
  88.     hd->hpib_acr = AUX_CHDFE;
  89.     hd->hpib_acr = AUX_RHDF;
  90.     hd->hpib_acr = AUX_CSWRST;
  91.     nhpibifc(hd);
  92.     hd->hpib_ie = IDS_IE;
  93.     hd->hpib_data = C_DCL;
  94.     DELAY(100000);
  95. }
  96.  
  97. nhpibifc(hd)
  98.     register struct nhpibdevice *hd;
  99. {
  100.     hd->hpib_acr = AUX_TCA;
  101.     hd->hpib_acr = AUX_CSRE;
  102.     hd->hpib_acr = AUX_SSIC;
  103.     DELAY(100);
  104.     hd->hpib_acr = AUX_CSIC;
  105.     hd->hpib_acr = AUX_SSRE;
  106. }
  107.  
  108. nhpibsend(unit, slave, sec, addr, origcnt)
  109.     register char *addr;
  110. {
  111.     register struct hpib_softc *hs = &hpib_softc[unit];
  112.     register struct nhpibdevice *hd;
  113.     register int cnt = origcnt;
  114.  
  115.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  116.     hd->hpib_acr = AUX_TCA;
  117.     hd->hpib_data = C_UNL;
  118.     if (nhpibwait(hd, MIS_BO))
  119.         goto senderror;
  120.     hd->hpib_data = C_TAG + hs->sc_ba;
  121.     hd->hpib_acr = AUX_STON;
  122.     if (nhpibwait(hd, MIS_BO))
  123.         goto senderror;
  124.     hd->hpib_data = C_LAG + slave;
  125.     if (nhpibwait(hd, MIS_BO))
  126.         goto senderror;
  127.     if (sec != -1) {
  128.         hd->hpib_data = C_SCG + sec;
  129.         if (nhpibwait(hd, MIS_BO))
  130.             goto senderror;
  131.     }
  132.     hd->hpib_acr = AUX_GTS;
  133.     if (cnt) {
  134.         while (--cnt > 0) {
  135.             hd->hpib_data = *addr++;
  136.             if (nhpibwait(hd, MIS_BO))
  137.                 goto senderror;
  138.         }
  139.         hd->hpib_acr = AUX_EOI;
  140.         hd->hpib_data = *addr;
  141.         if (nhpibwait(hd, MIS_BO))
  142.             goto senderror;
  143.         hd->hpib_acr = AUX_TCA;
  144. #if 0
  145.         /*
  146.          * May be causing 345 disks to hang due to interference
  147.          * with PPOLL mechanism.
  148.          */
  149.         hd->hpib_data = C_UNL;
  150.         (void) nhpibwait(hd, MIS_BO);
  151. #endif
  152.     }
  153.     return(origcnt);
  154. senderror:
  155.     nhpibifc(hd);
  156.     return(origcnt - cnt - 1);
  157. }
  158.  
  159. nhpibrecv(unit, slave, sec, addr, origcnt)
  160.     register char *addr;
  161. {
  162.     register struct hpib_softc *hs = &hpib_softc[unit];
  163.     register struct nhpibdevice *hd;
  164.     register int cnt = origcnt;
  165.  
  166.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  167.     hd->hpib_acr = AUX_TCA;
  168.     hd->hpib_data = C_UNL;
  169.     if (nhpibwait(hd, MIS_BO))
  170.         goto recverror;
  171.     hd->hpib_data = C_LAG + hs->sc_ba;
  172.     hd->hpib_acr = AUX_SLON;
  173.     if (nhpibwait(hd, MIS_BO))
  174.         goto recverror;
  175.     hd->hpib_data = C_TAG + slave;
  176.     if (nhpibwait(hd, MIS_BO))
  177.         goto recverror;
  178.     if (sec != -1) {
  179.         hd->hpib_data = C_SCG + sec;
  180.         if (nhpibwait(hd, MIS_BO))
  181.             goto recverror;
  182.     }
  183.     hd->hpib_acr = AUX_RHDF;
  184.     hd->hpib_acr = AUX_GTS;
  185.     if (cnt) {
  186.         while (--cnt >= 0) {
  187.             if (nhpibwait(hd, MIS_BI))
  188.                 goto recvbyteserror;
  189.             *addr++ = hd->hpib_data;
  190.         }
  191.         hd->hpib_acr = AUX_TCA;
  192.         hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
  193.         (void) nhpibwait(hd, MIS_BO);
  194.     }
  195.     return(origcnt);
  196. recverror:
  197.     nhpibifc(hd);
  198. recvbyteserror:
  199.     return(origcnt - cnt - 1);
  200. }
  201.  
  202. nhpibgo(unit, slave, sec, addr, count, rw)
  203.     register int unit, slave;
  204.     char *addr;
  205. {
  206.     register struct hpib_softc *hs = &hpib_softc[unit];
  207.     register struct nhpibdevice *hd;
  208.  
  209.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  210.     hs->sc_flags |= HPIBF_IO;
  211.     if (rw == B_READ)
  212.         hs->sc_flags |= HPIBF_READ;
  213. #ifdef DEBUG
  214.     else if (hs->sc_flags & HPIBF_READ) {
  215.         printf("nhpibgo: HPIBF_READ still set\n");
  216.         hs->sc_flags &= ~HPIBF_READ;
  217.     }
  218. #endif
  219.     hs->sc_count = count;
  220.     hs->sc_addr = addr;
  221.     if (hs->sc_flags & HPIBF_READ) {
  222.         hs->sc_curcnt = count;
  223.         dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ);
  224.         nhpibrecv(unit, slave, sec, 0, 0);
  225.         hd->hpib_mim = MIS_END;
  226.     } else {
  227.         hd->hpib_mim = 0;
  228.         if (count < hpibdmathresh) {
  229.             hs->sc_curcnt = count;
  230.             nhpibsend(unit, slave, sec, addr, count);
  231.             nhpibdone(unit);
  232.             return;
  233.         }
  234.         hs->sc_curcnt = --count;
  235.         dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
  236.         nhpibsend(unit, slave, sec, 0, 0);
  237.     }
  238.     hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
  239. }
  240.  
  241. nhpibdone(unit)
  242.     register int unit;
  243. {
  244.     register struct hpib_softc *hs = &hpib_softc[unit];
  245.     register struct nhpibdevice *hd;
  246.     register int cnt;
  247.  
  248.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  249.     cnt = hs->sc_curcnt;
  250.     hs->sc_addr += cnt;
  251.     hs->sc_count -= cnt;
  252.     hs->sc_flags |= HPIBF_DONE;
  253.     hd->hpib_ie = IDS_IE;
  254.     if ((hs->sc_flags & HPIBF_READ) == 0) {
  255.         if (hs->sc_count == 1) {
  256.             (void) nhpibwait(hd, MIS_BO);
  257.             hd->hpib_acr = AUX_EOI;
  258.             hd->hpib_data = *hs->sc_addr;
  259.             hd->hpib_mim = MIS_BO;
  260.         }
  261. #ifdef DEBUG
  262.         else if (hs->sc_count)
  263.             panic("nhpibdone");
  264. #endif
  265.     }
  266. }
  267.  
  268. nhpibintr(unit)
  269.     register int unit;
  270. {
  271.     register struct hpib_softc *hs = &hpib_softc[unit];
  272.     register struct nhpibdevice *hd;
  273.     register struct devqueue *dq;
  274.     register int stat0;
  275.     int stat1;
  276.  
  277. #ifdef lint
  278.     if (stat1 = unit) return(1);
  279. #endif
  280.     hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
  281.     if ((hd->hpib_ids & IDS_IR) == 0)
  282.         return(0);
  283.     stat0 = hd->hpib_mis;
  284.     stat1 = hd->hpib_lis;
  285.     dq = hs->sc_sq.dq_forw;
  286.     if (hs->sc_flags & HPIBF_IO) {
  287.         hd->hpib_mim = 0;
  288.         if ((hs->sc_flags & HPIBF_DONE) == 0)
  289.             dmastop(hs->sc_dq.dq_ctlr);
  290.         hd->hpib_acr = AUX_TCA;
  291.         hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
  292.         dmafree(&hs->sc_dq);
  293.         (dq->dq_driver->d_intr)(dq->dq_unit);
  294.     } else if (hs->sc_flags & HPIBF_PPOLL) {
  295.         hd->hpib_mim = 0;
  296.         stat0 = nhpibppoll(unit);
  297.         if (stat0 & (0x80 >> dq->dq_slave)) {
  298.             hs->sc_flags &= ~HPIBF_PPOLL;
  299.             (dq->dq_driver->d_intr)(dq->dq_unit);
  300.         }
  301. #ifdef DEBUG
  302.         else
  303.             printf("hpib%d: PPOLL intr bad status %x\n",
  304.                    unit, stat0);
  305. #endif
  306.     }
  307.     return(1);
  308. }
  309.  
  310. nhpibppoll(unit)
  311.     int unit;
  312. {
  313.     register struct nhpibdevice *hd;
  314.     register int ppoll;
  315.  
  316.     hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
  317.     hd->hpib_acr = AUX_SPP;
  318.     DELAY(25);
  319.     ppoll = hd->hpib_cpt;
  320.     hd->hpib_acr = AUX_CPP;
  321.     return(ppoll);
  322. }
  323.  
  324. nhpibwait(hd, x)
  325.     register struct nhpibdevice *hd;
  326. {
  327.     register int timo = hpibtimeout;
  328.  
  329.     while ((hd->hpib_mis & x) == 0 && --timo)
  330.         DELAY(1);
  331.     if (timo == 0)
  332.         return(-1);
  333.     return(0);
  334. }
  335.  
  336. nhpibppwatch(unit)
  337.     register int unit;
  338. {
  339.     register struct hpib_softc *hs = &hpib_softc[unit];
  340.  
  341.     if ((hs->sc_flags & HPIBF_PPOLL) == 0)
  342.         return;
  343.     if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
  344.                ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
  345.     else
  346.         timeout(nhpibppwatch, unit, 1);
  347. }
  348. #endif
  349.