Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (29 commits)
  pcmcia: disable PCMCIA ioctl also for ARM
  drivers/staging/comedi: dev_node removal (quatech_daqp_cs)
  drivers/staging/comedi: dev_node removal (ni_mio_cs)
  drivers/staging/comedi: dev_node removal (ni_labpc_cs)
  drivers/staging/comedi: dev_node removal (ni_daq_dio24)
  drivers/staging/comedi: dev_node removal (ni_daq_700)
  drivers/staging/comedi: dev_node removal (das08_cs)
  drivers/staging/comedi: dev_node removal (cb_das16_cs)
  pata_pcmcia: get rid of extra indirection
  pcmcia: remove suspend-related comment from yenta_socket.c
  pcmcia: call pcmcia_{read,write}_cis_mem with ops_mutex held
  pcmcia: remove pcmcia_add_device_lock
  pcmcia: update gfp/slab.h includes
  pcmcia: remove unused mem_op.h
  pcmcia: do not autoadd root PCI bus resources
  pcmcia: clarify alloc_io_space, move it to resource handlers
  pcmcia: move all pcmcia_resource_ops providers into one module
  pcmcia: move high level CIS access code to separate file
  pcmcia: dev_node removal (core)
  pcmcia: dev_node removal (remaining drivers)
  ...
This commit is contained in:
Linus Torvalds 2010-05-20 09:09:46 -07:00
commit 5429126351
86 changed files with 1199 additions and 2159 deletions

View File

@ -1,4 +1,17 @@
This file details changes in 2.6 which affect PCMCIA card driver authors: This file details changes in 2.6 which affect PCMCIA card driver authors:
* No dev_node_t (as of 2.6.35)
There is no more need to fill out a "dev_node_t" structure.
* New IRQ request rules (as of 2.6.35)
Instead of the old pcmcia_request_irq() interface, drivers may now
choose between:
- calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq.
- use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will
clean up automatically on calls to pcmcia_disable_device() or
device ejection.
- drivers still not capable of IRQF_SHARED (or not telling us so) may
use the deprecated pcmcia_request_exclusive_irq() for the time
being; they might receive a shared IRQ nonetheless.
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33) * no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
Instead of the cs_error() callback or the CS_CHECK() macro, please use Instead of the cs_error() callback or the CS_CHECK() macro, please use

View File

@ -45,16 +45,6 @@
#define DRV_NAME "pata_pcmcia" #define DRV_NAME "pata_pcmcia"
#define DRV_VERSION "0.3.5" #define DRV_VERSION "0.3.5"
/*
* Private data structure to glue stuff together
*/
struct ata_pcmcia_info {
struct pcmcia_device *pdev;
int ndev;
dev_node_t node;
};
/** /**
* pcmcia_set_mode - PCMCIA specific mode setup * pcmcia_set_mode - PCMCIA specific mode setup
* @link: link * @link: link
@ -248,7 +238,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
{ {
struct ata_host *host; struct ata_host *host;
struct ata_port *ap; struct ata_port *ap;
struct ata_pcmcia_info *info;
struct pcmcia_config_check *stk = NULL; struct pcmcia_config_check *stk = NULL;
int is_kme = 0, ret = -ENOMEM, p; int is_kme = 0, ret = -ENOMEM, p;
unsigned long io_base, ctl_base; unsigned long io_base, ctl_base;
@ -256,19 +245,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
int n_ports = 1; int n_ports = 1;
struct ata_port_operations *ops = &pcmcia_port_ops; struct ata_port_operations *ops = &pcmcia_port_ops;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
/* Glue stuff together. FIXME: We may be able to get rid of info with care */
info->pdev = pdev;
pdev->priv = info;
/* Set up attributes in order to probe card and get resources */ /* Set up attributes in order to probe card and get resources */
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
pdev->io.IOAddrLines = 3; pdev->io.IOAddrLines = 3;
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
pdev->conf.Attributes = CONF_ENABLE_IRQ; pdev->conf.Attributes = CONF_ENABLE_IRQ;
pdev->conf.IntType = INT_MEMORY_AND_IO; pdev->conf.IntType = INT_MEMORY_AND_IO;
@ -293,8 +273,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
} }
io_base = pdev->io.BasePort1; io_base = pdev->io.BasePort1;
ctl_base = stk->ctl_base; ctl_base = stk->ctl_base;
ret = pcmcia_request_irq(pdev, &pdev->irq); if (!pdev->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(pdev, &pdev->conf); ret = pcmcia_request_configuration(pdev, &pdev->conf);
@ -344,21 +323,19 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
} }
/* activate */ /* activate */
ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_sff_interrupt, ret = ata_host_activate(host, pdev->irq, ata_sff_interrupt,
IRQF_SHARED, &pcmcia_sht); IRQF_SHARED, &pcmcia_sht);
if (ret) if (ret)
goto failed; goto failed;
info->ndev = 1; pdev->priv = host;
kfree(stk); kfree(stk);
return 0; return 0;
failed: failed:
kfree(stk); kfree(stk);
info->ndev = 0;
pcmcia_disable_device(pdev); pcmcia_disable_device(pdev);
out1: out1:
kfree(info);
return ret; return ret;
} }
@ -372,20 +349,12 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
static void pcmcia_remove_one(struct pcmcia_device *pdev) static void pcmcia_remove_one(struct pcmcia_device *pdev)
{ {
struct ata_pcmcia_info *info = pdev->priv; struct ata_host *host = pdev->priv;
struct device *dev = &pdev->dev;
if (host)
ata_host_detach(host);
if (info != NULL) {
/* If we have attached the device to the ATA layer, detach it */
if (info->ndev) {
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
}
info->ndev = 0;
pdev->priv = NULL;
}
pcmcia_disable_device(pdev); pcmcia_disable_device(pdev);
kfree(info);
} }
static struct pcmcia_device_id pcmcia_devices[] = { static struct pcmcia_device_id pcmcia_devices[] = {

View File

@ -65,7 +65,6 @@ MODULE_LICENSE("GPL");
typedef struct bluecard_info_t { typedef struct bluecard_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev; struct hci_dev *hdev;
@ -869,9 +868,6 @@ static int bluecard_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = bluecard_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -908,9 +904,9 @@ static int bluecard_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, bluecard_interrupt);
if (i != 0) if (i != 0)
link->irq.AssignedIRQ = 0; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
@ -919,9 +915,6 @@ static int bluecard_config(struct pcmcia_device *link)
if (bluecard_open(info) != 0) if (bluecard_open(info) != 0)
goto failed; goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev_node = &info->node;
return 0; return 0;
failed: failed:

View File

@ -72,7 +72,6 @@ MODULE_FIRMWARE("BT3CPCC.bin");
typedef struct bt3c_info_t { typedef struct bt3c_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev; struct hci_dev *hdev;
@ -661,9 +660,6 @@ static int bt3c_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = bt3c_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -743,9 +739,9 @@ static int bt3c_config(struct pcmcia_device *link)
goto failed; goto failed;
found_port: found_port:
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, &bt3c_interrupt);
if (i != 0) if (i != 0)
link->irq.AssignedIRQ = 0; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
@ -754,9 +750,6 @@ static int bt3c_config(struct pcmcia_device *link)
if (bt3c_open(info) != 0) if (bt3c_open(info) != 0)
goto failed; goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev_node = &info->node;
return 0; return 0;
failed: failed:

View File

@ -67,7 +67,6 @@ MODULE_LICENSE("GPL");
typedef struct btuart_info_t { typedef struct btuart_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev; struct hci_dev *hdev;
@ -590,9 +589,6 @@ static int btuart_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = btuart_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -672,9 +668,9 @@ static int btuart_config(struct pcmcia_device *link)
goto failed; goto failed;
found_port: found_port:
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, btuart_interrupt);
if (i != 0) if (i != 0)
link->irq.AssignedIRQ = 0; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
@ -683,9 +679,6 @@ static int btuart_config(struct pcmcia_device *link)
if (btuart_open(info) != 0) if (btuart_open(info) != 0)
goto failed; goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev_node = &info->node;
return 0; return 0;
failed: failed:

View File

@ -67,7 +67,6 @@ MODULE_LICENSE("GPL");
typedef struct dtl1_info_t { typedef struct dtl1_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev; struct hci_dev *hdev;
@ -575,9 +574,6 @@ static int dtl1_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = dtl1_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -621,9 +617,9 @@ static int dtl1_config(struct pcmcia_device *link)
if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
goto failed; goto failed;
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, dtl1_interrupt);
if (i != 0) if (i != 0)
link->irq.AssignedIRQ = 0; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
@ -632,9 +628,6 @@ static int dtl1_config(struct pcmcia_device *link)
if (dtl1_open(info) != 0) if (dtl1_open(info) != 0)
goto failed; goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev_node = &info->node;
return 0; return 0;
failed: failed:

View File

@ -106,7 +106,6 @@ static int major; /* major number we get from the kernel */
struct cm4000_dev { struct cm4000_dev {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node; /* OS node (major,minor) */
unsigned char atr[MAX_ATR]; unsigned char atr[MAX_ATR];
unsigned char rbuf[512]; unsigned char rbuf[512];
@ -884,8 +883,7 @@ static void monitor_card(unsigned long p)
/* slow down warning, but prompt immediately after insertion */ /* slow down warning, but prompt immediately after insertion */
if (dev->cwarn == 0 || dev->cwarn == 10) { if (dev->cwarn == 0 || dev->cwarn == 10) {
set_bit(IS_BAD_CARD, &dev->flags); set_bit(IS_BAD_CARD, &dev->flags);
printk(KERN_WARNING MODULE_NAME ": device %s: ", dev_warn(&dev->p_dev->dev, MODULE_NAME ": ");
dev->node.dev_name);
if (test_bit(IS_BAD_CSUM, &dev->flags)) { if (test_bit(IS_BAD_CSUM, &dev->flags)) {
DEBUGP(4, dev, "ATR checksum (0x%.2x, should " DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
"be zero) failed\n", dev->atr_csum); "be zero) failed\n", dev->atr_csum);
@ -1781,11 +1779,6 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
goto cs_release; goto cs_release;
dev = link->priv; dev = link->priv;
sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
dev->node.major = major;
dev->node.minor = devno;
dev->node.next = NULL;
link->dev_node = &dev->node;
return 0; return 0;

View File

@ -72,7 +72,6 @@ static struct class *cmx_class;
struct reader_dev { struct reader_dev {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
wait_queue_head_t devq; wait_queue_head_t devq;
wait_queue_head_t poll_wait; wait_queue_head_t poll_wait;
wait_queue_head_t read_wait; wait_queue_head_t read_wait;
@ -568,10 +567,6 @@ static int reader_config(struct pcmcia_device *link, int devno)
} }
dev = link->priv; dev = link->priv;
sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
dev->node.major = major;
dev->node.minor = devno;
dev->node.next = &dev->node;
DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);

View File

@ -195,9 +195,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = ipwireless_interrupt;
INIT_WORK(&ipw->work_reboot, signalled_reboot_work); INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1, ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1,
@ -205,8 +202,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ipw->is_v2_card, signalled_reboot_callback, ipw->is_v2_card, signalled_reboot_callback,
ipw); ipw);
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, ipwireless_interrupt);
if (ret != 0) if (ret != 0)
goto exit; goto exit;
@ -217,7 +213,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
(unsigned int) link->io.BasePort1, (unsigned int) link->io.BasePort1,
(unsigned int) (link->io.BasePort1 + (unsigned int) (link->io.BasePort1 +
link->io.NumPorts1 - 1), link->io.NumPorts1 - 1),
(unsigned int) link->irq.AssignedIRQ); (unsigned int) link->irq);
if (ipw->attr_memory && ipw->common_memory) if (ipw->attr_memory && ipw->common_memory)
printk(KERN_INFO IPWIRELESS_PCCARD_NAME printk(KERN_INFO IPWIRELESS_PCCARD_NAME
": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
@ -232,8 +228,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
if (!ipw->network) if (!ipw->network)
goto exit; goto exit;
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network);
ipw->nodes);
if (!ipw->tty) if (!ipw->tty)
goto exit; goto exit;
@ -248,8 +243,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
if (ret != 0) if (ret != 0)
goto exit; goto exit;
link->dev_node = &ipw->nodes[0];
return 0; return 0;
exit: exit:
@ -271,8 +264,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
static void release_ipwireless(struct ipw_dev *ipw) static void release_ipwireless(struct ipw_dev *ipw)
{ {
pcmcia_disable_device(ipw->link);
if (ipw->common_memory) { if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base, release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size); ipw->request_common_memory.Size);
@ -288,7 +279,6 @@ static void release_ipwireless(struct ipw_dev *ipw)
if (ipw->attr_memory) if (ipw->attr_memory)
pcmcia_release_window(ipw->link, ipw->handle_attr_memory); pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
/* Break the link with Card Services */
pcmcia_disable_device(ipw->link); pcmcia_disable_device(ipw->link);
} }
@ -313,9 +303,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
ipw->link = link; ipw->link = link;
link->priv = ipw; link->priv = ipw;
/* Link this device into our device list. */
link->dev_node = &ipw->nodes[0];
ipw->hardware = ipwireless_hardware_create(); ipw->hardware = ipwireless_hardware_create();
if (!ipw->hardware) { if (!ipw->hardware) {
kfree(ipw); kfree(ipw);

View File

@ -54,7 +54,6 @@ struct ipw_dev {
void __iomem *common_memory; void __iomem *common_memory;
win_req_t request_common_memory; win_req_t request_common_memory;
dev_node_t nodes[2];
/* Reference to attribute memory, containing CIS data */ /* Reference to attribute memory, containing CIS data */
void *attribute_memory; void *attribute_memory;

View File

@ -487,7 +487,7 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file,
return tty_mode_ioctl(linux_tty, file, cmd , arg); return tty_mode_ioctl(linux_tty, file, cmd , arg);
} }
static int add_tty(dev_node_t *nodesp, int j, static int add_tty(int j,
struct ipw_hardware *hardware, struct ipw_hardware *hardware,
struct ipw_network *network, int channel_idx, struct ipw_network *network, int channel_idx,
int secondary_channel_idx, int tty_type) int secondary_channel_idx, int tty_type)
@ -510,19 +510,13 @@ static int add_tty(dev_node_t *nodesp, int j,
ipwireless_associate_network_tty(network, ipwireless_associate_network_tty(network,
secondary_channel_idx, secondary_channel_idx,
ttys[j]); ttys[j]);
if (nodesp != NULL) {
sprintf(nodesp->dev_name, "ttyIPWp%d", j);
nodesp->major = ipw_tty_driver->major;
nodesp->minor = j + ipw_tty_driver->minor_start;
}
if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j])
report_registering(ttys[j]); report_registering(ttys[j]);
return 0; return 0;
} }
struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware,
struct ipw_network *network, struct ipw_network *network)
dev_node_t *nodes)
{ {
int i, j; int i, j;
@ -539,26 +533,23 @@ struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware,
if (allfree) { if (allfree) {
j = i; j = i;
if (add_tty(&nodes[0], j, hardware, network, if (add_tty(j, hardware, network,
IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS,
TTYTYPE_MODEM)) TTYTYPE_MODEM))
return NULL; return NULL;
j += IPWIRELESS_PCMCIA_MINOR_RANGE; j += IPWIRELESS_PCMCIA_MINOR_RANGE;
if (add_tty(&nodes[1], j, hardware, network, if (add_tty(j, hardware, network,
IPW_CHANNEL_DIALLER, -1, IPW_CHANNEL_DIALLER, -1,
TTYTYPE_MONITOR)) TTYTYPE_MONITOR))
return NULL; return NULL;
j += IPWIRELESS_PCMCIA_MINOR_RANGE; j += IPWIRELESS_PCMCIA_MINOR_RANGE;
if (add_tty(NULL, j, hardware, network, if (add_tty(j, hardware, network,
IPW_CHANNEL_RAS, -1, IPW_CHANNEL_RAS, -1,
TTYTYPE_RAS_RAW)) TTYTYPE_RAS_RAW))
return NULL; return NULL;
nodes[0].next = &nodes[1];
nodes[1].next = NULL;
return ttys[i]; return ttys[i];
} }
} }

View File

@ -34,8 +34,7 @@ int ipwireless_tty_init(void);
void ipwireless_tty_release(void); void ipwireless_tty_release(void);
struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw, struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw,
struct ipw_network *net, struct ipw_network *net);
dev_node_t *nodes);
void ipwireless_tty_free(struct ipw_tty *tty); void ipwireless_tty_free(struct ipw_tty *tty);
void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data,
unsigned int length); unsigned int length);

View File

@ -220,7 +220,6 @@ typedef struct _mgslpc_info {
/* PCMCIA support */ /* PCMCIA support */
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
int stop; int stop;
/* SPPP/Cisco HDLC device parts */ /* SPPP/Cisco HDLC device parts */
@ -552,10 +551,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Initialize the struct pcmcia_device structure */ /* Initialize the struct pcmcia_device structure */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
link->conf.Attributes = 0; link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -608,9 +603,7 @@ static int mgslpc_config(struct pcmcia_device *link)
link->conf.ConfigIndex = 8; link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
link->irq.Handler = mgslpc_isr; ret = pcmcia_request_irq(link, mgslpc_isr);
ret = pcmcia_request_irq(link, &link->irq);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
@ -618,17 +611,12 @@ static int mgslpc_config(struct pcmcia_device *link)
goto failed; goto failed;
info->io_base = link->io.BasePort1; info->io_base = link->io.BasePort1;
info->irq_level = link->irq.AssignedIRQ; info->irq_level = link->irq;
/* add to linked list of devices */ dev_info(&link->dev, "index 0x%02x:",
sprintf(info->node.dev_name, "mgslpc0"); link->conf.ConfigIndex);
info->node.major = info->node.minor = 0;
link->dev_node = &info->node;
printk(KERN_INFO "%s: index 0x%02x:",
info->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);

View File

@ -65,8 +65,7 @@ MODULE_LICENSE("Dual MPL/GPL");
typedef struct ide_info_t { typedef struct ide_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
struct ide_host *host; struct ide_host *host;
int ndev; int ndev;
dev_node_t node;
} ide_info_t; } ide_info_t;
static void ide_release(struct pcmcia_device *); static void ide_release(struct pcmcia_device *);
@ -102,7 +101,6 @@ static int ide_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3; link->io.IOAddrLines = 3;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -285,8 +283,7 @@ static int ide_config(struct pcmcia_device *link)
io_base = link->io.BasePort1; io_base = link->io.BasePort1;
ctl_base = stk->ctl_base; ctl_base = stk->ctl_base;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
@ -299,24 +296,21 @@ static int ide_config(struct pcmcia_device *link)
if (is_kme) if (is_kme)
outb(0x81, ctl_base+1); outb(0x81, ctl_base+1);
host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); host = idecs_register(io_base, ctl_base, link->irq, link);
if (host == NULL && link->io.NumPorts1 == 0x20) { if (host == NULL && link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10); outb(0x02, ctl_base + 0x10);
host = idecs_register(io_base + 0x10, ctl_base + 0x10, host = idecs_register(io_base + 0x10, ctl_base + 0x10,
link->irq.AssignedIRQ, link); link->irq, link);
} }
if (host == NULL) if (host == NULL)
goto failed; goto failed;
info->ndev = 1; info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2);
info->node.major = host->ports[0]->major;
info->node.minor = 0;
info->host = host; info->host = host;
link->dev_node = &info->node; dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", 'a' + host->ports[0]->index * 2,
info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); link->conf.Vpp / 10, link->conf.Vpp % 10);
kfree(stk); kfree(stk);
return 0; return 0;

View File

