Commit 7cf4ec8d authored by Jaroslav Kysela's avatar Jaroslav Kysela

Linux PnP Support 0.94

(Adam Belay)            -use list_del instead of list_del_init in some areas
                        -introduce pnp capability and status flags
                        -remove static resource setting, I did some research and found that only
                         PnPBIOS supports it, therefore it is better to implememt this in the
                         PnPBIOS protocol itself. (it appears ACPI doesn't use this)
                        -Remove pnp_dev_has_driver and use PNP_ATTACHED instead, this is necessary
                         because a card driver only has rights over a device that it requests.
                        -added card_for_each_dev macro
                        -undo isapnp protocol changes, the pnp layer was designed to handle cards
                         and devices on the same protocol and I feel they should not be seperated.
(Pual Laufer)           -Fix remove driver bug in pnp card services
(Adam Richter)          -Fix a potential oops in id registration functions
parent b0de9c76
...@@ -62,6 +62,7 @@ int pnpc_add_id(struct pnp_id *id, struct pnp_card *card) ...@@ -62,6 +62,7 @@ int pnpc_add_id(struct pnp_id *id, struct pnp_card *card)
return -EINVAL; return -EINVAL;
if (!card) if (!card)
return -EINVAL; return -EINVAL;
id->next = NULL;
ptr = card->id; ptr = card->id;
while (ptr && ptr->next) while (ptr && ptr->next)
ptr = ptr->next; ptr = ptr->next;
...@@ -131,16 +132,17 @@ int pnpc_add_card(struct pnp_card *card) ...@@ -131,16 +132,17 @@ int pnpc_add_card(struct pnp_card *card)
void pnpc_remove_card(struct pnp_card *card) void pnpc_remove_card(struct pnp_card *card)
{ {
struct list_head *pos; struct list_head *pos, *temp;
if (!card) if (!card)
return; return;
device_unregister(&card->dev); device_unregister(&card->dev);
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
list_del_init(&card->global_list); list_del(&card->global_list);
list_del_init(&card->protocol_list); list_del(&card->protocol_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
list_for_each(pos,&card->devices){ list_for_each_safe(pos,temp,&card->devices){
struct pnp_dev *dev = card_to_pnp_dev(pos); struct pnp_dev *dev = card_to_pnp_dev(pos);
pnpc_remove_device(dev);
__pnp_remove_device(dev); __pnp_remove_device(dev);
} }
} }
...@@ -174,7 +176,7 @@ void pnpc_remove_device(struct pnp_dev *dev) ...@@ -174,7 +176,7 @@ void pnpc_remove_device(struct pnp_dev *dev)
{ {
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
dev->card = NULL; dev->card = NULL;
list_del_init(&dev->card_list); list_del(&dev->card_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
__pnp_remove_device(dev); __pnp_remove_device(dev);
} }
...@@ -213,6 +215,13 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, ...@@ -213,6 +215,13 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id,
return NULL; return NULL;
found: found:
spin_lock(&pnp_lock);
if(dev->status != PNP_READY){
spin_unlock(&pnp_lock);
return NULL;
}
dev->status = PNP_ATTACHED;
spin_unlock(&pnp_lock);
cdrv = to_pnpc_driver(card->dev.driver); cdrv = to_pnpc_driver(card->dev.driver);
if (dev->active == 0) { if (dev->active == 0) {
if (!(cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE)) { if (!(cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE)) {
...@@ -239,15 +248,17 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, ...@@ -239,15 +248,17 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id,
void pnp_release_card_device(struct pnp_dev *dev) void pnp_release_card_device(struct pnp_dev *dev)
{ {
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
list_del_init(&dev->rdev_list); list_del(&dev->rdev_list);
if (dev->status == PNP_ATTACHED)
dev->status = PNP_READY;
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
pnp_disable_dev(dev); pnp_disable_dev(dev);
} }
static void pnpc_recover_devices(struct pnp_card *card) static void pnpc_recover_devices(struct pnp_card *card)
{ {
struct list_head *pos; struct list_head *pos, *temp;
list_for_each(pos,&card->rdevs){ list_for_each_safe(pos,temp,&card->rdevs){
struct pnp_dev *dev = list_entry(pos, struct pnp_dev, rdev_list); struct pnp_dev *dev = list_entry(pos, struct pnp_dev, rdev_list);
pnp_release_card_device(dev); pnp_release_card_device(dev);
} }
......
...@@ -81,7 +81,7 @@ int pnp_register_protocol(struct pnp_protocol *protocol) ...@@ -81,7 +81,7 @@ int pnp_register_protocol(struct pnp_protocol *protocol)
void pnp_unregister_protocol(struct pnp_protocol *protocol) void pnp_unregister_protocol(struct pnp_protocol *protocol)
{ {
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
list_del_init(&protocol->protocol_list); list_del(&protocol->protocol_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
device_unregister(&protocol->dev); device_unregister(&protocol->dev);
} }
...@@ -119,6 +119,7 @@ int __pnp_add_device(struct pnp_dev *dev) ...@@ -119,6 +119,7 @@ int __pnp_add_device(struct pnp_dev *dev)
dev->dev.name[DEVICE_NAME_SIZE-1] = '\0'; dev->dev.name[DEVICE_NAME_SIZE-1] = '\0';
dev->dev.bus = &pnp_bus_type; dev->dev.bus = &pnp_bus_type;
dev->dev.release = &pnp_release_device; dev->dev.release = &pnp_release_device;
dev->status = PNP_READY;
error = device_register(&dev->dev); error = device_register(&dev->dev);
if (error == 0){ if (error == 0){
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
...@@ -149,8 +150,8 @@ int pnp_add_device(struct pnp_dev *dev) ...@@ -149,8 +150,8 @@ int pnp_add_device(struct pnp_dev *dev)
void __pnp_remove_device(struct pnp_dev *dev) void __pnp_remove_device(struct pnp_dev *dev)
{ {
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
list_del_init(&dev->global_list); list_del(&dev->global_list);
list_del_init(&dev->protocol_list); list_del(&dev->protocol_list);
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
device_unregister(&dev->dev); device_unregister(&dev->dev);
} }
...@@ -171,7 +172,7 @@ void pnp_remove_device(struct pnp_dev *dev) ...@@ -171,7 +172,7 @@ void pnp_remove_device(struct pnp_dev *dev)
static int __init pnp_init(void) static int __init pnp_init(void)
{ {
printk(KERN_INFO "Linux Plug and Play Support v0.93 (c) Adam Belay\n"); printk(KERN_INFO "Linux Plug and Play Support v0.94 (c) Adam Belay\n");
return bus_register(&pnp_bus_type); return bus_register(&pnp_bus_type);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#endif #endif
#include <linux/pnp.h> #include <linux/pnp.h>
#include "base.h"
static int compare_func(const char *ida, const char *idb) static int compare_func(const char *ida, const char *idb)
{ {
...@@ -75,6 +76,14 @@ static int pnp_device_probe(struct device *dev) ...@@ -75,6 +76,14 @@ static int pnp_device_probe(struct device *dev)
pnp_dbg("pnp: match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name); pnp_dbg("pnp: match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name);
spin_lock(&pnp_lock);
if(pnp_dev->status != PNP_READY){
spin_unlock(&pnp_lock);
return -EBUSY;
}
pnp_dev->status = PNP_ATTACHED;
spin_unlock(&pnp_lock);
if (pnp_dev->active == 0) { if (pnp_dev->active == 0) {
if (!(pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE)) { if (!(pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE)) {
error = pnp_activate_dev(pnp_dev, NULL); error = pnp_activate_dev(pnp_dev, NULL);
...@@ -95,6 +104,13 @@ static int pnp_device_probe(struct device *dev) ...@@ -95,6 +104,13 @@ static int pnp_device_probe(struct device *dev)
pnp_dev->driver = pnp_drv; pnp_dev->driver = pnp_drv;
error = 0; error = 0;
} }
else
goto fail;
return error;
fail:
pnp_dev->status = PNP_READY;
pnp_disable_dev(pnp_dev);
return error; return error;
} }
...@@ -108,6 +124,10 @@ static int pnp_device_remove(struct device *dev) ...@@ -108,6 +124,10 @@ static int pnp_device_remove(struct device *dev)
drv->remove(pnp_dev); drv->remove(pnp_dev);
pnp_dev->driver = NULL; pnp_dev->driver = NULL;
} }
spin_lock(&pnp_lock);
if (pnp_dev->status == PNP_ATTACHED)
pnp_dev->status = PNP_READY;
spin_unlock(&pnp_lock);
pnp_disable_dev(pnp_dev); pnp_disable_dev(pnp_dev);
return 0; return 0;
} }
...@@ -172,6 +192,7 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) ...@@ -172,6 +192,7 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
return -EINVAL; return -EINVAL;
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
id->next = NULL;
ptr = dev->id; ptr = dev->id;
while (ptr && ptr->next) while (ptr && ptr->next)
ptr = ptr->next; ptr = ptr->next;
......
...@@ -286,13 +286,12 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count, ...@@ -286,13 +286,12 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count,
{ {
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
char command[20]; char command[20];
char type[20];
int num_args; int num_args;
int error = 0; int error = 0;
int depnum, mode = 0; int depnum;
if (off) if (off)
return 0; return 0;
num_args = sscanf(buf,"%10s %i %10s",command,&depnum,type); num_args = sscanf(buf,"%10s %i",command,&depnum);
if (!num_args) if (!num_args)
goto done; goto done;
if (!strnicmp(command,"lock",4)) { if (!strnicmp(command,"lock",4)) {
...@@ -320,11 +319,9 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count, ...@@ -320,11 +319,9 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count,
goto done; goto done;
} }
if (!strnicmp(command,"manual",6)) { if (!strnicmp(command,"manual",6)) {
if (num_args != 3) if (num_args != 2)
goto done; goto done;
if (!strnicmp(type,"static",6)) error = pnp_raw_set_dev(dev,depnum,NULL);
mode = PNP_STATIC;
error = pnp_raw_set_dev(dev,depnum,NULL,mode);
goto done; goto done;
} }
done: done:
......
...@@ -454,6 +454,10 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si ...@@ -454,6 +454,10 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
if (size > 5) if (size > 5)
dev->regs |= tmp[5] << 8; dev->regs |= tmp[5] << 8;
dev->protocol = &isapnp_protocol; dev->protocol = &isapnp_protocol;
dev->capabilities |= PNP_CONFIGURABLE;
dev->capabilities |= PNP_READ;
dev->capabilities |= PNP_WRITE;
dev->capabilities |= PNP_DISABLE;
return dev; return dev;
} }
...@@ -889,7 +893,7 @@ static int __init isapnp_build_device_list(void) ...@@ -889,7 +893,7 @@ static int __init isapnp_build_device_list(void)
if (isapnp_checksum_value != 0x00) if (isapnp_checksum_value != 0x00)
printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value); printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
card->checksum = isapnp_checksum_value; card->checksum = isapnp_checksum_value;
card->protocol = &isapnp_card_protocol; card->protocol = &isapnp_protocol;
pnpc_add_card(card); pnpc_add_card(card);
} }
return 0; return 0;
...@@ -903,7 +907,7 @@ int isapnp_present(void) ...@@ -903,7 +907,7 @@ int isapnp_present(void)
{ {
struct pnp_card *card; struct pnp_card *card;
pnp_for_each_card(card) { pnp_for_each_card(card) {
if (card->protocol == &isapnp_card_protocol) if (card->protocol == &isapnp_protocol)
return 1; return 1;
} }
return 0; return 0;
...@@ -1002,7 +1006,7 @@ static int isapnp_get_resources(struct pnp_dev *dev) ...@@ -1002,7 +1006,7 @@ static int isapnp_get_resources(struct pnp_dev *dev)
return 0; return 0;
} }
static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_cfg *cfg, char flags) static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_cfg *cfg)
{ {
int tmp; int tmp;
isapnp_cfg_begin(dev->card->number, dev->number); isapnp_cfg_begin(dev->card->number, dev->number);
...@@ -1042,15 +1046,8 @@ static int isapnp_disable_resources(struct pnp_dev *dev) ...@@ -1042,15 +1046,8 @@ static int isapnp_disable_resources(struct pnp_dev *dev)
return 0; return 0;
} }
struct pnp_protocol isapnp_card_protocol = {
.name = "ISA Plug and Play - card",
.get = NULL,
.set = NULL,
.disable = NULL,
};
struct pnp_protocol isapnp_protocol = { struct pnp_protocol isapnp_protocol = {
.name = "ISA Plug and Play - device", .name = "ISA Plug and Play",
.get = isapnp_get_resources, .get = isapnp_get_resources,
.set = isapnp_set_resources, .set = isapnp_set_resources,
.disable = isapnp_disable_resources, .disable = isapnp_disable_resources,
...@@ -1081,9 +1078,6 @@ int __init isapnp_init(void) ...@@ -1081,9 +1078,6 @@ int __init isapnp_init(void)
return -EBUSY; return -EBUSY;
} }
if(pnp_register_protocol(&isapnp_card_protocol)<0)
return -EBUSY;
if(pnp_register_protocol(&isapnp_protocol)<0) if(pnp_register_protocol(&isapnp_protocol)<0)
return -EBUSY; return -EBUSY;
......
...@@ -1261,9 +1261,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev) ...@@ -1261,9 +1261,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
struct pnp_bios_node * node; struct pnp_bios_node * node;
/* just in case */ /* just in case */
if(pnp_dev_has_driver(dev)) if(!pnpbios_is_dynamic(dev))
return -EBUSY;
if(!pnp_is_dynamic(dev))
return -EPERM; return -EPERM;
if (pnp_bios_dev_node_info(&node_info) != 0) if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV; return -ENODEV;
...@@ -1277,16 +1275,14 @@ static int pnpbios_get_resources(struct pnp_dev *dev) ...@@ -1277,16 +1275,14 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
return 0; return 0;
} }
static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config, char flags) static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config)
{ {
struct pnp_dev_node_info node_info; struct pnp_dev_node_info node_info;
u8 nodenum = dev->number; u8 nodenum = dev->number;
struct pnp_bios_node * node; struct pnp_bios_node * node;
/* just in case */ /* just in case */
if(pnp_dev_has_driver(dev)) if (!pnpbios_is_dynamic(dev))
return -EBUSY;
if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev))
return -EPERM; return -EPERM;
if (pnp_bios_dev_node_info(&node_info) != 0) if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV; return -ENODEV;
...@@ -1338,9 +1334,7 @@ static int pnpbios_disable_resources(struct pnp_dev *dev) ...@@ -1338,9 +1334,7 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
if (!config) if (!config)
return -1; return -1;
/* just in case */ /* just in case */
if(pnp_dev_has_driver(dev)) if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
return -EBUSY;
if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev))
return -EPERM; return -EPERM;
memset(config, 0, sizeof(struct pnp_cfg)); memset(config, 0, sizeof(struct pnp_cfg));
if (!dev || !dev->active) if (!dev || !dev->active)
...@@ -1449,6 +1443,15 @@ static void __init build_devlist(void) ...@@ -1449,6 +1443,15 @@ static void __init build_devlist(void)
pos = 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); node_id_data_to_dev(pos,node,dev);
dev->flags = node->flags; dev->flags = node->flags;
if (!(dev->flags & PNPBIOS_NO_CONFIG))
dev->capabilities |= PNP_CONFIGURABLE;
if (!(dev->flags & PNPBIOS_NO_DISABLE))
dev->capabilities |= PNP_DISABLE;
dev->capabilities |= PNP_READ;
if (pnpbios_is_dynamic(dev))
dev->capabilities |= PNP_WRITE;
if (dev->flags & PNPBIOS_REMOVABLE)
dev->capabilities |= PNP_REMOVABLE;
dev->protocol = &pnpbios_protocol; dev->protocol = &pnpbios_protocol;
......
...@@ -750,7 +750,7 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum) ...@@ -750,7 +750,7 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum)
dma = dma->next; dma = dma->next;
} }
return config; return config;
fail: fail:
kfree(config); kfree(config);
return NULL; return NULL;
...@@ -772,13 +772,13 @@ int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template) ...@@ -772,13 +772,13 @@ int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template)
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
max = pnp_get_max_depnum(dev); max = pnp_get_max_depnum(dev);
if (dev->active) if (!pnp_can_configure(dev))
return -EBUSY; return -EBUSY;
if (pnp_dev_has_driver(dev)){ if (dev->status != PNP_READY && dev->status != PNP_ATTACHED){
printk(KERN_INFO "pnp: Automatic configuration failed because the PnP device '%s' is busy\n", dev->dev.bus_id); printk(KERN_INFO "pnp: Automatic configuration failed because the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL; return -EINVAL;
} }
if (!dev->protocol->get || !dev->protocol->set) if (!pnp_can_write(dev))
return -EINVAL; return -EINVAL;
if (max == 0) if (max == 0)
return 0; return 0;
...@@ -796,8 +796,8 @@ int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template) ...@@ -796,8 +796,8 @@ int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template)
done: done:
pnp_dbg("the device '%s' has been activated", dev->dev.bus_id); pnp_dbg("the device '%s' has been activated", dev->dev.bus_id);
dev->protocol->set(dev,config,0); dev->protocol->set(dev,config);
if (dev->protocol->get) if (pnp_can_read(dev))
dev->protocol->get(dev); dev->protocol->get(dev);
kfree(config); kfree(config);
return 0; return 0;
...@@ -814,13 +814,13 @@ int pnp_disable_dev(struct pnp_dev *dev) ...@@ -814,13 +814,13 @@ int pnp_disable_dev(struct pnp_dev *dev)
{ {
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
if (pnp_dev_has_driver(dev)){ if (dev->status != PNP_READY){
printk(KERN_INFO "pnp: Disable failed becuase the PnP device '%s' is busy\n", dev->dev.bus_id); printk(KERN_INFO "pnp: Disable failed becuase the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL; return -EINVAL;
} }
if (dev->lock_resources) if (dev->lock_resources)
return -EPERM; return -EPERM;
if (!dev->protocol->disable || !dev->active) if (!pnp_can_disable(dev) || !dev->active)
return -EINVAL; return -EINVAL;
pnp_dbg("the device '%s' has been disabled", dev->dev.bus_id); pnp_dbg("the device '%s' has been disabled", dev->dev.bus_id);
return dev->protocol->disable(dev); return dev->protocol->disable(dev);
...@@ -834,16 +834,16 @@ int pnp_disable_dev(struct pnp_dev *dev) ...@@ -834,16 +834,16 @@ int pnp_disable_dev(struct pnp_dev *dev)
* *
*/ */
int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *template, int mode) int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *template)
{ {
struct pnp_cfg *config; struct pnp_cfg *config;
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
if (pnp_dev_has_driver(dev)){ if (dev->status != PNP_READY){
printk(KERN_INFO "pnp: Unable to set resources because the PnP device '%s' is busy\n", dev->dev.bus_id); printk(KERN_INFO "pnp: Unable to set resources because the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL; return -EINVAL;
} }
if (!dev->protocol->get || !dev->protocol->set) if (!pnp_can_write(dev) || !pnp_can_configure(dev))
return -EINVAL; return -EINVAL;
config = pnp_generate_config(dev,depnum); config = pnp_generate_config(dev,depnum);
if (!config) if (!config)
...@@ -855,8 +855,8 @@ int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *templat ...@@ -855,8 +855,8 @@ int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *templat
return -ENOENT; return -ENOENT;
done: done:
dev->protocol->set(dev,config,mode); dev->protocol->set(dev,config);
if (dev->protocol->get) if (pnp_can_read(dev))
dev->protocol->get(dev); dev->protocol->get(dev);
kfree(config); kfree(config);
return 0; return 0;
......
...@@ -84,6 +84,9 @@ static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data) ...@@ -84,6 +84,9 @@ static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data)
struct pnp_dev { struct pnp_dev {
char name[80]; /* device name */ char name[80]; /* device name */
int active; /* status of the device */ int active; /* status of the device */
int capabilities;
int status;
struct list_head global_list; /* node in global list of devices */ struct list_head global_list; /* node in global list of devices */
struct list_head protocol_list; /* node in list of device's protocol */ struct list_head protocol_list; /* node in list of device's protocol */
struct list_head card_list; /* node in card's list of devices */ struct list_head card_list; /* node in card's list of devices */
...@@ -116,13 +119,10 @@ struct pnp_dev { ...@@ -116,13 +119,10 @@ struct pnp_dev {
for(dev = global_to_pnp_dev(pnp_global.next); \ for(dev = global_to_pnp_dev(pnp_global.next); \
dev != global_to_pnp_dev(&pnp_global); \ dev != global_to_pnp_dev(&pnp_global); \
dev = global_to_pnp_dev(dev->global_list.next)) dev = global_to_pnp_dev(dev->global_list.next))
#define card_for_each_dev(card,dev) \
static inline int pnp_dev_has_driver(struct pnp_dev *pdev) for((dev) = card_to_pnp_dev((card)->devices.next); \
{ (dev) != card_to_pnp_dev(&(card)->devices); \
if (pdev->driver || (pdev->card && pdev->card->driver)) (dev) = card_to_pnp_dev((dev)->card_list.next))
return 1;
return 0;
}
static inline void *pnp_get_drvdata (struct pnp_dev *pdev) static inline void *pnp_get_drvdata (struct pnp_dev *pdev)
{ {
...@@ -149,6 +149,28 @@ struct pnp_fixup { ...@@ -149,6 +149,28 @@ struct pnp_fixup {
void (*quirk_function)(struct pnp_dev *dev); /* fixup function */ void (*quirk_function)(struct pnp_dev *dev); /* fixup function */
}; };
/* capabilities */
#define PNP_READ 0x0001
#define PNP_WRITE 0x0002
#define PNP_DISABLE 0x0004
#define PNP_CONFIGURABLE 0x0008
#define PNP_REMOVABLE 0x0010
#define pnp_can_read(dev) (((dev)->protocol) && ((dev)->protocol->get) && \
((dev)->capabilities & PNP_READ))
#define pnp_can_write(dev) (((dev)->protocol) && ((dev)->protocol->set) && \
((dev)->capabilities & PNP_WRITE))
#define pnp_can_disable(dev) (((dev)->protocol) && ((dev)->protocol->disable) && \
((dev)->capabilities & PNP_DISABLE))
#define pnp_can_configure(dev) ((!(dev)->active) && ((dev)->capabilities & PNP_CONFIGURABLE))
/* status */
#define PNP_INIT 0x0000
#define PNP_READY 0x0001
#define PNP_ATTACHED 0x0002
#define PNP_BUSY 0x0004
#define PNP_FAULTY 0x0008
/* /*
* Driver Management * Driver Management
...@@ -303,9 +325,6 @@ struct pnp_res_cfg { ...@@ -303,9 +325,6 @@ struct pnp_res_cfg {
struct resource irq_resource[DEVICE_COUNT_IRQ]; struct resource irq_resource[DEVICE_COUNT_IRQ];
}; };
#define PNP_DYNAMIC 0 /* get or set current resource */
#define PNP_STATIC 1 /* get or set resource for next boot */
struct pnp_cfg { struct pnp_cfg {
struct pnp_port *port[8]; struct pnp_port *port[8];
struct pnp_irq *irq[2]; struct pnp_irq *irq[2];
...@@ -325,7 +344,7 @@ struct pnp_protocol { ...@@ -325,7 +344,7 @@ struct pnp_protocol {
/* functions */ /* functions */
int (*get)(struct pnp_dev *dev); int (*get)(struct pnp_dev *dev);
int (*set)(struct pnp_dev *dev, struct pnp_cfg *config, char flags); int (*set)(struct pnp_dev *dev, struct pnp_cfg *config);
int (*disable)(struct pnp_dev *dev); int (*disable)(struct pnp_dev *dev);
/* used by pnp layer only (look but don't touch) */ /* used by pnp layer only (look but don't touch) */
...@@ -367,7 +386,7 @@ int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_mem32 *da ...@@ -367,7 +386,7 @@ int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_mem32 *da
int pnp_init_res_cfg(struct pnp_res_cfg *template); int pnp_init_res_cfg(struct pnp_res_cfg *template);
int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template); int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template);
int pnp_disable_dev(struct pnp_dev *dev); int pnp_disable_dev(struct pnp_dev *dev);
int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *template, int mode); int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *template);
void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size); void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
/* driver */ /* driver */
...@@ -395,7 +414,7 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct ...@@ -395,7 +414,7 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct
static inline int pnp_init_res_cfg(struct pnp_res_cfg *template) { return -ENODEV; } static inline int pnp_init_res_cfg(struct pnp_res_cfg *template) { return -ENODEV; }
static inline int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template) { return -ENODEV; } static inline int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template) { 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, struct pnp_res_cfg *template, int mode) { return -ENODEV; } static inline int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, struct pnp_res_cfg *template) { return -ENODEV; }
static inline int compare_pnp_id(struct list_head * id_list, const char * id) { return -ENODEV; } static inline int compare_pnp_id(struct list_head * id_list, 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_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; }
......
...@@ -78,15 +78,15 @@ ...@@ -78,15 +78,15 @@
/* /*
* Plug and Play BIOS flags * Plug and Play BIOS flags
*/ */
#define PNP_NO_DISABLE 0x0001 #define PNPBIOS_NO_DISABLE 0x0001
#define PNP_NO_CONFIG 0x0002 #define PNPBIOS_NO_CONFIG 0x0002
#define PNP_OUTPUT 0x0004 #define PNPBIOS_OUTPUT 0x0004
#define PNP_INPUT 0x0008 #define PNPBIOS_INPUT 0x0008
#define PNP_BOOTABLE 0x0010 #define PNPBIOS_BOOTABLE 0x0010
#define PNP_DOCK 0x0020 #define PNPBIOS_DOCK 0x0020
#define PNP_REMOVABLE 0x0040 #define PNPBIOS_REMOVABLE 0x0040
#define pnp_is_static(x) (x->flags & 0x0100) == 0x0000 #define pnpbios_is_static(x) ((x)->flags & 0x0100) == 0x0000
#define pnp_is_dynamic(x) x->flags & 0x0080 #define pnpbios_is_dynamic(x) (x)->flags & 0x0080
/* 0x8000 through 0xffff are OEM defined */ /* 0x8000 through 0xffff are OEM defined */
......
...@@ -2987,7 +2987,7 @@ static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev ...@@ -2987,7 +2987,7 @@ static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev
if(dev->active) if(dev->active)
return(dev); return(dev);
if((err = pnp_activate_dev(dev)) < 0) { if((err = pnp_activate_dev(dev,NULL)) < 0) {
printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err); printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
pnp_disable_dev(dev); pnp_disable_dev(dev);
......
...@@ -836,14 +836,14 @@ static void __exit unload_opl3sa2(struct address_info* hw_config, int card) ...@@ -836,14 +836,14 @@ static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
} }
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
struct pnp_id pnp_opl3sa2_list[] = { struct pnp_device_id pnp_opl3sa2_list[] = {
{.id = "YMH0021", .driver_data = 0}, {.id = "YMH0021", .driver_data = 0},
{.id = ""} {.id = ""}
}; };
MODULE_DEVICE_TABLE(pnp, pnp_opl3sa2_list); MODULE_DEVICE_TABLE(pnp, pnp_opl3sa2_list);
static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *dev_id) static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{ {
int card = opl3sa2_cards_num; int card = opl3sa2_cards_num;
if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX) if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX)
......
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