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