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

Commit c132f692 authored by Dan Williams's avatar Dan Williams Committed by James Bottomley
Browse files

[SCSI] isci: kill iphy->isci_port lookups



This field is a holdover from the OS abstraction conversion.  The stable
phy to port lookups are done via iphy->ownining_port under scic_lock.
After this conversion to use port->lldd_port the only volatile lookup is
the initial lookup in isci_port_formed().  After that point any lookup
via a successfully notified domain_device is guaranteed to be valid
until the domain_device is destroyed.

Delete ->start_complete as it is only set once and is set as a
consequence of the port going link up, by definition of getting a port
formed event the port is "ready".

While we are correcting port lookups also move the asd_sas_port table
out from under the isci_port.  This is to preclude any temptation to use
container_of() to convert an asd_sas_port to an isci_port, the
association is dynamic and under libsas control.

Tested-by: default avatarMaciej Trela <maciej.trela@intel.com>
[dmilburn@redhat.com: fix i686 compile error]
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent cb48d672
Loading
Loading
Loading
Loading
+1 −18
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ struct isci_host {
	int id; /* unique within a given pci device */
	struct isci_phy phys[SCI_MAX_PHYS];
	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
	struct asd_sas_port sas_ports[SCI_MAX_PORTS];
	struct sas_ha_struct sas_ha;

	spinlock_t state_lock;
@@ -393,24 +394,6 @@ static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
#define sci_controller_clear_invalid_phy(controller, phy) \
	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))

static inline struct device *sciphy_to_dev(struct isci_phy *iphy)
{

	if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
		return NULL;

	return &iphy->isci_port->isci_host->pdev->dev;
}

static inline struct device *sciport_to_dev(struct isci_port *iport)
{

	if (!iport || !iport->isci_host)
		return NULL;

	return &iport->isci_host->pdev->dev;
}

static inline struct device *scirdev_to_dev(struct isci_remote_device *idev)
{
	if (!idev || !idev->isci_port || !idev->isci_port->isci_host)
+1 −6
Original line number Diff line number Diff line
@@ -241,18 +241,13 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
	if (!sas_ports)
		return -ENOMEM;

	/*----------------- Libsas Initialization Stuff----------------------
	 * Set various fields in the sas_ha struct:
	 */

	sas_ha->sas_ha_name = DRV_NAME;
	sas_ha->lldd_module = THIS_MODULE;
	sas_ha->sas_addr    = &isci_host->phys[0].sas_addr[0];

	/* set the array of phy and port structs.  */
	for (i = 0; i < SCI_MAX_PHYS; i++) {
		sas_phys[i] = &isci_host->phys[i].sas_phy;
		sas_ports[i] = &isci_host->ports[i].sas_port;
		sas_ports[i] = &isci_host->sas_ports[i];
	}

	sas_ha->sas_phy  = sas_phys;
+12 −6
Original line number Diff line number Diff line
@@ -67,6 +67,14 @@ enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
	return iphy->max_negotiated_speed;
}

static struct device *sciphy_to_dev(struct isci_phy *iphy)
{
	struct isci_phy *table = iphy - iphy->phy_index;
	struct isci_host *ihost = container_of(table, typeof(*ihost), phys[0]);

	return &ihost->pdev->dev;
}

static enum sci_status
sci_phy_transport_layer_initialization(struct isci_phy *iphy,
				       struct scu_transport_layer_registers __iomem *reg)
@@ -1299,7 +1307,6 @@ void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
	sas_addr = cpu_to_be64(sci_sas_addr);
	memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));

	iphy->isci_port = NULL;
	iphy->sas_phy.enabled = 0;
	iphy->sas_phy.id = index;
	iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