@ -13,7 +13,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/serial.h> #include <linux/serial.h>
@ -61,31 +60,6 @@ static void avmcs_release(struct pcmcia_device *link);
static void avmcs_detach(struct pcmcia_device *p_dev); static void avmcs_detach(struct pcmcia_device *p_dev);
/*
A linked list of "instances" of the skeleton device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally can't be allocated dynamically.
*/
typedef struct local_info_t {
dev_node_t node;
} local_info_t;
/*====================================================================== /*======================================================================
avmcs_attach() creates an "instance" of the driver, allocating avmcs_attach() creates an "instance" of the driver, allocating
@ -100,32 +74,19 @@ typedef struct local_info_t {
static int avmcs_probe(struct pcmcia_device *p_dev) static int avmcs_probe(struct pcmcia_device *p_dev)
{ {
local_info_t *local;
/* The io structure describes IO port mapping */ /* The io structure describes IO port mapping */
p_dev->io.NumPorts1 = 16; p_dev->io.NumPorts1 = 16;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts2 = 0;
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
p_dev->conf.ConfigIndex = 1; p_dev->conf.ConfigIndex = 1;
p_dev->conf.Present = PRESENT_OPTION; p_dev->conf.Present = PRESENT_OPTION;
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local)
goto err;
p_dev->priv = local;
return avmcs_config(p_dev); return avmcs_config(p_dev);
err:
return -ENOMEM;
} /* avmcs_attach */ } /* avmcs_attach */
/*====================================================================== /*======================================================================
@ -140,7 +101,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
static void avmcs_detach(struct pcmcia_device *link) static void avmcs_detach(struct pcmcia_device *link)
{ {
avmcs_release(link); avmcs_release(link);
kfree(link->priv);
} /* avmcs_detach */ } /* avmcs_detach */
/*====================================================================== /*======================================================================
@ -171,14 +131,11 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev,
static int avmcs_config(struct pcmcia_device *link) static int avmcs_config(struct pcmcia_device *link)
{ {
local_info_t *dev; int i = -1;
int i;
char devname[128]; char devname[128];
int cardtype; int cardtype;
int (*addcard)(unsigned int port, unsigned irq); int (*addcard)(unsigned int port, unsigned irq);
dev = link->priv;
devname[0] = 0; devname[0] = 0;
if (link->prod_id[1]) if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname)); strlcpy(devname, link->prod_id[1], sizeof(devname));
@ -190,11 +147,7 @@ static int avmcs_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
do { do {
/* if (!link->irq) {
* allocate an interrupt line
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != 0) {
/* undo */ /* undo */
pcmcia_disable_device(link); pcmcia_disable_device(link);
break; break;
@ -211,15 +164,11 @@ static int avmcs_config(struct pcmcia_device *link)
} while (0); } while (0);
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. */
if (devname[0]) { if (devname[0]) {
char *s = strrchr(devname, ' '); char *s = strrchr(devname, ' ');
if (!s) if (!s)
s = devname; s = devname;
else s++; else s++;
strcpy(dev->node.dev_name, s);
if (strcmp("M1", s) == 0) { if (strcmp("M1", s) == 0) {
cardtype = AVM_CARDTYPE_M1; cardtype = AVM_CARDTYPE_M1;
} else if (strcmp("M2", s) == 0) { } else if (strcmp("M2", s) == 0) {
@ -227,14 +176,8 @@ static int avmcs_config(struct pcmcia_device *link)
} else { } else {
cardtype = AVM_CARDTYPE_B1; cardtype = AVM_CARDTYPE_B1;
} }
} else { } else
strcpy(dev->node.dev_name, "b1");
cardtype = AVM_CARDTYPE_B1; cardtype = AVM_CARDTYPE_B1;
}
dev->node.major = 64;
dev->node.minor = 0;
link->dev_node = &dev->node;
/* If any step failed, release any partially configured state */ /* If any step failed, release any partially configured state */
if (i != 0) { if (i != 0) {
@ -249,13 +192,12 @@ static int avmcs_config(struct pcmcia_device *link)
default: default:
case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
} }
if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) {
printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev_err(&link->dev, "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); link->io.BasePort1, link->irq);
avmcs_release(link); avmcs_release(link);
return -ENODEV; return -ENODEV;
} }
dev->node.minor = i;
return 0; return 0;
} /* avmcs_config */ } /* avmcs_config */
@ -270,7 +212,7 @@ static int avmcs_config(struct pcmcia_device *link)
static void avmcs_release(struct pcmcia_device *link) static void avmcs_release(struct pcmcia_device *link)
{ {
b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); b1pcmcia_delcard(link->io.BasePort1, link->irq);
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* avmcs_release */ } /* avmcs_release */

View File

@ -62,31 +62,6 @@ static void avma1cs_release(struct pcmcia_device *link);
static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
/*
A linked list of "instances" of the skeleton device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally can't be allocated dynamically.
*/
typedef struct local_info_t {
dev_node_t node;
} local_info_t;
/*====================================================================== /*======================================================================
avma1cs_attach() creates an "instance" of the driver, allocating avma1cs_attach() creates an "instance" of the driver, allocating
@ -101,17 +76,8 @@ typedef struct local_info_t {
static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
{ {
local_info_t *local;
dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local)
return -ENOMEM;
p_dev->priv = local;
/* The io structure describes IO port mapping */ /* The io structure describes IO port mapping */
p_dev->io.NumPorts1 = 16; p_dev->io.NumPorts1 = 16;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@ -119,9 +85,6 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
p_dev->io.IOAddrLines = 5; p_dev->io.IOAddrLines = 5;
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -176,14 +139,11 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev,
static int __devinit avma1cs_config(struct pcmcia_device *link) static int __devinit avma1cs_config(struct pcmcia_device *link)
{ {
local_info_t *dev; int i = -1;
int i;
char devname[128]; char devname[128];
IsdnCard_t icard; IsdnCard_t icard;
int busy = 0; int busy = 0;
dev = link->priv;
dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link); dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
devname[0] = 0; devname[0] = 0;
@ -197,8 +157,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
/* /*
* allocate an interrupt line * allocate an interrupt line
*/ */
i = pcmcia_request_irq(link, &link->irq); if (!link->irq) {
if (i != 0) {
/* undo */ /* undo */
pcmcia_disable_device(link); pcmcia_disable_device(link);
break; break;
@ -215,14 +174,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
} while (0); } while (0);
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. */
strcpy(dev->node.dev_name, "A1");
dev->node.major = 45;
dev->node.minor = 0;
link->dev_node = &dev->node;
/* If any step failed, release any partially configured state */ /* If any step failed, release any partially configured state */
if (i != 0) { if (i != 0) {
avma1cs_release(link); avma1cs_release(link);
@ -230,9 +181,9 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
} }
printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
link->io.BasePort1, link->irq.AssignedIRQ); link->io.BasePort1, link->irq);
icard.para[0] = link->irq.AssignedIRQ; icard.para[0] = link->irq;
icard.para[1] = link->io.BasePort1; icard.para[1] = link->io.BasePort1;
icard.protocol = isdnprot; icard.protocol = isdnprot;
icard.typ = ISDN_CTYPE_A1_PCMCIA; icard.typ = ISDN_CTYPE_A1_PCMCIA;
@ -243,7 +194,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
avma1cs_release(link); avma1cs_release(link);
return -ENODEV; return -ENODEV;
} }
dev->node.minor = i; link->priv = (void *) (unsigned long) i;
return 0; return 0;
} /* avma1cs_config */ } /* avma1cs_config */
@ -258,12 +209,12 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
static void avma1cs_release(struct pcmcia_device *link) static void avma1cs_release(struct pcmcia_device *link)
{ {
local_info_t *local = link->priv; unsigned long minor = (unsigned long) link->priv;
dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link); dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
/* now unregister function with hisax */ /* now unregister function with hisax */
HiSax_closecard(local->node.minor); HiSax_closecard(minor);
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* avma1cs_release */ } /* avma1cs_release */

View File

@ -87,24 +87,8 @@ static void elsa_cs_release(struct pcmcia_device *link);
static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t { typedef struct local_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
int busy; int busy;
int cardnr; int cardnr;
} local_info_t; } local_info_t;
@ -136,10 +120,6 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link)
local->cardnr = -1; local->cardnr = -1;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -223,28 +203,18 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (i != 0) {
link->irq.AssignedIRQ = 0;
goto failed; goto failed;
}
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
goto failed; goto failed;
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. *//* */
sprintf(dev->node.dev_name, "elsa");
dev->node.major = dev->node.minor = 0x0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ", dev_info(&link->dev, "index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex); link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
@ -253,7 +223,7 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
link->io.BasePort2+link->io.NumPorts2-1); link->io.BasePort2+link->io.NumPorts2-1);
printk("\n"); printk("\n");
icard.para[0] = link->irq.AssignedIRQ; icard.para[0] = link->irq;
icard.para[1] = link->io.BasePort1; icard.para[1] = link->io.BasePort1;
icard.protocol = protocol; icard.protocol = protocol;
icard.typ = ISDN_CTYPE_ELSA_PCMCIA; icard.typ = ISDN_CTYPE_ELSA_PCMCIA;

View File

@ -87,32 +87,8 @@ static void sedlbauer_release(struct pcmcia_device *link);
static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'memory_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t { typedef struct local_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
int stop; int stop;
int cardnr; int cardnr;
} local_info_t; } local_info_t;
@ -143,10 +119,6 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -227,9 +199,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -285,7 +255,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
static int __devinit sedlbauer_config(struct pcmcia_device *link) static int __devinit sedlbauer_config(struct pcmcia_device *link)
{ {
local_info_t *dev = link->priv;
win_req_t *req; win_req_t *req;
int ret; int ret;
IsdnCard_t icard; IsdnCard_t icard;
@ -312,17 +281,6 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
Allocate an interrupt line. Note that this does not assign a
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the the I/O windows and the interrupt mapping, and putting the
@ -332,21 +290,13 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "sedlbauer");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x:", dev_info(&link->dev, "index 0x%02x:",
dev->node.dev_name, link->conf.ConfigIndex); link->conf.ConfigIndex);
if (link->conf.Vpp) if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
@ -358,7 +308,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
req->Base+req->Size-1); req->Base+req->Size-1);
printk("\n"); printk("\n");
icard.para[0] = link->irq.AssignedIRQ; icard.para[0] = link->irq;
icard.para[1] = link->io.BasePort1; icard.para[1] = link->io.BasePort1;
icard.protocol = protocol; icard.protocol = protocol;
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;

View File

@ -68,34 +68,8 @@ static void teles_cs_release(struct pcmcia_device *link);
static void teles_detach(struct pcmcia_device *p_dev) __devexit ; static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
/*
A linked list of "instances" of the teles_cs device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t { typedef struct local_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
int busy; int busy;
int cardnr; int cardnr;
} local_info_t; } local_info_t;
@ -126,10 +100,6 @@ static int __devinit teles_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -213,28 +183,18 @@ static int __devinit teles_cs_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto cs_failed; goto cs_failed;
i = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (i != 0) {
link->irq.AssignedIRQ = 0;
goto cs_failed; goto cs_failed;
}
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
goto cs_failed; goto cs_failed;
/* At this point, the dev_node_t structure(s) should be
initialized and arranged in a linked list at link->dev. *//* */
sprintf(dev->node.dev_name, "teles");
dev->node.major = dev->node.minor = 0x0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x:", dev_info(&link->dev, "index 0x%02x:",
dev->node.dev_name, link->conf.ConfigIndex); link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
@ -243,7 +203,7 @@ static int __devinit teles_cs_config(struct pcmcia_device *link)
link->io.BasePort2+link->io.NumPorts2-1); link->io.BasePort2+link->io.NumPorts2-1);
printk("\n"); printk("\n");
icard.para[0] = link->irq.AssignedIRQ; icard.para[0] = link->irq;
icard.para[1] = link->io.BasePort1; icard.para[1] = link->io.BasePort1;
icard.protocol = protocol; icard.protocol = protocol;
icard.typ = ISDN_CTYPE_TELESPCMCIA; icard.typ = ISDN_CTYPE_TELESPCMCIA;

View File

@ -52,7 +52,6 @@ static const int debug = 0;
struct pcmciamtd_dev { struct pcmciamtd_dev {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node; /* device node */
caddr_t win_base; /* ioremapped address of PCMCIA window */ caddr_t win_base; /* ioremapped address of PCMCIA window */
unsigned int win_size; /* size of window */ unsigned int win_size; /* size of window */
unsigned int offset; /* offset into card the window currently points at */ unsigned int offset; /* offset into card the window currently points at */
@ -647,9 +646,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
pcmciamtd_release(link); pcmciamtd_release(link);
return -ENODEV; return -ENODEV;
} }
snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
info("mtd%d: %s", mtd->index, mtd->name); info("mtd%d: %s", mtd->index, mtd->name);
link->dev_node = &dev->node;
return 0; return 0;
failed: failed:

View File

@ -93,7 +93,6 @@ earlier 3Com products.
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/mem_op.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
@ -200,7 +199,6 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
struct el3_private { struct el3_private {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
u16 advertising, partner; /* NWay media advertisement */ u16 advertising, partner; /* NWay media advertisement */
unsigned char phys; /* MII device address */ unsigned char phys; /* MII device address */
unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */ unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */
@ -283,8 +281,6 @@ static int tc574_probe(struct pcmcia_device *link)
spin_lock_init(&lp->window_lock); spin_lock_init(&lp->window_lock);
link->io.NumPorts1 = 32; link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &el3_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
@ -311,8 +307,7 @@ static void tc574_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "3c574_detach()\n"); dev_dbg(&link->dev, "3c574_detach()\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
tc574_release(link); tc574_release(link);
@ -353,7 +348,7 @@ static int tc574_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, el3_interrupt);
if (ret) if (ret)
goto failed; goto failed;
@ -361,7 +356,7 @@ static int tc574_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
ioaddr = dev->base_addr; ioaddr = dev->base_addr;
@ -446,17 +441,13 @@ static int tc574_config(struct pcmcia_device *link)
} }
} }
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(lp->node.dev_name, dev->name);
printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
"hw_addr %pM.\n", "hw_addr %pM.\n",
dev->name, cardname, dev->base_addr, dev->irq, dev->name, cardname, dev->base_addr, dev->irq,

View File

