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