Commit 9beaf628 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] parport: option parsing cleanup

	parport_pc options parsing moved to parport_pc.c; parport/init.c is
gone.
	Warning fixes from -mm added.
parent 00c16378
......@@ -2,7 +2,7 @@
# Makefile for the kernel Parallel port device drivers.
#
parport-objs := share.o ieee1284.o ieee1284_ops.o procfs.o init.o
parport-objs := share.o ieee1284.o ieee1284_ops.o procfs.o
ifeq ($(CONFIG_PARPORT_1284),y)
parport-objs += daisy.o probe.o
......
/* Parallel-port initialisation code.
*
* Authors: David Campbell <campbell@torque.net>
* Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
*
* based on work by Grant Guenther <grant@torque.net>
* and Philip Blundell <Philip.Blundell@pobox.com>
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/threads.h>
#include <linux/string.h>
#include <linux/parport.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#ifndef MODULE
static int io[PARPORT_MAX+1] __initdata = { [0 ... PARPORT_MAX] = 0 };
#ifdef CONFIG_PARPORT_PC
static int io_hi[PARPORT_MAX+1] __initdata =
{ [0 ... PARPORT_MAX] = PARPORT_IOHI_AUTO };
#endif
static int irq[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_IRQ_PROBEONLY };
static int dma[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_DMA_NONE };
extern int parport_pc_init(int *io, int *io_hi, int *irq, int *dma);
static int parport_setup_ptr __initdata = 0;
/*
* Acceptable parameters:
*
* parport=0
* parport=auto
* parport=0xBASE[,IRQ[,DMA]]
*
* IRQ/DMA may be numeric or 'auto' or 'none'
*/
static int __init parport_setup (char *str)
{
char *endptr;
char *sep;
int val;
if (!str || !*str || (*str == '0' && !*(str+1))) {
/* Disable parport if "parport=0" in cmdline */
io[0] = PARPORT_DISABLE;
return 1;
}
if (!strncmp (str, "auto", 4)) {
irq[0] = PARPORT_IRQ_AUTO;
dma[0] = PARPORT_DMA_AUTO;
return 1;
}
val = simple_strtoul (str, &endptr, 0);
if (endptr == str) {
printk (KERN_WARNING "parport=%s not understood\n", str);
return 1;
}
if (parport_setup_ptr == PARPORT_MAX) {
printk(KERN_ERR "parport=%s ignored, too many ports\n", str);
return 1;
}
io[parport_setup_ptr] = val;
irq[parport_setup_ptr] = PARPORT_IRQ_NONE;
dma[parport_setup_ptr] = PARPORT_DMA_NONE;
sep = strchr (str, ',');
if (sep++) {
if (!strncmp (sep, "auto", 4))
irq[parport_setup_ptr] = PARPORT_IRQ_AUTO;
else if (strncmp (sep, "none", 4)) {
val = simple_strtoul (sep, &endptr, 0);
if (endptr == sep) {
printk (KERN_WARNING
"parport=%s: irq not understood\n",
str);
return 1;
}
irq[parport_setup_ptr] = val;
}
}
sep = strchr (sep, ',');
if (sep++) {
if (!strncmp (sep, "auto", 4))
dma[parport_setup_ptr] = PARPORT_DMA_AUTO;
else if (!strncmp (sep, "nofifo", 6))
dma[parport_setup_ptr] = PARPORT_DMA_NOFIFO;
else if (strncmp (sep, "none", 4)) {
val = simple_strtoul (sep, &endptr, 0);
if (endptr == sep) {
printk (KERN_WARNING
"parport=%s: dma not understood\n",
str);
return 1;
}
dma[parport_setup_ptr] = val;
}
}
parport_setup_ptr++;
return 1;
}
__setup ("parport=", parport_setup);
int __init parport_init (void)
{
if (io[0] == PARPORT_DISABLE)
return 1;
#ifdef CONFIG_PARPORT_PC
parport_pc_init(io, io_hi, irq, dma);
#endif
return 0;
}
__initcall(parport_init);
#endif
......@@ -2346,6 +2346,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
return NULL;
}
EXPORT_SYMBOL (parport_pc_probe_port);
void parport_pc_unregister_port (struct parport *p)
{
#ifdef CONFIG_PARPORT_PC_FIFO
......@@ -2373,6 +2375,8 @@ void parport_pc_unregister_port (struct parport *p)
kfree (ops); /* hope no-one cached it */
}
EXPORT_SYMBOL (parport_pc_unregister_port);
#ifdef CONFIG_PCI
/* ITE support maintained by Rich Liu <richliu@poorman.org> */
......@@ -2931,45 +2935,57 @@ static int __init parport_pc_find_ports (int autoirq, int autodma)
return count;
}
int __init parport_pc_init (int *io, int *io_hi, int *irq, int *dma)
{
int count = 0, i = 0;
/* try to activate any PnP parports first */
pnp_register_driver(&parport_pc_pnp_driver);
/*
* Piles of crap below pretend to be a parser for module and kernel
* parameters. Say "thank you" to whoever had come up with that
* syntax and keep in mind that code below is a cleaned up version.
*/
if (io && *io) {
/* Only probe the ports we were given. */
user_specified = 1;
do {
if ((*io_hi) == PARPORT_IOHI_AUTO)
*io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
*(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
count += parport_pc_find_ports (irq[0], dma[0]);
static int __initdata io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
static int __initdata io_hi[PARPORT_PC_MAX_PORTS+1] =
{ [0 ... PARPORT_PC_MAX_PORTS] = PARPORT_IOHI_AUTO };
static int __initdata dmaval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_DMA_NONE };
static int __initdata irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY };
static int __init parport_parse_param(const char *s, int *val,
int automatic, int none, int nofifo)
{
if (!s)
return 0;
if (!strncmp(s, "auto", 4))
*val = automatic;
else if (!strncmp(s, "none", 4))
*val = none;
else if (nofifo && !strncmp(s, "nofifo", 4))
*val = nofifo;
else {
char *ep;
unsigned long r = simple_strtoul(s, &ep, 0);
if (ep != s)
*val = r;
else {
printk(KERN_ERR "parport: bad specifier `%s'\n", s);
return -1;
}
}
return 0;
}
return count;
static int __init parport_parse_irq(const char *irqstr, int *val)
{
return parport_parse_param(irqstr, val, PARPORT_IRQ_AUTO,
PARPORT_IRQ_NONE, 0);
}
/* Exported symbols. */
EXPORT_SYMBOL (parport_pc_probe_port);
EXPORT_SYMBOL (parport_pc_unregister_port);
static int __init parport_parse_dma(const char *dmastr, int *val)
{
return parport_parse_param(dmastr, val, PARPORT_DMA_AUTO,
PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
}
#ifdef MODULE
static int io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
static int io_hi[PARPORT_PC_MAX_PORTS+1] =
{ [0 ... PARPORT_PC_MAX_PORTS] = PARPORT_IOHI_AUTO };
static int dmaval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_DMA_NONE };
static int irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY };
static const char *irq[PARPORT_PC_MAX_PORTS] = { NULL, };
static const char *dma[PARPORT_PC_MAX_PORTS] = { NULL, };
MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
MODULE_DESCRIPTION("PC-style parallel port driver");
MODULE_LICENSE("GPL");
static const char *irq[PARPORT_PC_MAX_PORTS];
static const char *dma[PARPORT_PC_MAX_PORTS];
MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
......@@ -2985,22 +3001,22 @@ MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
MODULE_PARM(verbose_probing, "i");
#endif
int init_module(void)
{
/* Work out how many ports we have, then get parport_share to parse
the irq values. */
static int __init parse_parport_params(void)
{
unsigned int i;
int ret;
for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++);
if (i) {
if (parport_parse_irqs(i, irq, irqval)) return 1;
if (parport_parse_dmas(i, dma, dmaval)) return 1;
int val;
for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++) {
if (parport_parse_irq(irq[i], &val))
return 1;
irqval[i] = val;
if (parport_parse_dma(dma[i], &val))
return 1;
dmaval[i] = val;
}
else {
if (!io[0]) {
/* The user can make us use any IRQs or DMAs we find. */
int val;
if (irq[0] && !parport_parse_irqs (1, irq, &val))
if (irq[0] && !parport_parse_irq(irq[0], &val))
switch (val) {
case PARPORT_IRQ_NONE:
case PARPORT_IRQ_AUTO:
......@@ -3013,7 +3029,7 @@ int init_module(void)
"to specify one\n");
}
if (dma[0] && !parport_parse_dmas (1, dma, &val))
if (dma[0] && !parport_parse_dma(dma[0], &val))
switch (val) {
case PARPORT_DMA_NONE:
case PARPORT_DMA_AUTO:
......@@ -3026,20 +3042,124 @@ int init_module(void)
"to specify one\n");
}
}
return 0;
}
ret = !parport_pc_init (io, io_hi, irqval, dmaval);
if (ret && registered_parport)
pci_unregister_driver (&parport_pc_pci_driver);
#else
static int parport_setup_ptr __initdata = 0;
/*
* Acceptable parameters:
*
* parport=0
* parport=auto
* parport=0xBASE[,IRQ[,DMA]]
*
* IRQ/DMA may be numeric or 'auto' or 'none'
*/
static int __init parport_setup (char *str)
{
char *endptr;
char *sep;
int val;
return ret;
if (!str || !*str || (*str == '0' && !*(str+1))) {
/* Disable parport if "parport=0" in cmdline */
io[0] = PARPORT_DISABLE;
return 1;
}
if (!strncmp (str, "auto", 4)) {
irqval[0] = PARPORT_IRQ_AUTO;
dmaval[0] = PARPORT_DMA_AUTO;
return 1;
}
val = simple_strtoul (str, &endptr, 0);
if (endptr == str) {
printk (KERN_WARNING "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);
return 1;
}
io[parport_setup_ptr] = val;
irqval[parport_setup_ptr] = PARPORT_IRQ_NONE;
dmaval[parport_setup_ptr] = PARPORT_DMA_NONE;
sep = strchr(str, ',');
if (sep++) {
if (parport_parse_irq(sep, &val))
return 1;
irqval[parport_setup_ptr] = val;
sep = strchr(sep, ',');
if (sep++) {
if (parport_parse_dma(sep, &val))
return 1;
dmaval[parport_setup_ptr] = val;
}
}
parport_setup_ptr++;
return 1;
}
void cleanup_module(void)
static int __init parse_parport_params(void)
{
return io[0] == PARPORT_DISABLE;
}
__setup ("parport=", parport_setup);
#endif
/* "Parser" ends here */
static int __init parport_pc_init(void)
{
int count = 0;
if (parse_parport_params())
return -EINVAL;
/* try to activate any PnP parports first */
pnp_register_driver(&parport_pc_pnp_driver);
if (io[0]) {
int i;
/* Only probe the ports we were given. */
user_specified = 1;
for (i = 0; i < PARPORT_PC_MAX_PORTS; i++) {
if (!io[i])
break;
if ((io_hi[i]) == PARPORT_IOHI_AUTO)
io_hi[i] = 0x400 + io[i];
if (parport_pc_probe_port(io[i], io_hi[i],
irqval[i], dmaval[i], NULL))
count++;
}
} else {
count += parport_pc_find_ports (irqval[0], dmaval[0]);
if (!count && registered_parport)
pci_unregister_driver (&parport_pc_pci_driver);
}
if (!count) {
pnp_unregister_driver (&parport_pc_pnp_driver);
return -ENODEV;
}
return 0;
}
static void __exit parport_pc_exit(void)
{
/* We ought to keep track of which ports are actually ours. */
struct parport *p = parport_enumerate(), *tmp;
if (!user_specified)
if (registered_parport)
pci_unregister_driver (&parport_pc_pci_driver);
while (p) {
......@@ -3051,4 +3171,13 @@ void cleanup_module(void)
}
pnp_unregister_driver (&parport_pc_pnp_driver);
}
#endif
MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
MODULE_DESCRIPTION("PC-style parallel port driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
MODULE_DESCRIPTION("PC-style parallel port driver");
MODULE_LICENSE("GPL");
module_init(parport_pc_init)
module_exit(parport_pc_exit)
......@@ -1078,44 +1078,4 @@ EXPORT_SYMBOL(parport_put_port);
EXPORT_SYMBOL(parport_find_number);
EXPORT_SYMBOL(parport_find_base);
EXPORT_SYMBOL(parport_parse_irqs);
EXPORT_SYMBOL(parport_parse_dmas);
static int parport_parse_params (int nports, const char *str[], int val[],
int automatic, int none, int nofifo)
{
unsigned int i;
for (i = 0; i < nports && str[i]; i++) {
if (!strncmp(str[i], "auto", 4))
val[i] = automatic;
else if (!strncmp(str[i], "none", 4))
val[i] = none;
else if (nofifo && !strncmp(str[i], "nofifo", 4))
val[i] = nofifo;
else {
char *ep;
unsigned long r = simple_strtoul(str[i], &ep, 0);
if (ep != str[i])
val[i] = r;
else {
printk(KERN_ERR "parport: bad specifier `%s'\n", str[i]);
return -1;
}
}
}
return 0;
}
int parport_parse_irqs(int nports, const char *irqstr[], int irqval[])
{
return parport_parse_params (nports, irqstr, irqval, PARPORT_IRQ_AUTO,
PARPORT_IRQ_NONE, 0);
}
int parport_parse_dmas(int nports, const char *dmastr[], int dmaval[])
{
return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO,
PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
}
MODULE_LICENSE("GPL");
......@@ -451,9 +451,6 @@ static __inline__ int parport_yield_blocking(struct pardevice *dev)
#define PARPORT_FLAG_EXCL (1<<1) /* EXCL driver registered. */
extern int parport_parse_irqs(int, const char *[], int irqval[]);
extern int parport_parse_dmas(int, const char *[], int dmaval[]);
/* IEEE1284 functions */
extern void parport_ieee1284_interrupt (int, void *, struct pt_regs *);
extern int parport_negotiate (struct parport *, int mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment