Browse Source

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)
  ...
Linus Torvalds 15 years ago
parent
commit
5429126351
86 changed files with 1179 additions and 2139 deletions
  1. 13 0
      Documentation/pcmcia/driver-changes.txt
  2. 8 39
      drivers/ata/pata_pcmcia.c
  3. 2 9
      drivers/bluetooth/bluecard_cs.c
  4. 2 9
      drivers/bluetooth/bt3c_cs.c
  5. 2 9
      drivers/bluetooth/btuart_cs.c
  6. 2 9
      drivers/bluetooth/dtl1_cs.c
  7. 1 8
      drivers/char/pcmcia/cm4000_cs.c
  8. 0 5
      drivers/char/pcmcia/cm4040_cs.c
  9. 3 16
      drivers/char/pcmcia/ipwireless/main.c
  10. 0 1
      drivers/char/pcmcia/ipwireless/main.h
  11. 5 14
      drivers/char/pcmcia/ipwireless/tty.c
  12. 1 2
      drivers/char/pcmcia/ipwireless/tty.h
  13. 5 17
      drivers/char/pcmcia/synclink_cs.c
  14. 7 13
      drivers/ide/ide-cs.c
  15. 9 67
      drivers/isdn/hardware/avm/avm_cs.c
  16. 7 56
      drivers/isdn/hisax/avma1_cs.c
  17. 5 35
      drivers/isdn/hisax/elsa_cs.c
  18. 5 55
      drivers/isdn/hisax/sedlbauer_cs.c
  19. 5 45
      drivers/isdn/hisax/teles_cs.c
  20. 0 3
      drivers/mtd/maps/pcmciamtd.c
  21. 3 12
      drivers/net/pcmcia/3c574_cs.c
  22. 4 12
      drivers/net/pcmcia/3c589_cs.c
  23. 5 16
      drivers/net/pcmcia/axnet_cs.c
  24. 10 19
      drivers/net/pcmcia/com20020_cs.c
  25. 3 15
      drivers/net/pcmcia/fmvj18x_cs.c
  26. 4 12
      drivers/net/pcmcia/ibmtr_cs.c
  27. 3 11
      drivers/net/pcmcia/nmclan_cs.c
  28. 3 13
      drivers/net/pcmcia/pcnet_cs.c
  29. 3 14
      drivers/net/pcmcia/smc91c92_cs.c
  30. 3 33
      drivers/net/pcmcia/xirc2ps_cs.c
  31. 7 65
      drivers/net/wireless/airo_cs.c
  32. 5 65
      drivers/net/wireless/atmel_cs.c
  33. 1 4
      drivers/net/wireless/b43/pcmcia.c
  34. 8 30
      drivers/net/wireless/hostap/hostap_cs.c
  35. 6 15
      drivers/net/wireless/libertas/if_cs.c
  36. 3 24
      drivers/net/wireless/orinoco/orinoco_cs.c
  37. 3 24
      drivers/net/wireless/orinoco/spectrum_cs.c
  38. 3 12
      drivers/net/wireless/ray_cs.c
  39. 0 1
      drivers/net/wireless/ray_cs.h
  40. 0 1
      drivers/net/wireless/wl3501.h
  41. 5 18
      drivers/net/wireless/wl3501_cs.c
  42. 3 10
      drivers/parport/parport_cs.c
  43. 1 21
      drivers/pcmcia/Kconfig
  44. 6 3
      drivers/pcmcia/Makefile
  45. 1 1
      drivers/pcmcia/bfin_cf_pcmcia.c
  46. 0 1
      drivers/pcmcia/cardbus.c
  47. 9 112
      drivers/pcmcia/cistpl.c
  48. 0 1
      drivers/pcmcia/cs.c
  49. 15 7
      drivers/pcmcia/cs_internal.h
  50. 12 22
      drivers/pcmcia/ds.c
  51. 1 1
      drivers/pcmcia/omap_cf.c
  52. 356 0
      drivers/pcmcia/pcmcia_cis.c
  53. 9 14
      drivers/pcmcia/pcmcia_ioctl.c
  54. 162 472
      drivers/pcmcia/pcmcia_resource.c
  55. 172 0
      drivers/pcmcia/rsrc_iodyn.c
  56. 19 93
      drivers/pcmcia/rsrc_mgr.c
  57. 130 34
      drivers/pcmcia/rsrc_nonstatic.c
  58. 0 7
      drivers/pcmcia/yenta_socket.c
  59. 2 7
      drivers/scsi/pcmcia/aha152x_stub.c
  60. 2 7
      drivers/scsi/pcmcia/fdomain_stub.c
  61. 5 18
      drivers/scsi/pcmcia/nsp_cs.c
  62. 0 1
      drivers/scsi/pcmcia/nsp_cs.h
  63. 4 9
      drivers/scsi/pcmcia/qlogic_stub.c
  64. 2 7
      drivers/scsi/pcmcia/sym53c500_cs.c
  65. 9 27
      drivers/serial/serial_cs.c
  66. 1 1
      drivers/ssb/main.c
  67. 10 35
      drivers/staging/comedi/drivers/cb_das16_cs.c
  68. 7 28
      drivers/staging/comedi/drivers/das08_cs.c
  69. 8 34
      drivers/staging/comedi/drivers/ni_daq_700.c
  70. 8 34
      drivers/staging/comedi/drivers/ni_daq_dio24.c
  71. 8 34
      drivers/staging/comedi/drivers/ni_labpc_cs.c
  72. 4 15
      drivers/staging/comedi/drivers/ni_mio_cs.c
  73. 8 37
      drivers/staging/comedi/drivers/quatech_daqp_cs.c
  74. 2 7
      drivers/staging/netwave/netwave_cs.c
  75. 3 12
      drivers/staging/wavelan/wavelan_cs.c
  76. 3 6
      drivers/staging/wlags49_h2/wl_cs.c
  77. 0 3
      drivers/telephony/ixj_pcmcia.c
  78. 7 21
      drivers/usb/host/sl811_cs.c
  79. 1 18
      include/pcmcia/cs.h
  80. 17 12
      include/pcmcia/ds.h
  81. 0 116
      include/pcmcia/mem_op.h
  82. 3 4
      include/pcmcia/ss.h
  83. 3 9
      sound/pcmcia/pdaudiocf/pdaudiocf.c
  84. 0 1
      sound/pcmcia/pdaudiocf/pdaudiocf.h
  85. 2 8
      sound/pcmcia/vx/vxpocket.c
  86. 0 1
      sound/pcmcia/vx/vxpocket.h

