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