diff options
Diffstat (limited to 'drivers/parport/ieee1284.c')
-rw-r--r-- | drivers/parport/ieee1284.c | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c new file mode 100644 index 000000000000..694bae162fed --- /dev/null +++ b/drivers/parport/ieee1284.c | |||
@@ -0,0 +1,819 @@ | |||
1 | /* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $ | ||
2 | * IEEE-1284 implementation for parport. | ||
3 | * | ||
4 | * Authors: Phil Blundell <philb@gnu.org> | ||
5 | * Carsten Gross <carsten@sol.wohnheim.uni-ulm.de> | ||
6 | * Jose Renau <renau@acm.org> | ||
7 | * Tim Waugh <tim@cyberelk.demon.co.uk> (largely rewritten) | ||
8 | * | ||
9 | * This file is responsible for IEEE 1284 negotiation, and for handing | ||
10 | * read/write requests to low-level drivers. | ||
11 | * | ||
12 | * Any part of this program may be used in documents licensed under | ||
13 | * the GNU Free Documentation License, Version 1.1 or any later version | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * Various hacks, Fred Barnes <frmb2@ukc.ac.uk>, 04/2000 | ||
17 | */ | ||
18 | |||
19 | #include <linux/config.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/threads.h> | ||
22 | #include <linux/parport.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/sched.h> | ||
28 | |||
29 | #undef DEBUG /* undef me for production */ | ||
30 | |||
31 | #ifdef CONFIG_LP_CONSOLE | ||
32 | #undef DEBUG /* Don't want a garbled console */ | ||
33 | #endif | ||
34 | |||
35 | #ifdef DEBUG | ||
36 | #define DPRINTK(stuff...) printk (stuff) | ||
37 | #else | ||
38 | #define DPRINTK(stuff...) | ||
39 | #endif | ||
40 | |||
41 | /* Make parport_wait_peripheral wake up. | ||
42 | * It will be useful to call this from an interrupt handler. */ | ||
43 | static void parport_ieee1284_wakeup (struct parport *port) | ||
44 | { | ||
45 | up (&port->physport->ieee1284.irq); | ||
46 | } | ||
47 | |||
48 | static struct parport *port_from_cookie[PARPORT_MAX]; | ||
49 | static void timeout_waiting_on_port (unsigned long cookie) | ||
50 | { | ||
51 | parport_ieee1284_wakeup (port_from_cookie[cookie % PARPORT_MAX]); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * parport_wait_event - wait for an event on a parallel port | ||
56 | * @port: port to wait on | ||
57 | * @timeout: time to wait (in jiffies) | ||
58 | * | ||
59 | * This function waits for up to @timeout jiffies for an | ||
60 | * interrupt to occur on a parallel port. If the port timeout is | ||
61 | * set to zero, it returns immediately. | ||
62 | * | ||
63 | * If an interrupt occurs before the timeout period elapses, this | ||
64 | * function returns one immediately. If it times out, it returns | ||
65 | * a value greater than zero. An error code less than zero | ||
66 | * indicates an error (most likely a pending signal), and the | ||
67 | * calling code should finish what it's doing as soon as it can. | ||
68 | */ | ||
69 | |||
70 | int parport_wait_event (struct parport *port, signed long timeout) | ||
71 | { | ||
72 | int ret; | ||
73 | struct timer_list timer; | ||
74 | |||
75 | if (!port->physport->cad->timeout) | ||
76 | /* Zero timeout is special, and we can't down() the | ||
77 | semaphore. */ | ||
78 | return 1; | ||
79 | |||
80 | init_timer (&timer); | ||
81 | timer.expires = jiffies + timeout; | ||
82 | timer.function = timeout_waiting_on_port; | ||
83 | port_from_cookie[port->number % PARPORT_MAX] = port; | ||
84 | timer.data = port->number; | ||
85 | |||
86 | add_timer (&timer); | ||
87 | ret = down_interruptible (&port->physport->ieee1284.irq); | ||
88 | if (!del_timer (&timer) && !ret) | ||
89 | /* Timed out. */ | ||
90 | ret = 1; | ||
91 | |||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * parport_poll_peripheral - poll status lines | ||
97 | * @port: port to watch | ||
98 | * @mask: status lines to watch | ||
99 | * @result: desired values of chosen status lines | ||
100 | * @usec: timeout | ||
101 | * | ||
102 | * This function busy-waits until the masked status lines have | ||
103 | * the desired values, or until the timeout period elapses. The | ||
104 | * @mask and @result parameters are bitmasks, with the bits | ||
105 | * defined by the constants in parport.h: %PARPORT_STATUS_BUSY, | ||
106 | * and so on. | ||
107 | * | ||
108 | * This function does not call schedule(); instead it busy-waits | ||
109 | * using udelay(). It currently has a resolution of 5usec. | ||
110 | * | ||
111 | * If the status lines take on the desired values before the | ||
112 | * timeout period elapses, parport_poll_peripheral() returns zero | ||
113 | * immediately. A zero return value greater than zero indicates | ||
114 | * a timeout. An error code (less than zero) indicates an error, | ||
115 | * most likely a signal that arrived, and the caller should | ||
116 | * finish what it is doing as soon as possible. | ||
117 | */ | ||
118 | |||
119 | int parport_poll_peripheral(struct parport *port, | ||
120 | unsigned char mask, | ||
121 | unsigned char result, | ||
122 | int usec) | ||
123 | { | ||
124 | /* Zero return code is success, >0 is timeout. */ | ||
125 | int count = usec / 5 + 2; | ||
126 | int i; | ||
127 | unsigned char status; | ||
128 | for (i = 0; i < count; i++) { | ||
129 | status = parport_read_status (port); | ||
130 | if ((status & mask) == result) | ||
131 | return 0; | ||
132 | if (signal_pending (current)) | ||
133 | return -EINTR; | ||
134 | if (need_resched()) | ||
135 | break; | ||
136 | if (i >= 2) | ||
137 | udelay (5); | ||
138 | } | ||
139 | |||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * parport_wait_peripheral - wait for status lines to change in 35ms | ||
145 | * @port: port to watch | ||
146 | * @mask: status lines to watch | ||
147 | * @result: desired values of chosen status lines | ||
148 | * | ||
149 | * This function waits until the masked status lines have the | ||
150 | * desired values, or until 35ms have elapsed (see IEEE 1284-1994 | ||
151 | * page 24 to 25 for why this value in particular is hardcoded). | ||
152 | * The @mask and @result parameters are bitmasks, with the bits | ||
153 | * defined by the constants in parport.h: %PARPORT_STATUS_BUSY, | ||
154 | * and so on. | ||
155 | * | ||
156 | * The port is polled quickly to start off with, in anticipation | ||
157 | * of a fast response from the peripheral. This fast polling | ||
158 | * time is configurable (using /proc), and defaults to 500usec. | ||
159 | * If the timeout for this port (see parport_set_timeout()) is | ||
160 | * zero, the fast polling time is 35ms, and this function does | ||
161 | * not call schedule(). | ||
162 | * | ||
163 | * If the timeout for this port is non-zero, after the fast | ||
164 | * polling fails it uses parport_wait_event() to wait for up to | ||
165 | * 10ms, waking up if an interrupt occurs. | ||
166 | */ | ||
167 | |||
168 | int parport_wait_peripheral(struct parport *port, | ||
169 | unsigned char mask, | ||
170 | unsigned char result) | ||
171 | { | ||
172 | int ret; | ||
173 | int usec; | ||
174 | unsigned long deadline; | ||
175 | unsigned char status; | ||
176 | |||
177 | usec = port->physport->spintime; /* usecs of fast polling */ | ||
178 | if (!port->physport->cad->timeout) | ||
179 | /* A zero timeout is "special": busy wait for the | ||
180 | entire 35ms. */ | ||
181 | usec = 35000; | ||
182 | |||
183 | /* Fast polling. | ||
184 | * | ||
185 | * This should be adjustable. | ||
186 | * How about making a note (in the device structure) of how long | ||
187 | * it takes, so we know for next time? | ||
188 | */ | ||
189 | ret = parport_poll_peripheral (port, mask, result, usec); | ||
190 | if (ret != 1) | ||
191 | return ret; | ||
192 | |||
193 | if (!port->physport->cad->timeout) | ||
194 | /* We may be in an interrupt handler, so we can't poll | ||
195 | * slowly anyway. */ | ||
196 | return 1; | ||
197 | |||
198 | /* 40ms of slow polling. */ | ||
199 | deadline = jiffies + (HZ + 24) / 25; | ||
200 | while (time_before (jiffies, deadline)) { | ||
201 | int ret; | ||
202 | |||
203 | if (signal_pending (current)) | ||
204 | return -EINTR; | ||
205 | |||
206 | /* Wait for 10ms (or until an interrupt occurs if | ||
207 | * the handler is set) */ | ||
208 | if ((ret = parport_wait_event (port, (HZ + 99) / 100)) < 0) | ||
209 | return ret; | ||
210 | |||
211 | status = parport_read_status (port); | ||
212 | if ((status & mask) == result) | ||
213 | return 0; | ||
214 | |||
215 | if (!ret) { | ||
216 | /* parport_wait_event didn't time out, but the | ||
217 | * peripheral wasn't actually ready either. | ||
218 | * Wait for another 10ms. */ | ||
219 | __set_current_state (TASK_INTERRUPTIBLE); | ||
220 | schedule_timeout ((HZ+ 99) / 100); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | #ifdef CONFIG_PARPORT_1284 | ||
228 | /* Terminate a negotiated mode. */ | ||
229 | static void parport_ieee1284_terminate (struct parport *port) | ||
230 | { | ||
231 | int r; | ||
232 | port = port->physport; | ||
233 | |||
234 | /* EPP terminates differently. */ | ||
235 | switch (port->ieee1284.mode) { | ||
236 | case IEEE1284_MODE_EPP: | ||
237 | case IEEE1284_MODE_EPPSL: | ||
238 | case IEEE1284_MODE_EPPSWE: | ||
239 | /* Terminate from EPP mode. */ | ||
240 | |||
241 | /* Event 68: Set nInit low */ | ||
242 | parport_frob_control (port, PARPORT_CONTROL_INIT, 0); | ||
243 | udelay (50); | ||
244 | |||
245 | /* Event 69: Set nInit high, nSelectIn low */ | ||
246 | parport_frob_control (port, | ||
247 | PARPORT_CONTROL_SELECT | ||
248 | | PARPORT_CONTROL_INIT, | ||
249 | PARPORT_CONTROL_SELECT | ||
250 | | PARPORT_CONTROL_INIT); | ||
251 | break; | ||
252 | |||
253 | case IEEE1284_MODE_ECP: | ||
254 | case IEEE1284_MODE_ECPRLE: | ||
255 | case IEEE1284_MODE_ECPSWE: | ||
256 | /* In ECP we can only terminate from fwd idle phase. */ | ||
257 | if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE) { | ||
258 | /* Event 47: Set nInit high */ | ||
259 | parport_frob_control (port, | ||
260 | PARPORT_CONTROL_INIT | ||
261 | | PARPORT_CONTROL_AUTOFD, | ||
262 | PARPORT_CONTROL_INIT | ||
263 | | PARPORT_CONTROL_AUTOFD); | ||
264 | |||
265 | /* Event 49: PError goes high */ | ||
266 | r = parport_wait_peripheral (port, | ||
267 | PARPORT_STATUS_PAPEROUT, | ||
268 | PARPORT_STATUS_PAPEROUT); | ||
269 | if (r) | ||
270 | DPRINTK (KERN_INFO "%s: Timeout at event 49\n", | ||
271 | port->name); | ||
272 | |||
273 | parport_data_forward (port); | ||
274 | DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", | ||
275 | port->name); | ||
276 | port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
277 | } | ||
278 | |||
279 | /* fall-though.. */ | ||
280 | |||
281 | default: | ||
282 | /* Terminate from all other modes. */ | ||
283 | |||
284 | /* Event 22: Set nSelectIn low, nAutoFd high */ | ||
285 | parport_frob_control (port, | ||
286 | PARPORT_CONTROL_SELECT | ||
287 | | PARPORT_CONTROL_AUTOFD, | ||
288 | PARPORT_CONTROL_SELECT); | ||
289 | |||
290 | /* Event 24: nAck goes low */ | ||
291 | r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); | ||
292 | if (r) | ||
293 | DPRINTK (KERN_INFO "%s: Timeout at event 24\n", | ||
294 | port->name); | ||
295 | |||
296 | /* Event 25: Set nAutoFd low */ | ||
297 | parport_frob_control (port, | ||
298 | PARPORT_CONTROL_AUTOFD, | ||
299 | PARPORT_CONTROL_AUTOFD); | ||
300 | |||
301 | /* Event 27: nAck goes high */ | ||
302 | r = parport_wait_peripheral (port, | ||
303 | PARPORT_STATUS_ACK, | ||
304 | PARPORT_STATUS_ACK); | ||
305 | if (r) | ||
306 | DPRINTK (KERN_INFO "%s: Timeout at event 27\n", | ||
307 | port->name); | ||
308 | |||
309 | /* Event 29: Set nAutoFd high */ | ||
310 | parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); | ||
311 | } | ||
312 | |||
313 | port->ieee1284.mode = IEEE1284_MODE_COMPAT; | ||
314 | port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
315 | |||
316 | DPRINTK (KERN_DEBUG "%s: In compatibility (forward idle) mode\n", | ||
317 | port->name); | ||
318 | } | ||
319 | #endif /* IEEE1284 support */ | ||
320 | |||
321 | /** | ||
322 | * parport_negotiate - negotiate an IEEE 1284 mode | ||
323 | * @port: port to use | ||
324 | * @mode: mode to negotiate to | ||
325 | * | ||
326 | * Use this to negotiate to a particular IEEE 1284 transfer mode. | ||
327 | * The @mode parameter should be one of the constants in | ||
328 | * parport.h starting %IEEE1284_MODE_xxx. | ||
329 | * | ||
330 | * The return value is 0 if the peripheral has accepted the | ||
331 | * negotiation to the mode specified, -1 if the peripheral is not | ||
332 | * IEEE 1284 compliant (or not present), or 1 if the peripheral | ||
333 | * has rejected the negotiation. | ||
334 | */ | ||
335 | |||
336 | int parport_negotiate (struct parport *port, int mode) | ||
337 | { | ||
338 | #ifndef CONFIG_PARPORT_1284 | ||
339 | if (mode == IEEE1284_MODE_COMPAT) | ||
340 | return 0; | ||
341 | printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); | ||
342 | return -1; | ||
343 | #else | ||
344 | int m = mode & ~IEEE1284_ADDR; | ||
345 | int r; | ||
346 | unsigned char xflag; | ||
347 | |||
348 | port = port->physport; | ||
349 | |||
350 | /* Is there anything to do? */ | ||
351 | if (port->ieee1284.mode == mode) | ||
352 | return 0; | ||
353 | |||
354 | /* Is the difference just an address-or-not bit? */ | ||
355 | if ((port->ieee1284.mode & ~IEEE1284_ADDR) == (mode & ~IEEE1284_ADDR)){ | ||
356 | port->ieee1284.mode = mode; | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | /* Go to compability forward idle mode */ | ||
361 | if (port->ieee1284.mode != IEEE1284_MODE_COMPAT) | ||
362 | parport_ieee1284_terminate (port); | ||
363 | |||
364 | if (mode == IEEE1284_MODE_COMPAT) | ||
365 | /* Compatibility mode: no negotiation. */ | ||
366 | return 0; | ||
367 | |||
368 | switch (mode) { | ||
369 | case IEEE1284_MODE_ECPSWE: | ||
370 | m = IEEE1284_MODE_ECP; | ||
371 | break; | ||
372 | case IEEE1284_MODE_EPPSL: | ||
373 | case IEEE1284_MODE_EPPSWE: | ||
374 | m = IEEE1284_MODE_EPP; | ||
375 | break; | ||
376 | case IEEE1284_MODE_BECP: | ||
377 | return -ENOSYS; /* FIXME (implement BECP) */ | ||
378 | } | ||
379 | |||
380 | if (mode & IEEE1284_EXT_LINK) | ||
381 | m = 1<<7; /* request extensibility link */ | ||
382 | |||
383 | port->ieee1284.phase = IEEE1284_PH_NEGOTIATION; | ||
384 | |||
385 | /* Start off with nStrobe and nAutoFd high, and nSelectIn low */ | ||
386 | parport_frob_control (port, | ||
387 | PARPORT_CONTROL_STROBE | ||
388 | | PARPORT_CONTROL_AUTOFD | ||
389 | | PARPORT_CONTROL_SELECT, | ||
390 | PARPORT_CONTROL_SELECT); | ||
391 | udelay(1); | ||
392 | |||
393 | /* Event 0: Set data */ | ||
394 | parport_data_forward (port); | ||
395 | parport_write_data (port, m); | ||
396 | udelay (400); /* Shouldn't need to wait this long. */ | ||
397 | |||
398 | /* Event 1: Set nSelectIn high, nAutoFd low */ | ||
399 | parport_frob_control (port, | ||
400 | PARPORT_CONTROL_SELECT | ||
401 | | PARPORT_CONTROL_AUTOFD, | ||
402 | PARPORT_CONTROL_AUTOFD); | ||
403 | |||
404 | /* Event 2: PError, Select, nFault go high, nAck goes low */ | ||
405 | if (parport_wait_peripheral (port, | ||
406 | PARPORT_STATUS_ERROR | ||
407 | | PARPORT_STATUS_SELECT | ||
408 | | PARPORT_STATUS_PAPEROUT | ||
409 | | PARPORT_STATUS_ACK, | ||
410 | PARPORT_STATUS_ERROR | ||
411 | | PARPORT_STATUS_SELECT | ||
412 | | PARPORT_STATUS_PAPEROUT)) { | ||
413 | /* Timeout */ | ||
414 | parport_frob_control (port, | ||
415 | PARPORT_CONTROL_SELECT | ||
416 | | PARPORT_CONTROL_AUTOFD, | ||
417 | PARPORT_CONTROL_SELECT); | ||
418 | DPRINTK (KERN_DEBUG | ||
419 | "%s: Peripheral not IEEE1284 compliant (0x%02X)\n", | ||
420 | port->name, parport_read_status (port)); | ||
421 | port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
422 | return -1; /* Not IEEE1284 compliant */ | ||
423 | } | ||
424 | |||
425 | /* Event 3: Set nStrobe low */ | ||
426 | parport_frob_control (port, | ||
427 | PARPORT_CONTROL_STROBE, | ||
428 | PARPORT_CONTROL_STROBE); | ||
429 | |||
430 | /* Event 4: Set nStrobe and nAutoFd high */ | ||
431 | udelay (5); | ||
432 | parport_frob_control (port, | ||
433 | PARPORT_CONTROL_STROBE | ||
434 | | PARPORT_CONTROL_AUTOFD, | ||
435 | 0); | ||
436 | |||
437 | /* Event 6: nAck goes high */ | ||
438 | if (parport_wait_peripheral (port, | ||
439 | PARPORT_STATUS_ACK, | ||
440 | PARPORT_STATUS_ACK)) { | ||
441 | /* This shouldn't really happen with a compliant device. */ | ||
442 | DPRINTK (KERN_DEBUG | ||
443 | "%s: Mode 0x%02x not supported? (0x%02x)\n", | ||
444 | port->name, mode, port->ops->read_status (port)); | ||
445 | parport_ieee1284_terminate (port); | ||
446 | return 1; | ||
447 | } | ||
448 | |||
449 | xflag = parport_read_status (port) & PARPORT_STATUS_SELECT; | ||
450 | |||
451 | /* xflag should be high for all modes other than nibble (0). */ | ||
452 | if (mode && !xflag) { | ||
453 | /* Mode not supported. */ | ||
454 | DPRINTK (KERN_DEBUG "%s: Mode 0x%02x rejected by peripheral\n", | ||
455 | port->name, mode); | ||
456 | parport_ieee1284_terminate (port); | ||
457 | return 1; | ||
458 | } | ||
459 | |||
460 | /* More to do if we've requested extensibility link. */ | ||
461 | if (mode & IEEE1284_EXT_LINK) { | ||
462 | m = mode & 0x7f; | ||
463 | udelay (1); | ||
464 | parport_write_data (port, m); | ||
465 | udelay (1); | ||
466 | |||
467 | /* Event 51: Set nStrobe low */ | ||
468 | parport_frob_control (port, | ||
469 | PARPORT_CONTROL_STROBE, | ||
470 | PARPORT_CONTROL_STROBE); | ||
471 | |||
472 | /* Event 52: nAck goes low */ | ||
473 | if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) { | ||
474 | /* This peripheral is _very_ slow. */ | ||
475 | DPRINTK (KERN_DEBUG | ||
476 | "%s: Event 52 didn't happen\n", | ||
477 | port->name); | ||
478 | parport_ieee1284_terminate (port); | ||
479 | return 1; | ||
480 | } | ||
481 | |||
482 | /* Event 53: Set nStrobe high */ | ||
483 | parport_frob_control (port, | ||
484 | PARPORT_CONTROL_STROBE, | ||
485 | 0); | ||
486 | |||
487 | /* Event 55: nAck goes high */ | ||
488 | if (parport_wait_peripheral (port, | ||
489 | PARPORT_STATUS_ACK, | ||
490 | PARPORT_STATUS_ACK)) { | ||
491 | /* This shouldn't really happen with a compliant | ||
492 | * device. */ | ||
493 | DPRINTK (KERN_DEBUG | ||
494 | "%s: Mode 0x%02x not supported? (0x%02x)\n", | ||
495 | port->name, mode, | ||
496 | port->ops->read_status (port)); | ||
497 | parport_ieee1284_terminate (port); | ||
498 | return 1; | ||
499 | } | ||
500 | |||
501 | /* Event 54: Peripheral sets XFlag to reflect support */ | ||
502 | xflag = parport_read_status (port) & PARPORT_STATUS_SELECT; | ||
503 | |||
504 | /* xflag should be high. */ | ||
505 | if (!xflag) { | ||
506 | /* Extended mode not supported. */ | ||
507 | DPRINTK (KERN_DEBUG "%s: Extended mode 0x%02x not " | ||
508 | "supported\n", port->name, mode); | ||
509 | parport_ieee1284_terminate (port); | ||
510 | return 1; | ||
511 | } | ||
512 | |||
513 | /* Any further setup is left to the caller. */ | ||
514 | } | ||
515 | |||
516 | /* Mode is supported */ | ||
517 | DPRINTK (KERN_DEBUG "%s: In mode 0x%02x\n", port->name, mode); | ||
518 | port->ieee1284.mode = mode; | ||
519 | |||
520 | /* But ECP is special */ | ||
521 | if (!(mode & IEEE1284_EXT_LINK) && (m & IEEE1284_MODE_ECP)) { | ||
522 | port->ieee1284.phase = IEEE1284_PH_ECP_SETUP; | ||
523 | |||
524 | /* Event 30: Set nAutoFd low */ | ||
525 | parport_frob_control (port, | ||
526 | PARPORT_CONTROL_AUTOFD, | ||
527 | PARPORT_CONTROL_AUTOFD); | ||
528 | |||
529 | /* Event 31: PError goes high. */ | ||
530 | r = parport_wait_peripheral (port, | ||
531 | PARPORT_STATUS_PAPEROUT, | ||
532 | PARPORT_STATUS_PAPEROUT); | ||
533 | if (r) { | ||
534 | DPRINTK (KERN_INFO "%s: Timeout at event 31\n", | ||
535 | port->name); | ||
536 | } | ||
537 | |||
538 | port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
539 | DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", | ||
540 | port->name); | ||
541 | } else switch (mode) { | ||
542 | case IEEE1284_MODE_NIBBLE: | ||
543 | case IEEE1284_MODE_BYTE: | ||
544 | port->ieee1284.phase = IEEE1284_PH_REV_IDLE; | ||
545 | break; | ||
546 | default: | ||
547 | port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
548 | } | ||
549 | |||
550 | |||
551 | return 0; | ||
552 | #endif /* IEEE1284 support */ | ||
553 | } | ||
554 | |||
555 | /* Acknowledge that the peripheral has data available. | ||
556 | * Events 18-20, in order to get from Reverse Idle phase | ||
557 | * to Host Busy Data Available. | ||
558 | * This will most likely be called from an interrupt. | ||
559 | * Returns zero if data was available. | ||
560 | */ | ||
561 | #ifdef CONFIG_PARPORT_1284 | ||
562 | static int parport_ieee1284_ack_data_avail (struct parport *port) | ||
563 | { | ||
564 | if (parport_read_status (port) & PARPORT_STATUS_ERROR) | ||
565 | /* Event 18 didn't happen. */ | ||
566 | return -1; | ||
567 | |||
568 | /* Event 20: nAutoFd goes high. */ | ||
569 | port->ops->frob_control (port, PARPORT_CONTROL_AUTOFD, 0); | ||
570 | port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL; | ||
571 | return 0; | ||
572 | } | ||
573 | #endif /* IEEE1284 support */ | ||
574 | |||
575 | /* Handle an interrupt. */ | ||
576 | void parport_ieee1284_interrupt (int which, void *handle, struct pt_regs *regs) | ||
577 | { | ||
578 | struct parport *port = handle; | ||
579 | parport_ieee1284_wakeup (port); | ||
580 | |||
581 | #ifdef CONFIG_PARPORT_1284 | ||
582 | if (port->ieee1284.phase == IEEE1284_PH_REV_IDLE) { | ||
583 | /* An interrupt in this phase means that data | ||
584 | * is now available. */ | ||
585 | DPRINTK (KERN_DEBUG "%s: Data available\n", port->name); | ||
586 | parport_ieee1284_ack_data_avail (port); | ||
587 | } | ||
588 | #endif /* IEEE1284 support */ | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * parport_write - write a block of data to a parallel port | ||
593 | * @port: port to write to | ||
594 | * @buffer: data buffer (in kernel space) | ||
595 | * @len: number of bytes of data to transfer | ||
596 | * | ||
597 | * This will write up to @len bytes of @buffer to the port | ||
598 | * specified, using the IEEE 1284 transfer mode most recently | ||
599 | * negotiated to (using parport_negotiate()), as long as that | ||
600 | * mode supports forward transfers (host to peripheral). | ||
601 | * | ||
602 | * It is the caller's responsibility to ensure that the first | ||
603 | * @len bytes of @buffer are valid. | ||
604 | * | ||
605 | * This function returns the number of bytes transferred (if zero | ||
606 | * or positive), or else an error code. | ||
607 | */ | ||
608 | |||
609 | ssize_t parport_write (struct parport *port, const void *buffer, size_t len) | ||
610 | { | ||
611 | #ifndef CONFIG_PARPORT_1284 | ||
612 | return port->ops->compat_write_data (port, buffer, len, 0); | ||
613 | #else | ||
614 | ssize_t retval; | ||
615 | int mode = port->ieee1284.mode; | ||
616 | int addr = mode & IEEE1284_ADDR; | ||
617 | size_t (*fn) (struct parport *, const void *, size_t, int); | ||
618 | |||
619 | /* Ignore the device-ID-request bit and the address bit. */ | ||
620 | mode &= ~(IEEE1284_DEVICEID | IEEE1284_ADDR); | ||
621 | |||
622 | /* Use the mode we're in. */ | ||
623 | switch (mode) { | ||
624 | case IEEE1284_MODE_NIBBLE: | ||
625 | case IEEE1284_MODE_BYTE: | ||
626 | parport_negotiate (port, IEEE1284_MODE_COMPAT); | ||
627 | case IEEE1284_MODE_COMPAT: | ||
628 | DPRINTK (KERN_DEBUG "%s: Using compatibility mode\n", | ||
629 | port->name); | ||
630 | fn = port->ops->compat_write_data; | ||
631 | break; | ||
632 | |||
633 | case IEEE1284_MODE_EPP: | ||
634 | DPRINTK (KERN_DEBUG "%s: Using EPP mode\n", port->name); | ||
635 | if (addr) { | ||
636 | fn = port->ops->epp_write_addr; | ||
637 | } else { | ||
638 | fn = port->ops->epp_write_data; | ||
639 | } | ||
640 | break; | ||
641 | case IEEE1284_MODE_EPPSWE: | ||
642 | DPRINTK (KERN_DEBUG "%s: Using software-emulated EPP mode\n", | ||
643 | port->name); | ||
644 | if (addr) { | ||
645 | fn = parport_ieee1284_epp_write_addr; | ||
646 | } else { | ||
647 | fn = parport_ieee1284_epp_write_data; | ||
648 | } | ||
649 | break; | ||
650 | case IEEE1284_MODE_ECP: | ||
651 | case IEEE1284_MODE_ECPRLE: | ||
652 | DPRINTK (KERN_DEBUG "%s: Using ECP mode\n", port->name); | ||
653 | if (addr) { | ||
654 | fn = port->ops->ecp_write_addr; | ||
655 | } else { | ||
656 | fn = port->ops->ecp_write_data; | ||
657 | } | ||
658 | break; | ||
659 | |||
660 | case IEEE1284_MODE_ECPSWE: | ||
661 | DPRINTK (KERN_DEBUG "%s: Using software-emulated ECP mode\n", | ||
662 | port->name); | ||
663 | /* The caller has specified that it must be emulated, | ||
664 | * even if we have ECP hardware! */ | ||
665 | if (addr) { | ||
666 | fn = parport_ieee1284_ecp_write_addr; | ||
667 | } else { | ||
668 | fn = parport_ieee1284_ecp_write_data; | ||
669 | } | ||
670 | break; | ||
671 | |||
672 | default: | ||
673 | DPRINTK (KERN_DEBUG "%s: Unknown mode 0x%02x\n", port->name, | ||
674 | port->ieee1284.mode); | ||
675 | return -ENOSYS; | ||
676 | } | ||
677 | |||
678 | retval = (*fn) (port, buffer, len, 0); | ||
679 | DPRINTK (KERN_DEBUG "%s: wrote %d/%d bytes\n", port->name, retval, len); | ||
680 | return retval; | ||
681 | #endif /* IEEE1284 support */ | ||
682 | } | ||
683 | |||
684 | /** | ||
685 | * parport_read - read a block of data from a parallel port | ||
686 | * @port: port to read from | ||
687 | * @buffer: data buffer (in kernel space) | ||
688 | * @len: number of bytes of data to transfer | ||
689 | * | ||
690 | * This will read up to @len bytes of @buffer to the port | ||
691 | * specified, using the IEEE 1284 transfer mode most recently | ||
692 | * negotiated to (using parport_negotiate()), as long as that | ||
693 | * mode supports reverse transfers (peripheral to host). | ||
694 | * | ||
695 | * It is the caller's responsibility to ensure that the first | ||
696 | * @len bytes of @buffer are available to write to. | ||
697 | * | ||
698 | * This function returns the number of bytes transferred (if zero | ||
699 | * or positive), or else an error code. | ||
700 | */ | ||
701 | |||
702 | ssize_t parport_read (struct parport *port, void *buffer, size_t len) | ||
703 | { | ||
704 | #ifndef CONFIG_PARPORT_1284 | ||
705 | printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); | ||
706 | return -ENODEV; | ||
707 | #else | ||
708 | int mode = port->physport->ieee1284.mode; | ||
709 | int addr = mode & IEEE1284_ADDR; | ||
710 | size_t (*fn) (struct parport *, void *, size_t, int); | ||
711 | |||
712 | /* Ignore the device-ID-request bit and the address bit. */ | ||
713 | mode &= ~(IEEE1284_DEVICEID | IEEE1284_ADDR); | ||
714 | |||
715 | /* Use the mode we're in. */ | ||
716 | switch (mode) { | ||
717 | case IEEE1284_MODE_COMPAT: | ||
718 | /* if we can tri-state use BYTE mode instead of NIBBLE mode, | ||
719 | * if that fails, revert to NIBBLE mode -- ought to store somewhere | ||
720 | * the device's ability to do BYTE mode reverse transfers, so we don't | ||
721 | * end up needlessly calling negotiate(BYTE) repeately.. (fb) | ||
722 | */ | ||
723 | if ((port->physport->modes & PARPORT_MODE_TRISTATE) && | ||
724 | !parport_negotiate (port, IEEE1284_MODE_BYTE)) { | ||
725 | /* got into BYTE mode OK */ | ||
726 | DPRINTK (KERN_DEBUG "%s: Using byte mode\n", port->name); | ||
727 | fn = port->ops->byte_read_data; | ||
728 | break; | ||
729 | } | ||
730 | if (parport_negotiate (port, IEEE1284_MODE_NIBBLE)) { | ||
731 | return -EIO; | ||
732 | } | ||
733 | /* fall through to NIBBLE */ | ||
734 | case IEEE1284_MODE_NIBBLE: | ||
735 | DPRINTK (KERN_DEBUG "%s: Using nibble mode\n", port->name); | ||
736 | fn = port->ops->nibble_read_data; | ||
737 | break; | ||
738 | |||
739 | case IEEE1284_MODE_BYTE: | ||
740 | DPRINTK (KERN_DEBUG "%s: Using byte mode\n", port->name); | ||
741 | fn = port->ops->byte_read_data; | ||
742 | break; | ||
743 | |||
744 | case IEEE1284_MODE_EPP: | ||
745 | DPRINTK (KERN_DEBUG "%s: Using EPP mode\n", port->name); | ||
746 | if (addr) { | ||
747 | fn = port->ops->epp_read_addr; | ||
748 | } else { | ||
749 | fn = port->ops->epp_read_data; | ||
750 | } | ||
751 | break; | ||
752 | case IEEE1284_MODE_EPPSWE: | ||
753 | DPRINTK (KERN_DEBUG "%s: Using software-emulated EPP mode\n", | ||
754 | port->name); | ||
755 | if (addr) { | ||
756 | fn = parport_ieee1284_epp_read_addr; | ||
757 | } else { | ||
758 | fn = parport_ieee1284_epp_read_data; | ||
759 | } | ||
760 | break; | ||
761 | case IEEE1284_MODE_ECP: | ||
762 | case IEEE1284_MODE_ECPRLE: | ||
763 | DPRINTK (KERN_DEBUG "%s: Using ECP mode\n", port->name); | ||
764 | fn = port->ops->ecp_read_data; | ||
765 | break; | ||
766 | |||
767 | case IEEE1284_MODE_ECPSWE: | ||
768 | DPRINTK (KERN_DEBUG "%s: Using software-emulated ECP mode\n", | ||
769 | port->name); | ||
770 | fn = parport_ieee1284_ecp_read_data; | ||
771 | break; | ||
772 | |||
773 | default: | ||
774 | DPRINTK (KERN_DEBUG "%s: Unknown mode 0x%02x\n", port->name, | ||
775 | port->physport->ieee1284.mode); | ||
776 | return -ENOSYS; | ||
777 | } | ||
778 | |||
779 | return (*fn) (port, buffer, len, 0); | ||
780 | #endif /* IEEE1284 support */ | ||
781 | } | ||
782 | |||
783 | /** | ||
784 | * parport_set_timeout - set the inactivity timeout for a device | ||
785 | * @dev: device on a port | ||
786 | * @inactivity: inactivity timeout (in jiffies) | ||
787 | * | ||
788 | * This sets the inactivity timeout for a particular device on a | ||
789 | * port. This affects functions like parport_wait_peripheral(). | ||
790 | * The special value 0 means not to call schedule() while dealing | ||
791 | * with this device. | ||
792 | * | ||
793 | * The return value is the previous inactivity timeout. | ||
794 | * | ||
795 | * Any callers of parport_wait_event() for this device are woken | ||
796 | * up. | ||
797 | */ | ||
798 | |||
799 | long parport_set_timeout (struct pardevice *dev, long inactivity) | ||
800 | { | ||
801 | long int old = dev->timeout; | ||
802 | |||
803 | dev->timeout = inactivity; | ||
804 | |||
805 | if (dev->port->physport->cad == dev) | ||
806 | parport_ieee1284_wakeup (dev->port); | ||
807 | |||
808 | return old; | ||
809 | } | ||
810 | |||
811 | /* Exported symbols for modules. */ | ||
812 | |||
813 | EXPORT_SYMBOL(parport_negotiate); | ||
814 | EXPORT_SYMBOL(parport_write); | ||
815 | EXPORT_SYMBOL(parport_read); | ||
816 | EXPORT_SYMBOL(parport_wait_peripheral); | ||
817 | EXPORT_SYMBOL(parport_wait_event); | ||
818 | EXPORT_SYMBOL(parport_set_timeout); | ||
819 | EXPORT_SYMBOL(parport_ieee1284_interrupt); | ||