@ -106,7 +106,6 @@ enum RxFilter {
struct el3_private { struct el3_private {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
/* For transceiver monitoring */ /* For transceiver monitoring */
struct timer_list media; struct timer_list media;
u16 media_status; u16 media_status;
@ -194,8 +193,7 @@ static int tc589_probe(struct pcmcia_device *link)
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &el3_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
@ -223,8 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "3c589_detach\n"); dev_dbg(&link->dev, "3c589_detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
tc589_release(link); tc589_release(link);
@ -242,7 +239,6 @@ static void tc589_detach(struct pcmcia_device *link)
static int tc589_config(struct pcmcia_device *link) static int tc589_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
__be16 *phys_addr; __be16 *phys_addr;
int ret, i, j, multi = 0, fifo; int ret, i, j, multi = 0, fifo;
unsigned int ioaddr; unsigned int ioaddr;
@ -271,7 +267,7 @@ static int tc589_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, el3_interrupt);
if (ret) if (ret)
goto failed; goto failed;
@ -279,7 +275,7 @@ static int tc589_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
ioaddr = dev->base_addr; ioaddr = dev->base_addr;
EL3WINDOW(0); EL3WINDOW(0);
@ -313,17 +309,13 @@ static int tc589_config(struct pcmcia_device *link)
else else
printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(lp->node.dev_name, dev->name);
printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, " printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, "
"hw_addr %pM\n", "hw_addr %pM\n",
dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq, dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq,

View File

@ -113,7 +113,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id);
typedef struct axnet_dev_t { typedef struct axnet_dev_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
caddr_t base; caddr_t base;
struct timer_list watchdog; struct timer_list watchdog;
int stale, fast_poll; int stale, fast_poll;
@ -168,7 +167,6 @@ static int axnet_probe(struct pcmcia_device *link)
info = PRIV(dev); info = PRIV(dev);
info->p_dev = link; info->p_dev = link;
link->priv = dev; link->priv = dev;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -195,8 +193,7 @@ static void axnet_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
axnet_release(link); axnet_release(link);
@ -265,12 +262,9 @@ static int try_io_port(struct pcmcia_device *link)
int j, ret; int j, ret;
if (link->io.NumPorts1 == 32) { if (link->io.NumPorts1 == 32) {
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */
/* for master/slave multifunction cards */ if (link->io.NumPorts2 > 0)
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.Attributes =
IRQ_TYPE_DYNAMIC_SHARING;
}
} else { } else {
/* This should be two 16-port windows */ /* This should be two 16-port windows */
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@ -336,8 +330,7 @@ static int axnet_config(struct pcmcia_device *link)
if (ret != 0) if (ret != 0)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
if (link->io.NumPorts2 == 8) { if (link->io.NumPorts2 == 8) {
@ -349,7 +342,7 @@ static int axnet_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
if (!get_prom(link)) { if (!get_prom(link)) {
@ -397,17 +390,13 @@ static int axnet_config(struct pcmcia_device *link)
} }
info->phy_id = (i < 32) ? i : -1; info->phy_id = (i < 32) ? i : -1;
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(info->node.dev_name, dev->name);
printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
"hw_addr %pM\n", "hw_addr %pM\n",
dev->name, ((info->flags & IS_AX88790) ? 7 : 1), dev->name, ((info->flags & IS_AX88790) ? 7 : 1),

View File

@ -122,7 +122,6 @@ static void com20020_detach(struct pcmcia_device *p_dev);
typedef struct com20020_dev_t { typedef struct com20020_dev_t {
struct net_device *dev; struct net_device *dev;
dev_node_t node;
} com20020_dev_t; } com20020_dev_t;
/*====================================================================== /*======================================================================
@ -163,7 +162,6 @@ static int com20020_probe(struct pcmcia_device *p_dev)
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.NumPorts1 = 16; p_dev->io.NumPorts1 = 16;
p_dev->io.IOAddrLines = 16; p_dev->io.IOAddrLines = 16;
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -196,18 +194,16 @@ static void com20020_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "com20020_detach\n"); dev_dbg(&link->dev, "com20020_detach\n");
if (link->dev_node) { dev_dbg(&link->dev, "unregister...\n");
dev_dbg(&link->dev, "unregister...\n");
unregister_netdev(dev); unregister_netdev(dev);
/* /*
* this is necessary because we register our IRQ separately * this is necessary because we register our IRQ separately
* from card services. * from card services.
*/ */
if (dev->irq) if (dev->irq)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
}
com20020_release(link); com20020_release(link);
@ -275,15 +271,14 @@ static int com20020_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
dev_dbg(&link->dev, "request IRQ %d\n", dev_dbg(&link->dev, "request IRQ %d\n",
link->irq.AssignedIRQ); link->irq);
i = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (i != 0)
{ {
dev_dbg(&link->dev, "requestIRQ failed totally!\n"); dev_dbg(&link->dev, "requestIRQ failed totally!\n");
goto failed; goto failed;
} }
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
@ -299,7 +294,6 @@ static int com20020_config(struct pcmcia_device *link)
lp->card_name = "PCMCIA COM20020"; lp->card_name = "PCMCIA COM20020";
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
i = com20020_found(dev, 0); /* calls register_netdev */ i = com20020_found(dev, 0); /* calls register_netdev */
@ -307,12 +301,9 @@ static int com20020_config(struct pcmcia_device *link)
if (i != 0) { if (i != 0) {
dev_printk(KERN_NOTICE, &link->dev, dev_printk(KERN_NOTICE, &link->dev,
"com20020_cs: com20020_found() failed\n"); "com20020_cs: com20020_found() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(info->node.dev_name, dev->name);
dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
dev->name, dev->base_addr, dev->irq); dev->name, dev->base_addr, dev->irq);
return 0; return 0;

View File

@ -110,7 +110,6 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
*/ */
typedef struct local_info_t { typedef struct local_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
long open_time; long open_time;
uint tx_started:1; uint tx_started:1;
uint tx_queue; uint tx_queue;
@ -254,10 +253,6 @@ static int fmvj18x_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 5; link->io.IOAddrLines = 5;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = fjn_interrupt;
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -278,8 +273,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "fmvj18x_detach\n"); dev_dbg(&link->dev, "fmvj18x_detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
fmvj18x_release(link); fmvj18x_release(link);
@ -425,8 +419,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
} }
if (link->io.NumPorts2 != 0) { if (link->io.NumPorts2 != 0) {
link->irq.Attributes =
IRQ_TYPE_DYNAMIC_SHARING;
ret = mfc_try_io_port(link); ret = mfc_try_io_port(link);
if (ret != 0) goto failed; if (ret != 0) goto failed;
} else if (cardtype == UNGERMANN) { } else if (cardtype == UNGERMANN) {
@ -437,14 +429,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
} }
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, fjn_interrupt);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
if (link->io.BasePort2 != 0) { if (link->io.BasePort2 != 0) {
@ -529,17 +521,13 @@ static int fmvj18x_config(struct pcmcia_device *link)
} }
lp->cardtype = cardtype; lp->cardtype = cardtype;
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(lp->node.dev_name, dev->name);
/* print current configuration */ /* print current configuration */
printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, "
"hw_addr %pM\n", "hw_addr %pM\n",

View File

@ -104,7 +104,6 @@ static void ibmtr_detach(struct pcmcia_device *p_dev);
typedef struct ibmtr_dev_t { typedef struct ibmtr_dev_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
struct net_device *dev; struct net_device *dev;
dev_node_t node;
window_handle_t sram_win_handle; window_handle_t sram_win_handle;
struct tok_info *ti; struct tok_info *ti;
} ibmtr_dev_t; } ibmtr_dev_t;
@ -156,8 +155,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 4; link->io.NumPorts1 = 4;
link->io.IOAddrLines = 16; link->io.IOAddrLines = 16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = ibmtr_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
@ -192,8 +189,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
*/ */
ti->sram_phys |= 1; ti->sram_phys |= 1;
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
del_timer_sync(&(ti->tr_timer)); del_timer_sync(&(ti->tr_timer));
@ -238,11 +234,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
} }
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
ti->irq = link->irq.AssignedIRQ; ti->irq = link->irq;
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
/* Allocate the MMIO memory window */ /* Allocate the MMIO memory window */
@ -291,18 +287,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
Adapters Technical Reference" SC30-3585 for this info. */ Adapters Technical Reference" SC30-3585 for this info. */
ibmtr_hw_setup(dev, mmiobase); ibmtr_hw_setup(dev, mmiobase);
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
i = ibmtr_probe_card(dev); i = ibmtr_probe_card(dev);
if (i != 0) { if (i != 0) {
printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(info->node.dev_name, dev->name);
printk(KERN_INFO printk(KERN_INFO
"%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
dev->name, dev->base_addr, dev->irq, dev->name, dev->base_addr, dev->irq,

View File

@ -363,7 +363,6 @@ typedef struct _mace_statistics {
typedef struct _mace_private { typedef struct _mace_private {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct net_device_stats linux_stats; /* Linux statistics counters */ struct net_device_stats linux_stats; /* Linux statistics counters */
mace_statistics mace_stats; /* MACE chip statistics counters */ mace_statistics mace_stats; /* MACE chip statistics counters */
@ -463,8 +462,6 @@ static int nmclan_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 32; link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 5; link->io.IOAddrLines = 5;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = mace_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
@ -493,8 +490,7 @@ static void nmclan_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "nmclan_detach\n"); dev_dbg(&link->dev, "nmclan_detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
nmclan_release(link); nmclan_release(link);
@ -652,14 +648,14 @@ static int nmclan_config(struct pcmcia_device *link)
ret = pcmcia_request_io(link, &link->io); ret = pcmcia_request_io(link, &link->io);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
ioaddr = dev->base_addr; ioaddr = dev->base_addr;
@ -698,18 +694,14 @@ static int nmclan_config(struct pcmcia_device *link)
else else
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev); i = register_netdev(dev);
if (i != 0) { if (i != 0) {
printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(lp->node.dev_name, dev->name);
printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
" hw_addr %pM\n", " hw_addr %pM\n",
dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],

View File

@ -208,7 +208,6 @@ static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
typedef struct pcnet_dev_t { typedef struct pcnet_dev_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
u_int flags; u_int flags;
void __iomem *base; void __iomem *base;
struct timer_list watchdog; struct timer_list watchdog;
@ -264,7 +263,6 @@ static int pcnet_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = dev; link->priv = dev;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -288,8 +286,7 @@ static void pcnet_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "pcnet_detach\n"); dev_dbg(&link->dev, "pcnet_detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
pcnet_release(link); pcnet_release(link);
@ -488,8 +485,6 @@ static int try_io_port(struct pcmcia_device *link)
if (link->io.NumPorts2 > 0) { if (link->io.NumPorts2 > 0) {
/* for master/slave multifunction cards */ /* for master/slave multifunction cards */
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.Attributes =
IRQ_TYPE_DYNAMIC_SHARING;
} }
} else { } else {
/* This should be two 16-port windows */ /* This should be two 16-port windows */
@ -559,8 +554,7 @@ static int pcnet_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
if (link->io.NumPorts2 == 8) { if (link->io.NumPorts2 == 8) {
@ -574,7 +568,7 @@ static int pcnet_config(struct pcmcia_device *link)
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
if (info->flags & HAS_MISC_REG) { if (info->flags & HAS_MISC_REG) {
if ((if_port == 1) || (if_port == 2)) if ((if_port == 1) || (if_port == 2))
@ -643,17 +637,13 @@ static int pcnet_config(struct pcmcia_device *link)
if (info->flags & (IS_DL10019|IS_DL10022)) if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev); mii_phy_probe(dev);
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto failed; goto failed;
} }
strcpy(info->node.dev_name, dev->name);
if (info->flags & (IS_DL10019|IS_DL10022)) { if (info->flags & (IS_DL10019|IS_DL10022)) {
u_char id = inb(dev->base_addr + 0x1a); u_char id = inb(dev->base_addr + 0x1a);
printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ", printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",

View File

@ -103,7 +103,6 @@ struct smc_private {
u_short manfid; u_short manfid;
u_short cardid; u_short cardid;
dev_node_t node;
struct sk_buff *saved_skb; struct sk_buff *saved_skb;
int packets_waiting; int packets_waiting;
void __iomem *base; void __iomem *base;
@ -323,14 +322,11 @@ static int smc91c92_probe(struct pcmcia_device *link)
return -ENOMEM; return -ENOMEM;
smc = netdev_priv(dev); smc = netdev_priv(dev);
smc->p_dev = link; smc->p_dev = link;
link->priv = dev;
spin_lock_init(&smc->lock); spin_lock_init(&smc->lock);
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 4; link->io.IOAddrLines = 4;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &smc_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -363,8 +359,7 @@ static void smc91c92_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "smc91c92_detach\n"); dev_dbg(&link->dev, "smc91c92_detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
smc91c92_release(link); smc91c92_release(link);
@ -453,7 +448,6 @@ static int mhz_mfc_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA; link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->io.IOAddrLines = 16; link->io.IOAddrLines = 16;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8; link->io.NumPorts2 = 8;
@ -652,7 +646,6 @@ static int osi_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA; link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->io.NumPorts1 = 64; link->io.NumPorts1 = 64;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8; link->io.NumPorts2 = 8;
@ -877,7 +870,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if (i) if (i)
goto config_failed; goto config_failed;
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, smc_interrupt);
if (i) if (i)
goto config_failed; goto config_failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
@ -887,7 +880,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if (smc->manfid == MANFID_MOTOROLA) if (smc->manfid == MANFID_MOTOROLA)
mot_config(link); mot_config(link);
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
if ((if_port >= 0) && (if_port <= 2)) if ((if_port >= 0) && (if_port <= 2))
dev->if_port = if_port; dev->if_port = if_port;
@ -960,17 +953,13 @@ static int smc91c92_config(struct pcmcia_device *link)
SMC_SELECT_BANK(0); SMC_SELECT_BANK(0);
} }
link->dev_node = &smc->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
link->dev_node = NULL;
goto config_undo; goto config_undo;
} }
strcpy(smc->node.dev_name, dev->name);
printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
"hw_addr %pM\n", "hw_addr %pM\n",
dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,

View File

@ -297,31 +297,9 @@ static void xirc2ps_detach(struct pcmcia_device *p_dev);
static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);
/****************
* A linked list of "instances" of the device. Each actual
* PCMCIA card corresponds to one device instance, and is described
* by one struct pcmcia_device structure (defined in ds.h).
*
* You may not want to use a linked list for this -- for example, the
* memory card driver uses an array of struct pcmcia_device pointers, where minor
* device numbers are used to derive the corresponding array index.
*/
/****************
* A driver needs to provide a dev_node_t structure for each device
* on a card. In some cases, there is only one device per card (for
* example, ethernet cards, modems). In other cases, there may be
* many actual or logical devices (SCSI adapters, memory cards with
* multiple partitions). The dev_node_t structures need to be kept
* in a linked list starting at the 'dev' field of a struct pcmcia_device
* structure. We allocate them in the card's private data structure,
* because they generally can't be allocated dynamically.
*/
typedef struct local_info_t { typedef struct local_info_t {
struct net_device *dev; struct net_device *dev;
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
int card_type; int card_type;
int probe_port; int probe_port;
@ -555,7 +533,6 @@ xirc2ps_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
link->irq.Handler = xirc2ps_interrupt;
/* Fill in card specific entries */ /* Fill in card specific entries */
dev->netdev_ops = &netdev_ops; dev->netdev_ops = &netdev_ops;
@ -580,8 +557,7 @@ xirc2ps_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "detach\n"); dev_dbg(&link->dev, "detach\n");
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
xirc2ps_release(link); xirc2ps_release(link);
@ -841,7 +817,6 @@ xirc2ps_config(struct pcmcia_device * link)
link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status |= CCSR_AUDIO_ENA; link->conf.Status |= CCSR_AUDIO_ENA;
} }
link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
link->io.NumPorts2 = 8; link->io.NumPorts2 = 8;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
if (local->dingo) { if (local->dingo) {
@ -866,7 +841,6 @@ xirc2ps_config(struct pcmcia_device * link)
} }
printk(KNOT_XIRC "no ports available\n"); printk(KNOT_XIRC "no ports available\n");
} else { } else {
link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
link->io.BasePort1 = ioaddr; link->io.BasePort1 = ioaddr;
@ -885,7 +859,7 @@ xirc2ps_config(struct pcmcia_device * link)
* Now allocate an interrupt line. Note that this does not * Now allocate an interrupt line. Note that this does not
* actually assign a handler to the interrupt. * actually assign a handler to the interrupt.
*/ */
if ((err=pcmcia_request_irq(link, &link->irq))) if ((err=pcmcia_request_irq(link, xirc2ps_interrupt)))
goto config_error; goto config_error;
/**************** /****************
@ -982,23 +956,19 @@ xirc2ps_config(struct pcmcia_device * link)
printk(KNOT_XIRC "invalid if_port requested\n"); printk(KNOT_XIRC "invalid if_port requested\n");
/* we can now register the device with the net subsystem */ /* we can now register the device with the net subsystem */
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
if (local->dingo) if (local->dingo)
do_reset(dev, 1); /* a kludge to make the cem56 work */ do_reset(dev, 1); /* a kludge to make the cem56 work */
link->dev_node = &local->node;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if ((err=register_netdev(dev))) { if ((err=register_netdev(dev))) {
printk(KNOT_XIRC "register_netdev() failed\n"); printk(KNOT_XIRC "register_netdev() failed\n");
link->dev_node = NULL;
goto config_error; goto config_error;
} }
strcpy(local->node.dev_name, dev->name);
/* give some infos about the hardware */ /* give some infos about the hardware */
printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n", printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n",
dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq,

View File

@ -75,42 +75,7 @@ static void airo_release(struct pcmcia_device *link);
static void airo_detach(struct pcmcia_device *p_dev); static void airo_detach(struct pcmcia_device *p_dev);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'pcmem_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
/*
A linked list of "instances" of the aironet device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers,
where minor device numbers are used to derive the corresponding
array index.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t { typedef struct local_info_t {
dev_node_t node;
struct net_device *eth_dev; struct net_device *eth_dev;
} local_info_t; } local_info_t;
@ -132,10 +97,6 @@ static int airo_probe(struct pcmcia_device *p_dev)
dev_dbg(&p_dev->dev, "airo_attach()\n"); dev_dbg(&p_dev->dev, "airo_attach()\n");
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -212,9 +173,7 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -300,16 +259,8 @@ static int airo_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/* if (!link->irq)
Allocate an interrupt line. Note that this does not assign a goto failed;
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -320,26 +271,17 @@ static int airo_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
((local_info_t *)link->priv)->eth_dev = ((local_info_t *)link->priv)->eth_dev =
init_airo_card(link->irq.AssignedIRQ, init_airo_card(link->irq,
link->io.BasePort1, 1, &link->dev); link->io.BasePort1, 1, &link->dev);
if (!((local_info_t *)link->priv)->eth_dev) if (!((local_info_t *)link->priv)->eth_dev)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev_node.
*/
strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name);
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ", dev_info(&link->dev, "index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex); link->conf.ConfigIndex);
if (link->conf.Vpp) if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq);
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);

View File

@ -85,41 +85,7 @@ static void atmel_release(struct pcmcia_device *link);
static void atmel_detach(struct pcmcia_device *p_dev); static void atmel_detach(struct pcmcia_device *p_dev);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'pcmem_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
/*
A linked list of "instances" of the atmelnet device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
/*
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t { typedef struct local_info_t {
dev_node_t node;
struct net_device *eth_dev; struct net_device *eth_dev;
} local_info_t; } local_info_t;
@ -141,10 +107,6 @@ static int atmel_probe(struct pcmcia_device *p_dev)
dev_dbg(&p_dev->dev, "atmel_attach()\n"); dev_dbg(&p_dev->dev, "atmel_attach()\n");
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -226,9 +188,7 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -278,15 +238,9 @@ static int atmel_config(struct pcmcia_device *link)
if (pcmcia_loop_config(link, atmel_config_check, NULL)) if (pcmcia_loop_config(link, atmel_config_check, NULL))
goto failed; goto failed;
/* if (!link->irq) {
Allocate an interrupt line. Note that this does not assign a dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
handler to the interrupt, unless the 'Handler' member of the goto failed;
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
} }
/* /*
@ -298,14 +252,8 @@ static int atmel_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
if (link->irq.AssignedIRQ == 0) {
printk(KERN_ALERT
"atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
goto failed;
}
((local_info_t*)link->priv)->eth_dev = ((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq.AssignedIRQ, init_atmel_card(link->irq,
link->io.BasePort1, link->io.BasePort1,
did ? did->driver_info : ATMEL_FW_TYPE_NONE, did ? did->driver_info : ATMEL_FW_TYPE_NONE,
&link->dev, &link->dev,
@ -315,14 +263,6 @@ static int atmel_config(struct pcmcia_device *link)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev_node.
*/
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
return 0; return 0;
failed: failed:

View File

@ -98,10 +98,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
if (res != 0) if (res != 0)
goto err_disable; goto err_disable;
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; if (!dev->irq)
dev->irq.Handler = NULL; /* The handler is registered later. */
res = pcmcia_request_irq(dev, &dev->irq);
if (res != 0)
goto err_disable; goto err_disable;
res = pcmcia_request_configuration(dev, &dev->conf); res = pcmcia_request_configuration(dev, &dev->conf);

View File

@ -39,7 +39,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
/* struct local_info::hw_priv */ /* struct local_info::hw_priv */
struct hostap_cs_priv { struct hostap_cs_priv {
dev_node_t node;
struct pcmcia_device *link; struct pcmcia_device *link;
int sandisk_connectplus; int sandisk_connectplus;
}; };
@ -556,15 +555,7 @@ static int prism2_config_check(struct pcmcia_device *p_dev,
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
/* At least Compaq WL200 does not have IRQInfo1 set,
* but it does not work without interrupts.. */
printk(KERN_WARNING "Config has no IRQ info, but trying to "
"enable IRQ anyway..\n");
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
}
/* IO window settings */ /* IO window settings */
PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
@ -633,21 +624,10 @@ static int prism2_config(struct pcmcia_device *link)
local = iface->local; local = iface->local;
local->hw_priv = hw_priv; local->hw_priv = hw_priv;
hw_priv->link = link; hw_priv->link = link;
strcpy(hw_priv->node.dev_name, dev->name);
link->dev_node = &hw_priv->node;
/* ret = pcmcia_request_irq(link, prism2_interrupt);
* Allocate an interrupt line. Note that this does not assign a if (ret)
* handler to the interrupt, unless the 'Handler' member of the goto failed;
* irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = prism2_interrupt;
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
* This actually configures the PCMCIA socket -- setting up * This actually configures the PCMCIA socket -- setting up
@ -658,7 +638,7 @@ static int prism2_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
/* Finally, report what we've done */ /* Finally, report what we've done */
@ -668,7 +648,7 @@ static int prism2_config(struct pcmcia_device *link)
printk(", Vpp %d.%d", link->conf.Vpp / 10, printk(", Vpp %d.%d", link->conf.Vpp / 10,
link->conf.Vpp % 10); link->conf.Vpp % 10);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
@ -682,11 +662,9 @@ static int prism2_config(struct pcmcia_device *link)
sandisk_enable_wireless(dev); sandisk_enable_wireless(dev);
ret = prism2_hw_config(dev, 1); ret = prism2_hw_config(dev, 1);
if (!ret) { if (!ret)
ret = hostap_hw_ready(dev); ret = hostap_hw_ready(dev);
if (ret == 0 && local->ddev)
strcpy(hw_priv->node.dev_name, local->ddev->name);
}
return ret; return ret;
failed: failed:

View File

