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