diff options
Diffstat (limited to 'drivers/parport')
| -rw-r--r-- | drivers/parport/Kconfig | 38 | ||||
| -rw-r--r-- | drivers/parport/Makefile | 4 | ||||
| -rw-r--r-- | drivers/parport/daisy.c | 74 | ||||
| -rw-r--r-- | drivers/parport/ieee1284.c | 122 | ||||
| -rw-r--r-- | drivers/parport/ieee1284_ops.c | 77 | ||||
| -rw-r--r-- | drivers/parport/multiface.h | 1 | ||||
| -rw-r--r-- | drivers/parport/parport_amiga.c | 37 | ||||
| -rw-r--r-- | drivers/parport/parport_atari.c | 10 | ||||
| -rw-r--r-- | drivers/parport/parport_ax88796.c | 427 | ||||
| -rw-r--r-- | drivers/parport/parport_cs.c | 11 | ||||
| -rw-r--r-- | drivers/parport/parport_gsc.c | 85 | ||||
| -rw-r--r-- | drivers/parport/parport_gsc.h | 44 | ||||
| -rw-r--r-- | drivers/parport/parport_ip32.c | 174 | ||||
| -rw-r--r-- | drivers/parport/parport_mfc3.c | 30 | ||||
| -rw-r--r-- | drivers/parport/parport_pc.c | 567 | ||||
| -rw-r--r-- | drivers/parport/parport_serial.c | 277 | ||||
| -rw-r--r-- | drivers/parport/parport_sunbpp.c | 19 | ||||
| -rw-r--r-- | drivers/parport/probe.c | 50 | ||||
| -rw-r--r-- | drivers/parport/procfs.c | 275 | ||||
| -rw-r--r-- | drivers/parport/share.c | 669 |
20 files changed, 1385 insertions, 1606 deletions
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index dc82ef096f3b..631c193fe42c 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig @@ -1,20 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only # # For a description of the syntax of this configuration file, -# see Documentation/kbuild/kconfig-language.txt. +# see Documentation/kbuild/kconfig-language.rst. # # Parport configuration. # +config ARCH_MIGHT_HAVE_PC_PARPORT + bool + help + Select this config option from the architecture Kconfig if + the architecture might have PC parallel port hardware. + menuconfig PARPORT tristate "Parallel port support" depends on HAS_IOMEM - ---help--- + help If you want to use devices connected to your machine's parallel port (the connector at the computer with 25 holes), e.g. printer, ZIP drive, PLIP link (Parallel Line Internet Protocol is mainly used to create a mini network by connecting the parallel ports of two local machines) etc., then you need to say Y here; please read - <file:Documentation/parport.txt> and + <file:Documentation/admin-guide/parport.rst> and <file:drivers/parport/BUGS-parport>. For extensive information about drivers for many devices attaching @@ -27,7 +34,7 @@ menuconfig PARPORT the module will be called parport. If you have more than one parallel port and want to specify which port and IRQ to be used by this driver at module load time, take a - look at <file:Documentation/parport.txt>. + look at <file:Documentation/admin-guide/parport.rst>. If unsure, say Y. @@ -35,11 +42,9 @@ if PARPORT config PARPORT_PC tristate "PC-style hardware" - depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && !S390 && \ - (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && \ - !XTENSA && !CRIS - - ---help--- + depends on ARCH_MIGHT_HAVE_PC_PARPORT || PCI + depends on HAS_IOPORT + help You should say Y here if you have a PC-style parallel port. All IBM PC compatible computers and some Alphas have PC-style parallel ports. PA-RISC owners should only say Y here if they @@ -68,12 +73,12 @@ config PARPORT_PC_FIFO As well as actually having a FIFO, or DMA capability, the kernel will need to know which IRQ the parallel port has. By default, parallel port interrupts will not be used, and so neither will the - FIFO. See <file:Documentation/parport.txt> to find out how to + FIFO. See <file:Documentation/admin-guide/parport.rst> to find out how to specify which IRQ/DMA to use. config PARPORT_PC_SUPERIO bool "SuperIO chipset support" - depends on PARPORT_PC && !PARISC + depends on ARCH_MIGHT_HAVE_PC_PARPORT && PARPORT_PC && !PARISC help Saying Y here enables some probes for Super-IO chipsets in order to find out things like base addresses, IRQ lines and DMA channels. It @@ -136,17 +141,6 @@ config PARPORT_SUNBPP found on many Sun machines. Note that many of the newer Ultras actually have pc style hardware instead. -config PARPORT_AX88796 - tristate "AX88796 Parallel Port" - select PARPORT_NOT_PC - help - Say Y here if you need support for the parallel port hardware on - the AX88796 network controller chip. This code is also available - as a module (say M), called parport_ax88796. - - The driver is not dependent on the AX88796 network driver, and - should not interfere with the networking functions of the chip. - config PARPORT_1284 bool "IEEE 1284 transfer modes" help diff --git a/drivers/parport/Makefile b/drivers/parport/Makefile index 696b8d4ca887..d4a6b890852d 100644 --- a/drivers/parport/Makefile +++ b/drivers/parport/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the kernel Parallel port device drivers. # @@ -17,5 +18,4 @@ obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o -obj-$(CONFIG_PARPORT_AX88796) += parport_ax88796.o -obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o
\ No newline at end of file +obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index 5bed17f68ef4..2231dbfd870d 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c @@ -23,19 +23,13 @@ #include <linux/parport.h> #include <linux/delay.h> #include <linux/slab.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <asm/current.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #undef DEBUG -#ifdef DEBUG -#define DPRINTK(stuff...) printk(stuff) -#else -#define DPRINTK(stuff...) -#endif - static struct daisydev { struct daisydev *next; struct parport *port; @@ -44,7 +38,8 @@ static struct daisydev { } *topology = NULL; static DEFINE_SPINLOCK(topology_lock); -static int numdevs = 0; +static int numdevs; +static bool daisy_init_done; /* Forward-declaration of lower-level functions. */ static int mux_present(struct parport *port); @@ -87,6 +82,23 @@ static struct parport *clone_parport(struct parport *real, int muxport) return extra; } +static int daisy_drv_probe(struct pardevice *par_dev) +{ + struct device_driver *drv = par_dev->dev.driver; + + if (strcmp(drv->name, "daisy_drv")) + return -ENODEV; + if (strcmp(par_dev->name, daisy_dev_name)) + return -ENODEV; + + return 0; +} + +static struct parport_driver daisy_driver = { + .name = "daisy_drv", + .probe = daisy_drv_probe, +}; + /* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains. * Return value is number of devices actually detected. */ int parport_daisy_init(struct parport *port) @@ -98,6 +110,23 @@ int parport_daisy_init(struct parport *port) int i; int last_try = 0; + if (!daisy_init_done) { + /* + * flag should be marked true first as + * parport_register_driver() might try to load the low + * level driver which will lead to announcing new ports + * and which will again come back here at + * parport_daisy_init() + */ + daisy_init_done = true; + i = parport_register_driver(&daisy_driver); + if (i) { + pr_err("daisy registration failed\n"); + daisy_init_done = false; + return i; + } + } + again: /* Because this is called before any other devices exist, * we don't have to claim exclusive access. */ @@ -109,8 +138,7 @@ again: ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) { /* Leave original as port zero. */ port->muxport = 0; - printk(KERN_INFO - "%s: 1st (default) port of %d-way multiplexor\n", + pr_info("%s: 1st (default) port of %d-way multiplexor\n", port->name, num_ports); for (i = 1; i < num_ports; i++) { /* Clone the port. */ @@ -123,8 +151,7 @@ again: continue; } - printk(KERN_INFO - "%s: %d%s port of %d-way multiplexor on %s\n", + pr_info("%s: %d%s port of %d-way multiplexor on %s\n", extra->name, i + 1, th[i + 1], num_ports, port->name); @@ -213,10 +240,12 @@ void parport_daisy_fini(struct parport *port) struct pardevice *parport_open(int devnum, const char *name) { struct daisydev *p = topology; + struct pardev_cb par_cb; struct parport *port; struct pardevice *dev; int daisy; + memset(&par_cb, 0, sizeof(par_cb)); spin_lock(&topology_lock); while (p && p->devnum != devnum) p = p->next; @@ -230,7 +259,7 @@ struct pardevice *parport_open(int devnum, const char *name) port = parport_get_port(p->port); spin_unlock(&topology_lock); - dev = parport_register_device(port, name, NULL, NULL, NULL, 0, NULL); + dev = parport_register_dev_model(port, name, &par_cb, devnum); parport_put_port(port); if (!dev) return NULL; @@ -285,8 +314,7 @@ static int cpp_daisy(struct parport *port, int cmd) | PARPORT_STATUS_PAPEROUT | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) { - DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n", - port->name, s); + pr_debug("%s: cpp_daisy: aa5500ff(%02x)\n", port->name, s); return -ENXIO; } @@ -296,8 +324,7 @@ static int cpp_daisy(struct parport *port, int cmd) | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR); if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) { - DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n", - port->name, s); + pr_debug("%s: cpp_daisy: aa5500ff87(%02x)\n", port->name, s); return -ENXIO; } @@ -332,7 +359,7 @@ static int cpp_mux(struct parport *port, int cmd) s = parport_read_status(port); if (!(s & PARPORT_STATUS_ACK)) { - DPRINTK(KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n", + pr_debug("%s: cpp_mux: aa55f00f52ad%02x(%02x)\n", port->name, cmd, s); return -EIO; } @@ -418,8 +445,7 @@ static int assign_addrs(struct parport *port) | PARPORT_STATUS_PAPEROUT | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) { - DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n", - port->name, s); + pr_debug("%s: assign_addrs: aa5500ff(%02x)\n", port->name, s); return 0; } @@ -429,8 +455,7 @@ static int assign_addrs(struct parport *port) | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR); if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) { - DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n", - port->name, s); + pr_debug("%s: assign_addrs: aa5500ff87(%02x)\n", port->name, s); return 0; } @@ -467,8 +492,7 @@ static int assign_addrs(struct parport *port) parport_write_data(port, 0xff); udelay(2); detected = numdevs - thisdev; - DPRINTK(KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name, - detected); + pr_debug("%s: Found %d daisy-chained devices\n", port->name, detected); /* Ask the new devices to introduce themselves. */ deviceid = kmalloc(1024, GFP_KERNEL); diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index f9fd4b33a546..4035010249cd 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -23,7 +23,7 @@ #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/timer.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #undef DEBUG /* undef me for production */ @@ -31,12 +31,6 @@ #undef DEBUG /* Don't want a garbled console */ #endif -#ifdef DEBUG -#define DPRINTK(stuff...) printk (stuff) -#else -#define DPRINTK(stuff...) -#endif - /* Make parport_wait_peripheral wake up. * It will be useful to call this from an interrupt handler. */ static void parport_ieee1284_wakeup (struct parport *port) @@ -44,10 +38,11 @@ static void parport_ieee1284_wakeup (struct parport *port) up (&port->physport->ieee1284.irq); } -static struct parport *port_from_cookie[PARPORT_MAX]; -static void timeout_waiting_on_port (unsigned long cookie) +static void timeout_waiting_on_port (struct timer_list *t) { - parport_ieee1284_wakeup (port_from_cookie[cookie % PARPORT_MAX]); + struct parport *port = timer_container_of(port, t, timer); + + parport_ieee1284_wakeup (port); } /** @@ -69,27 +64,19 @@ static void timeout_waiting_on_port (unsigned long cookie) int parport_wait_event (struct parport *port, signed long timeout) { int ret; - struct timer_list timer; if (!port->physport->cad->timeout) /* Zero timeout is special, and we can't down() the semaphore. */ return 1; - init_timer_on_stack(&timer); - timer.expires = jiffies + timeout; - timer.function = timeout_waiting_on_port; - port_from_cookie[port->number % PARPORT_MAX] = port; - timer.data = port->number; - - add_timer (&timer); + timer_setup(&port->timer, timeout_waiting_on_port, 0); + mod_timer(&port->timer, jiffies + timeout); ret = down_interruptible (&port->physport->ieee1284.irq); - if (!del_timer_sync(&timer) && !ret) + if (!timer_delete_sync(&port->timer) && !ret) /* Timed out. */ ret = 1; - destroy_timer_on_stack(&timer); - return ret; } @@ -265,16 +252,15 @@ static void parport_ieee1284_terminate (struct parport *port) PARPORT_STATUS_PAPEROUT, PARPORT_STATUS_PAPEROUT); if (r) - DPRINTK (KERN_INFO "%s: Timeout at event 49\n", + pr_debug("%s: Timeout at event 49\n", port->name); parport_data_forward (port); - DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", - port->name); + pr_debug("%s: ECP direction: forward\n", port->name); port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; } - /* fall-though.. */ + fallthrough; default: /* Terminate from all other modes. */ @@ -288,8 +274,7 @@ static void parport_ieee1284_terminate (struct parport *port) /* Event 24: nAck goes low */ r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); if (r) - DPRINTK (KERN_INFO "%s: Timeout at event 24\n", - port->name); + pr_debug("%s: Timeout at event 24\n", port->name); /* Event 25: Set nAutoFd low */ parport_frob_control (port, @@ -301,8 +286,7 @@ static void parport_ieee1284_terminate (struct parport *port) PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); if (r) - DPRINTK (KERN_INFO "%s: Timeout at event 27\n", - port->name); + pr_debug("%s: Timeout at event 27\n", port->name); /* Event 29: Set nAutoFd high */ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); @@ -311,8 +295,7 @@ static void parport_ieee1284_terminate (struct parport *port) port->ieee1284.mode = IEEE1284_MODE_COMPAT; port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; - DPRINTK (KERN_DEBUG "%s: In compatibility (forward idle) mode\n", - port->name); + pr_debug("%s: In compatibility (forward idle) mode\n", port->name); } #endif /* IEEE1284 support */ @@ -336,7 +319,7 @@ int parport_negotiate (struct parport *port, int mode) #ifndef CONFIG_PARPORT_1284 if (mode == IEEE1284_MODE_COMPAT) return 0; - printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); + pr_err("parport: IEEE1284 not supported in this kernel\n"); return -1; #else int m = mode & ~IEEE1284_ADDR; @@ -413,8 +396,7 @@ int parport_negotiate (struct parport *port, int mode) PARPORT_CONTROL_SELECT | PARPORT_CONTROL_AUTOFD, PARPORT_CONTROL_SELECT); - DPRINTK (KERN_DEBUG - "%s: Peripheral not IEEE1284 compliant (0x%02X)\n", + pr_debug("%s: Peripheral not IEEE1284 compliant (0x%02X)\n", port->name, parport_read_status (port)); port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; return -1; /* Not IEEE1284 compliant */ @@ -437,8 +419,7 @@ int parport_negotiate (struct parport *port, int mode) PARPORT_STATUS_ACK, PARPORT_STATUS_ACK)) { /* This shouldn't really happen with a compliant device. */ - DPRINTK (KERN_DEBUG - "%s: Mode 0x%02x not supported? (0x%02x)\n", + pr_debug("%s: Mode 0x%02x not supported? (0x%02x)\n", port->name, mode, port->ops->read_status (port)); parport_ieee1284_terminate (port); return 1; @@ -449,7 +430,7 @@ int parport_negotiate (struct parport *port, int mode) /* xflag should be high for all modes other than nibble (0). */ if (mode && !xflag) { /* Mode not supported. */ - DPRINTK (KERN_DEBUG "%s: Mode 0x%02x rejected by peripheral\n", + pr_debug("%s: Mode 0x%02x rejected by peripheral\n", port->name, mode); parport_ieee1284_terminate (port); return 1; @@ -470,9 +451,7 @@ int parport_negotiate (struct parport *port, int mode) /* Event 52: nAck goes low */ if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) { /* This peripheral is _very_ slow. */ - DPRINTK (KERN_DEBUG - "%s: Event 52 didn't happen\n", - port->name); + pr_debug("%s: Event 52 didn't happen\n", port->name); parport_ieee1284_terminate (port); return 1; } @@ -488,10 +467,9 @@ int parport_negotiate (struct parport *port, int mode) PARPORT_STATUS_ACK)) { /* This shouldn't really happen with a compliant * device. */ - DPRINTK (KERN_DEBUG - "%s: Mode 0x%02x not supported? (0x%02x)\n", + pr_debug("%s: Mode 0x%02x not supported? (0x%02x)\n", port->name, mode, - port->ops->read_status (port)); + port->ops->read_status(port)); parport_ieee1284_terminate (port); return 1; } @@ -502,8 +480,8 @@ int parport_negotiate (struct parport *port, int mode) /* xflag should be high. */ if (!xflag) { /* Extended mode not supported. */ - DPRINTK (KERN_DEBUG "%s: Extended mode 0x%02x not " - "supported\n", port->name, mode); + pr_debug("%s: Extended mode 0x%02x not supported\n", + port->name, mode); parport_ieee1284_terminate (port); return 1; } @@ -512,7 +490,7 @@ int parport_negotiate (struct parport *port, int mode) } /* Mode is supported */ - DPRINTK (KERN_DEBUG "%s: In mode 0x%02x\n", port->name, mode); + pr_debug("%s: In mode 0x%02x\n", port->name, mode); port->ieee1284.mode = mode; /* But ECP is special */ @@ -529,13 +507,11 @@ int parport_negotiate (struct parport *port, int mode) PARPORT_STATUS_PAPEROUT, PARPORT_STATUS_PAPEROUT); if (r) { - DPRINTK (KERN_INFO "%s: Timeout at event 31\n", - port->name); + pr_debug("%s: Timeout at event 31\n", port->name); } port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; - DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", - port->name); + pr_debug("%s: ECP direction: forward\n", port->name); } else switch (mode) { case IEEE1284_MODE_NIBBLE: case IEEE1284_MODE_BYTE: @@ -580,7 +556,7 @@ void parport_ieee1284_interrupt (void *handle) if (port->ieee1284.phase == IEEE1284_PH_REV_IDLE) { /* An interrupt in this phase means that data * is now available. */ - DPRINTK (KERN_DEBUG "%s: Data available\n", port->name); + pr_debug("%s: Data available\n", port->name); parport_ieee1284_ack_data_avail (port); } #endif /* IEEE1284 support */ @@ -622,14 +598,14 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) case IEEE1284_MODE_NIBBLE: case IEEE1284_MODE_BYTE: parport_negotiate (port, IEEE1284_MODE_COMPAT); + fallthrough; case IEEE1284_MODE_COMPAT: - DPRINTK (KERN_DEBUG "%s: Using compatibility mode\n", - port->name); + pr_debug("%s: Using compatibility mode\n", port->name); fn = port->ops->compat_write_data; break; case IEEE1284_MODE_EPP: - DPRINTK (KERN_DEBUG "%s: Using EPP mode\n", port->name); + pr_debug("%s: Using EPP mode\n", port->name); if (addr) { fn = port->ops->epp_write_addr; } else { @@ -637,8 +613,7 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) } break; case IEEE1284_MODE_EPPSWE: - DPRINTK (KERN_DEBUG "%s: Using software-emulated EPP mode\n", - port->name); + pr_debug("%s: Using software-emulated EPP mode\n", port->name); if (addr) { fn = parport_ieee1284_epp_write_addr; } else { @@ -647,7 +622,7 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) break; case IEEE1284_MODE_ECP: case IEEE1284_MODE_ECPRLE: - DPRINTK (KERN_DEBUG "%s: Using ECP mode\n", port->name); + pr_debug("%s: Using ECP mode\n", port->name); if (addr) { fn = port->ops->ecp_write_addr; } else { @@ -656,8 +631,7 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) break; case IEEE1284_MODE_ECPSWE: - DPRINTK (KERN_DEBUG "%s: Using software-emulated ECP mode\n", - port->name); + pr_debug("%s: Using software-emulated ECP mode\n", port->name); /* The caller has specified that it must be emulated, * even if we have ECP hardware! */ if (addr) { @@ -668,13 +642,13 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) break; default: - DPRINTK (KERN_DEBUG "%s: Unknown mode 0x%02x\n", port->name, - port->ieee1284.mode); + pr_debug("%s: Unknown mode 0x%02x\n", + port->name, port->ieee1284.mode); return -ENOSYS; } retval = (*fn) (port, buffer, len, 0); - DPRINTK (KERN_DEBUG "%s: wrote %d/%d bytes\n", port->name, retval, len); + pr_debug("%s: wrote %zd/%zu bytes\n", port->name, retval, len); return retval; #endif /* IEEE1284 support */ } @@ -700,7 +674,7 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len) ssize_t parport_read (struct parport *port, void *buffer, size_t len) { #ifndef CONFIG_PARPORT_1284 - printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); + pr_err("parport: IEEE1284 not supported in this kernel\n"); return -ENODEV; #else int mode = port->physport->ieee1284.mode; @@ -721,26 +695,26 @@ ssize_t parport_read (struct parport *port, void *buffer, size_t len) if ((port->physport->modes & PARPORT_MODE_TRISTATE) && !parport_negotiate (port, IEEE1284_MODE_BYTE)) { /* got into BYTE mode OK */ - DPRINTK (KERN_DEBUG "%s: Using byte mode\n", port->name); + pr_debug("%s: Using byte mode\n", port->name); fn = port->ops->byte_read_data; break; } if (parport_negotiate (port, IEEE1284_MODE_NIBBLE)) { return -EIO; } - /* fall through to NIBBLE */ + fallthrough; /* to NIBBLE */ case IEEE1284_MODE_NIBBLE: - DPRINTK (KERN_DEBUG "%s: Using nibble mode\n", port->name); + pr_debug("%s: Using nibble mode\n", port->name); fn = port->ops->nibble_read_data; break; case IEEE1284_MODE_BYTE: - DPRINTK (KERN_DEBUG "%s: Using byte mode\n", port->name); + pr_debug("%s: Using byte mode\n", port->name); fn = port->ops->byte_read_data; break; case IEEE1284_MODE_EPP: - DPRINTK (KERN_DEBUG "%s: Using EPP mode\n", port->name); + pr_debug("%s: Using EPP mode\n", port->name); if (addr) { fn = port->ops->epp_read_addr; } else { @@ -748,8 +722,7 @@ ssize_t parport_read (struct parport *port, void *buffer, size_t len) } break; case IEEE1284_MODE_EPPSWE: - DPRINTK (KERN_DEBUG "%s: Using software-emulated EPP mode\n", - port->name); + pr_debug("%s: Using software-emulated EPP mode\n", port->name); if (addr) { fn = parport_ieee1284_epp_read_addr; } else { @@ -758,19 +731,18 @@ ssize_t parport_read (struct parport *port, void *buffer, size_t len) break; case IEEE1284_MODE_ECP: case IEEE1284_MODE_ECPRLE: - DPRINTK (KERN_DEBUG "%s: Using ECP mode\n", port->name); + pr_debug("%s: Using ECP mode\n", port->name); fn = port->ops->ecp_read_data; break; case IEEE1284_MODE_ECPSWE: - DPRINTK (KERN_DEBUG "%s: Using software-emulated ECP mode\n", - port->name); + pr_debug("%s: Using software-emulated ECP mode\n", port->name); fn = parport_ieee1284_ecp_read_data; break; default: - DPRINTK (KERN_DEBUG "%s: Unknown mode 0x%02x\n", port->name, - port->physport->ieee1284.mode); + pr_debug("%s: Unknown mode 0x%02x\n", + port->name, port->physport->ieee1284.mode); return -ENOSYS; } diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c index 2e21af43d91e..17061f1df0f4 100644 --- a/drivers/parport/ieee1284_ops.c +++ b/drivers/parport/ieee1284_ops.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* IEEE-1284 operations for parport. * * This file is for generic IEEE 1284 operations. The idea is that @@ -17,8 +18,8 @@ #include <linux/module.h> #include <linux/parport.h> #include <linux/delay.h> -#include <linux/sched.h> -#include <asm/uaccess.h> +#include <linux/sched/signal.h> +#include <linux/uaccess.h> #undef DEBUG /* undef me for production */ @@ -26,12 +27,6 @@ #undef DEBUG /* Don't want a garbled console */ #endif -#ifdef DEBUG -#define DPRINTK(stuff...) printk (stuff) -#else -#define DPRINTK(stuff...) -#endif - /*** * * One-way data transfer functions. * * ***/ @@ -114,7 +109,7 @@ size_t parport_ieee1284_write_compat (struct parport *port, if (signal_pending (current)) break; - DPRINTK (KERN_DEBUG "%s: Timed out\n", port->name); + pr_debug("%s: Timed out\n", port->name); break; ready: @@ -177,9 +172,8 @@ size_t parport_ieee1284_read_nibble (struct parport *port, if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) { /* Timeout -- no more data? */ - DPRINTK (KERN_DEBUG - "%s: Nibble timeout at event 9 (%d bytes)\n", - port->name, i/2); + pr_debug("%s: Nibble timeout at event 9 (%d bytes)\n", + port->name, i / 2); parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); break; } @@ -200,8 +194,7 @@ size_t parport_ieee1284_read_nibble (struct parport *port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK)) { /* Timeout -- no more data? */ - DPRINTK (KERN_DEBUG - "%s: Nibble timeout at event 11\n", + pr_debug("%s: Nibble timeout at event 11\n", port->name); break; } @@ -218,9 +211,8 @@ size_t parport_ieee1284_read_nibble (struct parport *port, /* Read the last nibble without checking data avail. */ if (parport_read_status (port) & PARPORT_STATUS_ERROR) { end_of_data: - DPRINTK (KERN_DEBUG - "%s: No more nibble data (%d bytes)\n", - port->name, i/2); + pr_debug("%s: No more nibble data (%d bytes)\n", + port->name, i / 2); /* Go to reverse idle phase. */ parport_frob_control (port, @@ -271,8 +263,7 @@ size_t parport_ieee1284_read_byte (struct parport *port, /* Timeout -- no more data? */ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); - DPRINTK (KERN_DEBUG "%s: Byte timeout at event 9\n", - port->name); + pr_debug("%s: Byte timeout at event 9\n", port->name); break; } @@ -287,8 +278,7 @@ size_t parport_ieee1284_read_byte (struct parport *port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK)) { /* Timeout -- no more data? */ - DPRINTK (KERN_DEBUG "%s: Byte timeout at event 11\n", - port->name); + pr_debug("%s: Byte timeout at event 11\n", port->name); break; } @@ -306,8 +296,7 @@ size_t parport_ieee1284_read_byte (struct parport *port, /* Read the last byte without checking data avail. */ if (parport_read_status (port) & PARPORT_STATUS_ERROR) { end_of_data: - DPRINTK (KERN_DEBUG - "%s: No more byte data (%Zd bytes)\n", + pr_debug("%s: No more byte data (%zd bytes)\n", port->name, count); /* Go to reverse idle phase. */ @@ -352,12 +341,10 @@ int ecp_forward_to_reverse (struct parport *port) PARPORT_STATUS_PAPEROUT, 0); if (!retval) { - DPRINTK (KERN_DEBUG "%s: ECP direction: reverse\n", - port->name); + pr_debug("%s: ECP direction: reverse\n", port->name); port->ieee1284.phase = IEEE1284_PH_REV_IDLE; } else { - DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n", - port->name); + pr_debug("%s: ECP direction: failed to reverse\n", port->name); port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN; } @@ -383,12 +370,10 @@ int ecp_reverse_to_forward (struct parport *port) if (!retval) { parport_data_forward (port); - DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", - port->name); + pr_debug("%s: ECP direction: forward\n", port->name); port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; } else { - DPRINTK (KERN_DEBUG - "%s: ECP direction: failed to switch forward\n", + pr_debug("%s: ECP direction: failed to switch forward\n", port->name); port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN; } @@ -449,7 +434,7 @@ size_t parport_ieee1284_ecp_write_data (struct parport *port, } /* Time for Host Transfer Recovery (page 41 of IEEE1284) */ - DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name); + pr_debug("%s: ECP transfer stalled!\n", port->name); parport_frob_control (port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT); @@ -465,8 +450,7 @@ size_t parport_ieee1284_ecp_write_data (struct parport *port, if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT)) break; - DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n", - port->name); + pr_debug("%s: Host transfer recovered\n", port->name); if (time_after_eq (jiffies, expire)) break; goto try_again; @@ -534,7 +518,7 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, goto out; /* Yield the port for a while. */ - if (count && dev->port->irq != PARPORT_IRQ_NONE) { + if (dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); schedule_timeout_interruptible(msecs_to_jiffies(40)); parport_claim_or_block (dev); @@ -564,23 +548,20 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, command or a normal data byte, don't accept it. */ if (command) { if (byte & 0x80) { - DPRINTK (KERN_DEBUG "%s: stopping short at " - "channel command (%02x)\n", + pr_debug("%s: stopping short at channel command (%02x)\n", port->name, byte); goto out; } else if (port->ieee1284.mode != IEEE1284_MODE_ECPRLE) - DPRINTK (KERN_DEBUG "%s: device illegally " - "using RLE; accepting anyway\n", + pr_debug("%s: device illegally using RLE; accepting anyway\n", port->name); rle_count = byte + 1; /* Are we allowed to read that many bytes? */ if (rle_count > (len - count)) { - DPRINTK (KERN_DEBUG "%s: leaving %d RLE bytes " - "for next time\n", port->name, - rle_count); + pr_debug("%s: leaving %d RLE bytes for next time\n", + port->name, rle_count); break; } @@ -595,11 +576,10 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, PARPORT_STATUS_ACK)) { /* It's gone wrong. Return what data we have to the caller. */ - DPRINTK (KERN_DEBUG "ECP read timed out at 45\n"); + pr_debug("ECP read timed out at 45\n"); if (command) - printk (KERN_WARNING - "%s: command ignored (%02x)\n", + pr_warn("%s: command ignored (%02x)\n", port->name, byte); break; @@ -619,7 +599,7 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, memset (buf, byte, rle_count); buf += rle_count; count += rle_count; - DPRINTK (KERN_DEBUG "%s: decompressed to %d bytes\n", + pr_debug("%s: decompressed to %d bytes\n", port->name, rle_count); } else { /* Normal data byte. */ @@ -685,7 +665,7 @@ size_t parport_ieee1284_ecp_write_addr (struct parport *port, } /* Time for Host Transfer Recovery (page 41 of IEEE1284) */ - DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name); + pr_debug("%s: ECP transfer stalled!\n", port->name); parport_frob_control (port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT); @@ -701,8 +681,7 @@ size_t parport_ieee1284_ecp_write_addr (struct parport *port, if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT)) break; - DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n", - port->name); + pr_debug("%s: Host transfer recovered\n", port->name); if (time_after_eq (jiffies, expire)) break; goto try_again; diff --git a/drivers/parport/multiface.h b/drivers/parport/multiface.h index 56769dd5d315..6513a44b9ca7 100644 --- a/drivers/parport/multiface.h +++ b/drivers/parport/multiface.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MULTIFACE_H_ #define _MULTIFACE_H_ diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c index 09503b8d12e6..6a819bd00866 100644 --- a/drivers/parport/parport_amiga.c +++ b/drivers/parport/parport_amiga.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Low-level parallel port routines for the Amiga built-in port * * Author: Joerg Dorchain <joerg@dorchain.net> @@ -27,16 +28,10 @@ #include <asm/amigaints.h> #undef DEBUG -#ifdef DEBUG -#define DPRINTK printk -#else -#define DPRINTK(x...) do { } while (0) -#endif - static void amiga_write_data(struct parport *p, unsigned char data) { - DPRINTK(KERN_DEBUG "write_data %c\n",data); + pr_debug("write_data %c\n", data); /* Triggers also /STROBE. This behavior cannot be changed */ ciaa.prb = data; mb(); @@ -58,13 +53,13 @@ static unsigned char control_amiga_to_pc(unsigned char control) static void amiga_write_control(struct parport *p, unsigned char control) { - DPRINTK(KERN_DEBUG "write_control %02x\n",control); + pr_debug("write_control %02x\n", control); /* No implementation possible */ } static unsigned char amiga_read_control( struct parport *p) { - DPRINTK(KERN_DEBUG "read_control \n"); + pr_debug("read_control\n"); return control_amiga_to_pc(0); } @@ -72,7 +67,7 @@ static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, { unsigned char old; - DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val); + pr_debug("frob_control mask %02x, value %02x\n", mask, val); old = amiga_read_control(p); amiga_write_control(p, (old & ~mask) ^ val); return old; @@ -98,7 +93,7 @@ static unsigned char amiga_read_status(struct parport *p) unsigned char status; status = status_amiga_to_pc(ciab.pra & 7); - DPRINTK(KERN_DEBUG "read_status %02x\n", status); + pr_debug("read_status %02x\n", status); return status; } @@ -114,14 +109,14 @@ static void amiga_disable_irq(struct parport *p) static void amiga_data_forward(struct parport *p) { - DPRINTK(KERN_DEBUG "forward\n"); + pr_debug("forward\n"); ciaa.ddrb = 0xff; /* all pins output */ mb(); } static void amiga_data_reverse(struct parport *p) { - DPRINTK(KERN_DEBUG "reverse\n"); + pr_debug("reverse\n"); ciaa.ddrb = 0; /* all pins input */ mb(); } @@ -211,7 +206,7 @@ static int __init amiga_parallel_probe(struct platform_device *pdev) if (err) goto out_irq; - printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name); + pr_info("%s: Amiga built-in port using irq\n", p->name); /* XXX: set operating mode */ parport_announce_port(p); @@ -224,7 +219,7 @@ out_irq: return err; } -static int __exit amiga_parallel_remove(struct platform_device *pdev) +static void __exit amiga_parallel_remove(struct platform_device *pdev) { struct parport *port = platform_get_drvdata(pdev); @@ -232,15 +227,18 @@ static int __exit amiga_parallel_remove(struct platform_device *pdev) if (port->irq != PARPORT_IRQ_NONE) free_irq(IRQ_AMIGA_CIAA_FLG, port); parport_put_port(port); - platform_set_drvdata(pdev, NULL); - return 0; } -static struct platform_driver amiga_parallel_driver = { +/* + * amiga_parallel_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver amiga_parallel_driver __refdata = { .remove = __exit_p(amiga_parallel_remove), .driver = { .name = "amiga-parallel", - .owner = THIS_MODULE, }, }; @@ -248,6 +246,5 @@ module_platform_driver_probe(amiga_parallel_driver, amiga_parallel_probe); MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); -MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:amiga-parallel"); diff --git a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c index 7ad59ac68cf6..1623f010cdcc 100644 --- a/drivers/parport/parport_atari.c +++ b/drivers/parport/parport_atari.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Low-level parallel port routines for the Atari builtin port * * Author: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> @@ -18,7 +19,7 @@ #include <asm/irq.h> #include <asm/atariints.h> -static struct parport *this_port = NULL; +static struct parport *this_port; static unsigned char parport_atari_read_data(struct parport *p) @@ -192,14 +193,14 @@ static int __init parport_atari_init(void) &parport_atari_ops); if (!p) return -ENODEV; - if (request_irq(IRQ_MFP_BUSY, parport_irq_handler, - IRQ_TYPE_SLOW, p->name, p)) { + if (request_irq(IRQ_MFP_BUSY, parport_irq_handler, 0, p->name, + p)) { parport_put_port (p); return -ENODEV; } this_port = p; - printk(KERN_INFO "%s: Atari built-in port using irq\n", p->name); + pr_info("%s: Atari built-in port using irq\n", p->name); parport_announce_port (p); return 0; @@ -217,7 +218,6 @@ static void __exit parport_atari_exit(void) MODULE_AUTHOR("Andreas Schwab"); MODULE_DESCRIPTION("Parport Driver for Atari builtin Port"); -MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port"); MODULE_LICENSE("GPL"); module_init(parport_atari_init) diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c deleted file mode 100644 index 7c5d86696eed..000000000000 --- a/drivers/parport/parport_ax88796.c +++ /dev/null @@ -1,427 +0,0 @@ -/* linux/drivers/parport/parport_ax88796.c - * - * (c) 2005,2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/parport.h> -#include <linux/interrupt.h> -#include <linux/errno.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#define AX_SPR_BUSY (1<<7) -#define AX_SPR_ACK (1<<6) -#define AX_SPR_PE (1<<5) -#define AX_SPR_SLCT (1<<4) -#define AX_SPR_ERR (1<<3) - -#define AX_CPR_nDOE (1<<5) -#define AX_CPR_SLCTIN (1<<3) -#define AX_CPR_nINIT (1<<2) -#define AX_CPR_ATFD (1<<1) -#define AX_CPR_STRB (1<<0) - -struct ax_drvdata { - struct parport *parport; - struct parport_state suspend; - - struct device *dev; - struct resource *io; - - unsigned char irq_enabled; - - void __iomem *base; - void __iomem *spp_data; - void __iomem *spp_spr; - void __iomem *spp_cpr; -}; - -static inline struct ax_drvdata *pp_to_drv(struct parport *p) -{ - return p->private_data; -} - -static unsigned char -parport_ax88796_read_data(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - return readb(dd->spp_data); -} - -static void -parport_ax88796_write_data(struct parport *p, unsigned char data) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - writeb(data, dd->spp_data); -} - -static unsigned char -parport_ax88796_read_control(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int cpr = readb(dd->spp_cpr); - unsigned int ret = 0; - - if (!(cpr & AX_CPR_STRB)) - ret |= PARPORT_CONTROL_STROBE; - - if (!(cpr & AX_CPR_ATFD)) - ret |= PARPORT_CONTROL_AUTOFD; - - if (cpr & AX_CPR_nINIT) - ret |= PARPORT_CONTROL_INIT; - - if (!(cpr & AX_CPR_SLCTIN)) - ret |= PARPORT_CONTROL_SELECT; - - return ret; -} - -static void -parport_ax88796_write_control(struct parport *p, unsigned char control) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int cpr = readb(dd->spp_cpr); - - cpr &= AX_CPR_nDOE; - - if (!(control & PARPORT_CONTROL_STROBE)) - cpr |= AX_CPR_STRB; - - if (!(control & PARPORT_CONTROL_AUTOFD)) - cpr |= AX_CPR_ATFD; - - if (control & PARPORT_CONTROL_INIT) - cpr |= AX_CPR_nINIT; - - if (!(control & PARPORT_CONTROL_SELECT)) - cpr |= AX_CPR_SLCTIN; - - dev_dbg(dd->dev, "write_control: ctrl=%02x, cpr=%02x\n", control, cpr); - writeb(cpr, dd->spp_cpr); - - if (parport_ax88796_read_control(p) != control) { - dev_err(dd->dev, "write_control: read != set (%02x, %02x)\n", - parport_ax88796_read_control(p), control); - } -} - -static unsigned char -parport_ax88796_read_status(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int status = readb(dd->spp_spr); - unsigned int ret = 0; - - if (status & AX_SPR_BUSY) - ret |= PARPORT_STATUS_BUSY; - - if (status & AX_SPR_ACK) - ret |= PARPORT_STATUS_ACK; - - if (status & AX_SPR_ERR) - ret |= PARPORT_STATUS_ERROR; - - if (status & AX_SPR_SLCT) - ret |= PARPORT_STATUS_SELECT; - - if (status & AX_SPR_PE) - ret |= PARPORT_STATUS_PAPEROUT; - - return ret; -} - -static unsigned char -parport_ax88796_frob_control(struct parport *p, unsigned char mask, - unsigned char val) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned char old = parport_ax88796_read_control(p); - - dev_dbg(dd->dev, "frob: mask=%02x, val=%02x, old=%02x\n", - mask, val, old); - - parport_ax88796_write_control(p, (old & ~mask) | val); - return old; -} - -static void -parport_ax88796_enable_irq(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned long flags; - - local_irq_save(flags); - if (!dd->irq_enabled) { - enable_irq(p->irq); - dd->irq_enabled = 1; - } - local_irq_restore(flags); -} - -static void -parport_ax88796_disable_irq(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned long flags; - - local_irq_save(flags); - if (dd->irq_enabled) { - disable_irq(p->irq); - dd->irq_enabled = 0; - } - local_irq_restore(flags); -} - -static void -parport_ax88796_data_forward(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - void __iomem *cpr = dd->spp_cpr; - - writeb((readb(cpr) & ~AX_CPR_nDOE), cpr); -} - -static void -parport_ax88796_data_reverse(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - void __iomem *cpr = dd->spp_cpr; - - writeb(readb(cpr) | AX_CPR_nDOE, cpr); -} - -static void -parport_ax88796_init_state(struct pardevice *d, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(d->port); - - memset(s, 0, sizeof(struct parport_state)); - - dev_dbg(dd->dev, "init_state: %p: state=%p\n", d, s); - s->u.ax88796.cpr = readb(dd->spp_cpr); -} - -static void -parport_ax88796_save_state(struct parport *p, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - dev_dbg(dd->dev, "save_state: %p: state=%p\n", p, s); - s->u.ax88796.cpr = readb(dd->spp_cpr); -} - -static void -parport_ax88796_restore_state(struct parport *p, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - dev_dbg(dd->dev, "restore_state: %p: state=%p\n", p, s); - writeb(s->u.ax88796.cpr, dd->spp_cpr); -} - -static struct parport_operations parport_ax88796_ops = { - .write_data = parport_ax88796_write_data, - .read_data = parport_ax88796_read_data, - - .write_control = parport_ax88796_write_control, - .read_control = parport_ax88796_read_control, - .frob_control = parport_ax88796_frob_control, - - .read_status = parport_ax88796_read_status, - - .enable_irq = parport_ax88796_enable_irq, - .disable_irq = parport_ax88796_disable_irq, - - .data_forward = parport_ax88796_data_forward, - .data_reverse = parport_ax88796_data_reverse, - - .init_state = parport_ax88796_init_state, - .save_state = parport_ax88796_save_state, - .restore_state = parport_ax88796_restore_state, - - .epp_write_data = parport_ieee1284_epp_write_data, - .epp_read_data = parport_ieee1284_epp_read_data, - .epp_write_addr = parport_ieee1284_epp_write_addr, - .epp_read_addr = parport_ieee1284_epp_read_addr, - - .ecp_write_data = parport_ieee1284_ecp_write_data, - .ecp_read_data = parport_ieee1284_ecp_read_data, - .ecp_write_addr = parport_ieee1284_ecp_write_addr, - - .compat_write_data = parport_ieee1284_write_compat, - .nibble_read_data = parport_ieee1284_read_nibble, - .byte_read_data = parport_ieee1284_read_byte, - - .owner = THIS_MODULE, -}; - -static int parport_ax88796_probe(struct platform_device *pdev) -{ - struct device *_dev = &pdev->dev; - struct ax_drvdata *dd; - struct parport *pp = NULL; - struct resource *res; - unsigned long size; - int spacing; - int irq; - int ret; - - dd = kzalloc(sizeof(struct ax_drvdata), GFP_KERNEL); - if (dd == NULL) { - dev_err(_dev, "no memory for private data\n"); - return -ENOMEM; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(_dev, "no MEM specified\n"); - ret = -ENXIO; - goto exit_mem; - } - - size = resource_size(res); - spacing = size / 3; - - dd->io = request_mem_region(res->start, size, pdev->name); - if (dd->io == NULL) { - dev_err(_dev, "cannot reserve memory\n"); - ret = -ENXIO; - goto exit_mem; - } - - dd->base = ioremap(res->start, size); - if (dd->base == NULL) { - dev_err(_dev, "cannot ioremap region\n"); - ret = -ENXIO; - goto exit_res; - } - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - irq = PARPORT_IRQ_NONE; - - pp = parport_register_port((unsigned long)dd->base, irq, - PARPORT_DMA_NONE, - &parport_ax88796_ops); - - if (pp == NULL) { - dev_err(_dev, "failed to register parallel port\n"); - ret = -ENOMEM; - goto exit_unmap; - } - - pp->private_data = dd; - dd->parport = pp; - dd->dev = _dev; - - dd->spp_data = dd->base; - dd->spp_spr = dd->base + (spacing * 1); - dd->spp_cpr = dd->base + (spacing * 2); - - /* initialise the port controls */ - writeb(AX_CPR_STRB, dd->spp_cpr); - - if (irq >= 0) { - /* request irq */ - ret = request_irq(irq, parport_irq_handler, - IRQF_TRIGGER_FALLING, pdev->name, pp); - - if (ret < 0) - goto exit_port; - - dd->irq_enabled = 1; - } - - platform_set_drvdata(pdev, pp); - - dev_info(_dev, "attached parallel port driver\n"); - parport_announce_port(pp); - - return 0; - - exit_port: - parport_remove_port(pp); - exit_unmap: - iounmap(dd->base); - exit_res: - release_resource(dd->io); - kfree(dd->io); - exit_mem: - kfree(dd); - return ret; -} - -static int parport_ax88796_remove(struct platform_device *pdev) -{ - struct parport *p = platform_get_drvdata(pdev); - struct ax_drvdata *dd = pp_to_drv(p); - - free_irq(p->irq, p); - parport_remove_port(p); - iounmap(dd->base); - release_resource(dd->io); - kfree(dd->io); - kfree(dd); - - return 0; -} - -#ifdef CONFIG_PM - -static int parport_ax88796_suspend(struct platform_device *dev, - pm_message_t state) -{ - struct parport *p = platform_get_drvdata(dev); - struct ax_drvdata *dd = pp_to_drv(p); - - parport_ax88796_save_state(p, &dd->suspend); - writeb(AX_CPR_nDOE | AX_CPR_STRB, dd->spp_cpr); - return 0; -} - -static int parport_ax88796_resume(struct platform_device *dev) -{ - struct parport *p = platform_get_drvdata(dev); - struct ax_drvdata *dd = pp_to_drv(p); - - parport_ax88796_restore_state(p, &dd->suspend); - return 0; -} - -#else -#define parport_ax88796_suspend NULL -#define parport_ax88796_resume NULL -#endif - -MODULE_ALIAS("platform:ax88796-pp"); - -static struct platform_driver axdrv = { - .driver = { - .name = "ax88796-pp", - .owner = THIS_MODULE, - }, - .probe = parport_ax88796_probe, - .remove = parport_ax88796_remove, - .suspend = parport_ax88796_suspend, - .resume = parport_ax88796_resume, -}; - -module_platform_driver(axdrv); - -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("AX88796 Parport parallel port driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index e9b52e4a4648..8e7e3ac4bb87 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -142,10 +142,8 @@ static int parport_config(struct pcmcia_device *link) link->irq, PARPORT_DMA_NONE, &link->dev, IRQF_SHARED); if (p == NULL) { - printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " - "0x%3x, irq %u failed\n", - (unsigned int) link->resource[0]->start, - link->irq); + pr_notice("parport_cs: parport_pc_probe_port() at 0x%3x, irq %u failed\n", + (unsigned int)link->resource[0]->start, link->irq); goto failed; } @@ -158,8 +156,9 @@ static int parport_config(struct pcmcia_device *link) return 0; failed: - parport_cs_release(link); - return -ENODEV; + parport_cs_release(link); + kfree(link->priv); + return -ENODEV; } /* parport_config */ static void parport_cs_release(struct pcmcia_device *link) diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 6e3a60c78873..c7e18382dc01 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -1,14 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Low-level parallel-support for PC-style hardware integrated in the * LASI-Controller (on GSC-Bus) for HP-PARISC Workstations * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * * (C) 1999-2001 by Helge Deller <deller@gmx.de> - * * * based on parport_pc.c by * Grant Guenther <grant@torque.net> @@ -33,8 +28,7 @@ #include <linux/sysctl.h> #include <asm/io.h> -#include <asm/dma.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/superio.h> #include <linux/parport.h> @@ -46,7 +40,6 @@ MODULE_AUTHOR("Helge Deller <deller@gmx.de>"); MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver"); -MODULE_SUPPORTED_DEVICE("integrated PC-style parallel port"); MODULE_LICENSE("GPL"); @@ -232,9 +225,9 @@ static int parport_PS2_supported(struct parport *pb) /* --- Initialisation code -------------------------------- */ -struct parport *parport_gsc_probe_port(unsigned long base, +static struct parport *parport_gsc_probe_port(unsigned long base, unsigned long base_hi, int irq, - int dma, struct parisc_device *padev) + struct parisc_device *padev) { struct parport_gsc_private *priv; struct parport_operations *ops; @@ -243,25 +236,22 @@ struct parport *parport_gsc_probe_port(unsigned long base, priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); if (!priv) { - printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); + printk(KERN_DEBUG "parport (0x%lx): no memory!\n", base); return NULL; } ops = kmemdup(&parport_gsc_ops, sizeof(struct parport_operations), GFP_KERNEL); if (!ops) { - printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", - base); + printk(KERN_DEBUG "parport (0x%lx): no memory for ops!\n", + base); kfree (priv); return NULL; } priv->ctr = 0xc; priv->ctr_writable = 0xff; - priv->dma_buf = 0; - priv->dma_handle = 0; p->base = base; p->base_hi = base_hi; p->irq = irq; - p->dma = dma; p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; p->ops = ops; p->private_data = priv; @@ -287,44 +277,38 @@ struct parport *parport_gsc_probe_port(unsigned long base, p->size = (p->modes & PARPORT_MODE_EPP)?8:3; p->private_data = priv; - printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); + pr_info("%s: PC-style at 0x%lx", p->name, p->base); p->irq = irq; if (p->irq == PARPORT_IRQ_AUTO) { p->irq = PARPORT_IRQ_NONE; } - if (p->irq != PARPORT_IRQ_NONE) { - printk(", irq %d", p->irq); - - if (p->dma == PARPORT_DMA_AUTO) { - p->dma = PARPORT_DMA_NONE; - } - } - if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq - is mandatory (see above) */ - p->dma = PARPORT_DMA_NONE; - - printk(" ["); -#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}} + if (p->irq != PARPORT_IRQ_NONE) + pr_cont(", irq %d", p->irq); + + pr_cont(" ["); +#define printmode(x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) { int f = 0; printmode(PCSPP); printmode(TRISTATE); - printmode(COMPAT) + printmode(COMPAT); printmode(EPP); // printmode(ECP); // printmode(DMA); } #undef printmode - printk("]\n"); + pr_cont("]\n"); if (p->irq != PARPORT_IRQ_NONE) { if (request_irq (p->irq, parport_irq_handler, 0, p->name, p)) { - printk (KERN_WARNING "%s: irq %d in use, " - "resorting to polled operation\n", + pr_warn("%s: irq %d in use, resorting to polled operation\n", p->name, p->irq); p->irq = PARPORT_IRQ_NONE; - p->dma = PARPORT_DMA_NONE; } } @@ -346,13 +330,13 @@ struct parport *parport_gsc_probe_port(unsigned long base, static int parport_count; -static int parport_init_chip(struct parisc_device *dev) +static int __init parport_init_chip(struct parisc_device *dev) { struct parport *p; unsigned long port; if (!dev->irq) { - printk(KERN_WARNING "IRQ not found for parallel device at 0x%llx\n", + pr_warn("IRQ not found for parallel device at 0x%llx\n", (unsigned long long)dev->hpa.start); return -ENODEV; } @@ -365,15 +349,14 @@ static int parport_init_chip(struct parisc_device *dev) if (boot_cpu_data.cpu_type > pcxt && !pdc_add_valid(port+4)) { /* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */ - printk("%s: initialize bidirectional-mode.\n", __func__); + pr_info("%s: initialize bidirectional-mode\n", __func__); parport_writeb ( (0x10 + 0x20), port + 4); } else { - printk("%s: enhanced parport-modes not supported.\n", __func__); + pr_info("%s: enhanced parport-modes not supported\n", __func__); } - p = parport_gsc_probe_port(port, 0, dev->irq, - /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); + p = parport_gsc_probe_port(port, 0, dev->irq, dev); if (p) parport_count++; dev_set_drvdata(&dev->dev, p); @@ -381,43 +364,35 @@ static int parport_init_chip(struct parisc_device *dev) return 0; } -static int parport_remove_chip(struct parisc_device *dev) +static void __exit parport_remove_chip(struct parisc_device *dev) { struct parport *p = dev_get_drvdata(&dev->dev); if (p) { - struct parport_gsc_private *priv = p->private_data; struct parport_operations *ops = p->ops; parport_remove_port(p); - if (p->dma != PARPORT_DMA_NONE) - free_dma(p->dma); if (p->irq != PARPORT_IRQ_NONE) free_irq(p->irq, p); - if (priv->dma_buf) - pci_free_consistent(priv->dev, PAGE_SIZE, - priv->dma_buf, - priv->dma_handle); kfree (p->private_data); parport_put_port(p); kfree (ops); /* hope no-one cached it */ } - return 0; } -static struct parisc_device_id parport_tbl[] = { +static const struct parisc_device_id parport_tbl[] __initconst = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 }, { 0, } }; MODULE_DEVICE_TABLE(parisc, parport_tbl); -static struct parisc_driver parport_driver = { +static struct parisc_driver parport_driver __refdata = { .name = "Parallel", .id_table = parport_tbl, .probe = parport_init_chip, - .remove = parport_remove_chip, + .remove = __exit_p(parport_remove_chip), }; -int parport_gsc_init(void) +static int parport_gsc_init(void) { return register_parisc_driver(&parport_driver); } diff --git a/drivers/parport/parport_gsc.h b/drivers/parport/parport_gsc.h index 812214768d27..d447a568c257 100644 --- a/drivers/parport/parport_gsc.h +++ b/drivers/parport/parport_gsc.h @@ -1,24 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Low-level parallel-support for PC-style hardware integrated in the * LASI-Controller (on GSC-Bus) for HP-PARISC Workstations * * (C) 1999-2001 by Helge Deller <deller@gmx.de> * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * based on parport_pc.c by * Grant Guenther <grant@torque.net> * Phil Blundell <Philip.Blundell@pobox.com> @@ -77,15 +63,13 @@ struct parport_gsc_private { int writeIntrThreshold; /* buffer suitable for DMA, if DMA enabled */ - char *dma_buf; - dma_addr_t dma_handle; struct pci_dev *dev; }; static inline void parport_gsc_write_data(struct parport *p, unsigned char d) { #ifdef DEBUG_PARPORT - printk (KERN_DEBUG "parport_gsc_write_data(%p,0x%02x)\n", p, d); + printk(KERN_DEBUG "%s(%p,0x%02x)\n", __func__, p, d); #endif parport_writeb(d, DATA(p)); } @@ -94,8 +78,7 @@ static inline unsigned char parport_gsc_read_data(struct parport *p) { unsigned char val = parport_readb (DATA (p)); #ifdef DEBUG_PARPORT - printk (KERN_DEBUG "parport_gsc_read_data(%p) = 0x%02x\n", - p, val); + printk(KERN_DEBUG "%s(%p) = 0x%02x\n", __func__, p, val); #endif return val; } @@ -109,9 +92,9 @@ static inline unsigned char __parport_gsc_frob_control(struct parport *p, struct parport_gsc_private *priv = p->physport->private_data; unsigned char ctr = priv->ctr; #ifdef DEBUG_PARPORT - printk (KERN_DEBUG - "__parport_gsc_frob_control(%02x,%02x): %02x -> %02x\n", - mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); + printk(KERN_DEBUG "%s(%02x,%02x): %02x -> %02x\n", + __func__, mask, val, + ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); #endif ctr = (ctr & ~mask) ^ val; ctr &= priv->ctr_writable; /* only write writable bits. */ @@ -140,8 +123,8 @@ static inline void parport_gsc_write_control(struct parport *p, /* Take this out when drivers have adapted to newer interface. */ if (d & 0x20) { - printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n", - p->name, p->cad->name); + printk(KERN_DEBUG "%s (%s): use data_reverse for this!\n", + p->name, p->cad->name); parport_gsc_data_reverse (p); } @@ -169,9 +152,9 @@ static inline unsigned char parport_gsc_frob_control(struct parport *p, /* Take this out when drivers have adapted to newer interface. */ if (mask & 0x20) { - printk (KERN_DEBUG "%s (%s): use data_%s for this!\n", - p->name, p->cad->name, - (val & 0x20) ? "reverse" : "forward"); + printk(KERN_DEBUG "%s (%s): use data_%s for this!\n", + p->name, p->cad->name, + (val & 0x20) ? "reverse" : "forward"); if (val & 0x20) parport_gsc_data_reverse (p); else @@ -214,9 +197,4 @@ extern void parport_gsc_inc_use_count(void); extern void parport_gsc_dec_use_count(void); -extern struct parport *parport_gsc_probe_port(unsigned long base, - unsigned long base_hi, - int irq, int dma, - struct parisc_device *padev); - #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c index d4716273651e..0919ed99ba94 100644 --- a/drivers/parport/parport_ip32.c +++ b/drivers/parport/parport_ip32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* Low-level parallel port routines for built-in port on SGI IP32 * * Author: Arnaud Giersch <arnaud.giersch@free.fr> @@ -9,20 +10,6 @@ * Thanks to Ilya A. Volynets-Evenbakh for his help. * * Copyright (C) 2005, 2006 Arnaud Giersch. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Current status: @@ -102,7 +89,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/parport.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/stddef.h> @@ -138,7 +125,7 @@ static unsigned int features = ~0U; static bool verbose_probing = DEFAULT_VERBOSE_PROBING; /* We do not support more than one port. */ -static struct parport *this_port = NULL; +static struct parport *this_port; /* Timing constants for FIFO modes. */ #define FIFO_NFAULT_TIMEOUT 100 /* milliseconds */ @@ -341,19 +328,19 @@ static void parport_ip32_dump_state(struct parport *p, char *str, "TST", "CFG"}; unsigned int ecr = readb(priv->regs.ecr); printk(KERN_DEBUG PPIP32 " ecr=0x%02x", ecr); - printk(" %s", - ecr_modes[(ecr & ECR_MODE_MASK) >> ECR_MODE_SHIFT]); + pr_cont(" %s", + ecr_modes[(ecr & ECR_MODE_MASK) >> ECR_MODE_SHIFT]); if (ecr & ECR_nERRINTR) - printk(",nErrIntrEn"); + pr_cont(",nErrIntrEn"); if (ecr & ECR_DMAEN) - printk(",dmaEn"); + pr_cont(",dmaEn"); if (ecr & ECR_SERVINTR) - printk(",serviceIntr"); + pr_cont(",serviceIntr"); if (ecr & ECR_F_FULL) - printk(",f_full"); + pr_cont(",f_full"); if (ecr & ECR_F_EMPTY) - printk(",f_empty"); - printk("\n"); + pr_cont(",f_empty"); + pr_cont("\n"); } if (show_ecp_config) { unsigned int oecr, cnfgA, cnfgB; @@ -365,52 +352,53 @@ static void parport_ip32_dump_state(struct parport *p, char *str, writeb(ECR_MODE_PS2, priv->regs.ecr); writeb(oecr, priv->regs.ecr); printk(KERN_DEBUG PPIP32 " cnfgA=0x%02x", cnfgA); - printk(" ISA-%s", (cnfgA & CNFGA_IRQ) ? "Level" : "Pulses"); + pr_cont(" ISA-%s", (cnfgA & CNFGA_IRQ) ? "Level" : "Pulses"); switch (cnfgA & CNFGA_ID_MASK) { case CNFGA_ID_8: - printk(",8 bits"); + pr_cont(",8 bits"); break; case CNFGA_ID_16: - printk(",16 bits"); + pr_cont(",16 bits"); break; case CNFGA_ID_32: - printk(",32 bits"); + pr_cont(",32 bits"); break; default: - printk(",unknown ID"); + pr_cont(",unknown ID"); break; } if (!(cnfgA & CNFGA_nBYTEINTRANS)) - printk(",ByteInTrans"); + pr_cont(",ByteInTrans"); if ((cnfgA & CNFGA_ID_MASK) != CNFGA_ID_8) - printk(",%d byte%s left", cnfgA & CNFGA_PWORDLEFT, - ((cnfgA & CNFGA_PWORDLEFT) > 1) ? "s" : ""); - printk("\n"); + pr_cont(",%d byte%s left", + cnfgA & CNFGA_PWORDLEFT, + ((cnfgA & CNFGA_PWORDLEFT) > 1) ? "s" : ""); + pr_cont("\n"); printk(KERN_DEBUG PPIP32 " cnfgB=0x%02x", cnfgB); - printk(" irq=%u,dma=%u", - (cnfgB & CNFGB_IRQ_MASK) >> CNFGB_IRQ_SHIFT, - (cnfgB & CNFGB_DMA_MASK) >> CNFGB_DMA_SHIFT); - printk(",intrValue=%d", !!(cnfgB & CNFGB_INTRVAL)); + pr_cont(" irq=%u,dma=%u", + (cnfgB & CNFGB_IRQ_MASK) >> CNFGB_IRQ_SHIFT, + (cnfgB & CNFGB_DMA_MASK) >> CNFGB_DMA_SHIFT); + pr_cont(",intrValue=%d", !!(cnfgB & CNFGB_INTRVAL)); if (cnfgB & CNFGB_COMPRESS) - printk(",compress"); - printk("\n"); + pr_cont(",compress"); + pr_cont("\n"); } for (i = 0; i < 2; i++) { unsigned int dcr = i ? priv->dcr_cache : readb(priv->regs.dcr); printk(KERN_DEBUG PPIP32 " dcr(%s)=0x%02x", i ? "soft" : "hard", dcr); - printk(" %s", (dcr & DCR_DIR) ? "rev" : "fwd"); + pr_cont(" %s", (dcr & DCR_DIR) ? "rev" : "fwd"); if (dcr & DCR_IRQ) - printk(",ackIntEn"); + pr_cont(",ackIntEn"); if (!(dcr & DCR_SELECT)) - printk(",nSelectIn"); + pr_cont(",nSelectIn"); if (dcr & DCR_nINIT) - printk(",nInit"); + pr_cont(",nInit"); if (!(dcr & DCR_AUTOFD)) - printk(",nAutoFD"); + pr_cont(",nAutoFD"); if (!(dcr & DCR_STROBE)) - printk(",nStrobe"); - printk("\n"); + pr_cont(",nStrobe"); + pr_cont("\n"); } #define sep (f++ ? ',' : ' ') { @@ -418,20 +406,20 @@ static void parport_ip32_dump_state(struct parport *p, char *str, unsigned int dsr = readb(priv->regs.dsr); printk(KERN_DEBUG PPIP32 " dsr=0x%02x", dsr); if (!(dsr & DSR_nBUSY)) - printk("%cBusy", sep); + pr_cont("%cBusy", sep); if (dsr & DSR_nACK) - printk("%cnAck", sep); + pr_cont("%cnAck", sep); if (dsr & DSR_PERROR) - printk("%cPError", sep); + pr_cont("%cPError", sep); if (dsr & DSR_SELECT) - printk("%cSelect", sep); + pr_cont("%cSelect", sep); if (dsr & DSR_nFAULT) - printk("%cnFault", sep); + pr_cont("%cnFault", sep); if (!(dsr & DSR_nPRINT)) - printk("%c(Print)", sep); + pr_cont("%c(Print)", sep); if (dsr & DSR_TIMEOUT) - printk("%cTimeout", sep); - printk("\n"); + pr_cont("%cTimeout", sep); + pr_cont("\n"); } #undef sep } @@ -568,6 +556,7 @@ static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id) /** * parport_ip32_dma_start - begins a DMA transfer + * @p: partport to work on * @dir: DMA direction: DMA_TO_DEVICE or DMA_FROM_DEVICE * @addr: pointer to data buffer * @count: buffer size @@ -575,8 +564,8 @@ static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id) * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be * correctly balanced. */ -static int parport_ip32_dma_start(enum dma_data_direction dir, - void *addr, size_t count) +static int parport_ip32_dma_start(struct parport *p, + enum dma_data_direction dir, void *addr, size_t count) { unsigned int limit; u64 ctrl; @@ -601,7 +590,7 @@ static int parport_ip32_dma_start(enum dma_data_direction dir, /* Prepare DMA pointers */ parport_ip32_dma.dir = dir; - parport_ip32_dma.buf = dma_map_single(NULL, addr, count, dir); + parport_ip32_dma.buf = dma_map_single(&p->bus_dev, addr, count, dir); parport_ip32_dma.len = count; parport_ip32_dma.next = parport_ip32_dma.buf; parport_ip32_dma.left = parport_ip32_dma.len; @@ -625,11 +614,12 @@ static int parport_ip32_dma_start(enum dma_data_direction dir, /** * parport_ip32_dma_stop - ends a running DMA transfer + * @p: partport to work on * * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be * correctly balanced. */ -static void parport_ip32_dma_stop(void) +static void parport_ip32_dma_stop(struct parport *p) { u64 ctx_a; u64 ctx_b; @@ -685,8 +675,8 @@ static void parport_ip32_dma_stop(void) enable_irq(MACEISA_PAR_CTXB_IRQ); parport_ip32_dma.irq_on = 1; - dma_unmap_single(NULL, parport_ip32_dma.buf, parport_ip32_dma.len, - parport_ip32_dma.dir); + dma_unmap_single(&p->bus_dev, parport_ip32_dma.buf, + parport_ip32_dma.len, parport_ip32_dma.dir); } /** @@ -1331,7 +1321,7 @@ static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p) break; /* Initialize mutex used to take interrupts into account */ - INIT_COMPLETION(priv->irq_complete); + reinit_completion(&priv->irq_complete); /* Enable serviceIntr */ parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); @@ -1348,9 +1338,8 @@ static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p) ecr = parport_ip32_read_econtrol(p); if ((ecr & ECR_F_EMPTY) && !(ecr & ECR_SERVINTR) && !lost_interrupt) { - printk(KERN_WARNING PPIP32 - "%s: lost interrupt in %s\n", - p->name, __func__); + pr_warn(PPIP32 "%s: lost interrupt in %s\n", + p->name, __func__); lost_interrupt = 1; } } @@ -1445,8 +1434,8 @@ static size_t parport_ip32_fifo_write_block_dma(struct parport *p, priv->irq_mode = PARPORT_IP32_IRQ_HERE; - parport_ip32_dma_start(DMA_TO_DEVICE, (void *)buf, len); - INIT_COMPLETION(priv->irq_complete); + parport_ip32_dma_start(p, DMA_TO_DEVICE, (void *)buf, len); + reinit_completion(&priv->irq_complete); parport_ip32_frob_econtrol(p, ECR_DMAEN | ECR_SERVINTR, ECR_DMAEN); nfault_timeout = min((unsigned long)physport->cad->timeout, @@ -1461,7 +1450,7 @@ static size_t parport_ip32_fifo_write_block_dma(struct parport *p, if (ecr & ECR_SERVINTR) break; /* DMA transfer just finished */ } - parport_ip32_dma_stop(); + parport_ip32_dma_stop(p); written = len - parport_ip32_dma_get_residue(); priv->irq_mode = PARPORT_IP32_IRQ_FWD; @@ -1654,8 +1643,8 @@ static size_t parport_ip32_compat_write_data(struct parport *p, DSR_nBUSY | DSR_nFAULT)) { /* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); + pr_info(PPIP32 "%s: not ready in %s\n", + p->name, __func__); ready_before = 0; goto stop; } @@ -1715,7 +1704,7 @@ static size_t parport_ip32_ecp_write_data(struct parport *p, /* Event 49: PError goes high. */ if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) { - printk(KERN_DEBUG PPIP32 "%s: PError timeout in %s", + printk(KERN_DEBUG PPIP32 "%s: PError timeout in %s\n", p->name, __func__); physport->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN; return 0; @@ -1735,8 +1724,8 @@ static size_t parport_ip32_ecp_write_data(struct parport *p, DSR_nBUSY | DSR_nFAULT)) { /* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); + pr_info(PPIP32 "%s: not ready in %s\n", + p->name, __func__); ready_before = 0; goto stop; } @@ -1769,7 +1758,7 @@ stop: /*--- Default parport operations ---------------------------------------*/ -static __initdata struct parport_operations parport_ip32_ops = { +static const struct parport_operations parport_ip32_ops __initconst = { .write_data = parport_ip32_write_data, .read_data = parport_ip32_read_data, @@ -2075,8 +2064,7 @@ static __init struct parport *parport_ip32_probe_port(void) p->modes |= PARPORT_MODE_TRISTATE; if (!parport_ip32_fifo_supported(p)) { - printk(KERN_WARNING PPIP32 - "%s: error: FIFO disabled\n", p->name); + pr_warn(PPIP32 "%s: error: FIFO disabled\n", p->name); /* Disable hardware modes depending on a working FIFO. */ features &= ~PARPORT_IP32_ENABLE_SPP; features &= ~PARPORT_IP32_ENABLE_ECP; @@ -2088,8 +2076,7 @@ static __init struct parport *parport_ip32_probe_port(void) if (features & PARPORT_IP32_ENABLE_IRQ) { int irq = MACEISA_PARALLEL_IRQ; if (request_irq(irq, parport_ip32_interrupt, 0, p->name, p)) { - printk(KERN_WARNING PPIP32 - "%s: error: IRQ disabled\n", p->name); + pr_warn(PPIP32 "%s: error: IRQ disabled\n", p->name); /* DMA cannot work without interrupts. */ features &= ~PARPORT_IP32_ENABLE_DMA; } else { @@ -2102,8 +2089,7 @@ static __init struct parport *parport_ip32_probe_port(void) /* Allocate DMA resources */ if (features & PARPORT_IP32_ENABLE_DMA) { if (parport_ip32_dma_register()) - printk(KERN_WARNING PPIP32 - "%s: error: DMA disabled\n", p->name); + pr_warn(PPIP32 "%s: error: DMA disabled\n", p->name); else { pr_probe(p, "DMA support enabled\n"); p->dma = 0; /* arbitrary value != PARPORT_DMA_NONE */ @@ -2145,13 +2131,15 @@ static __init struct parport *parport_ip32_probe_port(void) parport_ip32_dump_state(p, "end init", 0); /* Print out what we found */ - printk(KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)", - p->name, p->base, p->base_hi); + pr_info("%s: SGI IP32 at 0x%lx (0x%lx)", p->name, p->base, p->base_hi); if (p->irq != PARPORT_IRQ_NONE) - printk(", irq %d", p->irq); - printk(" ["); -#define printmode(x) if (p->modes & PARPORT_MODE_##x) \ - printk("%s%s", f++ ? "," : "", #x) + pr_cont(", irq %d", p->irq); + pr_cont(" ["); +#define printmode(x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) { unsigned int f = 0; printmode(PCSPP); @@ -2162,7 +2150,7 @@ static __init struct parport *parport_ip32_probe_port(void) printmode(DMA); } #undef printmode - printk("]\n"); + pr_cont("]\n"); parport_announce_port(p); return p; @@ -2204,7 +2192,7 @@ static int __init parport_ip32_init(void) { pr_info(PPIP32 "SGI IP32 built-in parallel port driver v0.6\n"); this_port = parport_ip32_probe_port(); - return IS_ERR(this_port) ? PTR_ERR(this_port) : 0; + return PTR_ERR_OR_ZERO(this_port); } /** @@ -2236,15 +2224,3 @@ MODULE_PARM_DESC(features, ", bit 2: hardware SPP mode" ", bit 3: hardware EPP mode" ", bit 4: hardware ECP mode"); - -/*--- Inform (X)Emacs about preferred coding style ---------------------*/ -/* - * Local Variables: - * mode: c - * c-file-style: "linux" - * indent-tabs-mode: t - * tab-width: 8 - * fill-column: 78 - * ispell-local-dictionary: "american" - * End: - */ diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c index 7578d79b3688..bb1817218d7b 100644 --- a/drivers/parport/parport_mfc3.c +++ b/drivers/parport/parport_mfc3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Low-level parallel port routines for the Multiface 3 card * * Author: Joerg Dorchain <joerg@dorchain.net> @@ -69,11 +70,6 @@ #define MAX_MFC 5 #undef DEBUG -#ifdef DEBUG -#define DPRINTK printk -#else -static inline int DPRINTK(void *nothing, ...) {return 0;} -#endif static struct parport *this_port[MAX_MFC] = {NULL, }; static volatile int dummy; /* for trigger readds */ @@ -83,7 +79,7 @@ static struct parport_operations pp_mfc3_ops; static void mfc3_write_data(struct parport *p, unsigned char data) { -DPRINTK(KERN_DEBUG "write_data %c\n",data); + pr_debug("write_data %c\n", data); dummy = pia(p)->pprb; /* clears irq bit */ /* Triggers also /STROBE.*/ @@ -106,8 +102,7 @@ static unsigned char control_pc_to_mfc3(unsigned char control) ret |= 128; if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */ ret &= ~64; - if (control & PARPORT_CONTROL_STROBE) /* Strobe */ - /* Handled directly by hardware */; + /* PARPORT_CONTROL_STROBE handled directly by hardware */ return ret; } @@ -127,13 +122,13 @@ static unsigned char control_mfc3_to_pc(unsigned char control) static void mfc3_write_control(struct parport *p, unsigned char control) { -DPRINTK(KERN_DEBUG "write_control %02x\n",control); + pr_debug("write_control %02x\n", control); pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control); } static unsigned char mfc3_read_control( struct parport *p) { -DPRINTK(KERN_DEBUG "read_control \n"); + pr_debug("read_control\n"); return control_mfc3_to_pc(pia(p)->ppra & 0xe0); } @@ -141,7 +136,7 @@ static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, u { unsigned char old; -DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val); + pr_debug("frob_control mask %02x, value %02x\n", mask, val); old = mfc3_read_control(p); mfc3_write_control(p, (old & ~mask) ^ val); return old; @@ -170,11 +165,11 @@ static unsigned char mfc3_read_status(struct parport *p) unsigned char status; status = status_mfc3_to_pc(pia(p)->ppra & 0x1f); -DPRINTK(KERN_DEBUG "read_status %02x\n", status); + pr_debug("read_status %02x\n", status); return status; } -static int use_cnt = 0; +static int use_cnt; static irqreturn_t mfc3_interrupt(int irq, void *dev_id) { @@ -201,7 +196,7 @@ static void mfc3_disable_irq(struct parport *p) static void mfc3_data_forward(struct parport *p) { - DPRINTK(KERN_DEBUG "forward\n"); + pr_debug("forward\n"); pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ pia(p)->pddrb = 255; /* all pins output */ pia(p)->crb |= PIA_DDR; /* make data register visible - default */ @@ -209,7 +204,7 @@ static void mfc3_data_forward(struct parport *p) static void mfc3_data_reverse(struct parport *p) { - DPRINTK(KERN_DEBUG "reverse\n"); + pr_debug("reverse\n"); pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ pia(p)->pddrb = 0; /* all pins input */ pia(p)->crb |= PIA_DDR; /* make data register visible - default */ @@ -300,7 +295,7 @@ static int __init parport_mfc3_init(void) if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) continue; - pp = (struct pia *)ZTWO_VADDR(piabase); + pp = ZTWO_VADDR(piabase); pp->crb = 0; pp->pddrb = 255; /* all data pins output */ pp->crb = PIA_DDR|32|8; @@ -324,7 +319,7 @@ static int __init parport_mfc3_init(void) p->dev = &z->dev; this_port[pias++] = p; - printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); + pr_info("%s: Multiface III port using irq\n", p->name); /* XXX: set operating mode */ p->private_data = (void *)piabase; @@ -363,7 +358,6 @@ static void __exit parport_mfc3_exit(void) MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port"); -MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port"); MODULE_LICENSE("GPL"); module_init(parport_mfc3_init) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 903e1285fda0..f33b5d1ddfc1 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Low-level parallel-port routines for 8255-based PC-style hardware. * * Authors: Phil Blundell <philb@gnu.org> @@ -44,7 +45,7 @@ #include <linux/module.h> #include <linux/init.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/delay.h> #include <linux/errno.h> #include <linux/interrupt.h> @@ -86,13 +87,6 @@ #undef DEBUG -#ifdef DEBUG -#define DPRINTK printk -#else -#define DPRINTK(stuff...) -#endif - - #define NR_SUPERIOS 3 static struct superio_struct { /* For Super-IO chips autodetection */ int io; @@ -112,15 +106,22 @@ static int pnp_registered_parport; static void frob_econtrol(struct parport *pb, unsigned char m, unsigned char v) { + const struct parport_pc_private *priv = pb->physport->private_data; + unsigned char ecr_writable = priv->ecr_writable; unsigned char ectr = 0; + unsigned char new; if (m != 0xff) ectr = inb(ECONTROL(pb)); - DPRINTK(KERN_DEBUG "frob_econtrol(%02x,%02x): %02x -> %02x\n", - m, v, ectr, (ectr & ~m) ^ v); + new = (ectr & ~m) ^ v; + if (ecr_writable) + /* All known users of the ECR mask require bit 0 to be set. */ + new = (new & ecr_writable) | 1; + + pr_debug("frob_econtrol(%02x,%02x): %02x -> %02x\n", m, v, ectr, new); - outb((ectr & ~m) ^ v, ECONTROL(pb)); + outb(new, ECONTROL(pb)); } static inline void frob_set_mode(struct parport *p, int mode) @@ -141,7 +142,7 @@ static int change_mode(struct parport *p, int m) unsigned char oecr; int mode; - DPRINTK(KERN_INFO "parport change_mode ECP-ISA to mode 0x%02x\n", m); + pr_debug("parport change_mode ECP-ISA to mode 0x%02x\n", m); if (!priv->ecr) { printk(KERN_DEBUG "change_mode: but there's no ECR!\n"); @@ -297,16 +298,22 @@ static size_t parport_pc_epp_read_data(struct parport *port, void *buf, status = inb(STATUS(port)); if (status & 0x01) { /* EPP timeout should never occur... */ - printk(KERN_DEBUG -"%s: EPP timeout occurred while talking to w91284pic (should not have done)\n", port->name); + printk(KERN_DEBUG "%s: EPP timeout occurred while talking to w91284pic (should not have done)\n", + port->name); clear_epp_timeout(port); } } return got; } - if ((flags & PARPORT_EPP_FAST) && (length > 1)) { - if (!(((long)buf | length) & 0x03)) + if ((length > 1) && ((flags & PARPORT_EPP_FAST_32) + || flags & PARPORT_EPP_FAST_16 + || flags & PARPORT_EPP_FAST_8)) { + if ((flags & PARPORT_EPP_FAST_32) + && !(((long)buf | length) & 0x03)) insl(EPPDATA(port), buf, (length >> 2)); + else if ((flags & PARPORT_EPP_FAST_16) + && !(((long)buf | length) & 0x01)) + insw(EPPDATA(port), buf, length >> 1); else insb(EPPDATA(port), buf, length); if (inb(STATUS(port)) & 0x01) { @@ -333,9 +340,15 @@ static size_t parport_pc_epp_write_data(struct parport *port, const void *buf, { size_t written = 0; - if ((flags & PARPORT_EPP_FAST) && (length > 1)) { - if (!(((long)buf | length) & 0x03)) + if ((length > 1) && ((flags & PARPORT_EPP_FAST_32) + || flags & PARPORT_EPP_FAST_16 + || flags & PARPORT_EPP_FAST_8)) { + if ((flags & PARPORT_EPP_FAST_32) + && !(((long)buf | length) & 0x03)) outsl(EPPDATA(port), buf, (length >> 2)); + else if ((flags & PARPORT_EPP_FAST_16) + && !(((long)buf | length) & 0x01)) + outsw(EPPDATA(port), buf, length >> 1); else outsb(EPPDATA(port), buf, length); if (inb(STATUS(port)) & 0x01) { @@ -474,7 +487,7 @@ static size_t parport_pc_fifo_write_block_pio(struct parport *port, const unsigned char *bufp = buf; size_t left = length; unsigned long expire = jiffies + port->physport->cad->timeout; - const int fifo = FIFO(port); + const unsigned long fifo = FIFO(port); int poll_for = 8; /* 80 usecs */ const struct parport_pc_private *priv = port->physport->private_data; const int fifo_depth = priv->fifo_depth; @@ -726,7 +739,7 @@ static size_t parport_pc_compat_write_block_pio(struct parport *port, r = change_mode(port, ECR_PPF); /* Parallel port FIFO */ if (r) printk(KERN_DEBUG "%s: Warning change_mode ECR_PPF failed\n", - port->name); + port->name); port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; @@ -769,9 +782,8 @@ static size_t parport_pc_compat_write_block_pio(struct parport *port, PARPORT_STATUS_BUSY, PARPORT_STATUS_BUSY); if (r) - printk(KERN_DEBUG - "%s: BUSY timeout (%d) in compat_write_block_pio\n", - port->name, r); + printk(KERN_DEBUG "%s: BUSY timeout (%d) in compat_write_block_pio\n", + port->name, r); port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; @@ -809,8 +821,8 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, PARPORT_STATUS_PAPEROUT, PARPORT_STATUS_PAPEROUT); if (r) { - printk(KERN_DEBUG "%s: PError timeout (%d) " - "in ecp_write_block_pio\n", port->name, r); + printk(KERN_DEBUG "%s: PError timeout (%d) in ecp_write_block_pio\n", + port->name, r); } } @@ -823,7 +835,7 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, r = change_mode(port, ECR_ECP); /* ECP FIFO */ if (r) printk(KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", - port->name); + port->name); port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; /* Write the data to the FIFO. */ @@ -866,8 +878,8 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, parport_frob_control(port, PARPORT_CONTROL_INIT, 0); r = parport_wait_peripheral(port, PARPORT_STATUS_PAPEROUT, 0); if (r) - printk(KERN_DEBUG "%s: PE,1 timeout (%d) " - "in ecp_write_block_pio\n", port->name, r); + printk(KERN_DEBUG "%s: PE,1 timeout (%d) in ecp_write_block_pio\n", + port->name, r); parport_frob_control(port, PARPORT_CONTROL_INIT, @@ -876,17 +888,16 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, PARPORT_STATUS_PAPEROUT, PARPORT_STATUS_PAPEROUT); if (r) - printk(KERN_DEBUG "%s: PE,2 timeout (%d) " - "in ecp_write_block_pio\n", port->name, r); + printk(KERN_DEBUG "%s: PE,2 timeout (%d) in ecp_write_block_pio\n", + port->name, r); } r = parport_wait_peripheral(port, PARPORT_STATUS_BUSY, PARPORT_STATUS_BUSY); if (r) - printk(KERN_DEBUG - "%s: BUSY timeout (%d) in ecp_write_block_pio\n", - port->name, r); + printk(KERN_DEBUG "%s: BUSY timeout (%d) in ecp_write_block_pio\n", + port->name, r); port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; @@ -902,7 +913,7 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, * ****************************************** */ -/* GCC is not inlining extern inline function later overwriten to non-inline, +/* GCC is not inlining extern inline function later overwritten to non-inline, so we use outlined_ variants here. */ static const struct parport_operations parport_pc_ops = { .write_data = parport_pc_write_data, @@ -981,28 +992,24 @@ static void show_parconfig_smsc37c669(int io, int key) outb(0xaa, io); if (verbose_probing) { - printk(KERN_INFO - "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, " - "A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n", + pr_info("SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n", cr1, cr4, cra, cr23, cr26, cr27); /* The documentation calls DMA and IRQ-Lines by letters, so the board maker can/will wire them appropriately/randomly... G=reserved H=IDE-irq, */ - printk(KERN_INFO - "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, fifo threshold=%d\n", - cr23 * 4, - (cr27 & 0x0f) ? 'A' - 1 + (cr27 & 0x0f) : '-', - (cr26 & 0x0f) ? 'A' - 1 + (cr26 & 0x0f) : '-', - cra & 0x0f); - printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n", - (cr23 * 4 >= 0x100) ? "yes" : "no", - (cr1 & 4) ? "yes" : "no"); - printk(KERN_INFO - "SMSC LPT Config: Port mode=%s, EPP version =%s\n", - (cr1 & 0x08) ? "Standard mode only (SPP)" - : modes[cr4 & 0x03], - (cr4 & 0x40) ? "1.7" : "1.9"); + pr_info("SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, fifo threshold=%d\n", + cr23 * 4, + (cr27 & 0x0f) ? 'A' - 1 + (cr27 & 0x0f) : '-', + (cr26 & 0x0f) ? 'A' - 1 + (cr26 & 0x0f) : '-', + cra & 0x0f); + pr_info("SMSC LPT Config: enabled=%s power=%s\n", + (cr23 * 4 >= 0x100) ? "yes" : "no", + (cr1 & 4) ? "yes" : "no"); + pr_info("SMSC LPT Config: Port mode=%s, EPP version =%s\n", + (cr1 & 0x08) ? "Standard mode only (SPP)" + : modes[cr4 & 0x03], + (cr4 & 0x40) ? "1.7" : "1.9"); } /* Heuristics ! BIOS setup for this mainboard device limits @@ -1012,7 +1019,7 @@ static void show_parconfig_smsc37c669(int io, int key) if (cr23 * 4 >= 0x100) { /* if active */ s = find_free_superio(); if (s == NULL) - printk(KERN_INFO "Super-IO: too many chips!\n"); + pr_info("Super-IO: too many chips!\n"); else { int d; switch (cr23 * 4) { @@ -1077,26 +1084,24 @@ static void show_parconfig_winbond(int io, int key) outb(0xaa, io); if (verbose_probing) { - printk(KERN_INFO - "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x 70=%02x 74=%02x, f0=%02x\n", - cr30, cr60, cr61, cr70, cr74, crf0); - printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", - (cr30 & 0x01) ? "yes" : "no", cr60, cr61, cr70 & 0x0f); + pr_info("Winbond LPT Config: cr_30=%02x 60,61=%02x%02x 70=%02x 74=%02x, f0=%02x\n", + cr30, cr60, cr61, cr70, cr74, crf0); + pr_info("Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", + (cr30 & 0x01) ? "yes" : "no", cr60, cr61, cr70 & 0x0f); if ((cr74 & 0x07) > 3) - printk("dma=none\n"); + pr_cont("dma=none\n"); else - printk("dma=%d\n", cr74 & 0x07); - printk(KERN_INFO - "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n", - irqtypes[crf0>>7], (crf0>>3)&0x0f); - printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", - modes[crf0 & 0x07]); + pr_cont("dma=%d\n", cr74 & 0x07); + pr_info("Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n", + irqtypes[crf0 >> 7], (crf0 >> 3) & 0x0f); + pr_info("Winbond LPT Config: Port mode=%s\n", + modes[crf0 & 0x07]); } if (cr30 & 0x01) { /* the settings can be interrogated later ... */ s = find_free_superio(); if (s == NULL) - printk(KERN_INFO "Super-IO: too many chips!\n"); + pr_info("Super-IO: too many chips!\n"); else { s->io = (cr60 << 8) | cr61; s->irq = cr70 & 0x0f; @@ -1150,9 +1155,8 @@ static void decode_winbond(int efer, int key, int devid, int devrev, int oldid) progif = 0; if (verbose_probing) - printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x " - "devid=%02x devrev=%02x oldid=%02x type=%s\n", - efer, key, devid, devrev, oldid, type); + pr_info("Winbond chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x oldid=%02x type=%s\n", + efer, key, devid, devrev, oldid, type); if (progif == 2) show_parconfig_winbond(efer, key); @@ -1183,9 +1187,8 @@ static void decode_smsc(int efer, int key, int devid, int devrev) type = "37c666GT"; if (verbose_probing) - printk(KERN_INFO "SMSC chip at EFER=0x%x " - "key=0x%02x devid=%02x devrev=%02x type=%s\n", - efer, key, devid, devrev, type); + pr_info("SMSC chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x type=%s\n", + efer, key, devid, devrev, type); if (func) func(efer, key); @@ -1357,7 +1360,7 @@ static void detect_and_report_it87(void) dev |= inb(0x2f); if (dev == 0x8712 || dev == 0x8705 || dev == 0x8715 || dev == 0x8716 || dev == 0x8718 || dev == 0x8726) { - printk(KERN_INFO "IT%04X SuperIO detected.\n", dev); + pr_info("IT%04X SuperIO detected\n", dev); outb(0x07, 0x2E); /* Parallel Port */ outb(0x03, 0x2F); outb(0xF0, 0x2E); /* BOOT 0x80 off */ @@ -1377,7 +1380,7 @@ static struct superio_struct *find_superio(struct parport *p) { int i; for (i = 0; i < NR_SUPERIOS; i++) - if (superios[i].io != p->base) + if (superios[i].io == p->base) return &superios[i]; return NULL; } @@ -1444,8 +1447,8 @@ static int parport_SPP_supported(struct parport *pb) if (user_specified) /* That didn't work, but the user thinks there's a * port here. */ - printk(KERN_INFO "parport 0x%lx (WARNING): CTR: " - "wrote 0x%02x, read 0x%02x\n", pb->base, w, r); + pr_info("parport 0x%lx (WARNING): CTR: wrote 0x%02x, read 0x%02x\n", + pb->base, w, r); /* Try the data register. The data lines aren't tri-stated at * this stage, so we expect back what we wrote. */ @@ -1463,10 +1466,9 @@ static int parport_SPP_supported(struct parport *pb) if (user_specified) { /* Didn't work, but the user is convinced this is the * place. */ - printk(KERN_INFO "parport 0x%lx (WARNING): DATA: " - "wrote 0x%02x, read 0x%02x\n", pb->base, w, r); - printk(KERN_INFO "parport 0x%lx: You gave this address, " - "but there is probably no parallel port there!\n", + pr_info("parport 0x%lx (WARNING): DATA: wrote 0x%02x, read 0x%02x\n", + pb->base, w, r); + pr_info("parport 0x%lx: You gave this address, but there is probably no parallel port there!\n", pb->base); } @@ -1496,21 +1498,24 @@ static int parport_ECR_present(struct parport *pb) struct parport_pc_private *priv = pb->private_data; unsigned char r = 0xc; - outb(r, CONTROL(pb)); - if ((inb(ECONTROL(pb)) & 0x3) == (r & 0x3)) { - outb(r ^ 0x2, CONTROL(pb)); /* Toggle bit 1 */ + if (!priv->ecr_writable) { + outb(r, CONTROL(pb)); + if ((inb(ECONTROL(pb)) & 0x3) == (r & 0x3)) { + outb(r ^ 0x2, CONTROL(pb)); /* Toggle bit 1 */ - r = inb(CONTROL(pb)); - if ((inb(ECONTROL(pb)) & 0x2) == (r & 0x2)) - goto no_reg; /* Sure that no ECR register exists */ - } + r = inb(CONTROL(pb)); + if ((inb(ECONTROL(pb)) & 0x2) == (r & 0x2)) + /* Sure that no ECR register exists */ + goto no_reg; + } - if ((inb(ECONTROL(pb)) & 0x3) != 0x1) - goto no_reg; + if ((inb(ECONTROL(pb)) & 0x3) != 0x1) + goto no_reg; - ECR_WRITE(pb, 0x34); - if (inb(ECONTROL(pb)) != 0x35) - goto no_reg; + ECR_WRITE(pb, 0x34); + if (inb(ECONTROL(pb)) != 0x35) + goto no_reg; + } priv->ecr = 1; outb(0xc, CONTROL(pb)); @@ -1619,7 +1624,7 @@ static int parport_ECP_supported(struct parport *pb) if (i <= priv->fifo_depth) { if (verbose_probing) printk(KERN_DEBUG "0x%lx: writeIntrThreshold is %d\n", - pb->base, i); + pb->base, i); } else /* Number of bytes we know we can write if we get an interrupt. */ @@ -1641,7 +1646,7 @@ static int parport_ECP_supported(struct parport *pb) if (i <= priv->fifo_depth) { if (verbose_probing) - printk(KERN_INFO "0x%lx: readIntrThreshold is %d\n", + pr_info("0x%lx: readIntrThreshold is %d\n", pb->base, i); } else /* Number of bytes we can read if we get an interrupt. */ @@ -1656,18 +1661,15 @@ static int parport_ECP_supported(struct parport *pb) switch (pword) { case 0: pword = 2; - printk(KERN_WARNING "0x%lx: Unsupported pword size!\n", - pb->base); + pr_warn("0x%lx: Unsupported pword size!\n", pb->base); break; case 2: pword = 4; - printk(KERN_WARNING "0x%lx: Unsupported pword size!\n", - pb->base); + pr_warn("0x%lx: Unsupported pword size!\n", pb->base); break; default: - printk(KERN_WARNING "0x%lx: Unknown implementation ID\n", - pb->base); - /* Assume 1 */ + pr_warn("0x%lx: Unknown implementation ID\n", pb->base); + fallthrough; /* Assume 1 */ case 1: pword = 1; } @@ -1675,24 +1677,24 @@ static int parport_ECP_supported(struct parport *pb) if (verbose_probing) { printk(KERN_DEBUG "0x%lx: PWord is %d bits\n", - pb->base, 8 * pword); + pb->base, 8 * pword); - printk(KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base, - config & 0x80 ? "Level" : "Pulses"); + printk(KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", + pb->base, config & 0x80 ? "Level" : "Pulses"); configb = inb(CONFIGB(pb)); printk(KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n", - pb->base, config, configb); + pb->base, config, configb); printk(KERN_DEBUG "0x%lx: ECP settings irq=", pb->base); if ((configb >> 3) & 0x07) - printk("%d", intrline[(configb >> 3) & 0x07]); + pr_cont("%d", intrline[(configb >> 3) & 0x07]); else - printk("<none or set by other means>"); - printk(" dma="); + pr_cont("<none or set by other means>"); + pr_cont(" dma="); if ((configb & 0x03) == 0x00) - printk("<none or set by other means>\n"); + pr_cont("<none or set by other means>\n"); else - printk("%d\n", configb & 0x07); + pr_cont("%d\n", configb & 0x07); } /* Go back to mode 000 */ @@ -1702,6 +1704,46 @@ static int parport_ECP_supported(struct parport *pb) } #endif +#ifdef CONFIG_X86_32 +static int intel_bug_present_check_epp(struct parport *pb) +{ + const struct parport_pc_private *priv = pb->private_data; + int bug_present = 0; + + if (priv->ecr) { + /* store value of ECR */ + unsigned char ecr = inb(ECONTROL(pb)); + unsigned char i; + for (i = 0x00; i < 0x80; i += 0x20) { + ECR_WRITE(pb, i); + if (clear_epp_timeout(pb)) { + /* Phony EPP in ECP. */ + bug_present = 1; + break; + } + } + /* return ECR into the inital state */ + ECR_WRITE(pb, ecr); + } + + return bug_present; +} +static int intel_bug_present(struct parport *pb) +{ +/* Check whether the device is legacy, not PCI or PCMCIA. Only legacy is known to be affected. */ + if (pb->dev != NULL) { + return 0; + } + + return intel_bug_present_check_epp(pb); +} +#else +static int intel_bug_present(struct parport *pb) +{ + return 0; +} +#endif /* CONFIG_X86_32 */ + static int parport_ECPPS2_supported(struct parport *pb) { const struct parport_pc_private *priv = pb->private_data; @@ -1722,8 +1764,6 @@ static int parport_ECPPS2_supported(struct parport *pb) static int parport_EPP_supported(struct parport *pb) { - const struct parport_pc_private *priv = pb->private_data; - /* * Theory: * Bit 0 of STR is the EPP timeout bit, this bit is 0 @@ -1742,16 +1782,8 @@ static int parport_EPP_supported(struct parport *pb) return 0; /* No way to clear timeout */ /* Check for Intel bug. */ - if (priv->ecr) { - unsigned char i; - for (i = 0x00; i < 0x80; i += 0x20) { - ECR_WRITE(pb, i); - if (clear_epp_timeout(pb)) { - /* Phony EPP in ECP. */ - return 0; - } - } - } + if (intel_bug_present(pb)) + return 0; pb->modes |= PARPORT_MODE_EPP; @@ -1990,11 +2022,13 @@ static int parport_dma_probe(struct parport *p) static LIST_HEAD(ports_list); static DEFINE_SPINLOCK(ports_lock); -struct parport *parport_pc_probe_port(unsigned long int base, - unsigned long int base_hi, - int irq, int dma, - struct device *dev, - int irqflags) +static struct parport *__parport_pc_probe_port(unsigned long int base, + unsigned long int base_hi, + int irq, int dma, + struct device *dev, + int irqflags, + unsigned int mode_mask, + unsigned char ecr_writable) { struct parport_pc_private *priv; struct parport_operations *ops; @@ -2004,6 +2038,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, struct resource *ECR_res = NULL; struct resource *EPP_res = NULL; struct platform_device *pdev = NULL; + int ret; if (!dev) { /* We need a physical device to attach to, but none was @@ -2014,8 +2049,11 @@ struct parport *parport_pc_probe_port(unsigned long int base, return NULL; dev = &pdev->dev; - dev->coherent_dma_mask = DMA_BIT_MASK(24); - dev->dma_mask = &dev->coherent_dma_mask; + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(24)); + if (ret) { + dev_err(dev, "Unable to set coherent dma mask: disabling DMA\n"); + dma = PARPORT_DMA_NONE; + } } ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); @@ -2039,6 +2077,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, priv->ctr = 0xc; priv->ctr_writable = ~0x10; priv->ecr = 0; + priv->ecr_writable = ecr_writable; priv->fifo_depth = 0; priv->dma_buf = NULL; priv->dma_handle = 0; @@ -2072,9 +2111,9 @@ struct parport *parport_pc_probe_port(unsigned long int base, p->size = (p->modes & PARPORT_MODE_EPP) ? 8 : 3; - printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); + pr_info("%s: PC-style at 0x%lx", p->name, p->base); if (p->base_hi && priv->ecr) - printk(KERN_CONT " (0x%lx)", p->base_hi); + pr_cont(" (0x%lx)", p->base_hi); if (p->irq == PARPORT_IRQ_AUTO) { p->irq = PARPORT_IRQ_NONE; parport_irq_probe(p); @@ -2085,7 +2124,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, p->irq = PARPORT_IRQ_NONE; } if (p->irq != PARPORT_IRQ_NONE) { - printk(KERN_CONT ", irq %d", p->irq); + pr_cont(", irq %d", p->irq); priv->ctr_writable |= 0x10; if (p->dma == PARPORT_DMA_AUTO) { @@ -2102,48 +2141,54 @@ struct parport *parport_pc_probe_port(unsigned long int base, p->dma != PARPORT_DMA_NOFIFO && priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) { p->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT; - p->ops->compat_write_data = parport_pc_compat_write_block_pio; -#ifdef CONFIG_PARPORT_1284 - p->ops->ecp_write_data = parport_pc_ecp_write_block_pio; - /* currently broken, but working on it.. (FB) */ - /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ -#endif /* IEEE 1284 support */ - if (p->dma != PARPORT_DMA_NONE) { - printk(KERN_CONT ", dma %d", p->dma); + if (p->dma != PARPORT_DMA_NONE) p->modes |= PARPORT_MODE_DMA; - } else - printk(KERN_CONT ", using FIFO"); } else /* We can't use the DMA channel after all. */ p->dma = PARPORT_DMA_NONE; #endif /* Allowed to use FIFO/DMA */ - printk(KERN_CONT " ["); + p->modes &= ~mode_mask; -#define printmode(x) \ - {\ - if (p->modes & PARPORT_MODE_##x) {\ - printk(KERN_CONT "%s%s", f ? "," : "", #x);\ - f++;\ - } \ +#ifdef CONFIG_PARPORT_PC_FIFO + if ((p->modes & PARPORT_MODE_COMPAT) != 0) + p->ops->compat_write_data = parport_pc_compat_write_block_pio; +#ifdef CONFIG_PARPORT_1284 + if ((p->modes & PARPORT_MODE_ECP) != 0) + p->ops->ecp_write_data = parport_pc_ecp_write_block_pio; +#endif + if ((p->modes & (PARPORT_MODE_ECP | PARPORT_MODE_COMPAT)) != 0) { + if ((p->modes & PARPORT_MODE_DMA) != 0) + pr_cont(", dma %d", p->dma); + else + pr_cont(", using FIFO"); } +#endif /* Allowed to use FIFO/DMA */ + + pr_cont(" ["); + +#define printmode(x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) { int f = 0; printmode(PCSPP); printmode(TRISTATE); - printmode(COMPAT) + printmode(COMPAT); printmode(EPP); printmode(ECP); printmode(DMA); } #undef printmode #ifndef CONFIG_PARPORT_1284 - printk(KERN_CONT "(,...)"); + pr_cont("(,...)"); #endif /* CONFIG_PARPORT_1284 */ - printk(KERN_CONT "]\n"); + pr_cont("]\n"); if (probedirq != PARPORT_IRQ_NONE) - printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq); + pr_info("%s: irq %d detected\n", p->name, probedirq); /* If No ECP release the ports grabbed above. */ if (ECR_res && (p->modes & PARPORT_MODE_ECP) == 0) { @@ -2158,8 +2203,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, if (p->irq != PARPORT_IRQ_NONE) { if (request_irq(p->irq, parport_irq_handler, irqflags, p->name, p)) { - printk(KERN_WARNING "%s: irq %d in use, " - "resorting to polled operation\n", + pr_warn("%s: irq %d in use, resorting to polled operation\n", p->name, p->irq); p->irq = PARPORT_IRQ_NONE; p->dma = PARPORT_DMA_NONE; @@ -2169,8 +2213,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, #ifdef HAS_DMA if (p->dma != PARPORT_DMA_NONE) { if (request_dma(p->dma, p->name)) { - printk(KERN_WARNING "%s: dma %d in use, " - "resorting to PIO operation\n", + pr_warn("%s: dma %d in use, resorting to PIO operation\n", p->name, p->dma); p->dma = PARPORT_DMA_NONE; } else { @@ -2180,9 +2223,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, &priv->dma_handle, GFP_KERNEL); if (!priv->dma_buf) { - printk(KERN_WARNING "%s: " - "cannot get buffer for DMA, " - "resorting to PIO operation\n", + pr_warn("%s: cannot get buffer for DMA, resorting to PIO operation\n", p->name); free_dma(p->dma); p->dma = PARPORT_DMA_NONE; @@ -2221,7 +2262,7 @@ out5: release_region(base+0x3, 5); release_region(base, 3); out4: - parport_put_port(p); + parport_del_port(p); out3: kfree(priv); out2: @@ -2231,6 +2272,16 @@ out1: platform_device_unregister(pdev); return NULL; } + +struct parport *parport_pc_probe_port(unsigned long int base, + unsigned long int base_hi, + int irq, int dma, + struct device *dev, + int irqflags) +{ + return __parport_pc_probe_port(base, base_hi, irq, dma, + dev, irqflags, 0, 0); +} EXPORT_SYMBOL(parport_pc_probe_port); void parport_pc_unregister_port(struct parport *p) @@ -2260,7 +2311,7 @@ void parport_pc_unregister_port(struct parport *p) priv->dma_handle); #endif kfree(p->private_data); - parport_put_port(p); + parport_del_port(p); kfree(ops); /* hope no-one cached it */ } EXPORT_SYMBOL(parport_pc_unregister_port); @@ -2278,7 +2329,7 @@ static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma, int irq; int i; - DPRINTK(KERN_DEBUG "sio_ite_8872_probe()\n"); + pr_debug("sio_ite_8872_probe()\n"); /* make sure which one chip */ for (i = 0; i < 5; i++) { @@ -2295,7 +2346,7 @@ static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma, } } if (i >= 5) { - printk(KERN_INFO "parport_pc: cannot find ITE8872 INTA\n"); + pr_info("parport_pc: cannot find ITE8872 INTA\n"); return 0; } @@ -2304,29 +2355,28 @@ static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma, switch (type) { case 0x2: - printk(KERN_INFO "parport_pc: ITE8871 found (1P)\n"); + pr_info("parport_pc: ITE8871 found (1P)\n"); ite8872set = 0x64200000; break; case 0xa: - printk(KERN_INFO "parport_pc: ITE8875 found (1P)\n"); + pr_info("parport_pc: ITE8875 found (1P)\n"); ite8872set = 0x64200000; break; case 0xe: - printk(KERN_INFO "parport_pc: ITE8872 found (2S1P)\n"); + pr_info("parport_pc: ITE8872 found (2S1P)\n"); ite8872set = 0x64e00000; break; case 0x6: - printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n"); + pr_info("parport_pc: ITE8873 found (1S)\n"); release_region(inta_addr[i], 32); return 0; case 0x8: - printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n"); + pr_info("parport_pc: ITE8874 found (2S)\n"); release_region(inta_addr[i], 32); return 0; default: - printk(KERN_INFO "parport_pc: unknown ITE887x\n"); - printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' " - "output to Rich.Liu@ite.com.tw\n"); + pr_info("parport_pc: unknown ITE887x\n"); + pr_info("parport_pc: please mail 'lspci -nvv' output to Rich.Liu@ite.com.tw\n"); release_region(inta_addr[i], 32); return 0; } @@ -2344,11 +2394,9 @@ static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma, pci_write_config_dword(pdev, 0x9c, ite8872set | (ite8872_irq * 0x11111)); - DPRINTK(KERN_DEBUG "ITE887x: The IRQ is %d.\n", ite8872_irq); - DPRINTK(KERN_DEBUG "ITE887x: The PARALLEL I/O port is 0x%x.\n", - ite8872_lpt); - DPRINTK(KERN_DEBUG "ITE887x: The PARALLEL I/O porthi is 0x%x.\n", - ite8872_lpthi); + pr_debug("ITE887x: The IRQ is %d\n", ite8872_irq); + pr_debug("ITE887x: The PARALLEL I/O port is 0x%x\n", ite8872_lpt); + pr_debug("ITE887x: The PARALLEL I/O porthi is 0x%x\n", ite8872_lpthi); /* Let the user (or defaults) steer us away from interrupts */ irq = ite8872_irq; @@ -2361,12 +2409,11 @@ static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma, release_region(inta_addr[i], 32); if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi, irq, PARPORT_DMA_NONE, &pdev->dev, 0)) { - printk(KERN_INFO - "parport_pc: ITE 8872 parallel port: io=0x%X", - ite8872_lpt); + pr_info("parport_pc: ITE 8872 parallel port: io=0x%X", + ite8872_lpt); if (irq != PARPORT_IRQ_NONE) - printk(", irq=%d", irq); - printk("\n"); + pr_cont(", irq=%d", irq); + pr_cont("\n"); return 1; } @@ -2436,8 +2483,7 @@ static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma, have_epp = 1; break; default: - printk(KERN_DEBUG - "parport_pc: probing current configuration\n"); + printk(KERN_DEBUG "parport_pc: probing current configuration\n"); siofunc = VIA_FUNCTION_PROBE; break; } @@ -2473,12 +2519,11 @@ static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma, port1 = inb(VIA_CONFIG_DATA) << 2; printk(KERN_DEBUG "parport_pc: Current parallel port base: 0x%X\n", - port1); + port1); if (port1 == 0x3BC && have_epp) { outb(via->viacfg_parport_base, VIA_CONFIG_INDEX); outb((0x378 >> 2), VIA_CONFIG_DATA); - printk(KERN_DEBUG - "parport_pc: Parallel port base changed to 0x378\n"); + printk(KERN_DEBUG "parport_pc: Parallel port base changed to 0x378\n"); port1 = 0x378; } @@ -2490,7 +2535,7 @@ static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma, pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp); if (siofunc == VIA_FUNCTION_PARPORT_DISABLE) { - printk(KERN_INFO "parport_pc: VIA parallel port disabled in BIOS\n"); + pr_info("parport_pc: VIA parallel port disabled in BIOS\n"); return 0; } @@ -2523,9 +2568,8 @@ static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma, case 0x278: port2 = 0x678; break; default: - printk(KERN_INFO - "parport_pc: Weird VIA parport base 0x%X, ignoring\n", - port1); + pr_info("parport_pc: Weird VIA parport base 0x%X, ignoring\n", + port1); return 0; } @@ -2544,17 +2588,16 @@ static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma, /* finally, do the probe with values obtained */ if (parport_pc_probe_port(port1, port2, irq, dma, &pdev->dev, 0)) { - printk(KERN_INFO - "parport_pc: VIA parallel port: io=0x%X", port1); + pr_info("parport_pc: VIA parallel port: io=0x%X", port1); if (irq != PARPORT_IRQ_NONE) - printk(", irq=%d", irq); + pr_cont(", irq=%d", irq); if (dma != PARPORT_DMA_NONE) - printk(", dma=%d", dma); - printk("\n"); + pr_cont(", dma=%d", dma); + pr_cont("\n"); return 1; } - printk(KERN_WARNING "parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n", + pr_warn("parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n", port1, irq, dma); return 0; } @@ -2596,8 +2639,6 @@ enum parport_pc_pci_cards { syba_2p_epp, syba_1p_ecp, titan_010l, - titan_1284p1, - titan_1284p2, avlab_1p, avlab_2p, oxsemi_952, @@ -2606,6 +2647,7 @@ enum parport_pc_pci_cards { oxsemi_pcie_pport, aks_0100, mobility_pp, + netmos_9900, netmos_9705, netmos_9715, netmos_9755, @@ -2613,7 +2655,11 @@ enum parport_pc_pci_cards { netmos_9815, netmos_9901, netmos_9865, + asix_ax99100, quatech_sppxp100, + wch_ch382l, + brainboxes_uc146, + brainboxes_px203, }; @@ -2626,7 +2672,14 @@ static struct parport_pc_pci { int lo; int hi; /* -1 if not there, >6 for offset-method (max BAR is 6) */ - } addr[4]; + } addr[2]; + + /* Bit field of parport modes to exclude. */ + unsigned int mode_mask; + + /* If non-zero, sets the bitmask of writable ECR bits. In that + * case additionally bit 0 will be forcibly set on writes. */ + unsigned char ecr_writable; /* If set, this is called immediately after pci_enable_device. * If it returns non-zero, no probing will take place and the @@ -2656,28 +2709,38 @@ static struct parport_pc_pci { /* syba_2p_epp AP138B */ { 2, { { 0, 0x078 }, { 0, 0x178 }, } }, /* syba_1p_ecp W83787 */ { 1, { { 0, 0x078 }, } }, /* titan_010l */ { 1, { { 3, -1 }, } }, - /* titan_1284p1 */ { 1, { { 0, 1 }, } }, - /* titan_1284p2 */ { 2, { { 0, 1 }, { 2, 3 }, } }, /* avlab_1p */ { 1, { { 0, 1}, } }, /* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} }, - /* The Oxford Semi cards are unusual: 954 doesn't support ECP, - * and 840 locks up if you write 1 to bit 2! */ - /* oxsemi_952 */ { 1, { { 0, 1 }, } }, - /* oxsemi_954 */ { 1, { { 0, -1 }, } }, - /* oxsemi_840 */ { 1, { { 0, 1 }, } }, - /* oxsemi_pcie_pport */ { 1, { { 0, 1 }, } }, + /* The Oxford Semi cards are unusual: older variants of 954 don't + * support ECP, and 840 locks up if you write 1 to bit 2! None + * implement nFault or service interrupts and all require 00001 + * bit pattern to be used for bits 4:0 with ECR writes. */ + /* oxsemi_952 */ { 1, { { 0, 1 }, }, + PARPORT_MODE_COMPAT, ECR_MODE_MASK }, + /* oxsemi_954 */ { 1, { { 0, 1 }, }, + PARPORT_MODE_ECP | + PARPORT_MODE_COMPAT, ECR_MODE_MASK }, + /* oxsemi_840 */ { 1, { { 0, 1 }, }, + PARPORT_MODE_COMPAT, ECR_MODE_MASK }, + /* oxsemi_pcie_pport */ { 1, { { 0, 1 }, }, + PARPORT_MODE_COMPAT, ECR_MODE_MASK }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, + /* netmos_9900 */ { 1, { { 0, -1 }, } }, /* The netmos entries below are untested */ /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* netmos_9715 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, - /* netmos_9805 */ { 1, { { 0, -1 }, } }, - /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, + /* netmos_9805 */ { 1, { { 0, 1 }, } }, + /* netmos_9815 */ { 2, { { 0, 1 }, { 2, 3 }, } }, /* netmos_9901 */ { 1, { { 0, -1 }, } }, /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* asix_ax99100 */ { 1, { { 0, 1 }, } }, /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, + /* wch_ch382l */ { 1, { { 2, -1 }, } }, + /* brainboxes_uc146 */ { 1, { { 3, -1 }, } }, + /* brainboxes_px203 */ { 1, { { 0, -1 }, } }, }; static const struct pci_device_id parport_pc_pci_tbl[] = { @@ -2718,8 +2781,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_1p_ecp }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l }, - { 0x9710, 0x9805, 0x1000, 0x0010, 0, 0, titan_1284p1 }, - { 0x9710, 0x9815, 0x1000, 0x0020, 0, 0, titan_1284p2 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ /* AFAVLAB_TK9902 */ { 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, @@ -2750,6 +2811,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 }, { 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp }, /* NetMos communication controllers */ + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, + 0xA000, 0x2000, 0, 0, netmos_9900 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9715, @@ -2766,9 +2829,31 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { 0xA000, 0x1000, 0, 0, netmos_9865 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x2000, 0, 0, netmos_9865 }, + /* ASIX AX99100 PCIe to Multi I/O Controller */ + { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, + 0xA000, 0x2000, 0, 0, asix_ax99100 }, /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, + /* WCH CH382L PCI-E single parallel port card */ + { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, + /* Brainboxes IX-500/550 */ + { PCI_VENDOR_ID_INTASHIELD, 0x402a, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, + /* Brainboxes UC-146/UC-157 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0be1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0be2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, + /* Brainboxes PX-146/PX-257 */ + { PCI_VENDOR_ID_INTASHIELD, 0x401c, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, + /* Brainboxes PX-203 */ + { PCI_VENDOR_ID_INTASHIELD, 0x4007, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px203 }, + /* Brainboxes PX-475 */ + { PCI_VENDOR_ID_INTASHIELD, 0x401f, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); @@ -2821,23 +2906,19 @@ static int parport_pc_pci_probe(struct pci_dev *dev, /* TODO: test if sharing interrupts works */ irq = dev->irq; if (irq == IRQ_NONE) { - printk(KERN_DEBUG - "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n", - parport_pc_pci_tbl[i + last_sio].vendor, - parport_pc_pci_tbl[i + last_sio].device, - io_lo, io_hi); + printk(KERN_DEBUG "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n", + id->vendor, id->device, io_lo, io_hi); irq = PARPORT_IRQ_NONE; } else { - printk(KERN_DEBUG - "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n", - parport_pc_pci_tbl[i + last_sio].vendor, - parport_pc_pci_tbl[i + last_sio].device, - io_lo, io_hi, irq); + printk(KERN_DEBUG "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n", + id->vendor, id->device, io_lo, io_hi, irq); } data->ports[count] = - parport_pc_probe_port(io_lo, io_hi, irq, - PARPORT_DMA_NONE, &dev->dev, - IRQF_SHARED); + __parport_pc_probe_port(io_lo, io_hi, irq, + PARPORT_DMA_NONE, &dev->dev, + IRQF_SHARED, + cards[i].mode_mask, + cards[i].ecr_writable); if (data->ports[count]) count++; } @@ -2862,8 +2943,6 @@ static void parport_pc_pci_remove(struct pci_dev *dev) struct pci_parport_data *data = pci_get_drvdata(dev); int i; - pci_set_drvdata(dev, NULL); - if (data) { for (i = data->num - 1; i >= 0; i--) parport_pc_unregister_port(data->ports[i]); @@ -2989,7 +3068,6 @@ static int parport_pc_platform_probe(struct platform_device *pdev) static struct platform_driver parport_pc_platform_driver = { .driver = { - .owner = THIS_MODULE, .name = "parport_pc", }, .probe = parport_pc_platform_probe, @@ -3085,7 +3163,7 @@ static int __init parport_parse_param(const char *s, int *val, if (ep != s) *val = r; else { - printk(KERN_ERR "parport: bad specifier `%s'\n", s); + pr_err("parport: bad specifier `%s'\n", s); return -1; } } @@ -3107,8 +3185,8 @@ static int __init parport_parse_dma(const char *dmastr, int *val) #ifdef CONFIG_PCI static int __init parport_init_mode_setup(char *str) { - printk(KERN_DEBUG - "parport_pc.c: Specified parameter parport_init_mode=%s\n", str); + printk(KERN_DEBUG "parport_pc.c: Specified parameter parport_init_mode=%s\n", + str); if (!strcmp(str, "spp")) parport_init_mode = 1; @@ -3129,13 +3207,13 @@ static char *irq[PARPORT_PC_MAX_PORTS]; static char *dma[PARPORT_PC_MAX_PORTS]; MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); -module_param_array(io, int, NULL, 0); +module_param_hw_array(io, int, ioport, NULL, 0); MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)"); -module_param_array(io_hi, int, NULL, 0); +module_param_hw_array(io_hi, int, ioport, NULL, 0); MODULE_PARM_DESC(irq, "IRQ line"); -module_param_array(irq, charp, NULL, 0); +module_param_hw_array(irq, charp, irq, NULL, 0); MODULE_PARM_DESC(dma, "DMA channel"); -module_param_array(dma, charp, NULL, 0); +module_param_hw_array(dma, charp, dma, NULL, 0); #if defined(CONFIG_PARPORT_PC_SUPERIO) || \ (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO)) MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation"); @@ -3175,10 +3253,7 @@ static int __init parse_parport_params(void) irqval[0] = val; break; default: - printk(KERN_WARNING - "parport_pc: irq specified " - "without base address. Use 'io=' " - "to specify one\n"); + pr_warn("parport_pc: irq specified without base address. Use 'io=' to specify one\n"); } if (dma[0] && !parport_parse_dma(dma[0], &val)) @@ -3188,10 +3263,7 @@ static int __init parse_parport_params(void) dmaval[0] = val; break; default: - printk(KERN_WARNING - "parport_pc: dma specified " - "without base address. Use 'io=' " - "to specify one\n"); + pr_warn("parport_pc: dma specified without base address. Use 'io=' to specify one\n"); } } return 0; @@ -3230,12 +3302,12 @@ static int __init parport_setup(char *str) val = simple_strtoul(str, &endptr, 0); if (endptr == str) { - printk(KERN_WARNING "parport=%s not understood\n", str); + pr_warn("parport=%s not understood\n", str); return 1; } if (parport_setup_ptr == PARPORT_PC_MAX_PORTS) { - printk(KERN_ERR "parport=%s ignored, too many ports\n", str); + pr_err("parport=%s ignored, too many ports\n", str); return 1; } @@ -3318,13 +3390,14 @@ static void __exit parport_pc_exit(void) while (!list_empty(&ports_list)) { struct parport_pc_private *priv; struct parport *port; + struct device *dev; priv = list_entry(ports_list.next, struct parport_pc_private, list); port = priv->port; - if (port->dev && port->dev->bus == &platform_bus_type) - platform_device_unregister( - to_platform_device(port->dev)); + dev = port->dev; parport_pc_unregister_port(port); + if (dev && dev->bus == &platform_bus_type) + platform_device_unregister(to_platform_device(dev)); } } diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 1b8bdb7e9bf4..24d4f3a3ec3d 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -1,30 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Support for common PCI multi-I/O cards (which is most of them) * * Copyright (C) 2001 Tim Waugh <twaugh@redhat.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * * Multi-function PCI cards are supposed to present separate logical * devices on the bus. A common thing to do seems to be to just use * one logical device with lots of base address registers for both * parallel ports and serial ports. This driver is for dealing with * that. - * */ -#include <linux/types.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/pci.h> #include <linux/interrupt.h> +#include <linux/module.h> #include <linux/parport.h> #include <linux/parport_pc.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/types.h> + #include <linux/8250_pci.h> enum parport_pc_pci_cards { @@ -62,8 +56,19 @@ enum parport_pc_pci_cards { timedia_9079a, timedia_9079b, timedia_9079c, + wch_ch353_1s1p, wch_ch353_2s1p, - sunix_2s1p, + wch_ch382_0s1p, + wch_ch382_2s1p, + brainboxes_5s1p, + sunix_4008a, + sunix_5069a, + sunix_5079a, + sunix_5099a, + brainboxes_uc257, + brainboxes_is300, + brainboxes_uc414, + brainboxes_px263, }; /* each element directly indexed from enum list, above */ @@ -148,13 +153,21 @@ static struct parport_pc_pci cards[] = { /* timedia_9079a */ { 1, { { 2, 3 }, } }, /* timedia_9079b */ { 1, { { 2, 3 }, } }, /* timedia_9079c */ { 1, { { 2, 3 }, } }, + /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } }, /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, - /* sunix_2s1p */ { 1, { { 3, -1 }, } }, + /* wch_ch382_0s1p*/ { 1, { { 2, -1}, } }, + /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } }, + /* brainboxes_5s1p */ { 1, { { 3, -1 }, } }, + /* sunix_4008a */ { 1, { { 1, 2 }, } }, + /* sunix_5069a */ { 1, { { 1, 2 }, } }, + /* sunix_5079a */ { 1, { { 1, 2 }, } }, + /* sunix_5099a */ { 1, { { 1, 2 }, } }, + /* brainboxes_uc257 */ { 1, { { 3, -1 }, } }, + /* brainboxes_is300 */ { 1, { { 3, -1 }, } }, + /* brainboxes_uc414 */ { 1, { { 3, -1 }, } }, + /* brainboxes_px263 */ { 1, { { 3, -1 }, } }, }; -#define PCI_VENDOR_ID_SUNIX 0x1fd4 -#define PCI_DEVICE_ID_SUNIX_1999 0x1999 - static struct pci_device_id parport_serial_pci_tbl[] = { /* PCI cards */ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, @@ -253,15 +266,60 @@ static struct pci_device_id parport_serial_pci_tbl[] = { { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, /* WCH CARDS */ - { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, - - /* - * More SUNIX variations. At least one of these has part number - * '5079A but subdevice 0x102. That board reports 0x0708 as - * its PCI Class. - */ + { PCI_VENDOR_ID_WCHCN, PCI_DEVICE_ID_WCHCN_CH353_1S1P, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p }, + { PCI_VENDOR_ID_WCHCN, PCI_DEVICE_ID_WCHCN_CH353_2S1P, + 0x4348, 0x3253, 0, 0, wch_ch353_2s1p }, + { PCI_VENDOR_ID_WCHIC, PCI_DEVICE_ID_WCHIC_CH382_0S1P, + 0x1c00, 0x3050, 0, 0, wch_ch382_0s1p }, + { PCI_VENDOR_ID_WCHIC, PCI_DEVICE_ID_WCHIC_CH382_2S1P, + 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p }, + + /* BrainBoxes PX272/PX306 MIO card */ + { PCI_VENDOR_ID_INTASHIELD, 0x4100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p }, + + /* Sunix boards */ + { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, + 0x0100, 0, 0, sunix_4008a }, + { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, + 0x0101, 0, 0, sunix_5069a }, + { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, + 0x0102, 0, 0, sunix_5079a }, { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, - 0x0102, 0, 0, sunix_2s1p }, + 0x0104, 0, 0, sunix_5099a }, + + /* Brainboxes UC-203 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0bc1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0bc2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes UC-257 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0861, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0862, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0863, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes UC-414 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0e61, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc414 }, + + /* Brainboxes UC-475 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0981, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0982, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes IS-300/IS-500 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0da0, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_is300 }, + + /* Brainboxes PX-263/PX-295 */ + { PCI_VENDOR_ID_INTASHIELD, 0x402c, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px263 }, { 0, } /* terminate list */ }; @@ -479,15 +537,76 @@ static struct pciserial_board pci_parport_serial_boards[] = { .base_baud = 921600, .uart_offset = 8, }, + [wch_ch353_1s1p] = { + .flags = FL_BASE0|FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, [wch_ch353_2s1p] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, .base_baud = 115200, .uart_offset = 8, }, - [sunix_2s1p] = { - .flags = FL_BASE0|FL_BASE_BARS, + [wch_ch382_0s1p] = { + .flags = FL_BASE0, + .num_ports = 0, + .base_baud = 115200, + .uart_offset = 8, + }, + [wch_ch382_2s1p] = { + .flags = FL_BASE0, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + .first_offset = 0xC0, + }, + [brainboxes_5s1p] = { + .flags = FL_BASE2, + .num_ports = 5, + .base_baud = 921600, + .uart_offset = 8, + }, + [sunix_4008a] = { + .num_ports = 0, + }, + [sunix_5069a] = { + .num_ports = 1, + .base_baud = 921600, + .uart_offset = 0x8, + }, + [sunix_5079a] = { .num_ports = 2, + .base_baud = 921600, + .uart_offset = 0x8, + }, + [sunix_5099a] = { + .num_ports = 4, + .base_baud = 921600, + .uart_offset = 0x8, + }, + [brainboxes_uc257] = { + .flags = FL_BASE2, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_is300] = { + .flags = FL_BASE2, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_uc414] = { + .flags = FL_BASE2, + .num_ports = 4, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_px263] = { + .flags = FL_BASE2, + .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, @@ -508,12 +627,10 @@ static int serial_register(struct pci_dev *dev, const struct pci_device_id *id) struct serial_private *serial; board = &pci_parport_serial_boards[id->driver_data]; - if (board->num_ports == 0) return 0; serial = pciserial_init_ports(dev, board); - if (IS_ERR(serial)) return PTR_ERR(serial); @@ -542,10 +659,9 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) int irq; if (priv->num_par == ARRAY_SIZE (priv->port)) { - printk (KERN_WARNING - "parport_serial: %s: only %zu parallel ports " - "supported (%d reported)\n", pci_name (dev), - ARRAY_SIZE(priv->port), card->numports); + dev_warn(&dev->dev, + "only %zu parallel ports supported (%d reported)\n", + ARRAY_SIZE(priv->port), card->numports); break; } @@ -558,15 +674,18 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) "hi" as an offset (see SYBA def.) */ /* TODO: test if sharing interrupts works */ - irq = dev->irq; - if (irq == IRQ_NONE) { + irq = pci_irq_vector(dev, 0); + if (irq < 0) + return irq; + if (irq == 0) + irq = PARPORT_IRQ_NONE; + if (irq == PARPORT_IRQ_NONE) { dev_dbg(&dev->dev, - "PCI parallel port detected: I/O at %#lx(%#lx)\n", + "PCI parallel port detected: I/O at %#lx(%#lx)\n", io_lo, io_hi); - irq = PARPORT_IRQ_NONE; } else { dev_dbg(&dev->dev, - "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n", + "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n", io_lo, io_hi, irq); } port = parport_pc_probe_port (io_lo, io_hi, irq, @@ -589,31 +708,26 @@ static int parport_serial_pci_probe(struct pci_dev *dev, struct parport_serial_private *priv; int err; - priv = kzalloc (sizeof *priv, GFP_KERNEL); + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + pci_set_drvdata (dev, priv); - err = pci_enable_device (dev); - if (err) { - pci_set_drvdata (dev, NULL); - kfree (priv); + err = pcim_enable_device(dev); + if (err) return err; - } - if (parport_register (dev, id)) { - pci_set_drvdata (dev, NULL); - kfree (priv); - return -ENODEV; - } + err = parport_register(dev, id); + if (err) + return err; - if (serial_register (dev, id)) { + err = serial_register(dev, id); + if (err) { int i; for (i = 0; i < priv->num_par; i++) parport_pc_unregister_port (priv->port[i]); - pci_set_drvdata (dev, NULL); - kfree (priv); - return -ENODEV; + return err; } return 0; @@ -624,8 +738,6 @@ static void parport_serial_pci_remove(struct pci_dev *dev) struct parport_serial_private *priv = pci_get_drvdata (dev); int i; - pci_set_drvdata(dev, NULL); - // Serial ports if (priv->serial) pciserial_remove_ports(priv->serial); @@ -634,78 +746,45 @@ static void parport_serial_pci_remove(struct pci_dev *dev) for (i = 0; i < priv->num_par; i++) parport_pc_unregister_port (priv->port[i]); - kfree (priv); return; } -#ifdef CONFIG_PM -static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) +static int __maybe_unused parport_serial_pci_suspend(struct device *dev) { - struct parport_serial_private *priv = pci_get_drvdata(dev); + struct parport_serial_private *priv = dev_get_drvdata(dev); if (priv->serial) pciserial_suspend_ports(priv->serial); /* FIXME: What about parport? */ - - pci_save_state(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); return 0; } -static int parport_serial_pci_resume(struct pci_dev *dev) +static int __maybe_unused parport_serial_pci_resume(struct device *dev) { - struct parport_serial_private *priv = pci_get_drvdata(dev); - int err; - - pci_set_power_state(dev, PCI_D0); - pci_restore_state(dev); - - /* - * The device may have been disabled. Re-enable it. - */ - err = pci_enable_device(dev); - if (err) { - printk(KERN_ERR "parport_serial: %s: error enabling " - "device for resume (%d)\n", pci_name(dev), err); - return err; - } + struct parport_serial_private *priv = dev_get_drvdata(dev); if (priv->serial) pciserial_resume_ports(priv->serial); /* FIXME: What about parport? */ - return 0; } -#endif + +static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops, + parport_serial_pci_suspend, parport_serial_pci_resume); static struct pci_driver parport_serial_pci_driver = { .name = "parport_serial", .id_table = parport_serial_pci_tbl, .probe = parport_serial_pci_probe, .remove = parport_serial_pci_remove, -#ifdef CONFIG_PM - .suspend = parport_serial_pci_suspend, - .resume = parport_serial_pci_resume, -#endif + .driver = { + .pm = &parport_serial_pm_ops, + }, }; - - -static int __init parport_serial_init (void) -{ - return pci_register_driver (&parport_serial_pci_driver); -} - -static void __exit parport_serial_exit (void) -{ - pci_unregister_driver (&parport_serial_pci_driver); - return; -} +module_pci_driver(parport_serial_pci_driver); MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>"); MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards"); MODULE_LICENSE("GPL"); - -module_init(parport_serial_init); -module_exit(parport_serial_exit); diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index dffd6d0bd15b..d6495f2f90a7 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* parport_sunbpp.c: Parallel-port routines for SBUS * * Author: Derrick J. Brashear <shadow@dementia.org> @@ -27,7 +28,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/parport.h> @@ -286,12 +287,16 @@ static int bpp_probe(struct platform_device *op) ops = kmemdup(&parport_sunbpp_ops, sizeof(struct parport_operations), GFP_KERNEL); - if (!ops) + if (!ops) { + err = -ENOMEM; goto out_unmap; + } dprintk(("register_port\n")); - if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) + if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) { + err = -ENOMEM; goto out_free_ops; + } p->size = size; p->dev = &op->dev; @@ -309,7 +314,7 @@ static int bpp_probe(struct platform_device *op) value_tcr &= ~P_TCR_DIR; sbus_writeb(value_tcr, ®s->p_tcr); - printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); + pr_info("%s: sunbpp at 0x%lx\n", p->name, p->base); dev_set_drvdata(&op->dev, p); @@ -329,7 +334,7 @@ out_unmap: return err; } -static int bpp_remove(struct platform_device *op) +static void bpp_remove(struct platform_device *op) { struct parport *p = dev_get_drvdata(&op->dev); struct parport_operations *ops = p->ops; @@ -346,8 +351,6 @@ static int bpp_remove(struct platform_device *op) kfree(ops); dev_set_drvdata(&op->dev, NULL); - - return 0; } static const struct of_device_id bpp_match[] = { @@ -362,7 +365,6 @@ MODULE_DEVICE_TABLE(of, bpp_match); static struct platform_driver bpp_sbus_driver = { .driver = { .name = "bpp", - .owner = THIS_MODULE, .of_match_table = bpp_match, }, .probe = bpp_probe, @@ -373,6 +375,5 @@ module_platform_driver(bpp_sbus_driver); MODULE_AUTHOR("Derrick J Brashear"); MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); -MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c index d763bc9e44c1..5d1b9aacb130 100644 --- a/drivers/parport/probe.c +++ b/drivers/parport/probe.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Parallel port device probing code * @@ -7,10 +8,10 @@ #include <linux/module.h> #include <linux/parport.h> -#include <linux/ctype.h> #include <linux/string.h> +#include <linux/string_helpers.h> #include <linux/slab.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> static const struct { const char *token; @@ -37,16 +38,16 @@ static void pretty_print(struct parport *port, int device) { struct parport_device_info *info = &port->probe_info[device + 1]; - printk(KERN_INFO "%s", port->name); + pr_info("%s", port->name); if (device >= 0) - printk (" (addr %d)", device); + pr_cont(" (addr %d)", device); - printk (": %s", classes[info->class].descr); + pr_cont(": %s", classes[info->class].descr); if (info->class) - printk(", %s %s", info->mfr, info->model); + pr_cont(", %s %s", info->mfr, info->model); - printk("\n"); + pr_cont("\n"); } static void parse_data(struct parport *port, int device, char *str) @@ -57,7 +58,7 @@ static void parse_data(struct parport *port, int device, char *str) struct parport_device_info *info = &port->probe_info[device + 1]; if (!txt) { - printk(KERN_WARNING "%s probe: memory squeeze\n", port->name); + pr_warn("%s probe: memory squeeze\n", port->name); return; } strcpy(txt, str); @@ -73,11 +74,7 @@ static void parse_data(struct parport *port, int device, char *str) u = sep + strlen (sep) - 1; while (u >= p && *u == ' ') *u-- = '\0'; - u = p; - while (*u) { - *u = toupper(*u); - u++; - } + string_upper(p, p); if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { kfree(info->mfr); info->mfr = kstrdup(sep, GFP_KERNEL); @@ -89,15 +86,15 @@ static void parse_data(struct parport *port, int device, char *str) kfree(info->class_name); info->class_name = kstrdup(sep, GFP_KERNEL); - for (u = sep; *u; u++) - *u = toupper(*u); + string_upper(sep, sep); for (i = 0; classes[i].token; i++) { if (!strcmp(classes[i].token, sep)) { info->class = i; goto rock_on; } } - printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep); + pr_warn("%s probe: warning, class '%s' not understood\n", + port->name, sep); info->class = PARPORT_CLASS_OTHER; } else if (!strcmp(p, "CMD") || !strcmp(p, "COMMAND SET")) { @@ -176,9 +173,8 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, * just return constant nibble forever. This catches * also those cases. */ if (idlens[0] == 0 || idlens[0] > 0xFFF) { - printk (KERN_DEBUG "%s: reported broken Device ID" - " length of %#zX bytes\n", - port->name, idlens[0]); + printk(KERN_DEBUG "%s: reported broken Device ID length of %#zX bytes\n", + port->name, idlens[0]); return -EIO; } numidlens = 2; @@ -200,10 +196,8 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) { if (belen != len) { - printk (KERN_DEBUG "%s: Device ID was %zd bytes" - " while device told it would be %d" - " bytes\n", - port->name, len, belen); + printk(KERN_DEBUG "%s: Device ID was %zd bytes while device told it would be %d bytes\n", + port->name, len, belen); } goto done; } @@ -213,11 +207,9 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, * the first 256 bytes or so that we must have read so * far. */ if (buffer[len-1] == ';') { - printk (KERN_DEBUG "%s: Device ID reading stopped" - " before device told data not available. " - "Current idlen %u of %u, len bytes %02X %02X\n", - port->name, current_idlen, numidlens, - length[0], length[1]); + printk(KERN_DEBUG "%s: Device ID reading stopped before device told data not available. Current idlen %u of %u, len bytes %02X %02X\n", + port->name, current_idlen, numidlens, + length[0], length[1]); goto done; } } @@ -256,7 +248,7 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, ssize_t parport_device_id (int devnum, char *buffer, size_t count) { ssize_t retval = -ENXIO; - struct pardevice *dev = parport_open (devnum, "Device ID probe"); + struct pardevice *dev = parport_open(devnum, daisy_dev_name); if (!dev) return -ENXIO; diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c index 92ed045a5f93..3880460e67f2 100644 --- a/drivers/parport/procfs.c +++ b/drivers/parport/procfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Sysctl interface for parport devices. * * Authors: David Campbell @@ -21,8 +22,9 @@ #include <linux/parport.h> #include <linux/ctype.h> #include <linux/sysctl.h> +#include <linux/device.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) @@ -31,8 +33,8 @@ #define PARPORT_MIN_SPINTIME_VALUE 1 #define PARPORT_MAX_SPINTIME_VALUE 1000 -static int do_active_device(ctl_table *table, int write, - void __user *result, size_t *lenp, loff_t *ppos) +static int do_active_device(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; char buffer[256]; @@ -49,12 +51,12 @@ static int do_active_device(ctl_table *table, int write, for (dev = port->devices; dev ; dev = dev->next) { if(dev == port->cad) { - len += sprintf(buffer, "%s\n", dev->name); + len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name); } } if(!len) { - len += sprintf(buffer, "%s\n", "none"); + len += scnprintf(buffer, sizeof(buffer), "%s\n", "none"); } if (len > *lenp) @@ -63,13 +65,13 @@ static int do_active_device(ctl_table *table, int write, *lenp = len; *ppos += len; - - return copy_to_user(result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } #ifdef CONFIG_PARPORT_1284 -static int do_autoprobe(ctl_table *table, int write, - void __user *result, size_t *lenp, loff_t *ppos) +static int do_autoprobe(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport_device_info *info = table->extra2; const char *str; @@ -85,19 +87,19 @@ static int do_autoprobe(ctl_table *table, int write, } if ((str = info->class_name) != NULL) - len += sprintf (buffer + len, "CLASS:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); if ((str = info->model) != NULL) - len += sprintf (buffer + len, "MODEL:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); if ((str = info->mfr) != NULL) - len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); if ((str = info->description) != NULL) - len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); if ((str = info->cmdset) != NULL) - len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); if (len > *lenp) len = *lenp; @@ -106,16 +108,16 @@ static int do_autoprobe(ctl_table *table, int write, *ppos += len; - return copy_to_user (result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } #endif /* IEEE1284.3 support. */ -static int do_hardware_base_addr (ctl_table *table, int write, - void __user *result, - size_t *lenp, loff_t *ppos) +static int do_hardware_base_addr(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; - char buffer[20]; + char buffer[64]; int len = 0; if (*ppos) { @@ -126,7 +128,7 @@ static int do_hardware_base_addr (ctl_table *table, int write, if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi); + len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); if (len > *lenp) len = *lenp; @@ -134,13 +136,12 @@ static int do_hardware_base_addr (ctl_table *table, int write, *lenp = len; *ppos += len; - - return copy_to_user(result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } -static int do_hardware_irq (ctl_table *table, int write, - void __user *result, - size_t *lenp, loff_t *ppos) +static int do_hardware_irq(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; char buffer[20]; @@ -154,7 +155,7 @@ static int do_hardware_irq (ctl_table *table, int write, if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%d\n", port->irq); + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq); if (len > *lenp) len = *lenp; @@ -162,13 +163,12 @@ static int do_hardware_irq (ctl_table *table, int write, *lenp = len; *ppos += len; - - return copy_to_user(result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } -static int do_hardware_dma (ctl_table *table, int write, - void __user *result, - size_t *lenp, loff_t *ppos) +static int do_hardware_dma(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; char buffer[20]; @@ -182,7 +182,7 @@ static int do_hardware_dma (ctl_table *table, int write, if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%d\n", port->dma); + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma); if (len > *lenp) len = *lenp; @@ -190,13 +190,12 @@ static int do_hardware_dma (ctl_table *table, int write, *lenp = len; *ppos += len; - - return copy_to_user(result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } -static int do_hardware_modes (ctl_table *table, int write, - void __user *result, - size_t *lenp, loff_t *ppos) +static int do_hardware_modes(const struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; char buffer[40]; @@ -211,7 +210,11 @@ static int do_hardware_modes (ctl_table *table, int write, return -EACCES; { -#define printmode(x) {if(port->modes&PARPORT_MODE_##x){len+=sprintf(buffer+len,"%s%s",f?",":"",#x);f++;}} +#define printmode(x) \ +do { \ + if (port->modes & PARPORT_MODE_##x) \ + len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ +} while (0) int f = 0; printmode(PCSPP); printmode(TRISTATE); @@ -229,17 +232,10 @@ static int do_hardware_modes (ctl_table *table, int write, *lenp = len; *ppos += len; - - return copy_to_user(result, buffer, len) ? -EFAULT : 0; + memcpy(result, buffer, len); + return 0; } -#define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD } -#define PARPORT_PARPORT_DIR(CHILD) { .procname = "parport", \ - .mode = 0555, .child = CHILD } -#define PARPORT_DEV_DIR(CHILD) { .procname = "dev", .mode = 0555, .child = CHILD } -#define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \ - .mode = 0555, .child = NULL } - static const unsigned long parport_min_timeslice_value = PARPORT_MIN_TIMESLICE_VALUE; @@ -254,17 +250,20 @@ PARPORT_MAX_SPINTIME_VALUE; struct parport_sysctl_table { - struct ctl_table_header *sysctl_header; - ctl_table vars[12]; - ctl_table device_dir[2]; - ctl_table port_dir[2]; - ctl_table parport_dir[2]; - ctl_table dev_dir[2]; + struct ctl_table_header *port_header; + struct ctl_table_header *devices_header; +#ifdef CONFIG_PARPORT_1284 + struct ctl_table vars[10]; +#else + struct ctl_table vars[5]; +#endif /* IEEE 1284 support */ + struct ctl_table device_dir[1]; }; static const struct parport_sysctl_table parport_sysctl_template = { - .sysctl_header = NULL, - { + .port_header = NULL, + .devices_header = NULL, + { { .procname = "spintime", .data = NULL, @@ -302,7 +301,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { .mode = 0444, .proc_handler = do_hardware_modes }, - PARPORT_DEVICES_ROOT_DIR, #ifdef CONFIG_PARPORT_1284 { .procname = "autoprobe", @@ -340,7 +338,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = do_autoprobe }, #endif /* IEEE 1284 support */ - {} }, { { @@ -350,31 +347,14 @@ static const struct parport_sysctl_table parport_sysctl_template = { .mode = 0444, .proc_handler = do_active_device }, - {} }, - { - PARPORT_PORT_DIR(NULL), - {} - }, - { - PARPORT_PARPORT_DIR(NULL), - {} - }, - { - PARPORT_DEV_DIR(NULL), - {} - } }; struct parport_device_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table vars[2]; - ctl_table device_dir[2]; - ctl_table devices_root_dir[2]; - ctl_table port_dir[2]; - ctl_table parport_dir[2]; - ctl_table dev_dir[2]; + struct ctl_table vars[1]; + struct ctl_table device_dir[1]; }; static const struct parport_device_sysctl_table @@ -397,35 +377,14 @@ parport_device_sysctl_template = { .data = NULL, .maxlen = 0, .mode = 0555, - .child = NULL }, - {} - }, - { - PARPORT_DEVICES_ROOT_DIR, - {} - }, - { - PARPORT_PORT_DIR(NULL), - {} - }, - { - PARPORT_PARPORT_DIR(NULL), - {} - }, - { - PARPORT_DEV_DIR(NULL), - {} } }; struct parport_default_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table vars[3]; - ctl_table default_dir[2]; - ctl_table parport_dir[2]; - ctl_table dev_dir[2]; + struct ctl_table vars[2]; }; static struct parport_default_sysctl_table @@ -450,31 +409,14 @@ parport_default_sysctl_table = { .extra1 = (void*) &parport_min_spintime_value, .extra2 = (void*) &parport_max_spintime_value }, - {} - }, - { - { - .procname = "default", - .mode = 0555, - .child = parport_default_sysctl_table.vars - }, - {} - }, - { - PARPORT_PARPORT_DIR(parport_default_sysctl_table.default_dir), - {} - }, - { - PARPORT_DEV_DIR(parport_default_sysctl_table.parport_dir), - {} } }; - int parport_proc_register(struct parport *port) { struct parport_sysctl_table *t; - int i; + char *tmp_dir_path; + int i, err = 0; t = kmemdup(&parport_sysctl_template, sizeof(*t), GFP_KERNEL); if (t == NULL) @@ -482,28 +424,54 @@ int parport_proc_register(struct parport *port) t->device_dir[0].extra1 = port; - for (i = 0; i < 5; i++) + t->vars[0].data = &port->spintime; + for (i = 0; i < 5; i++) { t->vars[i].extra1 = port; +#ifdef CONFIG_PARPORT_1284 + t->vars[5 + i].extra2 = &port->probe_info[i]; +#endif /* IEEE 1284 support */ + } - t->vars[0].data = &port->spintime; - t->vars[5].child = t->device_dir; - - for (i = 0; i < 5; i++) - t->vars[6 + i].extra2 = &port->probe_info[i]; + tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s/devices", port->name); + if (!tmp_dir_path) { + err = -ENOMEM; + goto exit_free_t; + } - t->port_dir[0].procname = port->name; + t->devices_header = register_sysctl(tmp_dir_path, t->device_dir); + if (t->devices_header == NULL) { + err = -ENOENT; + goto exit_free_tmp_dir_path; + } - t->port_dir[0].child = t->vars; - t->parport_dir[0].child = t->port_dir; - t->dev_dir[0].child = t->parport_dir; + kfree(tmp_dir_path); - t->sysctl_header = register_sysctl_table(t->dev_dir); - if (t->sysctl_header == NULL) { - kfree(t); - t = NULL; + tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s", port->name); + if (!tmp_dir_path) { + err = -ENOMEM; + goto unregister_devices_h; } + + t->port_header = register_sysctl(tmp_dir_path, t->vars); + if (t->port_header == NULL) { + err = -ENOENT; + goto unregister_devices_h; + } + port->sysctl_table = t; + + kfree(tmp_dir_path); return 0; + +unregister_devices_h: + unregister_sysctl_table(t->devices_header); + +exit_free_tmp_dir_path: + kfree(tmp_dir_path); + +exit_free_t: + kfree(t); + return err; } int parport_proc_unregister(struct parport *port) @@ -511,7 +479,8 @@ int parport_proc_unregister(struct parport *port) if (port->sysctl_table) { struct parport_sysctl_table *t = port->sysctl_table; port->sysctl_table = NULL; - unregister_sysctl_table(t->sysctl_header); + unregister_sysctl_table(t->devices_header); + unregister_sysctl_table(t->port_header); kfree(t); } return 0; @@ -521,28 +490,36 @@ int parport_device_proc_register(struct pardevice *device) { struct parport_device_sysctl_table *t; struct parport * port = device->port; + char *tmp_dir_path; + int err = 0; t = kmemdup(&parport_device_sysctl_template, sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; - t->dev_dir[0].child = t->parport_dir; - t->parport_dir[0].child = t->port_dir; - t->port_dir[0].procname = port->name; - t->port_dir[0].child = t->devices_root_dir; - t->devices_root_dir[0].child = t->device_dir; + /* Allocate a buffer for two paths: dev/parport/PORT/devices/DEVICE. */ + tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s/devices/%s", port->name, device->name); + if (!tmp_dir_path) { + err = -ENOMEM; + goto exit_free_t; + } - t->device_dir[0].procname = device->name; - t->device_dir[0].child = t->vars; t->vars[0].data = &device->timeslice; - t->sysctl_header = register_sysctl_table(t->dev_dir); + t->sysctl_header = register_sysctl(tmp_dir_path, t->vars); if (t->sysctl_header == NULL) { kfree(t); t = NULL; } device->sysctl_table = t; + + kfree(tmp_dir_path); return 0; + +exit_free_t: + kfree(t); + + return err; } int parport_device_proc_unregister(struct pardevice *device) @@ -558,8 +535,18 @@ int parport_device_proc_unregister(struct pardevice *device) static int __init parport_default_proc_register(void) { + int ret; + parport_default_sysctl_table.sysctl_header = - register_sysctl_table(parport_default_sysctl_table.dev_dir); + register_sysctl("dev/parport/default", parport_default_sysctl_table.vars); + if (!parport_default_sysctl_table.sysctl_header) + return -ENOMEM; + ret = parport_bus_init(); + if (ret) { + unregister_sysctl_table(parport_default_sysctl_table. + sysctl_header); + return ret; + } return 0; } @@ -570,6 +557,7 @@ static void __exit parport_default_proc_unregister(void) sysctl_header); parport_default_sysctl_table.sysctl_header = NULL; } + parport_bus_exit(); } #else /* no sysctl or no procfs*/ @@ -596,13 +584,14 @@ int parport_device_proc_unregister(struct pardevice *device) static int __init parport_default_proc_register (void) { - return 0; + return parport_bus_init(); } static void __exit parport_default_proc_unregister (void) { + parport_bus_exit(); } #endif -module_init(parport_default_proc_register) +subsys_initcall(parport_default_proc_register) module_exit(parport_default_proc_unregister) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 6a83ee1e9178..427abdf3c4c4 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -1,6 +1,6 @@ /* * Parallel-port resource manager code. - * + * * Authors: David Campbell <campbell@tirian.che.curtin.edu.au> * Tim Waugh <tim@cyberelk.demon.co.uk> * Jose Renau <renau@acm.org> @@ -27,8 +27,9 @@ #include <linux/ioport.h> #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/kmod.h> +#include <linux/device.h> #include <linux/spinlock.h> #include <linux/mutex.h> @@ -48,21 +49,19 @@ static DEFINE_SPINLOCK(parportlist_lock); static LIST_HEAD(all_ports); static DEFINE_SPINLOCK(full_list_lock); -static LIST_HEAD(drivers); - static DEFINE_MUTEX(registration_lock); /* What you can do to a port that's gone away.. */ -static void dead_write_lines (struct parport *p, unsigned char b){} -static unsigned char dead_read_lines (struct parport *p) { return 0; } -static unsigned char dead_frob_lines (struct parport *p, unsigned char b, +static void dead_write_lines(struct parport *p, unsigned char b){} +static unsigned char dead_read_lines(struct parport *p) { return 0; } +static unsigned char dead_frob_lines(struct parport *p, unsigned char b, unsigned char c) { return 0; } -static void dead_onearg (struct parport *p){} -static void dead_initstate (struct pardevice *d, struct parport_state *s) { } -static void dead_state (struct parport *p, struct parport_state *s) { } -static size_t dead_write (struct parport *p, const void *b, size_t l, int f) +static void dead_onearg(struct parport *p){} +static void dead_initstate(struct pardevice *d, struct parport_state *s) { } +static void dead_state(struct parport *p, struct parport_state *s) { } +static size_t dead_write(struct parport *p, const void *b, size_t l, int f) { return 0; } -static size_t dead_read (struct parport *p, void *b, size_t l, int f) +static size_t dead_read(struct parport *p, void *b, size_t l, int f) { return 0; } static struct parport_operations dead_ops = { .write_data = dead_write_lines, /* data */ @@ -92,7 +91,7 @@ static struct parport_operations dead_ops = { .ecp_write_data = dead_write, /* ecp */ .ecp_read_data = dead_read, .ecp_write_addr = dead_write, - + .compat_write_data = dead_write, /* compat */ .nibble_read_data = dead_read, /* nibble */ .byte_read_data = dead_read, /* byte */ @@ -100,43 +99,157 @@ static struct parport_operations dead_ops = { .owner = NULL, }; +static struct device_type parport_device_type = { + .name = "parport", +}; + +static int is_parport(struct device *dev) +{ + return dev->type == &parport_device_type; +} + +static int parport_probe(struct device *dev) +{ + struct parport_driver *drv; + + if (is_parport(dev)) + return -ENODEV; + + drv = to_parport_driver(dev->driver); + if (!drv->probe) { + /* if driver has not defined a custom probe */ + struct pardevice *par_dev = to_pardevice(dev); + + if (strcmp(par_dev->name, drv->name)) + return -ENODEV; + return 0; + } + /* if driver defined its own probe */ + return drv->probe(to_pardevice(dev)); +} + +static const struct bus_type parport_bus_type = { + .name = "parport", + .probe = parport_probe, +}; + +int parport_bus_init(void) +{ + return bus_register(&parport_bus_type); +} + +void parport_bus_exit(void) +{ + bus_unregister(&parport_bus_type); +} + +/* + * iterates through all the drivers registered with the bus and sends the port + * details to the match_port callback of the driver, so that the driver can + * know about the new port that just registered with the bus and decide if it + * wants to use this new port. + */ +static int driver_check(struct device_driver *dev_drv, void *_port) +{ + struct parport *port = _port; + struct parport_driver *drv = to_parport_driver(dev_drv); + + if (drv->match_port) + drv->match_port(port); + return 0; +} + /* Call attach(port) for each registered driver. */ static void attach_driver_chain(struct parport *port) { /* caller has exclusive registration_lock */ - struct parport_driver *drv; - list_for_each_entry(drv, &drivers, list) - drv->attach(port); + + /* + * call the driver_check function of the drivers registered in + * new device model + */ + + bus_for_each_drv(&parport_bus_type, NULL, port, driver_check); +} + +static int driver_detach(struct device_driver *_drv, void *_port) +{ + struct parport *port = _port; + struct parport_driver *drv = to_parport_driver(_drv); + + if (drv->detach) + drv->detach(port); + return 0; } /* Call detach(port) for each registered driver. */ static void detach_driver_chain(struct parport *port) { - struct parport_driver *drv; /* caller has exclusive registration_lock */ - list_for_each_entry(drv, &drivers, list) - drv->detach (port); + + /* + * call the detach function of the drivers registered in + * new device model + */ + + bus_for_each_drv(&parport_bus_type, NULL, port, driver_detach); } /* Ask kmod for some lowlevel drivers. */ -static void get_lowlevel_driver (void) +static void get_lowlevel_driver(void) +{ + /* + * There is no actual module called this: you should set + * up an alias for modutils. + */ + request_module("parport_lowlevel"); +} + +/* + * iterates through all the devices connected to the bus and sends the device + * details to the match_port callback of the driver, so that the driver can + * know what are all the ports that are connected to the bus and choose the + * port to which it wants to register its device. + */ +static int port_check(struct device *dev, void *dev_drv) +{ + struct parport_driver *drv = dev_drv; + + /* only send ports, do not send other devices connected to bus */ + if (is_parport(dev)) + drv->match_port(to_parport_dev(dev)); + return 0; +} + +/* + * Iterates through all the devices connected to the bus and return 1 + * if the device is a parallel port. + */ + +static int port_detect(struct device *dev, void *dev_drv) { - /* There is no actual module called this: you should set - * up an alias for modutils. */ - request_module ("parport_lowlevel"); + if (is_parport(dev)) + return 1; + return 0; } /** - * parport_register_driver - register a parallel port device driver + * __parport_register_driver - register a parallel port device driver * @drv: structure describing the driver + * @owner: owner module of drv + * @mod_name: module name string * * This can be called by a parallel port device driver in order * to receive notifications about ports being found in the * system, as well as ports no longer available. * + * If devmodel is true then the new device model is used + * for registration. + * * The @drv structure is allocated by the caller and must not be * deallocated until after calling parport_unregister_driver(). * + * If using the non device model: * The driver's attach() function may block. The port that * attach() is given will be valid for the duration of the * callback, but if the driver wants to take a copy of the @@ -148,24 +261,54 @@ static void get_lowlevel_driver (void) * callback, but if the driver wants to take a copy of the * pointer it must call parport_get_port() to do so. * - * Returns 0 on success. Currently it always succeeds. + * + * Returns 0 on success. The non device model will always succeeds. + * but the new device model can fail and will return the error code. **/ -int parport_register_driver (struct parport_driver *drv) +int __parport_register_driver(struct parport_driver *drv, struct module *owner, + const char *mod_name) { - struct parport *port; + /* using device model */ + int ret; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &parport_bus_type; + drv->driver.owner = owner; + drv->driver.mod_name = mod_name; + ret = driver_register(&drv->driver); + if (ret) + return ret; - if (list_empty(&portlist)) - get_lowlevel_driver (); + /* + * check if bus has any parallel port registered, if + * none is found then load the lowlevel driver. + */ + ret = bus_for_each_dev(&parport_bus_type, NULL, NULL, + port_detect); + if (!ret) + get_lowlevel_driver(); mutex_lock(®istration_lock); - list_for_each_entry(port, &portlist, list) - drv->attach(port); - list_add(&drv->list, &drivers); + if (drv->match_port) + bus_for_each_dev(&parport_bus_type, NULL, drv, + port_check); mutex_unlock(®istration_lock); return 0; } +EXPORT_SYMBOL(__parport_register_driver); + +static int port_detach(struct device *dev, void *_drv) +{ + struct parport_driver *drv = _drv; + + if (is_parport(dev) && drv->detach) + drv->detach(to_parport_dev(dev)); + + return 0; +} /** * parport_unregister_driver - deregister a parallel port device driver @@ -184,20 +327,20 @@ int parport_register_driver (struct parport_driver *drv) * finished by the time this function returns. **/ -void parport_unregister_driver (struct parport_driver *drv) +void parport_unregister_driver(struct parport_driver *drv) { - struct parport *port; - mutex_lock(®istration_lock); - list_del_init(&drv->list); - list_for_each_entry(port, &portlist, list) - drv->detach(port); + bus_for_each_dev(&parport_bus_type, NULL, drv, port_detach); + driver_unregister(&drv->driver); mutex_unlock(®istration_lock); } +EXPORT_SYMBOL(parport_unregister_driver); -static void free_port (struct parport *port) +static void free_port(struct device *dev) { int d; + struct parport *port = to_parport_dev(dev); + spin_lock(&full_list_lock); list_del(&port->full_list); spin_unlock(&full_list_lock); @@ -209,7 +352,6 @@ static void free_port (struct parport *port) kfree(port->probe_info[d].description); } - kfree(port->name); kfree(port); } @@ -221,28 +363,34 @@ static void free_port (struct parport *port) * until the matching parport_put_port() call. **/ -struct parport *parport_get_port (struct parport *port) +struct parport *parport_get_port(struct parport *port) +{ + struct device *dev = get_device(&port->bus_dev); + + return to_parport_dev(dev); +} +EXPORT_SYMBOL(parport_get_port); + +void parport_del_port(struct parport *port) { - atomic_inc (&port->ref_count); - return port; + device_unregister(&port->bus_dev); } +EXPORT_SYMBOL(parport_del_port); /** * parport_put_port - decrement a port's reference count * @port: the port * * This should be called once for each call to parport_get_port(), - * once the port is no longer needed. + * once the port is no longer needed. When the reference count reaches + * zero (port is no longer used), free_port is called. **/ -void parport_put_port (struct parport *port) +void parport_put_port(struct parport *port) { - if (atomic_dec_and_test (&port->ref_count)) - /* Can destroy it now. */ - free_port (port); - - return; + put_device(&port->bus_dev); } +EXPORT_SYMBOL(parport_put_port); /** * parport_register_port - register a parallel port @@ -280,26 +428,20 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, struct parport *tmp; int num; int device; - char *name; + int ret; tmp = kzalloc(sizeof(struct parport), GFP_KERNEL); - if (!tmp) { - printk(KERN_WARNING "parport: memory squeeze\n"); + if (!tmp) return NULL; - } /* Init our structure */ tmp->base = base; tmp->irq = irq; tmp->dma = dma; tmp->muxport = tmp->daisy = tmp->muxsel = -1; - tmp->modes = 0; - INIT_LIST_HEAD(&tmp->list); - tmp->devices = tmp->cad = NULL; - tmp->flags = 0; + INIT_LIST_HEAD(&tmp->list); tmp->ops = ops; tmp->physport = tmp; - memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info)); rwlock_init(&tmp->cad_lock); spin_lock_init(&tmp->waitlist_lock); spin_lock_init(&tmp->pardevice_lock); @@ -307,21 +449,16 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, tmp->ieee1284.phase = IEEE1284_PH_FWD_IDLE; sema_init(&tmp->ieee1284.irq, 0); tmp->spintime = parport_default_spintime; - atomic_set (&tmp->ref_count, 1); - INIT_LIST_HEAD(&tmp->full_list); + atomic_set(&tmp->ref_count, 1); - name = kmalloc(15, GFP_KERNEL); - if (!name) { - printk(KERN_ERR "parport: memory squeeze\n"); - kfree(tmp); - return NULL; - } /* Search for the lowest free parport number. */ spin_lock(&full_list_lock); - for (l = all_ports.next, num = 0; l != &all_ports; l = l->next, num++) { + num = 0; + list_for_each(l, &all_ports) { struct parport *p = list_entry(l, struct parport, full_list); - if (p->number != num) + + if (p->number != num++) break; } tmp->portnum = tmp->number = num; @@ -331,17 +468,26 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, /* * Now that the portnum is known finish doing the Init. */ - sprintf(name, "parport%d", tmp->portnum = tmp->number); - tmp->name = name; + dev_set_name(&tmp->bus_dev, "parport%d", tmp->portnum); + tmp->bus_dev.bus = &parport_bus_type; + tmp->bus_dev.release = free_port; + tmp->bus_dev.type = &parport_device_type; + + tmp->name = dev_name(&tmp->bus_dev); for (device = 0; device < 5; device++) /* assume the worst */ tmp->probe_info[device].class = PARPORT_CLASS_LEGACY; - tmp->waithead = tmp->waittail = NULL; + ret = device_register(&tmp->bus_dev); + if (ret) { + put_device(&tmp->bus_dev); + return NULL; + } return tmp; } +EXPORT_SYMBOL(parport_register_port); /** * parport_announce_port - tell device drivers about a parallel port @@ -355,7 +501,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, * functions will be called, with @port as the parameter. **/ -void parport_announce_port (struct parport *port) +void parport_announce_port(struct parport *port) { int i; @@ -365,9 +511,8 @@ void parport_announce_port (struct parport *port) #endif if (!port->dev) - printk(KERN_WARNING "%s: fix this legacy " - "no-device port driver!\n", - port->name); + pr_warn("%s: fix this legacy no-device port driver!\n", + port->name); parport_proc_register(port); mutex_lock(®istration_lock); @@ -381,7 +526,7 @@ void parport_announce_port (struct parport *port) spin_unlock_irq(&parportlist_lock); /* Let drivers know that new port(s) has arrived. */ - attach_driver_chain (port); + attach_driver_chain(port); for (i = 1; i < 3; i++) { struct parport *slave = port->slaves[i-1]; if (slave) @@ -389,6 +534,7 @@ void parport_announce_port (struct parport *port) } mutex_unlock(®istration_lock); } +EXPORT_SYMBOL(parport_announce_port); /** * parport_remove_port - deregister a parallel port @@ -416,7 +562,7 @@ void parport_remove_port(struct parport *port) mutex_lock(®istration_lock); /* Spread the word. */ - detach_driver_chain (port); + detach_driver_chain(port); #ifdef CONFIG_PARPORT_1284 /* Forget the IEEE1284.3 topology of the port. */ @@ -450,48 +596,50 @@ void parport_remove_port(struct parport *port) parport_put_port(slave); } } +EXPORT_SYMBOL(parport_remove_port); + +static void free_pardevice(struct device *dev) +{ + struct pardevice *par_dev = to_pardevice(dev); + + kfree_const(par_dev->name); + kfree(par_dev); +} /** - * parport_register_device - register a device on a parallel port + * parport_register_dev_model - register a device on a parallel port * @port: port to which the device is attached * @name: a name to refer to the device - * @pf: preemption callback - * @kf: kick callback (wake-up) - * @irq_func: interrupt handler - * @flags: registration flags - * @handle: data for callback functions + * @par_dev_cb: struct containing callbacks + * @id: device number to be given to the device * * This function, called by parallel port device drivers, * declares that a device is connected to a port, and tells the * system all it needs to know. * - * The @name is allocated by the caller and must not be - * deallocated until the caller calls @parport_unregister_device - * for that device. + * The struct pardev_cb contains pointer to callbacks. preemption + * callback function, @preempt, is called when this device driver + * has claimed access to the port but another device driver wants + * to use it. It is given, @private, as its parameter, and should + * return zero if it is willing for the system to release the port + * to another driver on its behalf. If it wants to keep control of + * the port it should return non-zero, and no action will be taken. + * It is good manners for the driver to try to release the port at + * the earliest opportunity after its preemption callback rejects a + * preemption attempt. Note that if a preemption callback is happy + * for preemption to go ahead, there is no need to release the + * port; it is done automatically. This function may not block, as + * it may be called from interrupt context. If the device driver + * does not support preemption, @preempt can be %NULL. * - * The preemption callback function, @pf, is called when this - * device driver has claimed access to the port but another - * device driver wants to use it. It is given @handle as its - * parameter, and should return zero if it is willing for the - * system to release the port to another driver on its behalf. - * If it wants to keep control of the port it should return - * non-zero, and no action will be taken. It is good manners for - * the driver to try to release the port at the earliest - * opportunity after its preemption callback rejects a preemption - * attempt. Note that if a preemption callback is happy for - * preemption to go ahead, there is no need to release the port; - * it is done automatically. This function may not block, as it - * may be called from interrupt context. If the device driver - * does not support preemption, @pf can be %NULL. - * - * The wake-up ("kick") callback function, @kf, is called when + * The wake-up ("kick") callback function, @wakeup, is called when * the port is available to be claimed for exclusive access; that * is, parport_claim() is guaranteed to succeed when called from * inside the wake-up callback function. If the driver wants to * claim the port it should do so; otherwise, it need not take * any action. This function may not block, as it may be called * from interrupt context. If the device driver does not want to - * be explicitly invited to claim the port in this way, @kf can + * be explicitly invited to claim the port in this way, @wakeup can * be %NULL. * * The interrupt handler, @irq_func, is called when an interrupt @@ -521,114 +669,145 @@ void parport_remove_port(struct parport *port) **/ struct pardevice * -parport_register_device(struct parport *port, const char *name, - int (*pf)(void *), void (*kf)(void *), - void (*irq_func)(void *), - int flags, void *handle) +parport_register_dev_model(struct parport *port, const char *name, + const struct pardev_cb *par_dev_cb, int id) { - struct pardevice *tmp; + struct pardevice *par_dev; + const char *devname; + int ret; if (port->physport->flags & PARPORT_FLAG_EXCL) { /* An exclusive device is registered. */ - printk (KERN_DEBUG "%s: no more devices allowed\n", - port->name); + pr_err("%s: no more devices allowed\n", port->name); return NULL; } - if (flags & PARPORT_DEV_LURK) { - if (!pf || !kf) { - printk(KERN_INFO "%s: refused to register lurking device (%s) without callbacks\n", port->name, name); + if (par_dev_cb->flags & PARPORT_DEV_LURK) { + if (!par_dev_cb->preempt || !par_dev_cb->wakeup) { + pr_info("%s: refused to register lurking device (%s) without callbacks\n", + port->name, name); return NULL; } } - /* We up our own module reference count, and that of the port - on which a device is to be registered, to ensure that - neither of us gets unloaded while we sleep in (e.g.) - kmalloc. - */ - if (!try_module_get(port->ops->owner)) { - return NULL; + if (par_dev_cb->flags & PARPORT_DEV_EXCL) { + if (port->physport->devices) { + /* + * If a device is already registered and this new + * device wants exclusive access, then no need to + * continue as we can not grant exclusive access to + * this device. + */ + pr_err("%s: cannot grant exclusive access for device %s\n", + port->name, name); + return NULL; + } } - - parport_get_port (port); - tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); - if (tmp == NULL) { - printk(KERN_WARNING "%s: memory squeeze, couldn't register %s.\n", port->name, name); - goto out; - } + if (!try_module_get(port->ops->owner)) + return NULL; - tmp->state = kmalloc(sizeof(struct parport_state), GFP_KERNEL); - if (tmp->state == NULL) { - printk(KERN_WARNING "%s: memory squeeze, couldn't register %s.\n", port->name, name); - goto out_free_pardevice; + parport_get_port(port); + + par_dev = kzalloc(sizeof(*par_dev), GFP_KERNEL); + if (!par_dev) + goto err_put_port; + + par_dev->state = kzalloc(sizeof(*par_dev->state), GFP_KERNEL); + if (!par_dev->state) + goto err_put_par_dev; + + devname = kstrdup_const(name, GFP_KERNEL); + if (!devname) + goto err_free_par_dev; + + par_dev->name = devname; + par_dev->port = port; + par_dev->daisy = -1; + par_dev->preempt = par_dev_cb->preempt; + par_dev->wakeup = par_dev_cb->wakeup; + par_dev->private = par_dev_cb->private; + par_dev->flags = par_dev_cb->flags; + par_dev->irq_func = par_dev_cb->irq_func; + par_dev->waiting = 0; + par_dev->timeout = 5 * HZ; + + par_dev->dev.parent = &port->bus_dev; + par_dev->dev.bus = &parport_bus_type; + ret = dev_set_name(&par_dev->dev, "%s.%d", devname, id); + if (ret) + goto err_free_devname; + par_dev->dev.release = free_pardevice; + par_dev->devmodel = true; + ret = device_register(&par_dev->dev); + if (ret) { + kfree(par_dev->state); + put_device(&par_dev->dev); + goto err_put_port; } - tmp->name = name; - tmp->port = port; - tmp->daisy = -1; - tmp->preempt = pf; - tmp->wakeup = kf; - tmp->private = handle; - tmp->flags = flags; - tmp->irq_func = irq_func; - tmp->waiting = 0; - tmp->timeout = 5 * HZ; - /* Chain this onto the list */ - tmp->prev = NULL; + par_dev->prev = NULL; /* * This function must not run from an irq handler so we don' t need * to clear irq on the local CPU. -arca */ spin_lock(&port->physport->pardevice_lock); - if (flags & PARPORT_DEV_EXCL) { + if (par_dev_cb->flags & PARPORT_DEV_EXCL) { if (port->physport->devices) { - spin_unlock (&port->physport->pardevice_lock); - printk (KERN_DEBUG - "%s: cannot grant exclusive access for " - "device %s\n", port->name, name); - goto out_free_all; + spin_unlock(&port->physport->pardevice_lock); + pr_debug("%s: cannot grant exclusive access for device %s\n", + port->name, name); + kfree(par_dev->state); + device_unregister(&par_dev->dev); + goto err_put_port; } port->flags |= PARPORT_FLAG_EXCL; } - tmp->next = port->physport->devices; - wmb(); /* Make sure that tmp->next is written before it's - added to the list; see comments marked 'no locking - required' */ + par_dev->next = port->physport->devices; + wmb(); /* + * Make sure that tmp->next is written before it's + * added to the list; see comments marked 'no locking + * required' + */ if (port->physport->devices) - port->physport->devices->prev = tmp; - port->physport->devices = tmp; + port->physport->devices->prev = par_dev; + port->physport->devices = par_dev; spin_unlock(&port->physport->pardevice_lock); - init_waitqueue_head(&tmp->wait_q); - tmp->timeslice = parport_default_timeslice; - tmp->waitnext = tmp->waitprev = NULL; + init_waitqueue_head(&par_dev->wait_q); + par_dev->timeslice = parport_default_timeslice; + par_dev->waitnext = NULL; + par_dev->waitprev = NULL; /* * This has to be run as last thing since init_state may need other * pardevice fields. -arca */ - port->ops->init_state(tmp, tmp->state); + port->ops->init_state(par_dev, par_dev->state); if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) { - port->proc_device = tmp; - parport_device_proc_register(tmp); + port->proc_device = par_dev; + parport_device_proc_register(par_dev); } - return tmp; - out_free_all: - kfree(tmp->state); - out_free_pardevice: - kfree(tmp); - out: - parport_put_port (port); + return par_dev; + +err_free_devname: + kfree_const(devname); +err_free_par_dev: + kfree(par_dev->state); +err_put_par_dev: + if (!par_dev->devmodel) + kfree(par_dev); +err_put_port: + parport_put_port(port); module_put(port->ops->owner); return NULL; } +EXPORT_SYMBOL(parport_register_dev_model); /** * parport_unregister_device - deregister a device on a parallel port @@ -642,8 +821,8 @@ void parport_unregister_device(struct pardevice *dev) struct parport *port; #ifdef PARPORT_PARANOID - if (dev == NULL) { - printk(KERN_ERR "parport_unregister_device: passed NULL\n"); + if (!dev) { + pr_err("%s: passed NULL\n", __func__); return; } #endif @@ -659,7 +838,7 @@ void parport_unregister_device(struct pardevice *dev) if (port->cad == dev) { printk(KERN_DEBUG "%s: %s forgot to release port\n", port->name, dev->name); - parport_release (dev); + parport_release(dev); } spin_lock(&port->pardevice_lock); @@ -675,8 +854,10 @@ void parport_unregister_device(struct pardevice *dev) spin_unlock(&port->pardevice_lock); - /* Make sure we haven't left any pointers around in the wait - * list. */ + /* + * Make sure we haven't left any pointers around in the wait + * list. + */ spin_lock_irq(&port->waitlist_lock); if (dev->waitprev || dev->waitnext || port->waithead == dev) { if (dev->waitprev) @@ -691,11 +872,12 @@ void parport_unregister_device(struct pardevice *dev) spin_unlock_irq(&port->waitlist_lock); kfree(dev->state); - kfree(dev); + device_unregister(&dev->dev); module_put(port->ops->owner); - parport_put_port (port); + parport_put_port(port); } +EXPORT_SYMBOL(parport_unregister_device); /** * parport_find_number - find a parallel port by number @@ -709,23 +891,24 @@ void parport_unregister_device(struct pardevice *dev) * gives you, use parport_put_port(). */ -struct parport *parport_find_number (int number) +struct parport *parport_find_number(int number) { struct parport *port, *result = NULL; if (list_empty(&portlist)) - get_lowlevel_driver (); + get_lowlevel_driver(); - spin_lock (&parportlist_lock); + spin_lock(&parportlist_lock); list_for_each_entry(port, &portlist, list) { if (port->number == number) { - result = parport_get_port (port); + result = parport_get_port(port); break; } } - spin_unlock (&parportlist_lock); + spin_unlock(&parportlist_lock); return result; } +EXPORT_SYMBOL(parport_find_number); /** * parport_find_base - find a parallel port by base address @@ -739,23 +922,24 @@ struct parport *parport_find_number (int number) * gives you, use parport_put_port(). */ -struct parport *parport_find_base (unsigned long base) +struct parport *parport_find_base(unsigned long base) { struct parport *port, *result = NULL; if (list_empty(&portlist)) - get_lowlevel_driver (); + get_lowlevel_driver(); - spin_lock (&parportlist_lock); + spin_lock(&parportlist_lock); list_for_each_entry(port, &portlist, list) { if (port->base == base) { - result = parport_get_port (port); + result = parport_get_port(port); break; } } - spin_unlock (&parportlist_lock); + spin_unlock(&parportlist_lock); return result; } +EXPORT_SYMBOL(parport_find_base); /** * parport_claim - claim access to a parallel port device @@ -776,14 +960,14 @@ int parport_claim(struct pardevice *dev) unsigned long flags; if (port->cad == dev) { - printk(KERN_INFO "%s: %s already owner\n", - dev->port->name,dev->name); + pr_info("%s: %s already owner\n", dev->port->name, dev->name); return 0; } /* Preempt any current device */ - write_lock_irqsave (&port->cad_lock, flags); - if ((oldcad = port->cad) != NULL) { + write_lock_irqsave(&port->cad_lock, flags); + oldcad = port->cad; + if (oldcad) { if (oldcad->preempt) { if (oldcad->preempt(oldcad->private)) goto blocked; @@ -792,11 +976,12 @@ int parport_claim(struct pardevice *dev) goto blocked; if (port->cad != oldcad) { - /* I think we'll actually deadlock rather than - get here, but just in case.. */ - printk(KERN_WARNING - "%s: %s released port when preempted!\n", - port->name, oldcad->name); + /* + * I think we'll actually deadlock rather than + * get here, but just in case.. + */ + pr_warn("%s: %s released port when preempted!\n", + port->name, oldcad->name); if (port->cad) goto blocked; } @@ -807,7 +992,7 @@ int parport_claim(struct pardevice *dev) dev->waiting = 0; /* Take ourselves out of the wait list again. */ - spin_lock_irq (&port->waitlist_lock); + spin_lock_irq(&port->waitlist_lock); if (dev->waitprev) dev->waitprev->waitnext = dev->waitnext; else @@ -816,7 +1001,7 @@ int parport_claim(struct pardevice *dev) dev->waitnext->waitprev = dev->waitprev; else port->waittail = dev->waitprev; - spin_unlock_irq (&port->waitlist_lock); + spin_unlock_irq(&port->waitlist_lock); dev->waitprev = dev->waitnext = NULL; } @@ -833,7 +1018,7 @@ int parport_claim(struct pardevice *dev) /* If it's a daisy chain device, select it. */ if (dev->daisy >= 0) { /* This could be lazier. */ - if (!parport_daisy_select (port, dev->daisy, + if (!parport_daisy_select(port, dev->daisy, IEEE1284_MODE_COMPAT)) port->daisy = dev->daisy; } @@ -846,13 +1031,15 @@ int parport_claim(struct pardevice *dev) return 0; blocked: - /* If this is the first time we tried to claim the port, register an - interest. This is only allowed for devices sleeping in - parport_claim_or_block(), or those with a wakeup function. */ + /* + * If this is the first time we tried to claim the port, register an + * interest. This is only allowed for devices sleeping in + * parport_claim_or_block(), or those with a wakeup function. + */ /* The cad_lock is still held for writing here */ if (dev->waiting & 2 || dev->wakeup) { - spin_lock (&port->waitlist_lock); + spin_lock(&port->waitlist_lock); if (test_and_set_bit(0, &dev->waiting) == 0) { /* First add ourselves to the end of the wait list. */ dev->waitnext = NULL; @@ -863,11 +1050,12 @@ blocked: } else port->waithead = port->waittail = dev; } - spin_unlock (&port->waitlist_lock); + spin_unlock(&port->waitlist_lock); } - write_unlock_irqrestore (&port->cad_lock, flags); + write_unlock_irqrestore(&port->cad_lock, flags); return -EAGAIN; } +EXPORT_SYMBOL(parport_claim); /** * parport_claim_or_block - claim access to a parallel port device @@ -883,15 +1071,18 @@ int parport_claim_or_block(struct pardevice *dev) { int r; - /* Signal to parport_claim() that we can wait even without a - wakeup function. */ + /* + * Signal to parport_claim() that we can wait even without a + * wakeup function. + */ dev->waiting = 2; /* Try to claim the port. If this fails, we need to sleep. */ r = parport_claim(dev); if (r == -EAGAIN) { #ifdef PARPORT_DEBUG_SHARING - printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n", dev->name); + printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n", + dev->name); #endif /* * FIXME!!! Use the proper locking for dev->waiting, @@ -902,13 +1093,15 @@ int parport_claim_or_block(struct pardevice *dev) * See also parport_release() */ - /* If dev->waiting is clear now, an interrupt - gave us the port and we would deadlock if we slept. */ + /* + * If dev->waiting is clear now, an interrupt + * gave us the port and we would deadlock if we slept. + */ if (dev->waiting) { - interruptible_sleep_on (&dev->wait_q); - if (signal_pending (current)) { + wait_event_interruptible(dev->wait_q, + !dev->waiting); + if (signal_pending(current)) return -EINTR; - } r = 1; } else { r = 0; @@ -920,15 +1113,15 @@ int parport_claim_or_block(struct pardevice *dev) #ifdef PARPORT_DEBUG_SHARING if (dev->port->physport->cad != dev) - printk(KERN_DEBUG "%s: exiting parport_claim_or_block " - "but %s owns port!\n", dev->name, - dev->port->physport->cad ? - dev->port->physport->cad->name:"nobody"); + printk(KERN_DEBUG "%s: exiting parport_claim_or_block but %s owns port!\n", + dev->name, dev->port->physport->cad ? + dev->port->physport->cad->name : "nobody"); #endif } dev->waiting = 0; return r; } +EXPORT_SYMBOL(parport_claim_or_block); /** * parport_release - give up access to a parallel port device @@ -948,9 +1141,9 @@ void parport_release(struct pardevice *dev) /* Make sure that dev is the current device */ write_lock_irqsave(&port->cad_lock, flags); if (port->cad != dev) { - write_unlock_irqrestore (&port->cad_lock, flags); - printk(KERN_WARNING "%s: %s tried to release parport " - "when not owner\n", port->name, dev->name); + write_unlock_irqrestore(&port->cad_lock, flags); + pr_warn("%s: %s tried to release parport when not owner\n", + port->name, dev->name); return; } @@ -963,7 +1156,7 @@ void parport_release(struct pardevice *dev) /* If this is a daisy device, deselect it. */ if (dev->daisy >= 0) { - parport_daisy_deselect_all (port); + parport_daisy_deselect_all(port); port->daisy = -1; } #endif @@ -974,8 +1167,10 @@ void parport_release(struct pardevice *dev) /* Save control registers */ port->ops->save_state(port, dev->state); - /* If anybody is waiting, find out who's been there longest and - then wake them up. (Note: no locking required) */ + /* + * If anybody is waiting, find out who's been there longest and + * then wake them up. (Note: no locking required) + */ /* !!! LOCKING IS NEEDED HERE */ for (pd = port->waithead; pd; pd = pd->waitnext) { if (pd->waiting & 2) { /* sleeping in claim_or_block */ @@ -988,18 +1183,22 @@ void parport_release(struct pardevice *dev) if (dev->port->cad) /* racy but no matter */ return; } else { - printk(KERN_ERR "%s: don't know how to wake %s\n", port->name, pd->name); + pr_err("%s: don't know how to wake %s\n", + port->name, pd->name); } } - /* Nobody was waiting, so walk the list to see if anyone is - interested in being woken up. (Note: no locking required) */ + /* + * Nobody was waiting, so walk the list to see if anyone is + * interested in being woken up. (Note: no locking required) + */ /* !!! LOCKING IS NEEDED HERE */ - for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) { + for (pd = port->devices; !port->cad && pd; pd = pd->next) { if (pd->wakeup && pd != dev) pd->wakeup(pd->private); } } +EXPORT_SYMBOL(parport_release); irqreturn_t parport_irq_handler(int irq, void *dev_id) { @@ -1009,23 +1208,7 @@ irqreturn_t parport_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } - -/* Exported symbols for modules. */ - -EXPORT_SYMBOL(parport_claim); -EXPORT_SYMBOL(parport_claim_or_block); -EXPORT_SYMBOL(parport_release); -EXPORT_SYMBOL(parport_register_port); -EXPORT_SYMBOL(parport_announce_port); -EXPORT_SYMBOL(parport_remove_port); -EXPORT_SYMBOL(parport_register_driver); -EXPORT_SYMBOL(parport_unregister_driver); -EXPORT_SYMBOL(parport_register_device); -EXPORT_SYMBOL(parport_unregister_device); -EXPORT_SYMBOL(parport_get_port); -EXPORT_SYMBOL(parport_put_port); -EXPORT_SYMBOL(parport_find_number); -EXPORT_SYMBOL(parport_find_base); EXPORT_SYMBOL(parport_irq_handler); +MODULE_DESCRIPTION("Parallel-port resource manager"); MODULE_LICENSE("GPL"); |
