diff options
Diffstat (limited to 'drivers/scsi/libsas')
| -rw-r--r-- | drivers/scsi/libsas/sas_init.c | 1 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_internal.h | 15 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_phy.c | 33 |
3 files changed, 32 insertions, 17 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 8566bb1208a0..6b15ad1bcada 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -141,6 +141,7 @@ Undo_event_q: Undo_ports: sas_unregister_ports(sas_ha); Undo_phys: + sas_unregister_phys(sas_ha); return error; } diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 6706f2be8d27..d104c87f04f5 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -54,6 +54,7 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev); void sas_scsi_recover_host(struct Scsi_Host *shost); int sas_register_phys(struct sas_ha_struct *sas_ha); +void sas_unregister_phys(struct sas_ha_struct *sas_ha); struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags); void sas_free_event(struct asd_sas_event *event); @@ -145,20 +146,6 @@ static inline void sas_fail_probe(struct domain_device *dev, const char *func, i func, dev->parent ? "exp-attached" : "direct-attached", SAS_ADDR(dev->sas_addr), err); - - /* - * If the device probe failed, the expander phy attached address - * needs to be reset so that the phy will not be treated as flutter - * in the next revalidation - */ - if (dev->parent && !dev_is_expander(dev->dev_type)) { - struct sas_phy *phy = dev->phy; - struct domain_device *parent = dev->parent; - struct ex_phy *ex_phy = &parent->ex_dev.ex_phy[phy->number]; - - memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - } - sas_unregister_dev(dev->port, dev); } diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index 635835c28ecd..58f08dc2c187 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c @@ -116,6 +116,7 @@ static void sas_phye_shutdown(struct work_struct *work) int sas_register_phys(struct sas_ha_struct *sas_ha) { int i; + int err; /* Now register the phys. */ for (i = 0; i < sas_ha->num_phys; i++) { @@ -132,8 +133,10 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->frame_rcvd_size = 0; phy->phy = sas_phy_alloc(&sas_ha->shost->shost_gendev, i); - if (!phy->phy) - return -ENOMEM; + if (!phy->phy) { + err = -ENOMEM; + goto rollback; + } phy->phy->identify.initiator_port_protocols = phy->iproto; @@ -146,10 +149,34 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN; phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; - sas_phy_add(phy->phy); + err = sas_phy_add(phy->phy); + if (err) { + sas_phy_free(phy->phy); + goto rollback; + } } return 0; +rollback: + for (i-- ; i >= 0 ; i--) { + struct asd_sas_phy *phy = sas_ha->sas_phy[i]; + + sas_phy_delete(phy->phy); + sas_phy_free(phy->phy); + } + return err; +} + +void sas_unregister_phys(struct sas_ha_struct *sas_ha) +{ + int i; + + for (i = 0 ; i < sas_ha->num_phys ; i++) { + struct asd_sas_phy *phy = sas_ha->sas_phy[i]; + + sas_phy_delete(phy->phy); + sas_phy_free(phy->phy); + } } const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = { |
