1 /* $NetBSD: ppbus_base.c,v 1.16 2008/04/08 07:35:35 cegger Exp $ */
4 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
28 * FreeBSD: src/sys/dev/ppbus/ppb_base.c,v 1.10.2.1 2000/08/01 23:26:26 n_hibma Exp
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ppbus_base.c,v 1.16 2008/04/08 07:35:35 cegger Exp $");
35 #include "opt_ppbus_1284.h"
36 #include "opt_ppbus.h"
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
42 #include <sys/systm.h>
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>
51 #ifndef DONTPROBE_1284
52 /* Utility functions */
53 static char * search_token(char *, int, const char *);
56 /* Perform general ppbus I/O request */
58 ppbus_io(device_t dev
, int iop
, u_char
* addr
, int cnt
, u_char byte
)
60 struct ppbus_softc
* bus
= device_private(dev
);
61 return (bus
->ppbus_io(device_parent(dev
), iop
, addr
, cnt
, byte
));
64 /* Execute microsequence */
66 ppbus_exec_microseq(device_t dev
, struct ppbus_microseq
** sequence
)
68 struct ppbus_softc
* bus
= device_private(dev
);
69 return (bus
->ppbus_exec_microseq(device_parent(dev
), sequence
));
72 /* Read instance variables of ppbus */
74 ppbus_read_ivar(device_t dev
, int index
, unsigned int * val
)
77 struct ppbus_softc
* bus
= device_private(dev
);
81 case PPBUS_IVAR_EPP_PROTO
:
83 return (bus
->ppbus_read_ivar(device_parent(dev
), index
, val
));
86 *val
= (bus
->sc_use_ieee
== PPBUS_ENABLE_IEEE
) ? 1 : 0;
96 /* Write an instance variable */
98 ppbus_write_ivar(device_t dev
, int index
, unsigned int * val
)
100 struct ppbus_softc
* bus
= device_private(dev
);
103 case PPBUS_IVAR_INTR
:
104 case PPBUS_IVAR_EPP_PROTO
:
106 return (bus
->ppbus_write_ivar(device_parent(dev
), index
, val
));
108 case PPBUS_IVAR_IEEE
:
109 bus
->sc_use_ieee
= ((*val
!= 0) ? PPBUS_ENABLE_IEEE
:
120 /* Polls the bus for a max of 10-milliseconds */
122 ppbus_poll_bus(device_t dev
, int maxp
, char mask
, char status
,
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
++) {
133 if ((r
& mask
) == status
)
138 if (!(how
& PPBUS_POLL
)) {
139 for (i
= 0; maxp
== PPBUS_FOREVER
|| i
< maxp
-1; i
++) {
140 if ((ppbus_rstr(dev
) & mask
) == status
)
146 tsleep((void *)dev
, PPBUSPRI
, "ppbuspoll", hz
/100);
152 if (((error
= tsleep((void *)dev
, PPBUSPRI
| PCATCH
,
153 "ppbuspoll", hz
/100)) != EWOULDBLOCK
) != 0) {
161 return (EWOULDBLOCK
);
164 /* Get operating mode of the chipset */
166 ppbus_get_mode(device_t dev
)
168 struct ppbus_softc
* bus
= device_private(dev
);
170 return (bus
->sc_mode
);
173 /* Set the operating mode of the chipset, return 0 on success. */
175 ppbus_set_mode(device_t dev
, int mode
, int options
)
177 struct ppbus_softc
* bus
= device_private(dev
);
180 /* If no mode change, do nothing */
181 if(bus
->sc_mode
== mode
)
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
);
190 /* Termination is unnecessary for standard<->fast */
191 else if(!(bus
->sc_mode
& (PPBUS_FAST
| PPBUS_COMPATIBLE
))) {
192 ppbus_1284_terminate(dev
);
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
));
202 /* Update host state if necessary */
203 if(!(error
) && (bus
->sc_use_ieee
== PPBUS_ENABLE_IEEE
)) {
205 case PPBUS_COMPATIBLE
:
209 ppbus_1284_set_state(dev
, PPBUS_FORWARD_IDLE
);
214 ppbus_1284_set_state(dev
, PPBUS_REVERSE_IDLE
);
222 /* Write charaters to the port */
224 ppbus_write(device_t dev
, char * buf
, int len
, int how
, size_t * cnt
)
226 struct ppbus_softc
* bus
= device_private(dev
);
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
));
236 return (bus
->ppbus_write(device_parent(bus
->sc_dev
), buf
, len
, how
, cnt
));
239 /* Read charaters from the port */
241 ppbus_read(device_t dev
, char * buf
, int len
, int how
, size_t * cnt
)
243 struct ppbus_softc
* bus
= device_private(dev
);
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
));
253 return (bus
->ppbus_read(device_parent(dev
), buf
, len
, how
, cnt
));
256 /* Reset the EPP timeout bit in the status register */
258 ppbus_reset_epp_timeout(device_t dev
)
260 struct ppbus_softc
* bus
= device_private(dev
);
262 if(bus
->sc_capabilities
& PPBUS_HAS_EPP
) {
263 bus
->ppbus_reset_epp_timeout(device_parent(dev
));
271 /* Wait for the ECP FIFO to be empty */
273 ppbus_ecp_sync(device_t dev
)
275 struct ppbus_softc
* bus
= device_private(dev
);
277 if(bus
->sc_capabilities
& PPBUS_HAS_ECP
) {
278 bus
->ppbus_ecp_sync(device_parent(dev
));
286 /* Allocate DMA for use with ppbus */
288 ppbus_dma_malloc(device_t dev
, void ** buf
, bus_addr_t
* addr
,
291 struct ppbus_softc
* ppbus
= device_private(dev
);
293 if(ppbus
->sc_capabilities
& PPBUS_HAS_DMA
)
294 return (ppbus
->ppbus_dma_malloc(device_parent(dev
), buf
, addr
,
300 /* Free memory allocated with ppbus_dma_malloc() */
302 ppbus_dma_free(device_t dev
, void ** buf
, bus_addr_t
* addr
,
305 struct ppbus_softc
* ppbus
= device_private(dev
);
307 if(ppbus
->sc_capabilities
& PPBUS_HAS_DMA
) {
308 ppbus
->ppbus_dma_free(device_parent(dev
), buf
, addr
, size
);
316 /* Install a handler to be called by hardware interrupt handler */
317 int ppbus_add_handler(device_t dev
, void (*func
)(void *), void *arg
)
319 struct ppbus_softc
* bus
= device_private(dev
);
321 if(bus
->sc_capabilities
& PPBUS_HAS_INTR
)
322 return bus
->ppbus_add_handler(device_parent(dev
), func
, arg
);
327 /* Remove a handler registered with ppbus_add_handler() */
328 int ppbus_remove_handler(device_t dev
, void (*func
)(void *))
330 struct ppbus_softc
* bus
= device_private(dev
);
332 if(bus
->sc_capabilities
& PPBUS_HAS_INTR
)
333 return bus
->ppbus_remove_handler(device_parent(dev
), func
);
341 * Read the status register and update the status info
344 ppbus_get_status(device_t dev
, struct ppbus_status
* status
)
346 register char r
= status
->status
= ppbus_rstr(dev
);
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
);
358 /* Allocate the device to perform transfers */
360 ppbus_request_bus(device_t dev
, device_t busdev
, int how
,
361 unsigned int timeout
)
363 struct ppbus_softc
* bus
= device_private(dev
);
364 unsigned int counter
= timeout
;
365 int priority
= PPBUSPRI
;
371 /* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */
373 if (mutex_tryenter(&(bus
->sc_lock
)))
376 if(how
& PPBUS_WAIT
) {
377 error
= ltsleep(bus
, priority
, __func__
, hz
/2, NULL
);
381 else if(error
!= EWOULDBLOCK
)
394 /* Set bus owner or return error if bus is taken */
395 if(bus
->ppbus_owner
== NULL
) {
396 bus
->ppbus_owner
= busdev
;
404 mutex_exit(&(bus
->sc_lock
));
410 /* Release the device allocated with ppbus_request_bus() */
412 ppbus_release_bus(device_t dev
, device_t busdev
, int how
,
413 unsigned int timeout
)
415 struct ppbus_softc
* bus
= device_private(dev
);
416 unsigned int counter
= timeout
;
417 int priority
= PPBUSPRI
;
423 /* Loop until lock acquired (if PPBUS_WAIT) or an error occurs */
425 if (mutex_tryenter(&(bus
->sc_lock
)))
428 if(how
& PPBUS_WAIT
) {
429 error
= ltsleep(bus
, priority
, __func__
, hz
/2, NULL
);
433 else if(error
!= EWOULDBLOCK
)
446 /* If the device is the owner, release bus */
447 if(bus
->ppbus_owner
!= busdev
) {
451 bus
->ppbus_owner
= NULL
;
456 mutex_exit(&(bus
->sc_lock
));
463 /* IEEE 1284-based probes */
465 #ifndef DONTPROBE_1284
467 static const char *pnp_tokens
[] = {
468 "PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA",
469 "FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL
};
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
};
481 * Search the first occurence of a token within a string
482 * XXX should use strxxx() calls
485 search_token(char *str
, int slen
, const char *token
)
490 #define UNKNOWN_LENGTH -1
492 if (slen
== UNKNOWN_LENGTH
)
493 /* get string's length */
494 for (slen
= 0, p
= str
; *p
!= '\0'; p
++)
497 /* get token's length */
498 for (tlen
= 0, p
= token
; *p
!= '\0'; p
++)
504 for (i
= 0; i
<= slen
-tlen
; i
++) {
505 for (j
= 0; j
< tlen
; j
++)
506 if (str
[i
+j
] != token
[j
])
515 /* Stores the class ID of the peripherial in soft config data */
517 ppbus_pnp_detect(device_t dev
)
519 struct ppbus_softc
* bus
= device_private(dev
);
529 printf("%s: Probing for PnP devices.\n", device_xname(dev
));
532 error
= ppbus_1284_read_id(dev
, PPBUS_NIBBLE
, &str
, &str_sz
, &len
);
535 printf("%s(%s): device returned less characters than expected "
536 "in device ID.\n", __func__
, device_xname(dev
));
540 printf("%s: Error getting device ID (errno = %d)\n",
541 device_xname(dev
), error
);
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
]);
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]; */
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);
562 printf("%s: <unknown", device_xname(dev
));
564 if ((token
= search_token(str
, len
, "MDL")) != NULL
||
565 (token
= search_token(str
, len
, "MODEL")) != NULL
)
567 search_token(token
, UNKNOWN_LENGTH
, ":") + 1);
569 if ((token
= search_token(str
, len
, "REV")) != NULL
)
571 search_token(token
, UNKNOWN_LENGTH
, ":") + 1);
575 if ((token
= search_token(str
, len
, "CLS")) != NULL
) {
576 class = search_token(token
, UNKNOWN_LENGTH
, ":") + 1;
577 printf(" %s", class);
580 if ((token
= search_token(str
, len
, "CMD")) != NULL
||
581 (token
= search_token(str
, len
, "COMMAND")) != NULL
)
583 search_token(token
, UNKNOWN_LENGTH
, ":") + 1);
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
;
596 bus
->sc_class_id
= PPBUS_PNP_UNKNOWN
;
604 /* Scan the ppbus for IEEE1284 compliant devices */
606 ppbus_scan_bus(device_t dev
)
608 struct ppbus_softc
* bus
= device_private(dev
);
611 /* Try IEEE1284 modes, one device only (no IEEE1284.3 support) */
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
)
617 ppbus_1284_terminate(dev
);
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");
624 error
= ppbus_1284_negotiate(dev
, PPBUS_PS2
, 0);
627 ppbus_1284_terminate(dev
);
629 error
= ppbus_1284_negotiate(dev
, PPBUS_ECP
, 0);
632 ppbus_1284_terminate(dev
);
634 error
= ppbus_1284_negotiate(dev
, PPBUS_ECP
, PPBUS_USE_RLE
);
637 ppbus_1284_terminate(dev
);
639 error
= ppbus_1284_negotiate(dev
, PPBUS_EPP
, 0);
642 ppbus_1284_terminate(dev
);
645 #endif /* PPBUS_VERBOSE || PPBUS_DEBUG */
650 #endif /* !DONTPROBE_1284 */