2004-01-30 05:08:21

by Adam Belay

[permalink] [raw]
Subject: [PATCH] PnP Updates for 2.6.2-rc2

Hi Andrew,

In reply to this message I will be posting PnP fixes against 2.6.2-rc2, and I would
appreciate if you would add them to your -mm tree. If you choose to include them
in -mm, could you please remove the following patches first:

pnp-fix-2.patch
pnp-fix-3.patch
8250_pnp-cleanup.patch
alsa-pnp-fix.patch

Many of these patches have been updated since thier initial inclusion. Just to be
safe, I think it would be best to start with a clean tree. I apologize if I have
overlooked any other patches.

Also, I decided to drop the isapnp fix and will be looking into a more complete fix
shortly. I'll have an update for it out soon.

This set of changes includes full support for the module_device_tables, various
fixes, and updated kconfig comments.

Thanks,
Adam


2004-01-30 05:13:21

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

Some PnPBIOSes do not follow the specifications with regard to disabling
devices. This patch preserves the tag bits, while zeroing the resource
settings. Previously we would zero the entire buffer. It has been tested and
appears to correct the issue while remaining compatible with unbroken PnPBIOSes.

--- a/drivers/pnp/pnpbios/core.c 2004-01-23 15:19:25.000000000 +0000
+++ b/drivers/pnp/pnpbios/core.c 2004-01-23 20:00:45.000000000 +0000
@@ -264,19 +264,49 @@
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)

2004-01-30 05:16:15

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch updates file2alias.c to support pnp ids. It is from Takashi Iwai
<[email protected]>.

--- a/scripts/file2alias.c 2004-01-09 06:59:33.000000000 +0000
+++ b/scripts/file2alias.c 2004-01-29 20:34:35.000000000 +0000
@@ -176,6 +176,29 @@
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 @@
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 */

2004-01-30 05:15:51

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

Recently many PnPBIOS bugs have been triggered by static resource information
requests. This patch makes an effort to further avoid making them.

diff -urN a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c 2004-01-09 06:59:06.000000000 +0000
+++ b/drivers/pnp/pnpbios/core.c 2004-01-17 21:45:05.000000000 +0000
@@ -251,7 +251,7 @@
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);

2004-01-30 05:10:21

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

The serial driver currently fails to unregister its pnp driver upon module
unload. This patch corrects the problem by calling pnp_unregister_driver and
implementing a proper remove function.

