[PATCH] pcmcia: new suspend core
Dominik Brodowski [Mon, 14 Nov 2005 20:21:18 +0000 (21:21 +0100)]
Move the suspend and resume methods out of the event handler, and into
special functions. Also use these functions for pre- and post-reset, as
almost all drivers already do, and the remaining ones can easily be
converted.

Bugfix to include/pcmcia/ds.c
Signed-off-by: Andrew Morton <akpm@osdl.org>

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>

45 files changed:
Documentation/pcmcia/driver-changes.txt
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/dtl1_cs.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/pcmcia/synclink_cs.c
drivers/ide/legacy/ide-cs.c
drivers/isdn/hardware/avm/avm_cs.c
drivers/isdn/hisax/avma1_cs.c
drivers/isdn/hisax/elsa_cs.c
drivers/isdn/hisax/sedlbauer_cs.c
drivers/isdn/hisax/teles_cs.c
drivers/mtd/maps/pcmciamtd.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/wireless/airo_cs.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/spectrum_cs.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/parport/parport_cs.c
drivers/pcmcia/ds.c
drivers/scsi/pcmcia/aha152x_stub.c
drivers/scsi/pcmcia/fdomain_stub.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/qlogic_stub.c
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/serial/serial_cs.c
drivers/telephony/ixj_pcmcia.c
drivers/usb/host/sl811_cs.c
include/pcmcia/ds.h

index 403e7b4..5c822f5 100644 (file)
@@ -1,5 +1,11 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* Move suspend, resume and reset out of event handler (as of 2.6.16)
+       int (*suspend)          (struct pcmcia_device *dev);
+       int (*resume)           (struct pcmcia_device *dev);
+  should be initialized in struct pcmcia_driver, and handle
+  (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
+
 * event handler initialization in struct pcmcia_driver (as of 2.6.13)
    The event handler is notified of all events, and must be initialized
    as the event() callback in the driver's struct pcmcia_driver.
index f36c563..5b24131 100644 (file)
@@ -1045,6 +1045,27 @@ static void bluecard_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int bluecard_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int bluecard_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
 
 static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
 {
@@ -1063,20 +1084,6 @@ static int bluecard_event(event_t event, int priority, event_callback_args_t *ar
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                bluecard_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
 
        return 0;
@@ -1099,6 +1106,8 @@ static struct pcmcia_driver bluecard_driver = {
        .event          = bluecard_event,
        .detach         = bluecard_detach,
        .id_table       = bluecard_ids,
+       .suspend        = bluecard_suspend,
+       .resume         = bluecard_resume,
 };
 
 static int __init init_bluecard_cs(void)
index d2a0add..1d524ba 100644 (file)
@@ -891,6 +891,27 @@ static void bt3c_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int bt3c_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int bt3c_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
 
 static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
 {
@@ -909,20 +930,6 @@ static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                bt3c_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
 
        return 0;
@@ -943,6 +950,8 @@ static struct pcmcia_driver bt3c_driver = {
        .event          = bt3c_event,
        .detach         = bt3c_detach,
        .id_table       = bt3c_ids,
+       .suspend        = bt3c_suspend,
+       .resume         = bt3c_resume,
 };
 
 static int __init init_bt3c_cs(void)
index 529a28a..1828ba6 100644 (file)
@@ -811,6 +811,28 @@ static void btuart_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int btuart_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int btuart_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 
 static int btuart_event(event_t event, int priority, event_callback_args_t *args)
 {
@@ -829,20 +851,6 @@ static int btuart_event(event_t event, int priority, event_callback_args_t *args
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                btuart_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
 
        return 0;
@@ -863,6 +871,8 @@ static struct pcmcia_driver btuart_driver = {
        .event          = btuart_event,
        .detach         = btuart_detach,
        .id_table       = btuart_ids,
+       .suspend        = btuart_suspend,
+       .resume         = btuart_resume,
 };
 
 static int __init init_btuart_cs(void)
index dec5980..9f9d3f9 100644 (file)
@@ -763,6 +763,27 @@ static void dtl1_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int dtl1_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int dtl1_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
 
 static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
 {
@@ -781,20 +802,6 @@ static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                dtl1_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
 
        return 0;
@@ -816,6 +823,8 @@ static struct pcmcia_driver dtl1_driver = {
        .event          = dtl1_event,
        .detach         = dtl1_detach,
        .id_table       = dtl1_ids,
+       .suspend        = dtl1_suspend,
+       .resume         = dtl1_resume,
 };
 
 static int __init init_dtl1_cs(void)
index 61681c9..05e9305 100644 (file)
@@ -1893,33 +1893,6 @@ static int cm4000_event(event_t event, int priority,
                link->state &= ~DEV_PRESENT;
                stop_monitor(dev);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-                     "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-               link->state |= DEV_SUSPEND;
-               /* fall-through */
-       case CS_EVENT_RESET_PHYSICAL:
-               DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-               if (link->state & DEV_CONFIG) {
-                       DEBUGP(5, dev, "ReleaseConfiguration\n");
-                       pcmcia_release_configuration(link->handle);
-               }
-               stop_monitor(dev);
-               break;
-       case CS_EVENT_PM_RESUME:
-               DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-                     "(fall-through to CS_EVENT_CARD_RESET)\n");
-               link->state &= ~DEV_SUSPEND;
-               /* fall-through */
-       case CS_EVENT_CARD_RESET:
-               DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-               if ((link->state & DEV_CONFIG)) {
-                       DEBUGP(5, dev, "RequestConfiguration\n");
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               }
-               if (link->open)
-                       start_monitor(dev);
-               break;
        default:
                DEBUGP(5, dev, "unknown event %.2x\n", event);
                break;
@@ -1928,6 +1901,38 @@ static int cm4000_event(event_t event, int priority,
        return CS_SUCCESS;
 }
 
+static int cm4000_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct cm4000_dev *dev;
+
+       dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+       stop_monitor(dev);
+
+       return 0;
+}
+
+static int cm4000_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct cm4000_dev *dev;
+
+       dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       if (link->open)
+               start_monitor(dev);
+
+       return 0;
+}
+
 static void cm4000_release(dev_link_t *link)
 {
        cmm_cm4000_release(link->priv); /* delay release until device closed */
@@ -2044,6 +2049,8 @@ static struct pcmcia_driver cm4000_driver = {
                },
        .attach   = cm4000_attach,
        .detach   = cm4000_detach,
+       .suspend  = cm4000_suspend,
+       .resume   = cm4000_resume,
        .event    = cm4000_event,
        .id_table = cm4000_ids,
 };
index 4c698d9..3622fd3 100644 (file)
@@ -656,31 +656,7 @@ static int reader_event(event_t event, int priority,
                        DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
                        link->state &= ~DEV_PRESENT;
                        break;
-               case CS_EVENT_PM_SUSPEND:
-                       DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-                             "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-                       link->state |= DEV_SUSPEND;
-
-               case CS_EVENT_RESET_PHYSICAL:
-                       DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-                       if (link->state & DEV_CONFIG) {
-                               DEBUGP(5, dev, "ReleaseConfiguration\n");
-                               pcmcia_release_configuration(link->handle);
-                       }
-                       break;
-               case CS_EVENT_PM_RESUME:
-                       DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-                             "(fall-through to CS_EVENT_CARD_RESET)\n");
-                       link->state &= ~DEV_SUSPEND;
-
-               case CS_EVENT_CARD_RESET:
-                       DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-                       if ((link->state & DEV_CONFIG)) {
-                               DEBUGP(5, dev, "RequestConfiguration\n");
-                               pcmcia_request_configuration(link->handle,
-                                                            &link->conf);
-                       }
-                       break;
+
                default:
                        DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
                               event);
@@ -690,6 +666,28 @@ static int reader_event(event_t event, int priority,
        return CS_SUCCESS;
 }
 
+static int reader_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int reader_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 static void reader_release(dev_link_t *link)
 {
        cm4040_reader_release(link->priv);
@@ -806,6 +804,8 @@ static struct pcmcia_driver reader_driver = {
        },
        .attach         = reader_attach,
        .detach         = reader_detach,
+       .suspend        = reader_suspend,
+       .resume         = reader_resume,
        .event          = reader_event,
        .id_table       = cm4040_ids,
 };
index 2c326ea..776103e 100644 (file)
@@ -773,11 +773,37 @@ static void mgslpc_detach(dev_link_t *link)
     mgslpc_remove_device((MGSLPC_INFO *)link->priv);
 }
 
+static int mgslpc_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       MGSLPC_INFO *info = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       info->stop = 1;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int mgslpc_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       MGSLPC_INFO *info = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+       info->stop = 0;
+
+       return 0;
+}
+
+
 static int mgslpc_event(event_t event, int priority,
                        event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    MGSLPC_INFO *info = link->priv;
     
     if (debug_level >= DEBUG_LEVEL_INFO)
            printk("mgslpc_event(0x%06x)\n", event);
@@ -794,23 +820,6 @@ static int mgslpc_event(event_t event, int priority,
            link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
            mgslpc_config(link);
            break;
-    case CS_EVENT_PM_SUSPEND:
-           link->state |= DEV_SUSPEND;
-           /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-           /* Mark the device as stopped, to block IO until later */
-           info->stop = 1;
-           if (link->state & DEV_CONFIG)
-                   pcmcia_release_configuration(link->handle);
-           break;
-    case CS_EVENT_PM_RESUME:
-           link->state &= ~DEV_SUSPEND;
-           /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-           if (link->state & DEV_CONFIG)
-                   pcmcia_request_configuration(link->handle, &link->conf);
-           info->stop = 0;
-           break;
     }
     return 0;
 }
@@ -3095,6 +3104,8 @@ static struct pcmcia_driver mgslpc_driver = {
        .event          = mgslpc_event,
        .detach         = mgslpc_detach,
        .id_table       = mgslpc_ids,
+       .suspend        = mgslpc_suspend,
+       .resume         = mgslpc_resume,
 };
 
 static struct tty_operations mgslpc_ops = {
index ef79805..982b74a 100644 (file)
@@ -406,6 +406,28 @@ void ide_release(dev_link_t *link)
 
 } /* ide_release */
 
+static int ide_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int ide_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -432,20 +454,6 @@ int ide_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        ide_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (DEV_OK(link))
-           pcmcia_request_configuration(link->handle, &link->conf);
-       break;
     }
     return 0;
 } /* ide_event */
