aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/airo_cs.c')
-rw-r--r--drivers/net/wireless/airo_cs.c158
1 files changed, 50 insertions, 108 deletions
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index a496460ce224..af0cbb6c5c0c 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -80,8 +80,8 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
80 event handler. 80 event handler.
81*/ 81*/
82 82
83static void airo_config(dev_link_t *link); 83static int airo_config(struct pcmcia_device *link);
84static void airo_release(dev_link_t *link); 84static void airo_release(struct pcmcia_device *link);
85 85
86/* 86/*
87 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
@@ -101,10 +101,10 @@ static void airo_detach(struct pcmcia_device *p_dev);
101/* 101/*
102 A linked list of "instances" of the aironet device. Each actual 102 A linked list of "instances" of the aironet device. Each actual
103 PCMCIA card corresponds to one device instance, and is described 103 PCMCIA card corresponds to one device instance, and is described
104 by one dev_link_t structure (defined in ds.h). 104 by one struct pcmcia_device structure (defined in ds.h).
105 105
106 You may not want to use a linked list for this -- for example, the 106 You may not want to use a linked list for this -- for example, the
107 memory card driver uses an array of dev_link_t pointers, where minor 107 memory card driver uses an array of struct pcmcia_device pointers, where minor
108 device numbers are used to derive the corresponding array index. 108 device numbers are used to derive the corresponding array index.
109*/ 109*/
110 110
@@ -114,7 +114,7 @@ static void airo_detach(struct pcmcia_device *p_dev);
114 example, ethernet cards, modems). In other cases, there may be 114 example, ethernet cards, modems). In other cases, there may be
115 many actual or logical devices (SCSI adapters, memory cards with 115 many actual or logical devices (SCSI adapters, memory cards with
116 multiple partitions). The dev_node_t structures need to be kept 116 multiple partitions). The dev_node_t structures need to be kept
117 in a linked list starting at the 'dev' field of a dev_link_t 117 in a linked list starting at the 'dev' field of a struct pcmcia_device
118 structure. We allocate them in the card's private data structure, 118 structure. We allocate them in the card's private data structure,
119 because they generally shouldn't be allocated dynamically. 119 because they generally shouldn't be allocated dynamically.
120 120
@@ -141,24 +141,16 @@ typedef struct local_info_t {
141 141
142 ======================================================================*/ 142 ======================================================================*/
143 143
144static int airo_attach(struct pcmcia_device *p_dev) 144static int airo_probe(struct pcmcia_device *p_dev)
145{ 145{
146 dev_link_t *link;
147 local_info_t *local; 146 local_info_t *local;
148 147
149 DEBUG(0, "airo_attach()\n"); 148 DEBUG(0, "airo_attach()\n");
150 149
151 /* Initialize the dev_link_t structure */
152 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
153 if (!link) {
154 printk(KERN_ERR "airo_cs: no memory for new device\n");
155 return -ENOMEM;
156 }
157
158 /* Interrupt setup */ 150 /* Interrupt setup */
159 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 151 p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
160 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 152 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
161 link->irq.Handler = NULL; 153 p_dev->irq.Handler = NULL;
162 154
163 /* 155 /*
164 General socket configuration defaults can go here. In this 156 General socket configuration defaults can go here. In this
@@ -167,26 +159,18 @@ static int airo_attach(struct pcmcia_device *p_dev)
167 and attributes of IO windows) are fixed by the nature of the 159 and attributes of IO windows) are fixed by the nature of the
168 device, and can be hard-wired here. 160 device, and can be hard-wired here.
169 */ 161 */
170 link->conf.Attributes = 0; 162 p_dev->conf.Attributes = 0;
171 link->conf.Vcc = 50; 163 p_dev->conf.IntType = INT_MEMORY_AND_IO;
172 link->conf.IntType = INT_MEMORY_AND_IO;
173 164
174 /* Allocate space for private device-specific data */ 165 /* Allocate space for private device-specific data */
175 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 166 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
176 if (!local) { 167 if (!local) {
177 printk(KERN_ERR "airo_cs: no memory for new device\n"); 168 printk(KERN_ERR "airo_cs: no memory for new device\n");
178 kfree (link);
179 return -ENOMEM; 169 return -ENOMEM;
180 } 170 }
181 link->priv = local; 171 p_dev->priv = local;
182 172
183 link->handle = p_dev; 173 return airo_config(p_dev);
184 p_dev->instance = link;
185
186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
187 airo_config(link);
188
189 return 0;
190} /* airo_attach */ 174} /* airo_attach */
191 175
192/*====================================================================== 176/*======================================================================
@@ -198,14 +182,11 @@ static int airo_attach(struct pcmcia_device *p_dev)
198 182
199 ======================================================================*/ 183 ======================================================================*/
200 184
201static void airo_detach(struct pcmcia_device *p_dev) 185static void airo_detach(struct pcmcia_device *link)
202{ 186{
203 dev_link_t *link = dev_to_instance(p_dev);
204
205 DEBUG(0, "airo_detach(0x%p)\n", link); 187 DEBUG(0, "airo_detach(0x%p)\n", link);
206 188
207 if (link->state & DEV_CONFIG) 189 airo_release(link);
208 airo_release(link);
209 190
210 if ( ((local_info_t*)link->priv)->eth_dev ) { 191 if ( ((local_info_t*)link->priv)->eth_dev ) {
211 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); 192 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
@@ -213,7 +194,6 @@ static void airo_detach(struct pcmcia_device *p_dev)
213 ((local_info_t*)link->priv)->eth_dev = NULL; 194 ((local_info_t*)link->priv)->eth_dev = NULL;
214 195
215 kfree(link->priv); 196 kfree(link->priv);
216 kfree(link);
217} /* airo_detach */ 197} /* airo_detach */
218 198
219/*====================================================================== 199/*======================================================================
@@ -227,9 +207,8 @@ static void airo_detach(struct pcmcia_device *p_dev)
227#define CS_CHECK(fn, ret) \ 207#define CS_CHECK(fn, ret) \
228do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 208do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
229 209
230static void airo_config(dev_link_t *link) 210static int airo_config(struct pcmcia_device *link)
231{ 211{
232 client_handle_t handle;
233 tuple_t tuple; 212 tuple_t tuple;
234 cisparse_t parse; 213 cisparse_t parse;
235 local_info_t *dev; 214 local_info_t *dev;
@@ -237,8 +216,7 @@ static void airo_config(dev_link_t *link)
237 u_char buf[64]; 216 u_char buf[64];
238 win_req_t req; 217 win_req_t req;
239 memreq_t map; 218 memreq_t map;
240 219
241 handle = link->handle;
242 dev = link->priv; 220 dev = link->priv;
243 221
244 DEBUG(0, "airo_config(0x%p)\n", link); 222 DEBUG(0, "airo_config(0x%p)\n", link);
@@ -252,15 +230,12 @@ static void airo_config(dev_link_t *link)
252 tuple.TupleData = buf; 230 tuple.TupleData = buf;
253 tuple.TupleDataMax = sizeof(buf); 231 tuple.TupleDataMax = sizeof(buf);
254 tuple.TupleOffset = 0; 232 tuple.TupleOffset = 0;
255 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 233 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
256 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 234 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
257 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 235 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
258 link->conf.ConfigBase = parse.config.base; 236 link->conf.ConfigBase = parse.config.base;
259 link->conf.Present = parse.config.rmask[0]; 237 link->conf.Present = parse.config.rmask[0];
260 238
261 /* Configure card */
262 link->state |= DEV_CONFIG;
263
264 /* 239 /*
265 In this loop, we scan the CIS for configuration table entries, 240 In this loop, we scan the CIS for configuration table entries,
266 each of which describes a valid card configuration, including 241 each of which describes a valid card configuration, including
@@ -274,12 +249,12 @@ static void airo_config(dev_link_t *link)
274 will only use the CIS to fill in implementation-defined details. 249 will only use the CIS to fill in implementation-defined details.
275 */ 250 */
276 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 251 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
277 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 252 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
278 while (1) { 253 while (1) {
279 cistpl_cftable_entry_t dflt = { 0 }; 254 cistpl_cftable_entry_t dflt = { 0 };
280 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 255 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
281 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 256 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
282 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 257 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
283 goto next_entry; 258 goto next_entry;
284 259
285 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; 260 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
@@ -294,16 +269,11 @@ static void airo_config(dev_link_t *link)
294 269
295 /* Use power settings for Vcc and Vpp if present */ 270 /* Use power settings for Vcc and Vpp if present */
296 /* Note that the CIS values need to be rescaled */ 271 /* Note that the CIS values need to be rescaled */
297 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
298 link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
299 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
300 link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
301
302 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 272 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
303 link->conf.Vpp1 = link->conf.Vpp2 = 273 link->conf.Vpp =
304 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 274 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
305 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 275 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
306 link->conf.Vpp1 = link->conf.Vpp2 = 276 link->conf.Vpp =
307 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; 277 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
308 278
309 /* Do we need to allocate an interrupt? */ 279 /* Do we need to allocate an interrupt? */
@@ -329,12 +299,12 @@ static void airo_config(dev_link_t *link)
329 } 299 }
330 300
331 /* This reserves IO space but doesn't actually enable it */ 301 /* This reserves IO space but doesn't actually enable it */
332 if (pcmcia_request_io(link->handle, &link->io) != 0) 302 if (pcmcia_request_io(link, &link->io) != 0)
333 goto next_entry; 303 goto next_entry;
334 304
335 /* 305 /*
336 Now set up a common memory window, if needed. There is room 306 Now set up a common memory window, if needed. There is room
337 in the dev_link_t structure for one memory window handle, 307 in the struct pcmcia_device structure for one memory window handle,
338 but if the base addresses need to be saved, or if multiple 308 but if the base addresses need to be saved, or if multiple
339 windows are needed, the info should go in the private data 309 windows are needed, the info should go in the private data
340 structure for this device. 310 structure for this device.
@@ -350,7 +320,7 @@ static void airo_config(dev_link_t *link)
350 req.Base = mem->win[0].host_addr; 320 req.Base = mem->win[0].host_addr;
351 req.Size = mem->win[0].len; 321 req.Size = mem->win[0].len;
352 req.AccessSpeed = 0; 322 req.AccessSpeed = 0;
353 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) 323 if (pcmcia_request_window(&link, &req, &link->win) != 0)
354 goto next_entry; 324 goto next_entry;
355 map.Page = 0; map.CardOffset = mem->win[0].card_addr; 325 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
356 if (pcmcia_map_mem_page(link->win, &map) != 0) 326 if (pcmcia_map_mem_page(link->win, &map) != 0)
@@ -360,7 +330,7 @@ static void airo_config(dev_link_t *link)
360 break; 330 break;
361 331
362 next_entry: 332 next_entry:
363 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 333 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
364 } 334 }
365 335
366 /* 336 /*
@@ -369,33 +339,32 @@ static void airo_config(dev_link_t *link)
369 irq structure is initialized. 339 irq structure is initialized.
370 */ 340 */
371 if (link->conf.Attributes & CONF_ENABLE_IRQ) 341 if (link->conf.Attributes & CONF_ENABLE_IRQ)
372 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 342 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
373 343
374 /* 344 /*
375 This actually configures the PCMCIA socket -- setting up 345 This actually configures the PCMCIA socket -- setting up
376 the I/O windows and the interrupt mapping, and putting the 346 the I/O windows and the interrupt mapping, and putting the
377 card and host interface into "Memory and IO" mode. 347 card and host interface into "Memory and IO" mode.
378 */ 348 */
379 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); 349 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
380 ((local_info_t*)link->priv)->eth_dev = 350 ((local_info_t*)link->priv)->eth_dev =
381 init_airo_card( link->irq.AssignedIRQ, 351 init_airo_card( link->irq.AssignedIRQ,
382 link->io.BasePort1, 1, &handle_to_dev(handle) ); 352 link->io.BasePort1, 1, &handle_to_dev(link) );
383 if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed; 353 if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
384 354
385 /* 355 /*
386 At this point, the dev_node_t structure(s) need to be 356 At this point, the dev_node_t structure(s) need to be
387 initialized and arranged in a linked list at link->dev. 357 initialized and arranged in a linked list at link->dev_node.
388 */ 358 */
389 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); 359 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
390 dev->node.major = dev->node.minor = 0; 360 dev->node.major = dev->node.minor = 0;
391 link->dev = &dev->node; 361 link->dev_node = &dev->node;
392 362
393 /* Finally, report what we've done */ 363 /* Finally, report what we've done */
394 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 364 printk(KERN_INFO "%s: index 0x%02x: ",
395 dev->node.dev_name, link->conf.ConfigIndex, 365 dev->node.dev_name, link->conf.ConfigIndex);
396 link->conf.Vcc/10, link->conf.Vcc%10); 366 if (link->conf.Vpp)
397 if (link->conf.Vpp1) 367 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
398 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
399 if (link->conf.Attributes & CONF_ENABLE_IRQ) 368 if (link->conf.Attributes & CONF_ENABLE_IRQ)
400 printk(", irq %d", link->irq.AssignedIRQ); 369 printk(", irq %d", link->irq.AssignedIRQ);
401 if (link->io.NumPorts1) 370 if (link->io.NumPorts1)
@@ -408,14 +377,12 @@ static void airo_config(dev_link_t *link)
408 printk(", mem 0x%06lx-0x%06lx", req.Base, 377 printk(", mem 0x%06lx-0x%06lx", req.Base,
409 req.Base+req.Size-1); 378 req.Base+req.Size-1);
410 printk("\n"); 379 printk("\n");
411 380 return 0;
412 link->state &= ~DEV_CONFIG_PENDING; 381
413 return;
414
415 cs_failed: 382 cs_failed:
416 cs_error(link->handle, last_fn, last_ret); 383 cs_error(link, last_fn, last_ret);
417 airo_release(link); 384 airo_release(link);
418 385 return -ENODEV;
419} /* airo_config */ 386} /* airo_config */
420 387
421/*====================================================================== 388/*======================================================================
@@ -426,51 +393,26 @@ static void airo_config(dev_link_t *link)
426 393
427 ======================================================================*/ 394 ======================================================================*/
428 395
429static void airo_release(dev_link_t *link) 396static void airo_release(struct pcmcia_device *link)
430{ 397{
431 DEBUG(0, "airo_release(0x%p)\n", link); 398 DEBUG(0, "airo_release(0x%p)\n", link);
432 399 pcmcia_disable_device(link);
433 /* Unlink the device chain */
434 link->dev = NULL;
435
436 /*
437 In a normal driver, additional code may be needed to release
438 other kernel data structures associated with this device.
439 */
440
441 /* Don't bother checking to see if these succeed or not */
442 if (link->win)
443 pcmcia_release_window(link->win);
444 pcmcia_release_configuration(link->handle);
445 if (link->io.NumPorts1)
446 pcmcia_release_io(link->handle, &link->io);
447 if (link->irq.AssignedIRQ)
448 pcmcia_release_irq(link->handle, &link->irq);
449 link->state &= ~DEV_CONFIG;
450} 400}
451 401
452static int airo_suspend(struct pcmcia_device *p_dev) 402static int airo_suspend(struct pcmcia_device *link)
453{ 403{
454 dev_link_t *link = dev_to_instance(p_dev);
455 local_info_t *local = link->priv; 404 local_info_t *local = link->priv;
456 405
457 link->state |= DEV_SUSPEND; 406 netif_device_detach(local->eth_dev);
458 if (link->state & DEV_CONFIG) {
459 netif_device_detach(local->eth_dev);
460 pcmcia_release_configuration(link->handle);
461 }
462 407
463 return 0; 408 return 0;
464} 409}
465 410
466static int airo_resume(struct pcmcia_device *p_dev) 411static int airo_resume(struct pcmcia_device *link)
467{ 412{
468 dev_link_t *link = dev_to_instance(p_dev);
469 local_info_t *local = link->priv; 413 local_info_t *local = link->priv;
470 414
471 link->state &= ~DEV_SUSPEND; 415 if (link->open) {
472 if (link->state & DEV_CONFIG) {
473 pcmcia_request_configuration(link->handle, &link->conf);
474 reset_airo_card(local->eth_dev); 416 reset_airo_card(local->eth_dev);
475 netif_device_attach(local->eth_dev); 417 netif_device_attach(local->eth_dev);
476 } 418 }
@@ -492,7 +434,7 @@ static struct pcmcia_driver airo_driver = {
492 .drv = { 434 .drv = {
493 .name = "airo_cs", 435 .name = "airo_cs",
494 }, 436 },
495 .probe = airo_attach, 437 .probe = airo_probe,
496 .remove = airo_detach, 438 .remove = airo_detach,
497 .id_table = airo_ids, 439 .id_table = airo_ids,
498 .suspend = airo_suspend, 440 .suspend = airo_suspend,