@ -777,7 +777,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
lbs_deb_enter(LBS_DEB_CS); lbs_deb_enter(LBS_DEB_CS);
free_irq(p_dev->irq.AssignedIRQ, card); free_irq(p_dev->irq, card);
pcmcia_disable_device(p_dev); pcmcia_disable_device(p_dev);
if (card->iobase) if (card->iobase)
ioport_unmap(card->iobase); ioport_unmap(card->iobase);
@ -807,8 +807,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
p_dev->io.NumPorts1 = cfg->io.win[0].len; p_dev->io.NumPorts1 = cfg->io.win[0].len;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
if (cfg->io.nwin != 1) { if (cfg->io.nwin != 1) {
@ -837,9 +836,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
card->p_dev = p_dev; card->p_dev = p_dev;
p_dev->priv = card; p_dev->priv = card;
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = NULL;
p_dev->conf.Attributes = 0; p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -854,13 +850,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
* a handler to the interrupt, unless the 'Handler' member of * a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized. * the irq structure is initialized.
*/ */
if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) { if (!p_dev->irq)
ret = pcmcia_request_irq(p_dev, &p_dev->irq); goto out1;
if (ret) {
lbs_pr_err("error in pcmcia_request_irq\n");
goto out1;
}
}
/* Initialize io access */ /* Initialize io access */
card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1); card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
@ -883,7 +874,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
/* Finally, report what we've done */ /* Finally, report what we've done */
lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n",
p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, p_dev->irq, p_dev->io.BasePort1,
p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
/* /*
@ -940,7 +931,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
priv->fw_ready = 1; priv->fw_ready = 1;
/* Now actually get the IRQ */ /* Now actually get the IRQ */
ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt, ret = request_irq(p_dev->irq, if_cs_interrupt,
IRQF_SHARED, DRV_NAME, card); IRQF_SHARED, DRV_NAME, card);
if (ret) { if (ret) {
lbs_pr_err("error in request_irq\n"); lbs_pr_err("error in request_irq\n");

View File

@ -50,7 +50,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
* struct orinoco_private */ * struct orinoco_private */
struct orinoco_pccard { struct orinoco_pccard {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
/* Used to handle hard reset */ /* Used to handle hard reset */
/* yuck, we need this hack to work around the insanity of the /* yuck, we need this hack to work around the insanity of the
@ -119,10 +118,6 @@ orinoco_cs_probe(struct pcmcia_device *link)
card->p_dev = link; card->p_dev = link;
link->priv = priv; link->priv = priv;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = orinoco_interrupt;
/* General socket configuration defaults can go here. In this /* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for * client, we assume very little, and rely on the CIS for
* almost everything. In most clients, many details (i.e., * almost everything. In most clients, many details (i.e.,
@ -144,8 +139,7 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
if (link->dev_node) orinoco_if_del(priv);
orinoco_if_del(priv);
orinoco_cs_release(link); orinoco_cs_release(link);
@ -230,7 +224,6 @@ static int
orinoco_cs_config(struct pcmcia_device *link) orinoco_cs_config(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw; hermes_t *hw = &priv->hw;
int ret; int ret;
void __iomem *mem; void __iomem *mem;
@ -258,12 +251,7 @@ orinoco_cs_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* ret = pcmcia_request_irq(link, orinoco_interrupt);
* Allocate an interrupt line. Note that this does not assign
* a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized.
*/
ret = pcmcia_request_irq(link, &link->irq);
if (ret) if (ret)
goto failed; goto failed;
@ -285,9 +273,6 @@ orinoco_cs_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/* Ok, we have the configuration, prepare to register the netdev */
card->node.major = card->node.minor = 0;
/* Initialise the main driver */ /* Initialise the main driver */
if (orinoco_init(priv) != 0) { if (orinoco_init(priv) != 0) {
printk(KERN_ERR PFX "orinoco_init() failed\n"); printk(KERN_ERR PFX "orinoco_init() failed\n");
@ -296,17 +281,11 @@ orinoco_cs_config(struct pcmcia_device *link)
/* Register an interface with the stack */ /* Register an interface with the stack */
if (orinoco_if_add(priv, link->io.BasePort1, if (orinoco_if_add(priv, link->io.BasePort1,
link->irq.AssignedIRQ) != 0) { link->irq) != 0) {
printk(KERN_ERR PFX "orinoco_if_add() failed\n"); printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed; goto failed;
} }
/* At this point, the dev_node_t structure(s) needs to be
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, priv->ndev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
* used to indicate that the
* net_device has been registered */
return 0; return 0;
failed: failed:

View File

@ -57,7 +57,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
* struct orinoco_private */ * struct orinoco_private */
struct orinoco_pccard { struct orinoco_pccard {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
}; };
/********************************************************************/ /********************************************************************/
@ -193,10 +192,6 @@ spectrum_cs_probe(struct pcmcia_device *link)
card->p_dev = link; card->p_dev = link;
link->priv = priv; link->priv = priv;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = orinoco_interrupt;
/* General socket configuration defaults can go here. In this /* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for * client, we assume very little, and rely on the CIS for
* almost everything. In most clients, many details (i.e., * almost everything. In most clients, many details (i.e.,
@ -218,8 +213,7 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
if (link->dev_node) orinoco_if_del(priv);
orinoco_if_del(priv);
spectrum_cs_release(link); spectrum_cs_release(link);
@ -304,7 +298,6 @@ static int
spectrum_cs_config(struct pcmcia_device *link) spectrum_cs_config(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw; hermes_t *hw = &priv->hw;
int ret; int ret;
void __iomem *mem; void __iomem *mem;
@ -332,12 +325,7 @@ spectrum_cs_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* ret = pcmcia_request_irq(link, orinoco_interrupt);
* Allocate an interrupt line. Note that this does not assign
* a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized.
*/
ret = pcmcia_request_irq(link, &link->irq);
if (ret) if (ret)
goto failed; goto failed;
@ -359,9 +347,6 @@ spectrum_cs_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/* Ok, we have the configuration, prepare to register the netdev */
card->node.major = card->node.minor = 0;
/* Reset card */ /* Reset card */
if (spectrum_cs_hard_reset(priv) != 0) if (spectrum_cs_hard_reset(priv) != 0)
goto failed; goto failed;
@ -374,17 +359,11 @@ spectrum_cs_config(struct pcmcia_device *link)
/* Register an interface with the stack */ /* Register an interface with the stack */
if (orinoco_if_add(priv, link->io.BasePort1, if (orinoco_if_add(priv, link->io.BasePort1,
link->irq.AssignedIRQ) != 0) { link->irq) != 0) {
printk(KERN_ERR PFX "orinoco_if_add() failed\n"); printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed; goto failed;
} }
/* At this point, the dev_node_t structure(s) needs to be
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, priv->ndev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
* used to indicate that the
* net_device has been registered */
return 0; return 0;
failed: failed:

View File

@ -51,7 +51,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/mem_op.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/iw_handler.h> #include <net/iw_handler.h>
@ -321,10 +320,6 @@ static int ray_probe(struct pcmcia_device *p_dev)
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = 5; p_dev->io.IOAddrLines = 5;
/* Interrupt setup. For PCMCIA, driver takes what's given */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = &ray_interrupt;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -383,8 +378,7 @@ static void ray_detach(struct pcmcia_device *link)
del_timer(&local->timer); del_timer(&local->timer);
if (link->priv) { if (link->priv) {
if (link->dev_node) unregister_netdev(dev);
unregister_netdev(dev);
free_netdev(dev); free_netdev(dev);
} }
dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
@ -417,10 +411,10 @@ static int ray_config(struct pcmcia_device *link)
/* Now allocate an interrupt line. Note that this does not /* Now allocate an interrupt line. Note that this does not
actually assign a handler to the interrupt. actually assign a handler to the interrupt.
*/ */
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, ray_interrupt);
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
/* This actually configures the PCMCIA socket -- setting up /* This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping. the I/O windows and the interrupt mapping.
@ -493,9 +487,6 @@ static int ray_config(struct pcmcia_device *link)
return i; return i;
} }
strcpy(local->node.dev_name, dev->name);
link->dev_node = &local->node;
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n", printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
dev->name, dev->irq, dev->dev_addr); dev->name, dev->irq, dev->dev_addr);

View File

@ -25,7 +25,6 @@ struct beacon_rx {
typedef struct ray_dev_t { typedef struct ray_dev_t {
int card_status; int card_status;
int authentication_state; int authentication_state;
dev_node_t node;
window_handle_t amem_handle; /* handle to window for attribute memory */ window_handle_t amem_handle; /* handle to window for attribute memory */
window_handle_t rmem_handle; /* handle to window for rx buffer on card */ window_handle_t rmem_handle; /* handle to window for rx buffer on card */
void __iomem *sram; /* pointer to beginning of shared RAM */ void __iomem *sram; /* pointer to beginning of shared RAM */

View File

@ -610,7 +610,6 @@ struct wl3501_card {
struct iw_statistics wstats; struct iw_statistics wstats;
struct iw_spy_data spy_data; struct iw_spy_data spy_data;
struct iw_public_data wireless_data; struct iw_public_data wireless_data;
struct dev_node_t node;
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
}; };
#endif #endif

View File

@ -1451,6 +1451,8 @@ static void wl3501_detach(struct pcmcia_device *link)
netif_device_detach(dev); netif_device_detach(dev);
wl3501_release(link); wl3501_release(link);
unregister_netdev(dev);
if (link->priv) if (link->priv)
free_netdev(link->priv); free_netdev(link->priv);
@ -1897,10 +1899,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = 5; p_dev->io.IOAddrLines = 5;
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = wl3501_interrupt;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -1961,7 +1959,7 @@ static int wl3501_config(struct pcmcia_device *link)
/* Now allocate an interrupt line. Note that this does not actually /* Now allocate an interrupt line. Note that this does not actually
* assign a handler to the interrupt. */ * assign a handler to the interrupt. */
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, wl3501_interrupt);
if (ret) if (ret)
goto failed; goto failed;
@ -1972,7 +1970,7 @@ static int wl3501_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev)) { if (register_netdev(dev)) {
@ -1981,20 +1979,15 @@ static int wl3501_config(struct pcmcia_device *link)
} }
this = netdev_priv(dev); this = netdev_priv(dev);
/*
* At this point, the dev_node_t structure(s) should be initialized and
* arranged in a linked list at link->dev_node.
*/
link->dev_node = &this->node;
this->base_addr = dev->base_addr; this->base_addr = dev->base_addr;
if (!wl3501_get_flash_mac_addr(this)) { if (!wl3501_get_flash_mac_addr(this)) {
printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n", printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n",
dev->name); dev->name);
unregister_netdev(dev);
goto failed; goto failed;
} }
strcpy(this->node.dev_name, dev->name);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; dev->dev_addr[i] = ((char *)&this->mac_addr)[i];
@ -2038,12 +2031,6 @@ static int wl3501_config(struct pcmcia_device *link)
*/ */
static void wl3501_release(struct pcmcia_device *link) static void wl3501_release(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv;
/* Unlink the device chain */
if (link->dev_node)
unregister_netdev(dev);
pcmcia_disable_device(link); pcmcia_disable_device(link);
} }

View File

@ -75,7 +75,6 @@ INT_MODULE_PARM(epp_mode, 1);
typedef struct parport_info_t { typedef struct parport_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
int ndev; int ndev;
dev_node_t node;
struct parport *port; struct parport *port;
} parport_info_t; } parport_info_t;
@ -105,7 +104,6 @@ static int parport_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -174,20 +172,19 @@ static int parport_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE, link->irq, PARPORT_DMA_NONE,
&link->dev, IRQF_SHARED); &link->dev, IRQF_SHARED);
if (p == NULL) { if (p == NULL) {
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
"0x%3x, irq %u failed\n", link->io.BasePort1, "0x%3x, irq %u failed\n", link->io.BasePort1,
link->irq.AssignedIRQ); link->irq);
goto failed; goto failed;
} }
@ -195,11 +192,7 @@ static int parport_config(struct pcmcia_device *link)
if (epp_mode) if (epp_mode)
p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP; p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
info->ndev = 1; info->ndev = 1;
info->node.major = LP_MAJOR;
info->node.minor = p->number;
info->port = p; info->port = p;
strcpy(info->node.dev_name, p->name);
link->dev_node = &info->node;
return 0; return 0;

View File

@ -49,26 +49,6 @@ config PCMCIA_LOAD_CIS
If unsure, say Y. If unsure, say Y.
config PCMCIA_IOCTL
bool "PCMCIA control ioctl (obsolete)"
depends on PCMCIA && ARM && !SMP && !PREEMPT
default y
help
If you say Y here, the deprecated ioctl interface to the PCMCIA
subsystem will be built. It is needed by the deprecated pcmcia-cs
tools (cardmgr, cardctl) to function properly.
You should use the new pcmciautils package instead (see
<file:Documentation/Changes> for location and details).
This config option will most likely be removed from kernel 2.6.35,
the associated code from kernel 2.6.36.
As the PCMCIA ioctl is not locking safe, it depends on !SMP and
!PREEMPT.
If unsure, say N.
config CARDBUS config CARDBUS
bool "32-bit CardBus support" bool "32-bit CardBus support"
depends on PCI depends on PCI
@ -318,7 +298,7 @@ config ELECTRA_CF
PA Semi Electra eval board. PA Semi Electra eval board.
config PCCARD_NONSTATIC config PCCARD_NONSTATIC
tristate bool
config PCCARD_IODYN config PCCARD_IODYN
bool bool

View File

@ -2,15 +2,18 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds) # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
# #
pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o pcmcia_core-y += cs.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
obj-$(CONFIG_PCCARD) += pcmcia_core.o obj-$(CONFIG_PCCARD) += pcmcia_core.o
pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o
pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
obj-$(CONFIG_PCMCIA) += pcmcia.o obj-$(CONFIG_PCMCIA) += pcmcia.o
obj-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o pcmcia_rsrc-y += rsrc_mgr.o
pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o
pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o
obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o
# socket drivers # socket drivers

View File

@ -113,7 +113,7 @@ static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp)
if (bfin_cf_present(cf->cd_pfx)) { if (bfin_cf_present(cf->cd_pfx)) {
*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
s->irq.AssignedIRQ = 0; s->pcmcia_irq = 0;
s->pci_irq = cf->irq; s->pci_irq = cf->irq;
} else } else

View File

@ -94,7 +94,6 @@ int __ref cb_alloc(struct pcmcia_socket *s)
pci_enable_bridges(bus); pci_enable_bridges(bus);
pci_bus_add_devices(bus); pci_bus_add_devices(bus);
s->irq.AssignedIRQ = s->pci_irq;
return 0; return 0;
} }

View File

@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
/** /**
* pcmcia_read_cis_mem() - low-level function to read CIS memory * pcmcia_read_cis_mem() - low-level function to read CIS memory
*
* must be called with ops_mutex held
*/ */
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
mutex_lock(&s->ops_mutex);
if (attr & IS_INDIRECT) { if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed /* Indirect accesses use a bunch of special registers at fixed
locations in common memory */ locations in common memory */
@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
if (!sys) { if (!sys) {
dev_dbg(&s->dev, "could not map memory\n"); dev_dbg(&s->dev, "could not map memory\n");
memset(ptr, 0xff, len); memset(ptr, 0xff, len);
mutex_unlock(&s->ops_mutex);
return -1; return -1;
} }
@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
if (!sys) { if (!sys) {
dev_dbg(&s->dev, "could not map memory\n"); dev_dbg(&s->dev, "could not map memory\n");
memset(ptr, 0xff, len); memset(ptr, 0xff, len);
mutex_unlock(&s->ops_mutex);
return -1; return -1;
} }
end = sys + s->map_size; end = sys + s->map_size;
@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
addr = 0; addr = 0;
} }
} }
mutex_unlock(&s->ops_mutex);
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
*(u_char *)(ptr+0), *(u_char *)(ptr+1), *(u_char *)(ptr+0), *(u_char *)(ptr+1),
*(u_char *)(ptr+2), *(u_char *)(ptr+3)); *(u_char *)(ptr+2), *(u_char *)(ptr+3));
@ -209,7 +207,8 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
/** /**
* pcmcia_write_cis_mem() - low-level function to write CIS memory * pcmcia_write_cis_mem() - low-level function to write CIS memory
* *
* Probably only useful for writing one-byte registers. * Probably only useful for writing one-byte registers. Must be called
* with ops_mutex held.
*/ */
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
dev_dbg(&s->dev, dev_dbg(&s->dev,
"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
mutex_lock(&s->ops_mutex);
if (attr & IS_INDIRECT) { if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed /* Indirect accesses use a bunch of special registers at fixed
locations in common memory */ locations in common memory */
@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
((cis_width) ? MAP_16BIT : 0)); ((cis_width) ? MAP_16BIT : 0));
if (!sys) { if (!sys) {
dev_dbg(&s->dev, "could not map memory\n"); dev_dbg(&s->dev, "could not map memory\n");
mutex_unlock(&s->ops_mutex);
return; /* FIXME: Error */ return; /* FIXME: Error */
} }
@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
sys = set_cis_map(s, card_offset, flags); sys = set_cis_map(s, card_offset, flags);
if (!sys) { if (!sys) {
dev_dbg(&s->dev, "could not map memory\n"); dev_dbg(&s->dev, "could not map memory\n");
mutex_unlock(&s->ops_mutex);
return; /* FIXME: error */ return; /* FIXME: error */
} }
@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
addr = 0; addr = 0;
} }
} }
mutex_unlock(&s->ops_mutex);
} }
@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
return 0; return 0;
} }
} }
mutex_unlock(&s->ops_mutex);
ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
cis->len = len; cis->len = len;
cis->attr = attr; cis->attr = attr;
memcpy(cis->cache, ptr, len); memcpy(cis->cache, ptr, len);
mutex_lock(&s->ops_mutex);
list_add(&cis->node, &s->cis_cache); list_add(&cis->node, &s->cis_cache);
mutex_unlock(&s->ops_mutex);
} }
} }
mutex_unlock(&s->ops_mutex);
return ret; return ret;
} }
@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
"no memory for verifying CIS\n"); "no memory for verifying CIS\n");
return -ENOMEM; return -ENOMEM;
} }
mutex_lock(&s->ops_mutex);
list_for_each_entry(cis, &s->cis_cache, node) { list_for_each_entry(cis, &s->cis_cache, node) {
int len = cis->len; int len = cis->len;
@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
if (ret || memcmp(buf, cis->cache, len) != 0) { if (ret || memcmp(buf, cis->cache, len) != 0) {
kfree(buf); kfree(buf);
mutex_unlock(&s->ops_mutex);
return -1; return -1;
} }
} }
kfree(buf); kfree(buf);
mutex_unlock(&s->ops_mutex);
return 0; return 0;
} }
@ -1361,106 +1358,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
EXPORT_SYMBOL(pcmcia_parse_tuple); EXPORT_SYMBOL(pcmcia_parse_tuple);
/**
* pccard_read_tuple() - internal CIS tuple access
* @s: the struct pcmcia_socket where the card is inserted
* @function: the device function we loop for
* @code: which CIS code shall we look for?
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
*
* pccard_read_tuple() reads out one tuple and attempts to parse it
*/
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, void *parse)
{
tuple_t tuple;
cisdata_t *buf;
int ret;
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.DesiredTuple = code;
tuple.Attributes = 0;
if (function == BIND_FN_ALL)
tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, &tuple);
if (ret != 0)
goto done;
tuple.TupleData = buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
ret = pccard_get_tuple_data(s, &tuple);
if (ret != 0)
goto done;
ret = pcmcia_parse_tuple(&tuple, parse);
done:
kfree(buf);
return ret;
}
/**
* pccard_loop_tuple() - loop over tuples in the CIS
* @s: the struct pcmcia_socket where the card is inserted
* @function: the device function we loop for
* @code: which CIS code shall we look for?
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple, the paresed tuple (if @parse is
* set) and @priv_data.
*
* pccard_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, cisparse_t *parse, void *priv_data,
int (*loop_tuple) (tuple_t *tuple,
cisparse_t *parse,
void *priv_data))
{
tuple_t tuple;
cisdata_t *buf;
int ret;
buf = kzalloc(256, GFP_KERNEL);
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.TupleData = buf;
tuple.TupleDataMax = 255;
tuple.TupleOffset = 0;
tuple.DesiredTuple = code;
tuple.Attributes = 0;
ret = pccard_get_first_tuple(s, function, &tuple);
while (!ret) {
if (pccard_get_tuple_data(s, &tuple))
goto next_entry;
if (parse)
if (pcmcia_parse_tuple(&tuple, parse))
goto next_entry;
ret = loop_tuple(&tuple, parse, priv_data);
if (!ret)
break;
next_entry:
ret = pccard_get_next_tuple(s, function, &tuple);
}
kfree(buf);
return ret;
}
/** /**
* pccard_validate_cis() - check whether card has a sensible CIS * pccard_validate_cis() - check whether card has a sensible CIS
* @s: the struct pcmcia_socket we are to check * @s: the struct pcmcia_socket we are to check

View File

@ -337,7 +337,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
s->socket = dead_socket; s->socket = dead_socket;
s->ops->init(s); s->ops->init(s);
s->ops->set_socket(s, &s->socket); s->ops->set_socket(s, &s->socket);
s->irq.AssignedIRQ = s->irq.Config = 0;
s->lock_count = 0; s->lock_count = 0;
kfree(s->fake_cis); kfree(s->fake_cis);
s->fake_cis = NULL; s->fake_cis = NULL;

View File

@ -52,13 +52,11 @@ struct cis_cache_entry {
struct pccard_resource_ops { struct pccard_resource_ops {
int (*validate_mem) (struct pcmcia_socket *s); int (*validate_mem) (struct pcmcia_socket *s);
int (*adjust_io_region) (struct resource *res, int (*find_io) (struct pcmcia_socket *s,
unsigned long r_start, unsigned int attr,
unsigned long r_end, unsigned int *base,
struct pcmcia_socket *s); unsigned int num,
struct resource* (*find_io) (unsigned long base, int num, unsigned int align);
unsigned long align,
struct pcmcia_socket *s);
struct resource* (*find_mem) (unsigned long base, unsigned long num, struct resource* (*find_mem) (unsigned long base, unsigned long num,
unsigned long align, int low, unsigned long align, int low,
struct pcmcia_socket *s); struct pcmcia_socket *s);
@ -88,6 +86,14 @@ struct pccard_resource_ops {
#define SOCKET_CARDBUS_CONFIG 0x10000 #define SOCKET_CARDBUS_CONFIG 0x10000
/*
* Stuff internal to module "pcmcia_rsrc":
*/
extern int static_init(struct pcmcia_socket *s);
extern struct resource *pcmcia_make_resource(unsigned long start,
unsigned long end,
int flags, const char *name);
/* /*
* Stuff internal to module "pcmcia_core": * Stuff internal to module "pcmcia_core":
*/ */
@ -149,6 +155,8 @@ extern struct resource *pcmcia_find_mem_region(u_long base,
int low, int low,
struct pcmcia_socket *s); struct pcmcia_socket *s);
void pcmcia_cleanup_irq(struct pcmcia_socket *s);
int pcmcia_setup_irq(struct pcmcia_device *p_dev);
/* cistpl.c */ /* cistpl.c */
extern struct bin_attribute pccard_cis_attr; extern struct bin_attribute pccard_cis_attr;

View File

@ -371,8 +371,6 @@ static int pcmcia_device_remove(struct device *dev)
if (p_drv->remove) if (p_drv->remove)
p_drv->remove(p_dev); p_drv->remove(p_dev);
p_dev->dev_node = NULL;
/* check for proper unloading */ /* check for proper unloading */
if (p_dev->_irq || p_dev->_io || p_dev->_locked) if (p_dev->_irq || p_dev->_io || p_dev->_locked)
dev_printk(KERN_INFO, dev, dev_printk(KERN_INFO, dev,
@ -479,15 +477,6 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
} }
/* device_add_lock is needed to avoid double registration by cardmgr and kernel.
* Serializes pcmcia_device_add; will most likely be removed in future.
*
* While it has the caveat that adding new PCMCIA devices inside(!) device_register()
* won't work, this doesn't matter much at the moment: the driver core doesn't
* support it either.
*/
static DEFINE_MUTEX(device_add_lock);
struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
{ {
struct pcmcia_device *p_dev, *tmp_dev; struct pcmcia_device *p_dev, *tmp_dev;
@ -497,8 +486,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
if (!s) if (!s)
return NULL; return NULL;
mutex_lock(&device_add_lock);
pr_debug("adding device to %d, function %d\n", s->sock, function); pr_debug("adding device to %d, function %d\n", s->sock, function);
p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
@ -538,8 +525,8 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
/* /*
* p_dev->function_config must be the same for all card functions. * p_dev->function_config must be the same for all card functions.
* Note that this is serialized by the device_add_lock, so that * Note that this is serialized by ops_mutex, so that only one
* only one such struct will be created. * such struct will be created.
*/ */
list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
if (p_dev->func == tmp_dev->func) { if (p_dev->func == tmp_dev->func) {
@ -552,28 +539,31 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
/* Add to the list in pcmcia_bus_socket */ /* Add to the list in pcmcia_bus_socket */
list_add(&p_dev->socket_device_list, &s->devices_list); list_add(&p_dev->socket_device_list, &s->devices_list);
mutex_unlock(&s->ops_mutex); if (pcmcia_setup_irq(p_dev))
dev_warn(&p_dev->dev,
"IRQ setup failed -- device might not work\n");
if (!p_dev->function_config) { if (!p_dev->function_config) {
dev_dbg(&p_dev->dev, "creating config_t\n"); dev_dbg(&p_dev->dev, "creating config_t\n");
p_dev->function_config = kzalloc(sizeof(struct config_t), p_dev->function_config = kzalloc(sizeof(struct config_t),
GFP_KERNEL); GFP_KERNEL);
if (!p_dev->function_config) if (!p_dev->function_config) {
mutex_unlock(&s->ops_mutex);
goto err_unreg; goto err_unreg;
}
kref_init(&p_dev->function_config->ref); kref_init(&p_dev->function_config->ref);
} }
mutex_unlock(&s->ops_mutex);
dev_printk(KERN_NOTICE, &p_dev->dev, dev_printk(KERN_NOTICE, &p_dev->dev,
"pcmcia: registering new device %s\n", "pcmcia: registering new device %s (IRQ: %d)\n",
p_dev->devname); p_dev->devname, p_dev->irq);
pcmcia_device_query(p_dev); pcmcia_device_query(p_dev);
if (device_register(&p_dev->dev)) if (device_register(&p_dev->dev))
goto err_unreg; goto err_unreg;
mutex_unlock(&device_add_lock);
return p_dev; return p_dev;
err_unreg: err_unreg:
@ -591,7 +581,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
kfree(p_dev->devname); kfree(p_dev->devname);
kfree(p_dev); kfree(p_dev);
err_put: err_put:
mutex_unlock(&device_add_lock);
pcmcia_put_socket(s); pcmcia_put_socket(s);
return NULL; return NULL;
@ -1258,6 +1247,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
handle_event(skt, event); handle_event(skt, event);
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
destroy_cis_cache(s); destroy_cis_cache(s);
pcmcia_cleanup_irq(s);
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
break; break;

View File

@ -117,7 +117,7 @@ static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp)
*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
cf = container_of(s, struct omap_cf_socket, socket); cf = container_of(s, struct omap_cf_socket, socket);
s->irq.AssignedIRQ = 0; s->pcmcia_irq = 0;
s->pci_irq = cf->irq; s->pci_irq = cf->irq;
} else } else
*sp = 0; *sp = 0;

356
drivers/pcmcia/pcmcia_cis.c Normal file
View File

@ -0,0 +1,356 @@
/*
* PCMCIA high-level CIS access functions
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* Copyright (C) 1999 David A. Hinds
* Copyright (C) 2004-2009 Dominik Brodowski
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/ds.h>
#include "cs_internal.h"
/**
* pccard_read_tuple() - internal CIS tuple access
* @s: the struct pcmcia_socket where the card is inserted
* @function: the device function we loop for
* @code: which CIS code shall we look for?
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
*
* pccard_read_tuple() reads out one tuple and attempts to parse it
*/
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, void *parse)
{
tuple_t tuple;
cisdata_t *buf;
int ret;
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.DesiredTuple = code;
tuple.Attributes = 0;
if (function == BIND_FN_ALL)
tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, &tuple);
if (ret != 0)
goto done;
tuple.TupleData = buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
ret = pccard_get_tuple_data(s, &tuple);
if (ret != 0)
goto done;
ret = pcmcia_parse_tuple(&tuple, parse);
done:
kfree(buf);
return ret;
}
/**
* pccard_loop_tuple() - loop over tuples in the CIS
* @s: the struct pcmcia_socket where the card is inserted
* @function: the device function we loop for
* @code: which CIS code shall we look for?
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple, the paresed tuple (if @parse is
* set) and @priv_data.
*
* pccard_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, cisparse_t *parse, void *priv_data,
int (*loop_tuple) (tuple_t *tuple,
cisparse_t *parse,
void *priv_data))
{
tuple_t tuple;
cisdata_t *buf;
int ret;
buf = kzalloc(256, GFP_KERNEL);
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.TupleData = buf;
tuple.TupleDataMax = 255;
tuple.TupleOffset = 0;
tuple.DesiredTuple = code;
tuple.Attributes = 0;
ret = pccard_get_first_tuple(s, function, &tuple);
while (!ret) {
if (pccard_get_tuple_data(s, &tuple))
goto next_entry;
if (parse)
if (pcmcia_parse_tuple(&tuple, parse))
goto next_entry;
ret = loop_tuple(&tuple, parse, priv_data);
if (!ret)
break;
next_entry:
ret = pccard_get_next_tuple(s, function, &tuple);
}
kfree(buf);
return ret;
}
struct pcmcia_cfg_mem {
struct pcmcia_device *p_dev;
void *priv_data;
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data);
cisparse_t parse;
cistpl_cftable_entry_t dflt;
};
/**
* pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
*
* pcmcia_do_loop_config() is the internal callback for the call from
* pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
* by a struct pcmcia_cfg_mem.
*/
static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
{
cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
struct pcmcia_cfg_mem *cfg_mem = priv;
/* default values */
cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
cfg_mem->dflt = *cfg;
return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
cfg_mem->p_dev->socket->socket.Vcc,
cfg_mem->priv_data);
}
/**
* pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option.
* It gets passed the struct pcmcia_device, the CIS data
* describing the configuration option, and private data
* being passed to pcmcia_loop_config()
* @priv_data: private data to be passed to the conf_check function.
*
* pcmcia_loop_config() loops over all configuration options, and calls
* the driver-specific conf_check() for each one, checking whether
* it is a valid one. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data),
void *priv_data)
{
struct pcmcia_cfg_mem *cfg_mem;
int ret;
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
if (cfg_mem == NULL)
return -ENOMEM;
cfg_mem->p_dev = p_dev;
cfg_mem->conf_check = conf_check;
cfg_mem->priv_data = priv_data;
ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
cfg_mem, pcmcia_do_loop_config);
kfree(cfg_mem);
return ret;
}
EXPORT_SYMBOL(pcmcia_loop_config);
struct pcmcia_loop_mem {
struct pcmcia_device *p_dev;
void *priv_data;
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data);
};
/**
* pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
*
* pcmcia_do_loop_tuple() is the internal callback for the call from
* pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
* by a struct pcmcia_cfg_mem.
*/
static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
{
struct pcmcia_loop_mem *loop = priv;
return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
};
/**
* pcmcia_loop_tuple() - loop over tuples in the CIS
* @p_dev: the struct pcmcia_device which we need to loop for.
* @code: which CIS code shall we look for?
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple and @priv_data.
*
* pcmcia_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data),
void *priv_data)
{
struct pcmcia_loop_mem loop = {
.p_dev = p_dev,
.loop_tuple = loop_tuple,
.priv_data = priv_data};
return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
&loop, pcmcia_do_loop_tuple);
}
EXPORT_SYMBOL(pcmcia_loop_tuple);
struct pcmcia_loop_get {
size_t len;
cisdata_t **buf;
};
/**
* pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
*
* pcmcia_do_get_tuple() is the internal callback for the call from
* pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
* the first tuple, return 0 unconditionally. Create a memory buffer large
* enough to hold the content of the tuple, and fill it with the tuple data.
* The caller is responsible to free the buffer.
*/
static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
void *priv)
{
struct pcmcia_loop_get *get = priv;
*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
if (*get->buf) {
get->len = tuple->TupleDataLen;
memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
} else
dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
return 0;
}
/**
* pcmcia_get_tuple() - get first tuple from CIS
* @p_dev: the struct pcmcia_device which we need to loop for.
* @code: which CIS code shall we look for?
* @buf: pointer to store the buffer to.
*
* pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
* It returns the buffer length (or zero). The caller is responsible to free
* the buffer passed in @buf.
*/
size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
unsigned char **buf)
{
struct pcmcia_loop_get get = {
.len = 0,
.buf = buf,
};
*get.buf = NULL;
pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
return get.len;
}
EXPORT_SYMBOL(pcmcia_get_tuple);
/**
* pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
*
* pcmcia_do_get_mac() is the internal callback for the call from
* pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
* tuple contains a proper LAN_NODE_ID of length 6, and copy the data
* to struct net_device->dev_addr[i].
*/
static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
void *priv)
{
struct net_device *dev = priv;
int i;
if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
return -EINVAL;
if (tuple->TupleDataLen < ETH_ALEN + 2) {
dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
"LAN_NODE_ID\n");
return -EINVAL;
}
if (tuple->TupleData[1] != ETH_ALEN) {
dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
return -EINVAL;
}
for (i = 0; i < 6; i++)
dev->dev_addr[i] = tuple->TupleData[i+2];
return 0;
}
/**
* pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
* @p_dev: the struct pcmcia_device for which we want the address.
* @dev: a properly prepared struct net_device to store the info to.
*
* pcmcia_get_mac_from_cis() reads out the hardware MAC address from
* CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
* must be set up properly by the driver (see examples!).
*/
int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
{
return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
}
EXPORT_SYMBOL(pcmcia_get_mac_from_cis);

View File

@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
u_char reg; u_char reg;
if (c->CardValues & PRESENT_PIN_REPLACE) { if (c->CardValues & PRESENT_PIN_REPLACE) {
mutex_lock(&s->ops_mutex);
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg); pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
mutex_unlock(&s->ops_mutex);
status->CardState |= status->CardState |=
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
status->CardState |= status->CardState |=
@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
status->CardState |= CS_EVENT_READY_CHANGE; status->CardState |= CS_EVENT_READY_CHANGE;
} }
if (c->CardValues & PRESENT_EXT_STATUS) { if (c->CardValues & PRESENT_EXT_STATUS) {
mutex_lock(&s->ops_mutex);
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg); pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
mutex_unlock(&s->ops_mutex);
status->CardState |= status->CardState |=
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
} }
@ -351,7 +355,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s,
if (s->state & SOCKET_CARDBUS_CONFIG) { if (s->state & SOCKET_CARDBUS_CONFIG) {
config->Attributes = CONF_VALID_CLIENT; config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS; config->IntType = INT_CARDBUS;
config->AssignedIRQ = s->irq.AssignedIRQ; config->AssignedIRQ = s->pcmcia_irq;
if (config->AssignedIRQ) if (config->AssignedIRQ)
config->Attributes |= CONF_ENABLE_IRQ; config->Attributes |= CONF_ENABLE_IRQ;
if (s->io[0].res) { if (s->io[0].res) {
@ -391,7 +395,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s,
config->ExtStatus = c->ExtStatus; config->ExtStatus = c->ExtStatus;
config->Present = config->CardValues = c->CardValues; config->Present = config->CardValues = c->CardValues;
config->IRQAttributes = c->irq.Attributes; config->IRQAttributes = c->irq.Attributes;
config->AssignedIRQ = s->irq.AssignedIRQ; config->AssignedIRQ = s->pcmcia_irq;
config->BasePort1 = c->io.BasePort1; config->BasePort1 = c->io.BasePort1;
config->NumPorts1 = c->io.NumPorts1; config->NumPorts1 = c->io.NumPorts1;
config->Attributes1 = c->io.Attributes1; config->Attributes1 = c->io.Attributes1;
@ -571,7 +575,6 @@ static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
{ {
dev_node_t *node;
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv; struct pcmcia_driver *p_drv;
int ret = 0; int ret = 0;
@ -633,21 +636,13 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
goto err_put; goto err_put;
} }
if (first) if (!first) {
node = p_dev->dev_node;
else
for (node = p_dev->dev_node; node; node = node->next)
if (node == bind_info->next)
break;
if (!node) {
ret = -ENODEV; ret = -ENODEV;
goto err_put; goto err_put;
} }
strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN); strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN);
bind_info->major = node->major; bind_info->next = NULL;
bind_info->minor = node->minor;
bind_info->next = node->next;
err_put: err_put:
pcmcia_put_dev(p_dev); pcmcia_put_dev(p_dev);

View File

@ -23,6 +23,8 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/irq.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h> #include <pcmcia/cs.h>
@ -38,29 +40,6 @@ static int io_speed;
module_param(io_speed, int, 0444); module_param(io_speed, int, 0444);
#ifdef CONFIG_PCMCIA_PROBE
#include <asm/irq.h>
/* mask of IRQs already reserved by other cards, we should avoid using them */
static u8 pcmcia_used_irq[NR_IRQS];
#endif
static int pcmcia_adjust_io_region(struct resource *res, unsigned long start,
unsigned long end, struct pcmcia_socket *s)
{
if (s->resource_ops->adjust_io_region)
return s->resource_ops->adjust_io_region(res, start, end, s);
return -ENOMEM;
}
static struct resource *pcmcia_find_io_region(unsigned long base, int num,
unsigned long align,
struct pcmcia_socket *s)
{
if (s->resource_ops->find_io)
return s->resource_ops->find_io(base, num, align, s);
return NULL;
}
int pcmcia_validate_mem(struct pcmcia_socket *s) int pcmcia_validate_mem(struct pcmcia_socket *s)
{ {
if (s->resource_ops->validate_mem) if (s->resource_ops->validate_mem)
@ -86,8 +65,7 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
static int alloc_io_space(struct pcmcia_socket *s, u_int attr, static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
unsigned int *base, unsigned int num, u_int lines) unsigned int *base, unsigned int num, u_int lines)
{ {
int i; unsigned int align;
unsigned int try, align;
align = (*base) ? (lines ? 1<<lines : 0) : 1; align = (*base) ? (lines ? 1<<lines : 0) : 1;
if (align && (align < num)) { if (align && (align < num)) {
@ -104,50 +82,8 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
*base, align); *base, align);
align = 0; align = 0;
} }
if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
*base = s->io_offset | (*base & 0x0fff); return s->resource_ops->find_io(s, attr, base, num, align);
return 0;
}
/* Check for an already-allocated window that must conflict with
* what was asked for. It is a hack because it does not catch all
* potential conflicts, just the most obvious ones.
*/
for (i = 0; i < MAX_IO_WIN; i++)
if ((s->io[i].res) && *base &&
((s->io[i].res->start & (align-1)) == *base))
return 1;
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res) {
s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
if (s->io[i].res) {
*base = s->io[i].res->start;
s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
s->io[i].InUse = num;
break;
} else
return 1;
} else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS))
continue;
/* Try to extend top of window */
try = s->io[i].res->end + 1;
if ((*base == 0) || (*base == try))
if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
s->io[i].res->end + num, s) == 0) {
*base = try;
s->io[i].InUse += num;
break;
}
/* Try to extend bottom of window */
try = s->io[i].res->start - num;
if ((*base == 0) || (*base == try))
if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
s->io[i].res->end, s) == 0) {
*base = try;
s->io[i].InUse += num;
break;
}
}
return (i == MAX_IO_WIN);
} /* alloc_io_space */ } /* alloc_io_space */
@ -187,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
config_t *c; config_t *c;
int addr; int addr;
u_char val; u_char val;
int ret = 0;
if (!p_dev || !p_dev->function_config) if (!p_dev || !p_dev->function_config)
return -EINVAL; return -EINVAL;
@ -203,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
} }
addr = (c->ConfigBase + reg->Offset) >> 1; addr = (c->ConfigBase + reg->Offset) >> 1;
mutex_unlock(&s->ops_mutex);
switch (reg->Action) { switch (reg->Action) {
case CS_READ: case CS_READ:
pcmcia_read_cis_mem(s, 1, addr, 1, &val); ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val);
reg->Value = val; reg->Value = val;
break; break;
case CS_WRITE: case CS_WRITE:
@ -216,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
break; break;
default: default:
dev_dbg(&s->dev, "Invalid conf register request\n"); dev_dbg(&s->dev, "Invalid conf register request\n");
return -EINVAL; ret = -EINVAL;
break; break;
} }
return 0; mutex_unlock(&s->ops_mutex);
return ret;
} /* pcmcia_access_configuration_register */ } /* pcmcia_access_configuration_register */
EXPORT_SYMBOL(pcmcia_access_configuration_register); EXPORT_SYMBOL(pcmcia_access_configuration_register);
@ -275,19 +212,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
goto unlock; goto unlock;
} }
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) {
if (mod->Attributes & CONF_ENABLE_IRQ) { dev_dbg(&s->dev,
c->Attributes |= CONF_ENABLE_IRQ; "changing Vcc or IRQ is not allowed at this time\n");
s->socket.io_irq = s->irq.AssignedIRQ;
} else {
c->Attributes &= ~CONF_ENABLE_IRQ;
s->socket.io_irq = 0;
}
s->ops->set_socket(s, &s->socket);
}
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
} }
@ -422,52 +349,6 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
} /* pcmcia_release_io */ } /* pcmcia_release_io */
static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
int ret = -EINVAL;
mutex_lock(&s->ops_mutex);
c = p_dev->function_config;
if (!p_dev->_irq)
goto out;
p_dev->_irq = 0;
if (c->state & CONFIG_LOCKED)
goto out;
if (c->irq.Attributes != req->Attributes) {
dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
goto out;
}
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
dev_dbg(&s->dev, "IRQ must match assigned one\n");
goto out;
}
if (--s->irq.Config == 0) {
c->state &= ~CONFIG_IRQ_REQ;
s->irq.AssignedIRQ = 0;
}
if (req->Handler)
free_irq(req->AssignedIRQ, p_dev->priv);
#ifdef CONFIG_PCMCIA_PROBE
pcmcia_used_irq[req->AssignedIRQ]--;
#endif
ret = 0;
out:
mutex_unlock(&s->ops_mutex);
return ret;
} /* pcmcia_release_irq */
int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
{ {
struct pcmcia_socket *s = p_dev->socket; struct pcmcia_socket *s = p_dev->socket;
@ -551,12 +432,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
if (req->Attributes & CONF_ENABLE_SPKR) if (req->Attributes & CONF_ENABLE_SPKR)
s->socket.flags |= SS_SPKR_ENA; s->socket.flags |= SS_SPKR_ENA;
if (req->Attributes & CONF_ENABLE_IRQ) if (req->Attributes & CONF_ENABLE_IRQ)
s->socket.io_irq = s->irq.AssignedIRQ; s->socket.io_irq = s->pcmcia_irq;
else else
s->socket.io_irq = 0; s->socket.io_irq = 0;
s->ops->set_socket(s, &s->socket); s->ops->set_socket(s, &s->socket);
s->lock_count++; s->lock_count++;
mutex_unlock(&s->ops_mutex);
/* Set up CIS configuration registers */ /* Set up CIS configuration registers */
base = c->ConfigBase = req->ConfigBase; base = c->ConfigBase = req->ConfigBase;
@ -574,9 +454,9 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
if (req->Present & PRESENT_IOBASE_0) if (req->Present & PRESENT_IOBASE_0)
c->Option |= COR_ADDR_DECODE; c->Option |= COR_ADDR_DECODE;
} }
if (c->state & CONFIG_IRQ_REQ) if ((req->Attributes & CONF_ENABLE_IRQ) &&
if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) !(req->Attributes & CONF_ENABLE_PULSE_IRQ))
c->Option |= COR_LEVEL_REQ; c->Option |= COR_LEVEL_REQ;
pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
mdelay(40); mdelay(40);
} }
@ -605,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
/* Configure I/O windows */ /* Configure I/O windows */
if (c->state & CONFIG_IO_REQ) { if (c->state & CONFIG_IO_REQ) {
mutex_lock(&s->ops_mutex);
iomap.speed = io_speed; iomap.speed = io_speed;
for (i = 0; i < MAX_IO_WIN; i++) for (i = 0; i < MAX_IO_WIN; i++)
if (s->io[i].res) { if (s->io[i].res) {
@ -624,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
s->ops->set_io_map(s, &iomap); s->ops->set_io_map(s, &iomap);
s->io[i].Config++; s->io[i].Config++;
} }
mutex_unlock(&s->ops_mutex);
} }
c->state |= CONFIG_LOCKED; c->state |= CONFIG_LOCKED;
p_dev->_locked = 1; p_dev->_locked = 1;
mutex_unlock(&s->ops_mutex);
return 0; return 0;
} /* pcmcia_request_configuration */ } /* pcmcia_request_configuration */
EXPORT_SYMBOL(pcmcia_request_configuration); EXPORT_SYMBOL(pcmcia_request_configuration);
@ -706,137 +585,176 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
EXPORT_SYMBOL(pcmcia_request_io); EXPORT_SYMBOL(pcmcia_request_io);
/** pcmcia_request_irq /**
* pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
* *
* Request_irq() reserves an irq for this client. * pcmcia_request_irq() is a wrapper around request_irq which will allow
* * the PCMCIA core to clean up the registration in pcmcia_disable_device().
* Also, since Linux only reserves irq's when they are actually * Drivers are free to use request_irq() directly, but then they need to
* hooked, we don't guarantee that an irq will still be available * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ
* when the configuration is locked. Now that I think about it, * handlers are allowed.
* there might be a way to fix this using a dummy handler.
*/ */
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
#ifdef CONFIG_PCMCIA_PROBE irq_handler_t handler)
static irqreturn_t test_action(int cpl, void *dev_id)
{ {
return IRQ_NONE; int ret;
if (!p_dev->irq)
return -EINVAL;
ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
p_dev->devname, p_dev->priv);
if (!ret)
p_dev->_irq = 1;
return ret;
} }
#endif EXPORT_SYMBOL(pcmcia_request_irq);
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
/**
* pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first
*
* pcmcia_request_exclusive_irq() is a wrapper around request_irq which
* attempts first to request an exclusive IRQ. If it fails, it also accepts
* a shared IRQ, but prints out a warning. PCMCIA drivers should allow for
* IRQ sharing and either use request_irq directly (then they need to call
* free_irq themselves, too), or the pcmcia_request_irq() function.
*/
int __must_check
__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
irq_handler_t handler)
{ {
struct pcmcia_socket *s = p_dev->socket; int ret;
config_t *c;
int ret = -EINVAL, irq = 0;
int type;
mutex_lock(&s->ops_mutex); if (!p_dev->irq)
return -EINVAL;
if (!(s->state & SOCKET_PRESENT)) { ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
dev_dbg(&s->dev, "No card present\n"); if (ret) {
goto out; ret = pcmcia_request_irq(p_dev, handler);
}
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) {
dev_dbg(&s->dev, "Configuration is locked\n");
goto out;
}
if (c->state & CONFIG_IRQ_REQ) {
dev_dbg(&s->dev, "IRQ already configured\n");
goto out;
}
/* Decide what type of interrupt we are registering */
type = 0;
if (s->functions > 1) /* All of this ought to be handled higher up */
type = IRQF_SHARED;
else if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)
type = IRQF_SHARED;
else
printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
/* If the interrupt is already assigned, it must be the same */
if (s->irq.AssignedIRQ != 0)
irq = s->irq.AssignedIRQ;
#ifdef CONFIG_PCMCIA_PROBE
if (!irq) {
int try;
u32 mask = s->irq_mask;
void *data = p_dev; /* something unique to this device */
for (try = 0; try < 64; try++) {
irq = try % 32;
/* marked as available by driver, and not blocked by userspace? */
if (!((mask >> irq) & 1))
continue;
/* avoid an IRQ which is already used by a PCMCIA card */
if ((try < 32) && pcmcia_used_irq[irq])
continue;
/* register the correct driver, if possible, of check whether
* registering a dummy handle works, i.e. if the IRQ isn't
* marked as used by the kernel resource management core */
ret = request_irq(irq,
(req->Handler) ? req->Handler : test_action,
type,
p_dev->devname,
(req->Handler) ? p_dev->priv : data);
if (!ret) {
if (!req->Handler)
free_irq(irq, data);
break;
}
}
}
#endif
/* only assign PCI irq if no IRQ already assigned */
if (ret && !s->irq.AssignedIRQ) {
if (!s->pci_irq) {
dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
goto out;
}
type = IRQF_SHARED;
irq = s->pci_irq;
}
if (ret && req->Handler) {
ret = request_irq(irq, req->Handler, type,
p_dev->devname, p_dev->priv);
if (ret) {
dev_printk(KERN_INFO, &s->dev,
"request_irq() failed\n");
goto out;
}
}
/* Make sure the fact the request type was overridden is passed back */
if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
"request for exclusive IRQ could not be fulfilled.\n"); "request for exclusive IRQ could not be fulfilled.\n");
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
"needs updating to supported shared IRQ lines.\n"); "needs updating to supported shared IRQ lines.\n");
} }
c->irq.Attributes = req->Attributes; if (ret)
s->irq.AssignedIRQ = req->AssignedIRQ = irq; dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
s->irq.Config++; else
p_dev->_irq = 1;
return ret;
} /* pcmcia_request_exclusive_irq */
EXPORT_SYMBOL(__pcmcia_request_exclusive_irq);
c->state |= CONFIG_IRQ_REQ;
p_dev->_irq = 1;
#ifdef CONFIG_PCMCIA_PROBE #ifdef CONFIG_PCMCIA_PROBE
pcmcia_used_irq[irq]++;
#endif
ret = 0; /* mask of IRQs already reserved by other cards, we should avoid using them */
out: static u8 pcmcia_used_irq[NR_IRQS];
mutex_unlock(&s->ops_mutex);
static irqreturn_t test_action(int cpl, void *dev_id)
{
return IRQ_NONE;
}
/**
* pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used
* @p_dev - the associated PCMCIA device
*
* locking note: must be called with ops_mutex locked.
*/
static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
{
struct pcmcia_socket *s = p_dev->socket;
unsigned int try, irq;
u32 mask = s->irq_mask;
int ret = -ENODEV;
for (try = 0; try < 64; try++) {
irq = try % 32;
/* marked as available by driver, not blocked by userspace? */
if (!((mask >> irq) & 1))
continue;
/* avoid an IRQ which is already used by another PCMCIA card */
if ((try < 32) && pcmcia_used_irq[irq])
continue;
/* register the correct driver, if possible, to check whether
* registering a dummy handle works, i.e. if the IRQ isn't
* marked as used by the kernel resource management core */
ret = request_irq(irq, test_action, type, p_dev->devname,
p_dev);
if (!ret) {
free_irq(irq, p_dev);
p_dev->irq = s->pcmcia_irq = irq;
pcmcia_used_irq[irq]++;
break;
}
}
return ret; return ret;
} /* pcmcia_request_irq */ }
EXPORT_SYMBOL(pcmcia_request_irq);
void pcmcia_cleanup_irq(struct pcmcia_socket *s)
{
pcmcia_used_irq[s->pcmcia_irq]--;
s->pcmcia_irq = 0;
}
#else /* CONFIG_PCMCIA_PROBE */
static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
{
return -EINVAL;
}
void pcmcia_cleanup_irq(struct pcmcia_socket *s)
{
s->pcmcia_irq = 0;
return;
}
#endif /* CONFIG_PCMCIA_PROBE */
/**
* pcmcia_setup_irq() - determine IRQ to be used for device
* @p_dev - the associated PCMCIA device
*
* locking note: must be called with ops_mutex locked.
*/
int pcmcia_setup_irq(struct pcmcia_device *p_dev)
{
struct pcmcia_socket *s = p_dev->socket;
if (p_dev->irq)
return 0;
/* already assigned? */
if (s->pcmcia_irq) {
p_dev->irq = s->pcmcia_irq;
return 0;
}
/* prefer an exclusive ISA irq */
if (!pcmcia_setup_isa_irq(p_dev, 0))
return 0;
/* but accept a shared ISA irq */
if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED))
return 0;
/* but use the PCI irq otherwise */
if (s->pci_irq) {
p_dev->irq = s->pcmcia_irq = s->pci_irq;
return 0;
}
return -EINVAL;
}
/** pcmcia_request_window /** pcmcia_request_window
@ -939,237 +857,9 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev)
{ {
pcmcia_release_configuration(p_dev); pcmcia_release_configuration(p_dev);
pcmcia_release_io(p_dev, &p_dev->io); pcmcia_release_io(p_dev, &p_dev->io);
pcmcia_release_irq(p_dev, &p_dev->irq); if (p_dev->_irq)
free_irq(p_dev->irq, p_dev->priv);
if (p_dev->win) if (p_dev->win)
pcmcia_release_window(p_dev, p_dev->win); pcmcia_release_window(p_dev, p_dev->win);
} }
EXPORT_SYMBOL(pcmcia_disable_device); EXPORT_SYMBOL(pcmcia_disable_device);
struct pcmcia_cfg_mem {
struct pcmcia_device *p_dev;
void *priv_data;
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data);
cisparse_t parse;
cistpl_cftable_entry_t dflt;
};
/**
* pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
*
* pcmcia_do_loop_config() is the internal callback for the call from
* pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
* by a struct pcmcia_cfg_mem.
*/
static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
{
cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
struct pcmcia_cfg_mem *cfg_mem = priv;
/* default values */
cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
cfg_mem->dflt = *cfg;
return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
cfg_mem->p_dev->socket->socket.Vcc,
cfg_mem->priv_data);
}
/**
* pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option.
* It gets passed the struct pcmcia_device, the CIS data
* describing the configuration option, and private data
* being passed to pcmcia_loop_config()
* @priv_data: private data to be passed to the conf_check function.
*
* pcmcia_loop_config() loops over all configuration options, and calls
* the driver-specific conf_check() for each one, checking whether
* it is a valid one. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data),
void *priv_data)
{
struct pcmcia_cfg_mem *cfg_mem;
int ret;
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
if (cfg_mem == NULL)
return -ENOMEM;
cfg_mem->p_dev = p_dev;
cfg_mem->conf_check = conf_check;
cfg_mem->priv_data = priv_data;
ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
cfg_mem, pcmcia_do_loop_config);
kfree(cfg_mem);
return ret;
}
EXPORT_SYMBOL(pcmcia_loop_config);
struct pcmcia_loop_mem {
struct pcmcia_device *p_dev;
void *priv_data;
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data);
};
/**
* pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
*
* pcmcia_do_loop_tuple() is the internal callback for the call from
* pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
* by a struct pcmcia_cfg_mem.
*/
static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
{
struct pcmcia_loop_mem *loop = priv;
return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
};
/**
* pcmcia_loop_tuple() - loop over tuples in the CIS
* @p_dev: the struct pcmcia_device which we need to loop for.
* @code: which CIS code shall we look for?
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple and @priv_data.
*
* pcmcia_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data),
void *priv_data)
{
struct pcmcia_loop_mem loop = {
.p_dev = p_dev,
.loop_tuple = loop_tuple,
.priv_data = priv_data};
return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
&loop, pcmcia_do_loop_tuple);
}
EXPORT_SYMBOL(pcmcia_loop_tuple);
struct pcmcia_loop_get {
size_t len;
cisdata_t **buf;
};
/**
* pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
*
* pcmcia_do_get_tuple() is the internal callback for the call from
* pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
* the first tuple, return 0 unconditionally. Create a memory buffer large
* enough to hold the content of the tuple, and fill it with the tuple data.
* The caller is responsible to free the buffer.
*/
static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
void *priv)
{
struct pcmcia_loop_get *get = priv;
*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
if (*get->buf) {
get->len = tuple->TupleDataLen;
memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
} else
dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
return 0;
}
/**
* pcmcia_get_tuple() - get first tuple from CIS
* @p_dev: the struct pcmcia_device which we need to loop for.
* @code: which CIS code shall we look for?
* @buf: pointer to store the buffer to.
*
* pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
* It returns the buffer length (or zero). The caller is responsible to free
* the buffer passed in @buf.
*/
size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
unsigned char **buf)
{
struct pcmcia_loop_get get = {
.len = 0,
.buf = buf,
};
*get.buf = NULL;
pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
return get.len;
}
EXPORT_SYMBOL(pcmcia_get_tuple);
/**
* pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
*
* pcmcia_do_get_mac() is the internal callback for the call from
* pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
* tuple contains a proper LAN_NODE_ID of length 6, and copy the data
* to struct net_device->dev_addr[i].
*/
static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
void *priv)
{
struct net_device *dev = priv;
int i;
if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
return -EINVAL;
if (tuple->TupleDataLen < ETH_ALEN + 2) {
dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
"LAN_NODE_ID\n");
return -EINVAL;
}
if (tuple->TupleData[1] != ETH_ALEN) {
dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
return -EINVAL;
}
for (i = 0; i < 6; i++)
dev->dev_addr[i] = tuple->TupleData[i+2];
return 0;
}
/**
* pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
* @p_dev: the struct pcmcia_device for which we want the address.
* @dev: a properly prepared struct net_device to store the info to.
*
* pcmcia_get_mac_from_cis() reads out the hardware MAC address from
* CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
* must be set up properly by the driver (see examples!).
*/
int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
{
return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
}
EXPORT_SYMBOL(pcmcia_get_mac_from_cis);

