Import 2.3.9
[davej-history.git] / drivers / pnp / parport_probe.c
blob8ae499311fc218a8f1681cf3e1c4f08e4e7d86bb
1 /* $Id: parport_probe.c,v 1.3 1997/10/19 18:18:46 phil Exp $
2 * Parallel port device probing code
3 *
4 * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
5 * Philip Blundell <Philip.Blundell@pobox.com>
6 */
8 #include <linux/tasks.h>
9 #include <linux/parport.h>
10 #include <linux/delay.h>
11 #include <linux/errno.h>
12 #include <linux/interrupt.h>
13 #include <linux/ioport.h>
14 #include <linux/kernel.h>
15 #include <linux/malloc.h>
16 #include <linux/ctype.h>
17 #include <linux/module.h>
19 #include <linux/lp.h>
21 #include <asm/io.h>
22 #include <asm/dma.h>
23 #include <asm/uaccess.h>
25 #undef DEBUG_PROBE
27 static inline int read_nibble(struct parport *port)
29 unsigned char i;
30 i = parport_read_status(port)>>3;
31 i &= ~8;
32 if ((i & 0x10) == 0) i |= 8;
33 return (i & 0x0f);
36 static void read_terminate(struct parport *port) {
37 parport_write_control(port, (parport_read_control(port) & ~2) | 8);
38 /* SelectIN high, AutoFeed low */
39 if (parport_wait_peripheral(port, 0x80, 0))
40 /* timeout, SelectIN high, Autofeed low */
41 return;
42 parport_write_control(port, parport_read_control(port) | 2);
43 /* AutoFeed high */
44 parport_wait_peripheral(port, 0x80, 0x80);
45 /* no timeout possible, Autofeed low, SelectIN high */
46 parport_write_control(port, (parport_read_control(port) & ~2) | 8);
49 static long read_polled(struct parport *port, char *buf,
50 unsigned long length)
52 int i;
53 char *temp=buf;
54 unsigned int count = 0;
55 unsigned char z=0;
56 unsigned char Byte=0;
57 unsigned long igiveupat=jiffies+5*HZ;
59 for (i=0; time_before(jiffies, igiveupat); i++) {
60 /* if(current->need_resched) schedule(); */
61 parport_write_control(port, parport_read_control(port) | 2); /* AutoFeed high */
62 if (parport_wait_peripheral(port, 0x40, 0)) {
63 #ifdef DEBUG_PROBE
64 /* Some peripherals just time out when they've sent
65 all their data. */
66 printk("%s: read1 timeout.\n", port->name);
67 #endif
68 parport_write_control(port, parport_read_control(port) & ~2);
69 break;
71 z = read_nibble(port);
72 parport_write_control(port, parport_read_control(port) & ~2); /* AutoFeed low */
73 if (parport_wait_peripheral(port, 0x40, 0x40)) {
74 printk("%s: read2 timeout.\n", port->name);
75 break;
77 if ((i & 1) != 0) {
78 Byte |= (z<<4);
79 if (temp)
80 *(temp++) = Byte;
81 if (++count == length)
82 temp = NULL;
83 /* Does the error line indicate end of data? */
84 if ((parport_read_status(port) & LP_PERRORP) ==
85 LP_PERRORP)
86 break;
87 } else
88 Byte=z;
90 read_terminate(port);
91 return count;
94 int parport_probe(struct parport *port, char *buffer, int len)
96 struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, 0, &dev);
98 int result = 0;
100 if (!dev) {
101 printk("%s: unable to register for probe.\n", port->name);
102 return -EINVAL;
105 parport_claim_or_block(dev);
107 switch (parport_ieee1284_nibble_mode_ok(port, 4)) {
108 case 2:
109 current->state=TASK_INTERRUPTIBLE;
110 /* HACK: wait 10ms because printer seems to ack wrong */
111 schedule_timeout((HZ+99)/100);
112 result = read_polled(port, buffer, len);
113 break;
114 default:
115 result = -EIO;
116 break;
119 parport_release(dev);
120 parport_unregister_device(dev);
122 return result;
125 static struct {
126 char *token;
127 char *descr;
128 } classes[] = {
129 { "", "Legacy device" },
130 { "PRINTER", "Printer" },
131 { "MODEM", "Modem" },
132 { "NET", "Network device" },
133 { "HDC", "Hard disk" },
134 { "PCMCIA", "PCMCIA" },
135 { "MEDIA", "Multimedia device" },
136 { "FDC", "Floppy disk" },
137 { "PORTS", "Ports" },
138 { "SCANNER", "Scanner" },
139 { "DIGICAM", "Digital camera" },
140 { "", "Unknown device" },
141 { "", "Unspecified" },
142 { NULL, NULL }
145 static char *strdup(char *str)
147 int n = strlen(str)+1;
148 char *s = kmalloc(n, GFP_KERNEL);
149 if (!s) return NULL;
150 return strcpy(s, str);
153 static void parse_data(struct parport *port, char *str)
155 char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
156 char *p = txt, *q;
157 int guessed_class = PARPORT_CLASS_UNSPEC;
159 if (!txt) {
160 printk("%s probe: memory squeeze\n", port->name);
161 return;
163 strcpy(txt, str);
164 while (p) {
165 char *sep;
166 q = strchr(p, ';');
167 if (q) *q = 0;
168 sep = strchr(p, ':');
169 if (sep) {
170 char *u = p;
171 *(sep++) = 0;
172 while (*u) {
173 *u = toupper(*u);
174 u++;
176 if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
177 if (port->probe_info.mfr)
178 kfree (port->probe_info.mfr);
179 port->probe_info.mfr = strdup(sep);
180 } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
181 if (port->probe_info.model)
182 kfree (port->probe_info.model);
183 port->probe_info.model = strdup(sep);
184 } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
185 int i;
186 if (port->probe_info.class_name)
187 kfree (port->probe_info.class_name);
188 port->probe_info.class_name = strdup(sep);
189 for (u = sep; *u; u++)
190 *u = toupper(*u);
191 for (i = 0; classes[i].token; i++) {
192 if (!strcmp(classes[i].token, sep)) {
193 port->probe_info.class = i;
194 goto rock_on;
197 printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep);
198 port->probe_info.class = PARPORT_CLASS_OTHER;
199 } else if (!strcmp(p, "CMD") || !strcmp(p, "COMMAND SET")) {
200 if (port->probe_info.cmdset)
201 kfree (port->probe_info.cmdset);
202 port->probe_info.cmdset = strdup(sep);
203 /* if it speaks printer language, it's
204 probably a printer */
205 if (strstr(sep, "PJL") || strstr(sep, "PCL"))
206 guessed_class = PARPORT_CLASS_PRINTER;
207 } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
208 if (port->probe_info.description)
209 kfree (port->probe_info.description);
210 port->probe_info.description = strdup(sep);
213 rock_on:
214 if (q) p = q+1; else p=NULL;
217 /* If the device didn't tell us its class, maybe we have managed to
218 guess one from the things it did say. */
219 if (port->probe_info.class == PARPORT_CLASS_UNSPEC)
220 port->probe_info.class = guessed_class;
222 kfree(txt);
225 static void pretty_print(struct parport *port)
227 printk(KERN_INFO "%s: %s", port->name,
228 classes[port->probe_info.class].descr);
229 if (port->probe_info.class) {
230 printk(", %s %s", port->probe_info.mfr,
231 port->probe_info.model);
233 printk("\n");
236 void parport_probe_one(struct parport *port)
238 char *buffer = kmalloc(2048, GFP_KERNEL);
239 int r;
241 MOD_INC_USE_COUNT;
242 port->probe_info.model = strdup ("Unknown device");
243 port->probe_info.mfr = strdup ("Unknown vendor");
244 port->probe_info.description = port->probe_info.cmdset = NULL;
245 port->probe_info.class = PARPORT_CLASS_UNSPEC;
246 port->probe_info.class_name = NULL;
248 if (!buffer) {
249 printk(KERN_ERR "%s probe: Memory squeeze.\n", port->name);
250 return;
253 r = parport_probe(port, buffer, 2047);
255 if (r < 0) {
256 printk(KERN_INFO "%s: no IEEE-1284 device present.\n",
257 port->name);
258 port->probe_info.class = PARPORT_CLASS_LEGACY;
259 } else if (r == 0) {
260 printk(KERN_INFO "%s: no ID data returned by device.\n",
261 port->name);
262 } else {
263 buffer[r] = 0;
264 #ifdef DEBUG_PROBE
265 printk("%s id: %s\n", port->name, buffer+2);
266 #endif
267 parse_data(port, buffer+2);
268 pretty_print(port);
270 kfree(buffer);
271 MOD_DEC_USE_COUNT;
274 #if MODULE
275 int init_module(void)
277 struct parport *p;
278 for (p = parport_enumerate(); p; p = p->next)
279 parport_probe_one(p);
280 parport_probe_hook = &parport_probe_one;
281 return 0;
284 void cleanup_module(void)
286 parport_probe_hook = NULL;
288 #endif