--- a/drivers/serial/8250_pnp.c 2004-01-28 22:35:02.000000000 +0000
+++ b/drivers/serial/8250_pnp.c 2004-01-28 22:33:40.000000000 +0000
@@ -418,7 +418,9 @@

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 = {
@@ -435,7 +437,7 @@

static void __exit serial8250_pnp_exit(void)
{
- /* FIXME */
+ pnp_unregister_driver(&serial_pnp_driver);
}

module_init(serial8250_pnp_init);

2004-01-30 05:13:09

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch reorganizes resource flags to ensure that manual resource settings
are properly recognized. This fix is necessary for many ALSA drivers. It also
prevents comparisons between unset resource structures. The bug was discovered
by Rene Herman <[email protected]>, who also wrote an initial version of
this patch. I made further improvements to ensure that the pnp subsystem was
compatible with this initial change.

diff -urN a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c 2004-01-09 06:59:43.000000000 +0000
+++ b/drivers/pnp/isapnp/core.c 2004-01-17 21:46:00.000000000 +0000
@@ -1039,17 +1039,17 @@

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);
diff -urN a/drivers/pnp/manager.c b/drivers/pnp/manager.c
--- a/drivers/pnp/manager.c 2004-01-09 07:00:04.000000000 +0000
+++ b/drivers/pnp/manager.c 2004-01-17 21:45:05.000000000 +0000
@@ -223,25 +223,25 @@
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 @@
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 @@
{
if (resource == NULL)
return;
- resource->flags &= ~IORESOURCE_AUTO;
+ resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
resource->start = start;
resource->end = start + size - 1;
}
diff -urN a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
--- a/drivers/pnp/pnpbios/rsparser.c 2004-01-09 06:59:26.000000000 +0000
+++ b/drivers/pnp/pnpbios/rsparser.c 2004-01-17 21:45:05.000000000 +0000
@@ -49,7 +49,7 @@
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 @@
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 @@
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 @@
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) {
diff -urN a/drivers/pnp/resource.c b/drivers/pnp/resource.c
--- a/drivers/pnp/resource.c 2004-01-09 06:59:44.000000000 +0000
+++ b/drivers/pnp/resource.c 2004-01-17 21:45:05.000000000 +0000
@@ -241,6 +241,9 @@
(*(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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
diff -urN a/include/linux/pnp.h b/include/linux/pnp.h
--- a/include/linux/pnp.h 2004-01-09 07:00:12.000000000 +0000
+++ b/include/linux/pnp.h 2004-01-17 21:46:00.000000000 +0000
@@ -33,7 +33,9 @@
#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 +47,9 @@
#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 +60,15 @@

#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)

2004-01-30 05:18:43

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch updates the matching code to ensure that all requested devices are
present on the card, even if they are in use. It is necessary for some ALSA
drivers to work properly because early vendors would have different sets of
devices on the same card ids. It is from Takashi Iwai <[email protected]>.

--- a/drivers/pnp/card.c 2004-01-09 07:00:03.000000000 +0000
+++ b/drivers/pnp/card.c 2004-01-29 22:06:22.000000000 +0000
@@ -26,8 +26,25 @@
{
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;

2004-01-30 05:21:49

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch cleans up the kconfig options for the pnp subsystem. It updates the
comments and makes pnpbios proc support an optional feature.

diff -urN a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
--- a/drivers/pnp/Kconfig 2003-10-25 18:43:39.000000000 +0000
+++ b/drivers/pnp/Kconfig 2003-11-03 22:01:26.000000000 +0000
@@ -30,33 +30,9 @@
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>.
+source "drivers/pnp/isapnp/Kconfig"

- 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).
-
- 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

diff -urN a/drivers/pnp/isapnp/Kconfig b/drivers/pnp/isapnp/Kconfig
--- a/drivers/pnp/isapnp/Kconfig 1970-01-01 00:00:00.000000000 +0000
+++ b/drivers/pnp/isapnp/Kconfig 2003-11-03 22:01:54.000000000 +0000
@@ -0,0 +1,11 @@
+#
+# 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.
diff -urN a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig
--- a/drivers/pnp/pnpbios/Kconfig 1970-01-01 00:00:00.000000000 +0000
+++ b/drivers/pnp/pnpbios/Kconfig 2003-11-03 22:55:41.000000000 +0000
@@ -0,0 +1,41 @@
+#
+# 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.
+
diff -urN a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
--- a/drivers/pnp/pnpbios/Makefile 2003-10-25 18:44:35.000000000 +0000
+++ b/drivers/pnp/pnpbios/Makefile 2003-11-03 22:10:53.000000000 +0000
@@ -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)
diff -urN a/drivers/pnp/pnpbios/pnpbios.h b/drivers/pnp/pnpbios/pnpbios.h
--- a/drivers/pnp/pnpbios/pnpbios.h 2003-10-25 18:43:17.000000000 +0000
+++ b/drivers/pnp/pnpbios/pnpbios.h 2003-11-03 22:11:38.000000000 +0000
@@ -36,7 +36,7 @@
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 @@
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 */

2004-01-30 05:18:41

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch moves the PnP ID declarations to mod_devicetable.h like most of the
other buses. It is from Takashi Iwai <[email protected]>.

--- a/include/linux/mod_devicetable.h 2004-01-09 07:00:05.000000000 +0000
+++ b/include/linux/mod_devicetable.h 2004-01-28 22:50:13.000000000 +0000
@@ -148,4 +148,21 @@
#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 */
--- a/include/linux/pnp.h 2004-01-23 15:19:25.000000000 +0000
+++ b/include/linux/pnp.h 2004-01-28 22:48:36.000000000 +0000
@@ -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;
@@ -287,19 +286,6 @@
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;

2004-01-30 05:21:52

by Adam Belay

[permalink] [raw]
Subject: Re: [PATCH] PnP Updates for 2.6.2-rc2

This patch adds some aditional information to sysfs for pnp cards. It should be
useful for userland tools.

--- a/drivers/pnp/card.c 2004-01-29 23:08:49.000000000 +0000
+++ b/drivers/pnp/card.c 2004-01-29 23:03:23.000000000 +0000
@@ -139,6 +139,39 @@
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
@@ -158,6 +191,7 @@
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);