@@ -498,6 +506,8 @@ static struct pcmcia_driver ide_cs_driver = {
        .event          = ide_event,
        .detach         = ide_detach,
        .id_table       = ide_ids,
+       .suspend        = ide_suspend,
+       .resume         = ide_resume,
 };
 
 static int __init init_ide_cs(void)
index 27391c3..6d9816e 100644 (file)
@@ -430,6 +430,28 @@ static void avmcs_release(dev_link_t *link)
     
 } /* avmcs_release */
 
+static int avmcs_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int avmcs_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -459,20 +481,6 @@ static int avmcs_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        avmcs_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG)
-           pcmcia_request_configuration(link->handle, &link->conf);
-       break;
     }
     return 0;
 } /* avmcs_event */
@@ -494,6 +502,8 @@ static struct pcmcia_driver avmcs_driver = {
        .event  = avmcs_event,
        .detach = avmcs_detach,
        .id_table = avmcs_ids,
+       .suspend= avmcs_suspend,
+       .resume = avmcs_resume,
 };
 
 static int __init avmcs_init(void)
index 5f5a5ae..433cec4 100644 (file)
@@ -445,6 +445,28 @@ static void avma1cs_release(dev_link_t *link)
        avma1cs_detach(link);
 } /* avma1cs_release */
 
+static int avma1cs_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int avma1cs_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -475,20 +497,6 @@ static int avma1cs_event(event_t event, int priority,
            link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
            avma1cs_config(link);
            break;
-       case CS_EVENT_PM_SUSPEND:
-           link->state |= DEV_SUSPEND;
-           /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-           if (link->state & DEV_CONFIG)
-               pcmcia_release_configuration(link->handle);
-           break;
-       case CS_EVENT_PM_RESUME:
-           link->state &= ~DEV_SUSPEND;
-           /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-           if (link->state & DEV_CONFIG)
-               pcmcia_request_configuration(link->handle, &link->conf);
-           break;
     }
     return 0;
 } /* avma1cs_event */
@@ -509,6 +517,8 @@ static struct pcmcia_driver avma1cs_driver = {
        .event          = avma1cs_event,
        .detach         = avma1cs_detach,
        .id_table       = avma1cs_ids,
+       .suspend        = avma1cs_suspend,
+       .resume         = avma1cs_resume,
 };
  
 /*====================================================================*/
index 6fc6868..0cbe045 100644 (file)
@@ -447,6 +447,32 @@ static void elsa_cs_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 } /* elsa_cs_release */
 
+static int elsa_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+        dev->busy = 1;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int elsa_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+        dev->busy = 0;
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -465,7 +491,6 @@ static int elsa_cs_event(event_t event, int priority,
                           event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
 
     DEBUG(1, "elsa_cs_event(%d)\n", event);
 
@@ -481,23 +506,6 @@ static int elsa_cs_event(event_t event, int priority,
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         elsa_cs_config(link);
         break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
-        dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
-        dev->busy = 0;
-        break;
     }
     return 0;
 } /* elsa_cs_event */
@@ -518,6 +526,8 @@ static struct pcmcia_driver elsa_cs_driver = {
        .event          = elsa_cs_event,
        .detach         = elsa_cs_detach,
        .id_table       = elsa_ids,
+       .suspend        = elsa_suspend,
+       .resume         = elsa_resume,
 };
 
 static int __init init_elsa_cs(void)
index dc334aa..27dce7c 100644 (file)
@@ -553,6 +553,32 @@ static void sedlbauer_release(dev_link_t *link)
     
 } /* sedlbauer_release */
 
+static int sedlbauer_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       dev->stop = 1;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int sedlbauer_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+       dev->stop = 0;
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -569,7 +595,6 @@ static int sedlbauer_event(event_t event, int priority,
                       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
     
     DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
     
@@ -585,27 +610,6 @@ static int sedlbauer_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        sedlbauer_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       /* Mark the device as stopped, to block IO until later */
-       dev->stop = 1;
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG)
-           pcmcia_request_configuration(link->handle, &link->conf);
-       dev->stop = 0;
-       /*
-         In a normal driver, additional code may go here to restore
-         the device state and restart IO. 
-       */
-       break;
     }
     return 0;
 } /* sedlbauer_event */
@@ -631,6 +635,8 @@ static struct pcmcia_driver sedlbauer_driver = {
        .event          = sedlbauer_event,
        .detach         = sedlbauer_detach,
        .id_table       = sedlbauer_ids,
+       .suspend        = sedlbauer_suspend,
+       .resume         = sedlbauer_resume,
 };
 
 static int __init init_sedlbauer_cs(void)
index 0ddef1b..70213bc 100644 (file)
@@ -428,6 +428,32 @@ static void teles_cs_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 } /* teles_cs_release */
 
+static int teles_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+        dev->busy = 1;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int teles_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+        dev->busy = 0;
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -446,7 +472,6 @@ static int teles_cs_event(event_t event, int priority,
                           event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
 
     DEBUG(1, "teles_cs_event(%d)\n", event);
 
@@ -462,23 +487,6 @@ static int teles_cs_event(event_t event, int priority,
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         teles_cs_config(link);
         break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
-        dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
-        dev->busy = 0;
-        break;
     }
     return 0;
 } /* teles_cs_event */
@@ -498,6 +506,8 @@ static struct pcmcia_driver teles_cs_driver = {
        .event          = teles_cs_event,
        .detach         = teles_detach,
        .id_table       = teles_ids,
+       .suspend        = teles_suspend,
+       .resume         = teles_resume,
 };
 
 static int __init init_teles_cs(void)
index af24216..86443cf 100644 (file)
@@ -691,6 +691,24 @@ static void pcmciamtd_config(dev_link_t *link)
 }
 
 
