xref: /dragonfly/sys/bus/ppbus/ppb_base.c (revision b40e316c)
1 /*-
2  * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/sys/dev/ppbus/ppb_base.c,v 1.10.2.1 2000/08/01 23:26:26 n_hibma Exp $
27  * $DragonFly: src/sys/bus/ppbus/ppb_base.c,v 1.5 2003/08/07 21:16:47 dillon Exp $
28  *
29  */
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/bus.h>
35 
36 #include <machine/clock.h>
37 
38 #include "ppbconf.h"
39 
40 #include "ppbus_if.h"
41 
42 #include "ppbio.h"
43 
44 #define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev))
45 
46 /*
47  * ppb_poll_bus()
48  *
49  * Polls the bus
50  *
51  * max is a delay in 10-milliseconds
52  */
53 int
54 ppb_poll_bus(device_t bus, int max,
55 	     char mask, char status, int how)
56 {
57 	int i, j, error;
58 	char r;
59 
60 	/* try at least up to 10ms */
61 	for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) {
62 		for (i = 0; i < 10000; i++) {
63 			r = ppb_rstr(bus);
64 			DELAY(1);
65 			if ((r & mask) == status)
66 				return (0);
67 		}
68 	}
69 
70 	if (!(how & PPB_POLL)) {
71 	   for (i = 0; max == PPB_FOREVER || i < max-1; i++) {
72 		if ((ppb_rstr(bus) & mask) == status)
73 			return (0);
74 
75 		switch (how) {
76 		case PPB_NOINTR:
77 			/* wait 10 ms */
78 			tsleep((caddr_t)bus, 0, "ppbpoll", hz/100);
79 			break;
80 
81 		case PPB_INTR:
82 		default:
83 			/* wait 10 ms */
84 			if (((error = tsleep((caddr_t)bus, PCATCH,
85 			    "ppbpoll", hz/100)) != EWOULDBLOCK) != 0) {
86 				return (error);
87 			}
88 			break;
89 		}
90 	   }
91 	}
92 
93 	return (EWOULDBLOCK);
94 }
95 
96 /*
97  * ppb_get_epp_protocol()
98  *
99  * Return the chipset EPP protocol
100  */
101 int
102 ppb_get_epp_protocol(device_t bus)
103 {
104 	uintptr_t protocol;
105 
106 	BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol);
107 
108 	return (protocol);
109 }
110 
111 /*
112  * ppb_get_mode()
113  *
114  */
115 int
116 ppb_get_mode(device_t bus)
117 {
118 	struct ppb_data *ppb = DEVTOSOFTC(bus);
119 
120 	/* XXX yet device mode = ppbus mode = chipset mode */
121 	return (ppb->mode);
122 }
123 
124 /*
125  * ppb_set_mode()
126  *
127  * Set the operating mode of the chipset, return the previous mode
128  */
129 int
130 ppb_set_mode(device_t bus, int mode)
131 {
132 	struct ppb_data *ppb = DEVTOSOFTC(bus);
133 	int old_mode = ppb_get_mode(bus);
134 
135 	if (PPBUS_SETMODE(device_get_parent(bus), mode))
136 		return -1;
137 
138 		/* XXX yet device mode = ppbus mode = chipset mode */
139 		ppb->mode = (mode & PPB_MASK);
140 
141 	return (old_mode);
142 }
143 
144 /*
145  * ppb_write()
146  *
147  * Write charaters to the port
148  */
149 int
150 ppb_write(device_t bus, char *buf, int len, int how)
151 {
152 	return (PPBUS_WRITE(device_get_parent(bus), buf, len, how));
153 }
154 
155 /*
156  * ppb_reset_epp_timeout()
157  *
158  * Reset the EPP timeout bit in the status register
159  */
160 int
161 ppb_reset_epp_timeout(device_t bus)
162 {
163 	return(PPBUS_RESET_EPP(device_get_parent(bus)));
164 }
165 
166 /*
167  * ppb_ecp_sync()
168  *
169  * Wait for the ECP FIFO to be empty
170  */
171 int
172 ppb_ecp_sync(device_t bus)
173 {
174 	return (PPBUS_ECP_SYNC(device_get_parent(bus)));
175 }
176 
177 /*
178  * ppb_get_status()
179  *
180  * Read the status register and update the status info
181  */
182 int
183 ppb_get_status(device_t bus, struct ppb_status *status)
184 {
185 	char r;
186 
187 	r = status->status = ppb_rstr(bus);
188 
189 	status->timeout	= r & TIMEOUT;
190 	status->error	= !(r & nFAULT);
191 	status->select	= r & SELECT;
192 	status->paper_end = r & PERROR;
193 	status->ack	= !(r & nACK);
194 	status->busy	= !(r & nBUSY);
195 
196 	return (0);
197 }
198