aboutsummaryrefslogtreecommitdiff
path: root/drivers/pnp/isapnp/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp/isapnp/core.c')
-rw-r--r--drivers/pnp/isapnp/core.c277
1 files changed, 103 insertions, 174 deletions
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index f1bccdbdeb0..cf88f9b6244 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/isapnp.h>
@@ -380,10 +379,6 @@ static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
*type = (tag >> 3) & 0x0f;
*size = tag & 0x07;
}
-#if 0
- printk(KERN_DEBUG "tag = 0x%x, type = 0x%x, size = %i\n", tag, *type,
- *size);
-#endif
if (*type == 0xff && *size == 0xffff) /* probably invalid data */
return -1;
return 0;
@@ -429,154 +424,135 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
* Add IRQ resource to resources list.
*/
static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[3];
- struct pnp_irq *irq;
unsigned long bits;
+ pnp_irq_mask_t map;
+ unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
isapnp_peek(tmp, size);
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
- return;
bits = (tmp[1] << 8) | tmp[0];
- bitmap_copy(irq->map, &bits, 16);
+
+ bitmap_zero(map.bits, PNP_IRQ_NR);
+ bitmap_copy(map.bits, &bits, 16);
+
if (size > 2)
- irq->flags = tmp[2];
- else
- irq->flags = IORESOURCE_IRQ_HIGHEDGE;
- pnp_register_irq_resource(dev, option, irq);
+ flags = tmp[2];
+
+ pnp_register_irq_resource(dev, option_flags, &map, flags);
}
/*
* Add DMA resource to resources list.
*/
static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[2];
- struct pnp_dma *dma;
isapnp_peek(tmp, size);
- dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!dma)
- return;
- dma->map = tmp[0];
- dma->flags = tmp[1];
- pnp_register_dma_resource(dev, option, dma);
+ pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
}
/*
* Add port resource to resources list.
*/
static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[7];
- struct pnp_port *port;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = (tmp[2] << 8) | tmp[1];
- port->max = (tmp[4] << 8) | tmp[3];
- port->align = tmp[5];
- port->size = tmp[6];
- port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
- pnp_register_port_resource(dev, option, port);
+ min = (tmp[2] << 8) | tmp[1];
+ max = (tmp[4] << 8) | tmp[3];
+ align = tmp[5];
+ len = tmp[6];
+ flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
+ pnp_register_port_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add fixed port resource to resources list.
*/
static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[3];
- struct pnp_port *port;
+ resource_size_t base, len;
isapnp_peek(tmp, size);
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = port->max = (tmp[1] << 8) | tmp[0];
- port->size = tmp[2];
- port->align = 0;
- port->flags = PNP_PORT_FLAG_FIXED;
- pnp_register_port_resource(dev, option, port);
+ base = (tmp[1] << 8) | tmp[0];
+ len = tmp[2];
+ pnp_register_port_resource(dev, option_flags, base, base, 0, len,
+ IORESOURCE_IO_FIXED);
}
/*
* Add memory resource to resources list.
*/
static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[9];
- struct pnp_mem *mem;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
- mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
- mem->align = (tmp[6] << 8) | tmp[5];
- mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ min = ((tmp[2] << 8) | tmp[1]) << 8;
+ max = ((tmp[4] << 8) | tmp[3]) << 8;
+ align = (tmp[6] << 8) | tmp[5];
+ len = ((tmp[8] << 8) | tmp[7]) << 8;
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add 32-bit memory resource to resources list.
*/
static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[17];
- struct pnp_mem *mem;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
- mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
- mem->align =
- (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
- mem->size =
- (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+ max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+ align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
+ len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add 32-bit fixed memory resource to resources list.
*/
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[9];
- struct pnp_mem *mem;
+ resource_size_t base, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = mem->max =
- (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
- mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
- mem->align = 0;
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+ len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
}
/*
@@ -604,20 +580,16 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
static int __init isapnp_create_device(struct pnp_card *card,
unsigned short size)
{
- int number = 0, skip = 0, priority = 0, compat = 0;
+ int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17];
- struct pnp_option *option;
+ unsigned int option_flags;
struct pnp_dev *dev;
u32 eisa_id;
char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- option = pnp_register_independent_option(dev);
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = 0;
pnp_add_card_device(card, dev);
while (1) {
@@ -634,16 +606,11 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1;
size = 0;
skip = 0;
- option = pnp_register_independent_option(dev);
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = 0;
pnp_add_card_device(card, dev);
} else {
skip = 1;
}
- priority = 0;
compat = 0;
break;
case _STAG_COMPATDEVID:
@@ -660,44 +627,42 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_IRQ:
if (size < 2 || size > 3)
goto __skip;
- isapnp_parse_irq_resource(dev, option, size);
+ isapnp_parse_irq_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_DMA:
if (size != 2)
goto __skip;
- isapnp_parse_dma_resource(dev, option, size);
+ isapnp_parse_dma_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_STARTDEP:
if (size > 1)
goto __skip;
- priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+ priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) {
isapnp_peek(tmp, size);
- priority = 0x100 | tmp[0];
+ priority = tmp[0];
size = 0;
}
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return 1;
+ option_flags = pnp_new_dependent_set(dev, priority);
break;
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
- priority = 0;
- dev_dbg(&dev->dev, "end dependent options\n");
+ option_flags = 0;
break;
case _STAG_IOPORT:
if (size != 7)
goto __skip;
- isapnp_parse_port_resource(dev, option, size);
+ isapnp_parse_port_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_FIXEDIO:
if (size != 3)
goto __skip;
- isapnp_parse_fixed_port_resource(dev, option, size);
+ isapnp_parse_fixed_port_resource(dev, option_flags,
+ size);
size = 0;
break;
case _STAG_VENDOR:
@@ -705,7 +670,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEMRANGE:
if (size != 9)
goto __skip;
- isapnp_parse_mem_resource(dev, option, size);
+ isapnp_parse_mem_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_ANSISTR:
@@ -720,13 +685,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEM32RANGE:
if (size != 17)
goto __skip;
- isapnp_parse_mem32_resource(dev, option, size);
+ isapnp_parse_mem32_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_FIXEDMEM32RANGE:
if (size != 9)
goto __skip;
- isapnp_parse_fixed_mem32_resource(dev, option, size);
+ isapnp_parse_fixed_mem32_resource(dev, option_flags,
+ size);
size = 0;
break;
case _STAG_END:
@@ -843,13 +809,6 @@ static int __init isapnp_build_device_list(void)
if (!card)
continue;
-#if 0
- 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]);
- dev_info(&card->dev, "checksum = %#x\n", checksum);
-#endif
INIT_LIST_HEAD(&card->devices);
card->serial =
(header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
@@ -928,10 +887,9 @@ EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_get_resources(struct pnp_dev *dev)
{
- struct pnp_resource *pnp_res;
int i, ret;
- dev_dbg(&dev->dev, "get resources\n");
+ pnp_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);
@@ -940,35 +898,23 @@ static int isapnp_get_resources(struct pnp_dev *dev)
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;
- }
+ pnp_add_io_resource(dev, ret, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
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;
- }
+ pnp_add_mem_resource(dev, ret, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
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;
- }
+ pnp_add_irq_resource(dev, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
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;
- }
+ pnp_add_dma_resource(dev, ret,
+ ret == 4 ? IORESOURCE_DISABLED : 0);
}
__end:
@@ -978,62 +924,45 @@ __end:
static int isapnp_set_resources(struct pnp_dev *dev)
{
- struct pnp_resource *pnp_res;
struct resource *res;
- int tmp, index;
+ int tmp;
- dev_dbg(&dev->dev, "set resources\n");
+ pnp_dbg(&dev->dev, "set resources\n");
isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1;
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 = pnp_get_resource(dev, IORESOURCE_IO, tmp);
+ if (pnp_resource_enabled(res)) {
+ pnp_dbg(&dev->dev, " set io %d to %#llx\n",
+ tmp, (unsigned long long) res->start);
+ isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 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)) {
+ res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
+ if (pnp_resource_enabled(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);
+ pnp_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq);
+ isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 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);
+ res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
+ if (pnp_resource_enabled(res)) {
+ pnp_dbg(&dev->dev, " set dma %d to %lld\n",
+ tmp, (unsigned long long) res->start);
+ isapnp_write_byte(ISAPNP_CFG_DMA + tmp, 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 = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
+ if (pnp_resource_enabled(res)) {
+ pnp_dbg(&dev->dev, " set mem %d to %#llx\n",
+ tmp, (unsigned long long) res->start);
+ isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
(res->start >> 8) & 0xffff);
}
}
@@ -1071,7 +1000,7 @@ static int __init isapnp_init(void)
printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
return 0;
}
-#ifdef CONFIG_PPC_MERGE
+#ifdef CONFIG_PPC
if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
return -EINVAL;
#endif