diff options
Diffstat (limited to 'drivers/net/pcmcia/pcnet_cs.c')
-rw-r--r-- | drivers/net/pcmcia/pcnet_cs.c | 129 |
1 files changed, 47 insertions, 82 deletions
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 818c185d6438..d85b758f3efa 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -105,8 +105,6 @@ module_param_array(hw_addr, int, NULL, 0); | |||
105 | static void mii_phy_probe(struct net_device *dev); | 105 | static void mii_phy_probe(struct net_device *dev); |
106 | static void pcnet_config(dev_link_t *link); | 106 | static void pcnet_config(dev_link_t *link); |
107 | static void pcnet_release(dev_link_t *link); | 107 | static void pcnet_release(dev_link_t *link); |
108 | static int pcnet_event(event_t event, int priority, | ||
109 | event_callback_args_t *args); | ||
110 | static int pcnet_open(struct net_device *dev); | 108 | static int pcnet_open(struct net_device *dev); |
111 | static int pcnet_close(struct net_device *dev); | 109 | static int pcnet_close(struct net_device *dev); |
112 | static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 110 | static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
@@ -120,11 +118,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg, | |||
120 | static int setup_dma_config(dev_link_t *link, int start_pg, | 118 | static int setup_dma_config(dev_link_t *link, int start_pg, |
121 | int stop_pg); | 119 | int stop_pg); |
122 | 120 | ||
123 | static dev_link_t *pcnet_attach(void); | 121 | static void pcnet_detach(struct pcmcia_device *p_dev); |
124 | static void pcnet_detach(dev_link_t *); | ||
125 | 122 | ||
126 | static dev_info_t dev_info = "pcnet_cs"; | 123 | static dev_info_t dev_info = "pcnet_cs"; |
127 | static dev_link_t *dev_list; | ||
128 | 124 | ||
129 | /*====================================================================*/ | 125 | /*====================================================================*/ |
130 | 126 | ||
@@ -244,19 +240,17 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev) | |||
244 | 240 | ||
245 | ======================================================================*/ | 241 | ======================================================================*/ |
246 | 242 | ||
247 | static dev_link_t *pcnet_attach(void) | 243 | static int pcnet_probe(struct pcmcia_device *p_dev) |
248 | { | 244 | { |
249 | pcnet_dev_t *info; | 245 | pcnet_dev_t *info; |
250 | dev_link_t *link; | 246 | dev_link_t *link; |
251 | struct net_device *dev; | 247 | struct net_device *dev; |
252 | client_reg_t client_reg; | ||
253 | int ret; | ||
254 | 248 | ||
255 | DEBUG(0, "pcnet_attach()\n"); | 249 | DEBUG(0, "pcnet_attach()\n"); |
256 | 250 | ||
257 | /* Create new ethernet device */ | 251 | /* Create new ethernet device */ |
258 | dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); | 252 | dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); |
259 | if (!dev) return NULL; | 253 | if (!dev) return -ENOMEM; |
260 | info = PRIV(dev); | 254 | info = PRIV(dev); |
261 | link = &info->link; | 255 | link = &info->link; |
262 | link->priv = dev; | 256 | link->priv = dev; |
@@ -271,20 +265,13 @@ static dev_link_t *pcnet_attach(void) | |||
271 | dev->stop = &pcnet_close; | 265 | dev->stop = &pcnet_close; |
272 | dev->set_config = &set_config; | 266 | dev->set_config = &set_config; |
273 | 267 | ||
274 | /* Register with Card Services */ | 268 | link->handle = p_dev; |
275 | link->next = dev_list; | 269 | p_dev->instance = link; |
276 | dev_list = link; | ||
277 | client_reg.dev_info = &dev_info; | ||
278 | client_reg.Version = 0x0210; | ||
279 | client_reg.event_callback_args.client_data = link; | ||
280 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
281 | if (ret != CS_SUCCESS) { | ||
282 | cs_error(link->handle, RegisterClient, ret); | ||
283 | pcnet_detach(link); | ||
284 | return NULL; | ||
285 | } | ||
286 | 270 | ||
287 | return link; | 271 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
272 | pcnet_config(link); | ||
273 | |||
274 | return 0; | ||
288 | } /* pcnet_attach */ | 275 | } /* pcnet_attach */ |
289 | 276 | ||
290 | /*====================================================================== | 277 | /*====================================================================== |
@@ -296,31 +283,20 @@ static dev_link_t *pcnet_attach(void) | |||
296 | 283 | ||
297 | ======================================================================*/ | 284 | ======================================================================*/ |
298 | 285 | ||
299 | static void pcnet_detach(dev_link_t *link) | 286 | static void pcnet_detach(struct pcmcia_device *p_dev) |
300 | { | 287 | { |
301 | struct net_device *dev = link->priv; | 288 | dev_link_t *link = dev_to_instance(p_dev); |
302 | dev_link_t **linkp; | 289 | struct net_device *dev = link->priv; |
303 | |||
304 | DEBUG(0, "pcnet_detach(0x%p)\n", link); | ||
305 | 290 | ||
306 | /* Locate device structure */ | 291 | DEBUG(0, "pcnet_detach(0x%p)\n", link); |
307 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
308 | if (*linkp == link) break; | ||
309 | if (*linkp == NULL) | ||
310 | return; | ||
311 | 292 | ||
312 | if (link->dev) | 293 | if (link->dev) |
313 | unregister_netdev(dev); | 294 | unregister_netdev(dev); |
314 | 295 | ||
315 | if (link->state & DEV_CONFIG) | 296 | if (link->state & DEV_CONFIG) |
316 | pcnet_release(link); | 297 | pcnet_release(link); |
317 | |||
318 | if (link->handle) | ||
319 | pcmcia_deregister_client(link->handle); | ||
320 | 298 | ||
321 | /* Unlink device structure, free bits */ | 299 | free_netdev(dev); |
322 | *linkp = link->next; | ||
323 | free_netdev(dev); | ||
324 | } /* pcnet_detach */ | 300 | } /* pcnet_detach */ |
325 | 301 | ||
326 | /*====================================================================== | 302 | /*====================================================================== |
@@ -780,50 +756,39 @@ static void pcnet_release(dev_link_t *link) | |||
780 | 756 | ||
781 | ======================================================================*/ | 757 | ======================================================================*/ |
782 | 758 | ||
783 | static int pcnet_event(event_t event, int priority, | 759 | static int pcnet_suspend(struct pcmcia_device *p_dev) |
784 | event_callback_args_t *args) | ||
785 | { | 760 | { |
786 | dev_link_t *link = args->client_data; | 761 | dev_link_t *link = dev_to_instance(p_dev); |
787 | struct net_device *dev = link->priv; | 762 | struct net_device *dev = link->priv; |
788 | 763 | ||
789 | DEBUG(2, "pcnet_event(0x%06x)\n", event); | ||
790 | |||
791 | switch (event) { | ||
792 | case CS_EVENT_CARD_REMOVAL: | ||
793 | link->state &= ~DEV_PRESENT; | ||
794 | if (link->state & DEV_CONFIG) | ||
795 | netif_device_detach(dev); | ||
796 | break; | ||
797 | case CS_EVENT_CARD_INSERTION: | ||
798 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
799 | pcnet_config(link); | ||
800 | break; | ||
801 | case CS_EVENT_PM_SUSPEND: | ||
802 | link->state |= DEV_SUSPEND; | 764 | link->state |= DEV_SUSPEND; |
803 | /* Fall through... */ | ||
804 | case CS_EVENT_RESET_PHYSICAL: | ||
805 | if (link->state & DEV_CONFIG) { | 765 | if (link->state & DEV_CONFIG) { |
806 | if (link->open) | 766 | if (link->open) |
807 | netif_device_detach(dev); | 767 | netif_device_detach(dev); |
808 | pcmcia_release_configuration(link->handle); | 768 | pcmcia_release_configuration(link->handle); |
809 | } | 769 | } |
810 | break; | 770 | |
811 | case CS_EVENT_PM_RESUME: | 771 | return 0; |
772 | } | ||
773 | |||
774 | static int pcnet_resume(struct pcmcia_device *p_dev) | ||
775 | { | ||
776 | dev_link_t *link = dev_to_instance(p_dev); | ||
777 | struct net_device *dev = link->priv; | ||
778 | |||
812 | link->state &= ~DEV_SUSPEND; | 779 | link->state &= ~DEV_SUSPEND; |
813 | /* Fall through... */ | ||
814 | case CS_EVENT_CARD_RESET: | ||
815 | if (link->state & DEV_CONFIG) { | 780 | if (link->state & DEV_CONFIG) { |
816 | pcmcia_request_configuration(link->handle, &link->conf); | 781 | pcmcia_request_configuration(link->handle, &link->conf); |
817 | if (link->open) { | 782 | if (link->open) { |
818 | pcnet_reset_8390(dev); | 783 | pcnet_reset_8390(dev); |
819 | NS8390_init(dev, 1); | 784 | NS8390_init(dev, 1); |
820 | netif_device_attach(dev); | 785 | netif_device_attach(dev); |
821 | } | 786 | } |
822 | } | 787 | } |
823 | break; | 788 | |
824 | } | 789 | return 0; |
825 | return 0; | 790 | } |
826 | } /* pcnet_event */ | 791 | |
827 | 792 | ||
828 | /*====================================================================== | 793 | /*====================================================================== |
829 | 794 | ||
@@ -1844,11 +1809,12 @@ static struct pcmcia_driver pcnet_driver = { | |||
1844 | .drv = { | 1809 | .drv = { |
1845 | .name = "pcnet_cs", | 1810 | .name = "pcnet_cs", |
1846 | }, | 1811 | }, |
1847 | .attach = pcnet_attach, | 1812 | .probe = pcnet_probe, |
1848 | .event = pcnet_event, | 1813 | .remove = pcnet_detach, |
1849 | .detach = pcnet_detach, | ||
1850 | .owner = THIS_MODULE, | 1814 | .owner = THIS_MODULE, |
1851 | .id_table = pcnet_ids, | 1815 | .id_table = pcnet_ids, |
1816 | .suspend = pcnet_suspend, | ||
1817 | .resume = pcnet_resume, | ||
1852 | }; | 1818 | }; |
1853 | 1819 | ||
1854 | static int __init init_pcnet_cs(void) | 1820 | static int __init init_pcnet_cs(void) |
@@ -1860,7 +1826,6 @@ static void __exit exit_pcnet_cs(void) | |||
1860 | { | 1826 | { |
1861 | DEBUG(0, "pcnet_cs: unloading\n"); | 1827 | DEBUG(0, "pcnet_cs: unloading\n"); |
1862 | pcmcia_unregister_driver(&pcnet_driver); | 1828 | pcmcia_unregister_driver(&pcnet_driver); |
1863 | BUG_ON(dev_list != NULL); | ||
1864 | } | 1829 | } |
1865 | 1830 | ||
1866 | module_init(init_pcnet_cs); | 1831 | module_init(init_pcnet_cs); |