@@ -1333,13 +1340,13 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
{
	int ret = 0;
	struct isci_phy *iphy = sas_phy->lldd_phy;
	struct isci_port *iport = iphy->isci_port;
	struct asd_sas_port *port = sas_phy->port;
	struct isci_host *ihost = sas_phy->ha->lldd_ha;
	unsigned long flags;

	dev_dbg(&ihost->pdev->dev,
		"%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
		__func__, sas_phy, func, buf, iphy, iport);
		__func__, sas_phy, func, buf, iphy, port);

	switch (func) {
	case PHY_FUNC_DISABLE:
@@ -1356,11 +1363,10 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
		break;

	case PHY_FUNC_HARD_RESET:
		if (!iport)
		if (!port)
			return -ENODEV;

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

		break;
	case PHY_FUNC_GET_EVENTS: {
+0 −1
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ struct isci_phy {
	struct scu_transport_layer_registers __iomem *transport_layer_registers;
	struct scu_link_layer_registers __iomem *link_layer_registers;
	struct asd_sas_phy sas_phy;
	struct isci_port *isci_port;
	u8 sas_addr[SAS_ADDR_SIZE];
	union {
		struct sas_identify_frame iaf;
+61 −23
Original line number Diff line number Diff line
@@ -60,6 +60,21 @@
#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT  (1000)
#define SCU_DUMMY_INDEX    (0xFFFF)

static struct device *sciport_to_dev(struct isci_port *iport)
{
	int i = iport->physical_port_index;
	struct isci_port *table;
	struct isci_host *ihost;

	if (i == SCIC_SDS_DUMMY_PORT)
		i = SCI_MAX_PORTS+1;

	table = iport - i;
	ihost = container_of(table, typeof(*ihost), ports[0]);

	return &ihost->pdev->dev;
}

static void isci_port_change_state(struct isci_port *iport, enum isci_status status)
{
	unsigned long flags;
@@ -165,17 +180,13 @@ static void isci_port_link_up(struct isci_host *isci_host,
	struct sci_port_properties properties;
	unsigned long success = true;

	BUG_ON(iphy->isci_port != NULL);

	iphy->isci_port = iport;

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

	spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);

	isci_port_change_state(iphy->isci_port, isci_starting);
	isci_port_change_state(iport, isci_starting);

	sci_port_get_properties(iport, &properties);

@@ -269,8 +280,6 @@ static void isci_port_link_down(struct isci_host *isci_host,
	isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
					   PHYE_LOSS_OF_SIGNAL);

	isci_phy->isci_port = NULL;

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p - Done\n", __func__, isci_port);
}
@@ -288,7 +297,6 @@ static void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_
	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p\n", __func__, isci_port);

	complete_all(&isci_port->start_complete);
	isci_port_change_state(isci_port, isci_ready);
	return;
}
@@ -1645,7 +1653,6 @@ void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
	INIT_LIST_HEAD(&iport->remote_dev_list);
	INIT_LIST_HEAD(&iport->domain_dev_list);
	spin_lock_init(&iport->state_lock);
	init_completion(&iport->start_complete);
	iport->isci_host = ihost;
	isci_port_change_state(iport, isci_freed);
}
@@ -1726,24 +1733,55 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
	return ret;
}

/**
 * isci_port_deformed() - This function is called by libsas when a port becomes
 *    inactive.
 * @phy: This parameter specifies the libsas phy with the inactive port.
 *
 */
void isci_port_deformed(struct asd_sas_phy *phy)
{
	pr_debug("%s: sas_phy = %p\n", __func__, phy);
}
	struct isci_host *ihost = phy->ha->lldd_ha;
	struct isci_port *iport = phy->port->lldd_port;
	unsigned long flags;
	int i;

/**
 * isci_port_formed() - This function is called by libsas when a port becomes
 *    active.
 * @phy: This parameter specifies the libsas phy with the active port.
 *
	/* we got a port notification on a port that was subsequently
	 * torn down and libsas is just now catching up
	 */
	if (!iport)
		return;

	spin_lock_irqsave(&ihost->scic_lock, flags);
	for (i = 0; i < SCI_MAX_PHYS; i++) {
		if (iport->active_phy_mask & 1 << i)
			break;
	}
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	if (i >= SCI_MAX_PHYS)
		dev_dbg(&ihost->pdev->dev, "%s: port: %ld\n",
			__func__, (long) (iport - &ihost->ports[0]));
}

void isci_port_formed(struct asd_sas_phy *phy)
{
	pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port);
	struct isci_host *ihost = phy->ha->lldd_ha;
	struct isci_phy *iphy = to_iphy(phy);
	struct asd_sas_port *port = phy->port;
	struct isci_port *iport;
	unsigned long flags;
	int i;

	/* initial ports are formed as the driver is still initializing,
	 * wait for that process to complete
	 */
	wait_for_start(ihost);

	spin_lock_irqsave(&ihost->scic_lock, flags);
	for (i = 0; i < SCI_MAX_PORTS; i++) {
		iport = &ihost->ports[i];
		if (iport->active_phy_mask & 1 << iphy->phy_index)
			break;
	}
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	if (i >= SCI_MAX_PORTS)
		iport = NULL;

	port->lldd_port = iport;
}
Loading