aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2006-01-15 03:32:39 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2006-03-31 10:15:50 -0500
commit5f2a71fcb7995633b335a1e380ac63a968e61320 (patch)
treed47f4227d314fc9f298b75c217fa78440004e6e7
parent1de9cedfbdff1d8adb662cd3afc5bda66e393351 (diff)
[PATCH] pcmcia: add pcmcia_disable_device
pcmcia_disable_device(struct pcmcia_device *p_dev) performs the necessary cleanups upon device or driver removal: it calls the appropriate pcmcia_release_* functions, and can replace (most) of the current drivers' _release() functions. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--Documentation/pcmcia/driver-changes.txt6
-rw-r--r--drivers/bluetooth/bluecard_cs.c8
-rw-r--r--drivers/bluetooth/bt3c_cs.c8
-rw-r--r--drivers/bluetooth/btuart_cs.c8
-rw-r--r--drivers/bluetooth/dtl1_cs.c8
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c3
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c3
-rw-r--r--drivers/char/pcmcia/synclink_cs.c10
-rw-r--r--drivers/ide/legacy/ide-cs.c8
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c12
-rw-r--r--drivers/isdn/hisax/avma1_cs.c17
-rw-r--r--drivers/isdn/hisax/elsa_cs.c12
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c17
-rw-r--r--drivers/isdn/hisax/teles_cs.c12
-rw-r--r--drivers/net/pcmcia/3c574_cs.c8
-rw-r--r--drivers/net/pcmcia/3c589_cs.c8
-rw-r--r--drivers/net/pcmcia/axnet_cs.c8
-rw-r--r--drivers/net/pcmcia/com20020_cs.c12
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c12
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c23
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c10
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c15
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c21
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c22
-rw-r--r--drivers/net/wireless/airo_cs.c19
-rw-r--r--drivers/net/wireless/atmel_cs.c21
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c11
-rw-r--r--drivers/net/wireless/netwave_cs.c19
-rw-r--r--drivers/net/wireless/orinoco_cs.c8
-rw-r--r--drivers/net/wireless/spectrum_cs.c8
-rw-r--r--drivers/net/wireless/wavelan_cs.c18
-rw-r--r--drivers/net/wireless/wl3501_cs.c10
-rw-r--r--drivers/parport/parport_cs.c24
-rw-r--r--drivers/pcmcia/pcmcia_resource.c71
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c8
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c17
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c11
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c9
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c8
-rw-r--r--drivers/serial/serial_cs.c7
-rw-r--r--include/pcmcia/cs.h2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c8
-rw-r--r--sound/pcmcia/vx/vxpocket.c8
43 files changed, 155 insertions, 403 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 97420f08c786..c89a5e29bb4c 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This file details changes in 2.6 which affect PCMCIA card driver authors:
2 2
3* New release helper (as of 2.6.17)
4 Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
5 necessary now is calling pcmcia_disable_device. As there is no valid
6 reason left to call pcmcia_release_io and pcmcia_release_irq, they will
7 be removed soon.
8
3* Unify detach and REMOVAL event code, as well as attach and INSERTION 9* Unify detach and REMOVAL event code, as well as attach and INSERTION
4 code (as of 2.6.16) 10 code (as of 2.6.16)
5 void (*remove) (struct pcmcia_device *dev); 11 void (*remove) (struct pcmcia_device *dev);
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 9888bc151755..128e41609a5d 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -1002,13 +1002,7 @@ static void bluecard_release(dev_link_t *link)
1002 1002
1003 del_timer(&(info->timer)); 1003 del_timer(&(info->timer));
1004 1004
1005 link->dev = NULL; 1005 pcmcia_disable_device(link->handle);
1006
1007 pcmcia_release_configuration(link->handle);
1008 pcmcia_release_io(link->handle, &link->io);
1009 pcmcia_release_irq(link->handle, &link->irq);
1010
1011 link->state &= ~DEV_CONFIG;
1012} 1006}
1013 1007
1014static int bluecard_suspend(struct pcmcia_device *dev) 1008static int bluecard_suspend(struct pcmcia_device *dev)
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 7e21b1ff27c4..ac1410c0a43e 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -839,13 +839,7 @@ static void bt3c_release(dev_link_t *link)
839 if (link->state & DEV_PRESENT) 839 if (link->state & DEV_PRESENT)
840 bt3c_close(info); 840 bt3c_close(info);
841 841
842 link->dev = NULL; 842 pcmcia_disable_device(link->handle);
843
844 pcmcia_release_configuration(link->handle);
845 pcmcia_release_io(link->handle, &link->io);
846 pcmcia_release_irq(link->handle, &link->irq);
847
848 link->state &= ~DEV_CONFIG;
849} 843}
850 844
851static int bt3c_suspend(struct pcmcia_device *dev) 845static int bt3c_suspend(struct pcmcia_device *dev)
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 7b4bff4cfa2d..8cd54bb199f9 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -768,13 +768,7 @@ static void btuart_release(dev_link_t *link)
768 if (link->state & DEV_PRESENT) 768 if (link->state & DEV_PRESENT)
769 btuart_close(info); 769 btuart_close(info);
770 770
771 link->dev = NULL; 771 pcmcia_disable_device(link->handle);
772
773 pcmcia_release_configuration(link->handle);
774 pcmcia_release_io(link->handle, &link->io);
775 pcmcia_release_irq(link->handle, &link->irq);
776
777 link->state &= ~DEV_CONFIG;
778} 772}
779 773
780static int btuart_suspend(struct pcmcia_device *dev) 774static int btuart_suspend(struct pcmcia_device *dev)
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 0449bc45ae5e..efbc8a543a9a 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -720,13 +720,7 @@ static void dtl1_release(dev_link_t *link)
720 if (link->state & DEV_PRESENT) 720 if (link->state & DEV_PRESENT)
721 dtl1_close(info); 721 dtl1_close(info);
722 722
723 link->dev = NULL; 723 pcmcia_disable_device(link->handle);
724
725 pcmcia_release_configuration(link->handle);
726 pcmcia_release_io(link->handle, &link->io);
727 pcmcia_release_irq(link->handle, &link->irq);
728
729 link->state &= ~DEV_CONFIG;
730} 724}
731 725
732static int dtl1_suspend(struct pcmcia_device *dev) 726static int dtl1_suspend(struct pcmcia_device *dev)
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 5fdf18515433..3ddd3da9e720 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1899,8 +1899,7 @@ static int cm4000_resume(struct pcmcia_device *p_dev)
1899static void cm4000_release(dev_link_t *link) 1899static void cm4000_release(dev_link_t *link)
1900{ 1900{
1901 cmm_cm4000_release(link->priv); /* delay release until device closed */ 1901 cmm_cm4000_release(link->priv); /* delay release until device closed */
1902 pcmcia_release_configuration(link->handle); 1902 pcmcia_disable_device(link->handle);
1903 pcmcia_release_io(link->handle, &link->io);
1904} 1903}
1905 1904
1906static int cm4000_attach(struct pcmcia_device *p_dev) 1905static int cm4000_attach(struct pcmcia_device *p_dev)
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 466e33bab029..1c355bd2be88 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -654,8 +654,7 @@ static int reader_resume(struct pcmcia_device *p_dev)
654static void reader_release(dev_link_t *link) 654static void reader_release(dev_link_t *link)
655{ 655{
656 cm4040_reader_release(link->priv); 656 cm4040_reader_release(link->priv);
657 pcmcia_release_configuration(link->handle); 657 pcmcia_disable_device(link->handle);
658 pcmcia_release_io(link->handle, &link->io);
659} 658}
660 659
661static int reader_attach(struct pcmcia_device *p_dev) 660static int reader_attach(struct pcmcia_device *p_dev)
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index e6b714b6390d..371d10b78004 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -710,15 +710,7 @@ static void mgslpc_release(u_long arg)
710 if (debug_level >= DEBUG_LEVEL_INFO) 710 if (debug_level >= DEBUG_LEVEL_INFO)
711 printk("mgslpc_release(0x%p)\n", link); 711 printk("mgslpc_release(0x%p)\n", link);
712 712
713 /* Unlink the device chain */ 713 pcmcia_disable_device(link->handle);
714 link->dev = NULL;
715 link->state &= ~DEV_CONFIG;
716
717 pcmcia_release_configuration(link->handle);
718 if (link->io.NumPorts1)
719 pcmcia_release_io(link->handle, &link->io);
720 if (link->irq.AssignedIRQ)
721 pcmcia_release_irq(link->handle, &link->irq);
722} 714}
723 715
724static void mgslpc_detach(struct pcmcia_device *p_dev) 716static void mgslpc_detach(struct pcmcia_device *p_dev)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 6213bd3caee5..024aad616484 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -369,14 +369,8 @@ void ide_release(dev_link_t *link)
369 ide_unregister(info->hd); 369 ide_unregister(info->hd);
370 } 370 }
371 info->ndev = 0; 371 info->ndev = 0;
372 link->dev = NULL;
373
374 pcmcia_release_configuration(link->handle);
375 pcmcia_release_io(link->handle, &link->io);
376 pcmcia_release_irq(link->handle, &link->irq);
377
378 link->state &= ~DEV_CONFIG;
379 372
373 pcmcia_disable_device(link->handle);
380} /* ide_release */ 374} /* ide_release */
381 375
382static int ide_suspend(struct pcmcia_device *dev) 376static int ide_suspend(struct pcmcia_device *dev)
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 2a2b03ff096b..f3889bdc8e43 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -367,16 +367,8 @@ found_port:
367 367
368static void avmcs_release(dev_link_t *link) 368static void avmcs_release(dev_link_t *link)
369{ 369{
370 b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); 370 b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
371 371 pcmcia_disable_device(link->handle);
372 /* Unlink the device chain */
373 link->dev = NULL;
374
375 /* Don't bother checking to see if these succeed or not */
376 pcmcia_release_configuration(link->handle);
377 pcmcia_release_io(link->handle, &link->io);
378 pcmcia_release_irq(link->handle, &link->irq);
379 link->state &= ~DEV_CONFIG;
380} /* avmcs_release */ 372} /* avmcs_release */
381 373
382static int avmcs_suspend(struct pcmcia_device *dev) 374static int avmcs_suspend(struct pcmcia_device *dev)
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 969da40c4248..729c2de0bc1d 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -373,21 +373,14 @@ found_port:
373 373
374static void avma1cs_release(dev_link_t *link) 374static void avma1cs_release(dev_link_t *link)
375{ 375{
376 local_info_t *local = link->priv; 376 local_info_t *local = link->priv;
377 377
378 DEBUG(0, "avma1cs_release(0x%p)\n", link); 378 DEBUG(0, "avma1cs_release(0x%p)\n", link);
379 379
380 /* no unregister function with hisax */ 380 /* now unregister function with hisax */
381 HiSax_closecard(local->node.minor); 381 HiSax_closecard(local->node.minor);
382 382
383 /* Unlink the device chain */ 383 pcmcia_disable_device(link->handle);
384 link->dev = NULL;
385
386 /* Don't bother checking to see if these succeed or not */
387 pcmcia_release_configuration(link->handle);
388 pcmcia_release_io(link->handle, &link->io);
389 pcmcia_release_irq(link->handle, &link->irq);
390 link->state &= ~DEV_CONFIG;
391} /* avma1cs_release */ 384} /* avma1cs_release */
392 385
393static int avma1cs_suspend(struct pcmcia_device *dev) 386static int avma1cs_suspend(struct pcmcia_device *dev)
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 062fb8f0739f..60c75c7c016e 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -380,16 +380,8 @@ static void elsa_cs_release(dev_link_t *link)
380 HiSax_closecard(local->cardnr); 380 HiSax_closecard(local->cardnr);
381 } 381 }
382 } 382 }
383 /* Unlink the device chain */ 383
384 link->dev = NULL; 384 pcmcia_disable_device(link->handle);
385
386 /* Don't bother checking to see if these succeed or not */
387 if (link->win)
388 pcmcia_release_window(link->win);
389 pcmcia_release_configuration(link->handle);
390 pcmcia_release_io(link->handle, &link->io);
391 pcmcia_release_irq(link->handle, &link->irq);
392 link->state &= ~DEV_CONFIG;
393} /* elsa_cs_release */ 385} /* elsa_cs_release */
394 386
395static int elsa_suspend(struct pcmcia_device *p_dev) 387static int elsa_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 6f5213a18a8d..e59539157d19 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -467,23 +467,8 @@ static void sedlbauer_release(dev_link_t *link)
467 HiSax_closecard(local->cardnr); 467 HiSax_closecard(local->cardnr);
468 } 468 }
469 } 469 }
470 /* Unlink the device chain */
471 link->dev = NULL;
472 470
473 /* 471 pcmcia_disable_device(link->handle);
474 In a normal driver, additional code may be needed to release
475 other kernel data structures associated with this device.
476 */
477
478 /* Don't bother checking to see if these succeed or not */
479 if (link->win)
480 pcmcia_release_window(link->win);
481 pcmcia_release_configuration(link->handle);
482 if (link->io.NumPorts1)
483 pcmcia_release_io(link->handle, &link->io);
484 if (link->irq.AssignedIRQ)
485 pcmcia_release_irq(link->handle, &link->irq);
486 link->state &= ~DEV_CONFIG;
487} /* sedlbauer_release */ 472} /* sedlbauer_release */
488 473
489static int sedlbauer_suspend(struct pcmcia_device *p_dev) 474static int sedlbauer_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 4e5c14c7240e..7945fd64621a 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -371,16 +371,8 @@ static void teles_cs_release(dev_link_t *link)
371 HiSax_closecard(local->cardnr); 371 HiSax_closecard(local->cardnr);
372 } 372 }
373 } 373 }
374 /* Unlink the device chain */ 374
375 link->dev = NULL; 375 pcmcia_disable_device(link->handle);
376
377 /* Don't bother checking to see if these succeed or not */
378 if (link->win)
379 pcmcia_release_window(link->win);
380 pcmcia_release_configuration(link->handle);
381 pcmcia_release_io(link->handle, &link->io);
382 pcmcia_release_irq(link->handle, &link->irq);
383 link->state &= ~DEV_CONFIG;
384} /* teles_cs_release */ 376} /* teles_cs_release */
385 377
386static int teles_suspend(struct pcmcia_device *p_dev) 378static int teles_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index ce90becb8bdf..1799660bdc67 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -511,13 +511,7 @@ failed:
511 511
512static void tc574_release(dev_link_t *link) 512static void tc574_release(dev_link_t *link)
513{ 513{
514 DEBUG(0, "3c574_release(0x%p)\n", link); 514 pcmcia_disable_device(link->handle);
515
516 pcmcia_release_configuration(link->handle);
517 pcmcia_release_io(link->handle, &link->io);
518 pcmcia_release_irq(link->handle, &link->irq);
519
520 link->state &= ~DEV_CONFIG;
521} 515}
522 516
523static int tc574_suspend(struct pcmcia_device *p_dev) 517static int tc574_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 3dba50849da7..e36153851793 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -386,13 +386,7 @@ failed:
386 386
387static void tc589_release(dev_link_t *link) 387static void tc589_release(dev_link_t *link)
388{ 388{
389 DEBUG(0, "3c589_release(0x%p)\n", link); 389 pcmcia_disable_device(link->handle);
390
391 pcmcia_release_configuration(link->handle);
392 pcmcia_release_io(link->handle, &link->io);
393 pcmcia_release_irq(link->handle, &link->irq);
394
395 link->state &= ~DEV_CONFIG;
396} 390}
397 391
398static int tc589_suspend(struct pcmcia_device *p_dev) 392static int tc589_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 1cc94b2d76c1..9b9c0f19b21c 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -456,13 +456,7 @@ failed:
456 456
457static void axnet_release(dev_link_t *link) 457static void axnet_release(dev_link_t *link)
458{ 458{
459 DEBUG(0, "axnet_release(0x%p)\n", link); 459 pcmcia_disable_device(link->handle);
460
461 pcmcia_release_configuration(link->handle);
462 pcmcia_release_io(link->handle, &link->io);
463 pcmcia_release_irq(link->handle, &link->irq);
464
465 link->state &= ~DEV_CONFIG;
466} 460}
467 461
468static int axnet_suspend(struct pcmcia_device *p_dev) 462static int axnet_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 2827a48ea37c..a0ec5e7aacc6 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -377,16 +377,8 @@ failed:
377 377
378static void com20020_release(dev_link_t *link) 378static void com20020_release(dev_link_t *link)
379{ 379{
380 380 DEBUG(0, "com20020_release(0x%p)\n", link);
381 DEBUG(1,"release...\n"); 381 pcmcia_disable_device(link->handle);
382
383 DEBUG(0, "com20020_release(0x%p)\n", link);
384
385 pcmcia_release_configuration(link->handle);
386 pcmcia_release_io(link->handle, &link->io);
387 pcmcia_release_irq(link->handle, &link->irq);
388
389 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
390} 382}
391 383
392static int com20020_suspend(struct pcmcia_device *p_dev) 384static int com20020_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index b7ac14ba8877..6b435e940607 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -674,16 +674,8 @@ static int fmvj18x_setup_mfc(dev_link_t *link)
674 674
675static void fmvj18x_release(dev_link_t *link) 675static void fmvj18x_release(dev_link_t *link)
676{ 676{
677 677 DEBUG(0, "fmvj18x_release(0x%p)\n", link);
678 DEBUG(0, "fmvj18x_release(0x%p)\n", link); 678 pcmcia_disable_device(link->handle);
679
680 /* Don't bother checking to see if these succeed or not */
681 pcmcia_release_window(link->win);
682 pcmcia_release_configuration(link->handle);
683 pcmcia_release_io(link->handle, &link->io);
684 pcmcia_release_irq(link->handle, &link->irq);
685
686 link->state &= ~DEV_CONFIG;
687} 679}
688 680
689static int fmvj18x_suspend(struct pcmcia_device *p_dev) 681static int fmvj18x_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b9c7e39576f5..1948a0bc198d 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -348,22 +348,17 @@ failed:
348 348
349static void ibmtr_release(dev_link_t *link) 349static void ibmtr_release(dev_link_t *link)
350{ 350{
351 ibmtr_dev_t *info = link->priv; 351 ibmtr_dev_t *info = link->priv;
352 struct net_device *dev = info->dev; 352 struct net_device *dev = info->dev;
353
354 DEBUG(0, "ibmtr_release(0x%p)\n", link);
355 353
356 pcmcia_release_configuration(link->handle); 354 DEBUG(0, "ibmtr_release(0x%p)\n", link);
357 pcmcia_release_io(link->handle, &link->io);
358 pcmcia_release_irq(link->handle, &link->irq);
359 if (link->win) {
360 struct tok_info *ti = netdev_priv(dev);
361 iounmap(ti->mmio);
362 pcmcia_release_window(link->win);
363 pcmcia_release_window(info->sram_win_handle);
364 }
365 355
366 link->state &= ~DEV_CONFIG; 356 if (link->win) {
357 struct tok_info *ti = netdev_priv(dev);
358 iounmap(ti->mmio);
359 pcmcia_release_window(info->sram_win_handle);
360 }
361 pcmcia_disable_device(link->handle);
367} 362}
368 363
369static int ibmtr_suspend(struct pcmcia_device *p_dev) 364static int ibmtr_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 787176c57fd9..76ef453d172d 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -765,14 +765,8 @@ nmclan_release
765---------------------------------------------------------------------------- */ 765---------------------------------------------------------------------------- */
766static void nmclan_release(dev_link_t *link) 766static void nmclan_release(dev_link_t *link)
767{ 767{
768 768 DEBUG(0, "nmclan_release(0x%p)\n", link);
769 DEBUG(0, "nmclan_release(0x%p)\n", link); 769 pcmcia_disable_device(link->handle);
770
771 pcmcia_release_configuration(link->handle);
772 pcmcia_release_io(link->handle, &link->io);
773 pcmcia_release_irq(link->handle, &link->irq);
774
775 link->state &= ~DEV_CONFIG;
776} 770}
777 771
778static int nmclan_suspend(struct pcmcia_device *p_dev) 772static int nmclan_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index b46e5f703efa..52f44bdff1f7 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -732,19 +732,14 @@ failed:
732 732
733static void pcnet_release(dev_link_t *link) 733static void pcnet_release(dev_link_t *link)
734{ 734{
735 pcnet_dev_t *info = PRIV(link->priv); 735 pcnet_dev_t *info = PRIV(link->priv);
736 736
737 DEBUG(0, "pcnet_release(0x%p)\n", link); 737 DEBUG(0, "pcnet_release(0x%p)\n", link);
738 738
739 if (info->flags & USE_SHMEM) { 739 if (info->flags & USE_SHMEM)
740 iounmap(info->base); 740 iounmap(info->base);
741 pcmcia_release_window(link->win);
742 }
743 pcmcia_release_configuration(link->handle);
744 pcmcia_release_io(link->handle, &link->io);
745 pcmcia_release_irq(link->handle, &link->irq);
746 741
747 link->state &= ~DEV_CONFIG; 742 pcmcia_disable_device(link->handle);
748} 743}
749 744
750/*====================================================================== 745/*======================================================================
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 8839c4faafd6..56700b154d44 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1181,20 +1181,13 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */
1181 1181
1182static void smc91c92_release(dev_link_t *link) 1182static void smc91c92_release(dev_link_t *link)
1183{ 1183{
1184 1184 DEBUG(0, "smc91c92_release(0x%p)\n", link);
1185 DEBUG(0, "smc91c92_release(0x%p)\n", link); 1185 if (link->win) {
1186 1186 struct net_device *dev = link->priv;
1187 pcmcia_release_configuration(link->handle); 1187 struct smc_private *smc = netdev_priv(dev);
1188 pcmcia_release_io(link->handle, &link->io); 1188 iounmap(smc->base);
1189 pcmcia_release_irq(link->handle, &link->irq); 1189 }
1190 if (link->win) { 1190 pcmcia_disable_device(link->handle);
1191 struct net_device *dev = link->priv;
1192 struct smc_private *smc = netdev_priv(dev);
1193 iounmap(smc->base);
1194 pcmcia_release_window(link->win);
1195 }
1196
1197 link->state &= ~DEV_CONFIG;
1198} 1191}
1199 1192
1200/*====================================================================== 1193/*======================================================================
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index eed496803fe4..2b57a87371f3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1090,21 +1090,15 @@ xirc2ps_config(dev_link_t * link)
1090static void 1090static void
1091xirc2ps_release(dev_link_t *link) 1091xirc2ps_release(dev_link_t *link)
1092{ 1092{
1093 DEBUG(0, "release(0x%p)\n", link);
1093 1094
1094 DEBUG(0, "release(0x%p)\n", link); 1095 if (link->win) {
1095 1096 struct net_device *dev = link->priv;
1096 if (link->win) { 1097 local_info_t *local = netdev_priv(dev);
1097 struct net_device *dev = link->priv; 1098 if (local->dingo)
1098 local_info_t *local = netdev_priv(dev); 1099 iounmap(local->dingo_ccr - 0x0800);
1099 if (local->dingo) 1100 }
1100 iounmap(local->dingo_ccr - 0x0800); 1101 pcmcia_disable_device(link->handle);
1101 pcmcia_release_window(link->win);
1102 }
1103 pcmcia_release_configuration(link->handle);
1104 pcmcia_release_io(link->handle, &link->io);
1105 pcmcia_release_irq(link->handle, &link->irq);
1106 link->state &= ~DEV_CONFIG;
1107
1108} /* xirc2ps_release */ 1102} /* xirc2ps_release */
1109 1103
1110/*====================================================================*/ 1104/*====================================================================*/
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index a496460ce224..489ef7f3d950 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -429,24 +429,7 @@ static void airo_config(dev_link_t *link)
429static void airo_release(dev_link_t *link) 429static void airo_release(dev_link_t *link)
430{ 430{
431 DEBUG(0, "airo_release(0x%p)\n", link); 431 DEBUG(0, "airo_release(0x%p)\n", link);
432 432 pcmcia_disable_device(link->handle);
433 /* Unlink the device chain */
434 link->dev = NULL;
435
436 /*
437 In a normal driver, additional code may be needed to release
438 other kernel data structures associated with this device.
439 */
440
441 /* Don't bother checking to see if these succeed or not */
442 if (link->win)
443 pcmcia_release_window(link->win);
444 pcmcia_release_configuration(link->handle);
445 if (link->io.NumPorts1)
446 pcmcia_release_io(link->handle, &link->io);
447 if (link->irq.AssignedIRQ)
448 pcmcia_release_irq(link->handle, &link->irq);
449 link->state &= ~DEV_CONFIG;
450} 433}
451 434
452static int airo_suspend(struct pcmcia_device *p_dev) 435static int airo_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index d6f4a5a3e55a..1da8e6197ffb 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -418,23 +418,14 @@ static void atmel_config(dev_link_t *link)
418static void atmel_release(dev_link_t *link) 418static void atmel_release(dev_link_t *link)
419{ 419{
420 struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; 420 struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
421 421
422 DEBUG(0, "atmel_release(0x%p)\n", link); 422 DEBUG(0, "atmel_release(0x%p)\n", link);
423 423
424 /* Unlink the device chain */ 424 if (dev)
425 link->dev = NULL;
426
427 if (dev)
428 stop_atmel_card(dev); 425 stop_atmel_card(dev);
429 ((local_info_t*)link->priv)->eth_dev = NULL; 426 ((local_info_t*)link->priv)->eth_dev = NULL;
430 427
431 /* Don't bother checking to see if these succeed or not */ 428 pcmcia_disable_device(link->handle);
432 pcmcia_release_configuration(link->handle);
433 if (link->io.NumPorts1)
434 pcmcia_release_io(link->handle, &link->io);
435 if (link->irq.AssignedIRQ)
436 pcmcia_release_irq(link->handle, &link->irq);
437 link->state &= ~DEV_CONFIG;
438} 429}
439 430
440static int atmel_suspend(struct pcmcia_device *dev) 431static int atmel_suspend(struct pcmcia_device *dev)
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index d335b250923a..7a1023f3875b 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -804,16 +804,7 @@ static void prism2_release(u_long arg)
804 iface->local->shutdown = 1; 804 iface->local->shutdown = 1;
805 } 805 }
806 806
807 if (link->win) 807 pcmcia_disable_device(link->handle);
808 pcmcia_release_window(link->win);
809 pcmcia_release_configuration(link->handle);
810 if (link->io.NumPorts1)
811 pcmcia_release_io(link->handle, &link->io);
812 if (link->irq.AssignedIRQ)
813 pcmcia_release_irq(link->handle, &link->irq);
814
815 link->state &= ~DEV_CONFIG;
816
817 PDEBUG(DEBUG_FLOW, "release - done\n"); 808 PDEBUG(DEBUG_FLOW, "release - done\n");
818} 809}
819 810
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 75ce6ddb0cf5..dfb47ac9da50 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -869,21 +869,14 @@ failed:
869 */ 869 */
870static void netwave_release(dev_link_t *link) 870static void netwave_release(dev_link_t *link)
871{ 871{
872 struct net_device *dev = link->priv; 872 struct net_device *dev = link->priv;
873 netwave_private *priv = netdev_priv(dev); 873 netwave_private *priv = netdev_priv(dev);
874
875 DEBUG(0, "netwave_release(0x%p)\n", link);
876 874
877 /* Don't bother checking to see if these succeed or not */ 875 DEBUG(0, "netwave_release(0x%p)\n", link);
878 if (link->win) {
879 iounmap(priv->ramBase);
880 pcmcia_release_window(link->win);
881 }
882 pcmcia_release_configuration(link->handle);
883 pcmcia_release_io(link->handle, &link->io);
884 pcmcia_release_irq(link->handle, &link->irq);
885 876
886 link->state &= ~DEV_CONFIG; 877 pcmcia_disable_device(link->handle);
878 if (link->win)
879 iounmap(priv->ramBase);
887} 880}
888 881
889static int netwave_suspend(struct pcmcia_device *p_dev) 882static int netwave_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index ec6f2a48895b..7fdc4ff55107 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -416,13 +416,7 @@ orinoco_cs_release(dev_link_t *link)
416 priv->hw_unavailable++; 416 priv->hw_unavailable++;
417 spin_unlock_irqrestore(&priv->lock, flags); 417 spin_unlock_irqrestore(&priv->lock, flags);
418 418
419 /* Don't bother checking to see if these succeed or not */ 419 pcmcia_disable_device(link->handle);
420 pcmcia_release_configuration(link->handle);
421 if (link->io.NumPorts1)
422 pcmcia_release_io(link->handle, &link->io);
423 if (link->irq.AssignedIRQ)
424 pcmcia_release_irq(link->handle, &link->irq);
425 link->state &= ~DEV_CONFIG;
426 if (priv->hw.iobase) 420 if (priv->hw.iobase)
427 ioport_unmap(priv->hw.iobase); 421 ioport_unmap(priv->hw.iobase);
428} /* orinoco_cs_release */ 422} /* orinoco_cs_release */
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 5fa6fbe35bb9..78320c1a1c15 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -894,13 +894,7 @@ spectrum_cs_release(dev_link_t *link)
894 priv->hw_unavailable++; 894 priv->hw_unavailable++;
895 spin_unlock_irqrestore(&priv->lock, flags); 895 spin_unlock_irqrestore(&priv->lock, flags);
896 896
897 /* Don't bother checking to see if these succeed or not */ 897 pcmcia_disable_device(link->handle);
898 pcmcia_release_configuration(link->handle);
899 if (link->io.NumPorts1)
900 pcmcia_release_io(link->handle, &link->io);
901 if (link->irq.AssignedIRQ)
902 pcmcia_release_irq(link->handle, &link->irq);
903 link->state &= ~DEV_CONFIG;
904 if (priv->hw.iobase) 898 if (priv->hw.iobase)
905 ioport_unmap(priv->hw.iobase); 899 ioport_unmap(priv->hw.iobase);
906} /* spectrum_cs_release */ 900} /* spectrum_cs_release */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 98122f3a4bc2..696aeb9d8f52 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4098,24 +4098,18 @@ wv_pcmcia_config(dev_link_t * link)
4098static void 4098static void
4099wv_pcmcia_release(dev_link_t *link) 4099wv_pcmcia_release(dev_link_t *link)
4100{ 4100{
4101 struct net_device * dev = (struct net_device *) link->priv; 4101 struct net_device * dev = (struct net_device *) link->priv;
4102 net_local * lp = netdev_priv(dev); 4102 net_local * lp = netdev_priv(dev);
4103 4103
4104#ifdef DEBUG_CONFIG_TRACE 4104#ifdef DEBUG_CONFIG_TRACE
4105 printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); 4105 printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
4106#endif 4106#endif
4107 4107
4108 /* Don't bother checking to see if these succeed or not */ 4108 iounmap(lp->mem);
4109 iounmap(lp->mem); 4109 pcmcia_disable_device(link->handle);
4110 pcmcia_release_window(link->win);
4111 pcmcia_release_configuration(link->handle);
4112 pcmcia_release_io(link->handle, &link->io);
4113 pcmcia_release_irq(link->handle, &link->irq);
4114
4115 link->state &= ~DEV_CONFIG;
4116 4110
4117#ifdef DEBUG_CONFIG_TRACE 4111#ifdef DEBUG_CONFIG_TRACE
4118 printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); 4112 printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
4119#endif 4113#endif
4120} 4114}
4121 4115
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 48e10b0c7e74..0c81b3e7d7ff 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -2149,16 +2149,10 @@ static void wl3501_release(dev_link_t *link)
2149 struct net_device *dev = link->priv; 2149 struct net_device *dev = link->priv;
2150 2150
2151 /* Unlink the device chain */ 2151 /* Unlink the device chain */
2152 if (link->dev) { 2152 if (link->dev)
2153 unregister_netdev(dev); 2153 unregister_netdev(dev);
2154 link->dev = NULL;
2155 }
2156 2154
2157 /* Don't bother checking to see if these succeed or not */ 2155 pcmcia_disable_device(link->handle);
2158 pcmcia_release_configuration(link->handle);
2159 pcmcia_release_io(link->handle, &link->io);
2160 pcmcia_release_irq(link->handle, &link->irq);
2161 link->state &= ~DEV_CONFIG;
2162} 2156}
2163 2157
2164static int wl3501_suspend(struct pcmcia_device *p_dev) 2158static int wl3501_suspend(struct pcmcia_device *p_dev)
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index d0fc8be56954..7edd7ef6c31f 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -267,23 +267,17 @@ failed:
267 267
268void parport_cs_release(dev_link_t *link) 268void parport_cs_release(dev_link_t *link)
269{ 269{
270 parport_info_t *info = link->priv; 270 parport_info_t *info = link->priv;
271
272 DEBUG(0, "parport_release(0x%p)\n", link);
273 271
274 if (info->ndev) { 272 DEBUG(0, "parport_release(0x%p)\n", link);
275 struct parport *p = info->port; 273
276 parport_pc_unregister_port(p); 274 if (info->ndev) {
277 } 275 struct parport *p = info->port;
278 info->ndev = 0; 276 parport_pc_unregister_port(p);
279 link->dev = NULL; 277 }
280 278 info->ndev = 0;
281 pcmcia_release_configuration(link->handle);
282 pcmcia_release_io(link->handle, &link->io);
283 pcmcia_release_irq(link->handle, &link->irq);
284
285 link->state &= ~DEV_CONFIG;
286 279
280 pcmcia_disable_device(link->handle);
287} /* parport_cs_release */ 281} /* parport_cs_release */
288 282
289static int parport_suspend(struct pcmcia_device *dev) 283static int parport_suspend(struct pcmcia_device *dev)
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index dbd5571064d1..555c8698ebd9 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -451,20 +451,20 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
451{ 451{
452 pccard_io_map io = { 0, 0, 0, 0, 1 }; 452 pccard_io_map io = { 0, 0, 0, 0, 1 };
453 struct pcmcia_socket *s = p_dev->socket; 453 struct pcmcia_socket *s = p_dev->socket;
454 config_t *c = p_dev->function_config;
454 int i; 455 int i;
455 456
456 if (!(p_dev->state & CLIENT_CONFIG_LOCKED)) 457 if (p_dev->state & CLIENT_CONFIG_LOCKED) {
457 return CS_BAD_HANDLE; 458 p_dev->state &= ~CLIENT_CONFIG_LOCKED;
458 p_dev->state &= ~CLIENT_CONFIG_LOCKED;
459
460 if (!(p_dev->state & CLIENT_STALE)) {
461 config_t *c = p_dev->function_config;
462 if (--(s->lock_count) == 0) { 459 if (--(s->lock_count) == 0) {
463 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ 460 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
464 s->socket.Vpp = 0; 461 s->socket.Vpp = 0;
465 s->socket.io_irq = 0; 462 s->socket.io_irq = 0;
466 s->ops->set_socket(s, &s->socket); 463 s->ops->set_socket(s, &s->socket);
467 } 464 }
465 }
466 if (c->state & CONFIG_LOCKED) {
467 c->state &= ~CONFIG_LOCKED;
468 if (c->state & CONFIG_IO_REQ) 468 if (c->state & CONFIG_IO_REQ)
469 for (i = 0; i < MAX_IO_WIN; i++) { 469 for (i = 0; i < MAX_IO_WIN; i++) {
470 if (!s->io[i].res) 470 if (!s->io[i].res)
@@ -475,7 +475,6 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
475 io.map = i; 475 io.map = i;
476 s->ops->set_io_map(s, &io); 476 s->ops->set_io_map(s, &io);
477 } 477 }
478 c->state &= ~CONFIG_LOCKED;
479 } 478 }
480 479
481 return CS_SUCCESS; 480 return CS_SUCCESS;
@@ -494,22 +493,20 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
494int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) 493int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
495{ 494{
496 struct pcmcia_socket *s = p_dev->socket; 495 struct pcmcia_socket *s = p_dev->socket;
496 config_t *c = p_dev->function_config;
497 497
498 if (!(p_dev->state & CLIENT_IO_REQ)) 498 if (!(p_dev->state & CLIENT_IO_REQ))
499 return CS_BAD_HANDLE; 499 return CS_BAD_HANDLE;
500
500 p_dev->state &= ~CLIENT_IO_REQ; 501 p_dev->state &= ~CLIENT_IO_REQ;
501 502
502 if (!(p_dev->state & CLIENT_STALE)) { 503 if ((c->io.BasePort1 != req->BasePort1) ||
503 config_t *c = p_dev->function_config; 504 (c->io.NumPorts1 != req->NumPorts1) ||
504 if (c->state & CONFIG_LOCKED) 505 (c->io.BasePort2 != req->BasePort2) ||
505 return CS_CONFIGURATION_LOCKED; 506 (c->io.NumPorts2 != req->NumPorts2))
506 if ((c->io.BasePort1 != req->BasePort1) || 507 return CS_BAD_ARGS;
507 (c->io.NumPorts1 != req->NumPorts1) || 508
508 (c->io.BasePort2 != req->BasePort2) || 509 c->state &= ~CONFIG_IO_REQ;
509 (c->io.NumPorts2 != req->NumPorts2))
510 return CS_BAD_ARGS;
511 c->state &= ~CONFIG_IO_REQ;
512 }
513 510
514 release_io_space(s, req->BasePort1, req->NumPorts1); 511 release_io_space(s, req->BasePort1, req->NumPorts1);
515 if (req->NumPorts2) 512 if (req->NumPorts2)
@@ -523,22 +520,21 @@ EXPORT_SYMBOL(pcmcia_release_io);
523int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) 520int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
524{ 521{
525 struct pcmcia_socket *s = p_dev->socket; 522 struct pcmcia_socket *s = p_dev->socket;
523 config_t *c= p_dev->function_config;
524
526 if (!(p_dev->state & CLIENT_IRQ_REQ)) 525 if (!(p_dev->state & CLIENT_IRQ_REQ))
527 return CS_BAD_HANDLE; 526 return CS_BAD_HANDLE;
528 p_dev->state &= ~CLIENT_IRQ_REQ; 527 p_dev->state &= ~CLIENT_IRQ_REQ;
529 528
530 if (!(p_dev->state & CLIENT_STALE)) { 529 if (c->state & CONFIG_LOCKED)
531 config_t *c= p_dev->function_config; 530 return CS_CONFIGURATION_LOCKED;
532 if (c->state & CONFIG_LOCKED) 531 if (c->irq.Attributes != req->Attributes)
533 return CS_CONFIGURATION_LOCKED; 532 return CS_BAD_ATTRIBUTE;
534 if (c->irq.Attributes != req->Attributes) 533 if (s->irq.AssignedIRQ != req->AssignedIRQ)
535 return CS_BAD_ATTRIBUTE; 534 return CS_BAD_IRQ;
536 if (s->irq.AssignedIRQ != req->AssignedIRQ) 535 if (--s->irq.Config == 0) {
537 return CS_BAD_IRQ; 536 c->state &= ~CONFIG_IRQ_REQ;
538 if (--s->irq.Config == 0) { 537 s->irq.AssignedIRQ = 0;
539 c->state &= ~CONFIG_IRQ_REQ;
540 s->irq.AssignedIRQ = 0;
541 }
542 } 538 }
543 539
544 if (req->Attributes & IRQ_HANDLE_PRESENT) { 540 if (req->Attributes & IRQ_HANDLE_PRESENT) {
@@ -929,3 +925,18 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
929 return CS_SUCCESS; 925 return CS_SUCCESS;
930} /* pcmcia_request_window */ 926} /* pcmcia_request_window */
931EXPORT_SYMBOL(pcmcia_request_window); 927EXPORT_SYMBOL(pcmcia_request_window);
928
929void pcmcia_disable_device(struct pcmcia_device *p_dev) {
930 if (!p_dev->instance)
931 return;
932
933 pcmcia_release_configuration(p_dev);
934 pcmcia_release_io(p_dev, &p_dev->instance->io);
935 pcmcia_release_irq(p_dev, &p_dev->instance->irq);
936 if (&p_dev->instance->win)
937 pcmcia_release_window(p_dev->instance->win);
938
939 p_dev->instance->dev = NULL;
940 p_dev->instance->state &= ~DEV_CONFIG;
941}
942EXPORT_SYMBOL(pcmcia_disable_device);
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 5609847e254a..e7f9d26a0d7c 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -248,13 +248,7 @@ static void aha152x_release_cs(dev_link_t *link)
248 scsi_info_t *info = link->priv; 248 scsi_info_t *info = link->priv;
249 249
250 aha152x_release(info->host); 250 aha152x_release(info->host);
251 link->dev = NULL; 251 pcmcia_disable_device(link->handle);
252
253 pcmcia_release_configuration(link->handle);
254 pcmcia_release_io(link->handle, &link->io);
255 pcmcia_release_irq(link->handle, &link->irq);
256
257 link->state &= ~DEV_CONFIG;
258} 252}
259 253
260static int aha152x_suspend(struct pcmcia_device *dev) 254static int aha152x_suspend(struct pcmcia_device *dev)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 788c58d805f3..fb7221cf511f 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -209,20 +209,13 @@ cs_failed:
209 209
210static void fdomain_release(dev_link_t *link) 210static void fdomain_release(dev_link_t *link)
211{ 211{
212 scsi_info_t *info = link->priv; 212 scsi_info_t *info = link->priv;
213
214 DEBUG(0, "fdomain_release(0x%p)\n", link);
215
216 scsi_remove_host(info->host);
217 link->dev = NULL;
218
219 pcmcia_release_configuration(link->handle);
220 pcmcia_release_io(link->handle, &link->io);
221 pcmcia_release_irq(link->handle, &link->irq);
222 213
223 scsi_unregister(info->host); 214 DEBUG(0, "fdomain_release(0x%p)\n", link);
224 215
225 link->state &= ~DEV_CONFIG; 216 scsi_remove_host(info->host);
217 pcmcia_disable_device(link->handle);
218 scsi_unregister(info->host);
226} 219}
227 220
228/*====================================================================*/ 221/*====================================================================*/
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 9e3ab3fd5355..dd383c538d98 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1974,16 +1974,9 @@ static void nsp_cs_release(dev_link_t *link)
1974 if (data != NULL) { 1974 if (data != NULL) {
1975 iounmap((void *)(data->MmioAddress)); 1975 iounmap((void *)(data->MmioAddress));
1976 } 1976 }
1977 pcmcia_release_window(link->win);
1978 } 1977 }
1979 pcmcia_release_configuration(link->handle); 1978 pcmcia_disable_device(link->handle);
1980 if (link->io.NumPorts1) { 1979
1981 pcmcia_release_io(link->handle, &link->io);
1982 }
1983 if (link->irq.AssignedIRQ) {
1984 pcmcia_release_irq(link->handle, &link->irq);
1985 }
1986 link->state &= ~DEV_CONFIG;
1987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) 1980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1988 if (info->host != NULL) { 1981 if (info->host != NULL) {
1989 scsi_host_put(info->host); 1982 scsi_host_put(info->host);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index dce7e687fd4a..70269fc10f30 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -289,6 +289,7 @@ out:
289cs_failed: 289cs_failed:
290 cs_error(link->handle, last_fn, last_ret); 290 cs_error(link->handle, last_fn, last_ret);
291 link->dev = NULL; 291 link->dev = NULL;
292
292 pcmcia_release_configuration(link->handle); 293 pcmcia_release_configuration(link->handle);
293 pcmcia_release_io(link->handle, &link->io); 294 pcmcia_release_io(link->handle, &link->io);
294 pcmcia_release_irq(link->handle, &link->irq); 295 pcmcia_release_irq(link->handle, &link->irq);
@@ -306,17 +307,11 @@ static void qlogic_release(dev_link_t *link)
306 DEBUG(0, "qlogic_release(0x%p)\n", link); 307 DEBUG(0, "qlogic_release(0x%p)\n", link);
307 308
308 scsi_remove_host(info->host); 309 scsi_remove_host(info->host);
309 link->dev = NULL;
310 310
311 free_irq(link->irq.AssignedIRQ, info->host); 311 free_irq(link->irq.AssignedIRQ, info->host);
312 312 pcmcia_disable_device(link->handle);
313 pcmcia_release_configuration(link->handle);
314 pcmcia_release_io(link->handle, &link->io);
315 pcmcia_release_irq(link->handle, &link->irq);
316 313
317 scsi_host_put(info->host); 314 scsi_host_put(info->host);
318
319 link->state &= ~DEV_CONFIG;
320} 315}
321 316
322/*====================================================================*/ 317/*====================================================================*/
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 3a4dd6f5b81f..42d002b6d1a5 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -550,13 +550,7 @@ SYM53C500_release(dev_link_t *link)
550 if (shost->io_port && shost->n_io_port) 550 if (shost->io_port && shost->n_io_port)
551 release_region(shost->io_port, shost->n_io_port); 551 release_region(shost->io_port, shost->n_io_port);
552 552
553 link->dev = NULL; 553 pcmcia_disable_device(link->handle);
554
555 pcmcia_release_configuration(link->handle);
556 pcmcia_release_io(link->handle, &link->io);
557 pcmcia_release_irq(link->handle, &link->irq);
558
559 link->state &= ~DEV_CONFIG;
560 554
561 scsi_host_put(shost); 555 scsi_host_put(shost);
562} /* SYM53C500_release */ 556} /* SYM53C500_release */
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 2307d9407a49..ff38820a03f5 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -141,11 +141,8 @@ static void serial_remove(dev_link_t *link)
141 141
142 info->link.dev = NULL; 142 info->link.dev = NULL;
143 143
144 if (!info->slave) { 144 if (!info->slave)
145 pcmcia_release_configuration(info->link.handle); 145 pcmcia_disable_device(link->handle);
146 pcmcia_release_io(info->link.handle, &info->link.io);
147 pcmcia_release_irq(info->link.handle, &info->link.irq);
148 }
149 146
150 info->link.state &= ~DEV_CONFIG; 147 info->link.state &= ~DEV_CONFIG;
151 } 148 }
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index eda32a595810..a5d8df24d56c 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -392,6 +392,8 @@ int pcmcia_eject_card(struct pcmcia_socket *skt);
392int pcmcia_insert_card(struct pcmcia_socket *skt); 392int pcmcia_insert_card(struct pcmcia_socket *skt);
393int pccard_reset_card(struct pcmcia_socket *skt); 393int pccard_reset_card(struct pcmcia_socket *skt);
394 394
395void pcmcia_disable_device(struct pcmcia_device *p_dev);
396
395struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt); 397struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
396void pcmcia_put_socket(struct pcmcia_socket *skt); 398void pcmcia_put_socket(struct pcmcia_socket *skt);
397 399
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 77caf43a3109..a2d3eb47f83c 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -62,13 +62,7 @@ static void snd_pdacf_detach(struct pcmcia_device *p_dev);
62 62
63static void pdacf_release(dev_link_t *link) 63static void pdacf_release(dev_link_t *link)
64{ 64{
65 if (link->state & DEV_CONFIG) { 65 pcmcia_disable_device(link->handle);
66 /* release cs resources */
67 pcmcia_release_configuration(link->handle);
68 pcmcia_release_io(link->handle, &link->io);
69 pcmcia_release_irq(link->handle, &link->irq);
70 link->state &= ~DEV_CONFIG;
71 }
72} 66}
73 67
74/* 68/*
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 66900d20a42f..92788744bc48 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -61,13 +61,7 @@ static unsigned int card_alloc;
61 */ 61 */
62static void vxpocket_release(dev_link_t *link) 62static void vxpocket_release(dev_link_t *link)
63{ 63{
64 if (link->state & DEV_CONFIG) { 64 pcmcia_disable_device(link->handle);
65 /* release cs resources */
66 pcmcia_release_configuration(link->handle);
67 pcmcia_release_io(link->handle, &link->io);
68 pcmcia_release_irq(link->handle, &link->irq);
69 link->state &= ~DEV_CONFIG;
70 }
71} 65}
72 66
73/* 67/*