+ 13 - 0
Documentation/pcmcia/driver-changes.txt

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

+ 8 - 39
drivers/ata/pata_pcmcia.c

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

+ 2 - 9
drivers/bluetooth/bluecard_cs.c

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

+ 2 - 9
drivers/bluetooth/bt3c_cs.c

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

+ 2 - 9
drivers/bluetooth/btuart_cs.c

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

+ 2 - 9
drivers/bluetooth/dtl1_cs.c

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

+ 1 - 8
drivers/char/pcmcia/cm4000_cs.c

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

+ 0 - 5
drivers/char/pcmcia/cm4040_cs.c

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

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

+ 0 - 1
drivers/char/pcmcia/ipwireless/main.h

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

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

+ 1 - 2
drivers/char/pcmcia/ipwireless/tty.h

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

+ 5 - 17
drivers/char/pcmcia/synclink_cs.c

@@ -220,7 +220,6 @@ typedef struct _mgslpc_info {
 
 
 	/* PCMCIA support */
 	/* PCMCIA support */
 	struct pcmcia_device	*p_dev;
 	struct pcmcia_device	*p_dev;
-	dev_node_t	      node;
 	int		      stop;
 	int		      stop;
 
 
 	/* SPPP/Cisco HDLC device parts */
 	/* SPPP/Cisco HDLC device parts */
@@ -552,10 +551,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
 
 
     /* Initialize the struct pcmcia_device structure */
     /* Initialize the struct pcmcia_device structure */
 
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = NULL;
-
     link->conf.Attributes = 0;
     link->conf.Attributes = 0;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
 
@@ -608,9 +603,7 @@ static int mgslpc_config(struct pcmcia_device *link)
     link->conf.ConfigIndex = 8;
     link->conf.ConfigIndex = 8;
     link->conf.Present = PRESENT_OPTION;
     link->conf.Present = PRESENT_OPTION;
 
 
-    link->irq.Handler     = mgslpc_isr;
-
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_irq(link, mgslpc_isr);
     if (ret)
     if (ret)
 	    goto failed;
 	    goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
     ret = pcmcia_request_configuration(link, &link->conf);
@@ -618,17 +611,12 @@ static int mgslpc_config(struct pcmcia_device *link)
 	    goto failed;
 	    goto failed;
 
 
     info->io_base = link->io.BasePort1;
     info->io_base = link->io.BasePort1;
-    info->irq_level = link->irq.AssignedIRQ;
-
-    /* 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)
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
-	    printk(", irq %d", link->irq.AssignedIRQ);
+	    printk(", irq %d", link->irq);
     if (link->io.NumPorts1)
     if (link->io.NumPorts1)
 	    printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 	    printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 		   link->io.BasePort1+link->io.NumPorts1-1);
 		   link->io.BasePort1+link->io.NumPorts1-1);

+ 7 - 13
drivers/ide/ide-cs.c

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

+ 9 - 67
drivers/isdn/hardware/avm/avm_cs.c

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

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

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

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

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

+ 0 - 3
drivers/mtd/maps/pcmciamtd.c

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

+ 3 - 12
drivers/net/pcmcia/3c574_cs.c

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

+ 4 - 12
drivers/net/pcmcia/3c589_cs.c

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

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

+ 10 - 19
drivers/net/pcmcia/com20020_cs.c

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

+ 3 - 15
drivers/net/pcmcia/fmvj18x_cs.c

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

+ 4 - 12
drivers/net/pcmcia/ibmtr_cs.c

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

+ 3 - 11
drivers/net/pcmcia/nmclan_cs.c

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

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

+ 3 - 14
drivers/net/pcmcia/smc91c92_cs.c

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

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

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

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

+ 1 - 4
drivers/net/wireless/b43/pcmcia.c

@@ -98,10 +98,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
 	if (res != 0)
 	if (res != 0)
 		goto err_disable;
 		goto err_disable;
 
 
-	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-	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;
 		goto err_disable;
 
 
 	res = pcmcia_request_configuration(dev, &dev->conf);
 	res = pcmcia_request_configuration(dev, &dev->conf);

+ 8 - 30
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 local_info::hw_priv */
 struct hostap_cs_priv {
 struct hostap_cs_priv {
-	dev_node_t node;
 	struct pcmcia_device *link;
 	struct pcmcia_device *link;
 	int sandisk_connectplus;
 	int sandisk_connectplus;
 };
 };
@@ -556,15 +555,7 @@ static int prism2_config_check(struct pcmcia_device *p_dev,
 		p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
 		p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
 
 
 	/* Do we need to allocate an interrupt? */
 	/* Do we need to allocate an interrupt? */
-	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-	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 */
 	/* IO window settings */
 	PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
 	PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
@@ -633,21 +624,10 @@ static int prism2_config(struct pcmcia_device *link)
 	local = iface->local;
 	local = iface->local;
 	local->hw_priv = hw_priv;
 	local->hw_priv = hw_priv;
 	hw_priv->link = link;
 	hw_priv->link = link;
-	strcpy(hw_priv->node.dev_name, dev->name);
-	link->dev_node = &hw_priv->node;
 
 
-	/*
-	 * 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
 	 * This actually configures the PCMCIA socket -- setting up
@@ -658,7 +638,7 @@ static int prism2_config(struct pcmcia_device *link)
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
-	dev->irq = link->irq.AssignedIRQ;
+	dev->irq = link->irq;
 	dev->base_addr = link->io.BasePort1;
 	dev->base_addr = link->io.BasePort1;
 
 
 	/* Finally, report what we've done */
 	/* Finally, report what we've done */
@@ -668,7 +648,7 @@ static int prism2_config(struct pcmcia_device *link)
 		printk(", Vpp %d.%d", link->conf.Vpp / 10,
 		printk(", Vpp %d.%d", link->conf.Vpp / 10,
 		       link->conf.Vpp % 10);
 		       link->conf.Vpp % 10);
 	if (link->conf.Attributes & CONF_ENABLE_IRQ)
 	if (link->conf.Attributes & CONF_ENABLE_IRQ)
-		printk(", irq %d", link->irq.AssignedIRQ);
+		printk(", irq %d", link->irq);
 	if (link->io.NumPorts1)
 	if (link->io.NumPorts1)
 		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 		       link->io.BasePort1+link->io.NumPorts1-1);
 		       link->io.BasePort1+link->io.NumPorts1-1);
