^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* IEEE-1284 operations for parport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is for generic IEEE 1284 operations. The idea is that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * they are used by the low-level drivers. If they have a special way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * of doing something, they can provide their own routines (and put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * the function pointers in port->ops); if not, they can just use these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * as a fallback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Note: Make no assumptions about hardware or architecture in this file!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Author: Tim Waugh <tim@cyberelk.demon.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Fixed AUTOFD polarity in ecp_forward_to_reverse(). Fred Barnes, 1999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Software emulated EPP fixes, Fred Barnes, 04/2001.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/parport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #undef DEBUG /* undef me for production */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifdef CONFIG_LP_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #undef DEBUG /* Don't want a garbled console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*** *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * One-way data transfer functions. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Compatibility mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) size_t parport_ieee1284_write_compat (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int no_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ssize_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const unsigned char *addr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct pardevice *dev = port->physport->cad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned char ctl = (PARPORT_CONTROL_SELECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) | PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (port->irq != PARPORT_IRQ_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) parport_enable_irq (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) no_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) parport_write_control (port, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) parport_data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) while (count < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned long expire = jiffies + dev->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) long wait = msecs_to_jiffies(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned char mask = (PARPORT_STATUS_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) | PARPORT_STATUS_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned char val = (PARPORT_STATUS_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) | PARPORT_STATUS_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Wait until the peripheral's ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Is the peripheral ready yet? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!parport_wait_peripheral (port, mask, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Skip the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) goto ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Is the peripheral upset? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if ((parport_read_status (port) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) (PARPORT_STATUS_PAPEROUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PARPORT_STATUS_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) PARPORT_STATUS_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) != (PARPORT_STATUS_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) PARPORT_STATUS_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* If nFault is asserted (i.e. no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * error) and PAPEROUT and SELECT are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * just red herrings, give the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * a chance to check it's happy with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * that before continuing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Have we run out of time? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!time_before (jiffies, expire))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Yield the port for a while. If this is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) first time around the loop, don't let go of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) the port. This way, we find out if we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) our interrupt handler called. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (count && no_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) parport_release (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) schedule_timeout_interruptible(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) parport_claim_or_block (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* We must have the device claimed here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) parport_wait_event (port, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Is there a signal pending? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (signal_pending (current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Wait longer next time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) wait *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } while (time_before (jiffies, expire));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (signal_pending (current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pr_debug("%s: Timed out\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ready:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Write the character to the data lines. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) byte = *addr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) parport_write_data (port, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) udelay (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* Pulse strobe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) parport_write_control (port, ctl | PARPORT_CONTROL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) udelay (1); /* strobe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) parport_write_control (port, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) udelay (1); /* hold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Assume the peripheral received it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Let another process run if it needs to. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (time_before (jiffies, expire))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!parport_yield_blocking (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) && need_resched())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) schedule ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Nibble mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) size_t parport_ieee1284_read_nibble (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #ifndef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned char byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) len *= 2; /* in nibbles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for (i=0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned char nibble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Does the error line indicate end of data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (((i & 1) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) goto end_of_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Event 7: Set nAutoFd low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Event 9: nAck goes low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) port->ieee1284.phase = IEEE1284_PH_REV_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) PARPORT_STATUS_ACK, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Timeout -- no more data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_debug("%s: Nibble timeout at event 9 (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) port->name, i / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Read a nibble. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nibble = parport_read_status (port) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nibble &= ~8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if ((nibble & 0x10) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) nibble |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) nibble &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Event 10: Set nAutoFd high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Event 11: nAck goes high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) PARPORT_STATUS_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) PARPORT_STATUS_ACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Timeout -- no more data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pr_debug("%s: Nibble timeout at event 11\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (i & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Second nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) byte |= nibble << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *buf++ = byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) byte = nibble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (i == len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Read the last nibble without checking data avail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) end_of_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pr_debug("%s: No more nibble data (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) port->name, i / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Go to reverse idle phase. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return i/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Byte mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) size_t parport_ieee1284_read_byte (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #ifndef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ssize_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) for (count = 0; count < len; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* Data available? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto end_of_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Event 14: Place data bus in high impedance state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) parport_data_reverse (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Event 7: Set nAutoFd low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Event 9: nAck goes low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) port->physport->ieee1284.phase = IEEE1284_PH_REV_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) PARPORT_STATUS_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Timeout -- no more data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pr_debug("%s: Byte timeout at event 9\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) byte = parport_read_data (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *buf++ = byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* Event 10: Set nAutoFd high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Event 11: nAck goes high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) PARPORT_STATUS_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) PARPORT_STATUS_ACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Timeout -- no more data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) pr_debug("%s: Byte timeout at event 11\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Event 16: Set nStrobe low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) PARPORT_CONTROL_STROBE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) PARPORT_CONTROL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Event 17: Set nStrobe high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (count == len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Read the last byte without checking data avail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) end_of_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) pr_debug("%s: No more byte data (%zd bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) port->name, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Go to reverse idle phase. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*** *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * ECP Functions. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #ifdef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int ecp_forward_to_reverse (struct parport *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* Event 38: Set nAutoFd low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) parport_data_reverse (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Event 39: Set nInit low to initiate bus reversal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Event 40: PError goes low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) retval = parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) PARPORT_STATUS_PAPEROUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pr_debug("%s: ECP direction: reverse\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pr_debug("%s: ECP direction: failed to reverse\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int ecp_reverse_to_forward (struct parport *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Event 47: Set nInit high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) PARPORT_CONTROL_INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) | PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) PARPORT_CONTROL_INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) | PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Event 49: PError goes high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) retval = parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) PARPORT_STATUS_PAPEROUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) PARPORT_STATUS_PAPEROUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) parport_data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) pr_debug("%s: ECP direction: forward\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pr_debug("%s: ECP direction: failed to switch forward\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* ECP mode, forward channel, data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) size_t parport_ieee1284_ecp_write_data (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) const void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #ifndef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) const unsigned char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) size_t written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) port = port->physport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ecp_reverse_to_forward (port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) port->ieee1284.phase = IEEE1284_PH_FWD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* HostAck high (data, not command) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) PARPORT_CONTROL_AUTOFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) | PARPORT_CONTROL_STROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) | PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) for (written = 0; written < len; written++, buf++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned long expire = jiffies + port->cad->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) byte = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) try_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) parport_write_data (port, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) parport_frob_control (port, PARPORT_CONTROL_STROBE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) PARPORT_CONTROL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (retry = 0; retry < 100; retry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) PARPORT_STATUS_BUSY, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (signal_pending (current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) PARPORT_CONTROL_STROBE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* Time for Host Transfer Recovery (page 41 of IEEE1284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pr_debug("%s: ECP transfer stalled!\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) parport_frob_control (port, PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) udelay (50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* It's buggered. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) udelay (50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pr_debug("%s: Host transfer recovered\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (time_after_eq (jiffies, expire)) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto try_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) PARPORT_STATUS_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Peripheral hasn't accepted the data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* ECP mode, reverse channel, data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) size_t parport_ieee1284_ecp_read_data (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) void *buffer, size_t len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #ifndef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct pardevice *dev = port->cad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) unsigned char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int rle_count = 0; /* shut gcc up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) unsigned char ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) int rle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ssize_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) port = port->physport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (ecp_forward_to_reverse (port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) port->ieee1284.phase = IEEE1284_PH_REV_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Set HostAck low to start accepting data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ctl = parport_read_control (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ctl &= ~(PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) parport_write_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ctl | PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) while (count < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned long expire = jiffies + dev->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Event 43: Peripheral sets nAck low. It can take as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) long as it wants. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) while (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* The peripheral hasn't given us data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 35ms. If we have data to give back to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) caller, do it now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* If we've used up all the time we were allowed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) give up altogether. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!time_before (jiffies, expire))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Yield the port for a while. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (dev->port->irq != PARPORT_IRQ_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) parport_release (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) schedule_timeout_interruptible(msecs_to_jiffies(40));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) parport_claim_or_block (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* We must have the device claimed here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) parport_wait_event (port, msecs_to_jiffies(40));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Is there a signal pending? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (signal_pending (current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Is this a command? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (rle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* The last byte was a run-length count, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) this can't be as well. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) command = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) command = (parport_read_status (port) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) PARPORT_STATUS_BUSY) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Read the data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) byte = parport_read_data (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* If this is a channel command, rather than an RLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) command or a normal data byte, don't accept it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (byte & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pr_debug("%s: stopping short at channel command (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) port->name, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) else if (port->ieee1284.mode != IEEE1284_MODE_ECPRLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pr_debug("%s: device illegally using RLE; accepting anyway\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) rle_count = byte + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Are we allowed to read that many bytes? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (rle_count > (len - count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) pr_debug("%s: leaving %d RLE bytes for next time\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) port->name, rle_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) rle = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Event 44: Set HostAck high, acknowledging handshake. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) parport_write_control (port, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Event 45: The peripheral has 35ms to set nAck high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (parport_wait_peripheral (port, PARPORT_STATUS_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) PARPORT_STATUS_ACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* It's gone wrong. Return what data we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) to the caller. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pr_debug("ECP read timed out at 45\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pr_warn("%s: command ignored (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) port->name, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Event 46: Set HostAck low and accept the data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) parport_write_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ctl | PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* If we just read a run-length count, fetch the data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* If this is the byte after a run-length count, decompress. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (rle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) rle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) memset (buf, byte, rle_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) buf += rle_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) count += rle_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) pr_debug("%s: decompressed to %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) port->name, rle_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Normal data byte. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) *buf = byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) buf++, count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* ECP mode, forward channel, commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) size_t parport_ieee1284_ecp_write_addr (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) const void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #ifndef CONFIG_PARPORT_1284
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) const unsigned char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) size_t written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) port = port->physport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ecp_reverse_to_forward (port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) port->ieee1284.phase = IEEE1284_PH_FWD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* HostAck low (command, not data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) PARPORT_CONTROL_AUTOFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) | PARPORT_CONTROL_STROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) | PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) PARPORT_CONTROL_AUTOFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) | PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) for (written = 0; written < len; written++, buf++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned long expire = jiffies + port->cad->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) byte = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) try_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) parport_write_data (port, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) parport_frob_control (port, PARPORT_CONTROL_STROBE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) PARPORT_CONTROL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) for (retry = 0; retry < 100; retry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (!parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) PARPORT_STATUS_BUSY, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) goto success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (signal_pending (current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) PARPORT_CONTROL_STROBE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* Time for Host Transfer Recovery (page 41 of IEEE1284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pr_debug("%s: ECP transfer stalled!\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) parport_frob_control (port, PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) udelay (50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* It's buggered. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) udelay (50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pr_debug("%s: Host transfer recovered\n", port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (time_after_eq (jiffies, expire)) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) goto try_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (parport_wait_peripheral (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) PARPORT_STATUS_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* Peripheral hasn't accepted the data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #endif /* IEEE1284 support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*** *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * EPP functions. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* EPP mode, forward channel, data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) size_t parport_ieee1284_epp_write_data (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) const void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) unsigned char *bp = (unsigned char *) buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) size_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* set EPP idle state (just to make sure) with strobe low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) PARPORT_CONTROL_AUTOFD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) PARPORT_CONTROL_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) port->ops->data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) for (; len > 0; len--, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Event 62: Write data and set autofd low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) parport_write_data (port, *bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* Event 58: wait for busy (nWait) to go high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Event 63: set nAutoFd (nDStrb) high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /* Event 60: wait for busy (nWait) to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) PARPORT_STATUS_BUSY, 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* Event 61: set strobe (nWrite) high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* EPP mode, reverse channel, data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) size_t parport_ieee1284_epp_read_data (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) unsigned char *bp = (unsigned char *) buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) unsigned ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* set EPP idle state (just to make sure) with strobe high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) PARPORT_CONTROL_AUTOFD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) PARPORT_CONTROL_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) port->ops->data_reverse (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) for (; len > 0; len--, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* Event 67: set nAutoFd (nDStrb) low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) PARPORT_CONTROL_AUTOFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) PARPORT_CONTROL_AUTOFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Event 58: wait for Busy to go high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) *bp = parport_read_data (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* Event 63: set nAutoFd (nDStrb) high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Event 60: wait for Busy to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) PARPORT_STATUS_BUSY, 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) port->ops->data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* EPP mode, forward channel, addresses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) size_t parport_ieee1284_epp_write_addr (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) const void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned char *bp = (unsigned char *) buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) size_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /* set EPP idle state (just to make sure) with strobe low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) PARPORT_CONTROL_AUTOFD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) PARPORT_CONTROL_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) port->ops->data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) for (; len > 0; len--, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Event 56: Write data and set nAStrb low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) parport_write_data (port, *bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) parport_frob_control (port, PARPORT_CONTROL_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) PARPORT_CONTROL_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* Event 58: wait for busy (nWait) to go high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Event 59: set nAStrb high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* Event 60: wait for busy (nWait) to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) PARPORT_STATUS_BUSY, 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /* Event 61: set strobe (nWrite) high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* EPP mode, reverse channel, addresses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) size_t parport_ieee1284_epp_read_addr (struct parport *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) void *buffer, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) unsigned char *bp = (unsigned char *) buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) unsigned ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* Set EPP idle state (just to make sure) with strobe high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) parport_frob_control (port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) PARPORT_CONTROL_STROBE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) PARPORT_CONTROL_AUTOFD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) PARPORT_CONTROL_SELECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) PARPORT_CONTROL_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) PARPORT_CONTROL_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) port->ops->data_reverse (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) for (; len > 0; len--, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /* Event 64: set nSelectIn (nAStrb) low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) parport_frob_control (port, PARPORT_CONTROL_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) PARPORT_CONTROL_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* Event 58: wait for Busy to go high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) *bp = parport_read_data (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* Event 59: set nSelectIn (nAStrb) high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) parport_frob_control (port, PARPORT_CONTROL_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Event 60: wait for Busy to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) PARPORT_STATUS_BUSY, 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) port->ops->data_forward (port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) EXPORT_SYMBOL(parport_ieee1284_ecp_write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) EXPORT_SYMBOL(parport_ieee1284_ecp_read_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) EXPORT_SYMBOL(parport_ieee1284_ecp_write_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) EXPORT_SYMBOL(parport_ieee1284_write_compat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) EXPORT_SYMBOL(parport_ieee1284_read_nibble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) EXPORT_SYMBOL(parport_ieee1284_read_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) EXPORT_SYMBOL(parport_ieee1284_epp_write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) EXPORT_SYMBOL(parport_ieee1284_epp_read_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) EXPORT_SYMBOL(parport_ieee1284_epp_write_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) EXPORT_SYMBOL(parport_ieee1284_epp_read_addr);