172
drivers/pcmcia/rsrc_iodyn.c Normal file
View File

@ -0,0 +1,172 @@
/*
* rsrc_iodyn.c -- Resource management routines for MEM-static sockets.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
struct pcmcia_align_data {
unsigned long mask;
unsigned long offset;
};
static resource_size_t pcmcia_align(void *align_data,
const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pcmcia_align_data *data = align_data;
resource_size_t start;
start = (res->start & ~data->mask) + data->offset;
if (start < res->start)
start += data->mask + 1;
#ifdef CONFIG_X86
if (res->flags & IORESOURCE_IO) {
if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
}
#endif
#ifdef CONFIG_M68K
if (res->flags & IORESOURCE_IO) {
if ((res->start + size - 1) >= 1024)
start = res->end;
}
#endif
return start;
}
static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s,
unsigned long base, int num,
unsigned long align)
{
struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
data.mask = align - 1;
data.offset = base & data.mask;
#ifdef CONFIG_PCI
if (s->cb_dev) {
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
min, 0, pcmcia_align, &data);
} else
#endif
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
1, pcmcia_align, &data);
if (ret != 0) {
kfree(res);
res = NULL;
}
return res;
}
static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
{
int i, ret = 0;
/* Check for an already-allocated window that must conflict with
* what was asked for. It is a hack because it does not catch all
* potential conflicts, just the most obvious ones.
*/
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
if (!*base)
continue;
if ((s->io[i].res->start & (align-1)) == *base)
return -EBUSY;
}
for (i = 0; i < MAX_IO_WIN; i++) {
struct resource *res = s->io[i].res;
unsigned int try;
if (res && (res->flags & IORESOURCE_BITS) !=
(attr & IORESOURCE_BITS))
continue;
if (!res) {
if (align == 0)
align = 0x10000;
res = s->io[i].res = __iodyn_find_io_region(s, *base,
num, align);
if (!res)
return -EINVAL;
*base = res->start;
s->io[i].res->flags =
((res->flags & ~IORESOURCE_BITS) |
(attr & IORESOURCE_BITS));
s->io[i].InUse = num;
return 0;
}
/* Try to extend top of window */
try = res->end + 1;
if ((*base == 0) || (*base == try)) {
if (adjust_resource(s->io[i].res, res->start,
res->end - res->start + num + 1))
continue;
*base = try;
s->io[i].InUse += num;
return 0;
}
/* Try to extend bottom of window */
try = res->start - num;
if ((*base == 0) || (*base == try)) {
if (adjust_resource(s->io[i].res,
res->start - num,
res->end - res->start + num + 1))
continue;
*base = try;
s->io[i].InUse += num;
return 0;
}
}
return -EINVAL;
}
struct pccard_resource_ops pccard_iodyn_ops = {
.validate_mem = NULL,
.find_io = iodyn_find_io,
.find_mem = NULL,
.add_io = NULL,
.add_mem = NULL,
.init = static_init,
.exit = NULL,
};
EXPORT_SYMBOL(pccard_iodyn_ops);

View File

@ -22,7 +22,7 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"
static int static_init(struct pcmcia_socket *s) int static_init(struct pcmcia_socket *s)
{ {
/* the good thing about SS_CAP_STATIC_MAP sockets is /* the good thing about SS_CAP_STATIC_MAP sockets is
* that they don't need a resource database */ * that they don't need a resource database */
@ -32,11 +32,35 @@ static int static_init(struct pcmcia_socket *s)
return 0; return 0;
} }
struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
int flags, const char *name)
{
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
res->name = name;
res->start = start;
res->end = start + end - 1;
res->flags = flags;
}
return res;
}
static int static_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
{
if (!s->io_offset)
return -EINVAL;
*base = s->io_offset | (*base & 0x0fff);
return 0;
}
struct pccard_resource_ops pccard_static_ops = { struct pccard_resource_ops pccard_static_ops = {
.validate_mem = NULL, .validate_mem = NULL,
.adjust_io_region = NULL, .find_io = static_find_io,
.find_io = NULL,
.find_mem = NULL, .find_mem = NULL,
.add_io = NULL, .add_io = NULL,
.add_mem = NULL, .add_mem = NULL,
@ -46,104 +70,6 @@ struct pccard_resource_ops pccard_static_ops = {
EXPORT_SYMBOL(pccard_static_ops); EXPORT_SYMBOL(pccard_static_ops);
#ifdef CONFIG_PCCARD_IODYN MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
MODULE_LICENSE("GPL");
static struct resource * MODULE_ALIAS("rsrc_nonstatic");
make_resource(unsigned long b, unsigned long n, int flags, char *name)
{
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
res->name = name;
res->start = b;
res->end = b + n - 1;
res->flags = flags;
}
return res;
}
struct pcmcia_align_data {
unsigned long mask;
unsigned long offset;
};
static resource_size_t pcmcia_align(void *align_data,
const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pcmcia_align_data *data = align_data;
resource_size_t start;
start = (res->start & ~data->mask) + data->offset;
if (start < res->start)
start += data->mask + 1;
#ifdef CONFIG_X86
if (res->flags & IORESOURCE_IO) {
if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
}
#endif
#ifdef CONFIG_M68K
if (res->flags & IORESOURCE_IO) {
if ((res->start + size - 1) >= 1024)
start = res->end;
}
#endif
return start;
}
static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
unsigned long r_end, struct pcmcia_socket *s)
{
return adjust_resource(res, r_start, r_end - r_start + 1);
}
static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
if (align == 0)
align = 0x10000;
data.mask = align - 1;
data.offset = base & data.mask;
#ifdef CONFIG_PCI
if (s->cb_dev) {
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
min, 0, pcmcia_align, &data);
} else
#endif
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
1, pcmcia_align, &data);
if (ret != 0) {
kfree(res);
res = NULL;
}
return res;
}
struct pccard_resource_ops pccard_iodyn_ops = {
.validate_mem = NULL,
.adjust_io_region = iodyn_adjust_io_region,
.find_io = iodyn_find_io_region,
.find_mem = NULL,
.add_io = NULL,
.add_mem = NULL,
.init = static_init,
.exit = NULL,
};
EXPORT_SYMBOL(pccard_iodyn_ops);
#endif /* CONFIG_PCCARD_IODYN */

View File

