// SPDX-License-Identifier: GPL-2.0
/*
 * zfcp device driver
 *
 * Tracking of manually configured LUNs and helper functions to
 * register the LUNs with the SCSI midlayer.
 *
 * Copyright IBM Corp. 2010
 */

#include "zfcp_def.h"
#include "zfcp_ext.h"

/**
 * zfcp_unit_scsi_scan - Register LUN with SCSI midlayer
 * @unit: The zfcp LUN/unit to register
 *
 * When the SCSI midlayer is not allowed to automatically scan and
 * attach SCSI devices, zfcp has to register the single devices with
 * the SCSI midlayer.
 */
void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
{
	struct fc_rport *rport = unit->port->rport;
	u64 lun;

	lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);

	if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
		scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun,
				 SCSI_SCAN_MANUAL);
}

static void zfcp_unit_scsi_scan_work(struct work_struct *work)
{
	struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
					      scsi_work);

	zfcp_unit_scsi_scan(unit);
	put_device(&unit->dev);
}

/**
 * zfcp_unit_queue_scsi_scan - Register configured units on port
 * @port: The zfcp_port where to register units
 *
 * After opening a port, all units configured on this port have to be
 * registered with the SCSI midlayer. This function should be called
 * after calling fc_remote_port_add, so that the fc_rport is already
 * ONLINE and the call to scsi_scan_target runs the same way as the
 * call in the FC transport class.
 */
void zfcp_unit_queue_scsi_scan(struct zfcp_port *port)
{
	struct zfcp_unit *unit;

	read_lock_irq(&port->unit_list_lock);
	list_for_each_entry(unit, &port->unit_list, list) {
		get_device(&unit->dev);
		if (scsi_queue_work(port->adapter->scsi_host,
				    &unit->scsi_work) <= 0)
			put_device(&unit->dev);
	}
	read_unlock_irq(&port->unit_list_lock);
}

static struct zfcp_unit *_zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;

	list_for_each_entry(unit, &port->unit_list, list)
		if (unit->fcp_lun == fcp_lun) {
			get_device(&unit->dev);
			return unit;
		}

	return NULL;
}

/**
 * zfcp_unit_find - Find and return zfcp_unit with specified FCP LUN
 * @port: zfcp_port where to look for the unit
 * @fcp_lun: 64 Bit FCP LUN used to identify the zfcp_unit
 *
 * If zfcp_unit is found, a reference is acquired that has to be
 * released later.
 *
 * Returns: Pointer to the zfcp_unit, or NULL if there is no zfcp_unit
 *          with the specified FCP LUN.
 */
struct zfcp_unit *zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;

	read_lock_irq(&port->unit_list_lock);
	unit = _zfcp_unit_find(port, fcp_lun);
	read_unlock_irq(&port->unit_list_lock);
	return unit;
}

/**
 * zfcp_unit_release - Drop reference to zfcp_port and free memory of zfcp_unit.
 * @dev: pointer to device in zfcp_unit
 */
static void zfcp_unit_release(struct device *dev)
{
	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);

	atomic_dec(&unit->port->units);
	kfree(unit);
}

/**
 * zfcp_unit_add - add unit to unit list of a port.
 * @port: pointer to port where unit is added
 * @fcp_lun: FCP LUN of unit to be added
 * Returns: 0 success
 *
 * Sets up some unit internal structures and creates sysfs entry.
 */
int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;
	int retval = 0;

	mutex_lock(&zfcp_sysfs_port_units_mutex);
	if (zfcp_sysfs_port_is_removing(port)) {
		/* port is already gone */
		retval = -ENODEV;
		goto out;
	}

	unit = zfcp_unit_find(port, fcp_lun);
	if (unit) {
		put_device(&unit->dev);
		retval = -EEXIST;
		goto out;
	}

	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
	if (!unit) {
		retval = -ENOMEM;
		goto out;
	}

	unit->port = port;
	unit->fcp_lun = fcp_lun;
	unit->dev.parent = &port->dev;
	unit->dev.release = zfcp_unit_release;
	unit->dev.groups = zfcp_unit_attr_groups;
	INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work);

	if (dev_set_name(&unit->dev, "0x%016llx",
			 (unsigned long long) fcp_lun)) {
		kfree(unit);
		retval = -ENOMEM;
		goto out;
	}

	if (device_register(&unit->dev)) {
		put_device(&unit->dev);
		retval = -ENOMEM;
		goto out;
	}

	atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */

	write_lock_irq(&port->unit_list_lock);
	list_add_tail(&unit->list, &port->unit_list);
	write_unlock_irq(&port->unit_list_lock);
	/*
	 * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
	 * due to      zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
	 */
	mutex_unlock(&zfcp_sysfs_port_units_mutex);

	zfcp_unit_scsi_scan(unit);
	return retval;

out:
	mutex_unlock(&zfcp_sysfs_port_units_mutex);
	return retval;
}

/**
 * zfcp_unit_sdev - Return SCSI device for zfcp_unit
 * @unit: The zfcp_unit where to get the SCSI device for
 *
 * Returns: scsi_device pointer on success, NULL if there is no SCSI
 *          device for this zfcp_unit
 *
 * On success, the caller also holds a reference to the SCSI device
 * that must be released with scsi_device_put.
 */
struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit)
{
	struct Scsi_Host *shost;
	struct zfcp_port *port;
	u64 lun;

	lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
	port = unit->port;
	shost = port->adapter->scsi_host;
	return scsi_device_lookup(shost, 0, port->starget_id, lun);
}

/**
 * zfcp_unit_sdev_status - Return zfcp LUN status for SCSI device
 * @unit: The unit to lookup the SCSI device for
 *
 * Returns the zfcp LUN status field of the SCSI device if the SCSI device
 * for the zfcp_unit exists, 0 otherwise.
 */
unsigned int zfcp_unit_sdev_status(struct zfcp_unit *unit)
{
	unsigned int status = 0;
	struct scsi_device *sdev;
	struct zfcp_scsi_dev *zfcp_sdev;

	sdev = zfcp_unit_sdev(unit);
	if (sdev) {
		zfcp_sdev = sdev_to_zfcp(sdev);
		status = atomic_read(&zfcp_sdev->status);
		scsi_device_put(sdev);
	}

	return status;
}

/**
 * zfcp_unit_remove - Remove entry from list of configured units
 * @port: The port where to remove the unit from the configuration
 * @fcp_lun: The 64 bit LUN of the unit to remove
 *
 * Returns: -EINVAL if a unit with the specified LUN does not exist,
 *          0 on success.
 */
int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;
	struct scsi_device *sdev;

	write_lock_irq(&port->unit_list_lock);
	unit = _zfcp_unit_find(port, fcp_lun);
	if (unit)
		list_del(&unit->list);
	write_unlock_irq(&port->unit_list_lock);

	if (!unit)
		return -EINVAL;

	sdev = zfcp_unit_sdev(unit);
	if (sdev) {
		scsi_remove_device(sdev);
		scsi_device_put(sdev);
	}

	device_unregister(&unit->dev);

	put_device(&unit->dev); /* undo _zfcp_unit_find() */

	return 0;
}
