linux-stable/drivers/isdn/hardware/avm/b1isa.c
David Howells b9351f7e51 Annotate hardware config module parameters in drivers/isdn/
When the kernel is running in secure boot mode, we lock down the kernel to
prevent userspace from modifying the running kernel image.  Whilst this
includes prohibiting access to things like /dev/mem, it must also prevent
access by means of configuring driver modules in such a way as to cause a
device to access or modify the kernel image.

To this end, annotate module_param* statements that refer to hardware
configuration and indicate for future reference what type of parameter they
specify.  The parameter parser in the core sees this information and can
skip such parameters with an error message if the kernel is locked down.
The module initialisation then runs as normal, but just sees whatever the
default values for those parameters is.

Note that we do still need to do the module initialisation because some
drivers have viable defaults set in case parameters aren't specified and
some drivers support automatic configuration (e.g. PNP or PCI) in addition
to manually coded parameters.

This patch annotates drivers in drivers/isdn/.

Suggested-by: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Karsten Keil <isdn@linux-pingi.de>
cc: netdev@vger.kernel.org
2017-04-20 12:02:32 +01:00

243 lines
5.9 KiB
C

/* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
*
* Module for AVM B1 ISA-card.
*
* Copyright 1999 by Carsten Paeth <calle@calle.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/capi.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capilli.h>
#include "avmcard.h"
/* ------------------------------------------------------------- */
static char *revision = "$Revision: 1.1.2.3 $";
/* ------------------------------------------------------------- */
MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static void b1isa_remove(struct pci_dev *pdev)
{
avmctrl_info *cinfo = pci_get_drvdata(pdev);
avmcard *card;
if (!cinfo)
return;
card = cinfo->card;
b1_reset(card->port);
b1_reset(card->port);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
}
/* ------------------------------------------------------------- */
static char *b1isa_procinfo(struct capi_ctr *ctrl);
static int b1isa_probe(struct pci_dev *pdev)
{
avmctrl_info *cinfo;
avmcard *card;
int retval;
card = b1_alloc_card(1);
if (!card) {
printk(KERN_WARNING "b1isa: no memory.\n");
retval = -ENOMEM;
goto err;
}
cinfo = card->ctrlinfo;
card->port = pci_resource_start(pdev, 0);
card->irq = pdev->irq;
card->cardtype = avm_b1isa;
sprintf(card->name, "b1isa-%x", card->port);
if (card->port != 0x150 && card->port != 0x250
&& card->port != 0x300 && card->port != 0x340) {
printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port);
retval = -EINVAL;
goto err_free;
}
if (b1_irq_table[card->irq & 0xf] == 0) {
printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
retval = -EINVAL;
goto err_free;
}
if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n",
card->port, card->port + AVMB1_PORTLEN);
retval = -EBUSY;
goto err_free;
}
retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
if (retval) {
printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
goto err_release_region;
}
b1_reset(card->port);
if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n",
card->port, retval);
retval = -ENODEV;
goto err_free_irq;
}
b1_reset(card->port);
b1_getrevision(card);
cinfo->capi_ctrl.owner = THIS_MODULE;
cinfo->capi_ctrl.driver_name = "b1isa";
cinfo->capi_ctrl.driverdata = cinfo;
cinfo->capi_ctrl.register_appl = b1_register_appl;
cinfo->capi_ctrl.release_appl = b1_release_appl;
cinfo->capi_ctrl.send_message = b1_send_message;
cinfo->capi_ctrl.load_firmware = b1_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
cinfo->capi_ctrl.procinfo = b1isa_procinfo;
cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "b1isa: attach controller failed.\n");
goto err_free_irq;
}
printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n",
card->port, card->irq, card->revision);
pci_set_drvdata(pdev, cinfo);
return 0;
err_free_irq:
free_irq(card->irq, card);
err_release_region:
release_region(card->port, AVMB1_PORTLEN);
err_free:
b1_free_card(card);
err:
return retval;
}
static char *b1isa_procinfo(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
if (!cinfo)
return "";
sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
cinfo->cardname[0] ? cinfo->cardname : "-",
cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
cinfo->card ? cinfo->card->port : 0x0,
cinfo->card ? cinfo->card->irq : 0,
cinfo->card ? cinfo->card->revision : 0
);
return cinfo->infobuf;
}
/* ------------------------------------------------------------- */
#define MAX_CARDS 4
static struct pci_dev isa_dev[MAX_CARDS];
static int io[MAX_CARDS];
static int irq[MAX_CARDS];
module_param_hw_array(io, int, ioport, NULL, 0);
module_param_hw_array(irq, int, irq, NULL, 0);
MODULE_PARM_DESC(io, "I/O base address(es)");
MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
static int b1isa_add_card(struct capi_driver *driver, capicardparams *data)
{
int i;
for (i = 0; i < MAX_CARDS; i++) {
if (isa_dev[i].resource[0].start)
continue;
isa_dev[i].resource[0].start = data->port;
isa_dev[i].irq = data->irq;
if (b1isa_probe(&isa_dev[i]) == 0)
return 0;
}
return -ENODEV;
}
static struct capi_driver capi_driver_b1isa = {
.name = "b1isa",
.revision = "1.0",
.add_card = b1isa_add_card,
};
static int __init b1isa_init(void)
{
char *p;
char rev[32];
int i;
if ((p = strchr(revision, ':')) != NULL && p[1]) {
strlcpy(rev, p + 2, 32);
if ((p = strchr(rev, '$')) != NULL && p > rev)
*(p - 1) = 0;
} else
strcpy(rev, "1.0");
for (i = 0; i < MAX_CARDS; i++) {
if (!io[i])
break;
isa_dev[i].resource[0].start = io[i];
isa_dev[i].irq = irq[i];
if (b1isa_probe(&isa_dev[i]) != 0)
return -ENODEV;
}
strlcpy(capi_driver_b1isa.revision, rev, 32);
register_capi_driver(&capi_driver_b1isa);
printk(KERN_INFO "b1isa: revision %s\n", rev);
return 0;
}
static void __exit b1isa_exit(void)
{
int i;
for (i = 0; i < MAX_CARDS; i++) {
if (isa_dev[i].resource[0].start)
b1isa_remove(&isa_dev[i]);
}
unregister_capi_driver(&capi_driver_b1isa);
}
module_init(b1isa_init);
module_exit(b1isa_exit);