diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 09:09:46 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 09:09:46 -0700 | 
| commit | 54291263519ac2c9bdda68b23b02fef3808deed4 (patch) | |
| tree | d71de8172a6ab2bbe3068aece7d8911eeeb276fd | |
| parent | 46ee9645094ad1eb5b4888882ecaa1fb87dcd2a3 (diff) | |
| parent | acd200bf45487271d54f05938ad9e30f32a530ee (diff) | |
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)
  ...
86 files changed, 1179 insertions, 2139 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 446f43b309df..61bc4e943116 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -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 diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index d94b8f0bd743..aa39bda6441a 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -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; - -	if (info != NULL) { -		/* If we have attached the device to the ATA layer, detach it */ -		if (info->ndev) { -			struct ata_host *host = dev_get_drvdata(dev); -			ata_host_detach(host); -		} -		info->ndev = 0; -		pdev->priv = NULL; -	} +	struct ata_host *host = pdev->priv; + +	if (host) +		ata_host_detach(host); +  	pcmcia_disable_device(pdev); -	kfree(info);  }  static struct pcmcia_device_id pcmcia_devices[] = { diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index d9bf87ca9e83..6f907ebed2d5 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -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: diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 027cb8bf650f..21e05fdc9121 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -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: diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 60c0953d7d00..4ed7288f99db 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -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: diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 17788317c51a..ef044d55cb25 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -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: diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 90b199f97bec..e7956acf2ad6 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -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; diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index a6a70e476bea..c0775c844e08 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -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); diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index dff24dae1485..63c32e3f23ba 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -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); diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h index 0e0363af9ab2..96d0ef31b172 100644 --- a/drivers/char/pcmcia/ipwireless/main.h +++ b/drivers/char/pcmcia/ipwireless/main.h @@ -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; diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 2bb7874a6899..1a2c2c3b068f 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c @@ -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];  		}  	} diff --git a/drivers/char/pcmcia/ipwireless/tty.h b/drivers/char/pcmcia/ipwireless/tty.h index b0deb9168b6b..4da6c201f727 100644 --- a/drivers/char/pcmcia/ipwireless/tty.h +++ b/drivers/char/pcmcia/ipwireless/tty.h @@ -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); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c31a0d913d37..308903ec8bf8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -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; - -    /* add to linked list of devices */ -    sprintf(info->node.dev_name, "mgslpc0"); -    info->node.major = info->node.minor = 0; -    link->dev_node = &info->node; +    info->irq_level = link->irq; -    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); diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index b85450865ff0..0b7815d2581c 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -65,8 +65,7 @@ MODULE_LICENSE("Dual MPL/GPL");  typedef struct ide_info_t {  	struct pcmcia_device	*p_dev;  	struct ide_host		*host; -    int		ndev; -    dev_node_t	node; +	int			ndev;  } 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; diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 94b796d84053..f410d0eb2fef 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -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); -	avmcs_release(link); -	return -ENODEV; +    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 */ diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 8d1d63a02b34..a80a7617f16f 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -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 */ diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c9f2279e21f5..218927e3a4ea 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -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; diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 71b3ddef03bb..1f4feaab21af 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -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,9 +199,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -285,7 +255,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,  static int __devinit sedlbauer_config(struct pcmcia_device *link)  { -    local_info_t *dev = link->priv;      win_req_t *req;      int ret;      IsdnCard_t  icard; @@ -313,17 +282,6 @@ static int __devinit sedlbauer_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) -		    goto failed; -    } -	 -    /*         This actually configures the PCMCIA socket -- setting up         the I/O windows and the interrupt mapping, and putting the         card and host interface into "Memory and IO" mode. @@ -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; diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index d010a0da8e19..5771955cc532 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -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; diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 689d6a79ffc0..87b2b8ff331e 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -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: diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 757f87bb1db3..30b7cf70fbe6 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -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,8 +307,7 @@ static void tc574_detach(struct pcmcia_device *link)  	dev_dbg(&link->dev, "3c574_detach()\n"); -	if (link->dev_node) -		unregister_netdev(dev); +	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, diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 091e0b00043e..5ab589d3b385 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -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,8 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)      dev_dbg(&link->dev, "3c589_detach\n"); -    if (link->dev_node) -	unregister_netdev(dev); +    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, diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 9f3d593f14ed..59f6fa3c9ddc 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -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,8 +193,7 @@ 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); +    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 */ +	/* 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), diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 21d9c9d815d1..5643f94541bc 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -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,18 +194,16 @@ 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"); +    dev_dbg(&link->dev, "unregister...\n"); -	unregister_netdev(dev); +    unregister_netdev(dev); -	/* -	 * this is necessary because we register our IRQ separately -	 * from card services. -	 */ -	if (dev->irq) +    /* +     * this is necessary because we register our IRQ separately +     * from card services. +     */ +    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; diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index b9dc80b9d04a..6580d78397d1 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -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,8 +273,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)      dev_dbg(&link->dev, "fmvj18x_detach\n"); -    if (link->dev_node) -	unregister_netdev(dev); +    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", diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 37f4a6fdc3ef..2e42d80f8cae 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -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,8 +189,7 @@ static void ibmtr_detach(struct pcmcia_device *link)       */      ti->sram_phys |= 1; -    if (link->dev_node) -	unregister_netdev(dev); +    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, diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index c717b143f11a..d8a3b3cf246e 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -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,8 +490,7 @@ static void nmclan_detach(struct pcmcia_device *link)      dev_dbg(&link->dev, "nmclan_detach\n"); -    if (link->dev_node) -	unregister_netdev(dev); +    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], diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 4c0368de1815..6f77a768ba88 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -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,8 +286,7 @@ static void pcnet_detach(struct pcmcia_device *link)  	dev_dbg(&link->dev, "pcnet_detach\n"); -	if (link->dev_node) -		unregister_netdev(dev); +	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): ", diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index ccc553782a0d..59796e7d09c4 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -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,8 +359,7 @@ static void smc91c92_detach(struct pcmcia_device *link)      dev_dbg(&link->dev, "smc91c92_detach\n"); -    if (link->dev_node) -	unregister_netdev(dev); +    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, diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 4d1802e457be..5e6b62ba8887 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -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,8 +557,7 @@ xirc2ps_detach(struct pcmcia_device *link)      dev_dbg(&link->dev, "detach\n"); -    if (link->dev_node) -	unregister_netdev(dev); +    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, diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index f6036fb42319..33bdc6a84e81 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -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,9 +173,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -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) -			goto failed; -	} +	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); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 32407911842f..c2746fc7f2be 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -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,9 +188,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -278,15 +238,9 @@ static int atmel_config(struct pcmcia_device *link)  	if (pcmcia_loop_config(link, atmel_config_check, NULL))  		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; +	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: diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 609e7051e018..0e99b634267c 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -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); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index a36501dbbe02..db72461c486b 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -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; -	} +	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); -		if (ret) -			goto failed; -	} +	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: diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 6d55439a7b97..08e4e3908003 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -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,8 +807,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	if (cfg->io.nwin != 1) { @@ -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"); -			goto out1; -		} -	} +	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"); diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 1d4ada188eda..03056ab73032 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -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,8 +139,7 @@ static void orinoco_cs_detach(struct pcmcia_device *link)  {  	struct orinoco_private *priv = link->priv; -	if (link->dev_node) -		orinoco_if_del(priv); +	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: diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 59bda240fdc2..41b9ce425855 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -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,8 +213,7 @@ static void spectrum_cs_detach(struct pcmcia_device *link)  {  	struct orinoco_private *priv = link->priv; -	if (link->dev_node) -		orinoco_if_del(priv); +	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: diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 11865ea21875..f7d2a34ca531 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -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,8 +378,7 @@ static void ray_detach(struct pcmcia_device *link)  	del_timer(&local->timer);  	if (link->priv) { -		if (link->dev_node) -			unregister_netdev(dev); +		unregister_netdev(dev);  		free_netdev(dev);  	}  	dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); @@ -417,10 +411,10 @@ static int ray_config(struct pcmcia_device *link)  	/* Now allocate an interrupt line.  Note that this does not  	   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); diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index 1e23b7f4cca7..9f01ddb19748 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h @@ -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     */ diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index 8bce1a550a22..8816e371fd0e 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h @@ -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 diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 7b9621de239f..5e5d24c1ce2b 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -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);  } diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 7dd370fa3439..fd8cfe95f0a3 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -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; diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index a44733d44ca1..d0f5ad306078 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -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 diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 4dae3613c458..d006e8beab9c 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -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 diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 9e84d039de41..eae9cbe37a3e 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -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 diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index e6ab2a47d8cb..9a58862f1401 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -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;  } diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 854959cada3a..60d428be0b07 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -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);  		}  	} +	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;  } @@ -1362,106 +1359,6 @@ 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   * @info:	returns the number of tuples in the (valid) CIS, or 0 diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c3383750e333..976d80706eae 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -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; diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index f95864c2191e..4126a75445ea 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -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); @@ -89,6 +87,14 @@ struct pccard_resource_ops {  /* + * 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; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 041eee43fd8d..7ef7adee5e4f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -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; diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index a7cfc7964c7c..0ad06a3bd562 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -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; diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c new file mode 100644 index 000000000000..4a65eaf96b0a --- /dev/null +++ b/drivers/pcmcia/pcmcia_cis.c @@ -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); + diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 7631faa0cadd..ef0c5f133691 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -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); diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 7c3d03bb4f30..29f91fac1dff 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -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,9 +454,9 @@ 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)) -				c->Option |= COR_LEVEL_REQ; +		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. + * 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. + */ +int __must_check pcmcia_request_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, IRQF_SHARED, +			p_dev->devname, p_dev->priv); +	if (!ret) +		p_dev->_irq = 1; + +	return ret; +} +EXPORT_SYMBOL(pcmcia_request_irq); + + +/** + * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first   * - * 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_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"); +	} +	if (ret) +		dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n"); +	else +		p_dev->_irq = 1; + +	return ret; +} /* 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;  } -#endif -int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) +/** + * 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; -	config_t *c; -	int ret = -EINVAL, irq = 0; -	int type; +	unsigned int try, irq; +	u32 mask = s->irq_mask; +	int ret = -ENODEV; -	mutex_lock(&s->ops_mutex); +	for (try = 0; try < 64; try++) { +		irq = try % 32; -	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; +		/* 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; +		}  	} -	/* 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"); +	return ret; +} -	/* If the interrupt is already assigned, it must be the same */ -	if (s->irq.AssignedIRQ != 0) -		irq = s->irq.AssignedIRQ; +void pcmcia_cleanup_irq(struct pcmcia_socket *s) +{ +	pcmcia_used_irq[s->pcmcia_irq]--; +	s->pcmcia_irq = 0; +} -#ifdef CONFIG_PCMCIA_PROBE -	if (!irq) { -		int try; -		u32 mask = s->irq_mask; -		void *data = p_dev; /* something unique to this device */ +#else /* CONFIG_PCMCIA_PROBE */ -		for (try = 0; try < 64; try++) { -			irq = try % 32; +static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) +{ +	return -EINVAL; +} -			/* marked as available by driver, and not blocked by userspace? */ -			if (!((mask >> irq) & 1)) -				continue; +void pcmcia_cleanup_irq(struct pcmcia_socket *s) +{ +	s->pcmcia_irq = 0; +	return; +} -			/* avoid an IRQ which is already used by a PCMCIA card */ -			if ((try < 32) && pcmcia_used_irq[irq]) -				continue; +#endif  /* CONFIG_PCMCIA_PROBE */ -			/* register the correct driver, if possible, of check whether -			 * registering a dummy handle works, i.e. if the IRQ isn't -			 * marked as used by the kernel resource management core */ -			ret = request_irq(irq, -					  (req->Handler) ? req->Handler : test_action, -					  type, -					  p_dev->devname, -					  (req->Handler) ? p_dev->priv : data); -			if (!ret) { -				if (!req->Handler) -					free_irq(irq, data); -				break; -			} -		} -	} -#endif -	/* only assign PCI irq if no IRQ already assigned */ -	if (ret && !s->irq.AssignedIRQ) { -		if (!s->pci_irq) { -			dev_printk(KERN_INFO, &s->dev, "no IRQ found\n"); -			goto out; -		} -		type = IRQF_SHARED; -		irq = s->pci_irq; -	} -	if (ret && req->Handler) { -		ret = request_irq(irq, req->Handler, type, -				  p_dev->devname, p_dev->priv); -		if (ret) { -			dev_printk(KERN_INFO, &s->dev, -				"request_irq() failed\n"); -			goto out; -		} -	} +/** + * 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; -	/* Make sure the fact the request type was overridden is passed back */ -	if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { -		req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; -		dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " -			"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"); +	if (p_dev->irq) +		return 0; + +	/* already assigned? */ +	if (s->pcmcia_irq) { +		p_dev->irq = s->pcmcia_irq; +		return 0;  	} -	c->irq.Attributes = req->Attributes; -	s->irq.AssignedIRQ = req->AssignedIRQ = irq; -	s->irq.Config++; -	c->state |= CONFIG_IRQ_REQ; -	p_dev->_irq = 1; +	/* prefer an exclusive ISA irq */ +	if (!pcmcia_setup_isa_irq(p_dev, 0)) +		return 0; -#ifdef CONFIG_PCMCIA_PROBE -	pcmcia_used_irq[irq]++; -#endif +	/* but accept a shared ISA irq */ +	if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED)) +		return 0; -	ret = 0; -out: -	mutex_unlock(&s->ops_mutex); -	return ret; -} /* pcmcia_request_irq */ -EXPORT_SYMBOL(pcmcia_request_irq); +	/* 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); - diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c new file mode 100644 index 000000000000..d0bf35021065 --- /dev/null +++ b/drivers/pcmcia/rsrc_iodyn.c @@ -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); diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ffa5f3cae57b..142efac3c387 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -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,118 +32,44 @@ static int static_init(struct pcmcia_socket *s)  	return 0;  } - -struct pccard_resource_ops pccard_static_ops = { -	.validate_mem = NULL, -	.adjust_io_region = NULL, -	.find_io = NULL, -	.find_mem = NULL, -	.add_io = NULL, -	.add_mem = NULL, -	.init = static_init, -	.exit = NULL, -}; -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 *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 = b; -		res->end = b + n - 1; +		res->start = start; +		res->end = start + end - 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) +static int static_find_io(struct pcmcia_socket *s, unsigned int attr, +			unsigned int *base, unsigned int num, +			unsigned int align)  { -	struct pcmcia_align_data *data = align_data; -	resource_size_t start; +	if (!s->io_offset) +		return -EINVAL; +	*base = s->io_offset | (*base & 0x0fff); -	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); +	return 0;  } -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 = { +struct pccard_resource_ops pccard_static_ops = {  	.validate_mem = NULL, -	.adjust_io_region = iodyn_adjust_io_region, -	.find_io = iodyn_find_io_region, +	.find_io = static_find_io,  	.find_mem = NULL,  	.add_io = NULL,  	.add_mem = NULL,  	.init = static_init,  	.exit = NULL,  }; -EXPORT_SYMBOL(pccard_iodyn_ops); +EXPORT_SYMBOL(pccard_static_ops); + -#endif /* CONFIG_PCCARD_IODYN */ +MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("rsrc_nonstatic"); diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index a6eb7b59ba9f..dcd1a4ad3d63 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -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' */ @@ -70,27 +72,13 @@ 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)  {  	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, diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 83ace277426c..424e576f3acb 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -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;  } diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 528733b4a392..9d70aef99227 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -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; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 914040684079..21b141151dfc 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -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; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 021246454872..0f0e112c3f8e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -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,8 +1639,7 @@ 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; +		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  		/* IO window settings */  		p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -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)) -			goto cs_failed; -	} +	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) { diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 8c61a4fe1db9..d68c9f267c5e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -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; diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index f85f094870b4..f0fc6baed9fc 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -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); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index e7564d8f0cbf..a51164171179 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -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; diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 8cfa5b12ea7a..dadd686c9801 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -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: diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 80ff7d9e60de..bc9bdb277bec 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -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; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 5632991760af..30b522c0bf2c 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -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); -	} +	((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,8 +733,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -769,7 +761,6 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,  static void das16cs_pcmcia_config(struct pcmcia_device *link)  { -	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) -			goto failed; -	} +	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); diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9164ce158dcd..896d25bc85b5 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -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); -	} +	((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,8 +222,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -266,7 +258,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,  static void das08_pcmcia_config(struct pcmcia_device *link)  { -	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) -			goto failed; -	} +	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); diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7ea64538e055..06dd44ff1a95 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -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); -	} +	((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,8 +570,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -625,7 +617,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,  static void dio700_config(struct pcmcia_device *link)  { -	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) -			goto failed; -	} +	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); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index ddc312b5d20d..7bfe08b01fe9 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -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); -	} +	((struct local_info_t *)link->priv)->stop = 1; +	dio24_release(link);  	/* This points to the parent local_info_t struct */  	if (link->priv) @@ -328,8 +321,7 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,  	}  	/* Do we need to allocate an interrupt? */ -	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) -		p_dev->conf.Attributes |= CONF_ENABLE_IRQ; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -376,7 +368,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,  static void dio24_config(struct pcmcia_device *link)  { -	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) -			goto failed; -	} +	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); diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 8ad1055a5cc1..fd8d3e9520a0 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -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); -	} +	((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) -			goto failed; -	} +	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); diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index dc4849a40c97..1e8aebae8ae8 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -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,8 +286,7 @@ static void cs_detach(struct pcmcia_device *link)  {  	DPRINTK("cs_detach(link=%p)\n", link); -	if (link->dev_node) -		cs_release(link); +	cs_release(link);  }  static int mio_cs_suspend(struct pcmcia_device *link) @@ -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); diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3325f24448b5..1786db2f3378 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -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); -	} +	dev->stop = 1; +	daqp_cs_release(link);  	/* Unlink device structure, and free it */  	dev_table[dev->table_index] = NULL; @@ -1105,8 +1098,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -1133,7 +1125,6 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,  static void daqp_cs_config(struct pcmcia_device *link)  { -	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); -		if (ret) -			goto failed; -	} +	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); diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c index 3875a722d12b..f1ee2cbc8407 100644 --- a/drivers/staging/netwave/netwave_cs.c +++ b/drivers/staging/netwave/netwave_cs.c @@ -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); diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c index 04f691d127b4..37fa85517a58 100644 --- a/drivers/staging/wavelan/wavelan_cs.c +++ b/drivers/staging/wavelan/wavelan_cs.c @@ -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;    } diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 9da42e66085e..c9d99d88b786 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -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)); diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index d442fd35620a..99cb2246ac72 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -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; diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 39d253e841f6..58cb73c8420a 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -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,8 +162,7 @@ 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; +	p_dev->conf.Attributes |= CONF_ENABLE_IRQ;  	/* IO window settings */  	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; @@ -186,7 +184,6 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,  static int sl811_cs_config(struct pcmcia_device *link)  {  	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; diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 75fa3530345b..57d8d0393567 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -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 diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index aab3c13dc310..c180165fbd3e 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -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); diff --git a/include/pcmcia/mem_op.h b/include/pcmcia/mem_op.h deleted file mode 100644 index 0fa06e5d5376..000000000000 --- a/include/pcmcia/mem_op.h +++ /dev/null @@ -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 */ diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 344705cb42f4..764281b29218 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.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; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index edaa729126bb..df110df52a8b 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -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: diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h index b0601838112d..a0a7ec64222a 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h @@ -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) diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cfd1438bcc64..624b47a85f0a 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -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: diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index 27ea002294c0..ea4df16a28ef 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h @@ -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;  | 
