aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/atmel_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/atmel_cs.c')
-rw-r--r--drivers/net/wireless/atmel_cs.c162
1 files changed, 56 insertions, 106 deletions
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index d6f4a5a3e55a..26bf1127524d 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -91,8 +91,8 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
91 event handler. 91 event handler.
92*/ 92*/
93 93
94static void atmel_config(dev_link_t *link); 94static int atmel_config(struct pcmcia_device *link);
95static void atmel_release(dev_link_t *link); 95static void atmel_release(struct pcmcia_device *link);
96 96
97/* 97/*
98 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
@@ -112,10 +112,10 @@ static void atmel_detach(struct pcmcia_device *p_dev);
112/* 112/*
113 A linked list of "instances" of the atmelnet device. Each actual 113 A linked list of "instances" of the atmelnet device. Each actual
114 PCMCIA card corresponds to one device instance, and is described 114 PCMCIA card corresponds to one device instance, and is described
115 by one dev_link_t structure (defined in ds.h). 115 by one struct pcmcia_device structure (defined in ds.h).
116 116
117 You may not want to use a linked list for this -- for example, the 117 You may not want to use a linked list for this -- for example, the
118 memory card driver uses an array of dev_link_t pointers, where minor 118 memory card driver uses an array of struct pcmcia_device pointers, where minor
119 device numbers are used to derive the corresponding array index. 119 device numbers are used to derive the corresponding array index.
120*/ 120*/
121 121
@@ -125,7 +125,7 @@ static void atmel_detach(struct pcmcia_device *p_dev);
125 example, ethernet cards, modems). In other cases, there may be 125 example, ethernet cards, modems). In other cases, there may be
126 many actual or logical devices (SCSI adapters, memory cards with 126 many actual or logical devices (SCSI adapters, memory cards with
127 multiple partitions). The dev_node_t structures need to be kept 127 multiple partitions). The dev_node_t structures need to be kept
128 in a linked list starting at the 'dev' field of a dev_link_t 128 in a linked list starting at the 'dev' field of a struct pcmcia_device
129 structure. We allocate them in the card's private data structure, 129 structure. We allocate them in the card's private data structure,
130 because they generally shouldn't be allocated dynamically. 130 because they generally shouldn't be allocated dynamically.
131 131
@@ -152,24 +152,16 @@ typedef struct local_info_t {
152 152
153 ======================================================================*/ 153 ======================================================================*/
154 154
155static int atmel_attach(struct pcmcia_device *p_dev) 155static int atmel_probe(struct pcmcia_device *p_dev)
156{ 156{
157 dev_link_t *link;
158 local_info_t *local; 157 local_info_t *local;
159 158
160 DEBUG(0, "atmel_attach()\n"); 159 DEBUG(0, "atmel_attach()\n");
161 160
162 /* Initialize the dev_link_t structure */
163 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
164 if (!link) {
165 printk(KERN_ERR "atmel_cs: no memory for new device\n");
166 return -ENOMEM;
167 }
168
169 /* Interrupt setup */ 161 /* Interrupt setup */
170 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 162 p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
171 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 163 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
172 link->irq.Handler = NULL; 164 p_dev->irq.Handler = NULL;
173 165
174 /* 166 /*
175 General socket configuration defaults can go here. In this 167 General socket configuration defaults can go here. In this
@@ -178,26 +170,18 @@ static int atmel_attach(struct pcmcia_device *p_dev)
178 and attributes of IO windows) are fixed by the nature of the 170 and attributes of IO windows) are fixed by the nature of the
179 device, and can be hard-wired here. 171 device, and can be hard-wired here.
180 */ 172 */
181 link->conf.Attributes = 0; 173 p_dev->conf.Attributes = 0;
182 link->conf.Vcc = 50; 174 p_dev->conf.IntType = INT_MEMORY_AND_IO;
183 link->conf.IntType = INT_MEMORY_AND_IO;
184 175
185 /* Allocate space for private device-specific data */ 176 /* Allocate space for private device-specific data */
186 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 177 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
187 if (!local) { 178 if (!local) {
188 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 179 printk(KERN_ERR "atmel_cs: no memory for new device\n");
189 kfree (link);
190 return -ENOMEM; 180 return -ENOMEM;
191 } 181 }
192 link->priv = local; 182 p_dev->priv = local;
193 183
194 link->handle = p_dev; 184 return atmel_config(p_dev);
195 p_dev->instance = link;
196
197 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
198 atmel_config(link);
199
200 return 0;
201} /* atmel_attach */ 185} /* atmel_attach */
202 186
203/*====================================================================== 187/*======================================================================
@@ -209,17 +193,13 @@ static int atmel_attach(struct pcmcia_device *p_dev)
209 193
210 ======================================================================*/ 194 ======================================================================*/
211 195
212static void atmel_detach(struct pcmcia_device *p_dev) 196static void atmel_detach(struct pcmcia_device *link)
213{ 197{
214 dev_link_t *link = dev_to_instance(p_dev);
215
216 DEBUG(0, "atmel_detach(0x%p)\n", link); 198 DEBUG(0, "atmel_detach(0x%p)\n", link);
217 199
218 if (link->state & DEV_CONFIG) 200 atmel_release(link);
219 atmel_release(link);
220 201
221 kfree(link->priv); 202 kfree(link->priv);
222 kfree(link);
223} 203}
224 204
225/*====================================================================== 205/*======================================================================
@@ -236,19 +216,17 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
236/* Call-back function to interrogate PCMCIA-specific information 216/* Call-back function to interrogate PCMCIA-specific information
237 about the current existance of the card */ 217 about the current existance of the card */
238static int card_present(void *arg) 218static int card_present(void *arg)
239{ 219{
240 dev_link_t *link = (dev_link_t *)arg; 220 struct pcmcia_device *link = (struct pcmcia_device *)arg;
241 if (link->state & DEV_SUSPEND) 221
242 return 0; 222 if (pcmcia_dev_present(link))
243 else if (link->state & DEV_PRESENT)
244 return 1; 223 return 1;
245 224
246 return 0; 225 return 0;
247} 226}
248 227
249static void atmel_config(dev_link_t *link) 228static int atmel_config(struct pcmcia_device *link)
250{ 229{
251 client_handle_t handle;
252 tuple_t tuple; 230 tuple_t tuple;
253 cisparse_t parse; 231 cisparse_t parse;
254 local_info_t *dev; 232 local_info_t *dev;
@@ -256,9 +234,8 @@ static void atmel_config(dev_link_t *link)
256 u_char buf[64]; 234 u_char buf[64];
257 struct pcmcia_device_id *did; 235 struct pcmcia_device_id *did;
258 236
259 handle = link->handle;
260 dev = link->priv; 237 dev = link->priv;
261 did = handle_to_dev(handle).driver_data; 238 did = handle_to_dev(link).driver_data;
262 239
263 DEBUG(0, "atmel_config(0x%p)\n", link); 240 DEBUG(0, "atmel_config(0x%p)\n", link);
264 241
@@ -272,15 +249,12 @@ static void atmel_config(dev_link_t *link)
272 registers. 249 registers.
273 */ 250 */
274 tuple.DesiredTuple = CISTPL_CONFIG; 251 tuple.DesiredTuple = CISTPL_CONFIG;
275 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 252 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
276 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 253 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
277 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 254 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
278 link->conf.ConfigBase = parse.config.base; 255 link->conf.ConfigBase = parse.config.base;
279 link->conf.Present = parse.config.rmask[0]; 256 link->conf.Present = parse.config.rmask[0];
280 257
281 /* Configure card */
282 link->state |= DEV_CONFIG;
283
284 /* 258 /*
285 In this loop, we scan the CIS for configuration table entries, 259 In this loop, we scan the CIS for configuration table entries,
286 each of which describes a valid card configuration, including 260 each of which describes a valid card configuration, including
@@ -294,12 +268,12 @@ static void atmel_config(dev_link_t *link)
294 will only use the CIS to fill in implementation-defined details. 268 will only use the CIS to fill in implementation-defined details.
295 */ 269 */
296 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 270 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
297 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 271 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
298 while (1) { 272 while (1) {
299 cistpl_cftable_entry_t dflt = { 0 }; 273 cistpl_cftable_entry_t dflt = { 0 };
300 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 274 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
301 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 275 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
302 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 276 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
303 goto next_entry; 277 goto next_entry;
304 278
305 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; 279 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
@@ -314,16 +288,11 @@ static void atmel_config(dev_link_t *link)
314 288
315 /* Use power settings for Vcc and Vpp if present */ 289 /* Use power settings for Vcc and Vpp if present */
316 /* Note that the CIS values need to be rescaled */ 290 /* Note that the CIS values need to be rescaled */
317 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
318 link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
319 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
320 link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
321
322 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 291 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
323 link->conf.Vpp1 = link->conf.Vpp2 = 292 link->conf.Vpp =
324 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 293 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
325 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 294 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
326 link->conf.Vpp1 = link->conf.Vpp2 = 295 link->conf.Vpp =
327 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; 296 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
328 297
329 /* Do we need to allocate an interrupt? */ 298 /* Do we need to allocate an interrupt? */
@@ -349,14 +318,14 @@ static void atmel_config(dev_link_t *link)
349 } 318 }
350 319
351 /* This reserves IO space but doesn't actually enable it */ 320 /* This reserves IO space but doesn't actually enable it */
352 if (pcmcia_request_io(link->handle, &link->io) != 0) 321 if (pcmcia_request_io(link, &link->io) != 0)
353 goto next_entry; 322 goto next_entry;
354 323
355 /* If we got this far, we're cool! */ 324 /* If we got this far, we're cool! */
356 break; 325 break;
357 326
358 next_entry: 327 next_entry:
359 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 328 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
360 } 329 }
361 330
362 /* 331 /*
@@ -365,14 +334,14 @@ static void atmel_config(dev_link_t *link)
365 irq structure is initialized. 334 irq structure is initialized.
366 */ 335 */
367 if (link->conf.Attributes & CONF_ENABLE_IRQ) 336 if (link->conf.Attributes & CONF_ENABLE_IRQ)
368 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 337 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
369 338
370 /* 339 /*
371 This actually configures the PCMCIA socket -- setting up 340 This actually configures the PCMCIA socket -- setting up
372 the I/O windows and the interrupt mapping, and putting the 341 the I/O windows and the interrupt mapping, and putting the
373 card and host interface into "Memory and IO" mode. 342 card and host interface into "Memory and IO" mode.
374 */ 343 */
375 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); 344 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
376 345
377 if (link->irq.AssignedIRQ == 0) { 346 if (link->irq.AssignedIRQ == 0) {
378 printk(KERN_ALERT 347 printk(KERN_ALERT
@@ -384,7 +353,7 @@ static void atmel_config(dev_link_t *link)
384 init_atmel_card(link->irq.AssignedIRQ, 353 init_atmel_card(link->irq.AssignedIRQ,
385 link->io.BasePort1, 354 link->io.BasePort1,
386 did ? did->driver_info : ATMEL_FW_TYPE_NONE, 355 did ? did->driver_info : ATMEL_FW_TYPE_NONE,
387 &handle_to_dev(handle), 356 &handle_to_dev(link),
388 card_present, 357 card_present,
389 link); 358 link);
390 if (!((local_info_t*)link->priv)->eth_dev) 359 if (!((local_info_t*)link->priv)->eth_dev)
@@ -393,18 +362,18 @@ static void atmel_config(dev_link_t *link)
393 362
394 /* 363 /*
395 At this point, the dev_node_t structure(s) need to be 364 At this point, the dev_node_t structure(s) need to be
396 initialized and arranged in a linked list at link->dev. 365 initialized and arranged in a linked list at link->dev_node.
397 */ 366 */
398 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); 367 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
399 dev->node.major = dev->node.minor = 0; 368 dev->node.major = dev->node.minor = 0;
400 link->dev = &dev->node; 369 link->dev_node = &dev->node;
401 370
402 link->state &= ~DEV_CONFIG_PENDING; 371 return 0;
403 return; 372
404
405 cs_failed: 373 cs_failed:
406 cs_error(link->handle, last_fn, last_ret); 374 cs_error(link, last_fn, last_ret);
407 atmel_release(link); 375 atmel_release(link);
376 return -ENODEV;
408} 377}
409 378
410/*====================================================================== 379/*======================================================================
@@ -415,53 +384,34 @@ static void atmel_config(dev_link_t *link)
415 384
416 ======================================================================*/ 385 ======================================================================*/
417 386
418static void atmel_release(dev_link_t *link) 387static void atmel_release(struct pcmcia_device *link)
419{ 388{
420 struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; 389 struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
421 390
422 DEBUG(0, "atmel_release(0x%p)\n", link); 391 DEBUG(0, "atmel_release(0x%p)\n", link);
423 392
424 /* Unlink the device chain */ 393 if (dev)
425 link->dev = NULL;
426
427 if (dev)
428 stop_atmel_card(dev); 394 stop_atmel_card(dev);
429 ((local_info_t*)link->priv)->eth_dev = NULL; 395 ((local_info_t*)link->priv)->eth_dev = NULL;
430 396
431 /* Don't bother checking to see if these succeed or not */ 397 pcmcia_disable_device(link);
432 pcmcia_release_configuration(link->handle);
433 if (link->io.NumPorts1)
434 pcmcia_release_io(link->handle, &link->io);
435 if (link->irq.AssignedIRQ)
436 pcmcia_release_irq(link->handle, &link->irq);
437 link->state &= ~DEV_CONFIG;
438} 398}
439 399
440static int atmel_suspend(struct pcmcia_device *dev) 400static int atmel_suspend(struct pcmcia_device *link)
441{ 401{
442 dev_link_t *link = dev_to_instance(dev);
443 local_info_t *local = link->priv; 402 local_info_t *local = link->priv;
444 403
445 link->state |= DEV_SUSPEND; 404 netif_device_detach(local->eth_dev);
446 if (link->state & DEV_CONFIG) {
447 netif_device_detach(local->eth_dev);
448 pcmcia_release_configuration(link->handle);
449 }
450 405
451 return 0; 406 return 0;
452} 407}
453 408
454static int atmel_resume(struct pcmcia_device *dev) 409static int atmel_resume(struct pcmcia_device *link)
455{ 410{
456 dev_link_t *link = dev_to_instance(dev);
457 local_info_t *local = link->priv; 411 local_info_t *local = link->priv;
458 412
459 link->state &= ~DEV_SUSPEND; 413 atmel_open(local->eth_dev);
460 if (link->state & DEV_CONFIG) { 414 netif_device_attach(local->eth_dev);
461 pcmcia_request_configuration(link->handle, &link->conf);
462 atmel_open(local->eth_dev);
463 netif_device_attach(local->eth_dev);
464 }
465 415
466 return 0; 416 return 0;
467} 417}
@@ -515,7 +465,7 @@ static struct pcmcia_driver atmel_driver = {
515 .drv = { 465 .drv = {
516 .name = "atmel_cs", 466 .name = "atmel_cs",
517 }, 467 },
518 .probe = atmel_attach, 468 .probe = atmel_probe,
519 .remove = atmel_detach, 469 .remove = atmel_detach,
520 .id_table = atmel_ids, 470 .id_table = atmel_ids,
521 .suspend = atmel_suspend, 471 .suspend = atmel_suspend,