^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * zfcp device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Tracking of manually configured LUNs and helper functions to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * register the LUNs with the SCSI midlayer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright IBM Corp. 2010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "zfcp_def.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "zfcp_ext.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * zfcp_unit_scsi_scan - Register LUN with SCSI midlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @unit: The zfcp LUN/unit to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * When the SCSI midlayer is not allowed to automatically scan and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * attach SCSI devices, zfcp has to register the single devices with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * the SCSI midlayer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct fc_rport *rport = unit->port->rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u64 lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) SCSI_SCAN_MANUAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void zfcp_unit_scsi_scan_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) scsi_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) zfcp_unit_scsi_scan(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) put_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * zfcp_unit_queue_scsi_scan - Register configured units on port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @port: The zfcp_port where to register units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * After opening a port, all units configured on this port have to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * registered with the SCSI midlayer. This function should be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * after calling fc_remote_port_add, so that the fc_rport is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * ONLINE and the call to scsi_scan_target runs the same way as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * call in the FC transport class.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void zfcp_unit_queue_scsi_scan(struct zfcp_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct zfcp_unit *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) read_lock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) list_for_each_entry(unit, &port->unit_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) get_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (scsi_queue_work(port->adapter->scsi_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) &unit->scsi_work) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) put_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) read_unlock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static struct zfcp_unit *_zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct zfcp_unit *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) list_for_each_entry(unit, &port->unit_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (unit->fcp_lun == fcp_lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) get_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * zfcp_unit_find - Find and return zfcp_unit with specified FCP LUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @port: zfcp_port where to look for the unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @fcp_lun: 64 Bit FCP LUN used to identify the zfcp_unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * If zfcp_unit is found, a reference is acquired that has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * released later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Returns: Pointer to the zfcp_unit, or NULL if there is no zfcp_unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * with the specified FCP LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct zfcp_unit *zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct zfcp_unit *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) read_lock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unit = _zfcp_unit_find(port, fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) read_unlock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * zfcp_unit_release - Drop reference to zfcp_port and free memory of zfcp_unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @dev: pointer to device in zfcp_unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void zfcp_unit_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) atomic_dec(&unit->port->units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) kfree(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * zfcp_unit_enqueue - enqueue unit to unit list of a port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @port: pointer to port where unit is added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @fcp_lun: FCP LUN of unit to be enqueued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Returns: 0 success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Sets up some unit internal structures and creates sysfs entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct zfcp_unit *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mutex_lock(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (zfcp_sysfs_port_is_removing(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* port is already gone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unit = zfcp_unit_find(port, fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (unit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) put_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) retval = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!unit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unit->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unit->fcp_lun = fcp_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unit->dev.parent = &port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unit->dev.release = zfcp_unit_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unit->dev.groups = zfcp_unit_attr_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (dev_set_name(&unit->dev, "0x%016llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) (unsigned long long) fcp_lun)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kfree(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (device_register(&unit->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) put_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) write_lock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) list_add_tail(&unit->list, &port->unit_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) write_unlock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * due to zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mutex_unlock(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) zfcp_unit_scsi_scan(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mutex_unlock(&zfcp_sysfs_port_units_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * zfcp_unit_sdev - Return SCSI device for zfcp_unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @unit: The zfcp_unit where to get the SCSI device for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Returns: scsi_device pointer on success, NULL if there is no SCSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * device for this zfcp_unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * On success, the caller also holds a reference to the SCSI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * that must be released with scsi_device_put.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct zfcp_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u64 lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) port = unit->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) shost = port->adapter->scsi_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return scsi_device_lookup(shost, 0, port->starget_id, lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * zfcp_unit_sdev_status - Return zfcp LUN status for SCSI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * @unit: The unit to lookup the SCSI device for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * Returns the zfcp LUN status field of the SCSI device if the SCSI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * for the zfcp_unit exists, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned int zfcp_unit_sdev_status(struct zfcp_unit *unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct zfcp_scsi_dev *zfcp_sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sdev = zfcp_unit_sdev(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) zfcp_sdev = sdev_to_zfcp(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) status = atomic_read(&zfcp_sdev->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * zfcp_unit_remove - Remove entry from list of configured units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @port: The port where to remove the unit from the configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @fcp_lun: The 64 bit LUN of the unit to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Returns: -EINVAL if a unit with the specified LUN does not exist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct zfcp_unit *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) write_lock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unit = _zfcp_unit_find(port, fcp_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) list_del(&unit->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) write_unlock_irq(&port->unit_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) sdev = zfcp_unit_sdev(unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) scsi_remove_device(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) put_device(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) device_unregister(&unit->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }