aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ses.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai.lu@sun.com>2008-02-11 02:25:25 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-11 12:00:48 -0500
commit7c46c20aef185c3782d28c5111dcf1df88bbab32 (patch)
tree0ecd0412d0493305d14f7fb702fc2e944ba13eed /drivers/scsi/ses.c
parent95f6fb578970c9dbfcaa436ff98d2f3c6bdea953 (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.c23
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);