aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/spectrum_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/spectrum_cs.c')
-rw-r--r--drivers/net/wireless/spectrum_cs.c96
1 files changed, 53 insertions, 43 deletions
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..3938a5735659 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -948,6 +948,56 @@ spectrum_cs_release(dev_link_t *link)
948 ioport_unmap(priv->hw.iobase); 948 ioport_unmap(priv->hw.iobase);
949} /* spectrum_cs_release */ 949} /* spectrum_cs_release */
950 950
951
952static int
953spectrum_cs_suspend(struct pcmcia_device *p_dev)
954{
955 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv;
957 struct orinoco_private *priv = netdev_priv(dev);
958 unsigned long flags;
959 int err = 0;
960
961 link->state |= DEV_SUSPEND;
962 /* Mark the device as stopped, to block IO until later */
963 if (link->state & DEV_CONFIG) {
964 spin_lock_irqsave(&priv->lock, flags);
965
966 err = __orinoco_down(dev);
967 if (err)
968 printk(KERN_WARNING "%s: Error %d downing interface\n",
969 dev->name, err);
970
971 netif_device_detach(dev);
972 priv->hw_unavailable++;
973
974 spin_unlock_irqrestore(&priv->lock, flags);
975
976 pcmcia_release_configuration(link->handle);
977 }
978
979 return 0;
980}
981
982static int
983spectrum_cs_resume(struct pcmcia_device *p_dev)
984{
985 dev_link_t *link = dev_to_instance(p_dev);
986 struct net_device *dev = link->priv;
987 struct orinoco_private *priv = netdev_priv(dev);
988
989 link->state &= ~DEV_SUSPEND;
990 if (link->state & DEV_CONFIG) {
991 /* FIXME: should we double check that this is
992 * the same card as we had before */
993 pcmcia_request_configuration(link->handle, &link->conf);
994 netif_device_attach(dev);
995 priv->hw_unavailable--;
996 schedule_work(&priv->reset_work);
997 }
998 return 0;
999}
1000
951/* 1001/*
952 * The card status event handler. Mostly, this schedules other stuff 1002 * The card status event handler. Mostly, this schedules other stuff
953 * to run after an event is received. 1003 * to run after an event is received.
@@ -959,8 +1009,6 @@ spectrum_cs_event(event_t event, int priority,
959 dev_link_t *link = args->client_data; 1009 dev_link_t *link = args->client_data;
960 struct net_device *dev = link->priv; 1010 struct net_device *dev = link->priv;
961 struct orinoco_private *priv = netdev_priv(dev); 1011 struct orinoco_private *priv = netdev_priv(dev);
962 int err = 0;
963 unsigned long flags;
964 1012
965 switch (event) { 1013 switch (event) {
966 case CS_EVENT_CARD_REMOVAL: 1014 case CS_EVENT_CARD_REMOVAL:
@@ -980,49 +1028,9 @@ spectrum_cs_event(event_t event, int priority,
980 spectrum_cs_config(link); 1028 spectrum_cs_config(link);
981 break; 1029 break;
982 1030
983 case CS_EVENT_PM_SUSPEND:
984 link->state |= DEV_SUSPEND;
985 /* Fall through... */
986 case CS_EVENT_RESET_PHYSICAL:
987 /* Mark the device as stopped, to block IO until later */
988 if (link->state & DEV_CONFIG) {
989 /* This is probably racy, but I can't think of
990 a better way, short of rewriting the PCMCIA
991 layer to not suck :-( */
992 spin_lock_irqsave(&priv->lock, flags);
993
994 err = __orinoco_down(dev);
995 if (err)
996 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
997 dev->name,
998 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
999 err);
1000
1001 netif_device_detach(dev);
1002 priv->hw_unavailable++;
1003
1004 spin_unlock_irqrestore(&priv->lock, flags);
1005
1006 pcmcia_release_configuration(link->handle);
1007 }
1008 break;
1009
1010 case CS_EVENT_PM_RESUME:
1011 link->state &= ~DEV_SUSPEND;
1012 /* Fall through... */
1013 case CS_EVENT_CARD_RESET:
1014 if (link->state & DEV_CONFIG) {
1015 /* FIXME: should we double check that this is
1016 * the same card as we had before */
1017 pcmcia_request_configuration(link->handle, &link->conf);
1018 netif_device_attach(dev);
1019 priv->hw_unavailable--;
1020 schedule_work(&priv->reset_work);
1021 }
1022 break;
1023 } 1031 }
1024 1032
1025 return err; 1033 return 0;
1026} /* spectrum_cs_event */ 1034} /* spectrum_cs_event */
1027 1035
1028/********************************************************************/ 1036/********************************************************************/
@@ -1050,6 +1058,8 @@ static struct pcmcia_driver orinoco_driver = {
1050 }, 1058 },
1051 .attach = spectrum_cs_attach, 1059 .attach = spectrum_cs_attach,
1052 .detach = spectrum_cs_detach, 1060 .detach = spectrum_cs_detach,
1061 .suspend = spectrum_cs_suspend,
1062 .resume = spectrum_cs_resume,
1053 .event = spectrum_cs_event, 1063 .event = spectrum_cs_event,
1054 .id_table = spectrum_cs_ids, 1064 .id_table = spectrum_cs_ids,
1055}; 1065};