xref: /netbsd-src/sys/arch/sgimips/hpc/pi1ppc.c (revision fa98a90b9b574fe19ee98a773165ae2a94acd8da)
1 /* $NetBSD: pi1ppc.c,v 1.17 2022/11/01 19:45:35 andvar Exp $ */
2 
3 /*
4  * Copyright (c) 2001 Alcove - Nicolas Souchu
5  * Copyright (c) 2003, 2004 Gary Thorpe <gathorpe@users.sourceforge.net>
6  * Copyright (c) 2005 Joe Britt <britt@danger.com> - SGI PI1 version
7  * All rights reserved.
8  *
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * FreeBSD: src/sys/isa/ppc.c,v 1.26.2.5 2001/10/02 05:21:45 nsouch Exp
32  *
33  */
34 
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: pi1ppc.c,v 1.17 2022/11/01 19:45:35 andvar Exp $");
37 
38 #include "opt_pi1ppc.h"
39 
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/kernel.h>
43 #include <sys/kmem.h>
44 #include <sys/device.h>
45 #include <sys/systm.h>
46 
47 #include <sys/bus.h>
48 /*#include <machine/intr.h>*/
49 
50 #include <dev/ppbus/ppbus_conf.h>
51 #include <dev/ppbus/ppbus_msq.h>
52 #include <dev/ppbus/ppbus_io.h>
53 #include <dev/ppbus/ppbus_var.h>
54 
55 #include <machine/autoconf.h>
56 #include <machine/machtype.h>
57 
58 #include <sgimips/ioc/iocreg.h>
59 
60 #include <sgimips/hpc/hpcvar.h>
61 #include <sgimips/hpc/hpcreg.h>
62 
63 #include <sgimips/hpc/pi1ppcreg.h>
64 #include <sgimips/hpc/pi1ppcvar.h>
65 
66 #ifdef PI1PPC_DEBUG
67 int pi1ppc_debug = 1;
68 #endif
69 
70 #ifdef PI1PPC_VERBOSE
71 int pi1ppc_verbose = 1;
72 #endif
73 
74 /* Prototypes for functions. */
75 
76 /* PC-style register emulation */
77 static uint8_t r_reg(int reg, struct pi1ppc_softc *pi1ppc);
78 static void w_reg(int reg, struct pi1ppc_softc *pi1ppc, uint8_t byte);
79 
80 #define	AT_DATA_REG	0
81 #define	AT_STAT_REG	1
82 #define	AT_CTL_REG	2
83 
84 #define pi1ppc_r_str(_x)	r_reg(AT_STAT_REG,_x)
85 #define	pi1ppc_r_ctr(_x)	r_reg(AT_CTL_REG,_x)
86 #define	pi1ppc_r_dtr(_x)	r_reg(AT_DATA_REG,_x)
87 
88 #define	pi1ppc_w_str(_x,_y)
89 #define	pi1ppc_w_ctr(_x,_y)	w_reg(AT_CTL_REG,_x,_y)
90 #define	pi1ppc_w_dtr(_x,_y)	w_reg(AT_DATA_REG,_x,_y)
91 
92 /* do we need to do these? */
93 #define	pi1ppc_barrier_r(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \
94 					0,4,BUS_SPACE_BARRIER_READ)
95 #define	pi1ppc_barrier_w(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \
96 					0,4,BUS_SPACE_BARRIER_WRITE)
97 #define	pi1ppc_barrier(_x)  pi1ppc_barrier_r(_x)
98 
99 /* Print function for config_found() */
100 static int pi1ppc_print(void *, const char *);
101 
102 /* Routines for ppbus interface (bus + device) */
103 static int pi1ppc_read(device_t, char *, int, int, size_t *);
104 static int pi1ppc_write(device_t, char *, int, int, size_t *);
105 static int pi1ppc_setmode(device_t, int);
106 static int pi1ppc_getmode(device_t);
107 static int pi1ppc_exec_microseq(device_t, struct ppbus_microseq * *);
108 static uint8_t pi1ppc_io(device_t, int, u_char *, int, u_char);
109 static int pi1ppc_read_ivar(device_t, int, unsigned int *);
110 static int pi1ppc_write_ivar(device_t, int, unsigned int *);
111 static int pi1ppc_add_handler(device_t, void (*)(void *), void *);
112 static int pi1ppc_remove_handler(device_t, void (*)(void *));
113 
114 /* no-ops, do any IOC machines have ECP/EPP-capable ports? */
115 static void pi1ppc_reset_epp_timeout(device_t);
116 static void pi1ppc_ecp_sync(device_t);
117 
118 /* Utility functions */
119 
120 /* Functions to read bytes into device's input buffer */
121 static void pi1ppc_nibble_read(struct pi1ppc_softc * const);
122 static void pi1ppc_byte_read(struct pi1ppc_softc * const);
123 
124 /* Functions to write bytes to device's output buffer */
125 static void pi1ppc_std_write(struct pi1ppc_softc * const);
126 
127 /* Miscellaneous */
128 static void pi1ppc_set_intr_mask(struct pi1ppc_softc * const, uint8_t);
129 static uint8_t pi1ppc_get_intr_stat(struct pi1ppc_softc * const);
130 
131 #ifdef USE_INDY_ACK_HACK
132 static uint8_t pi1ppc_get_intr_mask(struct pi1ppc_softc * const);
133 #endif
134 
135 static int pi1ppc_poll_str(struct pi1ppc_softc * const, const uint8_t,
136 	const uint8_t);
137 static int pi1ppc_wait_interrupt(struct pi1ppc_softc * const, kcondvar_t *,
138 	const uint8_t);
139 
140 static int pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const,
141 	const uint8_t);
142 
143 static int pi1ppc_match(device_t parent, cfdata_t match, void *aux);
144 static void pi1ppc_attach(device_t parent, device_t self, void *aux);
145 
146 CFATTACH_DECL_NEW(pi1ppc, sizeof(struct pi1ppc_softc),
147 				pi1ppc_match,
148 				pi1ppc_attach,
149 				NULL,
150 				NULL);
151 
152 /* Currently only matching on Indy, though I think the Indigo1 also
153    uses PI1.  If it does, then the driver should work (if it is attached
154    at the appropriate base addr).
155  */
156 
157 static int
pi1ppc_match(device_t parent,cfdata_t match,void * aux)158 pi1ppc_match(device_t parent, cfdata_t match, void *aux)
159 {
160 	struct hpc_attach_args *ha = aux;
161 
162 	if (strcmp(ha->ha_name, match->cf_name) != 0)
163 		return 0;
164 
165 	if (mach_type == MACH_SGI_IP22)
166 		return 1;
167 
168 	return 0;
169 }
170 
171 static void
pi1ppc_attach(device_t parent,device_t self,void * aux)172 pi1ppc_attach(device_t parent, device_t self, void *aux)
173 {
174 	struct pi1ppc_softc *sc;
175 	struct hpc_attach_args *haa;
176 
177 	sc = device_private(self);
178 	sc->sc_dev = self;
179 	haa = aux;
180 	sc->sc_iot = haa->ha_st;
181 
182 	if (bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff,
183 			0x28, 		/* # bytes in par port regs */
184 			&sc->sc_ioh)) {
185 		aprint_error(": unable to map control registers\n");
186 		return;
187 	}
188 
189 	pi1ppc_sc_attach(sc);
190 }
191 
192 /*
193  * Generic attach and detach functions for pi1ppc device.
194  *
195  * If sc_dev_ok in soft configuration data is not ATPPC_ATTACHED, these should
196  * be skipped altogether.
197  */
198 
199 /* Soft configuration attach for pi1ppc */
200 void
pi1ppc_sc_attach(struct pi1ppc_softc * lsc)201 pi1ppc_sc_attach(struct pi1ppc_softc *lsc)
202 {
203 	/* Adapter used to configure ppbus device */
204 	struct parport_adapter sc_parport_adapter;
205 	char buf[64];
206 
207 	/* For a PC, this is where the installed chipset is probed.
208 	 * We *know* what we have, no need to probe.
209 	 */
210 	lsc->sc_type = PI1PPC_TYPE_INDY;
211 	lsc->sc_model = GENERIC;
212 
213 	/* XXX Once we support Interrupts & DMA, update this */
214 	lsc->sc_has = PI1PPC_HAS_PS2;
215 
216 	mutex_init(&lsc->sc_lock, MUTEX_DEFAULT, IPL_TTY);
217 	cv_init(&lsc->sc_in_cv, "pi1ppcin");
218 	cv_init(&lsc->sc_out_cv, "pi1ppcou");
219 
220         /* Print out chipset capabilities */
221 	snprintb(buf, sizeof(buf), "\20\1INTR\2DMA\3FIFO\4PS2\5ECP\6EPP",
222 	    lsc->sc_has);
223 	printf("\n%s: capabilities=%s\n", device_xname(lsc->sc_dev), buf);
224 
225 	/* Initialize device's buffer pointers */
226 	lsc->sc_outb = lsc->sc_outbstart = lsc->sc_inb = lsc->sc_inbstart
227 		= NULL;
228 	lsc->sc_inb_nbytes = lsc->sc_outb_nbytes = 0;
229 
230 	/* Last configuration step: set mode to standard mode */
231 	if (pi1ppc_setmode(lsc->sc_dev, PPBUS_COMPATIBLE) != 0) {
232 		PI1PPC_DPRINTF(("%s: unable to initialize mode.\n",
233                    device_xname(lsc->sc_dev)));
234 	}
235 
236 	/* Set up parport_adapter structure */
237 
238 	/* Set capabilities */
239 	sc_parport_adapter.capabilities = 0;
240 	if (lsc->sc_has & PI1PPC_HAS_INTR) {
241 		sc_parport_adapter.capabilities |= PPBUS_HAS_INTR;
242 	}
243 	if (lsc->sc_has & PI1PPC_HAS_DMA) {
244 		sc_parport_adapter.capabilities |= PPBUS_HAS_DMA;
245 	}
246 	if (lsc->sc_has & PI1PPC_HAS_FIFO) {
247 		sc_parport_adapter.capabilities |= PPBUS_HAS_FIFO;
248 	}
249 	if (lsc->sc_has & PI1PPC_HAS_PS2) {
250 		sc_parport_adapter.capabilities |= PPBUS_HAS_PS2;
251 	}
252 
253 	/* Set function pointers */
254 	sc_parport_adapter.parport_io = pi1ppc_io;
255 	sc_parport_adapter.parport_exec_microseq = pi1ppc_exec_microseq;
256 	sc_parport_adapter.parport_setmode = pi1ppc_setmode;
257 	sc_parport_adapter.parport_getmode = pi1ppc_getmode;
258 	sc_parport_adapter.parport_read = pi1ppc_read;
259 	sc_parport_adapter.parport_write = pi1ppc_write;
260 	sc_parport_adapter.parport_read_ivar = pi1ppc_read_ivar;
261 	sc_parport_adapter.parport_write_ivar = pi1ppc_write_ivar;
262 	sc_parport_adapter.parport_dma_malloc = lsc->sc_dma_malloc;
263 	sc_parport_adapter.parport_dma_free = lsc->sc_dma_free;
264 	sc_parport_adapter.parport_add_handler = pi1ppc_add_handler;
265 	sc_parport_adapter.parport_remove_handler = pi1ppc_remove_handler;
266 
267 	/* these are no-ops (does later machines have ECP/EPP support?) */
268 	sc_parport_adapter.parport_ecp_sync = pi1ppc_ecp_sync;
269 	sc_parport_adapter.parport_reset_epp_timeout =
270 		pi1ppc_reset_epp_timeout;
271 
272 	/* Initialize handler list, may be added to by grandchildren */
273 	SLIST_INIT(&(lsc->sc_handler_listhead));
274 
275 	/* Initialize interrupt state */
276 	lsc->sc_irqstat = PI1PPC_IRQ_NONE;
277 	lsc->sc_ecr_intr = lsc->sc_ctr_intr = lsc->sc_str_intr = 0;
278 
279 	/* Disable DMA/interrupts (each ppbus driver selects usage itself) */
280 	lsc->sc_use = 0;
281 
282 	/* Configure child of the device. */
283 	lsc->child = config_found(lsc->sc_dev, &(sc_parport_adapter),
284 		pi1ppc_print, CFARGS_NONE);
285 
286 	return;
287 }
288 
289 /* Soft configuration detach */
290 int
pi1ppc_sc_detach(struct pi1ppc_softc * lsc,int flag)291 pi1ppc_sc_detach(struct pi1ppc_softc *lsc, int flag)
292 {
293 	device_t dev = lsc->sc_dev;
294 
295 	/* Detach children devices */
296 	if (config_detach(lsc->child, flag) && !(flag & DETACH_QUIET)) {
297 		printf("%s not able to detach child device, ", device_xname(dev));
298 
299 		if (!(flag & DETACH_FORCE)) {
300 			printf("cannot detach\n");
301 			return 1;
302 		} else {
303 			printf("continuing (DETACH_FORCE)\n");
304 		}
305 	}
306 	if (!(flag & DETACH_QUIET))
307 		printf("%s detached", device_xname(dev));
308 
309 	mutex_destroy(&lsc->sc_lock);
310 	cv_destroy(&lsc->sc_in_cv);
311 	cv_destroy(&lsc->sc_out_cv);
312 	return 0;
313 }
314 
315 /* Used by config_found() to print out device information */
316 static int
pi1ppc_print(void * aux,const char * name)317 pi1ppc_print(void *aux, const char *name)
318 {
319 	/* Print out something on failure. */
320 	if (name != NULL) {
321 		printf("%s: child devices", name);
322 		return UNCONF;
323 	}
324 
325 	return QUIET;
326 }
327 
328 /* Interrupt handler for pi1ppc device: wakes up read/write functions */
329 int
pi1ppcintr(void * arg)330 pi1ppcintr(void *arg)
331 {
332 /* NO INTERRUPTS YET */
333 #if 0
334 	device_t dev = arg;
335 	struct pi1ppc_softc *pi1ppc = device_private(dev);
336 	int claim = 1;
337 	enum { NONE, READER, WRITER } wake_up = NONE;
338 
339 	PI1PPC_LOCK(pi1ppc);
340 
341 	/* Record registers' status */
342 	pi1ppc->sc_str_intr = pi1ppc_r_str(pi1ppc);
343 	pi1ppc->sc_ctr_intr = pi1ppc_r_ctr(pi1ppc);
344 	pi1ppc_barrier_r(pi1ppc);
345 
346 	/* Determine cause of interrupt and wake up top half */
347 	switch (atppc->sc_mode) {
348 	case ATPPC_MODE_STD:
349 		/* nAck pulsed for 5 usec, too fast to check reliably, assume */
350 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
351 		if (atppc->sc_outb)
352 			wake_up = WRITER;
353 		else
354 			claim = 0;
355 		break;
356 
357 	case ATPPC_MODE_NIBBLE:
358 	case ATPPC_MODE_PS2:
359 		/* nAck is set low by device and then high on ack */
360 		if (!(atppc->sc_str_intr & nACK)) {
361 			claim = 0;
362 			break;
363 		}
364 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
365 		if (atppc->sc_inb)
366 			wake_up = READER;
367 		break;
368 
369 	case ATPPC_MODE_ECP:
370 	case ATPPC_MODE_FAST:
371 		/* Confirm interrupt cause: these are not pulsed as in nAck. */
372 		if (atppc->sc_ecr_intr & ATPPC_SERVICE_INTR) {
373 			if (atppc->sc_ecr_intr & ATPPC_ENABLE_DMA)
374 				atppc->sc_irqstat |= ATPPC_IRQ_DMA;
375 			else
376 				atppc->sc_irqstat |= ATPPC_IRQ_FIFO;
377 
378 			/* Decide where top half will be waiting */
379 			if (atppc->sc_mode & ATPPC_MODE_ECP) {
380 				if (atppc->sc_ctr_intr & PCD) {
381 					if (atppc->sc_inb)
382 						wake_up = READER;
383 					else
384 						claim = 0;
385 				} else {
386 					if (atppc->sc_outb)
387 						wake_up = WRITER;
388 					else
389 						claim = 0;
390 				}
391 			} else {
392 				if (atppc->sc_outb)
393 					wake_up = WRITER;
394 				else
395 					claim = 0;
396 			}
397 		}
398 		/* Determine if nFault has occurred */
399 		if ((atppc->sc_mode & ATPPC_MODE_ECP) &&
400 			(atppc->sc_ecr_intr & ATPPC_nFAULT_INTR) &&
401 			!(atppc->sc_str_intr & nFAULT)) {
402 
403 			/* Device is requesting the channel */
404 			atppc->sc_irqstat |= ATPPC_IRQ_nFAULT;
405 			claim = 1;
406 		}
407 		break;
408 
409 	case ATPPC_MODE_EPP:
410 		/* nAck pulsed for 5 usec, too fast to check reliably */
411 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
412 		if (atppc->sc_inb)
413 			wake_up = WRITER;
414 		else if (atppc->sc_outb)
415 			wake_up = READER;
416 		else
417 			claim = 0;
418 		break;
419 
420 	default:
421 		panic("%s: chipset is in invalid mode.", device_xname(dev));
422 	}
423 
424 	if (claim) {
425 		switch (wake_up) {
426 		case NONE:
427 			break;
428 
429 		case READER:
430 			cv_broadcast(atppc->sc_in_cv);
431 			break;
432 
433 		case WRITER:
434 			cv_broadcast(atppc->sc_out_cv);
435 			break;
436 		}
437 	}
438 
439 	/* Call all of the installed handlers */
440 	if (claim) {
441 		struct atppc_handler_node * callback;
442 		SLIST_FOREACH(callback, &(atppc->sc_handler_listhead),
443 			entries) {
444 				(*callback->func)(callback->arg);
445 		}
446 	}
447 	PI1PPC_UNLOCK(atppc);
448 
449 	return claim;
450 #else
451 	return 0;		/* NO INTERRUPTS YET */
452 #endif
453 }
454 
455 /* Functions which support ppbus interface */
456 
457 static void
pi1ppc_reset_epp_timeout(device_t dev)458 pi1ppc_reset_epp_timeout(device_t dev)
459 {
460 	return;
461 }
462 
463 /* Read from pi1ppc device: returns 0 on success. */
464 static int
pi1ppc_read(device_t dev,char * buf,int len,int ioflag,size_t * cnt)465 pi1ppc_read(device_t dev, char *buf, int len, int ioflag,
466 	size_t *cnt)
467 {
468 	struct pi1ppc_softc *pi1ppc = device_private(dev);
469 	int error = 0;
470 
471 	PI1PPC_LOCK(pi1ppc);
472 
473 	*cnt = 0;
474 
475 	/* Initialize buffer */
476 	pi1ppc->sc_inb = pi1ppc->sc_inbstart = buf;
477 	pi1ppc->sc_inb_nbytes = len;
478 
479 	/* Initialize device input error state for new operation */
480 	pi1ppc->sc_inerr = 0;
481 
482 	/* Call appropriate function to read bytes */
483 	switch(pi1ppc->sc_mode) {
484 	case PI1PPC_MODE_STD:
485 		error = ENODEV;
486 		break;
487 
488 	case PI1PPC_MODE_NIBBLE:
489 		pi1ppc_nibble_read(pi1ppc);
490 		break;
491 
492 	case PI1PPC_MODE_PS2:
493 		pi1ppc_byte_read(pi1ppc);
494 		break;
495 
496 	default:
497 		panic("%s(%s): chipset in invalid mode.\n", __func__,
498                       device_xname(dev));
499 	}
500 
501 	/* Update counter*/
502 	*cnt = (pi1ppc->sc_inbstart - pi1ppc->sc_inb);
503 
504 	/* Reset buffer */
505 	pi1ppc->sc_inb = pi1ppc->sc_inbstart = NULL;
506 	pi1ppc->sc_inb_nbytes = 0;
507 
508 	if (!(error))
509 		error = pi1ppc->sc_inerr;
510 
511 	PI1PPC_UNLOCK(pi1ppc);
512 
513 	return (error);
514 }
515 
516 /* Write to pi1ppc device: returns 0 on success. */
517 static int
pi1ppc_write(device_t dev,char * buf,int len,int ioflag,size_t * cnt)518 pi1ppc_write(device_t dev, char *buf, int len, int ioflag, size_t *cnt)
519 {
520 	struct pi1ppc_softc * const pi1ppc = device_private(dev);
521 	int error = 0;
522 
523 	*cnt = 0;
524 
525 	PI1PPC_LOCK(pi1ppc);
526 
527 	/* Set up line buffer */
528 	pi1ppc->sc_outb = pi1ppc->sc_outbstart = buf;
529 	pi1ppc->sc_outb_nbytes = len;
530 
531 	/* Initialize device output error state for new operation */
532 	pi1ppc->sc_outerr = 0;
533 
534 	/* Call appropriate function to write bytes */
535 	switch (pi1ppc->sc_mode) {
536 	case PI1PPC_MODE_STD:
537 		pi1ppc_std_write(pi1ppc);
538 		break;
539 
540 	case PI1PPC_MODE_NIBBLE:
541 	case PI1PPC_MODE_PS2:
542 		error = ENODEV;
543 		break;
544 
545 	default:
546 		panic("%s(%s): chipset in invalid mode.\n", __func__,
547                       device_xname(dev));
548 	}
549 
550 	/* Update counter*/
551 	*cnt = (pi1ppc->sc_outbstart - pi1ppc->sc_outb);
552 
553 	/* Reset output buffer */
554 	pi1ppc->sc_outb = pi1ppc->sc_outbstart = NULL;
555 	pi1ppc->sc_outb_nbytes = 0;
556 
557 	if (!(error))
558 		error = pi1ppc->sc_outerr;
559 
560 	PI1PPC_UNLOCK(pi1ppc);
561 
562 	return (error);
563 }
564 
565 /*
566  * Set mode of chipset to mode argument. Modes not supported are ignored. If
567  * multiple modes are flagged, the mode is not changed. Modes are those
568  * defined for ppbus_softc.sc_mode in ppbus_conf.h. Only ECP-capable chipsets
569  * can change their mode of operation. However, ALL operation modes support
570  * centronics mode and nibble mode. Modes determine both hardware AND software
571  * behaviour.
572  * NOTE: the mode for ECP should only be changed when the channel is in
573  * forward idle mode. This function does not make sure FIFO's have flushed or
574  * any consistency checks.
575  */
576 static int
pi1ppc_setmode(device_t dev,int mode)577 pi1ppc_setmode(device_t dev, int mode)
578 {
579 	struct pi1ppc_softc *pi1ppc = device_private(dev);
580 	uint8_t ecr;
581 	uint8_t chipset_mode;
582 	int rval = 0;
583 
584 	PI1PPC_LOCK(pi1ppc);
585 
586 	switch (mode) {
587 	case PPBUS_PS2:
588 		/* Indy has this, other PI1 machines do too? */
589 		chipset_mode = PI1PPC_MODE_PS2;
590 		break;
591 
592 	case PPBUS_NIBBLE:
593 		/* Set nibble mode (virtual) */
594 		chipset_mode = PI1PPC_MODE_NIBBLE;
595 		break;
596 
597 	case PPBUS_COMPATIBLE:
598 		chipset_mode = PI1PPC_MODE_STD;
599 		break;
600 
601 	case PPBUS_ECP:
602 	case PPBUS_EPP:
603 		rval = ENODEV;
604 		goto end;
605 
606 	default:
607 		PI1PPC_DPRINTF(("%s(%s): invalid mode passed as "
608                                 "argument.\n", __func__, device_xname(dev)));
609 		rval = ENODEV;
610 		goto end;
611 	}
612 
613 	pi1ppc->sc_mode = chipset_mode;
614 	if (chipset_mode == PI1PPC_MODE_PS2) {
615 		/* Set direction bit to reverse */
616 		ecr = pi1ppc_r_ctr(pi1ppc);
617 		pi1ppc_barrier_r(pi1ppc);
618 		ecr |= PCD;			/* data is INPUT */
619 		pi1ppc_w_ctr(pi1ppc, ecr);
620 		pi1ppc_barrier_w(pi1ppc);
621 	}
622 
623 end:
624 	PI1PPC_UNLOCK(pi1ppc);
625 
626 	return rval;
627 }
628 
629 /* Get the current mode of chipset */
630 static int
pi1ppc_getmode(device_t dev)631 pi1ppc_getmode(device_t dev)
632 {
633 	struct pi1ppc_softc *pi1ppc = device_private(dev);
634 	int mode;
635 
636 	PI1PPC_LOCK(pi1ppc);
637 
638 	/* The chipset can only be in one mode at a time logically */
639 	switch (pi1ppc->sc_mode) {
640 	case PI1PPC_MODE_PS2:
641 		mode = PPBUS_PS2;
642 		break;
643 
644 	case PI1PPC_MODE_STD:
645 		mode = PPBUS_COMPATIBLE;
646 		break;
647 
648 	case PI1PPC_MODE_NIBBLE:
649 		mode = PPBUS_NIBBLE;
650 		break;
651 
652 	default:
653 		panic("%s(%s): device is in invalid mode!", __func__,
654                       device_xname(dev));
655 		break;
656 	}
657 
658 	PI1PPC_UNLOCK(pi1ppc);
659 
660 	return mode;
661 }
662 
663 
664 /* Wait for FIFO buffer to empty for ECP-capable chipset */
665 static void
pi1ppc_ecp_sync(device_t dev)666 pi1ppc_ecp_sync(device_t dev)
667 {
668 	return;
669 }
670 
671 /* Execute a microsequence to handle fast I/O operations. */
672 
673 /* microsequence registers are equivalent to PC-like port registers */
674 /* therefore, translate bit positions & polarities */
675 
676 /* Bit 4 of ctl_reg_int_en is used to emulate the PC's int enable
677    bit.  Without it, lpt doesn't like the port.
678  */
679 static uint8_t ctl_reg_int_en = 0;
680 
681 static uint8_t
r_reg(int reg,struct pi1ppc_softc * pi1ppc)682 r_reg(int reg, struct pi1ppc_softc *pi1ppc)
683 {
684 	int val = 0;
685 
686 	/* if we read the status reg, make it look like the PC */
687 	if(reg == AT_STAT_REG) {
688 		val = bus_space_read_4((pi1ppc)->sc_iot,
689 				(pi1ppc)->sc_ioh, IOC_PLP_STAT);
690 		val &= 0xff;
691 
692 		/* invert /BUSY */
693 		val ^= 0x80;
694 
695 		/* bit 2 reads as '1' on Indy (why?) */
696 		val &= 0xf8;
697 
698 		return val;
699 	}
700 
701 	/* if we read the ctl reg, make it look like the PC */
702 	if(reg == AT_CTL_REG) {
703 		val = bus_space_read_4((pi1ppc)->sc_iot,
704 				(pi1ppc)->sc_ioh, IOC_PLP_CTL);
705 		val &= 0xff;
706 
707 		/* get the dir bit in the right place */
708 		val = ((val >> 1) & 0x20) | (val & 0x0f);
709 
710 		/* invert /SEL, /AUTOFD, and /STB */
711 		val ^= 0x0b;
712 
713 		/* emulate the PC's int enable ctl bit */
714 		val |= (ctl_reg_int_en & 0x10);
715 
716 		return val;
717 	}
718 
719 	if(reg == AT_DATA_REG) {
720 		val = bus_space_read_4((pi1ppc)->sc_iot,
721 				(pi1ppc)->sc_ioh, IOC_PLP_DATA);
722 		val &= 0xff;
723 
724 		return val;
725 	}
726 
727 	return 0;
728 }
729 
730 static void
w_reg(int reg,struct pi1ppc_softc * pi1ppc,uint8_t byte)731 w_reg(int reg, struct pi1ppc_softc *pi1ppc, uint8_t byte)
732 {
733 	/* don't try to write to the status reg */
734 
735 	/* if we are writing the ctl reg, adjust PC style -> IOC style */
736 	if(reg == AT_CTL_REG) {
737 		/* preserve pc-style int enable bit */
738 		ctl_reg_int_en = (byte & 0x10);
739 
740 		/* get the dir bit in the right place */
741 		byte = ((byte << 1) & 0x40) | (byte & 0x0f);
742 
743 		/* invert /SEL, /AUTOFD, and /STB */
744 		byte ^= 0x0b;
745 
746 		bus_space_write_4((pi1ppc)->sc_iot,
747 				(pi1ppc)->sc_ioh, IOC_PLP_CTL, byte);
748 	}
749 
750 	if(reg == AT_DATA_REG) {
751 		bus_space_write_4((pi1ppc)->sc_iot,
752 				(pi1ppc)->sc_ioh, IOC_PLP_DATA, byte);
753 	}
754 }
755 
756 static int
pi1ppc_exec_microseq(device_t dev,struct ppbus_microseq ** p_msq)757 pi1ppc_exec_microseq(device_t dev, struct ppbus_microseq **p_msq)
758 {
759 	struct pi1ppc_softc *pi1ppc = device_private(dev);
760 	struct ppbus_microseq *mi = *p_msq;
761 	char cc, *p;
762 	int i, iter, len;
763 	int error;
764 	register int reg;
765 	register unsigned char mask;
766 	register int accum = 0;
767 	register char *ptr = NULL;
768 	struct ppbus_microseq *stack = NULL;
769 
770 	PI1PPC_LOCK(pi1ppc);
771 
772 	/* Loop until microsequence execution finishes (ending op code) */
773 	for (;;) {
774 		switch (mi->opcode) {
775 		case MS_OP_RSET:
776 			cc = r_reg(mi->arg[0].i, pi1ppc);
777 			pi1ppc_barrier_r(pi1ppc);
778 			cc &= (char)mi->arg[2].i;	/* clear mask */
779 			cc |= (char)mi->arg[1].i;	/* assert mask */
780 			w_reg(mi->arg[0].i, pi1ppc, cc);
781 			pi1ppc_barrier_w(pi1ppc);
782 			mi++;
783                        	break;
784 
785 		case MS_OP_RASSERT_P:
786 			reg = mi->arg[1].i;
787 			ptr = pi1ppc->sc_ptr;
788 
789 			if ((len = mi->arg[0].i) == MS_ACCUM) {
790 				accum = pi1ppc->sc_accum;
791 				for (; accum; accum--) {
792 					w_reg(reg, pi1ppc, *ptr++);
793 					pi1ppc_barrier_w(pi1ppc);
794 				}
795 				pi1ppc->sc_accum = accum;
796 			} else {
797 				for (i = 0; i < len; i++) {
798 					w_reg(reg, pi1ppc, *ptr++);
799 					pi1ppc_barrier_w(pi1ppc);
800 				}
801 			}
802 
803 			pi1ppc->sc_ptr = ptr;
804 			mi++;
805 			break;
806 
807        	        case MS_OP_RFETCH_P:
808 			reg = mi->arg[1].i;
809 			mask = (char)mi->arg[2].i;
810 			ptr = pi1ppc->sc_ptr;
811 
812 			if ((len = mi->arg[0].i) == MS_ACCUM) {
813 				accum = pi1ppc->sc_accum;
814 				for (; accum; accum--) {
815 					*ptr++ = r_reg(reg, pi1ppc) & mask;
816 					pi1ppc_barrier_r(pi1ppc);
817 				}
818 				pi1ppc->sc_accum = accum;
819 			} else {
820 				for (i = 0; i < len; i++) {
821 					*ptr++ = r_reg(reg, pi1ppc) & mask;
822 					pi1ppc_barrier_r(pi1ppc);
823 				}
824 			}
825 
826 			pi1ppc->sc_ptr = ptr;
827 			mi++;
828 			break;
829 
830                 case MS_OP_RFETCH:
831 			*((char *)mi->arg[2].p) = r_reg(mi->arg[0].i, pi1ppc) &
832 				(char)mi->arg[1].i;
833 			pi1ppc_barrier_r(pi1ppc);
834 			mi++;
835        	                break;
836 
837 		case MS_OP_RASSERT:
838                 case MS_OP_DELAY:
839 			/* let's suppose the next instr. is the same */
840 			do {
841 				for (;mi->opcode == MS_OP_RASSERT; mi++) {
842 					w_reg(mi->arg[0].i, pi1ppc,
843 						(char)mi->arg[1].i);
844 					pi1ppc_barrier_w(pi1ppc);
845 				}
846 
847 				for (;mi->opcode == MS_OP_DELAY; mi++) {
848 					delay(mi->arg[0].i);
849 				}
850 			} while (mi->opcode == MS_OP_RASSERT);
851 			break;
852 
853 		case MS_OP_ADELAY:
854 			if (mi->arg[0].i) {
855 				DELAY(mi->arg[0].i * 1000);
856 			}
857 			mi++;
858 			break;
859 
860 		case MS_OP_TRIG:
861 			reg = mi->arg[0].i;
862 			iter = mi->arg[1].i;
863 			p = (char *)mi->arg[2].p;
864 
865 			/* XXX delay limited to 255 us */
866 			for (i = 0; i < iter; i++) {
867 				w_reg(reg, pi1ppc, *p++);
868 				pi1ppc_barrier_w(pi1ppc);
869 				delay((unsigned char)*p++);
870 			}
871 
872 			mi++;
873 			break;
874 
875 		case MS_OP_SET:
876                         pi1ppc->sc_accum = mi->arg[0].i;
877 			mi++;
878                        	break;
879 
880 		case MS_OP_DBRA:
881                        	if (--pi1ppc->sc_accum > 0) {
882                                	mi += mi->arg[0].i;
883 			}
884 
885 			mi++;
886 			break;
887 
888 		case MS_OP_BRSET:
889 			cc = pi1ppc_r_str(pi1ppc);
890 			pi1ppc_barrier_r(pi1ppc);
891 			if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) {
892 				mi += mi->arg[1].i;
893 			}
894 			mi++;
895 			break;
896 
897 		case MS_OP_BRCLEAR:
898 			cc = pi1ppc_r_str(pi1ppc);
899 			pi1ppc_barrier_r(pi1ppc);
900 			if ((cc & (char)mi->arg[0].i) == 0) {
901 				mi += mi->arg[1].i;
902 			}
903 			mi++;
904 			break;
905 
906 		case MS_OP_BRSTAT:
907 			cc = pi1ppc_r_str(pi1ppc);
908 			pi1ppc_barrier_r(pi1ppc);
909 			if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
910 				(char)mi->arg[0].i) {
911 				mi += mi->arg[2].i;
912 			}
913 			mi++;
914 			break;
915 
916 		case MS_OP_C_CALL:
917 			/*
918 			 * If the C call returns !0 then end the microseq.
919 			 * The current state of ptr is passed to the C function
920 			 */
921 			if ((error = mi->arg[0].f(mi->arg[1].p,
922 				pi1ppc->sc_ptr))) {
923 				PI1PPC_UNLOCK(pi1ppc);
924 				return (error);
925 			}
926 			mi++;
927 			break;
928 
929 		case MS_OP_PTR:
930 			pi1ppc->sc_ptr = (char *)mi->arg[0].p;
931 			mi++;
932 			break;
933 
934 		case MS_OP_CALL:
935 			if (stack) {
936 				panic("%s - %s: too many calls", device_xname(dev),
937 					__func__);
938 			}
939 
940 			if (mi->arg[0].p) {
941 				/* store state of the actual microsequence */
942 				stack = mi;
943 
944 				/* jump to the new microsequence */
945 				mi = (struct ppbus_microseq *)mi->arg[0].p;
946 			} else {
947 				mi++;
948 			}
949 			break;
950 
951 		case MS_OP_SUBRET:
952 			/* retrieve microseq and pc state before the call */
953 			mi = stack;
954 
955 			/* reset the stack */
956 			stack = 0;
957 
958 			/* XXX return code */
959 
960 			mi++;
961 			break;
962 
963 		case MS_OP_PUT:
964 		case MS_OP_GET:
965 		case MS_OP_RET:
966 			/*
967 			 * Can't return to pi1ppc level during the execution
968 			 * of a submicrosequence.
969 			 */
970 			if (stack) {
971 				panic("%s: cannot return to pi1ppc level",
972 					__func__);
973 			}
974 			/* update pc for pi1ppc level of execution */
975 			*p_msq = mi;
976 
977 			PI1PPC_UNLOCK(pi1ppc);
978 			return (0);
979 
980 		default:
981 			panic("%s: unknown microsequence "
982 				"opcode 0x%x", __func__, mi->opcode);
983 			break;
984 		}
985 	}
986 
987 	/* Should not be reached! */
988 #ifdef PI1PPC_DEBUG
989 	panic("%s: unexpected code reached!\n", __func__);
990 #endif
991 }
992 
993 /* General I/O routine */
994 static uint8_t
pi1ppc_io(device_t dev,int iop,u_char * addr,int cnt,u_char byte)995 pi1ppc_io(device_t dev, int iop, u_char *addr, int cnt, u_char byte)
996 {
997 	struct pi1ppc_softc *pi1ppc = device_private(dev);
998 	uint8_t val = 0;
999 
1000 	PI1PPC_LOCK(pi1ppc);
1001 
1002 	switch (iop) {
1003 	case PPBUS_RDTR:
1004 		val = r_reg(AT_DATA_REG, pi1ppc);
1005 		break;
1006 	case PPBUS_RSTR:
1007 		val = r_reg(AT_STAT_REG, pi1ppc);
1008 		break;
1009 	case PPBUS_RCTR:
1010 		val = r_reg(AT_CTL_REG, pi1ppc);
1011 		break;
1012 	case PPBUS_WDTR:
1013 		w_reg(AT_DATA_REG, pi1ppc, byte);
1014 		break;
1015 	case PPBUS_WSTR:
1016 		/* writing to the status register is weird */
1017 		break;
1018 	case PPBUS_WCTR:
1019 		w_reg(AT_CTL_REG, pi1ppc, byte);
1020 		break;
1021 	default:
1022 		panic("%s(%s): unknown I/O operation", device_xname(dev),
1023 			__func__);
1024 		break;
1025 	}
1026 
1027 	pi1ppc_barrier(pi1ppc);
1028 
1029 	PI1PPC_UNLOCK(pi1ppc);
1030 
1031 	return val;
1032 }
1033 
1034 /* Read "instance variables" of pi1ppc device */
1035 static int
pi1ppc_read_ivar(device_t dev,int index,unsigned int * val)1036 pi1ppc_read_ivar(device_t dev, int index, unsigned int *val)
1037 {
1038 	struct pi1ppc_softc *pi1ppc = device_private(dev);
1039 	int rval = 0;
1040 
1041 	PI1PPC_LOCK(pi1ppc);
1042 
1043 	switch(index) {
1044 	case PPBUS_IVAR_INTR:
1045 		*val = ((pi1ppc->sc_use & PI1PPC_USE_INTR) != 0);
1046 		break;
1047 
1048 	case PPBUS_IVAR_DMA:
1049 		*val = ((pi1ppc->sc_use & PI1PPC_USE_DMA) != 0);
1050 		break;
1051 
1052 	default:
1053 		rval = ENODEV;
1054 	}
1055 
1056 	PI1PPC_UNLOCK(pi1ppc);
1057 	return rval;
1058 }
1059 
1060 /* Write "instance variables" of pi1ppc device */
1061 static int
pi1ppc_write_ivar(device_t dev,int index,unsigned int * val)1062 pi1ppc_write_ivar(device_t dev, int index, unsigned int *val)
1063 {
1064 	struct pi1ppc_softc *pi1ppc = device_private(dev);
1065 	int rval = 0;
1066 
1067 	PI1PPC_LOCK(pi1ppc);
1068 
1069 	switch(index) {
1070 	case PPBUS_IVAR_INTR:
1071 		if (*val == 0)
1072 			pi1ppc->sc_use &= ~PI1PPC_USE_INTR;
1073 		else if (pi1ppc->sc_has & PI1PPC_HAS_INTR)
1074 			pi1ppc->sc_use |= PI1PPC_USE_INTR;
1075 		else
1076 			rval = ENODEV;
1077 		break;
1078 
1079 	case PPBUS_IVAR_DMA:
1080 		if (*val == 0)
1081 			pi1ppc->sc_use &= ~PI1PPC_USE_DMA;
1082 		else if (pi1ppc->sc_has & PI1PPC_HAS_DMA)
1083 			pi1ppc->sc_use |= PI1PPC_USE_DMA;
1084 		else
1085 			rval = ENODEV;
1086 		break;
1087 
1088 	default:
1089 		rval = ENODEV;
1090 	}
1091 
1092 	PI1PPC_UNLOCK(pi1ppc);
1093 	return rval;
1094 }
1095 
1096 /* Add a handler routine to be called by the interrupt handler */
1097 static int
pi1ppc_add_handler(device_t dev,void (* handler)(void *),void * arg)1098 pi1ppc_add_handler(device_t dev, void (*handler)(void *), void *arg)
1099 {
1100 	struct pi1ppc_softc *pi1ppc = device_private(dev);
1101 	struct pi1ppc_handler_node *callback;
1102 
1103 	if (handler == NULL) {
1104 		PI1PPC_DPRINTF(("%s(%s): attempt to register NULL handler.\n",
1105 			__func__, device_xname(dev)));
1106 		return EINVAL;
1107 	}
1108 	callback = kmem_alloc(sizeof(struct pi1ppc_handler_node), KM_SLEEP);
1109 
1110 	PI1PPC_LOCK(pi1ppc);
1111 	callback->func = handler;
1112 	callback->arg = arg;
1113 	SLIST_INSERT_HEAD(&(pi1ppc->sc_handler_listhead), callback, entries);
1114 	PI1PPC_UNLOCK(pi1ppc);
1115 
1116 	return 0;
1117 }
1118 
1119 /* Remove a handler added by pi1ppc_add_handler() */
1120 static int
pi1ppc_remove_handler(device_t dev,void (* handler)(void *))1121 pi1ppc_remove_handler(device_t dev, void (*handler)(void *))
1122 {
1123 	struct pi1ppc_softc *pi1ppc = device_private(dev);
1124 	struct pi1ppc_handler_node *callback;
1125 	int rval;
1126 
1127 	PI1PPC_LOCK(pi1ppc);
1128 	KASSERT(!SLIST_EMPTY(&(pi1ppc->sc_handler_listhead)));
1129 	SLIST_FOREACH(callback, &(pi1ppc->sc_handler_listhead), entries) {
1130 		if (callback->func == handler) {
1131 			SLIST_REMOVE(&(pi1ppc->sc_handler_listhead), callback,
1132 				pi1ppc_handler_node, entries);
1133 
1134 			break;
1135 		}
1136 	}
1137 	PI1PPC_UNLOCK(pi1ppc);
1138 
1139 	if (callback) {
1140 		kmem_free(callback, sizeof(struct pi1ppc_handler_node));
1141 		rval = 0;
1142 	} else {
1143 		rval = EINVAL;
1144 	}
1145 	return rval;
1146 }
1147 
1148 /* Utility functions */
1149 
1150 /*
1151  * Functions that read bytes from port into buffer: called from interrupt
1152  * handler depending on current chipset mode and cause of interrupt. Return
1153  * value: number of bytes moved.
1154  */
1155 
1156 /* note: BUSY is inverted in the PC world, but not on Indy, but the r_reg()
1157 	 and w_reg() functions make the Indy look like the PC. */
1158 
1159 /* Only the lower 4 bits of the final value are valid */
1160 #define nibble2char(s) ((((s) & ~nACK) >> 3) | (~(s) & nBUSY) >> 4)
1161 
1162 
1163 /* Read bytes in nibble mode */
1164 static void
pi1ppc_nibble_read(struct pi1ppc_softc * pi1ppc)1165 pi1ppc_nibble_read(struct pi1ppc_softc *pi1ppc)
1166 {
1167 	int i;
1168 	uint8_t nibble[2];
1169 	uint8_t ctr;
1170 	uint8_t str;
1171 
1172 	/* Enable interrupts if needed */
1173 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1174 
1175 		/* XXX JOE - need code to enable interrupts
1176 				--> emulate PC behavior in r_reg/w_reg
1177 		*/
1178 #if 0
1179 		ctr = pi1ppc_r_ctr(pi1ppc);
1180 		pi1ppc_barrier_r(ioppc);
1181 		if (!(ctr & IRQENABLE)) {
1182 			ctr |= IRQENABLE;
1183 			pi1ppc_w_ctr(pi1ppc, ctr);
1184 			pi1ppc_barrier_w(pi1ppc);
1185 		}
1186 #endif
1187 	}
1188 
1189 	while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) {
1190 		/* Check if device has data to send in idle phase */
1191 		str = pi1ppc_r_str(pi1ppc);
1192 		pi1ppc_barrier_r(pi1ppc);
1193 		if (str & nDATAVAIL) {
1194 			return;
1195 		}
1196 
1197 		/* Nibble-mode handshake transfer */
1198 		for (i = 0; i < 2; i++) {
1199 			/* Event 7 - ready to take data (HOSTBUSY low) */
1200 			ctr = pi1ppc_r_ctr(pi1ppc);
1201 			pi1ppc_barrier_r(pi1ppc);
1202 			ctr |= HOSTBUSY;
1203 			pi1ppc_w_ctr(pi1ppc, ctr);
1204 			pi1ppc_barrier_w(pi1ppc);
1205 
1206 			/* Event 8 - peripheral writes the first nibble */
1207 
1208 			/* Event 9 - peripheral set nAck low */
1209 			pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK);
1210 			if (pi1ppc->sc_inerr)
1211 				return;
1212 
1213 			/* read nibble */
1214 			nibble[i] = pi1ppc_r_str(pi1ppc);
1215 
1216 			/* Event 10 - ack, nibble received */
1217 			ctr &= ~HOSTBUSY;
1218 			pi1ppc_w_ctr(pi1ppc, ctr);
1219 
1220 			/* Event 11 - wait ack from peripheral */
1221 			if (pi1ppc->sc_use & PI1PPC_USE_INTR)
1222 				pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc,
1223 				    &pi1ppc->sc_in_cv, PI1PPC_IRQ_nACK);
1224 			else
1225 				pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK,
1226 					PTRCLK);
1227 			if (pi1ppc->sc_inerr)
1228 				return;
1229 		}
1230 
1231 		/* Store byte transferred */
1232 		*(pi1ppc->sc_inbstart) = ((nibble2char(nibble[1]) << 4) & 0xf0) |
1233 			(nibble2char(nibble[0]) & 0x0f);
1234 		pi1ppc->sc_inbstart++;
1235 	}
1236 }
1237 
1238 /* Read bytes in bidirectional mode */
1239 static void
pi1ppc_byte_read(struct pi1ppc_softc * const pi1ppc)1240 pi1ppc_byte_read(struct pi1ppc_softc * const pi1ppc)
1241 {
1242 	uint8_t ctr;
1243 	uint8_t str;
1244 
1245 	/* Check direction bit */
1246 	ctr = pi1ppc_r_ctr(pi1ppc);
1247 	pi1ppc_barrier_r(pi1ppc);
1248 	if (!(ctr & PCD)) {
1249 		PI1PPC_DPRINTF(("%s: byte-mode read attempted without direction "
1250                                 "bit set.", device_xname(pi1ppc->sc_dev)));
1251 		pi1ppc->sc_inerr = ENODEV;
1252 		return;
1253 	}
1254 	/* Enable interrupts if needed */
1255 
1256 		/* XXX JOE - need code to enable interrupts */
1257 #if 0
1258 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1259 		if (!(ctr & IRQENABLE)) {
1260 			ctr |= IRQENABLE;
1261 			pi1ppc_w_ctr(pi1ppc, ctr);
1262 			pi1ppc_barrier_w(pi1ppc);
1263 		}
1264 	}
1265 #endif
1266 
1267 	/* Byte-mode handshake transfer */
1268 	while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) {
1269 		/* Check if device has data to send */
1270 		str = pi1ppc_r_str(pi1ppc);
1271 		pi1ppc_barrier_r(pi1ppc);
1272 		if (str & nDATAVAIL) {
1273 			return;
1274 		}
1275 
1276 		/* Event 7 - ready to take data (nAUTO low) */
1277 		ctr |= HOSTBUSY;
1278 		pi1ppc_w_ctr(pi1ppc, ctr);
1279 		pi1ppc_barrier_w(pi1ppc);
1280 
1281 		/* Event 9 - peripheral set nAck low */
1282 		pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK);
1283 		if (pi1ppc->sc_inerr)
1284 			return;
1285 
1286 		/* Store byte transferred */
1287 		*(pi1ppc->sc_inbstart) = pi1ppc_r_dtr(pi1ppc);
1288 		pi1ppc_barrier_r(pi1ppc);
1289 
1290 		/* Event 10 - data received, can't accept more */
1291 		ctr &= ~HOSTBUSY;
1292 		pi1ppc_w_ctr(pi1ppc, ctr);
1293 		pi1ppc_barrier_w(pi1ppc);
1294 
1295 		/* Event 11 - peripheral ack */
1296 		if (pi1ppc->sc_use & PI1PPC_USE_INTR)
1297 			pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc,
1298 			    &pi1ppc->sc_in_cv, PI1PPC_IRQ_nACK);
1299 		else
1300 			pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK, PTRCLK);
1301 		if (pi1ppc->sc_inerr)
1302 			return;
1303 
1304 		/* Event 16 - strobe */
1305 		str |= HOSTCLK;
1306 		pi1ppc_w_str(pi1ppc, str);
1307 		pi1ppc_barrier_w(pi1ppc);
1308 		DELAY(1);
1309 		str &= ~HOSTCLK;
1310 		pi1ppc_w_str(pi1ppc, str);
1311 		pi1ppc_barrier_w(pi1ppc);
1312 
1313 		/* Update counter */
1314 		pi1ppc->sc_inbstart++;
1315 	}
1316 }
1317 
1318 /*
1319  * Functions that write bytes to port from buffer: called from pi1ppc_write()
1320  * function depending on current chipset mode. Returns number of bytes moved.
1321  */
1322 
1323 static void
pi1ppc_set_intr_mask(struct pi1ppc_softc * const pi1ppc,uint8_t mask)1324 pi1ppc_set_intr_mask(struct pi1ppc_softc * const pi1ppc, uint8_t mask)
1325 {
1326 	/* invert valid bits (0 = enabled) */
1327 	mask = ~mask;
1328 	mask &= 0xfc;
1329 
1330 	bus_space_write_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK, mask);
1331 	pi1ppc_barrier_w(pi1ppc);
1332 }
1333 
1334 
1335 #ifdef USE_INDY_ACK_HACK
1336 static uint8_t
pi1ppc_get_intr_mask(struct pi1ppc_softc * const pi1ppc)1337 pi1ppc_get_intr_mask(struct pi1ppc_softc * const pi1ppc)
1338 {
1339 	int val;
1340 	val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK);
1341 	pi1ppc_barrier_r(pi1ppc);
1342 
1343 	/* invert (0 = enabled) */
1344 	val = ~val;
1345 
1346 	return (val & 0xfc);
1347 }
1348 #endif
1349 
1350 static uint8_t
pi1ppc_get_intr_stat(struct pi1ppc_softc * const pi1ppc)1351 pi1ppc_get_intr_stat(struct pi1ppc_softc * const pi1ppc)
1352 {
1353 	int val;
1354 	val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTSTAT);
1355 	pi1ppc_barrier_r(pi1ppc);
1356 
1357 	return (val & 0xfc);
1358 }
1359 
1360 /* Write bytes in std/bidirectional mode */
1361 static void
pi1ppc_std_write(struct pi1ppc_softc * const pi1ppc)1362 pi1ppc_std_write(struct pi1ppc_softc * const pi1ppc)
1363 {
1364 	unsigned char ctr;
1365 
1366 	ctr = pi1ppc_r_ctr(pi1ppc);
1367 	pi1ppc_barrier_r(pi1ppc);
1368 
1369 	/* Ensure that the data lines are in OUTPUT mode */
1370 	ctr &= ~PCD;
1371 	pi1ppc_w_ctr(pi1ppc, ctr);
1372 	pi1ppc_barrier_w(pi1ppc);
1373 
1374 	/* XXX JOE - need code to enable interrupts */
1375 #if 0
1376 	/* Enable interrupts if needed */
1377 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1378 		if (!(ctr & IRQENABLE)) {
1379 			ctr |= IRQENABLE;
1380 			pi1ppc_w_ctr(pi1ppc, ctr);
1381 			pi1ppc_barrier_w(pi1ppc);
1382 		}
1383 	}
1384 #endif
1385 
1386 	while (pi1ppc->sc_outbstart < (pi1ppc->sc_outb + pi1ppc->sc_outb_nbytes)) {
1387 
1388 		/* Wait for peripheral to become ready for MAXBUSYWAIT */
1389 		pi1ppc->sc_outerr = pi1ppc_poll_str(pi1ppc, SPP_READY, SPP_MASK);
1390 		if (pi1ppc->sc_outerr) {
1391 			printf("pi1ppc: timeout waiting for peripheral to become ready\n");
1392 			return;
1393 		}
1394 
1395 		/* Put data in data register */
1396 		pi1ppc_w_dtr(pi1ppc, *(pi1ppc->sc_outbstart));
1397 		pi1ppc_barrier_w(pi1ppc);
1398 		DELAY(1);
1399 
1400 		/* If no intr, prepare to catch the rising edge of nACK */
1401 		if (!(pi1ppc->sc_use & PI1PPC_USE_INTR)) {
1402 			pi1ppc_get_intr_stat(pi1ppc);	/* clear any pending intr */
1403 			pi1ppc_set_intr_mask(pi1ppc, PI1_PLP_ACK_INTR);
1404 		}
1405 
1406 		/* Pulse strobe to indicate valid data on lines */
1407 		ctr |= STROBE;
1408 		pi1ppc_w_ctr(pi1ppc, ctr);
1409 		pi1ppc_barrier_w(pi1ppc);
1410 		DELAY(1);
1411 		ctr &= ~STROBE;
1412 		pi1ppc_w_ctr(pi1ppc, ctr);
1413 		pi1ppc_barrier_w(pi1ppc);
1414 
1415 		/* Wait for nACK for MAXBUSYWAIT */
1416 		if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1417 			pi1ppc->sc_outerr = pi1ppc_wait_interrupt(pi1ppc,
1418 			    &pi1ppc->sc_out_cv, PI1PPC_IRQ_nACK);
1419 			if (pi1ppc->sc_outerr)
1420 				return;
1421 		} else {
1422 			/* Try to catch the pulsed acknowledgement */
1423 			pi1ppc->sc_outerr = pi1ppc_poll_interrupt_stat(pi1ppc,
1424 				PI1_PLP_ACK_INTR);
1425 
1426 			if (pi1ppc->sc_outerr) {
1427 				printf("pi1ppc: timeout waiting for ACK: %02x\n",pi1ppc_r_str(pi1ppc));
1428 				return;
1429 			}
1430 		}
1431 
1432 		/* Update buffer position, byte count and counter */
1433 		pi1ppc->sc_outbstart++;
1434 	}
1435 }
1436 
1437 /*
1438  * Poll status register using mask and status for MAXBUSYWAIT.
1439  * Returns 0 if device ready, error value otherwise.
1440  */
1441 static int
pi1ppc_poll_str(struct pi1ppc_softc * const pi1ppc,const uint8_t status,const uint8_t mask)1442 pi1ppc_poll_str(struct pi1ppc_softc * const pi1ppc, const uint8_t status,
1443 	const uint8_t mask)
1444 {
1445 	unsigned int timecount;
1446 	uint8_t str;
1447 	int error = EIO;
1448 
1449 	/* Wait for str to have status for MAXBUSYWAIT */
1450 	for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*1000000);
1451 		timecount++) {
1452 
1453 		str = pi1ppc_r_str(pi1ppc);
1454 		pi1ppc_barrier_r(pi1ppc);
1455 		if ((str & mask) == status) {
1456 			error = 0;
1457 			break;
1458 		}
1459 		DELAY(1);
1460 	}
1461 
1462 	return error;
1463 }
1464 
1465 /* Wait for interrupt for MAXBUSYWAIT: returns 0 if acknowledge received. */
1466 static int
pi1ppc_wait_interrupt(struct pi1ppc_softc * const sc,kcondvar_t * cv,const uint8_t irqstat)1467 pi1ppc_wait_interrupt(struct pi1ppc_softc * const sc, kcondvar_t *cv,
1468     const uint8_t irqstat)
1469 {
1470 	int error = EIO;
1471 
1472 	sc->sc_irqstat &= ~irqstat;
1473 	error = cv_timedwait_sig(cv, &sc->sc_lock, MAXBUSYWAIT);
1474 	if (!error && (sc->sc_irqstat & irqstat) == 0) {
1475 		sc->sc_irqstat &= ~irqstat;
1476 		error = 0;
1477 	}
1478 	return error;
1479 }
1480 
1481 /*
1482 	INDY ACK HACK DESCRIPTION
1483 
1484 	There appears to be a bug in the Indy's PI1 hardware - it sometimes
1485 	*misses* the rising edge of /ACK.  Ugh!
1486 
1487 	(Also, unlike the other status bits, /ACK doesn't generate an
1488 	 interrupt on its falling edge.)
1489 
1490 	So, we do something kind of skanky here.  We use a shorter timeout,
1491 	and, if we timeout, we first check BUSY.  If BUSY is high, we go
1492 	back to waiting for /ACK (because maybe this really is just a slow
1493 	peripheral).
1494 
1495 	If it's a normal printer, it will raise BUSY from when it sees our
1496 	/STROBE until it raises its /ACK:
1497 		_____   _____________________
1498 	/STB	     \_/
1499 		________________   __________
1500 	/ACK	                \_/
1501 		       ___________
1502 	BUSY	______/           \__________
1503 
1504 	So, if we time out and see BUSY low, then we probably just missed
1505 	the /ACK.
1506 
1507 	In that case, we then check /ERROR and SELECTIN.  If both are hi,
1508 	(the peripheral thinks it is selected, and is not asserting /ERROR)
1509 	we assume that the Indy's parallel port missed the /ACK, and return
1510 	success.
1511  */
1512 
1513 #ifdef USE_INDY_ACK_HACK
1514 	#define	ACK_TIMEOUT_SCALER	1000
1515 #else
1516 	#define ACK_TIMEOUT_SCALER	1000000
1517 #endif
1518 
1519 static int
pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const pi1ppc,const uint8_t match)1520 pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const pi1ppc,
1521 	const uint8_t match)
1522 {
1523 	unsigned int timecount;
1524 	uint8_t cur;
1525 	int error = EIO;
1526 
1527 #ifdef USE_INDY_ACK_HACK
1528 	/* retry 10000x */
1529 	int retry_count = 10000;
1530 
1531 retry:
1532 #endif
1533 
1534 	/* Wait for intr status to have match bits set for MAXBUSYWAIT */
1535 	for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*ACK_TIMEOUT_SCALER);
1536 		timecount++) {
1537 		cur = pi1ppc_get_intr_stat(pi1ppc);
1538 		if ((cur & match) == match) {
1539 			error = 0;
1540 			break;
1541 		}
1542 		DELAY(1);
1543 	}
1544 
1545 #ifdef USE_INDY_ACK_HACK
1546 	if(error != 0) {
1547 		cur = pi1ppc_r_str(pi1ppc);
1548 
1549 		/* retry if BUSY is hi (inverted, so lo) and we haven't
1550 			waited the usual amt */
1551 
1552 		if(((cur&nBUSY) == 0) && retry_count) {
1553 			retry_count--;
1554 			goto retry;
1555 		}
1556 
1557 		/* if /ERROR and SELECT are high, and the peripheral isn't
1558 	   		BUSY, assume that we just missed the /ACK.
1559 			(Remember, we emulate the PC's inverted BUSY!)
1560 		*/
1561 
1562 		if((cur&(nFAULT|SELECT|nBUSY)) == (nFAULT|SELECT|nBUSY))
1563 			error = 0;
1564 
1565 		/* if things still look bad, print out some info */
1566 		if(error!=0)
1567 			printf("int mask=%02x, int stat=%02x, str=%02x\n",
1568 						pi1ppc_get_intr_mask(pi1ppc),
1569 						pi1ppc_get_intr_stat(pi1ppc),
1570 						cur);
1571 	}
1572 #endif
1573 
1574 	return error;
1575 }
1576 
1577