ppi.c revision 42475
1/*-
2 * Copyright (c) 1997, 1998 Nicolas Souchu, Michael Smith
3 * 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 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$Id: ppi.c,v 1.8 1998/12/07 21:58:16 archie Exp $
27 *
28 */
29#include "ppi.h"
30
31#if NPPI > 0
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/conf.h>
36#include <sys/kernel.h>
37#include <sys/uio.h>
38#include <sys/malloc.h>
39#include <sys/fcntl.h>
40
41#include <machine/clock.h>
42
43#include <dev/ppbus/ppbconf.h>
44#include <dev/ppbus/ppb_msq.h>
45
46#include "opt_ppb_1284.h"
47
48#ifdef PERIPH_1284
49#include <dev/ppbus/ppb_1284.h>
50#endif
51
52#include <dev/ppbus/ppi.h>
53
54#define BUFSIZE		512
55
56struct ppi_data {
57
58    int		ppi_unit;
59    int		ppi_flags;
60#define HAVE_PPBUS	(1<<0)
61#define HAD_PPBUS	(1<<1)
62
63    int		ppi_count;
64    int		ppi_mode;			/* IEEE1284 mode */
65    char	ppi_buffer[BUFSIZE];
66
67    struct ppb_device ppi_dev;
68};
69
70#define MAXPPI		8			/* XXX not much better! */
71static int 		nppi = 0;
72static struct ppi_data	*ppidata[MAXPPI];
73
74/*
75 * Make ourselves visible as a ppbus driver
76 */
77
78static struct ppb_device	*ppiprobe(struct ppb_data *ppb);
79static int			ppiattach(struct ppb_device *dev);
80static void			ppiintr(int unit);
81
82static struct ppb_driver ppidriver = {
83    ppiprobe, ppiattach, "ppi"
84};
85DATA_SET(ppbdriver_set, ppidriver);
86
87static	d_open_t	ppiopen;
88static	d_close_t	ppiclose;
89static	d_ioctl_t	ppiioctl;
90static	d_write_t	ppiwrite;
91static	d_read_t	ppiread;
92
93#define CDEV_MAJOR 82
94static struct cdevsw ppi_cdevsw =
95	{ ppiopen,	ppiclose,	ppiread,	ppiwrite,	/* 82 */
96	  ppiioctl,	nullstop,	nullreset,	nodevtotty,
97	  seltrue,	nommap,		nostrat,	"ppi",	NULL,	-1 };
98
99#ifdef PERIPH_1284
100
101static void
102ppi_enable_intr(struct ppi_data *ppi)
103{
104	char r;
105
106	r = ppb_rctr(&ppi->ppi_dev);
107	ppb_wctr(&ppi->ppi_dev, r | IRQENABLE);
108
109	return;
110}
111
112static void
113ppi_disable_intr(struct ppi_data *ppi)
114{
115	char r;
116
117	r = ppb_rctr(&ppi->ppi_dev);
118	ppb_wctr(&ppi->ppi_dev, r & ~IRQENABLE);
119
120	return;
121}
122
123#endif /* PERIPH_1284 */
124
125/*
126 * ppiprobe()
127 */
128static struct ppb_device *
129ppiprobe(struct ppb_data *ppb)
130{
131	struct ppi_data *ppi;
132
133	ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data),
134							M_TEMP, M_NOWAIT);
135	if (!ppi) {
136		printf("ppi: cannot malloc!\n");
137		return 0;
138	}
139	bzero(ppi, sizeof(struct ppi_data));
140
141	ppidata[nppi] = ppi;
142
143	/*
144	 * ppi dependent initialisation.
145	 */
146	ppi->ppi_unit = nppi;
147
148	/*
149	 * ppbus dependent initialisation.
150	 */
151	ppi->ppi_dev.id_unit = ppi->ppi_unit;
152	ppi->ppi_dev.ppb = ppb;
153	ppi->ppi_dev.intr = ppiintr;
154
155	/* Ok, go to next device on next probe */
156	nppi ++;
157
158	return &ppi->ppi_dev;
159}
160
161static int
162ppiattach(struct ppb_device *dev)
163{
164	/*
165	 * Report ourselves
166	 */
167	printf("ppi%d: <generic parallel i/o> on ppbus %d\n",
168	       dev->id_unit, dev->ppb->ppb_link->adapter_unit);
169
170	return (1);
171}
172
173/*
174 * Cable
175 * -----
176 *
177 * Use an IEEE1284 compliant (DB25/DB25) cable with the following tricks:
178 *
179 * nStrobe   <-> nAck		1  <-> 10
180 * nAutofd   <-> Busy		11 <-> 14
181 * nSelectin <-> Select		17 <-> 13
182 * nInit     <-> nFault		15 <-> 16
183 *
184 */
185static void
186ppiintr(int unit)
187{
188#ifdef PERIPH_1284
189	struct ppi_data *ppi = ppidata[unit];
190
191	ppi_disable_intr(ppi);
192
193	switch (ppi->ppi_dev.ppb->state) {
194
195	/* accept IEEE1284 negociation then wakeup an waiting process to
196	 * continue negociation at process level */
197	case PPB_FORWARD_IDLE:
198		/* Event 1 */
199		if ((ppb_rstr(&ppi->ppi_dev) & (SELECT | nBUSY)) ==
200							(SELECT | nBUSY)) {
201			/* IEEE1284 negociation */
202#ifdef DEBUG_1284
203			printf("N");
204#endif
205
206			/* Event 2 - prepare for reading the ext. value */
207			ppb_wctr(&ppi->ppi_dev, (PCD | STROBE | nINIT) & ~SELECTIN);
208
209			ppi->ppi_dev.ppb->state = PPB_NEGOCIATION;
210
211		} else {
212#ifdef DEBUG_1284
213			printf("0x%x", ppb_rstr(&ppi->ppi_dev));
214#endif
215			ppb_peripheral_terminate(&ppi->ppi_dev, PPB_DONTWAIT);
216			break;
217		}
218
219		/* wake up any process waiting for negociation from
220		 * remote master host */
221
222		/* XXX should set a variable to warn the process about
223		 * the interrupt */
224
225		wakeup(ppi);
226		break;
227	default:
228#ifdef DEBUG_1284
229		printf("?%d", ppi->ppi_dev.ppb->state);
230#endif
231		ppi->ppi_dev.ppb->state = PPB_FORWARD_IDLE;
232		ppb_set_mode(&ppi->ppi_dev, PPB_COMPATIBLE);
233		break;
234	}
235
236	ppi_enable_intr(ppi);
237#endif /* PERIPH_1284 */
238
239	return;
240}
241
242static int
243ppiopen(dev_t dev, int flags, int fmt, struct proc *p)
244{
245	u_int unit = minor(dev);
246	struct ppi_data *ppi = ppidata[unit];
247	int res;
248
249	if (unit >= nppi)
250		return (ENXIO);
251
252	if (!(ppi->ppi_flags & HAVE_PPBUS)) {
253		if ((res = ppb_request_bus(&ppi->ppi_dev,
254			(flags & O_NONBLOCK) ? PPB_DONTWAIT :
255						(PPB_WAIT | PPB_INTR))))
256			return (res);
257
258		ppi->ppi_flags |= HAVE_PPBUS;
259	}
260	ppi->ppi_count += 1;
261
262	return (0);
263}
264
265static int
266ppiclose(dev_t dev, int flags, int fmt, struct proc *p)
267{
268	u_int unit = minor(dev);
269	struct ppi_data *ppi = ppidata[unit];
270
271	ppi->ppi_count --;
272	if (!ppi->ppi_count) {
273
274#ifdef PERIPH_1284
275		switch (ppi->ppi_dev.ppb->state) {
276		case PPB_PERIPHERAL_IDLE:
277			ppb_peripheral_terminate(&ppi->ppi_dev, 0);
278			break;
279		case PPB_REVERSE_IDLE:
280		case PPB_EPP_IDLE:
281		case PPB_ECP_FORWARD_IDLE:
282		default:
283			ppb_1284_terminate(&ppi->ppi_dev);
284			break;
285		}
286#endif /* PERIPH_1284 */
287
288		ppb_release_bus(&ppi->ppi_dev);
289		ppi->ppi_flags &= ~HAVE_PPBUS;
290	}
291
292	return (0);
293}
294
295/*
296 * ppiread()
297 *
298 * IEEE1284 compliant read.
299 *
300 * First, try negociation to BYTE then NIBBLE mode
301 * If no data is available, wait for it otherwise transfer as much as possible
302 */
303static int
304ppiread(dev_t dev, struct uio *uio, int ioflag)
305{
306#ifdef PERIPH_1284
307	u_int unit = minor(dev);
308	struct ppi_data *ppi = ppidata[unit];
309	int len, error = 0;
310
311	switch (ppi->ppi_dev.ppb->state) {
312	case PPB_PERIPHERAL_IDLE:
313		ppb_peripheral_terminate(&ppi->ppi_dev, 0);
314		/* fall throught */
315
316	case PPB_FORWARD_IDLE:
317		/* if can't negociate NIBBLE mode then try BYTE mode,
318		 * the peripheral may be a computer
319		 */
320		if ((ppb_1284_negociate(&ppi->ppi_dev,
321			ppi->ppi_mode = PPB_NIBBLE, 0))) {
322
323			/* XXX Wait 2 seconds to let the remote host some
324			 * time to terminate its interrupt
325			 */
326			tsleep(ppi, PPBPRI, "ppiread", 2*hz);
327
328			if ((error = ppb_1284_negociate(&ppi->ppi_dev,
329				ppi->ppi_mode = PPB_BYTE, 0)))
330				return (error);
331		}
332		break;
333
334	case PPB_REVERSE_IDLE:
335	case PPB_EPP_IDLE:
336	case PPB_ECP_FORWARD_IDLE:
337	default:
338		break;
339	}
340
341#ifdef DEBUG_1284
342	printf("N");
343#endif
344	/* read data */
345	len = 0;
346	while (uio->uio_resid) {
347		if ((error = ppb_1284_read(&ppi->ppi_dev, ppi->ppi_mode,
348			ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid),
349			&len))) {
350			goto error;
351		}
352
353		if (!len)
354			goto error;		/* no more data */
355
356#ifdef DEBUG_1284
357		printf("d");
358#endif
359		if ((error = uiomove(ppi->ppi_buffer, len, uio)))
360			goto error;
361	}
362
363error:
364
365#else /* PERIPH_1284 */
366	int error = ENODEV;
367#endif
368
369	return (error);
370}
371
372/*
373 * ppiwrite()
374 *
375 * IEEE1284 compliant write
376 *
377 * Actually, this is the peripheral side of a remote IEEE1284 read
378 *
379 * The first part of the negociation (IEEE1284 device detection) is
380 * done at interrupt level, then the remaining is done by the writing
381 * process
382 *
383 * Once negociation done, transfer data
384 */
385static int
386ppiwrite(dev_t dev, struct uio *uio, int ioflag)
387{
388#ifdef PERIPH_1284
389	u_int unit = minor(dev);
390	struct ppi_data *ppi = ppidata[unit];
391	struct ppb_data *ppb = ppi->ppi_dev.ppb;
392	int len, error = 0, sent;
393
394#if 0
395	int ret;
396
397	#define ADDRESS		MS_PARAM(0, 0, MS_TYP_PTR)
398	#define LENGTH		MS_PARAM(0, 1, MS_TYP_INT)
399
400	struct ppb_microseq msq[] = {
401		  { MS_OP_PUT, { MS_UNKNOWN, MS_UNKNOWN, MS_UNKNOWN } },
402		  MS_RET(0)
403	};
404
405	/* negociate ECP mode */
406	if (ppb_1284_negociate(&ppi->ppi_dev, PPB_ECP, 0)) {
407		printf("ppiwrite: ECP negociation failed\n");
408	}
409
410	while (!error && (len = min(uio->uio_resid, BUFSIZE))) {
411		uiomove(ppi->ppi_buffer, len, uio);
412
413		ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len);
414
415		error = ppb_MS_microseq(&ppi->ppi_dev, msq, &ret);
416	}
417#endif
418
419	/* we have to be peripheral to be able to send data, so
420	 * wait for the appropriate state
421	 */
422	if (ppb->state < PPB_PERIPHERAL_NEGOCIATION)
423		ppb_1284_terminate(&ppi->ppi_dev);
424
425	while (ppb->state != PPB_PERIPHERAL_IDLE) {
426		/* XXX should check a variable before sleeping */
427#ifdef DEBUG_1284
428		printf("s");
429#endif
430
431		ppi_enable_intr(ppi);
432
433		/* sleep until IEEE1284 negociation starts */
434		error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0);
435
436		switch (error) {
437		case 0:
438			/* negociate peripheral side with BYTE mode */
439			ppb_peripheral_negociate(&ppi->ppi_dev, PPB_BYTE, 0);
440			break;
441		case EWOULDBLOCK:
442			break;
443		default:
444			goto error;
445		}
446	}
447#ifdef DEBUG_1284
448	printf("N");
449#endif
450
451	/* negociation done, write bytes to master host */
452	while (len = min(uio->uio_resid, BUFSIZE)) {
453		uiomove(ppi->ppi_buffer, len, uio);
454		if ((error = byte_peripheral_write(&ppi->ppi_dev,
455						ppi->ppi_buffer, len, &sent)))
456			goto error;
457#ifdef DEBUG_1284
458		printf("d");
459#endif
460	}
461
462error:
463
464#else /* PERIPH_1284 */
465	int error = ENODEV;
466#endif
467
468	return (error);
469}
470
471static int
472ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
473{
474	u_int unit = minor(dev);
475	struct ppi_data *ppi = ppidata[unit];
476	int error = 0;
477	u_int8_t *val = (u_int8_t *)data;
478
479	switch (cmd) {
480
481	case PPIGDATA:			/* get data register */
482		*val = ppb_rdtr(&ppi->ppi_dev);
483		break;
484	case PPIGSTATUS:		/* get status bits */
485		*val = ppb_rstr(&ppi->ppi_dev);
486		break;
487	case PPIGCTRL:			/* get control bits */
488		*val = ppb_rctr(&ppi->ppi_dev);
489		break;
490	case PPIGEPP:			/* get EPP bits */
491		*val = ppb_repp(&ppi->ppi_dev);
492		break;
493	case PPIGECR:			/* get ECP bits */
494		*val = ppb_recr(&ppi->ppi_dev);
495		break;
496	case PPIGFIFO:			/* read FIFO */
497		*val = ppb_rfifo(&ppi->ppi_dev);
498		break;
499
500	case PPISDATA:			/* set data register */
501		ppb_wdtr(&ppi->ppi_dev, *val);
502		break;
503	case PPISSTATUS:		/* set status bits */
504		ppb_wstr(&ppi->ppi_dev, *val);
505		break;
506	case PPISCTRL:			/* set control bits */
507		ppb_wctr(&ppi->ppi_dev, *val);
508		break;
509	case PPISEPP:			/* set EPP bits */
510		ppb_wepp(&ppi->ppi_dev, *val);
511		break;
512	case PPISECR:			/* set ECP bits */
513		ppb_wecr(&ppi->ppi_dev, *val);
514		break;
515	case PPISFIFO:			/* write FIFO */
516		ppb_wfifo(&ppi->ppi_dev, *val);
517		break;
518	default:
519		error = ENOTTY;
520		break;
521	}
522
523	return (error);
524}
525
526#ifdef PPI_MODULE
527
528MOD_DEV(ppi, LM_DT_CHAR, CDEV_MAJOR, &ppi_cdevsw);
529
530static int
531ppi_load(struct lkm_table *lkmtp, int cmd)
532{
533	struct ppb_data *ppb;
534	struct ppb_device *dev;
535	int i;
536
537	for (ppb = ppb_next_bus(NULL); ppb; ppb = ppb_next_bus(ppb)) {
538
539		dev = ppiprobe(ppb);
540		ppiattach(dev);
541
542		ppb_attach_device(dev);
543	}
544
545	return (0);
546}
547
548static int
549ppi_unload(struct lkm_table *lkmtp, int cmd)
550{
551	int i;
552
553	for (i = nppi-1; i > 0; i--) {
554		ppb_remove_device(&ppidata[i]->ppi_dev);
555		free(ppidata[i], M_TEMP);
556	}
557
558	return (0);
559}
560
561int
562ppi_mod(struct lkm_table *lkmtp, int cmd, int ver)
563{
564	DISPATCH(lkmtp, cmd, ver, ppi_load, ppi_unload, lkm_nullcmd);
565}
566
567#endif /* PPI_MODULE */
568
569static ppi_devsw_installed = 0;
570
571static void ppi_drvinit(void *unused)
572{
573	dev_t dev;
574
575	if (!ppi_devsw_installed ) {
576		dev = makedev(CDEV_MAJOR, 0);
577		cdevsw_add(&dev, &ppi_cdevsw, NULL);
578		ppi_devsw_installed = 1;
579    	}
580}
581
582SYSINIT(ppidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ppi_drvinit,NULL)
583
584#endif /* NPPI */
585