diff options
author | Yinghai Lu <yinghai.lu@sun.com> | 2008-02-11 02:25:25 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-11 12:00:48 -0500 |
commit | 7c46c20aef185c3782d28c5111dcf1df88bbab32 (patch) | |
tree | 0ecd0412d0493305d14f7fb702fc2e944ba13eed /drivers/scsi/ses.c | |
parent | 95f6fb578970c9dbfcaa436ff98d2f3c6bdea953 (diff) |
[SCSI] ses: fix memory leaks
fix leaking with scomp leaking when failing. Also free page10 on
driver removal and remove one extra space.
Signed-off-by: Yinghai Lu <yinghai.lu@sun.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/ses.c')
-rw-r--r-- | drivers/scsi/ses.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 2a6e4f472eaa..a57fed47b39d 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -416,11 +416,11 @@ static int ses_intf_add(struct class_device *cdev, | |||
416 | int i, j, types, len, components = 0; | 416 | int i, j, types, len, components = 0; |
417 | int err = -ENOMEM; | 417 | int err = -ENOMEM; |
418 | struct enclosure_device *edev; | 418 | struct enclosure_device *edev; |
419 | struct ses_component *scomp; | 419 | struct ses_component *scomp = NULL; |
420 | 420 | ||
421 | if (!scsi_device_enclosure(sdev)) { | 421 | if (!scsi_device_enclosure(sdev)) { |
422 | /* not an enclosure, but might be in one */ | 422 | /* not an enclosure, but might be in one */ |
423 | edev = enclosure_find(&sdev->host->shost_gendev); | 423 | edev = enclosure_find(&sdev->host->shost_gendev); |
424 | if (edev) { | 424 | if (edev) { |
425 | ses_match_to_enclosure(edev, sdev); | 425 | ses_match_to_enclosure(edev, sdev); |
426 | class_device_put(&edev->cdev); | 426 | class_device_put(&edev->cdev); |
@@ -456,9 +456,6 @@ static int ses_intf_add(struct class_device *cdev, | |||
456 | if (!buf) | 456 | if (!buf) |
457 | goto err_free; | 457 | goto err_free; |
458 | 458 | ||
459 | ses_dev->page1 = buf; | ||
460 | ses_dev->page1_len = len; | ||
461 | |||
462 | result = ses_recv_diag(sdev, 1, buf, len); | 459 | result = ses_recv_diag(sdev, 1, buf, len); |
463 | if (result) | 460 | if (result) |
464 | goto recv_failed; | 461 | goto recv_failed; |
@@ -473,6 +470,9 @@ static int ses_intf_add(struct class_device *cdev, | |||
473 | type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) | 470 | type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) |
474 | components += type_ptr[1]; | 471 | components += type_ptr[1]; |
475 | } | 472 | } |
473 | ses_dev->page1 = buf; | ||
474 | ses_dev->page1_len = len; | ||
475 | buf = NULL; | ||
476 | 476 | ||
477 | result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE); | 477 | result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE); |
478 | if (result) | 478 | if (result) |
@@ -489,6 +489,7 @@ static int ses_intf_add(struct class_device *cdev, | |||
489 | goto recv_failed; | 489 | goto recv_failed; |
490 | ses_dev->page2 = buf; | 490 | ses_dev->page2 = buf; |
491 | ses_dev->page2_len = len; | 491 | ses_dev->page2_len = len; |
492 | buf = NULL; | ||
492 | 493 | ||
493 | /* The additional information page --- allows us | 494 | /* The additional information page --- allows us |
494 | * to match up the devices */ | 495 | * to match up the devices */ |
@@ -506,11 +507,12 @@ static int ses_intf_add(struct class_device *cdev, | |||
506 | goto recv_failed; | 507 | goto recv_failed; |
507 | ses_dev->page10 = buf; | 508 | ses_dev->page10 = buf; |
508 | ses_dev->page10_len = len; | 509 | ses_dev->page10_len = len; |
510 | buf = NULL; | ||
509 | 511 | ||
510 | no_page10: | 512 | no_page10: |
511 | scomp = kmalloc(sizeof(struct ses_component) * components, GFP_KERNEL); | 513 | scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); |
512 | if (!scomp) | 514 | if (!scomp) |
513 | goto err_free; | 515 | goto err_free; |
514 | 516 | ||
515 | edev = enclosure_register(cdev->dev, sdev->sdev_gendev.bus_id, | 517 | edev = enclosure_register(cdev->dev, sdev->sdev_gendev.bus_id, |
516 | components, &ses_enclosure_callbacks); | 518 | components, &ses_enclosure_callbacks); |
@@ -521,10 +523,9 @@ static int ses_intf_add(struct class_device *cdev, | |||
521 | 523 | ||
522 | edev->scratch = ses_dev; | 524 | edev->scratch = ses_dev; |
523 | for (i = 0; i < components; i++) | 525 | for (i = 0; i < components; i++) |
524 | edev->component[i].scratch = scomp++; | 526 | edev->component[i].scratch = scomp + i; |
525 | 527 | ||
526 | /* Page 7 for the descriptors is optional */ | 528 | /* Page 7 for the descriptors is optional */ |
527 | buf = NULL; | ||
528 | result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE); | 529 | result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE); |
529 | if (result) | 530 | if (result) |
530 | goto simple_populate; | 531 | goto simple_populate; |
@@ -532,6 +533,8 @@ static int ses_intf_add(struct class_device *cdev, | |||
532 | len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; | 533 | len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; |
533 | /* add 1 for trailing '\0' we'll use */ | 534 | /* add 1 for trailing '\0' we'll use */ |
534 | buf = kzalloc(len + 1, GFP_KERNEL); | 535 | buf = kzalloc(len + 1, GFP_KERNEL); |
536 | if (!buf) | ||
537 | goto simple_populate; | ||
535 | result = ses_recv_diag(sdev, 7, buf, len); | 538 | result = ses_recv_diag(sdev, 7, buf, len); |
536 | if (result) { | 539 | if (result) { |
537 | simple_populate: | 540 | simple_populate: |
@@ -598,6 +601,7 @@ static int ses_intf_add(struct class_device *cdev, | |||
598 | err = -ENODEV; | 601 | err = -ENODEV; |
599 | err_free: | 602 | err_free: |
600 | kfree(buf); | 603 | kfree(buf); |
604 | kfree(scomp); | ||
601 | kfree(ses_dev->page10); | 605 | kfree(ses_dev->page10); |
602 | kfree(ses_dev->page2); | 606 | kfree(ses_dev->page2); |
603 | kfree(ses_dev->page1); | 607 | kfree(ses_dev->page1); |
@@ -630,6 +634,7 @@ static void ses_intf_remove(struct class_device *cdev, | |||
630 | ses_dev = edev->scratch; | 634 | ses_dev = edev->scratch; |
631 | edev->scratch = NULL; | 635 | edev->scratch = NULL; |
632 | 636 | ||
637 | kfree(ses_dev->page10); | ||
633 | kfree(ses_dev->page1); | 638 | kfree(ses_dev->page1); |
634 | kfree(ses_dev->page2); | 639 | kfree(ses_dev->page2); |
635 | kfree(ses_dev); | 640 | kfree(ses_dev); |