xref: /netbsd/sys/dev/ppbus/ppbus_base.c (revision 6550d01e)
1 /* $NetBSD: ppbus_base.c,v 1.17 2008/04/15 15:02:29 cegger Exp $ */
2 
3 /*-
4  * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
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  * FreeBSD: src/sys/dev/ppbus/ppb_base.c,v 1.10.2.1 2000/08/01 23:26:26 n_hibma Exp
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ppbus_base.c,v 1.17 2008/04/15 15:02:29 cegger Exp $");
34 
35 #include "opt_ppbus_1284.h"
36 #include "opt_ppbus.h"
37 
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/proc.h>
42 #include <sys/systm.h>
43 
44 #include <dev/ppbus/ppbus_1284.h>
45 #include <dev/ppbus/ppbus_conf.h>
46 #include <dev/ppbus/ppbus_base.h>
47 #include <dev/ppbus/ppbus_device.h>
48 #include <dev/ppbus/ppbus_io.h>
49 #include <dev/ppbus/ppbus_var.h>
50 
51 #ifndef DONTPROBE_1284
52 /* Utility functions */
53 static char * search_token(char *, int, const char *);
54 #endif
55 
56 /* Perform general ppbus I/O request */
57 int
58 ppbus_io(device_t dev, int iop, u_char * addr, int cnt, u_char byte)
59 {
60 	struct ppbus_softc * bus = device_private(dev);
61 	return (bus->ppbus_io(device_parent(dev), iop, addr, cnt, byte));
62 }
63 
64 /* Execute microsequence */
65 int
66 ppbus_exec_microseq(device_t dev, struct ppbus_microseq ** sequence)
67 {
68 	struct ppbus_softc * bus = device_private(dev);
69 	return (bus->ppbus_exec_microseq(device_parent(dev), sequence));
70 }
71 
72 /* Read instance variables of ppbus */
73 int
74 ppbus_read_ivar(device_t dev, int index, unsigned int * val)
75 
76 {
77 	struct ppbus_softc * bus = device_private(dev);
78 
79 	switch (index) {
80 	case PPBUS_IVAR_INTR:
81 	case PPBUS_IVAR_EPP_PROTO:
82 	case PPBUS_IVAR_DMA:
83 		return (bus->ppbus_read_ivar(device_parent(dev), index, val));
84 
85 	case PPBUS_IVAR_IEEE:
86 		*val = (bus->sc_use_ieee == PPBUS_ENABLE_IEEE) ? 1 : 0;
87 		break;
88 
89 	default:
90 		return (ENOENT);
91 	}
92 
93 	return 0;
94 }
95 
96 /* Write an instance variable */
97 int
98 ppbus_write_ivar(device_t dev, int index, unsigned int * val)
99 {
100 	struct ppbus_softc * bus = device_private(dev);
101 
102 	switch (index) {
103 	case PPBUS_IVAR_INTR:
104 	case PPBUS_IVAR_EPP_PROTO:
105 	case PPBUS_IVAR_DMA:
106 		return (bus->ppbus_write_ivar(device_parent(dev), index, val));
107 
108 	case PPBUS_IVAR_IEEE:
109 		bus->sc_use_ieee = ((*val != 0) ? PPBUS_ENABLE_IEEE :
110 			PPBUS_DISABLE_IEEE);
111 		break;
112 
113 	default:
114 		return (ENOENT);
115 	}
116 
117 	return 0;
118 }
119 
120 /* Polls the bus for a max of 10-milliseconds */
121 int
122 ppbus_poll_bus(device_t dev, int maxp, char mask, char status,
123 	int how)
124 {
125 	int i, j, error;
126 	char r;
127 
128 	/* try at least up to 10ms */
129 	for (j = 0; j < ((how & PPBUS_POLL) ? maxp : 1); j++) {
130 		for (i = 0; i < 10000; i++) {
131 			r = ppbus_rstr(dev);
132 			DELAY(1);
133 			if ((r & mask) == status)
134 				return (0);
135 		}
136 	}
137 
138 	if (!(how & PPBUS_POLL)) {
139 	   for (i = 0; maxp == PPBUS_FOREVER || i < maxp-1; i++) {
140 		if ((ppbus_rstr(dev) & mask) == status)
141 			return (0);
142 
143 		switch (how) {
144 		case PPBUS_NOINTR:
145 			/* wait 10 ms */
146 			tsleep((void *)dev, PPBUSPRI, "ppbuspoll", hz/100);
147 			break;
148 
149 		case PPBUS_INTR:
150 		default:
151 			/* wait 10 ms */
152 			if (((error = tsleep((void *)dev, PPBUSPRI | PCATCH,
153 			    "ppbuspoll", hz/100)) != EWOULDBLOCK) != 0) {
154 				return (error);
155 			}
156 			break;
157 		}
158 	   }
159 	}
160 
161 	return (EWOULDBLOCK);
162 }
163 
164 /* Get operating mode of the chipset */
165 int
166 ppbus_get_mode(device_t dev)
167 {
168 	struct ppbus_softc * bus = device_private(dev);
169 
170 	return (bus->sc_mode);
171 }
172 
173 /* Set the operating mode of the chipset, return 0 on success. */
174 int
175 ppbus_set_mode(device_t dev, int mode, int options)
176 {
177 	struct ppbus_softc * bus = device_private(dev);
178 	int error = 0;
179 
180 	/* If no mode change, do nothing */
181 	if(bus->sc_mode == mode)
182 		return error;
183 
184 	/* Do necessary negotiations */
185 	if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) {
186 		/* Cannot negotiate standard mode */
187 		if(!(mode & (PPBUS_FAST | PPBUS_COMPATIBLE))) {
188  			error = ppbus_1284_negotiate(dev, mode, options);
189 		}
190 		/* Termination is unnecessary for standard<->fast */
191 		else if(!(bus->sc_mode & (PPBUS_FAST | PPBUS_COMPATIBLE))) {
192 			ppbus_1284_terminate(dev);
193 		}
194 	}
195 
196 	if(!error) {
197 		/* Set mode and update mode of ppbus to actual mode */
198 		error = bus->ppbus_setmode(device_parent(dev), mode);
199 		bus->sc_mode = bus->ppbus_getmode(device_parent(dev));
200 	}
201 
202 	/* Update host state if necessary */
203 	if(!(error) && (bus->sc_use_ieee == PPBUS_ENABLE_IEEE)) {
204 		switch(mode) {
205 		case PPBUS_COMPATIBLE:
206 		case PPBUS_FAST:
207 		case PPBUS_EPP:
208 		case PPBUS_ECP:
209 			ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
210 			break;
211 
212 		case PPBUS_NIBBLE:
213 		case PPBUS_PS2:
214 			ppbus_1284_set_state(dev, PPBUS_REVERSE_IDLE);
215 			break;
216 		}
217 	}
218 
219 	return error;
220 }
221 
222 /* Write charaters to the port */
223 int
224 ppbus_write(device_t dev, char * buf, int len, int how, size_t * cnt)
225 {
226 	struct ppbus_softc * bus = device_private(dev);
227 
228 	if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) {
229 		if(bus->sc_1284_state != PPBUS_FORWARD_IDLE) {
230 			printf("%s(%s): bus not in forward idle mode.\n",
231 				__func__, device_xname(dev));
232 			return ENODEV;
233 		}
234 	}
235 
236 	return (bus->ppbus_write(device_parent(bus->sc_dev), buf, len, how, cnt));
237 }
238 
239 /* Read charaters from the port */
240 int
241 ppbus_read(device_t dev, char * buf, int len, int how, size_t * cnt)
242 {
243 	struct ppbus_softc * bus = device_private(dev);
244 
245 	if(bus->sc_use_ieee == PPBUS_ENABLE_IEEE) {
246 		if(bus->sc_1284_state != PPBUS_REVERSE_IDLE) {
247 			printf("%s(%s): bus not in reverse idle mode.\n",
248 				__func__, device_xname(dev));
249 			return ENODEV;
250 		}
251 	}
252 
253 	return (bus->ppbus_read(device_parent(dev), buf, len, how, cnt));
254 }
255 
256 /* Reset the EPP timeout bit in the status register */
257 int
258 ppbus_reset_epp_timeout(device_t dev)
259 {
260 	struct ppbus_softc * bus = device_private(dev);
261 
262 	if(bus->sc_capabilities & PPBUS_HAS_EPP) {
263 		bus->ppbus_reset_epp_timeout(device_parent(dev));
264 		return 0;
265 	}
266 	else {
267 		return ENODEV;
268 	}
269 }
270 
271 /* Wait for the ECP FIFO to be empty */
272 int
273 ppbus_ecp_sync(device_t dev)
274 {
275 	struct ppbus_softc * bus = device_private(dev);
276 
277 	if(bus->sc_capabilities & PPBUS_HAS_ECP) {
278 		bus->ppbus_ecp_sync(device_parent(dev));
279 		return 0;
280 	}
281 	else {
282 		return ENODEV;
283 	}
284 }
285 
286 /* Allocate DMA for use with ppbus */
287 int
288 ppbus_dma_malloc(device_t dev, void ** buf, bus_addr_t * addr,
289 	bus_size_t size)
290 {
291 	struct ppbus_softc * ppbus = device_private(dev);
292 
293 	if(ppbus->sc_capabilities & PPBUS_HAS_DMA)
294 		return (ppbus->ppbus_dma_malloc(device_parent(dev), buf, addr,
295 			size));
296 	else
297 		return ENODEV;
298 }
299 
300 /* Free memory allocated with ppbus_dma_malloc() */
301 int
302 ppbus_dma_free(device_t dev, void ** buf, bus_addr_t * addr,
303 	bus_size_t size)
304 {
305 	struct ppbus_softc * ppbus = device_private(dev);
306 
307 	if(ppbus->sc_capabilities & PPBUS_HAS_DMA) {
308 		ppbus->ppbus_dma_free(device_parent(dev), buf, addr, size);
309 		return 0;
310 	}
311 	else {
312 		return ENODEV;
313 	}
314 }
315 
316 /* Install a handler to be called by hardware interrupt handler */
317 int ppbus_add_handler(device_t dev, void (*func)(void *), void *arg)
318 {
319 	struct ppbus_softc * bus = device_private(dev);
320 
321 	if(bus->sc_capabilities & PPBUS_HAS_INTR)
322 		return bus->ppbus_add_handler(device_parent(dev), func, arg);
323 	else
324 		return ENODEV;
325 }
326 
327 /* Remove a handler registered with ppbus_add_handler() */
328 int ppbus_remove_handler(device_t dev, void (*func)(void *))
329 {
330 	struct ppbus_softc * bus = device_private(dev);
331 
332 	if(bus->sc_capabilities & PPBUS_HAS_INTR)
333 		return bus->ppbus_remove_handler(device_parent(dev), func);
334 	else
335 		return ENODEV;
336 }
337 
338 /*
339  * ppbus_get_status()
340  *
341  * Read the status register and update the status info
342  */
343 int
344 ppbus_get_status(device_t dev, struct ppbus_status * status)
345 {
346 	register char r = status->status = ppbus_rstr(dev);
347 
348 	status->timeout	= r & TIMEOUT;
349 	status->error	= !(r & nFAULT);
350 	status->select	= r & SELECT;
351 	status->paper_end = r & PERROR;
352 	status->ack	= !(r & nACK);
353 	status->busy	= !(r & nBUSY);
354 
355 	return (0);
356 }
357 
358 /* Allocate the device to perform transfers */
359 int
360 ppbus_request_bus(device_t dev, device_t busdev, int how,
361 	unsigned int timeout)
362 {
363 	struct ppbus_softc * bus = device_private(dev);
364 	unsigned int counter = timeout;
365 	int priority = PPBUSPRI;
366 	int error;
367 
368 	if(how & PPBUS_INTR)
369 		priority |= PCATCH;
370 
371 	/* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */
372 	for(;;) {
373 		if (mutex_tryenter(&(bus->sc_lock)))
374 			break;
375 
376 		if(how & PPBUS_WAIT) {
377 			error = ltsleep(bus, priority, __func__, hz/2, NULL);
378 			counter -= (hz/2);
379 			if(!(error))
380 				continue;
381 			else if(error != EWOULDBLOCK)
382 				goto end;
383 			if(counter == 0) {
384 				error = ETIMEDOUT;
385 				goto end;
386 			}
387 		}
388 		else {
389 			error = EWOULDBLOCK;
390 			goto end;
391 		}
392 	}
393 
394 	/* Set bus owner or return error if bus is taken */
395 	if(bus->ppbus_owner == NULL) {
396 		bus->ppbus_owner = busdev;
397 		error = 0;
398 	}
399 	else {
400 		error = EBUSY;
401 	}
402 
403 	/* Release lock */
404 	mutex_exit(&(bus->sc_lock));
405 
406 end:
407 	return error;
408 }
409 
410 /* Release the device allocated with ppbus_request_bus() */
411 int
412 ppbus_release_bus(device_t dev, device_t busdev, int how,
413 	unsigned int timeout)
414 {
415 	struct ppbus_softc * bus = device_private(dev);
416 	unsigned int counter = timeout;
417 	int priority = PPBUSPRI;
418 	int error;
419 
420 	if(how & PPBUS_INTR)
421 		priority |= PCATCH;
422 
423 	/* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */
424 	for(;;) {
425 		if (mutex_tryenter(&(bus->sc_lock)))
426 			break;
427 
428 		if(how & PPBUS_WAIT) {
429 			error = ltsleep(bus, priority, __func__, hz/2, NULL);
430 			counter -= (hz/2);
431 			if(!(error))
432 				continue;
433 			else if(error != EWOULDBLOCK)
434 				goto end;
435 			if(counter == 0) {
436 				error = ETIMEDOUT;
437 				goto end;
438 			}
439 		}
440 		else {
441 			error = EWOULDBLOCK;
442 			goto end;
443 		}
444 	}
445 
446 	/* If the device is the owner, release bus */
447 	if(bus->ppbus_owner != busdev) {
448 		error = EINVAL;
449 	}
450 	else {
451 		bus->ppbus_owner = NULL;
452 		error = 0;
453 	}
454 
455 	/* Release lock */
456 	mutex_exit(&(bus->sc_lock));
457 
458 end:
459 	return error;
460 }
461 
462 
463 /* IEEE 1284-based probes */
464 
465 #ifndef DONTPROBE_1284
466 
467 static const char *pnp_tokens[] = {
468 	"PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA",
469 	"FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL };
470 
471 /* ??? */
472 #if 0
473 static char *pnp_classes[] = {
474 	"printer", "modem", "network device",
475 	"hard disk", "PCMCIA", "multimedia device",
476 	"floppy disk", "ports", "scanner",
477 	"digital camera", "unknown device", NULL };
478 #endif
479 
480 /*
481  * Search the first occurence of a token within a string
482  * XXX should use strxxx() calls
483  */
484 static char *
485 search_token(char *str, int slen, const char *token)
486 {
487 	const char *p;
488 	int tlen, i, j;
489 
490 #define UNKNOWN_LENGTH  -1
491 
492 	if (slen == UNKNOWN_LENGTH)
493 	       /* get string's length */
494 	       for (slen = 0, p = str; *p != '\0'; p++)
495 		       slen++;
496 
497        /* get token's length */
498        for (tlen = 0, p = token; *p != '\0'; p++)
499 	       tlen++;
500 
501        if (tlen == 0)
502 	       return (str);
503 
504        for (i = 0; i <= slen-tlen; i++) {
505 	       for (j = 0; j < tlen; j++)
506 		       if (str[i+j] != token[j])
507 			       break;
508 	       if (j == tlen)
509 		       return (&str[i]);
510        }
511 
512 	return (NULL);
513 }
514 
515 /* Stores the class ID of the peripherial in soft config data */
516 void
517 ppbus_pnp_detect(device_t dev)
518 {
519 	struct ppbus_softc * bus = device_private(dev);
520 	int i;
521 	int error;
522 	size_t len = 0;
523 	size_t str_sz = 0;
524 	char * str = NULL;
525 	char * class = NULL;
526 	char * token;
527 
528 #ifdef PPBUS_VERBOSE
529 	printf("%s: Probing for PnP devices.\n", device_xname(dev));
530 #endif
531 
532 	error = ppbus_1284_read_id(dev, PPBUS_NIBBLE, &str, &str_sz, &len);
533 	if(str_sz != len) {
534 #ifdef DEBUG_1284
535 		printf("%s(%s): device returned less characters than expected "
536 			"in device ID.\n", __func__, device_xname(dev));
537 #endif
538 	}
539 	if(error) {
540 		printf("%s: Error getting device ID (errno = %d)\n",
541 			device_xname(dev), error);
542 		goto end_detect;
543 	}
544 
545 #ifdef DEBUG_1284
546 	printf("%s: <PnP> %d characters: ", device_xname(dev), len);
547 	for (i = 0; i < len; i++)
548 		printf("%c(0x%x) ", str[i], str[i]);
549 	printf("\n");
550 #endif
551 
552 	/* replace ';' characters by '\0' */
553 	for (i = 0; i < len; i++)
554 		if(str[i] == ';') str[i] = '\0';
555 		/* str[i] = (str[i] == ';') ? '\0' : str[i]; */
556 
557 	if ((token = search_token(str, len, "MFG")) != NULL ||
558 		(token = search_token(str, len, "MANUFACTURER")) != NULL)
559 		printf("%s: <%s", device_xname(dev),
560 			search_token(token, UNKNOWN_LENGTH, ":") + 1);
561 	else
562 		printf("%s: <unknown", device_xname(dev));
563 
564 	if ((token = search_token(str, len, "MDL")) != NULL ||
565 		(token = search_token(str, len, "MODEL")) != NULL)
566 		printf(" %s",
567 			search_token(token, UNKNOWN_LENGTH, ":") + 1);
568 
569 	if ((token = search_token(str, len, "REV")) != NULL)
570 		printf(".%s",
571 			search_token(token, UNKNOWN_LENGTH, ":") + 1);
572 
573 	printf(">");
574 
575 	if ((token = search_token(str, len, "CLS")) != NULL) {
576 		class = search_token(token, UNKNOWN_LENGTH, ":") + 1;
577 		printf(" %s", class);
578 	}
579 
580 	if ((token = search_token(str, len, "CMD")) != NULL ||
581 		(token = search_token(str, len, "COMMAND")) != NULL)
582 		printf(" %s",
583 			search_token(token, UNKNOWN_LENGTH, ":") + 1);
584 
585 	printf("\n");
586 
587 	if (class) {
588 		/* identify class ident */
589 		for (i = 0; pnp_tokens[i] != NULL; i++) {
590 			if (search_token(class, len, pnp_tokens[i]) != NULL) {
591 				bus->sc_class_id = i;
592 				goto end_detect;
593 			}
594 		}
595 	}
596 	bus->sc_class_id = PPBUS_PNP_UNKNOWN;
597 
598 end_detect:
599 	if(str)
600 		free(str, M_DEVBUF);
601         return;
602 }
603 
604 /* Scan the ppbus for IEEE1284 compliant devices */
605 int
606 ppbus_scan_bus(device_t dev)
607 {
608 	struct ppbus_softc * bus = device_private(dev);
609 	int error;
610 
611 	/* Try IEEE1284 modes, one device only (no IEEE1284.3 support) */
612 
613 	error = ppbus_1284_negotiate(dev, PPBUS_NIBBLE, 0);
614 	if (error && bus->sc_1284_state == PPBUS_ERROR
615 	    && bus->sc_1284_error == PPBUS_NOT_IEEE1284)
616 		return (error);
617 	ppbus_1284_terminate(dev);
618 
619 #if defined(PPBUS_VERBOSE) || defined(PPBUS_DEBUG)
620 	/* IEEE1284 supported, print info */
621 	printf("%s: IEEE1284 negotiation: modes %s",
622 	    device_xname(dev), "NIBBLE");
623 
624 	error = ppbus_1284_negotiate(dev, PPBUS_PS2, 0);
625 	if (!error)
626 		printf("/PS2");
627 	ppbus_1284_terminate(dev);
628 
629 	error = ppbus_1284_negotiate(dev, PPBUS_ECP, 0);
630 	if (!error)
631 		printf("/ECP");
632 	ppbus_1284_terminate(dev);
633 
634 	error = ppbus_1284_negotiate(dev, PPBUS_ECP, PPBUS_USE_RLE);
635 	if (!error)
636 		printf("/ECP_RLE");
637 	ppbus_1284_terminate(dev);
638 
639 	error = ppbus_1284_negotiate(dev, PPBUS_EPP, 0);
640 	if (!error)
641 		printf("/EPP");
642 	ppbus_1284_terminate(dev);
643 
644 	printf("\n");
645 #endif /* PPBUS_VERBOSE || PPBUS_DEBUG */
646 
647 	return 0;
648 }
649 
650 #endif /* !DONTPROBE_1284 */
651 
652