Merge branch 'pnp' into release
This commit is contained in:
Коммит
008238b54a
|
@ -1,12 +1,78 @@
|
|||
extern spinlock_t pnp_lock;
|
||||
void *pnp_alloc(long size);
|
||||
|
||||
int pnp_register_protocol(struct pnp_protocol *protocol);
|
||||
void pnp_unregister_protocol(struct pnp_protocol *protocol);
|
||||
|
||||
#define PNP_EISA_ID_MASK 0x7fffffff
|
||||
void pnp_eisa_id_to_string(u32 id, char *str);
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid);
|
||||
struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
|
||||
|
||||
int pnp_add_device(struct pnp_dev *dev);
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
|
||||
int pnp_interface_attach_device(struct pnp_dev *dev);
|
||||
|
||||
int pnp_add_card(struct pnp_card *card);
|
||||
struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id);
|
||||
void pnp_remove_card(struct pnp_card *card);
|
||||
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
|
||||
void pnp_remove_card_device(struct pnp_dev *dev);
|
||||
|
||||
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
|
||||
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
|
||||
int priority);
|
||||
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_irq *data);
|
||||
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_dma *data);
|
||||
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_port *data);
|
||||
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_mem *data);
|
||||
void pnp_init_resources(struct pnp_dev *dev);
|
||||
|
||||
void pnp_fixup_device(struct pnp_dev *dev);
|
||||
void pnp_free_option(struct pnp_option *option);
|
||||
int __pnp_add_device(struct pnp_dev *dev);
|
||||
void __pnp_remove_device(struct pnp_dev *dev);
|
||||
|
||||
int pnp_check_port(struct pnp_dev * dev, int idx);
|
||||
int pnp_check_mem(struct pnp_dev * dev, int idx);
|
||||
int pnp_check_irq(struct pnp_dev * dev, int idx);
|
||||
int pnp_check_dma(struct pnp_dev * dev, int idx);
|
||||
int pnp_check_port(struct pnp_dev *dev, struct resource *res);
|
||||
int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
|
||||
int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
|
||||
int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
|
||||
|
||||
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
|
||||
|
||||
void pnp_init_resource(struct resource *res);
|
||||
|
||||
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
|
||||
unsigned int type, unsigned int num);
|
||||
|
||||
#define PNP_MAX_PORT 40
|
||||
#define PNP_MAX_MEM 24
|
||||
#define PNP_MAX_IRQ 2
|
||||
#define PNP_MAX_DMA 2
|
||||
|
||||
struct pnp_resource {
|
||||
struct resource res;
|
||||
unsigned int index; /* ISAPNP config register index */
|
||||
};
|
||||
|
||||
struct pnp_resource_table {
|
||||
struct pnp_resource port[PNP_MAX_PORT];
|
||||
struct pnp_resource mem[PNP_MAX_MEM];
|
||||
struct pnp_resource dma[PNP_MAX_DMA];
|
||||
struct pnp_resource irq[PNP_MAX_IRQ];
|
||||
};
|
||||
|
||||
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
|
||||
int flags);
|
||||
struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
|
||||
int flags);
|
||||
struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
|
||||
resource_size_t start,
|
||||
resource_size_t end, int flags);
|
||||
struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
|
||||
resource_size_t start,
|
||||
resource_size_t end, int flags);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
#include "base.h"
|
||||
|
@ -100,19 +101,33 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
|
|||
* @id: pointer to a pnp_id structure
|
||||
* @card: pointer to the desired card
|
||||
*/
|
||||
int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card)
|
||||
struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id)
|
||||
{
|
||||
struct pnp_id *ptr;
|
||||
struct pnp_id *dev_id, *ptr;
|
||||
|
||||
id->next = NULL;
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!dev_id)
|
||||
return NULL;
|
||||
|
||||
dev_id->id[0] = id[0];
|
||||
dev_id->id[1] = id[1];
|
||||
dev_id->id[2] = id[2];
|
||||
dev_id->id[3] = tolower(id[3]);
|
||||
dev_id->id[4] = tolower(id[4]);
|
||||
dev_id->id[5] = tolower(id[5]);
|
||||
dev_id->id[6] = tolower(id[6]);
|
||||
dev_id->id[7] = '\0';
|
||||
|
||||
dev_id->next = NULL;
|
||||
ptr = card->id;
|
||||
while (ptr && ptr->next)
|
||||
ptr = ptr->next;
|
||||
if (ptr)
|
||||
ptr->next = id;
|
||||
ptr->next = dev_id;
|
||||
else
|
||||
card->id = id;
|
||||
return 0;
|
||||
card->id = dev_id;
|
||||
|
||||
return dev_id;
|
||||
}
|
||||
|
||||
static void pnp_free_card_ids(struct pnp_card *card)
|
||||
|
@ -136,6 +151,31 @@ static void pnp_release_card(struct device *dmdev)
|
|||
kfree(card);
|
||||
}
|
||||
|
||||
struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnpid)
|
||||
{
|
||||
struct pnp_card *card;
|
||||
struct pnp_id *dev_id;
|
||||
|
||||
card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL);
|
||||
if (!card)
|
||||
return NULL;
|
||||
|
||||
card->protocol = protocol;
|
||||
card->number = id;
|
||||
|
||||
card->dev.parent = &card->protocol->dev;
|
||||
sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
|
||||
card->number);
|
||||
|
||||
dev_id = pnp_add_card_id(card, pnpid);
|
||||
if (!dev_id) {
|
||||
kfree(card);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
static ssize_t pnp_show_card_name(struct device *dmdev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -191,9 +231,6 @@ int pnp_add_card(struct pnp_card *card)
|
|||
int error;
|
||||
struct list_head *pos, *temp;
|
||||
|
||||
sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
|
||||
card->number);
|
||||
card->dev.parent = &card->protocol->dev;
|
||||
card->dev.bus = NULL;
|
||||
card->dev.release = &pnp_release_card;
|
||||
error = device_register(&card->dev);
|
||||
|
|
|
@ -106,18 +106,53 @@ static void pnp_release_device(struct device *dmdev)
|
|||
pnp_free_option(dev->independent);
|
||||
pnp_free_option(dev->dependent);
|
||||
pnp_free_ids(dev);
|
||||
kfree(dev->res);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid)
|
||||
{
|
||||
struct pnp_dev *dev;
|
||||
struct pnp_id *dev_id;
|
||||
|
||||
dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
|
||||
if (!dev->res) {
|
||||
kfree(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev->protocol = protocol;
|
||||
dev->number = id;
|
||||
dev->dma_mask = DMA_24BIT_MASK;
|
||||
|
||||
dev->dev.parent = &dev->protocol->dev;
|
||||
dev->dev.bus = &pnp_bus_type;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dev.coherent_dma_mask = dev->dma_mask;
|
||||
dev->dev.release = &pnp_release_device;
|
||||
|
||||
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
|
||||
dev->number);
|
||||
|
||||
dev_id = pnp_add_id(dev, pnpid);
|
||||
if (!dev_id) {
|
||||
kfree(dev->res);
|
||||
kfree(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
int __pnp_add_device(struct pnp_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pnp_fixup_device(dev);
|
||||
dev->dev.bus = &pnp_bus_type;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
|
||||
dev->dev.release = &pnp_release_device;
|
||||
dev->status = PNP_READY;
|
||||
spin_lock(&pnp_lock);
|
||||
list_add_tail(&dev->global_list, &pnp_global);
|
||||
|
@ -145,9 +180,6 @@ int pnp_add_device(struct pnp_dev *dev)
|
|||
if (dev->card)
|
||||
return -EINVAL;
|
||||
|
||||
dev->dev.parent = &dev->protocol->dev;
|
||||
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
|
||||
dev->number);
|
||||
ret = __pnp_add_device(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -226,22 +226,36 @@ void pnp_unregister_driver(struct pnp_driver *drv)
|
|||
|
||||
/**
|
||||
* pnp_add_id - adds an EISA id to the specified device
|
||||
* @id: pointer to a pnp_id structure
|
||||
* @dev: pointer to the desired device
|
||||
* @id: pointer to an EISA id string
|
||||
*/
|
||||
int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
|
||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id)
|
||||
{
|
||||
struct pnp_id *ptr;
|
||||
struct pnp_id *dev_id, *ptr;
|
||||
|
||||
id->next = NULL;
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!dev_id)
|
||||
return NULL;
|
||||
|
||||
dev_id->id[0] = id[0];
|
||||
dev_id->id[1] = id[1];
|
||||
dev_id->id[2] = id[2];
|
||||
dev_id->id[3] = tolower(id[3]);
|
||||
dev_id->id[4] = tolower(id[4]);
|
||||
dev_id->id[5] = tolower(id[5]);
|
||||
dev_id->id[6] = tolower(id[6]);
|
||||
dev_id->id[7] = '\0';
|
||||
|
||||
dev_id->next = NULL;
|
||||
ptr = dev->id;
|
||||
while (ptr && ptr->next)
|
||||
ptr = ptr->next;
|
||||
if (ptr)
|
||||
ptr->next = id;
|
||||
ptr->next = dev_id;
|
||||
else
|
||||
dev->id = id;
|
||||
return 0;
|
||||
dev->id = dev_id;
|
||||
|
||||
return dev_id;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pnp_register_driver);
|
||||
|
|
|
@ -248,6 +248,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
|
|||
char *buf)
|
||||
{
|
||||
struct pnp_dev *dev = to_pnp_dev(dmdev);
|
||||
struct resource *res;
|
||||
int i, ret;
|
||||
pnp_info_buffer_t *buffer;
|
||||
|
||||
|
@ -267,50 +268,46 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
|
|||
else
|
||||
pnp_printf(buffer, "disabled\n");
|
||||
|
||||
for (i = 0; i < PNP_MAX_PORT; i++) {
|
||||
if (pnp_port_valid(dev, i)) {
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
|
||||
if (pnp_resource_valid(res)) {
|
||||
pnp_printf(buffer, "io");
|
||||
if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED)
|
||||
if (res->flags & IORESOURCE_DISABLED)
|
||||
pnp_printf(buffer, " disabled\n");
|
||||
else
|
||||
pnp_printf(buffer, " 0x%llx-0x%llx\n",
|
||||
(unsigned long long)
|
||||
pnp_port_start(dev, i),
|
||||
(unsigned long long)pnp_port_end(dev,
|
||||
i));
|
||||
(unsigned long long) res->start,
|
||||
(unsigned long long) res->end);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_MEM; i++) {
|
||||
if (pnp_mem_valid(dev, i)) {
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
|
||||
if (pnp_resource_valid(res)) {
|
||||
pnp_printf(buffer, "mem");
|
||||
if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED)
|
||||
if (res->flags & IORESOURCE_DISABLED)
|
||||
pnp_printf(buffer, " disabled\n");
|
||||
else
|
||||
pnp_printf(buffer, " 0x%llx-0x%llx\n",
|
||||
(unsigned long long)
|
||||
pnp_mem_start(dev, i),
|
||||
(unsigned long long)pnp_mem_end(dev,
|
||||
i));
|
||||
(unsigned long long) res->start,
|
||||
(unsigned long long) res->end);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_IRQ; i++) {
|
||||
if (pnp_irq_valid(dev, i)) {
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
|
||||
if (pnp_resource_valid(res)) {
|
||||
pnp_printf(buffer, "irq");
|
||||
if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED)
|
||||
if (res->flags & IORESOURCE_DISABLED)
|
||||
pnp_printf(buffer, " disabled\n");
|
||||
else
|
||||
pnp_printf(buffer, " %lld\n",
|
||||
(unsigned long long)pnp_irq(dev, i));
|
||||
(unsigned long long) res->start);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_DMA; i++) {
|
||||
if (pnp_dma_valid(dev, i)) {
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
|
||||
if (pnp_resource_valid(res)) {
|
||||
pnp_printf(buffer, "dma");
|
||||
if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED)
|
||||
if (res->flags & IORESOURCE_DISABLED)
|
||||
pnp_printf(buffer, " disabled\n");
|
||||
else
|
||||
pnp_printf(buffer, " %lld\n",
|
||||
(unsigned long long)pnp_dma(dev, i));
|
||||
(unsigned long long) res->start);
|
||||
}
|
||||
}
|
||||
ret = (buffer->curr - buf);
|
||||
|
@ -323,8 +320,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
|
|||
const char *ubuf, size_t count)
|
||||
{
|
||||
struct pnp_dev *dev = to_pnp_dev(dmdev);
|
||||
struct pnp_resource *pnp_res;
|
||||
char *buf = (void *)ubuf;
|
||||
int retval = 0;
|
||||
resource_size_t start, end;
|
||||
|
||||
if (dev->status & PNP_ATTACHED) {
|
||||
retval = -EBUSY;
|
||||
|
@ -351,20 +350,20 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
|
|||
if (!strnicmp(buf, "auto", 4)) {
|
||||
if (dev->active)
|
||||
goto done;
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
retval = pnp_auto_config_dev(dev);
|
||||
goto done;
|
||||
}
|
||||
if (!strnicmp(buf, "clear", 5)) {
|
||||
if (dev->active)
|
||||
goto done;
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
goto done;
|
||||
}
|
||||
if (!strnicmp(buf, "get", 3)) {
|
||||
mutex_lock(&pnp_res_mutex);
|
||||
if (pnp_can_read(dev))
|
||||
dev->protocol->get(dev, &dev->res);
|
||||
dev->protocol->get(dev);
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
goto done;
|
||||
}
|
||||
|
@ -373,7 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
|
|||
if (dev->active)
|
||||
goto done;
|
||||
buf += 3;
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
mutex_lock(&pnp_res_mutex);
|
||||
while (1) {
|
||||
while (isspace(*buf))
|
||||
|
@ -382,76 +381,60 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
|
|||
buf += 2;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.port_resource[nport].start =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
start = simple_strtoul(buf, &buf, 0);
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
if (*buf == '-') {
|
||||
buf += 1;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.port_resource[nport].end =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
end = simple_strtoul(buf, &buf, 0);
|
||||
} else
|
||||
dev->res.port_resource[nport].end =
|
||||
dev->res.port_resource[nport].start;
|
||||
dev->res.port_resource[nport].flags =
|
||||
IORESOURCE_IO;
|
||||
nport++;
|
||||
if (nport >= PNP_MAX_PORT)
|
||||
break;
|
||||
end = start;
|
||||
pnp_res = pnp_add_io_resource(dev, start, end,
|
||||
0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = nport++;
|
||||
continue;
|
||||
}
|
||||
if (!strnicmp(buf, "mem", 3)) {
|
||||
buf += 3;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.mem_resource[nmem].start =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
start = simple_strtoul(buf, &buf, 0);
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
if (*buf == '-') {
|
||||
buf += 1;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.mem_resource[nmem].end =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
end = simple_strtoul(buf, &buf, 0);
|
||||
} else
|
||||
dev->res.mem_resource[nmem].end =
|
||||
dev->res.mem_resource[nmem].start;
|
||||
dev->res.mem_resource[nmem].flags =
|
||||
IORESOURCE_MEM;
|
||||
nmem++;
|
||||
if (nmem >= PNP_MAX_MEM)
|
||||
break;
|
||||
end = start;
|
||||
pnp_res = pnp_add_mem_resource(dev, start, end,
|
||||
0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = nmem++;
|
||||
continue;
|
||||
}
|
||||
if (!strnicmp(buf, "irq", 3)) {
|
||||
buf += 3;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.irq_resource[nirq].start =
|
||||
dev->res.irq_resource[nirq].end =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
dev->res.irq_resource[nirq].flags =
|
||||
IORESOURCE_IRQ;
|
||||
nirq++;
|
||||
if (nirq >= PNP_MAX_IRQ)
|
||||
break;
|
||||
start = simple_strtoul(buf, &buf, 0);
|
||||
pnp_res = pnp_add_irq_resource(dev, start, 0);
|
||||
if (pnp_res)
|
||||
nirq++;
|
||||
continue;
|
||||
}
|
||||
if (!strnicmp(buf, "dma", 3)) {
|
||||
buf += 3;
|
||||
while (isspace(*buf))
|
||||
++buf;
|
||||
dev->res.dma_resource[ndma].start =
|
||||
dev->res.dma_resource[ndma].end =
|
||||
simple_strtoul(buf, &buf, 0);
|
||||
dev->res.dma_resource[ndma].flags =
|
||||
IORESOURCE_DMA;
|
||||
ndma++;
|
||||
if (ndma >= PNP_MAX_DMA)
|
||||
break;
|
||||
start = simple_strtoul(buf, &buf, 0);
|
||||
pnp_res = pnp_add_dma_resource(dev, start, 0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = ndma++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -5,3 +5,7 @@
|
|||
isapnp-proc-$(CONFIG_PROC_FS) = proc.o
|
||||
|
||||
obj-y := core.o compat.o $(isapnp-proc-y)
|
||||
|
||||
ifeq ($(CONFIG_PNP_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "../base.h"
|
||||
|
||||
#if 0
|
||||
#define ISAPNP_REGION_OK
|
||||
#endif
|
||||
|
@ -88,6 +90,14 @@ MODULE_LICENSE("GPL");
|
|||
#define _LTAG_MEM32RANGE 0x85
|
||||
#define _LTAG_FIXEDMEM32RANGE 0x86
|
||||
|
||||
/* Logical device control and configuration registers */
|
||||
|
||||
#define ISAPNP_CFG_ACTIVATE 0x30 /* byte */
|
||||
#define ISAPNP_CFG_MEM 0x40 /* 4 * dword */
|
||||
#define ISAPNP_CFG_PORT 0x60 /* 8 * word */
|
||||
#define ISAPNP_CFG_IRQ 0x70 /* 2 * word */
|
||||
#define ISAPNP_CFG_DMA 0x74 /* 2 * byte */
|
||||
|
||||
/*
|
||||
* Sizes of ISAPNP logical device configuration register sets.
|
||||
* See PNP-ISA-v1.0a.pdf, Appendix A.
|
||||
|
@ -387,28 +397,6 @@ static void __init isapnp_skip_bytes(int count)
|
|||
isapnp_peek(NULL, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse EISA id.
|
||||
*/
|
||||
static void isapnp_parse_id(struct pnp_dev *dev, unsigned short vendor,
|
||||
unsigned short device)
|
||||
{
|
||||
struct pnp_id *id;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!id)
|
||||
return;
|
||||
sprintf(id->id, "%c%c%c%x%x%x%x",
|
||||
'A' + ((vendor >> 2) & 0x3f) - 1,
|
||||
'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
|
||||
'A' + ((vendor >> 8) & 0x1f) - 1,
|
||||
(device >> 4) & 0x0f,
|
||||
device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
|
||||
pnp_add_id(id, dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse logical device tag.
|
||||
*/
|
||||
|
@ -417,30 +405,31 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
|
|||
{
|
||||
unsigned char tmp[6];
|
||||
struct pnp_dev *dev;
|
||||
u32 eisa_id;
|
||||
char id[8];
|
||||
|
||||
isapnp_peek(tmp, size);
|
||||
dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
|
||||
eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
|
||||
pnp_eisa_id_to_string(eisa_id, id);
|
||||
|
||||
dev = pnp_alloc_dev(&isapnp_protocol, number, id);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
dev->number = number;
|
||||
isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
|
||||
dev->regs = tmp[4];
|
||||
|
||||
dev->card = card;
|
||||
if (size > 5)
|
||||
dev->regs |= tmp[5] << 8;
|
||||
dev->protocol = &isapnp_protocol;
|
||||
dev->capabilities |= PNP_CONFIGURABLE;
|
||||
dev->capabilities |= PNP_READ;
|
||||
dev->capabilities |= PNP_WRITE;
|
||||
dev->capabilities |= PNP_DISABLE;
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add IRQ resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_irq_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[3];
|
||||
|
@ -457,13 +446,14 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
|
|||
irq->flags = tmp[2];
|
||||
else
|
||||
irq->flags = IORESOURCE_IRQ_HIGHEDGE;
|
||||
pnp_register_irq_resource(option, irq);
|
||||
pnp_register_irq_resource(dev, option, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add DMA resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_dma_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[2];
|
||||
|
@ -475,13 +465,14 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
|
|||
return;
|
||||
dma->map = tmp[0];
|
||||
dma->flags = tmp[1];
|
||||
pnp_register_dma_resource(option, dma);
|
||||
pnp_register_dma_resource(dev, option, dma);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add port resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_port_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[7];
|
||||
|
@ -496,13 +487,14 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
|
|||
port->align = tmp[5];
|
||||
port->size = tmp[6];
|
||||
port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
|
||||
pnp_register_port_resource(option, port);
|
||||
pnp_register_port_resource(dev, option, port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add fixed port resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[3];
|
||||
|
@ -516,13 +508,14 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
|
|||
port->size = tmp[2];
|
||||
port->align = 0;
|
||||
port->flags = PNP_PORT_FLAG_FIXED;
|
||||
pnp_register_port_resource(option, port);
|
||||
pnp_register_port_resource(dev, option, port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add memory resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_mem_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[9];
|
||||
|
@ -537,13 +530,14 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
|
|||
mem->align = (tmp[6] << 8) | tmp[5];
|
||||
mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
|
||||
mem->flags = tmp[0];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add 32-bit memory resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[17];
|
||||
|
@ -560,13 +554,14 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
|
|||
mem->size =
|
||||
(tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
|
||||
mem->flags = tmp[0];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add 32-bit fixed memory resource to resources list.
|
||||
*/
|
||||
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
|
||||
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
|
||||
struct pnp_option *option,
|
||||
int size)
|
||||
{
|
||||
unsigned char tmp[9];
|
||||
|
@ -581,7 +576,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
|
|||
mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
|
||||
mem->align = 0;
|
||||
mem->flags = tmp[0];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -613,6 +608,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
unsigned char type, tmp[17];
|
||||
struct pnp_option *option;
|
||||
struct pnp_dev *dev;
|
||||
u32 eisa_id;
|
||||
char id[8];
|
||||
|
||||
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
|
||||
return 1;
|
||||
|
@ -652,8 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
case _STAG_COMPATDEVID:
|
||||
if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
|
||||
isapnp_peek(tmp, 4);
|
||||
isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0],
|
||||
(tmp[3] << 8) | tmp[2]);
|
||||
eisa_id = tmp[0] | tmp[1] << 8 |
|
||||
tmp[2] << 16 | tmp[3] << 24;
|
||||
pnp_eisa_id_to_string(eisa_id, id);
|
||||
pnp_add_id(dev, id);
|
||||
compat++;
|
||||
size = 0;
|
||||
}
|
||||
|
@ -661,13 +660,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
case _STAG_IRQ:
|
||||
if (size < 2 || size > 3)
|
||||
goto __skip;
|
||||
isapnp_parse_irq_resource(option, size);
|
||||
isapnp_parse_irq_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _STAG_DMA:
|
||||
if (size != 2)
|
||||
goto __skip;
|
||||
isapnp_parse_dma_resource(option, size);
|
||||
isapnp_parse_dma_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _STAG_STARTDEP:
|
||||
|
@ -687,17 +686,18 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
if (size != 0)
|
||||
goto __skip;
|
||||
priority = 0;
|
||||
dev_dbg(&dev->dev, "end dependent options\n");
|
||||
break;
|
||||
case _STAG_IOPORT:
|
||||
if (size != 7)
|
||||
goto __skip;
|
||||
isapnp_parse_port_resource(option, size);
|
||||
isapnp_parse_port_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _STAG_FIXEDIO:
|
||||
if (size != 3)
|
||||
goto __skip;
|
||||
isapnp_parse_fixed_port_resource(option, size);
|
||||
isapnp_parse_fixed_port_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _STAG_VENDOR:
|
||||
|
@ -705,7 +705,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
case _LTAG_MEMRANGE:
|
||||
if (size != 9)
|
||||
goto __skip;
|
||||
isapnp_parse_mem_resource(option, size);
|
||||
isapnp_parse_mem_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _LTAG_ANSISTR:
|
||||
|
@ -720,13 +720,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
case _LTAG_MEM32RANGE:
|
||||
if (size != 17)
|
||||
goto __skip;
|
||||
isapnp_parse_mem32_resource(option, size);
|
||||
isapnp_parse_mem32_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _LTAG_FIXEDMEM32RANGE:
|
||||
if (size != 9)
|
||||
goto __skip;
|
||||
isapnp_parse_fixed_mem32_resource(option, size);
|
||||
isapnp_parse_fixed_mem32_resource(dev, option, size);
|
||||
size = 0;
|
||||
break;
|
||||
case _STAG_END:
|
||||
|
@ -734,9 +734,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
|
|||
isapnp_skip_bytes(size);
|
||||
return 1;
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n",
|
||||
type, dev->number, card->number);
|
||||
dev_err(&dev->dev, "unknown tag %#x (card %i), "
|
||||
"ignored\n", type, card->number);
|
||||
}
|
||||
__skip:
|
||||
if (size > 0)
|
||||
|
@ -789,9 +788,8 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card)
|
|||
isapnp_skip_bytes(size);
|
||||
return;
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n",
|
||||
type, card->number);
|
||||
dev_err(&card->dev, "unknown tag %#x, ignored\n",
|
||||
type);
|
||||
}
|
||||
__skip:
|
||||
if (size > 0)
|
||||
|
@ -821,25 +819,6 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
|
|||
return checksum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse EISA id for ISA PnP card.
|
||||
*/
|
||||
static void isapnp_parse_card_id(struct pnp_card *card, unsigned short vendor,
|
||||
unsigned short device)
|
||||
{
|
||||
struct pnp_id *id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
|
||||
if (!id)
|
||||
return;
|
||||
sprintf(id->id, "%c%c%c%x%x%x%x",
|
||||
'A' + ((vendor >> 2) & 0x3f) - 1,
|
||||
'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
|
||||
'A' + ((vendor >> 8) & 0x1f) - 1,
|
||||
(device >> 4) & 0x0f,
|
||||
device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
|
||||
pnp_add_card_id(id, card);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build device list for all present ISA PnP devices.
|
||||
*/
|
||||
|
@ -848,6 +827,8 @@ static int __init isapnp_build_device_list(void)
|
|||
int csn;
|
||||
unsigned char header[9], checksum;
|
||||
struct pnp_card *card;
|
||||
u32 eisa_id;
|
||||
char id[8];
|
||||
|
||||
isapnp_wait();
|
||||
isapnp_key();
|
||||
|
@ -855,32 +836,30 @@ static int __init isapnp_build_device_list(void)
|
|||
isapnp_wake(csn);
|
||||
isapnp_peek(header, 9);
|
||||
checksum = isapnp_checksum(header);
|
||||
eisa_id = header[0] | header[1] << 8 |
|
||||
header[2] << 16 | header[3] << 24;
|
||||
pnp_eisa_id_to_string(eisa_id, id);
|
||||
card = pnp_alloc_card(&isapnp_protocol, csn, id);
|
||||
if (!card)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
printk(KERN_DEBUG
|
||||
dev_info(&card->dev,
|
||||
"vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
header[0], header[1], header[2], header[3], header[4],
|
||||
header[5], header[6], header[7], header[8]);
|
||||
printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
|
||||
dev_info(&card->dev, "checksum = %#x\n", checksum);
|
||||
#endif
|
||||
if ((card =
|
||||
kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
|
||||
continue;
|
||||
|
||||
card->number = csn;
|
||||
INIT_LIST_HEAD(&card->devices);
|
||||
isapnp_parse_card_id(card, (header[1] << 8) | header[0],
|
||||
(header[3] << 8) | header[2]);
|
||||
card->serial =
|
||||
(header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
|
||||
header[4];
|
||||
isapnp_checksum_value = 0x00;
|
||||
isapnp_parse_resource_map(card);
|
||||
if (isapnp_checksum_value != 0x00)
|
||||
printk(KERN_ERR
|
||||
"isapnp: checksum for device %i is not valid (0x%x)\n",
|
||||
csn, isapnp_checksum_value);
|
||||
dev_err(&card->dev, "invalid checksum %#x\n",
|
||||
isapnp_checksum_value);
|
||||
card->checksum = isapnp_checksum_value;
|
||||
card->protocol = &isapnp_protocol;
|
||||
|
||||
pnp_add_card(card);
|
||||
}
|
||||
|
@ -947,100 +926,117 @@ EXPORT_SYMBOL(isapnp_cfg_begin);
|
|||
EXPORT_SYMBOL(isapnp_cfg_end);
|
||||
EXPORT_SYMBOL(isapnp_write_byte);
|
||||
|
||||
static int isapnp_read_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
static int isapnp_get_resources(struct pnp_dev *dev)
|
||||
{
|
||||
int tmp, ret;
|
||||
struct pnp_resource *pnp_res;
|
||||
int i, ret;
|
||||
|
||||
dev_dbg(&dev->dev, "get resources\n");
|
||||
pnp_init_resources(dev);
|
||||
isapnp_cfg_begin(dev->card->number, dev->number);
|
||||
dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
|
||||
if (dev->active) {
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
|
||||
ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
|
||||
if (!ret)
|
||||
continue;
|
||||
res->port_resource[tmp].start = ret;
|
||||
res->port_resource[tmp].flags = IORESOURCE_IO;
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
|
||||
ret =
|
||||
isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8;
|
||||
if (!ret)
|
||||
continue;
|
||||
res->mem_resource[tmp].start = ret;
|
||||
res->mem_resource[tmp].flags = IORESOURCE_MEM;
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
|
||||
ret =
|
||||
(isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >>
|
||||
8);
|
||||
if (!ret)
|
||||
continue;
|
||||
res->irq_resource[tmp].start =
|
||||
res->irq_resource[tmp].end = ret;
|
||||
res->irq_resource[tmp].flags = IORESOURCE_IRQ;
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
|
||||
ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
|
||||
if (ret == 4)
|
||||
continue;
|
||||
res->dma_resource[tmp].start =
|
||||
res->dma_resource[tmp].end = ret;
|
||||
res->dma_resource[tmp].flags = IORESOURCE_DMA;
|
||||
if (!dev->active)
|
||||
goto __end;
|
||||
|
||||
for (i = 0; i < ISAPNP_MAX_PORT; i++) {
|
||||
ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
|
||||
if (ret) {
|
||||
pnp_res = pnp_add_io_resource(dev, ret, ret, 0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ISAPNP_MAX_MEM; i++) {
|
||||
ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
|
||||
if (ret) {
|
||||
pnp_res = pnp_add_mem_resource(dev, ret, ret, 0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
|
||||
ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
|
||||
if (ret) {
|
||||
pnp_res = pnp_add_irq_resource(dev, ret, 0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ISAPNP_MAX_DMA; i++) {
|
||||
ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
|
||||
if (ret != 4) {
|
||||
pnp_res = pnp_add_dma_resource(dev, ret, 0);
|
||||
if (pnp_res)
|
||||
pnp_res->index = i;
|
||||
}
|
||||
}
|
||||
|
||||
__end:
|
||||
isapnp_cfg_end();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isapnp_get_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
static int isapnp_set_resources(struct pnp_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pnp_init_resource_table(res);
|
||||
isapnp_cfg_begin(dev->card->number, dev->number);
|
||||
ret = isapnp_read_resources(dev, res);
|
||||
isapnp_cfg_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isapnp_set_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
{
|
||||
int tmp;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
int tmp, index;
|
||||
|
||||
dev_dbg(&dev->dev, "set resources\n");
|
||||
isapnp_cfg_begin(dev->card->number, dev->number);
|
||||
dev->active = 1;
|
||||
for (tmp = 0;
|
||||
tmp < ISAPNP_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 < ISAPNP_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 < ISAPNP_MAX_PORT; tmp++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp);
|
||||
if (!pnp_res)
|
||||
continue;
|
||||
res = &pnp_res->res;
|
||||
if (pnp_resource_valid(res)) {
|
||||
index = pnp_res->index;
|
||||
dev_dbg(&dev->dev, " set io %d to %#llx\n",
|
||||
index, (unsigned long long) res->start);
|
||||
isapnp_write_word(ISAPNP_CFG_PORT + (index << 1),
|
||||
res->start);
|
||||
}
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp);
|
||||
if (!pnp_res)
|
||||
continue;
|
||||
res = &pnp_res->res;
|
||||
if (pnp_resource_valid(res)) {
|
||||
int irq = res->start;
|
||||
if (irq == 2)
|
||||
irq = 9;
|
||||
index = pnp_res->index;
|
||||
dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq);
|
||||
isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
|
||||
}
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp);
|
||||
if (!pnp_res)
|
||||
continue;
|
||||
res = &pnp_res->res;
|
||||
if (pnp_resource_valid(res)) {
|
||||
index = pnp_res->index;
|
||||
dev_dbg(&dev->dev, " set dma %d to %lld\n",
|
||||
index, (unsigned long long) res->start);
|
||||
isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start);
|
||||
}
|
||||
}
|
||||
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp);
|
||||
if (!pnp_res)
|
||||
continue;
|
||||
res = &pnp_res->res;
|
||||
if (pnp_resource_valid(res)) {
|
||||
index = pnp_res->index;
|
||||
dev_dbg(&dev->dev, " set mem %d to %#llx\n",
|
||||
index, (unsigned long long) res->start);
|
||||
isapnp_write_word(ISAPNP_CFG_MEM + (index << 3),
|
||||
(res->start >> 8) & 0xffff);
|
||||
}
|
||||
}
|
||||
for (tmp = 0;
|
||||
tmp < ISAPNP_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 < ISAPNP_MAX_MEM
|
||||
&& (res->mem_resource[tmp].
|
||||
flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
|
||||
tmp++)
|
||||
isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
|
||||
(res->mem_resource[tmp].start >> 8) & 0xffff);
|
||||
/* FIXME: We aren't handling 32bit mems properly here */
|
||||
isapnp_activate(dev->number);
|
||||
isapnp_cfg_end();
|
||||
|
@ -1138,13 +1134,13 @@ static int __init isapnp_init(void)
|
|||
protocol_for_each_card(&isapnp_protocol, card) {
|
||||
cards++;
|
||||
if (isapnp_verbose) {
|
||||
printk(KERN_INFO "isapnp: Card '%s'\n",
|
||||
card->name[0] ? card->name : "Unknown");
|
||||
dev_info(&card->dev, "card '%s'\n",
|
||||
card->name[0] ? card->name : "unknown");
|
||||
if (isapnp_verbose < 2)
|
||||
continue;
|
||||
card_for_each_dev(card, dev) {
|
||||
printk(KERN_INFO "isapnp: Device '%s'\n",
|
||||
dev->name[0] ? dev->name : "Unknown");
|
||||
dev_info(&card->dev, "device '%s'\n",
|
||||
dev->name[0] ? dev->name : "unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,100 +19,118 @@ DEFINE_MUTEX(pnp_res_mutex);
|
|||
|
||||
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
|
||||
{
|
||||
resource_size_t *start, *end;
|
||||
unsigned long *flags;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
|
||||
if (idx >= PNP_MAX_PORT) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
|
||||
if (!pnp_res) {
|
||||
dev_err(&dev->dev, "too many I/O port resources\n");
|
||||
/* pretend we were successful so at least the manager won't try again */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO))
|
||||
return 1;
|
||||
res = &pnp_res->res;
|
||||
|
||||
start = &dev->res.port_resource[idx].start;
|
||||
end = &dev->res.port_resource[idx].end;
|
||||
flags = &dev->res.port_resource[idx].flags;
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(res->flags & IORESOURCE_AUTO)) {
|
||||
dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
|
||||
"flags %#lx\n", idx, (unsigned long long) res->start,
|
||||
(unsigned long long) res->end, res->flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set the initial values */
|
||||
*flags |= rule->flags | IORESOURCE_IO;
|
||||
*flags &= ~IORESOURCE_UNSET;
|
||||
pnp_res->index = idx;
|
||||
res->flags |= rule->flags | IORESOURCE_IO;
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
|
||||
if (!rule->size) {
|
||||
*flags |= IORESOURCE_DISABLED;
|
||||
res->flags |= IORESOURCE_DISABLED;
|
||||
dev_dbg(&dev->dev, " io %d disabled\n", idx);
|
||||
return 1; /* skip disabled resource requests */
|
||||
}
|
||||
|
||||
*start = rule->min;
|
||||
*end = *start + rule->size - 1;
|
||||
res->start = rule->min;
|
||||
res->end = res->start + rule->size - 1;
|
||||
|
||||
/* run through until pnp_check_port is happy */
|
||||
while (!pnp_check_port(dev, idx)) {
|
||||
*start += rule->align;
|
||||
*end = *start + rule->size - 1;
|
||||
if (*start > rule->max || !rule->align)
|
||||
while (!pnp_check_port(dev, res)) {
|
||||
res->start += rule->align;
|
||||
res->end = res->start + rule->size - 1;
|
||||
if (res->start > rule->max || !rule->align) {
|
||||
dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
|
||||
{
|
||||
resource_size_t *start, *end;
|
||||
unsigned long *flags;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
|
||||
if (idx >= PNP_MAX_MEM) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
|
||||
if (!pnp_res) {
|
||||
dev_err(&dev->dev, "too many memory resources\n");
|
||||
/* pretend we were successful so at least the manager won't try again */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO))
|
||||
return 1;
|
||||
res = &pnp_res->res;
|
||||
|
||||
start = &dev->res.mem_resource[idx].start;
|
||||
end = &dev->res.mem_resource[idx].end;
|
||||
flags = &dev->res.mem_resource[idx].flags;
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(res->flags & IORESOURCE_AUTO)) {
|
||||
dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
|
||||
"flags %#lx\n", idx, (unsigned long long) res->start,
|
||||
(unsigned long long) res->end, res->flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set the initial values */
|
||||
*flags |= rule->flags | IORESOURCE_MEM;
|
||||
*flags &= ~IORESOURCE_UNSET;
|
||||
pnp_res->index = idx;
|
||||
res->flags |= rule->flags | IORESOURCE_MEM;
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
|
||||
/* convert pnp flags to standard Linux flags */
|
||||
if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
|
||||
*flags |= IORESOURCE_READONLY;
|
||||
res->flags |= IORESOURCE_READONLY;
|
||||
if (rule->flags & IORESOURCE_MEM_CACHEABLE)
|
||||
*flags |= IORESOURCE_CACHEABLE;
|
||||
res->flags |= IORESOURCE_CACHEABLE;
|
||||
if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
|
||||
*flags |= IORESOURCE_RANGELENGTH;
|
||||
res->flags |= IORESOURCE_RANGELENGTH;
|
||||
if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
|
||||
*flags |= IORESOURCE_SHADOWABLE;
|
||||
res->flags |= IORESOURCE_SHADOWABLE;
|
||||
|
||||
if (!rule->size) {
|
||||
*flags |= IORESOURCE_DISABLED;
|
||||
res->flags |= IORESOURCE_DISABLED;
|
||||
dev_dbg(&dev->dev, " mem %d disabled\n", idx);
|
||||
return 1; /* skip disabled resource requests */
|
||||
}
|
||||
|
||||
*start = rule->min;
|
||||
*end = *start + rule->size - 1;
|
||||
res->start = rule->min;
|
||||
res->end = res->start + rule->size - 1;
|
||||
|
||||
/* run through until pnp_check_mem is happy */
|
||||
while (!pnp_check_mem(dev, idx)) {
|
||||
*start += rule->align;
|
||||
*end = *start + rule->size - 1;
|
||||
if (*start > rule->max || !rule->align)
|
||||
while (!pnp_check_mem(dev, res)) {
|
||||
res->start += rule->align;
|
||||
res->end = res->start + rule->size - 1;
|
||||
if (res->start > rule->max || !rule->align) {
|
||||
dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
|
||||
{
|
||||
resource_size_t *start, *end;
|
||||
unsigned long *flags;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
/* IRQ priority: this table is good for i386 */
|
||||
|
@ -120,49 +138,59 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
|
|||
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
|
||||
};
|
||||
|
||||
if (idx >= PNP_MAX_IRQ) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx);
|
||||
if (!pnp_res) {
|
||||
dev_err(&dev->dev, "too many IRQ resources\n");
|
||||
/* pretend we were successful so at least the manager won't try again */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO))
|
||||
return 1;
|
||||
res = &pnp_res->res;
|
||||
|
||||
start = &dev->res.irq_resource[idx].start;
|
||||
end = &dev->res.irq_resource[idx].end;
|
||||
flags = &dev->res.irq_resource[idx].flags;
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(res->flags & IORESOURCE_AUTO)) {
|
||||
dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
|
||||
idx, (int) res->start, res->flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set the initial values */
|
||||
*flags |= rule->flags | IORESOURCE_IRQ;
|
||||
*flags &= ~IORESOURCE_UNSET;
|
||||
pnp_res->index = idx;
|
||||
res->flags |= rule->flags | IORESOURCE_IRQ;
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
|
||||
if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
|
||||
*flags |= IORESOURCE_DISABLED;
|
||||
res->flags |= IORESOURCE_DISABLED;
|
||||
dev_dbg(&dev->dev, " irq %d disabled\n", idx);
|
||||
return 1; /* skip disabled resource requests */
|
||||
}
|
||||
|
||||
/* TBD: need check for >16 IRQ */
|
||||
*start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
|
||||
if (*start < PNP_IRQ_NR) {
|
||||
*end = *start;
|
||||
res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
|
||||
if (res->start < PNP_IRQ_NR) {
|
||||
res->end = res->start;
|
||||
dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
|
||||
(int) res->start);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (test_bit(xtab[i], rule->map)) {
|
||||
*start = *end = xtab[i];
|
||||
if (pnp_check_irq(dev, idx))
|
||||
res->start = res->end = xtab[i];
|
||||
if (pnp_check_irq(dev, res)) {
|
||||
dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
|
||||
(int) res->start);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
|
||||
{
|
||||
resource_size_t *start, *end;
|
||||
unsigned long *flags;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
/* DMA priority: this table is good for i386 */
|
||||
|
@ -170,71 +198,89 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
|
|||
1, 3, 5, 6, 7, 0, 2, 4
|
||||
};
|
||||
|
||||
if (idx >= PNP_MAX_DMA) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx);
|
||||
if (!pnp_res) {
|
||||
dev_err(&dev->dev, "too many DMA resources\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
|
||||
return;
|
||||
res = &pnp_res->res;
|
||||
|
||||
start = &dev->res.dma_resource[idx].start;
|
||||
end = &dev->res.dma_resource[idx].end;
|
||||
flags = &dev->res.dma_resource[idx].flags;
|
||||
/* check if this resource has been manually set, if so skip */
|
||||
if (!(res->flags & IORESOURCE_AUTO)) {
|
||||
dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
|
||||
idx, (int) res->start, res->flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the initial values */
|
||||
*flags |= rule->flags | IORESOURCE_DMA;
|
||||
*flags &= ~IORESOURCE_UNSET;
|
||||
pnp_res->index = idx;
|
||||
res->flags |= rule->flags | IORESOURCE_DMA;
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (rule->map & (1 << xtab[i])) {
|
||||
*start = *end = xtab[i];
|
||||
if (pnp_check_dma(dev, idx))
|
||||
res->start = res->end = xtab[i];
|
||||
if (pnp_check_dma(dev, res)) {
|
||||
dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
|
||||
(int) res->start);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef MAX_DMA_CHANNELS
|
||||
*start = *end = MAX_DMA_CHANNELS;
|
||||
res->start = res->end = MAX_DMA_CHANNELS;
|
||||
#endif
|
||||
*flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
|
||||
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
|
||||
dev_dbg(&dev->dev, " disable dma %d\n", idx);
|
||||
}
|
||||
|
||||
void pnp_init_resource(struct resource *res)
|
||||
{
|
||||
unsigned long type;
|
||||
|
||||
type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
|
||||
IORESOURCE_IRQ | IORESOURCE_DMA);
|
||||
|
||||
res->name = NULL;
|
||||
res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
|
||||
res->start = -1;
|
||||
res->end = -1;
|
||||
} else {
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pnp_init_resources - Resets a resource table to default values.
|
||||
* @table: pointer to the desired resource table
|
||||
*/
|
||||
void pnp_init_resource_table(struct pnp_resource_table *table)
|
||||
void pnp_init_resources(struct pnp_dev *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
|
||||
table->irq_resource[idx].name = NULL;
|
||||
table->irq_resource[idx].start = -1;
|
||||
table->irq_resource[idx].end = -1;
|
||||
table->irq_resource[idx].flags =
|
||||
IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->irq[idx].res;
|
||||
res->flags = IORESOURCE_IRQ;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
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_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->dma[idx].res;
|
||||
res->flags = IORESOURCE_DMA;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
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_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->port[idx].res;
|
||||
res->flags = IORESOURCE_IO;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
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_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->mem[idx].res;
|
||||
res->flags = IORESOURCE_MEM;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,41 +288,38 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
|
|||
* pnp_clean_resources - clears resources that were not manually set
|
||||
* @res: the resources to clean
|
||||
*/
|
||||
static void pnp_clean_resource_table(struct pnp_resource_table *res)
|
||||
static void pnp_clean_resource_table(struct pnp_dev *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
|
||||
if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
|
||||
continue;
|
||||
res->irq_resource[idx].start = -1;
|
||||
res->irq_resource[idx].end = -1;
|
||||
res->irq_resource[idx].flags =
|
||||
IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->irq[idx].res;
|
||||
if (res->flags & IORESOURCE_AUTO) {
|
||||
res->flags = IORESOURCE_IRQ;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
}
|
||||
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_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->dma[idx].res;
|
||||
if (res->flags & IORESOURCE_AUTO) {
|
||||
res->flags = IORESOURCE_DMA;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
}
|
||||
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_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->port[idx].res;
|
||||
if (res->flags & IORESOURCE_AUTO) {
|
||||
res->flags = IORESOURCE_IO;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
}
|
||||
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_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
|
||||
res = &dev->res->mem[idx].res;
|
||||
if (res->flags & IORESOURCE_AUTO) {
|
||||
res->flags = IORESOURCE_MEM;
|
||||
pnp_init_resource(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,9 +341,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
|
|||
if (!pnp_can_configure(dev))
|
||||
return -ENODEV;
|
||||
|
||||
dbg_pnp_show_resources(dev, "before pnp_assign_resources");
|
||||
mutex_lock(&pnp_res_mutex);
|
||||
pnp_clean_resource_table(&dev->res); /* start with a fresh slate */
|
||||
pnp_clean_resource_table(dev);
|
||||
if (dev->independent) {
|
||||
dev_dbg(&dev->dev, "assigning independent options\n");
|
||||
port = dev->independent->port;
|
||||
mem = dev->independent->mem;
|
||||
irq = dev->independent->irq;
|
||||
|
@ -333,6 +378,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
|
|||
if (depnum) {
|
||||
struct pnp_option *dep;
|
||||
int i;
|
||||
|
||||
dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
|
||||
for (i = 1, dep = dev->dependent; i < depnum;
|
||||
i++, dep = dep->next)
|
||||
if (!dep)
|
||||
|
@ -368,67 +415,16 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
|
|||
goto fail;
|
||||
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
dbg_pnp_show_resources(dev, "after pnp_assign_resources");
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
pnp_clean_resource_table(&dev->res);
|
||||
pnp_clean_resource_table(dev);
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
|
||||
* @dev: pointer to the desired device
|
||||
* @res: pointer to the new resource config
|
||||
* @mode: 0 or PNP_CONFIG_FORCE
|
||||
*
|
||||
* This function can be used by drivers that want to manually set thier resources.
|
||||
*/
|
||||
int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
|
||||
int mode)
|
||||
{
|
||||
int i;
|
||||
struct pnp_resource_table *bak;
|
||||
|
||||
if (!pnp_can_configure(dev))
|
||||
return -ENODEV;
|
||||
bak = pnp_alloc(sizeof(struct pnp_resource_table));
|
||||
if (!bak)
|
||||
return -ENOMEM;
|
||||
*bak = dev->res;
|
||||
|
||||
mutex_lock(&pnp_res_mutex);
|
||||
dev->res = *res;
|
||||
if (!(mode & PNP_CONFIG_FORCE)) {
|
||||
for (i = 0; i < PNP_MAX_PORT; i++) {
|
||||
if (!pnp_check_port(dev, i))
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_MEM; i++) {
|
||||
if (!pnp_check_mem(dev, i))
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_IRQ; i++) {
|
||||
if (!pnp_check_irq(dev, i))
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_DMA; i++) {
|
||||
if (!pnp_check_dma(dev, i))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
|
||||
kfree(bak);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dev->res = *bak;
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
kfree(bak);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pnp_auto_config_dev - automatically assigns resources to a device
|
||||
* @dev: pointer to the desired device
|
||||
|
@ -473,7 +469,8 @@ int pnp_start_dev(struct pnp_dev *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->protocol->set(dev, &dev->res) < 0) {
|
||||
dbg_pnp_show_resources(dev, "pnp_start_dev");
|
||||
if (dev->protocol->set(dev) < 0) {
|
||||
dev_err(&dev->dev, "activation failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -549,30 +546,13 @@ int pnp_disable_dev(struct pnp_dev *dev)
|
|||
|
||||
/* release the resources so that other devices can use them */
|
||||
mutex_lock(&pnp_res_mutex);
|
||||
pnp_clean_resource_table(&dev->res);
|
||||
pnp_clean_resource_table(dev);
|
||||
mutex_unlock(&pnp_res_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pnp_resource_change - change one resource
|
||||
* @resource: pointer to resource to be changed
|
||||
* @start: start of region
|
||||
* @size: size of region
|
||||
*/
|
||||
void pnp_resource_change(struct resource *resource, resource_size_t start,
|
||||
resource_size_t size)
|
||||
{
|
||||
resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
|
||||
resource->start = start;
|
||||
resource->end = start + size - 1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pnp_manual_config_dev);
|
||||
EXPORT_SYMBOL(pnp_start_dev);
|
||||
EXPORT_SYMBOL(pnp_stop_dev);
|
||||
EXPORT_SYMBOL(pnp_activate_dev);
|
||||
EXPORT_SYMBOL(pnp_disable_dev);
|
||||
EXPORT_SYMBOL(pnp_resource_change);
|
||||
EXPORT_SYMBOL(pnp_init_resource_table);
|
||||
|
|
|
@ -3,3 +3,7 @@
|
|||
#
|
||||
|
||||
obj-y := core.o rsparser.o
|
||||
|
||||
ifeq ($(CONFIG_PNP_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/actypes.h>
|
||||
|
||||
#include "../base.h"
|
||||
#include "pnpacpi.h"
|
||||
|
||||
static int num = 0;
|
||||
|
@ -72,40 +73,24 @@ static int __init ispnpidacpi(char *id)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void __init pnpidacpi_to_pnpid(char *id, char *str)
|
||||
static int pnpacpi_get_resources(struct pnp_dev *dev)
|
||||
{
|
||||
str[0] = id[0];
|
||||
str[1] = id[1];
|
||||
str[2] = id[2];
|
||||
str[3] = tolower(id[3]);
|
||||
str[4] = tolower(id[4]);
|
||||
str[5] = tolower(id[5]);
|
||||
str[6] = tolower(id[6]);
|
||||
str[7] = '\0';
|
||||
dev_dbg(&dev->dev, "get resources\n");
|
||||
return pnpacpi_parse_allocated_resource(dev);
|
||||
}
|
||||
|
||||
static int pnpacpi_get_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = pnpacpi_parse_allocated_resource((acpi_handle) dev->data,
|
||||
&dev->res);
|
||||
return ACPI_FAILURE(status) ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static int pnpacpi_set_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
static int pnpacpi_set_resources(struct pnp_dev *dev)
|
||||
{
|
||||
acpi_handle handle = dev->data;
|
||||
struct acpi_buffer buffer;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
acpi_status status;
|
||||
|
||||
ret = pnpacpi_build_resource_template(handle, &buffer);
|
||||
dev_dbg(&dev->dev, "set resources\n");
|
||||
ret = pnpacpi_build_resource_template(dev, &buffer);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = pnpacpi_encode_resources(res, &buffer);
|
||||
ret = pnpacpi_encode_resources(dev, &buffer);
|
||||
if (ret) {
|
||||
kfree(buffer.pointer);
|
||||
return ret;
|
||||
|
@ -163,7 +148,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
|||
{
|
||||
acpi_handle temp = NULL;
|
||||
acpi_status status;
|
||||
struct pnp_id *dev_id;
|
||||
struct pnp_dev *dev;
|
||||
|
||||
status = acpi_get_handle(device->handle, "_CRS", &temp);
|
||||
|
@ -171,11 +155,10 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
|||
is_exclusive_device(device))
|
||||
return 0;
|
||||
|
||||
dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
pnp_err("Out of memory");
|
||||
dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->data = device->handle;
|
||||
/* .enabled means the device can decode the resources */
|
||||
dev->active = device->status.enabled;
|
||||
|
@ -191,44 +174,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
|||
if (ACPI_SUCCESS(status))
|
||||
dev->capabilities |= PNP_DISABLE;
|
||||
|
||||
dev->protocol = &pnpacpi_protocol;
|
||||
|
||||
if (strlen(acpi_device_name(device)))
|
||||
strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
|
||||
else
|
||||
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
|
||||
|
||||
dev->number = num;
|
||||
if (dev->active)
|
||||
pnpacpi_parse_allocated_resource(dev);
|
||||
|
||||
/* set the initial values for the PnP device */
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!dev_id)
|
||||
goto err;
|
||||
pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
|
||||
pnp_add_id(dev_id, dev);
|
||||
if (dev->capabilities & PNP_CONFIGURABLE)
|
||||
pnpacpi_parse_resource_option_data(dev);
|
||||
|
||||
if (dev->active) {
|
||||
/* parse allocated resource */
|
||||
status = pnpacpi_parse_allocated_resource(device->handle,
|
||||
&dev->res);
|
||||
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
|
||||
pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s",
|
||||
dev_id->id);
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->capabilities & PNP_CONFIGURABLE) {
|
||||
status = pnpacpi_parse_resource_option_data(device->handle,
|
||||
dev);
|
||||
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
|
||||
pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s",
|
||||
dev_id->id);
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse compatible ids */
|
||||
if (device->flags.compatible_ids) {
|
||||
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
|
||||
int i;
|
||||
|
@ -236,27 +192,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
|||
for (i = 0; i < cid_list->count; i++) {
|
||||
if (!ispnpidacpi(cid_list->id[i].value))
|
||||
continue;
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!dev_id)
|
||||
continue;
|
||||
|
||||
pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
|
||||
pnp_add_id(dev_id, dev);
|
||||
pnp_add_id(dev, cid_list->id[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear out the damaged flags */
|
||||
if (!dev->active)
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
pnp_add_device(dev);
|
||||
num++;
|
||||
|
||||
return AE_OK;
|
||||
err1:
|
||||
kfree(dev_id);
|
||||
err:
|
||||
kfree(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
acpi_status pnpacpi_parse_allocated_resource(acpi_handle, struct pnp_resource_table*);
|
||||
acpi_status pnpacpi_parse_resource_option_data(acpi_handle, struct pnp_dev*);
|
||||
int pnpacpi_encode_resources(struct pnp_resource_table *, struct acpi_buffer *);
|
||||
int pnpacpi_build_resource_template(acpi_handle, struct acpi_buffer*);
|
||||
int pnpacpi_parse_allocated_resource(struct pnp_dev *);
|
||||
int pnpacpi_parse_resource_option_data(struct pnp_dev *);
|
||||
int pnpacpi_encode_resources(struct pnp_dev *, struct acpi_buffer *);
|
||||
int pnpacpi_build_resource_template(struct pnp_dev *, struct acpi_buffer *);
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,3 +5,7 @@
|
|||
pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
|
||||
|
||||
obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
|
||||
|
||||
ifeq ($(CONFIG_PNP_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pnpbios.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/mm.h>
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pnpbios.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/mm.h>
|
||||
|
@ -69,6 +68,7 @@
|
|||
#include <asm/system.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "../base.h"
|
||||
#include "pnpbios.h"
|
||||
|
||||
/*
|
||||
|
@ -203,8 +203,7 @@ static int pnp_dock_thread(void *unused)
|
|||
|
||||
#endif /* CONFIG_HOTPLUG */
|
||||
|
||||
static int pnpbios_get_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
static int pnpbios_get_resources(struct pnp_dev *dev)
|
||||
{
|
||||
u8 nodenum = dev->number;
|
||||
struct pnp_bios_node *node;
|
||||
|
@ -212,6 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
|
|||
if (!pnpbios_is_dynamic(dev))
|
||||
return -EPERM;
|
||||
|
||||
dev_dbg(&dev->dev, "get resources\n");
|
||||
node = kzalloc(node_info.max_node_size, GFP_KERNEL);
|
||||
if (!node)
|
||||
return -1;
|
||||
|
@ -219,14 +219,13 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
|
|||
kfree(node);
|
||||
return -ENODEV;
|
||||
}
|
||||
pnpbios_read_resources_from_node(res, node);
|
||||
pnpbios_read_resources_from_node(dev, node);
|
||||
dev->active = pnp_is_active(dev);
|
||||
kfree(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pnpbios_set_resources(struct pnp_dev *dev,
|
||||
struct pnp_resource_table *res)
|
||||
static int pnpbios_set_resources(struct pnp_dev *dev)
|
||||
{
|
||||
u8 nodenum = dev->number;
|
||||
struct pnp_bios_node *node;
|
||||
|
@ -235,6 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
|
|||
if (!pnpbios_is_dynamic(dev))
|
||||
return -EPERM;
|
||||
|
||||
dev_dbg(&dev->dev, "set resources\n");
|
||||
node = kzalloc(node_info.max_node_size, GFP_KERNEL);
|
||||
if (!node)
|
||||
return -1;
|
||||
|
@ -242,7 +242,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
|
|||
kfree(node);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (pnpbios_write_resources_to_node(res, node) < 0) {
|
||||
if (pnpbios_write_resources_to_node(dev, node) < 0) {
|
||||
kfree(node);
|
||||
return -1;
|
||||
}
|
||||
|
@ -317,7 +317,6 @@ static int __init insert_device(struct pnp_bios_node *node)
|
|||
{
|
||||
struct list_head *pos;
|
||||
struct pnp_dev *dev;
|
||||
struct pnp_id *dev_id;
|
||||
char id[8];
|
||||
|
||||
/* check if the device is already added */
|
||||
|
@ -327,20 +326,11 @@ static int __init insert_device(struct pnp_bios_node *node)
|
|||
return -1;
|
||||
}
|
||||
|
||||
dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
|
||||
pnp_eisa_id_to_string(node->eisa_id & PNP_EISA_ID_MASK, id);
|
||||
dev = pnp_alloc_dev(&pnpbios_protocol, node->handle, id);
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
if (!dev_id) {
|
||||
kfree(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev->number = node->handle;
|
||||
pnpid32_to_pnpid(node->eisa_id, id);
|
||||
memcpy(dev_id->id, id, 7);
|
||||
pnp_add_id(dev_id, dev);
|
||||
pnpbios_parse_data_stream(dev, node);
|
||||
dev->active = pnp_is_active(dev);
|
||||
dev->flags = node->flags;
|
||||
|
@ -353,11 +343,10 @@ static int __init insert_device(struct pnp_bios_node *node)
|
|||
dev->capabilities |= PNP_WRITE;
|
||||
if (dev->flags & PNPBIOS_REMOVABLE)
|
||||
dev->capabilities |= PNP_REMOVABLE;
|
||||
dev->protocol = &pnpbios_protocol;
|
||||
|
||||
/* clear out the damaged flags */
|
||||
if (!dev->active)
|
||||
pnp_init_resource_table(&dev->res);
|
||||
pnp_init_resources(dev);
|
||||
|
||||
pnp_add_device(dev);
|
||||
pnpbios_interface_attach_device(node);
|
||||
|
|
|
@ -2,6 +2,142 @@
|
|||
* pnpbios.h - contains local definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include file for the interface to a PnP BIOS
|
||||
*
|
||||
* Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
|
||||
* PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
|
||||
* Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return codes
|
||||
*/
|
||||
#define PNP_SUCCESS 0x00
|
||||
#define PNP_NOT_SET_STATICALLY 0x7f
|
||||
#define PNP_UNKNOWN_FUNCTION 0x81
|
||||
#define PNP_FUNCTION_NOT_SUPPORTED 0x82
|
||||
#define PNP_INVALID_HANDLE 0x83
|
||||
#define PNP_BAD_PARAMETER 0x84
|
||||
#define PNP_SET_FAILED 0x85
|
||||
#define PNP_EVENTS_NOT_PENDING 0x86
|
||||
#define PNP_SYSTEM_NOT_DOCKED 0x87
|
||||
#define PNP_NO_ISA_PNP_CARDS 0x88
|
||||
#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
|
||||
#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
|
||||
#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
|
||||
#define PNP_BUFFER_TOO_SMALL 0x8c
|
||||
#define PNP_USE_ESCD_SUPPORT 0x8d
|
||||
#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
|
||||
#define PNP_HARDWARE_ERROR 0x8f
|
||||
|
||||
#define ESCD_SUCCESS 0x00
|
||||
#define ESCD_IO_ERROR_READING 0x55
|
||||
#define ESCD_INVALID 0x56
|
||||
#define ESCD_BUFFER_TOO_SMALL 0x59
|
||||
#define ESCD_NVRAM_TOO_SMALL 0x5a
|
||||
#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
|
||||
|
||||
/*
|
||||
* Events that can be received by "get event"
|
||||
*/
|
||||
#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
|
||||
#define PNPEV_DOCK_CHANGED 0x0002
|
||||
#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
|
||||
#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
|
||||
#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
|
||||
/* 0x8000 through 0xfffe are OEM defined */
|
||||
|
||||
/*
|
||||
* Messages that should be sent through "send message"
|
||||
*/
|
||||
#define PNPMSG_OK 0x00
|
||||
#define PNPMSG_ABORT 0x01
|
||||
#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
|
||||
#define PNPMSG_POWER_OFF 0x41
|
||||
#define PNPMSG_PNP_OS_ACTIVE 0x42
|
||||
#define PNPMSG_PNP_OS_INACTIVE 0x43
|
||||
|
||||
/*
|
||||
* Plug and Play BIOS flags
|
||||
*/
|
||||
#define PNPBIOS_NO_DISABLE 0x0001
|
||||
#define PNPBIOS_NO_CONFIG 0x0002
|
||||
#define PNPBIOS_OUTPUT 0x0004
|
||||
#define PNPBIOS_INPUT 0x0008
|
||||
#define PNPBIOS_BOOTABLE 0x0010
|
||||
#define PNPBIOS_DOCK 0x0020
|
||||
#define PNPBIOS_REMOVABLE 0x0040
|
||||
#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
|
||||
#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
|
||||
|
||||
/*
|
||||
* Function Parameters
|
||||
*/
|
||||
#define PNPMODE_STATIC 1
|
||||
#define PNPMODE_DYNAMIC 0
|
||||
|
||||
/* 0x8000 through 0xffff are OEM defined */
|
||||
|
||||
#pragma pack(1)
|
||||
struct pnp_dev_node_info {
|
||||
__u16 no_nodes;
|
||||
__u16 max_node_size;
|
||||
};
|
||||
struct pnp_docking_station_info {
|
||||
__u32 location_id;
|
||||
__u32 serial;
|
||||
__u16 capabilities;
|
||||
};
|
||||
struct pnp_isa_config_struc {
|
||||
__u8 revision;
|
||||
__u8 no_csns;
|
||||
__u16 isa_rd_data_port;
|
||||
__u16 reserved;
|
||||
};
|
||||
struct escd_info_struc {
|
||||
__u16 min_escd_write_size;
|
||||
__u16 escd_size;
|
||||
__u32 nv_storage_base;
|
||||
};
|
||||
struct pnp_bios_node {
|
||||
__u16 size;
|
||||
__u8 handle;
|
||||
__u32 eisa_id;
|
||||
__u8 type_code[3];
|
||||
__u16 flags;
|
||||
__u8 data[0];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
/* non-exported */
|
||||
extern struct pnp_dev_node_info node_info;
|
||||
|
||||
extern int pnp_bios_dev_node_info(struct pnp_dev_node_info *data);
|
||||
extern int pnp_bios_get_dev_node(u8 *nodenum, char config,
|
||||
struct pnp_bios_node *data);
|
||||
extern int pnp_bios_set_dev_node(u8 nodenum, char config,
|
||||
struct pnp_bios_node *data);
|
||||
extern int pnp_bios_get_stat_res(char *info);
|
||||
extern int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data);
|
||||
extern int pnp_bios_escd_info(struct escd_info_struc *data);
|
||||
extern int pnp_bios_read_escd(char *data, u32 nvram_base);
|
||||
extern int pnp_bios_dock_station_info(struct pnp_docking_station_info *data);
|
||||
|
||||
#pragma pack(1)
|
||||
union pnp_bios_install_struct {
|
||||
struct {
|
||||
|
@ -28,8 +164,8 @@ extern int pnp_bios_present(void);
|
|||
extern int pnpbios_dont_use_current_config;
|
||||
|
||||
extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
|
||||
extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
|
||||
extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
|
||||
extern int pnpbios_read_resources_from_node(struct pnp_dev *dev, struct pnp_bios_node *node);
|
||||
extern int pnpbios_write_resources_to_node(struct pnp_dev *dev, struct pnp_bios_node *node);
|
||||
extern void pnpid32_to_pnpid(u32 id, char *str);
|
||||
|
||||
extern void pnpbios_print_status(const char * module, u16 status);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pnpbios.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/pnpbios.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -16,6 +15,7 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
|
|||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#include "../base.h"
|
||||
#include "pnpbios.h"
|
||||
|
||||
/* standard resource tags */
|
||||
|
@ -53,97 +53,43 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
|
|||
* Allocated Resources
|
||||
*/
|
||||
|
||||
static void pnpbios_parse_allocated_irqresource(struct pnp_resource_table *res,
|
||||
int irq)
|
||||
static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
|
||||
int start, int len)
|
||||
{
|
||||
int i = 0;
|
||||
int flags = 0;
|
||||
int end = start + len - 1;
|
||||
|
||||
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) {
|
||||
res->irq_resource[i].flags |= IORESOURCE_DISABLED;
|
||||
return;
|
||||
}
|
||||
res->irq_resource[i].start =
|
||||
res->irq_resource[i].end = (unsigned long)irq;
|
||||
pcibios_penalize_isa_irq(irq, 1);
|
||||
}
|
||||
if (len <= 0 || end >= 0x10003)
|
||||
flags |= IORESOURCE_DISABLED;
|
||||
|
||||
pnp_add_io_resource(dev, start, end, flags);
|
||||
}
|
||||
|
||||
static void pnpbios_parse_allocated_dmaresource(struct pnp_resource_table *res,
|
||||
int dma)
|
||||
static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
|
||||
int start, int len)
|
||||
{
|
||||
int i = 0;
|
||||
int flags = 0;
|
||||
int end = start + len - 1;
|
||||
|
||||
while (i < PNP_MAX_DMA &&
|
||||
!(res->dma_resource[i].flags & IORESOURCE_UNSET))
|
||||
i++;
|
||||
if (i < PNP_MAX_DMA) {
|
||||
res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
|
||||
if (dma == -1) {
|
||||
res->dma_resource[i].flags |= IORESOURCE_DISABLED;
|
||||
return;
|
||||
}
|
||||
res->dma_resource[i].start =
|
||||
res->dma_resource[i].end = (unsigned long)dma;
|
||||
}
|
||||
if (len <= 0)
|
||||
flags |= IORESOURCE_DISABLED;
|
||||
|
||||
pnp_add_mem_resource(dev, start, end, flags);
|
||||
}
|
||||
|
||||
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_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) {
|
||||
res->port_resource[i].flags |= IORESOURCE_DISABLED;
|
||||
return;
|
||||
}
|
||||
res->port_resource[i].start = (unsigned long)io;
|
||||
res->port_resource[i].end = (unsigned long)(io + len - 1);
|
||||
}
|
||||
}
|
||||
|
||||
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_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) {
|
||||
res->mem_resource[i].flags |= IORESOURCE_DISABLED;
|
||||
return;
|
||||
}
|
||||
res->mem_resource[i].start = (unsigned long)mem;
|
||||
res->mem_resource[i].end = (unsigned long)(mem + len - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
||||
unsigned char *end,
|
||||
struct
|
||||
pnp_resource_table
|
||||
*res)
|
||||
static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
|
||||
unsigned char *p,
|
||||
unsigned char *end)
|
||||
{
|
||||
unsigned int len, tag;
|
||||
int io, size, mask, i;
|
||||
int io, size, mask, i, flags;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
/* Blank the resource table values */
|
||||
pnp_init_resource_table(res);
|
||||
dev_dbg(&dev->dev, "parse allocated resources\n");
|
||||
|
||||
pnp_init_resources(dev);
|
||||
|
||||
while ((char *)p < (char *)end) {
|
||||
|
||||
|
@ -163,7 +109,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
goto len_err;
|
||||
io = *(short *)&p[4];
|
||||
size = *(short *)&p[10];
|
||||
pnpbios_parse_allocated_memresource(res, io, size);
|
||||
pnpbios_parse_allocated_memresource(dev, io, size);
|
||||
break;
|
||||
|
||||
case LARGE_TAG_ANSISTR:
|
||||
|
@ -179,7 +125,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
goto len_err;
|
||||
io = *(int *)&p[4];
|
||||
size = *(int *)&p[16];
|
||||
pnpbios_parse_allocated_memresource(res, io, size);
|
||||
pnpbios_parse_allocated_memresource(dev, io, size);
|
||||
break;
|
||||
|
||||
case LARGE_TAG_FIXEDMEM32:
|
||||
|
@ -187,29 +133,37 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
goto len_err;
|
||||
io = *(int *)&p[4];
|
||||
size = *(int *)&p[8];
|
||||
pnpbios_parse_allocated_memresource(res, io, size);
|
||||
pnpbios_parse_allocated_memresource(dev, io, size);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_IRQ:
|
||||
if (len < 2 || len > 3)
|
||||
goto len_err;
|
||||
flags = 0;
|
||||
io = -1;
|
||||
mask = p[1] + p[2] * 256;
|
||||
for (i = 0; i < 16; i++, mask = mask >> 1)
|
||||
if (mask & 0x01)
|
||||
io = i;
|
||||
pnpbios_parse_allocated_irqresource(res, io);
|
||||
if (io != -1)
|
||||
pcibios_penalize_isa_irq(io, 1);
|
||||
else
|
||||
flags = IORESOURCE_DISABLED;
|
||||
pnp_add_irq_resource(dev, io, flags);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_DMA:
|
||||
if (len != 2)
|
||||
goto len_err;
|
||||
flags = 0;
|
||||
io = -1;
|
||||
mask = p[1];
|
||||
for (i = 0; i < 8; i++, mask = mask >> 1)
|
||||
if (mask & 0x01)
|
||||
io = i;
|
||||
pnpbios_parse_allocated_dmaresource(res, io);
|
||||
if (io == -1)
|
||||
flags = IORESOURCE_DISABLED;
|
||||
pnp_add_dma_resource(dev, io, flags);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_PORT:
|
||||
|
@ -217,7 +171,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
goto len_err;
|
||||
io = p[2] + p[3] * 256;
|
||||
size = p[7];
|
||||
pnpbios_parse_allocated_ioresource(res, io, size);
|
||||
pnpbios_parse_allocated_ioresource(dev, io, size);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_VENDOR:
|
||||
|
@ -229,7 +183,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
goto len_err;
|
||||
io = p[1] + p[2] * 256;
|
||||
size = p[3];
|
||||
pnpbios_parse_allocated_ioresource(res, io, size);
|
||||
pnpbios_parse_allocated_ioresource(dev, io, size);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_END:
|
||||
|
@ -239,9 +193,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
|
|||
|
||||
default: /* an unkown tag */
|
||||
len_err:
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
|
||||
tag, len);
|
||||
dev_err(&dev->dev, "unknown tag %#x length %d\n",
|
||||
tag, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -252,8 +205,7 @@ len_err:
|
|||
p += len + 1;
|
||||
}
|
||||
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Resource structure does not contain an end tag.\n");
|
||||
dev_err(&dev->dev, "no end tag in resource structure\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -262,7 +214,8 @@ len_err:
|
|||
* Resource Configuration Options
|
||||
*/
|
||||
|
||||
static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
|
||||
static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_mem *mem;
|
||||
|
@ -275,10 +228,11 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
|
|||
mem->align = (p[9] << 8) | p[8];
|
||||
mem->size = ((p[11] << 8) | p[10]) << 8;
|
||||
mem->flags = p[3];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
|
||||
static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_mem *mem;
|
||||
|
@ -291,10 +245,11 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
|
|||
mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
|
||||
mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
|
||||
mem->flags = p[3];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
|
||||
static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_mem *mem;
|
||||
|
@ -306,11 +261,12 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
|
|||
mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
|
||||
mem->align = 0;
|
||||
mem->flags = p[3];
|
||||
pnp_register_mem_resource(option, mem);
|
||||
pnp_register_mem_resource(dev, option, mem);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_irq *irq;
|
||||
unsigned long bits;
|
||||
|
@ -324,11 +280,12 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
|
|||
irq->flags = p[3];
|
||||
else
|
||||
irq->flags = IORESOURCE_IRQ_HIGHEDGE;
|
||||
pnp_register_irq_resource(option, irq);
|
||||
pnp_register_irq_resource(dev, option, irq);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_dma *dma;
|
||||
|
||||
|
@ -337,10 +294,11 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
|
|||
return;
|
||||
dma->map = p[1];
|
||||
dma->flags = p[2];
|
||||
pnp_register_dma_resource(option, dma);
|
||||
pnp_register_dma_resource(dev, option, dma);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_port_option(unsigned char *p, int size,
|
||||
static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_port *port;
|
||||
|
@ -353,10 +311,11 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size,
|
|||
port->align = p[6];
|
||||
port->size = p[7];
|
||||
port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
|
||||
pnp_register_port_resource(option, port);
|
||||
pnp_register_port_resource(dev, option, port);
|
||||
}
|
||||
|
||||
static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
|
||||
static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
|
||||
unsigned char *p, int size,
|
||||
struct pnp_option *option)
|
||||
{
|
||||
struct pnp_port *port;
|
||||
|
@ -368,7 +327,7 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
|
|||
port->size = p[3];
|
||||
port->align = 0;
|
||||
port->flags = PNP_PORT_FLAG_FIXED;
|
||||
pnp_register_port_resource(option, port);
|
||||
pnp_register_port_resource(dev, option, port);
|
||||
}
|
||||
|
||||
static __init unsigned char *
|
||||
|
@ -382,6 +341,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
|
|||
if (!p)
|
||||
return NULL;
|
||||
|
||||
dev_dbg(&dev->dev, "parse resource options\n");
|
||||
|
||||
option_independent = option = pnp_register_independent_option(dev);
|
||||
if (!option)
|
||||
return NULL;
|
||||
|
@ -402,37 +363,37 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
|
|||
case LARGE_TAG_MEM:
|
||||
if (len != 9)
|
||||
goto len_err;
|
||||
pnpbios_parse_mem_option(p, len, option);
|
||||
pnpbios_parse_mem_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case LARGE_TAG_MEM32:
|
||||
if (len != 17)
|
||||
goto len_err;
|
||||
pnpbios_parse_mem32_option(p, len, option);
|
||||
pnpbios_parse_mem32_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case LARGE_TAG_FIXEDMEM32:
|
||||
if (len != 9)
|
||||
goto len_err;
|
||||
pnpbios_parse_fixed_mem32_option(p, len, option);
|
||||
pnpbios_parse_fixed_mem32_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_IRQ:
|
||||
if (len < 2 || len > 3)
|
||||
goto len_err;
|
||||
pnpbios_parse_irq_option(p, len, option);
|
||||
pnpbios_parse_irq_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_DMA:
|
||||
if (len != 2)
|
||||
goto len_err;
|
||||
pnpbios_parse_dma_option(p, len, option);
|
||||
pnpbios_parse_dma_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_PORT:
|
||||
if (len != 7)
|
||||
goto len_err;
|
||||
pnpbios_parse_port_option(p, len, option);
|
||||
pnpbios_parse_port_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_VENDOR:
|
||||
|
@ -442,7 +403,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
|
|||
case SMALL_TAG_FIXEDPORT:
|
||||
if (len != 3)
|
||||
goto len_err;
|
||||
pnpbios_parse_fixed_port_option(p, len, option);
|
||||
pnpbios_parse_fixed_port_option(dev, p, len, option);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_STARTDEP:
|
||||
|
@ -460,9 +421,10 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
|
|||
if (len != 0)
|
||||
goto len_err;
|
||||
if (option_independent == option)
|
||||
printk(KERN_WARNING
|
||||
"PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n");
|
||||
dev_warn(&dev->dev, "missing "
|
||||
"SMALL_TAG_STARTDEP tag\n");
|
||||
option = option_independent;
|
||||
dev_dbg(&dev->dev, "end dependent options\n");
|
||||
break;
|
||||
|
||||
case SMALL_TAG_END:
|
||||
|
@ -470,9 +432,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
|
|||
|
||||
default: /* an unkown tag */
|
||||
len_err:
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
|
||||
tag, len);
|
||||
dev_err(&dev->dev, "unknown tag %#x length %d\n",
|
||||
tag, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -483,8 +444,7 @@ len_err:
|
|||
p += len + 1;
|
||||
}
|
||||
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Resource structure does not contain an end tag.\n");
|
||||
dev_err(&dev->dev, "no end tag in resource structure\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -493,32 +453,12 @@ len_err:
|
|||
* Compatible Device IDs
|
||||
*/
|
||||
|
||||
#define HEX(id,a) hex[((id)>>a) & 15]
|
||||
#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
|
||||
|
||||
void pnpid32_to_pnpid(u32 id, char *str)
|
||||
{
|
||||
const char *hex = "0123456789abcdef";
|
||||
|
||||
id = be32_to_cpu(id);
|
||||
str[0] = CHAR(id, 26);
|
||||
str[1] = CHAR(id, 21);
|
||||
str[2] = CHAR(id, 16);
|
||||
str[3] = HEX(id, 12);
|
||||
str[4] = HEX(id, 8);
|
||||
str[5] = HEX(id, 4);
|
||||
str[6] = HEX(id, 0);
|
||||
str[7] = '\0';
|
||||
}
|
||||
|
||||
#undef CHAR
|
||||
#undef HEX
|
||||
|
||||
static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
|
||||
unsigned char *end,
|
||||
struct pnp_dev *dev)
|
||||
{
|
||||
int len, tag;
|
||||
u32 eisa_id;
|
||||
char id[8];
|
||||
struct pnp_id *dev_id;
|
||||
|
||||
|
@ -548,13 +488,11 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
|
|||
case SMALL_TAG_COMPATDEVID: /* compatible ID */
|
||||
if (len != 4)
|
||||
goto len_err;
|
||||
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
|
||||
eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24;
|
||||
pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id);
|
||||
dev_id = pnp_add_id(dev, id);
|
||||
if (!dev_id)
|
||||
return NULL;
|
||||
pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] <<
|
||||
24, id);
|
||||
memcpy(&dev_id->id, id, 7);
|
||||
pnp_add_id(dev_id, dev);
|
||||
break;
|
||||
|
||||
case SMALL_TAG_END:
|
||||
|
@ -564,9 +502,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
|
|||
|
||||
default: /* an unkown tag */
|
||||
len_err:
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
|
||||
tag, len);
|
||||
dev_err(&dev->dev, "unknown tag %#x length %d\n",
|
||||
tag, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -577,8 +514,7 @@ len_err:
|
|||
p += len + 1;
|
||||
}
|
||||
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Resource structure does not contain an end tag.\n");
|
||||
dev_err(&dev->dev, "no end tag in resource structure\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -587,7 +523,8 @@ len_err:
|
|||
* Allocated Resource Encoding
|
||||
*/
|
||||
|
||||
static void pnpbios_encode_mem(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long base = res->start;
|
||||
unsigned long len = res->end - res->start + 1;
|
||||
|
@ -598,9 +535,13 @@ static void pnpbios_encode_mem(unsigned char *p, struct resource *res)
|
|||
p[7] = ((base >> 8) >> 8) & 0xff;
|
||||
p[10] = (len >> 8) & 0xff;
|
||||
p[11] = ((len >> 8) >> 8) & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_mem32(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long base = res->start;
|
||||
unsigned long len = res->end - res->start + 1;
|
||||
|
@ -617,9 +558,13 @@ static void pnpbios_encode_mem32(unsigned char *p, struct resource *res)
|
|||
p[17] = (len >> 8) & 0xff;
|
||||
p[18] = (len >> 16) & 0xff;
|
||||
p[19] = (len >> 24) & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long base = res->start;
|
||||
unsigned long len = res->end - res->start + 1;
|
||||
|
@ -632,26 +577,36 @@ static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res)
|
|||
p[9] = (len >> 8) & 0xff;
|
||||
p[10] = (len >> 16) & 0xff;
|
||||
p[11] = (len >> 24) & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_irq(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long map = 0;
|
||||
|
||||
map = 1 << res->start;
|
||||
p[1] = map & 0xff;
|
||||
p[2] = (map >> 8) & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode irq %d\n", res->start);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_dma(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long map = 0;
|
||||
|
||||
map = 1 << res->start;
|
||||
p[1] = map & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode dma %d\n", res->start);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_port(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long base = res->start;
|
||||
unsigned long len = res->end - res->start + 1;
|
||||
|
@ -661,9 +616,13 @@ static void pnpbios_encode_port(unsigned char *p, struct resource *res)
|
|||
p[4] = base & 0xff;
|
||||
p[5] = (base >> 8) & 0xff;
|
||||
p[7] = len & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
}
|
||||
|
||||
static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res)
|
||||
static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
|
||||
struct resource *res)
|
||||
{
|
||||
unsigned long base = res->start;
|
||||
unsigned long len = res->end - res->start + 1;
|
||||
|
@ -671,13 +630,15 @@ static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res)
|
|||
p[1] = base & 0xff;
|
||||
p[2] = (base >> 8) & 0xff;
|
||||
p[3] = len & 0xff;
|
||||
|
||||
dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
|
||||
(unsigned long long) res->start, (unsigned long long) res->end);
|
||||
}
|
||||
|
||||
static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
|
||||
unsigned char *end,
|
||||
struct
|
||||
pnp_resource_table
|
||||
*res)
|
||||
static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
|
||||
*dev,
|
||||
unsigned char *p,
|
||||
unsigned char *end)
|
||||
{
|
||||
unsigned int len, tag;
|
||||
int port = 0, irq = 0, dma = 0, mem = 0;
|
||||
|
@ -701,42 +662,48 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
|
|||
case LARGE_TAG_MEM:
|
||||
if (len != 9)
|
||||
goto len_err;
|
||||
pnpbios_encode_mem(p, &res->mem_resource[mem]);
|
||||
pnpbios_encode_mem(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_MEM, mem));
|
||||
mem++;
|
||||
break;
|
||||
|
||||
case LARGE_TAG_MEM32:
|
||||
if (len != 17)
|
||||
goto len_err;
|
||||
pnpbios_encode_mem32(p, &res->mem_resource[mem]);
|
||||
pnpbios_encode_mem32(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_MEM, mem));
|
||||
mem++;
|
||||
break;
|
||||
|
||||
case LARGE_TAG_FIXEDMEM32:
|
||||
if (len != 9)
|
||||
goto len_err;
|
||||
pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]);
|
||||
pnpbios_encode_fixed_mem32(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_MEM, mem));
|
||||
mem++;
|
||||
break;
|
||||
|
||||
case SMALL_TAG_IRQ:
|
||||
if (len < 2 || len > 3)
|
||||
goto len_err;
|
||||
pnpbios_encode_irq(p, &res->irq_resource[irq]);
|
||||
pnpbios_encode_irq(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_IRQ, irq));
|
||||
irq++;
|
||||
break;
|
||||
|
||||
case SMALL_TAG_DMA:
|
||||
if (len != 2)
|
||||
goto len_err;
|
||||
pnpbios_encode_dma(p, &res->dma_resource[dma]);
|
||||
pnpbios_encode_dma(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_DMA, dma));
|
||||
dma++;
|
||||
break;
|
||||
|
||||
case SMALL_TAG_PORT:
|
||||
if (len != 7)
|
||||
goto len_err;
|
||||
pnpbios_encode_port(p, &res->port_resource[port]);
|
||||
pnpbios_encode_port(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_IO, port));
|
||||
port++;
|
||||
break;
|
||||
|
||||
|
@ -747,7 +714,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
|
|||
case SMALL_TAG_FIXEDPORT:
|
||||
if (len != 3)
|
||||
goto len_err;
|
||||
pnpbios_encode_fixed_port(p, &res->port_resource[port]);
|
||||
pnpbios_encode_fixed_port(dev, p,
|
||||
pnp_get_resource(dev, IORESOURCE_IO, port));
|
||||
port++;
|
||||
break;
|
||||
|
||||
|
@ -758,9 +726,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
|
|||
|
||||
default: /* an unkown tag */
|
||||
len_err:
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
|
||||
tag, len);
|
||||
dev_err(&dev->dev, "unknown tag %#x length %d\n",
|
||||
tag, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -771,8 +738,7 @@ len_err:
|
|||
p += len + 1;
|
||||
}
|
||||
|
||||
printk(KERN_ERR
|
||||
"PnPBIOS: Resource structure does not contain an end tag.\n");
|
||||
dev_err(&dev->dev, "no end tag in resource structure\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -787,7 +753,7 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
|
|||
unsigned char *p = (char *)node->data;
|
||||
unsigned char *end = (char *)(node->data + node->size);
|
||||
|
||||
p = pnpbios_parse_allocated_resource_data(p, end, &dev->res);
|
||||
p = pnpbios_parse_allocated_resource_data(dev, p, end);
|
||||
if (!p)
|
||||
return -EIO;
|
||||
p = pnpbios_parse_resource_option_data(p, end, dev);
|
||||
|
@ -799,25 +765,25 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pnpbios_read_resources_from_node(struct pnp_resource_table *res,
|
||||
int pnpbios_read_resources_from_node(struct pnp_dev *dev,
|
||||
struct pnp_bios_node *node)
|
||||
{
|
||||
unsigned char *p = (char *)node->data;
|
||||
unsigned char *end = (char *)(node->data + node->size);
|
||||
|
||||
p = pnpbios_parse_allocated_resource_data(p, end, res);
|
||||
p = pnpbios_parse_allocated_resource_data(dev, p, end);
|
||||
if (!p)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pnpbios_write_resources_to_node(struct pnp_resource_table *res,
|
||||
int pnpbios_write_resources_to_node(struct pnp_dev *dev,
|
||||
struct pnp_bios_node *node)
|
||||
{
|
||||
unsigned char *p = (char *)node->data;
|
||||
unsigned char *end = (char *)(node->data + node->size);
|
||||
|
||||
p = pnpbios_encode_allocated_resource_data(p, end, res);
|
||||
p = pnpbios_encode_allocated_resource_data(dev, p, end);
|
||||
if (!p)
|
||||
return -EIO;
|
||||
return 0;
|
||||
|
|
|
@ -117,6 +117,7 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
|
|||
static void quirk_system_pci_resources(struct pnp_dev *dev)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
struct resource *res;
|
||||
resource_size_t pnp_start, pnp_end, pci_start, pci_end;
|
||||
int i, j;
|
||||
|
||||
|
@ -137,13 +138,15 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
|||
|
||||
pci_start = pci_resource_start(pdev, i);
|
||||
pci_end = pci_resource_end(pdev, i);
|
||||
for (j = 0; j < PNP_MAX_MEM; j++) {
|
||||
if (!pnp_mem_valid(dev, j) ||
|
||||
pnp_mem_len(dev, j) == 0)
|
||||
for (j = 0;
|
||||
(res = pnp_get_resource(dev, IORESOURCE_MEM, j));
|
||||
j++) {
|
||||
if (res->flags & IORESOURCE_UNSET ||
|
||||
(res->start == 0 && res->end == 0))
|
||||
continue;
|
||||
|
||||
pnp_start = pnp_mem_start(dev, j);
|
||||
pnp_end = pnp_mem_end(dev, j);
|
||||
pnp_start = res->start;
|
||||
pnp_end = res->end;
|
||||
|
||||
/*
|
||||
* If the PNP region doesn't overlap the PCI
|
||||
|
@ -176,7 +179,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
|||
pci_name(pdev), i,
|
||||
(unsigned long long) pci_start,
|
||||
(unsigned long long) pci_end);
|
||||
pnp_mem_flags(dev, j) = 0;
|
||||
res->flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
|
|||
if (dev->independent)
|
||||
dev_err(&dev->dev, "independent resource already registered\n");
|
||||
dev->independent = option;
|
||||
|
||||
dev_dbg(&dev->dev, "new independent option\n");
|
||||
return option;
|
||||
}
|
||||
|
||||
|
@ -70,12 +72,18 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
|
|||
parent->next = option;
|
||||
} else
|
||||
dev->dependent = option;
|
||||
|
||||
dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
|
||||
return option;
|
||||
}
|
||||
|
||||
int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
|
||||
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_irq *data)
|
||||
{
|
||||
struct pnp_irq *ptr;
|
||||
#ifdef DEBUG
|
||||
char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
|
||||
#endif
|
||||
|
||||
ptr = option->irq;
|
||||
while (ptr && ptr->next)
|
||||
|
@ -94,10 +102,17 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
|
|||
pcibios_penalize_isa_irq(i, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
|
||||
dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
|
||||
data->flags);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
|
||||
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_dma *data)
|
||||
{
|
||||
struct pnp_dma *ptr;
|
||||
|
||||
|
@ -109,10 +124,13 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
|
|||
else
|
||||
option->dma = data;
|
||||
|
||||
dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
|
||||
data->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
|
||||
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_port *data)
|
||||
{
|
||||
struct pnp_port *ptr;
|
||||
|
||||
|
@ -124,10 +142,14 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
|
|||
else
|
||||
option->port = data;
|
||||
|
||||
dev_dbg(&dev->dev, " io "
|
||||
"min %#x max %#x align %d size %d flags %#x\n",
|
||||
data->min, data->max, data->align, data->size, data->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
|
||||
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
|
||||
struct pnp_mem *data)
|
||||
{
|
||||
struct pnp_mem *ptr;
|
||||
|
||||
|
@ -138,6 +160,10 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
|
|||
ptr->next = data;
|
||||
else
|
||||
option->mem = data;
|
||||
|
||||
dev_dbg(&dev->dev, " mem "
|
||||
"min %#x max %#x align %d size %d flags %#x\n",
|
||||
data->min, data->max, data->align, data->size, data->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -213,17 +239,18 @@ void pnp_free_option(struct pnp_option *option)
|
|||
#define cannot_compare(flags) \
|
||||
((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
|
||||
|
||||
int pnp_check_port(struct pnp_dev *dev, int idx)
|
||||
int pnp_check_port(struct pnp_dev *dev, struct resource *res)
|
||||
{
|
||||
int tmp;
|
||||
int i;
|
||||
struct pnp_dev *tdev;
|
||||
struct resource *tres;
|
||||
resource_size_t *port, *end, *tport, *tend;
|
||||
|
||||
port = &dev->res.port_resource[idx].start;
|
||||
end = &dev->res.port_resource[idx].end;
|
||||
port = &res->start;
|
||||
end = &res->end;
|
||||
|
||||
/* if the resource doesn't exist, don't complain about it */
|
||||
if (cannot_compare(dev->res.port_resource[idx].flags))
|
||||
if (cannot_compare(res->flags))
|
||||
return 1;
|
||||
|
||||
/* check if the resource is already in use, skip if the
|
||||
|
@ -234,18 +261,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
|
|||
}
|
||||
|
||||
/* check if the resource is reserved */
|
||||
for (tmp = 0; tmp < 8; tmp++) {
|
||||
int rport = pnp_reserve_io[tmp << 1];
|
||||
int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
int rport = pnp_reserve_io[i << 1];
|
||||
int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
|
||||
if (ranged_conflict(port, end, &rport, &rend))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for internal conflicts */
|
||||
for (tmp = 0; tmp < PNP_MAX_PORT && tmp != idx; tmp++) {
|
||||
if (dev->res.port_resource[tmp].flags & IORESOURCE_IO) {
|
||||
tport = &dev->res.port_resource[tmp].start;
|
||||
tend = &dev->res.port_resource[tmp].end;
|
||||
for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
|
||||
if (tres != res && tres->flags & IORESOURCE_IO) {
|
||||
tport = &tres->start;
|
||||
tend = &tres->end;
|
||||
if (ranged_conflict(port, end, tport, tend))
|
||||
return 0;
|
||||
}
|
||||
|
@ -255,13 +282,14 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
|
|||
pnp_for_each_dev(tdev) {
|
||||
if (tdev == dev)
|
||||
continue;
|
||||
for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
|
||||
if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
|
||||
if (cannot_compare
|
||||
(tdev->res.port_resource[tmp].flags))
|
||||
for (i = 0;
|
||||
(tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
|
||||
i++) {
|
||||
if (tres->flags & IORESOURCE_IO) {
|
||||
if (cannot_compare(tres->flags))
|
||||
continue;
|
||||
tport = &tdev->res.port_resource[tmp].start;
|
||||
tend = &tdev->res.port_resource[tmp].end;
|
||||
tport = &tres->start;
|
||||
tend = &tres->end;
|
||||
if (ranged_conflict(port, end, tport, tend))
|
||||
return 0;
|
||||
}
|
||||
|
@ -271,17 +299,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int pnp_check_mem(struct pnp_dev *dev, int idx)
|
||||
int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
|
||||
{
|
||||
int tmp;
|
||||
int i;
|
||||
struct pnp_dev *tdev;
|
||||
struct resource *tres;
|
||||
resource_size_t *addr, *end, *taddr, *tend;
|
||||
|
||||
addr = &dev->res.mem_resource[idx].start;
|
||||
end = &dev->res.mem_resource[idx].end;
|
||||
addr = &res->start;
|
||||
end = &res->end;
|
||||
|
||||
/* if the resource doesn't exist, don't complain about it */
|
||||
if (cannot_compare(dev->res.mem_resource[idx].flags))
|
||||
if (cannot_compare(res->flags))
|
||||
return 1;
|
||||
|
||||
/* check if the resource is already in use, skip if the
|
||||
|
@ -292,18 +321,18 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
|
|||
}
|
||||
|
||||
/* check if the resource is reserved */
|
||||
for (tmp = 0; tmp < 8; tmp++) {
|
||||
int raddr = pnp_reserve_mem[tmp << 1];
|
||||
int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
int raddr = pnp_reserve_mem[i << 1];
|
||||
int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
|
||||
if (ranged_conflict(addr, end, &raddr, &rend))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for internal conflicts */
|
||||
for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) {
|
||||
if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
|
||||
taddr = &dev->res.mem_resource[tmp].start;
|
||||
tend = &dev->res.mem_resource[tmp].end;
|
||||
for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
|
||||
if (tres != res && tres->flags & IORESOURCE_MEM) {
|
||||
taddr = &tres->start;
|
||||
tend = &tres->end;
|
||||
if (ranged_conflict(addr, end, taddr, tend))
|
||||
return 0;
|
||||
}
|
||||
|
@ -313,13 +342,14 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
|
|||
pnp_for_each_dev(tdev) {
|
||||
if (tdev == dev)
|
||||
continue;
|
||||
for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
|
||||
if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
|
||||
if (cannot_compare
|
||||
(tdev->res.mem_resource[tmp].flags))
|
||||
for (i = 0;
|
||||
(tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
|
||||
i++) {
|
||||
if (tres->flags & IORESOURCE_MEM) {
|
||||
if (cannot_compare(tres->flags))
|
||||
continue;
|
||||
taddr = &tdev->res.mem_resource[tmp].start;
|
||||
tend = &tdev->res.mem_resource[tmp].end;
|
||||
taddr = &tres->start;
|
||||
tend = &tres->end;
|
||||
if (ranged_conflict(addr, end, taddr, tend))
|
||||
return 0;
|
||||
}
|
||||
|
@ -334,14 +364,17 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int pnp_check_irq(struct pnp_dev *dev, int idx)
|
||||
int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
|
||||
{
|
||||
int tmp;
|
||||
int i;
|
||||
struct pnp_dev *tdev;
|
||||
resource_size_t *irq = &dev->res.irq_resource[idx].start;
|
||||
struct resource *tres;
|
||||
resource_size_t *irq;
|
||||
|
||||
irq = &res->start;
|
||||
|
||||
/* if the resource doesn't exist, don't complain about it */
|
||||
if (cannot_compare(dev->res.irq_resource[idx].flags))
|
||||
if (cannot_compare(res->flags))
|
||||
return 1;
|
||||
|
||||
/* check if the resource is valid */
|
||||
|
@ -349,15 +382,15 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
|
|||
return 0;
|
||||
|
||||
/* check if the resource is reserved */
|
||||
for (tmp = 0; tmp < 16; tmp++) {
|
||||
if (pnp_reserve_irq[tmp] == *irq)
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (pnp_reserve_irq[i] == *irq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for internal conflicts */
|
||||
for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) {
|
||||
if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
|
||||
if (dev->res.irq_resource[tmp].start == *irq)
|
||||
for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
|
||||
if (tres != res && tres->flags & IORESOURCE_IRQ) {
|
||||
if (tres->start == *irq)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -388,12 +421,13 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
|
|||
pnp_for_each_dev(tdev) {
|
||||
if (tdev == dev)
|
||||
continue;
|
||||
for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
|
||||
if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
|
||||
if (cannot_compare
|
||||
(tdev->res.irq_resource[tmp].flags))
|
||||
for (i = 0;
|
||||
(tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
|
||||
i++) {
|
||||
if (tres->flags & IORESOURCE_IRQ) {
|
||||
if (cannot_compare(tres->flags))
|
||||
continue;
|
||||
if ((tdev->res.irq_resource[tmp].start == *irq))
|
||||
if (tres->start == *irq)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -402,15 +436,18 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int pnp_check_dma(struct pnp_dev *dev, int idx)
|
||||
int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
|
||||
{
|
||||
#ifndef CONFIG_IA64
|
||||
int tmp;
|
||||
int i;
|
||||
struct pnp_dev *tdev;
|
||||
resource_size_t *dma = &dev->res.dma_resource[idx].start;
|
||||
struct resource *tres;
|
||||
resource_size_t *dma;
|
||||
|
||||
dma = &res->start;
|
||||
|
||||
/* if the resource doesn't exist, don't complain about it */
|
||||
if (cannot_compare(dev->res.dma_resource[idx].flags))
|
||||
if (cannot_compare(res->flags))
|
||||
return 1;
|
||||
|
||||
/* check if the resource is valid */
|
||||
|
@ -418,15 +455,15 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
|
|||
return 0;
|
||||
|
||||
/* check if the resource is reserved */
|
||||
for (tmp = 0; tmp < 8; tmp++) {
|
||||
if (pnp_reserve_dma[tmp] == *dma)
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (pnp_reserve_dma[i] == *dma)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for internal conflicts */
|
||||
for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) {
|
||||
if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
|
||||
if (dev->res.dma_resource[tmp].start == *dma)
|
||||
for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
|
||||
if (tres != res && tres->flags & IORESOURCE_DMA) {
|
||||
if (tres->start == *dma)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -443,12 +480,13 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
|
|||
pnp_for_each_dev(tdev) {
|
||||
if (tdev == dev)
|
||||
continue;
|
||||
for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
|
||||
if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
|
||||
if (cannot_compare
|
||||
(tdev->res.dma_resource[tmp].flags))
|
||||
for (i = 0;
|
||||
(tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
|
||||
i++) {
|
||||
if (tres->flags & IORESOURCE_DMA) {
|
||||
if (cannot_compare(tres->flags))
|
||||
continue;
|
||||
if ((tdev->res.dma_resource[tmp].start == *dma))
|
||||
if (tres->start == *dma)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -461,6 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
|
|||
#endif
|
||||
}
|
||||
|
||||
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
|
||||
unsigned int type, unsigned int num)
|
||||
{
|
||||
struct pnp_resource_table *res = dev->res;
|
||||
|
||||
switch (type) {
|
||||
case IORESOURCE_IO:
|
||||
if (num >= PNP_MAX_PORT)
|
||||
return NULL;
|
||||
return &res->port[num];
|
||||
case IORESOURCE_MEM:
|
||||
if (num >= PNP_MAX_MEM)
|
||||
return NULL;
|
||||
return &res->mem[num];
|
||||
case IORESOURCE_IRQ:
|
||||
if (num >= PNP_MAX_IRQ)
|
||||
return NULL;
|
||||
return &res->irq[num];
|
||||
case IORESOURCE_DMA:
|
||||
if (num >= PNP_MAX_DMA)
|
||||
return NULL;
|
||||
return &res->dma[num];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct resource *pnp_get_resource(struct pnp_dev *dev,
|
||||
unsigned int type, unsigned int num)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
|
||||
pnp_res = pnp_get_pnp_resource(dev, type, num);
|
||||
if (pnp_res)
|
||||
return &pnp_res->res;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(pnp_get_resource);
|
||||
|
||||
static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
int i;
|
||||
|
||||
switch (type) {
|
||||
case IORESOURCE_IO:
|
||||
for (i = 0; i < PNP_MAX_PORT; i++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
|
||||
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
|
||||
return pnp_res;
|
||||
}
|
||||
break;
|
||||
case IORESOURCE_MEM:
|
||||
for (i = 0; i < PNP_MAX_MEM; i++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
|
||||
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
|
||||
return pnp_res;
|
||||
}
|
||||
break;
|
||||
case IORESOURCE_IRQ:
|
||||
for (i = 0; i < PNP_MAX_IRQ; i++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
|
||||
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
|
||||
return pnp_res;
|
||||
}
|
||||
break;
|
||||
case IORESOURCE_DMA:
|
||||
for (i = 0; i < PNP_MAX_DMA; i++) {
|
||||
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
|
||||
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
|
||||
return pnp_res;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
|
||||
int flags)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
static unsigned char warned;
|
||||
|
||||
pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ);
|
||||
if (!pnp_res) {
|
||||
if (!warned) {
|
||||
dev_err(&dev->dev, "can't add resource for IRQ %d\n",
|
||||
irq);
|
||||
warned = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &pnp_res->res;
|
||||
res->flags = IORESOURCE_IRQ | flags;
|
||||
res->start = irq;
|
||||
res->end = irq;
|
||||
|
||||
dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
|
||||
int flags)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
static unsigned char warned;
|
||||
|
||||
pnp_res = pnp_new_resource(dev, IORESOURCE_DMA);
|
||||
if (!pnp_res) {
|
||||
if (!warned) {
|
||||
dev_err(&dev->dev, "can't add resource for DMA %d\n",
|
||||
dma);
|
||||
warned = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &pnp_res->res;
|
||||
res->flags = IORESOURCE_DMA | flags;
|
||||
res->start = dma;
|
||||
res->end = dma;
|
||||
|
||||
dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
|
||||
resource_size_t start,
|
||||
resource_size_t end, int flags)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
static unsigned char warned;
|
||||
|
||||
pnp_res = pnp_new_resource(dev, IORESOURCE_IO);
|
||||
if (!pnp_res) {
|
||||
if (!warned) {
|
||||
dev_err(&dev->dev, "can't add resource for IO "
|
||||
"%#llx-%#llx\n",(unsigned long long) start,
|
||||
(unsigned long long) end);
|
||||
warned = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &pnp_res->res;
|
||||
res->flags = IORESOURCE_IO | flags;
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n",
|
||||
(unsigned long long) start, (unsigned long long) end, flags);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
|
||||
resource_size_t start,
|
||||
resource_size_t end, int flags)
|
||||
{
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
static unsigned char warned;
|
||||
|
||||
pnp_res = pnp_new_resource(dev, IORESOURCE_MEM);
|
||||
if (!pnp_res) {
|
||||
if (!warned) {
|
||||
dev_err(&dev->dev, "can't add resource for MEM "
|
||||
"%#llx-%#llx\n",(unsigned long long) start,
|
||||
(unsigned long long) end);
|
||||
warned = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &pnp_res->res;
|
||||
res->flags = IORESOURCE_MEM | flags;
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n",
|
||||
(unsigned long long) start, (unsigned long long) end, flags);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
/* format is: pnp_reserve_irq=irq1[,irq2] .... */
|
||||
static int __init pnp_setup_reserve_irq(char *str)
|
||||
{
|
||||
|
|
|
@ -25,3 +25,66 @@ int pnp_is_active(struct pnp_dev *dev)
|
|||
}
|
||||
|
||||
EXPORT_SYMBOL(pnp_is_active);
|
||||
|
||||
/*
|
||||
* Functionally similar to acpi_ex_eisa_id_to_string(), but that's
|
||||
* buried in the ACPI CA, and we can't depend on it being present.
|
||||
*/
|
||||
void pnp_eisa_id_to_string(u32 id, char *str)
|
||||
{
|
||||
id = be32_to_cpu(id);
|
||||
|
||||
/*
|
||||
* According to the specs, the first three characters are five-bit
|
||||
* compressed ASCII, and the left-over high order bit should be zero.
|
||||
* However, the Linux ISAPNP code historically used six bits for the
|
||||
* first character, and there seem to be IDs that depend on that,
|
||||
* e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
|
||||
* FreeBSD sys/pc98/cbus/sio_cbus.c driver.
|
||||
*/
|
||||
str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
|
||||
str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
|
||||
str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
|
||||
str[3] = hex_asc((id >> 12) & 0xf);
|
||||
str[4] = hex_asc((id >> 8) & 0xf);
|
||||
str[5] = hex_asc((id >> 4) & 0xf);
|
||||
str[6] = hex_asc((id >> 0) & 0xf);
|
||||
str[7] = '\0';
|
||||
}
|
||||
|
||||
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
dev_dbg(&dev->dev, "current resources: %s\n", desc);
|
||||
|
||||
for (i = 0; i < PNP_MAX_IRQ; i++) {
|
||||
res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
|
||||
if (res && !(res->flags & IORESOURCE_UNSET))
|
||||
dev_dbg(&dev->dev, " irq %lld flags %#lx\n",
|
||||
(unsigned long long) res->start, res->flags);
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_DMA; i++) {
|
||||
res = pnp_get_resource(dev, IORESOURCE_DMA, i);
|
||||
if (res && !(res->flags & IORESOURCE_UNSET))
|
||||
dev_dbg(&dev->dev, " dma %lld flags %#lx\n",
|
||||
(unsigned long long) res->start, res->flags);
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_PORT; i++) {
|
||||
res = pnp_get_resource(dev, IORESOURCE_IO, i);
|
||||
if (res && !(res->flags & IORESOURCE_UNSET))
|
||||
dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n",
|
||||
(unsigned long long) res->start,
|
||||
(unsigned long long) res->end, res->flags);
|
||||
}
|
||||
for (i = 0; i < PNP_MAX_MEM; i++) {
|
||||
res = pnp_get_resource(dev, IORESOURCE_MEM, i);
|
||||
if (res && !(res->flags & IORESOURCE_UNSET))
|
||||
dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n",
|
||||
(unsigned long long) res->start,
|
||||
(unsigned long long) res->end, res->flags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -56,14 +56,15 @@ static void reserve_range(struct pnp_dev *dev, resource_size_t start,
|
|||
|
||||
static void reserve_resources_of_dev(struct pnp_dev *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PNP_MAX_PORT; i++) {
|
||||
if (!pnp_port_valid(dev, i))
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
|
||||
if (res->flags & IORESOURCE_UNSET)
|
||||
continue;
|
||||
if (pnp_port_start(dev, i) == 0)
|
||||
if (res->start == 0)
|
||||
continue; /* disabled */
|
||||
if (pnp_port_start(dev, i) < 0x100)
|
||||
if (res->start < 0x100)
|
||||
/*
|
||||
* Below 0x100 is only standard PC hardware
|
||||
* (pics, kbd, timer, dma, ...)
|
||||
|
@ -73,19 +74,17 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
|
|||
* So, do nothing
|
||||
*/
|
||||
continue;
|
||||
if (pnp_port_end(dev, i) < pnp_port_start(dev, i))
|
||||
if (res->end < res->start)
|
||||
continue; /* invalid */
|
||||
|
||||
reserve_range(dev, pnp_port_start(dev, i),
|
||||
pnp_port_end(dev, i), 1);
|
||||
reserve_range(dev, res->start, res->end, 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < PNP_MAX_MEM; i++) {
|
||||
if (!pnp_mem_valid(dev, i))
|
||||
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
|
||||
if (res->flags & IORESOURCE_UNSET)
|
||||
continue;
|
||||
|
||||
reserve_range(dev, pnp_mem_start(dev, i),
|
||||
pnp_mem_end(dev, i), 0);
|
||||
reserve_range(dev, res->start, res->end, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -854,11 +854,12 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
|||
* don't define the IRQ. It should always be safe to
|
||||
* hardcode it in these cases
|
||||
*/
|
||||
return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8);
|
||||
return cmos_do_probe(&pnp->dev,
|
||||
pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
|
||||
else
|
||||
return cmos_do_probe(&pnp->dev,
|
||||
&pnp->res.port_resource[0],
|
||||
pnp->res.irq_resource[0].start);
|
||||
pnp_get_resource(pnp, IORESOURCE_IO, 0),
|
||||
pnp_irq(pnp, 0));
|
||||
}
|
||||
|
||||
static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
|
||||
|
|
|
@ -25,16 +25,6 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
/*
|
||||
* Configuration registers (TODO: change by specification)
|
||||
*/
|
||||
|
||||
#define ISAPNP_CFG_ACTIVATE 0x30 /* byte */
|
||||
#define ISAPNP_CFG_MEM 0x40 /* 4 * dword */
|
||||
#define ISAPNP_CFG_PORT 0x60 /* 8 * word */
|
||||
#define ISAPNP_CFG_IRQ 0x70 /* 2 * word */
|
||||
#define ISAPNP_CFG_DMA 0x74 /* 2 * byte */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -13,59 +13,122 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
#define PNP_MAX_PORT 40
|
||||
#define PNP_MAX_MEM 24
|
||||
#define PNP_MAX_IRQ 2
|
||||
#define PNP_MAX_DMA 2
|
||||
#define PNP_NAME_LEN 50
|
||||
|
||||
struct pnp_protocol;
|
||||
struct pnp_dev;
|
||||
struct pnp_resource_table;
|
||||
|
||||
/*
|
||||
* Resource Management
|
||||
*/
|
||||
struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
|
||||
|
||||
/* Use these instead of directly reading pnp_dev to get resource information */
|
||||
#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 | IORESOURCE_UNSET)) \
|
||||
== IORESOURCE_IO)
|
||||
#define pnp_port_len(dev,bar) \
|
||||
((pnp_port_start((dev),(bar)) == 0 && \
|
||||
pnp_port_end((dev),(bar)) == \
|
||||
pnp_port_start((dev),(bar))) ? 0 : \
|
||||
\
|
||||
(pnp_port_end((dev),(bar)) - \
|
||||
pnp_port_start((dev),(bar)) + 1))
|
||||
static inline int pnp_resource_valid(struct resource *res)
|
||||
{
|
||||
if (res && !(res->flags & IORESOURCE_UNSET))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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 | IORESOURCE_UNSET)) \
|
||||
== IORESOURCE_MEM)
|
||||
#define pnp_mem_len(dev,bar) \
|
||||
((pnp_mem_start((dev),(bar)) == 0 && \
|
||||
pnp_mem_end((dev),(bar)) == \
|
||||
pnp_mem_start((dev),(bar))) ? 0 : \
|
||||
\
|
||||
(pnp_mem_end((dev),(bar)) - \
|
||||
pnp_mem_start((dev),(bar)) + 1))
|
||||
static inline resource_size_t pnp_resource_len(struct resource *res)
|
||||
{
|
||||
if (res->start == 0 && res->end == 0)
|
||||
return 0;
|
||||
return res->end - res->start + 1;
|
||||
}
|
||||
|
||||
#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 | 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 | IORESOURCE_UNSET)) \
|
||||
== IORESOURCE_DMA)
|
||||
static inline resource_size_t pnp_port_start(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_IO, bar)->start;
|
||||
}
|
||||
|
||||
static inline resource_size_t pnp_port_end(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_IO, bar)->end;
|
||||
}
|
||||
|
||||
static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags;
|
||||
}
|
||||
|
||||
static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_IO, bar));
|
||||
}
|
||||
|
||||
static inline resource_size_t pnp_port_len(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar));
|
||||
}
|
||||
|
||||
|
||||
static inline resource_size_t pnp_mem_start(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start;
|
||||
}
|
||||
|
||||
static inline resource_size_t pnp_mem_end(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end;
|
||||
}
|
||||
|
||||
static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags;
|
||||
}
|
||||
|
||||
static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_MEM, bar));
|
||||
}
|
||||
|
||||
static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
|
||||
unsigned int bar)
|
||||
{
|
||||
return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar));
|
||||
}
|
||||
|
||||
|
||||
static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start;
|
||||
}
|
||||
|
||||
static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags;
|
||||
}
|
||||
|
||||
static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_IRQ, bar));
|
||||
}
|
||||
|
||||
|
||||
static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start;
|
||||
}
|
||||
|
||||
static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags;
|
||||
}
|
||||
|
||||
static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
|
||||
{
|
||||
return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_DMA, bar));
|
||||
}
|
||||
|
||||
|
||||
#define PNP_PORT_FLAG_16BITADDR (1<<0)
|
||||
#define PNP_PORT_FLAG_FIXED (1<<1)
|
||||
|
@ -118,13 +181,6 @@ struct pnp_option {
|
|||
struct pnp_option *next; /* used to chain dependent resources */
|
||||
};
|
||||
|
||||
struct pnp_resource_table {
|
||||
struct resource port_resource[PNP_MAX_PORT];
|
||||
struct resource mem_resource[PNP_MAX_MEM];
|
||||
struct resource dma_resource[PNP_MAX_DMA];
|
||||
struct resource irq_resource[PNP_MAX_IRQ];
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Management
|
||||
*/
|
||||
|
@ -194,10 +250,9 @@ struct pnp_dev {
|
|||
int capabilities;
|
||||
struct pnp_option *independent;
|
||||
struct pnp_option *dependent;
|
||||
struct pnp_resource_table res;
|
||||
struct pnp_resource_table *res;
|
||||
|
||||
char name[PNP_NAME_LEN]; /* contains a human-readable name */
|
||||
unsigned short regs; /* ISAPnP: supported registers */
|
||||
int flags; /* used by protocols */
|
||||
struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */
|
||||
void *data;
|
||||
|
@ -328,8 +383,8 @@ struct pnp_protocol {
|
|||
char *name;
|
||||
|
||||
/* resource control functions */
|
||||
int (*get) (struct pnp_dev *dev, struct pnp_resource_table *res);
|
||||
int (*set) (struct pnp_dev *dev, struct pnp_resource_table *res);
|
||||
int (*get) (struct pnp_dev *dev);
|
||||
int (*set) (struct pnp_dev *dev);
|
||||
int (*disable) (struct pnp_dev *dev);
|
||||
|
||||
/* protocol specific suspend/resume */
|
||||
|
@ -358,20 +413,12 @@ extern struct bus_type pnp_bus_type;
|
|||
#if defined(CONFIG_PNP)
|
||||
|
||||
/* device management */
|
||||
int pnp_register_protocol(struct pnp_protocol *protocol);
|
||||
void pnp_unregister_protocol(struct pnp_protocol *protocol);
|
||||
int pnp_add_device(struct pnp_dev *dev);
|
||||
int pnp_device_attach(struct pnp_dev *pnp_dev);
|
||||
void pnp_device_detach(struct pnp_dev *pnp_dev);
|
||||
extern struct list_head pnp_global;
|
||||
extern int pnp_platform_devices;
|
||||
|
||||
/* multidevice card support */
|
||||
int pnp_add_card(struct pnp_card *card);
|
||||
void pnp_remove_card(struct pnp_card *card);
|
||||
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
|
||||
void pnp_remove_card_device(struct pnp_dev *dev);
|
||||
int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card);
|
||||
struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink,
|
||||
const char *id, struct pnp_dev *from);
|
||||
void pnp_release_card_device(struct pnp_dev *dev);
|
||||
|
@ -380,77 +427,42 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
|
|||
extern struct list_head pnp_cards;
|
||||
|
||||
/* resource management */
|
||||
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
|
||||
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
|
||||
int priority);
|
||||
int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data);
|
||||
int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data);
|
||||
int pnp_register_port_resource(struct pnp_option *option,
|
||||
struct pnp_port *data);
|
||||
int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data);
|
||||
void pnp_init_resource_table(struct pnp_resource_table *table);
|
||||
int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
|
||||
int mode);
|
||||
int pnp_auto_config_dev(struct pnp_dev *dev);
|
||||
int pnp_validate_config(struct pnp_dev *dev);
|
||||
int pnp_start_dev(struct pnp_dev *dev);
|
||||
int pnp_stop_dev(struct pnp_dev *dev);
|
||||
int pnp_activate_dev(struct pnp_dev *dev);
|
||||
int pnp_disable_dev(struct pnp_dev *dev);
|
||||
void pnp_resource_change(struct resource *resource, resource_size_t start,
|
||||
resource_size_t size);
|
||||
|
||||
/* protocol helpers */
|
||||
int pnp_is_active(struct pnp_dev *dev);
|
||||
int compare_pnp_id(struct pnp_id *pos, const char *id);
|
||||
int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
|
||||
int pnp_register_driver(struct pnp_driver *drv);
|
||||
void pnp_unregister_driver(struct pnp_driver *drv);
|
||||
|
||||
#else
|
||||
|
||||
/* device management */
|
||||
static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
|
||||
static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
|
||||
static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
|
||||
static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { }
|
||||
|
||||
#define pnp_platform_devices 0
|
||||
|
||||
/* multidevice card support */
|
||||
static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
|
||||
static inline void pnp_remove_card(struct pnp_card *card) { }
|
||||
static inline int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline void pnp_remove_card_device(struct pnp_dev *dev) { }
|
||||
static inline int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) { return -ENODEV; }
|
||||
static inline struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, const char *id, struct pnp_dev *from) { return NULL; }
|
||||
static inline void pnp_release_card_device(struct pnp_dev *dev) { }
|
||||
static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return -ENODEV; }
|
||||
static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
|
||||
|
||||
/* resource management */
|
||||
static inline struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) { return NULL; }
|
||||
static inline struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int priority) { return NULL; }
|
||||
static inline int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { return -ENODEV; }
|
||||
static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; }
|
||||
static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; }
|
||||
static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; }
|
||||
static inline void pnp_init_resource_table(struct pnp_resource_table *table) { }
|
||||
static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
|
||||
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline void pnp_resource_change(struct resource *resource, resource_size_t start, resource_size_t size) { }
|
||||
|
||||
/* protocol helpers */
|
||||
static inline int pnp_is_active(struct pnp_dev *dev) { return 0; }
|
||||
static inline int compare_pnp_id(struct pnp_id *pos, const char *id) { return -ENODEV; }
|
||||
static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
|
||||
static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
|
||||
static inline void pnp_unregister_driver(struct pnp_driver *drv) { }
|
||||
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Include file for the interface to a PnP BIOS
|
||||
*
|
||||
* Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
|
||||
* PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
|
||||
* Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_PNPBIOS_H
|
||||
#define _LINUX_PNPBIOS_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
/*
|
||||
* Return codes
|
||||
*/
|
||||
#define PNP_SUCCESS 0x00
|
||||
#define PNP_NOT_SET_STATICALLY 0x7f
|
||||
#define PNP_UNKNOWN_FUNCTION 0x81
|
||||
#define PNP_FUNCTION_NOT_SUPPORTED 0x82
|
||||
#define PNP_INVALID_HANDLE 0x83
|
||||
#define PNP_BAD_PARAMETER 0x84
|
||||
#define PNP_SET_FAILED 0x85
|
||||
#define PNP_EVENTS_NOT_PENDING 0x86
|
||||
#define PNP_SYSTEM_NOT_DOCKED 0x87
|
||||
#define PNP_NO_ISA_PNP_CARDS 0x88
|
||||
#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
|
||||
#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
|
||||
#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
|
||||
#define PNP_BUFFER_TOO_SMALL 0x8c
|
||||
#define PNP_USE_ESCD_SUPPORT 0x8d
|
||||
#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
|
||||
#define PNP_HARDWARE_ERROR 0x8f
|
||||
|
||||
#define ESCD_SUCCESS 0x00
|
||||
#define ESCD_IO_ERROR_READING 0x55
|
||||
#define ESCD_INVALID 0x56
|
||||
#define ESCD_BUFFER_TOO_SMALL 0x59
|
||||
#define ESCD_NVRAM_TOO_SMALL 0x5a
|
||||
#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
|
||||
|
||||
/*
|
||||
* Events that can be received by "get event"
|
||||
*/
|
||||
#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
|
||||
#define PNPEV_DOCK_CHANGED 0x0002
|
||||
#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
|
||||
#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
|
||||
#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
|
||||
/* 0x8000 through 0xfffe are OEM defined */
|
||||
|
||||
/*
|
||||
* Messages that should be sent through "send message"
|
||||
*/
|
||||
#define PNPMSG_OK 0x00
|
||||
#define PNPMSG_ABORT 0x01
|
||||
#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
|
||||
#define PNPMSG_POWER_OFF 0x41
|
||||
#define PNPMSG_PNP_OS_ACTIVE 0x42
|
||||
#define PNPMSG_PNP_OS_INACTIVE 0x43
|
||||
|
||||
/*
|
||||
* Plug and Play BIOS flags
|
||||
*/
|
||||
#define PNPBIOS_NO_DISABLE 0x0001
|
||||
#define PNPBIOS_NO_CONFIG 0x0002
|
||||
#define PNPBIOS_OUTPUT 0x0004
|
||||
#define PNPBIOS_INPUT 0x0008
|
||||
#define PNPBIOS_BOOTABLE 0x0010
|
||||
#define PNPBIOS_DOCK 0x0020
|
||||
#define PNPBIOS_REMOVABLE 0x0040
|
||||
#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
|
||||
#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
|
||||
|
||||
/*
|
||||
* Function Parameters
|
||||
*/
|
||||
#define PNPMODE_STATIC 1
|
||||
#define PNPMODE_DYNAMIC 0
|
||||
|
||||
/* 0x8000 through 0xffff are OEM defined */
|
||||
|
||||
#pragma pack(1)
|
||||
struct pnp_dev_node_info {
|
||||
__u16 no_nodes;
|
||||
__u16 max_node_size;
|
||||
};
|
||||
struct pnp_docking_station_info {
|
||||
__u32 location_id;
|
||||
__u32 serial;
|
||||
__u16 capabilities;
|
||||
};
|
||||
struct pnp_isa_config_struc {
|
||||
__u8 revision;
|
||||
__u8 no_csns;
|
||||
__u16 isa_rd_data_port;
|
||||
__u16 reserved;
|
||||
};
|
||||
struct escd_info_struc {
|
||||
__u16 min_escd_write_size;
|
||||
__u16 escd_size;
|
||||
__u32 nv_storage_base;
|
||||
};
|
||||
struct pnp_bios_node {
|
||||
__u16 size;
|
||||
__u8 handle;
|
||||
__u32 eisa_id;
|
||||
__u8 type_code[3];
|
||||
__u16 flags;
|
||||
__u8 data[0];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#ifdef CONFIG_PNPBIOS
|
||||
|
||||
/* non-exported */
|
||||
extern struct pnp_dev_node_info node_info;
|
||||
|
||||
extern int pnp_bios_dev_node_info(struct pnp_dev_node_info *data);
|
||||
extern int pnp_bios_get_dev_node(u8 *nodenum, char config,
|
||||
struct pnp_bios_node *data);
|
||||
extern int pnp_bios_set_dev_node(u8 nodenum, char config,
|
||||
struct pnp_bios_node *data);
|
||||
extern int pnp_bios_get_stat_res(char *info);
|
||||
extern int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data);
|
||||
extern int pnp_bios_escd_info(struct escd_info_struc *data);
|
||||
extern int pnp_bios_read_escd(char *data, u32 nvram_base);
|
||||
extern int pnp_bios_dock_station_info(struct pnp_docking_station_info *data);
|
||||
|
||||
#endif /* CONFIG_PNPBIOS */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_PNPBIOS_H */
|
Загрузка…
Ссылка в новой задаче