Commit de6d71e9 authored by Adam Belay's avatar Adam Belay

Merge http://linux.bkbits.net/linux-2.5

into neo.rr.com:/home/ambx1/linux/bk/linus-2.5
parents 7a650c81 bc2c9a76
......@@ -31,33 +31,9 @@ config PNP_DEBUG
comment "Protocols"
depends on PNP
config ISAPNP
bool "ISA Plug and Play support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL
help
Say Y here if you would like support for ISA Plug and Play devices.
Some information is in <file:Documentation/isapnp.txt>.
If unsure, say Y.
config PNPBIOS
bool "Plug and Play BIOS support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL
---help---
Linux uses the PNPBIOS as defined in "Plug and Play BIOS
Specification Version 1.0A May 5, 1994" to autodetect built-in
mainboard resources (e.g. parallel port resources).
source "drivers/pnp/isapnp/Kconfig"
Some features (e.g. event notification, docking station information,
ISAPNP services) are not used.
Note: ACPI is expected to supersede PNPBIOS some day, currently it
co-exists nicely.
See latest pcmcia-cs (stand-alone package) for a nice "lspnp" tools,
or have a look at /proc/bus/pnp.
If unsure, say Y.
source "drivers/pnp/pnpbios/Kconfig"
endmenu
......@@ -26,8 +26,25 @@ static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv
{
const struct pnp_card_device_id * drv_id = drv->id_table;
while (*drv_id->id){
if (compare_pnp_id(card->id,drv_id->id))
return drv_id;
if (compare_pnp_id(card->id,drv_id->id)) {
int i = 0;
for (;;) {
int found;
struct pnp_dev *dev;
if (i == PNP_MAX_DEVICES || ! *drv_id->devs[i].id)
return drv_id;
found = 0;
card_for_each_dev(card, dev) {
if (compare_pnp_id(dev->id, drv_id->devs[i].id)) {
found = 1;
break;
}
}
if (! found)
break;
i++;
}
}
drv_id++;
}
return NULL;
......@@ -122,6 +139,39 @@ static void pnp_release_card(struct device *dmdev)
kfree(card);
}
static ssize_t pnp_show_card_name(struct device *dmdev, char *buf)
{
char *str = buf;
struct pnp_card *card = to_pnp_card(dmdev);
str += sprintf(str,"%s\n", card->name);
return (str - buf);
}
static DEVICE_ATTR(name,S_IRUGO,pnp_show_card_name,NULL);
static ssize_t pnp_show_card_ids(struct device *dmdev, char *buf)
{
char *str = buf;
struct pnp_card *card = to_pnp_card(dmdev);
struct pnp_id * pos = card->id;
while (pos) {
str += sprintf(str,"%s\n", pos->id);
pos = pos->next;
}
return (str - buf);
}
static DEVICE_ATTR(card_id,S_IRUGO,pnp_show_card_ids,NULL);
static int pnp_interface_attach_card(struct pnp_card *card)
{
device_create_file(&card->dev,&dev_attr_name);
device_create_file(&card->dev,&dev_attr_card_id);
return 0;
}
/**
* pnp_add_card - adds a PnP card to the PnP Layer
* @card: pointer to the card to add
......@@ -141,6 +191,7 @@ int pnp_add_card(struct pnp_card * card)
error = device_register(&card->dev);
if (error == 0) {
pnp_interface_attach_card(card);
spin_lock(&pnp_lock);
list_add_tail(&card->global_list, &pnp_cards);
list_add_tail(&card->protocol_list, &card->protocol->cards);
......
#
# ISA Plug and Play configuration
#
config ISAPNP
bool "ISA Plug and Play support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL
help
Say Y here if you would like support for ISA Plug and Play devices.
Some information is in <file:Documentation/isapnp.txt>.
If unsure, say Y.
......@@ -1039,17 +1039,17 @@ static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_resource_table *
isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1;
for (tmp = 0; tmp < PNP_MAX_PORT && res->port_resource[tmp].flags & IORESOURCE_IO; tmp++)
for (tmp = 0; tmp < PNP_MAX_PORT && (res->port_resource[tmp].flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; tmp++)
isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), res->port_resource[tmp].start);
for (tmp = 0; tmp < PNP_MAX_IRQ && res->irq_resource[tmp].flags & IORESOURCE_IRQ; tmp++) {
for (tmp = 0; tmp < PNP_MAX_IRQ && (res->irq_resource[tmp].flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; tmp++) {
int irq = res->irq_resource[tmp].start;
if (irq == 2)
irq = 9;
isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
}
for (tmp = 0; tmp < PNP_MAX_DMA && res->dma_resource[tmp].flags & IORESOURCE_DMA; tmp++)
for (tmp = 0; tmp < PNP_MAX_DMA && (res->dma_resource[tmp].flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA; tmp++)
isapnp_write_byte(ISAPNP_CFG_DMA+tmp, res->dma_resource[tmp].start);
for (tmp = 0; tmp < PNP_MAX_MEM && res->mem_resource[tmp].flags & IORESOURCE_MEM; tmp++)
for (tmp = 0; tmp < PNP_MAX_MEM && (res->mem_resource[tmp].flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM; tmp++)
isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (res->mem_resource[tmp].start >> 8) & 0xffff);
/* FIXME: We aren't handling 32bit mems properly here */
isapnp_activate(dev->number);
......
......@@ -223,25 +223,25 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
table->irq_resource[idx].name = NULL;
table->irq_resource[idx].start = -1;
table->irq_resource[idx].end = -1;
table->irq_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
table->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
table->dma_resource[idx].name = NULL;
table->dma_resource[idx].start = -1;
table->dma_resource[idx].end = -1;
table->dma_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
table->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
table->port_resource[idx].name = NULL;
table->port_resource[idx].start = 0;
table->port_resource[idx].end = 0;
table->port_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
table->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
table->mem_resource[idx].name = NULL;
table->mem_resource[idx].start = 0;
table->mem_resource[idx].end = 0;
table->mem_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
table->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
}
......@@ -258,28 +258,28 @@ static void pnp_clean_resource_table(struct pnp_resource_table * res)
continue;
res->irq_resource[idx].start = -1;
res->irq_resource[idx].end = -1;
res->irq_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
res->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
continue;
res->dma_resource[idx].start = -1;
res->dma_resource[idx].end = -1;
res->dma_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
res->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
continue;
res->port_resource[idx].start = 0;
res->port_resource[idx].end = 0;
res->port_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
res->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
continue;
res->mem_resource[idx].start = 0;
res->mem_resource[idx].end = 0;
res->mem_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
res->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
}
......@@ -550,7 +550,7 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
{
if (resource == NULL)
return;
resource->flags &= ~IORESOURCE_AUTO;
resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
resource->start = start;
resource->end = start + size - 1;
}
......
#
# Plug and Play BIOS configuration
#
config PNPBIOS
bool "Plug and Play BIOS support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL
---help---
Linux uses the PNPBIOS as defined in "Plug and Play BIOS
Specification Version 1.0A May 5, 1994" to autodetect built-in
mainboard resources (e.g. parallel port resources).
Some features (e.g. event notification, docking station information,
ISAPNP services) are not currently implemented.
If you would like the kernel to detect and allocate resources to
your mainboard devices (on some systems they are disabled by the
BIOS) say Y here. Also the PNPBIOS can help prevent resource
conflicts between mainboard devices and other bus devices.
Note: ACPI is expected to supersede PNPBIOS some day, currently it
co-exists nicely. If you have a non-ISA system that supports ACPI,
you probably don't need PNPBIOS support.
config PNPBIOS_PROC_FS
bool "Plug and Play BIOS /proc interface"
depends on PNPBIOS && PROC_FS
---help---
If you say Y here and to "/proc file system support", you will be
able to directly access the PNPBIOS. This includes resource
allocation, ESCD, and other PNPBIOS services. Using this
interface is potentially dangerous because the PNPBIOS driver will
not be notified of any resource changes made by writting directly.
Also some buggy systems will fault when accessing certain features
in the PNPBIOS /proc interface (e.g. "boot" configs).
See the latest pcmcia-cs (stand-alone package) for a nice set of
PNPBIOS /proc interface tools (lspnp and setpnp).
Unless you are debugging or have other specific reasons, it is
recommended that you say N here.
......@@ -2,6 +2,6 @@
# Makefile for the kernel PNPBIOS driver.
#
pnpbios-proc-$(CONFIG_PROC_FS) = proc.o
pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
......@@ -251,7 +251,7 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -1;
if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_STATIC, node))
if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node))
return -ENODEV;
if(pnpbios_write_resources_to_node(res, node)<0) {
kfree(node);
......@@ -264,19 +264,49 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
return ret;
}
static void pnpbios_zero_data_stream(struct pnp_bios_node * node)
{
unsigned char * p = (char *)node->data;
unsigned char * end = (char *)(node->data + node->size);
unsigned int len;
int i;
while ((char *)p < (char *)end) {
if(p[0] & 0x80) { /* large tag */
len = (p[2] << 8) | p[1];
p += 3;
} else {
if (((p[0]>>3) & 0x0f) == 0x0f)
return;
len = p[0] & 0x07;
p += 1;
}
for (i = 0; i < len; i++)
p[i] = 0;
p += len;
}
printk(KERN_ERR "PnPBIOS: Resource structure did not contain an end tag.\n");
}
static int pnpbios_disable_resources(struct pnp_dev *dev)
{
struct pnp_bios_node * node;
u8 nodenum = dev->number;
int ret;
/* just in case */
if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
return -EPERM;
/* the value of this will be zero */
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -ENOMEM;
if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
kfree(node);
return -ENODEV;
}
pnpbios_zero_data_stream(node);
ret = pnp_bios_set_dev_node(dev->number, (char)PNPMODE_DYNAMIC, node);
kfree(node);
if (ret > 0)
......
......@@ -36,7 +36,7 @@ extern void pnpid32_to_pnpid(u32 id, char *str);
extern void pnpbios_print_status(const char * module, u16 status);
extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PNPBIOS_PROC_FS
extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
extern int pnpbios_proc_init (void);
extern void pnpbios_proc_exit (void);
......@@ -44,4 +44,4 @@ extern void pnpbios_proc_exit (void);
static inline int pnpbios_interface_attach_device(struct pnp_bios_node * node) { return 0; }
static inline int pnpbios_proc_init (void) { return 0; }
static inline void pnpbios_proc_exit (void) { ; }
#endif /* CONFIG_PROC */
#endif /* CONFIG_PNPBIOS_PROC_FS */
......@@ -49,7 +49,7 @@ static void
pnpbios_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
{
int i = 0;
while ((res->irq_resource[i].flags & IORESOURCE_IRQ) && i < PNP_MAX_IRQ) i++;
while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_IRQ) i++;
if (i < PNP_MAX_IRQ) {
res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
if (irq == -1) {
......@@ -65,7 +65,7 @@ static void
pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
{
int i = 0;
while ((res->dma_resource[i].flags & IORESOURCE_DMA) && i < PNP_MAX_DMA) i++;
while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_DMA) i++;
if (i < PNP_MAX_DMA) {
res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
if (dma == -1) {
......@@ -81,7 +81,7 @@ static void
pnpbios_parse_allocated_ioresource(struct pnp_resource_table * res, int io, int len)
{
int i = 0;
while ((res->port_resource[i].flags & IORESOURCE_IO) && i < PNP_MAX_PORT) i++;
while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_PORT) i++;
if (i < PNP_MAX_PORT) {
res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
if (len <= 0 || (io + len -1) >= 0x10003) {
......@@ -97,7 +97,7 @@ static void
pnpbios_parse_allocated_memresource(struct pnp_resource_table * res, int mem, int len)
{
int i = 0;
while ((res->mem_resource[i].flags & IORESOURCE_MEM) && i < PNP_MAX_MEM) i++;
while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_MEM) i++;
if (i < PNP_MAX_MEM) {
res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag
if (len <= 0) {
......
......@@ -241,6 +241,9 @@ void pnp_free_option(struct pnp_option *option)
(*(enda) >= *(startb) && *(enda) <= *(endb)) || \
(*(starta) < *(startb) && *(enda) > *(endb)))
#define cannot_compare(flags) \
((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
int pnp_check_port(struct pnp_dev * dev, int idx)
{
int tmp;
......@@ -250,7 +253,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
end = &dev->res.port_resource[idx].end;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.port_resource[idx].flags & IORESOURCE_UNSET)
if (cannot_compare(dev->res.port_resource[idx].flags))
return 1;
/* check if the resource is already in use, skip if the
......@@ -284,7 +287,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
continue;
for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
if (pnp_port_flags(dev, tmp) & IORESOURCE_DISABLED)
if (cannot_compare(tdev->res.port_resource[tmp].flags))
continue;
tport = &tdev->res.port_resource[tmp].start;
tend = &tdev->res.port_resource[tmp].end;
......@@ -306,7 +309,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
end = &dev->res.mem_resource[idx].end;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.mem_resource[idx].flags & IORESOURCE_UNSET)
if (cannot_compare(dev->res.mem_resource[idx].flags))
return 1;
/* check if the resource is already in use, skip if the
......@@ -340,7 +343,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
continue;
for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
if (pnp_mem_flags(dev, tmp) & IORESOURCE_DISABLED)
if (cannot_compare(tdev->res.mem_resource[tmp].flags))
continue;
taddr = &tdev->res.mem_resource[tmp].start;
tend = &tdev->res.mem_resource[tmp].end;
......@@ -365,7 +368,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx)
unsigned long * irq = &dev->res.irq_resource[idx].start;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.irq_resource[idx].flags & IORESOURCE_UNSET)
if (cannot_compare(dev->res.irq_resource[idx].flags))
return 1;
/* check if the resource is valid */
......@@ -411,7 +414,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx)
continue;
for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
if (pnp_irq_flags(dev, tmp) & IORESOURCE_DISABLED)
if (cannot_compare(tdev->res.irq_resource[tmp].flags))
continue;
if ((tdev->res.irq_resource[tmp].start == *irq))
return 0;
......@@ -429,7 +432,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
unsigned long * dma = &dev->res.dma_resource[idx].start;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.dma_resource[idx].flags & IORESOURCE_UNSET)
if (cannot_compare(dev->res.dma_resource[idx].flags))
return 1;
/* check if the resource is valid */
......@@ -464,7 +467,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
continue;
for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
if (pnp_dma_flags(dev, tmp) & IORESOURCE_DISABLED)
if (cannot_compare(tdev->res.dma_resource[tmp].flags))
continue;
if ((tdev->res.dma_resource[tmp].start == *dma))
return 0;
......
......@@ -420,7 +420,9 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
static void serial_pnp_remove(struct pnp_dev * dev)
{
return;
int line = (int)pnp_get_drvdata(dev);
if (line)
unregister_serial(line - 1);
}
static struct pnp_driver serial_pnp_driver = {
......@@ -437,7 +439,7 @@ static int __init serial8250_pnp_init(void)
static void __exit serial8250_pnp_exit(void)
{
/* FIXME */
pnp_unregister_driver(&serial_pnp_driver);
}
module_init(serial8250_pnp_init);
......
......@@ -148,4 +148,21 @@ struct ccw_device_id {
#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08
#define PNP_ID_LEN 8
#define PNP_MAX_DEVICES 8
struct pnp_device_id {
__u8 id[PNP_ID_LEN];
kernel_ulong_t driver_data;
};
struct pnp_card_device_id {
__u8 id[PNP_ID_LEN];
kernel_ulong_t driver_data;
struct {
__u8 id[PNP_ID_LEN];
} devs[PNP_MAX_DEVICES];
};
#endif /* LINUX_MOD_DEVICETABLE_H */
......@@ -12,13 +12,12 @@
#include <linux/device.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/mod_devicetable.h>
#define PNP_MAX_PORT 8
#define PNP_MAX_MEM 4
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
#define PNP_MAX_DEVICES 8
#define PNP_ID_LEN 8
#define PNP_NAME_LEN 50
struct pnp_protocol;
......@@ -33,7 +32,9 @@ struct pnp_dev;
#define pnp_port_start(dev,bar) ((dev)->res.port_resource[(bar)].start)
#define pnp_port_end(dev,bar) ((dev)->res.port_resource[(bar)].end)
#define pnp_port_flags(dev,bar) ((dev)->res.port_resource[(bar)].flags)
#define pnp_port_valid(dev,bar) (pnp_port_flags((dev),(bar)) & IORESOURCE_IO)
#define pnp_port_valid(dev,bar) \
((pnp_port_flags((dev),(bar)) & (IORESOURCE_IO | IORESOURCE_UNSET)) \
== IORESOURCE_IO)
#define pnp_port_len(dev,bar) \
((pnp_port_start((dev),(bar)) == 0 && \
pnp_port_end((dev),(bar)) == \
......@@ -45,7 +46,9 @@ struct pnp_dev;
#define pnp_mem_start(dev,bar) ((dev)->res.mem_resource[(bar)].start)
#define pnp_mem_end(dev,bar) ((dev)->res.mem_resource[(bar)].end)
#define pnp_mem_flags(dev,bar) ((dev)->res.mem_resource[(bar)].flags)
#define pnp_mem_valid(dev,bar) (pnp_mem_flags((dev),(bar)) & IORESOURCE_MEM)
#define pnp_mem_valid(dev,bar) \
((pnp_mem_flags((dev),(bar)) & (IORESOURCE_MEM | IORESOURCE_UNSET)) \
== IORESOURCE_MEM)
#define pnp_mem_len(dev,bar) \
((pnp_mem_start((dev),(bar)) == 0 && \
pnp_mem_end((dev),(bar)) == \
......@@ -56,11 +59,15 @@ struct pnp_dev;
#define pnp_irq(dev,bar) ((dev)->res.irq_resource[(bar)].start)
#define pnp_irq_flags(dev,bar) ((dev)->res.irq_resource[(bar)].flags)
#define pnp_irq_valid(dev,bar) (pnp_irq_flags((dev),(bar)) & IORESOURCE_IRQ)
#define pnp_irq_valid(dev,bar) \
((pnp_irq_flags((dev),(bar)) & (IORESOURCE_IRQ | IORESOURCE_UNSET)) \
== IORESOURCE_IRQ)
#define pnp_dma(dev,bar) ((dev)->res.dma_resource[(bar)].start)
#define pnp_dma_flags(dev,bar) ((dev)->res.dma_resource[(bar)].flags)
#define pnp_dma_valid(dev,bar) (pnp_dma_flags((dev),(bar)) & IORESOURCE_DMA)
#define pnp_dma_valid(dev,bar) \
((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \
== IORESOURCE_DMA)
#define PNP_PORT_FLAG_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1)
......@@ -279,19 +286,6 @@ struct pnp_id {
struct pnp_id * next;
};
struct pnp_device_id {
char id[PNP_ID_LEN];
unsigned long driver_data; /* data private to the driver */
};
struct pnp_card_device_id {
char id[PNP_ID_LEN];
unsigned long driver_data; /* data private to the driver */
struct {
char id[PNP_ID_LEN];
} devs[PNP_MAX_DEVICES]; /* logical devices */
};
struct pnp_driver {
char * name;
const struct pnp_device_id *id_table;
......
......@@ -176,6 +176,29 @@ static int do_ccw_entry(const char *filename,
return 1;
}
/* looks like: "pnp:dD" */
static int do_pnp_entry(const char *filename,
struct pnp_device_id *id, char *alias)
{
sprintf(alias, "pnp:d%s", id->id);
return 1;
}
/* looks like: "pnp:cCdD..." */
static int do_pnp_card_entry(const char *filename,
struct pnp_card_device_id *id, char *alias)
{
int i;
sprintf(alias, "pnp:c%s", id->id);
for (i = 0; i < PNP_MAX_DEVICES; i++) {
if (! *id->devs[i].id)
break;
sprintf(alias + strlen(alias), "d%s", id->devs[i].id);
}
return 1;
}
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
......@@ -242,6 +265,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
else if (sym_is(symname, "__mod_ccw_device_table"))
do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
do_ccw_entry, mod);
else if (sym_is(symname, "__mod_pnp_device_table"))
do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
do_pnp_entry, mod);
else if (sym_is(symname, "__mod_pnp_card_device_table"))
do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
do_pnp_card_entry, mod);
}
/* Now add out buffered information to the generated C source */
......
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