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:
commit
5429126351
|
@ -1,4 +1,17 @@
|
|||
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)
|
||||
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
||||
|
|
|
@ -45,16 +45,6 @@
|
|||
#define DRV_NAME "pata_pcmcia"
|
||||
#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
|
||||
* @link: link
|
||||
|
@ -248,7 +238,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
{
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct ata_pcmcia_info *info;
|
||||
struct pcmcia_config_check *stk = NULL;
|
||||
int is_kme = 0, ret = -ENOMEM, p;
|
||||
unsigned long io_base, ctl_base;
|
||||
|
@ -256,19 +245,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
int n_ports = 1;
|
||||
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 */
|
||||
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
pdev->io.IOAddrLines = 3;
|
||||
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
pdev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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;
|
||||
ctl_base = stk->ctl_base;
|
||||
ret = pcmcia_request_irq(pdev, &pdev->irq);
|
||||
if (ret)
|
||||
if (!pdev->irq)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(pdev, &pdev->conf);
|
||||
|
@ -344,21 +323,19 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
}
|
||||
|
||||
/* 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);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
info->ndev = 1;
|
||||
pdev->priv = host;
|
||||
kfree(stk);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
kfree(stk);
|
||||
info->ndev = 0;
|
||||
pcmcia_disable_device(pdev);
|
||||
out1:
|
||||
kfree(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -372,20 +349,12 @@ out1:
|
|||
|
||||
static void pcmcia_remove_one(struct pcmcia_device *pdev)
|
||||
{
|
||||
struct ata_pcmcia_info *info = pdev->priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_host *host = pdev->priv;
|
||||
|
||||
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);
|
||||
if (host)
|
||||
ata_host_detach(host);
|
||||
}
|
||||
info->ndev = 0;
|
||||
pdev->priv = NULL;
|
||||
}
|
||||
|
||||
pcmcia_disable_device(pdev);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
static struct pcmcia_device_id pcmcia_devices[] = {
|
||||
|
|
|
@ -65,7 +65,6 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
typedef struct bluecard_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
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.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = bluecard_interrupt;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -908,9 +904,9 @@ static int bluecard_config(struct pcmcia_device *link)
|
|||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
i = pcmcia_request_irq(link, bluecard_interrupt);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
|
@ -919,9 +915,6 @@ static int bluecard_config(struct pcmcia_device *link)
|
|||
if (bluecard_open(info) != 0)
|
||||
goto failed;
|
||||
|
||||
strcpy(info->node.dev_name, info->hdev->name);
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -72,7 +72,6 @@ MODULE_FIRMWARE("BT3CPCC.bin");
|
|||
|
||||
typedef struct bt3c_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
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.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = bt3c_interrupt;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -743,9 +739,9 @@ static int bt3c_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
i = pcmcia_request_irq(link, &bt3c_interrupt);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
|
@ -754,9 +750,6 @@ found_port:
|
|||
if (bt3c_open(info) != 0)
|
||||
goto failed;
|
||||
|
||||
strcpy(info->node.dev_name, info->hdev->name);
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -67,7 +67,6 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
typedef struct btuart_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
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.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = btuart_interrupt;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -672,9 +668,9 @@ static int btuart_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
i = pcmcia_request_irq(link, btuart_interrupt);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
|
@ -683,9 +679,6 @@ found_port:
|
|||
if (btuart_open(info) != 0)
|
||||
goto failed;
|
||||
|
||||
strcpy(info->node.dev_name, info->hdev->name);
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -67,7 +67,6 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
typedef struct dtl1_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
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.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = dtl1_interrupt;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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)
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
i = pcmcia_request_irq(link, dtl1_interrupt);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
|
@ -632,9 +628,6 @@ static int dtl1_config(struct pcmcia_device *link)
|
|||
if (dtl1_open(info) != 0)
|
||||
goto failed;
|
||||
|
||||
strcpy(info->node.dev_name, info->hdev->name);
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -106,7 +106,6 @@ static int major; /* major number we get from the kernel */
|
|||
|
||||
struct cm4000_dev {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node; /* OS node (major,minor) */
|
||||
|
||||
unsigned char atr[MAX_ATR];
|
||||
unsigned char rbuf[512];
|
||||
|
@ -884,8 +883,7 @@ static void monitor_card(unsigned long p)
|
|||
/* slow down warning, but prompt immediately after insertion */
|
||||
if (dev->cwarn == 0 || dev->cwarn == 10) {
|
||||
set_bit(IS_BAD_CARD, &dev->flags);
|
||||
printk(KERN_WARNING MODULE_NAME ": device %s: ",
|
||||
dev->node.dev_name);
|
||||
dev_warn(&dev->p_dev->dev, MODULE_NAME ": ");
|
||||
if (test_bit(IS_BAD_CSUM, &dev->flags)) {
|
||||
DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
|
||||
"be zero) failed\n", dev->atr_csum);
|
||||
|
@ -1781,11 +1779,6 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
|
|||
goto cs_release;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@ static struct class *cmx_class;
|
|||
|
||||
struct reader_dev {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
wait_queue_head_t devq;
|
||||
wait_queue_head_t poll_wait;
|
||||
wait_queue_head_t read_wait;
|
||||
|
@ -568,10 +567,6 @@ static int reader_config(struct pcmcia_device *link, int devno)
|
|||
}
|
||||
|
||||
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,
|
||||
link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
|
||||
|
|
|
@ -195,9 +195,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
|
||||
ret = pcmcia_request_irq(link, ipwireless_interrupt);
|
||||
if (ret != 0)
|
||||
goto exit;
|
||||
|
||||
|
@ -217,7 +213,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
(unsigned int) link->io.BasePort1,
|
||||
(unsigned int) (link->io.BasePort1 +
|
||||
link->io.NumPorts1 - 1),
|
||||
(unsigned int) link->irq.AssignedIRQ);
|
||||
(unsigned int) link->irq);
|
||||
if (ipw->attr_memory && ipw->common_memory)
|
||||
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
|
||||
": 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)
|
||||
goto exit;
|
||||
|
||||
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
|
||||
ipw->nodes);
|
||||
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network);
|
||||
if (!ipw->tty)
|
||||
goto exit;
|
||||
|
||||
|
@ -248,8 +243,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
if (ret != 0)
|
||||
goto exit;
|
||||
|
||||
link->dev_node = &ipw->nodes[0];
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
|
@ -271,8 +264,6 @@ exit:
|
|||
|
||||
static void release_ipwireless(struct ipw_dev *ipw)
|
||||
{
|
||||
pcmcia_disable_device(ipw->link);
|
||||
|
||||
if (ipw->common_memory) {
|
||||
release_mem_region(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size);
|
||||
|
@ -288,7 +279,6 @@ static void release_ipwireless(struct ipw_dev *ipw)
|
|||
if (ipw->attr_memory)
|
||||
pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
|
||||
|
||||
/* Break the link with Card Services */
|
||||
pcmcia_disable_device(ipw->link);
|
||||
}
|
||||
|
||||
|
@ -313,9 +303,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
|
|||
ipw->link = link;
|
||||
link->priv = ipw;
|
||||
|
||||
/* Link this device into our device list. */
|
||||
link->dev_node = &ipw->nodes[0];
|
||||
|
||||
ipw->hardware = ipwireless_hardware_create();
|
||||
if (!ipw->hardware) {
|
||||
kfree(ipw);
|
||||
|
|
|
@ -54,7 +54,6 @@ struct ipw_dev {
|
|||
void __iomem *common_memory;
|
||||
win_req_t request_common_memory;
|
||||
|
||||
dev_node_t nodes[2];
|
||||
/* Reference to attribute memory, containing CIS data */
|
||||
void *attribute_memory;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
static int add_tty(dev_node_t *nodesp, int j,
|
||||
static int add_tty(int j,
|
||||
struct ipw_hardware *hardware,
|
||||
struct ipw_network *network, int channel_idx,
|
||||
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,
|
||||
secondary_channel_idx,
|
||||
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])
|
||||
report_registering(ttys[j]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware,
|
||||
struct ipw_network *network,
|
||||
dev_node_t *nodes)
|
||||
struct ipw_network *network)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
@ -539,26 +533,23 @@ struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware,
|
|||
if (allfree) {
|
||||
j = i;
|
||||
|
||||
if (add_tty(&nodes[0], j, hardware, network,
|
||||
if (add_tty(j, hardware, network,
|
||||
IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS,
|
||||
TTYTYPE_MODEM))
|
||||
return NULL;
|
||||
|
||||
j += IPWIRELESS_PCMCIA_MINOR_RANGE;
|
||||
if (add_tty(&nodes[1], j, hardware, network,
|
||||
if (add_tty(j, hardware, network,
|
||||
IPW_CHANNEL_DIALLER, -1,
|
||||
TTYTYPE_MONITOR))
|
||||
return NULL;
|
||||
|
||||
j += IPWIRELESS_PCMCIA_MINOR_RANGE;
|
||||
if (add_tty(NULL, j, hardware, network,
|
||||
if (add_tty(j, hardware, network,
|
||||
IPW_CHANNEL_RAS, -1,
|
||||
TTYTYPE_RAS_RAW))
|
||||
return NULL;
|
||||
|
||||
nodes[0].next = &nodes[1];
|
||||
nodes[1].next = NULL;
|
||||
|
||||
return ttys[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ int ipwireless_tty_init(void);
|
|||
void ipwireless_tty_release(void);
|
||||
|
||||
struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw,
|
||||
struct ipw_network *net,
|
||||
dev_node_t *nodes);
|
||||
struct ipw_network *net);
|
||||
void ipwireless_tty_free(struct ipw_tty *tty);
|
||||
void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data,
|
||||
unsigned int length);
|
||||
|
|
|
@ -220,7 +220,6 @@ typedef struct _mgslpc_info {
|
|||
|
||||
/* PCMCIA support */
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
|
||||
/* SPPP/Cisco HDLC device parts */
|
||||
|
@ -552,10 +551,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
|||
|
||||
/* 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.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -608,9 +603,7 @@ static int mgslpc_config(struct pcmcia_device *link)
|
|||
link->conf.ConfigIndex = 8;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->irq.Handler = mgslpc_isr;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, mgslpc_isr);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
|
@ -618,17 +611,12 @@ static int mgslpc_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
|
||||
info->io_base = link->io.BasePort1;
|
||||
info->irq_level = link->irq.AssignedIRQ;
|
||||
info->irq_level = link->irq;
|
||||
|
||||
/* add to linked list of devices */
|
||||
sprintf(info->node.dev_name, "mgslpc0");
|
||||
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);
|
||||
dev_info(&link->dev, "index 0x%02x:",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
|
|
|
@ -66,7 +66,6 @@ typedef struct ide_info_t {
|
|||
struct pcmcia_device *p_dev;
|
||||
struct ide_host *host;
|
||||
int ndev;
|
||||
dev_node_t node;
|
||||
} ide_info_t;
|
||||
|
||||
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.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 3;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -285,8 +283,7 @@ static int ide_config(struct pcmcia_device *link)
|
|||
io_base = link->io.BasePort1;
|
||||
ctl_base = stk->ctl_base;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
|
@ -299,24 +296,21 @@ static int ide_config(struct pcmcia_device *link)
|
|||
if (is_kme)
|
||||
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) {
|
||||
outb(0x02, ctl_base + 0x10);
|
||||
host = idecs_register(io_base + 0x10, ctl_base + 0x10,
|
||||
link->irq.AssignedIRQ, link);
|
||||
link->irq, link);
|
||||
}
|
||||
|
||||
if (host == NULL)
|
||||
goto failed;
|
||||
|
||||
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;
|
||||
link->dev_node = &info->node;
|
||||
printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
|
||||
info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
|
||||
dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
|
||||
'a' + host->ports[0]->index * 2,
|
||||
link->conf.Vpp / 10, link->conf.Vpp % 10);
|
||||
|
||||
kfree(stk);
|
||||
return 0;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/tty.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);
|
||||
|
||||
/*
|
||||
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
|
||||
|
@ -100,32 +74,19 @@ typedef struct local_info_t {
|
|||
|
||||
static int avmcs_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
local_info_t *local;
|
||||
|
||||
/* The io structure describes IO port mapping */
|
||||
p_dev->io.NumPorts1 = 16;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.NumPorts2 = 0;
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->conf.ConfigIndex = 1;
|
||||
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);
|
||||
|
||||
err:
|
||||
return -ENOMEM;
|
||||
} /* avmcs_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -140,7 +101,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
|
|||
static void avmcs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
avmcs_release(link);
|
||||
kfree(link->priv);
|
||||
} /* avmcs_detach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -171,14 +131,11 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev,
|
|||
|
||||
static int avmcs_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev;
|
||||
int i;
|
||||
int i = -1;
|
||||
char devname[128];
|
||||
int cardtype;
|
||||
int (*addcard)(unsigned int port, unsigned irq);
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
strlcpy(devname, link->prod_id[1], sizeof(devname));
|
||||
|
@ -190,11 +147,7 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
return -ENODEV;
|
||||
|
||||
do {
|
||||
/*
|
||||
* allocate an interrupt line
|
||||
*/
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
if (!link->irq) {
|
||||
/* undo */
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
|
@ -211,15 +164,11 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
|
||||
} 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]) {
|
||||
char *s = strrchr(devname, ' ');
|
||||
if (!s)
|
||||
s = devname;
|
||||
else s++;
|
||||
strcpy(dev->node.dev_name, s);
|
||||
if (strcmp("M1", s) == 0) {
|
||||
cardtype = AVM_CARDTYPE_M1;
|
||||
} else if (strcmp("M2", s) == 0) {
|
||||
|
@ -227,14 +176,8 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
} else {
|
||||
cardtype = AVM_CARDTYPE_B1;
|
||||
}
|
||||
} else {
|
||||
strcpy(dev->node.dev_name, "b1");
|
||||
} else
|
||||
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 (i != 0) {
|
||||
|
@ -249,13 +192,12 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
default:
|
||||
case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
|
||||
}
|
||||
if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
|
||||
printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
|
||||
dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) {
|
||||
dev_err(&link->dev, "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
|
||||
link->io.BasePort1, link->irq);
|
||||
avmcs_release(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
dev->node.minor = i;
|
||||
return 0;
|
||||
|
||||
} /* avmcs_config */
|
||||
|
@ -270,7 +212,7 @@ static int avmcs_config(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);
|
||||
} /* avmcs_release */
|
||||
|
||||
|
|
|
@ -62,31 +62,6 @@ static void avma1cs_release(struct pcmcia_device *link);
|
|||
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
|
||||
|
@ -101,17 +76,8 @@ typedef struct local_info_t {
|
|||
|
||||
static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
local_info_t *local;
|
||||
|
||||
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 */
|
||||
p_dev->io.NumPorts1 = 16;
|
||||
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.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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)
|
||||
{
|
||||
local_info_t *dev;
|
||||
int i;
|
||||
int i = -1;
|
||||
char devname[128];
|
||||
IsdnCard_t icard;
|
||||
int busy = 0;
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
|
||||
|
||||
devname[0] = 0;
|
||||
|
@ -197,8 +157,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
|
|||
/*
|
||||
* allocate an interrupt line
|
||||
*/
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
if (!link->irq) {
|
||||
/* undo */
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
|
@ -215,14 +174,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
|
|||
|
||||
} 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 (i != 0) {
|
||||
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",
|
||||
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.protocol = isdnprot;
|
||||
icard.typ = ISDN_CTYPE_A1_PCMCIA;
|
||||
|
@ -243,7 +194,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
|
|||
avma1cs_release(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
dev->node.minor = i;
|
||||
link->priv = (void *) (unsigned long) i;
|
||||
|
||||
return 0;
|
||||
} /* avma1cs_config */
|
||||
|
@ -258,12 +209,12 @@ static int __devinit avma1cs_config(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);
|
||||
|
||||
/* now unregister function with hisax */
|
||||
HiSax_closecard(local->node.minor);
|
||||
HiSax_closecard(minor);
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
} /* avma1cs_release */
|
||||
|
|
|
@ -87,24 +87,8 @@ static void elsa_cs_release(struct pcmcia_device *link);
|
|||
|
||||
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 {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
int busy;
|
||||
int cardnr;
|
||||
} local_info_t;
|
||||
|
@ -136,10 +120,6 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link)
|
|||
|
||||
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
|
||||
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)
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
link->irq.AssignedIRQ = 0;
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x: ",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x: ",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
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);
|
||||
printk("\n");
|
||||
|
||||
icard.para[0] = link->irq.AssignedIRQ;
|
||||
icard.para[0] = link->irq;
|
||||
icard.para[1] = link->io.BasePort1;
|
||||
icard.protocol = protocol;
|
||||
icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
|
||||
|
|
|
@ -87,32 +87,8 @@ static void sedlbauer_release(struct pcmcia_device *link);
|
|||
|
||||
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 {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
int cardnr;
|
||||
} local_info_t;
|
||||
|
@ -143,10 +119,6 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
|
|||
local->p_dev = link;
|
||||
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
|
||||
client, we assume very little, and rely on the CIS for almost
|
||||
|
@ -227,8 +199,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
|||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -285,7 +255,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
|||
|
||||
static int __devinit sedlbauer_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev = link->priv;
|
||||
win_req_t *req;
|
||||
int ret;
|
||||
IsdnCard_t icard;
|
||||
|
@ -312,17 +281,6 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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
|
||||
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)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x:",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x:",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
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);
|
||||
printk("\n");
|
||||
|
||||
icard.para[0] = link->irq.AssignedIRQ;
|
||||
icard.para[0] = link->irq;
|
||||
icard.para[1] = link->io.BasePort1;
|
||||
icard.protocol = protocol;
|
||||
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
|
||||
|
|
|
@ -68,34 +68,8 @@ static void teles_cs_release(struct pcmcia_device *link);
|
|||
|
||||
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 {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
int busy;
|
||||
int cardnr;
|
||||
} local_info_t;
|
||||
|
@ -126,10 +100,6 @@ static int __devinit teles_probe(struct pcmcia_device *link)
|
|||
local->p_dev = link;
|
||||
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
|
||||
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)
|
||||
goto cs_failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
link->irq.AssignedIRQ = 0;
|
||||
if (!link->irq)
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x:",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x:",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
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);
|
||||
printk("\n");
|
||||
|
||||
icard.para[0] = link->irq.AssignedIRQ;
|
||||
icard.para[0] = link->irq;
|
||||
icard.para[1] = link->io.BasePort1;
|
||||
icard.protocol = protocol;
|
||||
icard.typ = ISDN_CTYPE_TELESPCMCIA;
|
||||
|
|
|
@ -52,7 +52,6 @@ static const int debug = 0;
|
|||
|
||||
struct pcmciamtd_dev {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node; /* device node */
|
||||
caddr_t win_base; /* ioremapped address of PCMCIA window */
|
||||
unsigned int win_size; /* size of window */
|
||||
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);
|
||||
return -ENODEV;
|
||||
}
|
||||
snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
|
||||
info("mtd%d: %s", mtd->index, mtd->name);
|
||||
link->dev_node = &dev->node;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -93,7 +93,6 @@ earlier 3Com products.
|
|||
#include <pcmcia/cisreg.h>
|
||||
#include <pcmcia/ciscode.h>
|
||||
#include <pcmcia/ds.h>
|
||||
#include <pcmcia/mem_op.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -200,7 +199,6 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
|
|||
|
||||
struct el3_private {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
u16 advertising, partner; /* NWay media advertisement */
|
||||
unsigned char phys; /* MII device address */
|
||||
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);
|
||||
link->io.NumPorts1 = 32;
|
||||
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.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -311,7 +307,6 @@ static void tc574_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "3c574_detach()\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
tc574_release(link);
|
||||
|
@ -353,7 +348,7 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, el3_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -361,7 +356,7 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
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);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(lp->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
|
||||
"hw_addr %pM.\n",
|
||||
dev->name, cardname, dev->base_addr, dev->irq,
|
||||
|
|
|
@ -106,7 +106,6 @@ enum RxFilter {
|
|||
|
||||
struct el3_private {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
/* For transceiver monitoring */
|
||||
struct timer_list media;
|
||||
u16 media_status;
|
||||
|
@ -194,8 +193,7 @@ static int tc589_probe(struct pcmcia_device *link)
|
|||
spin_lock_init(&lp->lock);
|
||||
link->io.NumPorts1 = 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.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -223,7 +221,6 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "3c589_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
tc589_release(link);
|
||||
|
@ -242,7 +239,6 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||
static int tc589_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct el3_private *lp = netdev_priv(dev);
|
||||
__be16 *phys_addr;
|
||||
int ret, i, j, multi = 0, fifo;
|
||||
unsigned int ioaddr;
|
||||
|
@ -271,7 +267,7 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, el3_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -279,7 +275,7 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
ioaddr = dev->base_addr;
|
||||
EL3WINDOW(0);
|
||||
|
@ -313,17 +309,13 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
else
|
||||
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
|
||||
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(lp->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, "
|
||||
"hw_addr %pM\n",
|
||||
dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq,
|
||||
|
|
|
@ -113,7 +113,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id);
|
|||
|
||||
typedef struct axnet_dev_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
caddr_t base;
|
||||
struct timer_list watchdog;
|
||||
int stale, fast_poll;
|
||||
|
@ -168,7 +167,6 @@ static int axnet_probe(struct pcmcia_device *link)
|
|||
info = PRIV(dev);
|
||||
info->p_dev = link;
|
||||
link->priv = dev;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -195,7 +193,6 @@ static void axnet_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
axnet_release(link);
|
||||
|
@ -265,12 +262,9 @@ static int try_io_port(struct pcmcia_device *link)
|
|||
int j, ret;
|
||||
if (link->io.NumPorts1 == 32) {
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (link->io.NumPorts2 > 0) {
|
||||
/* for master/slave multifunction cards */
|
||||
if (link->io.NumPorts2 > 0)
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING;
|
||||
}
|
||||
} else {
|
||||
/* This should be two 16-port windows */
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
|
@ -336,8 +330,7 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
if (ret != 0)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
|
@ -349,7 +342,7 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
if (!get_prom(link)) {
|
||||
|
@ -397,17 +390,13 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
info->phy_id = (i < 32) ? i : -1;
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(info->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
|
||||
"hw_addr %pM\n",
|
||||
dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
|
||||
|
|
|
@ -122,7 +122,6 @@ static void com20020_detach(struct pcmcia_device *p_dev);
|
|||
|
||||
typedef struct com20020_dev_t {
|
||||
struct net_device *dev;
|
||||
dev_node_t node;
|
||||
} 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.NumPorts1 = 16;
|
||||
p_dev->io.IOAddrLines = 16;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -196,7 +194,6 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "com20020_detach\n");
|
||||
|
||||
if (link->dev_node) {
|
||||
dev_dbg(&link->dev, "unregister...\n");
|
||||
|
||||
unregister_netdev(dev);
|
||||
|
@ -207,7 +204,6 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||
*/
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
}
|
||||
|
||||
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, "request IRQ %d\n",
|
||||
link->irq.AssignedIRQ);
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0)
|
||||
link->irq);
|
||||
if (!link->irq)
|
||||
{
|
||||
dev_dbg(&link->dev, "requestIRQ failed totally!\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
|
@ -299,7 +294,6 @@ static int com20020_config(struct pcmcia_device *link)
|
|||
lp->card_name = "PCMCIA COM20020";
|
||||
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = com20020_found(dev, 0); /* calls register_netdev */
|
||||
|
@ -307,12 +301,9 @@ static int com20020_config(struct pcmcia_device *link)
|
|||
if (i != 0) {
|
||||
dev_printk(KERN_NOTICE, &link->dev,
|
||||
"com20020_cs: com20020_found() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(info->node.dev_name, dev->name);
|
||||
|
||||
dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
|
||||
dev->name, dev->base_addr, dev->irq);
|
||||
return 0;
|
||||
|
|
|
@ -110,7 +110,6 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
|
|||
*/
|
||||
typedef struct local_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
long open_time;
|
||||
uint tx_started:1;
|
||||
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.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = fjn_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -278,7 +273,6 @@ static void fmvj18x_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "fmvj18x_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
fmvj18x_release(link);
|
||||
|
@ -425,8 +419,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
if (link->io.NumPorts2 != 0) {
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING;
|
||||
ret = mfc_try_io_port(link);
|
||||
if (ret != 0) goto failed;
|
||||
} else if (cardtype == UNGERMANN) {
|
||||
|
@ -437,14 +429,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, fjn_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
if (link->io.BasePort2 != 0) {
|
||||
|
@ -529,17 +521,13 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
lp->cardtype = cardtype;
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(lp->node.dev_name, dev->name);
|
||||
|
||||
/* print current configuration */
|
||||
printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, "
|
||||
"hw_addr %pM\n",
|
||||
|
|
|
@ -104,7 +104,6 @@ static void ibmtr_detach(struct pcmcia_device *p_dev);
|
|||
typedef struct ibmtr_dev_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
struct net_device *dev;
|
||||
dev_node_t node;
|
||||
window_handle_t sram_win_handle;
|
||||
struct tok_info *ti;
|
||||
} 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.NumPorts1 = 4;
|
||||
link->io.IOAddrLines = 16;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = ibmtr_interrupt;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
@ -192,7 +189,6 @@ static void ibmtr_detach(struct pcmcia_device *link)
|
|||
*/
|
||||
ti->sram_phys |= 1;
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
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;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
ti->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
ti->irq = link->irq;
|
||||
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
|
||||
|
||||
/* 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. */
|
||||
ibmtr_hw_setup(dev, mmiobase);
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = ibmtr_probe_card(dev);
|
||||
if (i != 0) {
|
||||
printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(info->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO
|
||||
"%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
|
||||
dev->name, dev->base_addr, dev->irq,
|
||||
|
|
|
@ -363,7 +363,6 @@ typedef struct _mace_statistics {
|
|||
|
||||
typedef struct _mace_private {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct net_device_stats linux_stats; /* Linux 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.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 5;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = mace_interrupt;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -493,7 +490,6 @@ static void nmclan_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "nmclan_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
nmclan_release(link);
|
||||
|
@ -652,14 +648,14 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
ioaddr = dev->base_addr;
|
||||
|
@ -698,18 +694,14 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||
else
|
||||
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
|
||||
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = register_netdev(dev);
|
||||
if (i != 0) {
|
||||
printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(lp->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
|
||||
" hw_addr %pM\n",
|
||||
dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
|
||||
|
|
|
@ -208,7 +208,6 @@ static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
|
|||
|
||||
typedef struct pcnet_dev_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
u_int flags;
|
||||
void __iomem *base;
|
||||
struct timer_list watchdog;
|
||||
|
@ -264,7 +263,6 @@ static int pcnet_probe(struct pcmcia_device *link)
|
|||
info->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -288,7 +286,6 @@ static void pcnet_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "pcnet_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
pcnet_release(link);
|
||||
|
@ -488,8 +485,6 @@ static int try_io_port(struct pcmcia_device *link)
|
|||
if (link->io.NumPorts2 > 0) {
|
||||
/* for master/slave multifunction cards */
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING;
|
||||
}
|
||||
} else {
|
||||
/* This should be two 16-port windows */
|
||||
|
@ -559,8 +554,7 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
|
@ -574,7 +568,7 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
if (info->flags & HAS_MISC_REG) {
|
||||
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))
|
||||
mii_phy_probe(dev);
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(info->node.dev_name, dev->name);
|
||||
|
||||
if (info->flags & (IS_DL10019|IS_DL10022)) {
|
||||
u_char id = inb(dev->base_addr + 0x1a);
|
||||
printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
|
||||
|
|
|
@ -103,7 +103,6 @@ struct smc_private {
|
|||
u_short manfid;
|
||||
u_short cardid;
|
||||
|
||||
dev_node_t node;
|
||||
struct sk_buff *saved_skb;
|
||||
int packets_waiting;
|
||||
void __iomem *base;
|
||||
|
@ -323,14 +322,11 @@ static int smc91c92_probe(struct pcmcia_device *link)
|
|||
return -ENOMEM;
|
||||
smc = netdev_priv(dev);
|
||||
smc->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
spin_lock_init(&smc->lock);
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 4;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = &smc_interrupt;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -363,7 +359,6 @@ static void smc91c92_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "smc91c92_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
smc91c92_release(link);
|
||||
|
@ -453,7 +448,6 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->io.IOAddrLines = 16;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_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.Status = CCSR_AUDIO_ENA;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->io.NumPorts1 = 64;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts2 = 8;
|
||||
|
@ -877,7 +870,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
if (i)
|
||||
goto config_failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
i = pcmcia_request_irq(link, smc_interrupt);
|
||||
if (i)
|
||||
goto config_failed;
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
|
@ -887,7 +880,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
mot_config(link);
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
|
||||
if ((if_port >= 0) && (if_port <= 2))
|
||||
dev->if_port = if_port;
|
||||
|
@ -960,17 +953,13 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
SMC_SELECT_BANK(0);
|
||||
}
|
||||
|
||||
link->dev_node = &smc->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto config_undo;
|
||||
}
|
||||
|
||||
strcpy(smc->node.dev_name, dev->name);
|
||||
|
||||
printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
|
||||
"hw_addr %pM\n",
|
||||
dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
|
||||
|
|
|
@ -297,31 +297,9 @@ static void xirc2ps_detach(struct pcmcia_device *p_dev);
|
|||
|
||||
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 {
|
||||
struct net_device *dev;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
int card_type;
|
||||
int probe_port;
|
||||
|
@ -555,7 +533,6 @@ xirc2ps_probe(struct pcmcia_device *link)
|
|||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
link->irq.Handler = xirc2ps_interrupt;
|
||||
|
||||
/* Fill in card specific entries */
|
||||
dev->netdev_ops = &netdev_ops;
|
||||
|
@ -580,7 +557,6 @@ xirc2ps_detach(struct pcmcia_device *link)
|
|||
|
||||
dev_dbg(&link->dev, "detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
xirc2ps_release(link);
|
||||
|
@ -841,7 +817,6 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status |= CCSR_AUDIO_ENA;
|
||||
}
|
||||
link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->io.NumPorts2 = 8;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
if (local->dingo) {
|
||||
|
@ -866,7 +841,6 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
}
|
||||
printk(KNOT_XIRC "no ports available\n");
|
||||
} else {
|
||||
link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->io.NumPorts1 = 16;
|
||||
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
|
||||
link->io.BasePort1 = ioaddr;
|
||||
|
@ -885,7 +859,7 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
* Now allocate an interrupt line. Note that this does not
|
||||
* 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;
|
||||
|
||||
/****************
|
||||
|
@ -982,23 +956,19 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
printk(KNOT_XIRC "invalid if_port requested\n");
|
||||
|
||||
/* 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;
|
||||
|
||||
if (local->dingo)
|
||||
do_reset(dev, 1); /* a kludge to make the cem56 work */
|
||||
|
||||
link->dev_node = &local->node;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if ((err=register_netdev(dev))) {
|
||||
printk(KNOT_XIRC "register_netdev() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
strcpy(local->node.dev_name, dev->name);
|
||||
|
||||
/* give some infos about the hardware */
|
||||
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,
|
||||
|
|
|
@ -75,42 +75,7 @@ static void airo_release(struct pcmcia_device *link);
|
|||
|
||||
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 {
|
||||
dev_node_t node;
|
||||
struct net_device *eth_dev;
|
||||
} local_info_t;
|
||||
|
||||
|
@ -132,10 +97,6 @@ static int airo_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
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
|
||||
client, we assume very little, and rely on the CIS for almost
|
||||
|
@ -212,8 +173,6 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
|||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -300,16 +259,8 @@ static int airo_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -320,26 +271,17 @@ static int airo_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
((local_info_t *)link->priv)->eth_dev =
|
||||
init_airo_card(link->irq.AssignedIRQ,
|
||||
init_airo_card(link->irq,
|
||||
link->io.BasePort1, 1, &link->dev);
|
||||
if (!((local_info_t *)link->priv)->eth_dev)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x: ",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x: ",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
|
|
|
@ -85,41 +85,7 @@ static void atmel_release(struct pcmcia_device *link);
|
|||
|
||||
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 {
|
||||
dev_node_t node;
|
||||
struct net_device *eth_dev;
|
||||
} local_info_t;
|
||||
|
||||
|
@ -141,10 +107,6 @@ static int atmel_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
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
|
||||
client, we assume very little, and rely on the CIS for almost
|
||||
|
@ -226,8 +188,6 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
|
|||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -278,14 +238,8 @@ static int atmel_config(struct pcmcia_device *link)
|
|||
if (pcmcia_loop_config(link, atmel_config_check, NULL))
|
||||
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)
|
||||
if (!link->irq) {
|
||||
dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -298,14 +252,8 @@ static int atmel_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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 =
|
||||
init_atmel_card(link->irq.AssignedIRQ,
|
||||
init_atmel_card(link->irq,
|
||||
link->io.BasePort1,
|
||||
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
|
||||
&link->dev,
|
||||
|
@ -315,14 +263,6 @@ static int atmel_config(struct pcmcia_device *link)
|
|||
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;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -98,10 +98,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
|||
if (res != 0)
|
||||
goto err_disable;
|
||||
|
||||
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
dev->irq.Handler = NULL; /* The handler is registered later. */
|
||||
res = pcmcia_request_irq(dev, &dev->irq);
|
||||
if (res != 0)
|
||||
if (!dev->irq)
|
||||
goto err_disable;
|
||||
|
||||
res = pcmcia_request_configuration(dev, &dev->conf);
|
||||
|
|
|
@ -39,7 +39,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
|
|||
|
||||
/* struct local_info::hw_priv */
|
||||
struct hostap_cs_priv {
|
||||
dev_node_t node;
|
||||
struct pcmcia_device *link;
|
||||
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;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
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 */
|
||||
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->hw_priv = hw_priv;
|
||||
hw_priv->link = link;
|
||||
strcpy(hw_priv->node.dev_name, dev->name);
|
||||
link->dev_node = &hw_priv->node;
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = prism2_interrupt;
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, prism2_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -658,7 +638,7 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
/* 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,
|
||||
link->conf.Vpp % 10);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
|
@ -682,11 +662,9 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
sandisk_enable_wireless(dev);
|
||||
|
||||
ret = prism2_hw_config(dev, 1);
|
||||
if (!ret) {
|
||||
if (!ret)
|
||||
ret = hostap_hw_ready(dev);
|
||||
if (ret == 0 && local->ddev)
|
||||
strcpy(hw_priv->node.dev_name, local->ddev->name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -777,7 +777,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
|
|||
|
||||
lbs_deb_enter(LBS_DEB_CS);
|
||||
|
||||
free_irq(p_dev->irq.AssignedIRQ, card);
|
||||
free_irq(p_dev->irq, card);
|
||||
pcmcia_disable_device(p_dev);
|
||||
if (card->iobase)
|
||||
ioport_unmap(card->iobase);
|
||||
|
@ -807,7 +807,6 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
|
|||
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -837,9 +836,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
|||
card->p_dev = p_dev;
|
||||
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.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
|
||||
* the irq structure is initialized.
|
||||
*/
|
||||
if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(p_dev, &p_dev->irq);
|
||||
if (ret) {
|
||||
lbs_pr_err("error in pcmcia_request_irq\n");
|
||||
if (!p_dev->irq)
|
||||
goto out1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize io access */
|
||||
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 */
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -940,7 +931,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
|||
priv->fw_ready = 1;
|
||||
|
||||
/* 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);
|
||||
if (ret) {
|
||||
lbs_pr_err("error in request_irq\n");
|
||||
|
|
|
@ -50,7 +50,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
|
|||
* struct orinoco_private */
|
||||
struct orinoco_pccard {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
/* Used to handle hard reset */
|
||||
/* 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;
|
||||
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
|
||||
* client, we assume very little, and rely on the CIS for
|
||||
* almost everything. In most clients, many details (i.e.,
|
||||
|
@ -144,7 +139,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct orinoco_private *priv = link->priv;
|
||||
|
||||
if (link->dev_node)
|
||||
orinoco_if_del(priv);
|
||||
|
||||
orinoco_cs_release(link);
|
||||
|
@ -230,7 +224,6 @@ static int
|
|||
orinoco_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct orinoco_private *priv = link->priv;
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
int ret;
|
||||
void __iomem *mem;
|
||||
|
@ -258,12 +251,7 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
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.
|
||||
*/
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -285,9 +273,6 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
card->node.major = card->node.minor = 0;
|
||||
|
||||
/* Initialise the main driver */
|
||||
if (orinoco_init(priv) != 0) {
|
||||
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 */
|
||||
if (orinoco_if_add(priv, link->io.BasePort1,
|
||||
link->irq.AssignedIRQ) != 0) {
|
||||
link->irq) != 0) {
|
||||
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
|
||||
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;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -57,7 +57,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
|
|||
* struct orinoco_private */
|
||||
struct orinoco_pccard {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -193,10 +192,6 @@ spectrum_cs_probe(struct pcmcia_device *link)
|
|||
card->p_dev = link;
|
||||
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
|
||||
* client, we assume very little, and rely on the CIS for
|
||||
* almost everything. In most clients, many details (i.e.,
|
||||
|
@ -218,7 +213,6 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct orinoco_private *priv = link->priv;
|
||||
|
||||
if (link->dev_node)
|
||||
orinoco_if_del(priv);
|
||||
|
||||
spectrum_cs_release(link);
|
||||
|
@ -304,7 +298,6 @@ static int
|
|||
spectrum_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct orinoco_private *priv = link->priv;
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
int ret;
|
||||
void __iomem *mem;
|
||||
|
@ -332,12 +325,7 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
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.
|
||||
*/
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -359,9 +347,6 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
card->node.major = card->node.minor = 0;
|
||||
|
||||
/* Reset card */
|
||||
if (spectrum_cs_hard_reset(priv) != 0)
|
||||
goto failed;
|
||||
|
@ -374,17 +359,11 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
|
||||
/* Register an interface with the stack */
|
||||
if (orinoco_if_add(priv, link->io.BasePort1,
|
||||
link->irq.AssignedIRQ) != 0) {
|
||||
link->irq) != 0) {
|
||||
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
|
||||
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;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include <pcmcia/cistpl.h>
|
||||
#include <pcmcia/cisreg.h>
|
||||
#include <pcmcia/ds.h>
|
||||
#include <pcmcia/mem_op.h>
|
||||
|
||||
#include <linux/wireless.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.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 */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -383,7 +378,6 @@ static void ray_detach(struct pcmcia_device *link)
|
|||
del_timer(&local->timer);
|
||||
|
||||
if (link->priv) {
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
@ -417,10 +411,10 @@ static int ray_config(struct pcmcia_device *link)
|
|||
/* Now allocate an interrupt line. Note that this does not
|
||||
actually assign a handler to the interrupt.
|
||||
*/
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, ray_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
|
||||
/* This actually configures the PCMCIA socket -- setting up
|
||||
the I/O windows and the interrupt mapping.
|
||||
|
@ -493,9 +487,6 @@ static int ray_config(struct pcmcia_device *link)
|
|||
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",
|
||||
dev->name, dev->irq, dev->dev_addr);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ struct beacon_rx {
|
|||
typedef struct ray_dev_t {
|
||||
int card_status;
|
||||
int authentication_state;
|
||||
dev_node_t node;
|
||||
window_handle_t amem_handle; /* handle to window for attribute memory */
|
||||
window_handle_t rmem_handle; /* handle to window for rx buffer on card */
|
||||
void __iomem *sram; /* pointer to beginning of shared RAM */
|
||||
|
|
|
@ -610,7 +610,6 @@ struct wl3501_card {
|
|||
struct iw_statistics wstats;
|
||||
struct iw_spy_data spy_data;
|
||||
struct iw_public_data wireless_data;
|
||||
struct dev_node_t node;
|
||||
struct pcmcia_device *p_dev;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1451,6 +1451,8 @@ static void wl3501_detach(struct pcmcia_device *link)
|
|||
netif_device_detach(dev);
|
||||
wl3501_release(link);
|
||||
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (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.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.Handler = wl3501_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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
|
||||
* assign a handler to the interrupt. */
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, wl3501_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -1972,7 +1970,7 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
if (register_netdev(dev)) {
|
||||
|
@ -1981,20 +1979,15 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!wl3501_get_flash_mac_addr(this)) {
|
||||
printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n",
|
||||
dev->name);
|
||||
unregister_netdev(dev);
|
||||
goto failed;
|
||||
}
|
||||
strcpy(this->node.dev_name, dev->name);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = ((char *)&this->mac_addr)[i];
|
||||
|
@ -2038,12 +2031,6 @@ failed:
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,6 @@ INT_MODULE_PARM(epp_mode, 1);
|
|||
typedef struct parport_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
int ndev;
|
||||
dev_node_t node;
|
||||
struct parport *port;
|
||||
} 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.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -174,20 +172,19 @@ static int parport_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
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);
|
||||
if (p == NULL) {
|
||||
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
|
||||
"0x%3x, irq %u failed\n", link->io.BasePort1,
|
||||
link->irq.AssignedIRQ);
|
||||
link->irq);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -195,11 +192,7 @@ static int parport_config(struct pcmcia_device *link)
|
|||
if (epp_mode)
|
||||
p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
|
||||
info->ndev = 1;
|
||||
info->node.major = LP_MAJOR;
|
||||
info->node.minor = p->number;
|
||||
info->port = p;
|
||||
strcpy(info->node.dev_name, p->name);
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -49,26 +49,6 @@ config PCMCIA_LOAD_CIS
|
|||
|
||||
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
|
||||
bool "32-bit CardBus support"
|
||||
depends on PCI
|
||||
|
@ -318,7 +298,7 @@ config ELECTRA_CF
|
|||
PA Semi Electra eval board.
|
||||
|
||||
config PCCARD_NONSTATIC
|
||||
tristate
|
||||
bool
|
||||
|
||||
config PCCARD_IODYN
|
||||
bool
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
# 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
|
||||
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
|
||||
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
|
||||
|
|
|
@ -113,7 +113,7 @@ static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp)
|
|||
|
||||
if (bfin_cf_present(cf->cd_pfx)) {
|
||||
*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
|
||||
s->irq.AssignedIRQ = 0;
|
||||
s->pcmcia_irq = 0;
|
||||
s->pci_irq = cf->irq;
|
||||
|
||||
} else
|
||||
|
|
|
@ -94,7 +94,6 @@ int __ref cb_alloc(struct pcmcia_socket *s)
|
|||
pci_enable_bridges(bus);
|
||||
pci_bus_add_devices(bus);
|
||||
|
||||
s->irq.AssignedIRQ = s->pci_irq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* must be called with ops_mutex held
|
||||
*/
|
||||
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||
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);
|
||||
|
||||
mutex_lock(&s->ops_mutex);
|
||||
if (attr & IS_INDIRECT) {
|
||||
/* Indirect accesses use a bunch of special registers at fixed
|
||||
locations in common memory */
|
||||
|
@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
if (!sys) {
|
||||
dev_dbg(&s->dev, "could not map memory\n");
|
||||
memset(ptr, 0xff, len);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
if (!sys) {
|
||||
dev_dbg(&s->dev, "could not map memory\n");
|
||||
memset(ptr, 0xff, len);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
||||
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
||||
*(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
|
||||
*
|
||||
* 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,
|
||||
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,
|
||||
"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||
|
||||
mutex_lock(&s->ops_mutex);
|
||||
if (attr & IS_INDIRECT) {
|
||||
/* Indirect accesses use a bunch of special registers at fixed
|
||||
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));
|
||||
if (!sys) {
|
||||
dev_dbg(&s->dev, "could not map memory\n");
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
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);
|
||||
if (!sys) {
|
||||
dev_dbg(&s->dev, "could not map memory\n");
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return; /* FIXME: error */
|
||||
}
|
||||
|
||||
|
@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
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;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
|
||||
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->attr = attr;
|
||||
memcpy(cis->cache, ptr, len);
|
||||
mutex_lock(&s->ops_mutex);
|
||||
list_add(&cis->node, &s->cis_cache);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
|
|||
"no memory for verifying CIS\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_lock(&s->ops_mutex);
|
||||
list_for_each_entry(cis, &s->cis_cache, node) {
|
||||
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);
|
||||
if (ret || memcmp(buf, cis->cache, len) != 0) {
|
||||
kfree(buf);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
kfree(buf);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1361,106 +1358,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
|
|||
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
|
||||
* @s: the struct pcmcia_socket we are to check
|
||||
|
|
|
@ -337,7 +337,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
|
|||
s->socket = dead_socket;
|
||||
s->ops->init(s);
|
||||
s->ops->set_socket(s, &s->socket);
|
||||
s->irq.AssignedIRQ = s->irq.Config = 0;
|
||||
s->lock_count = 0;
|
||||
kfree(s->fake_cis);
|
||||
s->fake_cis = NULL;
|
||||
|
|
|
@ -52,13 +52,11 @@ struct cis_cache_entry {
|
|||
|
||||
struct pccard_resource_ops {
|
||||
int (*validate_mem) (struct pcmcia_socket *s);
|
||||
int (*adjust_io_region) (struct resource *res,
|
||||
unsigned long r_start,
|
||||
unsigned long r_end,
|
||||
struct pcmcia_socket *s);
|
||||
struct resource* (*find_io) (unsigned long base, int num,
|
||||
unsigned long align,
|
||||
struct pcmcia_socket *s);
|
||||
int (*find_io) (struct pcmcia_socket *s,
|
||||
unsigned int attr,
|
||||
unsigned int *base,
|
||||
unsigned int num,
|
||||
unsigned int align);
|
||||
struct resource* (*find_mem) (unsigned long base, unsigned long num,
|
||||
unsigned long align, int low,
|
||||
struct pcmcia_socket *s);
|
||||
|
@ -88,6 +86,14 @@ struct pccard_resource_ops {
|
|||
#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":
|
||||
*/
|
||||
|
@ -149,6 +155,8 @@ extern struct resource *pcmcia_find_mem_region(u_long base,
|
|||
int low,
|
||||
struct pcmcia_socket *s);
|
||||
|
||||
void pcmcia_cleanup_irq(struct pcmcia_socket *s);
|
||||
int pcmcia_setup_irq(struct pcmcia_device *p_dev);
|
||||
|
||||
/* cistpl.c */
|
||||
extern struct bin_attribute pccard_cis_attr;
|
||||
|
|
|
@ -371,8 +371,6 @@ static int pcmcia_device_remove(struct device *dev)
|
|||
if (p_drv->remove)
|
||||
p_drv->remove(p_dev);
|
||||
|
||||
p_dev->dev_node = NULL;
|
||||
|
||||
/* check for proper unloading */
|
||||
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
|
||||
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 *p_dev, *tmp_dev;
|
||||
|
@ -497,8 +486,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
|
|||
if (!s)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&device_add_lock);
|
||||
|
||||
pr_debug("adding device to %d, function %d\n", s->sock, function);
|
||||
|
||||
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.
|
||||
* Note that this is serialized by the device_add_lock, so that
|
||||
* only one such struct will be created.
|
||||
* Note that this is serialized by ops_mutex, so that only one
|
||||
* such struct will be created.
|
||||
*/
|
||||
list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
|
||||
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 */
|
||||
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) {
|
||||
dev_dbg(&p_dev->dev, "creating config_t\n");
|
||||
p_dev->function_config = kzalloc(sizeof(struct config_t),
|
||||
GFP_KERNEL);
|
||||
if (!p_dev->function_config)
|
||||
if (!p_dev->function_config) {
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
goto err_unreg;
|
||||
}
|
||||
kref_init(&p_dev->function_config->ref);
|
||||
}
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
|
||||
dev_printk(KERN_NOTICE, &p_dev->dev,
|
||||
"pcmcia: registering new device %s\n",
|
||||
p_dev->devname);
|
||||
"pcmcia: registering new device %s (IRQ: %d)\n",
|
||||
p_dev->devname, p_dev->irq);
|
||||
|
||||
pcmcia_device_query(p_dev);
|
||||
|
||||
if (device_register(&p_dev->dev))
|
||||
goto err_unreg;
|
||||
|
||||
mutex_unlock(&device_add_lock);
|
||||
|
||||
return p_dev;
|
||||
|
||||
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);
|
||||
err_put:
|
||||
mutex_unlock(&device_add_lock);
|
||||
pcmcia_put_socket(s);
|
||||
|
||||
return NULL;
|
||||
|
@ -1258,6 +1247,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
|||
handle_event(skt, event);
|
||||
mutex_lock(&s->ops_mutex);
|
||||
destroy_cis_cache(s);
|
||||
pcmcia_cleanup_irq(s);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
break;
|
||||
|
||||
|
|
|
@ -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;
|
||||
cf = container_of(s, struct omap_cf_socket, socket);
|
||||
s->irq.AssignedIRQ = 0;
|
||||
s->pcmcia_irq = 0;
|
||||
s->pci_irq = cf->irq;
|
||||
} else
|
||||
*sp = 0;
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
|
|||
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
|
||||
u_char reg;
|
||||
if (c->CardValues & PRESENT_PIN_REPLACE) {
|
||||
mutex_lock(&s->ops_mutex);
|
||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
status->CardState |=
|
||||
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
|
||||
status->CardState |=
|
||||
|
@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
|
|||
status->CardState |= CS_EVENT_READY_CHANGE;
|
||||
}
|
||||
if (c->CardValues & PRESENT_EXT_STATUS) {
|
||||
mutex_lock(&s->ops_mutex);
|
||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
status->CardState |=
|
||||
(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) {
|
||||
config->Attributes = CONF_VALID_CLIENT;
|
||||
config->IntType = INT_CARDBUS;
|
||||
config->AssignedIRQ = s->irq.AssignedIRQ;
|
||||
config->AssignedIRQ = s->pcmcia_irq;
|
||||
if (config->AssignedIRQ)
|
||||
config->Attributes |= CONF_ENABLE_IRQ;
|
||||
if (s->io[0].res) {
|
||||
|
@ -391,7 +395,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s,
|
|||
config->ExtStatus = c->ExtStatus;
|
||||
config->Present = config->CardValues = c->CardValues;
|
||||
config->IRQAttributes = c->irq.Attributes;
|
||||
config->AssignedIRQ = s->irq.AssignedIRQ;
|
||||
config->AssignedIRQ = s->pcmcia_irq;
|
||||
config->BasePort1 = c->io.BasePort1;
|
||||
config->NumPorts1 = c->io.NumPorts1;
|
||||
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)
|
||||
{
|
||||
dev_node_t *node;
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_driver *p_drv;
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!first) {
|
||||
ret = -ENODEV;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
|
||||
bind_info->major = node->major;
|
||||
bind_info->minor = node->minor;
|
||||
bind_info->next = node->next;
|
||||
strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN);
|
||||
bind_info->next = NULL;
|
||||
|
||||
err_put:
|
||||
pcmcia_put_dev(p_dev);
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/ss.h>
|
||||
#include <pcmcia/cs.h>
|
||||
|
@ -38,29 +40,6 @@ static int io_speed;
|
|||
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)
|
||||
{
|
||||
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,
|
||||
unsigned int *base, unsigned int num, u_int lines)
|
||||
{
|
||||
int i;
|
||||
unsigned int try, align;
|
||||
unsigned int align;
|
||||
|
||||
align = (*base) ? (lines ? 1<<lines : 0) : 1;
|
||||
if (align && (align < num)) {
|
||||
|
@ -104,50 +82,8 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
|
|||
*base, align);
|
||||
align = 0;
|
||||
}
|
||||
if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
|
||||
*base = s->io_offset | (*base & 0x0fff);
|
||||
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);
|
||||
|
||||
return s->resource_ops->find_io(s, attr, base, num, align);
|
||||
} /* alloc_io_space */
|
||||
|
||||
|
||||
|
@ -187,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||
config_t *c;
|
||||
int addr;
|
||||
u_char val;
|
||||
int ret = 0;
|
||||
|
||||
if (!p_dev || !p_dev->function_config)
|
||||
return -EINVAL;
|
||||
|
@ -203,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||
}
|
||||
|
||||
addr = (c->ConfigBase + reg->Offset) >> 1;
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
|
||||
switch (reg->Action) {
|
||||
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;
|
||||
break;
|
||||
case CS_WRITE:
|
||||
|
@ -216,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||
break;
|
||||
default:
|
||||
dev_dbg(&s->dev, "Invalid conf register request\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return ret;
|
||||
} /* 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;
|
||||
}
|
||||
|
||||
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
|
||||
if (mod->Attributes & CONF_ENABLE_IRQ) {
|
||||
c->Attributes |= CONF_ENABLE_IRQ;
|
||||
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");
|
||||
if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) {
|
||||
dev_dbg(&s->dev,
|
||||
"changing Vcc or IRQ is not allowed at this time\n");
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -422,52 +349,6 @@ out:
|
|||
} /* 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)
|
||||
{
|
||||
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)
|
||||
s->socket.flags |= SS_SPKR_ENA;
|
||||
if (req->Attributes & CONF_ENABLE_IRQ)
|
||||
s->socket.io_irq = s->irq.AssignedIRQ;
|
||||
s->socket.io_irq = s->pcmcia_irq;
|
||||
else
|
||||
s->socket.io_irq = 0;
|
||||
s->ops->set_socket(s, &s->socket);
|
||||
s->lock_count++;
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
|
||||
/* Set up CIS configuration registers */
|
||||
base = c->ConfigBase = req->ConfigBase;
|
||||
|
@ -574,8 +454,8 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
if (req->Present & PRESENT_IOBASE_0)
|
||||
c->Option |= COR_ADDR_DECODE;
|
||||
}
|
||||
if (c->state & CONFIG_IRQ_REQ)
|
||||
if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
|
||||
if ((req->Attributes & CONF_ENABLE_IRQ) &&
|
||||
!(req->Attributes & CONF_ENABLE_PULSE_IRQ))
|
||||
c->Option |= COR_LEVEL_REQ;
|
||||
pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
|
||||
mdelay(40);
|
||||
|
@ -605,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
|
||||
/* Configure I/O windows */
|
||||
if (c->state & CONFIG_IO_REQ) {
|
||||
mutex_lock(&s->ops_mutex);
|
||||
iomap.speed = io_speed;
|
||||
for (i = 0; i < MAX_IO_WIN; i++)
|
||||
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->io[i].Config++;
|
||||
}
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
}
|
||||
|
||||
c->state |= CONFIG_LOCKED;
|
||||
p_dev->_locked = 1;
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return 0;
|
||||
} /* pcmcia_request_configuration */
|
||||
EXPORT_SYMBOL(pcmcia_request_configuration);
|
||||
|
@ -706,137 +585,176 @@ out:
|
|||
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.
|
||||
*
|
||||
* Also, since Linux only reserves irq's when they are actually
|
||||
* hooked, we don't guarantee that an irq will still be available
|
||||
* when the configuration is locked. Now that I think about it,
|
||||
* there might be a way to fix this using a dummy handler.
|
||||
* pcmcia_request_irq() is a wrapper around request_irq which will allow
|
||||
* the PCMCIA core to clean up the registration in pcmcia_disable_device().
|
||||
* Drivers are free to use request_irq() directly, but then they need to
|
||||
* call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ
|
||||
* handlers are allowed.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PCMCIA_PROBE
|
||||
static irqreturn_t test_action(int cpl, void *dev_id)
|
||||
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
|
||||
irq_handler_t handler)
|
||||
{
|
||||
return IRQ_NONE;
|
||||
}
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
||||
{
|
||||
struct pcmcia_socket *s = p_dev->socket;
|
||||
config_t *c;
|
||||
int ret = -EINVAL, irq = 0;
|
||||
int type;
|
||||
if (!p_dev->irq)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&s->ops_mutex);
|
||||
|
||||
if (!(s->state & SOCKET_PRESENT)) {
|
||||
dev_dbg(&s->dev, "No card present\n");
|
||||
goto out;
|
||||
}
|
||||
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,
|
||||
ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
|
||||
p_dev->devname, p_dev->priv);
|
||||
if (ret) {
|
||||
dev_printk(KERN_INFO, &s->dev,
|
||||
"request_irq() failed\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
p_dev->_irq = 1;
|
||||
|
||||
/* 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;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_request_irq);
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!p_dev->irq)
|
||||
return -EINVAL;
|
||||
|
||||
ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
|
||||
if (ret) {
|
||||
ret = pcmcia_request_irq(p_dev, handler);
|
||||
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
|
||||
"request for exclusive IRQ could not be fulfilled.\n");
|
||||
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
|
||||
"needs updating to supported shared IRQ lines.\n");
|
||||
}
|
||||
c->irq.Attributes = req->Attributes;
|
||||
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
|
||||
s->irq.Config++;
|
||||
|
||||
c->state |= CONFIG_IRQ_REQ;
|
||||
if (ret)
|
||||
dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
|
||||
else
|
||||
p_dev->_irq = 1;
|
||||
|
||||
#ifdef CONFIG_PCMCIA_PROBE
|
||||
pcmcia_used_irq[irq]++;
|
||||
#endif
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
mutex_unlock(&s->ops_mutex);
|
||||
return ret;
|
||||
} /* pcmcia_request_irq */
|
||||
EXPORT_SYMBOL(pcmcia_request_irq);
|
||||
} /* pcmcia_request_exclusive_irq */
|
||||
EXPORT_SYMBOL(__pcmcia_request_exclusive_irq);
|
||||
|
||||
|
||||
#ifdef CONFIG_PCMCIA_PROBE
|
||||
|
||||
/* mask of IRQs already reserved by other cards, we should avoid using them */
|
||||
static u8 pcmcia_used_irq[NR_IRQS];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -939,237 +857,9 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev)
|
|||
{
|
||||
pcmcia_release_configuration(p_dev);
|
||||
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)
|
||||
pcmcia_release_window(p_dev, p_dev->win);
|
||||
}
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
|
@ -22,7 +22,7 @@
|
|||
#include <pcmcia/cistpl.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
|
||||
* that they don't need a resource database */
|
||||
|
@ -32,11 +32,35 @@ static int static_init(struct pcmcia_socket *s)
|
|||
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 = {
|
||||
.validate_mem = NULL,
|
||||
.adjust_io_region = NULL,
|
||||
.find_io = NULL,
|
||||
.find_io = static_find_io,
|
||||
.find_mem = NULL,
|
||||
.add_io = NULL,
|
||||
.add_mem = NULL,
|
||||
|
@ -46,104 +70,6 @@ struct pccard_resource_ops pccard_static_ops = {
|
|||
EXPORT_SYMBOL(pccard_static_ops);
|
||||
|
||||
|
||||
#ifdef CONFIG_PCCARD_IODYN
|
||||
|
||||
static struct resource *
|
||||
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 */
|
||||
MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("rsrc_nonstatic");
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
#include <pcmcia/cistpl.h>
|
||||
#include "cs_internal.h"
|
||||
|
||||
/* moved to rsrc_mgr.c
|
||||
MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
|
||||
MODULE_LICENSE("GPL");
|
||||
*/
|
||||
|
||||
/* 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 *
|
||||
claim_region(struct pcmcia_socket *s, resource_size_t base,
|
||||
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;
|
||||
|
||||
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) {
|
||||
#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
|
||||
* encroach outside the resources which the user supplied.
|
||||
*/
|
||||
static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
|
||||
unsigned long r_end, struct pcmcia_socket *s)
|
||||
static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
|
||||
unsigned long r_start,
|
||||
unsigned long r_end)
|
||||
{
|
||||
struct resource_map *m;
|
||||
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)
|
||||
continue;
|
||||
|
||||
ret = adjust_resource(res, r_start, r_end - r_start + 1);
|
||||
break;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned long align, struct pcmcia_socket *s)
|
||||
static struct resource *__nonstatic_find_io_region(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 pcmcia_align_data data;
|
||||
unsigned long min = base;
|
||||
int ret;
|
||||
|
||||
if (align == 0)
|
||||
align = 0x10000;
|
||||
|
||||
data.mask = align - 1;
|
||||
data.offset = base & data.mask;
|
||||
data.map = &s_data->io_db;
|
||||
|
@ -727,10 +714,97 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||
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,
|
||||
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 pcmcia_align_data data;
|
||||
unsigned long min, max;
|
||||
|
@ -861,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
|||
return -ENODEV;
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
/* If this is the root bus, the risk of hitting
|
||||
* some strange system devices which aren't protected
|
||||
* by either ACPI resource tables or properly requested
|
||||
* resources is too big. Therefore, don't do auto-adding
|
||||
* of resources at the moment.
|
||||
/* If this is the root bus, the risk of hitting some strange
|
||||
* system devices is too high: If a driver isn't loaded, the
|
||||
* resources are not claimed; even if a driver is loaded, it
|
||||
* may not request all resources or even the wrong one. We
|
||||
* 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)
|
||||
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) {
|
||||
#endif
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
||||
"pcmcia: parent PCI bridge window: %pR\n",
|
||||
res);
|
||||
|
@ -887,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
|||
}
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
||||
"pcmcia: parent PCI bridge window: %pR\n",
|
||||
res);
|
||||
|
@ -956,8 +1053,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
|
|||
|
||||
struct pccard_resource_ops pccard_nonstatic_ops = {
|
||||
.validate_mem = pcmcia_nonstatic_validate_mem,
|
||||
.adjust_io_region = nonstatic_adjust_io_region,
|
||||
.find_io = nonstatic_find_io_region,
|
||||
.find_io = nonstatic_find_io,
|
||||
.find_mem = nonstatic_find_mem_region,
|
||||
.add_io = adjust_io,
|
||||
.add_mem = adjust_memory,
|
||||
|
|
|
@ -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_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ MODULE_LICENSE("Dual MPL/GPL");
|
|||
|
||||
typedef struct scsi_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
} scsi_info_t;
|
||||
|
||||
|
@ -105,7 +104,6 @@ static int aha152x_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 0x20;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
@ -160,8 +158,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
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));
|
||||
s.conf = "PCMCIA setup";
|
||||
s.io_port = link->io.BasePort1;
|
||||
s.irq = link->irq.AssignedIRQ;
|
||||
s.irq = link->irq;
|
||||
s.scsiid = host_id;
|
||||
s.reconnect = reconnect;
|
||||
s.parity = parity;
|
||||
|
@ -187,8 +184,6 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -63,7 +63,6 @@ MODULE_LICENSE("Dual MPL/GPL");
|
|||
|
||||
typedef struct scsi_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
} scsi_info_t;
|
||||
|
||||
|
@ -88,7 +87,6 @@ static int fdomain_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 0x10;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
@ -133,8 +131,7 @@ static int fdomain_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
|
@ -144,7 +141,7 @@ static int fdomain_config(struct pcmcia_device *link)
|
|||
release_region(link->io.BasePort1, link->io.NumPorts1);
|
||||
|
||||
/* 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);
|
||||
|
||||
host = __fdomain_16x0_detect(&fdomain_driver_template);
|
||||
|
@ -157,8 +154,6 @@ static int fdomain_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
scsi_scan_host(host);
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1563,13 +1563,6 @@ static int nsp_cs_probe(struct pcmcia_device *link)
|
|||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
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 */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -1646,7 +1639,6 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
|
|||
}
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -1720,10 +1712,8 @@ static int nsp_cs_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto cs_failed;
|
||||
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
if (pcmcia_request_irq(link, &link->irq))
|
||||
if (pcmcia_request_irq(link, nspintr))
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
|
@ -1741,7 +1731,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
|
|||
/* Set port and IRQ */
|
||||
data->BaseAddress = link->io.BasePort1;
|
||||
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",
|
||||
data->BaseAddress, data->NumAddress, data->IrqNumber);
|
||||
|
@ -1764,8 +1754,6 @@ static int nsp_cs_config(struct pcmcia_device *link)
|
|||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
}
|
||||
if (link->io.NumPorts1) {
|
||||
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) {
|
||||
scsi_remove_host(info->host);
|
||||
}
|
||||
link->dev_node = NULL;
|
||||
|
||||
if (link->win) {
|
||||
if (data != NULL) {
|
||||
|
|
|
@ -224,7 +224,6 @@
|
|||
typedef struct scsi_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
struct Scsi_Host *host;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
} scsi_info_t;
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ static struct scsi_host_template qlogicfas_driver_template = {
|
|||
|
||||
typedef struct scsi_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
unsigned short manf_id;
|
||||
} scsi_info_t;
|
||||
|
@ -161,7 +160,6 @@ static int qlogic_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
@ -209,8 +207,7 @@ static int qlogic_config(struct pcmcia_device * link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
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 */
|
||||
if (link->io.NumPorts1 == 32)
|
||||
host = qlogic_detect(&qlogicfas_driver_template, link,
|
||||
link->io.BasePort1 + 16, link->irq.AssignedIRQ);
|
||||
link->io.BasePort1 + 16, link->irq);
|
||||
else
|
||||
host = qlogic_detect(&qlogicfas_driver_template, link,
|
||||
link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
link->io.BasePort1, link->irq);
|
||||
|
||||
if (!host) {
|
||||
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
return 0;
|
||||
|
@ -258,7 +253,7 @@ static void qlogic_release(struct pcmcia_device *link)
|
|||
|
||||
scsi_remove_host(info->host);
|
||||
|
||||
free_irq(link->irq.AssignedIRQ, info->host);
|
||||
free_irq(link->irq, info->host);
|
||||
pcmcia_disable_device(link);
|
||||
|
||||
scsi_host_put(info->host);
|
||||
|
|
|
@ -191,7 +191,6 @@
|
|||
|
||||
struct scsi_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
unsigned short manf_id;
|
||||
};
|
||||
|
@ -719,8 +718,7 @@ SYM53C500_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
|
@ -752,7 +750,7 @@ SYM53C500_config(struct pcmcia_device *link)
|
|||
* 0x320, 0x330, 0x340, 0x350
|
||||
*/
|
||||
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",
|
||||
port_base, irq_level, USE_FAST_PIO);)
|
||||
|
@ -793,8 +791,6 @@ SYM53C500_config(struct pcmcia_device *link)
|
|||
*/
|
||||
data->fast_pio = USE_FAST_PIO;
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
if (scsi_add_host(host, NULL))
|
||||
|
@ -866,7 +862,6 @@ SYM53C500_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ struct serial_info {
|
|||
int manfid;
|
||||
int prodid;
|
||||
int c950ctrl;
|
||||
dev_node_t node[4];
|
||||
int line[4];
|
||||
const struct serial_quirk *quirk;
|
||||
};
|
||||
|
@ -289,8 +288,6 @@ static void serial_remove(struct pcmcia_device *link)
|
|||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_unregister_port(info->line[i]);
|
||||
|
||||
info->p_dev->dev_node = NULL;
|
||||
|
||||
if (!info->slave)
|
||||
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.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
if (do_sound) {
|
||||
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;
|
||||
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++;
|
||||
|
||||
return 0;
|
||||
|
@ -486,7 +477,7 @@ static int simple_config(struct pcmcia_device *link)
|
|||
}
|
||||
if (info->slave) {
|
||||
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;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
|
||||
if (info->multi && (info->manfid == MANFID_3COM))
|
||||
link->conf.ConfigIndex &= ~(0x08);
|
||||
|
||||
|
@ -523,7 +510,7 @@ found_port:
|
|||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0)
|
||||
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,
|
||||
|
@ -586,13 +573,9 @@ static int multi_config(struct pcmcia_device *link)
|
|||
}
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
/* FIXME: comment does not fit, error handling does not fit */
|
||||
printk(KERN_NOTICE
|
||||
"serial_cs: no usable port range found, giving up\n");
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
if (!link->irq)
|
||||
dev_warn(&link->dev,
|
||||
"serial_cs: no usable IRQ found, continuing...\n");
|
||||
|
||||
/*
|
||||
* Apply any configuration quirks.
|
||||
|
@ -615,11 +598,11 @@ static int multi_config(struct pcmcia_device *link)
|
|||
if (link->conf.ConfigIndex == 1 ||
|
||||
link->conf.ConfigIndex == 3) {
|
||||
err = setup_serial(link, info, base2,
|
||||
link->irq.AssignedIRQ);
|
||||
link->irq);
|
||||
base2 = link->io.BasePort1;
|
||||
} else {
|
||||
err = setup_serial(link, info, link->io.BasePort1,
|
||||
link->irq.AssignedIRQ);
|
||||
link->irq);
|
||||
}
|
||||
info->c950ctrl = base2;
|
||||
|
||||
|
@ -633,10 +616,10 @@ static int multi_config(struct pcmcia_device *link)
|
|||
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++)
|
||||
setup_serial(link, info, base2 + (8 * i),
|
||||
link->irq.AssignedIRQ);
|
||||
link->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -720,7 +703,6 @@ static int serial_config(struct pcmcia_device * link)
|
|||
if (info->quirk->post(link))
|
||||
goto failed;
|
||||
|
||||
link->dev_node = &info->node[0];
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -490,7 +490,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
|
|||
break;
|
||||
case SSB_BUSTYPE_PCMCIA:
|
||||
#ifdef CONFIG_SSB_PCMCIAHOST
|
||||
sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
|
||||
sdev->irq = bus->host_pcmcia->irq;
|
||||
dev->parent = &bus->host_pcmcia->dev;
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -180,12 +180,12 @@ static int das16cs_attach(struct comedi_device *dev,
|
|||
}
|
||||
printk("\n");
|
||||
|
||||
ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
|
||||
ret = request_irq(link->irq, das16cs_interrupt,
|
||||
IRQF_SHARED, "cb_das16_cs", dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
printk("irq=%u ", dev->irq);
|
||||
|
||||
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 pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
struct bus_operations *bus;
|
||||
};
|
||||
|
@ -702,10 +701,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
|
|||
link->priv = local;
|
||||
|
||||
/* Initialize the pcmcia_device structure */
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
link->conf.Attributes = 0;
|
||||
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");
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
das16cs_pcmcia_release(link);
|
||||
}
|
||||
/* This points to the parent struct local_info_t struct */
|
||||
if (link->priv)
|
||||
kfree(link->priv);
|
||||
|
@ -740,7 +733,6 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
return -EINVAL;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -769,7 +761,6 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
|
||||
static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
|
||||
|
@ -780,16 +771,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
|||
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)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
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)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %u", link->irq.AssignedIRQ);
|
||||
printk(", irq %u", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -142,7 +142,6 @@ static const dev_info_t dev_info = "pcm-das08";
|
|||
|
||||
struct local_info_t {
|
||||
struct pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
struct bus_operations *bus;
|
||||
};
|
||||
|
@ -172,10 +171,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
|
|||
local->link = link;
|
||||
link->priv = local;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
General socket configuration defaults can go here. In this
|
||||
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");
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
das08_pcmcia_release(link);
|
||||
}
|
||||
|
||||
/* This points to the parent struct local_info_t struct */
|
||||
if (link->priv)
|
||||
|
@ -229,7 +222,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
return -ENODEV;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -266,7 +258,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
|
||||
static void das08_pcmcia_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&link->dev, "das08_pcmcia_config\n");
|
||||
|
@ -277,11 +268,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -292,19 +280,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %u", link->irq.AssignedIRQ);
|
||||
printk(", irq %u", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -380,7 +380,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
return -EIO;
|
||||
iobase = link->io.BasePort1;
|
||||
#ifdef incomplete
|
||||
irq = link->irq.AssignedIRQ;
|
||||
irq = link->irq;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -470,7 +470,6 @@ static const dev_info_t dev_info = "ni_daq_700";
|
|||
|
||||
struct local_info_t {
|
||||
struct pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
struct bus_operations *bus;
|
||||
};
|
||||
|
@ -502,10 +501,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
|
|||
local->link = link;
|
||||
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
|
||||
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");
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
dio700_release(link);
|
||||
}
|
||||
|
||||
/* This points to the parent struct local_info_t struct */
|
||||
if (link->priv)
|
||||
|
@ -577,7 +570,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
}
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -625,7 +617,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
|
||||
static void dio700_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
win_req_t req;
|
||||
int ret;
|
||||
|
||||
|
@ -639,16 +630,8 @@ static void dio700_config(struct pcmcia_device *link)
|
|||
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)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -659,19 +642,10 @@ static void dio700_config(struct pcmcia_device *link)
|
|||
if (ret != 0)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -131,7 +131,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
return -EIO;
|
||||
iobase = link->io.BasePort1;
|
||||
#ifdef incomplete
|
||||
irq = link->irq.AssignedIRQ;
|
||||
irq = link->irq;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -221,7 +221,6 @@ static const dev_info_t dev_info = "ni_daq_dio24";
|
|||
|
||||
struct local_info_t {
|
||||
struct pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
struct bus_operations *bus;
|
||||
};
|
||||
|
@ -253,10 +252,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
|
|||
local->link = link;
|
||||
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
|
||||
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");
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
dio24_release(link);
|
||||
}
|
||||
|
||||
/* This points to the parent local_info_t struct */
|
||||
if (link->priv)
|
||||
|
@ -328,7 +321,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
}
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -376,7 +368,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
|
||||
static void dio24_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
win_req_t req;
|
||||
|
||||
|
@ -390,16 +381,8 @@ static void dio24_config(struct pcmcia_device *link)
|
|||
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)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -410,19 +393,10 @@ static void dio24_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -144,7 +144,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
if (!link)
|
||||
return -EIO;
|
||||
iobase = link->io.BasePort1;
|
||||
irq = link->irq.AssignedIRQ;
|
||||
irq = link->irq;
|
||||
break;
|
||||
default:
|
||||
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 pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
struct bus_operations *bus;
|
||||
};
|
||||
|
@ -229,10 +228,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
|
|||
local->link = link;
|
||||
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
|
||||
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
|
||||
detach().
|
||||
*/
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
labpc_release(link);
|
||||
}
|
||||
|
||||
/* This points to the parent local_info_t struct (may be null) */
|
||||
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? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
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)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
win_req_t req;
|
||||
|
||||
|
@ -367,16 +358,8 @@ static void labpc_config(struct pcmcia_device *link)
|
|||
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)
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -387,19 +370,10 @@ static void labpc_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", irq %d", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -262,17 +262,11 @@ static void cs_detach(struct pcmcia_device *);
|
|||
|
||||
static struct pcmcia_device *cur_dev = NULL;
|
||||
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)
|
||||
{
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
link->io.NumPorts1 = 16;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -292,7 +286,6 @@ static void cs_detach(struct pcmcia_device *link)
|
|||
{
|
||||
DPRINTK("cs_detach(link=%p)\n", link);
|
||||
|
||||
if (link->dev_node)
|
||||
cs_release(link);
|
||||
}
|
||||
|
||||
|
@ -344,14 +337,10 @@ static void mio_cs_config(struct pcmcia_device *link)
|
|||
return;
|
||||
}
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret) {
|
||||
printk("pcmcia_request_irq() returned error: %i\n", ret);
|
||||
}
|
||||
if (!link->irq)
|
||||
dev_info(&link->dev, "no IRQ available\n");
|
||||
|
||||
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)
|
||||
|
@ -369,7 +358,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
dev->driver = &driver_ni_mio_cs;
|
||||
dev->iobase = link->io.BasePort1;
|
||||
|
||||
irq = link->irq.AssignedIRQ;
|
||||
irq = link->irq;
|
||||
|
||||
printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
|
||||
dev->minor, dev->driver->driver_name, dev->iobase, irq);
|
||||
|
|
|
@ -60,7 +60,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
|
|||
|
||||
struct local_info_t {
|
||||
struct pcmcia_device *link;
|
||||
dev_node_t node;
|
||||
int stop;
|
||||
int table_index;
|
||||
char board_name[32];
|
||||
|
@ -1040,10 +1039,6 @@ static int daqp_cs_attach(struct pcmcia_device *link)
|
|||
local->link = link;
|
||||
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
|
||||
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");
|
||||
|
||||
if (link->dev_node) {
|
||||
dev->stop = 1;
|
||||
daqp_cs_release(link);
|
||||
}
|
||||
|
||||
/* Unlink device structure, and free it */
|
||||
dev_table[dev->table_index] = NULL;
|
||||
|
@ -1105,7 +1098,6 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
return -ENODEV;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -1133,7 +1125,6 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
|||
|
||||
static void daqp_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&link->dev, "daqp_cs_config\n");
|
||||
|
@ -1144,16 +1135,9 @@ static void daqp_cs_config(struct pcmcia_device *link)
|
|||
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);
|
||||
ret = pcmcia_request_irq(link, daqp_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
|
@ -1164,23 +1148,10 @@ static void daqp_cs_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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 */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %u", link->irq.AssignedIRQ);
|
||||
printk(", irq %u", link->irq);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include <pcmcia/cistpl.h>
|
||||
#include <pcmcia/cisreg.h>
|
||||
#include <pcmcia/ds.h>
|
||||
#include <pcmcia/mem_op.h>
|
||||
|
||||
#include <asm/system.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.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = &netwave_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
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
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_irq(link, netwave_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -767,7 +762,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
|||
ramBase = ioremap(req.Base, 0x8000);
|
||||
priv->ramBase = ramBase;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
|
|
|
@ -3850,12 +3850,8 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||
if (i != 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Now allocate an interrupt line. Note that this does not
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0)
|
||||
i = pcmcia_request_interrupt(link, wavelan_interrupt);
|
||||
if (!i)
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -3890,7 +3886,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||
break;
|
||||
|
||||
/* Feed device with this info... */
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
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.IOAddrLines = 3;
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.Handler = wavelan_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -4487,7 +4479,6 @@ wavelan_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
ret = wv_hw_config(dev);
|
||||
if (ret) {
|
||||
dev->irq = 0;
|
||||
pcmcia_disable_device(p_dev);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -156,15 +156,12 @@ static int wl_adapter_attach(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = HCF_NUM_IO_PORTS;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
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.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 5;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->priv = link->irq.Instance = dev;
|
||||
link->priv = dev;
|
||||
lp = wl_priv(dev);
|
||||
lp->link = link;
|
||||
|
||||
|
@ -318,11 +315,11 @@ void wl_adapter_insert( struct pcmcia_device *link )
|
|||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
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));
|
||||
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
typedef struct ixj_info_t {
|
||||
int ndev;
|
||||
dev_node_t node;
|
||||
struct ixj *port;
|
||||
} 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);
|
||||
|
||||
info->ndev = 1;
|
||||
info->node.major = PHONE_MAJOR;
|
||||
link->dev_node = &info->node;
|
||||
ixj_get_serial(link, j);
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ static const char driver_name[DEV_NAME_LEN] = "sl811_cs";
|
|||
|
||||
typedef struct local_info_t {
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
} local_info_t;
|
||||
|
||||
static void sl811_cs_release(struct pcmcia_device * link);
|
||||
|
@ -163,7 +162,6 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
|
|||
dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* we need an interrupt */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
|
@ -186,7 +184,6 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
|
|||
static int sl811_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct device *parent = &link->dev;
|
||||
local_info_t *dev = link->priv;
|
||||
int ret;
|
||||
|
||||
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 */
|
||||
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
|
||||
goto failed;
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
} else
|
||||
|
||||
if (!link->irq)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
sprintf(dev->node.dev_name, driver_name);
|
||||
dev->node.major = dev->node.minor = 0;
|
||||
link->dev_node = &dev->node;
|
||||
|
||||
printk(KERN_INFO "%s: index 0x%02x: ",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev_info(&link->dev, "index 0x%02x: ",
|
||||
link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
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,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
printk("\n");
|
||||
|
||||
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
|
||||
if (sl811_hc_init(parent, link->io.BasePort1, link->irq)
|
||||
< 0) {
|
||||
failed:
|
||||
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;
|
||||
link->priv = local;
|
||||
|
||||
/* Initialize */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
link->conf.Attributes = 0;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ typedef struct config_req_t {
|
|||
#define CONF_ENABLE_IRQ 0x01
|
||||
#define CONF_ENABLE_DMA 0x02
|
||||
#define CONF_ENABLE_SPKR 0x04
|
||||
#define CONF_ENABLE_PULSE_IRQ 0x08
|
||||
#define CONF_VALID_CLIENT 0x100
|
||||
|
||||
/* IntType field */
|
||||
|
@ -113,25 +114,7 @@ typedef struct io_req_t {
|
|||
#define IO_DATA_PATH_WIDTH_16 0x08
|
||||
#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 */
|
||||
#define IRQ_MASK 0x0f
|
||||
#define IRQ_NMI_ID 0x01
|
||||
#define IRQ_IOCK_ID 0x02
|
||||
#define IRQ_BERR_ID 0x04
|
||||
|
|
|
@ -62,15 +62,6 @@ struct pcmcia_driver {
|
|||
int pcmcia_register_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 {
|
||||
/* the socket and the device_no [for multifunction devices]
|
||||
uniquely define a pcmcia_device */
|
||||
|
@ -88,13 +79,14 @@ struct pcmcia_device {
|
|||
struct list_head socket_device_list;
|
||||
|
||||
/* deprecated, will be cleaned up soon */
|
||||
dev_node_t *dev_node;
|
||||
u_int open;
|
||||
io_req_t io;
|
||||
irq_req_t irq;
|
||||
config_req_t conf;
|
||||
window_handle_t win;
|
||||
|
||||
/* device setup */
|
||||
unsigned int irq;
|
||||
|
||||
/* Is the device suspended? */
|
||||
u16 suspended:1;
|
||||
|
||||
|
@ -191,7 +183,20 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||
|
||||
/* device configuration */
|
||||
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,
|
||||
config_req_t *req);
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -141,10 +141,6 @@ struct pcmcia_socket {
|
|||
u_short lock_count;
|
||||
pccard_mem_map cis_mem;
|
||||
void __iomem *cis_virt;
|
||||
struct {
|
||||
u_int AssignedIRQ;
|
||||
u_int Config;
|
||||
} irq;
|
||||
io_window_t io[MAX_IO_WIN];
|
||||
pccard_mem_map win[MAX_WIN];
|
||||
struct list_head cis_cache;
|
||||
|
@ -235,6 +231,9 @@ struct pcmcia_socket {
|
|||
/* non-zero if PCMCIA card is present */
|
||||
atomic_t present;
|
||||
|
||||
/* IRQ to be used by PCMCIA devices. May not be IRQ 0. */
|
||||
unsigned int pcmcia_irq;
|
||||
|
||||
#ifdef CONFIG_PCMCIA_IOCTL
|
||||
struct user_info_t *user;
|
||||
wait_queue_head_t queue;
|
||||
|
|
|
@ -142,12 +142,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
|
|||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.NumPorts1 = 16;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
|
||||
/* 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.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
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;
|
||||
|
||||
link->dev_node = &pdacf->node;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -117,7 +117,6 @@ struct snd_pdacf {
|
|||
|
||||
/* pcmcia stuff */
|
||||
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)
|
||||
|
|
|
@ -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.NumPorts1 = 16;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
|
||||
link->irq.Handler = &snd_vx_irq_handler;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
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)
|
||||
{
|
||||
struct vx_core *chip = link->priv;
|
||||
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
|
||||
int ret;
|
||||
|
||||
snd_printdd(KERN_DEBUG "vxpocket_config called\n");
|
||||
|
@ -235,7 +230,7 @@ static int vxpocket_config(struct pcmcia_device *link)
|
|||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -246,10 +241,9 @@ static int vxpocket_config(struct pcmcia_device *link)
|
|||
chip->dev = &link->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;
|
||||
|
||||
link->dev_node = &vxp->node;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -43,7 +43,6 @@ struct snd_vxpocket {
|
|||
|
||||
/* pcmcia stuff */
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
};
|
||||
|
||||
extern struct snd_vx_ops snd_vxpocket_ops;
|
||||
|
|
Loading…
Reference in New Issue