@@ -682,11 +662,9 @@ static int prism2_config(struct pcmcia_device *link)
 	sandisk_enable_wireless(dev);
 	sandisk_enable_wireless(dev);
 
 
 	ret = prism2_hw_config(dev, 1);
 	ret = prism2_hw_config(dev, 1);
-	if (!ret) {
+	if (!ret)
 		ret = hostap_hw_ready(dev);
 		ret = hostap_hw_ready(dev);
-		if (ret == 0 && local->ddev)
-			strcpy(hw_priv->node.dev_name, local->ddev->name);
-	}
+
 	return ret;
 	return ret;
 
 
  failed:
  failed:

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

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

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

+ 3 - 12
drivers/net/wireless/ray_cs.c

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

+ 0 - 1
drivers/net/wireless/ray_cs.h

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

+ 0 - 1
drivers/net/wireless/wl3501.h

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

+ 5 - 18
drivers/net/wireless/wl3501_cs.c

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

+ 3 - 10
drivers/parport/parport_cs.c

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

+ 1 - 21
drivers/pcmcia/Kconfig

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

+ 6 - 3
drivers/pcmcia/Makefile

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

+ 1 - 1
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)) {
 	if (bfin_cf_present(cf->cd_pfx)) {
 		*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
 		*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
-		s->irq.AssignedIRQ = 0;
+		s->pcmcia_irq = 0;
 		s->pci_irq = cf->irq;
 		s->pci_irq = cf->irq;
 
 
 	} else
 	} else

+ 0 - 1
drivers/pcmcia/cardbus.c

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

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

+ 0 - 1
drivers/pcmcia/cs.c

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

+ 15 - 7
drivers/pcmcia/cs_internal.h

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

+ 12 - 22
drivers/pcmcia/ds.c

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

+ 1 - 1
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;
 		*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
 		cf = container_of(s, struct omap_cf_socket, socket);
 		cf = container_of(s, struct omap_cf_socket, socket);
-		s->irq.AssignedIRQ = 0;
+		s->pcmcia_irq = 0;
 		s->pci_irq = cf->irq;
 		s->pci_irq = cf->irq;
 	} else
 	} else
 		*sp = 0;
 		*sp = 0;

+ 356 - 0
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);
+

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

+ 162 - 472
drivers/pcmcia/pcmcia_resource.c

@@ -23,6 +23,8 @@
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
+#include <asm/irq.h>
+
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cs.h>
@@ -38,29 +40,6 @@ static int io_speed;
 module_param(io_speed, int, 0444);
 module_param(io_speed, int, 0444);
 
 
 
 
-#ifdef CONFIG_PCMCIA_PROBE
-#include <asm/irq.h>
-/* mask of IRQs already reserved by other cards, we should avoid using them */
-static u8 pcmcia_used_irq[NR_IRQS];
-#endif
-
-static int pcmcia_adjust_io_region(struct resource *res, unsigned long start,
-				   unsigned long end, struct pcmcia_socket *s)
-{
-	if (s->resource_ops->adjust_io_region)
-		return s->resource_ops->adjust_io_region(res, start, end, s);
-	return -ENOMEM;
-}
-
-static struct resource *pcmcia_find_io_region(unsigned long base, int num,
-					      unsigned long align,
-					      struct pcmcia_socket *s)
-{
-	if (s->resource_ops->find_io)
-		return s->resource_ops->find_io(base, num, align, s);
-	return NULL;
-}
-
 int pcmcia_validate_mem(struct pcmcia_socket *s)
 int pcmcia_validate_mem(struct pcmcia_socket *s)
 {
 {
 	if (s->resource_ops->validate_mem)
 	if (s->resource_ops->validate_mem)
@@ -86,8 +65,7 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
 static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
 static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
 			  unsigned int *base, unsigned int num, u_int lines)
 			  unsigned int *base, unsigned int num, u_int lines)
 {
 {
-	int i;
-	unsigned int try, align;
+	unsigned int align;
 
 
 	align = (*base) ? (lines ? 1<<lines : 0) : 1;
 	align = (*base) ? (lines ? 1<<lines : 0) : 1;
 	if (align && (align < num)) {
 	if (align && (align < num)) {
@@ -104,50 +82,8 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
 		       *base, align);
 		       *base, align);
 		align = 0;
 		align = 0;
 	}
 	}
