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

Commit 4393aa4e authored by Dan Williams's avatar Dan Williams
Browse files

isci: fix fragile/conditional isci_host lookups



A domain_device can always reference back to ->lldd_ha unlike local lldd
structures.  Fix up cases where the driver uses local objects to look up the
isci_host.  This also changes the calling conventions of some routines to
expect a valid isci_host parameter rather than re-lookup the pointer on entry.

Incidentally cleans up some macros that are longer to type than the open-coded
equivalent:
  isci_host_from_sas_ha
  isci_dev_from_domain_dev

Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 037afc78
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ void isci_host_start_complete(struct isci_host *ihost, enum sci_status completio

int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
	struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
	struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;

	if (test_bit(IHOST_START_PENDING, &ihost->flags))
		return 0;
@@ -149,7 +149,7 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)

void isci_host_scan_start(struct Scsi_Host *shost)
{
	struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
	struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
	struct scic_sds_controller *scic = ihost->core_controller;
	unsigned long tmo = scic_controller_get_suggested_start_timeout(scic);

+4 −9
Original line number Diff line number Diff line
@@ -233,15 +233,10 @@ static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_rem
	wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
}

/**
 * isci_host_from_sas_ha() - This accessor retrieves the isci_host object
 *    reference from the Linux sas_ha_struct reference.
 * @ha_struct,: This parameter points to the Linux sas_ha_struct object
 *
 * A reference to the associated isci_host structure.
 */
#define isci_host_from_sas_ha(ha_struct) \
	((struct isci_host *)(ha_struct)->lldd_ha)
static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
{
	return dev->port->ha->lldd_ha;
}

/**
 * isci_host_scan_finished() -
+1 −1
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
			return -ENODEV;

		/* Perform the port reset. */
		ret = isci_port_perform_hard_reset(iport, iphy);
		ret = isci_port_perform_hard_reset(ihost, iport, iphy);

		break;

+24 −44
Original line number Diff line number Diff line
@@ -400,55 +400,43 @@ void isci_port_hard_reset_complete(struct isci_port *isci_port,

	complete_all(&isci_port->hard_reset_complete);
}
/**
 * isci_port_perform_hard_reset() - This function is one of the SAS Domain
 *    Template functions. This is a phy management function.
 * @isci_port:
 * @isci_phy:
 *
 * status, TMF_RESP_FUNC_COMPLETE indicates success.
 */
int isci_port_perform_hard_reset(
	struct isci_port *isci_port,
	struct isci_phy *isci_phy)

int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
				 struct isci_phy *iphy)
{
	unsigned long flags;
	enum sci_status status;
	int ret = TMF_RESP_FUNC_COMPLETE;
	unsigned long flags;

	dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
		__func__, iport);

	dev_dbg(&isci_port->isci_host->pdev->dev,
		"%s: isci_port = %p\n",
		__func__, isci_port);
	init_completion(&iport->hard_reset_complete);

	BUG_ON(isci_port == NULL);

	init_completion(&isci_port->hard_reset_complete);

	spin_lock_irqsave(&isci_port->isci_host->scic_lock, flags);
	spin_lock_irqsave(&ihost->scic_lock, flags);

	#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
	status = scic_port_hard_reset(isci_port->sci_port_handle,
	status = scic_port_hard_reset(iport->sci_port_handle,
				      ISCI_PORT_RESET_TIMEOUT);

	spin_unlock_irqrestore(&isci_port->isci_host->scic_lock, flags);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	if (status == SCI_SUCCESS) {
		wait_for_completion(&isci_port->hard_reset_complete);
		wait_for_completion(&iport->hard_reset_complete);

		dev_dbg(&isci_port->isci_host->pdev->dev,
			"%s: isci_port = %p; hard reset completion\n",
			__func__, isci_port);
		dev_dbg(&ihost->pdev->dev,
			"%s: iport = %p; hard reset completion\n",
			__func__, iport);

		if (isci_port->hard_reset_status != SCI_SUCCESS)
		if (iport->hard_reset_status != SCI_SUCCESS)
			ret = TMF_RESP_FUNC_FAILED;
	} else {
		ret = TMF_RESP_FUNC_FAILED;

		dev_err(&isci_port->isci_host->pdev->dev,
			"%s: isci_port = %p; scic_port_hard_reset call"
		dev_err(&ihost->pdev->dev,
			"%s: iport = %p; scic_port_hard_reset call"
			" failed 0x%x\n",
			__func__, isci_port, status);
			__func__, iport, status);

	}

@@ -456,19 +444,12 @@ int isci_port_perform_hard_reset(
	 * the same as link failures on all phys in the port.
	 */
	if (ret != TMF_RESP_FUNC_COMPLETE) {
		BUG_ON(isci_port->isci_host == NULL);

		dev_err(&isci_port->isci_host->pdev->dev,
			"%s: isci_port = %p; hard reset failed "
		dev_err(&ihost->pdev->dev,
			"%s: iport = %p; hard reset failed "
			"(0x%x) - sending link down to libsas for phy %p\n",
			__func__,
			isci_port,
			isci_port->hard_reset_status,
			isci_phy);
			__func__, iport, iport->hard_reset_status, iphy);

		isci_port_link_down(isci_port->isci_host,
				    isci_phy,
				    isci_port);
		isci_port_link_down(ihost, iphy, iport);
	}

	return ret;
@@ -491,8 +472,7 @@ void isci_port_invalid_link_up(struct scic_sds_controller *scic,
				      struct scic_sds_port *sci_port,
				      struct scic_sds_phy *phy)
{
	struct isci_host *ihost =
		(struct isci_host *)sci_object_get_association(scic);
	struct isci_host *ihost = sci_object_get_association(scic);

	dev_warn(&ihost->pdev->dev, "Invalid link up!\n");
}
+2 −3
Original line number Diff line number Diff line
@@ -143,9 +143,8 @@ void isci_port_hard_reset_complete(
	struct isci_port *isci_port,
	enum sci_status completion_status);

int isci_port_perform_hard_reset(
	struct isci_port *isci_port_ptr,
	struct isci_phy *isci_phy_ptr);
int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
				 struct isci_phy *iphy);

void isci_port_invalid_link_up(
		struct scic_sds_controller *scic,
Loading