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