/**
 * sas_discover_domain -- discover the domain
 * @port: port to the domain of interest
 *
 * NOTE: this process _must_ quit (return) as soon as any connection
 * errors are encountered.  Connection recovery is done elsewhere.
 * Discover process only interrogates devices in order to discover the
 * domain.
 */
static void sas_discover_domain(struct work_struct *work)
{
	struct domain_device *dev;
	int error = 0;
	struct sas_discovery_event *ev =
		container_of(work, struct sas_discovery_event, work);
	struct asd_sas_port *port = ev->port;

	sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock,
			&port->disc.pending);

	if (port->port_dev)
		return;

	error = sas_get_port_device(port);
	if (error)
		return;
	dev = port->port_dev;

	SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
		    task_pid_nr(current));

	switch (dev->dev_type) {
	case SAS_END_DEV:
		error = sas_discover_end_dev(dev);
		break;
	case EDGE_DEV:
	case FANOUT_DEV:
		error = sas_discover_root_expander(dev);
		break;
	case SATA_DEV:
	case SATA_PM:
#ifdef CONFIG_SCSI_SAS_ATA
		error = sas_discover_sata(dev);
		break;
#else
		SAS_DPRINTK("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n");
		/* Fall through */
#endif
	default:
		error = -ENXIO;
		SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
		break;
	}

	if (error) {
		sas_rphy_free(dev->rphy);
		dev->rphy = NULL;

		spin_lock_irq(&port->dev_list_lock);
		list_del_init(&dev->dev_list_node);
		spin_unlock_irq(&port->dev_list_lock);

		kfree(dev); /* not kobject_register-ed yet */
		port->port_dev = NULL;
	}

	SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
		    task_pid_nr(current), error);
}
Beispiel #2
0
static void sas_phye_oob_error(struct work_struct *work)
{
	struct asd_sas_event *ev =
		container_of(work, struct asd_sas_event, work);
	struct asd_sas_phy *phy = ev->phy;
	struct sas_ha_struct *sas_ha = phy->ha;
	struct asd_sas_port *port = phy->port;
	struct sas_internal *i =
		to_sas_internal(sas_ha->core.shost->transportt);

	sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
			&phy->phy_events_pending);

	sas_deform_port(phy, 1);

	if (!port && phy->enabled && i->dft->lldd_control_phy) {
		phy->error++;
		switch (phy->error) {
		case 1:
		case 2:
			i->dft->lldd_control_phy(phy, PHY_FUNC_HARD_RESET,
						 NULL);
			break;
		case 3:
		default:
			phy->error = 0;
			phy->enabled = 0;
			i->dft->lldd_control_phy(phy, PHY_FUNC_DISABLE, NULL);
			break;
		}
	}
}
Beispiel #3
0
static void sas_phye_oob_done(void *data)
{
	struct asd_sas_phy *phy = data;

	sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
			&phy->phy_events_pending);
	phy->error = 0;
}
Beispiel #4
0
static void sas_phye_loss_of_signal(void *data)
{
	struct asd_sas_phy *phy = data;

	sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
			&phy->phy_events_pending);
	phy->error = 0;
	sas_deform_port(phy, 1);
}
Beispiel #5
0
static void sas_phye_oob_done(struct work_struct *work)
{
	struct asd_sas_event *ev =
		container_of(work, struct asd_sas_event, work);
	struct asd_sas_phy *phy = ev->phy;

	sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
			&phy->phy_events_pending);
	phy->error = 0;
}
static void sas_phye_loss_of_signal(struct work_struct *work)
{
    struct asd_sas_event *ev =
        container_of(work, struct asd_sas_event, work);
    struct asd_sas_phy *phy = ev->phy;

    sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
                    &phy->phy_events_pending);
    phy->error = 0;
    <<<<<<< HEAD
Beispiel #7
0
static void sas_phye_spinup_hold(void *data)
{
	struct asd_sas_phy *phy = data;
	struct sas_ha_struct *sas_ha = phy->ha;
	struct sas_internal *i =
		to_sas_internal(sas_ha->core.shost->transportt);

	sas_begin_event(PHYE_SPINUP_HOLD, &phy->ha->event_lock,
			&phy->phy_events_pending);

	phy->error = 0;
	i->dft->lldd_control_phy_new(phy, PHY_FUNC_RELEASE_SPINUP_HOLD, NULL);
}
Beispiel #8
0
static void sas_phye_spinup_hold(struct work_struct *work)
{
	struct asd_sas_event *ev =
		container_of(work, struct asd_sas_event, work);
	struct asd_sas_phy *phy = ev->phy;
	struct sas_ha_struct *sas_ha = phy->ha;
	struct sas_internal *i =
		to_sas_internal(sas_ha->core.shost->transportt);

	sas_begin_event(PHYE_SPINUP_HOLD, &phy->ha->event_lock,
			&phy->phy_events_pending);

	phy->error = 0;
	i->dft->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD, NULL);
}
static void sas_revalidate_domain(struct work_struct *work)
{
	int res = 0;
	struct sas_discovery_event *ev =
		container_of(work, struct sas_discovery_event, work);
	struct asd_sas_port *port = ev->port;

	sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock,
			&port->disc.pending);

	SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
		    task_pid_nr(current));
	if (port->port_dev)
		res = sas_ex_revalidate_domain(port->port_dev);

	SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
		    port->id, task_pid_nr(current), res);
}