+static int pcmciamtd_suspend(struct pcmcia_device *dev)
+{
+       DEBUG(2, "EVENT_PM_RESUME");
+
+       /* get_lock(link); */
+
+       return 0;
+}
+
+static int pcmciamtd_resume(struct pcmcia_device *dev)
+{
+       DEBUG(2, "EVENT_PM_SUSPEND");
+
+       /* free_lock(link); */
+
+       return 0;
+}
+
 /* The card status event handler.  Mostly, this schedules other
  * stuff to run after an event is received.  A CARD_REMOVAL event
  * also sets some flags to discourage the driver from trying
@@ -721,22 +739,6 @@ static int pcmciamtd_event(event_t event, int priority,
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                pcmciamtd_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               DEBUG(2, "EVENT_PM_SUSPEND");
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               DEBUG(2, "EVENT_RESET_PHYSICAL");
-               /* get_lock(link); */
-               break;
-       case CS_EVENT_PM_RESUME:
-               DEBUG(2, "EVENT_PM_RESUME");
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               DEBUG(2, "EVENT_CARD_RESET");
-               /* free_lock(link); */
-               break;
        default:
                DEBUG(2, "Unknown event %d", event);
        }
@@ -848,6 +850,8 @@ static struct pcmcia_driver pcmciamtd_driver = {
        .detach         = pcmciamtd_detach,
        .owner          = THIS_MODULE,
        .id_table       = pcmciamtd_ids,
+       .suspend        = pcmciamtd_suspend,
+       .resume         = pcmciamtd_resume,
 };
 
 
index 71fd411..80414a7 100644 (file)
@@ -547,6 +547,38 @@ static void tc574_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int tc574_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int tc574_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       tc574_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 /*
        The card status event handler.  Mostly, this schedules other
        stuff to run after an event is received.  A CARD_REMOVAL event
@@ -572,28 +604,6 @@ static int tc574_event(event_t event, int priority,
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                tc574_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG) {
-                       if (link->open)
-                               netif_device_detach(dev);
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       if (link->open) {
-                               tc574_reset(dev);
-                               netif_device_attach(dev);
-                       }
-               }
-               break;
        }
        return 0;
 } /* tc574_event */
@@ -1296,6 +1306,8 @@ static struct pcmcia_driver tc574_driver = {
        .event          = tc574_event,
        .detach         = tc574_detach,
        .id_table       = tc574_ids,
+       .suspend        = tc574_suspend,
+       .resume         = tc574_resume,
 };
 
 static int __init init_tc574(void)
index d83fdd8..bbda681 100644 (file)
@@ -421,6 +421,38 @@ static void tc589_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
+static int tc589_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int tc589_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       tc589_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -448,28 +480,6 @@ static int tc589_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        tc589_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               tc589_reset(dev);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* tc589_event */
@@ -1071,6 +1081,8 @@ static struct pcmcia_driver tc589_driver = {
        .event          = tc589_event,
        .detach         = tc589_detach,
         .id_table       = tc589_ids,
+       .suspend        = tc589_suspend,
+       .resume         = tc589_resume,
 };
 
 static int __init init_tc589(void)
index 8bb4e85..6c6b252 100644 (file)
@@ -490,6 +490,40 @@ static void axnet_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
+static int axnet_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int axnet_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       axnet_reset_8390(dev);
+                       AX88190_init(dev, 1);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -517,29 +551,6 @@ static int axnet_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        axnet_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               axnet_reset_8390(dev);
-               AX88190_init(dev, 1);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* axnet_event */
@@ -881,6 +892,8 @@ static struct pcmcia_driver axnet_cs_driver = {
        .event          = axnet_event,
        .detach         = axnet_detach,
        .id_table       = axnet_ids,
+       .suspend        = axnet_suspend,
+       .resume         = axnet_resume,
 };
 
 static int __init init_axnet_cs(void)
index b9355d9..6861222 100644 (file)
@@ -421,6 +421,42 @@ static void com20020_release(dev_link_t *link)
     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
 }
 
+static int com20020_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       com20020_dev_t *info = link->priv;
+       struct net_device *dev = info->dev;
+
+       link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               if (link->open) {
+                       netif_device_detach(dev);
+               }
+               pcmcia_release_configuration(link->handle);
+        }
+
+       return 0;
+}
+
+static int com20020_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       com20020_dev_t *info = link->priv;
+       struct net_device *dev = info->dev;
+
+       link->state &= ~DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       int ioaddr = dev->base_addr;
+                       struct arcnet_local *lp = dev->priv;
+                       ARCRESET;
+               }
+        }
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -449,30 +485,6 @@ static int com20020_event(event_t event, int priority,
         link->state |= DEV_PRESENT;
        com20020_config(link); 
        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open) {
-                netif_device_detach(dev);
-            }
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-               int ioaddr = dev->base_addr;
-               struct arcnet_local *lp = dev->priv;
-               ARCRESET;
-            }
-        }
-        break;
     }
     return 0;
 } /* com20020_event */
@@ -492,6 +504,8 @@ static struct pcmcia_driver com20020_cs_driver = {
        .event          = com20020_event,
        .detach         = com20020_detach,
        .id_table       = com20020_ids,
+       .suspend        = com20020_suspend,
+       .resume         = com20020_resume,
 };
 
 static int __init init_com20020_cs(void)
index 356f509..388ecad 100644 (file)
@@ -713,6 +713,39 @@ static void fmvj18x_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
+static int fmvj18x_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+
+       return 0;
+}
+
+static int fmvj18x_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       fjn_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 /*====================================================================*/
 
 static int fmvj18x_event(event_t event, int priority,
@@ -733,28 +766,6 @@ static int fmvj18x_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        fmvj18x_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               fjn_reset(dev);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* fmvj18x_event */
@@ -793,6 +804,8 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
        .event          = fmvj18x_event,
        .detach         = fmvj18x_detach,
        .id_table       = fmvj18x_ids,
+       .suspend        = fmvj18x_suspend,
+       .resume         = fmvj18x_resume,
 };
 
 static int __init init_fmvj18x_cs(void)
index b6c140e..3a7218e 100644 (file)
@@ -401,6 +401,41 @@ static void ibmtr_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
+static int ibmtr_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       ibmtr_dev_t *info = link->priv;
+       struct net_device *dev = info->dev;
+
+       link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+        }
+
+       return 0;
+}
+
+static int ibmtr_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       ibmtr_dev_t *info = link->priv;
+       struct net_device *dev = info->dev;
+
+       link->state &= ~DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       ibmtr_probe(dev);       /* really? */
+                       netif_device_attach(dev);
+               }
+        }
+
+       return 0;
+}
+
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -433,28 +468,6 @@ static int ibmtr_event(event_t event, int priority,
         link->state |= DEV_PRESENT;
        ibmtr_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open)
-               netif_device_detach(dev);
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-               ibmtr_probe(dev);       /* really? */
-               netif_device_attach(dev);
-            }
-        }
-        break;
     }
     return 0;
 } /* ibmtr_event */
@@ -518,6 +531,8 @@ static struct pcmcia_driver ibmtr_cs_driver = {
        .event          = ibmtr_event,
        .detach         = ibmtr_detach,
        .id_table       = ibmtr_ids,
+       .suspend        = ibmtr_suspend,
+       .resume         = ibmtr_resume,
 };
 
 static int __init init_ibmtr_cs(void)
index 980d7e5..fa4921f 100644 (file)
@@ -801,6 +801,39 @@ static void nmclan_release(dev_link_t *link)
   link->state &= ~DEV_CONFIG;
 }
 
