Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 024879ea authored by James Bottomley's avatar James Bottomley Committed by James Bottomley
Browse files

[SCSI] libsas: better error handling in sas_expander.c



With async scanning, we're now tripping the BUG_ON in
sas_ex_discover_end_dev(), so make the error handling here correct.

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ba8d5504
Loading
Loading
Loading
Loading
+24 −12
Original line number Original line Diff line number Diff line
@@ -597,10 +597,15 @@ static struct domain_device *sas_ex_discover_end_dev(
	child->iproto = phy->attached_iproto;
	child->iproto = phy->attached_iproto;
	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
	if (!phy->port) {
		phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
		phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
	BUG_ON(!phy->port);
		if (unlikely(!phy->port))
	/* FIXME: better error handling*/
			goto out_err;
	BUG_ON(sas_port_add(phy->port) != 0);
		if (unlikely(sas_port_add(phy->port) != 0)) {
			sas_port_free(phy->port);
			goto out_err;
		}
	}
	sas_ex_get_linkrate(parent, child, phy);
	sas_ex_get_linkrate(parent, child, phy);


	if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
	if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
@@ -615,8 +620,7 @@ static struct domain_device *sas_ex_discover_end_dev(
			SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
			SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
				    "0x%x\n", SAS_ADDR(parent->sas_addr),
				    "0x%x\n", SAS_ADDR(parent->sas_addr),
				    phy_id, res);
				    phy_id, res);
			kfree(child);
			goto out_free;
			return NULL;
		}
		}
		memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
		memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
		       sizeof(struct dev_to_host_fis));
		       sizeof(struct dev_to_host_fis));
@@ -627,14 +631,14 @@ static struct domain_device *sas_ex_discover_end_dev(
				    "%016llx:0x%x returned 0x%x\n",
				    "%016llx:0x%x returned 0x%x\n",
				    SAS_ADDR(child->sas_addr),
				    SAS_ADDR(child->sas_addr),
				    SAS_ADDR(parent->sas_addr), phy_id, res);
				    SAS_ADDR(parent->sas_addr), phy_id, res);
			kfree(child);
			goto out_free;
			return NULL;
		}
		}
	} else if (phy->attached_tproto & SAS_PROTO_SSP) {
	} else if (phy->attached_tproto & SAS_PROTO_SSP) {
		child->dev_type = SAS_END_DEV;
		child->dev_type = SAS_END_DEV;
		rphy = sas_end_device_alloc(phy->port);
		rphy = sas_end_device_alloc(phy->port);
		/* FIXME: error handling */
		/* FIXME: error handling */
		BUG_ON(!rphy);
		if (unlikely(!rphy))
			goto out_free;
		child->tproto = phy->attached_tproto;
		child->tproto = phy->attached_tproto;
		sas_init_dev(child);
		sas_init_dev(child);


@@ -651,9 +655,7 @@ static struct domain_device *sas_ex_discover_end_dev(
				    "at %016llx:0x%x returned 0x%x\n",
				    "at %016llx:0x%x returned 0x%x\n",
				    SAS_ADDR(child->sas_addr),
				    SAS_ADDR(child->sas_addr),
				    SAS_ADDR(parent->sas_addr), phy_id, res);
				    SAS_ADDR(parent->sas_addr), phy_id, res);
			/* FIXME: this kfrees list elements without removing them */
			goto out_list_del;
			//kfree(child);
			return NULL;
		}
		}
	} else {
	} else {
		SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
		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(


	list_add_tail(&child->siblings, &parent_ex->children);
	list_add_tail(&child->siblings, &parent_ex->children);
	return child;
	return child;

 out_list_del:
	list_del(&child->dev_list_node);
	sas_rphy_free(rphy);
 out_free:
	sas_port_delete(phy->port);
 out_err:
	phy->port = NULL;
	kfree(child);
	return NULL;
}
}


static struct domain_device *sas_ex_discover_expander(
static struct domain_device *sas_ex_discover_expander(