diff options
86 files changed, 1179 insertions, 2139 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 446f43b309df..61bc4e943116 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt | |||
@@ -1,4 +1,17 @@ | |||
1 | This file details changes in 2.6 which affect PCMCIA card driver authors: | 1 | This file details changes in 2.6 which affect PCMCIA card driver authors: |
2 | * No dev_node_t (as of 2.6.35) | ||
3 | There is no more need to fill out a "dev_node_t" structure. | ||
4 | |||
5 | * New IRQ request rules (as of 2.6.35) | ||
6 | Instead of the old pcmcia_request_irq() interface, drivers may now | ||
7 | choose between: | ||
8 | - calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq. | ||
9 | - use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will | ||
10 | clean up automatically on calls to pcmcia_disable_device() or | ||
11 | device ejection. | ||
12 | - drivers still not capable of IRQF_SHARED (or not telling us so) may | ||
13 | use the deprecated pcmcia_request_exclusive_irq() for the time | ||
14 | being; they might receive a shared IRQ nonetheless. | ||
2 | 15 | ||
3 | * no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33) | 16 | * no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33) |
4 | Instead of the cs_error() callback or the CS_CHECK() macro, please use | 17 | Instead of the cs_error() callback or the CS_CHECK() macro, please use |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index d94b8f0bd743..aa39bda6441a 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -45,16 +45,6 @@ | |||
45 | #define DRV_NAME "pata_pcmcia" | 45 | #define DRV_NAME "pata_pcmcia" |
46 | #define DRV_VERSION "0.3.5" | 46 | #define DRV_VERSION "0.3.5" |
47 | 47 | ||
48 | /* | ||
49 | * Private data structure to glue stuff together | ||
50 | */ | ||
51 | |||
52 | struct ata_pcmcia_info { | ||
53 | struct pcmcia_device *pdev; | ||
54 | int ndev; | ||
55 | dev_node_t node; | ||
56 | }; | ||
57 | |||
58 | /** | 48 | /** |
59 | * pcmcia_set_mode - PCMCIA specific mode setup | 49 | * pcmcia_set_mode - PCMCIA specific mode setup |
60 | * @link: link | 50 | * @link: link |
@@ -248,7 +238,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
248 | { | 238 | { |
249 | struct ata_host *host; | 239 | struct ata_host *host; |
250 | struct ata_port *ap; | 240 | struct ata_port *ap; |
251 | struct ata_pcmcia_info *info; | ||
252 | struct pcmcia_config_check *stk = NULL; | 241 | struct pcmcia_config_check *stk = NULL; |
253 | int is_kme = 0, ret = -ENOMEM, p; | 242 | int is_kme = 0, ret = -ENOMEM, p; |
254 | unsigned long io_base, ctl_base; | 243 | unsigned long io_base, ctl_base; |
@@ -256,19 +245,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
256 | int n_ports = 1; | 245 | int n_ports = 1; |
257 | struct ata_port_operations *ops = &pcmcia_port_ops; | 246 | struct ata_port_operations *ops = &pcmcia_port_ops; |
258 | 247 | ||
259 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
260 | if (info == NULL) | ||
261 | return -ENOMEM; | ||
262 | |||
263 | /* Glue stuff together. FIXME: We may be able to get rid of info with care */ | ||
264 | info->pdev = pdev; | ||
265 | pdev->priv = info; | ||
266 | |||
267 | /* Set up attributes in order to probe card and get resources */ | 248 | /* Set up attributes in order to probe card and get resources */ |
268 | pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 249 | pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
269 | pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 250 | pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
270 | pdev->io.IOAddrLines = 3; | 251 | pdev->io.IOAddrLines = 3; |
271 | pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
272 | pdev->conf.Attributes = CONF_ENABLE_IRQ; | 252 | pdev->conf.Attributes = CONF_ENABLE_IRQ; |
273 | pdev->conf.IntType = INT_MEMORY_AND_IO; | 253 | pdev->conf.IntType = INT_MEMORY_AND_IO; |
274 | 254 | ||
@@ -293,8 +273,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
293 | } | 273 | } |
294 | io_base = pdev->io.BasePort1; | 274 | io_base = pdev->io.BasePort1; |
295 | ctl_base = stk->ctl_base; | 275 | ctl_base = stk->ctl_base; |
296 | ret = pcmcia_request_irq(pdev, &pdev->irq); | 276 | if (!pdev->irq) |
297 | if (ret) | ||
298 | goto failed; | 277 | goto failed; |
299 | 278 | ||
300 | ret = pcmcia_request_configuration(pdev, &pdev->conf); | 279 | ret = pcmcia_request_configuration(pdev, &pdev->conf); |
@@ -344,21 +323,19 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
344 | } | 323 | } |
345 | 324 | ||
346 | /* activate */ | 325 | /* activate */ |
347 | ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_sff_interrupt, | 326 | ret = ata_host_activate(host, pdev->irq, ata_sff_interrupt, |
348 | IRQF_SHARED, &pcmcia_sht); | 327 | IRQF_SHARED, &pcmcia_sht); |
349 | if (ret) | 328 | if (ret) |
350 | goto failed; | 329 | goto failed; |
351 | 330 | ||
352 | info->ndev = 1; | 331 | pdev->priv = host; |
353 | kfree(stk); | 332 | kfree(stk); |
354 | return 0; | 333 | return 0; |
355 | 334 | ||
356 | failed: | 335 | failed: |
357 | kfree(stk); | 336 | kfree(stk); |
358 | info->ndev = 0; | ||
359 | pcmcia_disable_device(pdev); | 337 | pcmcia_disable_device(pdev); |
360 | out1: | 338 | out1: |
361 | kfree(info); | ||
362 | return ret; | 339 | return ret; |
363 | } | 340 | } |
364 | 341 | ||
@@ -372,20 +349,12 @@ out1: | |||
372 | 349 | ||
373 | static void pcmcia_remove_one(struct pcmcia_device *pdev) | 350 | static void pcmcia_remove_one(struct pcmcia_device *pdev) |
374 | { | 351 | { |
375 | struct ata_pcmcia_info *info = pdev->priv; | 352 | struct ata_host *host = pdev->priv; |
376 | struct device *dev = &pdev->dev; | 353 | |
377 | 354 | if (host) | |
378 | if (info != NULL) { | 355 | ata_host_detach(host); |
379 | /* If we have attached the device to the ATA layer, detach it */ | 356 | |
380 | if (info->ndev) { | ||
381 | struct ata_host *host = dev_get_drvdata(dev); | ||
382 | ata_host_detach(host); | ||
383 | } | ||
384 | info->ndev = 0; | ||
385 | pdev->priv = NULL; | ||
386 | } | ||
387 | pcmcia_disable_device(pdev); | 357 | pcmcia_disable_device(pdev); |
388 | kfree(info); | ||
389 | } | 358 | } |
390 | 359 | ||
391 | static struct pcmcia_device_id pcmcia_devices[] = { | 360 | static struct pcmcia_device_id pcmcia_devices[] = { |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index d9bf87ca9e83..6f907ebed2d5 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -65,7 +65,6 @@ MODULE_LICENSE("GPL"); | |||
65 | 65 | ||
66 | typedef struct bluecard_info_t { | 66 | typedef struct bluecard_info_t { |
67 | struct pcmcia_device *p_dev; | 67 | struct pcmcia_device *p_dev; |
68 | dev_node_t node; | ||
69 | 68 | ||
70 | struct hci_dev *hdev; | 69 | struct hci_dev *hdev; |
71 | 70 | ||
@@ -869,9 +868,6 @@ static int bluecard_probe(struct pcmcia_device *link) | |||
869 | 868 | ||
870 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 869 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
871 | link->io.NumPorts1 = 8; | 870 | link->io.NumPorts1 = 8; |
872 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
873 | |||
874 | link->irq.Handler = bluecard_interrupt; | ||
875 | 871 | ||
876 | link->conf.Attributes = CONF_ENABLE_IRQ; | 872 | link->conf.Attributes = CONF_ENABLE_IRQ; |
877 | link->conf.IntType = INT_MEMORY_AND_IO; | 873 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -908,9 +904,9 @@ static int bluecard_config(struct pcmcia_device *link) | |||
908 | if (i != 0) | 904 | if (i != 0) |
909 | goto failed; | 905 | goto failed; |
910 | 906 | ||
911 | i = pcmcia_request_irq(link, &link->irq); | 907 | i = pcmcia_request_irq(link, bluecard_interrupt); |
912 | if (i != 0) | 908 | if (i != 0) |
913 | link->irq.AssignedIRQ = 0; | 909 | goto failed; |
914 | 910 | ||
915 | i = pcmcia_request_configuration(link, &link->conf); | 911 | i = pcmcia_request_configuration(link, &link->conf); |
916 | if (i != 0) | 912 | if (i != 0) |
@@ -919,9 +915,6 @@ static int bluecard_config(struct pcmcia_device *link) | |||
919 | if (bluecard_open(info) != 0) | 915 | if (bluecard_open(info) != 0) |
920 | goto failed; | 916 | goto failed; |
921 | 917 | ||
922 | strcpy(info->node.dev_name, info->hdev->name); | ||
923 | link->dev_node = &info->node; | ||
924 | |||
925 | return 0; | 918 | return 0; |
926 | 919 | ||
927 | failed: | 920 | failed: |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 027cb8bf650f..21e05fdc9121 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -72,7 +72,6 @@ MODULE_FIRMWARE("BT3CPCC.bin"); | |||
72 | 72 | ||
73 | typedef struct bt3c_info_t { | 73 | typedef struct bt3c_info_t { |
74 | struct pcmcia_device *p_dev; | 74 | struct pcmcia_device *p_dev; |
75 | dev_node_t node; | ||
76 | 75 | ||
77 | struct hci_dev *hdev; | 76 | struct hci_dev *hdev; |
78 | 77 | ||
@@ -661,9 +660,6 @@ static int bt3c_probe(struct pcmcia_device *link) | |||
661 | 660 | ||
662 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 661 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
663 | link->io.NumPorts1 = 8; | 662 | link->io.NumPorts1 = 8; |
664 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
665 | |||
666 | link->irq.Handler = bt3c_interrupt; | ||
667 | 663 | ||
668 | link->conf.Attributes = CONF_ENABLE_IRQ; | 664 | link->conf.Attributes = CONF_ENABLE_IRQ; |
669 | link->conf.IntType = INT_MEMORY_AND_IO; | 665 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -743,9 +739,9 @@ static int bt3c_config(struct pcmcia_device *link) | |||
743 | goto failed; | 739 | goto failed; |
744 | 740 | ||
745 | found_port: | 741 | found_port: |
746 | i = pcmcia_request_irq(link, &link->irq); | 742 | i = pcmcia_request_irq(link, &bt3c_interrupt); |
747 | if (i != 0) | 743 | if (i != 0) |
748 | link->irq.AssignedIRQ = 0; | 744 | goto failed; |
749 | 745 | ||
750 | i = pcmcia_request_configuration(link, &link->conf); | 746 | i = pcmcia_request_configuration(link, &link->conf); |
751 | if (i != 0) | 747 | if (i != 0) |
@@ -754,9 +750,6 @@ found_port: | |||
754 | if (bt3c_open(info) != 0) | 750 | if (bt3c_open(info) != 0) |
755 | goto failed; | 751 | goto failed; |
756 | 752 | ||
757 | strcpy(info->node.dev_name, info->hdev->name); | ||
758 | link->dev_node = &info->node; | ||
759 | |||
760 | return 0; | 753 | return 0; |
761 | 754 | ||
762 | failed: | 755 | failed: |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 60c0953d7d00..4ed7288f99db 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -67,7 +67,6 @@ MODULE_LICENSE("GPL"); | |||
67 | 67 | ||
68 | typedef struct btuart_info_t { | 68 | typedef struct btuart_info_t { |
69 | struct pcmcia_device *p_dev; | 69 | struct pcmcia_device *p_dev; |
70 | dev_node_t node; | ||
71 | 70 | ||
72 | struct hci_dev *hdev; | 71 | struct hci_dev *hdev; |
73 | 72 | ||
@@ -590,9 +589,6 @@ static int btuart_probe(struct pcmcia_device *link) | |||
590 | 589 | ||
591 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 590 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
592 | link->io.NumPorts1 = 8; | 591 | link->io.NumPorts1 = 8; |
593 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
594 | |||
595 | link->irq.Handler = btuart_interrupt; | ||
596 | 592 | ||
597 | link->conf.Attributes = CONF_ENABLE_IRQ; | 593 | link->conf.Attributes = CONF_ENABLE_IRQ; |
598 | link->conf.IntType = INT_MEMORY_AND_IO; | 594 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -672,9 +668,9 @@ static int btuart_config(struct pcmcia_device *link) | |||
672 | goto failed; | 668 | goto failed; |
673 | 669 | ||
674 | found_port: | 670 | found_port: |
675 | i = pcmcia_request_irq(link, &link->irq); | 671 | i = pcmcia_request_irq(link, btuart_interrupt); |
676 | if (i != 0) | 672 | if (i != 0) |
677 | link->irq.AssignedIRQ = 0; | 673 | goto failed; |
678 | 674 | ||
679 | i = pcmcia_request_configuration(link, &link->conf); | 675 | i = pcmcia_request_configuration(link, &link->conf); |
680 | if (i != 0) | 676 | if (i != 0) |
@@ -683,9 +679,6 @@ found_port: | |||
683 | if (btuart_open(info) != 0) | 679 | if (btuart_open(info) != 0) |
684 | goto failed; | 680 | goto failed; |
685 | 681 | ||
686 | strcpy(info->node.dev_name, info->hdev->name); | ||
687 | link->dev_node = &info->node; | ||
688 | |||
689 | return 0; | 682 | return 0; |
690 | 683 | ||
691 | failed: | 684 | failed: |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 17788317c51a..ef044d55cb25 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -67,7 +67,6 @@ MODULE_LICENSE("GPL"); | |||
67 | 67 | ||
68 | typedef struct dtl1_info_t { | 68 | typedef struct dtl1_info_t { |
69 | struct pcmcia_device *p_dev; | 69 | struct pcmcia_device *p_dev; |
70 | dev_node_t node; | ||
71 | 70 | ||
72 | struct hci_dev *hdev; | 71 | struct hci_dev *hdev; |
73 | 72 | ||
@@ -575,9 +574,6 @@ static int dtl1_probe(struct pcmcia_device *link) | |||
575 | 574 | ||
576 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 575 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
577 | link->io.NumPorts1 = 8; | 576 | link->io.NumPorts1 = 8; |
578 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
579 | |||
580 | link->irq.Handler = dtl1_interrupt; | ||
581 | 577 | ||
582 | link->conf.Attributes = CONF_ENABLE_IRQ; | 578 | link->conf.Attributes = CONF_ENABLE_IRQ; |
583 | link->conf.IntType = INT_MEMORY_AND_IO; | 579 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -621,9 +617,9 @@ static int dtl1_config(struct pcmcia_device *link) | |||
621 | if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) | 617 | if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) |
622 | goto failed; | 618 | goto failed; |
623 | 619 | ||
624 | i = pcmcia_request_irq(link, &link->irq); | 620 | i = pcmcia_request_irq(link, dtl1_interrupt); |
625 | if (i != 0) | 621 | if (i != 0) |
626 | link->irq.AssignedIRQ = 0; | 622 | goto failed; |
627 | 623 | ||
628 | i = pcmcia_request_configuration(link, &link->conf); | 624 | i = pcmcia_request_configuration(link, &link->conf); |
629 | if (i != 0) | 625 | if (i != 0) |
@@ -632,9 +628,6 @@ static int dtl1_config(struct pcmcia_device *link) | |||
632 | if (dtl1_open(info) != 0) | 628 | if (dtl1_open(info) != 0) |
633 | goto failed; | 629 | goto failed; |
634 | 630 | ||
635 | strcpy(info->node.dev_name, info->hdev->name); | ||
636 | link->dev_node = &info->node; | ||
637 | |||
638 | return 0; | 631 | return 0; |
639 | 632 | ||
640 | failed: | 633 | failed: |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 90b199f97bec..e7956acf2ad6 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -106,7 +106,6 @@ static int major; /* major number we get from the kernel */ | |||
106 | 106 | ||
107 | struct cm4000_dev { | 107 | struct cm4000_dev { |
108 | struct pcmcia_device *p_dev; | 108 | struct pcmcia_device *p_dev; |
109 | dev_node_t node; /* OS node (major,minor) */ | ||
110 | 109 | ||
111 | unsigned char atr[MAX_ATR]; | 110 | unsigned char atr[MAX_ATR]; |
112 | unsigned char rbuf[512]; | 111 | unsigned char rbuf[512]; |
@@ -884,8 +883,7 @@ static void monitor_card(unsigned long p) | |||
884 | /* slow down warning, but prompt immediately after insertion */ | 883 | /* slow down warning, but prompt immediately after insertion */ |
885 | if (dev->cwarn == 0 || dev->cwarn == 10) { | 884 | if (dev->cwarn == 0 || dev->cwarn == 10) { |
886 | set_bit(IS_BAD_CARD, &dev->flags); | 885 | set_bit(IS_BAD_CARD, &dev->flags); |
887 | printk(KERN_WARNING MODULE_NAME ": device %s: ", | 886 | dev_warn(&dev->p_dev->dev, MODULE_NAME ": "); |
888 | dev->node.dev_name); | ||
889 | if (test_bit(IS_BAD_CSUM, &dev->flags)) { | 887 | if (test_bit(IS_BAD_CSUM, &dev->flags)) { |
890 | DEBUGP(4, dev, "ATR checksum (0x%.2x, should " | 888 | DEBUGP(4, dev, "ATR checksum (0x%.2x, should " |
891 | "be zero) failed\n", dev->atr_csum); | 889 | "be zero) failed\n", dev->atr_csum); |
@@ -1781,11 +1779,6 @@ static int cm4000_config(struct pcmcia_device * link, int devno) | |||
1781 | goto cs_release; | 1779 | goto cs_release; |
1782 | 1780 | ||
1783 | dev = link->priv; | 1781 | dev = link->priv; |
1784 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | ||
1785 | dev->node.major = major; | ||
1786 | dev->node.minor = devno; | ||
1787 | dev->node.next = NULL; | ||
1788 | link->dev_node = &dev->node; | ||
1789 | 1782 | ||
1790 | return 0; | 1783 | return 0; |
1791 | 1784 | ||
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index a6a70e476bea..c0775c844e08 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -72,7 +72,6 @@ static struct class *cmx_class; | |||
72 | 72 | ||
73 | struct reader_dev { | 73 | struct reader_dev { |
74 | struct pcmcia_device *p_dev; | 74 | struct pcmcia_device *p_dev; |
75 | dev_node_t node; | ||
76 | wait_queue_head_t devq; | 75 | wait_queue_head_t devq; |
77 | wait_queue_head_t poll_wait; | 76 | wait_queue_head_t poll_wait; |
78 | wait_queue_head_t read_wait; | 77 | wait_queue_head_t read_wait; |
@@ -568,10 +567,6 @@ static int reader_config(struct pcmcia_device *link, int devno) | |||
568 | } | 567 | } |
569 | 568 | ||
570 | dev = link->priv; | 569 | dev = link->priv; |
571 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | ||
572 | dev->node.major = major; | ||
573 | dev->node.minor = devno; | ||
574 | dev->node.next = &dev->node; | ||
575 | 570 | ||
576 | DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, | 571 | DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, |
577 | link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); | 572 | link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); |
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index dff24dae1485..63c32e3f23ba 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -195,9 +195,6 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
195 | link->conf.Attributes = CONF_ENABLE_IRQ; | 195 | link->conf.Attributes = CONF_ENABLE_IRQ; |
196 | link->conf.IntType = INT_MEMORY_AND_IO; | 196 | link->conf.IntType = INT_MEMORY_AND_IO; |
197 | 197 | ||
198 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
199 | link->irq.Handler = ipwireless_interrupt; | ||
200 | |||
201 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); | 198 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); |
202 | 199 | ||
203 | ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1, | 200 | ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1, |
@@ -205,8 +202,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
205 | ipw->is_v2_card, signalled_reboot_callback, | 202 | ipw->is_v2_card, signalled_reboot_callback, |
206 | ipw); | 203 | ipw); |
207 | 204 | ||
208 | ret = pcmcia_request_irq(link, &link->irq); | 205 | ret = pcmcia_request_irq(link, ipwireless_interrupt); |
209 | |||
210 | if (ret != 0) | 206 | if (ret != 0) |
211 | goto exit; | 207 | goto exit; |
212 | 208 | ||
@@ -217,7 +213,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
217 | (unsigned int) link->io.BasePort1, | 213 | (unsigned int) link->io.BasePort1, |
218 | (unsigned int) (link->io.BasePort1 + | 214 | (unsigned int) (link->io.BasePort1 + |
219 | link->io.NumPorts1 - 1), | 215 | link->io.NumPorts1 - 1), |
220 | (unsigned int) link->irq.AssignedIRQ); | 216 | (unsigned int) link->irq); |
221 | if (ipw->attr_memory && ipw->common_memory) | 217 | if (ipw->attr_memory && ipw->common_memory) |
222 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 218 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
223 | ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", | 219 | ": 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) | |||
232 | if (!ipw->network) | 228 | if (!ipw->network) |
233 | goto exit; | 229 | goto exit; |
234 | 230 | ||
235 | ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, | 231 | ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network); |
236 | ipw->nodes); | ||
237 | if (!ipw->tty) | 232 | if (!ipw->tty) |
238 | goto exit; | 233 | goto exit; |
239 | 234 | ||
@@ -248,8 +243,6 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
248 | if (ret != 0) | 243 | if (ret != 0) |
249 | goto exit; | 244 | goto exit; |
250 | 245 | ||
251 | link->dev_node = &ipw->nodes[0]; | ||
252 | |||
253 | return 0; | 246 | return 0; |
254 | 247 | ||
255 | exit: | 248 | exit: |
@@ -271,8 +264,6 @@ exit: | |||
271 | 264 | ||
272 | static void release_ipwireless(struct ipw_dev *ipw) | 265 | static void release_ipwireless(struct ipw_dev *ipw) |
273 | { | 266 | { |
274 | pcmcia_disable_device(ipw->link); | ||
275 | |||
276 | if (ipw->common_memory) { | 267 | if (ipw->common_memory) { |
277 | release_mem_region(ipw->request_common_memory.Base, | 268 | release_mem_region(ipw->request_common_memory.Base, |
278 | ipw->request_common_memory.Size); | 269 | ipw->request_common_memory.Size); |
@@ -288,7 +279,6 @@ static void release_ipwireless(struct ipw_dev *ipw) | |||
288 | if (ipw->attr_memory) | 279 | if (ipw->attr_memory) |
289 | pcmcia_release_window(ipw->link, ipw->handle_attr_memory); | 280 | pcmcia_release_window(ipw->link, ipw->handle_attr_memory); |
290 | 281 | ||
291 | /* Break the link with Card Services */ | ||
292 | pcmcia_disable_device(ipw->link); | 282 | pcmcia_disable_device(ipw->link); |
293 | } | 283 | } |
294 | 284 | ||
@@ -313,9 +303,6 @@ static int ipwireless_attach(struct pcmcia_device *link) | |||
313 | ipw->link = link; | 303 | ipw->link = link; |
314 | link->priv = ipw; | 304 | link->priv = ipw; |
315 | 305 | ||
316 | /* Link this device into our device list. */ | ||
317 | link->dev_node = &ipw->nodes[0]; | ||
318 | |||
319 | ipw->hardware = ipwireless_hardware_create(); | 306 | ipw->hardware = ipwireless_hardware_create(); |
320 | if (!ipw->hardware) { | 307 | if (!ipw->hardware) { |
321 | kfree(ipw); | 308 | kfree(ipw); |
diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h index 0e0363af9ab2..96d0ef31b172 100644 --- a/drivers/char/pcmcia/ipwireless/main.h +++ b/drivers/char/pcmcia/ipwireless/main.h | |||
@@ -54,7 +54,6 @@ struct ipw_dev { | |||
54 | void __iomem *common_memory; | 54 | void __iomem *common_memory; |
55 | win_req_t request_common_memory; | 55 | win_req_t request_common_memory; |
56 | 56 | ||
57 | dev_node_t nodes[2]; | ||
58 | /* Reference to attribute memory, containing CIS data */ | 57 | /* Reference to attribute memory, containing CIS data */ |
59 | void *attribute_memory; | 58 | void *attribute_memory; |
60 | 59 | ||
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 2bb7874a6899..1a2c2c3b068f 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -487,7 +487,7 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
487 | return tty_mode_ioctl(linux_tty, file, cmd , arg); | 487 | return tty_mode_ioctl(linux_tty, file, cmd , arg); |
488 | } | 488 | } |
489 | 489 | ||
490 | static int add_tty(dev_node_t *nodesp, int j, | 490 | static int add_tty(int j, |
491 | struct ipw_hardware *hardware, | 491 | struct ipw_hardware *hardware, |
492 | struct ipw_network *network, int channel_idx, | 492 | struct ipw_network *network, int channel_idx, |
493 | int secondary_channel_idx, int tty_type) | 493 | int secondary_channel_idx, int tty_type) |
@@ -510,19 +510,13 @@ static int add_tty(dev_node_t *nodesp, int j, | |||
510 | ipwireless_associate_network_tty(network, | 510 | ipwireless_associate_network_tty(network, |
511 | secondary_channel_idx, | 511 | secondary_channel_idx, |
512 | ttys[j]); | 512 | ttys[j]); |
513 | if (nodesp != NULL) { | ||
514 | sprintf(nodesp->dev_name, "ttyIPWp%d", j); | ||
515 | nodesp->major = ipw_tty_driver->major; | ||
516 | nodesp->minor = j + ipw_tty_driver->minor_start; | ||
517 | } | ||
518 | if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) | 513 | if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) |
519 | report_registering(ttys[j]); | 514 | report_registering(ttys[j]); |
520 | return 0; | 515 | return 0; |
521 | } | 516 | } |
522 | 517 | ||
523 | struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, | 518 | struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, |
524 | struct ipw_network *network, | 519 | struct ipw_network *network) |
525 | dev_node_t *nodes) | ||
526 | { | 520 | { |
527 | int i, j; | 521 | int i, j; |
528 | 522 | ||
@@ -539,26 +533,23 @@ struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, | |||
539 | if (allfree) { | 533 | if (allfree) { |
540 | j = i; | 534 | j = i; |
541 | 535 | ||
542 | if (add_tty(&nodes[0], j, hardware, network, | 536 | if (add_tty(j, hardware, network, |
543 | IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, | 537 | IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, |
544 | TTYTYPE_MODEM)) | 538 | TTYTYPE_MODEM)) |
545 | return NULL; | 539 | return NULL; |
546 | 540 | ||
547 | j += IPWIRELESS_PCMCIA_MINOR_RANGE; | 541 | j += IPWIRELESS_PCMCIA_MINOR_RANGE; |
548 | if (add_tty(&nodes[1], j, hardware, network, | 542 | if (add_tty(j, hardware, network, |
549 | IPW_CHANNEL_DIALLER, -1, | 543 | IPW_CHANNEL_DIALLER, -1, |
550 | TTYTYPE_MONITOR)) | 544 | TTYTYPE_MONITOR)) |
551 | return NULL; | 545 | return NULL; |
552 | 546 | ||
553 | j += IPWIRELESS_PCMCIA_MINOR_RANGE; | 547 | j += IPWIRELESS_PCMCIA_MINOR_RANGE; |
554 | if (add_tty(NULL, j, hardware, network, | 548 | if (add_tty(j, hardware, network, |
555 | IPW_CHANNEL_RAS, -1, | 549 | IPW_CHANNEL_RAS, -1, |
556 | TTYTYPE_RAS_RAW)) | 550 | TTYTYPE_RAS_RAW)) |
557 | return NULL; | 551 | return NULL; |
558 | 552 | ||
559 | nodes[0].next = &nodes[1]; | ||
560 | nodes[1].next = NULL; | ||
561 | |||
562 | return ttys[i]; | 553 | return ttys[i]; |
563 | } | 554 | } |
564 | } | 555 | } |
diff --git a/drivers/char/pcmcia/ipwireless/tty.h b/drivers/char/pcmcia/ipwireless/tty.h index b0deb9168b6b..4da6c201f727 100644 --- a/drivers/char/pcmcia/ipwireless/tty.h +++ b/drivers/char/pcmcia/ipwireless/tty.h | |||
@@ -34,8 +34,7 @@ int ipwireless_tty_init(void); | |||
34 | void ipwireless_tty_release(void); | 34 | void ipwireless_tty_release(void); |
35 | 35 | ||
36 | struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw, | 36 | struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw, |
37 | struct ipw_network *net, | 37 | struct ipw_network *net); |
38 | dev_node_t *nodes); | ||
39 | void ipwireless_tty_free(struct ipw_tty *tty); | 38 | void ipwireless_tty_free(struct ipw_tty *tty); |
40 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | 39 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, |
41 | unsigned int length); | 40 | unsigned int length); |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c31a0d913d37..308903ec8bf8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -220,7 +220,6 @@ typedef struct _mgslpc_info { | |||
220 | 220 | ||
221 | /* PCMCIA support */ | 221 | /* PCMCIA support */ |
222 | struct pcmcia_device *p_dev; | 222 | struct pcmcia_device *p_dev; |
223 | dev_node_t node; | ||
224 | int stop; | 223 | int stop; |
225 | 224 | ||
226 | /* SPPP/Cisco HDLC device parts */ | 225 | /* SPPP/Cisco HDLC device parts */ |
@@ -552,10 +551,6 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
552 | 551 | ||
553 | /* Initialize the struct pcmcia_device structure */ | 552 | /* Initialize the struct pcmcia_device structure */ |
554 | 553 | ||
555 | /* Interrupt setup */ | ||
556 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
557 | link->irq.Handler = NULL; | ||
558 | |||
559 | link->conf.Attributes = 0; | 554 | link->conf.Attributes = 0; |
560 | link->conf.IntType = INT_MEMORY_AND_IO; | 555 | link->conf.IntType = INT_MEMORY_AND_IO; |
561 | 556 | ||
@@ -608,9 +603,7 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
608 | link->conf.ConfigIndex = 8; | 603 | link->conf.ConfigIndex = 8; |
609 | link->conf.Present = PRESENT_OPTION; | 604 | link->conf.Present = PRESENT_OPTION; |
610 | 605 | ||
611 | link->irq.Handler = mgslpc_isr; | 606 | ret = pcmcia_request_irq(link, mgslpc_isr); |
612 | |||
613 | ret = pcmcia_request_irq(link, &link->irq); | ||
614 | if (ret) | 607 | if (ret) |
615 | goto failed; | 608 | goto failed; |
616 | ret = pcmcia_request_configuration(link, &link->conf); | 609 | ret = pcmcia_request_configuration(link, &link->conf); |
@@ -618,17 +611,12 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
618 | goto failed; | 611 | goto failed; |
619 | 612 | ||
620 | info->io_base = link->io.BasePort1; | 613 | info->io_base = link->io.BasePort1; |
621 | info->irq_level = link->irq.AssignedIRQ; | 614 | info->irq_level = link->irq; |
622 | |||
623 | /* add to linked list of devices */ | ||
624 | sprintf(info->node.dev_name, "mgslpc0"); | ||
625 | info->node.major = info->node.minor = 0; | ||
626 | link->dev_node = &info->node; | ||
627 | 615 | ||
628 | printk(KERN_INFO "%s: index 0x%02x:", | 616 | dev_info(&link->dev, "index 0x%02x:", |
629 | info->node.dev_name, link->conf.ConfigIndex); | 617 | link->conf.ConfigIndex); |
630 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 618 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
631 | printk(", irq %d", link->irq.AssignedIRQ); | 619 | printk(", irq %d", link->irq); |
632 | if (link->io.NumPorts1) | 620 | if (link->io.NumPorts1) |
633 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 621 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
634 | link->io.BasePort1+link->io.NumPorts1-1); | 622 | link->io.BasePort1+link->io.NumPorts1-1); |
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index b85450865ff0..0b7815d2581c 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c | |||
@@ -65,8 +65,7 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
65 | typedef struct ide_info_t { | 65 | typedef struct ide_info_t { |
66 | struct pcmcia_device *p_dev; | 66 | struct pcmcia_device *p_dev; |
67 | struct ide_host *host; | 67 | struct ide_host *host; |
68 | int ndev; | 68 | int ndev; |
69 | dev_node_t node; | ||
70 | } ide_info_t; | 69 | } ide_info_t; |
71 | 70 | ||
72 | static void ide_release(struct pcmcia_device *); | 71 | static void ide_release(struct pcmcia_device *); |
@@ -102,7 +101,6 @@ static int ide_probe(struct pcmcia_device *link) | |||
102 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 101 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
103 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 102 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
104 | link->io.IOAddrLines = 3; | 103 | link->io.IOAddrLines = 3; |
105 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
106 | link->conf.Attributes = CONF_ENABLE_IRQ; | 104 | link->conf.Attributes = CONF_ENABLE_IRQ; |
107 | link->conf.IntType = INT_MEMORY_AND_IO; | 105 | link->conf.IntType = INT_MEMORY_AND_IO; |
108 | 106 | ||
@@ -285,8 +283,7 @@ static int ide_config(struct pcmcia_device *link) | |||
285 | io_base = link->io.BasePort1; | 283 | io_base = link->io.BasePort1; |
286 | ctl_base = stk->ctl_base; | 284 | ctl_base = stk->ctl_base; |
287 | 285 | ||
288 | ret = pcmcia_request_irq(link, &link->irq); | 286 | if (!link->irq) |
289 | if (ret) | ||
290 | goto failed; | 287 | goto failed; |
291 | ret = pcmcia_request_configuration(link, &link->conf); | 288 | ret = pcmcia_request_configuration(link, &link->conf); |
292 | if (ret) | 289 | if (ret) |
@@ -299,24 +296,21 @@ static int ide_config(struct pcmcia_device *link) | |||
299 | if (is_kme) | 296 | if (is_kme) |
300 | outb(0x81, ctl_base+1); | 297 | outb(0x81, ctl_base+1); |
301 | 298 | ||
302 | host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); | 299 | host = idecs_register(io_base, ctl_base, link->irq, link); |
303 | if (host == NULL && link->io.NumPorts1 == 0x20) { | 300 | if (host == NULL && link->io.NumPorts1 == 0x20) { |
304 | outb(0x02, ctl_base + 0x10); | 301 | outb(0x02, ctl_base + 0x10); |
305 | host = idecs_register(io_base + 0x10, ctl_base + 0x10, | 302 | host = idecs_register(io_base + 0x10, ctl_base + 0x10, |
306 | link->irq.AssignedIRQ, link); | 303 | link->irq, link); |
307 | } | 304 | } |
308 | 305 | ||
309 | if (host == NULL) | 306 | if (host == NULL) |
310 | goto failed; | 307 | goto failed; |
311 | 308 | ||
312 | info->ndev = 1; | 309 | info->ndev = 1; |
313 | sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2); | ||
314 | info->node.major = host->ports[0]->major; | ||
315 | info->node.minor = 0; | ||
316 | info->host = host; | 310 | info->host = host; |
317 | link->dev_node = &info->node; | 311 | dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n", |
318 | printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", | 312 | 'a' + host->ports[0]->index * 2, |
319 | info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); | 313 | link->conf.Vpp / 10, link->conf.Vpp % 10); |
320 | 314 | ||
321 | kfree(stk); | 315 | kfree(stk); |
322 | return 0; | 316 | return 0; |
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 94b796d84053..f410d0eb2fef 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
16 | #include <linux/slab.h> | ||
17 | #include <linux/string.h> | 16 | #include <linux/string.h> |
18 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
19 | #include <linux/serial.h> | 18 | #include <linux/serial.h> |
@@ -61,31 +60,6 @@ static void avmcs_release(struct pcmcia_device *link); | |||
61 | 60 | ||
62 | static void avmcs_detach(struct pcmcia_device *p_dev); | 61 | static void avmcs_detach(struct pcmcia_device *p_dev); |
63 | 62 | ||
64 | /* | ||
65 | A linked list of "instances" of the skeleton device. Each actual | ||
66 | PCMCIA card corresponds to one device instance, and is described | ||
67 | by one struct pcmcia_device structure (defined in ds.h). | ||
68 | |||
69 | You may not want to use a linked list for this -- for example, the | ||
70 | memory card driver uses an array of struct pcmcia_device pointers, where minor | ||
71 | device numbers are used to derive the corresponding array index. | ||
72 | */ | ||
73 | |||
74 | /* | ||
75 | A driver needs to provide a dev_node_t structure for each device | ||
76 | on a card. In some cases, there is only one device per card (for | ||
77 | example, ethernet cards, modems). In other cases, there may be | ||
78 | many actual or logical devices (SCSI adapters, memory cards with | ||
79 | multiple partitions). The dev_node_t structures need to be kept | ||
80 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
81 | structure. We allocate them in the card's private data structure, | ||
82 | because they generally can't be allocated dynamically. | ||
83 | */ | ||
84 | |||
85 | typedef struct local_info_t { | ||
86 | dev_node_t node; | ||
87 | } local_info_t; | ||
88 | |||
89 | /*====================================================================== | 63 | /*====================================================================== |
90 | 64 | ||
91 | avmcs_attach() creates an "instance" of the driver, allocating | 65 | avmcs_attach() creates an "instance" of the driver, allocating |
@@ -100,32 +74,19 @@ typedef struct local_info_t { | |||
100 | 74 | ||
101 | static int avmcs_probe(struct pcmcia_device *p_dev) | 75 | static int avmcs_probe(struct pcmcia_device *p_dev) |
102 | { | 76 | { |
103 | local_info_t *local; | ||
104 | 77 | ||
105 | /* The io structure describes IO port mapping */ | 78 | /* The io structure describes IO port mapping */ |
106 | p_dev->io.NumPorts1 = 16; | 79 | p_dev->io.NumPorts1 = 16; |
107 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 80 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
108 | p_dev->io.NumPorts2 = 0; | 81 | p_dev->io.NumPorts2 = 0; |
109 | 82 | ||
110 | /* Interrupt setup */ | ||
111 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
112 | |||
113 | /* General socket configuration */ | 83 | /* General socket configuration */ |
114 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 84 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
115 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 85 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
116 | p_dev->conf.ConfigIndex = 1; | 86 | p_dev->conf.ConfigIndex = 1; |
117 | p_dev->conf.Present = PRESENT_OPTION; | 87 | p_dev->conf.Present = PRESENT_OPTION; |
118 | 88 | ||
119 | /* Allocate space for private device-specific data */ | ||
120 | local = kzalloc(sizeof(local_info_t), GFP_KERNEL); | ||
121 | if (!local) | ||
122 | goto err; | ||
123 | p_dev->priv = local; | ||
124 | |||
125 | return avmcs_config(p_dev); | 89 | return avmcs_config(p_dev); |
126 | |||
127 | err: | ||
128 | return -ENOMEM; | ||
129 | } /* avmcs_attach */ | 90 | } /* avmcs_attach */ |
130 | 91 | ||
131 | /*====================================================================== | 92 | /*====================================================================== |
@@ -140,7 +101,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev) | |||
140 | static void avmcs_detach(struct pcmcia_device *link) | 101 | static void avmcs_detach(struct pcmcia_device *link) |
141 | { | 102 | { |
142 | avmcs_release(link); | 103 | avmcs_release(link); |
143 | kfree(link->priv); | ||
144 | } /* avmcs_detach */ | 104 | } /* avmcs_detach */ |
145 | 105 | ||
146 | /*====================================================================== | 106 | /*====================================================================== |
@@ -171,14 +131,11 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev, | |||
171 | 131 | ||
172 | static int avmcs_config(struct pcmcia_device *link) | 132 | static int avmcs_config(struct pcmcia_device *link) |
173 | { | 133 | { |
174 | local_info_t *dev; | 134 | int i = -1; |
175 | int i; | ||
176 | char devname[128]; | 135 | char devname[128]; |
177 | int cardtype; | 136 | int cardtype; |
178 | int (*addcard)(unsigned int port, unsigned irq); | 137 | int (*addcard)(unsigned int port, unsigned irq); |
179 | 138 | ||
180 | dev = link->priv; | ||
181 | |||
182 | devname[0] = 0; | 139 | devname[0] = 0; |
183 | if (link->prod_id[1]) | 140 | if (link->prod_id[1]) |
184 | strlcpy(devname, link->prod_id[1], sizeof(devname)); | 141 | strlcpy(devname, link->prod_id[1], sizeof(devname)); |
@@ -190,11 +147,7 @@ static int avmcs_config(struct pcmcia_device *link) | |||
190 | return -ENODEV; | 147 | return -ENODEV; |
191 | 148 | ||
192 | do { | 149 | do { |
193 | /* | 150 | if (!link->irq) { |
194 | * allocate an interrupt line | ||
195 | */ | ||
196 | i = pcmcia_request_irq(link, &link->irq); | ||
197 | if (i != 0) { | ||
198 | /* undo */ | 151 | /* undo */ |
199 | pcmcia_disable_device(link); | 152 | pcmcia_disable_device(link); |
200 | break; | 153 | break; |
@@ -211,15 +164,11 @@ static int avmcs_config(struct pcmcia_device *link) | |||
211 | 164 | ||
212 | } while (0); | 165 | } while (0); |
213 | 166 | ||
214 | /* At this point, the dev_node_t structure(s) should be | ||
215 | initialized and arranged in a linked list at link->dev. */ | ||
216 | |||
217 | if (devname[0]) { | 167 | if (devname[0]) { |
218 | char *s = strrchr(devname, ' '); | 168 | char *s = strrchr(devname, ' '); |
219 | if (!s) | 169 | if (!s) |
220 | s = devname; | 170 | s = devname; |
221 | else s++; | 171 | else s++; |
222 | strcpy(dev->node.dev_name, s); | ||
223 | if (strcmp("M1", s) == 0) { | 172 | if (strcmp("M1", s) == 0) { |
224 | cardtype = AVM_CARDTYPE_M1; | 173 | cardtype = AVM_CARDTYPE_M1; |
225 | } else if (strcmp("M2", s) == 0) { | 174 | } else if (strcmp("M2", s) == 0) { |
@@ -227,14 +176,8 @@ static int avmcs_config(struct pcmcia_device *link) | |||
227 | } else { | 176 | } else { |
228 | cardtype = AVM_CARDTYPE_B1; | 177 | cardtype = AVM_CARDTYPE_B1; |
229 | } | 178 | } |
230 | } else { | 179 | } else |
231 | strcpy(dev->node.dev_name, "b1"); | ||
232 | cardtype = AVM_CARDTYPE_B1; | 180 | cardtype = AVM_CARDTYPE_B1; |
233 | } | ||
234 | |||
235 | dev->node.major = 64; | ||
236 | dev->node.minor = 0; | ||
237 | link->dev_node = &dev->node; | ||
238 | 181 | ||
239 | /* If any step failed, release any partially configured state */ | 182 | /* If any step failed, release any partially configured state */ |
240 | if (i != 0) { | 183 | if (i != 0) { |
@@ -249,13 +192,12 @@ static int avmcs_config(struct pcmcia_device *link) | |||
249 | default: | 192 | default: |
250 | case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; | 193 | case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; |
251 | } | 194 | } |
252 | if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { | 195 | if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) { |
253 | printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", | 196 | dev_err(&link->dev, "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n", |
254 | dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); | 197 | link->io.BasePort1, link->irq); |
255 | avmcs_release(link); | 198 | avmcs_release(link); |
256 | return -ENODEV; | 199 | return -ENODEV; |
257 | } | 200 | } |
258 | dev->node.minor = i; | ||
259 | return 0; | 201 | return 0; |
260 | 202 | ||
261 | } /* avmcs_config */ | 203 | } /* avmcs_config */ |
@@ -270,7 +212,7 @@ static int avmcs_config(struct pcmcia_device *link) | |||
270 | 212 | ||
271 | static void avmcs_release(struct pcmcia_device *link) | 213 | static void avmcs_release(struct pcmcia_device *link) |
272 | { | 214 | { |
273 | b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); | 215 | b1pcmcia_delcard(link->io.BasePort1, link->irq); |
274 | pcmcia_disable_device(link); | 216 | pcmcia_disable_device(link); |
275 | } /* avmcs_release */ | 217 | } /* avmcs_release */ |
276 | 218 | ||
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 8d1d63a02b34..a80a7617f16f 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c | |||
@@ -62,31 +62,6 @@ static void avma1cs_release(struct pcmcia_device *link); | |||
62 | static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; | 62 | static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; |
63 | 63 | ||
64 | 64 | ||
65 | /* | ||
66 | A linked list of "instances" of the skeleton device. Each actual | ||
67 | PCMCIA card corresponds to one device instance, and is described | ||
68 | by one struct pcmcia_device structure (defined in ds.h). | ||
69 | |||
70 | You may not want to use a linked list for this -- for example, the | ||
71 | memory card driver uses an array of struct pcmcia_device pointers, where minor | ||
72 | device numbers are used to derive the corresponding array index. | ||
73 | */ | ||
74 | |||
75 | /* | ||
76 | A driver needs to provide a dev_node_t structure for each device | ||
77 | on a card. In some cases, there is only one device per card (for | ||
78 | example, ethernet cards, modems). In other cases, there may be | ||
79 | many actual or logical devices (SCSI adapters, memory cards with | ||
80 | multiple partitions). The dev_node_t structures need to be kept | ||
81 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
82 | structure. We allocate them in the card's private data structure, | ||
83 | because they generally can't be allocated dynamically. | ||
84 | */ | ||
85 | |||
86 | typedef struct local_info_t { | ||
87 | dev_node_t node; | ||
88 | } local_info_t; | ||
89 | |||
90 | /*====================================================================== | 65 | /*====================================================================== |
91 | 66 | ||
92 | avma1cs_attach() creates an "instance" of the driver, allocating | 67 | avma1cs_attach() creates an "instance" of the driver, allocating |
@@ -101,17 +76,8 @@ typedef struct local_info_t { | |||
101 | 76 | ||
102 | static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) | 77 | static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) |
103 | { | 78 | { |
104 | local_info_t *local; | ||
105 | |||
106 | dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); | 79 | dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); |
107 | 80 | ||
108 | /* Allocate space for private device-specific data */ | ||
109 | local = kzalloc(sizeof(local_info_t), GFP_KERNEL); | ||
110 | if (!local) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | p_dev->priv = local; | ||
114 | |||
115 | /* The io structure describes IO port mapping */ | 81 | /* The io structure describes IO port mapping */ |
116 | p_dev->io.NumPorts1 = 16; | 82 | p_dev->io.NumPorts1 = 16; |
117 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 83 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
@@ -119,9 +85,6 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) | |||
119 | p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; | 85 | p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; |
120 | p_dev->io.IOAddrLines = 5; | 86 | p_dev->io.IOAddrLines = 5; |
121 | 87 | ||
122 | /* Interrupt setup */ | ||
123 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
124 | |||
125 | /* General socket configuration */ | 88 | /* General socket configuration */ |
126 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 89 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
127 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 90 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
@@ -176,14 +139,11 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, | |||
176 | 139 | ||
177 | static int __devinit avma1cs_config(struct pcmcia_device *link) | 140 | static int __devinit avma1cs_config(struct pcmcia_device *link) |
178 | { | 141 | { |
179 | local_info_t *dev; | 142 | int i = -1; |
180 | int i; | ||
181 | char devname[128]; | 143 | char devname[128]; |
182 | IsdnCard_t icard; | 144 | IsdnCard_t icard; |
183 | int busy = 0; | 145 | int busy = 0; |
184 | 146 | ||
185 | dev = link->priv; | ||
186 | |||
187 | dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link); | 147 | dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link); |
188 | 148 | ||
189 | devname[0] = 0; | 149 | devname[0] = 0; |
@@ -197,8 +157,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
197 | /* | 157 | /* |
198 | * allocate an interrupt line | 158 | * allocate an interrupt line |
199 | */ | 159 | */ |
200 | i = pcmcia_request_irq(link, &link->irq); | 160 | if (!link->irq) { |
201 | if (i != 0) { | ||
202 | /* undo */ | 161 | /* undo */ |
203 | pcmcia_disable_device(link); | 162 | pcmcia_disable_device(link); |
204 | break; | 163 | break; |
@@ -215,14 +174,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
215 | 174 | ||
216 | } while (0); | 175 | } while (0); |
217 | 176 | ||
218 | /* At this point, the dev_node_t structure(s) should be | ||
219 | initialized and arranged in a linked list at link->dev. */ | ||
220 | |||
221 | strcpy(dev->node.dev_name, "A1"); | ||
222 | dev->node.major = 45; | ||
223 | dev->node.minor = 0; | ||
224 | link->dev_node = &dev->node; | ||
225 | |||
226 | /* If any step failed, release any partially configured state */ | 177 | /* If any step failed, release any partially configured state */ |
227 | if (i != 0) { | 178 | if (i != 0) { |
228 | avma1cs_release(link); | 179 | avma1cs_release(link); |
@@ -230,9 +181,9 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
230 | } | 181 | } |
231 | 182 | ||
232 | printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", | 183 | printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", |
233 | link->io.BasePort1, link->irq.AssignedIRQ); | 184 | link->io.BasePort1, link->irq); |
234 | 185 | ||
235 | icard.para[0] = link->irq.AssignedIRQ; | 186 | icard.para[0] = link->irq; |
236 | icard.para[1] = link->io.BasePort1; | 187 | icard.para[1] = link->io.BasePort1; |
237 | icard.protocol = isdnprot; | 188 | icard.protocol = isdnprot; |
238 | icard.typ = ISDN_CTYPE_A1_PCMCIA; | 189 | icard.typ = ISDN_CTYPE_A1_PCMCIA; |
@@ -243,7 +194,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
243 | avma1cs_release(link); | 194 | avma1cs_release(link); |
244 | return -ENODEV; | 195 | return -ENODEV; |
245 | } | 196 | } |
246 | dev->node.minor = i; | 197 | link->priv = (void *) (unsigned long) i; |
247 | 198 | ||
248 | return 0; | 199 | return 0; |
249 | } /* avma1cs_config */ | 200 | } /* avma1cs_config */ |
@@ -258,12 +209,12 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
258 | 209 | ||
259 | static void avma1cs_release(struct pcmcia_device *link) | 210 | static void avma1cs_release(struct pcmcia_device *link) |
260 | { | 211 | { |
261 | local_info_t *local = link->priv; | 212 | unsigned long minor = (unsigned long) link->priv; |
262 | 213 | ||
263 | dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link); | 214 | dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link); |
264 | 215 | ||
265 | /* now unregister function with hisax */ | 216 | /* now unregister function with hisax */ |
266 | HiSax_closecard(local->node.minor); | 217 | HiSax_closecard(minor); |
267 | 218 | ||
268 | pcmcia_disable_device(link); | 219 | pcmcia_disable_device(link); |
269 | } /* avma1cs_release */ | 220 | } /* avma1cs_release */ |
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c9f2279e21f5..218927e3a4ea 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c | |||
@@ -87,24 +87,8 @@ static void elsa_cs_release(struct pcmcia_device *link); | |||
87 | 87 | ||
88 | static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; | 88 | static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; |
89 | 89 | ||
90 | /* | ||
91 | A driver needs to provide a dev_node_t structure for each device | ||
92 | on a card. In some cases, there is only one device per card (for | ||
93 | example, ethernet cards, modems). In other cases, there may be | ||
94 | many actual or logical devices (SCSI adapters, memory cards with | ||
95 | multiple partitions). The dev_node_t structures need to be kept | ||
96 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
97 | structure. We allocate them in the card's private data structure, | ||
98 | because they generally shouldn't be allocated dynamically. | ||
99 | In this case, we also provide a flag to indicate if a device is | ||
100 | "stopped" due to a power management event, or card ejection. The | ||
101 | device IO routines can use a flag like this to throttle IO to a | ||
102 | card that is not ready to accept it. | ||
103 | */ | ||
104 | |||
105 | typedef struct local_info_t { | 90 | typedef struct local_info_t { |
106 | struct pcmcia_device *p_dev; | 91 | struct pcmcia_device *p_dev; |
107 | dev_node_t node; | ||
108 | int busy; | 92 | int busy; |
109 | int cardnr; | 93 | int cardnr; |
110 | } local_info_t; | 94 | } local_info_t; |
@@ -136,10 +120,6 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link) | |||
136 | 120 | ||
137 | local->cardnr = -1; | 121 | local->cardnr = -1; |
138 | 122 | ||
139 | /* Interrupt setup */ | ||
140 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
141 | link->irq.Handler = NULL; | ||
142 | |||
143 | /* | 123 | /* |
144 | General socket configuration defaults can go here. In this | 124 | General socket configuration defaults can go here. In this |
145 | client, we assume very little, and rely on the CIS for almost | 125 | 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) | |||
223 | if (i != 0) | 203 | if (i != 0) |
224 | goto failed; | 204 | goto failed; |
225 | 205 | ||
226 | i = pcmcia_request_irq(link, &link->irq); | 206 | if (!link->irq) |
227 | if (i != 0) { | ||
228 | link->irq.AssignedIRQ = 0; | ||
229 | goto failed; | 207 | goto failed; |
230 | } | ||
231 | 208 | ||
232 | i = pcmcia_request_configuration(link, &link->conf); | 209 | i = pcmcia_request_configuration(link, &link->conf); |
233 | if (i != 0) | 210 | if (i != 0) |
234 | goto failed; | 211 | goto failed; |
235 | 212 | ||
236 | /* At this point, the dev_node_t structure(s) should be | ||
237 | initialized and arranged in a linked list at link->dev. *//* */ | ||
238 | sprintf(dev->node.dev_name, "elsa"); | ||
239 | dev->node.major = dev->node.minor = 0x0; | ||
240 | |||
241 | link->dev_node = &dev->node; | ||
242 | |||
243 | /* Finally, report what we've done */ | 213 | /* Finally, report what we've done */ |
244 | printk(KERN_INFO "%s: index 0x%02x: ", | 214 | dev_info(&link->dev, "index 0x%02x: ", |
245 | dev->node.dev_name, link->conf.ConfigIndex); | 215 | link->conf.ConfigIndex); |
246 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 216 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
247 | printk(", irq %d", link->irq.AssignedIRQ); | 217 | printk(", irq %d", link->irq); |
248 | if (link->io.NumPorts1) | 218 | if (link->io.NumPorts1) |
249 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 219 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
250 | link->io.BasePort1+link->io.NumPorts1-1); | 220 | link->io.BasePort1+link->io.NumPorts1-1); |
@@ -253,7 +223,7 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) | |||
253 | link->io.BasePort2+link->io.NumPorts2-1); | 223 | link->io.BasePort2+link->io.NumPorts2-1); |
254 | printk("\n"); | 224 | printk("\n"); |
255 | 225 | ||
256 | icard.para[0] = link->irq.AssignedIRQ; | 226 | icard.para[0] = link->irq; |
257 | icard.para[1] = link->io.BasePort1; | 227 | icard.para[1] = link->io.BasePort1; |
258 | icard.protocol = protocol; | 228 | icard.protocol = protocol; |
259 | icard.typ = ISDN_CTYPE_ELSA_PCMCIA; | 229 | icard.typ = ISDN_CTYPE_ELSA_PCMCIA; |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 71b3ddef03bb..1f4feaab21af 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -87,32 +87,8 @@ static void sedlbauer_release(struct pcmcia_device *link); | |||
87 | 87 | ||
88 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; | 88 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; |
89 | 89 | ||
90 | /* | ||
91 | You'll also need to prototype all the functions that will actually | ||
92 | be used to talk to your device. See 'memory_cs' for a good example | ||
93 | of a fully self-sufficient driver; the other drivers rely more or | ||
94 | less on other parts of the kernel. | ||
95 | */ | ||
96 | |||
97 | /* | ||
98 | A driver needs to provide a dev_node_t structure for each device | ||
99 | on a card. In some cases, there is only one device per card (for | ||
100 | example, ethernet cards, modems). In other cases, there may be | ||
101 | many actual or logical devices (SCSI adapters, memory cards with | ||
102 | multiple partitions). The dev_node_t structures need to be kept | ||
103 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
104 | structure. We allocate them in the card's private data structure, | ||
105 | because they generally shouldn't be allocated dynamically. | ||
106 | |||
107 | In this case, we also provide a flag to indicate if a device is | ||
108 | "stopped" due to a power management event, or card ejection. The | ||
109 | device IO routines can use a flag like this to throttle IO to a | ||
110 | card that is not ready to accept it. | ||
111 | */ | ||
112 | |||
113 | typedef struct local_info_t { | 90 | typedef struct local_info_t { |
114 | struct pcmcia_device *p_dev; | 91 | struct pcmcia_device *p_dev; |
115 | dev_node_t node; | ||
116 | int stop; | 92 | int stop; |
117 | int cardnr; | 93 | int cardnr; |
118 | } local_info_t; | 94 | } local_info_t; |
@@ -143,10 +119,6 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link) | |||
143 | local->p_dev = link; | 119 | local->p_dev = link; |
144 | link->priv = local; | 120 | link->priv = local; |
145 | 121 | ||
146 | /* Interrupt setup */ | ||
147 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
148 | link->irq.Handler = NULL; | ||
149 | |||
150 | /* | 122 | /* |
151 | General socket configuration defaults can go here. In this | 123 | General socket configuration defaults can go here. In this |
152 | client, we assume very little, and rely on the CIS for almost | 124 | 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, | |||
227 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | 199 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) |
228 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | 200 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; |
229 | 201 | ||
230 | /* Do we need to allocate an interrupt? */ | 202 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
231 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
232 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
233 | 203 | ||
234 | /* IO window settings */ | 204 | /* IO window settings */ |
235 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 205 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -285,7 +255,6 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, | |||
285 | 255 | ||
286 | static int __devinit sedlbauer_config(struct pcmcia_device *link) | 256 | static int __devinit sedlbauer_config(struct pcmcia_device *link) |
287 | { | 257 | { |
288 | local_info_t *dev = link->priv; | ||
289 | win_req_t *req; | 258 | win_req_t *req; |
290 | int ret; | 259 | int ret; |
291 | IsdnCard_t icard; | 260 | IsdnCard_t icard; |
@@ -313,17 +282,6 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) | |||
313 | goto failed; | 282 | goto failed; |
314 | 283 | ||
315 | /* | 284 | /* |
316 | Allocate an interrupt line. Note that this does not assign a | ||
317 | handler to the interrupt, unless the 'Handler' member of the | ||
318 | irq structure is initialized. | ||
319 | */ | ||
320 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
321 | ret = pcmcia_request_irq(link, &link->irq); | ||
322 | if (ret) | ||
323 | goto failed; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | This actually configures the PCMCIA socket -- setting up | 285 | This actually configures the PCMCIA socket -- setting up |
328 | the I/O windows and the interrupt mapping, and putting the | 286 | the I/O windows and the interrupt mapping, and putting the |
329 | card and host interface into "Memory and IO" mode. | 287 | card and host interface into "Memory and IO" mode. |
@@ -332,21 +290,13 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) | |||
332 | if (ret) | 290 | if (ret) |
333 | goto failed; | 291 | goto failed; |
334 | 292 | ||
335 | /* | ||
336 | At this point, the dev_node_t structure(s) need to be | ||
337 | initialized and arranged in a linked list at link->dev. | ||
338 | */ | ||
339 | sprintf(dev->node.dev_name, "sedlbauer"); | ||
340 | dev->node.major = dev->node.minor = 0; | ||
341 | link->dev_node = &dev->node; | ||
342 | |||
343 | /* Finally, report what we've done */ | 293 | /* Finally, report what we've done */ |
344 | printk(KERN_INFO "%s: index 0x%02x:", | 294 | dev_info(&link->dev, "index 0x%02x:", |
345 | dev->node.dev_name, link->conf.ConfigIndex); | 295 | link->conf.ConfigIndex); |
346 | if (link->conf.Vpp) | 296 | if (link->conf.Vpp) |
347 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); | 297 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); |
348 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 298 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
349 | printk(", irq %d", link->irq.AssignedIRQ); | 299 | printk(", irq %d", link->irq); |
350 | if (link->io.NumPorts1) | 300 | if (link->io.NumPorts1) |
351 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 301 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
352 | link->io.BasePort1+link->io.NumPorts1-1); | 302 | link->io.BasePort1+link->io.NumPorts1-1); |
@@ -358,7 +308,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) | |||
358 | req->Base+req->Size-1); | 308 | req->Base+req->Size-1); |
359 | printk("\n"); | 309 | printk("\n"); |
360 | 310 | ||
361 | icard.para[0] = link->irq.AssignedIRQ; | 311 | icard.para[0] = link->irq; |
362 | icard.para[1] = link->io.BasePort1; | 312 | icard.para[1] = link->io.BasePort1; |
363 | icard.protocol = protocol; | 313 | icard.protocol = protocol; |
364 | icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; | 314 | icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; |
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index d010a0da8e19..5771955cc532 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c | |||
@@ -68,34 +68,8 @@ static void teles_cs_release(struct pcmcia_device *link); | |||
68 | 68 | ||
69 | static void teles_detach(struct pcmcia_device *p_dev) __devexit ; | 69 | static void teles_detach(struct pcmcia_device *p_dev) __devexit ; |
70 | 70 | ||
71 | /* | ||
72 | A linked list of "instances" of the teles_cs device. Each actual | ||
73 | PCMCIA card corresponds to one device instance, and is described | ||
74 | by one struct pcmcia_device structure (defined in ds.h). | ||
75 | |||
76 | You may not want to use a linked list for this -- for example, the | ||
77 | memory card driver uses an array of struct pcmcia_device pointers, where minor | ||
78 | device numbers are used to derive the corresponding array index. | ||
79 | */ | ||
80 | |||
81 | /* | ||
82 | A driver needs to provide a dev_node_t structure for each device | ||
83 | on a card. In some cases, there is only one device per card (for | ||
84 | example, ethernet cards, modems). In other cases, there may be | ||
85 | many actual or logical devices (SCSI adapters, memory cards with | ||
86 | multiple partitions). The dev_node_t structures need to be kept | ||
87 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
88 | structure. We allocate them in the card's private data structure, | ||
89 | because they generally shouldn't be allocated dynamically. | ||
90 | In this case, we also provide a flag to indicate if a device is | ||
91 | "stopped" due to a power management event, or card ejection. The | ||
92 | device IO routines can use a flag like this to throttle IO to a | ||
93 | card that is not ready to accept it. | ||
94 | */ | ||
95 | |||
96 | typedef struct local_info_t { | 71 | typedef struct local_info_t { |
97 | struct pcmcia_device *p_dev; | 72 | struct pcmcia_device *p_dev; |
98 | dev_node_t node; | ||
99 | int busy; | 73 | int busy; |
100 | int cardnr; | 74 | int cardnr; |
101 | } local_info_t; | 75 | } local_info_t; |
@@ -126,10 +100,6 @@ static int __devinit teles_probe(struct pcmcia_device *link) | |||
126 | local->p_dev = link; | 100 | local->p_dev = link; |
127 | link->priv = local; | 101 | link->priv = local; |
128 | 102 | ||
129 | /* Interrupt setup */ | ||
130 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
131 | link->irq.Handler = NULL; | ||
132 | |||
133 | /* | 103 | /* |
134 | General socket configuration defaults can go here. In this | 104 | General socket configuration defaults can go here. In this |
135 | client, we assume very little, and rely on the CIS for almost | 105 | 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) | |||
213 | if (i != 0) | 183 | if (i != 0) |
214 | goto cs_failed; | 184 | goto cs_failed; |
215 | 185 | ||
216 | i = pcmcia_request_irq(link, &link->irq); | 186 | if (!link->irq) |
217 | if (i != 0) { | ||
218 | link->irq.AssignedIRQ = 0; | ||
219 | goto cs_failed; | 187 | goto cs_failed; |
220 | } | ||
221 | 188 | ||
222 | i = pcmcia_request_configuration(link, &link->conf); | 189 | i = pcmcia_request_configuration(link, &link->conf); |
223 | if (i != 0) | 190 | if (i != 0) |
224 | goto cs_failed; | 191 | goto cs_failed; |
225 | 192 | ||
226 | /* At this point, the dev_node_t structure(s) should be | ||
227 | initialized and arranged in a linked list at link->dev. *//* */ | ||
228 | sprintf(dev->node.dev_name, "teles"); | ||
229 | dev->node.major = dev->node.minor = 0x0; | ||
230 | |||
231 | link->dev_node = &dev->node; | ||
232 | |||
233 | /* Finally, report what we've done */ | 193 | /* Finally, report what we've done */ |
234 | printk(KERN_INFO "%s: index 0x%02x:", | 194 | dev_info(&link->dev, "index 0x%02x:", |
235 | dev->node.dev_name, link->conf.ConfigIndex); | 195 | link->conf.ConfigIndex); |
236 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 196 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
237 | printk(", irq %d", link->irq.AssignedIRQ); | 197 | printk(", irq %d", link->irq); |
238 | if (link->io.NumPorts1) | 198 | if (link->io.NumPorts1) |
239 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 199 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
240 | link->io.BasePort1+link->io.NumPorts1-1); | 200 | link->io.BasePort1+link->io.NumPorts1-1); |
@@ -243,7 +203,7 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) | |||
243 | link->io.BasePort2+link->io.NumPorts2-1); | 203 | link->io.BasePort2+link->io.NumPorts2-1); |
244 | printk("\n"); | 204 | printk("\n"); |
245 | 205 | ||
246 | icard.para[0] = link->irq.AssignedIRQ; | 206 | icard.para[0] = link->irq; |
247 | icard.para[1] = link->io.BasePort1; | 207 | icard.para[1] = link->io.BasePort1; |
248 | icard.protocol = protocol; | 208 | icard.protocol = protocol; |
249 | icard.typ = ISDN_CTYPE_TELESPCMCIA; | 209 | icard.typ = ISDN_CTYPE_TELESPCMCIA; |
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 689d6a79ffc0..87b2b8ff331e 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -52,7 +52,6 @@ static const int debug = 0; | |||
52 | 52 | ||
53 | struct pcmciamtd_dev { | 53 | struct pcmciamtd_dev { |
54 | struct pcmcia_device *p_dev; | 54 | struct pcmcia_device *p_dev; |
55 | dev_node_t node; /* device node */ | ||
56 | caddr_t win_base; /* ioremapped address of PCMCIA window */ | 55 | caddr_t win_base; /* ioremapped address of PCMCIA window */ |
57 | unsigned int win_size; /* size of window */ | 56 | unsigned int win_size; /* size of window */ |
58 | unsigned int offset; /* offset into card the window currently points at */ | 57 | unsigned int offset; /* offset into card the window currently points at */ |
@@ -647,9 +646,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) | |||
647 | pcmciamtd_release(link); | 646 | pcmciamtd_release(link); |
648 | return -ENODEV; | 647 | return -ENODEV; |
649 | } | 648 | } |
650 | snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); | ||
651 | info("mtd%d: %s", mtd->index, mtd->name); | 649 | info("mtd%d: %s", mtd->index, mtd->name); |
652 | link->dev_node = &dev->node; | ||
653 | return 0; | 650 | return 0; |
654 | 651 | ||
655 | failed: | 652 | failed: |
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 757f87bb1db3..30b7cf70fbe6 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -93,7 +93,6 @@ earlier 3Com products. | |||
93 | #include <pcmcia/cisreg.h> | 93 | #include <pcmcia/cisreg.h> |
94 | #include <pcmcia/ciscode.h> | 94 | #include <pcmcia/ciscode.h> |
95 | #include <pcmcia/ds.h> | 95 | #include <pcmcia/ds.h> |
96 | #include <pcmcia/mem_op.h> | ||
97 | 96 | ||
98 | #include <asm/uaccess.h> | 97 | #include <asm/uaccess.h> |
99 | #include <asm/io.h> | 98 | #include <asm/io.h> |
@@ -200,7 +199,6 @@ enum Window4 { /* Window 4: Xcvr/media bits. */ | |||
200 | 199 | ||
201 | struct el3_private { | 200 | struct el3_private { |
202 | struct pcmcia_device *p_dev; | 201 | struct pcmcia_device *p_dev; |
203 | dev_node_t node; | ||
204 | u16 advertising, partner; /* NWay media advertisement */ | 202 | u16 advertising, partner; /* NWay media advertisement */ |
205 | unsigned char phys; /* MII device address */ | 203 | unsigned char phys; /* MII device address */ |
206 | unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */ | 204 | 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) | |||
283 | spin_lock_init(&lp->window_lock); | 281 | spin_lock_init(&lp->window_lock); |
284 | link->io.NumPorts1 = 32; | 282 | link->io.NumPorts1 = 32; |
285 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 283 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |
286 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
287 | link->irq.Handler = &el3_interrupt; | ||
288 | link->conf.Attributes = CONF_ENABLE_IRQ; | 284 | link->conf.Attributes = CONF_ENABLE_IRQ; |
289 | link->conf.IntType = INT_MEMORY_AND_IO; | 285 | link->conf.IntType = INT_MEMORY_AND_IO; |
290 | link->conf.ConfigIndex = 1; | 286 | link->conf.ConfigIndex = 1; |
@@ -311,8 +307,7 @@ static void tc574_detach(struct pcmcia_device *link) | |||
311 | 307 | ||
312 | dev_dbg(&link->dev, "3c574_detach()\n"); | 308 | dev_dbg(&link->dev, "3c574_detach()\n"); |
313 | 309 | ||
314 | if (link->dev_node) | 310 | unregister_netdev(dev); |
315 | unregister_netdev(dev); | ||
316 | 311 | ||
317 | tc574_release(link); | 312 | tc574_release(link); |
318 | 313 | ||
@@ -353,7 +348,7 @@ static int tc574_config(struct pcmcia_device *link) | |||
353 | if (i != 0) | 348 | if (i != 0) |
354 | goto failed; | 349 | goto failed; |
355 | 350 | ||
356 | ret = pcmcia_request_irq(link, &link->irq); | 351 | ret = pcmcia_request_irq(link, el3_interrupt); |
357 | if (ret) | 352 | if (ret) |
358 | goto failed; | 353 | goto failed; |
359 | 354 | ||
@@ -361,7 +356,7 @@ static int tc574_config(struct pcmcia_device *link) | |||
361 | if (ret) | 356 | if (ret) |
362 | goto failed; | 357 | goto failed; |
363 | 358 | ||
364 | dev->irq = link->irq.AssignedIRQ; | 359 | dev->irq = link->irq; |
365 | dev->base_addr = link->io.BasePort1; | 360 | dev->base_addr = link->io.BasePort1; |
366 | 361 | ||
367 | ioaddr = dev->base_addr; | 362 | ioaddr = dev->base_addr; |
@@ -446,17 +441,13 @@ static int tc574_config(struct pcmcia_device *link) | |||
446 | } | 441 | } |
447 | } | 442 | } |
448 | 443 | ||
449 | link->dev_node = &lp->node; | ||
450 | SET_NETDEV_DEV(dev, &link->dev); | 444 | SET_NETDEV_DEV(dev, &link->dev); |
451 | 445 | ||
452 | if (register_netdev(dev) != 0) { | 446 | if (register_netdev(dev) != 0) { |
453 | printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); | 447 | printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); |
454 | link->dev_node = NULL; | ||
455 | goto failed; | 448 | goto failed; |
456 | } | 449 | } |
457 | 450 | ||
458 | strcpy(lp->node.dev_name, dev->name); | ||
459 | |||
460 | printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " | 451 | printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " |
461 | "hw_addr %pM.\n", | 452 | "hw_addr %pM.\n", |
462 | dev->name, cardname, dev->base_addr, dev->irq, | 453 | dev->name, cardname, dev->base_addr, dev->irq, |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 091e0b00043e..5ab589d3b385 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -106,7 +106,6 @@ enum RxFilter { | |||
106 | 106 | ||
107 | struct el3_private { | 107 | struct el3_private { |
108 | struct pcmcia_device *p_dev; | 108 | struct pcmcia_device *p_dev; |
109 | dev_node_t node; | ||
110 | /* For transceiver monitoring */ | 109 | /* For transceiver monitoring */ |
111 | struct timer_list media; | 110 | struct timer_list media; |
112 | u16 media_status; | 111 | u16 media_status; |
@@ -194,8 +193,7 @@ static int tc589_probe(struct pcmcia_device *link) | |||
194 | spin_lock_init(&lp->lock); | 193 | spin_lock_init(&lp->lock); |
195 | link->io.NumPorts1 = 16; | 194 | link->io.NumPorts1 = 16; |
196 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 195 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |
197 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | 196 | |
198 | link->irq.Handler = &el3_interrupt; | ||
199 | link->conf.Attributes = CONF_ENABLE_IRQ; | 197 | link->conf.Attributes = CONF_ENABLE_IRQ; |
200 | link->conf.IntType = INT_MEMORY_AND_IO; | 198 | link->conf.IntType = INT_MEMORY_AND_IO; |
201 | link->conf.ConfigIndex = 1; | 199 | link->conf.ConfigIndex = 1; |
@@ -223,8 +221,7 @@ static void tc589_detach(struct pcmcia_device *link) | |||
223 | 221 | ||
224 | dev_dbg(&link->dev, "3c589_detach\n"); | 222 | dev_dbg(&link->dev, "3c589_detach\n"); |
225 | 223 | ||
226 | if (link->dev_node) | 224 | unregister_netdev(dev); |
227 | unregister_netdev(dev); | ||
228 | 225 | ||
229 | tc589_release(link); | 226 | tc589_release(link); |
230 | 227 | ||
@@ -242,7 +239,6 @@ static void tc589_detach(struct pcmcia_device *link) | |||
242 | static int tc589_config(struct pcmcia_device *link) | 239 | static int tc589_config(struct pcmcia_device *link) |
243 | { | 240 | { |
244 | struct net_device *dev = link->priv; | 241 | struct net_device *dev = link->priv; |
245 | struct el3_private *lp = netdev_priv(dev); | ||
246 | __be16 *phys_addr; | 242 | __be16 *phys_addr; |
247 | int ret, i, j, multi = 0, fifo; | 243 | int ret, i, j, multi = 0, fifo; |
248 | unsigned int ioaddr; | 244 | unsigned int ioaddr; |
@@ -271,7 +267,7 @@ static int tc589_config(struct pcmcia_device *link) | |||
271 | if (i != 0) | 267 | if (i != 0) |
272 | goto failed; | 268 | goto failed; |
273 | 269 | ||
274 | ret = pcmcia_request_irq(link, &link->irq); | 270 | ret = pcmcia_request_irq(link, el3_interrupt); |
275 | if (ret) | 271 | if (ret) |
276 | goto failed; | 272 | goto failed; |
277 | 273 | ||
@@ -279,7 +275,7 @@ static int tc589_config(struct pcmcia_device *link) | |||
279 | if (ret) | 275 | if (ret) |
280 | goto failed; | 276 | goto failed; |
281 | 277 | ||
282 | dev->irq = link->irq.AssignedIRQ; | 278 | dev->irq = link->irq; |
283 | dev->base_addr = link->io.BasePort1; | 279 | dev->base_addr = link->io.BasePort1; |
284 | ioaddr = dev->base_addr; | 280 | ioaddr = dev->base_addr; |
285 | EL3WINDOW(0); | 281 | EL3WINDOW(0); |
@@ -313,17 +309,13 @@ static int tc589_config(struct pcmcia_device *link) | |||
313 | else | 309 | else |
314 | printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); | 310 | printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); |
315 | 311 | ||
316 | link->dev_node = &lp->node; | ||
317 | SET_NETDEV_DEV(dev, &link->dev); | 312 | SET_NETDEV_DEV(dev, &link->dev); |
318 | 313 | ||
319 | if (register_netdev(dev) != 0) { | 314 | if (register_netdev(dev) != 0) { |
320 | printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); | 315 | printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); |
321 | link->dev_node = NULL; | ||
322 | goto failed; | 316 | goto failed; |
323 | } | 317 | } |
324 | 318 | ||
325 | strcpy(lp->node.dev_name, dev->name); | ||
326 | |||
327 | printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, " | 319 | printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, " |
328 | "hw_addr %pM\n", | 320 | "hw_addr %pM\n", |
329 | dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq, | 321 | dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq, |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 9f3d593f14ed..59f6fa3c9ddc 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -113,7 +113,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id); | |||
113 | 113 | ||
114 | typedef struct axnet_dev_t { | 114 | typedef struct axnet_dev_t { |
115 | struct pcmcia_device *p_dev; | 115 | struct pcmcia_device *p_dev; |
116 | dev_node_t node; | ||
117 | caddr_t base; | 116 | caddr_t base; |
118 | struct timer_list watchdog; | 117 | struct timer_list watchdog; |
119 | int stale, fast_poll; | 118 | int stale, fast_poll; |
@@ -168,7 +167,6 @@ static int axnet_probe(struct pcmcia_device *link) | |||
168 | info = PRIV(dev); | 167 | info = PRIV(dev); |
169 | info->p_dev = link; | 168 | info->p_dev = link; |
170 | link->priv = dev; | 169 | link->priv = dev; |
171 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
172 | link->conf.Attributes = CONF_ENABLE_IRQ; | 170 | link->conf.Attributes = CONF_ENABLE_IRQ; |
173 | link->conf.IntType = INT_MEMORY_AND_IO; | 171 | link->conf.IntType = INT_MEMORY_AND_IO; |
174 | 172 | ||
@@ -195,8 +193,7 @@ static void axnet_detach(struct pcmcia_device *link) | |||
195 | 193 | ||
196 | dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); | 194 | dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); |
197 | 195 | ||
198 | if (link->dev_node) | 196 | unregister_netdev(dev); |
199 | unregister_netdev(dev); | ||
200 | 197 | ||
201 | axnet_release(link); | 198 | axnet_release(link); |
202 | 199 | ||
@@ -265,12 +262,9 @@ static int try_io_port(struct pcmcia_device *link) | |||
265 | int j, ret; | 262 | int j, ret; |
266 | if (link->io.NumPorts1 == 32) { | 263 | if (link->io.NumPorts1 == 32) { |
267 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 264 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
268 | if (link->io.NumPorts2 > 0) { | 265 | /* for master/slave multifunction cards */ |
269 | /* for master/slave multifunction cards */ | 266 | if (link->io.NumPorts2 > 0) |
270 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 267 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
271 | link->irq.Attributes = | ||
272 | IRQ_TYPE_DYNAMIC_SHARING; | ||
273 | } | ||
274 | } else { | 268 | } else { |
275 | /* This should be two 16-port windows */ | 269 | /* This should be two 16-port windows */ |
276 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 270 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
@@ -336,8 +330,7 @@ static int axnet_config(struct pcmcia_device *link) | |||
336 | if (ret != 0) | 330 | if (ret != 0) |
337 | goto failed; | 331 | goto failed; |
338 | 332 | ||
339 | ret = pcmcia_request_irq(link, &link->irq); | 333 | if (!link->irq) |
340 | if (ret) | ||
341 | goto failed; | 334 | goto failed; |
342 | 335 | ||
343 | if (link->io.NumPorts2 == 8) { | 336 | if (link->io.NumPorts2 == 8) { |
@@ -349,7 +342,7 @@ static int axnet_config(struct pcmcia_device *link) | |||
349 | if (ret) | 342 | if (ret) |
350 | goto failed; | 343 | goto failed; |
351 | 344 | ||
352 | dev->irq = link->irq.AssignedIRQ; | 345 | dev->irq = link->irq; |
353 | dev->base_addr = link->io.BasePort1; | 346 | dev->base_addr = link->io.BasePort1; |
354 | 347 | ||
355 | if (!get_prom(link)) { | 348 | if (!get_prom(link)) { |
@@ -397,17 +390,13 @@ static int axnet_config(struct pcmcia_device *link) | |||
397 | } | 390 | } |
398 | 391 | ||
399 | info->phy_id = (i < 32) ? i : -1; | 392 | info->phy_id = (i < 32) ? i : -1; |
400 | link->dev_node = &info->node; | ||
401 | SET_NETDEV_DEV(dev, &link->dev); | 393 | SET_NETDEV_DEV(dev, &link->dev); |
402 | 394 | ||
403 | if (register_netdev(dev) != 0) { | 395 | if (register_netdev(dev) != 0) { |
404 | printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); | 396 | printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); |
405 | link->dev_node = NULL; | ||
406 | goto failed; | 397 | goto failed; |
407 | } | 398 | } |
408 | 399 | ||
409 | strcpy(info->node.dev_name, dev->name); | ||
410 | |||
411 | printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " | 400 | printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " |
412 | "hw_addr %pM\n", | 401 | "hw_addr %pM\n", |
413 | dev->name, ((info->flags & IS_AX88790) ? 7 : 1), | 402 | dev->name, ((info->flags & IS_AX88790) ? 7 : 1), |
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 21d9c9d815d1..5643f94541bc 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c | |||
@@ -122,7 +122,6 @@ static void com20020_detach(struct pcmcia_device *p_dev); | |||
122 | 122 | ||
123 | typedef struct com20020_dev_t { | 123 | typedef struct com20020_dev_t { |
124 | struct net_device *dev; | 124 | struct net_device *dev; |
125 | dev_node_t node; | ||
126 | } com20020_dev_t; | 125 | } com20020_dev_t; |
127 | 126 | ||
128 | /*====================================================================== | 127 | /*====================================================================== |
@@ -163,7 +162,6 @@ static int com20020_probe(struct pcmcia_device *p_dev) | |||
163 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 162 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
164 | p_dev->io.NumPorts1 = 16; | 163 | p_dev->io.NumPorts1 = 16; |
165 | p_dev->io.IOAddrLines = 16; | 164 | p_dev->io.IOAddrLines = 16; |
166 | p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
167 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 165 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
168 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 166 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
169 | 167 | ||
@@ -196,18 +194,16 @@ static void com20020_detach(struct pcmcia_device *link) | |||
196 | 194 | ||
197 | dev_dbg(&link->dev, "com20020_detach\n"); | 195 | dev_dbg(&link->dev, "com20020_detach\n"); |
198 | 196 | ||
199 | if (link->dev_node) { | 197 | dev_dbg(&link->dev, "unregister...\n"); |
200 | dev_dbg(&link->dev, "unregister...\n"); | ||
201 | 198 | ||
202 | unregister_netdev(dev); | 199 | unregister_netdev(dev); |
203 | 200 | ||
204 | /* | 201 | /* |
205 | * this is necessary because we register our IRQ separately | 202 | * this is necessary because we register our IRQ separately |
206 | * from card services. | 203 | * from card services. |
207 | */ | 204 | */ |
208 | if (dev->irq) | 205 | if (dev->irq) |
209 | free_irq(dev->irq, dev); | 206 | free_irq(dev->irq, dev); |
210 | } | ||
211 | 207 | ||
212 | com20020_release(link); | 208 | com20020_release(link); |
213 | 209 | ||
@@ -275,15 +271,14 @@ static int com20020_config(struct pcmcia_device *link) | |||
275 | dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); | 271 | dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); |
276 | 272 | ||
277 | dev_dbg(&link->dev, "request IRQ %d\n", | 273 | dev_dbg(&link->dev, "request IRQ %d\n", |
278 | link->irq.AssignedIRQ); | 274 | link->irq); |
279 | i = pcmcia_request_irq(link, &link->irq); | 275 | if (!link->irq) |
280 | if (i != 0) | ||
281 | { | 276 | { |
282 | dev_dbg(&link->dev, "requestIRQ failed totally!\n"); | 277 | dev_dbg(&link->dev, "requestIRQ failed totally!\n"); |
283 | goto failed; | 278 | goto failed; |
284 | } | 279 | } |
285 | 280 | ||
286 | dev->irq = link->irq.AssignedIRQ; | 281 | dev->irq = link->irq; |
287 | 282 | ||
288 | ret = pcmcia_request_configuration(link, &link->conf); | 283 | ret = pcmcia_request_configuration(link, &link->conf); |
289 | if (ret) | 284 | if (ret) |
@@ -299,7 +294,6 @@ static int com20020_config(struct pcmcia_device *link) | |||
299 | lp->card_name = "PCMCIA COM20020"; | 294 | lp->card_name = "PCMCIA COM20020"; |
300 | lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ | 295 | lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ |
301 | 296 | ||
302 | link->dev_node = &info->node; | ||
303 | SET_NETDEV_DEV(dev, &link->dev); | 297 | SET_NETDEV_DEV(dev, &link->dev); |
304 | 298 | ||
305 | i = com20020_found(dev, 0); /* calls register_netdev */ | 299 | i = com20020_found(dev, 0); /* calls register_netdev */ |
@@ -307,12 +301,9 @@ static int com20020_config(struct pcmcia_device *link) | |||
307 | if (i != 0) { | 301 | if (i != 0) { |
308 | dev_printk(KERN_NOTICE, &link->dev, | 302 | dev_printk(KERN_NOTICE, &link->dev, |
309 | "com20020_cs: com20020_found() failed\n"); | 303 | "com20020_cs: com20020_found() failed\n"); |
310 | link->dev_node = NULL; | ||
311 | goto failed; | 304 | goto failed; |
312 | } | 305 | } |
313 | 306 | ||
314 | strcpy(info->node.dev_name, dev->name); | ||
315 | |||
316 | dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", | 307 | dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", |
317 | dev->name, dev->base_addr, dev->irq); | 308 | dev->name, dev->base_addr, dev->irq); |
318 | return 0; | 309 | return 0; |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index b9dc80b9d04a..6580d78397d1 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -110,7 +110,6 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, | |||
110 | */ | 110 | */ |
111 | typedef struct local_info_t { | 111 | typedef struct local_info_t { |
112 | struct pcmcia_device *p_dev; | 112 | struct pcmcia_device *p_dev; |
113 | dev_node_t node; | ||
114 | long open_time; | 113 | long open_time; |
115 | uint tx_started:1; | 114 | uint tx_started:1; |
116 | uint tx_queue; | 115 | uint tx_queue; |
@@ -254,10 +253,6 @@ static int fmvj18x_probe(struct pcmcia_device *link) | |||
254 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 253 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
255 | link->io.IOAddrLines = 5; | 254 | link->io.IOAddrLines = 5; |
256 | 255 | ||
257 | /* Interrupt setup */ | ||
258 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
259 | link->irq.Handler = fjn_interrupt; | ||
260 | |||
261 | /* General socket configuration */ | 256 | /* General socket configuration */ |
262 | link->conf.Attributes = CONF_ENABLE_IRQ; | 257 | link->conf.Attributes = CONF_ENABLE_IRQ; |
263 | link->conf.IntType = INT_MEMORY_AND_IO; | 258 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -278,8 +273,7 @@ static void fmvj18x_detach(struct pcmcia_device *link) | |||
278 | 273 | ||
279 | dev_dbg(&link->dev, "fmvj18x_detach\n"); | 274 | dev_dbg(&link->dev, "fmvj18x_detach\n"); |
280 | 275 | ||
281 | if (link->dev_node) | 276 | unregister_netdev(dev); |
282 | unregister_netdev(dev); | ||
283 | 277 | ||
284 | fmvj18x_release(link); | 278 | fmvj18x_release(link); |
285 | 279 | ||
@@ -425,8 +419,6 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
425 | } | 419 | } |
426 | 420 | ||
427 | if (link->io.NumPorts2 != 0) { | 421 | if (link->io.NumPorts2 != 0) { |
428 | link->irq.Attributes = | ||
429 | IRQ_TYPE_DYNAMIC_SHARING; | ||
430 | ret = mfc_try_io_port(link); | 422 | ret = mfc_try_io_port(link); |
431 | if (ret != 0) goto failed; | 423 | if (ret != 0) goto failed; |
432 | } else if (cardtype == UNGERMANN) { | 424 | } else if (cardtype == UNGERMANN) { |
@@ -437,14 +429,14 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
437 | if (ret) | 429 | if (ret) |
438 | goto failed; | 430 | goto failed; |
439 | } | 431 | } |
440 | ret = pcmcia_request_irq(link, &link->irq); | 432 | ret = pcmcia_request_irq(link, fjn_interrupt); |
441 | if (ret) | 433 | if (ret) |
442 | goto failed; | 434 | goto failed; |
443 | ret = pcmcia_request_configuration(link, &link->conf); | 435 | ret = pcmcia_request_configuration(link, &link->conf); |
444 | if (ret) | 436 | if (ret) |
445 | goto failed; | 437 | goto failed; |
446 | 438 | ||
447 | dev->irq = link->irq.AssignedIRQ; | 439 | dev->irq = link->irq; |
448 | dev->base_addr = link->io.BasePort1; | 440 | dev->base_addr = link->io.BasePort1; |
449 | 441 | ||
450 | if (link->io.BasePort2 != 0) { | 442 | if (link->io.BasePort2 != 0) { |
@@ -529,17 +521,13 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
529 | } | 521 | } |
530 | 522 | ||
531 | lp->cardtype = cardtype; | 523 | lp->cardtype = cardtype; |
532 | link->dev_node = &lp->node; | ||
533 | SET_NETDEV_DEV(dev, &link->dev); | 524 | SET_NETDEV_DEV(dev, &link->dev); |
534 | 525 | ||
535 | if (register_netdev(dev) != 0) { | 526 | if (register_netdev(dev) != 0) { |
536 | printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); | 527 | printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); |
537 | link->dev_node = NULL; | ||
538 | goto failed; | 528 | goto failed; |
539 | } | 529 | } |
540 | 530 | ||
541 | strcpy(lp->node.dev_name, dev->name); | ||
542 | |||
543 | /* print current configuration */ | 531 | /* print current configuration */ |
544 | printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " | 532 | printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " |
545 | "hw_addr %pM\n", | 533 | "hw_addr %pM\n", |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 37f4a6fdc3ef..2e42d80f8cae 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
@@ -104,7 +104,6 @@ static void ibmtr_detach(struct pcmcia_device *p_dev); | |||
104 | typedef struct ibmtr_dev_t { | 104 | typedef struct ibmtr_dev_t { |
105 | struct pcmcia_device *p_dev; | 105 | struct pcmcia_device *p_dev; |
106 | struct net_device *dev; | 106 | struct net_device *dev; |
107 | dev_node_t node; | ||
108 | window_handle_t sram_win_handle; | 107 | window_handle_t sram_win_handle; |
109 | struct tok_info *ti; | 108 | struct tok_info *ti; |
110 | } ibmtr_dev_t; | 109 | } ibmtr_dev_t; |
@@ -156,8 +155,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) | |||
156 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 155 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
157 | link->io.NumPorts1 = 4; | 156 | link->io.NumPorts1 = 4; |
158 | link->io.IOAddrLines = 16; | 157 | link->io.IOAddrLines = 16; |
159 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
160 | link->irq.Handler = ibmtr_interrupt; | ||
161 | link->conf.Attributes = CONF_ENABLE_IRQ; | 158 | link->conf.Attributes = CONF_ENABLE_IRQ; |
162 | link->conf.IntType = INT_MEMORY_AND_IO; | 159 | link->conf.IntType = INT_MEMORY_AND_IO; |
163 | link->conf.Present = PRESENT_OPTION; | 160 | link->conf.Present = PRESENT_OPTION; |
@@ -192,8 +189,7 @@ static void ibmtr_detach(struct pcmcia_device *link) | |||
192 | */ | 189 | */ |
193 | ti->sram_phys |= 1; | 190 | ti->sram_phys |= 1; |
194 | 191 | ||
195 | if (link->dev_node) | 192 | unregister_netdev(dev); |
196 | unregister_netdev(dev); | ||
197 | 193 | ||
198 | del_timer_sync(&(ti->tr_timer)); | 194 | del_timer_sync(&(ti->tr_timer)); |
199 | 195 | ||
@@ -238,11 +234,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) | |||
238 | } | 234 | } |
239 | dev->base_addr = link->io.BasePort1; | 235 | dev->base_addr = link->io.BasePort1; |
240 | 236 | ||
241 | ret = pcmcia_request_irq(link, &link->irq); | 237 | ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); |
242 | if (ret) | 238 | if (ret) |
243 | goto failed; | 239 | goto failed; |
244 | dev->irq = link->irq.AssignedIRQ; | 240 | dev->irq = link->irq; |
245 | ti->irq = link->irq.AssignedIRQ; | 241 | ti->irq = link->irq; |
246 | ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); | 242 | ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); |
247 | 243 | ||
248 | /* Allocate the MMIO memory window */ | 244 | /* Allocate the MMIO memory window */ |
@@ -291,18 +287,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) | |||
291 | Adapters Technical Reference" SC30-3585 for this info. */ | 287 | Adapters Technical Reference" SC30-3585 for this info. */ |
292 | ibmtr_hw_setup(dev, mmiobase); | 288 | ibmtr_hw_setup(dev, mmiobase); |
293 | 289 | ||
294 | link->dev_node = &info->node; | ||
295 | SET_NETDEV_DEV(dev, &link->dev); | 290 | SET_NETDEV_DEV(dev, &link->dev); |
296 | 291 | ||
297 | i = ibmtr_probe_card(dev); | 292 | i = ibmtr_probe_card(dev); |
298 | if (i != 0) { | 293 | if (i != 0) { |
299 | printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); | 294 | printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); |
300 | link->dev_node = NULL; | ||
301 | goto failed; | 295 | goto failed; |
302 | } | 296 | } |
303 | 297 | ||
304 | strcpy(info->node.dev_name, dev->name); | ||
305 | |||
306 | printk(KERN_INFO | 298 | printk(KERN_INFO |
307 | "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", | 299 | "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", |
308 | dev->name, dev->base_addr, dev->irq, | 300 | dev->name, dev->base_addr, dev->irq, |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index c717b143f11a..d8a3b3cf246e 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -363,7 +363,6 @@ typedef struct _mace_statistics { | |||
363 | 363 | ||
364 | typedef struct _mace_private { | 364 | typedef struct _mace_private { |
365 | struct pcmcia_device *p_dev; | 365 | struct pcmcia_device *p_dev; |
366 | dev_node_t node; | ||
367 | struct net_device_stats linux_stats; /* Linux statistics counters */ | 366 | struct net_device_stats linux_stats; /* Linux statistics counters */ |
368 | mace_statistics mace_stats; /* MACE chip statistics counters */ | 367 | mace_statistics mace_stats; /* MACE chip statistics counters */ |
369 | 368 | ||
@@ -463,8 +462,6 @@ static int nmclan_probe(struct pcmcia_device *link) | |||
463 | link->io.NumPorts1 = 32; | 462 | link->io.NumPorts1 = 32; |
464 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 463 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
465 | link->io.IOAddrLines = 5; | 464 | link->io.IOAddrLines = 5; |
466 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
467 | link->irq.Handler = mace_interrupt; | ||
468 | link->conf.Attributes = CONF_ENABLE_IRQ; | 465 | link->conf.Attributes = CONF_ENABLE_IRQ; |
469 | link->conf.IntType = INT_MEMORY_AND_IO; | 466 | link->conf.IntType = INT_MEMORY_AND_IO; |
470 | link->conf.ConfigIndex = 1; | 467 | link->conf.ConfigIndex = 1; |
@@ -493,8 +490,7 @@ static void nmclan_detach(struct pcmcia_device *link) | |||
493 | 490 | ||
494 | dev_dbg(&link->dev, "nmclan_detach\n"); | 491 | dev_dbg(&link->dev, "nmclan_detach\n"); |
495 | 492 | ||
496 | if (link->dev_node) | 493 | unregister_netdev(dev); |
497 | unregister_netdev(dev); | ||
498 | 494 | ||
499 | nmclan_release(link); | 495 | nmclan_release(link); |
500 | 496 | ||
@@ -652,14 +648,14 @@ static int nmclan_config(struct pcmcia_device *link) | |||
652 | ret = pcmcia_request_io(link, &link->io); | 648 | ret = pcmcia_request_io(link, &link->io); |
653 | if (ret) | 649 | if (ret) |
654 | goto failed; | 650 | goto failed; |
655 | ret = pcmcia_request_irq(link, &link->irq); | 651 | ret = pcmcia_request_exclusive_irq(link, mace_interrupt); |
656 | if (ret) | 652 | if (ret) |
657 | goto failed; | 653 | goto failed; |
658 | ret = pcmcia_request_configuration(link, &link->conf); | 654 | ret = pcmcia_request_configuration(link, &link->conf); |
659 | if (ret) | 655 | if (ret) |
660 | goto failed; | 656 | goto failed; |
661 | 657 | ||
662 | dev->irq = link->irq.AssignedIRQ; | 658 | dev->irq = link->irq; |
663 | dev->base_addr = link->io.BasePort1; | 659 | dev->base_addr = link->io.BasePort1; |
664 | 660 | ||
665 | ioaddr = dev->base_addr; | 661 | ioaddr = dev->base_addr; |
@@ -698,18 +694,14 @@ static int nmclan_config(struct pcmcia_device *link) | |||
698 | else | 694 | else |
699 | printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); | 695 | printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); |
700 | 696 | ||
701 | link->dev_node = &lp->node; | ||
702 | SET_NETDEV_DEV(dev, &link->dev); | 697 | SET_NETDEV_DEV(dev, &link->dev); |
703 | 698 | ||
704 | i = register_netdev(dev); | 699 | i = register_netdev(dev); |
705 | if (i != 0) { | 700 | if (i != 0) { |
706 | printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); | 701 | printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); |
707 | link->dev_node = NULL; | ||
708 | goto failed; | 702 | goto failed; |
709 | } | 703 | } |
710 | 704 | ||
711 | strcpy(lp->node.dev_name, dev->name); | ||
712 | |||
713 | printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," | 705 | printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," |
714 | " hw_addr %pM\n", | 706 | " hw_addr %pM\n", |
715 | dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], | 707 | dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 4c0368de1815..6f77a768ba88 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -208,7 +208,6 @@ static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII }; | |||
208 | 208 | ||
209 | typedef struct pcnet_dev_t { | 209 | typedef struct pcnet_dev_t { |
210 | struct pcmcia_device *p_dev; | 210 | struct pcmcia_device *p_dev; |
211 | dev_node_t node; | ||
212 | u_int flags; | 211 | u_int flags; |
213 | void __iomem *base; | 212 | void __iomem *base; |
214 | struct timer_list watchdog; | 213 | struct timer_list watchdog; |
@@ -264,7 +263,6 @@ static int pcnet_probe(struct pcmcia_device *link) | |||
264 | info->p_dev = link; | 263 | info->p_dev = link; |
265 | link->priv = dev; | 264 | link->priv = dev; |
266 | 265 | ||
267 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
268 | link->conf.Attributes = CONF_ENABLE_IRQ; | 266 | link->conf.Attributes = CONF_ENABLE_IRQ; |
269 | link->conf.IntType = INT_MEMORY_AND_IO; | 267 | link->conf.IntType = INT_MEMORY_AND_IO; |
270 | 268 | ||
@@ -288,8 +286,7 @@ static void pcnet_detach(struct pcmcia_device *link) | |||
288 | 286 | ||
289 | dev_dbg(&link->dev, "pcnet_detach\n"); | 287 | dev_dbg(&link->dev, "pcnet_detach\n"); |
290 | 288 | ||
291 | if (link->dev_node) | 289 | unregister_netdev(dev); |
292 | unregister_netdev(dev); | ||
293 | 290 | ||
294 | pcnet_release(link); | 291 | pcnet_release(link); |
295 | 292 | ||
@@ -488,8 +485,6 @@ static int try_io_port(struct pcmcia_device *link) | |||
488 | if (link->io.NumPorts2 > 0) { | 485 | if (link->io.NumPorts2 > 0) { |
489 | /* for master/slave multifunction cards */ | 486 | /* for master/slave multifunction cards */ |
490 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 487 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
491 | link->irq.Attributes = | ||
492 | IRQ_TYPE_DYNAMIC_SHARING; | ||
493 | } | 488 | } |
494 | } else { | 489 | } else { |
495 | /* This should be two 16-port windows */ | 490 | /* This should be two 16-port windows */ |
@@ -559,8 +554,7 @@ static int pcnet_config(struct pcmcia_device *link) | |||
559 | if (ret) | 554 | if (ret) |
560 | goto failed; | 555 | goto failed; |
561 | 556 | ||
562 | ret = pcmcia_request_irq(link, &link->irq); | 557 | if (!link->irq) |
563 | if (ret) | ||
564 | goto failed; | 558 | goto failed; |
565 | 559 | ||
566 | if (link->io.NumPorts2 == 8) { | 560 | if (link->io.NumPorts2 == 8) { |
@@ -574,7 +568,7 @@ static int pcnet_config(struct pcmcia_device *link) | |||
574 | ret = pcmcia_request_configuration(link, &link->conf); | 568 | ret = pcmcia_request_configuration(link, &link->conf); |
575 | if (ret) | 569 | if (ret) |
576 | goto failed; | 570 | goto failed; |
577 | dev->irq = link->irq.AssignedIRQ; | 571 | dev->irq = link->irq; |
578 | dev->base_addr = link->io.BasePort1; | 572 | dev->base_addr = link->io.BasePort1; |
579 | if (info->flags & HAS_MISC_REG) { | 573 | if (info->flags & HAS_MISC_REG) { |
580 | if ((if_port == 1) || (if_port == 2)) | 574 | if ((if_port == 1) || (if_port == 2)) |
@@ -643,17 +637,13 @@ static int pcnet_config(struct pcmcia_device *link) | |||
643 | if (info->flags & (IS_DL10019|IS_DL10022)) | 637 | if (info->flags & (IS_DL10019|IS_DL10022)) |
644 | mii_phy_probe(dev); | 638 | mii_phy_probe(dev); |
645 | 639 | ||
646 | link->dev_node = &info->node; | ||
647 | SET_NETDEV_DEV(dev, &link->dev); | 640 | SET_NETDEV_DEV(dev, &link->dev); |
648 | 641 | ||
649 | if (register_netdev(dev) != 0) { | 642 | if (register_netdev(dev) != 0) { |
650 | printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); | 643 | printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); |
651 | link->dev_node = NULL; | ||
652 | goto failed; | 644 | goto failed; |
653 | } | 645 | } |
654 | 646 | ||
655 | strcpy(info->node.dev_name, dev->name); | ||
656 | |||
657 | if (info->flags & (IS_DL10019|IS_DL10022)) { | 647 | if (info->flags & (IS_DL10019|IS_DL10022)) { |
658 | u_char id = inb(dev->base_addr + 0x1a); | 648 | u_char id = inb(dev->base_addr + 0x1a); |
659 | printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ", | 649 | printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ", |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index ccc553782a0d..59796e7d09c4 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -103,7 +103,6 @@ struct smc_private { | |||
103 | u_short manfid; | 103 | u_short manfid; |
104 | u_short cardid; | 104 | u_short cardid; |
105 | 105 | ||
106 | dev_node_t node; | ||
107 | struct sk_buff *saved_skb; | 106 | struct sk_buff *saved_skb; |
108 | int packets_waiting; | 107 | int packets_waiting; |
109 | void __iomem *base; | 108 | void __iomem *base; |
@@ -323,14 +322,11 @@ static int smc91c92_probe(struct pcmcia_device *link) | |||
323 | return -ENOMEM; | 322 | return -ENOMEM; |
324 | smc = netdev_priv(dev); | 323 | smc = netdev_priv(dev); |
325 | smc->p_dev = link; | 324 | smc->p_dev = link; |
326 | link->priv = dev; | ||
327 | 325 | ||
328 | spin_lock_init(&smc->lock); | 326 | spin_lock_init(&smc->lock); |
329 | link->io.NumPorts1 = 16; | 327 | link->io.NumPorts1 = 16; |
330 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 328 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
331 | link->io.IOAddrLines = 4; | 329 | link->io.IOAddrLines = 4; |
332 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
333 | link->irq.Handler = &smc_interrupt; | ||
334 | link->conf.Attributes = CONF_ENABLE_IRQ; | 330 | link->conf.Attributes = CONF_ENABLE_IRQ; |
335 | link->conf.IntType = INT_MEMORY_AND_IO; | 331 | link->conf.IntType = INT_MEMORY_AND_IO; |
336 | 332 | ||
@@ -363,8 +359,7 @@ static void smc91c92_detach(struct pcmcia_device *link) | |||
363 | 359 | ||
364 | dev_dbg(&link->dev, "smc91c92_detach\n"); | 360 | dev_dbg(&link->dev, "smc91c92_detach\n"); |
365 | 361 | ||
366 | if (link->dev_node) | 362 | unregister_netdev(dev); |
367 | unregister_netdev(dev); | ||
368 | 363 | ||
369 | smc91c92_release(link); | 364 | smc91c92_release(link); |
370 | 365 | ||
@@ -453,7 +448,6 @@ static int mhz_mfc_config(struct pcmcia_device *link) | |||
453 | 448 | ||
454 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 449 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
455 | link->conf.Status = CCSR_AUDIO_ENA; | 450 | link->conf.Status = CCSR_AUDIO_ENA; |
456 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
457 | link->io.IOAddrLines = 16; | 451 | link->io.IOAddrLines = 16; |
458 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 452 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
459 | link->io.NumPorts2 = 8; | 453 | link->io.NumPorts2 = 8; |
@@ -652,7 +646,6 @@ static int osi_config(struct pcmcia_device *link) | |||
652 | 646 | ||
653 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 647 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
654 | link->conf.Status = CCSR_AUDIO_ENA; | 648 | link->conf.Status = CCSR_AUDIO_ENA; |
655 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
656 | link->io.NumPorts1 = 64; | 649 | link->io.NumPorts1 = 64; |
657 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 650 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
658 | link->io.NumPorts2 = 8; | 651 | link->io.NumPorts2 = 8; |
@@ -877,7 +870,7 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
877 | if (i) | 870 | if (i) |
878 | goto config_failed; | 871 | goto config_failed; |
879 | 872 | ||
880 | i = pcmcia_request_irq(link, &link->irq); | 873 | i = pcmcia_request_irq(link, smc_interrupt); |
881 | if (i) | 874 | if (i) |
882 | goto config_failed; | 875 | goto config_failed; |
883 | i = pcmcia_request_configuration(link, &link->conf); | 876 | i = pcmcia_request_configuration(link, &link->conf); |
@@ -887,7 +880,7 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
887 | if (smc->manfid == MANFID_MOTOROLA) | 880 | if (smc->manfid == MANFID_MOTOROLA) |
888 | mot_config(link); | 881 | mot_config(link); |
889 | 882 | ||
890 | dev->irq = link->irq.AssignedIRQ; | 883 | dev->irq = link->irq; |
891 | 884 | ||
892 | if ((if_port >= 0) && (if_port <= 2)) | 885 | if ((if_port >= 0) && (if_port <= 2)) |
893 | dev->if_port = if_port; | 886 | dev->if_port = if_port; |
@@ -960,17 +953,13 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
960 | SMC_SELECT_BANK(0); | 953 | SMC_SELECT_BANK(0); |
961 | } | 954 | } |
962 | 955 | ||
963 | link->dev_node = &smc->node; | ||
964 | SET_NETDEV_DEV(dev, &link->dev); | 956 | SET_NETDEV_DEV(dev, &link->dev); |
965 | 957 | ||
966 | if (register_netdev(dev) != 0) { | 958 | if (register_netdev(dev) != 0) { |
967 | printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); | 959 | printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); |
968 | link->dev_node = NULL; | ||
969 | goto config_undo; | 960 | goto config_undo; |
970 | } | 961 | } |
971 | 962 | ||
972 | strcpy(smc->node.dev_name, dev->name); | ||
973 | |||
974 | printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " | 963 | printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " |
975 | "hw_addr %pM\n", | 964 | "hw_addr %pM\n", |
976 | dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, | 965 | dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, |
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 4d1802e457be..5e6b62ba8887 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -297,31 +297,9 @@ static void xirc2ps_detach(struct pcmcia_device *p_dev); | |||
297 | 297 | ||
298 | static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); | 298 | static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); |
299 | 299 | ||
300 | /**************** | ||
301 | * A linked list of "instances" of the device. Each actual | ||
302 | * PCMCIA card corresponds to one device instance, and is described | ||
303 | * by one struct pcmcia_device structure (defined in ds.h). | ||
304 | * | ||
305 | * You may not want to use a linked list for this -- for example, the | ||
306 | * memory card driver uses an array of struct pcmcia_device pointers, where minor | ||
307 | * device numbers are used to derive the corresponding array index. | ||
308 | */ | ||
309 | |||
310 | /**************** | ||
311 | * A driver needs to provide a dev_node_t structure for each device | ||
312 | * on a card. In some cases, there is only one device per card (for | ||
313 | * example, ethernet cards, modems). In other cases, there may be | ||
314 | * many actual or logical devices (SCSI adapters, memory cards with | ||
315 | * multiple partitions). The dev_node_t structures need to be kept | ||
316 | * in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
317 | * structure. We allocate them in the card's private data structure, | ||
318 | * because they generally can't be allocated dynamically. | ||
319 | */ | ||
320 | |||
321 | typedef struct local_info_t { | 300 | typedef struct local_info_t { |
322 | struct net_device *dev; | 301 | struct net_device *dev; |
323 | struct pcmcia_device *p_dev; | 302 | struct pcmcia_device *p_dev; |
324 | dev_node_t node; | ||
325 | 303 | ||
326 | int card_type; | 304 | int card_type; |
327 | int probe_port; | 305 | int probe_port; |
@@ -555,7 +533,6 @@ xirc2ps_probe(struct pcmcia_device *link) | |||
555 | link->conf.Attributes = CONF_ENABLE_IRQ; | 533 | link->conf.Attributes = CONF_ENABLE_IRQ; |
556 | link->conf.IntType = INT_MEMORY_AND_IO; | 534 | link->conf.IntType = INT_MEMORY_AND_IO; |
557 | link->conf.ConfigIndex = 1; | 535 | link->conf.ConfigIndex = 1; |
558 | link->irq.Handler = xirc2ps_interrupt; | ||
559 | 536 | ||
560 | /* Fill in card specific entries */ | 537 | /* Fill in card specific entries */ |
561 | dev->netdev_ops = &netdev_ops; | 538 | dev->netdev_ops = &netdev_ops; |
@@ -580,8 +557,7 @@ xirc2ps_detach(struct pcmcia_device *link) | |||
580 | 557 | ||
581 | dev_dbg(&link->dev, "detach\n"); | 558 | dev_dbg(&link->dev, "detach\n"); |
582 | 559 | ||
583 | if (link->dev_node) | 560 | unregister_netdev(dev); |
584 | unregister_netdev(dev); | ||
585 | 561 | ||
586 | xirc2ps_release(link); | 562 | xirc2ps_release(link); |
587 | 563 | ||
@@ -841,7 +817,6 @@ xirc2ps_config(struct pcmcia_device * link) | |||
841 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 817 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
842 | link->conf.Status |= CCSR_AUDIO_ENA; | 818 | link->conf.Status |= CCSR_AUDIO_ENA; |
843 | } | 819 | } |
844 | link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING; | ||
845 | link->io.NumPorts2 = 8; | 820 | link->io.NumPorts2 = 8; |
846 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 821 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
847 | if (local->dingo) { | 822 | if (local->dingo) { |
@@ -866,7 +841,6 @@ xirc2ps_config(struct pcmcia_device * link) | |||
866 | } | 841 | } |
867 | printk(KNOT_XIRC "no ports available\n"); | 842 | printk(KNOT_XIRC "no ports available\n"); |
868 | } else { | 843 | } else { |
869 | link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING; | ||
870 | link->io.NumPorts1 = 16; | 844 | link->io.NumPorts1 = 16; |
871 | for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { | 845 | for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { |
872 | link->io.BasePort1 = ioaddr; | 846 | link->io.BasePort1 = ioaddr; |
@@ -885,7 +859,7 @@ xirc2ps_config(struct pcmcia_device * link) | |||
885 | * Now allocate an interrupt line. Note that this does not | 859 | * Now allocate an interrupt line. Note that this does not |
886 | * actually assign a handler to the interrupt. | 860 | * actually assign a handler to the interrupt. |
887 | */ | 861 | */ |
888 | if ((err=pcmcia_request_irq(link, &link->irq))) | 862 | if ((err=pcmcia_request_irq(link, xirc2ps_interrupt))) |
889 | goto config_error; | 863 | goto config_error; |
890 | 864 | ||
891 | /**************** | 865 | /**************** |
@@ -982,23 +956,19 @@ xirc2ps_config(struct pcmcia_device * link) | |||
982 | printk(KNOT_XIRC "invalid if_port requested\n"); | 956 | printk(KNOT_XIRC "invalid if_port requested\n"); |
983 | 957 | ||
984 | /* we can now register the device with the net subsystem */ | 958 | /* we can now register the device with the net subsystem */ |
985 | dev->irq = link->irq.AssignedIRQ; | 959 | dev->irq = link->irq; |
986 | dev->base_addr = link->io.BasePort1; | 960 | dev->base_addr = link->io.BasePort1; |
987 | 961 | ||
988 | if (local->dingo) | 962 | if (local->dingo) |
989 | do_reset(dev, 1); /* a kludge to make the cem56 work */ | 963 | do_reset(dev, 1); /* a kludge to make the cem56 work */ |
990 | 964 | ||
991 | link->dev_node = &local->node; | ||
992 | SET_NETDEV_DEV(dev, &link->dev); | 965 | SET_NETDEV_DEV(dev, &link->dev); |
993 | 966 | ||
994 | if ((err=register_netdev(dev))) { | 967 | if ((err=register_netdev(dev))) { |
995 | printk(KNOT_XIRC "register_netdev() failed\n"); | 968 | printk(KNOT_XIRC "register_netdev() failed\n"); |
996 | link->dev_node = NULL; | ||
997 | goto config_error; | 969 | goto config_error; |
998 | } | 970 | } |
999 | 971 | ||
1000 | strcpy(local->node.dev_name, dev->name); | ||
1001 | |||
1002 | /* give some infos about the hardware */ | 972 | /* give some infos about the hardware */ |
1003 | printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n", | 973 | printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n", |
1004 | dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, | 974 | dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, |
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index f6036fb42319..33bdc6a84e81 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c | |||
@@ -75,42 +75,7 @@ static void airo_release(struct pcmcia_device *link); | |||
75 | 75 | ||
76 | static void airo_detach(struct pcmcia_device *p_dev); | 76 | static void airo_detach(struct pcmcia_device *p_dev); |
77 | 77 | ||
78 | /* | ||
79 | You'll also need to prototype all the functions that will actually | ||
80 | be used to talk to your device. See 'pcmem_cs' for a good example | ||
81 | of a fully self-sufficient driver; the other drivers rely more or | ||
82 | less on other parts of the kernel. | ||
83 | */ | ||
84 | |||
85 | /* | ||
86 | A linked list of "instances" of the aironet device. Each actual | ||
87 | PCMCIA card corresponds to one device instance, and is described | ||
88 | by one struct pcmcia_device structure (defined in ds.h). | ||
89 | |||
90 | You may not want to use a linked list for this -- for example, the | ||
91 | memory card driver uses an array of struct pcmcia_device pointers, | ||
92 | where minor device numbers are used to derive the corresponding | ||
93 | array index. | ||
94 | */ | ||
95 | |||
96 | /* | ||
97 | A driver needs to provide a dev_node_t structure for each device | ||
98 | on a card. In some cases, there is only one device per card (for | ||
99 | example, ethernet cards, modems). In other cases, there may be | ||
100 | many actual or logical devices (SCSI adapters, memory cards with | ||
101 | multiple partitions). The dev_node_t structures need to be kept | ||
102 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
103 | structure. We allocate them in the card's private data structure, | ||
104 | because they generally shouldn't be allocated dynamically. | ||
105 | |||
106 | In this case, we also provide a flag to indicate if a device is | ||
107 | "stopped" due to a power management event, or card ejection. The | ||
108 | device IO routines can use a flag like this to throttle IO to a | ||
109 | card that is not ready to accept it. | ||
110 | */ | ||
111 | |||
112 | typedef struct local_info_t { | 78 | typedef struct local_info_t { |
113 | dev_node_t node; | ||
114 | struct net_device *eth_dev; | 79 | struct net_device *eth_dev; |
115 | } local_info_t; | 80 | } local_info_t; |
116 | 81 | ||
@@ -132,10 +97,6 @@ static int airo_probe(struct pcmcia_device *p_dev) | |||
132 | 97 | ||
133 | dev_dbg(&p_dev->dev, "airo_attach()\n"); | 98 | dev_dbg(&p_dev->dev, "airo_attach()\n"); |
134 | 99 | ||
135 | /* Interrupt setup */ | ||
136 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
137 | p_dev->irq.Handler = NULL; | ||
138 | |||
139 | /* | 100 | /* |
140 | General socket configuration defaults can go here. In this | 101 | General socket configuration defaults can go here. In this |
141 | client, we assume very little, and rely on the CIS for almost | 102 | 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, | |||
212 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | 173 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) |
213 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | 174 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; |
214 | 175 | ||
215 | /* Do we need to allocate an interrupt? */ | 176 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
216 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
217 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
218 | 177 | ||
219 | /* IO window settings */ | 178 | /* IO window settings */ |
220 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 179 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -300,16 +259,8 @@ static int airo_config(struct pcmcia_device *link) | |||
300 | if (ret) | 259 | if (ret) |
301 | goto failed; | 260 | goto failed; |
302 | 261 | ||
303 | /* | 262 | if (!link->irq) |
304 | Allocate an interrupt line. Note that this does not assign a | 263 | goto failed; |
305 | handler to the interrupt, unless the 'Handler' member of the | ||
306 | irq structure is initialized. | ||
307 | */ | ||
308 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
309 | ret = pcmcia_request_irq(link, &link->irq); | ||
310 | if (ret) | ||
311 | goto failed; | ||
312 | } | ||
313 | 264 | ||
314 | /* | 265 | /* |
315 | This actually configures the PCMCIA socket -- setting up | 266 | This actually configures the PCMCIA socket -- setting up |
@@ -320,26 +271,17 @@ static int airo_config(struct pcmcia_device *link) | |||
320 | if (ret) | 271 | if (ret) |
321 | goto failed; | 272 | goto failed; |
322 | ((local_info_t *)link->priv)->eth_dev = | 273 | ((local_info_t *)link->priv)->eth_dev = |
323 | init_airo_card(link->irq.AssignedIRQ, | 274 | init_airo_card(link->irq, |
324 | link->io.BasePort1, 1, &link->dev); | 275 | link->io.BasePort1, 1, &link->dev); |
325 | if (!((local_info_t *)link->priv)->eth_dev) | 276 | if (!((local_info_t *)link->priv)->eth_dev) |
326 | goto failed; | 277 | goto failed; |
327 | 278 | ||
328 | /* | ||
329 | At this point, the dev_node_t structure(s) need to be | ||
330 | initialized and arranged in a linked list at link->dev_node. | ||
331 | */ | ||
332 | strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name); | ||
333 | dev->node.major = dev->node.minor = 0; | ||
334 | link->dev_node = &dev->node; | ||
335 | |||
336 | /* Finally, report what we've done */ | 279 | /* Finally, report what we've done */ |
337 | printk(KERN_INFO "%s: index 0x%02x: ", | 280 | dev_info(&link->dev, "index 0x%02x: ", |
338 | dev->node.dev_name, link->conf.ConfigIndex); | 281 | link->conf.ConfigIndex); |
339 | if (link->conf.Vpp) | 282 | if (link->conf.Vpp) |
340 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); | 283 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); |
341 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 284 | printk(", irq %d", link->irq); |
342 | printk(", irq %d", link->irq.AssignedIRQ); | ||
343 | if (link->io.NumPorts1) | 285 | if (link->io.NumPorts1) |
344 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 286 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
345 | link->io.BasePort1+link->io.NumPorts1-1); | 287 | link->io.BasePort1+link->io.NumPorts1-1); |
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 32407911842f..c2746fc7f2be 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -85,41 +85,7 @@ static void atmel_release(struct pcmcia_device *link); | |||
85 | 85 | ||
86 | static void atmel_detach(struct pcmcia_device *p_dev); | 86 | static void atmel_detach(struct pcmcia_device *p_dev); |
87 | 87 | ||
88 | /* | ||
89 | You'll also need to prototype all the functions that will actually | ||
90 | be used to talk to your device. See 'pcmem_cs' for a good example | ||
91 | of a fully self-sufficient driver; the other drivers rely more or | ||
92 | less on other parts of the kernel. | ||
93 | */ | ||
94 | |||
95 | /* | ||
96 | A linked list of "instances" of the atmelnet device. Each actual | ||
97 | PCMCIA card corresponds to one device instance, and is described | ||
98 | by one struct pcmcia_device structure (defined in ds.h). | ||
99 | |||
100 | You may not want to use a linked list for this -- for example, the | ||
101 | memory card driver uses an array of struct pcmcia_device pointers, where minor | ||
102 | device numbers are used to derive the corresponding array index. | ||
103 | */ | ||
104 | |||
105 | /* | ||
106 | A driver needs to provide a dev_node_t structure for each device | ||
107 | on a card. In some cases, there is only one device per card (for | ||
108 | example, ethernet cards, modems). In other cases, there may be | ||
109 | many actual or logical devices (SCSI adapters, memory cards with | ||
110 | multiple partitions). The dev_node_t structures need to be kept | ||
111 | in a linked list starting at the 'dev' field of a struct pcmcia_device | ||
112 | structure. We allocate them in the card's private data structure, | ||
113 | because they generally shouldn't be allocated dynamically. | ||
114 | |||
115 | In this case, we also provide a flag to indicate if a device is | ||
116 | "stopped" due to a power management event, or card ejection. The | ||
117 | device IO routines can use a flag like this to throttle IO to a | ||
118 | card that is not ready to accept it. | ||
119 | */ | ||
120 | |||
121 | typedef struct local_info_t { | 88 | typedef struct local_info_t { |
122 | dev_node_t node; | ||
123 | struct net_device *eth_dev; | 89 | struct net_device *eth_dev; |
124 | } local_info_t; | 90 | } local_info_t; |
125 | 91 | ||
@@ -141,10 +107,6 @@ static int atmel_probe(struct pcmcia_device *p_dev) | |||
141 | 107 | ||
142 | dev_dbg(&p_dev->dev, "atmel_attach()\n"); | 108 | dev_dbg(&p_dev->dev, "atmel_attach()\n"); |
143 | 109 | ||
144 | /* Interrupt setup */ | ||
145 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
146 | p_dev->irq.Handler = NULL; | ||
147 | |||
148 | /* | 110 | /* |
149 | General socket configuration defaults can go here. In this | 111 | General socket configuration defaults can go here. In this |
150 | client, we assume very little, and rely on the CIS for almost | 112 | 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, | |||
226 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | 188 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) |
227 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | 189 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; |
228 | 190 | ||
229 | /* Do we need to allocate an interrupt? */ | 191 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
230 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
231 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
232 | 192 | ||
233 | /* IO window settings */ | 193 | /* IO window settings */ |
234 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 194 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -278,15 +238,9 @@ static int atmel_config(struct pcmcia_device *link) | |||
278 | if (pcmcia_loop_config(link, atmel_config_check, NULL)) | 238 | if (pcmcia_loop_config(link, atmel_config_check, NULL)) |
279 | goto failed; | 239 | goto failed; |
280 | 240 | ||
281 | /* | 241 | if (!link->irq) { |
282 | Allocate an interrupt line. Note that this does not assign a | 242 | dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); |
283 | handler to the interrupt, unless the 'Handler' member of the | 243 | goto failed; |
284 | irq structure is initialized. | ||
285 | */ | ||
286 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
287 | ret = pcmcia_request_irq(link, &link->irq); | ||
288 | if (ret) | ||
289 | goto failed; | ||
290 | } | 244 | } |
291 | 245 | ||
292 | /* | 246 | /* |
@@ -298,14 +252,8 @@ static int atmel_config(struct pcmcia_device *link) | |||
298 | if (ret) | 252 | if (ret) |
299 | goto failed; | 253 | goto failed; |
300 | 254 | ||
301 | if (link->irq.AssignedIRQ == 0) { | ||
302 | printk(KERN_ALERT | ||
303 | "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); | ||
304 | goto failed; | ||
305 | } | ||
306 | |||
307 | ((local_info_t*)link->priv)->eth_dev = | 255 | ((local_info_t*)link->priv)->eth_dev = |
308 | init_atmel_card(link->irq.AssignedIRQ, | 256 | init_atmel_card(link->irq, |
309 | link->io.BasePort1, | 257 | link->io.BasePort1, |
310 | did ? did->driver_info : ATMEL_FW_TYPE_NONE, | 258 | did ? did->driver_info : ATMEL_FW_TYPE_NONE, |
311 | &link->dev, | 259 | &link->dev, |
@@ -315,14 +263,6 @@ static int atmel_config(struct pcmcia_device *link) | |||
315 | goto failed; | 263 | goto failed; |
316 | 264 | ||
317 | 265 | ||
318 | /* | ||
319 | At this point, the dev_node_t structure(s) need to be | ||
320 | initialized and arranged in a linked list at link->dev_node. | ||
321 | */ | ||
322 | strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); | ||
323 | dev->node.major = dev->node.minor = 0; | ||
324 | link->dev_node = &dev->node; | ||
325 | |||
326 | return 0; | 266 | return 0; |
327 | 267 | ||
328 | failed: | 268 | failed: |
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 609e7051e018..0e99b634267c 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c | |||
@@ -98,10 +98,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) | |||
98 | if (res != 0) | 98 | if (res != 0) |
99 | goto err_disable; | 99 | goto err_disable; |
100 | 100 | ||
101 | dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | 101 | if (!dev->irq) |
102 | dev->irq.Handler = NULL; /* The handler is registered later. */ | ||
103 | res = pcmcia_request_irq(dev, &dev->irq); | ||
104 | if (res != 0) | ||
105 | goto err_disable; | 102 | goto err_disable; |
106 | 103 | ||
107 | res = pcmcia_request_configuration(dev, &dev->conf); | 104 | res = pcmcia_request_configuration(dev, &dev->conf); |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index a36501dbbe02..db72461c486b 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -39,7 +39,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry"); | |||
39 | 39 | ||
40 | /* struct local_info::hw_priv */ | 40 | /* struct local_info::hw_priv */ |
41 | struct hostap_cs_priv { | 41 | struct hostap_cs_priv { |
42 | dev_node_t node; | ||
43 | struct pcmcia_device *link; | 42 | struct pcmcia_device *link; |
44 | int sandisk_connectplus; | 43 | int sandisk_connectplus; |
45 | }; | 44 | }; |
@@ -556,15 +555,7 @@ static int prism2_config_check(struct pcmcia_device *p_dev, | |||
556 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 555 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
557 | 556 | ||
558 | /* Do we need to allocate an interrupt? */ | 557 | /* Do we need to allocate an interrupt? */ |
559 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 558 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
560 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
561 | else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) { | ||
562 | /* At least Compaq WL200 does not have IRQInfo1 set, | ||
563 | * but it does not work without interrupts.. */ | ||
564 | printk(KERN_WARNING "Config has no IRQ info, but trying to " | ||
565 | "enable IRQ anyway..\n"); | ||
566 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
567 | } | ||
568 | 559 | ||
569 | /* IO window settings */ | 560 | /* IO window settings */ |
570 | PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " | 561 | PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " |
@@ -633,21 +624,10 @@ static int prism2_config(struct pcmcia_device *link) | |||
633 | local = iface->local; | 624 | local = iface->local; |
634 | local->hw_priv = hw_priv; | 625 | local->hw_priv = hw_priv; |
635 | hw_priv->link = link; | 626 | hw_priv->link = link; |
636 | strcpy(hw_priv->node.dev_name, dev->name); | ||
637 | link->dev_node = &hw_priv->node; | ||
638 | 627 | ||
639 | /* | 628 | ret = pcmcia_request_irq(link, prism2_interrupt); |
640 | * Allocate an interrupt line. Note that this does not assign a | 629 | if (ret) |
641 | * handler to the interrupt, unless the 'Handler' member of the | 630 | goto failed; |
642 | * irq structure is initialized. | ||
643 | */ | ||
644 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
645 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
646 | link->irq.Handler = prism2_interrupt; | ||
647 | ret = pcmcia_request_irq(link, &link->irq); | ||
648 | if (ret) | ||
649 | goto failed; | ||
650 | } | ||
651 | 631 | ||
652 | /* | 632 | /* |
653 | * This actually configures the PCMCIA socket -- setting up | 633 | * This actually configures the PCMCIA socket -- setting up |
@@ -658,7 +638,7 @@ static int prism2_config(struct pcmcia_device *link) | |||
658 | if (ret) | 638 | if (ret) |
659 | goto failed; | 639 | goto failed; |
660 | 640 | ||
661 | dev->irq = link->irq.AssignedIRQ; | 641 | dev->irq = link->irq; |
662 | dev->base_addr = link->io.BasePort1; | 642 | dev->base_addr = link->io.BasePort1; |
663 | 643 | ||
664 | /* Finally, report what we've done */ | 644 | /* Finally, report what we've done */ |
@@ -668,7 +648,7 @@ static int prism2_config(struct pcmcia_device *link) | |||
668 | printk(", Vpp %d.%d", link->conf.Vpp / 10, | 648 | printk(", Vpp %d.%d", link->conf.Vpp / 10, |
669 | link->conf.Vpp % 10); | 649 | link->conf.Vpp % 10); |
670 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 650 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
671 | printk(", irq %d", link->irq.AssignedIRQ); | 651 | printk(", irq %d", link->irq); |
672 | if (link->io.NumPorts1) | 652 | if (link->io.NumPorts1) |
673 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 653 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
674 | link->io.BasePort1+link->io.NumPorts1-1); | 654 | link->io.BasePort1+link->io.NumPorts1-1); |
@@ -682,11 +662,9 @@ static int prism2_config(struct pcmcia_device *link) | |||
682 | sandisk_enable_wireless(dev); | 662 | sandisk_enable_wireless(dev); |
683 | 663 | ||
684 | ret = prism2_hw_config(dev, 1); | 664 | ret = prism2_hw_config(dev, 1); |
685 | if (!ret) { | 665 | if (!ret) |
686 | ret = hostap_hw_ready(dev); | 666 | ret = hostap_hw_ready(dev); |
687 | if (ret == 0 && local->ddev) | 667 | |
688 | strcpy(hw_priv->node.dev_name, local->ddev->name); | ||
689 | } | ||
690 | return ret; | 668 | return ret; |
691 | 669 | ||
692 | failed: | 670 | failed: |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 6d55439a7b97..08e4e3908003 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -777,7 +777,7 @@ static void if_cs_release(struct pcmcia_device *p_dev) | |||
777 | 777 | ||
778 | lbs_deb_enter(LBS_DEB_CS); | 778 | lbs_deb_enter(LBS_DEB_CS); |
779 | 779 | ||
780 | free_irq(p_dev->irq.AssignedIRQ, card); | 780 | free_irq(p_dev->irq, card); |
781 | pcmcia_disable_device(p_dev); | 781 | pcmcia_disable_device(p_dev); |
782 | if (card->iobase) | 782 | if (card->iobase) |
783 | ioport_unmap(card->iobase); | 783 | ioport_unmap(card->iobase); |
@@ -807,8 +807,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, | |||
807 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | 807 | p_dev->io.NumPorts1 = cfg->io.win[0].len; |
808 | 808 | ||
809 | /* Do we need to allocate an interrupt? */ | 809 | /* Do we need to allocate an interrupt? */ |
810 | if (cfg->irq.IRQInfo1) | 810 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
811 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
812 | 811 | ||
813 | /* IO window settings */ | 812 | /* IO window settings */ |
814 | if (cfg->io.nwin != 1) { | 813 | if (cfg->io.nwin != 1) { |
@@ -837,9 +836,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
837 | card->p_dev = p_dev; | 836 | card->p_dev = p_dev; |
838 | p_dev->priv = card; | 837 | p_dev->priv = card; |
839 | 838 | ||
840 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
841 | p_dev->irq.Handler = NULL; | ||
842 | |||
843 | p_dev->conf.Attributes = 0; | 839 | p_dev->conf.Attributes = 0; |
844 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 840 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
845 | 841 | ||
@@ -854,13 +850,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
854 | * a handler to the interrupt, unless the 'Handler' member of | 850 | * a handler to the interrupt, unless the 'Handler' member of |
855 | * the irq structure is initialized. | 851 | * the irq structure is initialized. |
856 | */ | 852 | */ |
857 | if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) { | 853 | if (!p_dev->irq) |
858 | ret = pcmcia_request_irq(p_dev, &p_dev->irq); | 854 | goto out1; |
859 | if (ret) { | ||
860 | lbs_pr_err("error in pcmcia_request_irq\n"); | ||
861 | goto out1; | ||
862 | } | ||
863 | } | ||
864 | 855 | ||
865 | /* Initialize io access */ | 856 | /* Initialize io access */ |
866 | card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1); | 857 | 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) | |||
883 | 874 | ||
884 | /* Finally, report what we've done */ | 875 | /* Finally, report what we've done */ |
885 | lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", | 876 | lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", |
886 | p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, | 877 | p_dev->irq, p_dev->io.BasePort1, |
887 | p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); | 878 | p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); |
888 | 879 | ||
889 | /* | 880 | /* |
@@ -940,7 +931,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
940 | priv->fw_ready = 1; | 931 | priv->fw_ready = 1; |
941 | 932 | ||
942 | /* Now actually get the IRQ */ | 933 | /* Now actually get the IRQ */ |
943 | ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt, | 934 | ret = request_irq(p_dev->irq, if_cs_interrupt, |
944 | IRQF_SHARED, DRV_NAME, card); | 935 | IRQF_SHARED, DRV_NAME, card); |
945 | if (ret) { | 936 | if (ret) { |
946 | lbs_pr_err("error in request_irq\n"); | 937 | lbs_pr_err("error in request_irq\n"); |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 1d4ada188eda..03056ab73032 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -50,7 +50,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket | |||
50 | * struct orinoco_private */ | 50 | * struct orinoco_private */ |
51 | struct orinoco_pccard { | 51 | struct orinoco_pccard { |
52 | struct pcmcia_device *p_dev; | 52 | struct pcmcia_device *p_dev; |
53 | dev_node_t node; | ||
54 | 53 | ||
55 | /* Used to handle hard reset */ | 54 | /* Used to handle hard reset */ |
56 | /* yuck, we need this hack to work around the insanity of the | 55 | /* yuck, we need this hack to work around the insanity of the |
@@ -119,10 +118,6 @@ orinoco_cs_probe(struct pcmcia_device *link) | |||
119 | card->p_dev = link; | 118 | card->p_dev = link; |
120 | link->priv = priv; | 119 | link->priv = priv; |
121 | 120 | ||
122 | /* Interrupt setup */ | ||
123 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
124 | link->irq.Handler = orinoco_interrupt; | ||
125 | |||
126 | /* General socket configuration defaults can go here. In this | 121 | /* General socket configuration defaults can go here. In this |
127 | * client, we assume very little, and rely on the CIS for | 122 | * client, we assume very little, and rely on the CIS for |
128 | * almost everything. In most clients, many details (i.e., | 123 | * almost everything. In most clients, many details (i.e., |
@@ -144,8 +139,7 @@ static void orinoco_cs_detach(struct pcmcia_device *link) | |||
144 | { | 139 | { |
145 | struct orinoco_private *priv = link->priv; | 140 | struct orinoco_private *priv = link->priv; |
146 | 141 | ||
147 | if (link->dev_node) | 142 | orinoco_if_del(priv); |
148 | orinoco_if_del(priv); | ||
149 | 143 | ||
150 | orinoco_cs_release(link); | 144 | orinoco_cs_release(link); |
151 | 145 | ||
@@ -230,7 +224,6 @@ static int | |||
230 | orinoco_cs_config(struct pcmcia_device *link) | 224 | orinoco_cs_config(struct pcmcia_device *link) |
231 | { | 225 | { |
232 | struct orinoco_private *priv = link->priv; | 226 | struct orinoco_private *priv = link->priv; |
233 | struct orinoco_pccard *card = priv->card; | ||
234 | hermes_t *hw = &priv->hw; | 227 | hermes_t *hw = &priv->hw; |
235 | int ret; | 228 | int ret; |
236 | void __iomem *mem; | 229 | void __iomem *mem; |
@@ -258,12 +251,7 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
258 | goto failed; | 251 | goto failed; |
259 | } | 252 | } |
260 | 253 | ||
261 | /* | 254 | ret = pcmcia_request_irq(link, orinoco_interrupt); |
262 | * Allocate an interrupt line. Note that this does not assign | ||
263 | * a handler to the interrupt, unless the 'Handler' member of | ||
264 | * the irq structure is initialized. | ||
265 | */ | ||
266 | ret = pcmcia_request_irq(link, &link->irq); | ||
267 | if (ret) | 255 | if (ret) |
268 | goto failed; | 256 | goto failed; |
269 | 257 | ||
@@ -285,9 +273,6 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
285 | if (ret) | 273 | if (ret) |
286 | goto failed; | 274 | goto failed; |
287 | 275 | ||
288 | /* Ok, we have the configuration, prepare to register the netdev */ | ||
289 | card->node.major = card->node.minor = 0; | ||
290 | |||
291 | /* Initialise the main driver */ | 276 | /* Initialise the main driver */ |
292 | if (orinoco_init(priv) != 0) { | 277 | if (orinoco_init(priv) != 0) { |
293 | printk(KERN_ERR PFX "orinoco_init() failed\n"); | 278 | printk(KERN_ERR PFX "orinoco_init() failed\n"); |
@@ -296,17 +281,11 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
296 | 281 | ||
297 | /* Register an interface with the stack */ | 282 | /* Register an interface with the stack */ |
298 | if (orinoco_if_add(priv, link->io.BasePort1, | 283 | if (orinoco_if_add(priv, link->io.BasePort1, |
299 | link->irq.AssignedIRQ) != 0) { | 284 | link->irq) != 0) { |
300 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 285 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
301 | goto failed; | 286 | goto failed; |
302 | } | 287 | } |
303 | 288 | ||
304 | /* At this point, the dev_node_t structure(s) needs to be | ||
305 | * initialized and arranged in a linked list at link->dev_node. */ | ||
306 | strcpy(card->node.dev_name, priv->ndev->name); | ||
307 | link->dev_node = &card->node; /* link->dev_node being non-NULL is also | ||
308 | * used to indicate that the | ||
309 | * net_device has been registered */ | ||
310 | return 0; | 289 | return 0; |
311 | 290 | ||
312 | failed: | 291 | failed: |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 59bda240fdc2..41b9ce425855 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -57,7 +57,6 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket | |||
57 | * struct orinoco_private */ | 57 | * struct orinoco_private */ |
58 | struct orinoco_pccard { | 58 | struct orinoco_pccard { |
59 | struct pcmcia_device *p_dev; | 59 | struct pcmcia_device *p_dev; |
60 | dev_node_t node; | ||
61 | }; | 60 | }; |
62 | 61 | ||
63 | /********************************************************************/ | 62 | /********************************************************************/ |
@@ -193,10 +192,6 @@ spectrum_cs_probe(struct pcmcia_device *link) | |||
193 | card->p_dev = link; | 192 | card->p_dev = link; |
194 | link->priv = priv; | 193 | link->priv = priv; |
195 | 194 | ||
196 | /* Interrupt setup */ | ||
197 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
198 | link->irq.Handler = orinoco_interrupt; | ||
199 | |||
200 | /* General socket configuration defaults can go here. In this | 195 | /* General socket configuration defaults can go here. In this |
201 | * client, we assume very little, and rely on the CIS for | 196 | * client, we assume very little, and rely on the CIS for |
202 | * almost everything. In most clients, many details (i.e., | 197 | * almost everything. In most clients, many details (i.e., |
@@ -218,8 +213,7 @@ static void spectrum_cs_detach(struct pcmcia_device *link) | |||
218 | { | 213 | { |
219 | struct orinoco_private *priv = link->priv; | 214 | struct orinoco_private *priv = link->priv; |
220 | 215 | ||
221 | if (link->dev_node) | 216 | orinoco_if_del(priv); |
222 | orinoco_if_del(priv); | ||
223 | 217 | ||
224 | spectrum_cs_release(link); | 218 | spectrum_cs_release(link); |
225 | 219 | ||
@@ -304,7 +298,6 @@ static int | |||
304 | spectrum_cs_config(struct pcmcia_device *link) | 298 | spectrum_cs_config(struct pcmcia_device *link) |
305 | { | 299 | { |
306 | struct orinoco_private *priv = link->priv; | 300 | struct orinoco_private *priv = link->priv; |
307 | struct orinoco_pccard *card = priv->card; | ||
308 | hermes_t *hw = &priv->hw; | 301 | hermes_t *hw = &priv->hw; |
309 | int ret; | 302 | int ret; |
310 | void __iomem *mem; | 303 | void __iomem *mem; |
@@ -332,12 +325,7 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
332 | goto failed; | 325 | goto failed; |
333 | } | 326 | } |
334 | 327 | ||
335 | /* | 328 | ret = pcmcia_request_irq(link, orinoco_interrupt); |
336 | * Allocate an interrupt line. Note that this does not assign | ||
337 | * a handler to the interrupt, unless the 'Handler' member of | ||
338 | * the irq structure is initialized. | ||
339 | */ | ||
340 | ret = pcmcia_request_irq(link, &link->irq); | ||
341 | if (ret) | 329 | if (ret) |
342 | goto failed; | 330 | goto failed; |
343 | 331 | ||
@@ -359,9 +347,6 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
359 | if (ret) | 347 | if (ret) |
360 | goto failed; | 348 | goto failed; |
361 | 349 | ||
362 | /* Ok, we have the configuration, prepare to register the netdev */ | ||
363 | card->node.major = card->node.minor = 0; | ||
364 | |||
365 | /* Reset card */ | 350 | /* Reset card */ |
366 | if (spectrum_cs_hard_reset(priv) != 0) | 351 | if (spectrum_cs_hard_reset(priv) != 0) |
367 | goto failed; | 352 | goto failed; |
@@ -374,17 +359,11 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
374 | 359 | ||
375 | /* Register an interface with the stack */ | 360 | /* Register an interface with the stack */ |
376 | if (orinoco_if_add(priv, link->io.BasePort1, | 361 | if (orinoco_if_add(priv, link->io.BasePort1, |
377 | link->irq.AssignedIRQ) != 0) { | 362 | link->irq) != 0) { |
378 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 363 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
379 | goto failed; | 364 | goto failed; |
380 | } | 365 | } |
381 | 366 | ||
382 | /* At this point, the dev_node_t structure(s) needs to be | ||
383 | * initialized and arranged in a linked list at link->dev_node. */ | ||
384 | strcpy(card->node.dev_name, priv->ndev->name); | ||
385 | link->dev_node = &card->node; /* link->dev_node being non-NULL is also | ||
386 | * used to indicate that the | ||
387 | * net_device has been registered */ | ||
388 | return 0; | 367 | return 0; |
389 | 368 | ||
390 | failed: | 369 | failed: |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 11865ea21875..f7d2a34ca531 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <pcmcia/cistpl.h> | 51 | #include <pcmcia/cistpl.h> |
52 | #include <pcmcia/cisreg.h> | 52 | #include <pcmcia/cisreg.h> |
53 | #include <pcmcia/ds.h> | 53 | #include <pcmcia/ds.h> |
54 | #include <pcmcia/mem_op.h> | ||
55 | 54 | ||
56 | #include <linux/wireless.h> | 55 | #include <linux/wireless.h> |
57 | #include <net/iw_handler.h> | 56 | #include <net/iw_handler.h> |
@@ -321,10 +320,6 @@ static int ray_probe(struct pcmcia_device *p_dev) | |||
321 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 320 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
322 | p_dev->io.IOAddrLines = 5; | 321 | p_dev->io.IOAddrLines = 5; |
323 | 322 | ||
324 | /* Interrupt setup. For PCMCIA, driver takes what's given */ | ||
325 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
326 | p_dev->irq.Handler = &ray_interrupt; | ||
327 | |||
328 | /* General socket configuration */ | 323 | /* General socket configuration */ |
329 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 324 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
330 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 325 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
@@ -383,8 +378,7 @@ static void ray_detach(struct pcmcia_device *link) | |||
383 | del_timer(&local->timer); | 378 | del_timer(&local->timer); |
384 | 379 | ||
385 | if (link->priv) { | 380 | if (link->priv) { |
386 | if (link->dev_node) | 381 | unregister_netdev(dev); |
387 | unregister_netdev(dev); | ||
388 | free_netdev(dev); | 382 | free_netdev(dev); |
389 | } | 383 | } |
390 | dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); | 384 | dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); |
@@ -417,10 +411,10 @@ static int ray_config(struct pcmcia_device *link) | |||
417 | /* Now allocate an interrupt line. Note that this does not | 411 | /* Now allocate an interrupt line. Note that this does not |
418 | actually assign a handler to the interrupt. | 412 | actually assign a handler to the interrupt. |
419 | */ | 413 | */ |
420 | ret = pcmcia_request_irq(link, &link->irq); | 414 | ret = pcmcia_request_irq(link, ray_interrupt); |
421 | if (ret) | 415 | if (ret) |
422 | goto failed; | 416 | goto failed; |
423 | dev->irq = link->irq.AssignedIRQ; | 417 | dev->irq = link->irq; |
424 | 418 | ||
425 | /* This actually configures the PCMCIA socket -- setting up | 419 | /* This actually configures the PCMCIA socket -- setting up |
426 | the I/O windows and the interrupt mapping. | 420 | the I/O windows and the interrupt mapping. |
@@ -493,9 +487,6 @@ static int ray_config(struct pcmcia_device *link) | |||
493 | return i; | 487 | return i; |
494 | } | 488 | } |
495 | 489 | ||
496 | strcpy(local->node.dev_name, dev->name); | ||
497 | link->dev_node = &local->node; | ||
498 | |||
499 | printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n", | 490 | printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n", |
500 | dev->name, dev->irq, dev->dev_addr); | 491 | dev->name, dev->irq, dev->dev_addr); |
501 | 492 | ||
diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index 1e23b7f4cca7..9f01ddb19748 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h | |||
@@ -25,7 +25,6 @@ struct beacon_rx { | |||
25 | typedef struct ray_dev_t { | 25 | typedef struct ray_dev_t { |
26 | int card_status; | 26 | int card_status; |
27 | int authentication_state; | 27 | int authentication_state; |
28 | dev_node_t node; | ||
29 | window_handle_t amem_handle; /* handle to window for attribute memory */ | 28 | window_handle_t amem_handle; /* handle to window for attribute memory */ |
30 | window_handle_t rmem_handle; /* handle to window for rx buffer on card */ | 29 | window_handle_t rmem_handle; /* handle to window for rx buffer on card */ |
31 | void __iomem *sram; /* pointer to beginning of shared RAM */ | 30 | void __iomem *sram; /* pointer to beginning of shared RAM */ |
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index 8bce1a550a22..8816e371fd0e 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h | |||
@@ -610,7 +610,6 @@ struct wl3501_card { | |||
610 | struct iw_statistics wstats; | 610 | struct iw_statistics wstats; |
611 | struct iw_spy_data spy_data; | 611 | struct iw_spy_data spy_data; |
612 | struct iw_public_data wireless_data; | 612 | struct iw_public_data wireless_data; |
613 | struct dev_node_t node; | ||
614 | struct pcmcia_device *p_dev; | 613 | struct pcmcia_device *p_dev; |
615 | }; | 614 | }; |
616 | #endif | 615 | #endif |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 7b9621de239f..5e5d24c1ce2b 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -1451,6 +1451,8 @@ static void wl3501_detach(struct pcmcia_device *link) | |||
1451 | netif_device_detach(dev); | 1451 | netif_device_detach(dev); |
1452 | wl3501_release(link); | 1452 | wl3501_release(link); |
1453 | 1453 | ||
1454 | unregister_netdev(dev); | ||
1455 | |||
1454 | if (link->priv) | 1456 | if (link->priv) |
1455 | free_netdev(link->priv); | 1457 | free_netdev(link->priv); |
1456 | 1458 | ||
@@ -1897,10 +1899,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev) | |||
1897 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 1899 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
1898 | p_dev->io.IOAddrLines = 5; | 1900 | p_dev->io.IOAddrLines = 5; |
1899 | 1901 | ||
1900 | /* Interrupt setup */ | ||
1901 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
1902 | p_dev->irq.Handler = wl3501_interrupt; | ||
1903 | |||
1904 | /* General socket configuration */ | 1902 | /* General socket configuration */ |
1905 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 1903 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
1906 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 1904 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
@@ -1961,7 +1959,7 @@ static int wl3501_config(struct pcmcia_device *link) | |||
1961 | /* Now allocate an interrupt line. Note that this does not actually | 1959 | /* Now allocate an interrupt line. Note that this does not actually |
1962 | * assign a handler to the interrupt. */ | 1960 | * assign a handler to the interrupt. */ |
1963 | 1961 | ||
1964 | ret = pcmcia_request_irq(link, &link->irq); | 1962 | ret = pcmcia_request_irq(link, wl3501_interrupt); |
1965 | if (ret) | 1963 | if (ret) |
1966 | goto failed; | 1964 | goto failed; |
1967 | 1965 | ||
@@ -1972,7 +1970,7 @@ static int wl3501_config(struct pcmcia_device *link) | |||
1972 | if (ret) | 1970 | if (ret) |
1973 | goto failed; | 1971 | goto failed; |
1974 | 1972 | ||
1975 | dev->irq = link->irq.AssignedIRQ; | 1973 | dev->irq = link->irq; |
1976 | dev->base_addr = link->io.BasePort1; | 1974 | dev->base_addr = link->io.BasePort1; |
1977 | SET_NETDEV_DEV(dev, &link->dev); | 1975 | SET_NETDEV_DEV(dev, &link->dev); |
1978 | if (register_netdev(dev)) { | 1976 | if (register_netdev(dev)) { |
@@ -1981,20 +1979,15 @@ static int wl3501_config(struct pcmcia_device *link) | |||
1981 | } | 1979 | } |
1982 | 1980 | ||
1983 | this = netdev_priv(dev); | 1981 | this = netdev_priv(dev); |
1984 | /* | ||
1985 | * At this point, the dev_node_t structure(s) should be initialized and | ||
1986 | * arranged in a linked list at link->dev_node. | ||
1987 | */ | ||
1988 | link->dev_node = &this->node; | ||
1989 | 1982 | ||
1990 | this->base_addr = dev->base_addr; | 1983 | this->base_addr = dev->base_addr; |
1991 | 1984 | ||
1992 | if (!wl3501_get_flash_mac_addr(this)) { | 1985 | if (!wl3501_get_flash_mac_addr(this)) { |
1993 | printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n", | 1986 | printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n", |
1994 | dev->name); | 1987 | dev->name); |
1988 | unregister_netdev(dev); | ||
1995 | goto failed; | 1989 | goto failed; |
1996 | } | 1990 | } |
1997 | strcpy(this->node.dev_name, dev->name); | ||
1998 | 1991 | ||
1999 | for (i = 0; i < 6; i++) | 1992 | for (i = 0; i < 6; i++) |
2000 | dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; | 1993 | dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; |
@@ -2038,12 +2031,6 @@ failed: | |||
2038 | */ | 2031 | */ |
2039 | static void wl3501_release(struct pcmcia_device *link) | 2032 | static void wl3501_release(struct pcmcia_device *link) |
2040 | { | 2033 | { |
2041 | struct net_device *dev = link->priv; | ||
2042 | |||
2043 | /* Unlink the device chain */ | ||
2044 | if (link->dev_node) | ||
2045 | unregister_netdev(dev); | ||
2046 | |||
2047 | pcmcia_disable_device(link); | 2034 | pcmcia_disable_device(link); |
2048 | } | 2035 | } |
2049 | 2036 | ||
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 7dd370fa3439..fd8cfe95f0a3 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c | |||
@@ -75,7 +75,6 @@ INT_MODULE_PARM(epp_mode, 1); | |||
75 | typedef struct parport_info_t { | 75 | typedef struct parport_info_t { |
76 | struct pcmcia_device *p_dev; | 76 | struct pcmcia_device *p_dev; |
77 | int ndev; | 77 | int ndev; |
78 | dev_node_t node; | ||
79 | struct parport *port; | 78 | struct parport *port; |
80 | } parport_info_t; | 79 | } parport_info_t; |
81 | 80 | ||
@@ -105,7 +104,6 @@ static int parport_probe(struct pcmcia_device *link) | |||
105 | 104 | ||
106 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 105 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
107 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 106 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
108 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
109 | link->conf.Attributes = CONF_ENABLE_IRQ; | 107 | link->conf.Attributes = CONF_ENABLE_IRQ; |
110 | link->conf.IntType = INT_MEMORY_AND_IO; | 108 | link->conf.IntType = INT_MEMORY_AND_IO; |
111 | 109 | ||
@@ -174,20 +172,19 @@ static int parport_config(struct pcmcia_device *link) | |||
174 | if (ret) | 172 | if (ret) |
175 | goto failed; | 173 | goto failed; |
176 | 174 | ||
177 | ret = pcmcia_request_irq(link, &link->irq); | 175 | if (!link->irq) |
178 | if (ret) | ||
179 | goto failed; | 176 | goto failed; |
180 | ret = pcmcia_request_configuration(link, &link->conf); | 177 | ret = pcmcia_request_configuration(link, &link->conf); |
181 | if (ret) | 178 | if (ret) |
182 | goto failed; | 179 | goto failed; |
183 | 180 | ||
184 | p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, | 181 | p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, |
185 | link->irq.AssignedIRQ, PARPORT_DMA_NONE, | 182 | link->irq, PARPORT_DMA_NONE, |
186 | &link->dev, IRQF_SHARED); | 183 | &link->dev, IRQF_SHARED); |
187 | if (p == NULL) { | 184 | if (p == NULL) { |
188 | printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " | 185 | printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " |
189 | "0x%3x, irq %u failed\n", link->io.BasePort1, | 186 | "0x%3x, irq %u failed\n", link->io.BasePort1, |
190 | link->irq.AssignedIRQ); | 187 | link->irq); |
191 | goto failed; | 188 | goto failed; |
192 | } | 189 | } |
193 | 190 | ||
@@ -195,11 +192,7 @@ static int parport_config(struct pcmcia_device *link) | |||
195 | if (epp_mode) | 192 | if (epp_mode) |
196 | p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP; | 193 | p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP; |
197 | info->ndev = 1; | 194 | info->ndev = 1; |
198 | info->node.major = LP_MAJOR; | ||
199 | info->node.minor = p->number; | ||
200 | info->port = p; | 195 | info->port = p; |
201 | strcpy(info->node.dev_name, p->name); | ||
202 | link->dev_node = &info->node; | ||
203 | 196 | ||
204 | return 0; | 197 | return 0; |
205 | 198 | ||
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index a44733d44ca1..d0f5ad306078 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -49,26 +49,6 @@ config PCMCIA_LOAD_CIS | |||
49 | 49 | ||
50 | If unsure, say Y. | 50 | If unsure, say Y. |
51 | 51 | ||
52 | config PCMCIA_IOCTL | ||
53 | bool "PCMCIA control ioctl (obsolete)" | ||
54 | depends on PCMCIA && ARM && !SMP && !PREEMPT | ||
55 | default y | ||
56 | help | ||
57 | If you say Y here, the deprecated ioctl interface to the PCMCIA | ||
58 | subsystem will be built. It is needed by the deprecated pcmcia-cs | ||
59 | tools (cardmgr, cardctl) to function properly. | ||
60 | |||
61 | You should use the new pcmciautils package instead (see | ||
62 | <file:Documentation/Changes> for location and details). | ||
63 | |||
64 | This config option will most likely be removed from kernel 2.6.35, | ||
65 | the associated code from kernel 2.6.36. | ||
66 | |||
67 | As the PCMCIA ioctl is not locking safe, it depends on !SMP and | ||
68 | !PREEMPT. | ||
69 | |||
70 | If unsure, say N. | ||
71 | |||
72 | config CARDBUS | 52 | config CARDBUS |
73 | bool "32-bit CardBus support" | 53 | bool "32-bit CardBus support" |
74 | depends on PCI | 54 | depends on PCI |
@@ -318,7 +298,7 @@ config ELECTRA_CF | |||
318 | PA Semi Electra eval board. | 298 | PA Semi Electra eval board. |
319 | 299 | ||
320 | config PCCARD_NONSTATIC | 300 | config PCCARD_NONSTATIC |
321 | tristate | 301 | bool |
322 | 302 | ||
323 | config PCCARD_IODYN | 303 | config PCCARD_IODYN |
324 | bool | 304 | bool |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 4dae3613c458..d006e8beab9c 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -2,15 +2,18 @@ | |||
2 | # Makefile for the kernel pcmcia subsystem (c/o David Hinds) | 2 | # Makefile for the kernel pcmcia subsystem (c/o David Hinds) |
3 | # | 3 | # |
4 | 4 | ||
5 | pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o | 5 | pcmcia_core-y += cs.o socket_sysfs.o |
6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o | 6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o |
7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o | 7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o |
8 | 8 | ||
9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o | 9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o |
10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o | 10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o |
11 | obj-$(CONFIG_PCMCIA) += pcmcia.o | 11 | obj-$(CONFIG_PCMCIA) += pcmcia.o |
12 | 12 | ||
13 | obj-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o | 13 | pcmcia_rsrc-y += rsrc_mgr.o |
14 | pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o | ||
15 | pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o | ||
16 | obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o | ||
14 | 17 | ||
15 | 18 | ||
16 | # socket drivers | 19 | # socket drivers |
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 9e84d039de41..eae9cbe37a3e 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c | |||
@@ -113,7 +113,7 @@ static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
113 | 113 | ||
114 | if (bfin_cf_present(cf->cd_pfx)) { | 114 | if (bfin_cf_present(cf->cd_pfx)) { |
115 | *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; | 115 | *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; |
116 | s->irq.AssignedIRQ = 0; | 116 | s->pcmcia_irq = 0; |
117 | s->pci_irq = cf->irq; | 117 | s->pci_irq = cf->irq; |
118 | 118 | ||
119 | } else | 119 | } else |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index e6ab2a47d8cb..9a58862f1401 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -94,7 +94,6 @@ int __ref cb_alloc(struct pcmcia_socket *s) | |||
94 | pci_enable_bridges(bus); | 94 | pci_enable_bridges(bus); |
95 | pci_bus_add_devices(bus); | 95 | pci_bus_add_devices(bus); |
96 | 96 | ||
97 | s->irq.AssignedIRQ = s->pci_irq; | ||
98 | return 0; | 97 | return 0; |
99 | } | 98 | } |
100 | 99 | ||
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 854959cada3a..60d428be0b07 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s, | |||
129 | 129 | ||
130 | /** | 130 | /** |
131 | * pcmcia_read_cis_mem() - low-level function to read CIS memory | 131 | * pcmcia_read_cis_mem() - low-level function to read CIS memory |
132 | * | ||
133 | * must be called with ops_mutex held | ||
132 | */ | 134 | */ |
133 | int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | 135 | int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, |
134 | u_int len, void *ptr) | 136 | u_int len, void *ptr) |
@@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
138 | 140 | ||
139 | dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); | 141 | dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); |
140 | 142 | ||
141 | mutex_lock(&s->ops_mutex); | ||
142 | if (attr & IS_INDIRECT) { | 143 | if (attr & IS_INDIRECT) { |
143 | /* Indirect accesses use a bunch of special registers at fixed | 144 | /* Indirect accesses use a bunch of special registers at fixed |
144 | locations in common memory */ | 145 | locations in common memory */ |
@@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
153 | if (!sys) { | 154 | if (!sys) { |
154 | dev_dbg(&s->dev, "could not map memory\n"); | 155 | dev_dbg(&s->dev, "could not map memory\n"); |
155 | memset(ptr, 0xff, len); | 156 | memset(ptr, 0xff, len); |
156 | mutex_unlock(&s->ops_mutex); | ||
157 | return -1; | 157 | return -1; |
158 | } | 158 | } |
159 | 159 | ||
@@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
184 | if (!sys) { | 184 | if (!sys) { |
185 | dev_dbg(&s->dev, "could not map memory\n"); | 185 | dev_dbg(&s->dev, "could not map memory\n"); |
186 | memset(ptr, 0xff, len); | 186 | memset(ptr, 0xff, len); |
187 | mutex_unlock(&s->ops_mutex); | ||
188 | return -1; | 187 | return -1; |
189 | } | 188 | } |
190 | end = sys + s->map_size; | 189 | end = sys + s->map_size; |
@@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
198 | addr = 0; | 197 | addr = 0; |
199 | } | 198 | } |
200 | } | 199 | } |
201 | mutex_unlock(&s->ops_mutex); | ||
202 | dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", | 200 | dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", |
203 | *(u_char *)(ptr+0), *(u_char *)(ptr+1), | 201 | *(u_char *)(ptr+0), *(u_char *)(ptr+1), |
204 | *(u_char *)(ptr+2), *(u_char *)(ptr+3)); | 202 | *(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, | |||
209 | /** | 207 | /** |
210 | * pcmcia_write_cis_mem() - low-level function to write CIS memory | 208 | * pcmcia_write_cis_mem() - low-level function to write CIS memory |
211 | * | 209 | * |
212 | * Probably only useful for writing one-byte registers. | 210 | * Probably only useful for writing one-byte registers. Must be called |
211 | * with ops_mutex held. | ||
213 | */ | 212 | */ |
214 | void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | 213 | void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, |
215 | u_int len, void *ptr) | 214 | u_int len, void *ptr) |
@@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
220 | dev_dbg(&s->dev, | 219 | dev_dbg(&s->dev, |
221 | "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); | 220 | "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); |
222 | 221 | ||
223 | mutex_lock(&s->ops_mutex); | ||
224 | if (attr & IS_INDIRECT) { | 222 | if (attr & IS_INDIRECT) { |
225 | /* Indirect accesses use a bunch of special registers at fixed | 223 | /* Indirect accesses use a bunch of special registers at fixed |
226 | locations in common memory */ | 224 | locations in common memory */ |
@@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
234 | ((cis_width) ? MAP_16BIT : 0)); | 232 | ((cis_width) ? MAP_16BIT : 0)); |
235 | if (!sys) { | 233 | if (!sys) { |
236 | dev_dbg(&s->dev, "could not map memory\n"); | 234 | dev_dbg(&s->dev, "could not map memory\n"); |
237 | mutex_unlock(&s->ops_mutex); | ||
238 | return; /* FIXME: Error */ | 235 | return; /* FIXME: Error */ |
239 | } | 236 | } |
240 | 237 | ||
@@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
260 | sys = set_cis_map(s, card_offset, flags); | 257 | sys = set_cis_map(s, card_offset, flags); |
261 | if (!sys) { | 258 | if (!sys) { |
262 | dev_dbg(&s->dev, "could not map memory\n"); | 259 | dev_dbg(&s->dev, "could not map memory\n"); |
263 | mutex_unlock(&s->ops_mutex); | ||
264 | return; /* FIXME: error */ | 260 | return; /* FIXME: error */ |
265 | } | 261 | } |
266 | 262 | ||
@@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
275 | addr = 0; | 271 | addr = 0; |
276 | } | 272 | } |
277 | } | 273 | } |
278 | mutex_unlock(&s->ops_mutex); | ||
279 | } | 274 | } |
280 | 275 | ||
281 | 276 | ||
@@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, | |||
314 | return 0; | 309 | return 0; |
315 | } | 310 | } |
316 | } | 311 | } |
317 | mutex_unlock(&s->ops_mutex); | ||
318 | 312 | ||
319 | ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); | 313 | ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); |
320 | 314 | ||
@@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, | |||
326 | cis->len = len; | 320 | cis->len = len; |
327 | cis->attr = attr; | 321 | cis->attr = attr; |
328 | memcpy(cis->cache, ptr, len); | 322 | memcpy(cis->cache, ptr, len); |
329 | mutex_lock(&s->ops_mutex); | ||
330 | list_add(&cis->node, &s->cis_cache); | 323 | list_add(&cis->node, &s->cis_cache); |
331 | mutex_unlock(&s->ops_mutex); | ||
332 | } | 324 | } |
333 | } | 325 | } |
326 | mutex_unlock(&s->ops_mutex); | ||
327 | |||
334 | return ret; | 328 | return ret; |
335 | } | 329 | } |
336 | 330 | ||
@@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s) | |||
386 | "no memory for verifying CIS\n"); | 380 | "no memory for verifying CIS\n"); |
387 | return -ENOMEM; | 381 | return -ENOMEM; |
388 | } | 382 | } |
383 | mutex_lock(&s->ops_mutex); | ||
389 | list_for_each_entry(cis, &s->cis_cache, node) { | 384 | list_for_each_entry(cis, &s->cis_cache, node) { |
390 | int len = cis->len; | 385 | int len = cis->len; |
391 | 386 | ||
@@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s) | |||
395 | ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); | 390 | ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); |
396 | if (ret || memcmp(buf, cis->cache, len) != 0) { | 391 | if (ret || memcmp(buf, cis->cache, len) != 0) { |
397 | kfree(buf); | 392 | kfree(buf); |
393 | mutex_unlock(&s->ops_mutex); | ||
398 | return -1; | 394 | return -1; |
399 | } | 395 | } |
400 | } | 396 | } |
401 | kfree(buf); | 397 | kfree(buf); |
398 | mutex_unlock(&s->ops_mutex); | ||
402 | return 0; | 399 | return 0; |
403 | } | 400 | } |
404 | 401 | ||
@@ -1362,106 +1359,6 @@ EXPORT_SYMBOL(pcmcia_parse_tuple); | |||
1362 | 1359 | ||
1363 | 1360 | ||
1364 | /** | 1361 | /** |
1365 | * pccard_read_tuple() - internal CIS tuple access | ||
1366 | * @s: the struct pcmcia_socket where the card is inserted | ||
1367 | * @function: the device function we loop for | ||
1368 | * @code: which CIS code shall we look for? | ||
1369 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
1370 | * | ||
1371 | * pccard_read_tuple() reads out one tuple and attempts to parse it | ||
1372 | */ | ||
1373 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, | ||
1374 | cisdata_t code, void *parse) | ||
1375 | { | ||
1376 | tuple_t tuple; | ||
1377 | cisdata_t *buf; | ||
1378 | int ret; | ||
1379 | |||
1380 | buf = kmalloc(256, GFP_KERNEL); | ||
1381 | if (buf == NULL) { | ||
1382 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
1383 | return -ENOMEM; | ||
1384 | } | ||
1385 | tuple.DesiredTuple = code; | ||
1386 | tuple.Attributes = 0; | ||
1387 | if (function == BIND_FN_ALL) | ||
1388 | tuple.Attributes = TUPLE_RETURN_COMMON; | ||
1389 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
1390 | if (ret != 0) | ||
1391 | goto done; | ||
1392 | tuple.TupleData = buf; | ||
1393 | tuple.TupleOffset = 0; | ||
1394 | tuple.TupleDataMax = 255; | ||
1395 | ret = pccard_get_tuple_data(s, &tuple); | ||
1396 | if (ret != 0) | ||
1397 | goto done; | ||
1398 | ret = pcmcia_parse_tuple(&tuple, parse); | ||
1399 | done: | ||
1400 | kfree(buf); | ||
1401 | return ret; | ||
1402 | } | ||
1403 | |||
1404 | |||
1405 | /** | ||
1406 | * pccard_loop_tuple() - loop over tuples in the CIS | ||
1407 | * @s: the struct pcmcia_socket where the card is inserted | ||
1408 | * @function: the device function we loop for | ||
1409 | * @code: which CIS code shall we look for? | ||
1410 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
1411 | * @priv_data: private data to be passed to the loop_tuple function. | ||
1412 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
1413 | * gets passed the raw tuple, the paresed tuple (if @parse is | ||
1414 | * set) and @priv_data. | ||
1415 | * | ||
1416 | * pccard_loop_tuple() loops over all CIS entries of type @function, and | ||
1417 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
1418 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
1419 | */ | ||
1420 | int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, | ||
1421 | cisdata_t code, cisparse_t *parse, void *priv_data, | ||
1422 | int (*loop_tuple) (tuple_t *tuple, | ||
1423 | cisparse_t *parse, | ||
1424 | void *priv_data)) | ||
1425 | { | ||
1426 | tuple_t tuple; | ||
1427 | cisdata_t *buf; | ||
1428 | int ret; | ||
1429 | |||
1430 | buf = kzalloc(256, GFP_KERNEL); | ||
1431 | if (buf == NULL) { | ||
1432 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
1433 | return -ENOMEM; | ||
1434 | } | ||
1435 | |||
1436 | tuple.TupleData = buf; | ||
1437 | tuple.TupleDataMax = 255; | ||
1438 | tuple.TupleOffset = 0; | ||
1439 | tuple.DesiredTuple = code; | ||
1440 | tuple.Attributes = 0; | ||
1441 | |||
1442 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
1443 | while (!ret) { | ||
1444 | if (pccard_get_tuple_data(s, &tuple)) | ||
1445 | goto next_entry; | ||
1446 | |||
1447 | if (parse) | ||
1448 | if (pcmcia_parse_tuple(&tuple, parse)) | ||
1449 | goto next_entry; | ||
1450 | |||
1451 | ret = loop_tuple(&tuple, parse, priv_data); | ||
1452 | if (!ret) | ||
1453 | break; | ||
1454 | |||
1455 | next_entry: | ||
1456 | ret = pccard_get_next_tuple(s, function, &tuple); | ||
1457 | } | ||
1458 | |||
1459 | kfree(buf); | ||
1460 | return ret; | ||
1461 | } | ||
1462 | |||
1463 | |||
1464 | /** | ||
1465 | * pccard_validate_cis() - check whether card has a sensible CIS | 1362 | * pccard_validate_cis() - check whether card has a sensible CIS |
1466 | * @s: the struct pcmcia_socket we are to check | 1363 | * @s: the struct pcmcia_socket we are to check |
1467 | * @info: returns the number of tuples in the (valid) CIS, or 0 | 1364 | * @info: returns the number of tuples in the (valid) CIS, or 0 |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c3383750e333..976d80706eae 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -337,7 +337,6 @@ static void socket_shutdown(struct pcmcia_socket *s) | |||
337 | s->socket = dead_socket; | 337 | s->socket = dead_socket; |
338 | s->ops->init(s); | 338 | s->ops->init(s); |
339 | s->ops->set_socket(s, &s->socket); | 339 | s->ops->set_socket(s, &s->socket); |
340 | s->irq.AssignedIRQ = s->irq.Config = 0; | ||
341 | s->lock_count = 0; | 340 | s->lock_count = 0; |
342 | kfree(s->fake_cis); | 341 | kfree(s->fake_cis); |
343 | s->fake_cis = NULL; | 342 | s->fake_cis = NULL; |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index f95864c2191e..4126a75445ea 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -52,13 +52,11 @@ struct cis_cache_entry { | |||
52 | 52 | ||
53 | struct pccard_resource_ops { | 53 | struct pccard_resource_ops { |
54 | int (*validate_mem) (struct pcmcia_socket *s); | 54 | int (*validate_mem) (struct pcmcia_socket *s); |
55 | int (*adjust_io_region) (struct resource *res, | 55 | int (*find_io) (struct pcmcia_socket *s, |
56 | unsigned long r_start, | 56 | unsigned int attr, |
57 | unsigned long r_end, | 57 | unsigned int *base, |
58 | struct pcmcia_socket *s); | 58 | unsigned int num, |
59 | struct resource* (*find_io) (unsigned long base, int num, | 59 | unsigned int align); |
60 | unsigned long align, | ||
61 | struct pcmcia_socket *s); | ||
62 | struct resource* (*find_mem) (unsigned long base, unsigned long num, | 60 | struct resource* (*find_mem) (unsigned long base, unsigned long num, |
63 | unsigned long align, int low, | 61 | unsigned long align, int low, |
64 | struct pcmcia_socket *s); | 62 | struct pcmcia_socket *s); |
@@ -89,6 +87,14 @@ struct pccard_resource_ops { | |||
89 | 87 | ||
90 | 88 | ||
91 | /* | 89 | /* |
90 | * Stuff internal to module "pcmcia_rsrc": | ||
91 | */ | ||
92 | extern int static_init(struct pcmcia_socket *s); | ||
93 | extern struct resource *pcmcia_make_resource(unsigned long start, | ||
94 | unsigned long end, | ||
95 | int flags, const char *name); | ||
96 | |||
97 | /* | ||
92 | * Stuff internal to module "pcmcia_core": | 98 | * Stuff internal to module "pcmcia_core": |
93 | */ | 99 | */ |
94 | 100 | ||
@@ -149,6 +155,8 @@ extern struct resource *pcmcia_find_mem_region(u_long base, | |||
149 | int low, | 155 | int low, |
150 | struct pcmcia_socket *s); | 156 | struct pcmcia_socket *s); |
151 | 157 | ||
158 | void pcmcia_cleanup_irq(struct pcmcia_socket *s); | ||
159 | int pcmcia_setup_irq(struct pcmcia_device *p_dev); | ||
152 | 160 | ||
153 | /* cistpl.c */ | 161 | /* cistpl.c */ |
154 | extern struct bin_attribute pccard_cis_attr; | 162 | extern struct bin_attribute pccard_cis_attr; |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 041eee43fd8d..7ef7adee5e4f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -371,8 +371,6 @@ static int pcmcia_device_remove(struct device *dev) | |||
371 | if (p_drv->remove) | 371 | if (p_drv->remove) |
372 | p_drv->remove(p_dev); | 372 | p_drv->remove(p_dev); |
373 | 373 | ||
374 | p_dev->dev_node = NULL; | ||
375 | |||
376 | /* check for proper unloading */ | 374 | /* check for proper unloading */ |
377 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) | 375 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) |
378 | dev_printk(KERN_INFO, dev, | 376 | dev_printk(KERN_INFO, dev, |
@@ -479,15 +477,6 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
479 | } | 477 | } |
480 | 478 | ||
481 | 479 | ||
482 | /* device_add_lock is needed to avoid double registration by cardmgr and kernel. | ||
483 | * Serializes pcmcia_device_add; will most likely be removed in future. | ||
484 | * | ||
485 | * While it has the caveat that adding new PCMCIA devices inside(!) device_register() | ||
486 | * won't work, this doesn't matter much at the moment: the driver core doesn't | ||
487 | * support it either. | ||
488 | */ | ||
489 | static DEFINE_MUTEX(device_add_lock); | ||
490 | |||
491 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) | 480 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) |
492 | { | 481 | { |
493 | struct pcmcia_device *p_dev, *tmp_dev; | 482 | struct pcmcia_device *p_dev, *tmp_dev; |
@@ -497,8 +486,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
497 | if (!s) | 486 | if (!s) |
498 | return NULL; | 487 | return NULL; |
499 | 488 | ||
500 | mutex_lock(&device_add_lock); | ||
501 | |||
502 | pr_debug("adding device to %d, function %d\n", s->sock, function); | 489 | pr_debug("adding device to %d, function %d\n", s->sock, function); |
503 | 490 | ||
504 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); | 491 | 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 | |||
538 | 525 | ||
539 | /* | 526 | /* |
540 | * p_dev->function_config must be the same for all card functions. | 527 | * p_dev->function_config must be the same for all card functions. |
541 | * Note that this is serialized by the device_add_lock, so that | 528 | * Note that this is serialized by ops_mutex, so that only one |
542 | * only one such struct will be created. | 529 | * such struct will be created. |
543 | */ | 530 | */ |
544 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) | 531 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) |
545 | if (p_dev->func == tmp_dev->func) { | 532 | if (p_dev->func == tmp_dev->func) { |
@@ -552,28 +539,31 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
552 | /* Add to the list in pcmcia_bus_socket */ | 539 | /* Add to the list in pcmcia_bus_socket */ |
553 | list_add(&p_dev->socket_device_list, &s->devices_list); | 540 | list_add(&p_dev->socket_device_list, &s->devices_list); |
554 | 541 | ||
555 | mutex_unlock(&s->ops_mutex); | 542 | if (pcmcia_setup_irq(p_dev)) |
543 | dev_warn(&p_dev->dev, | ||
544 | "IRQ setup failed -- device might not work\n"); | ||
556 | 545 | ||
557 | if (!p_dev->function_config) { | 546 | if (!p_dev->function_config) { |
558 | dev_dbg(&p_dev->dev, "creating config_t\n"); | 547 | dev_dbg(&p_dev->dev, "creating config_t\n"); |
559 | p_dev->function_config = kzalloc(sizeof(struct config_t), | 548 | p_dev->function_config = kzalloc(sizeof(struct config_t), |
560 | GFP_KERNEL); | 549 | GFP_KERNEL); |
561 | if (!p_dev->function_config) | 550 | if (!p_dev->function_config) { |
551 | mutex_unlock(&s->ops_mutex); | ||
562 | goto err_unreg; | 552 | goto err_unreg; |
553 | } | ||
563 | kref_init(&p_dev->function_config->ref); | 554 | kref_init(&p_dev->function_config->ref); |
564 | } | 555 | } |
556 | mutex_unlock(&s->ops_mutex); | ||
565 | 557 | ||
566 | dev_printk(KERN_NOTICE, &p_dev->dev, | 558 | dev_printk(KERN_NOTICE, &p_dev->dev, |
567 | "pcmcia: registering new device %s\n", | 559 | "pcmcia: registering new device %s (IRQ: %d)\n", |
568 | p_dev->devname); | 560 | p_dev->devname, p_dev->irq); |
569 | 561 | ||
570 | pcmcia_device_query(p_dev); | 562 | pcmcia_device_query(p_dev); |
571 | 563 | ||
572 | if (device_register(&p_dev->dev)) | 564 | if (device_register(&p_dev->dev)) |
573 | goto err_unreg; | 565 | goto err_unreg; |
574 | 566 | ||
575 | mutex_unlock(&device_add_lock); | ||
576 | |||
577 | return p_dev; | 567 | return p_dev; |
578 | 568 | ||
579 | err_unreg: | 569 | err_unreg: |
@@ -591,7 +581,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
591 | kfree(p_dev->devname); | 581 | kfree(p_dev->devname); |
592 | kfree(p_dev); | 582 | kfree(p_dev); |
593 | err_put: | 583 | err_put: |
594 | mutex_unlock(&device_add_lock); | ||
595 | pcmcia_put_socket(s); | 584 | pcmcia_put_socket(s); |
596 | 585 | ||
597 | return NULL; | 586 | return NULL; |
@@ -1258,6 +1247,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1258 | handle_event(skt, event); | 1247 | handle_event(skt, event); |
1259 | mutex_lock(&s->ops_mutex); | 1248 | mutex_lock(&s->ops_mutex); |
1260 | destroy_cis_cache(s); | 1249 | destroy_cis_cache(s); |
1250 | pcmcia_cleanup_irq(s); | ||
1261 | mutex_unlock(&s->ops_mutex); | 1251 | mutex_unlock(&s->ops_mutex); |
1262 | break; | 1252 | break; |
1263 | 1253 | ||
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index a7cfc7964c7c..0ad06a3bd562 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c | |||
@@ -117,7 +117,7 @@ static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
117 | 117 | ||
118 | *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; | 118 | *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; |
119 | cf = container_of(s, struct omap_cf_socket, socket); | 119 | cf = container_of(s, struct omap_cf_socket, socket); |
120 | s->irq.AssignedIRQ = 0; | 120 | s->pcmcia_irq = 0; |
121 | s->pci_irq = cf->irq; | 121 | s->pci_irq = cf->irq; |
122 | } else | 122 | } else |
123 | *sp = 0; | 123 | *sp = 0; |
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c new file mode 100644 index 000000000000..4a65eaf96b0a --- /dev/null +++ b/drivers/pcmcia/pcmcia_cis.c | |||
@@ -0,0 +1,356 @@ | |||
1 | /* | ||
2 | * PCMCIA high-level CIS access functions | ||
3 | * | ||
4 | * The initial developer of the original code is David A. Hinds | ||
5 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
6 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
7 | * | ||
8 | * Copyright (C) 1999 David A. Hinds | ||
9 | * Copyright (C) 2004-2009 Dominik Brodowski | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/slab.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/netdevice.h> | ||
21 | |||
22 | #include <pcmcia/cs_types.h> | ||
23 | #include <pcmcia/cisreg.h> | ||
24 | #include <pcmcia/cistpl.h> | ||
25 | #include <pcmcia/ss.h> | ||
26 | #include <pcmcia/cs.h> | ||
27 | #include <pcmcia/ds.h> | ||
28 | #include "cs_internal.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * pccard_read_tuple() - internal CIS tuple access | ||
33 | * @s: the struct pcmcia_socket where the card is inserted | ||
34 | * @function: the device function we loop for | ||
35 | * @code: which CIS code shall we look for? | ||
36 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
37 | * | ||
38 | * pccard_read_tuple() reads out one tuple and attempts to parse it | ||
39 | */ | ||
40 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, | ||
41 | cisdata_t code, void *parse) | ||
42 | { | ||
43 | tuple_t tuple; | ||
44 | cisdata_t *buf; | ||
45 | int ret; | ||
46 | |||
47 | buf = kmalloc(256, GFP_KERNEL); | ||
48 | if (buf == NULL) { | ||
49 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
50 | return -ENOMEM; | ||
51 | } | ||
52 | tuple.DesiredTuple = code; | ||
53 | tuple.Attributes = 0; | ||
54 | if (function == BIND_FN_ALL) | ||
55 | tuple.Attributes = TUPLE_RETURN_COMMON; | ||
56 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
57 | if (ret != 0) | ||
58 | goto done; | ||
59 | tuple.TupleData = buf; | ||
60 | tuple.TupleOffset = 0; | ||
61 | tuple.TupleDataMax = 255; | ||
62 | ret = pccard_get_tuple_data(s, &tuple); | ||
63 | if (ret != 0) | ||
64 | goto done; | ||
65 | ret = pcmcia_parse_tuple(&tuple, parse); | ||
66 | done: | ||
67 | kfree(buf); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | |||
72 | /** | ||
73 | * pccard_loop_tuple() - loop over tuples in the CIS | ||
74 | * @s: the struct pcmcia_socket where the card is inserted | ||
75 | * @function: the device function we loop for | ||
76 | * @code: which CIS code shall we look for? | ||
77 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
78 | * @priv_data: private data to be passed to the loop_tuple function. | ||
79 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
80 | * gets passed the raw tuple, the paresed tuple (if @parse is | ||
81 | * set) and @priv_data. | ||
82 | * | ||
83 | * pccard_loop_tuple() loops over all CIS entries of type @function, and | ||
84 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
85 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
86 | */ | ||
87 | int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, | ||
88 | cisdata_t code, cisparse_t *parse, void *priv_data, | ||
89 | int (*loop_tuple) (tuple_t *tuple, | ||
90 | cisparse_t *parse, | ||
91 | void *priv_data)) | ||
92 | { | ||
93 | tuple_t tuple; | ||
94 | cisdata_t *buf; | ||
95 | int ret; | ||
96 | |||
97 | buf = kzalloc(256, GFP_KERNEL); | ||
98 | if (buf == NULL) { | ||
99 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | |||
103 | tuple.TupleData = buf; | ||
104 | tuple.TupleDataMax = 255; | ||
105 | tuple.TupleOffset = 0; | ||
106 | tuple.DesiredTuple = code; | ||
107 | tuple.Attributes = 0; | ||
108 | |||
109 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
110 | while (!ret) { | ||
111 | if (pccard_get_tuple_data(s, &tuple)) | ||
112 | goto next_entry; | ||
113 | |||
114 | if (parse) | ||
115 | if (pcmcia_parse_tuple(&tuple, parse)) | ||
116 | goto next_entry; | ||
117 | |||
118 | ret = loop_tuple(&tuple, parse, priv_data); | ||
119 | if (!ret) | ||
120 | break; | ||
121 | |||
122 | next_entry: | ||
123 | ret = pccard_get_next_tuple(s, function, &tuple); | ||
124 | } | ||
125 | |||
126 | kfree(buf); | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | struct pcmcia_cfg_mem { | ||
131 | struct pcmcia_device *p_dev; | ||
132 | void *priv_data; | ||
133 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
134 | cistpl_cftable_entry_t *cfg, | ||
135 | cistpl_cftable_entry_t *dflt, | ||
136 | unsigned int vcc, | ||
137 | void *priv_data); | ||
138 | cisparse_t parse; | ||
139 | cistpl_cftable_entry_t dflt; | ||
140 | }; | ||
141 | |||
142 | /** | ||
143 | * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() | ||
144 | * | ||
145 | * pcmcia_do_loop_config() is the internal callback for the call from | ||
146 | * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred | ||
147 | * by a struct pcmcia_cfg_mem. | ||
148 | */ | ||
149 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
150 | { | ||
151 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
152 | struct pcmcia_cfg_mem *cfg_mem = priv; | ||
153 | |||
154 | /* default values */ | ||
155 | cfg_mem->p_dev->conf.ConfigIndex = cfg->index; | ||
156 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
157 | cfg_mem->dflt = *cfg; | ||
158 | |||
159 | return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, | ||
160 | cfg_mem->p_dev->socket->socket.Vcc, | ||
161 | cfg_mem->priv_data); | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * pcmcia_loop_config() - loop over configuration options | ||
166 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
167 | * @conf_check: function to call for each configuration option. | ||
168 | * It gets passed the struct pcmcia_device, the CIS data | ||
169 | * describing the configuration option, and private data | ||
170 | * being passed to pcmcia_loop_config() | ||
171 | * @priv_data: private data to be passed to the conf_check function. | ||
172 | * | ||
173 | * pcmcia_loop_config() loops over all configuration options, and calls | ||
174 | * the driver-specific conf_check() for each one, checking whether | ||
175 | * it is a valid one. Returns 0 on success or errorcode otherwise. | ||
176 | */ | ||
177 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | ||
178 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
179 | cistpl_cftable_entry_t *cfg, | ||
180 | cistpl_cftable_entry_t *dflt, | ||
181 | unsigned int vcc, | ||
182 | void *priv_data), | ||
183 | void *priv_data) | ||
184 | { | ||
185 | struct pcmcia_cfg_mem *cfg_mem; | ||
186 | int ret; | ||
187 | |||
188 | cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); | ||
189 | if (cfg_mem == NULL) | ||
190 | return -ENOMEM; | ||
191 | |||
192 | cfg_mem->p_dev = p_dev; | ||
193 | cfg_mem->conf_check = conf_check; | ||
194 | cfg_mem->priv_data = priv_data; | ||
195 | |||
196 | ret = pccard_loop_tuple(p_dev->socket, p_dev->func, | ||
197 | CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, | ||
198 | cfg_mem, pcmcia_do_loop_config); | ||
199 | |||
200 | kfree(cfg_mem); | ||
201 | return ret; | ||
202 | } | ||
203 | EXPORT_SYMBOL(pcmcia_loop_config); | ||
204 | |||
205 | |||
206 | struct pcmcia_loop_mem { | ||
207 | struct pcmcia_device *p_dev; | ||
208 | void *priv_data; | ||
209 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
210 | tuple_t *tuple, | ||
211 | void *priv_data); | ||
212 | }; | ||
213 | |||
214 | /** | ||
215 | * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() | ||
216 | * | ||
217 | * pcmcia_do_loop_tuple() is the internal callback for the call from | ||
218 | * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred | ||
219 | * by a struct pcmcia_cfg_mem. | ||
220 | */ | ||
221 | static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
222 | { | ||
223 | struct pcmcia_loop_mem *loop = priv; | ||
224 | |||
225 | return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); | ||
226 | }; | ||
227 | |||
228 | /** | ||
229 | * pcmcia_loop_tuple() - loop over tuples in the CIS | ||
230 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
231 | * @code: which CIS code shall we look for? | ||
232 | * @priv_data: private data to be passed to the loop_tuple function. | ||
233 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
234 | * gets passed the raw tuple and @priv_data. | ||
235 | * | ||
236 | * pcmcia_loop_tuple() loops over all CIS entries of type @function, and | ||
237 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
238 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
239 | */ | ||
240 | int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
241 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
242 | tuple_t *tuple, | ||
243 | void *priv_data), | ||
244 | void *priv_data) | ||
245 | { | ||
246 | struct pcmcia_loop_mem loop = { | ||
247 | .p_dev = p_dev, | ||
248 | .loop_tuple = loop_tuple, | ||
249 | .priv_data = priv_data}; | ||
250 | |||
251 | return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, | ||
252 | &loop, pcmcia_do_loop_tuple); | ||
253 | } | ||
254 | EXPORT_SYMBOL(pcmcia_loop_tuple); | ||
255 | |||
256 | |||
257 | struct pcmcia_loop_get { | ||
258 | size_t len; | ||
259 | cisdata_t **buf; | ||
260 | }; | ||
261 | |||
262 | /** | ||
263 | * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() | ||
264 | * | ||
265 | * pcmcia_do_get_tuple() is the internal callback for the call from | ||
266 | * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in | ||
267 | * the first tuple, return 0 unconditionally. Create a memory buffer large | ||
268 | * enough to hold the content of the tuple, and fill it with the tuple data. | ||
269 | * The caller is responsible to free the buffer. | ||
270 | */ | ||
271 | static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
272 | void *priv) | ||
273 | { | ||
274 | struct pcmcia_loop_get *get = priv; | ||
275 | |||
276 | *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); | ||
277 | if (*get->buf) { | ||
278 | get->len = tuple->TupleDataLen; | ||
279 | memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); | ||
280 | } else | ||
281 | dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * pcmcia_get_tuple() - get first tuple from CIS | ||
287 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
288 | * @code: which CIS code shall we look for? | ||
289 | * @buf: pointer to store the buffer to. | ||
290 | * | ||
291 | * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. | ||
292 | * It returns the buffer length (or zero). The caller is responsible to free | ||
293 | * the buffer passed in @buf. | ||
294 | */ | ||
295 | size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
296 | unsigned char **buf) | ||
297 | { | ||
298 | struct pcmcia_loop_get get = { | ||
299 | .len = 0, | ||
300 | .buf = buf, | ||
301 | }; | ||
302 | |||
303 | *get.buf = NULL; | ||
304 | pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); | ||
305 | |||
306 | return get.len; | ||
307 | } | ||
308 | EXPORT_SYMBOL(pcmcia_get_tuple); | ||
309 | |||
310 | |||
311 | /** | ||
312 | * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() | ||
313 | * | ||
314 | * pcmcia_do_get_mac() is the internal callback for the call from | ||
315 | * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the | ||
316 | * tuple contains a proper LAN_NODE_ID of length 6, and copy the data | ||
317 | * to struct net_device->dev_addr[i]. | ||
318 | */ | ||
319 | static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
320 | void *priv) | ||
321 | { | ||
322 | struct net_device *dev = priv; | ||
323 | int i; | ||
324 | |||
325 | if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) | ||
326 | return -EINVAL; | ||
327 | if (tuple->TupleDataLen < ETH_ALEN + 2) { | ||
328 | dev_warn(&p_dev->dev, "Invalid CIS tuple length for " | ||
329 | "LAN_NODE_ID\n"); | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | |||
333 | if (tuple->TupleData[1] != ETH_ALEN) { | ||
334 | dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | for (i = 0; i < 6; i++) | ||
338 | dev->dev_addr[i] = tuple->TupleData[i+2]; | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE | ||
344 | * @p_dev: the struct pcmcia_device for which we want the address. | ||
345 | * @dev: a properly prepared struct net_device to store the info to. | ||
346 | * | ||
347 | * pcmcia_get_mac_from_cis() reads out the hardware MAC address from | ||
348 | * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which | ||
349 | * must be set up properly by the driver (see examples!). | ||
350 | */ | ||
351 | int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) | ||
352 | { | ||
353 | return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); | ||
354 | } | ||
355 | EXPORT_SYMBOL(pcmcia_get_mac_from_cis); | ||
356 | |||
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 7631faa0cadd..ef0c5f133691 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
301 | (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { | 301 | (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { |
302 | u_char reg; | 302 | u_char reg; |
303 | if (c->CardValues & PRESENT_PIN_REPLACE) { | 303 | if (c->CardValues & PRESENT_PIN_REPLACE) { |
304 | mutex_lock(&s->ops_mutex); | ||
304 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); | 305 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); |
306 | mutex_unlock(&s->ops_mutex); | ||
305 | status->CardState |= | 307 | status->CardState |= |
306 | (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; | 308 | (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; |
307 | status->CardState |= | 309 | status->CardState |= |
@@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
315 | status->CardState |= CS_EVENT_READY_CHANGE; | 317 | status->CardState |= CS_EVENT_READY_CHANGE; |
316 | } | 318 | } |
317 | if (c->CardValues & PRESENT_EXT_STATUS) { | 319 | if (c->CardValues & PRESENT_EXT_STATUS) { |
320 | mutex_lock(&s->ops_mutex); | ||
318 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); | 321 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); |
322 | mutex_unlock(&s->ops_mutex); | ||
319 | status->CardState |= | 323 | status->CardState |= |
320 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; | 324 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; |
321 | } | 325 | } |
@@ -351,7 +355,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s, | |||
351 | if (s->state & SOCKET_CARDBUS_CONFIG) { | 355 | if (s->state & SOCKET_CARDBUS_CONFIG) { |
352 | config->Attributes = CONF_VALID_CLIENT; | 356 | config->Attributes = CONF_VALID_CLIENT; |
353 | config->IntType = INT_CARDBUS; | 357 | config->IntType = INT_CARDBUS; |
354 | config->AssignedIRQ = s->irq.AssignedIRQ; | 358 | config->AssignedIRQ = s->pcmcia_irq; |
355 | if (config->AssignedIRQ) | 359 | if (config->AssignedIRQ) |
356 | config->Attributes |= CONF_ENABLE_IRQ; | 360 | config->Attributes |= CONF_ENABLE_IRQ; |
357 | if (s->io[0].res) { | 361 | if (s->io[0].res) { |
@@ -391,7 +395,7 @@ static int pccard_get_configuration_info(struct pcmcia_socket *s, | |||
391 | config->ExtStatus = c->ExtStatus; | 395 | config->ExtStatus = c->ExtStatus; |
392 | config->Present = config->CardValues = c->CardValues; | 396 | config->Present = config->CardValues = c->CardValues; |
393 | config->IRQAttributes = c->irq.Attributes; | 397 | config->IRQAttributes = c->irq.Attributes; |
394 | config->AssignedIRQ = s->irq.AssignedIRQ; | 398 | config->AssignedIRQ = s->pcmcia_irq; |
395 | config->BasePort1 = c->io.BasePort1; | 399 | config->BasePort1 = c->io.BasePort1; |
396 | config->NumPorts1 = c->io.NumPorts1; | 400 | config->NumPorts1 = c->io.NumPorts1; |
397 | config->Attributes1 = c->io.Attributes1; | 401 | config->Attributes1 = c->io.Attributes1; |
@@ -571,7 +575,6 @@ static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s) | |||
571 | 575 | ||
572 | static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) | 576 | static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) |
573 | { | 577 | { |
574 | dev_node_t *node; | ||
575 | struct pcmcia_device *p_dev; | 578 | struct pcmcia_device *p_dev; |
576 | struct pcmcia_driver *p_drv; | 579 | struct pcmcia_driver *p_drv; |
577 | int ret = 0; | 580 | int ret = 0; |
@@ -633,21 +636,13 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int | |||
633 | goto err_put; | 636 | goto err_put; |
634 | } | 637 | } |
635 | 638 | ||
636 | if (first) | 639 | if (!first) { |
637 | node = p_dev->dev_node; | ||
638 | else | ||
639 | for (node = p_dev->dev_node; node; node = node->next) | ||
640 | if (node == bind_info->next) | ||
641 | break; | ||
642 | if (!node) { | ||
643 | ret = -ENODEV; | 640 | ret = -ENODEV; |
644 | goto err_put; | 641 | goto err_put; |
645 | } | 642 | } |
646 | 643 | ||
647 | strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN); | 644 | strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN); |
648 | bind_info->major = node->major; | 645 | bind_info->next = NULL; |
649 | bind_info->minor = node->minor; | ||
650 | bind_info->next = node->next; | ||
651 | 646 | ||
652 | err_put: | 647 | err_put: |
653 | pcmcia_put_dev(p_dev); | 648 | pcmcia_put_dev(p_dev); |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 7c3d03bb4f30..29f91fac1dff 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include <asm/irq.h> | ||
27 | |||
26 | #include <pcmcia/cs_types.h> | 28 | #include <pcmcia/cs_types.h> |
27 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
28 | #include <pcmcia/cs.h> | 30 | #include <pcmcia/cs.h> |
@@ -38,29 +40,6 @@ static int io_speed; | |||
38 | module_param(io_speed, int, 0444); | 40 | module_param(io_speed, int, 0444); |
39 | 41 | ||
40 | 42 | ||
41 | #ifdef CONFIG_PCMCIA_PROBE | ||
42 | #include <asm/irq.h> | ||
43 | /* mask of IRQs already reserved by other cards, we should avoid using them */ | ||
44 | static u8 pcmcia_used_irq[NR_IRQS]; | ||
45 | #endif | ||
46 | |||
47 | static int pcmcia_adjust_io_region(struct resource *res, unsigned long start, | ||
48 | unsigned long end, struct pcmcia_socket *s) | ||
49 | { | ||
50 | if (s->resource_ops->adjust_io_region) | ||
51 | return s->resource_ops->adjust_io_region(res, start, end, s); | ||
52 | return -ENOMEM; | ||
53 | } | ||
54 | |||
55 | static struct resource *pcmcia_find_io_region(unsigned long base, int num, | ||
56 | unsigned long align, | ||
57 | struct pcmcia_socket *s) | ||
58 | { | ||
59 | if (s->resource_ops->find_io) | ||
60 | return s->resource_ops->find_io(base, num, align, s); | ||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | int pcmcia_validate_mem(struct pcmcia_socket *s) | 43 | int pcmcia_validate_mem(struct pcmcia_socket *s) |
65 | { | 44 | { |
66 | if (s->resource_ops->validate_mem) | 45 | 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, | |||
86 | static int alloc_io_space(struct pcmcia_socket *s, u_int attr, | 65 | static int alloc_io_space(struct pcmcia_socket *s, u_int attr, |
87 | unsigned int *base, unsigned int num, u_int lines) | 66 | unsigned int *base, unsigned int num, u_int lines) |
88 | { | 67 | { |
89 | int i; | 68 | unsigned int align; |
90 | unsigned int try, align; | ||
91 | 69 | ||
92 | align = (*base) ? (lines ? 1<<lines : 0) : 1; | 70 | align = (*base) ? (lines ? 1<<lines : 0) : 1; |
93 | if (align && (align < num)) { | 71 | if (align && (align < num)) { |
@@ -104,50 +82,8 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, | |||
104 | *base, align); | 82 | *base, align); |
105 | align = 0; | 83 | align = 0; |
106 | } | 84 | } |
107 | if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { | 85 | |
108 | *base = s->io_offset | (*base & 0x0fff); | 86 | return s->resource_ops->find_io(s, attr, base, num, align); |
109 | return 0; | ||
110 | } | ||
111 | /* Check for an already-allocated window that must conflict with | ||
112 | * what was asked for. It is a hack because it does not catch all | ||
113 | * potential conflicts, just the most obvious ones. | ||
114 | */ | ||
115 | for (i = 0; i < MAX_IO_WIN; i++) | ||
116 | if ((s->io[i].res) && *base && | ||
117 | ((s->io[i].res->start & (align-1)) == *base)) | ||
118 | return 1; | ||
119 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
120 | if (!s->io[i].res) { | ||
121 | s->io[i].res = pcmcia_find_io_region(*base, num, align, s); | ||
122 | if (s->io[i].res) { | ||
123 | *base = s->io[i].res->start; | ||
124 | s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); | ||
125 | s->io[i].InUse = num; | ||
126 | break; | ||
127 | } else | ||
128 | return 1; | ||
129 | } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS)) | ||
130 | continue; | ||
131 | /* Try to extend top of window */ | ||
132 | try = s->io[i].res->end + 1; | ||
133 | if ((*base == 0) || (*base == try)) | ||
134 | if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, | ||
135 | s->io[i].res->end + num, s) == 0) { | ||
136 | *base = try; | ||
137 | s->io[i].InUse += num; | ||
138 | break; | ||
139 | } | ||
140 | /* Try to extend bottom of window */ | ||
141 | try = s->io[i].res->start - num; | ||
142 | if ((*base == 0) || (*base == try)) | ||
143 | if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, | ||
144 | s->io[i].res->end, s) == 0) { | ||
145 | *base = try; | ||
146 | s->io[i].InUse += num; | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | return (i == MAX_IO_WIN); | ||
151 | } /* alloc_io_space */ | 87 | } /* alloc_io_space */ |
152 | 88 | ||
153 | 89 | ||
@@ -187,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
187 | config_t *c; | 123 | config_t *c; |
188 | int addr; | 124 | int addr; |
189 | u_char val; | 125 | u_char val; |
126 | int ret = 0; | ||
190 | 127 | ||
191 | if (!p_dev || !p_dev->function_config) | 128 | if (!p_dev || !p_dev->function_config) |
192 | return -EINVAL; | 129 | return -EINVAL; |
@@ -203,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
203 | } | 140 | } |
204 | 141 | ||
205 | addr = (c->ConfigBase + reg->Offset) >> 1; | 142 | addr = (c->ConfigBase + reg->Offset) >> 1; |
206 | mutex_unlock(&s->ops_mutex); | ||
207 | 143 | ||
208 | switch (reg->Action) { | 144 | switch (reg->Action) { |
209 | case CS_READ: | 145 | case CS_READ: |
210 | pcmcia_read_cis_mem(s, 1, addr, 1, &val); | 146 | ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val); |
211 | reg->Value = val; | 147 | reg->Value = val; |
212 | break; | 148 | break; |
213 | case CS_WRITE: | 149 | case CS_WRITE: |
@@ -216,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
216 | break; | 152 | break; |
217 | default: | 153 | default: |
218 | dev_dbg(&s->dev, "Invalid conf register request\n"); | 154 | dev_dbg(&s->dev, "Invalid conf register request\n"); |
219 | return -EINVAL; | 155 | ret = -EINVAL; |
220 | break; | 156 | break; |
221 | } | 157 | } |
222 | return 0; | 158 | mutex_unlock(&s->ops_mutex); |
159 | return ret; | ||
223 | } /* pcmcia_access_configuration_register */ | 160 | } /* pcmcia_access_configuration_register */ |
224 | EXPORT_SYMBOL(pcmcia_access_configuration_register); | 161 | EXPORT_SYMBOL(pcmcia_access_configuration_register); |
225 | 162 | ||
@@ -275,19 +212,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
275 | goto unlock; | 212 | goto unlock; |
276 | } | 213 | } |
277 | 214 | ||
278 | if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { | 215 | if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { |
279 | if (mod->Attributes & CONF_ENABLE_IRQ) { | 216 | dev_dbg(&s->dev, |
280 | c->Attributes |= CONF_ENABLE_IRQ; | 217 | "changing Vcc or IRQ is not allowed at this time\n"); |
281 | s->socket.io_irq = s->irq.AssignedIRQ; | ||
282 | } else { | ||
283 | c->Attributes &= ~CONF_ENABLE_IRQ; | ||
284 | s->socket.io_irq = 0; | ||
285 | } | ||
286 | s->ops->set_socket(s, &s->socket); | ||
287 | } | ||
288 | |||
289 | if (mod->Attributes & CONF_VCC_CHANGE_VALID) { | ||
290 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); | ||
291 | ret = -EINVAL; | 218 | ret = -EINVAL; |
292 | goto unlock; | 219 | goto unlock; |
293 | } | 220 | } |
@@ -422,52 +349,6 @@ out: | |||
422 | } /* pcmcia_release_io */ | 349 | } /* pcmcia_release_io */ |
423 | 350 | ||
424 | 351 | ||
425 | static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) | ||
426 | { | ||
427 | struct pcmcia_socket *s = p_dev->socket; | ||
428 | config_t *c; | ||
429 | int ret = -EINVAL; | ||
430 | |||
431 | mutex_lock(&s->ops_mutex); | ||
432 | |||
433 | c = p_dev->function_config; | ||
434 | |||
435 | if (!p_dev->_irq) | ||
436 | goto out; | ||
437 | |||
438 | p_dev->_irq = 0; | ||
439 | |||
440 | if (c->state & CONFIG_LOCKED) | ||
441 | goto out; | ||
442 | |||
443 | if (c->irq.Attributes != req->Attributes) { | ||
444 | dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n"); | ||
445 | goto out; | ||
446 | } | ||
447 | if (s->irq.AssignedIRQ != req->AssignedIRQ) { | ||
448 | dev_dbg(&s->dev, "IRQ must match assigned one\n"); | ||
449 | goto out; | ||
450 | } | ||
451 | if (--s->irq.Config == 0) { | ||
452 | c->state &= ~CONFIG_IRQ_REQ; | ||
453 | s->irq.AssignedIRQ = 0; | ||
454 | } | ||
455 | |||
456 | if (req->Handler) | ||
457 | free_irq(req->AssignedIRQ, p_dev->priv); | ||
458 | |||
459 | #ifdef CONFIG_PCMCIA_PROBE | ||
460 | pcmcia_used_irq[req->AssignedIRQ]--; | ||
461 | #endif | ||
462 | ret = 0; | ||
463 | |||
464 | out: | ||
465 | mutex_unlock(&s->ops_mutex); | ||
466 | |||
467 | return ret; | ||
468 | } /* pcmcia_release_irq */ | ||
469 | |||
470 | |||
471 | int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | 352 | int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) |
472 | { | 353 | { |
473 | struct pcmcia_socket *s = p_dev->socket; | 354 | struct pcmcia_socket *s = p_dev->socket; |
@@ -551,12 +432,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
551 | if (req->Attributes & CONF_ENABLE_SPKR) | 432 | if (req->Attributes & CONF_ENABLE_SPKR) |
552 | s->socket.flags |= SS_SPKR_ENA; | 433 | s->socket.flags |= SS_SPKR_ENA; |
553 | if (req->Attributes & CONF_ENABLE_IRQ) | 434 | if (req->Attributes & CONF_ENABLE_IRQ) |
554 | s->socket.io_irq = s->irq.AssignedIRQ; | 435 | s->socket.io_irq = s->pcmcia_irq; |
555 | else | 436 | else |
556 | s->socket.io_irq = 0; | 437 | s->socket.io_irq = 0; |
557 | s->ops->set_socket(s, &s->socket); | 438 | s->ops->set_socket(s, &s->socket); |
558 | s->lock_count++; | 439 | s->lock_count++; |
559 | mutex_unlock(&s->ops_mutex); | ||
560 | 440 | ||
561 | /* Set up CIS configuration registers */ | 441 | /* Set up CIS configuration registers */ |
562 | base = c->ConfigBase = req->ConfigBase; | 442 | base = c->ConfigBase = req->ConfigBase; |
@@ -574,9 +454,9 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
574 | if (req->Present & PRESENT_IOBASE_0) | 454 | if (req->Present & PRESENT_IOBASE_0) |
575 | c->Option |= COR_ADDR_DECODE; | 455 | c->Option |= COR_ADDR_DECODE; |
576 | } | 456 | } |
577 | if (c->state & CONFIG_IRQ_REQ) | 457 | if ((req->Attributes & CONF_ENABLE_IRQ) && |
578 | if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) | 458 | !(req->Attributes & CONF_ENABLE_PULSE_IRQ)) |
579 | c->Option |= COR_LEVEL_REQ; | 459 | c->Option |= COR_LEVEL_REQ; |
580 | pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); | 460 | pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); |
581 | mdelay(40); | 461 | mdelay(40); |
582 | } | 462 | } |
@@ -605,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
605 | 485 | ||
606 | /* Configure I/O windows */ | 486 | /* Configure I/O windows */ |
607 | if (c->state & CONFIG_IO_REQ) { | 487 | if (c->state & CONFIG_IO_REQ) { |
608 | mutex_lock(&s->ops_mutex); | ||
609 | iomap.speed = io_speed; | 488 | iomap.speed = io_speed; |
610 | for (i = 0; i < MAX_IO_WIN; i++) | 489 | for (i = 0; i < MAX_IO_WIN; i++) |
611 | if (s->io[i].res) { | 490 | if (s->io[i].res) { |
@@ -624,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
624 | s->ops->set_io_map(s, &iomap); | 503 | s->ops->set_io_map(s, &iomap); |
625 | s->io[i].Config++; | 504 | s->io[i].Config++; |
626 | } | 505 | } |
627 | mutex_unlock(&s->ops_mutex); | ||
628 | } | 506 | } |
629 | 507 | ||
630 | c->state |= CONFIG_LOCKED; | 508 | c->state |= CONFIG_LOCKED; |
631 | p_dev->_locked = 1; | 509 | p_dev->_locked = 1; |
510 | mutex_unlock(&s->ops_mutex); | ||
632 | return 0; | 511 | return 0; |
633 | } /* pcmcia_request_configuration */ | 512 | } /* pcmcia_request_configuration */ |
634 | EXPORT_SYMBOL(pcmcia_request_configuration); | 513 | EXPORT_SYMBOL(pcmcia_request_configuration); |
@@ -706,137 +585,176 @@ out: | |||
706 | EXPORT_SYMBOL(pcmcia_request_io); | 585 | EXPORT_SYMBOL(pcmcia_request_io); |
707 | 586 | ||
708 | 587 | ||
709 | /** pcmcia_request_irq | 588 | /** |
589 | * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device | ||
710 | * | 590 | * |
711 | * Request_irq() reserves an irq for this client. | 591 | * pcmcia_request_irq() is a wrapper around request_irq which will allow |
592 | * the PCMCIA core to clean up the registration in pcmcia_disable_device(). | ||
593 | * Drivers are free to use request_irq() directly, but then they need to | ||
594 | * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ | ||
595 | * handlers are allowed. | ||
596 | */ | ||
597 | int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, | ||
598 | irq_handler_t handler) | ||
599 | { | ||
600 | int ret; | ||
601 | |||
602 | if (!p_dev->irq) | ||
603 | return -EINVAL; | ||
604 | |||
605 | ret = request_irq(p_dev->irq, handler, IRQF_SHARED, | ||
606 | p_dev->devname, p_dev->priv); | ||
607 | if (!ret) | ||
608 | p_dev->_irq = 1; | ||
609 | |||
610 | return ret; | ||
611 | } | ||
612 | EXPORT_SYMBOL(pcmcia_request_irq); | ||
613 | |||
614 | |||
615 | /** | ||
616 | * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first | ||
712 | * | 617 | * |
713 | * Also, since Linux only reserves irq's when they are actually | 618 | * pcmcia_request_exclusive_irq() is a wrapper around request_irq which |
714 | * hooked, we don't guarantee that an irq will still be available | 619 | * attempts first to request an exclusive IRQ. If it fails, it also accepts |
715 | * when the configuration is locked. Now that I think about it, | 620 | * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for |
716 | * there might be a way to fix this using a dummy handler. | 621 | * IRQ sharing and either use request_irq directly (then they need to call |
622 | * free_irq themselves, too), or the pcmcia_request_irq() function. | ||
717 | */ | 623 | */ |
624 | int __must_check | ||
625 | __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, | ||
626 | irq_handler_t handler) | ||
627 | { | ||
628 | int ret; | ||
629 | |||
630 | if (!p_dev->irq) | ||
631 | return -EINVAL; | ||
632 | |||
633 | ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv); | ||
634 | if (ret) { | ||
635 | ret = pcmcia_request_irq(p_dev, handler); | ||
636 | dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " | ||
637 | "request for exclusive IRQ could not be fulfilled.\n"); | ||
638 | dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " | ||
639 | "needs updating to supported shared IRQ lines.\n"); | ||
640 | } | ||
641 | if (ret) | ||
642 | dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n"); | ||
643 | else | ||
644 | p_dev->_irq = 1; | ||
645 | |||
646 | return ret; | ||
647 | } /* pcmcia_request_exclusive_irq */ | ||
648 | EXPORT_SYMBOL(__pcmcia_request_exclusive_irq); | ||
649 | |||
718 | 650 | ||
719 | #ifdef CONFIG_PCMCIA_PROBE | 651 | #ifdef CONFIG_PCMCIA_PROBE |
652 | |||
653 | /* mask of IRQs already reserved by other cards, we should avoid using them */ | ||
654 | static u8 pcmcia_used_irq[NR_IRQS]; | ||
655 | |||
720 | static irqreturn_t test_action(int cpl, void *dev_id) | 656 | static irqreturn_t test_action(int cpl, void *dev_id) |
721 | { | 657 | { |
722 | return IRQ_NONE; | 658 | return IRQ_NONE; |
723 | } | 659 | } |
724 | #endif | ||
725 | 660 | ||
726 | int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | 661 | /** |
662 | * pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used | ||
663 | * @p_dev - the associated PCMCIA device | ||
664 | * | ||
665 | * locking note: must be called with ops_mutex locked. | ||
666 | */ | ||
667 | static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) | ||
727 | { | 668 | { |
728 | struct pcmcia_socket *s = p_dev->socket; | 669 | struct pcmcia_socket *s = p_dev->socket; |
729 | config_t *c; | 670 | unsigned int try, irq; |
730 | int ret = -EINVAL, irq = 0; | 671 | u32 mask = s->irq_mask; |
731 | int type; | 672 | int ret = -ENODEV; |
732 | 673 | ||
733 | mutex_lock(&s->ops_mutex); | 674 | for (try = 0; try < 64; try++) { |
675 | irq = try % 32; | ||
734 | 676 | ||
735 | if (!(s->state & SOCKET_PRESENT)) { | 677 | /* marked as available by driver, not blocked by userspace? */ |
736 | dev_dbg(&s->dev, "No card present\n"); | 678 | if (!((mask >> irq) & 1)) |
737 | goto out; | 679 | continue; |
738 | } | 680 | |
739 | c = p_dev->function_config; | 681 | /* avoid an IRQ which is already used by another PCMCIA card */ |
740 | if (c->state & CONFIG_LOCKED) { | 682 | if ((try < 32) && pcmcia_used_irq[irq]) |
741 | dev_dbg(&s->dev, "Configuration is locked\n"); | 683 | continue; |
742 | goto out; | 684 | |
743 | } | 685 | /* register the correct driver, if possible, to check whether |
744 | if (c->state & CONFIG_IRQ_REQ) { | 686 | * registering a dummy handle works, i.e. if the IRQ isn't |
745 | dev_dbg(&s->dev, "IRQ already configured\n"); | 687 | * marked as used by the kernel resource management core */ |
746 | goto out; | 688 | ret = request_irq(irq, test_action, type, p_dev->devname, |
689 | p_dev); | ||
690 | if (!ret) { | ||
691 | free_irq(irq, p_dev); | ||
692 | p_dev->irq = s->pcmcia_irq = irq; | ||
693 | pcmcia_used_irq[irq]++; | ||
694 | break; | ||
695 | } | ||
747 | } | 696 | } |
748 | 697 | ||
749 | /* Decide what type of interrupt we are registering */ | 698 | return ret; |
750 | type = 0; | 699 | } |
751 | if (s->functions > 1) /* All of this ought to be handled higher up */ | ||
752 | type = IRQF_SHARED; | ||
753 | else if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) | ||
754 | type = IRQF_SHARED; | ||
755 | else | ||
756 | printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); | ||
757 | 700 | ||
758 | /* If the interrupt is already assigned, it must be the same */ | 701 | void pcmcia_cleanup_irq(struct pcmcia_socket *s) |
759 | if (s->irq.AssignedIRQ != 0) | 702 | { |
760 | irq = s->irq.AssignedIRQ; | 703 | pcmcia_used_irq[s->pcmcia_irq]--; |
704 | s->pcmcia_irq = 0; | ||
705 | } | ||
761 | 706 | ||
762 | #ifdef CONFIG_PCMCIA_PROBE | 707 | #else /* CONFIG_PCMCIA_PROBE */ |
763 | if (!irq) { | ||
764 | int try; | ||
765 | u32 mask = s->irq_mask; | ||
766 | void *data = p_dev; /* something unique to this device */ | ||
767 | 708 | ||
768 | for (try = 0; try < 64; try++) { | 709 | static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) |
769 | irq = try % 32; | 710 | { |
711 | return -EINVAL; | ||
712 | } | ||
770 | 713 | ||
771 | /* marked as available by driver, and not blocked by userspace? */ | 714 | void pcmcia_cleanup_irq(struct pcmcia_socket *s) |
772 | if (!((mask >> irq) & 1)) | 715 | { |
773 | continue; | 716 | s->pcmcia_irq = 0; |
717 | return; | ||
718 | } | ||
774 | 719 | ||
775 | /* avoid an IRQ which is already used by a PCMCIA card */ | 720 | #endif /* CONFIG_PCMCIA_PROBE */ |
776 | if ((try < 32) && pcmcia_used_irq[irq]) | ||
777 | continue; | ||
778 | 721 | ||
779 | /* register the correct driver, if possible, of check whether | ||
780 | * registering a dummy handle works, i.e. if the IRQ isn't | ||
781 | * marked as used by the kernel resource management core */ | ||
782 | ret = request_irq(irq, | ||
783 | (req->Handler) ? req->Handler : test_action, | ||
784 | type, | ||
785 | p_dev->devname, | ||
786 | (req->Handler) ? p_dev->priv : data); | ||
787 | if (!ret) { | ||
788 | if (!req->Handler) | ||
789 | free_irq(irq, data); | ||
790 | break; | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | #endif | ||
795 | /* only assign PCI irq if no IRQ already assigned */ | ||
796 | if (ret && !s->irq.AssignedIRQ) { | ||
797 | if (!s->pci_irq) { | ||
798 | dev_printk(KERN_INFO, &s->dev, "no IRQ found\n"); | ||
799 | goto out; | ||
800 | } | ||
801 | type = IRQF_SHARED; | ||
802 | irq = s->pci_irq; | ||
803 | } | ||
804 | 722 | ||
805 | if (ret && req->Handler) { | 723 | /** |
806 | ret = request_irq(irq, req->Handler, type, | 724 | * pcmcia_setup_irq() - determine IRQ to be used for device |
807 | p_dev->devname, p_dev->priv); | 725 | * @p_dev - the associated PCMCIA device |
808 | if (ret) { | 726 | * |
809 | dev_printk(KERN_INFO, &s->dev, | 727 | * locking note: must be called with ops_mutex locked. |
810 | "request_irq() failed\n"); | 728 | */ |
811 | goto out; | 729 | int pcmcia_setup_irq(struct pcmcia_device *p_dev) |
812 | } | 730 | { |
813 | } | 731 | struct pcmcia_socket *s = p_dev->socket; |
814 | 732 | ||
815 | /* Make sure the fact the request type was overridden is passed back */ | 733 | if (p_dev->irq) |
816 | if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { | 734 | return 0; |
817 | req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; | 735 | |
818 | dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " | 736 | /* already assigned? */ |
819 | "request for exclusive IRQ could not be fulfilled.\n"); | 737 | if (s->pcmcia_irq) { |
820 | dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " | 738 | p_dev->irq = s->pcmcia_irq; |
821 | "needs updating to supported shared IRQ lines.\n"); | 739 | return 0; |
822 | } | 740 | } |
823 | c->irq.Attributes = req->Attributes; | ||
824 | s->irq.AssignedIRQ = req->AssignedIRQ = irq; | ||
825 | s->irq.Config++; | ||
826 | 741 | ||
827 | c->state |= CONFIG_IRQ_REQ; | 742 | /* prefer an exclusive ISA irq */ |
828 | p_dev->_irq = 1; | 743 | if (!pcmcia_setup_isa_irq(p_dev, 0)) |
744 | return 0; | ||
829 | 745 | ||
830 | #ifdef CONFIG_PCMCIA_PROBE | 746 | /* but accept a shared ISA irq */ |
831 | pcmcia_used_irq[irq]++; | 747 | if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED)) |
832 | #endif | 748 | return 0; |
833 | 749 | ||
834 | ret = 0; | 750 | /* but use the PCI irq otherwise */ |
835 | out: | 751 | if (s->pci_irq) { |
836 | mutex_unlock(&s->ops_mutex); | 752 | p_dev->irq = s->pcmcia_irq = s->pci_irq; |
837 | return ret; | 753 | return 0; |
838 | } /* pcmcia_request_irq */ | 754 | } |
839 | EXPORT_SYMBOL(pcmcia_request_irq); | 755 | |
756 | return -EINVAL; | ||
757 | } | ||
840 | 758 | ||
841 | 759 | ||
842 | /** pcmcia_request_window | 760 | /** pcmcia_request_window |
@@ -939,237 +857,9 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) | |||
939 | { | 857 | { |
940 | pcmcia_release_configuration(p_dev); | 858 | pcmcia_release_configuration(p_dev); |
941 | pcmcia_release_io(p_dev, &p_dev->io); | 859 | pcmcia_release_io(p_dev, &p_dev->io); |
942 | pcmcia_release_irq(p_dev, &p_dev->irq); | 860 | if (p_dev->_irq) |
861 | free_irq(p_dev->irq, p_dev->priv); | ||
943 | if (p_dev->win) | 862 | if (p_dev->win) |
944 | pcmcia_release_window(p_dev, p_dev->win); | 863 | pcmcia_release_window(p_dev, p_dev->win); |
945 | } | 864 | } |
946 | EXPORT_SYMBOL(pcmcia_disable_device); | 865 | EXPORT_SYMBOL(pcmcia_disable_device); |
947 | |||
948 | |||
949 | struct pcmcia_cfg_mem { | ||
950 | struct pcmcia_device *p_dev; | ||
951 | void *priv_data; | ||
952 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
953 | cistpl_cftable_entry_t *cfg, | ||
954 | cistpl_cftable_entry_t *dflt, | ||
955 | unsigned int vcc, | ||
956 | void *priv_data); | ||
957 | cisparse_t parse; | ||
958 | cistpl_cftable_entry_t dflt; | ||
959 | }; | ||
960 | |||
961 | /** | ||
962 | * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() | ||
963 | * | ||
964 | * pcmcia_do_loop_config() is the internal callback for the call from | ||
965 | * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred | ||
966 | * by a struct pcmcia_cfg_mem. | ||
967 | */ | ||
968 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
969 | { | ||
970 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
971 | struct pcmcia_cfg_mem *cfg_mem = priv; | ||
972 | |||
973 | /* default values */ | ||
974 | cfg_mem->p_dev->conf.ConfigIndex = cfg->index; | ||
975 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
976 | cfg_mem->dflt = *cfg; | ||
977 | |||
978 | return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, | ||
979 | cfg_mem->p_dev->socket->socket.Vcc, | ||
980 | cfg_mem->priv_data); | ||
981 | } | ||
982 | |||
983 | /** | ||
984 | * pcmcia_loop_config() - loop over configuration options | ||
985 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
986 | * @conf_check: function to call for each configuration option. | ||
987 | * It gets passed the struct pcmcia_device, the CIS data | ||
988 | * describing the configuration option, and private data | ||
989 | * being passed to pcmcia_loop_config() | ||
990 | * @priv_data: private data to be passed to the conf_check function. | ||
991 | * | ||
992 | * pcmcia_loop_config() loops over all configuration options, and calls | ||
993 | * the driver-specific conf_check() for each one, checking whether | ||
994 | * it is a valid one. Returns 0 on success or errorcode otherwise. | ||
995 | */ | ||
996 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | ||
997 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
998 | cistpl_cftable_entry_t *cfg, | ||
999 | cistpl_cftable_entry_t *dflt, | ||
1000 | unsigned int vcc, | ||
1001 | void *priv_data), | ||
1002 | void *priv_data) | ||
1003 | { | ||
1004 | struct pcmcia_cfg_mem *cfg_mem; | ||
1005 | int ret; | ||
1006 | |||
1007 | cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); | ||
1008 | if (cfg_mem == NULL) | ||
1009 | return -ENOMEM; | ||
1010 | |||
1011 | cfg_mem->p_dev = p_dev; | ||
1012 | cfg_mem->conf_check = conf_check; | ||
1013 | cfg_mem->priv_data = priv_data; | ||
1014 | |||
1015 | ret = pccard_loop_tuple(p_dev->socket, p_dev->func, | ||
1016 | CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, | ||
1017 | cfg_mem, pcmcia_do_loop_config); | ||
1018 | |||
1019 | kfree(cfg_mem); | ||
1020 | return ret; | ||
1021 | } | ||
1022 | EXPORT_SYMBOL(pcmcia_loop_config); | ||
1023 | |||
1024 | |||
1025 | struct pcmcia_loop_mem { | ||
1026 | struct pcmcia_device *p_dev; | ||
1027 | void *priv_data; | ||
1028 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
1029 | tuple_t *tuple, | ||
1030 | void *priv_data); | ||
1031 | }; | ||
1032 | |||
1033 | /** | ||
1034 | * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() | ||
1035 | * | ||
1036 | * pcmcia_do_loop_tuple() is the internal callback for the call from | ||
1037 | * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred | ||
1038 | * by a struct pcmcia_cfg_mem. | ||
1039 | */ | ||
1040 | static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
1041 | { | ||
1042 | struct pcmcia_loop_mem *loop = priv; | ||
1043 | |||
1044 | return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); | ||
1045 | }; | ||
1046 | |||
1047 | /** | ||
1048 | * pcmcia_loop_tuple() - loop over tuples in the CIS | ||
1049 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
1050 | * @code: which CIS code shall we look for? | ||
1051 | * @priv_data: private data to be passed to the loop_tuple function. | ||
1052 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
1053 | * gets passed the raw tuple and @priv_data. | ||
1054 | * | ||
1055 | * pcmcia_loop_tuple() loops over all CIS entries of type @function, and | ||
1056 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
1057 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
1058 | */ | ||
1059 | int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
1060 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
1061 | tuple_t *tuple, | ||
1062 | void *priv_data), | ||
1063 | void *priv_data) | ||
1064 | { | ||
1065 | struct pcmcia_loop_mem loop = { | ||
1066 | .p_dev = p_dev, | ||
1067 | .loop_tuple = loop_tuple, | ||
1068 | .priv_data = priv_data}; | ||
1069 | |||
1070 | return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, | ||
1071 | &loop, pcmcia_do_loop_tuple); | ||
1072 | } | ||
1073 | EXPORT_SYMBOL(pcmcia_loop_tuple); | ||
1074 | |||
1075 | |||
1076 | struct pcmcia_loop_get { | ||
1077 | size_t len; | ||
1078 | cisdata_t **buf; | ||
1079 | }; | ||
1080 | |||
1081 | /** | ||
1082 | * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() | ||
1083 | * | ||
1084 | * pcmcia_do_get_tuple() is the internal callback for the call from | ||
1085 | * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in | ||
1086 | * the first tuple, return 0 unconditionally. Create a memory buffer large | ||
1087 | * enough to hold the content of the tuple, and fill it with the tuple data. | ||
1088 | * The caller is responsible to free the buffer. | ||
1089 | */ | ||
1090 | static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
1091 | void *priv) | ||
1092 | { | ||
1093 | struct pcmcia_loop_get *get = priv; | ||
1094 | |||
1095 | *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); | ||
1096 | if (*get->buf) { | ||
1097 | get->len = tuple->TupleDataLen; | ||
1098 | memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); | ||
1099 | } else | ||
1100 | dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); | ||
1101 | return 0; | ||
1102 | } | ||
1103 | |||
1104 | /** | ||
1105 | * pcmcia_get_tuple() - get first tuple from CIS | ||
1106 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
1107 | * @code: which CIS code shall we look for? | ||
1108 | * @buf: pointer to store the buffer to. | ||
1109 | * | ||
1110 | * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. | ||
1111 | * It returns the buffer length (or zero). The caller is responsible to free | ||
1112 | * the buffer passed in @buf. | ||
1113 | */ | ||
1114 | size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
1115 | unsigned char **buf) | ||
1116 | { | ||
1117 | struct pcmcia_loop_get get = { | ||
1118 | .len = 0, | ||
1119 | .buf = buf, | ||
1120 | }; | ||
1121 | |||
1122 | *get.buf = NULL; | ||
1123 | pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); | ||
1124 | |||
1125 | return get.len; | ||
1126 | } | ||
1127 | EXPORT_SYMBOL(pcmcia_get_tuple); | ||
1128 | |||
1129 | |||
1130 | /** | ||
1131 | * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() | ||
1132 | * | ||
1133 | * pcmcia_do_get_mac() is the internal callback for the call from | ||
1134 | * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the | ||
1135 | * tuple contains a proper LAN_NODE_ID of length 6, and copy the data | ||
1136 | * to struct net_device->dev_addr[i]. | ||
1137 | */ | ||
1138 | static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
1139 | void *priv) | ||
1140 | { | ||
1141 | struct net_device *dev = priv; | ||
1142 | int i; | ||
1143 | |||
1144 | if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) | ||
1145 | return -EINVAL; | ||
1146 | if (tuple->TupleDataLen < ETH_ALEN + 2) { | ||
1147 | dev_warn(&p_dev->dev, "Invalid CIS tuple length for " | ||
1148 | "LAN_NODE_ID\n"); | ||
1149 | return -EINVAL; | ||
1150 | } | ||
1151 | |||
1152 | if (tuple->TupleData[1] != ETH_ALEN) { | ||
1153 | dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); | ||
1154 | return -EINVAL; | ||
1155 | } | ||
1156 | for (i = 0; i < 6; i++) | ||
1157 | dev->dev_addr[i] = tuple->TupleData[i+2]; | ||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | /** | ||
1162 | * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE | ||
1163 | * @p_dev: the struct pcmcia_device for which we want the address. | ||
1164 | * @dev: a properly prepared struct net_device to store the info to. | ||
1165 | * | ||
1166 | * pcmcia_get_mac_from_cis() reads out the hardware MAC address from | ||
1167 | * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which | ||
1168 | * must be set up properly by the driver (see examples!). | ||
1169 | */ | ||
1170 | int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) | ||
1171 | { | ||
1172 | return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); | ||
1173 | } | ||
1174 | EXPORT_SYMBOL(pcmcia_get_mac_from_cis); | ||
1175 | |||
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c new file mode 100644 index 000000000000..d0bf35021065 --- /dev/null +++ b/drivers/pcmcia/rsrc_iodyn.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * rsrc_iodyn.c -- Resource management routines for MEM-static sockets. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * The initial developer of the original code is David A. Hinds | ||
9 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
10 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
11 | * | ||
12 | * (C) 1999 David A. Hinds | ||
13 | */ | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | |||
19 | #include <pcmcia/cs_types.h> | ||
20 | #include <pcmcia/ss.h> | ||
21 | #include <pcmcia/cs.h> | ||
22 | #include <pcmcia/cistpl.h> | ||
23 | #include "cs_internal.h" | ||
24 | |||
25 | |||
26 | struct pcmcia_align_data { | ||
27 | unsigned long mask; | ||
28 | unsigned long offset; | ||
29 | }; | ||
30 | |||
31 | static resource_size_t pcmcia_align(void *align_data, | ||
32 | const struct resource *res, | ||
33 | resource_size_t size, resource_size_t align) | ||
34 | { | ||
35 | struct pcmcia_align_data *data = align_data; | ||
36 | resource_size_t start; | ||
37 | |||
38 | start = (res->start & ~data->mask) + data->offset; | ||
39 | if (start < res->start) | ||
40 | start += data->mask + 1; | ||
41 | |||
42 | #ifdef CONFIG_X86 | ||
43 | if (res->flags & IORESOURCE_IO) { | ||
44 | if (start & 0x300) | ||
45 | start = (start + 0x3ff) & ~0x3ff; | ||
46 | } | ||
47 | #endif | ||
48 | |||
49 | #ifdef CONFIG_M68K | ||
50 | if (res->flags & IORESOURCE_IO) { | ||
51 | if ((res->start + size - 1) >= 1024) | ||
52 | start = res->end; | ||
53 | } | ||
54 | #endif | ||
55 | |||
56 | return start; | ||
57 | } | ||
58 | |||
59 | |||
60 | static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s, | ||
61 | unsigned long base, int num, | ||
62 | unsigned long align) | ||
63 | { | ||
64 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, | ||
65 | dev_name(&s->dev)); | ||
66 | struct pcmcia_align_data data; | ||
67 | unsigned long min = base; | ||
68 | int ret; | ||
69 | |||
70 | data.mask = align - 1; | ||
71 | data.offset = base & data.mask; | ||
72 | |||
73 | #ifdef CONFIG_PCI | ||
74 | if (s->cb_dev) { | ||
75 | ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | ||
76 | min, 0, pcmcia_align, &data); | ||
77 | } else | ||
78 | #endif | ||
79 | ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, | ||
80 | 1, pcmcia_align, &data); | ||
81 | |||
82 | if (ret != 0) { | ||
83 | kfree(res); | ||
84 | res = NULL; | ||
85 | } | ||
86 | return res; | ||
87 | } | ||
88 | |||
89 | static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, | ||
90 | unsigned int *base, unsigned int num, | ||
91 | unsigned int align) | ||
92 | { | ||
93 | int i, ret = 0; | ||
94 | |||
95 | /* Check for an already-allocated window that must conflict with | ||
96 | * what was asked for. It is a hack because it does not catch all | ||
97 | * potential conflicts, just the most obvious ones. | ||
98 | */ | ||
99 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
100 | if (!s->io[i].res) | ||
101 | continue; | ||
102 | |||
103 | if (!*base) | ||
104 | continue; | ||
105 | |||
106 | if ((s->io[i].res->start & (align-1)) == *base) | ||
107 | return -EBUSY; | ||
108 | } | ||
109 | |||
110 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
111 | struct resource *res = s->io[i].res; | ||
112 | unsigned int try; | ||
113 | |||
114 | if (res && (res->flags & IORESOURCE_BITS) != | ||
115 | (attr & IORESOURCE_BITS)) | ||
116 | continue; | ||
117 | |||
118 | if (!res) { | ||
119 | if (align == 0) | ||
120 | align = 0x10000; | ||
121 | |||
122 | res = s->io[i].res = __iodyn_find_io_region(s, *base, | ||
123 | num, align); | ||
124 | if (!res) | ||
125 | return -EINVAL; | ||
126 | |||
127 | *base = res->start; | ||
128 | s->io[i].res->flags = | ||
129 | ((res->flags & ~IORESOURCE_BITS) | | ||
130 | (attr & IORESOURCE_BITS)); | ||
131 | s->io[i].InUse = num; | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* Try to extend top of window */ | ||
136 | try = res->end + 1; | ||
137 | if ((*base == 0) || (*base == try)) { | ||
138 | if (adjust_resource(s->io[i].res, res->start, | ||
139 | res->end - res->start + num + 1)) | ||
140 | continue; | ||
141 | *base = try; | ||
142 | s->io[i].InUse += num; | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /* Try to extend bottom of window */ | ||
147 | try = res->start - num; | ||
148 | if ((*base == 0) || (*base == try)) { | ||
149 | if (adjust_resource(s->io[i].res, | ||
150 | res->start - num, | ||
151 | res->end - res->start + num + 1)) | ||
152 | continue; | ||
153 | *base = try; | ||
154 | s->io[i].InUse += num; | ||
155 | return 0; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | return -EINVAL; | ||
160 | } | ||
161 | |||
162 | |||
163 | struct pccard_resource_ops pccard_iodyn_ops = { | ||
164 | .validate_mem = NULL, | ||
165 | .find_io = iodyn_find_io, | ||
166 | .find_mem = NULL, | ||
167 | .add_io = NULL, | ||
168 | .add_mem = NULL, | ||
169 | .init = static_init, | ||
170 | .exit = NULL, | ||
171 | }; | ||
172 | EXPORT_SYMBOL(pccard_iodyn_ops); | ||
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ffa5f3cae57b..142efac3c387 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <pcmcia/cistpl.h> | 22 | #include <pcmcia/cistpl.h> |
23 | #include "cs_internal.h" | 23 | #include "cs_internal.h" |
24 | 24 | ||
25 | static int static_init(struct pcmcia_socket *s) | 25 | int static_init(struct pcmcia_socket *s) |
26 | { | 26 | { |
27 | /* the good thing about SS_CAP_STATIC_MAP sockets is | 27 | /* the good thing about SS_CAP_STATIC_MAP sockets is |
28 | * that they don't need a resource database */ | 28 | * that they don't need a resource database */ |
@@ -32,118 +32,44 @@ static int static_init(struct pcmcia_socket *s) | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | 35 | struct resource *pcmcia_make_resource(unsigned long start, unsigned long end, | |
36 | struct pccard_resource_ops pccard_static_ops = { | 36 | int flags, const char *name) |
37 | .validate_mem = NULL, | ||
38 | .adjust_io_region = NULL, | ||
39 | .find_io = NULL, | ||
40 | .find_mem = NULL, | ||
41 | .add_io = NULL, | ||
42 | .add_mem = NULL, | ||
43 | .init = static_init, | ||
44 | .exit = NULL, | ||
45 | }; | ||
46 | EXPORT_SYMBOL(pccard_static_ops); | ||
47 | |||
48 | |||
49 | #ifdef CONFIG_PCCARD_IODYN | ||
50 | |||
51 | static struct resource * | ||
52 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | ||
53 | { | 37 | { |
54 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 38 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
55 | 39 | ||
56 | if (res) { | 40 | if (res) { |
57 | res->name = name; | 41 | res->name = name; |
58 | res->start = b; | 42 | res->start = start; |
59 | res->end = b + n - 1; | 43 | res->end = start + end - 1; |
60 | res->flags = flags; | 44 | res->flags = flags; |
61 | } | 45 | } |
62 | return res; | 46 | return res; |
63 | } | 47 | } |
64 | 48 | ||
65 | struct pcmcia_align_data { | 49 | static int static_find_io(struct pcmcia_socket *s, unsigned int attr, |
66 | unsigned long mask; | 50 | unsigned int *base, unsigned int num, |
67 | unsigned long offset; | 51 | unsigned int align) |
68 | }; | ||
69 | |||
70 | static resource_size_t pcmcia_align(void *align_data, | ||
71 | const struct resource *res, | ||
72 | resource_size_t size, resource_size_t align) | ||
73 | { | 52 | { |
74 | struct pcmcia_align_data *data = align_data; | 53 | if (!s->io_offset) |
75 | resource_size_t start; | 54 | return -EINVAL; |
55 | *base = s->io_offset | (*base & 0x0fff); | ||
76 | 56 | ||
77 | start = (res->start & ~data->mask) + data->offset; | 57 | return 0; |
78 | if (start < res->start) | ||
79 | start += data->mask + 1; | ||
80 | |||
81 | #ifdef CONFIG_X86 | ||
82 | if (res->flags & IORESOURCE_IO) { | ||
83 | if (start & 0x300) | ||
84 | start = (start + 0x3ff) & ~0x3ff; | ||
85 | } | ||
86 | #endif | ||
87 | |||
88 | #ifdef CONFIG_M68K | ||
89 | if (res->flags & IORESOURCE_IO) { | ||
90 | if ((res->start + size - 1) >= 1024) | ||
91 | start = res->end; | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | return start; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, | ||
100 | unsigned long r_end, struct pcmcia_socket *s) | ||
101 | { | ||
102 | return adjust_resource(res, r_start, r_end - r_start + 1); | ||
103 | } | 58 | } |
104 | 59 | ||
105 | 60 | ||
106 | static struct resource *iodyn_find_io_region(unsigned long base, int num, | 61 | struct pccard_resource_ops pccard_static_ops = { |
107 | unsigned long align, struct pcmcia_socket *s) | ||
108 | { | ||
109 | struct resource *res = make_resource(0, num, IORESOURCE_IO, | ||
110 | dev_name(&s->dev)); | ||
111 | struct pcmcia_align_data data; | ||
112 | unsigned long min = base; | ||
113 | int ret; | ||
114 | |||
115 | if (align == 0) | ||
116 | align = 0x10000; | ||
117 | |||
118 | data.mask = align - 1; | ||
119 | data.offset = base & data.mask; | ||
120 | |||
121 | #ifdef CONFIG_PCI | ||
122 | if (s->cb_dev) { | ||
123 | ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | ||
124 | min, 0, pcmcia_align, &data); | ||
125 | } else | ||
126 | #endif | ||
127 | ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, | ||
128 | 1, pcmcia_align, &data); | ||
129 | |||
130 | if (ret != 0) { | ||
131 | kfree(res); | ||
132 | res = NULL; | ||
133 | } | ||
134 | return res; | ||
135 | } | ||
136 | |||
137 | struct pccard_resource_ops pccard_iodyn_ops = { | ||
138 | .validate_mem = NULL, | 62 | .validate_mem = NULL, |
139 | .adjust_io_region = iodyn_adjust_io_region, | 63 | .find_io = static_find_io, |
140 | .find_io = iodyn_find_io_region, | ||
141 | .find_mem = NULL, | 64 | .find_mem = NULL, |
142 | .add_io = NULL, | 65 | .add_io = NULL, |
143 | .add_mem = NULL, | 66 | .add_mem = NULL, |
144 | .init = static_init, | 67 | .init = static_init, |
145 | .exit = NULL, | 68 | .exit = NULL, |
146 | }; | 69 | }; |
147 | EXPORT_SYMBOL(pccard_iodyn_ops); | 70 | EXPORT_SYMBOL(pccard_static_ops); |
71 | |||
148 | 72 | ||
149 | #endif /* CONFIG_PCCARD_IODYN */ | 73 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); |
74 | MODULE_LICENSE("GPL"); | ||
75 | MODULE_ALIAS("rsrc_nonstatic"); | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index a6eb7b59ba9f..dcd1a4ad3d63 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -34,8 +34,10 @@ | |||
34 | #include <pcmcia/cistpl.h> | 34 | #include <pcmcia/cistpl.h> |
35 | #include "cs_internal.h" | 35 | #include "cs_internal.h" |
36 | 36 | ||
37 | /* moved to rsrc_mgr.c | ||
37 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); | 38 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); |
38 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | */ | ||
39 | 41 | ||
40 | /* Parameters that can be set with 'insmod' */ | 42 | /* Parameters that can be set with 'insmod' */ |
41 | 43 | ||
@@ -70,27 +72,13 @@ struct socket_data { | |||
70 | ======================================================================*/ | 72 | ======================================================================*/ |
71 | 73 | ||
72 | static struct resource * | 74 | static struct resource * |
73 | make_resource(resource_size_t b, resource_size_t n, int flags, const char *name) | ||
74 | { | ||
75 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
76 | |||
77 | if (res) { | ||
78 | res->name = name; | ||
79 | res->start = b; | ||
80 | res->end = b + n - 1; | ||
81 | res->flags = flags; | ||
82 | } | ||
83 | return res; | ||
84 | } | ||
85 | |||
86 | static struct resource * | ||
87 | claim_region(struct pcmcia_socket *s, resource_size_t base, | 75 | claim_region(struct pcmcia_socket *s, resource_size_t base, |
88 | resource_size_t size, int type, char *name) | 76 | resource_size_t size, int type, char *name) |
89 | { | 77 | { |
90 | struct resource *res, *parent; | 78 | struct resource *res, *parent; |
91 | 79 | ||
92 | parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; | 80 | parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; |
93 | res = make_resource(base, size, type | IORESOURCE_BUSY, name); | 81 | res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name); |
94 | 82 | ||
95 | if (res) { | 83 | if (res) { |
96 | #ifdef CONFIG_PCI | 84 | #ifdef CONFIG_PCI |
@@ -661,8 +649,9 @@ pcmcia_align(void *align_data, const struct resource *res, | |||
661 | * Adjust an existing IO region allocation, but making sure that we don't | 649 | * Adjust an existing IO region allocation, but making sure that we don't |
662 | * encroach outside the resources which the user supplied. | 650 | * encroach outside the resources which the user supplied. |
663 | */ | 651 | */ |
664 | static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start, | 652 | static int __nonstatic_adjust_io_region(struct pcmcia_socket *s, |
665 | unsigned long r_end, struct pcmcia_socket *s) | 653 | unsigned long r_start, |
654 | unsigned long r_end) | ||
666 | { | 655 | { |
667 | struct resource_map *m; | 656 | struct resource_map *m; |
668 | struct socket_data *s_data = s->resource_data; | 657 | 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 | |||
675 | if (start > r_start || r_end > end) | 664 | if (start > r_start || r_end > end) |
676 | continue; | 665 | continue; |
677 | 666 | ||
678 | ret = adjust_resource(res, r_start, r_end - r_start + 1); | 667 | ret = 0; |
679 | break; | ||
680 | } | 668 | } |
681 | 669 | ||
682 | return ret; | 670 | return ret; |
@@ -695,18 +683,17 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star | |||
695 | 683 | ||
696 | ======================================================================*/ | 684 | ======================================================================*/ |
697 | 685 | ||
698 | static struct resource *nonstatic_find_io_region(unsigned long base, int num, | 686 | static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s, |
699 | unsigned long align, struct pcmcia_socket *s) | 687 | unsigned long base, int num, |
688 | unsigned long align) | ||
700 | { | 689 | { |
701 | struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); | 690 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, |
691 | dev_name(&s->dev)); | ||
702 | struct socket_data *s_data = s->resource_data; | 692 | struct socket_data *s_data = s->resource_data; |
703 | struct pcmcia_align_data data; | 693 | struct pcmcia_align_data data; |
704 | unsigned long min = base; | 694 | unsigned long min = base; |
705 | int ret; | 695 | int ret; |
706 | 696 | ||
707 | if (align == 0) | ||
708 | align = 0x10000; | ||
709 | |||
710 | data.mask = align - 1; | 697 | data.mask = align - 1; |
711 | data.offset = base & data.mask; | 698 | data.offset = base & data.mask; |
712 | data.map = &s_data->io_db; | 699 | data.map = &s_data->io_db; |
@@ -727,10 +714,97 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, | |||
727 | return res; | 714 | return res; |
728 | } | 715 | } |
729 | 716 | ||
717 | static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, | ||
718 | unsigned int *base, unsigned int num, | ||
719 | unsigned int align) | ||
720 | { | ||
721 | int i, ret = 0; | ||
722 | |||
723 | /* Check for an already-allocated window that must conflict with | ||
724 | * what was asked for. It is a hack because it does not catch all | ||
725 | * potential conflicts, just the most obvious ones. | ||
726 | */ | ||
727 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
728 | if (!s->io[i].res) | ||
729 | continue; | ||
730 | |||
731 | if (!*base) | ||
732 | continue; | ||
733 | |||
734 | if ((s->io[i].res->start & (align-1)) == *base) | ||
735 | return -EBUSY; | ||
736 | } | ||
737 | |||
738 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
739 | struct resource *res = s->io[i].res; | ||
740 | unsigned int try; | ||
741 | |||
742 | if (res && (res->flags & IORESOURCE_BITS) != | ||
743 | (attr & IORESOURCE_BITS)) | ||
744 | continue; | ||
745 | |||
746 | if (!res) { | ||
747 | if (align == 0) | ||
748 | align = 0x10000; | ||
749 | |||
750 | res = s->io[i].res = __nonstatic_find_io_region(s, | ||
751 | *base, num, | ||
752 | align); | ||
753 | if (!res) | ||
754 | return -EINVAL; | ||
755 | |||
756 | *base = res->start; | ||
757 | s->io[i].res->flags = | ||
758 | ((res->flags & ~IORESOURCE_BITS) | | ||
759 | (attr & IORESOURCE_BITS)); | ||
760 | s->io[i].InUse = num; | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | /* Try to extend top of window */ | ||
765 | try = res->end + 1; | ||
766 | if ((*base == 0) || (*base == try)) { | ||
767 | ret = __nonstatic_adjust_io_region(s, res->start, | ||
768 | res->end + num); | ||
769 | if (!ret) { | ||
770 | ret = adjust_resource(s->io[i].res, res->start, | ||
771 | res->end - res->start + num + 1); | ||
772 | if (ret) | ||
773 | continue; | ||
774 | *base = try; | ||
775 | s->io[i].InUse += num; | ||
776 | return 0; | ||
777 | } | ||
778 | } | ||
779 | |||
780 | /* Try to extend bottom of window */ | ||
781 | try = res->start - num; | ||
782 | if ((*base == 0) || (*base == try)) { | ||
783 | ret = __nonstatic_adjust_io_region(s, | ||
784 | res->start - num, | ||
785 | res->end); | ||
786 | if (!ret) { | ||
787 | ret = adjust_resource(s->io[i].res, | ||
788 | res->start - num, | ||
789 | res->end - res->start + num + 1); | ||
790 | if (ret) | ||
791 | continue; | ||
792 | *base = try; | ||
793 | s->io[i].InUse += num; | ||
794 | return 0; | ||
795 | } | ||
796 | } | ||
797 | } | ||
798 | |||
799 | return -EINVAL; | ||
800 | } | ||
801 | |||
802 | |||
730 | static struct resource *nonstatic_find_mem_region(u_long base, u_long num, | 803 | static struct resource *nonstatic_find_mem_region(u_long base, u_long num, |
731 | u_long align, int low, struct pcmcia_socket *s) | 804 | u_long align, int low, struct pcmcia_socket *s) |
732 | { | 805 | { |
733 | struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); | 806 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM, |
807 | dev_name(&s->dev)); | ||
734 | struct socket_data *s_data = s->resource_data; | 808 | struct socket_data *s_data = s->resource_data; |
735 | struct pcmcia_align_data data; | 809 | struct pcmcia_align_data data; |
736 | unsigned long min, max; | 810 | unsigned long min, max; |
@@ -861,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
861 | return -ENODEV; | 935 | return -ENODEV; |
862 | 936 | ||
863 | #if defined(CONFIG_X86) | 937 | #if defined(CONFIG_X86) |
864 | /* If this is the root bus, the risk of hitting | 938 | /* If this is the root bus, the risk of hitting some strange |
865 | * some strange system devices which aren't protected | 939 | * system devices is too high: If a driver isn't loaded, the |
866 | * by either ACPI resource tables or properly requested | 940 | * resources are not claimed; even if a driver is loaded, it |
867 | * resources is too big. Therefore, don't do auto-adding | 941 | * may not request all resources or even the wrong one. We |
868 | * of resources at the moment. | 942 | * can neither trust the rest of the kernel nor ACPI/PNP and |
943 | * CRS parsing to get it right. Therefore, use several | ||
944 | * safeguards: | ||
945 | * | ||
946 | * - Do not auto-add resources if the CardBus bridge is on | ||
947 | * the PCI root bus | ||
948 | * | ||
949 | * - Avoid any I/O ports < 0x100. | ||
950 | * | ||
951 | * - On PCI-PCI bridges, only use resources which are set up | ||
952 | * exclusively for the secondary PCI bus: the risk of hitting | ||
953 | * system devices is quite low, as they usually aren't | ||
954 | * connected to the secondary PCI bus. | ||
869 | */ | 955 | */ |
870 | if (s->cb_dev->bus->number == 0) | 956 | if (s->cb_dev->bus->number == 0) |
871 | return -EINVAL; | 957 | return -EINVAL; |
872 | #endif | ||
873 | 958 | ||
959 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { | ||
960 | res = s->cb_dev->bus->resource[i]; | ||
961 | #else | ||
874 | pci_bus_for_each_resource(s->cb_dev->bus, res, i) { | 962 | pci_bus_for_each_resource(s->cb_dev->bus, res, i) { |
963 | #endif | ||
875 | if (!res) | 964 | if (!res) |
876 | continue; | 965 | continue; |
877 | 966 | ||
878 | if (res->flags & IORESOURCE_IO) { | 967 | if (res->flags & IORESOURCE_IO) { |
968 | /* safeguard against the root resource, where the | ||
969 | * risk of hitting any other device would be too | ||
970 | * high */ | ||
879 | if (res == &ioport_resource) | 971 | if (res == &ioport_resource) |
880 | continue; | 972 | continue; |
973 | |||
881 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 974 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
882 | "pcmcia: parent PCI bridge window: %pR\n", | 975 | "pcmcia: parent PCI bridge window: %pR\n", |
883 | res); | 976 | res); |
@@ -887,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
887 | } | 980 | } |
888 | 981 | ||
889 | if (res->flags & IORESOURCE_MEM) { | 982 | if (res->flags & IORESOURCE_MEM) { |
983 | /* safeguard against the root resource, where the | ||
984 | * risk of hitting any other device would be too | ||
985 | * high */ | ||
890 | if (res == &iomem_resource) | 986 | if (res == &iomem_resource) |
891 | continue; | 987 | continue; |
988 | |||
892 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 989 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
893 | "pcmcia: parent PCI bridge window: %pR\n", | 990 | "pcmcia: parent PCI bridge window: %pR\n", |
894 | res); | 991 | res); |
@@ -956,8 +1053,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) | |||
956 | 1053 | ||
957 | struct pccard_resource_ops pccard_nonstatic_ops = { | 1054 | struct pccard_resource_ops pccard_nonstatic_ops = { |
958 | .validate_mem = pcmcia_nonstatic_validate_mem, | 1055 | .validate_mem = pcmcia_nonstatic_validate_mem, |
959 | .adjust_io_region = nonstatic_adjust_io_region, | 1056 | .find_io = nonstatic_find_io, |
960 | .find_io = nonstatic_find_io_region, | ||
961 | .find_mem = nonstatic_find_mem_region, | 1057 | .find_mem = nonstatic_find_mem_region, |
962 | .add_io = adjust_io, | 1058 | .add_io = adjust_io, |
963 | .add_mem = adjust_memory, | 1059 | .add_mem = adjust_memory, |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 83ace277426c..424e576f3acb 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -1303,13 +1303,6 @@ static int yenta_dev_suspend_noirq(struct device *dev) | |||
1303 | pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); | 1303 | pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); |
1304 | pci_disable_device(pdev); | 1304 | pci_disable_device(pdev); |
1305 | 1305 | ||
1306 | /* | ||
1307 | * Some laptops (IBM T22) do not like us putting the Cardbus | ||
1308 | * bridge into D3. At a guess, some other laptop will | ||
1309 | * probably require this, so leave it commented out for now. | ||
1310 | */ | ||
1311 | /* pci_set_power_state(dev, 3); */ | ||
1312 | |||
1313 | return 0; | 1306 | return 0; |
1314 | } | 1307 | } |
1315 | 1308 | ||
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 528733b4a392..9d70aef99227 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c | |||
@@ -80,7 +80,6 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
80 | 80 | ||
81 | typedef struct scsi_info_t { | 81 | typedef struct scsi_info_t { |
82 | struct pcmcia_device *p_dev; | 82 | struct pcmcia_device *p_dev; |
83 | dev_node_t node; | ||
84 | struct Scsi_Host *host; | 83 | struct Scsi_Host *host; |
85 | } scsi_info_t; | 84 | } scsi_info_t; |
86 | 85 | ||
@@ -105,7 +104,6 @@ static int aha152x_probe(struct pcmcia_device *link) | |||
105 | link->io.NumPorts1 = 0x20; | 104 | link->io.NumPorts1 = 0x20; |
106 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 105 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
107 | link->io.IOAddrLines = 10; | 106 | link->io.IOAddrLines = 10; |
108 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
109 | link->conf.Attributes = CONF_ENABLE_IRQ; | 107 | link->conf.Attributes = CONF_ENABLE_IRQ; |
110 | link->conf.IntType = INT_MEMORY_AND_IO; | 108 | link->conf.IntType = INT_MEMORY_AND_IO; |
111 | link->conf.Present = PRESENT_OPTION; | 109 | link->conf.Present = PRESENT_OPTION; |
@@ -160,8 +158,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) | |||
160 | if (ret) | 158 | if (ret) |
161 | goto failed; | 159 | goto failed; |
162 | 160 | ||
163 | ret = pcmcia_request_irq(link, &link->irq); | 161 | if (!link->irq) |
164 | if (ret) | ||
165 | goto failed; | 162 | goto failed; |
166 | 163 | ||
167 | ret = pcmcia_request_configuration(link, &link->conf); | 164 | ret = pcmcia_request_configuration(link, &link->conf); |
@@ -172,7 +169,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) | |||
172 | memset(&s, 0, sizeof(s)); | 169 | memset(&s, 0, sizeof(s)); |
173 | s.conf = "PCMCIA setup"; | 170 | s.conf = "PCMCIA setup"; |
174 | s.io_port = link->io.BasePort1; | 171 | s.io_port = link->io.BasePort1; |
175 | s.irq = link->irq.AssignedIRQ; | 172 | s.irq = link->irq; |
176 | s.scsiid = host_id; | 173 | s.scsiid = host_id; |
177 | s.reconnect = reconnect; | 174 | s.reconnect = reconnect; |
178 | s.parity = parity; | 175 | s.parity = parity; |
@@ -187,8 +184,6 @@ static int aha152x_config_cs(struct pcmcia_device *link) | |||
187 | goto failed; | 184 | goto failed; |
188 | } | 185 | } |
189 | 186 | ||
190 | sprintf(info->node.dev_name, "scsi%d", host->host_no); | ||
191 | link->dev_node = &info->node; | ||
192 | info->host = host; | 187 | info->host = host; |
193 | 188 | ||
194 | return 0; | 189 | return 0; |
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 914040684079..21b141151dfc 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c | |||
@@ -63,7 +63,6 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
63 | 63 | ||
64 | typedef struct scsi_info_t { | 64 | typedef struct scsi_info_t { |
65 | struct pcmcia_device *p_dev; | 65 | struct pcmcia_device *p_dev; |
66 | dev_node_t node; | ||
67 | struct Scsi_Host *host; | 66 | struct Scsi_Host *host; |
68 | } scsi_info_t; | 67 | } scsi_info_t; |
69 | 68 | ||
@@ -88,7 +87,6 @@ static int fdomain_probe(struct pcmcia_device *link) | |||
88 | link->io.NumPorts1 = 0x10; | 87 | link->io.NumPorts1 = 0x10; |
89 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 88 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
90 | link->io.IOAddrLines = 10; | 89 | link->io.IOAddrLines = 10; |
91 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
92 | link->conf.Attributes = CONF_ENABLE_IRQ; | 90 | link->conf.Attributes = CONF_ENABLE_IRQ; |
93 | link->conf.IntType = INT_MEMORY_AND_IO; | 91 | link->conf.IntType = INT_MEMORY_AND_IO; |
94 | link->conf.Present = PRESENT_OPTION; | 92 | link->conf.Present = PRESENT_OPTION; |
@@ -133,8 +131,7 @@ static int fdomain_config(struct pcmcia_device *link) | |||
133 | if (ret) | 131 | if (ret) |
134 | goto failed; | 132 | goto failed; |
135 | 133 | ||
136 | ret = pcmcia_request_irq(link, &link->irq); | 134 | if (!link->irq) |
137 | if (ret) | ||
138 | goto failed; | 135 | goto failed; |
139 | ret = pcmcia_request_configuration(link, &link->conf); | 136 | ret = pcmcia_request_configuration(link, &link->conf); |
140 | if (ret) | 137 | if (ret) |
@@ -144,7 +141,7 @@ static int fdomain_config(struct pcmcia_device *link) | |||
144 | release_region(link->io.BasePort1, link->io.NumPorts1); | 141 | release_region(link->io.BasePort1, link->io.NumPorts1); |
145 | 142 | ||
146 | /* Set configuration options for the fdomain driver */ | 143 | /* Set configuration options for the fdomain driver */ |
147 | sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); | 144 | sprintf(str, "%d,%d", link->io.BasePort1, link->irq); |
148 | fdomain_setup(str); | 145 | fdomain_setup(str); |
149 | 146 | ||
150 | host = __fdomain_16x0_detect(&fdomain_driver_template); | 147 | host = __fdomain_16x0_detect(&fdomain_driver_template); |
@@ -157,8 +154,6 @@ static int fdomain_config(struct pcmcia_device *link) | |||
157 | goto failed; | 154 | goto failed; |
158 | scsi_scan_host(host); | 155 | scsi_scan_host(host); |
159 | 156 | ||
160 | sprintf(info->node.dev_name, "scsi%d", host->host_no); | ||
161 | link->dev_node = &info->node; | ||
162 | info->host = host; | 157 | info->host = host; |
163 | 158 | ||
164 | return 0; | 159 | return 0; |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 021246454872..0f0e112c3f8e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1563,13 +1563,6 @@ static int nsp_cs_probe(struct pcmcia_device *link) | |||
1563 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 1563 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
1564 | link->io.IOAddrLines = 10; /* not used */ | 1564 | link->io.IOAddrLines = 10; /* not used */ |
1565 | 1565 | ||
1566 | /* Interrupt setup */ | ||
1567 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
1568 | |||
1569 | /* Interrupt handler */ | ||
1570 | link->irq.Handler = &nspintr; | ||
1571 | link->irq.Attributes |= IRQF_SHARED; | ||
1572 | |||
1573 | /* General socket configuration */ | 1566 | /* General socket configuration */ |
1574 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1567 | link->conf.Attributes = CONF_ENABLE_IRQ; |
1575 | link->conf.IntType = INT_MEMORY_AND_IO; | 1568 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -1646,8 +1639,7 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev, | |||
1646 | } | 1639 | } |
1647 | 1640 | ||
1648 | /* Do we need to allocate an interrupt? */ | 1641 | /* Do we need to allocate an interrupt? */ |
1649 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 1642 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
1650 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
1651 | 1643 | ||
1652 | /* IO window settings */ | 1644 | /* IO window settings */ |
1653 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 1645 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -1720,10 +1712,8 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1720 | if (ret) | 1712 | if (ret) |
1721 | goto cs_failed; | 1713 | goto cs_failed; |
1722 | 1714 | ||
1723 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1715 | if (pcmcia_request_irq(link, nspintr)) |
1724 | if (pcmcia_request_irq(link, &link->irq)) | 1716 | goto cs_failed; |
1725 | goto cs_failed; | ||
1726 | } | ||
1727 | 1717 | ||
1728 | ret = pcmcia_request_configuration(link, &link->conf); | 1718 | ret = pcmcia_request_configuration(link, &link->conf); |
1729 | if (ret) | 1719 | if (ret) |
@@ -1741,7 +1731,7 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1741 | /* Set port and IRQ */ | 1731 | /* Set port and IRQ */ |
1742 | data->BaseAddress = link->io.BasePort1; | 1732 | data->BaseAddress = link->io.BasePort1; |
1743 | data->NumAddress = link->io.NumPorts1; | 1733 | data->NumAddress = link->io.NumPorts1; |
1744 | data->IrqNumber = link->irq.AssignedIRQ; | 1734 | data->IrqNumber = link->irq; |
1745 | 1735 | ||
1746 | nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", | 1736 | nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", |
1747 | data->BaseAddress, data->NumAddress, data->IrqNumber); | 1737 | data->BaseAddress, data->NumAddress, data->IrqNumber); |
@@ -1764,8 +1754,6 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1764 | 1754 | ||
1765 | scsi_scan_host(host); | 1755 | scsi_scan_host(host); |
1766 | 1756 | ||
1767 | snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); | ||
1768 | link->dev_node = &info->node; | ||
1769 | info->host = host; | 1757 | info->host = host; |
1770 | 1758 | ||
1771 | /* Finally, report what we've done */ | 1759 | /* Finally, report what we've done */ |
@@ -1775,7 +1763,7 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1775 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); | 1763 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); |
1776 | } | 1764 | } |
1777 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1765 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { |
1778 | printk(", irq %d", link->irq.AssignedIRQ); | 1766 | printk(", irq %d", link->irq); |
1779 | } | 1767 | } |
1780 | if (link->io.NumPorts1) { | 1768 | if (link->io.NumPorts1) { |
1781 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 1769 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
@@ -1823,7 +1811,6 @@ static void nsp_cs_release(struct pcmcia_device *link) | |||
1823 | if (info->host != NULL) { | 1811 | if (info->host != NULL) { |
1824 | scsi_remove_host(info->host); | 1812 | scsi_remove_host(info->host); |
1825 | } | 1813 | } |
1826 | link->dev_node = NULL; | ||
1827 | 1814 | ||
1828 | if (link->win) { | 1815 | if (link->win) { |
1829 | if (data != NULL) { | 1816 | if (data != NULL) { |
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 8c61a4fe1db9..d68c9f267c5e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -224,7 +224,6 @@ | |||
224 | typedef struct scsi_info_t { | 224 | typedef struct scsi_info_t { |
225 | struct pcmcia_device *p_dev; | 225 | struct pcmcia_device *p_dev; |
226 | struct Scsi_Host *host; | 226 | struct Scsi_Host *host; |
227 | dev_node_t node; | ||
228 | int stop; | 227 | int stop; |
229 | } scsi_info_t; | 228 | } scsi_info_t; |
230 | 229 | ||
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index f85f094870b4..f0fc6baed9fc 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c | |||
@@ -82,7 +82,6 @@ static struct scsi_host_template qlogicfas_driver_template = { | |||
82 | 82 | ||
83 | typedef struct scsi_info_t { | 83 | typedef struct scsi_info_t { |
84 | struct pcmcia_device *p_dev; | 84 | struct pcmcia_device *p_dev; |
85 | dev_node_t node; | ||
86 | struct Scsi_Host *host; | 85 | struct Scsi_Host *host; |
87 | unsigned short manf_id; | 86 | unsigned short manf_id; |
88 | } scsi_info_t; | 87 | } scsi_info_t; |
@@ -161,7 +160,6 @@ static int qlogic_probe(struct pcmcia_device *link) | |||
161 | link->io.NumPorts1 = 16; | 160 | link->io.NumPorts1 = 16; |
162 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 161 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
163 | link->io.IOAddrLines = 10; | 162 | link->io.IOAddrLines = 10; |
164 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
165 | link->conf.Attributes = CONF_ENABLE_IRQ; | 163 | link->conf.Attributes = CONF_ENABLE_IRQ; |
166 | link->conf.IntType = INT_MEMORY_AND_IO; | 164 | link->conf.IntType = INT_MEMORY_AND_IO; |
167 | link->conf.Present = PRESENT_OPTION; | 165 | link->conf.Present = PRESENT_OPTION; |
@@ -209,8 +207,7 @@ static int qlogic_config(struct pcmcia_device * link) | |||
209 | if (ret) | 207 | if (ret) |
210 | goto failed; | 208 | goto failed; |
211 | 209 | ||
212 | ret = pcmcia_request_irq(link, &link->irq); | 210 | if (!link->irq) |
213 | if (ret) | ||
214 | goto failed; | 211 | goto failed; |
215 | 212 | ||
216 | ret = pcmcia_request_configuration(link, &link->conf); | 213 | ret = pcmcia_request_configuration(link, &link->conf); |
@@ -227,18 +224,16 @@ static int qlogic_config(struct pcmcia_device * link) | |||
227 | /* The KXL-810AN has a bigger IO port window */ | 224 | /* The KXL-810AN has a bigger IO port window */ |
228 | if (link->io.NumPorts1 == 32) | 225 | if (link->io.NumPorts1 == 32) |
229 | host = qlogic_detect(&qlogicfas_driver_template, link, | 226 | host = qlogic_detect(&qlogicfas_driver_template, link, |
230 | link->io.BasePort1 + 16, link->irq.AssignedIRQ); | 227 | link->io.BasePort1 + 16, link->irq); |
231 | else | 228 | else |
232 | host = qlogic_detect(&qlogicfas_driver_template, link, | 229 | host = qlogic_detect(&qlogicfas_driver_template, link, |
233 | link->io.BasePort1, link->irq.AssignedIRQ); | 230 | link->io.BasePort1, link->irq); |
234 | 231 | ||
235 | if (!host) { | 232 | if (!host) { |
236 | printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); | 233 | printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); |
237 | goto failed; | 234 | goto failed; |
238 | } | 235 | } |
239 | 236 | ||
240 | sprintf(info->node.dev_name, "scsi%d", host->host_no); | ||
241 | link->dev_node = &info->node; | ||
242 | info->host = host; | 237 | info->host = host; |
243 | 238 | ||
244 | return 0; | 239 | return 0; |
@@ -258,7 +253,7 @@ static void qlogic_release(struct pcmcia_device *link) | |||
258 | 253 | ||
259 | scsi_remove_host(info->host); | 254 | scsi_remove_host(info->host); |
260 | 255 | ||
261 | free_irq(link->irq.AssignedIRQ, info->host); | 256 | free_irq(link->irq, info->host); |
262 | pcmcia_disable_device(link); | 257 | pcmcia_disable_device(link); |
263 | 258 | ||
264 | scsi_host_put(info->host); | 259 | scsi_host_put(info->host); |
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index e7564d8f0cbf..a51164171179 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c | |||
@@ -191,7 +191,6 @@ | |||
191 | 191 | ||
192 | struct scsi_info_t { | 192 | struct scsi_info_t { |
193 | struct pcmcia_device *p_dev; | 193 | struct pcmcia_device *p_dev; |
194 | dev_node_t node; | ||
195 | struct Scsi_Host *host; | 194 | struct Scsi_Host *host; |
196 | unsigned short manf_id; | 195 | unsigned short manf_id; |
197 | }; | 196 | }; |
@@ -719,8 +718,7 @@ SYM53C500_config(struct pcmcia_device *link) | |||
719 | if (ret) | 718 | if (ret) |
720 | goto failed; | 719 | goto failed; |
721 | 720 | ||
722 | ret = pcmcia_request_irq(link, &link->irq); | 721 | if (!link->irq) |
723 | if (ret) | ||
724 | goto failed; | 722 | goto failed; |
725 | 723 | ||
726 | ret = pcmcia_request_configuration(link, &link->conf); | 724 | ret = pcmcia_request_configuration(link, &link->conf); |
@@ -752,7 +750,7 @@ SYM53C500_config(struct pcmcia_device *link) | |||
752 | * 0x320, 0x330, 0x340, 0x350 | 750 | * 0x320, 0x330, 0x340, 0x350 |
753 | */ | 751 | */ |
754 | port_base = link->io.BasePort1; | 752 | port_base = link->io.BasePort1; |
755 | irq_level = link->irq.AssignedIRQ; | 753 | irq_level = link->irq; |
756 | 754 | ||
757 | DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n", | 755 | DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n", |
758 | port_base, irq_level, USE_FAST_PIO);) | 756 | port_base, irq_level, USE_FAST_PIO);) |
@@ -793,8 +791,6 @@ SYM53C500_config(struct pcmcia_device *link) | |||
793 | */ | 791 | */ |
794 | data->fast_pio = USE_FAST_PIO; | 792 | data->fast_pio = USE_FAST_PIO; |
795 | 793 | ||
796 | sprintf(info->node.dev_name, "scsi%d", host->host_no); | ||
797 | link->dev_node = &info->node; | ||
798 | info->host = host; | 794 | info->host = host; |
799 | 795 | ||
800 | if (scsi_add_host(host, NULL)) | 796 | if (scsi_add_host(host, NULL)) |
@@ -866,7 +862,6 @@ SYM53C500_probe(struct pcmcia_device *link) | |||
866 | link->io.NumPorts1 = 16; | 862 | link->io.NumPorts1 = 16; |
867 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 863 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
868 | link->io.IOAddrLines = 10; | 864 | link->io.IOAddrLines = 10; |
869 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
870 | link->conf.Attributes = CONF_ENABLE_IRQ; | 865 | link->conf.Attributes = CONF_ENABLE_IRQ; |
871 | link->conf.IntType = INT_MEMORY_AND_IO; | 866 | link->conf.IntType = INT_MEMORY_AND_IO; |
872 | 867 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 8cfa5b12ea7a..dadd686c9801 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -89,7 +89,6 @@ struct serial_info { | |||
89 | int manfid; | 89 | int manfid; |
90 | int prodid; | 90 | int prodid; |
91 | int c950ctrl; | 91 | int c950ctrl; |
92 | dev_node_t node[4]; | ||
93 | int line[4]; | 92 | int line[4]; |
94 | const struct serial_quirk *quirk; | 93 | const struct serial_quirk *quirk; |
95 | }; | 94 | }; |
@@ -289,8 +288,6 @@ static void serial_remove(struct pcmcia_device *link) | |||
289 | for (i = 0; i < info->ndev; i++) | 288 | for (i = 0; i < info->ndev; i++) |
290 | serial8250_unregister_port(info->line[i]); | 289 | serial8250_unregister_port(info->line[i]); |
291 | 290 | ||
292 | info->p_dev->dev_node = NULL; | ||
293 | |||
294 | if (!info->slave) | 291 | if (!info->slave) |
295 | pcmcia_disable_device(link); | 292 | pcmcia_disable_device(link); |
296 | } | 293 | } |
@@ -343,7 +340,6 @@ static int serial_probe(struct pcmcia_device *link) | |||
343 | 340 | ||
344 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 341 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
345 | link->io.NumPorts1 = 8; | 342 | link->io.NumPorts1 = 8; |
346 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
347 | link->conf.Attributes = CONF_ENABLE_IRQ; | 343 | link->conf.Attributes = CONF_ENABLE_IRQ; |
348 | if (do_sound) { | 344 | if (do_sound) { |
349 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 345 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
@@ -411,11 +407,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
411 | } | 407 | } |
412 | 408 | ||
413 | info->line[info->ndev] = line; | 409 | info->line[info->ndev] = line; |
414 | sprintf(info->node[info->ndev].dev_name, "ttyS%d", line); | ||
415 | info->node[info->ndev].major = TTY_MAJOR; | ||
416 | info->node[info->ndev].minor = 0x40 + line; | ||
417 | if (info->ndev > 0) | ||
418 | info->node[info->ndev - 1].next = &info->node[info->ndev]; | ||
419 | info->ndev++; | 410 | info->ndev++; |
420 | 411 | ||
421 | return 0; | 412 | return 0; |
@@ -486,7 +477,7 @@ static int simple_config(struct pcmcia_device *link) | |||
486 | } | 477 | } |
487 | if (info->slave) { | 478 | if (info->slave) { |
488 | return setup_serial(link, info, port, | 479 | return setup_serial(link, info, port, |
489 | link->irq.AssignedIRQ); | 480 | link->irq); |
490 | } | 481 | } |
491 | } | 482 | } |
492 | 483 | ||
@@ -507,10 +498,6 @@ static int simple_config(struct pcmcia_device *link) | |||
507 | return -1; | 498 | return -1; |
508 | 499 | ||
509 | found_port: | 500 | found_port: |
510 | i = pcmcia_request_irq(link, &link->irq); | ||
511 | if (i != 0) | ||
512 | link->irq.AssignedIRQ = 0; | ||
513 | |||
514 | if (info->multi && (info->manfid == MANFID_3COM)) | 501 | if (info->multi && (info->manfid == MANFID_3COM)) |
515 | link->conf.ConfigIndex &= ~(0x08); | 502 | link->conf.ConfigIndex &= ~(0x08); |
516 | 503 | ||
@@ -523,7 +510,7 @@ found_port: | |||
523 | i = pcmcia_request_configuration(link, &link->conf); | 510 | i = pcmcia_request_configuration(link, &link->conf); |
524 | if (i != 0) | 511 | if (i != 0) |
525 | return -1; | 512 | return -1; |
526 | return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | 513 | return setup_serial(link, info, link->io.BasePort1, link->irq); |
527 | } | 514 | } |
528 | 515 | ||
529 | static int multi_config_check(struct pcmcia_device *p_dev, | 516 | static int multi_config_check(struct pcmcia_device *p_dev, |
@@ -586,13 +573,9 @@ static int multi_config(struct pcmcia_device *link) | |||
586 | } | 573 | } |
587 | } | 574 | } |
588 | 575 | ||
589 | i = pcmcia_request_irq(link, &link->irq); | 576 | if (!link->irq) |
590 | if (i != 0) { | 577 | dev_warn(&link->dev, |
591 | /* FIXME: comment does not fit, error handling does not fit */ | 578 | "serial_cs: no usable IRQ found, continuing...\n"); |
592 | printk(KERN_NOTICE | ||
593 | "serial_cs: no usable port range found, giving up\n"); | ||
594 | link->irq.AssignedIRQ = 0; | ||
595 | } | ||
596 | 579 | ||
597 | /* | 580 | /* |
598 | * Apply any configuration quirks. | 581 | * Apply any configuration quirks. |
@@ -615,11 +598,11 @@ static int multi_config(struct pcmcia_device *link) | |||
615 | if (link->conf.ConfigIndex == 1 || | 598 | if (link->conf.ConfigIndex == 1 || |
616 | link->conf.ConfigIndex == 3) { | 599 | link->conf.ConfigIndex == 3) { |
617 | err = setup_serial(link, info, base2, | 600 | err = setup_serial(link, info, base2, |
618 | link->irq.AssignedIRQ); | 601 | link->irq); |
619 | base2 = link->io.BasePort1; | 602 | base2 = link->io.BasePort1; |
620 | } else { | 603 | } else { |
621 | err = setup_serial(link, info, link->io.BasePort1, | 604 | err = setup_serial(link, info, link->io.BasePort1, |
622 | link->irq.AssignedIRQ); | 605 | link->irq); |
623 | } | 606 | } |
624 | info->c950ctrl = base2; | 607 | info->c950ctrl = base2; |
625 | 608 | ||
@@ -633,10 +616,10 @@ static int multi_config(struct pcmcia_device *link) | |||
633 | return 0; | 616 | return 0; |
634 | } | 617 | } |
635 | 618 | ||
636 | setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | 619 | setup_serial(link, info, link->io.BasePort1, link->irq); |
637 | for (i = 0; i < info->multi - 1; i++) | 620 | for (i = 0; i < info->multi - 1; i++) |
638 | setup_serial(link, info, base2 + (8 * i), | 621 | setup_serial(link, info, base2 + (8 * i), |
639 | link->irq.AssignedIRQ); | 622 | link->irq); |
640 | return 0; | 623 | return 0; |
641 | } | 624 | } |
642 | 625 | ||
@@ -720,7 +703,6 @@ static int serial_config(struct pcmcia_device * link) | |||
720 | if (info->quirk->post(link)) | 703 | if (info->quirk->post(link)) |
721 | goto failed; | 704 | goto failed; |
722 | 705 | ||
723 | link->dev_node = &info->node[0]; | ||
724 | return 0; | 706 | return 0; |
725 | 707 | ||
726 | failed: | 708 | failed: |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 80ff7d9e60de..bc9bdb277bec 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -490,7 +490,7 @@ static int ssb_devices_register(struct ssb_bus *bus) | |||
490 | break; | 490 | break; |
491 | case SSB_BUSTYPE_PCMCIA: | 491 | case SSB_BUSTYPE_PCMCIA: |
492 | #ifdef CONFIG_SSB_PCMCIAHOST | 492 | #ifdef CONFIG_SSB_PCMCIAHOST |
493 | sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; | 493 | sdev->irq = bus->host_pcmcia->irq; |
494 | dev->parent = &bus->host_pcmcia->dev; | 494 | dev->parent = &bus->host_pcmcia->dev; |
495 | #endif | 495 | #endif |
496 | break; | 496 | break; |
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 5632991760af..30b522c0bf2c 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c | |||
@@ -180,12 +180,12 @@ static int das16cs_attach(struct comedi_device *dev, | |||
180 | } | 180 | } |
181 | printk("\n"); | 181 | printk("\n"); |
182 | 182 | ||
183 | ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt, | 183 | ret = request_irq(link->irq, das16cs_interrupt, |
184 | IRQF_SHARED, "cb_das16_cs", dev); | 184 | IRQF_SHARED, "cb_das16_cs", dev); |
185 | if (ret < 0) { | 185 | if (ret < 0) { |
186 | return ret; | 186 | return ret; |
187 | } | 187 | } |
188 | dev->irq = link->irq.AssignedIRQ; | 188 | dev->irq = link->irq; |
189 | printk("irq=%u ", dev->irq); | 189 | printk("irq=%u ", dev->irq); |
190 | 190 | ||
191 | dev->board_ptr = das16cs_probe(dev, link); | 191 | dev->board_ptr = das16cs_probe(dev, link); |
@@ -671,7 +671,6 @@ static dev_info_t dev_info = "cb_das16_cs"; | |||
671 | 671 | ||
672 | struct local_info_t { | 672 | struct local_info_t { |
673 | struct pcmcia_device *link; | 673 | struct pcmcia_device *link; |
674 | dev_node_t node; | ||
675 | int stop; | 674 | int stop; |
676 | struct bus_operations *bus; | 675 | struct bus_operations *bus; |
677 | }; | 676 | }; |
@@ -702,10 +701,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) | |||
702 | link->priv = local; | 701 | link->priv = local; |
703 | 702 | ||
704 | /* Initialize the pcmcia_device structure */ | 703 | /* Initialize the pcmcia_device structure */ |
705 | /* Interrupt setup */ | ||
706 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
707 | link->irq.Handler = NULL; | ||
708 | |||
709 | link->conf.Attributes = 0; | 704 | link->conf.Attributes = 0; |
710 | link->conf.IntType = INT_MEMORY_AND_IO; | 705 | link->conf.IntType = INT_MEMORY_AND_IO; |
711 | 706 | ||
@@ -720,10 +715,8 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) | |||
720 | { | 715 | { |
721 | dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); | 716 | dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); |
722 | 717 | ||
723 | if (link->dev_node) { | 718 | ((struct local_info_t *)link->priv)->stop = 1; |
724 | ((struct local_info_t *)link->priv)->stop = 1; | 719 | das16cs_pcmcia_release(link); |
725 | das16cs_pcmcia_release(link); | ||
726 | } | ||
727 | /* This points to the parent struct local_info_t struct */ | 720 | /* This points to the parent struct local_info_t struct */ |
728 | if (link->priv) | 721 | if (link->priv) |
729 | kfree(link->priv); | 722 | kfree(link->priv); |
@@ -740,8 +733,7 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
740 | return -EINVAL; | 733 | return -EINVAL; |
741 | 734 | ||
742 | /* Do we need to allocate an interrupt? */ | 735 | /* Do we need to allocate an interrupt? */ |
743 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 736 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
744 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
745 | 737 | ||
746 | /* IO window settings */ | 738 | /* IO window settings */ |
747 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 739 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -769,7 +761,6 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
769 | 761 | ||
770 | static void das16cs_pcmcia_config(struct pcmcia_device *link) | 762 | static void das16cs_pcmcia_config(struct pcmcia_device *link) |
771 | { | 763 | { |
772 | struct local_info_t *dev = link->priv; | ||
773 | int ret; | 764 | int ret; |
774 | 765 | ||
775 | dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); | 766 | dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); |
@@ -780,16 +771,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) | |||
780 | goto failed; | 771 | goto failed; |
781 | } | 772 | } |
782 | 773 | ||
783 | /* | 774 | if (!link->irq) |
784 | Allocate an interrupt line. Note that this does not assign a | 775 | goto failed; |
785 | handler to the interrupt, unless the 'Handler' member of the | 776 | |
786 | irq structure is initialized. | ||
787 | */ | ||
788 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
789 | ret = pcmcia_request_irq(link, &link->irq); | ||
790 | if (ret) | ||
791 | goto failed; | ||
792 | } | ||
793 | /* | 777 | /* |
794 | This actually configures the PCMCIA socket -- setting up | 778 | This actually configures the PCMCIA socket -- setting up |
795 | the I/O windows and the interrupt mapping, and putting the | 779 | the I/O windows and the interrupt mapping, and putting the |
@@ -799,19 +783,10 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) | |||
799 | if (ret) | 783 | if (ret) |
800 | goto failed; | 784 | goto failed; |
801 | 785 | ||
802 | /* | ||
803 | At this point, the dev_node_t structure(s) need to be | ||
804 | initialized and arranged in a linked list at link->dev. | ||
805 | */ | ||
806 | sprintf(dev->node.dev_name, "cb_das16_cs"); | ||
807 | dev->node.major = dev->node.minor = 0; | ||
808 | link->dev_node = &dev->node; | ||
809 | |||
810 | /* Finally, report what we've done */ | 786 | /* Finally, report what we've done */ |
811 | printk(KERN_INFO "%s: index 0x%02x", | 787 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
812 | dev->node.dev_name, link->conf.ConfigIndex); | ||
813 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 788 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
814 | printk(", irq %u", link->irq.AssignedIRQ); | 789 | printk(", irq %u", link->irq); |
815 | if (link->io.NumPorts1) | 790 | if (link->io.NumPorts1) |
816 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 791 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
817 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 792 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9164ce158dcd..896d25bc85b5 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c | |||
@@ -142,7 +142,6 @@ static const dev_info_t dev_info = "pcm-das08"; | |||
142 | 142 | ||
143 | struct local_info_t { | 143 | struct local_info_t { |
144 | struct pcmcia_device *link; | 144 | struct pcmcia_device *link; |
145 | dev_node_t node; | ||
146 | int stop; | 145 | int stop; |
147 | struct bus_operations *bus; | 146 | struct bus_operations *bus; |
148 | }; | 147 | }; |
@@ -172,10 +171,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) | |||
172 | local->link = link; | 171 | local->link = link; |
173 | link->priv = local; | 172 | link->priv = local; |
174 | 173 | ||
175 | /* Interrupt setup */ | ||
176 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
177 | link->irq.Handler = NULL; | ||
178 | |||
179 | /* | 174 | /* |
180 | General socket configuration defaults can go here. In this | 175 | General socket configuration defaults can go here. In this |
181 | client, we assume very little, and rely on the CIS for almost | 176 | 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) | |||
207 | 202 | ||
208 | dev_dbg(&link->dev, "das08_pcmcia_detach\n"); | 203 | dev_dbg(&link->dev, "das08_pcmcia_detach\n"); |
209 | 204 | ||
210 | if (link->dev_node) { | 205 | ((struct local_info_t *)link->priv)->stop = 1; |
211 | ((struct local_info_t *)link->priv)->stop = 1; | 206 | das08_pcmcia_release(link); |
212 | das08_pcmcia_release(link); | ||
213 | } | ||
214 | 207 | ||
215 | /* This points to the parent struct local_info_t struct */ | 208 | /* This points to the parent struct local_info_t struct */ |
216 | if (link->priv) | 209 | if (link->priv) |
@@ -229,8 +222,7 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
229 | return -ENODEV; | 222 | return -ENODEV; |
230 | 223 | ||
231 | /* Do we need to allocate an interrupt? */ | 224 | /* Do we need to allocate an interrupt? */ |
232 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 225 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
233 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
234 | 226 | ||
235 | /* IO window settings */ | 227 | /* IO window settings */ |
236 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 228 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -266,7 +258,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
266 | 258 | ||
267 | static void das08_pcmcia_config(struct pcmcia_device *link) | 259 | static void das08_pcmcia_config(struct pcmcia_device *link) |
268 | { | 260 | { |
269 | struct local_info_t *dev = link->priv; | ||
270 | int ret; | 261 | int ret; |
271 | 262 | ||
272 | dev_dbg(&link->dev, "das08_pcmcia_config\n"); | 263 | dev_dbg(&link->dev, "das08_pcmcia_config\n"); |
@@ -277,11 +268,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link) | |||
277 | goto failed; | 268 | goto failed; |
278 | } | 269 | } |
279 | 270 | ||
280 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 271 | if (!link->irq) |
281 | ret = pcmcia_request_irq(link, &link->irq); | 272 | goto failed; |
282 | if (ret) | ||
283 | goto failed; | ||
284 | } | ||
285 | 273 | ||
286 | /* | 274 | /* |
287 | This actually configures the PCMCIA socket -- setting up | 275 | This actually configures the PCMCIA socket -- setting up |
@@ -292,19 +280,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link) | |||
292 | if (ret) | 280 | if (ret) |
293 | goto failed; | 281 | goto failed; |
294 | 282 | ||
295 | /* | ||
296 | At this point, the dev_node_t structure(s) need to be | ||
297 | initialized and arranged in a linked list at link->dev. | ||
298 | */ | ||
299 | sprintf(dev->node.dev_name, "pcm-das08"); | ||
300 | dev->node.major = dev->node.minor = 0; | ||
301 | link->dev_node = &dev->node; | ||
302 | |||
303 | /* Finally, report what we've done */ | 283 | /* Finally, report what we've done */ |
304 | printk(KERN_INFO "%s: index 0x%02x", | 284 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
305 | dev->node.dev_name, link->conf.ConfigIndex); | ||
306 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 285 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
307 | printk(", irq %u", link->irq.AssignedIRQ); | 286 | printk(", irq %u", link->irq); |
308 | if (link->io.NumPorts1) | 287 | if (link->io.NumPorts1) |
309 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 288 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
310 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 289 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7ea64538e055..06dd44ff1a95 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c | |||
@@ -380,7 +380,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
380 | return -EIO; | 380 | return -EIO; |
381 | iobase = link->io.BasePort1; | 381 | iobase = link->io.BasePort1; |
382 | #ifdef incomplete | 382 | #ifdef incomplete |
383 | irq = link->irq.AssignedIRQ; | 383 | irq = link->irq; |
384 | #endif | 384 | #endif |
385 | break; | 385 | break; |
386 | default: | 386 | default: |
@@ -470,7 +470,6 @@ static const dev_info_t dev_info = "ni_daq_700"; | |||
470 | 470 | ||
471 | struct local_info_t { | 471 | struct local_info_t { |
472 | struct pcmcia_device *link; | 472 | struct pcmcia_device *link; |
473 | dev_node_t node; | ||
474 | int stop; | 473 | int stop; |
475 | struct bus_operations *bus; | 474 | struct bus_operations *bus; |
476 | }; | 475 | }; |
@@ -502,10 +501,6 @@ static int dio700_cs_attach(struct pcmcia_device *link) | |||
502 | local->link = link; | 501 | local->link = link; |
503 | link->priv = local; | 502 | link->priv = local; |
504 | 503 | ||
505 | /* Interrupt setup */ | ||
506 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
507 | link->irq.Handler = NULL; | ||
508 | |||
509 | /* | 504 | /* |
510 | General socket configuration defaults can go here. In this | 505 | General socket configuration defaults can go here. In this |
511 | client, we assume very little, and rely on the CIS for almost | 506 | 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) | |||
539 | 534 | ||
540 | dev_dbg(&link->dev, "dio700_cs_detach\n"); | 535 | dev_dbg(&link->dev, "dio700_cs_detach\n"); |
541 | 536 | ||
542 | if (link->dev_node) { | 537 | ((struct local_info_t *)link->priv)->stop = 1; |
543 | ((struct local_info_t *)link->priv)->stop = 1; | 538 | dio700_release(link); |
544 | dio700_release(link); | ||
545 | } | ||
546 | 539 | ||
547 | /* This points to the parent struct local_info_t struct */ | 540 | /* This points to the parent struct local_info_t struct */ |
548 | if (link->priv) | 541 | if (link->priv) |
@@ -577,8 +570,7 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
577 | } | 570 | } |
578 | 571 | ||
579 | /* Do we need to allocate an interrupt? */ | 572 | /* Do we need to allocate an interrupt? */ |
580 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 573 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
581 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
582 | 574 | ||
583 | /* IO window settings */ | 575 | /* IO window settings */ |
584 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 576 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -625,7 +617,6 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
625 | 617 | ||
626 | static void dio700_config(struct pcmcia_device *link) | 618 | static void dio700_config(struct pcmcia_device *link) |
627 | { | 619 | { |
628 | struct local_info_t *dev = link->priv; | ||
629 | win_req_t req; | 620 | win_req_t req; |
630 | int ret; | 621 | int ret; |
631 | 622 | ||
@@ -639,16 +630,8 @@ static void dio700_config(struct pcmcia_device *link) | |||
639 | goto failed; | 630 | goto failed; |
640 | } | 631 | } |
641 | 632 | ||
642 | /* | 633 | if (!link->irq) |
643 | Allocate an interrupt line. Note that this does not assign a | 634 | goto failed; |
644 | handler to the interrupt, unless the 'Handler' member of the | ||
645 | irq structure is initialized. | ||
646 | */ | ||
647 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
648 | ret = pcmcia_request_irq(link, &link->irq); | ||
649 | if (ret) | ||
650 | goto failed; | ||
651 | } | ||
652 | 635 | ||
653 | /* | 636 | /* |
654 | This actually configures the PCMCIA socket -- setting up | 637 | This actually configures the PCMCIA socket -- setting up |
@@ -659,19 +642,10 @@ static void dio700_config(struct pcmcia_device *link) | |||
659 | if (ret != 0) | 642 | if (ret != 0) |
660 | goto failed; | 643 | goto failed; |
661 | 644 | ||
662 | /* | ||
663 | At this point, the dev_node_t structure(s) need to be | ||
664 | initialized and arranged in a linked list at link->dev. | ||
665 | */ | ||
666 | sprintf(dev->node.dev_name, "ni_daq_700"); | ||
667 | dev->node.major = dev->node.minor = 0; | ||
668 | link->dev_node = &dev->node; | ||
669 | |||
670 | /* Finally, report what we've done */ | 645 | /* Finally, report what we've done */ |
671 | printk(KERN_INFO "%s: index 0x%02x", | 646 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
672 | dev->node.dev_name, link->conf.ConfigIndex); | ||
673 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 647 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
674 | printk(", irq %d", link->irq.AssignedIRQ); | 648 | printk(", irq %d", link->irq); |
675 | if (link->io.NumPorts1) | 649 | if (link->io.NumPorts1) |
676 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 650 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
677 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 651 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index ddc312b5d20d..7bfe08b01fe9 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c | |||
@@ -131,7 +131,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
131 | return -EIO; | 131 | return -EIO; |
132 | iobase = link->io.BasePort1; | 132 | iobase = link->io.BasePort1; |
133 | #ifdef incomplete | 133 | #ifdef incomplete |
134 | irq = link->irq.AssignedIRQ; | 134 | irq = link->irq; |
135 | #endif | 135 | #endif |
136 | break; | 136 | break; |
137 | default: | 137 | default: |
@@ -221,7 +221,6 @@ static const dev_info_t dev_info = "ni_daq_dio24"; | |||
221 | 221 | ||
222 | struct local_info_t { | 222 | struct local_info_t { |
223 | struct pcmcia_device *link; | 223 | struct pcmcia_device *link; |
224 | dev_node_t node; | ||
225 | int stop; | 224 | int stop; |
226 | struct bus_operations *bus; | 225 | struct bus_operations *bus; |
227 | }; | 226 | }; |
@@ -253,10 +252,6 @@ static int dio24_cs_attach(struct pcmcia_device *link) | |||
253 | local->link = link; | 252 | local->link = link; |
254 | link->priv = local; | 253 | link->priv = local; |
255 | 254 | ||
256 | /* Interrupt setup */ | ||
257 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
258 | link->irq.Handler = NULL; | ||
259 | |||
260 | /* | 255 | /* |
261 | General socket configuration defaults can go here. In this | 256 | General socket configuration defaults can go here. In this |
262 | client, we assume very little, and rely on the CIS for almost | 257 | 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) | |||
290 | 285 | ||
291 | dev_dbg(&link->dev, "dio24_cs_detach\n"); | 286 | dev_dbg(&link->dev, "dio24_cs_detach\n"); |
292 | 287 | ||
293 | if (link->dev_node) { | 288 | ((struct local_info_t *)link->priv)->stop = 1; |
294 | ((struct local_info_t *)link->priv)->stop = 1; | 289 | dio24_release(link); |
295 | dio24_release(link); | ||
296 | } | ||
297 | 290 | ||
298 | /* This points to the parent local_info_t struct */ | 291 | /* This points to the parent local_info_t struct */ |
299 | if (link->priv) | 292 | if (link->priv) |
@@ -328,8 +321,7 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
328 | } | 321 | } |
329 | 322 | ||
330 | /* Do we need to allocate an interrupt? */ | 323 | /* Do we need to allocate an interrupt? */ |
331 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 324 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
332 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
333 | 325 | ||
334 | /* IO window settings */ | 326 | /* IO window settings */ |
335 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 327 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -376,7 +368,6 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
376 | 368 | ||
377 | static void dio24_config(struct pcmcia_device *link) | 369 | static void dio24_config(struct pcmcia_device *link) |
378 | { | 370 | { |
379 | struct local_info_t *dev = link->priv; | ||
380 | int ret; | 371 | int ret; |
381 | win_req_t req; | 372 | win_req_t req; |
382 | 373 | ||
@@ -390,16 +381,8 @@ static void dio24_config(struct pcmcia_device *link) | |||
390 | goto failed; | 381 | goto failed; |
391 | } | 382 | } |
392 | 383 | ||
393 | /* | 384 | if (!link->irq) |
394 | Allocate an interrupt line. Note that this does not assign a | 385 | goto failed; |
395 | handler to the interrupt, unless the 'Handler' member of the | ||
396 | irq structure is initialized. | ||
397 | */ | ||
398 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
399 | ret = pcmcia_request_irq(link, &link->irq); | ||
400 | if (ret) | ||
401 | goto failed; | ||
402 | } | ||
403 | 386 | ||
404 | /* | 387 | /* |
405 | This actually configures the PCMCIA socket -- setting up | 388 | This actually configures the PCMCIA socket -- setting up |
@@ -410,19 +393,10 @@ static void dio24_config(struct pcmcia_device *link) | |||
410 | if (ret) | 393 | if (ret) |
411 | goto failed; | 394 | goto failed; |
412 | 395 | ||
413 | /* | ||
414 | At this point, the dev_node_t structure(s) need to be | ||
415 | initialized and arranged in a linked list at link->dev. | ||
416 | */ | ||
417 | sprintf(dev->node.dev_name, "ni_daq_dio24"); | ||
418 | dev->node.major = dev->node.minor = 0; | ||
419 | link->dev_node = &dev->node; | ||
420 | |||
421 | /* Finally, report what we've done */ | 396 | /* Finally, report what we've done */ |
422 | printk(KERN_INFO "%s: index 0x%02x", | 397 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
423 | dev->node.dev_name, link->conf.ConfigIndex); | ||
424 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 398 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
425 | printk(", irq %d", link->irq.AssignedIRQ); | 399 | printk(", irq %d", link->irq); |
426 | if (link->io.NumPorts1) | 400 | if (link->io.NumPorts1) |
427 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 401 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
428 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 402 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 8ad1055a5cc1..fd8d3e9520a0 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c | |||
@@ -144,7 +144,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
144 | if (!link) | 144 | if (!link) |
145 | return -EIO; | 145 | return -EIO; |
146 | iobase = link->io.BasePort1; | 146 | iobase = link->io.BasePort1; |
147 | irq = link->irq.AssignedIRQ; | 147 | irq = link->irq; |
148 | break; | 148 | break; |
149 | default: | 149 | default: |
150 | printk("bug! couldn't determine board type\n"); | 150 | printk("bug! couldn't determine board type\n"); |
@@ -199,7 +199,6 @@ static const dev_info_t dev_info = "daqcard-1200"; | |||
199 | 199 | ||
200 | struct local_info_t { | 200 | struct local_info_t { |
201 | struct pcmcia_device *link; | 201 | struct pcmcia_device *link; |
202 | dev_node_t node; | ||
203 | int stop; | 202 | int stop; |
204 | struct bus_operations *bus; | 203 | struct bus_operations *bus; |
205 | }; | 204 | }; |
@@ -229,10 +228,6 @@ static int labpc_cs_attach(struct pcmcia_device *link) | |||
229 | local->link = link; | 228 | local->link = link; |
230 | link->priv = local; | 229 | link->priv = local; |
231 | 230 | ||
232 | /* Interrupt setup */ | ||
233 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; | ||
234 | link->irq.Handler = NULL; | ||
235 | |||
236 | /* | 231 | /* |
237 | General socket configuration defaults can go here. In this | 232 | General socket configuration defaults can go here. In this |
238 | client, we assume very little, and rely on the CIS for almost | 233 | 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) | |||
269 | the release() function is called, that will trigger a proper | 264 | the release() function is called, that will trigger a proper |
270 | detach(). | 265 | detach(). |
271 | */ | 266 | */ |
272 | if (link->dev_node) { | 267 | ((struct local_info_t *)link->priv)->stop = 1; |
273 | ((struct local_info_t *)link->priv)->stop = 1; | 268 | labpc_release(link); |
274 | labpc_release(link); | ||
275 | } | ||
276 | 269 | ||
277 | /* This points to the parent local_info_t struct (may be null) */ | 270 | /* This points to the parent local_info_t struct (may be null) */ |
278 | kfree(link->priv); | 271 | kfree(link->priv); |
@@ -306,8 +299,7 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
306 | } | 299 | } |
307 | 300 | ||
308 | /* Do we need to allocate an interrupt? */ | 301 | /* Do we need to allocate an interrupt? */ |
309 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 302 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; |
310 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
311 | 303 | ||
312 | /* IO window settings */ | 304 | /* IO window settings */ |
313 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 305 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -355,7 +347,6 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
355 | 347 | ||
356 | static void labpc_config(struct pcmcia_device *link) | 348 | static void labpc_config(struct pcmcia_device *link) |
357 | { | 349 | { |
358 | struct local_info_t *dev = link->priv; | ||
359 | int ret; | 350 | int ret; |
360 | win_req_t req; | 351 | win_req_t req; |
361 | 352 | ||
@@ -367,16 +358,8 @@ static void labpc_config(struct pcmcia_device *link) | |||
367 | goto failed; | 358 | goto failed; |
368 | } | 359 | } |
369 | 360 | ||
370 | /* | 361 | if (!link->irq) |
371 | Allocate an interrupt line. Note that this does not assign a | 362 | goto failed; |
372 | handler to the interrupt, unless the 'Handler' member of the | ||
373 | irq structure is initialized. | ||
374 | */ | ||
375 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
376 | ret = pcmcia_request_irq(link, &link->irq); | ||
377 | if (ret) | ||
378 | goto failed; | ||
379 | } | ||
380 | 363 | ||
381 | /* | 364 | /* |
382 | This actually configures the PCMCIA socket -- setting up | 365 | This actually configures the PCMCIA socket -- setting up |
@@ -387,19 +370,10 @@ static void labpc_config(struct pcmcia_device *link) | |||
387 | if (ret) | 370 | if (ret) |
388 | goto failed; | 371 | goto failed; |
389 | 372 | ||
390 | /* | ||
391 | At this point, the dev_node_t structure(s) need to be | ||
392 | initialized and arranged in a linked list at link->dev. | ||
393 | */ | ||
394 | sprintf(dev->node.dev_name, "daqcard-1200"); | ||
395 | dev->node.major = dev->node.minor = 0; | ||
396 | link->dev_node = &dev->node; | ||
397 | |||
398 | /* Finally, report what we've done */ | 373 | /* Finally, report what we've done */ |
399 | printk(KERN_INFO "%s: index 0x%02x", | 374 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
400 | dev->node.dev_name, link->conf.ConfigIndex); | ||
401 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 375 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
402 | printk(", irq %d", link->irq.AssignedIRQ); | 376 | printk(", irq %d", link->irq); |
403 | if (link->io.NumPorts1) | 377 | if (link->io.NumPorts1) |
404 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 378 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
405 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 379 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index dc4849a40c97..1e8aebae8ae8 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c | |||
@@ -262,17 +262,11 @@ static void cs_detach(struct pcmcia_device *); | |||
262 | 262 | ||
263 | static struct pcmcia_device *cur_dev = NULL; | 263 | static struct pcmcia_device *cur_dev = NULL; |
264 | static const dev_info_t dev_info = "ni_mio_cs"; | 264 | static const dev_info_t dev_info = "ni_mio_cs"; |
265 | static dev_node_t dev_node = { | ||
266 | "ni_mio_cs", | ||
267 | COMEDI_MAJOR, 0, | ||
268 | NULL | ||
269 | }; | ||
270 | 265 | ||
271 | static int cs_attach(struct pcmcia_device *link) | 266 | static int cs_attach(struct pcmcia_device *link) |
272 | { | 267 | { |
273 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 268 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |
274 | link->io.NumPorts1 = 16; | 269 | link->io.NumPorts1 = 16; |
275 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
276 | link->conf.Attributes = CONF_ENABLE_IRQ; | 270 | link->conf.Attributes = CONF_ENABLE_IRQ; |
277 | link->conf.IntType = INT_MEMORY_AND_IO; | 271 | link->conf.IntType = INT_MEMORY_AND_IO; |
278 | 272 | ||
@@ -292,8 +286,7 @@ static void cs_detach(struct pcmcia_device *link) | |||
292 | { | 286 | { |
293 | DPRINTK("cs_detach(link=%p)\n", link); | 287 | DPRINTK("cs_detach(link=%p)\n", link); |
294 | 288 | ||
295 | if (link->dev_node) | 289 | cs_release(link); |
296 | cs_release(link); | ||
297 | } | 290 | } |
298 | 291 | ||
299 | static int mio_cs_suspend(struct pcmcia_device *link) | 292 | static int mio_cs_suspend(struct pcmcia_device *link) |
@@ -344,14 +337,10 @@ static void mio_cs_config(struct pcmcia_device *link) | |||
344 | return; | 337 | return; |
345 | } | 338 | } |
346 | 339 | ||
347 | ret = pcmcia_request_irq(link, &link->irq); | 340 | if (!link->irq) |
348 | if (ret) { | 341 | dev_info(&link->dev, "no IRQ available\n"); |
349 | printk("pcmcia_request_irq() returned error: %i\n", ret); | ||
350 | } | ||
351 | 342 | ||
352 | ret = pcmcia_request_configuration(link, &link->conf); | 343 | ret = pcmcia_request_configuration(link, &link->conf); |
353 | |||
354 | link->dev_node = &dev_node; | ||
355 | } | 344 | } |
356 | 345 | ||
357 | static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) | 346 | 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) | |||
369 | dev->driver = &driver_ni_mio_cs; | 358 | dev->driver = &driver_ni_mio_cs; |
370 | dev->iobase = link->io.BasePort1; | 359 | dev->iobase = link->io.BasePort1; |
371 | 360 | ||
372 | irq = link->irq.AssignedIRQ; | 361 | irq = link->irq; |
373 | 362 | ||
374 | printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", | 363 | printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", |
375 | dev->minor, dev->driver->driver_name, dev->iobase, irq); | 364 | dev->minor, dev->driver->driver_name, dev->iobase, irq); |
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3325f24448b5..1786db2f3378 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c | |||
@@ -60,7 +60,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 | |||
60 | 60 | ||
61 | struct local_info_t { | 61 | struct local_info_t { |
62 | struct pcmcia_device *link; | 62 | struct pcmcia_device *link; |
63 | dev_node_t node; | ||
64 | int stop; | 63 | int stop; |
65 | int table_index; | 64 | int table_index; |
66 | char board_name[32]; | 65 | char board_name[32]; |
@@ -1040,10 +1039,6 @@ static int daqp_cs_attach(struct pcmcia_device *link) | |||
1040 | local->link = link; | 1039 | local->link = link; |
1041 | link->priv = local; | 1040 | link->priv = local; |
1042 | 1041 | ||
1043 | /* Interrupt setup */ | ||
1044 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
1045 | link->irq.Handler = daqp_interrupt; | ||
1046 | |||
1047 | /* | 1042 | /* |
1048 | General socket configuration defaults can go here. In this | 1043 | General socket configuration defaults can go here. In this |
1049 | client, we assume very little, and rely on the CIS for almost | 1044 | 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) | |||
1074 | 1069 | ||
1075 | dev_dbg(&link->dev, "daqp_cs_detach\n"); | 1070 | dev_dbg(&link->dev, "daqp_cs_detach\n"); |
1076 | 1071 | ||
1077 | if (link->dev_node) { | 1072 | dev->stop = 1; |
1078 | dev->stop = 1; | 1073 | daqp_cs_release(link); |
1079 | daqp_cs_release(link); | ||
1080 | } | ||
1081 | 1074 | ||
1082 | /* Unlink device structure, and free it */ | 1075 | /* Unlink device structure, and free it */ |
1083 | dev_table[dev->table_index] = NULL; | 1076 | dev_table[dev->table_index] = NULL; |
@@ -1105,8 +1098,7 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
1105 | return -ENODEV; | 1098 | return -ENODEV; |
1106 | 1099 | ||
1107 | /* Do we need to allocate an interrupt? */ | 1100 | /* Do we need to allocate an interrupt? */ |
1108 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 1101 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
1109 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
1110 | 1102 | ||
1111 | /* IO window settings */ | 1103 | /* IO window settings */ |
1112 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 1104 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -1133,7 +1125,6 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
1133 | 1125 | ||
1134 | static void daqp_cs_config(struct pcmcia_device *link) | 1126 | static void daqp_cs_config(struct pcmcia_device *link) |
1135 | { | 1127 | { |
1136 | struct local_info_t *dev = link->priv; | ||
1137 | int ret; | 1128 | int ret; |
1138 | 1129 | ||
1139 | dev_dbg(&link->dev, "daqp_cs_config\n"); | 1130 | dev_dbg(&link->dev, "daqp_cs_config\n"); |
@@ -1144,16 +1135,9 @@ static void daqp_cs_config(struct pcmcia_device *link) | |||
1144 | goto failed; | 1135 | goto failed; |
1145 | } | 1136 | } |
1146 | 1137 | ||
1147 | /* | 1138 | ret = pcmcia_request_irq(link, daqp_interrupt); |
1148 | Allocate an interrupt line. Note that this does not assign a | 1139 | if (ret) |
1149 | handler to the interrupt, unless the 'Handler' member of the | 1140 | goto failed; |
1150 | irq structure is initialized. | ||
1151 | */ | ||
1152 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | ||
1153 | ret = pcmcia_request_irq(link, &link->irq); | ||
1154 | if (ret) | ||
1155 | goto failed; | ||
1156 | } | ||
1157 | 1141 | ||
1158 | /* | 1142 | /* |
1159 | This actually configures the PCMCIA socket -- setting up | 1143 | This actually configures the PCMCIA socket -- setting up |
@@ -1164,23 +1148,10 @@ static void daqp_cs_config(struct pcmcia_device *link) | |||
1164 | if (ret) | 1148 | if (ret) |
1165 | goto failed; | 1149 | goto failed; |
1166 | 1150 | ||
1167 | /* | ||
1168 | At this point, the dev_node_t structure(s) need to be | ||
1169 | initialized and arranged in a linked list at link->dev. | ||
1170 | */ | ||
1171 | /* Comedi's PCMCIA script uses this device name (extracted | ||
1172 | * from /var/lib/pcmcia/stab) to pass to comedi_config | ||
1173 | */ | ||
1174 | /* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */ | ||
1175 | sprintf(dev->node.dev_name, "quatech_daqp_cs"); | ||
1176 | dev->node.major = dev->node.minor = 0; | ||
1177 | link->dev_node = &dev->node; | ||
1178 | |||
1179 | /* Finally, report what we've done */ | 1151 | /* Finally, report what we've done */ |
1180 | printk(KERN_INFO "%s: index 0x%02x", | 1152 | dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); |
1181 | dev->node.dev_name, link->conf.ConfigIndex); | ||
1182 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 1153 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
1183 | printk(", irq %u", link->irq.AssignedIRQ); | 1154 | printk(", irq %u", link->irq); |
1184 | if (link->io.NumPorts1) | 1155 | if (link->io.NumPorts1) |
1185 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 1156 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
1186 | link->io.BasePort1 + link->io.NumPorts1 - 1); | 1157 | link->io.BasePort1 + link->io.NumPorts1 - 1); |
diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c index 3875a722d12b..f1ee2cbc8407 100644 --- a/drivers/staging/netwave/netwave_cs.c +++ b/drivers/staging/netwave/netwave_cs.c | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <pcmcia/cistpl.h> | 61 | #include <pcmcia/cistpl.h> |
62 | #include <pcmcia/cisreg.h> | 62 | #include <pcmcia/cisreg.h> |
63 | #include <pcmcia/ds.h> | 63 | #include <pcmcia/ds.h> |
64 | #include <pcmcia/mem_op.h> | ||
65 | 64 | ||
66 | #include <asm/system.h> | 65 | #include <asm/system.h> |
67 | #include <asm/io.h> | 66 | #include <asm/io.h> |
@@ -382,10 +381,6 @@ static int netwave_probe(struct pcmcia_device *link) | |||
382 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ | 381 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ |
383 | link->io.IOAddrLines = 5; | 382 | link->io.IOAddrLines = 5; |
384 | 383 | ||
385 | /* Interrupt setup */ | ||
386 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
387 | link->irq.Handler = &netwave_interrupt; | ||
388 | |||
389 | /* General socket configuration */ | 384 | /* General socket configuration */ |
390 | link->conf.Attributes = CONF_ENABLE_IRQ; | 385 | link->conf.Attributes = CONF_ENABLE_IRQ; |
391 | link->conf.IntType = INT_MEMORY_AND_IO; | 386 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -732,7 +727,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { | |||
732 | * Now allocate an interrupt line. Note that this does not | 727 | * Now allocate an interrupt line. Note that this does not |
733 | * actually assign a handler to the interrupt. | 728 | * actually assign a handler to the interrupt. |
734 | */ | 729 | */ |
735 | ret = pcmcia_request_irq(link, &link->irq); | 730 | ret = pcmcia_request_irq(link, netwave_interrupt); |
736 | if (ret) | 731 | if (ret) |
737 | goto failed; | 732 | goto failed; |
738 | 733 | ||
@@ -767,7 +762,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { | |||
767 | ramBase = ioremap(req.Base, 0x8000); | 762 | ramBase = ioremap(req.Base, 0x8000); |
768 | priv->ramBase = ramBase; | 763 | priv->ramBase = ramBase; |
769 | 764 | ||
770 | dev->irq = link->irq.AssignedIRQ; | 765 | dev->irq = link->irq; |
771 | dev->base_addr = link->io.BasePort1; | 766 | dev->base_addr = link->io.BasePort1; |
772 | SET_NETDEV_DEV(dev, &link->dev); | 767 | SET_NETDEV_DEV(dev, &link->dev); |
773 | 768 | ||
diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c index 04f691d127b4..37fa85517a58 100644 --- a/drivers/staging/wavelan/wavelan_cs.c +++ b/drivers/staging/wavelan/wavelan_cs.c | |||
@@ -3850,12 +3850,8 @@ wv_pcmcia_config(struct pcmcia_device * link) | |||
3850 | if (i != 0) | 3850 | if (i != 0) |
3851 | break; | 3851 | break; |
3852 | 3852 | ||
3853 | /* | 3853 | i = pcmcia_request_interrupt(link, wavelan_interrupt); |
3854 | * Now allocate an interrupt line. Note that this does not | 3854 | if (!i) |
3855 | * actually assign a handler to the interrupt. | ||
3856 | */ | ||
3857 | i = pcmcia_request_irq(link, &link->irq); | ||
3858 | if (i != 0) | ||
3859 | break; | 3855 | break; |
3860 | 3856 | ||
3861 | /* | 3857 | /* |
@@ -3890,7 +3886,7 @@ wv_pcmcia_config(struct pcmcia_device * link) | |||
3890 | break; | 3886 | break; |
3891 | 3887 | ||
3892 | /* Feed device with this info... */ | 3888 | /* Feed device with this info... */ |
3893 | dev->irq = link->irq.AssignedIRQ; | 3889 | dev->irq = link->irq; |
3894 | dev->base_addr = link->io.BasePort1; | 3890 | dev->base_addr = link->io.BasePort1; |
3895 | netif_start_queue(dev); | 3891 | netif_start_queue(dev); |
3896 | 3892 | ||
@@ -4437,10 +4433,6 @@ wavelan_probe(struct pcmcia_device *p_dev) | |||
4437 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 4433 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
4438 | p_dev->io.IOAddrLines = 3; | 4434 | p_dev->io.IOAddrLines = 3; |
4439 | 4435 | ||
4440 | /* Interrupt setup */ | ||
4441 | p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
4442 | p_dev->irq.Handler = wavelan_interrupt; | ||
4443 | |||
4444 | /* General socket configuration */ | 4436 | /* General socket configuration */ |
4445 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 4437 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
4446 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 4438 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
@@ -4487,7 +4479,6 @@ wavelan_probe(struct pcmcia_device *p_dev) | |||
4487 | 4479 | ||
4488 | ret = wv_hw_config(dev); | 4480 | ret = wv_hw_config(dev); |
4489 | if (ret) { | 4481 | if (ret) { |
4490 | dev->irq = 0; | ||
4491 | pcmcia_disable_device(p_dev); | 4482 | pcmcia_disable_device(p_dev); |
4492 | return ret; | 4483 | return ret; |
4493 | } | 4484 | } |
diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 9da42e66085e..c9d99d88b786 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c | |||
@@ -156,15 +156,12 @@ static int wl_adapter_attach(struct pcmcia_device *link) | |||
156 | link->io.NumPorts1 = HCF_NUM_IO_PORTS; | 156 | link->io.NumPorts1 = HCF_NUM_IO_PORTS; |
157 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 157 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |
158 | link->io.IOAddrLines = 6; | 158 | link->io.IOAddrLines = 6; |
159 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; | ||
160 | link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; | ||
161 | link->irq.Handler = &wl_isr; | ||
162 | link->conf.Attributes = CONF_ENABLE_IRQ; | 159 | link->conf.Attributes = CONF_ENABLE_IRQ; |
163 | link->conf.IntType = INT_MEMORY_AND_IO; | 160 | link->conf.IntType = INT_MEMORY_AND_IO; |
164 | link->conf.ConfigIndex = 5; | 161 | link->conf.ConfigIndex = 5; |
165 | link->conf.Present = PRESENT_OPTION; | 162 | link->conf.Present = PRESENT_OPTION; |
166 | 163 | ||
167 | link->priv = link->irq.Instance = dev; | 164 | link->priv = dev; |
168 | lp = wl_priv(dev); | 165 | lp = wl_priv(dev); |
169 | lp->link = link; | 166 | lp->link = link; |
170 | 167 | ||
@@ -318,11 +315,11 @@ void wl_adapter_insert( struct pcmcia_device *link ) | |||
318 | link->conf.Attributes |= CONF_ENABLE_IRQ; | 315 | link->conf.Attributes |= CONF_ENABLE_IRQ; |
319 | 316 | ||
320 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); | 317 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); |
321 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | 318 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, wl_isr)); |
322 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 319 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
323 | 320 | ||
324 | 321 | ||
325 | dev->irq = link->irq.AssignedIRQ; | 322 | dev->irq = link->irq; |
326 | dev->base_addr = link->io.BasePort1; | 323 | dev->base_addr = link->io.BasePort1; |
327 | 324 | ||
328 | SET_NETDEV_DEV(dev, &handle_to_dev(link)); | 325 | SET_NETDEV_DEV(dev, &handle_to_dev(link)); |
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index d442fd35620a..99cb2246ac72 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | typedef struct ixj_info_t { | 23 | typedef struct ixj_info_t { |
24 | int ndev; | 24 | int ndev; |
25 | dev_node_t node; | ||
26 | struct ixj *port; | 25 | struct ixj *port; |
27 | } ixj_info_t; | 26 | } ixj_info_t; |
28 | 27 | ||
@@ -155,8 +154,6 @@ static int ixj_config(struct pcmcia_device * link) | |||
155 | j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10); | 154 | j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10); |
156 | 155 | ||
157 | info->ndev = 1; | 156 | info->ndev = 1; |
158 | info->node.major = PHONE_MAJOR; | ||
159 | link->dev_node = &info->node; | ||
160 | ixj_get_serial(link, j); | 157 | ixj_get_serial(link, j); |
161 | return 0; | 158 | return 0; |
162 | 159 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 39d253e841f6..58cb73c8420a 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -47,7 +47,6 @@ static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; | |||
47 | 47 | ||
48 | typedef struct local_info_t { | 48 | typedef struct local_info_t { |
49 | struct pcmcia_device *p_dev; | 49 | struct pcmcia_device *p_dev; |
50 | dev_node_t node; | ||
51 | } local_info_t; | 50 | } local_info_t; |
52 | 51 | ||
53 | static void sl811_cs_release(struct pcmcia_device * link); | 52 | static void sl811_cs_release(struct pcmcia_device * link); |
@@ -163,8 +162,7 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev, | |||
163 | dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | 162 | dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; |
164 | 163 | ||
165 | /* we need an interrupt */ | 164 | /* we need an interrupt */ |
166 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | 165 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
167 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
168 | 166 | ||
169 | /* IO window settings */ | 167 | /* IO window settings */ |
170 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | 168 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
@@ -186,7 +184,6 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev, | |||
186 | static int sl811_cs_config(struct pcmcia_device *link) | 184 | static int sl811_cs_config(struct pcmcia_device *link) |
187 | { | 185 | { |
188 | struct device *parent = &link->dev; | 186 | struct device *parent = &link->dev; |
189 | local_info_t *dev = link->priv; | ||
190 | int ret; | 187 | int ret; |
191 | 188 | ||
192 | dev_dbg(&link->dev, "sl811_cs_config\n"); | 189 | dev_dbg(&link->dev, "sl811_cs_config\n"); |
@@ -197,31 +194,24 @@ static int sl811_cs_config(struct pcmcia_device *link) | |||
197 | /* require an IRQ and two registers */ | 194 | /* require an IRQ and two registers */ |
198 | if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) | 195 | if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) |
199 | goto failed; | 196 | goto failed; |
200 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 197 | |
201 | ret = pcmcia_request_irq(link, &link->irq); | 198 | if (!link->irq) |
202 | if (ret) | ||
203 | goto failed; | ||
204 | } else | ||
205 | goto failed; | 199 | goto failed; |
206 | 200 | ||
207 | ret = pcmcia_request_configuration(link, &link->conf); | 201 | ret = pcmcia_request_configuration(link, &link->conf); |
208 | if (ret) | 202 | if (ret) |
209 | goto failed; | 203 | goto failed; |
210 | 204 | ||
211 | sprintf(dev->node.dev_name, driver_name); | 205 | dev_info(&link->dev, "index 0x%02x: ", |
212 | dev->node.major = dev->node.minor = 0; | 206 | link->conf.ConfigIndex); |
213 | link->dev_node = &dev->node; | ||
214 | |||
215 | printk(KERN_INFO "%s: index 0x%02x: ", | ||
216 | dev->node.dev_name, link->conf.ConfigIndex); | ||
217 | if (link->conf.Vpp) | 207 | if (link->conf.Vpp) |
218 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); | 208 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); |
219 | printk(", irq %d", link->irq.AssignedIRQ); | 209 | printk(", irq %d", link->irq); |
220 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 210 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
221 | link->io.BasePort1+link->io.NumPorts1-1); | 211 | link->io.BasePort1+link->io.NumPorts1-1); |
222 | printk("\n"); | 212 | printk("\n"); |
223 | 213 | ||
224 | if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) | 214 | if (sl811_hc_init(parent, link->io.BasePort1, link->irq) |
225 | < 0) { | 215 | < 0) { |
226 | failed: | 216 | failed: |
227 | printk(KERN_WARNING "sl811_cs_config failed\n"); | 217 | printk(KERN_WARNING "sl811_cs_config failed\n"); |
@@ -241,10 +231,6 @@ static int sl811_cs_probe(struct pcmcia_device *link) | |||
241 | local->p_dev = link; | 231 | local->p_dev = link; |
242 | link->priv = local; | 232 | link->priv = local; |
243 | 233 | ||
244 | /* Initialize */ | ||
245 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
246 | link->irq.Handler = NULL; | ||
247 | |||
248 | link->conf.Attributes = 0; | 234 | link->conf.Attributes = 0; |
249 | link->conf.IntType = INT_MEMORY_AND_IO; | 235 | link->conf.IntType = INT_MEMORY_AND_IO; |
250 | 236 | ||
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 75fa3530345b..57d8d0393567 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h | |||
@@ -85,6 +85,7 @@ typedef struct config_req_t { | |||
85 | #define CONF_ENABLE_IRQ 0x01 | 85 | #define CONF_ENABLE_IRQ 0x01 |
86 | #define CONF_ENABLE_DMA 0x02 | 86 | #define CONF_ENABLE_DMA 0x02 |
87 | #define CONF_ENABLE_SPKR 0x04 | 87 | #define CONF_ENABLE_SPKR 0x04 |
88 | #define CONF_ENABLE_PULSE_IRQ 0x08 | ||
88 | #define CONF_VALID_CLIENT 0x100 | 89 | #define CONF_VALID_CLIENT 0x100 |
89 | 90 | ||
90 | /* IntType field */ | 91 | /* IntType field */ |
@@ -113,25 +114,7 @@ typedef struct io_req_t { | |||
113 | #define IO_DATA_PATH_WIDTH_16 0x08 | 114 | #define IO_DATA_PATH_WIDTH_16 0x08 |
114 | #define IO_DATA_PATH_WIDTH_AUTO 0x10 | 115 | #define IO_DATA_PATH_WIDTH_AUTO 0x10 |
115 | 116 | ||
116 | /* For RequestIRQ and ReleaseIRQ */ | ||
117 | typedef struct irq_req_t { | ||
118 | u_int Attributes; | ||
119 | u_int AssignedIRQ; | ||
120 | irq_handler_t Handler; | ||
121 | } irq_req_t; | ||
122 | |||
123 | /* Attributes for RequestIRQ and ReleaseIRQ */ | ||
124 | #define IRQ_TYPE 0x03 | ||
125 | #define IRQ_TYPE_EXCLUSIVE 0x00 | ||
126 | #define IRQ_TYPE_TIME 0x01 | ||
127 | #define IRQ_TYPE_DYNAMIC_SHARING 0x02 | ||
128 | #define IRQ_FORCED_PULSE 0x04 | ||
129 | #define IRQ_FIRST_SHARED 0x08 /* unused */ | ||
130 | #define IRQ_HANDLE_PRESENT 0x10 /* unused */ | ||
131 | #define IRQ_PULSE_ALLOCATED 0x100 | ||
132 | |||
133 | /* Bits in IRQInfo1 field */ | 117 | /* Bits in IRQInfo1 field */ |
134 | #define IRQ_MASK 0x0f | ||
135 | #define IRQ_NMI_ID 0x01 | 118 | #define IRQ_NMI_ID 0x01 |
136 | #define IRQ_IOCK_ID 0x02 | 119 | #define IRQ_IOCK_ID 0x02 |
137 | #define IRQ_BERR_ID 0x04 | 120 | #define IRQ_BERR_ID 0x04 |
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index aab3c13dc310..c180165fbd3e 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h | |||
@@ -62,15 +62,6 @@ struct pcmcia_driver { | |||
62 | int pcmcia_register_driver(struct pcmcia_driver *driver); | 62 | int pcmcia_register_driver(struct pcmcia_driver *driver); |
63 | void pcmcia_unregister_driver(struct pcmcia_driver *driver); | 63 | void pcmcia_unregister_driver(struct pcmcia_driver *driver); |
64 | 64 | ||
65 | /* Some drivers use dev_node_t to store char or block device information. | ||
66 | * Don't use this in new drivers, though. | ||
67 | */ | ||
68 | typedef struct dev_node_t { | ||
69 | char dev_name[DEV_NAME_LEN]; | ||
70 | u_short major, minor; | ||
71 | struct dev_node_t *next; | ||
72 | } dev_node_t; | ||
73 | |||
74 | struct pcmcia_device { | 65 | struct pcmcia_device { |
75 | /* the socket and the device_no [for multifunction devices] | 66 | /* the socket and the device_no [for multifunction devices] |
76 | uniquely define a pcmcia_device */ | 67 | uniquely define a pcmcia_device */ |
@@ -88,13 +79,14 @@ struct pcmcia_device { | |||
88 | struct list_head socket_device_list; | 79 | struct list_head socket_device_list; |
89 | 80 | ||
90 | /* deprecated, will be cleaned up soon */ | 81 | /* deprecated, will be cleaned up soon */ |
91 | dev_node_t *dev_node; | ||
92 | u_int open; | 82 | u_int open; |
93 | io_req_t io; | 83 | io_req_t io; |
94 | irq_req_t irq; | ||
95 | config_req_t conf; | 84 | config_req_t conf; |
96 | window_handle_t win; | 85 | window_handle_t win; |
97 | 86 | ||
87 | /* device setup */ | ||
88 | unsigned int irq; | ||
89 | |||
98 | /* Is the device suspended? */ | 90 | /* Is the device suspended? */ |
99 | u16 suspended:1; | 91 | u16 suspended:1; |
100 | 92 | ||
@@ -191,7 +183,20 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
191 | 183 | ||
192 | /* device configuration */ | 184 | /* device configuration */ |
193 | int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); | 185 | int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); |
194 | int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req); | 186 | |
187 | int __must_check | ||
188 | __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, | ||
189 | irq_handler_t handler); | ||
190 | static inline __must_check __deprecated int | ||
191 | pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, | ||
192 | irq_handler_t handler) | ||
193 | { | ||
194 | return __pcmcia_request_exclusive_irq(p_dev, handler); | ||
195 | } | ||
196 | |||
197 | int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, | ||
198 | irq_handler_t handler); | ||
199 | |||
195 | int pcmcia_request_configuration(struct pcmcia_device *p_dev, | 200 | int pcmcia_request_configuration(struct pcmcia_device *p_dev, |
196 | config_req_t *req); | 201 | config_req_t *req); |
197 | 202 | ||
diff --git a/include/pcmcia/mem_op.h b/include/pcmcia/mem_op.h deleted file mode 100644 index 0fa06e5d5376..000000000000 --- a/include/pcmcia/mem_op.h +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* | ||
2 | * mem_op.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * The initial developer of the original code is David A. Hinds | ||
9 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
10 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
11 | * | ||
12 | * (C) 1999 David A. Hinds | ||
13 | */ | ||
14 | |||
15 | #ifndef _LINUX_MEM_OP_H | ||
16 | #define _LINUX_MEM_OP_H | ||
17 | |||
18 | #include <linux/io.h> | ||
19 | #include <asm/uaccess.h> | ||
20 | |||
21 | /* | ||
22 | If UNSAFE_MEMCPY is defined, we use the (optimized) system routines | ||
23 | to copy between a card and kernel memory. These routines do 32-bit | ||
24 | operations which may not work with all PCMCIA controllers. The | ||
25 | safe versions defined here will do only 8-bit and 16-bit accesses. | ||
26 | */ | ||
27 | |||
28 | #ifdef UNSAFE_MEMCPY | ||
29 | |||
30 | #define copy_from_pc memcpy_fromio | ||
31 | #define copy_to_pc memcpy_toio | ||
32 | |||
33 | static inline void copy_pc_to_user(void *to, const void *from, size_t n) | ||
34 | { | ||
35 | size_t odd = (n & 3); | ||
36 | n -= odd; | ||
37 | while (n) { | ||
38 | put_user(__raw_readl(from), (int *)to); | ||
39 | (char *)from += 4; (char *)to += 4; n -= 4; | ||
40 | } | ||
41 | while (odd--) | ||
42 | put_user(readb((char *)from++), (char *)to++); | ||
43 | } | ||
44 | |||
45 | static inline void copy_user_to_pc(void *to, const void *from, size_t n) | ||
46 | { | ||
47 | int l; | ||
48 | char c; | ||
49 | size_t odd = (n & 3); | ||
50 | n -= odd; | ||
51 | while (n) { | ||
52 | get_user(l, (int *)from); | ||
53 | __raw_writel(l, to); | ||
54 | (char *)to += 4; (char *)from += 4; n -= 4; | ||
55 | } | ||
56 | while (odd--) { | ||
57 | get_user(c, (char *)from++); | ||
58 | writeb(c, (char *)to++); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #else /* UNSAFE_MEMCPY */ | ||
63 | |||
64 | static inline void copy_from_pc(void *to, void __iomem *from, size_t n) | ||
65 | { | ||
66 | __u16 *t = to; | ||
67 | __u16 __iomem *f = from; | ||
68 | size_t odd = (n & 1); | ||
69 | for (n >>= 1; n; n--) | ||
70 | *t++ = __raw_readw(f++); | ||
71 | if (odd) | ||
72 | *(__u8 *)t = readb(f); | ||
73 | } | ||
74 | |||
75 | static inline void copy_to_pc(void __iomem *to, const void *from, size_t n) | ||
76 | { | ||
77 | __u16 __iomem *t = to; | ||
78 | const __u16 *f = from; | ||
79 | size_t odd = (n & 1); | ||
80 | for (n >>= 1; n ; n--) | ||
81 | __raw_writew(*f++, t++); | ||
82 | if (odd) | ||
83 | writeb(*(__u8 *)f, t); | ||
84 | } | ||
85 | |||
86 | static inline void copy_pc_to_user(void __user *to, void __iomem *from, size_t n) | ||
87 | { | ||
88 | __u16 __user *t = to; | ||
89 | __u16 __iomem *f = from; | ||
90 | size_t odd = (n & 1); | ||
91 | for (n >>= 1; n ; n--) | ||
92 | put_user(__raw_readw(f++), t++); | ||
93 | if (odd) | ||
94 | put_user(readb(f), (char __user *)t); | ||
95 | } | ||
96 | |||
97 | static inline void copy_user_to_pc(void __iomem *to, void __user *from, size_t n) | ||
98 | { | ||
99 | __u16 __user *f = from; | ||
100 | __u16 __iomem *t = to; | ||
101 | short s; | ||
102 | char c; | ||
103 | size_t odd = (n & 1); | ||
104 | for (n >>= 1; n; n--) { | ||
105 | get_user(s, f++); | ||
106 | __raw_writew(s, t++); | ||
107 | } | ||
108 | if (odd) { | ||
109 | get_user(c, (char __user *)f); | ||
110 | writeb(c, t); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | #endif /* UNSAFE_MEMCPY */ | ||
115 | |||
116 | #endif /* _LINUX_MEM_OP_H */ | ||
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 344705cb42f4..764281b29218 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h | |||
@@ -141,10 +141,6 @@ struct pcmcia_socket { | |||
141 | u_short lock_count; | 141 | u_short lock_count; |
142 | pccard_mem_map cis_mem; | 142 | pccard_mem_map cis_mem; |
143 | void __iomem *cis_virt; | 143 | void __iomem *cis_virt; |
144 | struct { | ||
145 | u_int AssignedIRQ; | ||
146 | u_int Config; | ||
147 | } irq; | ||
148 | io_window_t io[MAX_IO_WIN]; | 144 | io_window_t io[MAX_IO_WIN]; |
149 | pccard_mem_map win[MAX_WIN]; | 145 | pccard_mem_map win[MAX_WIN]; |
150 | struct list_head cis_cache; | 146 | struct list_head cis_cache; |
@@ -235,6 +231,9 @@ struct pcmcia_socket { | |||
235 | /* non-zero if PCMCIA card is present */ | 231 | /* non-zero if PCMCIA card is present */ |
236 | atomic_t present; | 232 | atomic_t present; |
237 | 233 | ||
234 | /* IRQ to be used by PCMCIA devices. May not be IRQ 0. */ | ||
235 | unsigned int pcmcia_irq; | ||
236 | |||
238 | #ifdef CONFIG_PCMCIA_IOCTL | 237 | #ifdef CONFIG_PCMCIA_IOCTL |
239 | struct user_info_t *user; | 238 | struct user_info_t *user; |
240 | wait_queue_head_t queue; | 239 | wait_queue_head_t queue; |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index edaa729126bb..df110df52a8b 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c | |||
@@ -142,12 +142,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link) | |||
142 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 142 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
143 | link->io.NumPorts1 = 16; | 143 | link->io.NumPorts1 = 16; |
144 | 144 | ||
145 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; | 145 | link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; |
146 | /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */ | ||
147 | /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */ | ||
148 | |||
149 | link->irq.Handler = pdacf_interrupt; | ||
150 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
151 | link->conf.IntType = INT_MEMORY_AND_IO; | 146 | link->conf.IntType = INT_MEMORY_AND_IO; |
152 | link->conf.ConfigIndex = 1; | 147 | link->conf.ConfigIndex = 1; |
153 | link->conf.Present = PRESENT_OPTION; | 148 | link->conf.Present = PRESENT_OPTION; |
@@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link) | |||
228 | if (ret) | 223 | if (ret) |
229 | goto failed; | 224 | goto failed; |
230 | 225 | ||
231 | ret = pcmcia_request_irq(link, &link->irq); | 226 | ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt); |
232 | if (ret) | 227 | if (ret) |
233 | goto failed; | 228 | goto failed; |
234 | 229 | ||
@@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link) | |||
236 | if (ret) | 231 | if (ret) |
237 | goto failed; | 232 | goto failed; |
238 | 233 | ||
239 | if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) | 234 | if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0) |
240 | goto failed; | 235 | goto failed; |
241 | 236 | ||
242 | link->dev_node = &pdacf->node; | ||
243 | return 0; | 237 | return 0; |
244 | 238 | ||
245 | failed: | 239 | failed: |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h index b0601838112d..a0a7ec64222a 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h | |||
@@ -117,7 +117,6 @@ struct snd_pdacf { | |||
117 | 117 | ||
118 | /* pcmcia stuff */ | 118 | /* pcmcia stuff */ |
119 | struct pcmcia_device *p_dev; | 119 | struct pcmcia_device *p_dev; |
120 | dev_node_t node; | ||
121 | }; | 120 | }; |
122 | 121 | ||
123 | static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val) | 122 | static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val) |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cfd1438bcc64..624b47a85f0a 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -162,10 +162,6 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, | |||
162 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 162 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
163 | link->io.NumPorts1 = 16; | 163 | link->io.NumPorts1 = 16; |
164 | 164 | ||
165 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
166 | |||
167 | link->irq.Handler = &snd_vx_irq_handler; | ||
168 | |||
169 | link->conf.Attributes = CONF_ENABLE_IRQ; | 165 | link->conf.Attributes = CONF_ENABLE_IRQ; |
170 | link->conf.IntType = INT_MEMORY_AND_IO; | 166 | link->conf.IntType = INT_MEMORY_AND_IO; |
171 | link->conf.ConfigIndex = 1; | 167 | link->conf.ConfigIndex = 1; |
@@ -215,7 +211,6 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq | |||
215 | static int vxpocket_config(struct pcmcia_device *link) | 211 | static int vxpocket_config(struct pcmcia_device *link) |
216 | { | 212 | { |
217 | struct vx_core *chip = link->priv; | 213 | struct vx_core *chip = link->priv; |
218 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
219 | int ret; | 214 | int ret; |
220 | 215 | ||
221 | snd_printdd(KERN_DEBUG "vxpocket_config called\n"); | 216 | snd_printdd(KERN_DEBUG "vxpocket_config called\n"); |
@@ -235,7 +230,7 @@ static int vxpocket_config(struct pcmcia_device *link) | |||
235 | if (ret) | 230 | if (ret) |
236 | goto failed; | 231 | goto failed; |
237 | 232 | ||
238 | ret = pcmcia_request_irq(link, &link->irq); | 233 | ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler); |
239 | if (ret) | 234 | if (ret) |
240 | goto failed; | 235 | goto failed; |
241 | 236 | ||
@@ -246,10 +241,9 @@ static int vxpocket_config(struct pcmcia_device *link) | |||
246 | chip->dev = &link->dev; | 241 | chip->dev = &link->dev; |
247 | snd_card_set_dev(chip->card, chip->dev); | 242 | snd_card_set_dev(chip->card, chip->dev); |
248 | 243 | ||
249 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) | 244 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0) |
250 | goto failed; | 245 | goto failed; |
251 | 246 | ||
252 | link->dev_node = &vxp->node; | ||
253 | return 0; | 247 | return 0; |
254 | 248 | ||
255 | failed: | 249 | failed: |
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index 27ea002294c0..ea4df16a28ef 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h | |||
@@ -43,7 +43,6 @@ struct snd_vxpocket { | |||
43 | 43 | ||
44 | /* pcmcia stuff */ | 44 | /* pcmcia stuff */ |
45 | struct pcmcia_device *p_dev; | 45 | struct pcmcia_device *p_dev; |
46 | dev_node_t node; | ||
47 | }; | 46 | }; |
48 | 47 | ||
49 | extern struct snd_vx_ops snd_vxpocket_ops; | 48 | extern struct snd_vx_ops snd_vxpocket_ops; |