Commit 8115f435 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/pnp-2.5
parents 7ba78799 cb59aeb2
......@@ -37,7 +37,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/slab.h>
#include <linux/isapnp.h>
#include <linux/pnp.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver");
......@@ -52,7 +52,7 @@ static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x
struct ns558 {
int type;
int size;
struct pci_dev *dev;
struct pnp_dev *dev;
struct list_head node;
struct gameport gameport;
char phys[32];
......@@ -159,67 +159,55 @@ static void ns558_isa_probe(int io)
list_add(&port->node, &ns558_list);
}
#ifdef __ISAPNP__
#define NS558_DEVICE(a,b,c,d)\
.card_vendor = ISAPNP_ANY_ID, card_device: ISAPNP_ANY_ID,\
.vendor = ISAPNP_VENDOR(a,b,c), function: ISAPNP_DEVICE(d)
static struct isapnp_device_id pnp_devids[] = {
{ NS558_DEVICE('@','P','@',0x0001) }, /* ALS 100 */
{ NS558_DEVICE('@','P','@',0x0020) }, /* ALS 200 */
{ NS558_DEVICE('@','P','@',0x1001) }, /* ALS 100+ */
{ NS558_DEVICE('@','P','@',0x2001) }, /* ALS 120 */
{ NS558_DEVICE('A','S','B',0x16fd) }, /* AdLib NSC16 */
{ NS558_DEVICE('A','Z','T',0x3001) }, /* AZT1008 */
{ NS558_DEVICE('C','D','C',0x0001) }, /* Opl3-SAx */
{ NS558_DEVICE('C','S','C',0x0001) }, /* CS4232 */
{ NS558_DEVICE('C','S','C',0x000f) }, /* CS4236 */
{ NS558_DEVICE('C','S','C',0x0101) }, /* CS4327 */
{ NS558_DEVICE('C','T','L',0x7001) }, /* SB16 */
{ NS558_DEVICE('C','T','L',0x7002) }, /* AWE64 */
{ NS558_DEVICE('C','T','L',0x7005) }, /* Vibra16 */
{ NS558_DEVICE('E','N','S',0x2020) }, /* SoundscapeVIVO */
{ NS558_DEVICE('E','S','S',0x0001) }, /* ES1869 */
{ NS558_DEVICE('E','S','S',0x0005) }, /* ES1878 */
{ NS558_DEVICE('E','S','S',0x6880) }, /* ES688 */
{ NS558_DEVICE('I','B','M',0x0012) }, /* CS4232 */
{ NS558_DEVICE('O','P','T',0x0001) }, /* OPTi Audio16 */
{ NS558_DEVICE('Y','M','H',0x0006) }, /* Opl3-SA */
{ NS558_DEVICE('Y','M','H',0x0022) }, /* Opl3-SAx */
{ NS558_DEVICE('P','N','P',0xb02f) }, /* Generic */
{ 0, },
#ifdef CONFIG_PNP
static struct pnp_device_id pnp_devids[] = {
{ .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
{ .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
{ .id = "@P@2001", .driver_data = 0 }, /* ALS 120 */
{ .id = "ASB16fd", .driver_data = 0 }, /* AdLib NSC16 */
{ .id = "AZT3001", .driver_data = 0 }, /* AZT1008 */
{ .id = "CDC0001", .driver_data = 0 }, /* Opl3-SAx */
{ .id = "CSC0001", .driver_data = 0 }, /* CS4232 */
{ .id = "CSC000f", .driver_data = 0 }, /* CS4236 */
{ .id = "CSC0101", .driver_data = 0 }, /* CS4327 */
{ .id = "CTL7001", .driver_data = 0 }, /* SB16 */
{ .id = "CTL7002", .driver_data = 0 }, /* AWE64 */
{ .id = "CTL7005", .driver_data = 0 }, /* Vibra16 */
{ .id = "ENS2020", .driver_data = 0 }, /* SoundscapeVIVO */
{ .id = "ESS0001", .driver_data = 0 }, /* ES1869 */
{ .id = "ESS0005", .driver_data = 0 }, /* ES1878 */
{ .id = "ESS6880", .driver_data = 0 }, /* ES688 */
{ .id = "IBM0012", .driver_data = 0 }, /* CS4232 */
{ .id = "OPT0001", .driver_data = 0 }, /* OPTi Audio16 */
{ .id = "YMH0006", .driver_data = 0 }, /* Opl3-SA */
{ .id = "YMH0022", .driver_data = 0 }, /* Opl3-SAx */
{ .id = "PNPb02f", .driver_data = 0 }, /* Generic */
{ .id = "", },
};
MODULE_DEVICE_TABLE(isapnp, pnp_devids);
MODULE_DEVICE_TABLE(pnp, pnp_devids);
static void ns558_pnp_probe(struct pci_dev *dev)
static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
int ioport, iolen;
struct ns558 *port;
if (dev->prepare && dev->prepare(dev) < 0)
return;
if (!(dev->resource[0].flags & IORESOURCE_IO)) {
printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n");
return;
}
if (dev->activate && dev->activate(dev) < 0) {
printk(KERN_ERR "ns558: PnP resource allocation failed\n");
return;
return -ENODEV;
}
ioport = pci_resource_start(dev, 0);
iolen = pci_resource_len(dev, 0);
ioport = pnp_port_start(dev,0);
iolen = pnp_port_len(dev,0);
if (!request_region(ioport, iolen, "ns558-pnp"))
goto deactivate;
return -EBUSY;
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
goto deactivate;
return -ENOMEM;
}
memset(port, 0, sizeof(struct ns558));
......@@ -231,36 +219,37 @@ static void ns558_pnp_probe(struct pci_dev *dev)
port->gameport.phys = port->phys;
port->gameport.name = port->name;
port->gameport.id.bustype = BUS_ISAPNP;
port->gameport.id.vendor = dev->vendor;
port->gameport.id.product = dev->device;
port->gameport.id.version = 0x100;
sprintf(port->phys, "isapnp%d.%d/gameport0", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
sprintf(port->phys, "pnp%s/gameport0", dev->dev.bus_id);
sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport");
gameport_register_port(&port->gameport);
printk(KERN_INFO "gameport: NS558 PnP at isapnp%d.%d io %#x",
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), port->gameport.io);
printk(KERN_INFO "gameport: NS558 PnP at pnp%s io %#x",
dev->dev.bus_id, port->gameport.io);
if (iolen > 1) printk(" size %d", iolen);
printk(" speed %d kHz\n", port->gameport.speed);
list_add_tail(&port->node, &ns558_list);
return;
deactivate:
if (dev->deactivate)
dev->deactivate(dev);
return 0;
}
static struct pnp_driver ns558_pnp_driver = {
.name = "ns558",
.id_table = pnp_devids,
.probe = ns558_pnp_probe,
};
#else
static const struct pnp_driver ns558_pnp_driver;
#endif
int __init ns558_init(void)
{
int i = 0;
#ifdef __ISAPNP__
struct isapnp_device_id *devid;
struct pci_dev *dev = NULL;
#endif
/*
* Probe for ISA ports.
......@@ -269,16 +258,7 @@ int __init ns558_init(void)
while (ns558_isa_portlist[i])
ns558_isa_probe(ns558_isa_portlist[i++]);
/*
* Probe for PnP ports.
*/
#ifdef __ISAPNP__
for (devid = pnp_devids; devid->vendor; devid++)
while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev)))
ns558_pnp_probe(dev);
#endif
pnp_register_driver(&ns558_pnp_driver);
return list_empty(&ns558_list) ? -ENODEV : 0;
}
......@@ -290,13 +270,10 @@ void __exit ns558_exit(void)
gameport_unregister_port(&port->gameport);
switch (port->type) {
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
case NS558_PNP:
if (port->dev->deactivate)
port->dev->deactivate(port->dev);
/* fall through */
#endif
case NS558_ISA:
release_region(port->gameport.io, port->size);
break;
......@@ -305,6 +282,7 @@ void __exit ns558_exit(void)
break;
}
}
pnp_unregister_driver(&ns558_pnp_driver);
}
module_init(ns558_init);
......
......@@ -87,8 +87,8 @@
extern int e100_create_proc_subdir(struct e100_private *, char *);
extern void e100_remove_proc_subdir(struct e100_private *, char *);
#else
#define e100_create_proc_subdir(X) 0
#define e100_remove_proc_subdir(X) do {} while(0)
#define e100_create_proc_subdir(X, Y) 0
#define e100_remove_proc_subdir(X, Y) do {} while(0)
#endif
static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
......
......@@ -2973,7 +2973,7 @@ static int __init parport_pc_init_superio(int autoirq, int autodma) {return 0;}
#endif /* CONFIG_PCI */
#ifdef CONFIG_PNP
static const struct pnp_id pnp_dev_table[] = {
static const struct pnp_device_id pnp_dev_table[] = {
/* Standard LPT Printer Port */
{.id = "PNP0400", .driver_data = 0},
/* ECP Printer Port */
......@@ -2984,7 +2984,6 @@ static const struct pnp_id pnp_dev_table[] = {
/* we only need the pnp layer to activate the device, at least for now */
static struct pnp_driver parport_pc_pnp_driver = {
.name = "parport_pc",
.card_id_table = NULL,
.id_table = pnp_dev_table,
};
#else
......
......@@ -2,7 +2,7 @@
# Plug and Play configuration
#
menu "Plug and Play configuration"
menu "Plug and Play support"
config PNP
bool "Plug and Play support"
......@@ -30,6 +30,15 @@ config PNP_NAMES
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
bool "PnP Debug Messages"
depends on PNP
......@@ -42,7 +51,7 @@ comment "Protocols"
config ISAPNP
bool "ISA Plug and Play support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL
depends on PNP && EXPERIMENTAL && PNP_CARD
help
Say Y here if you would like support for ISA Plug and Play devices.
Some information is in <file:Documentation/isapnp.txt>.
......
......@@ -2,11 +2,13 @@
# Makefile for the Linux Plug-and-Play Support.
#
obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o
pnp-card-$(CONFIG_PNP_CARD) = card.o
obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o $(pnp-card-y)
obj-$(CONFIG_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/
export-objs := core.o driver.o resource.o
export-objs := core.o driver.o resource.o $(pnp-card-y)
include $(TOPDIR)/Rules.make
......@@ -4,5 +4,6 @@ extern void *pnp_alloc(long size);
extern int pnp_interface_attach_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_free_ids(struct pnp_dev *dev);
extern void pnp_free_resources(struct pnp_resources *resources);
extern int __pnp_add_device(struct pnp_dev *dev);
extern void __pnp_remove_device(struct pnp_dev *dev);
/*
* card.c - contains functions for managing groups of PnP devices
*
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#ifdef CONFIG_PNP_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/pnp.h>
#include <linux/init.h>
#include "base.h"
LIST_HEAD(pnp_cards);
static const struct pnp_card_id * match_card(struct pnpc_driver *drv, struct pnp_card *card)
{
const struct pnp_card_id *drv_id = drv->id_table;
while (*drv_id->id){
if (compare_pnp_id(card->id,drv_id->id))
return drv_id;
drv_id++;
}
return NULL;
}
static int card_bus_match(struct device *dev, struct device_driver *drv)
{
struct pnp_card * card = to_pnp_card(dev);
struct pnpc_driver * pnp_drv = to_pnpc_driver(drv);
if (match_card(pnp_drv, card) == NULL)
return 0;
return 1;
}
struct bus_type pnpc_bus_type = {
name: "pnp_card",
match: card_bus_match,
};
/**
* pnpc_add_id - adds an EISA id to the specified card
* @id: pointer to a pnp_id structure
* @card: pointer to the desired card
*
*/
int pnpc_add_id(struct pnp_id *id, struct pnp_card *card)
{
struct pnp_id *ptr;
if (!id)
return -EINVAL;
if (!card)
return -EINVAL;
ptr = card->id;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = id;
else
card->id = id;
return 0;
}
static void pnpc_free_ids(struct pnp_card *card)
{
struct pnp_id * id;
struct pnp_id *next;
if (!card)
return;
id = card->id;
while (id) {
next = id->next;
kfree(id);
id = next;
}
}
static void pnp_release_card(struct device *dmdev)
{
struct pnp_card * card = to_pnp_card(dmdev);
pnpc_free_ids(card);
kfree(card);
}
/**
* pnpc_add_card - adds a PnP card to the PnP Layer
* @card: pointer to the card to add
*/
int pnpc_add_card(struct pnp_card *card)
{
int error = 0;
if (!card || !card->protocol)
return -EINVAL;
sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number);
INIT_LIST_HEAD(&card->rdevs);
strcpy(card->dev.name,card->name);
card->dev.parent = &card->protocol->dev;
card->dev.bus = &pnpc_bus_type;
card->dev.release = &pnp_release_card;
error = device_register(&card->dev);
if (error == 0){
struct list_head *pos;
spin_lock(&pnp_lock);
list_add_tail(&card->global_list, &pnp_cards);
list_add_tail(&card->protocol_list, &card->protocol->cards);
spin_unlock(&pnp_lock);
list_for_each(pos,&card->devices){
struct pnp_dev *dev = card_to_pnp_dev(pos);
__pnp_add_device(dev);
}
}
return error;
}
/**
* pnpc_remove_card - removes a PnP card from the PnP Layer
* @card: pointer to the card to remove
*/
void pnpc_remove_card(struct pnp_card *card)
{
struct list_head *pos;
if (!card)
return;
device_unregister(&card->dev);
spin_lock(&pnp_lock);
list_del_init(&card->global_list);
list_del_init(&card->protocol_list);
spin_unlock(&pnp_lock);
list_for_each(pos,&card->devices){
struct pnp_dev *dev = card_to_pnp_dev(pos);
__pnp_remove_device(dev);
}
}
/**
* pnpc_add_device - adds a device to the specified card
* @card: pointer to the card to add to
* @dev: pointer to the device to add
*/
int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev)
{
if (!dev || !dev->protocol || !card)
return -EINVAL;
dev->dev.parent = &card->dev;
sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number, card->number,dev->number);
spin_lock(&pnp_lock);
dev->card = card;
list_add_tail(&dev->card_list, &card->devices);
spin_unlock(&pnp_lock);
return 0;
}
/**
* pnpc_remove_device- removes a device from the specified card
* @card: pointer to the card to remove from
* @dev: pointer to the device to remove
*/
void pnpc_remove_device(struct pnp_dev *dev)
{
spin_lock(&pnp_lock);
dev->card = NULL;
list_del_init(&dev->card_list);
spin_unlock(&pnp_lock);
__pnp_remove_device(dev);
}
/**
* pnp_request_card_device - Searches for a PnP device under the specified card
* @card: pointer to the card to search under, cannot be NULL
* @id: pointer to a PnP ID structure that explains the rules for finding the device
* @from: Starting place to search from. If NULL it will start from the begining.
*
* Will activate the device
*/
struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from)
{
struct list_head *pos;
struct pnp_dev *dev;
if (!card || !id)
goto done;
if (!from) {
pos = card->devices.next;
} else {
if (from->card != card)
goto done;
pos = from->card_list.next;
}
while (pos != &card->devices) {
dev = card_to_pnp_dev(pos);
if (compare_pnp_id(dev->id,id))
goto found;
pos = pos->next;
}
done:
return NULL;
found:
if (dev->active == 0)
if(pnp_activate_dev(dev)<0)
return NULL;
spin_lock(&pnp_lock);
list_add_tail(&dev->rdev_list, &card->rdevs);
spin_unlock(&pnp_lock);
return dev;
}
/**
* pnp_release_card_device - call this when the driver no longer needs the device
* @dev: pointer to the PnP device stucture
*
* Will disable the device
*/
void pnp_release_card_device(struct pnp_dev *dev)
{
spin_lock(&pnp_lock);
list_del_init(&dev->rdev_list);
spin_unlock(&pnp_lock);
pnp_disable_dev(dev);
}
static void pnpc_recover_devices(struct pnp_card *card)
{
struct list_head *pos;
list_for_each(pos,&card->rdevs){
struct pnp_dev *dev = list_entry(pos, struct pnp_dev, rdev_list);
pnp_release_card_device(dev);
}
}
static int pnpc_card_probe(struct device *dev)
{
int error = 0;
struct pnpc_driver *drv = to_pnpc_driver(dev->driver);
struct pnp_card *card = to_pnp_card(dev);
const struct pnp_card_id *card_id = NULL;
pnp_dbg("pnp: match found with the PnP card '%s' and the driver '%s'", dev->bus_id,drv->name);
if (drv->probe) {
card_id = match_card(drv, card);
if (card_id != NULL)
error = drv->probe(card, card_id);
if (error >= 0){
card->driver = drv;
error = 0;
} else
pnpc_recover_devices(card);
}
return error;
}
static int pnpc_card_remove(struct device *dev)
{
struct pnp_card * card = to_pnp_card(dev);
struct pnpc_driver * drv = card->driver;
if (drv) {
if (drv->remove)
drv->remove(card);
card->driver = NULL;
}
pnpc_recover_devices(card);
return 0;
}
/**
* pnpc_register_driver - registers a PnP card driver with the PnP Layer
* @cdrv: pointer to the driver to register
*/
int pnpc_register_driver(struct pnpc_driver * drv)
{
int count;
struct list_head *pos;
drv->driver.name = drv->name;
drv->driver.bus = &pnpc_bus_type;
drv->driver.probe = pnpc_card_probe;
drv->driver.remove = pnpc_card_remove;
pnp_dbg("the card driver '%s' has been registered", drv->name);
count = driver_register(&drv->driver);
/* get the number of initial matches */
if (count >= 0){
count = 0;
list_for_each(pos,&drv->driver.devices){
count++;
}
}
return count;
}
/**
* pnpc_unregister_driver - unregisters a PnP card driver from the PnP Layer
* @cdrv: pointer to the driver to unregister
*
* Automatically disables requested devices
*/
void pnpc_unregister_driver(struct pnpc_driver *drv)
{
driver_unregister(&drv->driver);
pnp_dbg("the card driver '%s' has been unregistered", drv->name);
}
static int __init pnp_card_init(void)
{
printk(KERN_INFO "pnp: Enabling Plug and Play Card Services.\n");
return bus_register(&pnpc_bus_type);
}
subsys_initcall(pnp_card_init);
EXPORT_SYMBOL(pnpc_add_card);
EXPORT_SYMBOL(pnpc_remove_card);
EXPORT_SYMBOL(pnpc_add_device);
EXPORT_SYMBOL(pnpc_remove_device);
EXPORT_SYMBOL(pnp_request_card_device);
EXPORT_SYMBOL(pnp_release_card_device);
EXPORT_SYMBOL(pnpc_register_driver);
EXPORT_SYMBOL(pnpc_unregister_driver);
EXPORT_SYMBOL(pnpc_add_id);
......@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include "base.h"
......@@ -41,7 +42,7 @@ void *pnp_alloc(long size)
* Ex protocols: ISAPNP, PNPBIOS, etc
*/
int pnp_protocol_register(struct pnp_protocol *protocol)
int pnp_register_protocol(struct pnp_protocol *protocol)
{
int nodenum;
struct list_head * pos;
......@@ -50,6 +51,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol)
return -EINVAL;
INIT_LIST_HEAD(&protocol->devices);
INIT_LIST_HEAD(&protocol->cards);
nodenum = 0;
spin_lock(&pnp_lock);
......@@ -76,7 +78,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol)
* @protocol: pointer to the corresponding pnp_protocol structure
*
*/
void pnp_protocol_unregister(struct pnp_protocol *protocol)
void pnp_unregister_protocol(struct pnp_protocol *protocol)
{
spin_lock(&pnp_lock);
list_del_init(&protocol->protocol_list);
......@@ -84,17 +86,19 @@ void pnp_protocol_unregister(struct pnp_protocol *protocol)
device_unregister(&protocol->dev);
}
/**
* pnp_init_device - pnp protocols should call this before adding a PnP device
* @dev: pointer to dev to init
*
* for now it only inits dev->ids, more later?
*/
int pnp_init_device(struct pnp_dev *dev)
static void pnp_free_ids(struct pnp_dev *dev)
{
INIT_LIST_HEAD(&dev->ids);
return 0;
struct pnp_id * id;
struct pnp_id * next;
if (!dev)
return;
id = dev->id;
while (id) {
next = id->next;
kfree(id);
id = next;
}
}
static void pnp_release_device(struct device *dmdev)
......@@ -106,68 +110,73 @@ static void pnp_release_device(struct device *dmdev)
kfree(dev);
}
/**
* pnp_add_device - adds a pnp device to the pnp layer
* @dev: pointer to dev to add
*
* adds to driver model, name database, fixups, interface, etc.
*/
int pnp_add_device(struct pnp_dev *dev)
int __pnp_add_device(struct pnp_dev *dev)
{
int error = 0;
if (!dev || !dev->protocol)
return -EINVAL;
if (dev->card)
sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number,
dev->card->number,dev->number);
else
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
dev->number);
pnp_name_device(dev);
pnp_fixup_device(dev);
strcpy(dev->dev.name,dev->name);
dev->dev.parent = &dev->protocol->dev;
dev->dev.bus = &pnp_bus_type;
dev->dev.release = &pnp_release_device;
error = device_register(&dev->dev);
if (error == 0){
spin_lock(&pnp_lock);
list_add_tail(&dev->global_list, &pnp_global);
list_add_tail(&dev->dev_list, &dev->protocol->devices);
list_add_tail(&dev->protocol_list, &dev->protocol->devices);
spin_unlock(&pnp_lock);
pnp_interface_attach_device(dev);
}
return error;
}
/*
* pnp_add_device - adds a pnp device to the pnp layer
* @dev: pointer to dev to add
*
* adds to driver model, name database, fixups, interface, etc.
*/
int pnp_add_device(struct pnp_dev *dev)
{
if (!dev || !dev->protocol || dev->card)
return -EINVAL;
dev->dev.parent = &dev->protocol->dev;
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, dev->number);
return __pnp_add_device(dev);
}
void __pnp_remove_device(struct pnp_dev *dev)
{
spin_lock(&pnp_lock);
list_del_init(&dev->global_list);
list_del_init(&dev->protocol_list);
spin_unlock(&pnp_lock);
device_unregister(&dev->dev);
}
/**
* pnp_remove_device - removes a pnp device from the pnp layer
* @dev: pointer to dev to add
*
* this function will free all mem used by dev
*/
void pnp_remove_device(struct pnp_dev *dev)
{
if (!dev)
if (!dev || dev->card)
return;
device_unregister(&dev->dev);
spin_lock(&pnp_lock);
list_del_init(&dev->global_list);
list_del_init(&dev->dev_list);
spin_unlock(&pnp_lock);
__pnp_remove_device(dev);
}
static int __init pnp_init(void)
{
printk(KERN_INFO "Linux Plug and Play Support v0.9 (c) Adam Belay\n");
printk(KERN_INFO "Linux Plug and Play Support v0.93 (c) Adam Belay\n");
return bus_register(&pnp_bus_type);
}
subsys_initcall(pnp_init);
EXPORT_SYMBOL(pnp_protocol_register);
EXPORT_SYMBOL(pnp_protocol_unregister);
EXPORT_SYMBOL(pnp_register_protocol);
EXPORT_SYMBOL(pnp_unregister_protocol);
EXPORT_SYMBOL(pnp_add_device);
EXPORT_SYMBOL(pnp_remove_device);
EXPORT_SYMBOL(pnp_init_device);
......@@ -34,46 +34,30 @@ static int compare_func(const char *ida, const char *idb)
return 1;
}
int compare_pnp_id(struct list_head *id_list, const char *id)
int compare_pnp_id(struct pnp_id *pos, const char *id)
{
struct list_head *pos;
if (!id_list || !id || (strlen(id) != 7))
if (!pos || !id || (strlen(id) != 7))
return 0;
if (memcmp(id,"ANYDEVS",7)==0)
return 1;
list_for_each(pos,id_list){
struct pnp_id *pnp_id = to_pnp_id(pos);
if (memcmp(pnp_id->id,id,3)==0)
if (compare_func(pnp_id->id,id)==1)
while (pos){
if (memcmp(pos->id,id,3)==0)
if (compare_func(pos->id,id)==1)
return 1;
pos = pos->next;
}
return 0;
}
static const struct pnp_id * match_card(struct pnp_driver *drv, struct pnp_card *card)
{
const struct pnp_id *drv_card_id = drv->card_id_table;
if (!drv)
return NULL;
if (!card)
return NULL;
while (*drv_card_id->id){
if (compare_pnp_id(&card->ids,drv_card_id->id))
return drv_card_id;
drv_card_id++;
}
return NULL;
}
static const struct pnp_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_id *drv_id = drv->id_table;
const struct pnp_device_id *drv_id = drv->id_table;
if (!drv)
return NULL;
if (!dev)
return NULL;
while (*drv_id->id){
if (compare_pnp_id(&dev->ids,drv_id->id))
if (compare_pnp_id(dev->id,drv_id->id))
return drv_id;
drv_id++;
}
......@@ -85,33 +69,24 @@ static int pnp_device_probe(struct device *dev)
int error = 0;
struct pnp_driver *pnp_drv;
struct pnp_dev *pnp_dev;
const struct pnp_id *card_id = NULL;
const struct pnp_id *dev_id = NULL;
const struct pnp_device_id *dev_id = NULL;
pnp_dev = to_pnp_dev(dev);
pnp_drv = to_pnp_driver(dev->driver);
pnp_dbg("pnp: match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name);
if (pnp_dev->active == 0)
if(pnp_activate_dev(pnp_dev)<0)
return -1;
if (pnp_drv->probe && pnp_dev->active) {
if (pnp_dev->card && pnp_drv->card_id_table){
card_id = match_card(pnp_drv, pnp_dev->card);
if (card_id != NULL)
dev_id = match_device(pnp_drv, pnp_dev);
if (dev_id != NULL)
error = pnp_drv->probe(pnp_dev, card_id, dev_id);
}
else{
dev_id = match_device(pnp_drv, pnp_dev);
if (dev_id != NULL)
error = pnp_drv->probe(pnp_dev, card_id, dev_id);
error = pnp_drv->probe(pnp_dev, dev_id);
}
if (error >= 0){
pnp_dev->driver = pnp_drv;
error = 0;
}
}
return error;
}
......@@ -133,9 +108,6 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv)
{
struct pnp_dev * pnp_dev = to_pnp_dev(dev);
struct pnp_driver * pnp_drv = to_pnp_driver(drv);
if (pnp_dev->card && pnp_drv->card_id_table
&& match_card(pnp_drv, pnp_dev->card) == NULL)
return 0;
if (match_device(pnp_drv, pnp_dev) == NULL)
return 0;
return 1;
......@@ -174,8 +146,8 @@ int pnp_register_driver(struct pnp_driver *drv)
void pnp_unregister_driver(struct pnp_driver *drv)
{
pnp_dbg("the driver '%s' has been unregistered", drv->name);
driver_unregister(&drv->driver);
pnp_dbg("the driver '%s' has been unregistered", drv->name);
}
/**
......@@ -187,25 +159,21 @@ void pnp_unregister_driver(struct pnp_driver *drv)
int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
{
struct pnp_id *ptr;
if (!id)
return -EINVAL;
if (!dev)
return -EINVAL;
list_add_tail(&id->id_list,&dev->ids);
ptr = dev->id;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = id;
else
dev->id = id;
return 0;
}
void pnp_free_ids(struct pnp_dev *dev)
{
struct list_head *pos;
if (!dev)
return;
list_for_each(pos,&dev->ids){
struct pnp_id *pnp_id = to_pnp_id(pos);
kfree(pnp_id);
}
}
EXPORT_SYMBOL(pnp_register_driver);
EXPORT_SYMBOL(pnp_unregister_driver);
EXPORT_SYMBOL(pnp_add_id);
......@@ -321,13 +321,13 @@ static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR,
static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf, size_t count, loff_t off)
{
char *str = buf;
struct list_head * pos;
struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_id * pos = dev->id;
if (off)
return 0;
list_for_each(pos,&dev->ids) {
struct pnp_id * cur = to_pnp_id(pos);
str += sprintf(str,"%s\n", cur->id);
while (pos) {
str += sprintf(str,"%s\n", pos->id);
pos = pos->next;
}
return (str - buf);
}
......
......@@ -2,10 +2,10 @@
# Makefile for the kernel ISAPNP driver.
#
export-objs := core.o compat.o
export-objs := core.o
isapnp-proc-$(CONFIG_PROC_FS) = proc.o
obj-y := core.o compat.o $(isapnp-proc-y)
obj-y := core.o $(isapnp-proc-y)
include $(TOPDIR)/Rules.make
......@@ -449,13 +449,13 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
dev = isapnp_alloc(sizeof(struct pnp_dev));
if (!dev)
return NULL;
pnp_init_device(dev);
dev->number = number;
isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
dev->regs = tmp[4];
dev->card = card;
if (size > 5)
dev->regs |= tmp[5] << 8;
dev->protocol = &isapnp_protocol;
return dev;
}
......@@ -640,7 +640,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1;
if (pnp_build_resource(dev, 0) == NULL)
return 1;
list_add_tail(&dev->card_list, &card->devices);
pnpc_add_device(card,dev);
while (1) {
if (isapnp_read_tag(&type, &size)<0)
return 1;
......@@ -653,7 +653,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
pnp_build_resource(dev,0);
list_add_tail(&dev->card_list, &card->devices);
pnpc_add_device(card,dev);
size = 0;
skip = 0;
} else {
......@@ -848,7 +848,7 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor,
device & 0x0f,
(device >> 12) & 0x0f,
(device >> 8) & 0x0f);
list_add_tail(&id->id_list,&card->ids);
pnpc_add_id(id,card);
}
/*
......@@ -879,12 +879,11 @@ static int __init isapnp_build_device_list(void)
;
else if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */
continue;
if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL)
continue;
card->number = csn;
INIT_LIST_HEAD(&card->devices);
INIT_LIST_HEAD(&card->ids);
isapnp_parse_card_id(card, (header[1] << 8) | header[0], (header[3] << 8) | header[2]);
card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
isapnp_checksum_value = 0x00;
......@@ -892,8 +891,8 @@ static int __init isapnp_build_device_list(void)
if (isapnp_checksum_value != 0x00)
printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
card->checksum = isapnp_checksum_value;
list_add_tail(&card->node, &isapnp_cards);
card->protocol = &isapnp_protocol;
pnpc_add_card(card);
}
return 0;
}
......@@ -1061,25 +1060,6 @@ struct pnp_protocol isapnp_protocol = {
.disable = isapnp_disable_resources,
};
static inline int isapnp_init_device_tree(void)
{
struct pnp_card *card;
isapnp_for_each_card(card) {
struct list_head *devlist;
for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
struct pnp_dev *dev = card_to_pnp_dev(devlist);
snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", dev->name);
dev->card = card;
dev->protocol = &isapnp_protocol;
pnp_add_device(dev);
}
}
return 0;
}
int __init isapnp_init(void)
{
int cards;
......@@ -1104,7 +1084,7 @@ int __init isapnp_init(void)
return -EBUSY;
}
if(pnp_protocol_register(&isapnp_protocol)<0)
if(pnp_register_protocol(&isapnp_protocol)<0)
return -EBUSY;
/*
......@@ -1143,7 +1123,7 @@ int __init isapnp_init(void)
isapnp_build_device_list();
cards = 0;
isapnp_for_each_card(card) {
protocol_for_each_card(&isapnp_protocol,card) {
cards++;
if (isapnp_verbose) {
struct list_head *devlist;
......@@ -1162,7 +1142,6 @@ int __init isapnp_init(void)
printk(KERN_INFO "isapnp: No Plug & Play card found\n");
}
isapnp_init_device_tree();
isapnp_proc_init();
return 0;
}
......
......@@ -146,7 +146,7 @@ int __init isapnp_proc_init(void)
{
struct pnp_dev *dev;
isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus);
isapnp_for_each_dev(dev) {
protocol_for_each_dev(&isapnp_protocol,dev) {
isapnp_proc_attach_device(dev);
}
return 0;
......
......@@ -32,7 +32,7 @@ pnp_name_device(struct pnp_dev *dev)
int i;
char *name = dev->name;
for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){
if (compare_pnp_id(&dev->ids,pnp_id_eisaid[i])){
if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){
sprintf(name, "%s", pnp_id_names[i]);
return;
}
......
......@@ -1256,6 +1256,12 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
struct pnp_dev_node_info node_info;
u8 nodenum = dev->number;
struct pnp_bios_node * node;
/* just in case */
if(dev->driver)
return -EBUSY;
if(!pnp_is_dynamic(dev))
return -EPERM;
if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV;
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
......@@ -1273,10 +1279,15 @@ static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config, ch
struct pnp_dev_node_info node_info;
u8 nodenum = dev->number;
struct pnp_bios_node * node;
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
/* just in case */
if(dev->driver)
return -EBUSY;
if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev))
return -EPERM;
if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV;
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -1;
if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
......@@ -1323,16 +1334,21 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
struct pnp_bios_node * node;
if (!config)
return -1;
/* just in case */
if(dev->driver)
return -EBUSY;
if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev))
return -EPERM;
memset(config, 0, sizeof(struct pnp_cfg));
if (!dev || !dev->active)
return -EINVAL;
for (i=0; i <= 8; i++)
for (i=0; i < 8; i++)
config->port[i] = &port;
for (i=0; i <= 4; i++)
for (i=0; i < 4; i++)
config->mem[i] = &mem;
for (i=0; i <= 2; i++)
for (i=0; i < 2; i++)
config->irq[i] = &irq;
for (i=0; i <= 2; i++)
for (i=0; i < 2; i++)
config->dma[i] = &dma;
dev->active = 0;
......@@ -1369,7 +1385,7 @@ static int inline insert_device(struct pnp_dev *dev)
struct list_head * pos;
struct pnp_dev * pnp_dev;
list_for_each (pos, &pnpbios_protocol.devices){
pnp_dev = list_entry(pos, struct pnp_dev, dev_list);
pnp_dev = list_entry(pos, struct pnp_dev, protocol_list);
if (dev->number == pnp_dev->number)
return -1;
}
......@@ -1402,10 +1418,13 @@ static void __init build_devlist(void)
for(nodenum=0; nodenum<0xff; ) {
u8 thisnodenum = nodenum;
/* We build the list from the "boot" config because
* asking for the "current" config causes some
* BIOSes to crash.
* we know that the resources couldn't have changed
* at this stage. Furthermore some buggy PnP BIOSes
* will crash if we request the "current" config
* from devices that are can only be static such as
* those controlled by the "system" driver.
*/
if (pnp_bios_get_dev_node(&nodenum, (char )0 , node))
if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
break;
nodes_got++;
dev = pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL);
......@@ -1416,7 +1435,6 @@ static void __init build_devlist(void)
if (!dev_id)
break;
memset(dev_id,0,sizeof(struct pnp_id));
pnp_init_device(dev);
dev->number = thisnodenum;
memcpy(dev->name,"Unknown Device",13);
dev->name[14] = '\0';
......@@ -1426,6 +1444,7 @@ static void __init build_devlist(void)
pos = node_current_resource_data_to_dev(node,dev);
pos = node_possible_resource_data_to_dev(pos,node,dev);
node_id_data_to_dev(pos,node,dev);
dev->flags = node->flags;
dev->protocol = &pnpbios_protocol;
......@@ -1450,10 +1469,7 @@ static void __init build_devlist(void)
*
*/
extern int is_sony_vaio_laptop;
static int pnpbios_disabled; /* = 0 */
static int dont_reserve_resources; /* = 0 */
int pnpbios_dont_use_current_config; /* = 0 */
#ifndef MODULE
......@@ -1471,8 +1487,6 @@ static int __init pnpbios_setup(char *str)
str += 3;
if (strncmp(str, "curr", 4) == 0)
pnpbios_dont_use_current_config = invert;
if (strncmp(str, "res", 3) == 0)
dont_reserve_resources = invert;
str = strchr(str, ',');
if (str != NULL)
str += strspn(str, ", \t");
......@@ -1499,9 +1513,6 @@ int __init pnpbios_init(void)
return -ENODEV;
}
if ( is_sony_vaio_laptop )
pnpbios_dont_use_current_config = 1;
/*
* Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
* structure and, if one is found, sets up the selectors and
......@@ -1544,7 +1555,7 @@ int __init pnpbios_init(void)
}
if (!pnp_bios_present())
return -ENODEV;
pnp_protocol_register(&pnpbios_protocol);
pnp_register_protocol(&pnpbios_protocol);
build_devlist();
/*if ( ! dont_reserve_resources )*/
/*reserve_resources();*/
......
......@@ -157,7 +157,7 @@ void pnp_fixup_device(struct pnp_dev *dev)
int i = 0;
while (*pnp_fixups[i].id) {
if (compare_pnp_id(&dev->ids,pnp_fixups[i].id)) {
if (compare_pnp_id(dev->id,pnp_fixups[i].id)) {
pnp_dbg("Calling quirk for %s",
dev->dev.bus_id);
pnp_fixups[i].quirk_function(dev);
......
......@@ -13,12 +13,7 @@
#include <linux/kernel.h>
#include <linux/ioport.h>
static const struct pnp_id pnp_card_table[] = {
{ "ANYDEVS", 0 },
{ "", 0 }
};
static const struct pnp_id pnp_dev_table[] = {
static const struct pnp_device_id pnp_dev_table[] = {
/* General ID for reserving resources */
{ "PNP0c02", 0 },
/* memory controller */
......@@ -101,7 +96,7 @@ static void __init reserve_resources_of_dev( struct pnp_dev *dev )
return;
}
static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
{
reserve_resources_of_dev(dev);
return 0;
......@@ -109,7 +104,6 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id,
static struct pnp_driver system_pnp_driver = {
.name = "system",
.card_id_table = pnp_card_table,
.id_table = pnp_dev_table,
.probe = system_pnp_probe,
.remove = NULL,
......
......@@ -33,12 +33,7 @@
#define UNKNOWN_DEV 0x3000
static const struct pnp_id pnp_card_table[] = {
{ "ANYDEVS", 0 },
{ "", 0 }
};
static const struct pnp_id pnp_dev_table[] = {
static const struct pnp_device_id pnp_dev_table[] = {
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
{ "AAC000F", 0 },
......@@ -316,6 +311,8 @@ static const struct pnp_id pnp_dev_table[] = {
{ "", 0 }
};
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
static void inline avoid_irq_share(struct pnp_dev *dev)
{
unsigned int map = 0x1FF8;
......@@ -384,7 +381,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
}
static int
serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
{
struct serial_struct serial_req;
int ret, line, flags = dev_id->driver_data;
......@@ -393,10 +390,10 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc
if (flags & SPCI_FL_NO_SHIRQ)
avoid_irq_share(dev);
memset(&serial_req, 0, sizeof(serial_req));
serial_req.irq = dev->irq_resource[0].start;
serial_req.port = pci_resource_start(dev, 0);
serial_req.irq = pnp_irq(dev,0);
serial_req.port = pnp_port_start(dev, 0);
if (HIGH_BITS_OFFSET)
serial_req.port = dev->resource[0].start >> HIGH_BITS_OFFSET;
serial_req.port = pnp_port_start(dev, 0) >> HIGH_BITS_OFFSET;
#ifdef SERIAL_DEBUG_PNP
printk("Setup PNP port: port %x, irq %d, type %d\n",
serial_req.port, serial_req.irq, serial_req.io_type);
......@@ -407,7 +404,7 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc
line = register_serial(&serial_req);
if (line >= 0)
dev->driver_data = (void *)(line + 1);
pnp_set_drvdata(dev, (void *)(line + 1));
return line >= 0 ? 0 : -ENODEV;
}
......@@ -419,7 +416,6 @@ static void serial_pnp_remove(struct pnp_dev * dev)
static struct pnp_driver serial_pnp_driver = {
.name = "serial",
.card_id_table = pnp_card_table,
.id_table = pnp_dev_table,
.probe = serial_pnp_probe,
.remove = serial_pnp_remove,
......@@ -442,5 +438,3 @@ EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
/* FIXME */
/*MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table);*/
This diff is collapsed.
......@@ -75,6 +75,19 @@
#define PNPMSG_POWER_OFF 0x41
#define PNPMSG_PNP_OS_ACTIVE 0x42
#define PNPMSG_PNP_OS_INACTIVE 0x43
/*
* Plug and Play BIOS flags
*/
#define PNP_NO_DISABLE 0x0001
#define PNP_NO_CONFIG 0x0002
#define PNP_OUTPUT 0x0004
#define PNP_INPUT 0x0008
#define PNP_BOOTABLE 0x0010
#define PNP_DOCK 0x0020
#define PNP_REMOVABLE 0x0040
#define pnp_is_static(x) (x->flags & 0x0100) == 0x0000
#define pnp_is_dynamic(x) x->flags & 0x0080
/* 0x8000 through 0xffff are OEM defined */
#pragma pack(1)
......
......@@ -61,16 +61,18 @@ extern struct proc_dir_entry *proc_net_rpc;
#else
static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
static inline void rpc_proc_unregister(const char *p) {}
static inline int rpc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; }
static inline void rpc_proc_zero(struct rpc_program *p) {}
static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s) { return NULL; }
static inline void svc_proc_unregister(const char *p) {}
static inline struct proc_dir_entry*svc_proc_register(struct svc_stat *s)
{
return NULL;
}
static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; }
static inline void svc_proc_zero(struct svc_program *p) {}
#define proc_net_rpc NULL
static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f)
{
return 0;
}
#endif
#endif /* _LINUX_SUNRPC_STATS_H */
......@@ -24,11 +24,7 @@
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/slab.h>
#ifndef LINUX_ISAPNP_H
#include <linux/isapnp.h>
#define isapnp_card pci_bus
#define isapnp_dev pci_dev
#endif
#include <linux/pnp.h>
#include <sound/core.h>
#include <sound/cs4231.h>
#include <sound/mpu401.h>
......@@ -51,7 +47,7 @@ MODULE_DEVICES("{{Yamaha,YMF719E-S},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */
......@@ -73,7 +69,7 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC);
......@@ -147,8 +143,8 @@ struct snd_opl3sa2 {
snd_hwdep_t *synth;
snd_rawmidi_t *rmidi;
cs4231_t *cs4231;
#ifdef __ISAPNP__
struct isapnp_dev *dev;
#ifdef CONFIG_PNP
struct pnp_dev *dev;
#endif
unsigned char ctlregs[0x20];
int ymode; /* SL added */
......@@ -163,33 +159,27 @@ struct snd_opl3sa2 {
static snd_card_t *snd_opl3sa2_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#ifdef __ISAPNP__
static struct isapnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
static const struct isapnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
#ifdef CONFIG_PNP
#define ISAPNP_OPL3SA2(_va, _vb, _vc, _device, _function) \
{ \
ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _function), } \
}
static struct pnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
static const struct pnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = {
static struct pnp_card_id snd_opl3sa2_pnpids[] = {
/* Yamaha YMF719E-S (Genius Sound Maker 3DX) */
ISAPNP_OPL3SA2('Y','M','H',0x0020,0x0021),
{.id = "YMH0020", .driver_data = 0, devs : { {.id="YMH0021"}, } },
/* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */
ISAPNP_OPL3SA2('Y','M','H',0x0030,0x0021),
{.id = "YMH0030", .driver_data = 0, devs : { {.id="YMH0021"}, } },
/* Yamaha OPL3-SA2 */
ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021),
{.id = "YMH0800", .driver_data = 0, devs : { {.id="YMH0021"}, } },
/* NeoMagic MagicWave 3DX */
ISAPNP_OPL3SA2('N','M','X',0x2200,0x2210),
{.id = "NMX2200", .driver_data = 0, devs : { {.id="NMX2210"}, } },
/* --- */
{ ISAPNP_CARD_END, } /* end */
{.id = "", } /* end */
};
ISAPNP_CARD_TABLE(snd_opl3sa2_pnpids);
/*PNP_CARD_TABLE(snd_opl3sa2_pnpids);*/
#endif /* __ISAPNP__ */
#endif /* CONFIG_PNP */
/* read control port (w/o spinlock) */
......@@ -634,41 +624,18 @@ static int snd_opl3sa2_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *
#endif /* CONFIG_PM */
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip)
{
const struct isapnp_card_id *id = snd_opl3sa2_isapnp_id[dev];
struct isapnp_card *card = snd_opl3sa2_isapnp_cards[dev];
struct isapnp_dev *pdev;
const struct pnp_card_id *id = snd_opl3sa2_isapnp_id[dev];
struct pnp_card *card = snd_opl3sa2_isapnp_cards[dev];
struct pnp_dev *pdev;
chip->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);
if (chip->dev->active) {
chip->dev = NULL;
return -EBUSY;
}
/* PnP initialization */
chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
pdev = chip->dev;
if (pdev->prepare(pdev)<0)
return -EAGAIN;
if (sb_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[0], sb_port[dev], 16);
if (wss_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[1], wss_port[dev], 8);
if (fm_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[2], fm_port[dev], 4);
if (midi_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[3], midi_port[dev], 2);
if (port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[4], port[dev], 2);
if (dma1[dev] != SNDRV_AUTO_DMA)
isapnp_resource_change(&pdev->dma_resource[0], dma1[dev], 1);
if (dma2[dev] != SNDRV_AUTO_DMA)
isapnp_resource_change(&pdev->dma_resource[1], dma2[dev], 1);
if (irq[dev] != SNDRV_AUTO_IRQ)
isapnp_resource_change(&pdev->irq_resource[0], irq[dev], 1);
if (pdev->activate(pdev)<0) {
snd_printk("isapnp configure failure (out of resources?)\n");
return -EBUSY;
if (!pdev){
snd_printdd("isapnp OPL3-SA: a card was found but it did not contain the needed devices\n",);
return -ENODEV;
}
sb_port[dev] = pdev->resource[0].start;
wss_port[dev] = pdev->resource[1].start;
......@@ -685,19 +652,12 @@ static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip)
return 0;
}
static void snd_opl3sa2_deactivate(opl3sa2_t *chip)
{
if (chip->dev) {
chip->dev->deactivate(chip->dev);
chip->dev = NULL;
}
}
#endif /* __ISAPNP__ */
#endif /* CONFIG_PNP */
static int snd_opl3sa2_free(opl3sa2_t *chip)
{
#ifdef __ISAPNP__
snd_opl3sa2_deactivate(chip);
#ifdef CONFIG_PNP
chip->dev = NULL;
#endif
#ifdef CONFIG_PM
if (chip->pm_dev)
......@@ -731,7 +691,7 @@ static int __init snd_opl3sa2_probe(int dev)
};
int err;
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
if (!isapnp[dev]) {
#endif
if (port[dev] == SNDRV_AUTO_PORT) {
......@@ -750,7 +710,7 @@ static int __init snd_opl3sa2_probe(int dev)
snd_printk("specify midi_port\n");
return -EINVAL;
}
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
}
#endif
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
......@@ -766,7 +726,7 @@ static int __init snd_opl3sa2_probe(int dev)
chip->irq = -1;
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
goto __error;
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
if (isapnp[dev] && (err = snd_opl3sa2_isapnp(dev, chip)) < 0)
goto __error;
#endif
......@@ -854,9 +814,9 @@ static int __init snd_opl3sa2_probe(int dev)
return err;
}
#ifdef __ISAPNP__
static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card,
const struct isapnp_card_id *id)
#ifdef CONFIG_PNP
static int __init snd_opl3sa2_isapnp_detect(struct pnp_card *card,
const struct pnp_card_id *id)
{
static int dev;
int res;
......@@ -874,7 +834,20 @@ static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card,
}
return -ENODEV;
}
#endif /* __ISAPNP__ */
static void snd_opl3sa2_isapnp_remove(struct pnp_card * card)
{
/* FIXME */
}
static struct pnpc_driver opl3sa2_pnpc_driver = {
.name = "opl3sa2",
.id_table = snd_opl3sa2_pnpids,
.probe = snd_opl3sa2_isapnp_detect,
.remove = snd_opl3sa2_isapnp_remove,
};
#endif /* CONFIG_PNP */
static int __init alsa_card_opl3sa2_init(void)
{
......@@ -883,15 +856,15 @@ static int __init alsa_card_opl3sa2_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
if (isapnp[dev])
continue;
#endif
if (snd_opl3sa2_probe(dev) >= 0)
cards++;
}
#ifdef __ISAPNP__
cards += isapnp_probe_cards(snd_opl3sa2_pnpids, snd_opl3sa2_isapnp_detect);
#ifdef CONFIG_PNP
cards += pnpc_register_driver(&opl3sa2_pnpc_driver);
#endif
if (!cards) {
#ifdef MODULE
......@@ -940,7 +913,7 @@ static int __init alsa_card_opl3sa2_setup(char *str)
get_option(&str,&dma1[nr_dev]) == 2 &&
get_option(&str,&dma2[nr_dev]) == 2 &&
get_option(&str,&opl3sa3_ymode[nr_dev]) == 2);
#ifdef __ISAPNP__
#ifdef CONFIG_PNP
if (pnp != INT_MAX)
isapnp[nr_dev] = pnp;
#endif
......
......@@ -841,10 +841,9 @@ struct pnp_id pnp_opl3sa2_list[] = {
{.id = ""}
};
/*MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);*/
MODULE_DEVICE_TABLE(pnp, pnp_opl3sa2_list);
static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id,
const struct pnp_id *dev_id)
static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *dev_id)
{
int card = opl3sa2_cards_num;
if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX)
......@@ -883,7 +882,6 @@ static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id,
static struct pnp_driver opl3sa2_driver = {
.name = "opl3sa2",
.card_id_table = NULL,
.id_table = pnp_opl3sa2_list,
.probe = opl3sa2_pnp_probe,
};
......
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