Commit 4a554b57 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/pnp-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 9179a307 e4efb4bf
...@@ -4,15 +4,17 @@ ...@@ -4,15 +4,17 @@
mainmenu_option next_comment mainmenu_option next_comment
comment 'Plug and Play configuration' comment 'Plug and Play configuration'
dep_bool 'Plug and Play support' CONFIG_PNP bool 'Plug and Play support' CONFIG_PNP
dep_bool ' Plug and Play device name database' CONFIG_PNP_NAMES $CONFIG_PNP if [ "$CONFIG_PNP" = "y" ]; then
dep_bool ' PnP Debug Messages' CONFIG_PNP_DEBUG $CONFIG_PNP bool ' Plug and Play device name database' CONFIG_PNP_NAMES
bool ' PnP Debug Messages' CONFIG_PNP_DEBUG
comment 'Protocols' $CONFIG_PNP comment 'Protocols'
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_bool ' ISA Plug and Play support (EXPERIMENTAL)' CONFIG_ISAPNP $CONFIG_PNP bool ' ISA Plug and Play support (EXPERIMENTAL)' CONFIG_ISAPNP
dep_bool ' Plug and Play BIOS support (EXPERIMENTAL)' CONFIG_PNPBIOS $CONFIG_PNP bool ' Plug and Play BIOS support (EXPERIMENTAL)' CONFIG_PNPBIOS
fi
fi fi
endmenu endmenu
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
# Makefile for the Linux Plug-and-Play Support. # Makefile for the Linux Plug-and-Play Support.
# #
obj-y := core.o driver.o resource.o interface.o quirks.o names.o compat.o system.o obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o
obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/ obj-$(CONFIG_ISAPNP) += isapnp/
export-objs := core.o driver.o resource.o compat.o export-objs := core.o driver.o resource.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -4,8 +4,5 @@ extern void *pnp_alloc(long size); ...@@ -4,8 +4,5 @@ extern void *pnp_alloc(long size);
extern int pnp_interface_attach_device(struct pnp_dev *dev); extern int pnp_interface_attach_device(struct pnp_dev *dev);
extern void pnp_name_device(struct pnp_dev *dev); extern void pnp_name_device(struct pnp_dev *dev);
extern void pnp_fixup_device(struct pnp_dev *dev); extern void pnp_fixup_device(struct pnp_dev *dev);
extern int compare_pnp_id(struct list_head * id_list, char * id);
extern void pnp_free_ids(struct pnp_dev *dev); extern void pnp_free_ids(struct pnp_dev *dev);
extern void pnp_free_resources(struct pnp_resources *resources); extern void pnp_free_resources(struct pnp_resources *resources);
...@@ -82,7 +82,6 @@ void pnp_protocol_unregister(struct pnp_protocol *protocol) ...@@ -82,7 +82,6 @@ void pnp_protocol_unregister(struct pnp_protocol *protocol)
list_del_init(&protocol->protocol_list); list_del_init(&protocol->protocol_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
device_unregister(&protocol->dev); device_unregister(&protocol->dev);
return;
} }
/** /**
...@@ -105,7 +104,6 @@ static void pnp_release_device(struct device *dmdev) ...@@ -105,7 +104,6 @@ static void pnp_release_device(struct device *dmdev)
pnp_free_resources(dev->res); pnp_free_resources(dev->res);
pnp_free_ids(dev); pnp_free_ids(dev);
kfree(dev); kfree(dev);
return;
} }
/** /**
...@@ -118,7 +116,7 @@ static void pnp_release_device(struct device *dmdev) ...@@ -118,7 +116,7 @@ static void pnp_release_device(struct device *dmdev)
int pnp_add_device(struct pnp_dev *dev) int pnp_add_device(struct pnp_dev *dev)
{ {
int error = 0; int error = 0;
if (!dev && !dev->protocol) if (!dev || !dev->protocol)
return -EINVAL; return -EINVAL;
if (dev->card) if (dev->card)
sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number, sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number,
...@@ -158,7 +156,6 @@ void pnp_remove_device(struct pnp_dev *dev) ...@@ -158,7 +156,6 @@ void pnp_remove_device(struct pnp_dev *dev)
list_del_init(&dev->global_list); list_del_init(&dev->global_list);
list_del_init(&dev->dev_list); list_del_init(&dev->dev_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
return;
} }
static int __init pnp_init(void) static int __init pnp_init(void)
......
...@@ -93,7 +93,7 @@ static int pnp_device_probe(struct device *dev) ...@@ -93,7 +93,7 @@ static int pnp_device_probe(struct device *dev)
if (pnp_dev->active == 0) if (pnp_dev->active == 0)
if(pnp_activate_dev(pnp_dev)<0) if(pnp_activate_dev(pnp_dev)<0)
return 0; return -1;
if (pnp_drv->probe && pnp_dev->active) { if (pnp_drv->probe && pnp_dev->active) {
if (pnp_dev->card && pnp_drv->card_id_table){ if (pnp_dev->card && pnp_drv->card_id_table){
card_id = match_card(pnp_drv, pnp_dev->card); card_id = match_card(pnp_drv, pnp_dev->card);
...@@ -150,7 +150,9 @@ struct bus_type pnp_bus_type = { ...@@ -150,7 +150,9 @@ struct bus_type pnp_bus_type = {
int pnp_register_driver(struct pnp_driver *drv) int pnp_register_driver(struct pnp_driver *drv)
{ {
int count = 0; int count;
struct list_head *pos;
pnp_dbg("the driver '%s' has been registered", drv->name); pnp_dbg("the driver '%s' has been registered", drv->name);
drv->driver.name = drv->name; drv->driver.name = drv->name;
...@@ -159,13 +161,21 @@ int pnp_register_driver(struct pnp_driver *drv) ...@@ -159,13 +161,21 @@ int pnp_register_driver(struct pnp_driver *drv)
drv->driver.remove = pnp_device_remove; drv->driver.remove = pnp_device_remove;
count = driver_register(&drv->driver); count = driver_register(&drv->driver);
return count ? count : 1;
/* get the number of initial matches */
if (count >= 0){
count = 0;
list_for_each(pos,&drv->driver.devices){
count++;
}
}
return count;
} }
void pnp_unregister_driver(struct pnp_driver *drv) void pnp_unregister_driver(struct pnp_driver *drv)
{ {
pnp_dbg("the driver '%s' has been unregistered", drv->name); pnp_dbg("the driver '%s' has been unregistered", drv->name);
remove_driver(&drv->driver); driver_unregister(&drv->driver);
} }
/** /**
...@@ -194,7 +204,6 @@ void pnp_free_ids(struct pnp_dev *dev) ...@@ -194,7 +204,6 @@ void pnp_free_ids(struct pnp_dev *dev)
struct pnp_id *pnp_id = to_pnp_id(pos); struct pnp_id *pnp_id = to_pnp_id(pos);
kfree(pnp_id); kfree(pnp_id);
} }
return;
} }
EXPORT_SYMBOL(pnp_register_driver); EXPORT_SYMBOL(pnp_register_driver);
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
# Makefile for the kernel ISAPNP driver. # Makefile for the kernel ISAPNP driver.
# #
export-objs := core.o export-objs := core.o compat.o
isapnp-proc-$(CONFIG_PROC_FS) = proc.o isapnp-proc-$(CONFIG_PROC_FS) = proc.o
obj-y := core.o $(isapnp-proc-y) obj-y := core.o compat.o $(isapnp-proc-y)
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/isapnp.h> #include <linux/isapnp.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/module.h> #include <linux/module.h>
#include "base.h"
static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short device) static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short device)
{ {
...@@ -24,7 +23,6 @@ static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short devi ...@@ -24,7 +23,6 @@ static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short devi
device & 0x0f, device & 0x0f,
(device >> 12) & 0x0f, (device >> 12) & 0x0f,
(device >> 8) & 0x0f); (device >> 8) & 0x0f);
return;
} }
struct pnp_card *pnp_find_card(unsigned short vendor, struct pnp_card *pnp_find_card(unsigned short vendor,
......
...@@ -37,7 +37,6 @@ pnp_name_device(struct pnp_dev *dev) ...@@ -37,7 +37,6 @@ pnp_name_device(struct pnp_dev *dev)
return; return;
} }
} }
return;
} }
#else #else
......
...@@ -680,7 +680,7 @@ static void add_irqresource(struct pnp_dev *dev, int irq) ...@@ -680,7 +680,7 @@ static void add_irqresource(struct pnp_dev *dev, int irq)
static void add_dmaresource(struct pnp_dev *dev, int dma) static void add_dmaresource(struct pnp_dev *dev, int dma)
{ {
int i = 8; int i = 0;
while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++; while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++;
if (i < DEVICE_COUNT_DMA) { if (i < DEVICE_COUNT_DMA) {
dev->dma_resource[i].start = (unsigned long) dma; dev->dma_resource[i].start = (unsigned long) dma;
...@@ -701,7 +701,7 @@ static void add_ioresource(struct pnp_dev *dev, int io, int len) ...@@ -701,7 +701,7 @@ static void add_ioresource(struct pnp_dev *dev, int io, int len)
static void add_memresource(struct pnp_dev *dev, int mem, int len) static void add_memresource(struct pnp_dev *dev, int mem, int len)
{ {
int i = 0; int i = 8;
while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++; while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
if (i < DEVICE_COUNT_RESOURCE) { if (i < DEVICE_COUNT_RESOURCE) {
dev->resource[i].start = (unsigned long) mem; dev->resource[i].start = (unsigned long) mem;
...@@ -816,6 +816,7 @@ static unsigned char *node_current_resource_data_to_dev(struct pnp_bios_node *no ...@@ -816,6 +816,7 @@ static unsigned char *node_current_resource_data_to_dev(struct pnp_bios_node *no
} /* while */ } /* while */
end: end:
if ((dev->resource[0].start == 0) && if ((dev->resource[0].start == 0) &&
(dev->resource[8].start == 0) &&
(dev->irq_resource[0].start == -1) && (dev->irq_resource[0].start == -1) &&
(dev->dma_resource[0].start == -1)) (dev->dma_resource[0].start == -1))
dev->active = 0; dev->active = 0;
...@@ -927,7 +928,6 @@ static void read_smtag_fport(unsigned char *p, int size, int depnum, struct pnp_ ...@@ -927,7 +928,6 @@ static void read_smtag_fport(unsigned char *p, int size, int depnum, struct pnp_
static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struct pnp_bios_node *node, struct pnp_dev *dev) static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struct pnp_bios_node *node, struct pnp_dev *dev)
{ {
unsigned char *lastp = NULL;
int len, depnum, dependent; int len, depnum, dependent;
if ((char *)p == NULL) if ((char *)p == NULL)
...@@ -963,8 +963,7 @@ static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struc ...@@ -963,8 +963,7 @@ static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struc
break; break;
} }
} /* switch */ } /* switch */
lastp = p+3; p += len + 3;
p = p + p[1] + p[2]*256 + 3;
continue; continue;
} }
len = p[0] & 0x07; len = p[0] & 0x07;
...@@ -1030,6 +1029,70 @@ static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struc ...@@ -1030,6 +1029,70 @@ static unsigned char *node_possible_resource_data_to_dev(unsigned char *p, struc
return NULL; return NULL;
} }
/* pnp EISA ids */
#define HEX(id,a) hex[((id)>>a) & 15]
#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
//
static void inline 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';
return;
}
//
#undef CHAR
#undef HEX
static void node_id_data_to_dev(unsigned char *p, struct pnp_bios_node *node, struct pnp_dev *dev)
{
int len;
struct pnp_id *dev_id;
if ((char *)p == NULL)
return;
while ( (char *)p < ((char *)node->data + node->size )) {
if( p[0] & 0x80 ) {// large item
len = (p[2] << 8) | p[1];
p += len + 3;
continue;
}
len = p[0] & 0x07;
switch ((p[0]>>3) & 0x0f) {
case 0x0f:
{
return;
break;
}
case 0x03: // compatible ID
{
if (len != 4)
goto __skip;
dev_id = pnpbios_kmalloc(sizeof (struct pnp_id), GFP_KERNEL);
if (!dev_id)
return;
pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,dev_id->id);
pnp_add_id(dev_id, dev);
break;
}
} /* switch */
__skip:
p += len + 1;
} /* while */
}
/* pnp resource writing functions */ /* pnp resource writing functions */
...@@ -1314,31 +1377,6 @@ static int inline insert_device(struct pnp_dev *dev) ...@@ -1314,31 +1377,6 @@ static int inline insert_device(struct pnp_dev *dev)
return 0; return 0;
} }
#define HEX(id,a) hex[((id)>>a) & 15]
#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
//
static void inline 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';
return;
}
//
#undef CHAR
#undef HEX
static void __init build_devlist(void) static void __init build_devlist(void)
{ {
u8 nodenum; u8 nodenum;
...@@ -1386,7 +1424,8 @@ static void __init build_devlist(void) ...@@ -1386,7 +1424,8 @@ static void __init build_devlist(void)
memcpy(dev_id->id,id,8); memcpy(dev_id->id,id,8);
pnp_add_id(dev_id, dev); pnp_add_id(dev_id, dev);
pos = node_current_resource_data_to_dev(node,dev); pos = node_current_resource_data_to_dev(node,dev);
node_possible_resource_data_to_dev(pos,node,dev); pos = node_possible_resource_data_to_dev(pos,node,dev);
node_id_data_to_dev(pos,node,dev);
dev->protocol = &pnpbios_protocol; dev->protocol = &pnpbios_protocol;
......
...@@ -164,6 +164,5 @@ void pnp_fixup_device(struct pnp_dev *dev) ...@@ -164,6 +164,5 @@ void pnp_fixup_device(struct pnp_dev *dev)
} }
i++; i++;
} }
return;
} }
...@@ -308,7 +308,7 @@ void pnp_free_resources(struct pnp_resources *resources) ...@@ -308,7 +308,7 @@ void pnp_free_resources(struct pnp_resources *resources)
/* resource validity checking functions */ /* resource validity checking functions */
static int pnp_check_port(int port, int size) static int pnp_check_port(int port, int size, int idx, struct pnp_cfg *config)
{ {
int i, tmp, rport, rsize; int i, tmp, rport, rsize;
struct pnp_dev *dev; struct pnp_dev *dev;
...@@ -338,10 +338,20 @@ static int pnp_check_port(int port, int size) ...@@ -338,10 +338,20 @@ static int pnp_check_port(int port, int size)
} }
} }
} }
for (tmp = 0; tmp < 8 && tmp != idx; tmp++) {
if (dev->resource[tmp].flags) {
rport = config->request.resource[tmp].start;
rsize = (config->request.resource[tmp].end - rport) + 1;
if (port >= rport && port < rport + rsize)
return 1;
if (port + size > rport && port + size < (rport + rsize) - 1)
return 1;
}
}
return 0; return 0;
} }
static int pnp_check_mem(unsigned int addr, unsigned int size) static int pnp_check_mem(unsigned int addr, unsigned int size, int idx, struct pnp_cfg *config)
{ {
int i, tmp; int i, tmp;
unsigned int raddr, rsize; unsigned int raddr, rsize;
...@@ -360,7 +370,7 @@ static int pnp_check_mem(unsigned int addr, unsigned int size) ...@@ -360,7 +370,7 @@ static int pnp_check_mem(unsigned int addr, unsigned int size)
pnp_for_each_dev(dev) { pnp_for_each_dev(dev) {
if (dev->active) { if (dev->active) {
for (tmp = 0; tmp < 4; tmp++) { for (tmp = 0; tmp < 4; tmp++) {
if (dev->resource[tmp].flags) { if (dev->resource[tmp + 8].flags) {
raddr = dev->resource[tmp + 8].start; raddr = dev->resource[tmp + 8].start;
rsize = (dev->resource[tmp + 8].end - raddr) + 1; rsize = (dev->resource[tmp + 8].end - raddr) + 1;
if (addr >= raddr && addr < raddr + rsize) if (addr >= raddr && addr < raddr + rsize)
...@@ -371,6 +381,16 @@ static int pnp_check_mem(unsigned int addr, unsigned int size) ...@@ -371,6 +381,16 @@ static int pnp_check_mem(unsigned int addr, unsigned int size)
} }
} }
} }
for (tmp = 0; tmp < 4 && tmp != idx; tmp++) {
if (dev->resource[tmp + 8].flags) {
raddr = config->request.resource[tmp + 8].start;
rsize = (config->request.resource[tmp + 8].end - raddr) + 1;
if (addr >= raddr && addr < raddr + rsize)
return 1;
if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
return 1;
}
}
return 0; return 0;
} }
...@@ -453,10 +473,11 @@ static int pnp_check_dma(int dma, struct pnp_cfg *config) ...@@ -453,10 +473,11 @@ static int pnp_check_dma(int dma, struct pnp_cfg *config)
/* config generation functions */ /* config generation functions */
static int pnp_generate_port(struct pnp_cfg *config, int num) static int pnp_generate_port(struct pnp_cfg *config, int num)
{ {
struct pnp_port *port = config->port[num]; struct pnp_port *port;
unsigned long *value1, *value2, *value3; unsigned long *value1, *value2, *value3;
if (!config || num < 0 || num > 7) if (!config || num < 0 || num > 7)
return -EINVAL; return -EINVAL;
port = config->port[num];
if (!port) if (!port)
return 0; return 0;
value1 = &config->request.resource[num].start; value1 = &config->request.resource[num].start;
...@@ -465,7 +486,7 @@ static int pnp_generate_port(struct pnp_cfg *config, int num) ...@@ -465,7 +486,7 @@ static int pnp_generate_port(struct pnp_cfg *config, int num)
*value1 = port->min; *value1 = port->min;
*value2 = *value1 + port->size -1; *value2 = *value1 + port->size -1;
*value3 = port->flags | IORESOURCE_IO; *value3 = port->flags | IORESOURCE_IO;
while (pnp_check_port(*value1, port->size)) { while (pnp_check_port(*value1, port->size, num, config)) {
*value1 += port->align; *value1 += port->align;
*value2 = *value1 + port->size - 1; *value2 = *value1 + port->size - 1;
if (*value1 > port->max || !port->align) if (*value1 > port->max || !port->align)
...@@ -476,10 +497,11 @@ static int pnp_generate_port(struct pnp_cfg *config, int num) ...@@ -476,10 +497,11 @@ static int pnp_generate_port(struct pnp_cfg *config, int num)
static int pnp_generate_mem(struct pnp_cfg *config, int num) static int pnp_generate_mem(struct pnp_cfg *config, int num)
{ {
struct pnp_mem *mem = config->mem[num]; struct pnp_mem *mem;
unsigned long *value1, *value2, *value3; unsigned long *value1, *value2, *value3;
if (!config || num < 0 || num > 3) if (!config || num < 0 || num > 3)
return -EINVAL; return -EINVAL;
mem = config->mem[num];
if (!mem) if (!mem)
return 0; return 0;
value1 = &config->request.resource[num + 8].start; value1 = &config->request.resource[num + 8].start;
...@@ -496,7 +518,7 @@ static int pnp_generate_mem(struct pnp_cfg *config, int num) ...@@ -496,7 +518,7 @@ static int pnp_generate_mem(struct pnp_cfg *config, int num)
*value3 |= IORESOURCE_RANGELENGTH; *value3 |= IORESOURCE_RANGELENGTH;
if (mem->flags & IORESOURCE_MEM_SHADOWABLE) if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
*value3 |= IORESOURCE_SHADOWABLE; *value3 |= IORESOURCE_SHADOWABLE;
while (pnp_check_mem(*value1, mem->size)) { while (pnp_check_mem(*value1, mem->size, num, config)) {
*value1 += mem->align; *value1 += mem->align;
*value2 = *value1 + mem->size - 1; *value2 = *value1 + mem->size - 1;
if (*value1 > mem->max || !mem->align) if (*value1 > mem->max || !mem->align)
...@@ -507,7 +529,7 @@ static int pnp_generate_mem(struct pnp_cfg *config, int num) ...@@ -507,7 +529,7 @@ static int pnp_generate_mem(struct pnp_cfg *config, int num)
static int pnp_generate_irq(struct pnp_cfg *config, int num) static int pnp_generate_irq(struct pnp_cfg *config, int num)
{ {
struct pnp_irq *irq = config->irq[num]; struct pnp_irq *irq;
unsigned long *value1, *value2, *value3; unsigned long *value1, *value2, *value3;
/* IRQ priority: this table is good for i386 */ /* IRQ priority: this table is good for i386 */
static unsigned short xtab[16] = { static unsigned short xtab[16] = {
...@@ -516,6 +538,7 @@ static int pnp_generate_irq(struct pnp_cfg *config, int num) ...@@ -516,6 +538,7 @@ static int pnp_generate_irq(struct pnp_cfg *config, int num)
int i; int i;
if (!config || num < 0 || num > 1) if (!config || num < 0 || num > 1)
return -EINVAL; return -EINVAL;
irq = config->irq[num];
if (!irq) if (!irq)
return 0; return 0;
value1 = &config->request.irq_resource[num].start; value1 = &config->request.irq_resource[num].start;
...@@ -536,16 +559,16 @@ static int pnp_generate_irq(struct pnp_cfg *config, int num) ...@@ -536,16 +559,16 @@ static int pnp_generate_irq(struct pnp_cfg *config, int num)
static int pnp_generate_dma(struct pnp_cfg *config, int num) static int pnp_generate_dma(struct pnp_cfg *config, int num)
{ {
struct pnp_dma *dma = config->dma[num]; struct pnp_dma *dma;
unsigned long *value1, *value2, *value3; unsigned long *value1, *value2, *value3;
/* DMA priority: this table is good for i386 */ /* DMA priority: this table is good for i386 */
static unsigned short xtab[16] = { static unsigned short xtab[16] = {
1, 3, 5, 6, 7, 0, 2, 4 1, 3, 5, 6, 7, 0, 2, 4
}; };
int i; int i;
if (!config || num < 0 || num > 1) if (!config || num < 0 || num > 1)
return -EINVAL; return -EINVAL;
dma = config->dma[num];
if (!dma) if (!dma)
return 0; return 0;
value1 = &config->request.dma_resource[num].start; value1 = &config->request.dma_resource[num].start;
...@@ -566,10 +589,11 @@ static int pnp_generate_dma(struct pnp_cfg *config, int num) ...@@ -566,10 +589,11 @@ static int pnp_generate_dma(struct pnp_cfg *config, int num)
static int pnp_prepare_request(struct pnp_cfg *config) static int pnp_prepare_request(struct pnp_cfg *config)
{ {
struct pnp_dev *dev = &config->request; struct pnp_dev *dev;
int idx; int idx;
if (!config) if (!config)
return -EINVAL; return -EINVAL;
dev = &config->request;
if (dev == NULL) if (dev == NULL)
return -EINVAL; return -EINVAL;
if (dev->active || dev->ro) if (dev->active || dev->ro)
...@@ -629,21 +653,29 @@ static int pnp_generate_request(struct pnp_cfg *config) ...@@ -629,21 +653,29 @@ static int pnp_generate_request(struct pnp_cfg *config)
static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum) static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum)
{ {
struct pnp_cfg * config = pnp_alloc(sizeof(struct pnp_cfg)); struct pnp_cfg * config;
int nport = 0, nirq = 0, ndma = 0, nmem = 0; int nport = 0, nirq = 0, ndma = 0, nmem = 0;
struct pnp_resources * res = dev->res; struct pnp_resources * res;
struct pnp_port * port = res->port; struct pnp_port * port;
struct pnp_mem * mem = res->mem; struct pnp_mem * mem;
struct pnp_irq * irq = res->irq; struct pnp_irq * irq;
struct pnp_dma * dma = res->dma; struct pnp_dma * dma;
if (!dev) if (!dev)
return NULL; return NULL;
if (depnum < 0) if (depnum < 0)
return NULL; return NULL;
config = pnp_alloc(sizeof(struct pnp_cfg));
if (!config) if (!config)
return NULL; return NULL;
/* independent */ /* independent */
res = pnp_find_resources(dev, 0);
if (!res)
goto fail;
port = res->port;
mem = res->mem;
irq = res->irq;
dma = res->dma;
while (port){ while (port){
config->port[nport] = port; config->port[nport] = port;
nport++; nport++;
...@@ -669,6 +701,8 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum) ...@@ -669,6 +701,8 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum)
if (depnum == 0) if (depnum == 0)
return config; return config;
res = pnp_find_resources(dev, depnum); res = pnp_find_resources(dev, depnum);
if (!res)
goto fail;
port = res->port; port = res->port;
mem = res->mem; mem = res->mem;
irq = res->irq; irq = res->irq;
...@@ -695,6 +729,10 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum) ...@@ -695,6 +729,10 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum)
dma = dma->next; dma = dma->next;
} }
return config; return config;
fail:
kfree(config);
return NULL;
} }
/* PnP Device Resource Management */ /* PnP Device Resource Management */
......
...@@ -94,7 +94,6 @@ struct pnp_driver { ...@@ -94,7 +94,6 @@ struct pnp_driver {
int (*probe) (struct pnp_dev *dev, const struct pnp_id *card_id, int (*probe) (struct pnp_dev *dev, const struct pnp_id *card_id,
const struct pnp_id *dev_id); const struct pnp_id *dev_id);
void (*remove) (struct pnp_dev *dev); void (*remove) (struct pnp_dev *dev);
struct device * (*legacy) (void);
struct device_driver driver; struct device_driver driver;
}; };
...@@ -227,20 +226,11 @@ int pnp_disable_dev(struct pnp_dev *dev); ...@@ -227,20 +226,11 @@ int pnp_disable_dev(struct pnp_dev *dev);
int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode); int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode);
/* driver */ /* driver */
int compare_pnp_id(struct list_head * id_list, const char * id);
int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev); int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
int pnp_register_driver(struct pnp_driver *drv); int pnp_register_driver(struct pnp_driver *drv);
void pnp_unregister_driver(struct pnp_driver *drv); void pnp_unregister_driver(struct pnp_driver *drv);
/* compat */
struct pnp_card *pnp_find_card(unsigned short vendor,
unsigned short device,
struct pnp_card *from);
struct pnp_dev *pnp_find_dev(struct pnp_card *card,
unsigned short vendor,
unsigned short function,
struct pnp_dev *from);
#else #else
/* just in case anyone decides to call these without PnP Support Enabled */ /* just in case anyone decides to call these without PnP Support Enabled */
...@@ -260,9 +250,25 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct ...@@ -260,9 +250,25 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct
static inline int pnp_activate_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 int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode) { return -ENODEV; } static inline int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode) { return -ENODEV; }
static inline int compare_pnp_id(struct list_head * id_list, char * id) { return -ENODEV; }
static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { 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 int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; } static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
#endif /* CONFIG_PNP */
#if defined(CONFIG_ISAPNP)
/* compat */
struct pnp_card *pnp_find_card(unsigned short vendor,
unsigned short device,
struct pnp_card *from);
struct pnp_dev *pnp_find_dev(struct pnp_card *card,
unsigned short vendor,
unsigned short function,
struct pnp_dev *from);
#else
static inline struct pnp_card *pnp_find_card(unsigned short vendor, static inline struct pnp_card *pnp_find_card(unsigned short vendor,
unsigned short device, unsigned short device,
struct pnp_card *from) { return NULL; } struct pnp_card *from) { return NULL; }
...@@ -271,7 +277,7 @@ static inline struct pnp_dev *pnp_find_dev(struct pnp_card *card, ...@@ -271,7 +277,7 @@ static inline struct pnp_dev *pnp_find_dev(struct pnp_card *card,
unsigned short function, unsigned short function,
struct pnp_dev *from) { return NULL; } struct pnp_dev *from) { return NULL; }
#endif /* CONFIG_PNP */ #endif /* CONFIG_ISAPNP */
#ifdef DEBUG #ifdef DEBUG
......
...@@ -3026,8 +3026,6 @@ static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_ ...@@ -3026,8 +3026,6 @@ static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_
{ {
char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name; char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
printk(KERN_INFO "ad1848: %s detected\n", busname);
/* Initialize this baby. */ /* Initialize this baby. */
if(ad1848_init_generic(bus, hw_config, slot)) { if(ad1848_init_generic(bus, hw_config, slot)) {
...@@ -3039,9 +3037,6 @@ static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_ ...@@ -3039,9 +3037,6 @@ static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_
hw_config->dma2); hw_config->dma2);
return 1; return 1;
} }
else
printk(KERN_INFO "ad1848: Failed to initialize %s\n", busname);
return 0; return 0;
} }
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/isapnp.h> #include <linux/pnp.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -71,7 +71,7 @@ static int mpu_base = 0, mpu_irq = 0; ...@@ -71,7 +71,7 @@ static int mpu_base = 0, mpu_irq = 0;
static int synth_base = 0, synth_irq = 0; static int synth_base = 0, synth_irq = 0;
static int mpu_detected = 0; static int mpu_detected = 0;
int __init probe_cs4232_mpu(struct address_info *hw_config) int probe_cs4232_mpu(struct address_info *hw_config)
{ {
/* /*
* Just write down the config values. * Just write down the config values.
...@@ -83,7 +83,7 @@ int __init probe_cs4232_mpu(struct address_info *hw_config) ...@@ -83,7 +83,7 @@ int __init probe_cs4232_mpu(struct address_info *hw_config)
return 1; return 1;
} }
static unsigned char crystal_key[] __initdata = /* A 32 byte magic key sequence */ static unsigned char crystal_key[] = /* A 32 byte magic key sequence */
{ {
0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc, 0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2, 0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2,
...@@ -97,7 +97,7 @@ static void sleep(unsigned howlong) ...@@ -97,7 +97,7 @@ static void sleep(unsigned howlong)
schedule_timeout(howlong); schedule_timeout(howlong);
} }
int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) int probe_cs4232(struct address_info *hw_config, int isapnp_configured)
{ {
int i, n; int i, n;
int base = hw_config->io_base, irq = hw_config->irq; int base = hw_config->io_base, irq = hw_config->irq;
...@@ -218,7 +218,7 @@ int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) ...@@ -218,7 +218,7 @@ int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
return 0; return 0;
} }
void __init attach_cs4232(struct address_info *hw_config) void attach_cs4232(struct address_info *hw_config)
{ {
int base = hw_config->io_base, int base = hw_config->io_base,
irq = hw_config->irq, irq = hw_config->irq,
...@@ -277,7 +277,7 @@ void __init attach_cs4232(struct address_info *hw_config) ...@@ -277,7 +277,7 @@ void __init attach_cs4232(struct address_info *hw_config)
} }
} }
static void __exit unload_cs4232(struct address_info *hw_config) static void unload_cs4232(struct address_info *hw_config)
{ {
int base = hw_config->io_base, irq = hw_config->irq; int base = hw_config->io_base, irq = hw_config->irq;
int dma1 = hw_config->dma, dma2 = hw_config->dma2; int dma1 = hw_config->dma, dma2 = hw_config->dma2;
...@@ -357,48 +357,24 @@ MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)"); ...@@ -357,48 +357,24 @@ MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)");
/* All cs4232 based cards have the main ad1848 card either as CSC0000 or /* All cs4232 based cards have the main ad1848 card either as CSC0000 or
* CSC0100. */ * CSC0100. */
struct isapnp_device_id isapnp_cs4232_list[] __initdata = { static const struct pnp_id cs4232_pnp_table[] = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID, { .id = "CSC0100", .driver_data = 0 },
ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), { .id = "CSC0000", .driver_data = 0 },
0 },
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000),
0 },
/* Guillemot Turtlebeach something appears to be cs4232 compatible /* Guillemot Turtlebeach something appears to be cs4232 compatible
* (untested) */ * (untested) */
{ ISAPNP_VENDOR('C','S','C'), ISAPNP_ANY_ID, { .id = "GIM0100", .driver_data = 0 },
ISAPNP_VENDOR('G','I','M'), ISAPNP_FUNCTION(0x0100), { .id = ""}
0 },
{0}
}; };
MODULE_DEVICE_TABLE(isapnp, isapnp_cs4232_list); /*MODULE_DEVICE_TABLE(isapnp, isapnp_cs4232_list);*/
int cs4232_isapnp_probe(struct pci_dev *dev, const struct isapnp_device_id *id) static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
{ {
int ret;
struct address_info *isapnpcfg; struct address_info *isapnpcfg;
isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL); isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
if (!isapnpcfg) if (!isapnpcfg)
return -ENOMEM; return -ENOMEM;
/*
* If device is active, assume configured with /proc/isapnp
* and use anyway. Any other way to check this?
*/
ret = dev->prepare(dev);
if(ret && ret != -EBUSY) {
printk(KERN_ERR "cs4232: ISA PnP found device that could not be autoconfigured.\n");
kfree(isapnpcfg);
return -ENODEV;
}
if(ret != -EBUSY) {
if(dev->activate(dev) < 0) {
printk(KERN_WARNING "cs4232: ISA PnP activate failed\n");
kfree(isapnpcfg);
return -ENODEV;
}
} /* else subfunction is already activated */
isapnpcfg->irq = dev->irq_resource[0].start; isapnpcfg->irq = dev->irq_resource[0].start;
isapnpcfg->dma = dev->dma_resource[0].start; isapnpcfg->dma = dev->dma_resource[0].start;
...@@ -409,10 +385,25 @@ int cs4232_isapnp_probe(struct pci_dev *dev, const struct isapnp_device_id *id) ...@@ -409,10 +385,25 @@ int cs4232_isapnp_probe(struct pci_dev *dev, const struct isapnp_device_id *id)
return -ENODEV; return -ENODEV;
} }
attach_cs4232(isapnpcfg); attach_cs4232(isapnpcfg);
pci_set_drvdata(dev,isapnpcfg); dev->driver_data = isapnpcfg;
return 0; return 0;
} }
static void cs4232_pnp_remove(struct pnp_dev *dev)
{
struct address_info *cfg = (struct address_info*) dev->driver_data;
if (cfg)
unload_cs4232(cfg);
}
static struct pnp_driver cs4232_driver = {
.name = "cs4232",
.card_id_table = NULL,
.id_table = cs4232_pnp_table,
.probe = cs4232_pnp_probe,
.remove = cs4232_pnp_remove,
};
static int __init init_cs4232(void) static int __init init_cs4232(void)
{ {
#ifdef CONFIG_SOUND_WAVEFRONT_MODULE #ifdef CONFIG_SOUND_WAVEFRONT_MODULE
...@@ -429,7 +420,7 @@ static int __init init_cs4232(void) ...@@ -429,7 +420,7 @@ static int __init init_cs4232(void)
cfg.irq = -1; cfg.irq = -1;
if (isapnp && if (isapnp &&
(isapnp_probe_devs(isapnp_cs4232_list, cs4232_isapnp_probe) > 0) (pnp_register_driver(&cs4232_driver) > 0)
) )
return 0; return 0;
...@@ -460,20 +451,9 @@ static int __init init_cs4232(void) ...@@ -460,20 +451,9 @@ static int __init init_cs4232(void)
return 0; return 0;
} }
static int __exit cs4232_isapnp_remove(struct pci_dev *dev,
const struct isapnp_device_id *id)
{
struct address_info *cfg = (struct address_info*)pci_get_drvdata(dev);
if (cfg)
unload_cs4232(cfg);
pci_set_drvdata(dev,NULL);
dev->deactivate(dev);
return 0;
}
static void __exit cleanup_cs4232(void) static void __exit cleanup_cs4232(void)
{ {
isapnp_probe_devs(isapnp_cs4232_list, cs4232_isapnp_remove); pnp_unregister_driver(&cs4232_driver);
if (cfg.irq != -1) if (cfg.irq != -1)
unload_cs4232(&cfg); /* Unloads global MPU as well, if needed */ unload_cs4232(&cfg); /* Unloads global MPU as well, if needed */
} }
...@@ -488,7 +468,7 @@ static int __init setup_cs4232(char *str) ...@@ -488,7 +468,7 @@ static int __init setup_cs4232(char *str)
int ints[7]; int ints[7];
/* If we have isapnp cards, no need for options */ /* If we have isapnp cards, no need for options */
if (isapnp_probe_devs(isapnp_cs4232_list, cs4232_isapnp_probe) > 0) if (pnp_register_driver(&cs4232_driver) > 0)
return 1; return 1;
str = get_options(str, ARRAY_SIZE(ints), ints); str = get_options(str, ARRAY_SIZE(ints), ints);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment