summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAdam Belay <ambx1@neo.rr.com>2002-10-18 02:51:11 -0700
committerAdam Belay <ambx1@neo.rr.com>2002-10-18 02:51:11 -0700
commitf72e5c5c861ccaaf3bb1e9dbe9ea48a6543bc5c8 (patch)
treea690762785261ab191c75e4e917c005d045067b9 /include/linux
parentfcaf0e9cdbca53a61d131e6c50e437a11ab201c9 (diff)
[PATCH] PnP Rewrite V0.9 - 2.5.43
The included patch is essentially a Linux Plug and Play Support rewrite. It contains many significant improvements, including the following: 1.) A Global Plug and Play Layer - Now drivers do not have to worry about which plug and play protocol they are using. Calls are made directly to the Linux Plug and Play Layer and then forwarded to the appropriate protocol. - This will make it very easy to integrate ACPI PnP support when it's ready 2.) A complete Plug and Play BIOS driver - The Plug and Play BIOS now supports reading and writing of resource configurations. - It is now possible to enable disabled PNPBIOS devices. Therefore the user can safely enable PnP OS support in their BIOS. 3.) Driver Model Integration - The entire plug and play layer is integrated into the driver model - The user interface is housed here - PnP protocols are listed under the bus "pnp" 4.) A powerful global resource configuration interface - The user can use this to activate PnP devices for legacy and user-level drivers - See the documentation for how to configure devices. 5.) Automatic resource allocation for needed devices 6.) A PnP device name database And many more improvements. This patch also adds me to the maintainers list, considering the current PnP maintainer has been inactive for over 2 years now.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/isapnp.h49
-rw-r--r--include/linux/pnp.h285
-rw-r--r--include/linux/pnpbios.h75
3 files changed, 315 insertions, 94 deletions
diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h
index 4884d178909a..6bfd60d699e5 100644
--- a/include/linux/isapnp.h
+++ b/include/linux/isapnp.h
@@ -190,40 +190,49 @@ void isapnp_activate(unsigned char device);
void isapnp_deactivate(unsigned char device);
void isapnp_fixup_device(struct pci_dev *dev);
void *isapnp_alloc(long size);
+
+#ifdef CONFIG_PROC_FS
int isapnp_proc_init(void);
int isapnp_proc_done(void);
-/* manager */
-struct pci_bus *isapnp_find_card(unsigned short vendor,
- unsigned short device,
- struct pci_bus *from);
-struct pci_dev *isapnp_find_dev(struct pci_bus *card,
- unsigned short vendor,
- unsigned short function,
- struct pci_dev *from);
-int isapnp_probe_cards(const struct isapnp_card_id *ids,
- int (*probe)(struct pci_bus *card,
- const struct isapnp_card_id *id));
-int isapnp_probe_devs(const struct isapnp_device_id *ids,
- int (*probe)(struct pci_dev *dev,
- const struct isapnp_device_id *id));
+#else
+static inline isapnp_proc_init(void) { return 0; }
+static inline isapnp_proc_done(void) { return 0; )
+#endif
+
/* misc */
void isapnp_resource_change(struct resource *resource,
unsigned long start,
unsigned long size);
-int isapnp_activate_dev(struct pci_dev *dev, const char *name);
/* init/main.c */
int isapnp_init(void);
+/* manager */
+static inline struct pci_bus *isapnp_find_card(unsigned short vendor,
+ unsigned short device,
+ struct pci_bus *from) { return NULL; }
+static inline struct pci_dev *isapnp_find_dev(struct pci_bus *card,
+ unsigned short vendor,
+ unsigned short function,
+ struct pci_dev *from) { return NULL; }
+static inline int isapnp_probe_cards(const struct isapnp_card_id *ids,
+ int (*probe)(struct pci_bus *card,
+ const struct isapnp_card_id *id)) { return -ENODEV; }
+static inline int isapnp_probe_devs(const struct isapnp_device_id *ids,
+ int (*probe)(struct pci_dev *dev,
+ const struct isapnp_device_id *id)) { return -ENODEV; }
+static inline int isapnp_activate_dev(struct pci_dev *dev, const char *name) { return -ENODEV; }
+
+static inline int isapnp_register_driver(struct isapnp_driver *drv) { return 0; }
+
+static inline void isapnp_unregister_driver(struct isapnp_driver *drv) { }
extern struct list_head isapnp_cards;
extern struct list_head isapnp_devices;
+extern struct pnp_protocol isapnp_protocol;
#define isapnp_for_each_card(card) \
- for(card = pci_bus_b(isapnp_cards.next); card != pci_bus_b(&isapnp_cards); card = pci_bus_b(card->node.next))
+ for(card = to_pnp_card(isapnp_cards.next); card != to_pnp_card(&isapnp_cards); card = to_pnp_card(card->node.next))
#define isapnp_for_each_dev(dev) \
- for(dev = pci_dev_g(isapnp_devices.next); dev != pci_dev_g(&isapnp_devices); dev = pci_dev_g(dev->global_list.next))
-
-int isapnp_register_driver(struct isapnp_driver *drv);
-void isapnp_unregister_driver(struct isapnp_driver *drv);
+ for(dev = protocol_to_pnp_dev(isapnp_protocol.devices.next); dev != protocol_to_pnp_dev(&isapnp_protocol.devices); dev = protocol_to_pnp_dev(dev->dev_list.next))
#else /* !CONFIG_ISAPNP */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
new file mode 100644
index 000000000000..5dc223b39724
--- /dev/null
+++ b/include/linux/pnp.h
@@ -0,0 +1,285 @@
+#ifndef _LINUX_PNP_H
+#define _LINUX_PNP_H
+
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/list.h>
+
+
+/* Device Managemnt */
+
+#define DEVICE_COUNT_IRQ 2
+#define DEVICE_COUNT_DMA 2
+#define DEVICE_COUNT_RESOURCE 12
+
+struct pnp_resource;
+struct pnp_protocol;
+
+struct pnp_card { /* this is for ISAPNP */
+ struct list_head node; /* node in list of cards */
+ char name[80];
+ unsigned char number; /* card number */
+ struct list_head ids; /* stores all supported dev ids */
+ struct list_head devices; /* devices attached to the card */
+ unsigned char pnpver; /* Plug & Play version */
+ unsigned char productver; /* product version */
+ unsigned int serial; /* serial number */
+ unsigned char checksum; /* if zero - checksum passed */
+ struct proc_dir_entry *procdir; /* directory entry in /proc/bus/isapnp */
+};
+
+#define to_pnp_card(n) list_entry(n, struct pnp_card, node)
+
+struct pnp_dev {
+ char name[80]; /* device name */
+ int active; /* status of the device */
+ int ro; /* read only */
+ struct list_head dev_list; /* node in list of device's protocol */
+ struct list_head global_list;
+ struct list_head card_list;
+ struct pnp_protocol * protocol;
+ struct pnp_card *card;
+
+ unsigned char number; /* must be unique */
+ unsigned short regs; /* ISAPnP: supported registers */
+ struct list_head ids; /* stores all supported dev ids */
+ struct pnp_resources *res; /* possible resource information */
+ struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
+ struct resource dma_resource[DEVICE_COUNT_DMA];
+ struct resource irq_resource[DEVICE_COUNT_IRQ];
+
+ struct pnp_driver * driver; /* which driver has allocated this device */
+ struct device dev; /* Driver Model device interface */
+ void * driver_data;/* data private to the driver */
+ void * protocol_data;
+ struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */
+};
+
+#define global_to_pnp_dev(n) list_entry(n, struct pnp_dev, global_list)
+#define card_to_pnp_dev(n) list_entry(n, struct pnp_dev, card_list)
+#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, dev_list)
+#define to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
+#define pnp_for_each_dev(dev) \
+ for(dev = global_to_pnp_dev(pnp_global.next); \
+ dev != global_to_pnp_dev(&pnp_global); \
+ dev = global_to_pnp_dev(dev->global_list.next))
+
+struct pnp_fixup {
+ char id[7];
+ void (*quirk_function)(struct pnp_dev *dev); /* fixup function */
+};
+
+/*
+ * Linux Plug and Play Support
+ * Copyright by Adam Belay <ambx1@neo.rr.com>
+ *
+ */
+
+/* Driver Management */
+
+struct pnp_id {
+ char id[7];
+ unsigned long driver_data; /* data private to the driver */
+ struct list_head id_list; /* node in card's or device's list */
+};
+
+#define to_pnp_id(n) list_entry(n, struct pnp_id, id_list)
+
+struct pnp_driver {
+ struct list_head node;
+ char *name;
+ const struct pnp_id *card_id_table;
+ const struct pnp_id *id_table;
+ int (*probe) (struct pnp_dev *dev, const struct pnp_id *card_id,
+ const struct pnp_id *dev_id);
+ void (*remove) (struct pnp_dev *dev);
+ struct device * (*legacy) (void);
+ struct device_driver driver;
+};
+
+#define to_pnp_driver(drv) container_of(drv,struct pnp_driver, driver)
+
+
+/* Resource Management */
+
+#define DEV_IO(dev, index) (dev->resource[index].start)
+#define DEV_MEM(dev, index) (dev->resource[index+8].start)
+#define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
+#define DEV_DMA(dev, index) (dev->dma_resource[index].start)
+
+#define PNP_PORT_FLAG_16BITADDR (1<<0)
+#define PNP_PORT_FLAG_FIXED (1<<1)
+
+struct pnp_port {
+ unsigned short min; /* min base number */
+ unsigned short max; /* max base number */
+ unsigned char align; /* align boundary */
+ unsigned char size; /* size of range */
+ unsigned char flags; /* port flags */
+ unsigned char pad; /* pad */
+ struct pnp_resources *res; /* parent */
+ struct pnp_port *next; /* next port */
+};
+
+struct pnp_irq {
+ unsigned short map; /* bitmaks for IRQ lines */
+ unsigned char flags; /* IRQ flags */
+ unsigned char pad; /* pad */
+ struct pnp_resources *res; /* parent */
+ struct pnp_irq *next; /* next IRQ */
+};
+
+struct pnp_dma {
+ unsigned char map; /* bitmask for DMA channels */
+ unsigned char flags; /* DMA flags */
+ struct pnp_resources *res; /* parent */
+ struct pnp_dma *next; /* next port */
+};
+
+struct pnp_mem {
+ unsigned int min; /* min base number */
+ unsigned int max; /* max base number */
+ unsigned int align; /* align boundary */
+ unsigned int size; /* size of range */
+ unsigned char flags; /* memory flags */
+ unsigned char pad; /* pad */
+ struct pnp_resources *res; /* parent */
+ struct pnp_mem *next; /* next memory resource */
+};
+
+struct pnp_mem32 {
+ unsigned char data[17];
+ struct pnp_resources *res; /* parent */
+ struct pnp_mem32 *next; /* next 32-bit memory resource */
+};
+
+#define PNP_RES_PRIORITY_PREFERRED 0
+#define PNP_RES_PRIORITY_ACCEPTABLE 1
+#define PNP_RES_PRIORITY_FUNCTIONAL 2
+#define PNP_RES_PRIORITY_INVALID 65535
+
+struct pnp_resources {
+ unsigned short priority; /* priority */
+ unsigned short dependent; /* dependent resources */
+ struct pnp_port *port; /* first port */
+ struct pnp_irq *irq; /* first IRQ */
+ struct pnp_dma *dma; /* first DMA */
+ struct pnp_mem *mem; /* first memory resource */
+ struct pnp_mem32 *mem32; /* first 32-bit memory */
+ struct pnp_dev *dev; /* parent */
+ struct pnp_resources *dep; /* dependent resources */
+};
+
+#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_port *port[8];
+ struct pnp_irq *irq[2];
+ struct pnp_dma *dma[2];
+ struct pnp_mem *mem[4];
+ struct pnp_dev request;
+};
+
+
+/* Protocol Management */
+
+struct pnp_protocol {
+ struct list_head protocol_list;
+ char name[DEVICE_NAME_SIZE];
+
+ /* functions */
+ int (*get)(struct pnp_dev *dev);
+ int (*set)(struct pnp_dev *dev, struct pnp_cfg *config, char flags);
+ int (*disable)(struct pnp_dev *dev);
+
+ /* used by pnp layer only (look but don't touch) */
+ unsigned char number; /* protocol number*/
+ struct device dev; /* link to driver model */
+ struct list_head devices;
+};
+
+#define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list)
+
+
+#if defined(CONFIG_PNP)
+
+/* core */
+int pnp_protocol_register(struct pnp_protocol *protocol);
+void pnp_protocol_unregister(struct pnp_protocol *protocol);
+int pnp_init_device(struct pnp_dev *dev);
+int pnp_add_device(struct pnp_dev *dev);
+void pnp_remove_device(struct pnp_dev *dev);
+extern struct list_head pnp_global;
+
+/* resource */
+struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent);
+struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum);
+int pnp_get_max_depnum(struct pnp_dev *dev);
+int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data);
+int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data);
+int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data);
+int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data);
+int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_mem32 *data);
+int pnp_activate_dev(struct pnp_dev *dev);
+int pnp_disable_dev(struct pnp_dev *dev);
+int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode);
+
+/* driver */
+int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
+int pnp_register_driver(struct pnp_driver *drv);
+void pnp_unregister_driver(struct pnp_driver *drv);
+
+/* 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
+
+/* just in case anyone decides to call these without PnP Support Enabled */
+static inline int pnp_protocol_register(struct pnp_protocol *protocol) { return -ENODEV; }
+static inline void pnp_protocol_unregister(struct pnp_protocol *protocol) { ; )
+static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
+static inline void pnp_remove_device(struct pnp_dev *dev) { ; }
+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 int pnp_get_max_depnum(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { 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_raw_set_dev(struct pnp_dev *dev, int depnum, int mode) { return -ENODEV; }
+static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
+static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
+static inline struct pnp_card *pnp_find_card(unsigned short vendor,
+ unsigned short device,
+ struct pnp_card *from) { return NULL; }
+static inline struct pnp_dev *pnp_find_dev(struct pnp_card *card,
+ unsigned short vendor,
+ unsigned short function,
+ struct pnp_dev *from) { return NULL; }
+
+#endif /* CONFIG_PNP */
+
+
+#ifdef DEBUG
+#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg)
+#else
+#define pnp_dbg(format, arg...) do {} while (0)
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_PNP_H */
diff --git a/include/linux/pnpbios.h b/include/linux/pnpbios.h
index e1e8542bda0a..3e5202b1b61c 100644
--- a/include/linux/pnpbios.h
+++ b/include/linux/pnpbios.h
@@ -108,38 +108,9 @@ struct pnp_bios_node {
};
#pragma pack()
-struct pnpbios_device_id
-{
- char id[8];
- unsigned long driver_data;
-};
-
-struct pnpbios_driver {
- struct list_head node;
- char *name;
- const struct pnpbios_device_id *id_table; /* NULL if wants all devices */
- int (*probe) (struct pci_dev *dev, const struct pnpbios_device_id *id); /* New device inserted */
- void (*remove) (struct pci_dev *dev); /* Device removed, either due to hotplug remove or module remove */
-};
-
#ifdef CONFIG_PNPBIOS
-/* exported */
-extern int pnpbios_register_driver(struct pnpbios_driver *drv);
-extern void pnpbios_unregister_driver(struct pnpbios_driver *drv);
-
/* non-exported */
-#define pnpbios_for_each_dev(dev) \
- for(dev = pnpbios_dev_g(pnpbios_devices.next); dev != pnpbios_dev_g(&pnpbios_devices); dev = pnpbios_dev_g(dev->global_list.next))
-
-
-#define pnpbios_dev_g(n) list_entry(n, struct pci_dev, global_list)
-
-static __inline struct pnpbios_driver *pnpbios_dev_driver(const struct pci_dev *dev)
-{
- return (struct pnpbios_driver *)dev->driver;
-}
-
extern int pnpbios_dont_use_current_config;
extern void *pnpbios_kmalloc(size_t size, int f);
extern int pnpbios_init (void);
@@ -161,52 +132,8 @@ extern int pnp_bios_apm_id_table (char *table, u16 *size);
extern int pnp_bios_write_escd (char *data, u32 nvram_base);
#endif
-/*
- * a helper function which helps ensure correct pnpbios_driver
- * setup and cleanup for commonly-encountered hotplug/modular cases
- *
- * This MUST stay in a header, as it checks for -DMODULE
- */
-
-static inline int pnpbios_module_init(struct pnpbios_driver *drv)
-{
- int rc = pnpbios_register_driver (drv);
-
- if (rc > 0)
- return 0;
-
- /* iff CONFIG_HOTPLUG and built into kernel, we should
- * leave the driver around for future hotplug events.
- * For the module case, a hotplug daemon of some sort
- * should load a module in response to an insert event. */
-#if defined(CONFIG_HOTPLUG) && !defined(MODULE)
- if (rc == 0)
- return 0;
-#else
- if (rc == 0)
- rc = -ENODEV;
-#endif
-
- /* if we get here, we need to clean up pci driver instance
- * and return some sort of error */
- pnpbios_unregister_driver (drv);
-
- return rc;
-}
-
-#else /* CONFIG_PNPBIOS */
-
-static __inline__ int pnpbios_register_driver(struct pnpbios_driver *drv)
-{
- return 0;
-}
-
-static __inline__ void pnpbios_unregister_driver(struct pnpbios_driver *drv)
-{
- return;
-}
-
#endif /* CONFIG_PNPBIOS */
+
#endif /* __KERNEL__ */
#endif /* _LINUX_PNPBIOS_H */