@ -34,8 +34,10 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"
/* moved to rsrc_mgr.c
MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
*/
/* Parameters that can be set with 'insmod' */ /* Parameters that can be set with 'insmod' */
@ -69,20 +71,6 @@ struct socket_data {
======================================================================*/ ======================================================================*/
static struct resource *
make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
{
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
res->name = name;
res->start = b;
res->end = b + n - 1;
res->flags = flags;
}
return res;
}
static struct resource * static struct resource *
claim_region(struct pcmcia_socket *s, resource_size_t base, claim_region(struct pcmcia_socket *s, resource_size_t base,
resource_size_t size, int type, char *name) resource_size_t size, int type, char *name)
@ -90,7 +78,7 @@ claim_region(struct pcmcia_socket *s, resource_size_t base,
struct resource *res, *parent; struct resource *res, *parent;
parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
res = make_resource(base, size, type | IORESOURCE_BUSY, name); res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
if (res) { if (res) {
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
@ -661,8 +649,9 @@ pcmcia_align(void *align_data, const struct resource *res,
* Adjust an existing IO region allocation, but making sure that we don't * Adjust an existing IO region allocation, but making sure that we don't
* encroach outside the resources which the user supplied. * encroach outside the resources which the user supplied.
*/ */
static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start, static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
unsigned long r_end, struct pcmcia_socket *s) unsigned long r_start,
unsigned long r_end)
{ {
struct resource_map *m; struct resource_map *m;
struct socket_data *s_data = s->resource_data; struct socket_data *s_data = s->resource_data;
@ -675,8 +664,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
if (start > r_start || r_end > end) if (start > r_start || r_end > end)
continue; continue;
ret = adjust_resource(res, r_start, r_end - r_start + 1); ret = 0;
break;
} }
return ret; return ret;
@ -695,18 +683,17 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
======================================================================*/ ======================================================================*/
static struct resource *nonstatic_find_io_region(unsigned long base, int num, static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
unsigned long align, struct pcmcia_socket *s) unsigned long base, int num,
unsigned long align)
{ {
struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
dev_name(&s->dev));
struct socket_data *s_data = s->resource_data; struct socket_data *s_data = s->resource_data;
struct pcmcia_align_data data; struct pcmcia_align_data data;
unsigned long min = base; unsigned long min = base;
int ret; int ret;
if (align == 0)
align = 0x10000;
data.mask = align - 1; data.mask = align - 1;
data.offset = base & data.mask; data.offset = base & data.mask;
data.map = &s_data->io_db; data.map = &s_data->io_db;
@ -727,10 +714,97 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
return res; return res;
} }
static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
{
int i, ret = 0;
/* Check for an already-allocated window that must conflict with
* what was asked for. It is a hack because it does not catch all
* potential conflicts, just the most obvious ones.
*/
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
if (!*base)
continue;
if ((s->io[i].res->start & (align-1)) == *base)
return -EBUSY;
}
for (i = 0; i < MAX_IO_WIN; i++) {
struct resource *res = s->io[i].res;
unsigned int try;
if (res && (res->flags & IORESOURCE_BITS) !=
(attr & IORESOURCE_BITS))
continue;
if (!res) {
if (align == 0)
align = 0x10000;
res = s->io[i].res = __nonstatic_find_io_region(s,
*base, num,
align);
if (!res)
return -EINVAL;
*base = res->start;
s->io[i].res->flags =
((res->flags & ~IORESOURCE_BITS) |
(attr & IORESOURCE_BITS));
s->io[i].InUse = num;
return 0;
}
/* Try to extend top of window */
try = res->end + 1;
if ((*base == 0) || (*base == try)) {
ret = __nonstatic_adjust_io_region(s, res->start,
res->end + num);
if (!ret) {
ret = adjust_resource(s->io[i].res, res->start,
res->end - res->start + num + 1);
if (ret)
continue;
*base = try;
s->io[i].InUse += num;
return 0;
}
}
/* Try to extend bottom of window */
try = res->start - num;
if ((*base == 0) || (*base == try)) {
ret = __nonstatic_adjust_io_region(s,
res->start - num,
res->end);
if (!ret) {
ret = adjust_resource(s->io[i].res,
res->start - num,
res->end - res->start + num + 1);
if (ret)
continue;
*base = try;
s->io[i].InUse += num;
return 0;
}
}
}
return -EINVAL;
}
static struct resource *nonstatic_find_mem_region(u_long base, u_long num, static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
u_long align, int low, struct pcmcia_socket *s) u_long align, int low, struct pcmcia_socket *s)
{ {
struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
dev_name(&s->dev));
struct socket_data *s_data = s->resource_data; struct socket_data *s_data = s->resource_data;
struct pcmcia_align_data data; struct pcmcia_align_data data;
unsigned long min, max; unsigned long min, max;
@ -861,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
return -ENODEV; return -ENODEV;
#if defined(CONFIG_X86) #if defined(CONFIG_X86)
/* If this is the root bus, the risk of hitting /* If this is the root bus, the risk of hitting some strange
* some strange system devices which aren't protected * system devices is too high: If a driver isn't loaded, the
* by either ACPI resource tables or properly requested * resources are not claimed; even if a driver is loaded, it
* resources is too big. Therefore, don't do auto-adding * may not request all resources or even the wrong one. We
* of resources at the moment. * can neither trust the rest of the kernel nor ACPI/PNP and
* CRS parsing to get it right. Therefore, use several
* safeguards:
*
* - Do not auto-add resources if the CardBus bridge is on
* the PCI root bus
*
* - Avoid any I/O ports < 0x100.
*
* - On PCI-PCI bridges, only use resources which are set up
* exclusively for the secondary PCI bus: the risk of hitting
* system devices is quite low, as they usually aren't
* connected to the secondary PCI bus.
*/ */
if (s->cb_dev->bus->number == 0) if (s->cb_dev->bus->number == 0)
return -EINVAL; return -EINVAL;
#endif
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
res = s->cb_dev->bus->resource[i];
#else
pci_bus_for_each_resource(s->cb_dev->bus, res, i) { pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
#endif
if (!res) if (!res)
continue; continue;
if (res->flags & IORESOURCE_IO) { if (res->flags & IORESOURCE_IO) {
/* safeguard against the root resource, where the
* risk of hitting any other device would be too
* high */
if (res == &ioport_resource) if (res == &ioport_resource)
continue; continue;
dev_printk(KERN_INFO, &s->cb_dev->dev, dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge window: %pR\n", "pcmcia: parent PCI bridge window: %pR\n",
res); res);
@ -887,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
} }
if (res->flags & IORESOURCE_MEM) { if (res->flags & IORESOURCE_MEM) {
/* safeguard against the root resource, where the
* risk of hitting any other device would be too
* high */
if (res == &iomem_resource) if (res == &iomem_resource)
continue; continue;
dev_printk(KERN_INFO, &s->cb_dev->dev, dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge window: %pR\n", "pcmcia: parent PCI bridge window: %pR\n",
res); res);
@ -956,8 +1053,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
struct pccard_resource_ops pccard_nonstatic_ops = { struct pccard_resource_ops pccard_nonstatic_ops = {
.validate_mem = pcmcia_nonstatic_validate_mem, .validate_mem = pcmcia_nonstatic_validate_mem,
.adjust_io_region = nonstatic_adjust_io_region, .find_io = nonstatic_find_io,
.find_io = nonstatic_find_io_region,
.find_mem = nonstatic_find_mem_region, .find_mem = nonstatic_find_mem_region,
.add_io = adjust_io, .add_io = adjust_io,
.add_mem = adjust_memory, .add_mem = adjust_memory,

View File

@ -1303,13 +1303,6 @@ static int yenta_dev_suspend_noirq(struct device *dev)
pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]);
pci_disable_device(pdev); pci_disable_device(pdev);
/*
* Some laptops (IBM T22) do not like us putting the Cardbus
* bridge into D3. At a guess, some other laptop will
* probably require this, so leave it commented out for now.
*/
/* pci_set_power_state(dev, 3); */
return 0; return 0;
} }

View File

@ -80,7 +80,6 @@ MODULE_LICENSE("Dual MPL/GPL");
typedef struct scsi_info_t { typedef struct scsi_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct Scsi_Host *host; struct Scsi_Host *host;
} scsi_info_t; } scsi_info_t;
@ -105,7 +104,6 @@ static int aha152x_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 0x20; link->io.NumPorts1 = 0x20;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
@ -160,8 +158,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
@ -172,7 +169,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
memset(&s, 0, sizeof(s)); memset(&s, 0, sizeof(s));
s.conf = "PCMCIA setup"; s.conf = "PCMCIA setup";
s.io_port = link->io.BasePort1; s.io_port = link->io.BasePort1;
s.irq = link->irq.AssignedIRQ; s.irq = link->irq;
s.scsiid = host_id; s.scsiid = host_id;
s.reconnect = reconnect; s.reconnect = reconnect;
s.parity = parity; s.parity = parity;
@ -187,8 +184,6 @@ static int aha152x_config_cs(struct pcmcia_device *link)
goto failed; goto failed;
} }
sprintf(info->node.dev_name, "scsi%d", host->host_no);
link->dev_node = &info->node;
info->host = host; info->host = host;
return 0; return 0;

View File

@ -63,7 +63,6 @@ MODULE_LICENSE("Dual MPL/GPL");
typedef struct scsi_info_t { typedef struct scsi_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct Scsi_Host *host; struct Scsi_Host *host;
} scsi_info_t; } scsi_info_t;
@ -88,7 +87,6 @@ static int fdomain_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 0x10; link->io.NumPorts1 = 0x10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
@ -133,8 +131,7 @@ static int fdomain_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
@ -144,7 +141,7 @@ static int fdomain_config(struct pcmcia_device *link)
release_region(link->io.BasePort1, link->io.NumPorts1); release_region(link->io.BasePort1, link->io.NumPorts1);
/* Set configuration options for the fdomain driver */ /* Set configuration options for the fdomain driver */
sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); sprintf(str, "%d,%d", link->io.BasePort1, link->irq);
fdomain_setup(str); fdomain_setup(str);
host = __fdomain_16x0_detect(&fdomain_driver_template); host = __fdomain_16x0_detect(&fdomain_driver_template);
@ -157,8 +154,6 @@ static int fdomain_config(struct pcmcia_device *link)
goto failed; goto failed;
scsi_scan_host(host); scsi_scan_host(host);
sprintf(info->node.dev_name, "scsi%d", host->host_no);
link->dev_node = &info->node;
info->host = host; info->host = host;
return 0; return 0;

View File

@ -1563,13 +1563,6 @@ static int nsp_cs_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; /* not used */ link->io.IOAddrLines = 10; /* not used */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
/* Interrupt handler */
link->irq.Handler = &nspintr;
link->irq.Attributes |= IRQF_SHARED;
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -1646,8 +1639,7 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
} }
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -1720,10 +1712,8 @@ static int nsp_cs_config(struct pcmcia_device *link)
if (ret) if (ret)
goto cs_failed; goto cs_failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ) { if (pcmcia_request_irq(link, nspintr))
if (pcmcia_request_irq(link, &link->irq)) goto cs_failed;
goto cs_failed;
}
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
@ -1741,7 +1731,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
/* Set port and IRQ */ /* Set port and IRQ */
data->BaseAddress = link->io.BasePort1; data->BaseAddress = link->io.BasePort1;
data->NumAddress = link->io.NumPorts1; data->NumAddress = link->io.NumPorts1;
data->IrqNumber = link->irq.AssignedIRQ; data->IrqNumber = link->irq;
nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
data->BaseAddress, data->NumAddress, data->IrqNumber); data->BaseAddress, data->NumAddress, data->IrqNumber);
@ -1764,8 +1754,6 @@ static int nsp_cs_config(struct pcmcia_device *link)
scsi_scan_host(host); scsi_scan_host(host);
snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
link->dev_node = &info->node;
info->host = host; info->host = host;
/* Finally, report what we've done */ /* Finally, report what we've done */
@ -1775,7 +1763,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
} }
if (link->conf.Attributes & CONF_ENABLE_IRQ) { if (link->conf.Attributes & CONF_ENABLE_IRQ) {
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
} }
if (link->io.NumPorts1) { if (link->io.NumPorts1) {
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
@ -1823,7 +1811,6 @@ static void nsp_cs_release(struct pcmcia_device *link)
if (info->host != NULL) { if (info->host != NULL) {
scsi_remove_host(info->host); scsi_remove_host(info->host);
} }
link->dev_node = NULL;
if (link->win) { if (link->win) {
if (data != NULL) { if (data != NULL) {

View File

@ -224,7 +224,6 @@
typedef struct scsi_info_t { typedef struct scsi_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
struct Scsi_Host *host; struct Scsi_Host *host;
dev_node_t node;
int stop; int stop;
} scsi_info_t; } scsi_info_t;

View File

@ -82,7 +82,6 @@ static struct scsi_host_template qlogicfas_driver_template = {
typedef struct scsi_info_t { typedef struct scsi_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct Scsi_Host *host; struct Scsi_Host *host;
unsigned short manf_id; unsigned short manf_id;
} scsi_info_t; } scsi_info_t;
@ -161,7 +160,6 @@ static int qlogic_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
@ -209,8 +207,7 @@ static int qlogic_config(struct pcmcia_device * link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
@ -227,18 +224,16 @@ static int qlogic_config(struct pcmcia_device * link)
/* The KXL-810AN has a bigger IO port window */ /* The KXL-810AN has a bigger IO port window */
if (link->io.NumPorts1 == 32) if (link->io.NumPorts1 == 32)
host = qlogic_detect(&qlogicfas_driver_template, link, host = qlogic_detect(&qlogicfas_driver_template, link,
link->io.BasePort1 + 16, link->irq.AssignedIRQ); link->io.BasePort1 + 16, link->irq);
else else
host = qlogic_detect(&qlogicfas_driver_template, link, host = qlogic_detect(&qlogicfas_driver_template, link,
link->io.BasePort1, link->irq.AssignedIRQ); link->io.BasePort1, link->irq);
if (!host) { if (!host) {
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
goto failed; goto failed;
} }
sprintf(info->node.dev_name, "scsi%d", host->host_no);
link->dev_node = &info->node;
info->host = host; info->host = host;
return 0; return 0;
@ -258,7 +253,7 @@ static void qlogic_release(struct pcmcia_device *link)
scsi_remove_host(info->host); scsi_remove_host(info->host);
free_irq(link->irq.AssignedIRQ, info->host); free_irq(link->irq, info->host);
pcmcia_disable_device(link); pcmcia_disable_device(link);
scsi_host_put(info->host); scsi_host_put(info->host);

View File

@ -191,7 +191,6 @@
struct scsi_info_t { struct scsi_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
struct Scsi_Host *host; struct Scsi_Host *host;
unsigned short manf_id; unsigned short manf_id;
}; };
@ -719,8 +718,7 @@ SYM53C500_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
@ -752,7 +750,7 @@ SYM53C500_config(struct pcmcia_device *link)
* 0x320, 0x330, 0x340, 0x350 * 0x320, 0x330, 0x340, 0x350
*/ */
port_base = link->io.BasePort1; port_base = link->io.BasePort1;
irq_level = link->irq.AssignedIRQ; irq_level = link->irq;
DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n", DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
port_base, irq_level, USE_FAST_PIO);) port_base, irq_level, USE_FAST_PIO);)
@ -793,8 +791,6 @@ SYM53C500_config(struct pcmcia_device *link)
*/ */
data->fast_pio = USE_FAST_PIO; data->fast_pio = USE_FAST_PIO;
sprintf(info->node.dev_name, "scsi%d", host->host_no);
link->dev_node = &info->node;
info->host = host; info->host = host;
if (scsi_add_host(host, NULL)) if (scsi_add_host(host, NULL))
@ -866,7 +862,6 @@ SYM53C500_probe(struct pcmcia_device *link)
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; link->io.IOAddrLines = 10;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;

View File

@ -89,7 +89,6 @@ struct serial_info {
int manfid; int manfid;
int prodid; int prodid;
int c950ctrl; int c950ctrl;
dev_node_t node[4];
int line[4]; int line[4];
const struct serial_quirk *quirk; const struct serial_quirk *quirk;
}; };
@ -289,8 +288,6 @@ static void serial_remove(struct pcmcia_device *link)
for (i = 0; i < info->ndev; i++) for (i = 0; i < info->ndev; i++)
serial8250_unregister_port(info->line[i]); serial8250_unregister_port(info->line[i]);
info->p_dev->dev_node = NULL;
if (!info->slave) if (!info->slave)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} }
@ -343,7 +340,6 @@ static int serial_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
if (do_sound) { if (do_sound) {
link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Attributes |= CONF_ENABLE_SPKR;
@ -411,11 +407,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
} }
info->line[info->ndev] = line; info->line[info->ndev] = line;
sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
info->node[info->ndev].major = TTY_MAJOR;
info->node[info->ndev].minor = 0x40 + line;
if (info->ndev > 0)
info->node[info->ndev - 1].next = &info->node[info->ndev];
info->ndev++; info->ndev++;
return 0; return 0;
@ -486,7 +477,7 @@ static int simple_config(struct pcmcia_device *link)
} }
if (info->slave) { if (info->slave) {
return setup_serial(link, info, port, return setup_serial(link, info, port,
link->irq.AssignedIRQ); link->irq);
} }
} }
@ -507,10 +498,6 @@ static int simple_config(struct pcmcia_device *link)
return -1; return -1;
found_port: found_port:
i = pcmcia_request_irq(link, &link->irq);
if (i != 0)
link->irq.AssignedIRQ = 0;
if (info->multi && (info->manfid == MANFID_3COM)) if (info->multi && (info->manfid == MANFID_3COM))
link->conf.ConfigIndex &= ~(0x08); link->conf.ConfigIndex &= ~(0x08);
@ -523,7 +510,7 @@ static int simple_config(struct pcmcia_device *link)
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_request_configuration(link, &link->conf);
if (i != 0) if (i != 0)
return -1; return -1;
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); return setup_serial(link, info, link->io.BasePort1, link->irq);
} }
static int multi_config_check(struct pcmcia_device *p_dev, static int multi_config_check(struct pcmcia_device *p_dev,
@ -586,13 +573,9 @@ static int multi_config(struct pcmcia_device *link)
} }
} }
i = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (i != 0) { dev_warn(&link->dev,
/* FIXME: comment does not fit, error handling does not fit */ "serial_cs: no usable IRQ found, continuing...\n");
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
link->irq.AssignedIRQ = 0;
}
/* /*
* Apply any configuration quirks. * Apply any configuration quirks.
@ -615,11 +598,11 @@ static int multi_config(struct pcmcia_device *link)
if (link->conf.ConfigIndex == 1 || if (link->conf.ConfigIndex == 1 ||
link->conf.ConfigIndex == 3) { link->conf.ConfigIndex == 3) {
err = setup_serial(link, info, base2, err = setup_serial(link, info, base2,
link->irq.AssignedIRQ); link->irq);
base2 = link->io.BasePort1; base2 = link->io.BasePort1;
} else { } else {
err = setup_serial(link, info, link->io.BasePort1, err = setup_serial(link, info, link->io.BasePort1,
link->irq.AssignedIRQ); link->irq);
} }
info->c950ctrl = base2; info->c950ctrl = base2;
@ -633,10 +616,10 @@ static int multi_config(struct pcmcia_device *link)
return 0; return 0;
} }
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); setup_serial(link, info, link->io.BasePort1, link->irq);
for (i = 0; i < info->multi - 1; i++) for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i), setup_serial(link, info, base2 + (8 * i),
link->irq.AssignedIRQ); link->irq);
return 0; return 0;
} }
@ -720,7 +703,6 @@ static int serial_config(struct pcmcia_device * link)
if (info->quirk->post(link)) if (info->quirk->post(link))
goto failed; goto failed;
link->dev_node = &info->node[0];
return 0; return 0;
failed: failed:

View File

@ -490,7 +490,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
break; break;
case SSB_BUSTYPE_PCMCIA: case SSB_BUSTYPE_PCMCIA:
#ifdef CONFIG_SSB_PCMCIAHOST #ifdef CONFIG_SSB_PCMCIAHOST
sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; sdev->irq = bus->host_pcmcia->irq;
dev->parent = &bus->host_pcmcia->dev; dev->parent = &bus->host_pcmcia->dev;
#endif #endif
break; break;

View File

@ -180,12 +180,12 @@ static int das16cs_attach(struct comedi_device *dev,
} }
printk("\n"); printk("\n");
ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt, ret = request_irq(link->irq, das16cs_interrupt,
IRQF_SHARED, "cb_das16_cs", dev); IRQF_SHARED, "cb_das16_cs", dev);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
printk("irq=%u ", dev->irq); printk("irq=%u ", dev->irq);
dev->board_ptr = das16cs_probe(dev, link); dev->board_ptr = das16cs_probe(dev, link);
@ -671,7 +671,6 @@ static dev_info_t dev_info = "cb_das16_cs";
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
@ -702,10 +701,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
link->priv = local; link->priv = local;
/* Initialize the pcmcia_device structure */ /* Initialize the pcmcia_device structure */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
link->conf.Attributes = 0; link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -720,10 +715,8 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); dev_dbg(&link->dev, "das16cs_pcmcia_detach\n");
if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1;
((struct local_info_t *)link->priv)->stop = 1; das16cs_pcmcia_release(link);
das16cs_pcmcia_release(link);
}
/* This points to the parent struct local_info_t struct */ /* This points to the parent struct local_info_t struct */
if (link->priv) if (link->priv)
kfree(link->priv); kfree(link->priv);
@ -740,8 +733,7 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
return -EINVAL; return -EINVAL;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -769,7 +761,6 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void das16cs_pcmcia_config(struct pcmcia_device *link) static void das16cs_pcmcia_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
int ret; int ret;
dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
@ -780,16 +771,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* if (!link->irq)
Allocate an interrupt line. Note that this does not assign a goto failed;
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the the I/O windows and the interrupt mapping, and putting the
@ -799,19 +783,10 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "cb_das16_cs");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq.AssignedIRQ); printk(", irq %u", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -142,7 +142,6 @@ static const dev_info_t dev_info = "pcm-das08";
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
@ -172,10 +171,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -207,10 +202,8 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "das08_pcmcia_detach\n"); dev_dbg(&link->dev, "das08_pcmcia_detach\n");
if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1;
((struct local_info_t *)link->priv)->stop = 1; das08_pcmcia_release(link);
das08_pcmcia_release(link);
}
/* This points to the parent struct local_info_t struct */ /* This points to the parent struct local_info_t struct */
if (link->priv) if (link->priv)
@ -229,8 +222,7 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
return -ENODEV; return -ENODEV;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -266,7 +258,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void das08_pcmcia_config(struct pcmcia_device *link) static void das08_pcmcia_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
int ret; int ret;
dev_dbg(&link->dev, "das08_pcmcia_config\n"); dev_dbg(&link->dev, "das08_pcmcia_config\n");
@ -277,11 +268,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
if (link->conf.Attributes & CONF_ENABLE_IRQ) { if (!link->irq)
ret = pcmcia_request_irq(link, &link->irq); goto failed;
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -292,19 +280,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "pcm-das08");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq.AssignedIRQ); printk(", irq %u", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -380,7 +380,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -EIO; return -EIO;
iobase = link->io.BasePort1; iobase = link->io.BasePort1;
#ifdef incomplete #ifdef incomplete
irq = link->irq.AssignedIRQ; irq = link->irq;
#endif #endif
break; break;
default: default:
@ -470,7 +470,6 @@ static const dev_info_t dev_info = "ni_daq_700";
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
@ -502,10 +501,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -539,10 +534,8 @@ static void dio700_cs_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "dio700_cs_detach\n"); dev_dbg(&link->dev, "dio700_cs_detach\n");
if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1;
((struct local_info_t *)link->priv)->stop = 1; dio700_release(link);
dio700_release(link);
}
/* This points to the parent struct local_info_t struct */ /* This points to the parent struct local_info_t struct */
if (link->priv) if (link->priv)
@ -577,8 +570,7 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
} }
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -625,7 +617,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void dio700_config(struct pcmcia_device *link) static void dio700_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
win_req_t req; win_req_t req;
int ret; int ret;
@ -639,16 +630,8 @@ static void dio700_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* if (!link->irq)
Allocate an interrupt line. Note that this does not assign a goto failed;
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -659,19 +642,10 @@ static void dio700_config(struct pcmcia_device *link)
if (ret != 0) if (ret != 0)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "ni_daq_700");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -131,7 +131,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -EIO; return -EIO;
iobase = link->io.BasePort1; iobase = link->io.BasePort1;
#ifdef incomplete #ifdef incomplete
irq = link->irq.AssignedIRQ; irq = link->irq;
#endif #endif
break; break;
default: default:
@ -221,7 +221,6 @@ static const dev_info_t dev_info = "ni_daq_dio24";
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
@ -253,10 +252,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -290,10 +285,8 @@ static void dio24_cs_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "dio24_cs_detach\n"); dev_dbg(&link->dev, "dio24_cs_detach\n");
if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1;
((struct local_info_t *)link->priv)->stop = 1; dio24_release(link);
dio24_release(link);
}
/* This points to the parent local_info_t struct */ /* This points to the parent local_info_t struct */
if (link->priv) if (link->priv)
@ -328,8 +321,7 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
} }
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -376,7 +368,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void dio24_config(struct pcmcia_device *link) static void dio24_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
int ret; int ret;
win_req_t req; win_req_t req;
@ -390,16 +381,8 @@ static void dio24_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* if (!link->irq)
Allocate an interrupt line. Note that this does not assign a goto failed;
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -410,19 +393,10 @@ static void dio24_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "ni_daq_dio24");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -144,7 +144,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!link) if (!link)
return -EIO; return -EIO;
iobase = link->io.BasePort1; iobase = link->io.BasePort1;
irq = link->irq.AssignedIRQ; irq = link->irq;
break; break;
default: default:
printk("bug! couldn't determine board type\n"); printk("bug! couldn't determine board type\n");
@ -199,7 +199,6 @@ static const dev_info_t dev_info = "daqcard-1200";
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
@ -229,10 +228,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
link->irq.Handler = NULL;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -269,10 +264,8 @@ static void labpc_cs_detach(struct pcmcia_device *link)
the release() function is called, that will trigger a proper the release() function is called, that will trigger a proper
detach(). detach().
*/ */
if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1;
((struct local_info_t *)link->priv)->stop = 1; labpc_release(link);
labpc_release(link);
}
/* This points to the parent local_info_t struct (may be null) */ /* This points to the parent local_info_t struct (may be null) */
kfree(link->priv); kfree(link->priv);
@ -306,8 +299,7 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
} }
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -355,7 +347,6 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void labpc_config(struct pcmcia_device *link) static void labpc_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
int ret; int ret;
win_req_t req; win_req_t req;
@ -367,16 +358,8 @@ static void labpc_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* if (!link->irq)
Allocate an interrupt line. Note that this does not assign a goto failed;
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -387,19 +370,10 @@ static void labpc_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
sprintf(dev->node.dev_name, "daqcard-1200");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -262,17 +262,11 @@ static void cs_detach(struct pcmcia_device *);
static struct pcmcia_device *cur_dev = NULL; static struct pcmcia_device *cur_dev = NULL;
static const dev_info_t dev_info = "ni_mio_cs"; static const dev_info_t dev_info = "ni_mio_cs";
static dev_node_t dev_node = {
"ni_mio_cs",
COMEDI_MAJOR, 0,
NULL
};
static int cs_attach(struct pcmcia_device *link) static int cs_attach(struct pcmcia_device *link)
{ {
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -292,8 +286,7 @@ static void cs_detach(struct pcmcia_device *link)
{ {
DPRINTK("cs_detach(link=%p)\n", link); DPRINTK("cs_detach(link=%p)\n", link);
if (link->dev_node) cs_release(link);
cs_release(link);
} }
static int mio_cs_suspend(struct pcmcia_device *link) static int mio_cs_suspend(struct pcmcia_device *link)
@ -344,14 +337,10 @@ static void mio_cs_config(struct pcmcia_device *link)
return; return;
} }
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret) { dev_info(&link->dev, "no IRQ available\n");
printk("pcmcia_request_irq() returned error: %i\n", ret);
}
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
link->dev_node = &dev_node;
} }
static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@ -369,7 +358,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->driver = &driver_ni_mio_cs; dev->driver = &driver_ni_mio_cs;
dev->iobase = link->io.BasePort1; dev->iobase = link->io.BasePort1;
irq = link->irq.AssignedIRQ; irq = link->irq;
printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
dev->minor, dev->driver->driver_name, dev->iobase, irq); dev->minor, dev->driver->driver_name, dev->iobase, irq);