+static int nmclan_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+
+       return 0;
+}
+
+static int nmclan_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       nmclan_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 /* ----------------------------------------------------------------------------
 nmclan_event
        The card status event handler.  Mostly, this schedules other
@@ -826,28 +859,6 @@ static int nmclan_event(event_t event, int priority,
       link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
       nmclan_config(link);
       break;
-    case CS_EVENT_PM_SUSPEND:
-      link->state |= DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-      if (link->state & DEV_CONFIG) {
-       if (link->open)
-         netif_device_detach(dev);
-       pcmcia_release_configuration(link->handle);
-      }
-      break;
-    case CS_EVENT_PM_RESUME:
-      link->state &= ~DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-      if (link->state & DEV_CONFIG) {
-       pcmcia_request_configuration(link->handle, &link->conf);
-       if (link->open) {
-         nmclan_reset(dev);
-         netif_device_attach(dev);
-       }
-      }
-      break;
     case CS_EVENT_RESET_REQUEST:
       return 1;
       break;
@@ -1685,6 +1696,8 @@ static struct pcmcia_driver nmclan_cs_driver = {
        .event          = nmclan_event,
        .detach         = nmclan_detach,
        .id_table       = nmclan_ids,
+       .suspend        = nmclan_suspend,
+       .resume         = nmclan_resume,
 };
 
 static int __init init_nmclan_cs(void)
index 818c185..7db4d6f 100644 (file)
@@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *link)
 
 ======================================================================*/
 
+static int pcnet_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       pcnet_reset_8390(dev);
+                       NS8390_init(dev, 1);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 static int pcnet_event(event_t event, int priority,
                       event_callback_args_t *args)
 {
@@ -798,29 +831,6 @@ static int pcnet_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        pcnet_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               pcnet_reset_8390(dev);
-               NS8390_init(dev, 1);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* pcnet_event */
@@ -1849,6 +1859,8 @@ static struct pcmcia_driver pcnet_driver = {
        .detach         = pcnet_detach,
        .owner          = THIS_MODULE,
        .id_table       = pcnet_ids,
+       .suspend        = pcnet_suspend,
+       .resume         = pcnet_resume,
 };
 
 static int __init init_pcnet_cs(void)
index c7cca84..7c61ec9 100644 (file)
@@ -895,6 +895,62 @@ free_cfg_mem:
    return rc;
 }
 
+static int smc91c92_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int smc91c92_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+       struct smc_private *smc = netdev_priv(dev);
+       int i;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if ((smc->manfid == MANFID_MEGAHERTZ) &&
+                   (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+                       mhz_3288_power(link);
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (smc->manfid == MANFID_MOTOROLA)
+                       mot_config(link);
+               if ((smc->manfid == MANFID_OSITECH) &&
+                   (smc->cardid != PRODID_OSITECH_SEVEN)) {
+                       /* Power up the card and enable interrupts */
+                       set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
+                       set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
+               }
+               if (((smc->manfid == MANFID_OSITECH) &&
+                    (smc->cardid == PRODID_OSITECH_SEVEN)) ||
+                   ((smc->manfid == MANFID_PSION) &&
+                    (smc->cardid == PRODID_PSION_NET100))) {
+                       /* Download the Seven of Diamonds firmware */
+                       for (i = 0; i < sizeof(__Xilinx7OD); i++) {
+                               outb(__Xilinx7OD[i], link->io.BasePort1+2);
+                               udelay(50);
+                       }
+               }
+               if (link->open) {
+                       smc_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
+
 /*======================================================================
 
     This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +991,12 @@ static int check_sig(dev_link_t *link)
     }
 
     if (width) {
-       event_callback_args_t args;
        printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
-       args.client_data = link;
-       smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
+       smc91c92_suspend(link->handle);
        pcmcia_release_io(link->handle, &link->io);
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        pcmcia_request_io(link->handle, &link->io);
-       smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
+       smc91c92_resume(link->handle);
        return check_sig(link);
     }
     return -ENODEV;
@@ -1184,8 +1238,6 @@ static int smc91c92_event(event_t event, int priority,
 {
     dev_link_t *link = args->client_data;
     struct net_device *dev = link->priv;
-    struct smc_private *smc = netdev_priv(dev);
-    int i;
 
     DEBUG(1, "smc91c92_event(0x%06x)\n", event);
 
@@ -1199,49 +1251,6 @@ static int smc91c92_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        smc91c92_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           if ((smc->manfid == MANFID_MEGAHERTZ) &&
-               (smc->cardid == PRODID_MEGAHERTZ_EM3288))
-               mhz_3288_power(link);
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (smc->manfid == MANFID_MOTOROLA)
-               mot_config(link);
-           if ((smc->manfid == MANFID_OSITECH) &&
-               (smc->cardid != PRODID_OSITECH_SEVEN)) {
-               /* Power up the card and enable interrupts */
-               set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
-               set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
-           }
-           if (((smc->manfid == MANFID_OSITECH) &&
-               (smc->cardid == PRODID_OSITECH_SEVEN)) ||
-               ((smc->manfid == MANFID_PSION) &&
-               (smc->cardid == PRODID_PSION_NET100))) {
-               /* Download the Seven of Diamonds firmware */
-               for (i = 0; i < sizeof(__Xilinx7OD); i++) {
-                   outb(__Xilinx7OD[i], link->io.BasePort1+2);
-                   udelay(50);
-               }
-           }
-           if (link->open) {
-               smc_reset(dev);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* smc91c92_event */
@@ -2364,6 +2373,8 @@ static struct pcmcia_driver smc91c92_cs_driver = {
        .event          = smc91c92_event,
        .detach         = smc91c92_detach,
        .id_table       = smc91c92_ids,
+       .suspend        = smc91c92_suspend,
+       .resume         = smc91c92_resume,
 };
 
 static int __init init_smc91c92_cs(void)
index ce143f0..917e50a 100644 (file)
@@ -1157,6 +1157,41 @@ xirc2ps_release(dev_link_t *link)
 
 /*====================================================================*/
 
+
+static int xirc2ps_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open) {
+                       netif_device_detach(dev);
+                       do_powerdown(dev);
+               }
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int xirc2ps_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       do_reset(dev,1);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
 /****************
  * The card status event handler.  Mostly, this schedules other
  * stuff to run after an event is received.  A CARD_REMOVAL event
@@ -1191,30 +1226,6 @@ xirc2ps_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        xirc2ps_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open) {
-               netif_device_detach(dev);
-               do_powerdown(dev);
-           }
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               do_reset(dev,1);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* xirc2ps_event */
@@ -2013,6 +2024,8 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
        .event          = xirc2ps_event,
        .detach         = xirc2ps_detach,
        .id_table       = xirc2ps_ids,
+       .suspend        = xirc2ps_suspend,
+       .resume         = xirc2ps_resume,
 };
 
 static int __init
index e328547..80c9de7 100644 (file)
@@ -492,6 +492,35 @@ static void airo_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int airo_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *local = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               netif_device_detach(local->eth_dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int airo_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       local_info_t *local = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               reset_airo_card(local->eth_dev);
+               netif_device_attach(local->eth_dev);
+       }
+
+       return 0;
+}
+
 /*======================================================================
   
   The card status event handler.  Mostly, this schedules other
@@ -524,25 +553,6 @@ static int airo_event(event_t event, int priority,
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                airo_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG) {
-                       netif_device_detach(local->eth_dev);
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       reset_airo_card(local->eth_dev);
-                       netif_device_attach(local->eth_dev);
-               }
-               break;
        }
        return 0;
 } /* airo_event */
@@ -565,6 +575,8 @@ static struct pcmcia_driver airo_driver = {
        .event          = airo_event,
        .detach         = airo_detach,
        .id_table       = airo_ids,
+       .suspend        = airo_suspend,
+       .resume         = airo_resume,
 };
 
 static int airo_cs_init(void)
index 17d1fd9..598a9cd 100644 (file)
@@ -477,6 +477,35 @@ static void atmel_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int atmel_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       local_info_t *local = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               netif_device_detach(local->eth_dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int atmel_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       local_info_t *local = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               atmel_open(local->eth_dev);
+               netif_device_attach(local->eth_dev);
+       }
+
+       return 0;
+}
+
 /*======================================================================
   
   The card status event handler.  Mostly, this schedules other
@@ -509,25 +538,6 @@ static int atmel_event(event_t event, int priority,
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                atmel_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG) {
-                       netif_device_detach(local->eth_dev);
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       atmel_open(local->eth_dev);
-                       netif_device_attach(local->eth_dev);
-               }
-               break;
        }
        return 0;
 } /* atmel_event */
@@ -585,6 +595,8 @@ static struct pcmcia_driver atmel_driver = {
        .event          = atmel_event,
        .detach         = atmel_detach,
        .id_table       = atmel_ids,
+       .suspend        = atmel_suspend,
+       .resume         = atmel_resume,
 };
 
 static int atmel_cs_init(void)
