/*
 * zfcp device driver
 *
 * Registration and callback for the s390 common I/O layer.
 *
 * Copyright IBM Corporation 2002, 2008
 */

#include "zfcp_ext.h"

/**
 * zfcp_ccw_probe - probe function of zfcp driver
 * @ccw_device: pointer to belonging ccw device
 *
 * This function gets called by the common i/o layer and sets up the initial
 * data structures for each fcp adapter, which was detected by the system.
 * Also the sysfs files for this adapter will be created by this function.
 * In addition the nameserver port will be added to the ports of the adapter
 * and its sysfs representation will be created too.
 */
static int zfcp_ccw_probe(struct ccw_device *ccw_device)
{
	int retval = 0;

	down(&zfcp_data.config_sema);
	if (zfcp_adapter_enqueue(ccw_device)) {
		dev_err(&ccw_device->dev,
			"Setup of data structures failed.\n");
		retval = -EINVAL;
	}
	up(&zfcp_data.config_sema);
	return retval;
}

/**
 * zfcp_ccw_remove - remove function of zfcp driver
 * @ccw_device: pointer to belonging ccw device
 *
 * This function gets called by the common i/o layer and removes an adapter
 * from the system. Task of this function is to get rid of all units and
 * ports that belong to this adapter. And in addition all resources of this
 * adapter will be freed too.
 */
static void zfcp_ccw_remove(struct ccw_device *ccw_device)
{
	struct zfcp_adapter *adapter;
	struct zfcp_port *port, *p;
	struct zfcp_unit *unit, *u;

	ccw_device_set_offline(ccw_device);
	down(&zfcp_data.config_sema);
	adapter = dev_get_drvdata(&ccw_device->dev);

	write_lock_irq(&zfcp_data.config_lock);
	list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
		list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
			list_move(&unit->list, &port->unit_remove_lh);
			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
					&unit->status);
		}
		list_move(&port->list, &adapter->port_remove_lh);
		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
	}
	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
	write_unlock_irq(&zfcp_data.config_lock);

	list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) {
		list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) {
			if (atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED,
				&unit->status))
				scsi_remove_device(unit->device);
			zfcp_unit_dequeue(unit);
		}
		zfcp_port_dequeue(port);
	}
	zfcp_adapter_wait(adapter);
	zfcp_adapter_dequeue(adapter);

	up(&zfcp_data.config_sema);
}

/**
 * zfcp_ccw_set_online - set_online function of zfcp driver
 * @ccw_device: pointer to belonging ccw device
 *
 * This function gets called by the common i/o layer and sets an adapter
 * into state online. Setting an fcp device online means that it will be
 * registered with the SCSI stack, that the QDIO queues will be set up
 * and that the adapter will be opened (asynchronously).
 */
static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
{
	struct zfcp_adapter *adapter;
	int retval;

	down(&zfcp_data.config_sema);
	adapter = dev_get_drvdata(&ccw_device->dev);

	retval = zfcp_erp_thread_setup(adapter);
	if (retval)
		goto out;

	retval = zfcp_adapter_scsi_register(adapter);
	if (retval)
		goto out_scsi_register;

	/* initialize request counter */
	BUG_ON(!zfcp_reqlist_isempty(adapter));
	adapter->req_no = 0;

	zfcp_erp_modify_adapter_status(adapter, 10, NULL,
				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
				NULL);
	zfcp_erp_wait(adapter);
	goto out;

 out_scsi_register:
	zfcp_erp_thread_kill(adapter);
 out:
	up(&zfcp_data.config_sema);
	return retval;
}

/**
 * zfcp_ccw_set_offline - set_offline function of zfcp driver
 * @ccw_device: pointer to belonging ccw device
 *
 * This function gets called by the common i/o layer and sets an adapter
 * into state offline.
 */
static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
{
	struct zfcp_adapter *adapter;

	down(&zfcp_data.config_sema);
	adapter = dev_get_drvdata(&ccw_device->dev);
	zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL);
	zfcp_erp_wait(adapter);
	zfcp_erp_thread_kill(adapter);
	up(&zfcp_data.config_sema);
	return 0;
}

/**
 * zfcp_ccw_notify - ccw notify function
 * @ccw_device: pointer to belonging ccw device
 * @event: indicates if adapter was detached or attached
 *
 * This function gets called by the common i/o layer if an adapter has gone
 * or reappeared.
 */
static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
{
	struct zfcp_adapter *adapter;

	down(&zfcp_data.config_sema);
	adapter = dev_get_drvdata(&ccw_device->dev);
	switch (event) {
	case CIO_GONE:
		dev_warn(&adapter->ccw_device->dev, "device gone\n");
		zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
		break;
	case CIO_NO_PATH:
		dev_warn(&adapter->ccw_device->dev, "no path\n");
		zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
		break;
	case CIO_OPER:
		dev_info(&adapter->ccw_device->dev, "operational again\n");
		zfcp_erp_modify_adapter_status(adapter, 11, NULL,
					       ZFCP_STATUS_COMMON_RUNNING,
					       ZFCP_SET);
		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
					89, NULL);
		break;
	}
	zfcp_erp_wait(adapter);
	up(&zfcp_data.config_sema);
	return 1;
}

/**
 * zfcp_ccw_shutdown - handle shutdown from cio
 * @cdev: device for adapter to shutdown.
 */
static void zfcp_ccw_shutdown(struct ccw_device *cdev)
{
	struct zfcp_adapter *adapter;

	down(&zfcp_data.config_sema);
	adapter = dev_get_drvdata(&cdev->dev);
	zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL);
	zfcp_erp_wait(adapter);
	up(&zfcp_data.config_sema);
}

static struct ccw_device_id zfcp_ccw_device_id[] = {
	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x4) }, /* priv. */
	{},
};

MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);

static struct ccw_driver zfcp_ccw_driver = {
	.owner       = THIS_MODULE,
	.name        = "zfcp",
	.ids         = zfcp_ccw_device_id,
	.probe       = zfcp_ccw_probe,
	.remove      = zfcp_ccw_remove,
	.set_online  = zfcp_ccw_set_online,
	.set_offline = zfcp_ccw_set_offline,
	.notify      = zfcp_ccw_notify,
	.shutdown    = zfcp_ccw_shutdown,
};

/**
 * zfcp_ccw_register - ccw register function
 *
 * Registers the driver at the common i/o layer. This function will be called
 * at module load time/system start.
 */
int __init zfcp_ccw_register(void)
{
	return ccw_driver_register(&zfcp_ccw_driver);
}
