aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/3c589_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/3c589_cs.c')
-rw-r--r--drivers/net/pcmcia/3c589_cs.c136
1 files changed, 44 insertions, 92 deletions
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c1943..1c3c9c666f74 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -143,8 +143,6 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
143 143
144static void tc589_config(dev_link_t *link); 144static void tc589_config(dev_link_t *link);
145static void tc589_release(dev_link_t *link); 145static void tc589_release(dev_link_t *link);
146static int tc589_event(event_t event, int priority,
147 event_callback_args_t *args);
148 146
149static u16 read_eeprom(kio_addr_t ioaddr, int index); 147static u16 read_eeprom(kio_addr_t ioaddr, int index);
150static void tc589_reset(struct net_device *dev); 148static void tc589_reset(struct net_device *dev);
@@ -161,12 +159,7 @@ static void el3_tx_timeout(struct net_device *dev);
161static void set_multicast_list(struct net_device *dev); 159static void set_multicast_list(struct net_device *dev);
162static struct ethtool_ops netdev_ethtool_ops; 160static struct ethtool_ops netdev_ethtool_ops;
163 161
164static dev_info_t dev_info = "3c589_cs"; 162static void tc589_detach(struct pcmcia_device *p_dev);
165
166static dev_link_t *tc589_attach(void);
167static void tc589_detach(dev_link_t *);
168
169static dev_link_t *dev_list;
170 163
171/*====================================================================== 164/*======================================================================
172 165
@@ -176,20 +169,18 @@ static dev_link_t *dev_list;
176 169
177======================================================================*/ 170======================================================================*/
178 171
179static dev_link_t *tc589_attach(void) 172static int tc589_attach(struct pcmcia_device *p_dev)
180{ 173{
181 struct el3_private *lp; 174 struct el3_private *lp;
182 client_reg_t client_reg;
183 dev_link_t *link; 175 dev_link_t *link;
184 struct net_device *dev; 176 struct net_device *dev;
185 int ret;
186 177
187 DEBUG(0, "3c589_attach()\n"); 178 DEBUG(0, "3c589_attach()\n");
188 179
189 /* Create new ethernet device */ 180 /* Create new ethernet device */
190 dev = alloc_etherdev(sizeof(struct el3_private)); 181 dev = alloc_etherdev(sizeof(struct el3_private));
191 if (!dev) 182 if (!dev)
192 return NULL; 183 return -ENOMEM;
193 lp = netdev_priv(dev); 184 lp = netdev_priv(dev);
194 link = &lp->link; 185 link = &lp->link;
195 link->priv = dev; 186 link->priv = dev;
@@ -206,7 +197,7 @@ static dev_link_t *tc589_attach(void)
206 link->conf.IntType = INT_MEMORY_AND_IO; 197 link->conf.IntType = INT_MEMORY_AND_IO;
207 link->conf.ConfigIndex = 1; 198 link->conf.ConfigIndex = 1;
208 link->conf.Present = PRESENT_OPTION; 199 link->conf.Present = PRESENT_OPTION;
209 200
210 /* The EL3-specific entries in the device structure. */ 201 /* The EL3-specific entries in the device structure. */
211 SET_MODULE_OWNER(dev); 202 SET_MODULE_OWNER(dev);
212 dev->hard_start_xmit = &el3_start_xmit; 203 dev->hard_start_xmit = &el3_start_xmit;
@@ -221,20 +212,13 @@ static dev_link_t *tc589_attach(void)
221#endif 212#endif
222 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 213 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
223 214
224 /* Register with Card Services */ 215 link->handle = p_dev;
225 link->next = dev_list; 216 p_dev->instance = link;
226 dev_list = link; 217
227 client_reg.dev_info = &dev_info; 218 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
228 client_reg.Version = 0x0210; 219 tc589_config(link);
229 client_reg.event_callback_args.client_data = link; 220
230 ret = pcmcia_register_client(&link->handle, &client_reg); 221 return 0;
231 if (ret != 0) {
232 cs_error(link->handle, RegisterClient, ret);
233 tc589_detach(link);
234 return NULL;
235 }
236
237 return link;
238} /* tc589_attach */ 222} /* tc589_attach */
239 223
240/*====================================================================== 224/*======================================================================
@@ -246,30 +230,19 @@ static dev_link_t *tc589_attach(void)
246 230
247======================================================================*/ 231======================================================================*/
248 232
249static void tc589_detach(dev_link_t *link) 233static void tc589_detach(struct pcmcia_device *p_dev)
250{ 234{
235 dev_link_t *link = dev_to_instance(p_dev);
251 struct net_device *dev = link->priv; 236 struct net_device *dev = link->priv;
252 dev_link_t **linkp; 237
253
254 DEBUG(0, "3c589_detach(0x%p)\n", link); 238 DEBUG(0, "3c589_detach(0x%p)\n", link);
255
256 /* Locate device structure */
257 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
258 if (*linkp == link) break;
259 if (*linkp == NULL)
260 return;
261 239
262 if (link->dev) 240 if (link->dev)
263 unregister_netdev(dev); 241 unregister_netdev(dev);
264 242
265 if (link->state & DEV_CONFIG) 243 if (link->state & DEV_CONFIG)
266 tc589_release(link); 244 tc589_release(link);
267 245
268 if (link->handle)
269 pcmcia_deregister_client(link->handle);
270
271 /* Unlink device structure, free bits */
272 *linkp = link->next;
273 free_netdev(dev); 246 free_netdev(dev);
274} /* tc589_detach */ 247} /* tc589_detach */
275 248
@@ -421,58 +394,37 @@ static void tc589_release(dev_link_t *link)
421 link->state &= ~DEV_CONFIG; 394 link->state &= ~DEV_CONFIG;
422} 395}
423 396
424/*====================================================================== 397static int tc589_suspend(struct pcmcia_device *p_dev)
425
426 The card status event handler. Mostly, this schedules other
427 stuff to run after an event is received. A CARD_REMOVAL event
428 also sets some flags to discourage the net drivers from trying
429 to talk to the card any more.
430
431======================================================================*/
432
433static int tc589_event(event_t event, int priority,
434 event_callback_args_t *args)
435{ 398{
436 dev_link_t *link = args->client_data; 399 dev_link_t *link = dev_to_instance(p_dev);
437 struct net_device *dev = link->priv; 400 struct net_device *dev = link->priv;
438 401
439 DEBUG(1, "3c589_event(0x%06x)\n", event);
440
441 switch (event) {
442 case CS_EVENT_CARD_REMOVAL:
443 link->state &= ~DEV_PRESENT;
444 if (link->state & DEV_CONFIG)
445 netif_device_detach(dev);
446 break;
447 case CS_EVENT_CARD_INSERTION:
448 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
449 tc589_config(link);
450 break;
451 case CS_EVENT_PM_SUSPEND:
452 link->state |= DEV_SUSPEND; 402 link->state |= DEV_SUSPEND;
453 /* Fall through... */
454 case CS_EVENT_RESET_PHYSICAL:
455 if (link->state & DEV_CONFIG) { 403 if (link->state & DEV_CONFIG) {
456 if (link->open) 404 if (link->open)
457 netif_device_detach(dev); 405 netif_device_detach(dev);
458 pcmcia_release_configuration(link->handle); 406 pcmcia_release_configuration(link->handle);
459 } 407 }
460 break; 408
461 case CS_EVENT_PM_RESUME: 409 return 0;
410}
411
412static int tc589_resume(struct pcmcia_device *p_dev)
413{
414 dev_link_t *link = dev_to_instance(p_dev);
415 struct net_device *dev = link->priv;
416
462 link->state &= ~DEV_SUSPEND; 417 link->state &= ~DEV_SUSPEND;
463 /* Fall through... */
464 case CS_EVENT_CARD_RESET:
465 if (link->state & DEV_CONFIG) { 418 if (link->state & DEV_CONFIG) {
466 pcmcia_request_configuration(link->handle, &link->conf); 419 pcmcia_request_configuration(link->handle, &link->conf);
467 if (link->open) { 420 if (link->open) {
468 tc589_reset(dev); 421 tc589_reset(dev);
469 netif_device_attach(dev); 422 netif_device_attach(dev);
470 } 423 }
471 } 424 }
472 break; 425
473 } 426 return 0;
474 return 0; 427}
475} /* tc589_event */
476 428
477/*====================================================================*/ 429/*====================================================================*/
478 430
@@ -1067,10 +1019,11 @@ static struct pcmcia_driver tc589_driver = {
1067 .drv = { 1019 .drv = {
1068 .name = "3c589_cs", 1020 .name = "3c589_cs",
1069 }, 1021 },
1070 .attach = tc589_attach, 1022 .probe = tc589_attach,
1071 .event = tc589_event, 1023 .remove = tc589_detach,
1072 .detach = tc589_detach,
1073 .id_table = tc589_ids, 1024 .id_table = tc589_ids,
1025 .suspend = tc589_suspend,
1026 .resume = tc589_resume,
1074}; 1027};
1075 1028
1076static int __init init_tc589(void) 1029static int __init init_tc589(void)
@@ -1081,7 +1034,6 @@ static int __init init_tc589(void)
1081static void __exit exit_tc589(void) 1034static void __exit exit_tc589(void)
1082{ 1035{
1083 pcmcia_unregister_driver(&tc589_driver); 1036 pcmcia_unregister_driver(&tc589_driver);
1084 BUG_ON(dev_list != NULL);
1085} 1037}
1086 1038
1087module_init(init_tc589); 1039module_init(init_tc589);