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