index 2643976..ba4a7da 100644 (file)
@@ -846,20 +846,64 @@ static void prism2_release(u_long arg)
        PDEBUG(DEBUG_FLOW, "release - done\n");
 }
 
+static int hostap_cs_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = (struct net_device *) link->priv;
+       int dev_open = 0;
 
-static int prism2_event(event_t event, int priority,
-                       event_callback_args_t *args)
+       PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
+
+       link->state |= DEV_SUSPEND;
+
+       if (link->state & DEV_CONFIG) {
+               struct hostap_interface *iface = netdev_priv(dev);
+               if (iface && iface->local)
+                       dev_open = iface->local->num_dev_open > 0;
+               if (dev_open) {
+                       netif_stop_queue(dev);
+                       netif_device_detach(dev);
+               }
+               prism2_suspend(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int hostap_cs_resume(struct pcmcia_device *p_dev)
 {
-       dev_link_t *link = args->client_data;
+       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *dev = (struct net_device *) link->priv;
        int dev_open = 0;
 
+       PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
+
+       link->state &= ~DEV_SUSPEND;
        if (link->state & DEV_CONFIG) {
                struct hostap_interface *iface = netdev_priv(dev);
                if (iface && iface->local)
                        dev_open = iface->local->num_dev_open > 0;
+
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+               prism2_hw_shutdown(dev, 1);
+               prism2_hw_config(dev, dev_open ? 0 : 1);
+               if (dev_open) {
+                       netif_device_attach(dev);
+                       netif_start_queue(dev);
+               }
        }
 
+       return 0;
+}
+
+static int prism2_event(event_t event, int priority,
+                       event_callback_args_t *args)
+{
+       dev_link_t *link = args->client_data;
+       struct net_device *dev = (struct net_device *) link->priv;
+
        switch (event) {
        case CS_EVENT_CARD_INSERTION:
                PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
@@ -879,42 +923,6 @@ static int prism2_event(event_t event, int priority,
                }
                break;
 
-       case CS_EVENT_PM_SUSPEND:
-               PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
-               link->state |= DEV_SUSPEND;
-               /* fall through */
-
-       case CS_EVENT_RESET_PHYSICAL:
-               PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
-               if (link->state & DEV_CONFIG) {
-                       if (dev_open) {
-                               netif_stop_queue(dev);
-                               netif_device_detach(dev);
-                       }
-                       prism2_suspend(dev);
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
-               link->state &= ~DEV_SUSPEND;
-               /* fall through */
-
-       case CS_EVENT_CARD_RESET:
-               PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle,
-                                                    &link->conf);
-                       prism2_hw_shutdown(dev, 1);
-                       prism2_hw_config(dev, dev_open ? 0 : 1);
-                       if (dev_open) {
-                               netif_device_attach(dev);
-                               netif_start_queue(dev);
-                       }
-               }
-               break;
-
        default:
                PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
                       dev_info, event);
@@ -987,6 +995,8 @@ static struct pcmcia_driver hostap_driver = {
        .owner          = THIS_MODULE,
        .event          = prism2_event,
        .id_table       = hostap_cs_ids,
+       .suspend        = hostap_cs_suspend,
+       .resume         = hostap_cs_resume,
 };
 
 static int __init init_prism2_pccard(void)
index 92793b9..7ab2d70 100644 (file)
@@ -935,6 +935,39 @@ static void netwave_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
+static int netwave_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int netwave_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       netwave_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
+
 /*
  * Function netwave_event (event, priority, args)
  *
@@ -973,28 +1006,6 @@ static int netwave_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        netwave_pcmcia_config( link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG) {
-           if (link->open)
-               netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-       }
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if (link->open) {
-               netwave_reset(dev);
-               netif_device_attach(dev);
-           }
-       }
-       break;
     }
     return 0;
 } /* netwave_event */
@@ -1495,6 +1506,8 @@ static struct pcmcia_driver netwave_driver = {
        .event          = netwave_event,
        .detach         = netwave_detach,
        .id_table       = netwave_ids,
+       .suspend        = netwave_suspend,
+       .resume         = netwave_resume,
 };
 
 static int __init init_netwave_cs(void)
index dc1128a..1d66050 100644 (file)
@@ -465,6 +465,83 @@ orinoco_cs_release(dev_link_t *link)
                ioport_unmap(priv->hw.iobase);
 }                              /* orinoco_cs_release */
 
+static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       int err = 0;
+       unsigned long flags;
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               /* This is probably racy, but I can't think of
+                  a better way, short of rewriting the PCMCIA
+                  layer to not suck :-( */
+               if (! test_bit(0, &card->hard_reset_in_progress)) {
+                       spin_lock_irqsave(&priv->lock, flags);
+
+                       err = __orinoco_down(dev);
+                       if (err)
+                               printk(KERN_WARNING "%s: Error %d downing interface\n",
+                                      dev->name, err);
+
+                       netif_device_detach(dev);
+                       priv->hw_unavailable++;
+
+                       spin_unlock_irqrestore(&priv->lock, flags);
+               }
+
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int orinoco_cs_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       int err = 0;
+       unsigned long flags;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               /* FIXME: should we double check that this is
+                * the same card as we had before */
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+               if (! test_bit(0, &card->hard_reset_in_progress)) {
+                       err = orinoco_reinit_firmware(dev);
+                       if (err) {
+                               printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+                                      dev->name, err);
+                               return -EIO;
+                       }
+
+                       spin_lock_irqsave(&priv->lock, flags);
+
+                       netif_device_attach(dev);
+                       priv->hw_unavailable--;
+
+                       if (priv->open && ! priv->hw_unavailable) {
+                               err = __orinoco_up(dev);
+                               if (err)
+                                       printk(KERN_ERR "%s: Error %d restarting card\n",
+                                              dev->name, err);
+                       }
+
+                       spin_unlock_irqrestore(&priv->lock, flags);
+               }
+       }
+
+       return 0;
+}
+
+
 /*
  * The card status event handler.  Mostly, this schedules other stuff
  * to run after an event is received.
@@ -476,9 +553,7 @@ orinoco_cs_event(event_t event, int priority,
        dev_link_t *link = args->client_data;
        struct net_device *dev = link->priv;
        struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pccard *card = priv->card;
        int err = 0;
-       unsigned long flags;
 
        switch (event) {
        case CS_EVENT_CARD_REMOVAL:
@@ -497,70 +572,6 @@ orinoco_cs_event(event_t event, int priority,
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                orinoco_cs_config(link);
                break;
-
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               /* Mark the device as stopped, to block IO until later */
-               if (link->state & DEV_CONFIG) {
-                       /* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-                       if (! test_bit(0, &card->hard_reset_in_progress)) {
-                               spin_lock_irqsave(&priv->lock, flags);
-
-                               err = __orinoco_down(dev);
-                               if (err)
-                                       printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-                                              dev->name,
-                                              event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-                                              err);
-                               
-                               netif_device_detach(dev);
-                               priv->hw_unavailable++;
-
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                       }
-
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       /* FIXME: should we double check that this is
-                        * the same card as we had before */
-                       pcmcia_request_configuration(link->handle, &link->conf);
-
-                       if (! test_bit(0, &card->hard_reset_in_progress)) {
-                               err = orinoco_reinit_firmware(dev);
-                               if (err) {
-                                       printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-                                              dev->name, err);
-                                       break;
-                               }
-                               
-                               spin_lock_irqsave(&priv->lock, flags);
-                               
-                               netif_device_attach(dev);
-                               priv->hw_unavailable--;
-                               
-                               if (priv->open && ! priv->hw_unavailable) {
-                                       err = __orinoco_up(dev);
-                                       if (err)
-                                               printk(KERN_ERR "%s: Error %d restarting card\n",
-                                                      dev->name, err);
-                                       
-                               }
-
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                       }
-               }
-               break;
        }
 
        return err;
