Commit 38daf88a authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

mxser: allow overlapping vector

For many cards, this saves some IO space because interrupt status port
has precedence over the rest of ports on the card. Hence it can be
mapped to a hole in I/O ports.

Here we add a kernel parameter which allows that if a user wants to.
But they need to explicitly enable it by a module parameter.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c565ee07
...@@ -2337,11 +2337,36 @@ static struct tty_port_operations mxser_port_ops = { ...@@ -2337,11 +2337,36 @@ static struct tty_port_operations mxser_port_ops = {
* The MOXA Smartio/Industio serial driver boot-time initialization code! * The MOXA Smartio/Industio serial driver boot-time initialization code!
*/ */
static bool allow_overlapping_vector;
module_param(allow_overlapping_vector, bool, 444);
MODULE_PARM_DESC(allow_overlapping_vector, "whether we allow ISA cards to be configured such that vector overlabs IO ports (default=no)");
static bool mxser_overlapping_vector(struct mxser_board *brd)
{
return allow_overlapping_vector &&
brd->vector >= brd->ports[0].ioaddr &&
brd->vector < brd->ports[0].ioaddr + 8 * brd->info->nports;
}
static int mxser_request_vector(struct mxser_board *brd)
{
if (mxser_overlapping_vector(brd))
return 0;
return request_region(brd->vector, 1, "mxser(vector)") ? 0 : -EIO;
}
static void mxser_release_vector(struct mxser_board *brd)
{
if (mxser_overlapping_vector(brd))
return;
release_region(brd->vector, 1);
}
static void mxser_release_ISA_res(struct mxser_board *brd) static void mxser_release_ISA_res(struct mxser_board *brd)
{ {
free_irq(brd->irq, brd); free_irq(brd->irq, brd);
release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
release_region(brd->vector, 1); mxser_release_vector(brd);
} }
static int __devinit mxser_initbrd(struct mxser_board *brd, static int __devinit mxser_initbrd(struct mxser_board *brd,
...@@ -2396,7 +2421,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, ...@@ -2396,7 +2421,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
{ {
int id, i, bits; int id, i, bits, ret;
unsigned short regs[16], irq; unsigned short regs[16], irq;
unsigned char scratch, scratch2; unsigned char scratch, scratch2;
...@@ -2492,13 +2517,15 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) ...@@ -2492,13 +2517,15 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
8 * brd->info->nports - 1); 8 * brd->info->nports - 1);
return -EIO; return -EIO;
} }
if (!request_region(brd->vector, 1, "mxser(vector)")) {
ret = mxser_request_vector(brd);
if (ret) {
release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
printk(KERN_ERR "mxser: can't request interrupt vector region: " printk(KERN_ERR "mxser: can't request interrupt vector region: "
"0x%.8lx-0x%.8lx\n", "0x%.8lx-0x%.8lx\n",
brd->ports[0].ioaddr, brd->ports[0].ioaddr + brd->ports[0].ioaddr, brd->ports[0].ioaddr +
8 * brd->info->nports - 1); 8 * brd->info->nports - 1);
return -EIO; return ret;
} }
return brd->info->nports; return brd->info->nports;
......
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