|
|
1.1 root 1: /*
2: * @(#)ik.c 7.1 (Berkeley) 5/31/88
3: */
4:
5: #include "ik.h"
6: #if NIK > 0
7: /*
8: * PS300/IKON DR-11W Device Driver.
9: */
10: #include "param.h"
11: #include "buf.h"
12: #include "cmap.h"
13: #include "conf.h"
14: #include "dir.h"
15: #include "dkstat.h"
16: #include "map.h"
17: #include "systm.h"
18: #include "user.h"
19: #include "vmmac.h"
20: #include "proc.h"
21: #include "uio.h"
22: #include "kernel.h"
23: #include "syslog.h"
24:
25: #include "../tahoe/mtpr.h"
26: #include "../tahoe/pte.h"
27:
28: #include "../tahoevba/vbavar.h"
29: #include "../tahoevba/ikreg.h"
30: #include "../tahoevba/psreg.h"
31: #include "../tahoevba/psproto.h"
32:
33: int ikprobe(), ikattach(), iktimer();
34: struct vba_device *ikinfo[NIK];
35: long ikstd[] = { 0 };
36: struct vba_driver ikdriver = { ikprobe, 0, ikattach, 0, ikstd, "ik", ikinfo };
37:
38: #define splik() spl4()
39: /*
40: * Devices are organized in pairs with the odd valued
41: * device being used for ``diagnostic'' purposes. That
42: * is diagnostic devices don't get auto-attach'd and
43: * detach'd on open-close.
44: */
45: #define IKUNIT(dev) (minor(dev) >> 1)
46: #define IKDIAG(dev) (minor(dev) & 01) /* is a diagnostic unit */
47:
48: struct ik_softc {
49: uid_t is_uid; /* uid of open processes */
50: u_short is_timeout; /* current timeout (seconds) */
51: u_short is_error; /* internal error codes */
52: u_short is_flags;
53: #define IKF_ATTACHED 0x1 /* unit is attached (not used yet) */
54: union {
55: u_short w[2];
56: u_long l;
57: } is_nameaddr; /* address of last symbol lookup */
58: caddr_t is_buf[PS_MAXDMA];/* i/o buffer XXX */
59: } ik_softc[NIK];
60:
61: struct buf iktab[NIK]; /* unit command queue headers */
62: struct buf rikbuf[NIK]; /* buffers for read/write operations */
63: struct buf cikbuf[NIK]; /* buffers for control operations */
64:
65: /* buf overlay definitions */
66: #define b_command b_resid
67:
68: int ikdiotimo = PS_DIOTIMO; /* dio polling timeout */
69: int iktimeout = PS_TIMEOUT; /* attention/dma timeout (in hz) */
70:
71: ikprobe(reg, vi)
72: caddr_t reg;
73: struct vba_device *vi;
74: {
75: register int br, cvec; /* r12, r11 */
76: register struct ikdevice *ik;
77:
78: #ifdef lint
79: br = 0; cvec = br; br = cvec;
80: ikintr(0);
81: #endif
82: if (badaddr(reg, 2))
83: return (0);
84: ik = (struct ikdevice *)reg;
85: ik->ik_vec = --vi->ui_hd->vh_lastiv;
86: /*
87: * Use extended non-privileged address modifier
88: * to avoid address overlap with 24-bit devices.
89: */
90: ik->ik_mod = 0xf1; /* address modifier */
91: /*
92: * Try and reset the PS300. Since this
93: * won't work if it's powered off, we
94: * can't use sucess/failure to decide
95: * if the device is present.
96: */
97: br = 0;
98: (void) psreset(ik, IKCSR_IENA);
99: if (br == 0) /* XXX */
100: br = 0x18, cvec = ik->ik_vec; /* XXX */
101: return (sizeof (struct ikdevice));
102: }
103:
104: /*
105: * Perform a ``hard'' reset.
106: */
107: psreset(ik, iena)
108: register struct ikdevice *ik;
109: {
110:
111: ik->ik_csr = IKCSR_MCLR|iena;
112: DELAY(10000);
113: ik->ik_csr = IKCSR_FNC3|iena;
114: if (!iena)
115: return (dioread(ik) == PS_RESET);
116: return (1);
117: }
118:
119: ikattach(vi)
120: struct vba_device *vi;
121: {
122:
123: ik_softc[vi->ui_unit].is_uid = -1;
124: }
125:
126: /*
127: * Open a PS300 and attach. We allow multiple
128: * processes with the same uid to share a unit.
129: */
130: /*ARGSUSED*/
131: ikopen(dev, flag)
132: dev_t dev;
133: int flag;
134: {
135: register int unit = IKUNIT(dev);
136: register struct ik_softc *sc;
137: struct vba_device *vi;
138: struct ikdevice *ik;
139: int reset;
140:
141: if (unit >= NIK || (vi = ikinfo[unit]) == 0 || vi->ui_alive == 0)
142: return (ENXIO);
143: sc = &ik_softc[unit];
144: if (sc->is_uid != (uid_t)-1 && sc->is_uid != u.u_uid)
145: return (EBUSY);
146: if (sc->is_uid == (uid_t)-1) {
147: sc->is_timeout = 0;
148: timeout(iktimer, (caddr_t)unit, hz);
149: /*
150: * Perform PS300 attach for first process.
151: */
152: if (!IKDIAG(dev)) {
153: reset = 0;
154: again:
155: if (ikcommand(dev, PS_ATTACH, 1)) {
156: /*
157: * If attach fails, perform a hard
158: * reset once, then retry the command.
159: */
160: ik = (struct ikdevice *)ikinfo[unit]->ui_addr;
161: if (!reset++ && psreset(ik, 0))
162: goto again;
163: untimeout(iktimer, (caddr_t)unit);
164: return (EIO);
165: }
166: }
167: sc->is_uid = u.u_uid;
168: }
169: return (0);
170: }
171:
172: /*ARGSUSED*/
173: ikclose(dev, flag)
174: dev_t dev;
175: int flag;
176: {
177: int unit = IKUNIT(dev);
178: register struct ik_softc *sc = &ik_softc[unit];
179:
180: if (!IKDIAG(dev))
181: (void) ikcommand(dev, PS_DETACH, 1); /* auto detach */
182: sc->is_uid = -1;
183: untimeout(iktimer, (caddr_t)unit);
184: }
185:
186: ikread(dev, uio)
187: dev_t dev;
188: struct uio *uio;
189: {
190:
191: return (ikrw(dev, uio, B_READ));
192: }
193:
194: ikwrite(dev, uio)
195: dev_t dev;
196: struct uio *uio;
197: {
198:
199: return (ikrw(dev, uio, B_WRITE));
200: }
201:
202: /*
203: * Take read/write request and perform physical i/o
204: * transaction with PS300. This involves constructing
205: * a physical i/o request vector based on the uio
206: * vector, performing the dma, and, finally, moving
207: * the data to it's final destination (because of CCI
208: * VERSAbus bogosities).
209: */
210: ikrw(dev, uio, rw)
211: dev_t dev;
212: register struct uio *uio;
213: int rw;
214: {
215: int error, unit = IKUNIT(dev), s, wrcmd;
216: register struct buf *bp;
217: register struct iovec *iov;
218: register struct psalist *ap;
219: struct ik_softc *sc = &ik_softc[unit];
220:
221: if (unit >= NIK)
222: return (ENXIO);
223: bp = &rikbuf[unit];
224: error = 0, iov = uio->uio_iov, wrcmd = PS_WRPHY;
225: for (; !error && uio->uio_iovcnt; iov++, uio->uio_iovcnt--) {
226: /*
227: * Hack way to set PS300 address w/o doing an lseek
228: * and specify write physical w/ refresh synchronization.
229: */
230: if (iov->iov_len == 0) {
231: if ((int)iov->iov_base&PSIO_SYNC)
232: wrcmd = PS_WRPHY_SYNC;
233: uio->uio_offset = (int)iov->iov_base & ~PSIO_SYNC;
234: continue;
235: }
236: if (iov->iov_len > PS_MAXDMA) {
237: sc->is_error = PSERROR_INVALBC, error = EINVAL;
238: continue;
239: }
240: if ((int)uio->uio_offset&01) {
241: sc->is_error = PSERROR_BADADDR, error = EINVAL;
242: continue;
243: }
244: s = splbio();
245: while (bp->b_flags&B_BUSY) {
246: bp->b_flags |= B_WANTED;
247: sleep((caddr_t)bp, PRIBIO+1);
248: }
249: splx(s);
250: bp->b_flags = B_BUSY | rw;
251: /*
252: * Construct address descriptor in buffer.
253: */
254: ap = (struct psalist *)sc->is_buf;
255: ap->nblocks = 1;
256: /* work-around dr300 word swapping */
257: ap->addr[0] = uio->uio_offset & 0xffff;
258: ap->addr[1] = uio->uio_offset >> 16;
259: ap->wc = (iov->iov_len + 1) >> 1;
260: if (rw == B_WRITE) {
261: error = copyin(iov->iov_base, (caddr_t)&ap[1],
262: (unsigned)iov->iov_len);
263: if (!error)
264: error = ikcommand(dev, wrcmd,
265: iov->iov_len + sizeof (*ap));
266: } else {
267: caddr_t cp;
268: int len;
269:
270: error = ikcommand(dev, PS_RDPHY, sizeof (*ap));
271: cp = (caddr_t)&ap[1], len = iov->iov_len;
272: for (; len > 0; len -= NBPG, cp += NBPG)
273: mtpr(P1DC, cp);
274: if (!error)
275: error = copyout((caddr_t)&ap[1], iov->iov_base,
276: (unsigned)iov->iov_len);
277: }
278: (void) splbio();
279: if (bp->b_flags&B_WANTED)
280: wakeup((caddr_t)bp);
281: splx(s);
282: uio->uio_resid -= iov->iov_len;
283: uio->uio_offset += iov->iov_len;
284: bp->b_flags &= ~(B_BUSY|B_WANTED);
285: }
286: return (error);
287: }
288:
289: /*
290: * Perform a PS300 command.
291: */
292: ikcommand(dev, com, count)
293: dev_t dev;
294: int com, count;
295: {
296: register struct buf *bp;
297: register int s;
298:
299: bp = &cikbuf[IKUNIT(dev)];
300: s = splik();
301: while (bp->b_flags&B_BUSY) {
302: if (bp->b_flags&B_DONE)
303: break;
304: bp->b_flags |= B_WANTED;
305: sleep((caddr_t)bp, PRIBIO);
306: }
307: bp->b_flags = B_BUSY|B_READ;
308: splx(s);
309: bp->b_dev = dev;
310: bp->b_command = com;
311: bp->b_bcount = count;
312: ikstrategy(bp);
313: biowait(bp);
314: if (bp->b_flags&B_WANTED)
315: wakeup((caddr_t)bp);
316: bp->b_flags &= B_ERROR;
317: return (geterror(bp));
318: }
319:
320: /*
321: * Physio strategy routine
322: */
323: ikstrategy(bp)
324: register struct buf *bp;
325: {
326: register struct buf *dp;
327:
328: /*
329: * Put request at end of controller queue.
330: */
331: dp = &iktab[IKUNIT(bp->b_dev)];
332: bp->av_forw = NULL;
333: (void) splik();
334: if (dp->b_actf != NULL) {
335: dp->b_actl->av_forw = bp;
336: dp->b_actl = bp;
337: } else
338: dp->b_actf = dp->b_actl = bp;
339: if (!dp->b_active)
340: ikstart(dp);
341: (void) spl0();
342: }
343:
344: /*
345: * Start the next command on the controller's queue.
346: */
347: ikstart(dp)
348: register struct buf *dp;
349: {
350: register struct buf *bp;
351: register struct ikdevice *ik;
352: register struct ik_softc *sc;
353: u_short bc, csr;
354: u_int addr;
355: int unit;
356:
357: loop:
358: /*
359: * Pull a request off the controller queue
360: */
361: if ((bp = dp->b_actf) == NULL) {
362: dp->b_active = 0;
363: return;
364: }
365: /*
366: * Mark controller busy and process this request.
367: */
368: dp->b_active = 1;
369: unit = IKUNIT(bp->b_dev);
370: sc = &ik_softc[unit];
371: ik = (struct ikdevice *)ikinfo[unit]->ui_addr;
372: switch ((int)bp->b_command) {
373:
374: case PS_ATTACH: /* logical unit attach */
375: case PS_DETACH: /* logical unit detach */
376: case PS_LOOKUP: /* name lookup */
377: case PS_RDPHY: /* physical i/o read */
378: case PS_WRPHY: /* physical i/o write */
379: case PS_WRPHY_SYNC: /* physical i/o write w/ sync */
380: /*
381: * Handshake command and, optionally,
382: * byte count and byte swap flag.
383: */
384: if (sc->is_error = diowrite(ik, (u_short)bp->b_command))
385: goto bad;
386: if (bp->b_command < PS_DETACH) {
387: if (sc->is_error = diowrite(ik, (u_short)bp->b_bcount))
388: goto bad;
389: if (sc->is_error = diowrite(ik, (u_short)0 /* !swab */))
390: goto bad;
391: }
392: /*
393: * Set timeout and wait for an attention interrupt.
394: */
395: sc->is_timeout = iktimeout;
396: return;
397:
398: case PS_DMAOUT: /* dma data host->PS300 */
399: bc = bp->b_bcount;
400: csr = IKCSR_CYCLE;
401: break;
402:
403: case PS_DMAIN: /* dma data PS300->host */
404: bc = bp->b_bcount;
405: csr = IKCSR_CYCLE|IKCSR_FNC1;
406: break;
407:
408: default:
409: log(LOG_ERR, "ik%d: bad cmd %x\n", unit, bp->b_command);
410: sc->is_error = PSERROR_BADCMD;
411: goto bad;
412: }
413: /* initiate dma transfer */
414: addr = vtoph((struct proc *)0, (unsigned)sc->is_buf);
415: ik->ik_bahi = addr >> 17;
416: ik->ik_balo = (addr >> 1) & 0xffff;
417: ik->ik_wc = ((bc + 1) >> 1) - 1; /* round & convert */
418: ik->ik_pulse = IKPULSE_RATTF|IKPULSE_RDMAF;
419: sc->is_timeout = iktimeout;
420: ik->ik_csr = IKCSR_IENA|IKCSR_GO|csr;
421: return;
422: bad:
423: bp->b_flags |= B_ERROR;
424: dp->b_actf = bp->av_forw; /* remove from queue */
425: biodone(bp);
426: goto loop;
427: }
428:
429: #define FETCHWORD(i) { \
430: v = dioread(ik); \
431: if (v == -1) { \
432: sc->is_error = PSERROR_NAMETIMO; \
433: goto bad; \
434: } \
435: sc->is_nameaddr.w[i] = v; \
436: }
437:
438: /*
439: * Process a device interrupt.
440: */
441: ikintr(ikon)
442: int ikon;
443: {
444: register struct ikdevice *ik;
445: register struct buf *bp, *dp;
446: struct ik_softc *sc;
447: register u_short data;
448: int v;
449:
450: /* should go by controller, but for now... */
451: if (ikinfo[ikon] == 0)
452: return;
453: ik = (struct ikdevice *)ikinfo[ikon]->ui_addr;
454: /*
455: * Discard all non-attention interrupts. The
456: * interrupts we're throwing away should all be
457: * associated with DMA completion.
458: */
459: data = ik->ik_data;
460: if ((ik->ik_csr&(IKCSR_ATTF|IKCSR_STATC)) != IKCSR_ATTF) {
461: ik->ik_pulse = IKPULSE_RATTF|IKPULSE_RDMAF|IKPULSE_SIENA;
462: return;
463: }
464: /*
465: * Fetch attention code immediately.
466: */
467: ik->ik_csr = IKCSR_RATTF|IKCSR_RDMAF|IKCSR_FNC1;
468: ik->ik_pulse = IKPULSE_FNC2;
469: /*
470: * Get device and block structures, and a pointer
471: * to the vba_device for the device. We receive an
472: * unsolicited interrupt whenever the PS300 is power
473: * cycled (so ignore it in that case).
474: */
475: dp = &iktab[ikon];
476: if ((bp = dp->b_actf) == NULL) {
477: if (PS_CODE(data) != PS_RESET) /* power failure */
478: log(LOG_WARNING, "ik%d: spurious interrupt, code %x\n",
479: ikon, data);
480: goto enable;
481: }
482: sc = &ik_softc[IKUNIT(bp->b_dev)];
483: sc->is_timeout = 0; /* disable timer */
484: switch (PS_CODE(data)) {
485:
486: case PS_LOOKUP: /* name lookup */
487: if (data == PS_LOOKUP) { /* dma name */
488: bp->b_command = PS_DMAOUT;
489: goto opcont;
490: }
491: if (data == PS_DMAOK(PS_LOOKUP)) {
492: /* reenable interrupt and wait for address */
493: sc->is_timeout = iktimeout;
494: goto enable;
495: }
496: /*
497: * Address should be present, extract it one
498: * word at a time from the PS300 (yech).
499: */
500: if (data != PS_ADROK(PS_LOOKUP))
501: goto bad;
502: FETCHWORD(0);
503: FETCHWORD(1);
504: goto opdone;
505:
506: case PS_WRPHY_SYNC: /* physical i/o write w/ sync */
507: if (data == PS_WRPHY_SYNC) { /* start dma transfer */
508: bp->b_command = PS_DMAOUT;
509: goto opcont;
510: }
511: if (data != PS_DMAOK(PS_WRPHY_SYNC))
512: goto bad;
513: goto opdone;
514:
515: case PS_WRPHY: /* physical i/o write */
516: if (data == PS_WRPHY) { /* start dma transfer */
517: bp->b_command = PS_DMAOUT;
518: goto opcont;
519: }
520: if (data != PS_DMAOK(PS_WRPHY))
521: goto bad;
522: goto opdone;
523:
524: case PS_ATTACH: /* attach unit */
525: case PS_DETACH: /* detach unit */
526: case PS_ABORT: /* abort code from ps300 */
527: if (data != bp->b_command)
528: goto bad;
529: goto opdone;
530:
531: case PS_RDPHY: /* physical i/o read */
532: if (data == PS_RDPHY) { /* dma address list */
533: bp->b_command = PS_DMAOUT;
534: goto opcont;
535: }
536: if (data == PS_ADROK(PS_RDPHY)) {
537: /* collect read byte count and start dma */
538: bp->b_bcount = dioread(ik);
539: if (bp->b_bcount == -1)
540: goto bad;
541: bp->b_command = PS_DMAIN;
542: goto opcont;
543: }
544: if (data == PS_DMAOK(PS_RDPHY))
545: goto opdone;
546: goto bad;
547: }
548: bad:
549: sc->is_error = data;
550: bp->b_flags |= B_ERROR;
551: opdone:
552: dp->b_actf = bp->av_forw; /* remove from queue */
553: biodone(bp);
554: opcont:
555: ikstart(dp);
556: enable:
557: ik->ik_pulse = IKPULSE_SIENA; /* explicitly reenable */
558: }
559:
560: /*
561: * Watchdog timer.
562: */
563: iktimer(unit)
564: int unit;
565: {
566: register struct ik_softc *sc = &ik_softc[unit];
567:
568: if (sc->is_timeout && --sc->is_timeout == 0) {
569: register struct buf *dp, *bp;
570: int s;
571:
572: log(LOG_ERR, "ik%d: timeout\n", unit);
573: s = splik();
574: /* should abort current command */
575: dp = &iktab[unit];
576: if (bp = dp->b_actf) {
577: sc->is_error = PSERROR_CMDTIMO;
578: bp->b_flags |= B_ERROR;
579: dp->b_actf = bp->av_forw; /* remove from queue */
580: biodone(bp);
581: ikstart(dp);
582: }
583: splx(s);
584: }
585: timeout(iktimer, (caddr_t)unit, hz);
586: }
587:
588: /*
589: * Handshake read from DR300.
590: */
591: dioread(ik)
592: register struct ikdevice *ik;
593: {
594: register int t;
595: u_short data;
596:
597: for (t = ikdiotimo; t > 0; t--)
598: if ((ik->ik_csr&(IKCSR_ATTF|IKCSR_STATC)) == IKCSR_ATTF) {
599: data = ik->ik_data;
600: ik->ik_csr = IKCSR_RATTF|IKCSR_RDMAF|IKCSR_FNC1;
601: ik->ik_pulse = IKPULSE_FNC2;
602: return (data);
603: }
604: return (-1);
605: }
606:
607: /*
608: * Handshake write to DR300.
609: *
610: * Interrupts are enabled before completing the work
611: * so the caller should either be at splik or be
612: * prepared to take the interrupt immediately.
613: */
614: diowrite(ik, v)
615: register struct ikdevice *ik;
616: u_short v;
617: {
618: register int t;
619: register u_short csr;
620:
621: top:
622: /*
623: * Deposit data and generate dr300 attention
624: */
625: ik->ik_data = v;
626: ik->ik_csr = IKCSR_RDMAF|IKCSR_RATTF;
627: ik->ik_pulse = IKPULSE_FNC2;
628: for (t = ikdiotimo; t > 0; t--) {
629: csr = ik->ik_csr;
630: #define IKCSR_DONE (IKCSR_STATA|IKCSR_STATC)
631: if ((csr&IKCSR_DONE) == IKCSR_DONE) {
632: /*
633: * Done, complete handshake by notifying dr300.
634: */
635: ik->ik_csr = IKCSR_IENA; /* ~IKCSR_FNC1 */
636: ik->ik_pulse = IKPULSE_FNC2;
637: return (0);
638: }
639: /* beware of potential deadlock with dioread */
640: if ((csr&(IKCSR_ATTF|IKCSR_STATC)) == IKCSR_ATTF)
641: goto top;
642: }
643: ik->ik_csr = IKCSR_IENA;
644: return (PSERROR_DIOTIMO);
645: }
646:
647: /*ARGSUSED*/
648: ikioctl(dev, cmd, data, flag)
649: dev_t dev;
650: int cmd;
651: caddr_t data;
652: int flag;
653: {
654: int error = 0, unit = IKUNIT(dev), s;
655: register struct ik_softc *sc = &ik_softc[unit];
656:
657: switch (cmd) {
658:
659: case PSIOGETERROR: /* get error code for last operation */
660: *(int *)data = sc->is_error;
661: break;
662:
663: case PSIOLOOKUP: { /* PS300 name lookup */
664: register struct pslookup *lp = (struct pslookup *)data;
665: register struct buf *bp;
666:
667: if (lp->pl_len > PS_MAXNAMELEN)
668: return (EINVAL);
669: bp = &rikbuf[unit];
670: s = splbio();
671: while (bp->b_flags&B_BUSY) {
672: bp->b_flags |= B_WANTED;
673: sleep((caddr_t)bp, PRIBIO+1);
674: }
675: splx(s);
676: bp->b_flags = B_BUSY | B_WRITE;
677: error = copyin(lp->pl_name, (caddr_t)sc->is_buf,
678: (unsigned)lp->pl_len);
679: if (error == 0) {
680: if (lp->pl_len&1)
681: sc->is_buf[lp->pl_len] = '\0';
682: error = ikcommand(dev, PS_LOOKUP, lp->pl_len);
683: }
684: s = splbio();
685: if (bp->b_flags&B_WANTED)
686: wakeup((caddr_t)bp);
687: splx(s);
688: bp->b_flags &= ~(B_BUSY|B_WANTED);
689: lp->pl_addr = sc->is_nameaddr.l;
690: break;
691: }
692: default:
693: return (ENOTTY);
694: }
695: return (error);
696: }
697: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.