diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
| -rw-r--r-- | drivers/pcmcia/ds.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 43da2e92d50f..080608c7381a 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
| @@ -354,6 +354,7 @@ static void pcmcia_release_dev(struct device *dev) | |||
| 354 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 354 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
| 355 | ds_dbg(1, "releasing dev %p\n", p_dev); | 355 | ds_dbg(1, "releasing dev %p\n", p_dev); |
| 356 | pcmcia_put_socket(p_dev->socket); | 356 | pcmcia_put_socket(p_dev->socket); |
| 357 | kfree(p_dev->devname); | ||
| 357 | kfree(p_dev); | 358 | kfree(p_dev); |
| 358 | } | 359 | } |
| 359 | 360 | ||
| @@ -424,9 +425,13 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
| 424 | { | 425 | { |
| 425 | cistpl_manfid_t manf_id; | 426 | cistpl_manfid_t manf_id; |
| 426 | cistpl_funcid_t func_id; | 427 | cistpl_funcid_t func_id; |
| 427 | cistpl_vers_1_t vers1; | 428 | cistpl_vers_1_t *vers1; |
| 428 | unsigned int i; | 429 | unsigned int i; |
| 429 | 430 | ||
| 431 | vers1 = kmalloc(sizeof(*vers1), GFP_KERNEL); | ||
| 432 | if (!vers1) | ||
| 433 | return -ENOMEM; | ||
| 434 | |||
| 430 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, | 435 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, |
| 431 | CISTPL_MANFID, &manf_id)) { | 436 | CISTPL_MANFID, &manf_id)) { |
| 432 | p_dev->manf_id = manf_id.manf; | 437 | p_dev->manf_id = manf_id.manf; |
| @@ -443,23 +448,30 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
| 443 | /* rule of thumb: cards with no FUNCID, but with | 448 | /* rule of thumb: cards with no FUNCID, but with |
| 444 | * common memory device geometry information, are | 449 | * common memory device geometry information, are |
| 445 | * probably memory cards (from pcmcia-cs) */ | 450 | * probably memory cards (from pcmcia-cs) */ |
| 446 | cistpl_device_geo_t devgeo; | 451 | cistpl_device_geo_t *devgeo; |
| 452 | |||
| 453 | devgeo = kmalloc(sizeof(*devgeo), GFP_KERNEL); | ||
| 454 | if (!devgeo) { | ||
| 455 | kfree(vers1); | ||
| 456 | return -ENOMEM; | ||
| 457 | } | ||
| 447 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, | 458 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, |
| 448 | CISTPL_DEVICE_GEO, &devgeo)) { | 459 | CISTPL_DEVICE_GEO, devgeo)) { |
| 449 | ds_dbg(0, "mem device geometry probably means " | 460 | ds_dbg(0, "mem device geometry probably means " |
| 450 | "FUNCID_MEMORY\n"); | 461 | "FUNCID_MEMORY\n"); |
| 451 | p_dev->func_id = CISTPL_FUNCID_MEMORY; | 462 | p_dev->func_id = CISTPL_FUNCID_MEMORY; |
| 452 | p_dev->has_func_id = 1; | 463 | p_dev->has_func_id = 1; |
| 453 | } | 464 | } |
| 465 | kfree(devgeo); | ||
| 454 | } | 466 | } |
| 455 | 467 | ||
| 456 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1, | 468 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1, |
| 457 | &vers1)) { | 469 | vers1)) { |
| 458 | for (i=0; i < vers1.ns; i++) { | 470 | for (i=0; i < vers1->ns; i++) { |
| 459 | char *tmp; | 471 | char *tmp; |
| 460 | unsigned int length; | 472 | unsigned int length; |
| 461 | 473 | ||
| 462 | tmp = vers1.str + vers1.ofs[i]; | 474 | tmp = vers1->str + vers1->ofs[i]; |
| 463 | 475 | ||
| 464 | length = strlen(tmp) + 1; | 476 | length = strlen(tmp) + 1; |
| 465 | if ((length < 3) || (length > 255)) | 477 | if ((length < 3) || (length > 255)) |
| @@ -475,6 +487,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
| 475 | } | 487 | } |
| 476 | } | 488 | } |
| 477 | 489 | ||
| 490 | kfree(vers1); | ||
| 478 | return 0; | 491 | return 0; |
| 479 | } | 492 | } |
| 480 | 493 | ||
| @@ -492,6 +505,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 492 | { | 505 | { |
| 493 | struct pcmcia_device *p_dev; | 506 | struct pcmcia_device *p_dev; |
| 494 | unsigned long flags; | 507 | unsigned long flags; |
| 508 | int bus_id_len; | ||
| 495 | 509 | ||
| 496 | s = pcmcia_get_socket(s); | 510 | s = pcmcia_get_socket(s); |
| 497 | if (!s) | 511 | if (!s) |
| @@ -515,7 +529,12 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 515 | p_dev->dev.bus = &pcmcia_bus_type; | 529 | p_dev->dev.bus = &pcmcia_bus_type; |
| 516 | p_dev->dev.parent = s->dev.dev; | 530 | p_dev->dev.parent = s->dev.dev; |
| 517 | p_dev->dev.release = pcmcia_release_dev; | 531 | p_dev->dev.release = pcmcia_release_dev; |
| 518 | sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); | 532 | bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); |
| 533 | |||
| 534 | p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL); | ||
| 535 | if (!p_dev->devname) | ||
| 536 | goto err_free; | ||
| 537 | sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); | ||
| 519 | 538 | ||
| 520 | /* compat */ | 539 | /* compat */ |
| 521 | p_dev->state = CLIENT_UNBOUND; | 540 | p_dev->state = CLIENT_UNBOUND; |
| @@ -540,6 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 540 | return p_dev; | 559 | return p_dev; |
| 541 | 560 | ||
| 542 | err_free: | 561 | err_free: |
| 562 | kfree(p_dev->devname); | ||
| 543 | kfree(p_dev); | 563 | kfree(p_dev); |
| 544 | s->device_count--; | 564 | s->device_count--; |
| 545 | err_put: | 565 | err_put: |
