static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result)
{
    struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);

    switch (result) {
    case ZFCP_ERP_SUCCEEDED :
        atomic_set(&zfcp_sdev->erp_counter, 0);
        zfcp_erp_lun_unblock(sdev);
        break;
    case ZFCP_ERP_FAILED :
        atomic_inc(&zfcp_sdev->erp_counter);
        if (atomic_read(&zfcp_sdev->erp_counter) > ZFCP_MAX_ERPS) {
            dev_err(&zfcp_sdev->port->adapter->ccw_device->dev,
                    "ERP failed for LUN 0x%016Lx on "
                    "port 0x%016Lx\n",
                    (unsigned long long)zfcp_scsi_dev_lun(sdev),
                    (unsigned long long)zfcp_sdev->port->wwpn);
            zfcp_erp_set_lun_status(sdev,
                                    ZFCP_STATUS_COMMON_ERP_FAILED);
        }
        break;
    }

    if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
        zfcp_erp_lun_block(sdev, 0);
        result = ZFCP_ERP_EXIT;
    }
    return result;
}
Exemple #2
0
static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
{
	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
	struct zfcp_adapter *adapter =
		(struct zfcp_adapter *) sdev->host->hostdata[0];
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
	struct zfcp_port *port;
	struct zfcp_unit *unit;
	int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE;

	zfcp_sdev->erp_action.adapter = adapter;
	zfcp_sdev->erp_action.sdev = sdev;

	port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
	if (!port)
		return -ENXIO;

	zfcp_sdev->erp_action.port = port;

	unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
	if (unit)
		put_device(&unit->dev);

	if (!unit && !(allow_lun_scan && npiv)) {
		put_device(&port->dev);
		return -ENXIO;
	}

	zfcp_sdev->port = port;
	zfcp_sdev->latencies.write.channel.min = 0xFFFFFFFF;
	zfcp_sdev->latencies.write.fabric.min = 0xFFFFFFFF;
	zfcp_sdev->latencies.read.channel.min = 0xFFFFFFFF;
	zfcp_sdev->latencies.read.fabric.min = 0xFFFFFFFF;
	zfcp_sdev->latencies.cmd.channel.min = 0xFFFFFFFF;
	zfcp_sdev->latencies.cmd.fabric.min = 0xFFFFFFFF;
	spin_lock_init(&zfcp_sdev->latencies.lock);

	zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
	zfcp_erp_lun_reopen(sdev, 0, "scsla_1");
	zfcp_erp_wait(port->adapter);

	return 0;
}
static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
	unsigned long val;
	struct scsi_device *sdev;

	if (strict_strtoul(buf, 0, &val) || val != 0)
		return -EINVAL;

	sdev = zfcp_unit_sdev(unit);
	if (sdev) {
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
		zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
				    "syufai2");
		zfcp_erp_wait(unit->port->adapter);
	} else
		zfcp_unit_scsi_scan(unit);

	return count;
}