@@ -669,6 +680,8 @@ static struct pcmcia_driver orinoco_driver = {
        .detach         = orinoco_cs_detach,
        .event          = orinoco_cs_event,
        .id_table       = orinoco_cs_ids,
+       .suspend        = orinoco_cs_suspend,
+       .resume         = orinoco_cs_resume,
 };
 
 static int __init
index 70fd6fd..c2cb6c8 100644 (file)
@@ -891,6 +891,40 @@ static void ray_release(dev_link_t *link)
     DEBUG(2,"ray_release ending\n");
 }
 
+static int ray_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+
+               pcmcia_release_configuration(link->handle);
+        }
+
+
+       return 0;
+}
+
+static int ray_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       ray_reset(dev);
+                       netif_device_attach(dev);
+               }
+        }
+
+       return 0;
+}
+
 /*=============================================================================
     The card status event handler.  Mostly, this schedules other
     stuff to run after an event is received.  A CARD_REMOVAL event
@@ -923,29 +957,6 @@ static int ray_event(event_t event, int priority,
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         ray_config(link);
         break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open)
-               netif_device_detach(dev);
-
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-                ray_reset(dev);
-               netif_device_attach(dev);
-            }
-        }
-        break;
     }
     return 0;
     DEBUG(2,"ray_event ending\n");
@@ -2949,6 +2960,8 @@ static struct pcmcia_driver ray_driver = {
        .event          = ray_event,
        .detach         = ray_detach,
        .id_table       = ray_ids,
+       .suspend        = ray_suspend,
+       .resume         = ray_resume,
 };
 
 static int __init init_ray_cs(void)
index b1bbc8e..3938a57 100644 (file)
@@ -948,6 +948,56 @@ spectrum_cs_release(dev_link_t *link)
                ioport_unmap(priv->hw.iobase);
 }                              /* spectrum_cs_release */
 
+
+static int
+spectrum_cs_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err = 0;
+
+       link->state |= DEV_SUSPEND;
+       /* Mark the device as stopped, to block IO until later */
+       if (link->state & DEV_CONFIG) {
+               spin_lock_irqsave(&priv->lock, flags);
+
+               err = __orinoco_down(dev);
+               if (err)
+                       printk(KERN_WARNING "%s: Error %d downing interface\n",
+                              dev->name, err);
+
+               netif_device_detach(dev);
+               priv->hw_unavailable++;
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int
+spectrum_cs_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               /* FIXME: should we double check that this is
+                * the same card as we had before */
+               pcmcia_request_configuration(link->handle, &link->conf);
+               netif_device_attach(dev);
+               priv->hw_unavailable--;
+               schedule_work(&priv->reset_work);
+       }
+       return 0;
+}
+
 /*
  * The card status event handler.  Mostly, this schedules other stuff
  * to run after an event is received.
@@ -959,8 +1009,6 @@ spectrum_cs_event(event_t event, int priority,
        dev_link_t *link = args->client_data;
        struct net_device *dev = link->priv;
        struct orinoco_private *priv = netdev_priv(dev);
-       int err = 0;
-       unsigned long flags;
 
        switch (event) {
        case CS_EVENT_CARD_REMOVAL:
@@ -980,49 +1028,9 @@ spectrum_cs_event(event_t event, int priority,
                spectrum_cs_config(link);
                break;
 
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               /* Mark the device as stopped, to block IO until later */
-               if (link->state & DEV_CONFIG) {
-                       /* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-                       spin_lock_irqsave(&priv->lock, flags);
-
-                       err = __orinoco_down(dev);
-                       if (err)
-                               printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-                                      dev->name,
-                                      event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-                                      err);
-
-                       netif_device_detach(dev);
-                       priv->hw_unavailable++;
-
-                       spin_unlock_irqrestore(&priv->lock, flags);
-
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       /* FIXME: should we double check that this is
-                        * the same card as we had before */
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       netif_device_attach(dev);
-                       priv->hw_unavailable--;
-                       schedule_work(&priv->reset_work);
-               }
-               break;
        }
 
-       return err;
+       return 0;
 }                              /* spectrum_cs_event */
 
 /********************************************************************/
@@ -1050,6 +1058,8 @@ static struct pcmcia_driver orinoco_driver = {
        },
        .attach         = spectrum_cs_attach,
        .detach         = spectrum_cs_detach,
+       .suspend        = spectrum_cs_suspend,
+       .resume         = spectrum_cs_resume,
        .event          = spectrum_cs_event,
        .id_table       = spectrum_cs_ids,
 };
index c822cad..3e35328 100644 (file)
@@ -4775,6 +4775,56 @@ wavelan_detach(dev_link_t *      link)
 #endif
 }
 
+static int wavelan_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *     dev = (struct net_device *) link->priv;
+
+       /* NB: wavelan_close will be called, but too late, so we are
+        * obliged to close nicely the wavelan here. David, could you
+        * close the device before suspending them ? And, by the way,
+        * could you, on resume, add a "route add -net ..." after the
+        * ifconfig up ? Thanks... */
+
+       /* Stop receiving new messages and wait end of transmission */
+       wv_ru_stop(dev);
+
+       /* Power down the module */
+       hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
+
+       /* The card is now suspended */
+       link->state |= DEV_SUSPEND;
+
+       if(link->state & DEV_CONFIG)
+       {
+               if(link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int wavelan_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *     dev = (struct net_device *) link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if(link->state & DEV_CONFIG)
+       {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if(link->open)  /* If RESET -> True, If RESUME -> False ? */
+               {
+                       wv_hw_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
+
 /*------------------------------------------------------------------*/
 /*
  * The card status event handler. Mostly, this schedules other stuff
@@ -4832,46 +4882,6 @@ wavelan_event(event_t            event,          /* The event received */
        else
          dev->irq = 0;
        break;
-
-      case CS_EVENT_PM_SUSPEND:
-       /* NB: wavelan_close will be called, but too late, so we are
-        * obliged to close nicely the wavelan here. David, could you
-        * close the device before suspending them ? And, by the way,
-        * could you, on resume, add a "route add -net ..." after the
-        * ifconfig up ? Thanks... */
-
-       /* Stop receiving new messages and wait end of transmission */
-       wv_ru_stop(dev);
-
-       /* Power down the module */
-       hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
-
-       /* The card is now suspended */
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-      case CS_EVENT_RESET_PHYSICAL:
-       if(link->state & DEV_CONFIG)
-         {
-           if(link->open)
-             netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-         }
-       break;
-
-      case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-      case CS_EVENT_CARD_RESET:
-       if(link->state & DEV_CONFIG)
-         {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if(link->open)      /* If RESET -> True, If RESUME -> False ? */
-             {
-               wv_hw_reset(dev);
-               netif_device_attach(dev);
-             }
-         }
-       break;
     }
 
 #ifdef DEBUG_CALLBACK_TRACE
@@ -4898,6 +4908,8 @@ static struct pcmcia_driver wavelan_driver = {
        .event          = wavelan_event,
        .detach         = wavelan_detach,
        .id_table       = wavelan_ids,
+       .suspend        = wavelan_suspend,
+       .resume         = wavelan_resume,
 };
 
 static int __init
index 978fdc6..7511431 100644 (file)
@@ -2173,6 +2173,41 @@ static void wl3501_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int wl3501_suspend(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       link->state |= DEV_SUSPEND;
+
+       wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
+       if (link->state & DEV_CONFIG) {
+               if (link->open)
+                       netif_device_detach(dev);
+               pcmcia_release_configuration(link->handle);
+       }
+
+       return 0;
+}
+
+static int wl3501_resume(struct pcmcia_device *p_dev)
+{
+       dev_link_t *link = dev_to_instance(p_dev);
+       struct net_device *dev = link->priv;
+
+       wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if (link->open) {
+                       wl3501_reset(dev);
+                       netif_device_attach(dev);
+               }
+       }
+
+       return 0;
+}
+
+
 /**
  * wl3501_event - The card status event handler
  * @event - event
@@ -2206,30 +2241,6 @@ static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                wl3501_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG) {
-                       if (link->open)
-                               netif_device_detach(dev);
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       if (link->open) {
-                               wl3501_reset(dev);
-                               netif_device_attach(dev);
-                       }
-               }
-               break;
        }
        return 0;
 }
@@ -2249,6 +2260,8 @@ static struct pcmcia_driver wl3501_driver = {
        .event          = wl3501_event,
        .detach         = wl3501_detach,
        .id_table       = wl3501_ids,
+       .suspend        = wl3501_suspend,
+       .resume         = wl3501_resume,
 };
 
 static int __init wl3501_init_module(void)
index 24e6aac..4c89853 100644 (file)
@@ -325,6 +325,28 @@ void parport_cs_release(dev_link_t *link)
 
 } /* parport_cs_release */
 
+static int parport_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int parport_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -349,20 +371,6 @@ int parport_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        parport_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (DEV_OK(link))
-           pcmcia_request_configuration(link->handle, &link->conf);
-       break;
     }
     return 0;
 } /* parport_event */
