Ejemplo n.º 1
0
static void __init zfcp_init_device_configure(void)
{
	struct zfcp_adapter *adapter;
	struct zfcp_port *port;
	struct zfcp_unit *unit;

	down(&zfcp_data.config_sema);
	read_lock_irq(&zfcp_data.config_lock);
	adapter = zfcp_get_adapter_by_busid(zfcp_data.init_busid);
	if (adapter)
		zfcp_adapter_get(adapter);
	read_unlock_irq(&zfcp_data.config_lock);

	if (!adapter)
		goto out_adapter;
	port = zfcp_port_enqueue(adapter, zfcp_data.init_wwpn, 0, 0);
	if (IS_ERR(port))
		goto out_port;
	unit = zfcp_unit_enqueue(port, zfcp_data.init_fcp_lun);
	if (IS_ERR(unit))
		goto out_unit;
	up(&zfcp_data.config_sema);
	ccw_device_set_online(adapter->ccw_device);
	zfcp_erp_wait(adapter);
	down(&zfcp_data.config_sema);
	zfcp_unit_put(unit);
out_unit:
	zfcp_port_put(port);
out_port:
	zfcp_adapter_put(adapter);
out_adapter:
	up(&zfcp_data.config_sema);
	return;
}
Ejemplo n.º 2
0
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
{
	struct zfcp_adapter *adapter = act->adapter;
	struct zfcp_port *port = act->port;
	struct zfcp_unit *unit = act->unit;

	switch (act->action) {
	case ZFCP_ERP_ACTION_REOPEN_UNIT:
		zfcp_unit_put(unit);
		break;

	case ZFCP_ERP_ACTION_REOPEN_PORT:
		if (result == ZFCP_ERP_SUCCEEDED)
			zfcp_scsi_schedule_rport_register(port);
		/* fall through */
	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
		zfcp_port_put(port);
		break;

	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
		if (result == ZFCP_ERP_SUCCEEDED) {
			register_service_level(&adapter->service_level);
			queue_work(adapter->work_queue, &adapter->scan_work);
		} else
			unregister_service_level(&adapter->service_level);
		zfcp_adapter_put(adapter);
		break;
	}
}
Ejemplo n.º 3
0
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
{
	struct zfcp_adapter *adapter = act->adapter;
	struct zfcp_port *port = act->port;
	struct zfcp_unit *unit = act->unit;

	switch (act->action) {
	case ZFCP_ERP_ACTION_REOPEN_UNIT:
		if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
			zfcp_unit_get(unit);
			if (scsi_queue_work(unit->port->adapter->scsi_host,
					    &unit->scsi_work) <= 0)
				zfcp_unit_put(unit);
		}
		zfcp_unit_put(unit);
		break;

	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
	case ZFCP_ERP_ACTION_REOPEN_PORT:
		if (result == ZFCP_ERP_SUCCEEDED)
			zfcp_scsi_schedule_rport_register(port);
		zfcp_port_put(port);
		break;

	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
		if (result == ZFCP_ERP_SUCCEEDED) {
			register_service_level(&adapter->service_level);
			schedule_work(&adapter->scan_work);
		} else
			unregister_service_level(&adapter->service_level);
		zfcp_adapter_put(adapter);
		break;
	}
}
Ejemplo n.º 4
0
/**
 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
 * @port: pointer to struct zfcp_port which should be removed
 */
void zfcp_port_dequeue(struct zfcp_port *port)
{
	write_lock_irq(&zfcp_data.config_lock);
	list_del(&port->list);
	write_unlock_irq(&zfcp_data.config_lock);
	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
	cancel_work_sync(&port->rport_work); /* usually not necessary */
	zfcp_adapter_put(port->adapter);
	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
}
Ejemplo n.º 5
0
/**
 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
 * @port: pointer to struct zfcp_port which should be removed
 */
