Commit ba4d3dce authored by Adam Belay's avatar Adam Belay

PnP Card Serivice Revisions

This set of changes addresses the following issues with the existing card 
service implementation:

1.) Only one driver can be bound to a card.
2.) repetive code is required for pnp_request_card_device and other 
functions

This patch will make the card services usable by ALSA.
parent 85622b58
...@@ -30,15 +30,6 @@ config PNP_NAMES ...@@ -30,15 +30,6 @@ config PNP_NAMES
If unsure, say Y. If unsure, say Y.
config PNP_CARD
bool "Plug and Play card services"
depends on PNP
help
Select Y if you want the PnP Layer to manage cards. Cards are groups
of PnP devices. Some drivers, especially PnP sound card drivers, use
these cards. If you want to use the protocol ISAPNP you will need to
say Y here.
config PNP_DEBUG config PNP_DEBUG
bool "PnP Debug Messages" bool "PnP Debug Messages"
depends on PNP depends on PNP
...@@ -51,7 +42,7 @@ comment "Protocols" ...@@ -51,7 +42,7 @@ comment "Protocols"
config ISAPNP config ISAPNP
bool "ISA Plug and Play support (EXPERIMENTAL)" bool "ISA Plug and Play support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL && PNP_CARD depends on PNP && EXPERIMENTAL
help help
Say Y here if you would like support for ISA Plug and Play devices. Say Y here if you would like support for ISA Plug and Play devices.
Some information is in <file:Documentation/isapnp.txt>. Some information is in <file:Documentation/isapnp.txt>.
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
# Makefile for the Linux Plug-and-Play Support. # Makefile for the Linux Plug-and-Play Support.
# #
pnp-card-$(CONFIG_PNP_CARD) = card.o obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o names.o system.o
obj-y := core.o driver.o resource.o manager.o support.o interface.o quirks.o names.o system.o $(pnp-card-y)
obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/ obj-$(CONFIG_ISAPNP) += isapnp/
This diff is collapsed.
...@@ -53,12 +53,11 @@ int compare_pnp_id(struct pnp_id *pos, const char *id) ...@@ -53,12 +53,11 @@ int compare_pnp_id(struct pnp_id *pos, const char *id)
static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev) static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev)
{ {
const struct pnp_device_id *drv_id = drv->id_table; const struct pnp_device_id *drv_id = drv->id_table;
if (!drv) if (!drv_id)
return NULL; return NULL;
if (!dev)
return NULL; while (*drv_id->id) {
while (*drv_id->id){ if (compare_pnp_id(dev->id, drv_id->id))
if (compare_pnp_id(dev->id,drv_id->id))
return drv_id; return drv_id;
drv_id++; drv_id++;
} }
...@@ -102,14 +101,18 @@ static int pnp_device_probe(struct device *dev) ...@@ -102,14 +101,18 @@ static int pnp_device_probe(struct device *dev)
return error; return error;
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_RES_DO_NOT_CHANGE)) {
error = pnp_activate_dev(pnp_dev); error = pnp_activate_dev(pnp_dev);
if (error < 0) if (error < 0)
return error; return error;
} }
} else if (pnp_drv->flags & PNP_DRIVER_RES_DISABLE) {
error = pnp_disable_dev(pnp_dev);
if (error < 0)
return error;
} }
error = 0; error = 0;
if (pnp_drv->probe && pnp_dev->active) { if (pnp_drv->probe) {
dev_id = match_device(pnp_drv, pnp_dev); dev_id = match_device(pnp_drv, pnp_dev);
if (dev_id != NULL) if (dev_id != NULL)
error = pnp_drv->probe(pnp_dev, dev_id); error = pnp_drv->probe(pnp_dev, dev_id);
...@@ -117,9 +120,8 @@ static int pnp_device_probe(struct device *dev) ...@@ -117,9 +120,8 @@ static int pnp_device_probe(struct device *dev)
if (error >= 0){ if (error >= 0){
pnp_dev->driver = pnp_drv; pnp_dev->driver = pnp_drv;
error = 0; error = 0;
} } else
else goto fail;
goto fail;
return error; return error;
fail: fail:
......
...@@ -626,7 +626,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size) ...@@ -626,7 +626,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
isapnp_peek(name, size1); isapnp_peek(name, size1);
name[size1] = '\0'; name[size1] = '\0';
*size -= size1; *size -= size1;
/* clean whitespace from end of string */ /* clean whitespace from end of string */
while (size1 > 0 && name[--size1] == ' ') while (size1 > 0 && name[--size1] == ' ')
name[size1] = '\0'; name[size1] = '\0';
...@@ -647,7 +647,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -647,7 +647,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1; return 1;
if (pnp_build_resource(dev, 0) == NULL) if (pnp_build_resource(dev, 0) == NULL)
return 1; return 1;
pnpc_add_device(card,dev); pnp_add_card_device(card,dev);
while (1) { while (1) {
if (isapnp_read_tag(&type, &size)<0) if (isapnp_read_tag(&type, &size)<0)
return 1; return 1;
...@@ -659,7 +659,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -659,7 +659,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
if ((dev = isapnp_parse_device(card, size, number++)) == NULL) if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1; return 1;
pnp_build_resource(dev,0); pnp_build_resource(dev,0);
pnpc_add_device(card,dev); pnp_add_card_device(card,dev);
size = 0; size = 0;
skip = 0; skip = 0;
} else { } else {
...@@ -852,7 +852,7 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor, ...@@ -852,7 +852,7 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor,
device & 0x0f, device & 0x0f,
(device >> 12) & 0x0f, (device >> 12) & 0x0f,
(device >> 8) & 0x0f); (device >> 8) & 0x0f);
pnpc_add_id(id,card); pnp_add_card_id(id,card);
} }
...@@ -962,7 +962,7 @@ static int __init isapnp_build_device_list(void) ...@@ -962,7 +962,7 @@ static int __init isapnp_build_device_list(void)
isapnp_parse_current_resources(dev, &dev->res); isapnp_parse_current_resources(dev, &dev->res);
} }
pnpc_add_card(card); pnp_add_card(card);
} }
isapnp_wait(); isapnp_wait();
return 0; return 0;
......
...@@ -93,7 +93,7 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *de ...@@ -93,7 +93,7 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *de
static struct pnp_driver system_pnp_driver = { static struct pnp_driver system_pnp_driver = {
.name = "system", .name = "system",
.flags = PNP_DRIVER_DO_NOT_ACTIVATE, .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
.id_table = pnp_dev_table, .id_table = pnp_dev_table,
.probe = system_pnp_probe, .probe = system_pnp_probe,
.remove = NULL, .remove = NULL,
......
...@@ -138,11 +138,9 @@ struct pnp_card { ...@@ -138,11 +138,9 @@ struct pnp_card {
struct list_head global_list; /* node in global list of cards */ struct list_head global_list; /* node in global list of cards */
struct list_head protocol_list; /* node in protocol's list of cards */ struct list_head protocol_list; /* node in protocol's list of cards */
struct list_head devices; /* devices attached to the card */ struct list_head devices; /* devices attached to the card */
struct list_head rdevs; /* a list of devices requested by the card driver */
int status; int status;
struct pnp_protocol * protocol; struct pnp_protocol * protocol;
struct pnpc_driver * driver;
struct pnp_id * id; /* contains supported EISA IDs*/ struct pnp_id * id; /* contains supported EISA IDs*/
void * protocol_data; /* Used to store protocol specific data */ void * protocol_data; /* Used to store protocol specific data */
...@@ -161,22 +159,22 @@ struct pnp_card { ...@@ -161,22 +159,22 @@ struct pnp_card {
(card) != global_to_pnp_card(&pnp_cards); \ (card) != global_to_pnp_card(&pnp_cards); \
(card) = global_to_pnp_card((card)->global_list.next)) (card) = global_to_pnp_card((card)->global_list.next))
static inline void *pnpc_get_drvdata (struct pnp_card *pcard) static inline void *pnp_get_card_drvdata (struct pnp_card *pcard)
{ {
return dev_get_drvdata(&pcard->dev); return dev_get_drvdata(&pcard->dev);
} }
static inline void pnpc_set_drvdata (struct pnp_card *pcard, void *data) static inline void pnp_set_card_drvdata (struct pnp_card *pcard, void *data)
{ {
dev_set_drvdata(&pcard->dev, data); dev_set_drvdata(&pcard->dev, data);
} }
static inline void *pnpc_get_protodata (struct pnp_card *pcard) static inline void *pnp_get_card_protodata (struct pnp_card *pcard)
{ {
return pcard->protocol_data; return pcard->protocol_data;
} }
static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data) static inline void pnp_set_card_protodata (struct pnp_card *pcard, void *data)
{ {
pcard->protocol_data = data; pcard->protocol_data = data;
} }
...@@ -299,11 +297,8 @@ struct pnp_card_id { ...@@ -299,11 +297,8 @@ struct pnp_card_id {
} devs[PNP_MAX_DEVICES]; /* logical devices */ } devs[PNP_MAX_DEVICES]; /* logical devices */
}; };
#define PNP_DRIVER_DO_NOT_ACTIVATE (1<<0)
struct pnp_driver { struct pnp_driver {
struct list_head node; char * name;
char *name;
const struct pnp_device_id *id_table; const struct pnp_device_id *id_table;
unsigned int flags; unsigned int flags;
int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id); int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
...@@ -311,21 +306,22 @@ struct pnp_driver { ...@@ -311,21 +306,22 @@ struct pnp_driver {
struct device_driver driver; struct device_driver driver;
}; };
#define to_pnp_driver(drv) container_of(drv,struct pnp_driver, driver) #define to_pnp_driver(drv) container_of(drv, struct pnp_driver, driver)
#define PNPC_DRIVER_DO_NOT_ACTIVATE (1<<0)
struct pnpc_driver { struct pnp_card_driver {
struct list_head node; char * name;
char *name;
const struct pnp_card_id *id_table; const struct pnp_card_id *id_table;
unsigned int flags; unsigned int flags;
int (*probe) (struct pnp_card *card, const struct pnp_card_id *card_id); int (*probe) (struct pnp_card *card, const struct pnp_card_id *card_id);
void (*remove) (struct pnp_card *card); void (*remove) (struct pnp_card *card);
struct device_driver driver; struct pnp_driver link;
}; };
#define to_pnpc_driver(drv) container_of(drv,struct pnpc_driver, driver) #define to_pnp_card_driver(drv) container_of(drv, struct pnp_card_driver, link)
/* pnp driver flags */
#define PNP_DRIVER_RES_DO_NOT_CHANGE 0x0001 /* do not change the state of the device */
#define PNP_DRIVER_RES_DISABLE 0x0003 /* ensure the device is disabled */
/* /*
...@@ -366,9 +362,21 @@ int pnp_register_protocol(struct pnp_protocol *protocol); ...@@ -366,9 +362,21 @@ int pnp_register_protocol(struct pnp_protocol *protocol);
void pnp_unregister_protocol(struct pnp_protocol *protocol); void pnp_unregister_protocol(struct pnp_protocol *protocol);
int pnp_add_device(struct pnp_dev *dev); int pnp_add_device(struct pnp_dev *dev);
void pnp_remove_device(struct pnp_dev *dev); void pnp_remove_device(struct pnp_dev *dev);
extern struct list_head pnp_global;
int pnp_device_attach(struct pnp_dev *pnp_dev); int pnp_device_attach(struct pnp_dev *pnp_dev);
void pnp_device_detach(struct pnp_dev *pnp_dev); void pnp_device_detach(struct pnp_dev *pnp_dev);
extern struct list_head pnp_global;
/* card */
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_driver * drv, struct pnp_card *card, const char * id, struct pnp_dev * from);
void pnp_release_card_device(struct pnp_dev * dev);
int pnp_register_card_driver(struct pnp_card_driver * drv);
void pnp_unregister_card_driver(struct pnp_card_driver * drv);
extern struct list_head pnp_cards;
/* resource */ /* resource */
struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent); struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent);
...@@ -413,6 +421,17 @@ static inline void pnp_remove_device(struct pnp_dev *dev) { } ...@@ -413,6 +421,17 @@ static inline void pnp_remove_device(struct pnp_dev *dev) { }
static inline int pnp_device_attach(struct pnp_dev *pnp_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) { ; } static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
/* card */
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_driver * drv, struct pnp_card *card, const char * id, struct pnp_dev * from) { return -ENODEV; }
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 */ /* resource */
static inline struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent) { return NULL; } static inline struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent) { return NULL; }
static inline struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum) { return NULL; } static inline struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum) { return NULL; }
...@@ -446,37 +465,6 @@ static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned ch ...@@ -446,37 +465,6 @@ static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned ch
#endif /* CONFIG_PNP */ #endif /* CONFIG_PNP */
#if defined(CONFIG_PNP_CARD)
/* card */
int pnpc_add_card(struct pnp_card *card);
void pnpc_remove_card(struct pnp_card *card);
int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev);
void pnpc_remove_device(struct pnp_dev *dev);
struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from);
void pnp_release_card_device(struct pnp_dev *dev);
int pnpc_register_driver(struct pnpc_driver * drv);
void pnpc_unregister_driver(struct pnpc_driver *drv);
int pnpc_add_id(struct pnp_id *id, struct pnp_card *card);
extern struct list_head pnp_cards;
int pnpc_attach(struct pnp_card *card);
void pnpc_detach(struct pnp_card *card);
#else
/* card */
static inline int pnpc_add_card(struct pnp_card *card) { return -ENODEV; }
static inline void pnpc_remove_card(struct pnp_card *card) { ; }
static inline int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
static inline void pnpc_remove_device(struct pnp_dev *dev) { ; }
static inline struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from) { return NULL; }
static inline void pnp_release_card_device(struct pnp_dev *dev) { ; }
static inline int pnpc_register_driver(struct pnpc_driver *drv) { return -ENODEV; }
static inline void pnpc_unregister_driver(struct pnpc_driver *drv) { ; }
static inline int pnpc_add_id(struct pnp_id *id, struct pnp_card *card) { return -ENODEV; }
#endif /* CONFIG_PNP_CARD */
#define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg) #define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg)
#define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg) #define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg)
#define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg) #define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg)
......
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