View File

@ -60,7 +60,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
dev_node_t node;
int stop; int stop;
int table_index; int table_index;
char board_name[32]; char board_name[32];
@ -1040,10 +1039,6 @@ static int daqp_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = daqp_interrupt;
/* /*
General socket configuration defaults can go here. In this General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost client, we assume very little, and rely on the CIS for almost
@ -1074,10 +1069,8 @@ static void daqp_cs_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "daqp_cs_detach\n"); dev_dbg(&link->dev, "daqp_cs_detach\n");
if (link->dev_node) { dev->stop = 1;
dev->stop = 1; daqp_cs_release(link);
daqp_cs_release(link);
}
/* Unlink device structure, and free it */ /* Unlink device structure, and free it */
dev_table[dev->table_index] = NULL; dev_table[dev->table_index] = NULL;
@ -1105,8 +1098,7 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
return -ENODEV; return -ENODEV;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -1133,7 +1125,6 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
static void daqp_cs_config(struct pcmcia_device *link) static void daqp_cs_config(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv;
int ret; int ret;
dev_dbg(&link->dev, "daqp_cs_config\n"); dev_dbg(&link->dev, "daqp_cs_config\n");
@ -1144,16 +1135,9 @@ static void daqp_cs_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* ret = pcmcia_request_irq(link, daqp_interrupt);
Allocate an interrupt line. Note that this does not assign a if (ret)
handler to the interrupt, unless the 'Handler' member of the goto failed;
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
}
/* /*
This actually configures the PCMCIA socket -- setting up This actually configures the PCMCIA socket -- setting up
@ -1164,23 +1148,10 @@ static void daqp_cs_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
*/
/* Comedi's PCMCIA script uses this device name (extracted
* from /var/lib/pcmcia/stab) to pass to comedi_config
*/
/* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */
sprintf(dev->node.dev_name, "quatech_daqp_cs");
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x", dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ) if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq.AssignedIRQ); printk(", irq %u", link->irq);
if (link->io.NumPorts1) if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

View File

@ -61,7 +61,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/mem_op.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
@ -382,10 +381,6 @@ static int netwave_probe(struct pcmcia_device *link)
link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
link->io.IOAddrLines = 5; link->io.IOAddrLines = 5;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = &netwave_interrupt;
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
@ -732,7 +727,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
* Now allocate an interrupt line. Note that this does not * Now allocate an interrupt line. Note that this does not
* actually assign a handler to the interrupt. * actually assign a handler to the interrupt.
*/ */
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_irq(link, netwave_interrupt);
if (ret) if (ret)
goto failed; goto failed;
@ -767,7 +762,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
ramBase = ioremap(req.Base, 0x8000); ramBase = ioremap(req.Base, 0x8000);
priv->ramBase = ramBase; priv->ramBase = ramBase;
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
SET_NETDEV_DEV(dev, &link->dev); SET_NETDEV_DEV(dev, &link->dev);

View File

@ -3850,12 +3850,8 @@ wv_pcmcia_config(struct pcmcia_device * link)
if (i != 0) if (i != 0)
break; break;
/* i = pcmcia_request_interrupt(link, wavelan_interrupt);
* Now allocate an interrupt line. Note that this does not if (!i)
* actually assign a handler to the interrupt.
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != 0)
break; break;
/* /*
@ -3890,7 +3886,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
break; break;
/* Feed device with this info... */ /* Feed device with this info... */
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
netif_start_queue(dev); netif_start_queue(dev);
@ -4437,10 +4433,6 @@ wavelan_probe(struct pcmcia_device *p_dev)
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = 3; p_dev->io.IOAddrLines = 3;
/* Interrupt setup */
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.Handler = wavelan_interrupt;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->conf.IntType = INT_MEMORY_AND_IO;
@ -4487,7 +4479,6 @@ wavelan_probe(struct pcmcia_device *p_dev)
ret = wv_hw_config(dev); ret = wv_hw_config(dev);
if (ret) { if (ret) {
dev->irq = 0;
pcmcia_disable_device(p_dev); pcmcia_disable_device(p_dev);
return ret; return ret;
} }

View File

@ -156,15 +156,12 @@ static int wl_adapter_attach(struct pcmcia_device *link)
link->io.NumPorts1 = HCF_NUM_IO_PORTS; link->io.NumPorts1 = HCF_NUM_IO_PORTS;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->io.IOAddrLines = 6; link->io.IOAddrLines = 6;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
link->irq.Handler = &wl_isr;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 5; link->conf.ConfigIndex = 5;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
link->priv = link->irq.Instance = dev; link->priv = dev;
lp = wl_priv(dev); lp = wl_priv(dev);
lp->link = link; lp->link = link;
@ -318,11 +315,11 @@ void wl_adapter_insert( struct pcmcia_device *link )
link->conf.Attributes |= CONF_ENABLE_IRQ; link->conf.Attributes |= CONF_ENABLE_IRQ;
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, wl_isr));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
SET_NETDEV_DEV(dev, &handle_to_dev(link)); SET_NETDEV_DEV(dev, &handle_to_dev(link));

View File

@ -22,7 +22,6 @@
typedef struct ixj_info_t { typedef struct ixj_info_t {
int ndev; int ndev;
dev_node_t node;
struct ixj *port; struct ixj *port;
} ixj_info_t; } ixj_info_t;
@ -155,8 +154,6 @@ static int ixj_config(struct pcmcia_device * link)
j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10); j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
info->ndev = 1; info->ndev = 1;
info->node.major = PHONE_MAJOR;
link->dev_node = &info->node;
ixj_get_serial(link, j); ixj_get_serial(link, j);
return 0; return 0;

View File

@ -47,7 +47,6 @@ static const char driver_name[DEV_NAME_LEN] = "sl811_cs";
typedef struct local_info_t { typedef struct local_info_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
} local_info_t; } local_info_t;
static void sl811_cs_release(struct pcmcia_device * link); static void sl811_cs_release(struct pcmcia_device * link);
@ -163,8 +162,7 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
/* we need an interrupt */ /* we need an interrupt */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */ /* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
@ -186,7 +184,6 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
static int sl811_cs_config(struct pcmcia_device *link) static int sl811_cs_config(struct pcmcia_device *link)
{ {
struct device *parent = &link->dev; struct device *parent = &link->dev;
local_info_t *dev = link->priv;
int ret; int ret;
dev_dbg(&link->dev, "sl811_cs_config\n"); dev_dbg(&link->dev, "sl811_cs_config\n");
@ -197,31 +194,24 @@ static int sl811_cs_config(struct pcmcia_device *link)
/* require an IRQ and two registers */ /* require an IRQ and two registers */
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
goto failed; goto failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
ret = pcmcia_request_irq(link, &link->irq); if (!link->irq)
if (ret)
goto failed;
} else
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
sprintf(dev->node.dev_name, driver_name); dev_info(&link->dev, "index 0x%02x: ",
dev->node.major = dev->node.minor = 0; link->conf.ConfigIndex);
link->dev_node = &dev->node;
printk(KERN_INFO "%s: index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Vpp) if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
printk(", irq %d", link->irq.AssignedIRQ); printk(", irq %d", link->irq);
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
printk("\n"); printk("\n");
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) if (sl811_hc_init(parent, link->io.BasePort1, link->irq)
< 0) { < 0) {
failed: failed:
printk(KERN_WARNING "sl811_cs_config failed\n"); printk(KERN_WARNING "sl811_cs_config failed\n");
@ -241,10 +231,6 @@ static int sl811_cs_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
/* Initialize */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = NULL;
link->conf.Attributes = 0; link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;

View File

@ -85,6 +85,7 @@ typedef struct config_req_t {
#define CONF_ENABLE_IRQ 0x01 #define CONF_ENABLE_IRQ 0x01
#define CONF_ENABLE_DMA 0x02 #define CONF_ENABLE_DMA 0x02
#define CONF_ENABLE_SPKR 0x04 #define CONF_ENABLE_SPKR 0x04
#define CONF_ENABLE_PULSE_IRQ 0x08
#define CONF_VALID_CLIENT 0x100 #define CONF_VALID_CLIENT 0x100
/* IntType field */ /* IntType field */
@ -113,25 +114,7 @@ typedef struct io_req_t {
#define IO_DATA_PATH_WIDTH_16 0x08 #define IO_DATA_PATH_WIDTH_16 0x08
#define IO_DATA_PATH_WIDTH_AUTO 0x10 #define IO_DATA_PATH_WIDTH_AUTO 0x10
/* For RequestIRQ and ReleaseIRQ */
typedef struct irq_req_t {
u_int Attributes;
u_int AssignedIRQ;
irq_handler_t Handler;
} irq_req_t;
/* Attributes for RequestIRQ and ReleaseIRQ */
#define IRQ_TYPE 0x03
#define IRQ_TYPE_EXCLUSIVE 0x00
#define IRQ_TYPE_TIME 0x01
#define IRQ_TYPE_DYNAMIC_SHARING 0x02
#define IRQ_FORCED_PULSE 0x04
#define IRQ_FIRST_SHARED 0x08 /* unused */
#define IRQ_HANDLE_PRESENT 0x10 /* unused */
#define IRQ_PULSE_ALLOCATED 0x100
/* Bits in IRQInfo1 field */ /* Bits in IRQInfo1 field */
#define IRQ_MASK 0x0f
#define IRQ_NMI_ID 0x01 #define IRQ_NMI_ID 0x01
#define IRQ_IOCK_ID 0x02 #define IRQ_IOCK_ID 0x02
#define IRQ_BERR_ID 0x04 #define IRQ_BERR_ID 0x04

View File

@ -62,15 +62,6 @@ struct pcmcia_driver {
int pcmcia_register_driver(struct pcmcia_driver *driver); int pcmcia_register_driver(struct pcmcia_driver *driver);
void pcmcia_unregister_driver(struct pcmcia_driver *driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver);
/* Some drivers use dev_node_t to store char or block device information.
* Don't use this in new drivers, though.
*/
typedef struct dev_node_t {
char dev_name[DEV_NAME_LEN];
u_short major, minor;
struct dev_node_t *next;
} dev_node_t;
struct pcmcia_device { struct pcmcia_device {
/* the socket and the device_no [for multifunction devices] /* the socket and the device_no [for multifunction devices]
uniquely define a pcmcia_device */ uniquely define a pcmcia_device */
@ -88,13 +79,14 @@ struct pcmcia_device {
struct list_head socket_device_list; struct list_head socket_device_list;
/* deprecated, will be cleaned up soon */ /* deprecated, will be cleaned up soon */
dev_node_t *dev_node;
u_int open; u_int open;
io_req_t io; io_req_t io;
irq_req_t irq;
config_req_t conf; config_req_t conf;
window_handle_t win; window_handle_t win;
/* device setup */
unsigned int irq;
/* Is the device suspended? */ /* Is the device suspended? */
u16 suspended:1; u16 suspended:1;
@ -191,7 +183,20 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
/* device configuration */ /* device configuration */
int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
int __must_check
__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
irq_handler_t handler);
static inline __must_check __deprecated int
pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
irq_handler_t handler)
{
return __pcmcia_request_exclusive_irq(p_dev, handler);
}
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
irq_handler_t handler);
int pcmcia_request_configuration(struct pcmcia_device *p_dev, int pcmcia_request_configuration(struct pcmcia_device *p_dev,
config_req_t *req); config_req_t *req);

View File

@ -1,116 +0,0 @@
/*
* mem_op.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
*/
#ifndef _LINUX_MEM_OP_H
#define _LINUX_MEM_OP_H
#include <linux/io.h>
#include <asm/uaccess.h>
/*
If UNSAFE_MEMCPY is defined, we use the (optimized) system routines
to copy between a card and kernel memory. These routines do 32-bit
operations which may not work with all PCMCIA controllers. The
safe versions defined here will do only 8-bit and 16-bit accesses.
*/
#ifdef UNSAFE_MEMCPY
#define copy_from_pc memcpy_fromio
#define copy_to_pc memcpy_toio
static inline void copy_pc_to_user(void *to, const void *from, size_t n)
{
size_t odd = (n & 3);
n -= odd;
while (n) {
put_user(__raw_readl(from), (int *)to);
(char *)from += 4; (char *)to += 4; n -= 4;
}
while (odd--)
put_user(readb((char *)from++), (char *)to++);
}
static inline void copy_user_to_pc(void *to, const void *from, size_t n)
{
int l;
char c;
size_t odd = (n & 3);
n -= odd;
while (n) {
get_user(l, (int *)from);
__raw_writel(l, to);
(char *)to += 4; (char *)from += 4; n -= 4;
}
while (odd--) {
get_user(c, (char *)from++);
writeb(c, (char *)to++);
}
}
#else /* UNSAFE_MEMCPY */
static inline void copy_from_pc(void *to, void __iomem *from, size_t n)
{
__u16 *t = to;
__u16 __iomem *f = from;
size_t odd = (n & 1);
for (n >>= 1; n; n--)
*t++ = __raw_readw(f++);
if (odd)
*(__u8 *)t = readb(f);
}
static inline void copy_to_pc(void __iomem *to, const void *from, size_t n)
{
__u16 __iomem *t = to;
const __u16 *f = from;
size_t odd = (n & 1);
for (n >>= 1; n ; n--)
__raw_writew(*f++, t++);
if (odd)
writeb(*(__u8 *)f, t);
}
static inline void copy_pc_to_user(void __user *to, void __iomem *from, size_t n)
{
__u16 __user *t = to;
__u16 __iomem *f = from;
size_t odd = (n & 1);
for (n >>= 1; n ; n--)
put_user(__raw_readw(f++), t++);
if (odd)
put_user(readb(f), (char __user *)t);
}
static inline void copy_user_to_pc(void __iomem *to, void __user *from, size_t n)
{
__u16 __user *f = from;
__u16 __iomem *t = to;
short s;
char c;
size_t odd = (n & 1);
for (n >>= 1; n; n--) {
get_user(s, f++);
__raw_writew(s, t++);
}
if (odd) {
get_user(c, (char __user *)f);
writeb(c, t);
}
}
#endif /* UNSAFE_MEMCPY */
#endif /* _LINUX_MEM_OP_H */

View File

@ -141,10 +141,6 @@ struct pcmcia_socket {
u_short lock_count; u_short lock_count;
pccard_mem_map cis_mem; pccard_mem_map cis_mem;
void __iomem *cis_virt; void __iomem *cis_virt;
struct {
u_int AssignedIRQ;
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN]; io_window_t io[MAX_IO_WIN];
pccard_mem_map win[MAX_WIN]; pccard_mem_map win[MAX_WIN];
struct list_head cis_cache; struct list_head cis_cache;
@ -235,6 +231,9 @@ struct pcmcia_socket {
/* non-zero if PCMCIA card is present */ /* non-zero if PCMCIA card is present */
atomic_t present; atomic_t present;
/* IRQ to be used by PCMCIA devices. May not be IRQ 0. */
unsigned int pcmcia_irq;
#ifdef CONFIG_PCMCIA_IOCTL #ifdef CONFIG_PCMCIA_IOCTL
struct user_info_t *user; struct user_info_t *user;
wait_queue_head_t queue; wait_queue_head_t queue;

View File

@ -142,12 +142,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
/* FIXME: This driver should be updated to allow for dynamic IRQ sharing */
/* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */
link->irq.Handler = pdacf_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
if (ret) if (ret)
goto failed; goto failed;
@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
goto failed; goto failed;
link->dev_node = &pdacf->node;
return 0; return 0;
failed: failed:

View File

@ -117,7 +117,6 @@ struct snd_pdacf {
/* pcmcia stuff */ /* pcmcia stuff */
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
}; };
static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val) static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val)

View File

@ -162,10 +162,6 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Handler = &snd_vx_irq_handler;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
@ -215,7 +211,6 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
static int vxpocket_config(struct pcmcia_device *link) static int vxpocket_config(struct pcmcia_device *link)
{ {
struct vx_core *chip = link->priv; struct vx_core *chip = link->priv;
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
int ret; int ret;
snd_printdd(KERN_DEBUG "vxpocket_config called\n"); snd_printdd(KERN_DEBUG "vxpocket_config called\n");
@ -235,7 +230,7 @@ static int vxpocket_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_irq(link, &link->irq); ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
if (ret) if (ret)
goto failed; goto failed;
@ -246,10 +241,9 @@ static int vxpocket_config(struct pcmcia_device *link)
chip->dev = &link->dev; chip->dev = &link->dev;
snd_card_set_dev(chip->card, chip->dev); snd_card_set_dev(chip->card, chip->dev);
if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0)
goto failed; goto failed;
link->dev_node = &vxp->node;
return 0; return 0;
failed: failed:

View File

@ -43,7 +43,6 @@ struct snd_vxpocket {
/* pcmcia stuff */ /* pcmcia stuff */
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
dev_node_t node;
}; };
extern struct snd_vx_ops snd_vxpocket_ops; extern struct snd_vx_ops snd_vxpocket_ops;