void zfcp_port_dequeue(struct zfcp_port *port)
{
	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
	write_lock_irq(&zfcp_data.config_lock);
	list_del(&port->list);
	write_unlock_irq(&zfcp_data.config_lock);
	if (port->rport)
		port->rport->dd_data = NULL;
	zfcp_adapter_put(port->adapter);
	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
}
Ejemplo n.º 6
0
/**
 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
 * @port: pointer to struct zfcp_port which should be removed
 */
void zfcp_port_dequeue(struct zfcp_port *port)
{
	write_lock_irq(&zfcp_data.config_lock);
	list_del(&port->list);
	write_unlock_irq(&zfcp_data.config_lock);
	if (cancel_work_sync(&port->gid_pn_work))
		zfcp_port_put(port);
	if (cancel_work_sync(&port->rport_work))
		zfcp_port_put(port);
	if (cancel_work_sync(&port->test_link_work))
		zfcp_port_put(port);
	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
	zfcp_adapter_put(port->adapter);
	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
}
Ejemplo n.º 7
0
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
{
	struct ccw_device *ccwdev;
	struct zfcp_adapter *adapter;
	struct zfcp_port *port;
	struct zfcp_unit *unit;

	ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
	if (!ccwdev)
		return;

	if (ccw_device_set_online(ccwdev))
		goto out_ccwdev;

	mutex_lock(&zfcp_data.config_mutex);
	adapter = dev_get_drvdata(&ccwdev->dev);
	if (!adapter)
		goto out_unlock;
	zfcp_adapter_get(adapter);

	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	if (!port)
		goto out_port;

	zfcp_port_get(port);
	unit = zfcp_unit_enqueue(port, lun);
	if (IS_ERR(unit))
		goto out_unit;
	mutex_unlock(&zfcp_data.config_mutex);

	zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
	zfcp_erp_wait(adapter);
	flush_work(&unit->scsi_work);

	mutex_lock(&zfcp_data.config_mutex);
	zfcp_unit_put(unit);
out_unit:
	zfcp_port_put(port);
out_port:
	zfcp_adapter_put(adapter);
out_unlock:
	mutex_unlock(&zfcp_data.config_mutex);
out_ccwdev:
	put_device(&ccwdev->dev);
	return;
}
Ejemplo n.º 8
0
/**
 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
 * @port: pointer to struct zfcp_port which should be removed
 */
