aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
committerJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
commit52cab57873c25d3c8324ee3e4d463db6e8e73fd7 (patch)
tree826cb36827afa363944e6478d19512e669446c64 /drivers/net/wireless
parent0a75c23a009ff65f651532cecc16675d05f4de37 (diff)
parent46f25dffbaba48c571d75f5f574f31978287b8d2 (diff)
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/airo_cs.c161
-rw-r--r--drivers/net/wireless/atmel_cs.c156
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c156
-rw-r--r--drivers/net/wireless/netwave_cs.c184
-rw-r--r--drivers/net/wireless/orinoco_cs.c208
-rw-r--r--drivers/net/wireless/ray_cs.c154
-rw-r--r--drivers/net/wireless/spectrum_cs.c175
-rw-r--r--drivers/net/wireless/wavelan_cs.c183
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h11
-rw-r--r--drivers/net/wireless/wl3501_cs.c133
10 files changed, 473 insertions, 1048 deletions
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599dc..a496460ce224 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -82,8 +82,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
82 82
83static void airo_config(dev_link_t *link); 83static void airo_config(dev_link_t *link);
84static void airo_release(dev_link_t *link); 84static void airo_release(dev_link_t *link);
85static int airo_event(event_t event, int priority,
86 event_callback_args_t *args);
87 85
88/* 86/*
89 The attach() and detach() entry points are used to create and destroy 87 The attach() and detach() entry points are used to create and destroy
@@ -91,8 +89,7 @@ static int airo_event(event_t event, int priority,
91 needed to manage one actual PCMCIA card. 89 needed to manage one actual PCMCIA card.
92*/ 90*/
93 91
94static dev_link_t *airo_attach(void); 92static void airo_detach(struct pcmcia_device *p_dev);
95static void airo_detach(dev_link_t *);
96 93
97/* 94/*
98 You'll also need to prototype all the functions that will actually 95 You'll also need to prototype all the functions that will actually
@@ -102,14 +99,6 @@ static void airo_detach(dev_link_t *);
102*/ 99*/
103 100
104/* 101/*
105 The dev_info variable is the "key" that is used to match up this
106 device driver with appropriate cards, through the card configuration
107 database.
108*/
109
110static dev_info_t dev_info = "airo_cs";
111
112/*
113 A linked list of "instances" of the aironet device. Each actual 102 A linked list of "instances" of the aironet device. Each actual
114 PCMCIA card corresponds to one device instance, and is described 103 PCMCIA card corresponds to one device instance, and is described
115 by one dev_link_t structure (defined in ds.h). 104 by one dev_link_t structure (defined in ds.h).
@@ -119,15 +108,7 @@ static dev_info_t dev_info = "airo_cs";
119 device numbers are used to derive the corresponding array index. 108 device numbers are used to derive the corresponding array index.
120*/ 109*/
121 110
122static dev_link_t *dev_list = NULL;
123
124/* 111/*
125 A dev_link_t structure has fields for most things that are needed
126 to keep track of a socket, but there will usually be some device
127 specific information that also needs to be kept track of. The
128 'priv' pointer in a dev_link_t structure can be used to point to
129 a device-specific private data structure, like this.
130
131 A driver needs to provide a dev_node_t structure for each device 112 A driver needs to provide a dev_node_t structure for each device
132 on a card. In some cases, there is only one device per card (for 113 on a card. In some cases, there is only one device per card (for
133 example, ethernet cards, modems). In other cases, there may be 114 example, ethernet cards, modems). In other cases, there may be
@@ -160,20 +141,18 @@ typedef struct local_info_t {
160 141
161 ======================================================================*/ 142 ======================================================================*/
162 143
163static dev_link_t *airo_attach(void) 144static int airo_attach(struct pcmcia_device *p_dev)
164{ 145{
165 client_reg_t client_reg;
166 dev_link_t *link; 146 dev_link_t *link;
167 local_info_t *local; 147 local_info_t *local;
168 int ret; 148
169
170 DEBUG(0, "airo_attach()\n"); 149 DEBUG(0, "airo_attach()\n");
171 150
172 /* Initialize the dev_link_t structure */ 151 /* Initialize the dev_link_t structure */
173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 152 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
174 if (!link) { 153 if (!link) {
175 printk(KERN_ERR "airo_cs: no memory for new device\n"); 154 printk(KERN_ERR "airo_cs: no memory for new device\n");
176 return NULL; 155 return -ENOMEM;
177 } 156 }
178 157
179 /* Interrupt setup */ 158 /* Interrupt setup */
@@ -197,24 +176,17 @@ static dev_link_t *airo_attach(void)
197 if (!local) { 176 if (!local) {
198 printk(KERN_ERR "airo_cs: no memory for new device\n"); 177 printk(KERN_ERR "airo_cs: no memory for new device\n");
199 kfree (link); 178 kfree (link);
200 return NULL; 179 return -ENOMEM;
201 } 180 }
202 link->priv = local; 181 link->priv = local;
203 182
204 /* Register with Card Services */ 183 link->handle = p_dev;
205 link->next = dev_list; 184 p_dev->instance = link;
206 dev_list = link; 185
207 client_reg.dev_info = &dev_info; 186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
208 client_reg.Version = 0x0210; 187 airo_config(link);
209 client_reg.event_callback_args.client_data = link; 188
210 ret = pcmcia_register_client(&link->handle, &client_reg); 189 return 0;
211 if (ret != 0) {
212 cs_error(link->handle, RegisterClient, ret);
213 airo_detach(link);
214 return NULL;
215 }
216
217 return link;
218} /* airo_attach */ 190} /* airo_attach */
219 191
220/*====================================================================== 192/*======================================================================
@@ -226,37 +198,22 @@ static dev_link_t *airo_attach(void)
226 198
227 ======================================================================*/ 199 ======================================================================*/
228 200
229static void airo_detach(dev_link_t *link) 201static void airo_detach(struct pcmcia_device *p_dev)
230{ 202{
231 dev_link_t **linkp; 203 dev_link_t *link = dev_to_instance(p_dev);
232 204
233 DEBUG(0, "airo_detach(0x%p)\n", link); 205 DEBUG(0, "airo_detach(0x%p)\n", link);
234 206
235 /* Locate device structure */
236 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
237 if (*linkp == link) break;
238 if (*linkp == NULL)
239 return;
240
241 if (link->state & DEV_CONFIG) 207 if (link->state & DEV_CONFIG)
242 airo_release(link); 208 airo_release(link);
243 209
244 if ( ((local_info_t*)link->priv)->eth_dev ) { 210 if ( ((local_info_t*)link->priv)->eth_dev ) {
245 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); 211 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
246 } 212 }
247 ((local_info_t*)link->priv)->eth_dev = NULL; 213 ((local_info_t*)link->priv)->eth_dev = NULL;
248 214
249 /* Break the link with Card Services */
250 if (link->handle)
251 pcmcia_deregister_client(link->handle);
252
253
254
255 /* Unlink device structure, free pieces */
256 *linkp = link->next;
257 kfree(link->priv); 215 kfree(link->priv);
258 kfree(link); 216 kfree(link);
259
260} /* airo_detach */ 217} /* airo_detach */
261 218
262/*====================================================================== 219/*======================================================================
@@ -492,60 +449,34 @@ static void airo_release(dev_link_t *link)
492 link->state &= ~DEV_CONFIG; 449 link->state &= ~DEV_CONFIG;
493} 450}
494 451
495/*====================================================================== 452static int airo_suspend(struct pcmcia_device *p_dev)
496 453{
497 The card status event handler. Mostly, this schedules other 454 dev_link_t *link = dev_to_instance(p_dev);
498 stuff to run after an event is received. 455 local_info_t *local = link->priv;
499 456
500 When a CARD_REMOVAL event is received, we immediately set a 457 link->state |= DEV_SUSPEND;
501 private flag to block future accesses to this device. All the 458 if (link->state & DEV_CONFIG) {
502 functions that actually access the device should check this flag 459 netif_device_detach(local->eth_dev);
503 to make sure the card is still present. 460 pcmcia_release_configuration(link->handle);
504 461 }
505 ======================================================================*/ 462
463 return 0;
464}
506 465
507static int airo_event(event_t event, int priority, 466static int airo_resume(struct pcmcia_device *p_dev)
508 event_callback_args_t *args)
509{ 467{
510 dev_link_t *link = args->client_data; 468 dev_link_t *link = dev_to_instance(p_dev);
511 local_info_t *local = link->priv; 469 local_info_t *local = link->priv;
512 470
513 DEBUG(1, "airo_event(0x%06x)\n", event); 471 link->state &= ~DEV_SUSPEND;
514 472 if (link->state & DEV_CONFIG) {
515 switch (event) { 473 pcmcia_request_configuration(link->handle, &link->conf);
516 case CS_EVENT_CARD_REMOVAL: 474 reset_airo_card(local->eth_dev);
517 link->state &= ~DEV_PRESENT; 475 netif_device_attach(local->eth_dev);
518 if (link->state & DEV_CONFIG) {
519 netif_device_detach(local->eth_dev);
520 airo_release(link);
521 }
522 break;
523 case CS_EVENT_CARD_INSERTION:
524 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
525 airo_config(link);
526 break;
527 case CS_EVENT_PM_SUSPEND:
528 link->state |= DEV_SUSPEND;
529 /* Fall through... */
530 case CS_EVENT_RESET_PHYSICAL:
531 if (link->state & DEV_CONFIG) {
532 netif_device_detach(local->eth_dev);
533 pcmcia_release_configuration(link->handle);
534 }
535 break;
536 case CS_EVENT_PM_RESUME:
537 link->state &= ~DEV_SUSPEND;
538 /* Fall through... */
539 case CS_EVENT_CARD_RESET:
540 if (link->state & DEV_CONFIG) {
541 pcmcia_request_configuration(link->handle, &link->conf);
542 reset_airo_card(local->eth_dev);
543 netif_device_attach(local->eth_dev);
544 }
545 break;
546 } 476 }
477
547 return 0; 478 return 0;
548} /* airo_event */ 479}
549 480
550static struct pcmcia_device_id airo_ids[] = { 481static struct pcmcia_device_id airo_ids[] = {
551 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a), 482 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
@@ -561,10 +492,11 @@ static struct pcmcia_driver airo_driver = {
561 .drv = { 492 .drv = {
562 .name = "airo_cs", 493 .name = "airo_cs",
563 }, 494 },
564 .attach = airo_attach, 495 .probe = airo_attach,
565 .event = airo_event, 496 .remove = airo_detach,
566 .detach = airo_detach,
567 .id_table = airo_ids, 497 .id_table = airo_ids,
498 .suspend = airo_suspend,
499 .resume = airo_resume,
568}; 500};
569 501
570static int airo_cs_init(void) 502static int airo_cs_init(void)
@@ -575,7 +507,6 @@ static int airo_cs_init(void)
575static void airo_cs_cleanup(void) 507static void airo_cs_cleanup(void)
576{ 508{
577 pcmcia_unregister_driver(&airo_driver); 509 pcmcia_unregister_driver(&airo_driver);
578 BUG_ON(dev_list != NULL);
579} 510}
580 511
581/* 512/*
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f832..d6f4a5a3e55a 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -93,8 +93,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
93 93
94static void atmel_config(dev_link_t *link); 94static void atmel_config(dev_link_t *link);
95static void atmel_release(dev_link_t *link); 95static void atmel_release(dev_link_t *link);
96static int atmel_event(event_t event, int priority,
97 event_callback_args_t *args);
98 96
99/* 97/*
100 The attach() and detach() entry points are used to create and destroy 98 The attach() and detach() entry points are used to create and destroy
@@ -102,8 +100,7 @@ static int atmel_event(event_t event, int priority,
102 needed to manage one actual PCMCIA card. 100 needed to manage one actual PCMCIA card.
103*/ 101*/
104 102
105static dev_link_t *atmel_attach(void); 103static void atmel_detach(struct pcmcia_device *p_dev);
106static void atmel_detach(dev_link_t *);
107 104
108/* 105/*
109 You'll also need to prototype all the functions that will actually 106 You'll also need to prototype all the functions that will actually
@@ -113,14 +110,6 @@ static void atmel_detach(dev_link_t *);
113*/ 110*/
114 111
115/* 112/*
116 The dev_info variable is the "key" that is used to match up this
117 device driver with appropriate cards, through the card configuration
118 database.
119*/
120
121static dev_info_t dev_info = "atmel_cs";
122
123/*
124 A linked list of "instances" of the atmelnet device. Each actual 113 A linked list of "instances" of the atmelnet device. Each actual
125 PCMCIA card corresponds to one device instance, and is described 114 PCMCIA card corresponds to one device instance, and is described
126 by one dev_link_t structure (defined in ds.h). 115 by one dev_link_t structure (defined in ds.h).
@@ -130,15 +119,7 @@ static dev_info_t dev_info = "atmel_cs";
130 device numbers are used to derive the corresponding array index. 119 device numbers are used to derive the corresponding array index.
131*/ 120*/
132 121
133static dev_link_t *dev_list = NULL;
134
135/* 122/*
136 A dev_link_t structure has fields for most things that are needed
137 to keep track of a socket, but there will usually be some device
138 specific information that also needs to be kept track of. The
139 'priv' pointer in a dev_link_t structure can be used to point to
140 a device-specific private data structure, like this.
141
142 A driver needs to provide a dev_node_t structure for each device 123 A driver needs to provide a dev_node_t structure for each device
143 on a card. In some cases, there is only one device per card (for 124 on a card. In some cases, there is only one device per card (for
144 example, ethernet cards, modems). In other cases, there may be 125 example, ethernet cards, modems). In other cases, there may be
@@ -171,27 +152,25 @@ typedef struct local_info_t {
171 152
172 ======================================================================*/ 153 ======================================================================*/
173 154
174static dev_link_t *atmel_attach(void) 155static int atmel_attach(struct pcmcia_device *p_dev)
175{ 156{
176 client_reg_t client_reg;
177 dev_link_t *link; 157 dev_link_t *link;
178 local_info_t *local; 158 local_info_t *local;
179 int ret; 159
180
181 DEBUG(0, "atmel_attach()\n"); 160 DEBUG(0, "atmel_attach()\n");
182 161
183 /* Initialize the dev_link_t structure */ 162 /* Initialize the dev_link_t structure */
184 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 163 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
185 if (!link) { 164 if (!link) {
186 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 165 printk(KERN_ERR "atmel_cs: no memory for new device\n");
187 return NULL; 166 return -ENOMEM;
188 } 167 }
189 168
190 /* Interrupt setup */ 169 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 170 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
192 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 171 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
193 link->irq.Handler = NULL; 172 link->irq.Handler = NULL;
194 173
195 /* 174 /*
196 General socket configuration defaults can go here. In this 175 General socket configuration defaults can go here. In this
197 client, we assume very little, and rely on the CIS for almost 176 client, we assume very little, and rely on the CIS for almost
@@ -202,30 +181,23 @@ static dev_link_t *atmel_attach(void)
202 link->conf.Attributes = 0; 181 link->conf.Attributes = 0;
203 link->conf.Vcc = 50; 182 link->conf.Vcc = 50;
204 link->conf.IntType = INT_MEMORY_AND_IO; 183 link->conf.IntType = INT_MEMORY_AND_IO;
205 184
206 /* Allocate space for private device-specific data */ 185 /* Allocate space for private device-specific data */
207 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 186 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 187 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 188 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 189 kfree (link);
211 return NULL; 190 return -ENOMEM;
212 } 191 }
213 link->priv = local; 192 link->priv = local;
214 193
215 /* Register with Card Services */ 194 link->handle = p_dev;
216 link->next = dev_list; 195 p_dev->instance = link;
217 dev_list = link; 196
218 client_reg.dev_info = &dev_info; 197 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
219 client_reg.Version = 0x0210; 198 atmel_config(link);
220 client_reg.event_callback_args.client_data = link; 199
221 ret = pcmcia_register_client(&link->handle, &client_reg); 200 return 0;
222 if (ret != 0) {
223 cs_error(link->handle, RegisterClient, ret);
224 atmel_detach(link);
225 return NULL;
226 }
227
228 return link;
229} /* atmel_attach */ 201} /* atmel_attach */
230 202
231/*====================================================================== 203/*======================================================================
@@ -237,27 +209,15 @@ static dev_link_t *atmel_attach(void)
237 209
238 ======================================================================*/ 210 ======================================================================*/
239 211
240static void atmel_detach(dev_link_t *link) 212static void atmel_detach(struct pcmcia_device *p_dev)
241{ 213{
242 dev_link_t **linkp; 214 dev_link_t *link = dev_to_instance(p_dev);
243 215
244 DEBUG(0, "atmel_detach(0x%p)\n", link); 216 DEBUG(0, "atmel_detach(0x%p)\n", link);
245
246 /* Locate device structure */
247 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
248 if (*linkp == link) break;
249 if (*linkp == NULL)
250 return;
251 217
252 if (link->state & DEV_CONFIG) 218 if (link->state & DEV_CONFIG)
253 atmel_release(link); 219 atmel_release(link);
254
255 /* Break the link with Card Services */
256 if (link->handle)
257 pcmcia_deregister_client(link->handle);
258 220
259 /* Unlink device structure, free pieces */
260 *linkp = link->next;
261 kfree(link->priv); 221 kfree(link->priv);
262 kfree(link); 222 kfree(link);
263} 223}
@@ -477,60 +437,34 @@ static void atmel_release(dev_link_t *link)
477 link->state &= ~DEV_CONFIG; 437 link->state &= ~DEV_CONFIG;
478} 438}
479 439
480/*====================================================================== 440static int atmel_suspend(struct pcmcia_device *dev)
481 441{
482 The card status event handler. Mostly, this schedules other 442 dev_link_t *link = dev_to_instance(dev);
483 stuff to run after an event is received. 443 local_info_t *local = link->priv;
484 444
485 When a CARD_REMOVAL event is received, we immediately set a 445 link->state |= DEV_SUSPEND;
486 private flag to block future accesses to this device. All the 446 if (link->state & DEV_CONFIG) {
487 functions that actually access the device should check this flag 447 netif_device_detach(local->eth_dev);
488 to make sure the card is still present. 448 pcmcia_release_configuration(link->handle);
489 449 }
490 ======================================================================*/ 450
451 return 0;
452}
491 453
492static int atmel_event(event_t event, int priority, 454static int atmel_resume(struct pcmcia_device *dev)
493 event_callback_args_t *args)
494{ 455{
495 dev_link_t *link = args->client_data; 456 dev_link_t *link = dev_to_instance(dev);
496 local_info_t *local = link->priv; 457 local_info_t *local = link->priv;
497 458
498 DEBUG(1, "atmel_event(0x%06x)\n", event); 459 link->state &= ~DEV_SUSPEND;
499 460 if (link->state & DEV_CONFIG) {
500 switch (event) { 461 pcmcia_request_configuration(link->handle, &link->conf);
501 case CS_EVENT_CARD_REMOVAL: 462 atmel_open(local->eth_dev);
502 link->state &= ~DEV_PRESENT; 463 netif_device_attach(local->eth_dev);
503 if (link->state & DEV_CONFIG) {
504 netif_device_detach(local->eth_dev);
505 atmel_release(link);
506 }
507 break;
508 case CS_EVENT_CARD_INSERTION:
509 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
510 atmel_config(link);
511 break;
512 case CS_EVENT_PM_SUSPEND:
513 link->state |= DEV_SUSPEND;
514 /* Fall through... */
515 case CS_EVENT_RESET_PHYSICAL:
516 if (link->state & DEV_CONFIG) {
517 netif_device_detach(local->eth_dev);
518 pcmcia_release_configuration(link->handle);
519 }
520 break;
521 case CS_EVENT_PM_RESUME:
522 link->state &= ~DEV_SUSPEND;
523 /* Fall through... */
524 case CS_EVENT_CARD_RESET:
525 if (link->state & DEV_CONFIG) {
526 pcmcia_request_configuration(link->handle, &link->conf);
527 atmel_open(local->eth_dev);
528 netif_device_attach(local->eth_dev);
529 }
530 break;
531 } 464 }
465
532 return 0; 466 return 0;
533} /* atmel_event */ 467}
534 468
535/*====================================================================*/ 469/*====================================================================*/
536/* We use the driver_info field to store the correct firmware type for a card. */ 470/* We use the driver_info field to store the correct firmware type for a card. */
@@ -581,10 +515,11 @@ static struct pcmcia_driver atmel_driver = {
581 .drv = { 515 .drv = {
582 .name = "atmel_cs", 516 .name = "atmel_cs",
583 }, 517 },
584 .attach = atmel_attach, 518 .probe = atmel_attach,
585 .event = atmel_event, 519 .remove = atmel_detach,
586 .detach = atmel_detach,
587 .id_table = atmel_ids, 520 .id_table = atmel_ids,
521 .suspend = atmel_suspend,
522 .resume = atmel_resume,
588}; 523};
589 524
590static int atmel_cs_init(void) 525static int atmel_cs_init(void)
@@ -595,7 +530,6 @@ static int atmel_cs_init(void)
595static void atmel_cs_cleanup(void) 530static void atmel_cs_cleanup(void)
596{ 531{
597 pcmcia_unregister_driver(&atmel_driver); 532 pcmcia_unregister_driver(&atmel_driver);
598 BUG_ON(dev_list != NULL);
599} 533}
600 534
601/* 535/*
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a6677..8bc0b528548f 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -25,7 +25,6 @@
25 25
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
27static dev_info_t dev_info = "hostap_cs"; 27static dev_info_t dev_info = "hostap_cs";
28static dev_link_t *dev_list = NULL;
29 28
30MODULE_AUTHOR("Jouni Malinen"); 29MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " 30MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
203 202
204 203
205 204
206static void prism2_detach(dev_link_t *link); 205static void prism2_detach(struct pcmcia_device *p_dev);
207static void prism2_release(u_long arg); 206static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority, 207static int prism2_config(dev_link_t *link);
209 event_callback_args_t *args);
210 208
211 209
212static int prism2_pccard_card_present(local_info_t *local) 210static int prism2_pccard_card_present(local_info_t *local)
@@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs =
503 501
504/* allocate local data and register with CardServices 502/* allocate local data and register with CardServices
505 * initialize dev_link structure, but do not configure the card yet */ 503 * initialize dev_link structure, but do not configure the card yet */
506static dev_link_t *prism2_attach(void) 504static int prism2_attach(struct pcmcia_device *p_dev)
507{ 505{
508 dev_link_t *link; 506 dev_link_t *link;
509 client_reg_t client_reg;
510 int ret;
511 507
512 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); 508 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
513 if (link == NULL) 509 if (link == NULL)
514 return NULL; 510 return -ENOMEM;
515 511
516 memset(link, 0, sizeof(dev_link_t)); 512 memset(link, 0, sizeof(dev_link_t));
517 513
@@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void)
519 link->conf.Vcc = 33; 515 link->conf.Vcc = 33;
520 link->conf.IntType = INT_MEMORY_AND_IO; 516 link->conf.IntType = INT_MEMORY_AND_IO;
521 517
522 /* register with CardServices */ 518 link->handle = p_dev;
523 link->next = dev_list; 519 p_dev->instance = link;
524 dev_list = link; 520
525 client_reg.dev_info = &dev_info; 521 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
526 client_reg.Version = 0x0210; 522 if (prism2_config(link))
527 client_reg.event_callback_args.client_data = link; 523 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
528 ret = pcmcia_register_client(&link->handle, &client_reg); 524
529 if (ret != CS_SUCCESS) { 525 return 0;
530 cs_error(link->handle, RegisterClient, ret);
531 prism2_detach(link);
532 return NULL;
533 }
534 return link;
535} 526}
536 527
537 528
538static void prism2_detach(dev_link_t *link) 529static void prism2_detach(struct pcmcia_device *p_dev)
539{ 530{
540 dev_link_t **linkp; 531 dev_link_t *link = dev_to_instance(p_dev);
541 532
542 PDEBUG(DEBUG_FLOW, "prism2_detach\n"); 533 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
543 534
544 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
545 if (*linkp == link)
546 break;
547 if (*linkp == NULL) {
548 printk(KERN_WARNING "%s: Attempt to detach non-existing "
549 "PCMCIA client\n", dev_info);
550 return;
551 }
552
553 if (link->state & DEV_CONFIG) { 535 if (link->state & DEV_CONFIG) {
554 prism2_release((u_long)link); 536 prism2_release((u_long)link);
555 } 537 }
556 538
557 if (link->handle) {
558 int res = pcmcia_deregister_client(link->handle);
559 if (res) {
560 printk("CardService(DeregisterClient) => %d\n", res);
561 cs_error(link->handle, DeregisterClient, res);
562 }
563 }
564
565 *linkp = link->next;
566 /* release net devices */ 539 /* release net devices */
567 if (link->priv) { 540 if (link->priv) {
568 struct hostap_cs_priv *hw_priv; 541 struct hostap_cs_priv *hw_priv;
@@ -846,84 +819,58 @@ static void prism2_release(u_long arg)
846 PDEBUG(DEBUG_FLOW, "release - done\n"); 819 PDEBUG(DEBUG_FLOW, "release - done\n");
847} 820}
848 821
849 822static int hostap_cs_suspend(struct pcmcia_device *p_dev)
850static int prism2_event(event_t event, int priority,
851 event_callback_args_t *args)
852{ 823{
853 dev_link_t *link = args->client_data; 824 dev_link_t *link = dev_to_instance(p_dev);
854 struct net_device *dev = (struct net_device *) link->priv; 825 struct net_device *dev = (struct net_device *) link->priv;
855 int dev_open = 0; 826 int dev_open = 0;
856 827
828 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
829
830 link->state |= DEV_SUSPEND;
831
857 if (link->state & DEV_CONFIG) { 832 if (link->state & DEV_CONFIG) {
858 struct hostap_interface *iface = netdev_priv(dev); 833 struct hostap_interface *iface = netdev_priv(dev);
859 if (iface && iface->local) 834 if (iface && iface->local)
860 dev_open = iface->local->num_dev_open > 0; 835 dev_open = iface->local->num_dev_open > 0;
861 } 836 if (dev_open) {
862
863 switch (event) {
864 case CS_EVENT_CARD_INSERTION:
865 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
866 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
867 if (prism2_config(link)) {
868 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
869 }
870 break;
871
872 case CS_EVENT_CARD_REMOVAL:
873 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
874 link->state &= ~DEV_PRESENT;
875 if (link->state & DEV_CONFIG) {
876 netif_stop_queue(dev); 837 netif_stop_queue(dev);
877 netif_device_detach(dev); 838 netif_device_detach(dev);
878 prism2_release((u_long) link);
879 } 839 }
880 break; 840 prism2_suspend(dev);
841 pcmcia_release_configuration(link->handle);
842 }
881 843
882 case CS_EVENT_PM_SUSPEND: 844 return 0;
883 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); 845}
884 link->state |= DEV_SUSPEND;
885 /* fall through */
886
887 case CS_EVENT_RESET_PHYSICAL:
888 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
889 if (link->state & DEV_CONFIG) {
890 if (dev_open) {
891 netif_stop_queue(dev);
892 netif_device_detach(dev);
893 }
894 prism2_suspend(dev);
895 pcmcia_release_configuration(link->handle);
896 }
897 break;
898 846
899 case CS_EVENT_PM_RESUME: 847static int hostap_cs_resume(struct pcmcia_device *p_dev)
900 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); 848{
901 link->state &= ~DEV_SUSPEND; 849 dev_link_t *link = dev_to_instance(p_dev);
902 /* fall through */ 850 struct net_device *dev = (struct net_device *) link->priv;
903 851 int dev_open = 0;
904 case CS_EVENT_CARD_RESET:
905 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
906 if (link->state & DEV_CONFIG) {
907 pcmcia_request_configuration(link->handle,
908 &link->conf);
909 prism2_hw_shutdown(dev, 1);
910 prism2_hw_config(dev, dev_open ? 0 : 1);
911 if (dev_open) {
912 netif_device_attach(dev);
913 netif_start_queue(dev);
914 }
915 }
916 break;
917 852
918 default: 853 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
919 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", 854
920 dev_info, event); 855 link->state &= ~DEV_SUSPEND;
921 break; 856 if (link->state & DEV_CONFIG) {
857 struct hostap_interface *iface = netdev_priv(dev);
858 if (iface && iface->local)
859 dev_open = iface->local->num_dev_open > 0;
860
861 pcmcia_request_configuration(link->handle, &link->conf);
862
863 prism2_hw_shutdown(dev, 1);
864 prism2_hw_config(dev, dev_open ? 0 : 1);
865 if (dev_open) {
866 netif_device_attach(dev);
867 netif_start_queue(dev);
868 }
922 } 869 }
870
923 return 0; 871 return 0;
924} 872}
925 873
926
927static struct pcmcia_device_id hostap_cs_ids[] = { 874static struct pcmcia_device_id hostap_cs_ids[] = {
928 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), 875 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
929 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), 876 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
@@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = {
982 .drv = { 929 .drv = {
983 .name = "hostap_cs", 930 .name = "hostap_cs",
984 }, 931 },
985 .attach = prism2_attach, 932 .probe = prism2_attach,
986 .detach = prism2_detach, 933 .remove = prism2_detach,
987 .owner = THIS_MODULE, 934 .owner = THIS_MODULE,
988 .event = prism2_event,
989 .id_table = hostap_cs_ids, 935 .id_table = hostap_cs_ids,
936 .suspend = hostap_cs_suspend,
937 .resume = hostap_cs_resume,
990}; 938};
991 939
992static int __init init_prism2_pccard(void) 940static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e32..bf6271ee387a 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -166,8 +166,6 @@ static char *version =
166#define DEBUG(n, args...) 166#define DEBUG(n, args...)
167#endif 167#endif
168 168
169static dev_info_t dev_info = "netwave_cs";
170
171/*====================================================================*/ 169/*====================================================================*/
172 170
173/* Parameters that can be set with 'insmod' */ 171/* Parameters that can be set with 'insmod' */
@@ -195,12 +193,9 @@ module_param(mem_speed, int, 0);
195 193
196/* PCMCIA (Card Services) related functions */ 194/* PCMCIA (Card Services) related functions */
197static void netwave_release(dev_link_t *link); /* Card removal */ 195static void netwave_release(dev_link_t *link); /* Card removal */
198static int netwave_event(event_t event, int priority,
199 event_callback_args_t *args);
200static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card 196static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
201 insertion */ 197 insertion */
202static dev_link_t *netwave_attach(void); /* Create instance */ 198static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
203static void netwave_detach(dev_link_t *); /* Destroy instance */
204 199
205/* Hardware configuration */ 200/* Hardware configuration */
206static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); 201static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
@@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
228static void set_multicast_list(struct net_device *dev); 223static void set_multicast_list(struct net_device *dev);
229 224
230/* 225/*
231 A linked list of "instances" of the skeleton device. Each actual
232 PCMCIA card corresponds to one device instance, and is described
233 by one dev_link_t structure (defined in ds.h).
234
235 You may not want to use a linked list for this -- for example, the
236 memory card driver uses an array of dev_link_t pointers, where minor
237 device numbers are used to derive the corresponding array index.
238*/
239static dev_link_t *dev_list;
240
241/*
242 A dev_link_t structure has fields for most things that are needed 226 A dev_link_t structure has fields for most things that are needed
243 to keep track of a socket, but there will usually be some device 227 to keep track of a socket, but there will usually be some device
244 specific information that also needs to be kept track of. The 228 specific information that also needs to be kept track of. The
@@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
394 * configure the card at this point -- we wait until we receive a 378 * configure the card at this point -- we wait until we receive a
395 * card insertion event. 379 * card insertion event.
396 */ 380 */
397static dev_link_t *netwave_attach(void) 381static int netwave_attach(struct pcmcia_device *p_dev)
398{ 382{
399 client_reg_t client_reg;
400 dev_link_t *link; 383 dev_link_t *link;
401 struct net_device *dev; 384 struct net_device *dev;
402 netwave_private *priv; 385 netwave_private *priv;
403 int ret; 386
404
405 DEBUG(0, "netwave_attach()\n"); 387 DEBUG(0, "netwave_attach()\n");
406 388
407 /* Initialize the dev_link_t structure */ 389 /* Initialize the dev_link_t structure */
408 dev = alloc_etherdev(sizeof(netwave_private)); 390 dev = alloc_etherdev(sizeof(netwave_private));
409 if (!dev) 391 if (!dev)
410 return NULL; 392 return -ENOMEM;
411 priv = netdev_priv(dev); 393 priv = netdev_priv(dev);
412 link = &priv->link; 394 link = &priv->link;
413 link->priv = dev; 395 link->priv = dev;
@@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void)
449 dev->open = &netwave_open; 431 dev->open = &netwave_open;
450 dev->stop = &netwave_close; 432 dev->stop = &netwave_close;
451 link->irq.Instance = dev; 433 link->irq.Instance = dev;
452
453 /* Register with Card Services */
454 link->next = dev_list;
455 dev_list = link;
456 client_reg.dev_info = &dev_info;
457 client_reg.Version = 0x0210;
458 client_reg.event_callback_args.client_data = link;
459 ret = pcmcia_register_client(&link->handle, &client_reg);
460 if (ret != 0) {
461 cs_error(link->handle, RegisterClient, ret);
462 netwave_detach(link);
463 return NULL;
464 }
465 434
466 return link; 435 link->handle = p_dev;
436 p_dev->instance = link;
437
438 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
439 netwave_pcmcia_config( link);
440
441 return 0;
467} /* netwave_attach */ 442} /* netwave_attach */
468 443
469/* 444/*
@@ -474,42 +449,20 @@ static dev_link_t *netwave_attach(void)
474 * structures are freed. Otherwise, the structures will be freed 449 * structures are freed. Otherwise, the structures will be freed
475 * when the device is released. 450 * when the device is released.
476 */ 451 */
477static void netwave_detach(dev_link_t *link) 452static void netwave_detach(struct pcmcia_device *p_dev)
478{ 453{
479 struct net_device *dev = link->priv; 454 dev_link_t *link = dev_to_instance(p_dev);
480 dev_link_t **linkp; 455 struct net_device *dev = link->priv;
481 456
482 DEBUG(0, "netwave_detach(0x%p)\n", link); 457 DEBUG(0, "netwave_detach(0x%p)\n", link);
483 458
484 /* 459 if (link->state & DEV_CONFIG)
485 If the device is currently configured and active, we won't 460 netwave_release(link);
486 actually delete it yet. Instead, it is marked so that when 461
487 the release() function is called, that will trigger a proper 462 if (link->dev)
488 detach(). 463 unregister_netdev(dev);
489 */ 464
490 if (link->state & DEV_CONFIG) 465 free_netdev(dev);
491 netwave_release(link);
492
493 /* Break the link with Card Services */
494 if (link->handle)
495 pcmcia_deregister_client(link->handle);
496
497 /* Locate device structure */
498 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
499 if (*linkp == link) break;
500 if (*linkp == NULL)
501 {
502 DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
503 link->dev->dev_name);
504 return;
505 }
506
507 /* Unlink device structure, free pieces */
508 *linkp = link->next;
509 if (link->dev)
510 unregister_netdev(dev);
511 free_netdev(dev);
512
513} /* netwave_detach */ 466} /* netwave_detach */
514 467
515/* 468/*
@@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link)
935 link->state &= ~DEV_CONFIG; 888 link->state &= ~DEV_CONFIG;
936} 889}
937 890
938/* 891static int netwave_suspend(struct pcmcia_device *p_dev)
939 * Function netwave_event (event, priority, args)
940 *
941 * The card status event handler. Mostly, this schedules other
942 * stuff to run after an event is received. A CARD_REMOVAL event
943 * also sets some flags to discourage the net drivers from trying
944 * to talk to the card any more.
945 *
946 * When a CARD_REMOVAL event is received, we immediately set a flag
947 * to block future accesses to this device. All the functions that
948 * actually access the device should check this flag to make sure
949 * the card is still present.
950 *
951 */
952static int netwave_event(event_t event, int priority,
953 event_callback_args_t *args)
954{ 892{
955 dev_link_t *link = args->client_data; 893 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv; 894 struct net_device *dev = link->priv;
957 895
958 DEBUG(1, "netwave_event(0x%06x)\n", event);
959
960 switch (event) {
961 case CS_EVENT_REGISTRATION_COMPLETE:
962 DEBUG(0, "netwave_cs: registration complete\n");
963 break;
964
965 case CS_EVENT_CARD_REMOVAL:
966 link->state &= ~DEV_PRESENT;
967 if (link->state & DEV_CONFIG) {
968 netif_device_detach(dev);
969 netwave_release(link);
970 }
971 break;
972 case CS_EVENT_CARD_INSERTION:
973 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
974 netwave_pcmcia_config( link);
975 break;
976 case CS_EVENT_PM_SUSPEND:
977 link->state |= DEV_SUSPEND; 896 link->state |= DEV_SUSPEND;
978 /* Fall through... */
979 case CS_EVENT_RESET_PHYSICAL:
980 if (link->state & DEV_CONFIG) { 897 if (link->state & DEV_CONFIG) {
981 if (link->open) 898 if (link->open)
982 netif_device_detach(dev); 899 netif_device_detach(dev);
983 pcmcia_release_configuration(link->handle); 900 pcmcia_release_configuration(link->handle);
984 } 901 }
985 break; 902
986 case CS_EVENT_PM_RESUME: 903 return 0;
904}
905
906static int netwave_resume(struct pcmcia_device *p_dev)
907{
908 dev_link_t *link = dev_to_instance(p_dev);
909 struct net_device *dev = link->priv;
910
987 link->state &= ~DEV_SUSPEND; 911 link->state &= ~DEV_SUSPEND;
988 /* Fall through... */
989 case CS_EVENT_CARD_RESET:
990 if (link->state & DEV_CONFIG) { 912 if (link->state & DEV_CONFIG) {
991 pcmcia_request_configuration(link->handle, &link->conf); 913 pcmcia_request_configuration(link->handle, &link->conf);
992 if (link->open) { 914 if (link->open) {
993 netwave_reset(dev); 915 netwave_reset(dev);
994 netif_device_attach(dev); 916 netif_device_attach(dev);
995 } 917 }
996 } 918 }
997 break; 919
998 } 920 return 0;
999 return 0; 921}
1000} /* netwave_event */ 922
1001 923
1002/* 924/*
1003 * Function netwave_doreset (ioBase, ramBase) 925 * Function netwave_doreset (ioBase, ramBase)
@@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = {
1491 .drv = { 1413 .drv = {
1492 .name = "netwave_cs", 1414 .name = "netwave_cs",
1493 }, 1415 },
1494 .attach = netwave_attach, 1416 .probe = netwave_attach,
1495 .event = netwave_event, 1417 .remove = netwave_detach,
1496 .detach = netwave_detach,
1497 .id_table = netwave_ids, 1418 .id_table = netwave_ids,
1419 .suspend = netwave_suspend,
1420 .resume = netwave_resume,
1498}; 1421};
1499 1422
1500static int __init init_netwave_cs(void) 1423static int __init init_netwave_cs(void)
@@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void)
1505static void __exit exit_netwave_cs(void) 1428static void __exit exit_netwave_cs(void)
1506{ 1429{
1507 pcmcia_unregister_driver(&netwave_driver); 1430 pcmcia_unregister_driver(&netwave_driver);
1508 BUG_ON(dev_list != NULL);
1509} 1431}
1510 1432
1511module_init(init_netwave_cs); 1433module_init(init_netwave_cs);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a00971..b664708481cc 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -43,17 +43,6 @@ module_param(ignore_cis_vcc, int, 0);
43MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 43MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
44 44
45/********************************************************************/ 45/********************************************************************/
46/* Magic constants */
47/********************************************************************/
48
49/*
50 * The dev_info variable is the "key" that is used to match up this
51 * device driver with appropriate cards, through the card
52 * configuration database.
53 */
54static dev_info_t dev_info = DRIVER_NAME;
55
56/********************************************************************/
57/* Data structures */ 46/* Data structures */
58/********************************************************************/ 47/********************************************************************/
59 48
@@ -69,19 +58,14 @@ struct orinoco_pccard {
69 unsigned long hard_reset_in_progress; 58 unsigned long hard_reset_in_progress;
70}; 59};
71 60
72/*
73 * A linked list of "instances" of the device. Each actual PCMCIA
74 * card corresponds to one device instance, and is described by one
75 * dev_link_t structure (defined in ds.h).
76 */
77static dev_link_t *dev_list; /* = NULL */
78 61
79/********************************************************************/ 62/********************************************************************/
80/* Function prototypes */ 63/* Function prototypes */
81/********************************************************************/ 64/********************************************************************/
82 65
66static void orinoco_cs_config(dev_link_t *link);
83static void orinoco_cs_release(dev_link_t *link); 67static void orinoco_cs_release(dev_link_t *link);
84static void orinoco_cs_detach(dev_link_t *link); 68static void orinoco_cs_detach(struct pcmcia_device *p_dev);
85 69
86/********************************************************************/ 70/********************************************************************/
87/* Device methods */ 71/* Device methods */
@@ -119,19 +103,17 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
119 * The dev_link structure is initialized, but we don't actually 103 * The dev_link structure is initialized, but we don't actually
120 * configure the card at this point -- we wait until we receive a card 104 * configure the card at this point -- we wait until we receive a card
121 * insertion event. */ 105 * insertion event. */
122static dev_link_t * 106static int
123orinoco_cs_attach(void) 107orinoco_cs_attach(struct pcmcia_device *p_dev)
124{ 108{
125 struct net_device *dev; 109 struct net_device *dev;
126 struct orinoco_private *priv; 110 struct orinoco_private *priv;
127 struct orinoco_pccard *card; 111 struct orinoco_pccard *card;
128 dev_link_t *link; 112 dev_link_t *link;
129 client_reg_t client_reg;
130 int ret;
131 113
132 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset); 114 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
133 if (! dev) 115 if (! dev)
134 return NULL; 116 return -ENOMEM;
135 priv = netdev_priv(dev); 117 priv = netdev_priv(dev);
136 card = priv->card; 118 card = priv->card;
137 119
@@ -154,22 +136,15 @@ orinoco_cs_attach(void)
154 link->conf.IntType = INT_MEMORY_AND_IO; 136 link->conf.IntType = INT_MEMORY_AND_IO;
155 137
156 /* Register with Card Services */ 138 /* Register with Card Services */
157 /* FIXME: need a lock? */ 139 link->next = NULL;
158 link->next = dev_list; 140
159 dev_list = link; 141 link->handle = p_dev;
160 142 p_dev->instance = link;
161 client_reg.dev_info = &dev_info; 143
162 client_reg.Version = 0x0210; /* FIXME: what does this mean? */ 144 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
163 client_reg.event_callback_args.client_data = link; 145 orinoco_cs_config(link);
164
165 ret = pcmcia_register_client(&link->handle, &client_reg);
166 if (ret != CS_SUCCESS) {
167 cs_error(link->handle, RegisterClient, ret);
168 orinoco_cs_detach(link);
169 return NULL;
170 }
171 146
172 return link; 147 return 0;
173} /* orinoco_cs_attach */ 148} /* orinoco_cs_attach */
174 149
175/* 150/*
@@ -178,27 +153,14 @@ orinoco_cs_attach(void)
178 * are freed. Otherwise, the structures will be freed when the device 153 * are freed. Otherwise, the structures will be freed when the device
179 * is released. 154 * is released.
180 */ 155 */
181static void orinoco_cs_detach(dev_link_t *link) 156static void orinoco_cs_detach(struct pcmcia_device *p_dev)
182{ 157{
183 dev_link_t **linkp; 158 dev_link_t *link = dev_to_instance(p_dev);
184 struct net_device *dev = link->priv; 159 struct net_device *dev = link->priv;
185 160
186 /* Locate device structure */
187 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
188 if (*linkp == link)
189 break;
190
191 BUG_ON(*linkp == NULL);
192
193 if (link->state & DEV_CONFIG) 161 if (link->state & DEV_CONFIG)
194 orinoco_cs_release(link); 162 orinoco_cs_release(link);
195 163
196 /* Break the link with Card Services */
197 if (link->handle)
198 pcmcia_deregister_client(link->handle);
199
200 /* Unlink device structure, and free it */
201 *linkp = link->next;
202 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); 164 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
203 if (link->dev) { 165 if (link->dev) {
204 DEBUG(0, PFX "About to unregister net device %p\n", 166 DEBUG(0, PFX "About to unregister net device %p\n",
@@ -465,106 +427,82 @@ orinoco_cs_release(dev_link_t *link)
465 ioport_unmap(priv->hw.iobase); 427 ioport_unmap(priv->hw.iobase);
466} /* orinoco_cs_release */ 428} /* orinoco_cs_release */
467 429
468/* 430static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
469 * The card status event handler. Mostly, this schedules other stuff
470 * to run after an event is received.
471 */
472static int
473orinoco_cs_event(event_t event, int priority,
474 event_callback_args_t * args)
475{ 431{
476 dev_link_t *link = args->client_data; 432 dev_link_t *link = dev_to_instance(p_dev);
477 struct net_device *dev = link->priv; 433 struct net_device *dev = link->priv;
478 struct orinoco_private *priv = netdev_priv(dev); 434 struct orinoco_private *priv = netdev_priv(dev);
479 struct orinoco_pccard *card = priv->card; 435 struct orinoco_pccard *card = priv->card;
480 int err = 0; 436 int err = 0;
481 unsigned long flags; 437 unsigned long flags;
482 438
483 switch (event) { 439 link->state |= DEV_SUSPEND;
484 case CS_EVENT_CARD_REMOVAL: 440 if (link->state & DEV_CONFIG) {
485 link->state &= ~DEV_PRESENT; 441 /* This is probably racy, but I can't think of
486 if (link->state & DEV_CONFIG) { 442 a better way, short of rewriting the PCMCIA
487 unsigned long flags; 443 layer to not suck :-( */
488 444 if (! test_bit(0, &card->hard_reset_in_progress)) {
489 spin_lock_irqsave(&priv->lock, flags); 445 spin_lock_irqsave(&priv->lock, flags);
446
447 err = __orinoco_down(dev);
448 if (err)
449 printk(KERN_WARNING "%s: Error %d downing interface\n",
450 dev->name, err);
451
490 netif_device_detach(dev); 452 netif_device_detach(dev);
491 priv->hw_unavailable++; 453 priv->hw_unavailable++;
454
492 spin_unlock_irqrestore(&priv->lock, flags); 455 spin_unlock_irqrestore(&priv->lock, flags);
493 } 456 }
494 break;
495 457
496 case CS_EVENT_CARD_INSERTION: 458 pcmcia_release_configuration(link->handle);
497 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 459 }
498 orinoco_cs_config(link);
499 break;
500 460
501 case CS_EVENT_PM_SUSPEND: 461 return 0;
502 link->state |= DEV_SUSPEND; 462}
503 /* Fall through... */ 463
504 case CS_EVENT_RESET_PHYSICAL: 464static int orinoco_cs_resume(struct pcmcia_device *p_dev)
505 /* Mark the device as stopped, to block IO until later */ 465{
506 if (link->state & DEV_CONFIG) { 466 dev_link_t *link = dev_to_instance(p_dev);
507 /* This is probably racy, but I can't think of 467 struct net_device *dev = link->priv;
508 a better way, short of rewriting the PCMCIA 468 struct orinoco_private *priv = netdev_priv(dev);
509 layer to not suck :-( */ 469 struct orinoco_pccard *card = priv->card;
510 if (! test_bit(0, &card->hard_reset_in_progress)) { 470 int err = 0;
511 spin_lock_irqsave(&priv->lock, flags); 471 unsigned long flags;
512 472
513 err = __orinoco_down(dev); 473 link->state &= ~DEV_SUSPEND;
514 if (err) 474 if (link->state & DEV_CONFIG) {
515 printk(KERN_WARNING "%s: %s: Error %d downing interface\n", 475 /* FIXME: should we double check that this is
516 dev->name, 476 * the same card as we had before */
517 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL", 477 pcmcia_request_configuration(link->handle, &link->conf);
518 err); 478
519 479 if (! test_bit(0, &card->hard_reset_in_progress)) {
520 netif_device_detach(dev); 480 err = orinoco_reinit_firmware(dev);
521 priv->hw_unavailable++; 481 if (err) {
522 482 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
523 spin_unlock_irqrestore(&priv->lock, flags); 483 dev->name, err);
484 return -EIO;
524 } 485 }
525 486
526 pcmcia_release_configuration(link->handle); 487 spin_lock_irqsave(&priv->lock, flags);
527 } 488
528 break; 489 netif_device_attach(dev);
490 priv->hw_unavailable--;
529 491
530 case CS_EVENT_PM_RESUME: 492 if (priv->open && ! priv->hw_unavailable) {
531 link->state &= ~DEV_SUSPEND; 493 err = __orinoco_up(dev);
532 /* Fall through... */ 494 if (err)
533 case CS_EVENT_CARD_RESET: 495 printk(KERN_ERR "%s: Error %d restarting card\n",
534 if (link->state & DEV_CONFIG) {
535 /* FIXME: should we double check that this is
536 * the same card as we had before */
537 pcmcia_request_configuration(link->handle, &link->conf);
538
539 if (! test_bit(0, &card->hard_reset_in_progress)) {
540 err = orinoco_reinit_firmware(dev);
541 if (err) {
542 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
543 dev->name, err); 496 dev->name, err);
544 break;
545 }
546
547 spin_lock_irqsave(&priv->lock, flags);
548
549 netif_device_attach(dev);
550 priv->hw_unavailable--;
551
552 if (priv->open && ! priv->hw_unavailable) {
553 err = __orinoco_up(dev);
554 if (err)
555 printk(KERN_ERR "%s: Error %d restarting card\n",
556 dev->name, err);
557
558 }
559
560 spin_unlock_irqrestore(&priv->lock, flags);
561 } 497 }
498
499 spin_unlock_irqrestore(&priv->lock, flags);
562 } 500 }
563 break;
564 } 501 }
565 502
566 return err; 503 return 0;
567} /* orinoco_cs_event */ 504}
505
568 506
569/********************************************************************/ 507/********************************************************************/
570/* Module initialization */ 508/* Module initialization */
@@ -665,10 +603,11 @@ static struct pcmcia_driver orinoco_driver = {
665 .drv = { 603 .drv = {
666 .name = DRIVER_NAME, 604 .name = DRIVER_NAME,
667 }, 605 },
668 .attach = orinoco_cs_attach, 606 .probe = orinoco_cs_attach,
669 .detach = orinoco_cs_detach, 607 .remove = orinoco_cs_detach,
670 .event = orinoco_cs_event,
671 .id_table = orinoco_cs_ids, 608 .id_table = orinoco_cs_ids,
609 .suspend = orinoco_cs_suspend,
610 .resume = orinoco_cs_resume,
672}; 611};
673 612
674static int __init 613static int __init
@@ -683,7 +622,6 @@ static void __exit
683exit_orinoco_cs(void) 622exit_orinoco_cs(void)
684{ 623{
685 pcmcia_unregister_driver(&orinoco_driver); 624 pcmcia_unregister_driver(&orinoco_driver);
686 BUG_ON(dev_list != NULL);
687} 625}
688 626
689module_init(init_orinoco_cs); 627module_init(init_orinoco_cs);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb9..319180ca7e71 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,9 +92,7 @@ module_param(pc_debug, int, 0);
92/** Prototypes based on PCMCIA skeleton driver *******************************/ 92/** Prototypes based on PCMCIA skeleton driver *******************************/
93static void ray_config(dev_link_t *link); 93static void ray_config(dev_link_t *link);
94static void ray_release(dev_link_t *link); 94static void ray_release(dev_link_t *link);
95static int ray_event(event_t event, int priority, event_callback_args_t *args); 95static void ray_detach(struct pcmcia_device *p_dev);
96static dev_link_t *ray_attach(void);
97static void ray_detach(dev_link_t *);
98 96
99/***** Prototypes indicated by device structure ******************************/ 97/***** Prototypes indicated by device structure ******************************/
100static int ray_dev_close(struct net_device *dev); 98static int ray_dev_close(struct net_device *dev);
@@ -192,12 +190,6 @@ static int bc;
192static char *phy_addr = NULL; 190static char *phy_addr = NULL;
193 191
194 192
195/* The dev_info variable is the "key" that is used to match up this
196 device driver with appropriate cards, through the card configuration
197 database.
198*/
199static dev_info_t dev_info = "ray_cs";
200
201/* A linked list of "instances" of the ray device. Each actual 193/* A linked list of "instances" of the ray device. Each actual
202 PCMCIA card corresponds to one device instance, and is described 194 PCMCIA card corresponds to one device instance, and is described
203 by one dev_link_t structure (defined in ds.h). 195 by one dev_link_t structure (defined in ds.h).
@@ -314,12 +306,10 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
314 configure the card at this point -- we wait until we receive a 306 configure the card at this point -- we wait until we receive a
315 card insertion event. 307 card insertion event.
316=============================================================================*/ 308=============================================================================*/
317static dev_link_t *ray_attach(void) 309static int ray_attach(struct pcmcia_device *p_dev)
318{ 310{
319 client_reg_t client_reg;
320 dev_link_t *link; 311 dev_link_t *link;
321 ray_dev_t *local; 312 ray_dev_t *local;
322 int ret;
323 struct net_device *dev; 313 struct net_device *dev;
324 314
325 DEBUG(1, "ray_attach()\n"); 315 DEBUG(1, "ray_attach()\n");
@@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void)
328 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 318 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
329 319
330 if (!link) 320 if (!link)
331 return NULL; 321 return -ENOMEM;
332 322
333 /* Allocate space for private device-specific data */ 323 /* Allocate space for private device-specific data */
334 dev = alloc_etherdev(sizeof(ray_dev_t)); 324 dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void)
387 dev->stop = &ray_dev_close; 377 dev->stop = &ray_dev_close;
388 netif_stop_queue(dev); 378 netif_stop_queue(dev);
389 379
390 /* Register with Card Services */ 380 init_timer(&local->timer);
391 link->next = dev_list;
392 dev_list = link;
393 client_reg.dev_info = &dev_info;
394 client_reg.Version = 0x0210;
395 client_reg.event_callback_args.client_data = link;
396 381
397 DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n"); 382 link->handle = p_dev;
383 p_dev->instance = link;
398 384
399 init_timer(&local->timer); 385 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
386 ray_config(link);
400 387
401 ret = pcmcia_register_client(&link->handle, &client_reg); 388 return 0;
402 if (ret != 0) {
403 printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
404 cs_error(link->handle, RegisterClient, ret);
405 ray_detach(link);
406 return NULL;
407 }
408 DEBUG(2,"ray_cs ray_attach ending\n");
409 return link;
410 389
411fail_alloc_dev: 390fail_alloc_dev:
412 kfree(link); 391 kfree(link);
413 return NULL; 392 return -ENOMEM;
414} /* ray_attach */ 393} /* ray_attach */
415/*============================================================================= 394/*=============================================================================
416 This deletes a driver "instance". The device is de-registered 395 This deletes a driver "instance". The device is de-registered
@@ -418,9 +397,12 @@ fail_alloc_dev:
418 structures are freed. Otherwise, the structures will be freed 397 structures are freed. Otherwise, the structures will be freed
419 when the device is released. 398 when the device is released.
420=============================================================================*/ 399=============================================================================*/
421static void ray_detach(dev_link_t *link) 400static void ray_detach(struct pcmcia_device *p_dev)
422{ 401{
402 dev_link_t *link = dev_to_instance(p_dev);
423 dev_link_t **linkp; 403 dev_link_t **linkp;
404 struct net_device *dev;
405 ray_dev_t *local;
424 406
425 DEBUG(1, "ray_detach(0x%p)\n", link); 407 DEBUG(1, "ray_detach(0x%p)\n", link);
426 408
@@ -430,22 +412,18 @@ static void ray_detach(dev_link_t *link)
430 if (*linkp == NULL) 412 if (*linkp == NULL)
431 return; 413 return;
432 414
433 /* If the device is currently configured and active, we won't 415 dev = link->priv;
434 actually delete it yet. Instead, it is marked so that when 416
435 the release() function is called, that will trigger a proper 417 if (link->state & DEV_CONFIG) {
436 detach(). 418 ray_release(link);
437 */ 419
438 if (link->state & DEV_CONFIG) 420 local = (ray_dev_t *)dev->priv;
439 ray_release(link); 421 del_timer(&local->timer);
422 }
440 423
441 /* Break the link with Card Services */
442 if (link->handle)
443 pcmcia_deregister_client(link->handle);
444
445 /* Unlink device structure, free pieces */ 424 /* Unlink device structure, free pieces */
446 *linkp = link->next; 425 *linkp = link->next;
447 if (link->priv) { 426 if (link->priv) {
448 struct net_device *dev = link->priv;
449 if (link->dev) unregister_netdev(dev); 427 if (link->dev) unregister_netdev(dev);
450 free_netdev(dev); 428 free_netdev(dev);
451 } 429 }
@@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link)
891 DEBUG(2,"ray_release ending\n"); 869 DEBUG(2,"ray_release ending\n");
892} 870}
893 871
894/*============================================================================= 872static int ray_suspend(struct pcmcia_device *p_dev)
895 The card status event handler. Mostly, this schedules other
896 stuff to run after an event is received. A CARD_REMOVAL event
897 also sets some flags to discourage the net drivers from trying
898 to talk to the card any more.
899
900 When a CARD_REMOVAL event is received, we immediately set a flag
901 to block future accesses to this device. All the functions that
902 actually access the device should check this flag to make sure
903 the card is still present.
904=============================================================================*/
905static int ray_event(event_t event, int priority,
906 event_callback_args_t *args)
907{ 873{
908 dev_link_t *link = args->client_data; 874 dev_link_t *link = dev_to_instance(p_dev);
909 struct net_device *dev = link->priv; 875 struct net_device *dev = link->priv;
910 ray_dev_t *local = (ray_dev_t *)dev->priv; 876
911 DEBUG(1, "ray_event(0x%06x)\n", event); 877 link->state |= DEV_SUSPEND;
912
913 switch (event) {
914 case CS_EVENT_CARD_REMOVAL:
915 link->state &= ~DEV_PRESENT;
916 netif_device_detach(dev);
917 if (link->state & DEV_CONFIG) {
918 ray_release(link);
919 del_timer(&local->timer);
920 }
921 break;
922 case CS_EVENT_CARD_INSERTION:
923 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
924 ray_config(link);
925 break;
926 case CS_EVENT_PM_SUSPEND:
927 link->state |= DEV_SUSPEND;
928 /* Fall through... */
929 case CS_EVENT_RESET_PHYSICAL:
930 if (link->state & DEV_CONFIG) { 878 if (link->state & DEV_CONFIG) {
931 if (link->open) 879 if (link->open)
932 netif_device_detach(dev); 880 netif_device_detach(dev);
933 881
934 pcmcia_release_configuration(link->handle); 882 pcmcia_release_configuration(link->handle);
935 } 883 }
936 break; 884
937 case CS_EVENT_PM_RESUME: 885
938 link->state &= ~DEV_SUSPEND; 886 return 0;
939 /* Fall through... */ 887}
940 case CS_EVENT_CARD_RESET: 888
889static int ray_resume(struct pcmcia_device *p_dev)
890{
891 dev_link_t *link = dev_to_instance(p_dev);
892 struct net_device *dev = link->priv;
893
894 link->state &= ~DEV_SUSPEND;
941 if (link->state & DEV_CONFIG) { 895 if (link->state & DEV_CONFIG) {
942 pcmcia_request_configuration(link->handle, &link->conf); 896 pcmcia_request_configuration(link->handle, &link->conf);
943 if (link->open) { 897 if (link->open) {
944 ray_reset(dev); 898 ray_reset(dev);
945 netif_device_attach(dev); 899 netif_device_attach(dev);
946 } 900 }
947 } 901 }
948 break; 902
949 } 903 return 0;
950 return 0; 904}
951 DEBUG(2,"ray_event ending\n"); 905
952} /* ray_event */
953/*===========================================================================*/ 906/*===========================================================================*/
954int ray_dev_init(struct net_device *dev) 907int ray_dev_init(struct net_device *dev)
955{ 908{
@@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = {
2945 .drv = { 2898 .drv = {
2946 .name = "ray_cs", 2899 .name = "ray_cs",
2947 }, 2900 },
2948 .attach = ray_attach, 2901 .probe = ray_attach,
2949 .event = ray_event, 2902 .remove = ray_detach,
2950 .detach = ray_detach,
2951 .id_table = ray_ids, 2903 .id_table = ray_ids,
2904 .suspend = ray_suspend,
2905 .resume = ray_resume,
2952}; 2906};
2953 2907
2954static int __init init_ray_cs(void) 2908static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..fee4be1ce810 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -57,17 +57,6 @@ module_param(ignore_cis_vcc, int, 0);
57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
58 58
59/********************************************************************/ 59/********************************************************************/
60/* Magic constants */
61/********************************************************************/
62
63/*
64 * The dev_info variable is the "key" that is used to match up this
65 * device driver with appropriate cards, through the card
66 * configuration database.
67 */
68static dev_info_t dev_info = DRIVER_NAME;
69
70/********************************************************************/
71/* Data structures */ 60/* Data structures */
72/********************************************************************/ 61/********************************************************************/
73 62
@@ -78,19 +67,12 @@ struct orinoco_pccard {
78 dev_node_t node; 67 dev_node_t node;
79}; 68};
80 69
81/*
82 * A linked list of "instances" of the device. Each actual PCMCIA
83 * card corresponds to one device instance, and is described by one
84 * dev_link_t structure (defined in ds.h).
85 */
86static dev_link_t *dev_list; /* = NULL */
87
88/********************************************************************/ 70/********************************************************************/
89/* Function prototypes */ 71/* Function prototypes */
90/********************************************************************/ 72/********************************************************************/
91 73
74static void spectrum_cs_config(dev_link_t *link);
92static void spectrum_cs_release(dev_link_t *link); 75static void spectrum_cs_release(dev_link_t *link);
93static void spectrum_cs_detach(dev_link_t *link);
94 76
95/********************************************************************/ 77/********************************************************************/
96/* Firmware downloader */ 78/* Firmware downloader */
@@ -601,19 +583,17 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)
601 * The dev_link structure is initialized, but we don't actually 583 * The dev_link structure is initialized, but we don't actually
602 * configure the card at this point -- we wait until we receive a card 584 * configure the card at this point -- we wait until we receive a card
603 * insertion event. */ 585 * insertion event. */
604static dev_link_t * 586static int
605spectrum_cs_attach(void) 587spectrum_cs_attach(struct pcmcia_device *p_dev)
606{ 588{
607 struct net_device *dev; 589 struct net_device *dev;
608 struct orinoco_private *priv; 590 struct orinoco_private *priv;
609 struct orinoco_pccard *card; 591 struct orinoco_pccard *card;
610 dev_link_t *link; 592 dev_link_t *link;
611 client_reg_t client_reg;
612 int ret;
613 593
614 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); 594 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
615 if (! dev) 595 if (! dev)
616 return NULL; 596 return -ENOMEM;
617 priv = netdev_priv(dev); 597 priv = netdev_priv(dev);
618 card = priv->card; 598 card = priv->card;
619 599
@@ -635,23 +615,13 @@ spectrum_cs_attach(void)
635 link->conf.Attributes = 0; 615 link->conf.Attributes = 0;
636 link->conf.IntType = INT_MEMORY_AND_IO; 616 link->conf.IntType = INT_MEMORY_AND_IO;
637 617
638 /* Register with Card Services */ 618 link->handle = p_dev;
639 /* FIXME: need a lock? */ 619 p_dev->instance = link;
640 link->next = dev_list;
641 dev_list = link;
642 620
643 client_reg.dev_info = &dev_info; 621 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
644 client_reg.Version = 0x0210; /* FIXME: what does this mean? */ 622 spectrum_cs_config(link);
645 client_reg.event_callback_args.client_data = link;
646 623
647 ret = pcmcia_register_client(&link->handle, &client_reg); 624 return 0;
648 if (ret != CS_SUCCESS) {
649 cs_error(link->handle, RegisterClient, ret);
650 spectrum_cs_detach(link);
651 return NULL;
652 }
653
654 return link;
655} /* spectrum_cs_attach */ 625} /* spectrum_cs_attach */
656 626
657/* 627/*
@@ -660,27 +630,14 @@ spectrum_cs_attach(void)
660 * are freed. Otherwise, the structures will be freed when the device 630 * are freed. Otherwise, the structures will be freed when the device
661 * is released. 631 * is released.
662 */ 632 */
663static void spectrum_cs_detach(dev_link_t *link) 633static void spectrum_cs_detach(struct pcmcia_device *p_dev)
664{ 634{
665 dev_link_t **linkp; 635 dev_link_t *link = dev_to_instance(p_dev);
666 struct net_device *dev = link->priv; 636 struct net_device *dev = link->priv;
667 637
668 /* Locate device structure */
669 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
670 if (*linkp == link)
671 break;
672
673 BUG_ON(*linkp == NULL);
674
675 if (link->state & DEV_CONFIG) 638 if (link->state & DEV_CONFIG)
676 spectrum_cs_release(link); 639 spectrum_cs_release(link);
677 640
678 /* Break the link with Card Services */
679 if (link->handle)
680 pcmcia_deregister_client(link->handle);
681
682 /* Unlink device structure, and free it */
683 *linkp = link->next;
684 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); 641 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
685 if (link->dev) { 642 if (link->dev) {
686 DEBUG(0, PFX "About to unregister net device %p\n", 643 DEBUG(0, PFX "About to unregister net device %p\n",
@@ -948,82 +905,56 @@ spectrum_cs_release(dev_link_t *link)
948 ioport_unmap(priv->hw.iobase); 905 ioport_unmap(priv->hw.iobase);
949} /* spectrum_cs_release */ 906} /* spectrum_cs_release */
950 907
951/* 908
952 * The card status event handler. Mostly, this schedules other stuff
953 * to run after an event is received.
954 */
955static int 909static int
956spectrum_cs_event(event_t event, int priority, 910spectrum_cs_suspend(struct pcmcia_device *p_dev)
957 event_callback_args_t * args)
958{ 911{
959 dev_link_t *link = args->client_data; 912 dev_link_t *link = dev_to_instance(p_dev);
960 struct net_device *dev = link->priv; 913 struct net_device *dev = link->priv;
961 struct orinoco_private *priv = netdev_priv(dev); 914 struct orinoco_private *priv = netdev_priv(dev);
962 int err = 0;
963 unsigned long flags; 915 unsigned long flags;
916 int err = 0;
964 917
965 switch (event) { 918 link->state |= DEV_SUSPEND;
966 case CS_EVENT_CARD_REMOVAL: 919 /* Mark the device as stopped, to block IO until later */
967 link->state &= ~DEV_PRESENT; 920 if (link->state & DEV_CONFIG) {
968 if (link->state & DEV_CONFIG) { 921 spin_lock_irqsave(&priv->lock, flags);
969 unsigned long flags;
970 922
971 spin_lock_irqsave(&priv->lock, flags); 923 err = __orinoco_down(dev);
972 netif_device_detach(dev); 924 if (err)
973 priv->hw_unavailable++; 925 printk(KERN_WARNING "%s: Error %d downing interface\n",
974 spin_unlock_irqrestore(&priv->lock, flags); 926 dev->name, err);
975 }
976 break;
977 927
978 case CS_EVENT_CARD_INSERTION: 928 netif_device_detach(dev);
979 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 929 priv->hw_unavailable++;
980 spectrum_cs_config(link);
981 break;
982 930
983 case CS_EVENT_PM_SUSPEND: 931 spin_unlock_irqrestore(&priv->lock, flags);
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 932
1010 case CS_EVENT_PM_RESUME: 933 pcmcia_release_configuration(link->handle);
1011 link->state &= ~DEV_SUSPEND; 934 }
1012 /* Fall through... */ 935
1013 case CS_EVENT_CARD_RESET: 936 return 0;
1014 if (link->state & DEV_CONFIG) { 937}
1015 /* FIXME: should we double check that this is 938
1016 * the same card as we had before */ 939static int
1017 pcmcia_request_configuration(link->handle, &link->conf); 940spectrum_cs_resume(struct pcmcia_device *p_dev)
1018 netif_device_attach(dev); 941{
1019 priv->hw_unavailable--; 942 dev_link_t *link = dev_to_instance(p_dev);
1020 schedule_work(&priv->reset_work); 943 struct net_device *dev = link->priv;
1021 } 944 struct orinoco_private *priv = netdev_priv(dev);
1022 break; 945
946 link->state &= ~DEV_SUSPEND;
947 if (link->state & DEV_CONFIG) {
948 /* FIXME: should we double check that this is
949 * the same card as we had before */
950 pcmcia_request_configuration(link->handle, &link->conf);
951 netif_device_attach(dev);
952 priv->hw_unavailable--;
953 schedule_work(&priv->reset_work);
1023 } 954 }
955 return 0;
956}
1024 957
1025 return err;
1026} /* spectrum_cs_event */
1027 958
1028/********************************************************************/ 959/********************************************************************/
1029/* Module initialization */ 960/* Module initialization */
@@ -1048,9 +979,10 @@ static struct pcmcia_driver orinoco_driver = {
1048 .drv = { 979 .drv = {
1049 .name = DRIVER_NAME, 980 .name = DRIVER_NAME,
1050 }, 981 },
1051 .attach = spectrum_cs_attach, 982 .probe = spectrum_cs_attach,
1052 .detach = spectrum_cs_detach, 983 .remove = spectrum_cs_detach,
1053 .event = spectrum_cs_event, 984 .suspend = spectrum_cs_suspend,
985 .resume = spectrum_cs_resume,
1054 .id_table = spectrum_cs_ids, 986 .id_table = spectrum_cs_ids,
1055}; 987};
1056 988
@@ -1066,7 +998,6 @@ static void __exit
1066exit_spectrum_cs(void) 998exit_spectrum_cs(void)
1067{ 999{
1068 pcmcia_unregister_driver(&orinoco_driver); 1000 pcmcia_unregister_driver(&orinoco_driver);
1069 BUG_ON(dev_list != NULL);
1070} 1001}
1071 1002
1072module_init(init_spectrum_cs); 1003module_init(init_spectrum_cs);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333f..7e2039f52c49 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4594,14 +4594,12 @@ wavelan_close(struct net_device * dev)
4594 * configure the card at this point -- we wait until we receive a 4594 * configure the card at this point -- we wait until we receive a
4595 * card insertion event. 4595 * card insertion event.
4596 */ 4596 */
4597static dev_link_t * 4597static int
4598wavelan_attach(void) 4598wavelan_attach(struct pcmcia_device *p_dev)
4599{ 4599{
4600 client_reg_t client_reg; /* Register with cardmgr */
4601 dev_link_t * link; /* Info for cardmgr */ 4600 dev_link_t * link; /* Info for cardmgr */
4602 struct net_device * dev; /* Interface generic data */ 4601 struct net_device * dev; /* Interface generic data */
4603 net_local * lp; /* Interface specific data */ 4602 net_local * lp; /* Interface specific data */
4604 int ret;
4605 4603
4606#ifdef DEBUG_CALLBACK_TRACE 4604#ifdef DEBUG_CALLBACK_TRACE
4607 printk(KERN_DEBUG "-> wavelan_attach()\n"); 4605 printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4609,7 +4607,7 @@ wavelan_attach(void)
4609 4607
4610 /* Initialize the dev_link_t structure */ 4608 /* Initialize the dev_link_t structure */
4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4609 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4610 if (!link) return -ENOMEM;
4613 4611
4614 /* The io structure describes IO port mapping */ 4612 /* The io structure describes IO port mapping */
4615 link->io.NumPorts1 = 8; 4613 link->io.NumPorts1 = 8;
@@ -4627,14 +4625,13 @@ wavelan_attach(void)
4627 link->conf.IntType = INT_MEMORY_AND_IO; 4625 link->conf.IntType = INT_MEMORY_AND_IO;
4628 4626
4629 /* Chain drivers */ 4627 /* Chain drivers */
4630 link->next = dev_list; 4628 link->next = NULL;
4631 dev_list = link;
4632 4629
4633 /* Allocate the generic data structure */ 4630 /* Allocate the generic data structure */
4634 dev = alloc_etherdev(sizeof(net_local)); 4631 dev = alloc_etherdev(sizeof(net_local));
4635 if (!dev) { 4632 if (!dev) {
4636 kfree(link); 4633 kfree(link);
4637 return NULL; 4634 return -ENOMEM;
4638 } 4635 }
4639 link->priv = link->irq.Instance = dev; 4636 link->priv = link->irq.Instance = dev;
4640 4637
@@ -4679,28 +4676,21 @@ wavelan_attach(void)
4679 /* Other specific data */ 4676 /* Other specific data */
4680 dev->mtu = WAVELAN_MTU; 4677 dev->mtu = WAVELAN_MTU;
4681 4678
4682 /* Register with Card Services */ 4679 link->handle = p_dev;
4683 client_reg.dev_info = &dev_info; 4680 p_dev->instance = link;
4684 client_reg.Version = 0x0210;
4685 client_reg.event_callback_args.client_data = link;
4686 4681
4687#ifdef DEBUG_CONFIG_INFO 4682 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4688 printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n"); 4683 if(wv_pcmcia_config(link) &&
4689#endif 4684 wv_hw_config(dev))
4690 4685 wv_init_info(dev);
4691 ret = pcmcia_register_client(&link->handle, &client_reg); 4686 else
4692 if(ret != 0) 4687 dev->irq = 0;
4693 {
4694 cs_error(link->handle, RegisterClient, ret);
4695 wavelan_detach(link);
4696 return NULL;
4697 }
4698 4688
4699#ifdef DEBUG_CALLBACK_TRACE 4689#ifdef DEBUG_CALLBACK_TRACE
4700 printk(KERN_DEBUG "<- wavelan_attach()\n"); 4690 printk(KERN_DEBUG "<- wavelan_attach()\n");
4701#endif 4691#endif
4702 4692
4703 return link; 4693 return 0;
4704} 4694}
4705 4695
4706/*------------------------------------------------------------------*/ 4696/*------------------------------------------------------------------*/
@@ -4711,8 +4701,10 @@ wavelan_attach(void)
4711 * is released. 4701 * is released.
4712 */ 4702 */
4713static void 4703static void
4714wavelan_detach(dev_link_t * link) 4704wavelan_detach(struct pcmcia_device *p_dev)
4715{ 4705{
4706 dev_link_t *link = dev_to_instance(p_dev);
4707
4716#ifdef DEBUG_CALLBACK_TRACE 4708#ifdef DEBUG_CALLBACK_TRACE
4717 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); 4709 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
4718#endif 4710#endif
@@ -4729,31 +4721,6 @@ wavelan_detach(dev_link_t * link)
4729 wv_pcmcia_release(link); 4721 wv_pcmcia_release(link);
4730 } 4722 }
4731 4723
4732 /* Break the link with Card Services */
4733 if(link->handle)
4734 pcmcia_deregister_client(link->handle);
4735
4736 /* Remove the interface data from the linked list */
4737 if(dev_list == link)
4738 dev_list = link->next;
4739 else
4740 {
4741 dev_link_t * prev = dev_list;
4742
4743 while((prev != (dev_link_t *) NULL) && (prev->next != link))
4744 prev = prev->next;
4745
4746 if(prev == (dev_link_t *) NULL)
4747 {
4748#ifdef DEBUG_CONFIG_ERRORS
4749 printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
4750#endif
4751 return;
4752 }
4753
4754 prev->next = link->next;
4755 }
4756
4757 /* Free pieces */ 4724 /* Free pieces */
4758 if(link->priv) 4725 if(link->priv)
4759 { 4726 {
@@ -4775,65 +4742,11 @@ wavelan_detach(dev_link_t * link)
4775#endif 4742#endif
4776} 4743}
4777 4744
4778/*------------------------------------------------------------------*/ 4745static int wavelan_suspend(struct pcmcia_device *p_dev)
4779/*
4780 * The card status event handler. Mostly, this schedules other stuff
4781 * to run after an event is received. A CARD_REMOVAL event also sets
4782 * some flags to discourage the net drivers from trying to talk to the
4783 * card any more.
4784 */
4785static int
4786wavelan_event(event_t event, /* The event received */
4787 int priority,
4788 event_callback_args_t * args)
4789{ 4746{
4790 dev_link_t * link = (dev_link_t *) args->client_data; 4747 dev_link_t *link = dev_to_instance(p_dev);
4791 struct net_device * dev = (struct net_device *) link->priv; 4748 struct net_device * dev = (struct net_device *) link->priv;
4792
4793#ifdef DEBUG_CALLBACK_TRACE
4794 printk(KERN_DEBUG "->wavelan_event(): %s\n",
4795 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
4796 ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
4797 ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
4798 ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
4799 ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
4800 ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
4801 ((event == CS_EVENT_CARD_RESET) ? "card reset" :
4802 "unknown"))))))));
4803#endif
4804
4805 switch(event)
4806 {
4807 case CS_EVENT_REGISTRATION_COMPLETE:
4808#ifdef DEBUG_CONFIG_INFO
4809 printk(KERN_DEBUG "wavelan_cs: registration complete\n");
4810#endif
4811 break;
4812 4749
4813 case CS_EVENT_CARD_REMOVAL:
4814 /* Oups ! The card is no more there */
4815 link->state &= ~DEV_PRESENT;
4816 if(link->state & DEV_CONFIG)
4817 {
4818 /* Accept no more transmissions */
4819 netif_device_detach(dev);
4820
4821 /* Release the card */
4822 wv_pcmcia_release(link);
4823 }
4824 break;
4825
4826 case CS_EVENT_CARD_INSERTION:
4827 /* Reset and configure the card */
4828 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4829 if(wv_pcmcia_config(link) &&
4830 wv_hw_config(dev))
4831 wv_init_info(dev);
4832 else
4833 dev->irq = 0;
4834 break;
4835
4836 case CS_EVENT_PM_SUSPEND:
4837 /* NB: wavelan_close will be called, but too late, so we are 4750 /* NB: wavelan_close will be called, but too late, so we are
4838 * obliged to close nicely the wavelan here. David, could you 4751 * obliged to close nicely the wavelan here. David, could you
4839 * close the device before suspending them ? And, by the way, 4752 * close the device before suspending them ? And, by the way,
@@ -4848,38 +4761,37 @@ wavelan_event(event_t event, /* The event received */
4848 4761
4849 /* The card is now suspended */ 4762 /* The card is now suspended */
4850 link->state |= DEV_SUSPEND; 4763 link->state |= DEV_SUSPEND;
4851 /* Fall through... */ 4764
4852 case CS_EVENT_RESET_PHYSICAL:
4853 if(link->state & DEV_CONFIG) 4765 if(link->state & DEV_CONFIG)
4854 { 4766 {
4855 if(link->open) 4767 if(link->open)
4856 netif_device_detach(dev); 4768 netif_device_detach(dev);
4857 pcmcia_release_configuration(link->handle); 4769 pcmcia_release_configuration(link->handle);
4858 } 4770 }
4859 break; 4771
4772 return 0;
4773}
4774
4775static int wavelan_resume(struct pcmcia_device *p_dev)
4776{
4777 dev_link_t *link = dev_to_instance(p_dev);
4778 struct net_device * dev = (struct net_device *) link->priv;
4860 4779
4861 case CS_EVENT_PM_RESUME:
4862 link->state &= ~DEV_SUSPEND; 4780 link->state &= ~DEV_SUSPEND;
4863 /* Fall through... */
4864 case CS_EVENT_CARD_RESET:
4865 if(link->state & DEV_CONFIG) 4781 if(link->state & DEV_CONFIG)
4866 { 4782 {
4867 pcmcia_request_configuration(link->handle, &link->conf); 4783 pcmcia_request_configuration(link->handle, &link->conf);
4868 if(link->open) /* If RESET -> True, If RESUME -> False ? */ 4784 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4869 { 4785 {
4870 wv_hw_reset(dev); 4786 wv_hw_reset(dev);
4871 netif_device_attach(dev); 4787 netif_device_attach(dev);
4872 } 4788 }
4873 } 4789 }
4874 break;
4875 }
4876 4790
4877#ifdef DEBUG_CALLBACK_TRACE 4791 return 0;
4878 printk(KERN_DEBUG "<-wavelan_event()\n");
4879#endif
4880 return 0;
4881} 4792}
4882 4793
4794
4883static struct pcmcia_device_id wavelan_ids[] = { 4795static struct pcmcia_device_id wavelan_ids[] = {
4884 PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975), 4796 PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
4885 PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06), 4797 PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
@@ -4894,10 +4806,11 @@ static struct pcmcia_driver wavelan_driver = {
4894 .drv = { 4806 .drv = {
4895 .name = "wavelan_cs", 4807 .name = "wavelan_cs",
4896 }, 4808 },
4897 .attach = wavelan_attach, 4809 .probe = wavelan_attach,
4898 .event = wavelan_event, 4810 .remove = wavelan_detach,
4899 .detach = wavelan_detach,
4900 .id_table = wavelan_ids, 4811 .id_table = wavelan_ids,
4812 .suspend = wavelan_suspend,
4813 .resume = wavelan_resume,
4901}; 4814};
4902 4815
4903static int __init 4816static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 724a715089c9..f2d597568151 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -754,20 +754,11 @@ static void
754static int 754static int
755 wavelan_open(struct net_device *), /* Open the device */ 755 wavelan_open(struct net_device *), /* Open the device */
756 wavelan_close(struct net_device *); /* Close the device */ 756 wavelan_close(struct net_device *); /* Close the device */
757static dev_link_t *
758 wavelan_attach(void); /* Create a new device */
759static void 757static void
760 wavelan_detach(dev_link_t *); /* Destroy a removed device */ 758 wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */
761static int
762 wavelan_event(event_t, /* Manage pcmcia events */
763 int,
764 event_callback_args_t *);
765 759
766/**************************** VARIABLES ****************************/ 760/**************************** VARIABLES ****************************/
767 761
768static dev_info_t dev_info = "wavelan_cs";
769static dev_link_t *dev_list = NULL; /* Linked list of devices */
770
771/* 762/*
772 * Parameters that can be set with 'insmod' 763 * Parameters that can be set with 'insmod'
773 * The exact syntax is 'insmod wavelan_cs.o <var>=<value>' 764 * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..48e10b0c7e74 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);
105 */ 105 */
106static void wl3501_config(dev_link_t *link); 106static void wl3501_config(dev_link_t *link);
107static void wl3501_release(dev_link_t *link); 107static void wl3501_release(dev_link_t *link);
108static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
109 108
110/* 109/*
111 * The dev_info variable is the "key" that is used to match up this 110 * The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,11 @@ static struct ethtool_ops ops = {
1498 * Services. If it has been released, all local data structures are freed. 1497 * Services. If it has been released, all local data structures are freed.
1499 * Otherwise, the structures will be freed when the device is released. 1498 * Otherwise, the structures will be freed when the device is released.
1500 */ 1499 */
1501static void wl3501_detach(dev_link_t *link) 1500static void wl3501_detach(struct pcmcia_device *p_dev)
1502{ 1501{
1502 dev_link_t *link = dev_to_instance(p_dev);
1503 dev_link_t **linkp; 1503 dev_link_t **linkp;
1504 struct net_device *dev = link->priv;
1504 1505
1505 /* Locate device structure */ 1506 /* Locate device structure */
1506 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) 1507 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
@@ -1514,16 +1515,12 @@ static void wl3501_detach(dev_link_t *link)
1514 * function is called, that will trigger a proper detach(). */ 1515 * function is called, that will trigger a proper detach(). */
1515 1516
1516 if (link->state & DEV_CONFIG) { 1517 if (link->state & DEV_CONFIG) {
1517#ifdef PCMCIA_DEBUG 1518 while (link->open > 0)
1518 printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' " 1519 wl3501_close(dev);
1519 "still locked\n", link->dev->dev_name);
1520#endif
1521 goto out;
1522 }
1523 1520
1524 /* Break the link with Card Services */ 1521 netif_device_detach(dev);
1525 if (link->handle) 1522 wl3501_release(link);
1526 pcmcia_deregister_client(link->handle); 1523 }
1527 1524
1528 /* Unlink device structure, free pieces */ 1525 /* Unlink device structure, free pieces */
1529 *linkp = link->next; 1526 *linkp = link->next;
@@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {
1956 * The dev_link structure is initialized, but we don't actually configure the 1953 * The dev_link structure is initialized, but we don't actually configure the
1957 * card at this point -- we wait until we receive a card insertion event. 1954 * card at this point -- we wait until we receive a card insertion event.
1958 */ 1955 */
1959static dev_link_t *wl3501_attach(void) 1956static int wl3501_attach(struct pcmcia_device *p_dev)
1960{ 1957{
1961 client_reg_t client_reg;
1962 dev_link_t *link; 1958 dev_link_t *link;
1963 struct net_device *dev; 1959 struct net_device *dev;
1964 struct wl3501_card *this; 1960 struct wl3501_card *this;
1965 int ret;
1966 1961
1967 /* Initialize the dev_link_t structure */ 1962 /* Initialize the dev_link_t structure */
1968 link = kzalloc(sizeof(*link), GFP_KERNEL); 1963 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1964 if (!link)
1970 goto out; 1965 return -ENOMEM;
1971 1966
1972 /* The io structure describes IO port mapping */ 1967 /* The io structure describes IO port mapping */
1973 link->io.NumPorts1 = 16; 1968 link->io.NumPorts1 = 16;
@@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)
2003 netif_stop_queue(dev); 1998 netif_stop_queue(dev);
2004 link->priv = link->irq.Instance = dev; 1999 link->priv = link->irq.Instance = dev;
2005 2000
2006 /* Register with Card Services */ 2001 link->handle = p_dev;
2007 link->next = wl3501_dev_list; 2002 p_dev->instance = link;
2008 wl3501_dev_list = link; 2003
2009 client_reg.dev_info = &wl3501_dev_info; 2004 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2010 client_reg.Version = 0x0210; 2005 wl3501_config(link);
2011 client_reg.event_callback_args.client_data = link; 2006
2012 ret = pcmcia_register_client(&link->handle, &client_reg); 2007 return 0;
2013 if (ret) {
2014 cs_error(link->handle, RegisterClient, ret);
2015 wl3501_detach(link);
2016 link = NULL;
2017 }
2018out:
2019 return link;
2020out_link: 2008out_link:
2021 kfree(link); 2009 kfree(link);
2022 link = NULL; 2010 link = NULL;
2023 goto out; 2011 return -ENOMEM;
2024} 2012}
2025 2013
2026#define CS_CHECK(fn, ret) \ 2014#define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)
2173 link->state &= ~DEV_CONFIG; 2161 link->state &= ~DEV_CONFIG;
2174} 2162}
2175 2163
2176/** 2164static int wl3501_suspend(struct pcmcia_device *p_dev)
2177 * wl3501_event - The card status event handler
2178 * @event - event
2179 * @pri - priority
2180 * @args - arguments for this event
2181 *
2182 * The card status event handler. Mostly, this schedules other stuff to run
2183 * after an event is received. A CARD_REMOVAL event also sets some flags to
2184 * discourage the net drivers from trying to talk to the card any more.
2185 *
2186 * When a CARD_REMOVAL event is received, we immediately set a flag to block
2187 * future accesses to this device. All the functions that actually access the
2188 * device should check this flag to make sure the card is still present.
2189 */
2190static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2191{ 2165{
2192 dev_link_t *link = args->client_data; 2166 dev_link_t *link = dev_to_instance(p_dev);
2193 struct net_device *dev = link->priv; 2167 struct net_device *dev = link->priv;
2194 2168
2195 switch (event) { 2169 link->state |= DEV_SUSPEND;
2196 case CS_EVENT_CARD_REMOVAL: 2170
2197 link->state &= ~DEV_PRESENT; 2171 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2198 if (link->state & DEV_CONFIG) { 2172 if (link->state & DEV_CONFIG) {
2199 while (link->open > 0) 2173 if (link->open)
2200 wl3501_close(dev);
2201 netif_device_detach(dev); 2174 netif_device_detach(dev);
2202 wl3501_release(link); 2175 pcmcia_release_configuration(link->handle);
2203 } 2176 }
2204 break; 2177
2205 case CS_EVENT_CARD_INSERTION: 2178 return 0;
2206 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 2179}
2207 wl3501_config(link); 2180
2208 break; 2181static int wl3501_resume(struct pcmcia_device *p_dev)
2209 case CS_EVENT_PM_SUSPEND: 2182{
2210 link->state |= DEV_SUSPEND; 2183 dev_link_t *link = dev_to_instance(p_dev);
2211 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); 2184 struct net_device *dev = link->priv;
2212 /* Fall through... */ 2185
2213 case CS_EVENT_RESET_PHYSICAL: 2186 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2214 if (link->state & DEV_CONFIG) { 2187 if (link->state & DEV_CONFIG) {
2215 if (link->open) 2188 pcmcia_request_configuration(link->handle, &link->conf);
2216 netif_device_detach(dev); 2189 if (link->open) {
2217 pcmcia_release_configuration(link->handle); 2190 wl3501_reset(dev);
2218 } 2191 netif_device_attach(dev);
2219 break;
2220 case CS_EVENT_PM_RESUME:
2221 link->state &= ~DEV_SUSPEND;
2222 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2223 /* Fall through... */
2224 case CS_EVENT_CARD_RESET:
2225 if (link->state & DEV_CONFIG) {
2226 pcmcia_request_configuration(link->handle, &link->conf);
2227 if (link->open) {
2228 wl3501_reset(dev);
2229 netif_device_attach(dev);
2230 }
2231 } 2192 }
2232 break;
2233 } 2193 }
2194
2234 return 0; 2195 return 0;
2235} 2196}
2236 2197
2198
2237static struct pcmcia_device_id wl3501_ids[] = { 2199static struct pcmcia_device_id wl3501_ids[] = {
2238 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001), 2200 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
2239 PCMCIA_DEVICE_NULL 2201 PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {
2245 .drv = { 2207 .drv = {
2246 .name = "wl3501_cs", 2208 .name = "wl3501_cs",
2247 }, 2209 },
2248 .attach = wl3501_attach, 2210 .probe = wl3501_attach,
2249 .event = wl3501_event, 2211 .remove = wl3501_detach,
2250 .detach = wl3501_detach,
2251 .id_table = wl3501_ids, 2212 .id_table = wl3501_ids,
2213 .suspend = wl3501_suspend,
2214 .resume = wl3501_resume,
2252}; 2215};
2253 2216
2254static int __init wl3501_init_module(void) 2217static int __init wl3501_init_module(void)