-	if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
-		*base = s->io_offset | (*base & 0x0fff);
-		return 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 */
 } /* alloc_io_space */
 
 
 
 
@@ -187,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
 	config_t *c;
 	config_t *c;
 	int addr;
 	int addr;
 	u_char val;
 	u_char val;
+	int ret = 0;
 
 
 	if (!p_dev || !p_dev->function_config)
 	if (!p_dev || !p_dev->function_config)
 		return -EINVAL;
 		return -EINVAL;
@@ -203,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
 	}
 	}
 
 
 	addr = (c->ConfigBase + reg->Offset) >> 1;
 	addr = (c->ConfigBase + reg->Offset) >> 1;
-	mutex_unlock(&s->ops_mutex);
 
 
 	switch (reg->Action) {
 	switch (reg->Action) {
 	case CS_READ:
 	case CS_READ:
-		pcmcia_read_cis_mem(s, 1, addr, 1, &val);
+		ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val);
 		reg->Value = val;
 		reg->Value = val;
 		break;
 		break;
 	case CS_WRITE:
 	case CS_WRITE:
@@ -216,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
 		break;
 		break;
 	default:
 	default:
 		dev_dbg(&s->dev, "Invalid conf register request\n");
 		dev_dbg(&s->dev, "Invalid conf register request\n");
-		return -EINVAL;
+		ret = -EINVAL;
 		break;
 		break;
 	}
 	}
-	return 0;
+	mutex_unlock(&s->ops_mutex);
+	return ret;
 } /* pcmcia_access_configuration_register */
 } /* pcmcia_access_configuration_register */
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
 
@@ -275,19 +212,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 		goto unlock;
 		goto unlock;
 	}
 	}
 
 
-	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
-		if (mod->Attributes & CONF_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;
 		ret = -EINVAL;
 		goto unlock;
 		goto unlock;
 	}
 	}
@@ -422,52 +349,6 @@ out:
 } /* pcmcia_release_io */
 } /* pcmcia_release_io */
 
 
 
 
-static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
-{
-	struct pcmcia_socket *s = p_dev->socket;
-	config_t *c;
-	int ret = -EINVAL;
-
-	mutex_lock(&s->ops_mutex);
-
-	c = p_dev->function_config;
-
-	if (!p_dev->_irq)
-		goto out;
-
-	p_dev->_irq = 0;
-
-	if (c->state & CONFIG_LOCKED)
-		goto out;
-
-	if (c->irq.Attributes != req->Attributes) {
-		dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
-		goto out;
-	}
-	if (s->irq.AssignedIRQ != req->AssignedIRQ) {
-		dev_dbg(&s->dev, "IRQ must match assigned one\n");
-		goto out;
-	}
-	if (--s->irq.Config == 0) {
-		c->state &= ~CONFIG_IRQ_REQ;
-		s->irq.AssignedIRQ = 0;
-	}
-
-	if (req->Handler)
-		free_irq(req->AssignedIRQ, p_dev->priv);
-
-#ifdef CONFIG_PCMCIA_PROBE
-	pcmcia_used_irq[req->AssignedIRQ]--;
-#endif
-	ret = 0;
-
-out:
-	mutex_unlock(&s->ops_mutex);
-
-	return ret;
-} /* pcmcia_release_irq */
-
-
 int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
 int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
 {
 {
 	struct pcmcia_socket *s = p_dev->socket;
 	struct pcmcia_socket *s = p_dev->socket;
@@ -551,12 +432,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 	if (req->Attributes & CONF_ENABLE_SPKR)
 	if (req->Attributes & CONF_ENABLE_SPKR)
 		s->socket.flags |= SS_SPKR_ENA;
 		s->socket.flags |= SS_SPKR_ENA;
 	if (req->Attributes & CONF_ENABLE_IRQ)
 	if (req->Attributes & CONF_ENABLE_IRQ)
-		s->socket.io_irq = s->irq.AssignedIRQ;
+		s->socket.io_irq = s->pcmcia_irq;
 	else
 	else
 		s->socket.io_irq = 0;
 		s->socket.io_irq = 0;
 	s->ops->set_socket(s, &s->socket);
 	s->ops->set_socket(s, &s->socket);
 	s->lock_count++;
 	s->lock_count++;
-	mutex_unlock(&s->ops_mutex);
 
 
 	/* Set up CIS configuration registers */
 	/* Set up CIS configuration registers */
 	base = c->ConfigBase = req->ConfigBase;
 	base = c->ConfigBase = req->ConfigBase;
@@ -574,9 +454,9 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 			if (req->Present & PRESENT_IOBASE_0)
 			if (req->Present & PRESENT_IOBASE_0)
 				c->Option |= COR_ADDR_DECODE;
 				c->Option |= COR_ADDR_DECODE;
 		}
 		}
-		if (c->state & CONFIG_IRQ_REQ)
-			if (!(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);
 		pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
 		mdelay(40);
 		mdelay(40);
 	}
 	}
