1 /* $NetBSD: nhpib.c,v 1.5 1994/10/26 07:24:44 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)nhpib.c 8.2 (Berkeley) 1/12/94 36 */ 37 38 /* 39 * Internal/98624 HPIB driver 40 */ 41 #include "hpib.h" 42 #if NHPIB > 0 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/buf.h> 47 48 #include <hp300/dev/device.h> 49 #include <hp300/dev/nhpibreg.h> 50 #include <hp300/dev/hpibvar.h> 51 #include <hp300/dev/dmavar.h> 52 53 nhpibtype(hc) 54 register struct hp_ctlr *hc; 55 { 56 register struct hpib_softc *hs = &hpib_softc[hc->hp_unit]; 57 register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr; 58 59 if (hc->hp_addr == internalhpib) { 60 hs->sc_type = HPIBA; 61 hs->sc_ba = HPIBA_BA; 62 hc->hp_ipl = HPIBA_IPL; 63 } 64 else if (hd->hpib_cid == HPIBB) { 65 hs->sc_type = HPIBB; 66 hs->sc_ba = hd->hpib_csa & CSA_BA; 67 hc->hp_ipl = HPIB_IPL(hd->hpib_ids); 68 } 69 else 70 return(0); 71 return(1); 72 } 73 74 nhpibreset(unit) 75 int unit; 76 { 77 register struct hpib_softc *hs = &hpib_softc[unit]; 78 register struct nhpibdevice *hd; 79 80 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 81 hd->hpib_acr = AUX_SSWRST; 82 hd->hpib_ar = hs->sc_ba; 83 hd->hpib_lim = LIS_ERR; 84 hd->hpib_mim = 0; 85 hd->hpib_acr = AUX_CDAI; 86 hd->hpib_acr = AUX_CSHDW; 87 hd->hpib_acr = AUX_SSTD1; 88 hd->hpib_acr = AUX_SVSTD1; 89 hd->hpib_acr = AUX_CPP; 90 hd->hpib_acr = AUX_CHDFA; 91 hd->hpib_acr = AUX_CHDFE; 92 hd->hpib_acr = AUX_RHDF; 93 hd->hpib_acr = AUX_CSWRST; 94 nhpibifc(hd); 95 hd->hpib_ie = IDS_IE; 96 hd->hpib_data = C_DCL; 97 DELAY(100000); 98 } 99 100 nhpibifc(hd) 101 register struct nhpibdevice *hd; 102 { 103 hd->hpib_acr = AUX_TCA; 104 hd->hpib_acr = AUX_CSRE; 105 hd->hpib_acr = AUX_SSIC; 106 DELAY(100); 107 hd->hpib_acr = AUX_CSIC; 108 hd->hpib_acr = AUX_SSRE; 109 } 110 111 nhpibsend(unit, slave, sec, addr, origcnt) 112 int unit, slave, sec, origcnt; 113 register char *addr; 114 { 115 register struct hpib_softc *hs = &hpib_softc[unit]; 116 register struct nhpibdevice *hd; 117 register int cnt = origcnt; 118 119 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 120 hd->hpib_acr = AUX_TCA; 121 hd->hpib_data = C_UNL; 122 if (nhpibwait(hd, MIS_BO)) 123 goto senderror; 124 hd->hpib_data = C_TAG + hs->sc_ba; 125 hd->hpib_acr = AUX_STON; 126 if (nhpibwait(hd, MIS_BO)) 127 goto senderror; 128 hd->hpib_data = C_LAG + slave; 129 if (nhpibwait(hd, MIS_BO)) 130 goto senderror; 131 if (sec != -1) { 132 hd->hpib_data = C_SCG + sec; 133 if (nhpibwait(hd, MIS_BO)) 134 goto senderror; 135 } 136 hd->hpib_acr = AUX_GTS; 137 if (cnt) { 138 while (--cnt > 0) { 139 hd->hpib_data = *addr++; 140 if (nhpibwait(hd, MIS_BO)) 141 goto senderror; 142 } 143 hd->hpib_acr = AUX_EOI; 144 hd->hpib_data = *addr; 145 if (nhpibwait(hd, MIS_BO)) 146 goto senderror; 147 hd->hpib_acr = AUX_TCA; 148 #if 0 149 /* 150 * May be causing 345 disks to hang due to interference 151 * with PPOLL mechanism. 152 */ 153 hd->hpib_data = C_UNL; 154 (void) nhpibwait(hd, MIS_BO); 155 #endif 156 } 157 return(origcnt); 158 senderror: 159 nhpibifc(hd); 160 return(origcnt - cnt - 1); 161 } 162 163 nhpibrecv(unit, slave, sec, addr, origcnt) 164 int unit, slave, sec, origcnt; 165 register char *addr; 166 { 167 register struct hpib_softc *hs = &hpib_softc[unit]; 168 register struct nhpibdevice *hd; 169 register int cnt = origcnt; 170 171 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 172 hd->hpib_acr = AUX_TCA; 173 hd->hpib_data = C_UNL; 174 if (nhpibwait(hd, MIS_BO)) 175 goto recverror; 176 hd->hpib_data = C_LAG + hs->sc_ba; 177 hd->hpib_acr = AUX_SLON; 178 if (nhpibwait(hd, MIS_BO)) 179 goto recverror; 180 hd->hpib_data = C_TAG + slave; 181 if (nhpibwait(hd, MIS_BO)) 182 goto recverror; 183 if (sec != -1) { 184 hd->hpib_data = C_SCG + sec; 185 if (nhpibwait(hd, MIS_BO)) 186 goto recverror; 187 } 188 hd->hpib_acr = AUX_RHDF; 189 hd->hpib_acr = AUX_GTS; 190 if (cnt) { 191 while (--cnt >= 0) { 192 if (nhpibwait(hd, MIS_BI)) 193 goto recvbyteserror; 194 *addr++ = hd->hpib_data; 195 } 196 hd->hpib_acr = AUX_TCA; 197 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT; 198 (void) nhpibwait(hd, MIS_BO); 199 } 200 return(origcnt); 201 recverror: 202 nhpibifc(hd); 203 recvbyteserror: 204 return(origcnt - cnt - 1); 205 } 206 207 nhpibgo(unit, slave, sec, addr, count, rw) 208 register int unit, slave; 209 int sec, count, rw; 210 char *addr; 211 { 212 register struct hpib_softc *hs = &hpib_softc[unit]; 213 register struct nhpibdevice *hd; 214 215 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 216 hs->sc_flags |= HPIBF_IO; 217 if (rw == B_READ) 218 hs->sc_flags |= HPIBF_READ; 219 #ifdef DEBUG 220 else if (hs->sc_flags & HPIBF_READ) { 221 printf("nhpibgo: HPIBF_READ still set\n"); 222 hs->sc_flags &= ~HPIBF_READ; 223 } 224 #endif 225 hs->sc_count = count; 226 hs->sc_addr = addr; 227 if (hs->sc_flags & HPIBF_READ) { 228 hs->sc_curcnt = count; 229 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ); 230 nhpibrecv(unit, slave, sec, 0, 0); 231 hd->hpib_mim = MIS_END; 232 } else { 233 hd->hpib_mim = 0; 234 if (count < hpibdmathresh) { 235 hs->sc_curcnt = count; 236 nhpibsend(unit, slave, sec, addr, count); 237 nhpibdone(unit); 238 return; 239 } 240 hs->sc_curcnt = --count; 241 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE); 242 nhpibsend(unit, slave, sec, 0, 0); 243 } 244 hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr); 245 } 246 247 nhpibdone(unit) 248 register int unit; 249 { 250 register struct hpib_softc *hs = &hpib_softc[unit]; 251 register struct nhpibdevice *hd; 252 register int cnt; 253 254 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 255 cnt = hs->sc_curcnt; 256 hs->sc_addr += cnt; 257 hs->sc_count -= cnt; 258 hs->sc_flags |= HPIBF_DONE; 259 hd->hpib_ie = IDS_IE; 260 if ((hs->sc_flags & HPIBF_READ) == 0) { 261 if (hs->sc_count == 1) { 262 (void) nhpibwait(hd, MIS_BO); 263 hd->hpib_acr = AUX_EOI; 264 hd->hpib_data = *hs->sc_addr; 265 hd->hpib_mim = MIS_BO; 266 } 267 #ifdef DEBUG 268 else if (hs->sc_count) 269 panic("nhpibdone"); 270 #endif 271 } 272 } 273 274 nhpibintr(unit) 275 register int unit; 276 { 277 register struct hpib_softc *hs = &hpib_softc[unit]; 278 register struct nhpibdevice *hd; 279 register struct devqueue *dq; 280 register int stat0; 281 int stat1; 282 283 #ifdef lint 284 if (stat1 = unit) return(1); 285 #endif 286 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr; 287 if ((hd->hpib_ids & IDS_IR) == 0) 288 return(0); 289 stat0 = hd->hpib_mis; 290 stat1 = hd->hpib_lis; 291 dq = hs->sc_sq.dq_forw; 292 if (hs->sc_flags & HPIBF_IO) { 293 hd->hpib_mim = 0; 294 if ((hs->sc_flags & HPIBF_DONE) == 0) 295 dmastop(hs->sc_dq.dq_ctlr); 296 hd->hpib_acr = AUX_TCA; 297 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ); 298 dmafree(&hs->sc_dq); 299 (dq->dq_driver->d_intr)(dq->dq_unit); 300 } else if (hs->sc_flags & HPIBF_PPOLL) { 301 hd->hpib_mim = 0; 302 stat0 = nhpibppoll(unit); 303 if (stat0 & (0x80 >> dq->dq_slave)) { 304 hs->sc_flags &= ~HPIBF_PPOLL; 305 (dq->dq_driver->d_intr)(dq->dq_unit); 306 } 307 #ifdef DEBUG 308 else 309 printf("hpib%d: PPOLL intr bad status %x\n", 310 unit, stat0); 311 #endif 312 } 313 return(1); 314 } 315 316 nhpibppoll(unit) 317 int unit; 318 { 319 register struct nhpibdevice *hd; 320 register int ppoll; 321 322 hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr; 323 hd->hpib_acr = AUX_SPP; 324 DELAY(25); 325 ppoll = hd->hpib_cpt; 326 hd->hpib_acr = AUX_CPP; 327 return(ppoll); 328 } 329 330 nhpibwait(hd, x) 331 register struct nhpibdevice *hd; 332 int x; 333 { 334 register int timo = hpibtimeout; 335 336 while ((hd->hpib_mis & x) == 0 && --timo) 337 DELAY(1); 338 if (timo == 0) 339 return(-1); 340 return(0); 341 } 342 343 void 344 nhpibppwatch(arg) 345 void *arg; 346 { 347 register struct hpib_softc *hs; 348 register int unit; 349 extern int cold; 350 351 unit = (int)arg; 352 hs = &hpib_softc[unit]; 353 if ((hs->sc_flags & HPIBF_PPOLL) == 0) 354 return; 355 again: 356 if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave)) 357 ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO; 358 else if (cold) 359 /* timeouts not working yet */ 360 goto again; 361 else 362 timeout(nhpibppwatch, (void *)unit, 1); 363 } 364 #endif 365