void zfcp_port_dequeue(struct zfcp_port *port)
{
	zfcp_port_wait(port);
	write_lock_irq(&zfcp_data.config_lock);
	list_del(&port->list);
	port->adapter->ports--;
	write_unlock_irq(&zfcp_data.config_lock);
	if (port->rport)
		fc_remote_port_delete(port->rport);
	port->rport = NULL;
	zfcp_adapter_put(port->adapter);
	if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
		sysfs_remove_group(&port->sysfs_device.kobj,
				   &zfcp_sysfs_ns_port_attrs);
	else
		sysfs_remove_group(&port->sysfs_device.kobj,
				   &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
}
Ejemplo n.º 9
0
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
{
	struct zfcp_adapter *adapter;
	struct zfcp_port *port;
	struct zfcp_unit *unit;

	down(&zfcp_data.config_sema);
	read_lock_irq(&zfcp_data.config_lock);
	adapter = zfcp_get_adapter_by_busid(busid);
	if (adapter)
		zfcp_adapter_get(adapter);
	read_unlock_irq(&zfcp_data.config_lock);

	if (!adapter)
		goto out_adapter;
	port = zfcp_port_enqueue(adapter, wwpn, 0, 0);
	if (IS_ERR(port))
		goto out_port;
	unit = zfcp_unit_enqueue(port, lun);
	if (IS_ERR(unit))
		goto out_unit;
	up(&zfcp_data.config_sema);
	ccw_device_set_online(adapter->ccw_device);

	zfcp_erp_wait(adapter);
	wait_event(adapter->erp_done_wqh,
		   !(atomic_read(&unit->status) &
				ZFCP_STATUS_UNIT_SCSI_WORK_PENDING));

	down(&zfcp_data.config_sema);
	zfcp_unit_put(unit);
out_unit:
	zfcp_port_put(port);
out_port:
	zfcp_adapter_put(adapter);
out_adapter:
	up(&zfcp_data.config_sema);
	return;
}
Ejemplo n.º 10
0
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
{
	struct zfcp_adapter *adapter;
	struct zfcp_port *port;
	struct zfcp_unit *unit;

	mutex_lock(&zfcp_data.config_mutex);
	read_lock_irq(&zfcp_data.config_lock);
	adapter = zfcp_get_adapter_by_busid(busid);
	if (adapter)
		zfcp_adapter_get(adapter);
	read_unlock_irq(&zfcp_data.config_lock);

	if (!adapter)
		goto out_adapter;
	port = zfcp_port_enqueue(adapter, wwpn, 0, 0);
	if (IS_ERR(port))
		goto out_port;
	unit = zfcp_unit_enqueue(port, lun);
	if (IS_ERR(unit))
		goto out_unit;
	mutex_unlock(&zfcp_data.config_mutex);
	ccw_device_set_online(adapter->ccw_device);

	zfcp_erp_wait(adapter);
	flush_work(&unit->scsi_work);

	mutex_lock(&zfcp_data.config_mutex);
	zfcp_unit_put(unit);
out_unit:
	zfcp_port_put(port);
out_port:
	zfcp_adapter_put(adapter);
out_adapter:
	mutex_unlock(&zfcp_data.config_mutex);
	return;
}
Ejemplo n.º 11
0
static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
				unsigned long buffer)
{
	struct zfcp_cfdc_data *data;
	struct zfcp_cfdc_data __user *data_user;
	struct zfcp_adapter *adapter;
	struct zfcp_fsf_req *req;
	struct zfcp_fsf_cfdc *fsf_cfdc;
	int retval;

	if (command != ZFCP_CFDC_IOC)
		return -ENOTTY;

	data_user = (void __user *) buffer;
	if (!data_user)
		return -EINVAL;

	fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL);
	if (!fsf_cfdc)
		return -ENOMEM;

	data = kmalloc(sizeof(struct zfcp_cfdc_data), GFP_KERNEL);
	if (!data) {
		retval = -ENOMEM;
		goto no_mem_sense;
	}

	retval = copy_from_user(data, data_user, sizeof(*data));
	if (retval) {
		retval = -EFAULT;
		goto free_buffer;
	}

	if (data->signature != 0xCFDCACDF) {
		retval = -EINVAL;
		goto free_buffer;
	}

	retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command);

	adapter = zfcp_cfdc_get_adapter(data->devno);
	if (!adapter) {
		retval = -ENXIO;
		goto free_buffer;
	}

	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
				    data_user->control_file);
	if (retval)
		goto adapter_put;
	req = zfcp_fsf_control_file(adapter, fsf_cfdc);
	if (IS_ERR(req)) {
		retval = PTR_ERR(req);
		goto free_sg;
	}

	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		retval = -ENXIO;
		goto free_fsf;
	}

	zfcp_cfdc_req_to_sense(data, req);
	retval = copy_to_user(data_user, data, sizeof(*data_user));
	if (retval) {
		retval = -EFAULT;
		goto free_fsf;
	}

	if (data->command & ZFCP_CFDC_UPLOAD)
		retval = zfcp_cfdc_copy_to_user(&data_user->control_file,
						fsf_cfdc->sg);

 free_fsf:
	zfcp_fsf_req_free(req);
 free_sg:
	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
 adapter_put:
	zfcp_adapter_put(adapter);
 free_buffer:
	kfree(data);
 no_mem_sense:
	kfree(fsf_cfdc);
	return retval;
}