@@ -605,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 
 
 	/* Configure I/O windows */
 	/* Configure I/O windows */
 	if (c->state & CONFIG_IO_REQ) {
 	if (c->state & CONFIG_IO_REQ) {
-		mutex_lock(&s->ops_mutex);
 		iomap.speed = io_speed;
 		iomap.speed = io_speed;
 		for (i = 0; i < MAX_IO_WIN; i++)
 		for (i = 0; i < MAX_IO_WIN; i++)
 			if (s->io[i].res) {
 			if (s->io[i].res) {
@@ -624,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 				s->ops->set_io_map(s, &iomap);
 				s->ops->set_io_map(s, &iomap);
 				s->io[i].Config++;
 				s->io[i].Config++;
 			}
 			}
-		mutex_unlock(&s->ops_mutex);
 	}
 	}
 
 
 	c->state |= CONFIG_LOCKED;
 	c->state |= CONFIG_LOCKED;
 	p_dev->_locked = 1;
 	p_dev->_locked = 1;
+	mutex_unlock(&s->ops_mutex);
 	return 0;
 	return 0;
 } /* pcmcia_request_configuration */
 } /* pcmcia_request_configuration */
 EXPORT_SYMBOL(pcmcia_request_configuration);
 EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -706,137 +585,176 @@ out:
 EXPORT_SYMBOL(pcmcia_request_io);
 EXPORT_SYMBOL(pcmcia_request_io);
 
 
 
 
-/** pcmcia_request_irq
+/**
+ * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
  *
  *
- * Request_irq() reserves an irq for this client.
+ * pcmcia_request_irq() is a wrapper around request_irq which will allow
+ * the PCMCIA core to clean up the registration in pcmcia_disable_device().
+ * 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
 #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)
 static irqreturn_t test_action(int cpl, void *dev_id)
 {
 {
 	return IRQ_NONE;
 	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;
 	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
 /** pcmcia_request_window
@@ -939,237 +857,9 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev)
 {
 {
 	pcmcia_release_configuration(p_dev);
 	pcmcia_release_configuration(p_dev);
 	pcmcia_release_io(p_dev, &p_dev->io);
 	pcmcia_release_io(p_dev, &p_dev->io);
-	pcmcia_release_irq(p_dev, &p_dev->irq);
+	if (p_dev->_irq)
+		free_irq(p_dev->irq, p_dev->priv);
 	if (p_dev->win)
 	if (p_dev->win)
 		pcmcia_release_window(p_dev, p_dev->win);
 		pcmcia_release_window(p_dev, p_dev->win);
 }
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
 EXPORT_SYMBOL(pcmcia_disable_device);
-
-
-struct pcmcia_cfg_mem {
-	struct pcmcia_device *p_dev;
-	void *priv_data;
-	int (*conf_check) (struct pcmcia_device *p_dev,
-			   cistpl_cftable_entry_t *cfg,
-			   cistpl_cftable_entry_t *dflt,
-			   unsigned int vcc,
-			   void *priv_data);
-	cisparse_t parse;
-	cistpl_cftable_entry_t dflt;
-};
-
-/**
- * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
- *
- * pcmcia_do_loop_config() is the internal callback for the call from
- * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
- * by a struct pcmcia_cfg_mem.
- */
-static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
-{
-	cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
-	struct pcmcia_cfg_mem *cfg_mem = priv;
-
-	/* default values */
-	cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
-	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-		cfg_mem->dflt = *cfg;
-
-	return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
-				   cfg_mem->p_dev->socket->socket.Vcc,
-				   cfg_mem->priv_data);
-}
-
-/**
- * pcmcia_loop_config() - loop over configuration options
- * @p_dev:	the struct pcmcia_device which we need to loop for.
- * @conf_check:	function to call for each configuration option.
- *		It gets passed the struct pcmcia_device, the CIS data
- *		describing the configuration option, and private data
- *		being passed to pcmcia_loop_config()
- * @priv_data:	private data to be passed to the conf_check function.
- *
- * pcmcia_loop_config() loops over all configuration options, and calls
- * the driver-specific conf_check() for each one, checking whether
- * it is a valid one. Returns 0 on success or errorcode otherwise.
- */
-int pcmcia_loop_config(struct pcmcia_device *p_dev,
-		       int	(*conf_check)	(struct pcmcia_device *p_dev,
-						 cistpl_cftable_entry_t *cfg,
-						 cistpl_cftable_entry_t *dflt,
-						 unsigned int vcc,
-						 void *priv_data),
-		       void *priv_data)
-{
-	struct pcmcia_cfg_mem *cfg_mem;
-	int ret;
-
-	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
-	if (cfg_mem == NULL)
-		return -ENOMEM;
-
-	cfg_mem->p_dev = p_dev;
-	cfg_mem->conf_check = conf_check;
-	cfg_mem->priv_data = priv_data;
-
-	ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
-				CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
-				cfg_mem, pcmcia_do_loop_config);
-
-	kfree(cfg_mem);
-	return ret;
-}
-EXPORT_SYMBOL(pcmcia_loop_config);
-
-
-struct pcmcia_loop_mem {
-	struct pcmcia_device *p_dev;
-	void *priv_data;
-	int (*loop_tuple) (struct pcmcia_device *p_dev,
-			   tuple_t *tuple,
-			   void *priv_data);
-};
-
-/**
- * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
- *
- * pcmcia_do_loop_tuple() is the internal callback for the call from
- * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
- * by a struct pcmcia_cfg_mem.
- */
-static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
-{
-	struct pcmcia_loop_mem *loop = priv;
-
-	return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
-};
-
-/**
- * pcmcia_loop_tuple() - loop over tuples in the CIS
- * @p_dev:	the struct pcmcia_device which we need to loop for.
- * @code:	which CIS code shall we look for?
- * @priv_data:	private data to be passed to the loop_tuple function.
- * @loop_tuple:	function to call for each CIS entry of type @function. IT
- *		gets passed the raw tuple and @priv_data.
- *
- * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
- * calls the @loop_tuple function for each entry. If the call to @loop_tuple
- * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
- */
-int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
-		      int (*loop_tuple) (struct pcmcia_device *p_dev,
-					 tuple_t *tuple,
-					 void *priv_data),
-		      void *priv_data)
-{
-	struct pcmcia_loop_mem loop = {
-		.p_dev = p_dev,
-		.loop_tuple = loop_tuple,
-		.priv_data = priv_data};
-
-	return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
-				 &loop, pcmcia_do_loop_tuple);
-}
-EXPORT_SYMBOL(pcmcia_loop_tuple);
-
-
-struct pcmcia_loop_get {
-	size_t len;
-	cisdata_t **buf;
-};
-
-/**
- * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
- *
- * pcmcia_do_get_tuple() is the internal callback for the call from
- * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
- * the first tuple, return 0 unconditionally. Create a memory buffer large
- * enough to hold the content of the tuple, and fill it with the tuple data.
- * The caller is responsible to free the buffer.
- */
-static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
-			       void *priv)
-{
-	struct pcmcia_loop_get *get = priv;
-
-	*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
-	if (*get->buf) {
-		get->len = tuple->TupleDataLen;
-		memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
-	} else
-		dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
-	return 0;
-}
-
-/**
- * pcmcia_get_tuple() - get first tuple from CIS
- * @p_dev:	the struct pcmcia_device which we need to loop for.
- * @code:	which CIS code shall we look for?
- * @buf:        pointer to store the buffer to.
- *
- * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
- * It returns the buffer length (or zero). The caller is responsible to free
- * the buffer passed in @buf.
- */
-size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
-			unsigned char **buf)
-{
-	struct pcmcia_loop_get get = {
-		.len = 0,
-		.buf = buf,
-	};
-
-	*get.buf = NULL;
-	pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
-
-	return get.len;
-}
-EXPORT_SYMBOL(pcmcia_get_tuple);
-
-
-/**
- * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
- *
- * pcmcia_do_get_mac() is the internal callback for the call from
- * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
- * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
- * to struct net_device->dev_addr[i].
- */
-static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
-			     void *priv)
-{
-	struct net_device *dev = priv;
-	int i;
-
-	if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
-		return -EINVAL;
-	if (tuple->TupleDataLen < ETH_ALEN + 2) {
-		dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
-			"LAN_NODE_ID\n");
-		return -EINVAL;
-	}
-
-	if (tuple->TupleData[1] != ETH_ALEN) {
-		dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
-		return -EINVAL;
-	}
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = tuple->TupleData[i+2];
-	return 0;
-}
-
-/**
- * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
- * @p_dev:	the struct pcmcia_device for which we want the address.
- * @dev:	a properly prepared struct net_device to store the info to.
- *
- * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
- * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
- * must be set up properly by the driver (see examples!).
- */
-int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
-{
-	return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
-}
-EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
-