@@ -383,7 +391,8 @@ static struct pcmcia_driver parport_cs_driver = {
        .event          = parport_event,
        .detach         = parport_detach,
        .id_table       = parport_ids,
-
+       .suspend        = parport_suspend,
+       .resume         = parport_resume,
 };
 
 static int __init init_parport_cs(void)
index b120794..a802c65 100644 (file)
@@ -951,6 +951,16 @@ static int send_event_callback(struct device *dev, void * _data)
        if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
                return 0;
 
+       if ((data->event == CS_EVENT_PM_SUSPEND) ||
+           (data->event == CS_EVENT_RESET_PHYSICAL)) {
+               if (p_drv->suspend)
+                       return p_drv->suspend(p_dev);
+       } else if ((data->event == CS_EVENT_PM_RESUME) ||
+                  (data->event == CS_EVENT_CARD_RESET)) {
+               if (p_drv->resume)
+                       return p_drv->resume(p_dev);
+       }
+
        if (p_drv->event)
                return p_drv->event(data->event, data->priority,
                                    &p_dev->event_callback_args);
index 7c53064..82988a3 100644 (file)
@@ -272,11 +272,37 @@ static void aha152x_release_cs(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int aha152x_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int aha152x_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       scsi_info_t *info = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               Scsi_Cmnd tmp;
+               pcmcia_request_configuration(link->handle, &link->conf);
+               tmp.device->host = info->host;
+               aha152x_host_reset(&tmp);
+       }
+
+       return 0;
+}
+
 static int aha152x_event(event_t event, int priority,
                         event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    scsi_info_t *info = link->priv;
     
     DEBUG(0, "aha152x_event(0x%06x)\n", event);
     
@@ -290,24 +316,6 @@ static int aha152x_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        aha152x_config_cs(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           Scsi_Cmnd tmp;
-           pcmcia_request_configuration(link->handle, &link->conf);
-           tmp.device->host = info->host;
-           aha152x_host_reset(&tmp);
-       }
-       break;
     }
     return 0;
 }
@@ -331,6 +339,8 @@ static struct pcmcia_driver aha152x_cs_driver = {
        .event          = aha152x_event,
        .detach         = aha152x_detach,
        .id_table       = aha152x_ids,
+       .suspend        = aha152x_suspend,
+       .resume         = aha152x_resume,
 };
 
 static int __init init_aha152x_cs(void)
index db8f5cd..9e1d68c 100644 (file)
@@ -256,6 +256,30 @@ static void fdomain_release(dev_link_t *link)
 
 /*====================================================================*/
 
+static int fdomain_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int fdomain_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+               fdomain_16x0_bus_reset(NULL);
+       }
+
+       return 0;
+}
+
 static int fdomain_event(event_t event, int priority,
                        event_callback_args_t *args)
 {
@@ -273,22 +297,6 @@ static int fdomain_event(event_t event, int priority,
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        fdomain_config(link);
        break;
-    case CS_EVENT_PM_SUSPEND:
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-       if (link->state & DEV_CONFIG)
-           pcmcia_release_configuration(link->handle);
-       break;
-    case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-       if (link->state & DEV_CONFIG) {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           fdomain_16x0_bus_reset(NULL);
-       }
-       break;
     }
     return 0;
 } /* fdomain_event */
@@ -311,6 +319,8 @@ static struct pcmcia_driver fdomain_cs_driver = {
        .event          = fdomain_event,
        .detach         = fdomain_detach,
        .id_table       = fdomain_ids,
+       .suspend        = fdomain_suspend,
+       .resume         = fdomain_resume,
 };
 
 static int __init init_fdomain_cs(void)
index 050ea13..870e871 100644 (file)
@@ -2021,6 +2021,59 @@ static void nsp_cs_release(dev_link_t *link)
 #endif
 } /* nsp_cs_release */
 
+static int nsp_cs_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       scsi_info_t *info = link->priv;
+       nsp_hw_data *data;
+
+       link->state |= DEV_SUSPEND;
+
+       nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
+
+       if (info->host != NULL) {
+               nsp_msg(KERN_INFO, "clear SDTR status");
+
+               data = (nsp_hw_data *)info->host->hostdata;
+
+               nsphw_init_sync(data);
+       }
+
+       info->stop = 1;
+
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int nsp_cs_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       scsi_info_t *info = link->priv;
+       nsp_hw_data *data;
+
+       nsp_dbg(NSP_DEBUG_INIT, "event: resume");
+
+       link->state &= ~DEV_SUSPEND;
+
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       info->stop = 0;
+
+       if (info->host != NULL) {
+               nsp_msg(KERN_INFO, "reset host and bus");
+
+               data = (nsp_hw_data *)info->host->hostdata;
+
+               nsphw_init   (data);
+               nsp_bus_reset(data);
+       }
+
+       return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -2039,8 +2092,6 @@ static int nsp_cs_event(event_t                  event,
                        event_callback_args_t *args)
 {
        dev_link_t  *link = args->client_data;
-       scsi_info_t *info = link->priv;
-       nsp_hw_data *data;
 
        nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
 
@@ -2062,51 +2113,6 @@ static int nsp_cs_event(event_t                 event,
 #endif
                nsp_cs_config(link);
                break;
-
-       case CS_EVENT_PM_SUSPEND:
-               nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               /* Mark the device as stopped, to block IO until later */
-               nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
-
-               if (info->host != NULL) {
-                       nsp_msg(KERN_INFO, "clear SDTR status");
-
-                       data = (nsp_hw_data *)info->host->hostdata;
-
-                       nsphw_init_sync(data);
-               }
-
-               info->stop = 1;
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_release_configuration(link->handle);
-               }
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               nsp_dbg(NSP_DEBUG_INIT, "event: resume");
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               nsp_dbg(NSP_DEBUG_INIT, "event: reset");
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               }
-               info->stop = 0;
-
-               if (info->host != NULL) {
-                       nsp_msg(KERN_INFO, "reset host and bus");
-
-                       data = (nsp_hw_data *)info->host->hostdata;
-
-                       nsphw_init   (data);
-                       nsp_bus_reset(data);
-               }
-
-               break;
-
        default:
                nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
                break;
@@ -2140,6 +2146,8 @@ static struct pcmcia_driver nsp_driver = {
        .event          = nsp_cs_event,
        .detach         = nsp_cs_detach,
        .id_table       = nsp_cs_ids,
+       .suspend        = nsp_cs_suspend,
+       .resume         = nsp_cs_resume,
 };
 #endif
 
index bb091a4..2541a99 100644 (file)
@@ -349,6 +349,40 @@ static void qlogic_release(dev_link_t *link)
 
 /*====================================================================*/
 
+static int qlogic_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int qlogic_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               scsi_info_t *info = link->priv;
+
+               pcmcia_request_configuration(link->handle, &link->conf);
+               if ((info->manf_id == MANFID_MACNICA) ||
+                   (info->manf_id == MANFID_PIONEER) ||
+                   (info->manf_id == 0x0098)) {
+                       outb(0x80, link->io.BasePort1 + 0xd);
+                       outb(0x24, link->io.BasePort1 + 0x9);
+                       outb(0x04, link->io.BasePort1 + 0xd);
+               }
+               /* Ugggglllyyyy!!! */
+               qlogicfas408_bus_reset(NULL);
+       }
+
+       return 0;
+}
+
 static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
 {
        dev_link_t *link = args->client_data;
@@ -365,29 +399,6 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                qlogic_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       scsi_info_t *info = link->priv;
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
-                               outb(0x80, link->io.BasePort1 + 0xd);
-                               outb(0x24, link->io.BasePort1 + 0x9);
-                               outb(0x04, link->io.BasePort1 + 0xd);
-                       }
-                       /* Ugggglllyyyy!!! */
-                       qlogicfas408_bus_reset(NULL);
-               }
-               break;
        }
        return 0;
 }                              /* qlogic_event */
