diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-05 19:09:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-05 19:09:46 -0500 |
commit | ec0bf39a471bf6fcd01def2bd677128cea940b73 (patch) | |
tree | 0d98b304d97605613a14329b40ed8cbb88296528 /drivers/scsi/libsas/sas_expander.c | |
parent | bf83c2a315637dee8a8b5c2221ce5030cc38c6db (diff) | |
parent | d32adcb85c74fd81963714689842993e7014515f (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (73 commits)
[SCSI] aic79xx: Add ASC-29320LPE ids to driver
[SCSI] stex: version update
[SCSI] stex: change wait loop code
[SCSI] stex: add new device type support
[SCSI] stex: update device id info
[SCSI] stex: adjust default queue length
[SCSI] stex: add value check in hard reset routine
[SCSI] stex: fix controller_info command handling
[SCSI] stex: fix biosparam calculation
[SCSI] megaraid: fix MMIO casts
[SCSI] tgt: fix undefined flush_dcache_page() problem
[SCSI] libsas: better error handling in sas_expander.c
[SCSI] lpfc 8.1.11 : Change version number to 8.1.11
[SCSI] lpfc 8.1.11 : Misc Fixes
[SCSI] lpfc 8.1.11 : Add soft_wwnn sysfs attribute, rename soft_wwn_enable
[SCSI] lpfc 8.1.11 : Removed decoding of PCI Subsystem Id
[SCSI] lpfc 8.1.11 : Add MSI (Message Signalled Interrupts) support
[SCSI] lpfc 8.1.11 : Adjust LOG_FCP logging
[SCSI] lpfc 8.1.11 : Fix Memory leaks
[SCSI] lpfc 8.1.11 : Fix lpfc_multi_ring_support
...
Diffstat (limited to 'drivers/scsi/libsas/sas_expander.c')
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index e34a93435497..d31e6fa466f7 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -597,10 +597,15 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
597 | child->iproto = phy->attached_iproto; | 597 | child->iproto = phy->attached_iproto; |
598 | memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); | 598 | memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); |
599 | sas_hash_addr(child->hashed_sas_addr, child->sas_addr); | 599 | sas_hash_addr(child->hashed_sas_addr, child->sas_addr); |
600 | phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); | 600 | if (!phy->port) { |
601 | BUG_ON(!phy->port); | 601 | phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); |
602 | /* FIXME: better error handling*/ | 602 | if (unlikely(!phy->port)) |
603 | BUG_ON(sas_port_add(phy->port) != 0); | 603 | goto out_err; |
604 | if (unlikely(sas_port_add(phy->port) != 0)) { | ||
605 | sas_port_free(phy->port); | ||
606 | goto out_err; | ||
607 | } | ||
608 | } | ||
604 | sas_ex_get_linkrate(parent, child, phy); | 609 | sas_ex_get_linkrate(parent, child, phy); |
605 | 610 | ||
606 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { | 611 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { |
@@ -615,8 +620,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
615 | SAS_DPRINTK("report phy sata to %016llx:0x%x returned " | 620 | SAS_DPRINTK("report phy sata to %016llx:0x%x returned " |
616 | "0x%x\n", SAS_ADDR(parent->sas_addr), | 621 | "0x%x\n", SAS_ADDR(parent->sas_addr), |
617 | phy_id, res); | 622 | phy_id, res); |
618 | kfree(child); | 623 | goto out_free; |
619 | return NULL; | ||
620 | } | 624 | } |
621 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, | 625 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, |
622 | sizeof(struct dev_to_host_fis)); | 626 | sizeof(struct dev_to_host_fis)); |
@@ -627,14 +631,14 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
627 | "%016llx:0x%x returned 0x%x\n", | 631 | "%016llx:0x%x returned 0x%x\n", |
628 | SAS_ADDR(child->sas_addr), | 632 | SAS_ADDR(child->sas_addr), |
629 | SAS_ADDR(parent->sas_addr), phy_id, res); | 633 | SAS_ADDR(parent->sas_addr), phy_id, res); |
630 | kfree(child); | 634 | goto out_free; |
631 | return NULL; | ||
632 | } | 635 | } |
633 | } else if (phy->attached_tproto & SAS_PROTO_SSP) { | 636 | } else if (phy->attached_tproto & SAS_PROTO_SSP) { |
634 | child->dev_type = SAS_END_DEV; | 637 | child->dev_type = SAS_END_DEV; |
635 | rphy = sas_end_device_alloc(phy->port); | 638 | rphy = sas_end_device_alloc(phy->port); |
636 | /* FIXME: error handling */ | 639 | /* FIXME: error handling */ |
637 | BUG_ON(!rphy); | 640 | if (unlikely(!rphy)) |
641 | goto out_free; | ||
638 | child->tproto = phy->attached_tproto; | 642 | child->tproto = phy->attached_tproto; |
639 | sas_init_dev(child); | 643 | sas_init_dev(child); |
640 | 644 | ||
@@ -651,9 +655,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
651 | "at %016llx:0x%x returned 0x%x\n", | 655 | "at %016llx:0x%x returned 0x%x\n", |
652 | SAS_ADDR(child->sas_addr), | 656 | SAS_ADDR(child->sas_addr), |
653 | SAS_ADDR(parent->sas_addr), phy_id, res); | 657 | SAS_ADDR(parent->sas_addr), phy_id, res); |
654 | /* FIXME: this kfrees list elements without removing them */ | 658 | goto out_list_del; |
655 | //kfree(child); | ||
656 | return NULL; | ||
657 | } | 659 | } |
658 | } else { | 660 | } else { |
659 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", | 661 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", |
@@ -663,6 +665,16 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
663 | 665 | ||
664 | list_add_tail(&child->siblings, &parent_ex->children); | 666 | list_add_tail(&child->siblings, &parent_ex->children); |
665 | return child; | 667 | return child; |
668 | |||
669 | out_list_del: | ||
670 | list_del(&child->dev_list_node); | ||
671 | sas_rphy_free(rphy); | ||
672 | out_free: | ||
673 | sas_port_delete(phy->port); | ||
674 | out_err: | ||
675 | phy->port = NULL; | ||
676 | kfree(child); | ||
677 | return NULL; | ||
666 | } | 678 | } |
667 | 679 | ||
668 | static struct domain_device *sas_ex_discover_expander( | 680 | static struct domain_device *sas_ex_discover_expander( |