+ 172 - 0
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);

+ 19 - 93
drivers/pcmcia/rsrc_mgr.c

@@ -22,7 +22,7 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 #include "cs_internal.h"
 
 
-static int static_init(struct pcmcia_socket *s)
+int static_init(struct pcmcia_socket *s)
 {
 {
 	/* the good thing about SS_CAP_STATIC_MAP sockets is
 	/* the good thing about SS_CAP_STATIC_MAP sockets is
 	 * that they don't need a resource database */
 	 * that they don't need a resource database */
@@ -32,118 +32,44 @@ static int static_init(struct pcmcia_socket *s)
 	return 0;
 	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);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 
 	if (res) {
 	if (res) {
 		res->name = name;
 		res->name = name;
-		res->start = b;
-		res->end = b + n - 1;
+		res->start = start;
+		res->end = start + end - 1;
 		res->flags = flags;
 		res->flags = flags;
 	}
 	}
 	return res;
 	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,
 	.validate_mem = NULL,
-	.adjust_io_region = iodyn_adjust_io_region,
-	.find_io = iodyn_find_io_region,
+	.find_io = static_find_io,
 	.find_mem = NULL,
 	.find_mem = NULL,
 	.add_io = NULL,
 	.add_io = NULL,
 	.add_mem = NULL,
 	.add_mem = NULL,
 	.init = static_init,
 	.init = static_init,
 	.exit = NULL,
 	.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");

+ 130 - 34
drivers/pcmcia/rsrc_nonstatic.c

@@ -34,8 +34,10 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 #include "cs_internal.h"
 
 
+/* moved to rsrc_mgr.c
 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+*/
 
 
 /* Parameters that can be set with 'insmod' */
 /* Parameters that can be set with 'insmod' */
 
 
@@ -69,20 +71,6 @@ struct socket_data {
 
 
 ======================================================================*/
 ======================================================================*/
 
 
-static struct resource *
-make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
-{
-	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
-
-	if (res) {
-		res->name = name;
-		res->start = b;
-		res->end = b + n - 1;
-		res->flags = flags;
-	}
-	return res;
-}
-
 static struct resource *
 static struct resource *
 claim_region(struct pcmcia_socket *s, resource_size_t base,
 claim_region(struct pcmcia_socket *s, resource_size_t base,
 		resource_size_t size, int type, char *name)
 		resource_size_t size, int type, char *name)
@@ -90,7 +78,7 @@ claim_region(struct pcmcia_socket *s, resource_size_t base,
 	struct resource *res, *parent;
 	struct resource *res, *parent;
 
 
 	parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
 	parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
-	res = make_resource(base, size, type | IORESOURCE_BUSY, name);
+	res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
 
 
 	if (res) {
 	if (res) {
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
@@ -661,8 +649,9 @@ pcmcia_align(void *align_data, const struct resource *res,
  * Adjust an existing IO region allocation, but making sure that we don't
  * Adjust an existing IO region allocation, but making sure that we don't
  * encroach outside the resources which the user supplied.
  * encroach outside the resources which the user supplied.
  */
  */
-static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
-				      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 resource_map *m;
 	struct socket_data *s_data = s->resource_data;
 	struct socket_data *s_data = s->resource_data;
@@ -675,8 +664,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
 		if (start > r_start || r_end > end)
 		if (start > r_start || r_end > end)
 			continue;
 			continue;
 
 
-		ret = adjust_resource(res, r_start, r_end - r_start + 1);
-		break;
+		ret = 0;
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -695,18 +683,17 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
 
 
 ======================================================================*/
 ======================================================================*/
 
 
-static struct resource *nonstatic_find_io_region(unsigned long base, int num,
-		   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 socket_data *s_data = s->resource_data;
 	struct pcmcia_align_data data;
 	struct pcmcia_align_data data;
 	unsigned long min = base;
 	unsigned long min = base;
 	int ret;
 	int ret;
 
 
-	if (align == 0)
-		align = 0x10000;
-
 	data.mask = align - 1;
 	data.mask = align - 1;
 	data.offset = base & data.mask;
 	data.offset = base & data.mask;
 	data.map = &s_data->io_db;
 	data.map = &s_data->io_db;
@@ -727,10 +714,97 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 	return res;
 	return res;
 }
 }
 
 
+static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
+			unsigned int *base, unsigned int num,
+			unsigned int align)
+{
+	int i, ret = 0;
+
+	/* Check for an already-allocated window that must conflict with
+	 * what was asked for.  It is a hack because it does not catch all
+	 * potential conflicts, just the most obvious ones.
+	 */
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		if (!s->io[i].res)
+			continue;
+
+		if (!*base)
+			continue;
+
+		if ((s->io[i].res->start & (align-1)) == *base)
+			return -EBUSY;
+	}
+
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		struct resource *res = s->io[i].res;
+		unsigned int try;
+
+		if (res && (res->flags & IORESOURCE_BITS) !=
+			(attr & IORESOURCE_BITS))
+			continue;
+
+		if (!res) {
+			if (align == 0)
+				align = 0x10000;
+
+			res = s->io[i].res = __nonstatic_find_io_region(s,
+								*base, num,
+								align);
+			if (!res)
+				return -EINVAL;
+
+			*base = res->start;
+			s->io[i].res->flags =
+				((res->flags & ~IORESOURCE_BITS) |
+					(attr & IORESOURCE_BITS));
+			s->io[i].InUse = num;
+			return 0;
+		}
+
+		/* Try to extend top of window */
+		try = res->end + 1;
+		if ((*base == 0) || (*base == try)) {
+			ret =  __nonstatic_adjust_io_region(s, res->start,
+							res->end + num);
+			if (!ret) {
+				ret = adjust_resource(s->io[i].res, res->start,
+					       res->end - res->start + num + 1);
+				if (ret)
+					continue;
+				*base = try;
+				s->io[i].InUse += num;
+				return 0;
+			}
+		}
+
+		/* Try to extend bottom of window */
+		try = res->start - num;
+		if ((*base == 0) || (*base == try)) {
+			ret =  __nonstatic_adjust_io_region(s,
+							res->start - num,
+							res->end);
+			if (!ret) {
+				ret = adjust_resource(s->io[i].res,
+					       res->start - num,
+					       res->end - res->start + num + 1);
+				if (ret)
+					continue;
+				*base = try;
+				s->io[i].InUse += num;
+				return 0;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+
 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 		u_long align, int low, struct pcmcia_socket *s)
 		u_long align, int low, struct pcmcia_socket *s)
 {
 {
-	struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
+	struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
+						dev_name(&s->dev));
 	struct socket_data *s_data = s->resource_data;
 	struct socket_data *s_data = s->resource_data;
 	struct pcmcia_align_data data;
 	struct pcmcia_align_data data;
 	unsigned long min, max;
 	unsigned long min, max;
@@ -861,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
 		return -ENODEV;
 		return -ENODEV;
 
 
 #if defined(CONFIG_X86)
 #if defined(CONFIG_X86)
-	/* If this is the root bus, the risk of hitting
-	 * 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)
 	if (s->cb_dev->bus->number == 0)
 		return -EINVAL;
 		return -EINVAL;
-#endif
 
 
+	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
+		res = s->cb_dev->bus->resource[i];
+#else
 	pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
 	pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
+#endif
 		if (!res)
 		if (!res)
 			continue;
 			continue;
 
 
 		if (res->flags & IORESOURCE_IO) {
 		if (res->flags & IORESOURCE_IO) {
+			/* safeguard against the root resource, where the
+			 * risk of hitting any other device would be too
+			 * high */
 			if (res == &ioport_resource)
 			if (res == &ioport_resource)
 				continue;
 				continue;
+
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
 				   "pcmcia: parent PCI bridge window: %pR\n",
 				   "pcmcia: parent PCI bridge window: %pR\n",
 				   res);
 				   res);
@@ -887,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
 		}
 		}
 
 
 		if (res->flags & IORESOURCE_MEM) {
 		if (res->flags & IORESOURCE_MEM) {
+			/* safeguard against the root resource, where the
+			 * risk of hitting any other device would be too
+			 * high */
 			if (res == &iomem_resource)
 			if (res == &iomem_resource)
 				continue;
 				continue;
+
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
 				   "pcmcia: parent PCI bridge window: %pR\n",
 				   "pcmcia: parent PCI bridge window: %pR\n",
 				   res);
 				   res);
@@ -956,8 +1053,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
 
 
 struct pccard_resource_ops pccard_nonstatic_ops = {
 struct pccard_resource_ops pccard_nonstatic_ops = {
 	.validate_mem = pcmcia_nonstatic_validate_mem,
 	.validate_mem = pcmcia_nonstatic_validate_mem,
-	.adjust_io_region = nonstatic_adjust_io_region,
-	.find_io = nonstatic_find_io_region,
+	.find_io = nonstatic_find_io,
 	.find_mem = nonstatic_find_mem_region,
 	.find_mem = nonstatic_find_mem_region,
 	.add_io = adjust_io,
 	.add_io = adjust_io,
 	.add_mem = adjust_memory,
 	.add_mem = adjust_memory,

+ 0 - 7
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_read_config_dword(pdev, 17*4, &socket->saved_state[1]);
 	pci_disable_device(pdev);
 	pci_disable_device(pdev);
 
 
-	/*
-	 * Some laptops (IBM T22) do not like us putting the Cardbus
-	 * bridge into D3.  At a guess, some other laptop will
-	 * probably require this, so leave it commented out for now.
-	 */
-	/* pci_set_power_state(dev, 3); */
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 7
drivers/scsi/pcmcia/aha152x_stub.c

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

+ 2 - 7
drivers/scsi/pcmcia/fdomain_stub.c

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

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

+ 0 - 1
drivers/scsi/pcmcia/nsp_cs.h

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

+ 4 - 9
drivers/scsi/pcmcia/qlogic_stub.c

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

+ 2 - 7
drivers/scsi/pcmcia/sym53c500_cs.c

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

+ 9 - 27
drivers/serial/serial_cs.c

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

+ 1 - 1
drivers/ssb/main.c

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

+ 10 - 35
drivers/staging/comedi/drivers/cb_das16_cs.c

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

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

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

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

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

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

+ 8 - 37
drivers/staging/comedi/drivers/quatech_daqp_cs.c

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

+ 2 - 7
drivers/staging/netwave/netwave_cs.c

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

+ 3 - 12
drivers/staging/wavelan/wavelan_cs.c

@@ -3850,12 +3850,8 @@ wv_pcmcia_config(struct pcmcia_device *	link)
       if (i != 0)
       if (i != 0)
 	  break;
 	  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;
 	  break;
 
 
       /*
       /*
@@ -3890,7 +3886,7 @@ wv_pcmcia_config(struct pcmcia_device *	link)
 	  break;
 	  break;
 
 
       /* Feed device with this info... */
       /* Feed device with this info... */
-      dev->irq = link->irq.AssignedIRQ;
+      dev->irq = link->irq;
       dev->base_addr = link->io.BasePort1;
       dev->base_addr = link->io.BasePort1;
       netif_start_queue(dev);
       netif_start_queue(dev);
 
 
@@ -4437,10 +4433,6 @@ wavelan_probe(struct pcmcia_device *p_dev)
   p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
   p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
   p_dev->io.IOAddrLines = 3;
   p_dev->io.IOAddrLines = 3;
 
 
-  /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-  p_dev->irq.Handler = wavelan_interrupt;
-
   /* General socket configuration */
   /* General socket configuration */
   p_dev->conf.Attributes = CONF_ENABLE_IRQ;
   p_dev->conf.Attributes = CONF_ENABLE_IRQ;
   p_dev->conf.IntType = INT_MEMORY_AND_IO;
   p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -4487,7 +4479,6 @@ wavelan_probe(struct pcmcia_device *p_dev)
 
 
   ret = wv_hw_config(dev);
   ret = wv_hw_config(dev);
   if (ret) {
   if (ret) {
-	  dev->irq = 0;
 	  pcmcia_disable_device(p_dev);
 	  pcmcia_disable_device(p_dev);
 	  return ret;
 	  return ret;
   }
   }

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

+ 0 - 3
drivers/telephony/ixj_pcmcia.c

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

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

+ 1 - 18
include/pcmcia/cs.h

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

+ 17 - 12
include/pcmcia/ds.h

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

+ 0 - 116
include/pcmcia/mem_op.h

@@ -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 */

+ 3 - 4
include/pcmcia/ss.h

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

+ 3 - 9
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.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.NumPorts1 = 16;
 	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.IntType = INT_MEMORY_AND_IO;
 	link->conf.ConfigIndex = 1;
 	link->conf.ConfigIndex = 1;
 	link->conf.Present = PRESENT_OPTION;
 	link->conf.Present = PRESENT_OPTION;
@@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
-	ret = pcmcia_request_irq(link, &link->irq);
+	ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
@@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link)
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
-	if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+	if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
 		goto failed;
 		goto failed;
 
 
-	link->dev_node = &pdacf->node;
 	return 0;
 	return 0;
 
 
 failed:
 failed:

+ 0 - 1
sound/pcmcia/pdaudiocf/pdaudiocf.h

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

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

+ 0 - 1
sound/pcmcia/vx/vxpocket.h

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