@@ -423,6 +434,8 @@ static struct pcmcia_driver qlogic_cs_driver = {
        .event          = qlogic_event,
        .detach         = qlogic_detach,
        .id_table       = qlogic_ids,
+       .suspend        = qlogic_suspend,
+       .resume         = qlogic_resume,
 };
 
 static int __init init_qlogic_cs(void)
index 98b64b2..c4e3e22 100644 (file)
@@ -872,11 +872,48 @@ cs_failed:
        return;
 } /* SYM53C500_config */
 
+static int sym53c500_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int sym53c500_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+       struct scsi_info_t *info = link->priv;
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG) {
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+               /* See earlier comment about manufacturer IDs. */
+               if ((info->manf_id == MANFID_MACNICA) ||
+                   (info->manf_id == MANFID_PIONEER) ||
+                   (info->manf_id == 0x0098)) {
+                       outb(0x80, link->io.BasePort1 + 0xd);
+                       outb(0x24, link->io.BasePort1 + 0x9);
+                       outb(0x04, link->io.BasePort1 + 0xd);
+               }
+               /*
+                *  If things don't work after a "resume",
+                *  this is a good place to start looking.
+                */
+               SYM53C500_int_host_reset(link->io.BasePort1);
+       }
+
+       return 0;
+}
+
 static int
 SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
 {
        dev_link_t *link = args->client_data;
-       struct scsi_info_t *info = link->priv;
 
        DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
 
@@ -890,34 +927,6 @@ SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                SYM53C500_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG) {
-                       pcmcia_request_configuration(link->handle, &link->conf);
-                       /* See earlier comment about manufacturer IDs. */
-                       if ((info->manf_id == MANFID_MACNICA) ||
-                           (info->manf_id == MANFID_PIONEER) ||
-                           (info->manf_id == 0x0098)) {
-                               outb(0x80, link->io.BasePort1 + 0xd);
-                               outb(0x24, link->io.BasePort1 + 0x9);
-                               outb(0x04, link->io.BasePort1 + 0xd);
-                       }
-                       /*
-                       *  If things don't work after a "resume",
-                       *  this is a good place to start looking.
-                       */
-                       SYM53C500_int_host_reset(link->io.BasePort1);
-               }
-               break;
        }
        return 0;
 } /* SYM53C500_event */
@@ -1012,6 +1021,8 @@ static struct pcmcia_driver sym53c500_cs_driver = {
        .event          = SYM53C500_event,
        .detach         = SYM53C500_detach,
        .id_table       = sym53c500_ids,
+       .suspend        = sym53c500_suspend,
+       .resume         = sym53c500_resume,
 };
 
 static int __init
index 7ce0c7e..3487ee9 100644 (file)
@@ -159,8 +159,9 @@ static void serial_remove(dev_link_t *link)
        }
 }
 
-static void serial_suspend(dev_link_t *link)
+static int serial_suspend(struct pcmcia_device *dev)
 {
+       dev_link_t *link = dev_to_instance(dev);
        link->state |= DEV_SUSPEND;
 
        if (link->state & DEV_CONFIG) {
@@ -173,10 +174,13 @@ static void serial_suspend(dev_link_t *link)
                if (!info->slave)
                        pcmcia_release_configuration(link->handle);
        }
+
+       return 0;
 }
 
-static void serial_resume(dev_link_t *link)
+static int serial_resume(struct pcmcia_device *dev)
 {
+       dev_link_t *link = dev_to_instance(dev);
        link->state &= ~DEV_SUSPEND;
 
        if (DEV_OK(link)) {
@@ -189,6 +193,8 @@ static void serial_resume(dev_link_t *link)
                for (i = 0; i < info->ndev; i++)
                        serial8250_resume_port(info->line[i]);
        }
+
+       return 0;
 }
 
 /*======================================================================
@@ -731,7 +737,6 @@ static int
 serial_event(event_t event, int priority, event_callback_args_t * args)
 {
        dev_link_t *link = args->client_data;
-       struct serial_info *info = link->priv;
 
        DEBUG(1, "serial_event(0x%06x)\n", event);
 
@@ -744,24 +749,6 @@ serial_event(event_t event, int priority, event_callback_args_t * args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                serial_config(link);
                break;
-
-       case CS_EVENT_PM_SUSPEND:
-               serial_suspend(link);
-               break;
-
-       case CS_EVENT_RESET_PHYSICAL:
-               if ((link->state & DEV_CONFIG) && !info->slave)
-                       pcmcia_release_configuration(link->handle);
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               serial_resume(link);
-               break;
-
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link) && !info->slave)
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
        return 0;
 }
@@ -881,6 +868,8 @@ static struct pcmcia_driver serial_cs_driver = {
        .event          = serial_event,
        .detach         = serial_detach,
        .id_table       = serial_ids,
+       .suspend        = serial_suspend,
+       .resume         = serial_resume,
 };
 
 static int __init init_serial_cs(void)
index 57c0c6e..7cca46b 100644 (file)
@@ -255,6 +255,28 @@ static void ixj_cs_release(dev_link_t *link)
        link->state &= ~DEV_CONFIG;
 }
 
+static int ixj_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int ixj_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (DEV_OK(link))
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 static int ixj_event(event_t event, int priority, event_callback_args_t * args)
 {
        dev_link_t *link = args->client_data;
@@ -271,20 +293,6 @@ static int ixj_event(event_t event, int priority, event_callback_args_t * args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                ixj_config(link);
                break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
        }
        return 0;
 }
@@ -304,6 +312,8 @@ static struct pcmcia_driver ixj_driver = {
        .event          = ixj_event,
        .detach         = ixj_detach,
        .id_table       = ixj_ids,
+       .suspend        = ixj_suspend,
+       .resume         = ixj_resume,
 };
 
 static int __init ixj_pcmcia_init(void)
index 5056b74..cb8c2bd 100644 (file)
@@ -323,6 +323,28 @@ cs_failed:
        }
 }
 
+static int sl811_suspend(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state |= DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
+
+       return 0;
+}
+
+static int sl811_resume(struct pcmcia_device *dev)
+{
+       dev_link_t *link = dev_to_instance(dev);
+
+       link->state &= ~DEV_SUSPEND;
+       if (link->state & DEV_CONFIG)
+               pcmcia_request_configuration(link->handle, &link->conf);
+
+       return 0;
+}
+
 static int
 sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
 {
@@ -341,23 +363,6 @@ sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
                sl811_cs_config(link);
                break;
-
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               DBG(0, "reset sl811-hcd here?\n");
-               break;
        }
        return 0;
 }
@@ -417,6 +422,8 @@ static struct pcmcia_driver sl811_cs_driver = {
        .event          = sl811_cs_event,
        .detach         = sl811_cs_detach,
        .id_table       = sl811_ids,
+       .suspend        = sl811_suspend,
+       .resume         = sl811_resume,
 };
 
 /*====================================================================*/
index cb8b6e6..0200551 100644 (file)
@@ -137,6 +137,10 @@ struct pcmcia_driver {
        int (*event)            (event_t event, int priority,
                                 event_callback_args_t *);
        void                    (*detach)(dev_link_t *);
+
+       int (*suspend)          (struct pcmcia_device *dev);
+       int (*resume)           (struct pcmcia_device *dev);
+
        struct module           *owner;
        struct pcmcia_device_id *id_table;
        struct device_driver    drv;
@@ -193,6 +197,8 @@ struct pcmcia_device {
 #define handle_to_pdev(handle) (handle)
 #define handle_to_dev(handle) (handle->dev)
 
+#define dev_to_instance(dev) (dev->instance)
+
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);