ppi.c revision 51658
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 * $FreeBSD: head/sys/dev/ppbus/ppi.c 51658 1999-09-25 18:24:47Z phk $
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	/* open */	ppiopen,
96	/* close */	ppiclose,
97	/* read */	ppiread,
98	/* write */	ppiwrite,
99	/* ioctl */	ppiioctl,
100	/* poll */	nopoll,
101	/* mmap */	nommap,
102	/* strategy */	nostrategy,
103	/* name */	"ppi",
104	/* maj */	CDEV_MAJOR,
105	/* dump */	nodump,
106	/* psize */	nopsize,
107	/* flags */	0,
108	/* bmaj */	-1
109};
110
111#ifdef PERIPH_1284
112
113static void
114ppi_enable_intr(struct ppi_data *ppi)
115{
116	char r;
117
118	r = ppb_rctr(&ppi->ppi_dev);
119	ppb_wctr(&ppi->ppi_dev, r | IRQENABLE);
120
121	return;
122}
123
124static void
125ppi_disable_intr(struct ppi_data *ppi)
126{
127	char r;
128
129	r = ppb_rctr(&ppi->ppi_dev);
130	ppb_wctr(&ppi->ppi_dev, r & ~IRQENABLE);
131
132	return;
133}
134
135#endif /* PERIPH_1284 */
136
137/*
138 * ppiprobe()
139 */
140static struct ppb_device *
141ppiprobe(struct ppb_data *ppb)
142{
143	struct ppi_data *ppi;
144	static int once;
145
146	if (!once++)
147		cdevsw_add(&ppi_cdevsw);
148
149	ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data),
150							M_TEMP, M_NOWAIT);
151	if (!ppi) {
152		printf("ppi: cannot malloc!\n");
153		return 0;
154	}
155	bzero(ppi, sizeof(struct ppi_data));
156
157	ppidata[nppi] = ppi;
158
159	/*
160	 * ppi dependent initialisation.
161	 */
162	ppi->ppi_unit = nppi;
163
164	/*
165	 * ppbus dependent initialisation.
166	 */
167	ppi->ppi_dev.id_unit = ppi->ppi_unit;
168	ppi->ppi_dev.ppb = ppb;
169	ppi->ppi_dev.intr = ppiintr;
170
171	/* Ok, go to next device on next probe */
172	nppi ++;
173
174	return &ppi->ppi_dev;
175}
176
177static int
178ppiattach(struct ppb_device *dev)
179{
180	/*
181	 * Report ourselves
182	 */
183	printf("ppi%d: <generic parallel i/o> on ppbus %d\n",
184	       dev->id_unit, dev->ppb->ppb_link->adapter_unit);
185
186	return (1);
187}
188
189/*
190 * Cable
191 * -----
192 *
193 * Use an IEEE1284 compliant (DB25/DB25) cable with the following tricks:
194 *
195 * nStrobe   <-> nAck		1  <-> 10
196 * nAutofd   <-> Busy		11 <-> 14
197 * nSelectin <-> Select		17 <-> 13
198 * nInit     <-> nFault		15 <-> 16
199 *
200 */
201static void
202ppiintr(int unit)
203{
204#ifdef PERIPH_1284
205	struct ppi_data *ppi = ppidata[unit];
206
207	ppi_disable_intr(ppi);
208
209	switch (ppi->ppi_dev.ppb->state) {
210
211	/* accept IEEE1284 negociation then wakeup an waiting process to
212	 * continue negociation at process level */
213	case PPB_FORWARD_IDLE:
214		/* Event 1 */
215		if ((ppb_rstr(&ppi->ppi_dev) & (SELECT | nBUSY)) ==
216							(SELECT | nBUSY)) {
217			/* IEEE1284 negociation */
218#ifdef DEBUG_1284
219			printf("N");
220#endif
221
222			/* Event 2 - prepare for reading the ext. value */
223			ppb_wctr(&ppi->ppi_dev, (PCD | STROBE | nINIT) & ~SELECTIN);
224
225			ppi->ppi_dev.ppb->state = PPB_NEGOCIATION;
226
227		} else {
228#ifdef DEBUG_1284
229			printf("0x%x", ppb_rstr(&ppi->ppi_dev));
230#endif
231			ppb_peripheral_terminate(&ppi->ppi_dev, PPB_DONTWAIT);
232			break;
233		}
234
235		/* wake up any process waiting for negociation from
236		 * remote master host */
237
238		/* XXX should set a variable to warn the process about
239		 * the interrupt */
240
241		wakeup(ppi);
242		break;
243	default:
244#ifdef DEBUG_1284
245		printf("?%d", ppi->ppi_dev.ppb->state);
246#endif
247		ppi->ppi_dev.ppb->state = PPB_FORWARD_IDLE;
248		ppb_set_mode(&ppi->ppi_dev, PPB_COMPATIBLE);
249		break;
250	}
251
252	ppi_enable_intr(ppi);
253#endif /* PERIPH_1284 */
254
255	return;
256}
257
258static int
259ppiopen(dev_t dev, int flags, int fmt, struct proc *p)
260{
261	u_int unit = minor(dev);
262	struct ppi_data *ppi = ppidata[unit];
263	int res;
264
265	if (unit >= nppi)
266		return (ENXIO);
267
268	if (!(ppi->ppi_flags & HAVE_PPBUS)) {
269		if ((res = ppb_request_bus(&ppi->ppi_dev,
270			(flags & O_NONBLOCK) ? PPB_DONTWAIT :
271						(PPB_WAIT | PPB_INTR))))
272			return (res);
273
274		ppi->ppi_flags |= HAVE_PPBUS;
275	}
276	ppi->ppi_count += 1;
277
278	return (0);
279}
280
281static int
282ppiclose(dev_t dev, int flags, int fmt, struct proc *p)
283{
284	u_int unit = minor(dev);
285	struct ppi_data *ppi = ppidata[unit];
286
287	ppi->ppi_count --;
288	if (!ppi->ppi_count) {
289
290#ifdef PERIPH_1284
291		switch (ppi->ppi_dev.ppb->state) {
292		case PPB_PERIPHERAL_IDLE:
293			ppb_peripheral_terminate(&ppi->ppi_dev, 0);
294			break;
295		case PPB_REVERSE_IDLE:
296		case PPB_EPP_IDLE:
297		case PPB_ECP_FORWARD_IDLE:
298		default:
299			ppb_1284_terminate(&ppi->ppi_dev);
300			break;
301		}
302#endif /* PERIPH_1284 */
303
304		ppb_release_bus(&ppi->ppi_dev);
305		ppi->ppi_flags &= ~HAVE_PPBUS;
306	}
307
308	return (0);
309}
310
311/*
312 * ppiread()
313 *
314 * IEEE1284 compliant read.
315 *
316 * First, try negociation to BYTE then NIBBLE mode
317 * If no data is available, wait for it otherwise transfer as much as possible
318 */
319static int
320ppiread(dev_t dev, struct uio *uio, int ioflag)
321{
322#ifdef PERIPH_1284
323	u_int unit = minor(dev);
324	struct ppi_data *ppi = ppidata[unit];
325	int len, error = 0;
326
327	switch (ppi->ppi_dev.ppb->state) {
328	case PPB_PERIPHERAL_IDLE:
329		ppb_peripheral_terminate(&ppi->ppi_dev, 0);
330		/* fall throught */
331
332	case PPB_FORWARD_IDLE:
333		/* if can't negociate NIBBLE mode then try BYTE mode,
334		 * the peripheral may be a computer
335		 */
336		if ((ppb_1284_negociate(&ppi->ppi_dev,
337			ppi->ppi_mode = PPB_NIBBLE, 0))) {
338
339			/* XXX Wait 2 seconds to let the remote host some
340			 * time to terminate its interrupt
341			 */
342			tsleep(ppi, PPBPRI, "ppiread", 2*hz);
343
344			if ((error = ppb_1284_negociate(&ppi->ppi_dev,
345				ppi->ppi_mode = PPB_BYTE, 0)))
346				return (error);
347		}
348		break;
349
350	case PPB_REVERSE_IDLE:
351	case PPB_EPP_IDLE:
352	case PPB_ECP_FORWARD_IDLE:
353	default:
354		break;
355	}
356
357#ifdef DEBUG_1284
358	printf("N");
359#endif
360	/* read data */
361	len = 0;
362	while (uio->uio_resid) {
363		if ((error = ppb_1284_read(&ppi->ppi_dev, ppi->ppi_mode,
364			ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid),
365			&len))) {
366			goto error;
367		}
368
369		if (!len)
370			goto error;		/* no more data */
371
372#ifdef DEBUG_1284
373		printf("d");
374#endif
375		if ((error = uiomove(ppi->ppi_buffer, len, uio)))
376			goto error;
377	}
378
379error:
380
381#else /* PERIPH_1284 */
382	int error = ENODEV;
383#endif
384
385	return (error);
386}
387
388/*
389 * ppiwrite()
390 *
391 * IEEE1284 compliant write
392 *
393 * Actually, this is the peripheral side of a remote IEEE1284 read
394 *
395 * The first part of the negociation (IEEE1284 device detection) is
396 * done at interrupt level, then the remaining is done by the writing
397 * process
398 *
399 * Once negociation done, transfer data
400 */
401static int
402ppiwrite(dev_t dev, struct uio *uio, int ioflag)
403{
404#ifdef PERIPH_1284
405	u_int unit = minor(dev);
406	struct ppi_data *ppi = ppidata[unit];
407	struct ppb_data *ppb = ppi->ppi_dev.ppb;
408	int len, error = 0, sent;
409
410#if 0
411	int ret;
412
413	#define ADDRESS		MS_PARAM(0, 0, MS_TYP_PTR)
414	#define LENGTH		MS_PARAM(0, 1, MS_TYP_INT)
415
416	struct ppb_microseq msq[] = {
417		  { MS_OP_PUT, { MS_UNKNOWN, MS_UNKNOWN, MS_UNKNOWN } },
418		  MS_RET(0)
419	};
420
421	/* negociate ECP mode */
422	if (ppb_1284_negociate(&ppi->ppi_dev, PPB_ECP, 0)) {
423		printf("ppiwrite: ECP negociation failed\n");
424	}
425
426	while (!error && (len = min(uio->uio_resid, BUFSIZE))) {
427		uiomove(ppi->ppi_buffer, len, uio);
428
429		ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len);
430
431		error = ppb_MS_microseq(&ppi->ppi_dev, msq, &ret);
432	}
433#endif
434
435	/* we have to be peripheral to be able to send data, so
436	 * wait for the appropriate state
437	 */
438	if (ppb->state < PPB_PERIPHERAL_NEGOCIATION)
439		ppb_1284_terminate(&ppi->ppi_dev);
440
441	while (ppb->state != PPB_PERIPHERAL_IDLE) {
442		/* XXX should check a variable before sleeping */
443#ifdef DEBUG_1284
444		printf("s");
445#endif
446
447		ppi_enable_intr(ppi);
448
449		/* sleep until IEEE1284 negociation starts */
450		error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0);
451
452		switch (error) {
453		case 0:
454			/* negociate peripheral side with BYTE mode */
455			ppb_peripheral_negociate(&ppi->ppi_dev, PPB_BYTE, 0);
456			break;
457		case EWOULDBLOCK:
458			break;
459		default:
460			goto error;
461		}
462	}
463#ifdef DEBUG_1284
464	printf("N");
465#endif
466
467	/* negociation done, write bytes to master host */
468	while ((len = min(uio->uio_resid, BUFSIZE)) != 0) {
469		uiomove(ppi->ppi_buffer, len, uio);
470		if ((error = byte_peripheral_write(&ppi->ppi_dev,
471						ppi->ppi_buffer, len, &sent)))
472			goto error;
473#ifdef DEBUG_1284
474		printf("d");
475#endif
476	}
477
478error:
479
480#else /* PERIPH_1284 */
481	int error = ENODEV;
482#endif
483
484	return (error);
485}
486
487static int
488ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
489{
490	u_int unit = minor(dev);
491	struct ppi_data *ppi = ppidata[unit];
492	int error = 0;
493	u_int8_t *val = (u_int8_t *)data;
494
495	switch (cmd) {
496
497	case PPIGDATA:			/* get data register */
498		*val = ppb_rdtr(&ppi->ppi_dev);
499		break;
500	case PPIGSTATUS:		/* get status bits */
501		*val = ppb_rstr(&ppi->ppi_dev);
502		break;
503	case PPIGCTRL:			/* get control bits */
504		*val = ppb_rctr(&ppi->ppi_dev);
505		break;
506	case PPIGEPPD:			/* get EPP data bits */
507		*val = ppb_repp_D(&ppi->ppi_dev);
508		break;
509	case PPIGECR:			/* get ECP bits */
510		*val = ppb_recr(&ppi->ppi_dev);
511		break;
512	case PPIGFIFO:			/* read FIFO */
513		*val = ppb_rfifo(&ppi->ppi_dev);
514		break;
515
516	case PPISDATA:			/* set data register */
517		ppb_wdtr(&ppi->ppi_dev, *val);
518		break;
519	case PPISSTATUS:		/* set status bits */
520		ppb_wstr(&ppi->ppi_dev, *val);
521		break;
522	case PPISCTRL:			/* set control bits */
523		ppb_wctr(&ppi->ppi_dev, *val);
524		break;
525	case PPISEPPD:			/* set EPP data bits */
526		ppb_wepp_D(&ppi->ppi_dev, *val);
527		break;
528	case PPISECR:			/* set ECP bits */
529		ppb_wecr(&ppi->ppi_dev, *val);
530		break;
531	case PPISFIFO:			/* write FIFO */
532		ppb_wfifo(&ppi->ppi_dev, *val);
533		break;
534
535	case PPIGEPPA:			/* get EPP address bits */
536		*val = ppb_repp_A(&ppi->ppi_dev);
537		break;
538	case PPISEPPA:			/* set EPP address bits */
539		ppb_wepp_A(&ppi->ppi_dev, *val);
540		break;
541	default:
542		error = ENOTTY;
543		break;
544	}
545
546	return (error);
547}
548
549#endif /* NPPI */
550