xref: /freebsd-13-stable/sys/dev/ppbus/ppi.c (revision 3bc80996974a61a4223eae4c1ccd47b6ee32a48a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 1997, 1998, 1999 Nicolas Souchu, Michael Smith
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 #include "opt_ppb_1284.h"
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/module.h>
37 #include <sys/bus.h>
38 #include <sys/conf.h>
39 #include <sys/kernel.h>
40 #include <sys/lock.h>
41 #include <sys/sx.h>
42 #include <sys/uio.h>
43 #include <sys/fcntl.h>
44 
45 #include <machine/bus.h>
46 #include <machine/resource.h>
47 #include <sys/rman.h>
48 
49 #include <dev/ppbus/ppbconf.h>
50 #include <dev/ppbus/ppb_msq.h>
51 
52 #ifdef PERIPH_1284
53 #include <sys/malloc.h>
54 #include <dev/ppbus/ppb_1284.h>
55 #endif
56 
57 #include <dev/ppbus/ppi.h>
58 
59 #include "ppbus_if.h"
60 
61 #include <dev/ppbus/ppbio.h>
62 
63 #define BUFSIZE		512
64 
65 struct ppi_data {
66     device_t	ppi_device;
67     struct cdev *ppi_cdev;
68     struct sx	ppi_lock;
69     int		ppi_flags;
70 #define HAVE_PPBUS	(1<<0)
71 
72     int		ppi_mode;			/* IEEE1284 mode */
73     char	ppi_buffer[BUFSIZE];
74 
75 #ifdef PERIPH_1284
76     struct resource *intr_resource;	/* interrupt resource */
77     void *intr_cookie;			/* interrupt registration cookie */
78 #endif /* PERIPH_1284 */
79 };
80 
81 #define DEVTOSOFTC(dev) \
82 	((struct ppi_data *)device_get_softc(dev))
83 
84 static devclass_t ppi_devclass;
85 
86 #ifdef PERIPH_1284
87 static void	ppiintr(void *arg);
88 #endif
89 
90 static	d_open_t	ppiopen;
91 static	d_close_t	ppiclose;
92 static	d_ioctl_t	ppiioctl;
93 static	d_write_t	ppiwrite;
94 static	d_read_t	ppiread;
95 
96 static struct cdevsw ppi_cdevsw = {
97 	.d_version =	D_VERSION,
98 	.d_open =	ppiopen,
99 	.d_close =	ppiclose,
100 	.d_read =	ppiread,
101 	.d_write =	ppiwrite,
102 	.d_ioctl =	ppiioctl,
103 	.d_name =	"ppi",
104 };
105 
106 #ifdef PERIPH_1284
107 
108 static void
ppi_enable_intr(device_t ppidev)109 ppi_enable_intr(device_t ppidev)
110 {
111 	char r;
112 	device_t ppbus = device_get_parent(ppidev);
113 
114 	r = ppb_rctr(ppbus);
115 	ppb_wctr(ppbus, r | IRQENABLE);
116 
117 	return;
118 }
119 
120 static void
ppi_disable_intr(device_t ppidev)121 ppi_disable_intr(device_t ppidev)
122 {
123 	char r;
124 	device_t ppbus = device_get_parent(ppidev);
125 
126 	r = ppb_rctr(ppbus);
127 	ppb_wctr(ppbus, r & ~IRQENABLE);
128 
129 	return;
130 }
131 
132 #endif /* PERIPH_1284 */
133 
134 static void
ppi_identify(driver_t * driver,device_t parent)135 ppi_identify(driver_t *driver, device_t parent)
136 {
137 
138 	device_t dev;
139 
140 	dev = device_find_child(parent, "ppi", -1);
141 	if (!dev)
142 		BUS_ADD_CHILD(parent, 0, "ppi", -1);
143 }
144 
145 /*
146  * ppi_probe()
147  */
148 static int
ppi_probe(device_t dev)149 ppi_probe(device_t dev)
150 {
151 	/* probe is always ok */
152 	device_set_desc(dev, "Parallel I/O");
153 
154 	return (0);
155 }
156 
157 /*
158  * ppi_attach()
159  */
160 static int
ppi_attach(device_t dev)161 ppi_attach(device_t dev)
162 {
163 	struct ppi_data *ppi = DEVTOSOFTC(dev);
164 #ifdef PERIPH_1284
165 	int error, rid = 0;
166 
167 	/* declare our interrupt handler */
168 	ppi->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
169 	    RF_ACTIVE);
170 	if (ppi->intr_resource) {
171 		/* register our interrupt handler */
172 		error = bus_setup_intr(dev, ppi->intr_resource,
173 		    INTR_TYPE_TTY | INTR_MPSAFE, NULL, ppiintr, dev,
174 		    &ppi->intr_cookie);
175 		if (error) {
176 			bus_release_resource(dev, SYS_RES_IRQ, rid,
177 			    ppi->intr_resource);
178 			device_printf(dev,
179 			    "Unable to register interrupt handler\n");
180 			return (error);
181 		}
182 	}
183 #endif /* PERIPH_1284 */
184 
185 	sx_init(&ppi->ppi_lock, "ppi");
186 	ppi->ppi_cdev = make_dev(&ppi_cdevsw, device_get_unit(dev),
187 		 UID_ROOT, GID_WHEEL,
188 		 0600, "ppi%d", device_get_unit(dev));
189 	if (ppi->ppi_cdev == NULL) {
190 		device_printf(dev, "Failed to create character device\n");
191 		return (ENXIO);
192 	}
193 	ppi->ppi_cdev->si_drv1 = ppi;
194 	ppi->ppi_device = dev;
195 
196 	return (0);
197 }
198 
199 static int
ppi_detach(device_t dev)200 ppi_detach(device_t dev)
201 {
202 	struct ppi_data *ppi = DEVTOSOFTC(dev);
203 
204 	destroy_dev(ppi->ppi_cdev);
205 #ifdef PERIPH_1284
206 	if (ppi->intr_resource != NULL) {
207 		bus_teardown_intr(dev, ppi->intr_resource, ppi->intr_cookie);
208 		bus_release_resource(dev, SYS_RES_IRQ, 0, ppi->intr_resource);
209 	}
210 #endif
211 	sx_destroy(&ppi->ppi_lock);
212 	return (0);
213 }
214 
215 #ifdef PERIPH_1284
216 /*
217  * Cable
218  * -----
219  *
220  * Use an IEEE1284 compliant (DB25/DB25) cable with the following tricks:
221  *
222  * nStrobe   <-> nAck		1  <-> 10
223  * nAutofd   <-> Busy		11 <-> 14
224  * nSelectin <-> Select		17 <-> 13
225  * nInit     <-> nFault		15 <-> 16
226  *
227  */
228 static void
ppiintr(void * arg)229 ppiintr(void *arg)
230 {
231 	device_t ppidev = (device_t)arg;
232 	device_t ppbus = device_get_parent(ppidev);
233 	struct ppi_data *ppi = DEVTOSOFTC(ppidev);
234 
235 	ppb_assert_locked(ppbus);
236 	ppi_disable_intr(ppidev);
237 
238 	switch (ppb_1284_get_state(ppbus)) {
239 	/* accept IEEE1284 negotiation then wakeup a waiting process to
240 	 * continue negotiation at process level */
241 	case PPB_FORWARD_IDLE:
242 		/* Event 1 */
243 		if ((ppb_rstr(ppbus) & (SELECT | nBUSY)) ==
244 							(SELECT | nBUSY)) {
245 			/* IEEE1284 negotiation */
246 #ifdef DEBUG_1284
247 			printf("N");
248 #endif
249 
250 			/* Event 2 - prepare for reading the ext. value */
251 			ppb_wctr(ppbus, (PCD | STROBE | nINIT) & ~SELECTIN);
252 
253 			ppb_1284_set_state(ppbus, PPB_NEGOCIATION);
254 
255 		} else {
256 #ifdef DEBUG_1284
257 			printf("0x%x", ppb_rstr(ppbus));
258 #endif
259 			ppb_peripheral_terminate(ppbus, PPB_DONTWAIT);
260 			break;
261 		}
262 
263 		/* wake up any process waiting for negotiation from
264 		 * remote master host */
265 
266 		/* XXX should set a variable to warn the process about
267 		 * the interrupt */
268 
269 		wakeup(ppi);
270 		break;
271 	default:
272 #ifdef DEBUG_1284
273 		printf("?%d", ppb_1284_get_state(ppbus));
274 #endif
275 		ppb_1284_set_state(ppbus, PPB_FORWARD_IDLE);
276 		ppb_set_mode(ppbus, PPB_COMPATIBLE);
277 		break;
278 	}
279 
280 	ppi_enable_intr(ppidev);
281 
282 	return;
283 }
284 #endif /* PERIPH_1284 */
285 
286 static int
ppiopen(struct cdev * dev,int flags,int fmt,struct thread * td)287 ppiopen(struct cdev *dev, int flags, int fmt, struct thread *td)
288 {
289 	struct ppi_data *ppi = dev->si_drv1;
290 	device_t ppidev = ppi->ppi_device;
291 	device_t ppbus = device_get_parent(ppidev);
292 	int res;
293 
294 	sx_xlock(&ppi->ppi_lock);
295 	if (!(ppi->ppi_flags & HAVE_PPBUS)) {
296 		ppb_lock(ppbus);
297 		res = ppb_request_bus(ppbus, ppidev,
298 		    (flags & O_NONBLOCK) ? PPB_DONTWAIT : PPB_WAIT | PPB_INTR);
299 		ppb_unlock(ppbus);
300 		if (res) {
301 			sx_xunlock(&ppi->ppi_lock);
302 			return (res);
303 		}
304 
305 		ppi->ppi_flags |= HAVE_PPBUS;
306 	}
307 	sx_xunlock(&ppi->ppi_lock);
308 
309 	return (0);
310 }
311 
312 static int
ppiclose(struct cdev * dev,int flags,int fmt,struct thread * td)313 ppiclose(struct cdev *dev, int flags, int fmt, struct thread *td)
314 {
315 	struct ppi_data *ppi = dev->si_drv1;
316 	device_t ppidev = ppi->ppi_device;
317 	device_t ppbus = device_get_parent(ppidev);
318 
319 	sx_xlock(&ppi->ppi_lock);
320 	ppb_lock(ppbus);
321 #ifdef PERIPH_1284
322 	switch (ppb_1284_get_state(ppbus)) {
323 	case PPB_PERIPHERAL_IDLE:
324 		ppb_peripheral_terminate(ppbus, 0);
325 		break;
326 	case PPB_REVERSE_IDLE:
327 	case PPB_EPP_IDLE:
328 	case PPB_ECP_FORWARD_IDLE:
329 	default:
330 		ppb_1284_terminate(ppbus);
331 		break;
332 	}
333 #endif /* PERIPH_1284 */
334 
335 	/* unregistration of interrupt forced by release */
336 	ppb_release_bus(ppbus, ppidev);
337 	ppb_unlock(ppbus);
338 
339 	ppi->ppi_flags &= ~HAVE_PPBUS;
340 	sx_xunlock(&ppi->ppi_lock);
341 
342 	return (0);
343 }
344 
345 /*
346  * ppiread()
347  *
348  * IEEE1284 compliant read.
349  *
350  * First, try negotiation to BYTE then NIBBLE mode
351  * If no data is available, wait for it otherwise transfer as much as possible
352  */
353 static int
ppiread(struct cdev * dev,struct uio * uio,int ioflag)354 ppiread(struct cdev *dev, struct uio *uio, int ioflag)
355 {
356 #ifdef PERIPH_1284
357 	struct ppi_data *ppi = dev->si_drv1;
358 	device_t ppidev = ppi->ppi_device;
359 	device_t ppbus = device_get_parent(ppidev);
360 	int len, error = 0;
361 	char *buffer;
362 
363 	buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
364 
365 	ppb_lock(ppbus);
366 	switch (ppb_1284_get_state(ppbus)) {
367 	case PPB_PERIPHERAL_IDLE:
368 		ppb_peripheral_terminate(ppbus, 0);
369 		/* FALLTHROUGH */
370 
371 	case PPB_FORWARD_IDLE:
372 		/* if can't negotiate NIBBLE mode then try BYTE mode,
373 		 * the peripheral may be a computer
374 		 */
375 		if ((ppb_1284_negociate(ppbus,
376 			ppi->ppi_mode = PPB_NIBBLE, 0))) {
377 			/* XXX Wait 2 seconds to let the remote host some
378 			 * time to terminate its interrupt
379 			 */
380 			ppb_sleep(ppbus, ppi, PPBPRI, "ppiread", 2 * hz);
381 
382 			if ((error = ppb_1284_negociate(ppbus,
383 			    ppi->ppi_mode = PPB_BYTE, 0))) {
384 				ppb_unlock(ppbus);
385 				free(buffer, M_DEVBUF);
386 				return (error);
387 			}
388 		}
389 		break;
390 
391 	case PPB_REVERSE_IDLE:
392 	case PPB_EPP_IDLE:
393 	case PPB_ECP_FORWARD_IDLE:
394 	default:
395 		break;
396 	}
397 
398 #ifdef DEBUG_1284
399 	printf("N");
400 #endif
401 	/* read data */
402 	len = 0;
403 	while (uio->uio_resid) {
404 		error = ppb_1284_read(ppbus, ppi->ppi_mode,
405 		    buffer, min(BUFSIZE, uio->uio_resid), &len);
406 		ppb_unlock(ppbus);
407 		if (error)
408 			goto error;
409 
410 		if (!len)
411 			goto error;		/* no more data */
412 
413 #ifdef DEBUG_1284
414 		printf("d");
415 #endif
416 		if ((error = uiomove(buffer, len, uio)))
417 			goto error;
418 		ppb_lock(ppbus);
419 	}
420 	ppb_unlock(ppbus);
421 
422 error:
423 	free(buffer, M_DEVBUF);
424 #else /* PERIPH_1284 */
425 	int error = ENODEV;
426 #endif
427 
428 	return (error);
429 }
430 
431 /*
432  * ppiwrite()
433  *
434  * IEEE1284 compliant write
435  *
436  * Actually, this is the peripheral side of a remote IEEE1284 read
437  *
438  * The first part of the negotiation (IEEE1284 device detection) is
439  * done at interrupt level, then the remaining is done by the writing
440  * process
441  *
442  * Once negotiation done, transfer data
443  */
444 static int
ppiwrite(struct cdev * dev,struct uio * uio,int ioflag)445 ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
446 {
447 #ifdef PERIPH_1284
448 	struct ppi_data *ppi = dev->si_drv1;
449 	device_t ppidev = ppi->ppi_device;
450 	device_t ppbus = device_get_parent(ppidev);
451 	int len, error = 0, sent;
452 	char *buffer;
453 
454 #if 0
455 	int ret;
456 
457 	#define ADDRESS		MS_PARAM(0, 0, MS_TYP_PTR)
458 	#define LENGTH		MS_PARAM(0, 1, MS_TYP_INT)
459 
460 	struct ppb_microseq msq[] = {
461 		  { MS_OP_PUT, { MS_UNKNOWN, MS_UNKNOWN, MS_UNKNOWN } },
462 		  MS_RET(0)
463 	};
464 
465 	buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
466 	ppb_lock(ppbus);
467 
468 	/* negotiate ECP mode */
469 	if (ppb_1284_negociate(ppbus, PPB_ECP, 0)) {
470 		printf("ppiwrite: ECP negotiation failed\n");
471 	}
472 
473 	while (!error && (len = min(uio->uio_resid, BUFSIZE))) {
474 		ppb_unlock(ppbus);
475 		uiomove(buffer, len, uio);
476 
477 		ppb_MS_init_msq(msq, 2, ADDRESS, buffer, LENGTH, len);
478 
479 		ppb_lock(ppbus);
480 		error = ppb_MS_microseq(ppbus, msq, &ret);
481 	}
482 #else
483 	buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
484 	ppb_lock(ppbus);
485 #endif
486 
487 	/* we have to be peripheral to be able to send data, so
488 	 * wait for the appropriate state
489 	 */
490  	if (ppb_1284_get_state(ppbus) < PPB_PERIPHERAL_NEGOCIATION)
491 		ppb_1284_terminate(ppbus);
492 
493  	while (ppb_1284_get_state(ppbus) != PPB_PERIPHERAL_IDLE) {
494 		/* XXX should check a variable before sleeping */
495 #ifdef DEBUG_1284
496 		printf("s");
497 #endif
498 
499 		ppi_enable_intr(ppidev);
500 
501 		/* sleep until IEEE1284 negotiation starts */
502 		error = ppb_sleep(ppbus, ppi, PCATCH | PPBPRI, "ppiwrite", 0);
503 
504 		switch (error) {
505 		case 0:
506 			/* negotiate peripheral side with BYTE mode */
507 			ppb_peripheral_negociate(ppbus, PPB_BYTE, 0);
508 			break;
509 		case EWOULDBLOCK:
510 			break;
511 		default:
512 			goto error;
513 		}
514 	}
515 #ifdef DEBUG_1284
516 	printf("N");
517 #endif
518 
519 	/* negotiation done, write bytes to master host */
520 	while ((len = min(uio->uio_resid, BUFSIZE)) != 0) {
521 		ppb_unlock(ppbus);
522 		uiomove(buffer, len, uio);
523 		ppb_lock(ppbus);
524 		if ((error = byte_peripheral_write(ppbus,
525 						buffer, len, &sent)))
526 			goto error;
527 #ifdef DEBUG_1284
528 		printf("d");
529 #endif
530 	}
531 
532 error:
533 	ppb_unlock(ppbus);
534 	free(buffer, M_DEVBUF);
535 #else /* PERIPH_1284 */
536 	int error = ENODEV;
537 #endif
538 
539 	return (error);
540 }
541 
542 static int
ppiioctl(struct cdev * dev,u_long cmd,caddr_t data,int flags,struct thread * td)543 ppiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td)
544 {
545 	struct ppi_data *ppi = dev->si_drv1;
546 	device_t ppidev = ppi->ppi_device;
547 	device_t ppbus = device_get_parent(ppidev);
548 	int error = 0;
549 	u_int8_t *val = (u_int8_t *)data;
550 
551 	ppb_lock(ppbus);
552 	switch (cmd) {
553 	case PPIGDATA:			/* get data register */
554 		*val = ppb_rdtr(ppbus);
555 		break;
556 	case PPIGSTATUS:		/* get status bits */
557 		*val = ppb_rstr(ppbus);
558 		break;
559 	case PPIGCTRL:			/* get control bits */
560 		*val = ppb_rctr(ppbus);
561 		break;
562 	case PPIGEPPD:			/* get EPP data bits */
563 		*val = ppb_repp_D(ppbus);
564 		break;
565 	case PPIGECR:			/* get ECP bits */
566 		*val = ppb_recr(ppbus);
567 		break;
568 	case PPIGFIFO:			/* read FIFO */
569 		*val = ppb_rfifo(ppbus);
570 		break;
571 	case PPISDATA:			/* set data register */
572 		ppb_wdtr(ppbus, *val);
573 		break;
574 	case PPISSTATUS:		/* set status bits */
575 		ppb_wstr(ppbus, *val);
576 		break;
577 	case PPISCTRL:			/* set control bits */
578 		ppb_wctr(ppbus, *val);
579 		break;
580 	case PPISEPPD:			/* set EPP data bits */
581 		ppb_wepp_D(ppbus, *val);
582 		break;
583 	case PPISECR:			/* set ECP bits */
584 		ppb_wecr(ppbus, *val);
585 		break;
586 	case PPISFIFO:			/* write FIFO */
587 		ppb_wfifo(ppbus, *val);
588 		break;
589 	case PPIGEPPA:			/* get EPP address bits */
590 		*val = ppb_repp_A(ppbus);
591 		break;
592 	case PPISEPPA:			/* set EPP address bits */
593 		ppb_wepp_A(ppbus, *val);
594 		break;
595 	default:
596 		error = ENOTTY;
597 		break;
598 	}
599 	ppb_unlock(ppbus);
600 
601 	return (error);
602 }
603 
604 static device_method_t ppi_methods[] = {
605 	/* device interface */
606 	DEVMETHOD(device_identify,	ppi_identify),
607 	DEVMETHOD(device_probe,		ppi_probe),
608 	DEVMETHOD(device_attach,	ppi_attach),
609 	DEVMETHOD(device_detach,	ppi_detach),
610 	{ 0, 0 }
611 };
612 
613 static driver_t ppi_driver = {
614 	"ppi",
615 	ppi_methods,
616 	sizeof(struct ppi_data),
617 };
618 DRIVER_MODULE(ppi, ppbus, ppi_driver, ppi_devclass, 0, 0);
619 MODULE_DEPEND(ppi, ppbus, 1, 1, 1);
620