You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (84 commits) [SCSI] be2iscsi: SGE Len == 64K [SCSI] be2iscsi: Remove premature free of cid [SCSI] be2iscsi: More time for FW [SCSI] libsas: fix bug for vacant phy [SCSI] sd: Fix overflow with big physical blocks [SCSI] st: add MTWEOFI to write filemarks without flushing drive buffer [SCSI] libsas: Don't issue commands to devices that have been hot-removed [SCSI] megaraid_sas: Add Online Controller Reset to MegaRAID SAS drive [SCSI] lpfc 8.3.17: Update lpfc driver version to 8.3.17 [SCSI] lpfc 8.3.17: Replace function reset methodology [SCSI] lpfc 8.3.17: SCSI fixes [SCSI] lpfc 8.3.17: BSG fixes [SCSI] lpfc 8.3.17: SLI Additions and Fixes [SCSI] lpfc 8.3.17: Code Cleanup and Locking fixes [SCSI] zfcp: Remove scsi_cmnd->serial_number from debug traces [SCSI] ipr: fix array error logging [SCSI] aha152x: enable PCMCIA on 64bit [SCSI] scsi_dh_alua: Handle all states correctly [SCSI] cxgb4i: connection and ddp setting update [SCSI] cxgb3i: fixed connection over vlan ...
This commit is contained in:
@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
|
||||
The driver is currently maintained by Kai Mäkisara (email
|
||||
Kai.Makisara@kolumbus.fi)
|
||||
|
||||
Last modified: Sun Feb 24 21:59:07 2008 by kai.makisara
|
||||
Last modified: Sun Aug 29 18:25:47 2010 by kai.makisara
|
||||
|
||||
|
||||
BASICS
|
||||
@@ -85,6 +85,17 @@ writing and the last operation has been a write. Two filemarks can be
|
||||
optionally written. In both cases end of data is signified by
|
||||
returning zero bytes for two consecutive reads.
|
||||
|
||||
Writing filemarks without the immediate bit set in the SCSI command block acts
|
||||
as a synchronization point, i.e., all remaining data form the drive buffers is
|
||||
written to tape before the command returns. This makes sure that write errors
|
||||
are caught at that point, but this takes time. In some applications, several
|
||||
consecutive files must be written fast. The MTWEOFI operation can be used to
|
||||
write the filemarks without flushing the drive buffer. Writing filemark at
|
||||
close() is always flushing the drive buffers. However, if the previous
|
||||
operation is MTWEOFI, close() does not write a filemark. This can be used if
|
||||
the program wants to close/open the tape device between files and wants to
|
||||
skip waiting.
|
||||
|
||||
If rewind, offline, bsf, or seek is done and previous tape operation was
|
||||
write, a filemark is written before moving tape.
|
||||
|
||||
@@ -301,6 +312,8 @@ MTBSR Space backward over count records.
|
||||
MTFSS Space forward over count setmarks.
|
||||
MTBSS Space backward over count setmarks.
|
||||
MTWEOF Write count filemarks.
|
||||
MTWEOFI Write count filemarks with immediate bit set (i.e., does not
|
||||
wait until data is on tape)
|
||||
MTWSM Write count setmarks.
|
||||
MTREW Rewind tape.
|
||||
MTOFFL Set device off line (often rewind plus eject).
|
||||
|
||||
@@ -5945,8 +5945,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
|
||||
goto out;
|
||||
|
||||
mem = kmalloc(iocpage2sz, GFP_KERNEL);
|
||||
if (!mem)
|
||||
if (!mem) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(mem, (u8 *)pIoc2, iocpage2sz);
|
||||
ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# Makefile for the S/390 specific device drivers
|
||||
#
|
||||
|
||||
zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
|
||||
zfcp_fsf.o zfcp_dbf.o zfcp_sysfs.o zfcp_fc.o zfcp_cfdc.o
|
||||
zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \
|
||||
zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \
|
||||
zfcp_unit.o
|
||||
|
||||
obj-$(CONFIG_ZFCP) += zfcp.o
|
||||
|
||||
@@ -56,7 +56,6 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
|
||||
struct ccw_device *cdev;
|
||||
struct zfcp_adapter *adapter;
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_unit *unit;
|
||||
|
||||
cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
|
||||
if (!cdev)
|
||||
@@ -72,17 +71,11 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
|
||||
port = zfcp_get_port_by_wwpn(adapter, wwpn);
|
||||
if (!port)
|
||||
goto out_port;
|
||||
flush_work(&port->rport_work);
|
||||
|
||||
unit = zfcp_unit_enqueue(port, lun);
|
||||
if (IS_ERR(unit))
|
||||
goto out_unit;
|
||||
|
||||
zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
flush_work(&unit->scsi_work);
|
||||
|
||||
out_unit:
|
||||
zfcp_unit_add(port, lun);
|
||||
put_device(&port->dev);
|
||||
|
||||
out_port:
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
out_ccw_device:
|
||||
@@ -158,6 +151,9 @@ static int __init zfcp_module_init(void)
|
||||
fc_attach_transport(&zfcp_transport_functions);
|
||||
if (!zfcp_data.scsi_transport_template)
|
||||
goto out_transport;
|
||||
scsi_transport_reserve_device(zfcp_data.scsi_transport_template,
|
||||
sizeof(struct zfcp_scsi_dev));
|
||||
|
||||
|
||||
retval = misc_register(&zfcp_cfdc_misc);
|
||||
if (retval) {
|
||||
@@ -210,30 +206,6 @@ static void __exit zfcp_module_exit(void)
|
||||
|
||||
module_exit(zfcp_module_exit);
|
||||
|
||||
/**
|
||||
* zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN
|
||||
* @port: pointer to port to search for unit
|
||||
* @fcp_lun: FCP LUN to search for
|
||||
*
|
||||
* Returns: pointer to zfcp_unit or NULL
|
||||
*/
|
||||
struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct zfcp_unit *unit;
|
||||
|
||||
read_lock_irqsave(&port->unit_list_lock, flags);
|
||||
list_for_each_entry(unit, &port->unit_list, list)
|
||||
if (unit->fcp_lun == fcp_lun) {
|
||||
if (!get_device(&unit->dev))
|
||||
unit = NULL;
|
||||
read_unlock_irqrestore(&port->unit_list_lock, flags);
|
||||
return unit;
|
||||
}
|
||||
read_unlock_irqrestore(&port->unit_list_lock, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_get_port_by_wwpn - find port in port list of adapter by wwpn
|
||||
* @adapter: pointer to adapter to search for port
|
||||
@@ -259,92 +231,6 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_unit_release - dequeue unit
|
||||
* @dev: pointer to device
|
||||
*
|
||||
* waits until all work is done on unit and removes it then from the unit->list
|
||||
* of the associated port.
|
||||
*/
|
||||
static void zfcp_unit_release(struct device *dev)
|
||||
{
|
||||
struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
|
||||
|
||||
put_device(&unit->port->dev);
|
||||
kfree(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_unit_enqueue - enqueue unit to unit list of a port.
|
||||
* @port: pointer to port where unit is added
|
||||
* @fcp_lun: FCP LUN of unit to be enqueued
|
||||
* Returns: pointer to enqueued unit on success, ERR_PTR on error
|
||||
*
|
||||
* Sets up some unit internal structures and creates sysfs entry.
|
||||
*/
|
||||
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
int retval = -ENOMEM;
|
||||
|
||||
get_device(&port->dev);
|
||||
|
||||
unit = zfcp_get_unit_by_lun(port, fcp_lun);
|
||||
if (unit) {
|
||||
put_device(&unit->dev);
|
||||
retval = -EEXIST;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
|
||||
if (!unit)
|
||||
goto err_out;
|
||||
|
||||
unit->port = port;
|
||||
unit->fcp_lun = fcp_lun;
|
||||
unit->dev.parent = &port->dev;
|
||||
unit->dev.release = zfcp_unit_release;
|
||||
|
||||
if (dev_set_name(&unit->dev, "0x%016llx",
|
||||
(unsigned long long) fcp_lun)) {
|
||||
kfree(unit);
|
||||
goto err_out;
|
||||
}
|
||||
retval = -EINVAL;
|
||||
|
||||
INIT_WORK(&unit->scsi_work, zfcp_scsi_scan_work);
|
||||
|
||||
spin_lock_init(&unit->latencies.lock);
|
||||
unit->latencies.write.channel.min = 0xFFFFFFFF;
|
||||
unit->latencies.write.fabric.min = 0xFFFFFFFF;
|
||||
unit->latencies.read.channel.min = 0xFFFFFFFF;
|
||||
unit->latencies.read.fabric.min = 0xFFFFFFFF;
|
||||
unit->latencies.cmd.channel.min = 0xFFFFFFFF;
|
||||
unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
|
||||
|
||||
if (device_register(&unit->dev)) {
|
||||
put_device(&unit->dev);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs))
|
||||
goto err_out_put;
|
||||
|
||||
write_lock_irq(&port->unit_list_lock);
|
||||
list_add_tail(&unit->list, &port->unit_list);
|
||||
write_unlock_irq(&port->unit_list_lock);
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
|
||||
|
||||
return unit;
|
||||
|
||||
err_out_put:
|
||||
device_unregister(&unit->dev);
|
||||
err_out:
|
||||
put_device(&port->dev);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
|
||||
static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
|
||||
{
|
||||
adapter->pool.erp_req =
|
||||
|
||||
@@ -46,8 +46,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
|
||||
if (!adapter)
|
||||
return 0;
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"ccresu2", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
@@ -164,14 +163,7 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
|
||||
BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
|
||||
adapter->req_no = 0;
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"ccsonl2", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
|
||||
flush_work(&adapter->scan_work);
|
||||
|
||||
zfcp_ccw_activate(cdev);
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
return 0;
|
||||
}
|
||||
@@ -224,9 +216,8 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
|
||||
break;
|
||||
case CIO_OPER:
|
||||
dev_info(&cdev->dev, "The FCP device is operational again\n");
|
||||
zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_set_adapter_status(adapter,
|
||||
ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"ccnoti4", NULL);
|
||||
break;
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
* zfcp device driver
|
||||
*
|
||||
* Userspace interface for accessing the
|
||||
* Access Control Lists / Control File Data Channel
|
||||
* Access Control Lists / Control File Data Channel;
|
||||
* handling of response code and states for ports and LUNs.
|
||||
*
|
||||
* Copyright IBM Corporation 2008, 2009
|
||||
* Copyright IBM Corporation 2008, 2010
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
@@ -261,3 +262,184 @@ struct miscdevice zfcp_cfdc_misc = {
|
||||
.name = "zfcp_cfdc",
|
||||
.fops = &zfcp_cfdc_fops,
|
||||
};
|
||||
|
||||
/**
|
||||
* zfcp_cfdc_adapter_access_changed - Process change in adapter ACT
|
||||
* @adapter: Adapter where the Access Control Table (ACT) changed
|
||||
*
|
||||
* After a change in the adapter ACT, check if access to any
|
||||
* previously denied resources is now possible.
|
||||
*/
|
||||
void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct zfcp_port *port;
|
||||
struct scsi_device *sdev;
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
int status;
|
||||
|
||||
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
|
||||
return;
|
||||
|
||||
read_lock_irqsave(&adapter->port_list_lock, flags);
|
||||
list_for_each_entry(port, &adapter->port_list, list) {
|
||||
status = atomic_read(&port->status);
|
||||
if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
|
||||
(status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
|
||||
zfcp_erp_port_reopen(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"cfaac_1", NULL);
|
||||
}
|
||||
read_unlock_irqrestore(&adapter->port_list_lock, flags);
|
||||
|
||||
shost_for_each_device(sdev, port->adapter->scsi_host) {
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
status = atomic_read(&zfcp_sdev->status);
|
||||
if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
|
||||
(status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
|
||||
zfcp_erp_lun_reopen(sdev,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"cfaac_2", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
|
||||
{
|
||||
u16 subtable = table >> 16;
|
||||
u16 rule = table & 0xffff;
|
||||
const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };
|
||||
|
||||
if (subtable && subtable < ARRAY_SIZE(act_type))
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"Access denied according to ACT rule type %s, "
|
||||
"rule %d\n", act_type[subtable], rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_cfdc_port_denied - Process "access denied" for port
|
||||
* @port: The port where the acces has been denied
|
||||
* @qual: The FSF status qualifier for the access denied FSF status
|
||||
*/
|
||||
void zfcp_cfdc_port_denied(struct zfcp_port *port,
|
||||
union fsf_status_qual *qual)
|
||||
{
|
||||
dev_warn(&port->adapter->ccw_device->dev,
|
||||
"Access denied to port 0x%016Lx\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
|
||||
zfcp_act_eval_err(port->adapter, qual->halfword[0]);
|
||||
zfcp_act_eval_err(port->adapter, qual->halfword[1]);
|
||||
zfcp_erp_set_port_status(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_cfdc_lun_denied - Process "access denied" for LUN
|
||||
* @sdev: The SCSI device / LUN where the access has been denied
|
||||
* @qual: The FSF status qualifier for the access denied FSF status
|
||||
*/
|
||||
void zfcp_cfdc_lun_denied(struct scsi_device *sdev,
|
||||
union fsf_status_qual *qual)
|
||||
{
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
|
||||
"Access denied to LUN 0x%016Lx on port 0x%016Lx\n",
|
||||
zfcp_scsi_dev_lun(sdev),
|
||||
(unsigned long long)zfcp_sdev->port->wwpn);
|
||||
zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
|
||||
zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
|
||||
zfcp_erp_set_lun_status(sdev,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED);
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
|
||||
atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status
|
||||
* @sdev: The LUN / SCSI device where sharing violation occurred
|
||||
* @qual: The FSF status qualifier from the LUN sharing violation
|
||||
*/
|
||||
void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev,
|
||||
union fsf_status_qual *qual)
|
||||
{
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
if (qual->word[0])
|
||||
dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
|
||||
"LUN 0x%Lx on port 0x%Lx is already in "
|
||||
"use by CSS%d, MIF Image ID %x\n",
|
||||
zfcp_scsi_dev_lun(sdev),
|
||||
(unsigned long long)zfcp_sdev->port->wwpn,
|
||||
qual->fsf_queue_designator.cssid,
|
||||
qual->fsf_queue_designator.hla);
|
||||
else
|
||||
zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);
|
||||
|
||||
zfcp_erp_set_lun_status(sdev,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED);
|
||||
atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
|
||||
atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun"
|
||||
* @sdev: The SCSI device / LUN where to evaluate the status
|
||||
* @bottom: The qtcb bottom with the status from the "open lun"
|
||||
*
|
||||
* Returns: 0 if LUN is usable, -EACCES if the access control table
|
||||
* reports an unsupported configuration.
|
||||
*/
|
||||
int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
|
||||
struct fsf_qtcb_bottom_support *bottom)
|
||||
{
|
||||
int shared, rw;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
|
||||
|
||||
if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) ||
|
||||
!(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) ||
|
||||
zfcp_ccw_priv_sch(adapter))
|
||||
return 0;
|
||||
|
||||
shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE);
|
||||
rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);
|
||||
|
||||
if (shared)
|
||||
atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
|
||||
|
||||
if (!rw) {
|
||||
atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
|
||||
dev_info(&adapter->ccw_device->dev, "SCSI device at LUN "
|
||||
"0x%016Lx on port 0x%016Lx opened read-only\n",
|
||||
zfcp_scsi_dev_lun(sdev),
|
||||
(unsigned long long)zfcp_sdev->port->wwpn);
|
||||
}
|
||||
|
||||
if (!shared && !rw) {
|
||||
dev_err(&adapter->ccw_device->dev, "Exclusive read-only access "
|
||||
"not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
|
||||
zfcp_scsi_dev_lun(sdev),
|
||||
(unsigned long long)zfcp_sdev->port->wwpn);
|
||||
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (shared && rw) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Shared read-write access not supported "
|
||||
"(LUN 0x%016Lx, port 0x%016Lx)\n",
|
||||
zfcp_scsi_dev_lun(sdev),
|
||||
(unsigned long long)zfcp_sdev->port->wwpn);
|
||||
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,6 @@ void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
|
||||
scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
|
||||
if (scsi_cmnd) {
|
||||
response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
|
||||
response->u.fcp.serial = scsi_cmnd->serial_number;
|
||||
response->u.fcp.data_dir =
|
||||
qtcb->bottom.io.data_direction;
|
||||
}
|
||||
@@ -330,7 +329,6 @@ static void zfcp_dbf_hba_view_response(char **p,
|
||||
break;
|
||||
zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir);
|
||||
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
|
||||
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
|
||||
*p += sprintf(*p, "\n");
|
||||
break;
|
||||
|
||||
@@ -482,7 +480,7 @@ static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view,
|
||||
zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
|
||||
zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
|
||||
zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
|
||||
zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us);
|
||||
zfcp_dbf_out(&p, "lun_status", "0x%08x", r->u.trigger.ls);
|
||||
break;
|
||||
case ZFCP_REC_DBF_ID_ACTION:
|
||||
zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
|
||||
@@ -600,19 +598,20 @@ void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port)
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_dbf_rec_unit - trace event for unit state change
|
||||
* zfcp_dbf_rec_lun - trace event for LUN state change
|
||||
* @id: identifier for trigger of state change
|
||||
* @ref: additional reference (e.g. request)
|
||||
* @unit: unit
|
||||
* @sdev: SCSI device
|
||||
*/
|
||||
void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit)
|
||||
void zfcp_dbf_rec_lun(char *id, void *ref, struct scsi_device *sdev)
|
||||
{
|
||||
struct zfcp_port *port = unit->port;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_port *port = zfcp_sdev->port;
|
||||
struct zfcp_dbf *dbf = port->adapter->dbf;
|
||||
|
||||
zfcp_dbf_rec_target(id, ref, dbf, &unit->status,
|
||||
&unit->erp_counter, port->wwpn, port->d_id,
|
||||
unit->fcp_lun);
|
||||
zfcp_dbf_rec_target(id, ref, dbf, &zfcp_sdev->status,
|
||||
&zfcp_sdev->erp_counter, port->wwpn, port->d_id,
|
||||
zfcp_scsi_dev_lun(sdev));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -624,11 +623,11 @@ void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit)
|
||||
* @action: address of error recovery action struct
|
||||
* @adapter: adapter
|
||||
* @port: port
|
||||
* @unit: unit
|
||||
* @sdev: SCSI device
|
||||
*/
|
||||
void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
|
||||
struct zfcp_adapter *adapter, struct zfcp_port *port,
|
||||
struct zfcp_unit *unit)
|
||||
struct scsi_device *sdev)
|
||||
{
|
||||
struct zfcp_dbf *dbf = adapter->dbf;
|
||||
struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
|
||||
@@ -647,9 +646,10 @@ void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
|
||||
r->u.trigger.ps = atomic_read(&port->status);
|
||||
r->u.trigger.wwpn = port->wwpn;
|
||||
}
|
||||
if (unit)
|
||||
r->u.trigger.us = atomic_read(&unit->status);
|
||||
r->u.trigger.fcp_lun = unit ? unit->fcp_lun : ZFCP_DBF_INVALID_LUN;
|
||||
if (sdev)
|
||||
r->u.trigger.ls = atomic_read(&sdev_to_zfcp(sdev)->status);
|
||||
r->u.trigger.fcp_lun = sdev ? zfcp_scsi_dev_lun(sdev) :
|
||||
ZFCP_DBF_INVALID_LUN;
|
||||
debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
|
||||
spin_unlock_irqrestore(&dbf->rec_lock, flags);
|
||||
}
|
||||
@@ -879,7 +879,6 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
|
||||
}
|
||||
rec->scsi_result = scsi_cmnd->result;
|
||||
rec->scsi_cmnd = (unsigned long)scsi_cmnd;
|
||||
rec->scsi_serial = scsi_cmnd->serial_number;
|
||||
memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
|
||||
min((int)scsi_cmnd->cmd_len,
|
||||
ZFCP_DBF_SCSI_OPCODE));
|
||||
@@ -948,7 +947,6 @@ static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view,
|
||||
zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun);
|
||||
zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result);
|
||||
zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd);
|
||||
zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial);
|
||||
zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE,
|
||||
0, ZFCP_DBF_SCSI_OPCODE);
|
||||
zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries);
|
||||
|
||||
@@ -60,7 +60,7 @@ struct zfcp_dbf_rec_record_trigger {
|
||||
u8 need;
|
||||
u32 as;
|
||||
u32 ps;
|
||||
u32 us;
|
||||
u32 ls;
|
||||
u64 ref;
|
||||
u64 action;
|
||||
u64 wwpn;
|
||||
@@ -110,7 +110,6 @@ struct zfcp_dbf_hba_record_response {
|
||||
union {
|
||||
struct {
|
||||
u64 cmnd;
|
||||
u64 serial;
|
||||
u32 data_dir;
|
||||
} fcp;
|
||||
struct {
|
||||
@@ -206,7 +205,6 @@ struct zfcp_dbf_scsi_record {
|
||||
u32 scsi_lun;
|
||||
u32 scsi_result;
|
||||
u64 scsi_cmnd;
|
||||
u64 scsi_serial;
|
||||
#define ZFCP_DBF_SCSI_OPCODE 16
|
||||
u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
|
||||
u8 scsi_retries;
|
||||
@@ -350,16 +348,16 @@ void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
|
||||
/**
|
||||
* zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset
|
||||
* @tag: tag indicating success or failure of reset operation
|
||||
* @scmnd: SCSI command which caused this error recovery
|
||||
* @flag: indicates type of reset (Target Reset, Logical Unit Reset)
|
||||
* @unit: unit that needs reset
|
||||
* @scsi_cmnd: SCSI command which caused this error recovery
|
||||
*/
|
||||
static inline
|
||||
void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
|
||||
struct scsi_cmnd *scsi_cmnd)
|
||||
void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag)
|
||||
{
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
|
||||
|
||||
zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
|
||||
unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
|
||||
zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0);
|
||||
}
|
||||
|
||||
#endif /* ZFCP_DBF_H */
|
||||
|
||||
@@ -85,8 +85,8 @@ struct zfcp_reqlist;
|
||||
#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002
|
||||
|
||||
/* logical unit status */
|
||||
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
|
||||
#define ZFCP_STATUS_UNIT_READONLY 0x00000008
|
||||
#define ZFCP_STATUS_LUN_SHARED 0x00000004
|
||||
#define ZFCP_STATUS_LUN_READONLY 0x00000008
|
||||
|
||||
/* FSF request status (this does not have a common part) */
|
||||
#define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002
|
||||
@@ -118,7 +118,7 @@ struct zfcp_erp_action {
|
||||
int action; /* requested action code */
|
||||
struct zfcp_adapter *adapter; /* device which should be recovered */
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_unit *unit;
|
||||
struct scsi_device *sdev;
|
||||
u32 status; /* recovery status */
|
||||
u32 step; /* active step of this erp action */
|
||||
unsigned long fsf_req_id;
|
||||
@@ -219,20 +219,65 @@ struct zfcp_port {
|
||||
unsigned int starget_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct zfcp_unit - LUN configured via zfcp sysfs
|
||||
* @dev: struct device for sysfs representation and reference counting
|
||||
* @list: entry in LUN/unit list per zfcp_port
|
||||
* @port: reference to zfcp_port where this LUN is configured
|
||||
* @fcp_lun: 64 bit LUN value
|
||||
* @scsi_work: for running scsi_scan_target
|
||||
*
|
||||
* This is the representation of a LUN that has been configured for
|
||||
* usage. The main data here is the 64 bit LUN value, data for
|
||||
* running I/O and recovery is in struct zfcp_scsi_dev.
|
||||
*/
|
||||
struct zfcp_unit {
|
||||
struct device dev;
|
||||
struct list_head list; /* list of logical units */
|
||||
struct zfcp_port *port; /* remote port of unit */
|
||||
atomic_t status; /* status of this logical unit */
|
||||
u64 fcp_lun; /* own FCP_LUN */
|
||||
u32 handle; /* handle assigned by FSF */
|
||||
struct scsi_device *device; /* scsi device struct pointer */
|
||||
struct zfcp_erp_action erp_action; /* pending error recovery */
|
||||
atomic_t erp_counter;
|
||||
struct zfcp_latencies latencies;
|
||||
struct device dev;
|
||||
struct list_head list;
|
||||
struct zfcp_port *port;
|
||||
u64 fcp_lun;
|
||||
struct work_struct scsi_work;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct zfcp_scsi_dev - zfcp data per SCSI device
|
||||
* @status: zfcp internal status flags
|
||||
* @lun_handle: handle from "open lun" for issuing FSF requests
|
||||
* @erp_action: zfcp erp data for opening and recovering this LUN
|
||||
* @erp_counter: zfcp erp counter for this LUN
|
||||
* @latencies: FSF channel and fabric latencies
|
||||
* @port: zfcp_port where this LUN belongs to
|
||||
*/
|
||||
struct zfcp_scsi_dev {
|
||||
atomic_t status;
|
||||
u32 lun_handle;
|
||||
struct zfcp_erp_action erp_action;
|
||||
atomic_t erp_counter;
|
||||
struct zfcp_latencies latencies;
|
||||
struct zfcp_port *port;
|
||||
};
|
||||
|
||||
/**
|
||||
* sdev_to_zfcp - Access zfcp LUN data for SCSI device
|
||||
* @sdev: scsi_device where to get the zfcp_scsi_dev pointer
|
||||
*/
|
||||
static inline struct zfcp_scsi_dev *sdev_to_zfcp(struct scsi_device *sdev)
|
||||
{
|
||||
return scsi_transport_device_data(sdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_scsi_dev_lun - Return SCSI device LUN as 64 bit FCP LUN
|
||||
* @sdev: SCSI device where to get the LUN from
|
||||
*/
|
||||
static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev)
|
||||
{
|
||||
u64 fcp_lun;
|
||||
|
||||
int_to_scsilun(sdev->lun, (struct scsi_lun *)&fcp_lun);
|
||||
return fcp_lun;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct zfcp_fsf_req - basic FSF request structure
|
||||
* @list: list of FSF requests
|
||||
@@ -249,7 +294,6 @@ struct zfcp_unit {
|
||||
* @erp_action: reference to erp action if request issued on behalf of ERP
|
||||
* @pool: reference to memory pool if used for this request
|
||||
* @issued: time when request was send (STCK)
|
||||
* @unit: reference to unit if this request is a SCSI request
|
||||
* @handler: handler which should be called to process response
|
||||
*/
|
||||
struct zfcp_fsf_req {
|
||||
@@ -267,7 +311,6 @@ struct zfcp_fsf_req {
|
||||
struct zfcp_erp_action *erp_action;
|
||||
mempool_t *pool;
|
||||
unsigned long long issued;
|
||||
struct zfcp_unit *unit;
|
||||
void (*handler)(struct zfcp_fsf_req *);
|
||||
};
|
||||
|
||||
@@ -282,9 +325,4 @@ struct zfcp_data {
|
||||
struct kmem_cache *adisc_cache;
|
||||
};
|
||||
|
||||
/********************** ZFCP SPECIFIC DEFINES ********************************/
|
||||
|
||||
#define ZFCP_SET 0x00000100
|
||||
#define ZFCP_CLEAR 0x00000200
|
||||
|
||||
#endif /* ZFCP_DEF_H */
|
||||
|
||||
+325
-382
File diff suppressed because it is too large
Load Diff
@@ -15,12 +15,10 @@
|
||||
#include "zfcp_fc.h"
|
||||
|
||||
/* zfcp_aux.c */
|
||||
extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
|
||||
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
|
||||
extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
|
||||
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
|
||||
u32);
|
||||
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
|
||||
extern void zfcp_sg_free_table(struct scatterlist *, int);
|
||||
extern int zfcp_sg_setup_table(struct scatterlist *, int);
|
||||
extern void zfcp_device_unregister(struct device *,
|
||||
@@ -36,6 +34,14 @@ extern void zfcp_ccw_adapter_put(struct zfcp_adapter *);
|
||||
|
||||
/* zfcp_cfdc.c */
|
||||
extern struct miscdevice zfcp_cfdc_misc;
|
||||
extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *);
|
||||
extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *);
|
||||
extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *,
|
||||
union fsf_status_qual *);
|
||||
extern int zfcp_cfdc_open_lun_eval(struct scsi_device *,
|
||||
struct fsf_qtcb_bottom_support *);
|
||||
extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *);
|
||||
|
||||
|
||||
/* zfcp_dbf.c */
|
||||
extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
|
||||
@@ -44,10 +50,10 @@ extern void zfcp_dbf_rec_thread(char *, struct zfcp_dbf *);
|
||||
extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *);
|
||||
extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *);
|
||||
extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *);
|
||||
extern void zfcp_dbf_rec_unit(char *, void *, struct zfcp_unit *);
|
||||
extern void zfcp_dbf_rec_lun(char *, void *, struct scsi_device *);
|
||||
extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *,
|
||||
struct zfcp_adapter *, struct zfcp_port *,
|
||||
struct zfcp_unit *);
|
||||
struct scsi_device *);
|
||||
extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *);
|
||||
extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *,
|
||||
struct zfcp_dbf *);
|
||||
@@ -65,34 +71,26 @@ extern void _zfcp_dbf_scsi(const char *, const char *, int, struct zfcp_dbf *,
|
||||
unsigned long);
|
||||
|
||||
/* zfcp_erp.c */
|
||||
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
|
||||
void *, u32, int);
|
||||
extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
|
||||
extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
|
||||
extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
|
||||
extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, char *, void *);
|
||||
extern void zfcp_erp_modify_port_status(struct zfcp_port *, char *, void *, u32,
|
||||
int);
|
||||
extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
|
||||
extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
|
||||
extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
|
||||
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
|
||||
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32,
|
||||
int);
|
||||
extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
|
||||
extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
|
||||
extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
|
||||
extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
|
||||
extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
|
||||
extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *);
|
||||
extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *);
|
||||
extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *);
|
||||
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_wait(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
|
||||
extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_unit_boxed(struct zfcp_unit *, char *, void *);
|
||||
extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
|
||||
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_timeout_handler(unsigned long);
|
||||
|
||||
/* zfcp_fc.c */
|
||||
@@ -118,8 +116,8 @@ extern int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *);
|
||||
extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *);
|
||||
extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_open_lun(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_close_lun(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *,
|
||||
struct fsf_qtcb_bottom_config *);
|
||||
@@ -135,12 +133,10 @@ extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
|
||||
mempool_t *, unsigned int);
|
||||
extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
|
||||
struct zfcp_fsf_ct_els *, unsigned int);
|
||||
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
|
||||
struct scsi_cmnd *);
|
||||
extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
|
||||
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
|
||||
struct zfcp_unit *);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *);
|
||||
extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
|
||||
|
||||
/* zfcp_qdio.c */
|
||||
@@ -163,8 +159,6 @@ extern void zfcp_scsi_rport_work(struct work_struct *);
|
||||
extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
|
||||
extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
|
||||
extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
|
||||
extern void zfcp_scsi_scan(struct zfcp_unit *);
|
||||
extern void zfcp_scsi_scan_work(struct work_struct *);
|
||||
extern void zfcp_scsi_set_prot(struct zfcp_adapter *);
|
||||
extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
|
||||
|
||||
@@ -175,4 +169,13 @@ extern struct attribute_group zfcp_sysfs_port_attrs;
|
||||
extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
|
||||
extern struct device_attribute *zfcp_sysfs_shost_attrs[];
|
||||
|
||||
/* zfcp_unit.c */
|
||||
extern int zfcp_unit_add(struct zfcp_port *, u64);
|
||||
extern int zfcp_unit_remove(struct zfcp_port *, u64);
|
||||
extern struct zfcp_unit *zfcp_unit_find(struct zfcp_port *, u64);
|
||||
extern struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit);
|
||||
extern void zfcp_unit_scsi_scan(struct zfcp_unit *);
|
||||
extern void zfcp_unit_queue_scsi_scan(struct zfcp_port *);
|
||||
extern unsigned int zfcp_unit_sdev_status(struct zfcp_unit *);
|
||||
|
||||
#endif /* ZFCP_EXT_H */
|
||||
|
||||
@@ -365,7 +365,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (!port->d_id) {
|
||||
zfcp_erp_port_failed(port, "fcgpn_2", NULL);
|
||||
zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
+263
-346
File diff suppressed because it is too large
Load Diff
@@ -60,13 +60,11 @@ static inline void zfcp_qdio_account(struct zfcp_qdio *qdio)
|
||||
unsigned long long now, span;
|
||||
int used;
|
||||
|
||||
spin_lock(&qdio->stat_lock);
|
||||
now = get_clock_monotonic();
|
||||
span = (now - qdio->req_q_time) >> 12;
|
||||
used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free);
|
||||
qdio->req_q_util += used * span;
|
||||
qdio->req_q_time = now;
|
||||
spin_unlock(&qdio->stat_lock);
|
||||
}
|
||||
|
||||
static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
|
||||
@@ -84,7 +82,9 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
|
||||
/* cleanup all SBALs being program-owned now */
|
||||
zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
|
||||
|
||||
spin_lock_irq(&qdio->stat_lock);
|
||||
zfcp_qdio_account(qdio);
|
||||
spin_unlock_irq(&qdio->stat_lock);
|
||||
atomic_add(count, &qdio->req_q_free);
|
||||
wake_up(&qdio->req_q_wq);
|
||||
}
|
||||
@@ -201,11 +201,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
|
||||
|
||||
static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
|
||||
{
|
||||
spin_lock_bh(&qdio->req_q_lock);
|
||||
spin_lock_irq(&qdio->req_q_lock);
|
||||
if (atomic_read(&qdio->req_q_free) ||
|
||||
!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
|
||||
return 1;
|
||||
spin_unlock_bh(&qdio->req_q_lock);
|
||||
spin_unlock_irq(&qdio->req_q_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
|
||||
{
|
||||
long ret;
|
||||
|
||||
spin_unlock_bh(&qdio->req_q_lock);
|
||||
spin_unlock_irq(&qdio->req_q_lock);
|
||||
ret = wait_event_interruptible_timeout(qdio->req_q_wq,
|
||||
zfcp_qdio_sbal_check(qdio), 5 * HZ);
|
||||
|
||||
@@ -239,7 +239,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
|
||||
zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL);
|
||||
}
|
||||
|
||||
spin_lock_bh(&qdio->req_q_lock);
|
||||
spin_lock_irq(&qdio->req_q_lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
|
||||
int retval;
|
||||
u8 sbal_number = q_req->sbal_number;
|
||||
|
||||
spin_lock(&qdio->stat_lock);
|
||||
zfcp_qdio_account(qdio);
|
||||
spin_unlock(&qdio->stat_lock);
|
||||
|
||||
retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
|
||||
q_req->sbal_first, sbal_number);
|
||||
@@ -328,9 +330,9 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
|
||||
return;
|
||||
|
||||
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
|
||||
spin_lock_bh(&qdio->req_q_lock);
|
||||
spin_lock_irq(&qdio->req_q_lock);
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
|
||||
spin_unlock_bh(&qdio->req_q_lock);
|
||||
spin_unlock_irq(&qdio->req_q_lock);
|
||||
|
||||
wake_up(&qdio->req_q_wq);
|
||||
|
||||
|
||||
+56
-104
@@ -49,11 +49,12 @@ static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
|
||||
return sdev->queue_depth;
|
||||
}
|
||||
|
||||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
||||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdev)
|
||||
{
|
||||
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
|
||||
unit->device = NULL;
|
||||
put_device(&unit->dev);
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
zfcp_erp_lun_shutdown_wait(sdev, "scssd_1");
|
||||
put_device(&zfcp_sdev->port->dev);
|
||||
}
|
||||
|
||||
static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
|
||||
@@ -78,23 +79,16 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
|
||||
static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
||||
void (*done) (struct scsi_cmnd *))
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
struct zfcp_adapter *adapter;
|
||||
int status, scsi_result, ret;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
|
||||
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
|
||||
int status, scsi_result, ret;
|
||||
|
||||
/* reset the status for this request */
|
||||
scpnt->result = 0;
|
||||
scpnt->host_scribble = NULL;
|
||||
scpnt->scsi_done = done;
|
||||
|
||||
/*
|
||||
* figure out adapter and target device
|
||||
* (stored there by zfcp_scsi_slave_alloc)
|
||||
*/
|
||||
adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
|
||||
unit = scpnt->device->hostdata;
|
||||
|
||||
scsi_result = fc_remote_port_chkready(rport);
|
||||
if (unlikely(scsi_result)) {
|
||||
scpnt->result = scsi_result;
|
||||
@@ -103,11 +97,11 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = atomic_read(&unit->status);
|
||||
status = atomic_read(&zfcp_sdev->status);
|
||||
if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) &&
|
||||
!(atomic_read(&unit->port->status) &
|
||||
!(atomic_read(&zfcp_sdev->port->status) &
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED)) {
|
||||
/* only unit access denied, but port is good
|
||||
/* only LUN access denied, but port is good
|
||||
* not covered by FC transport, have to fail here */
|
||||
zfcp_scsi_command_fail(scpnt, DID_ERROR);
|
||||
return 0;
|
||||
@@ -115,8 +109,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
||||
|
||||
if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
|
||||
/* This could be either
|
||||
* open unit pending: this is temporary, will result in
|
||||
* open unit or ERP_FAILED, so retry command
|
||||
* open LUN pending: this is temporary, will result in
|
||||
* open LUN or ERP_FAILED, so retry command
|
||||
* call to rport_delete pending: mimic retry from
|
||||
* fc_remote_port_chkready until rport is BLOCKED
|
||||
*/
|
||||
@@ -124,7 +118,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
|
||||
ret = zfcp_fsf_fcp_cmnd(scpnt);
|
||||
if (unlikely(ret == -EBUSY))
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
else if (unlikely(ret < 0))
|
||||
@@ -133,45 +127,42 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
|
||||
unsigned int id, u64 lun)
|
||||
static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
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 = NULL;
|
||||
|
||||
read_lock_irqsave(&adapter->port_list_lock, flags);
|
||||
list_for_each_entry(port, &adapter->port_list, list) {
|
||||
if (!port->rport || (id != port->rport->scsi_target_id))
|
||||
continue;
|
||||
unit = zfcp_get_unit_by_lun(port, lun);
|
||||
if (unit)
|
||||
break;
|
||||
}
|
||||
read_unlock_irqrestore(&adapter->port_list_lock, flags);
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
|
||||
{
|
||||
struct zfcp_adapter *adapter;
|
||||
struct zfcp_unit *unit;
|
||||
u64 lun;
|
||||
|
||||
adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
|
||||
if (!adapter)
|
||||
goto out;
|
||||
port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
|
||||
if (!port)
|
||||
return -ENXIO;
|
||||
|
||||
int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun);
|
||||
unit = zfcp_unit_lookup(adapter, sdp->id, lun);
|
||||
if (unit) {
|
||||
sdp->hostdata = unit;
|
||||
unit->device = sdp;
|
||||
return 0;
|
||||
unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
|
||||
if (unit)
|
||||
put_device(&unit->dev);
|
||||
|
||||
if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
|
||||
put_device(&port->dev);
|
||||
return -ENXIO;
|
||||
}
|
||||
out:
|
||||
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", NULL);
|
||||
zfcp_erp_wait(port->adapter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
@@ -179,7 +170,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
struct Scsi_Host *scsi_host = scpnt->device->host;
|
||||
struct zfcp_adapter *adapter =
|
||||
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_fsf_req *old_req, *abrt_req;
|
||||
unsigned long flags;
|
||||
unsigned long old_reqid = (unsigned long) scpnt->host_scribble;
|
||||
@@ -203,7 +193,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
write_unlock_irqrestore(&adapter->abort_lock, flags);
|
||||
|
||||
while (retry--) {
|
||||
abrt_req = zfcp_fsf_abort_fcp_command(old_reqid, unit);
|
||||
abrt_req = zfcp_fsf_abort_fcp_cmnd(scpnt);
|
||||
if (abrt_req)
|
||||
break;
|
||||
|
||||
@@ -238,14 +228,14 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
|
||||
static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
{
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
|
||||
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
|
||||
struct zfcp_fsf_req *fsf_req = NULL;
|
||||
int retval = SUCCESS, ret;
|
||||
int retry = 3;
|
||||
|
||||
while (retry--) {
|
||||
fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags);
|
||||
fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags);
|
||||
if (fsf_req)
|
||||
break;
|
||||
|
||||
@@ -256,7 +246,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
|
||||
if (!(atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_COMMON_RUNNING)) {
|
||||
zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt);
|
||||
zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -266,10 +256,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
wait_for_completion(&fsf_req->completion);
|
||||
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
|
||||
zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt);
|
||||
zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
|
||||
retval = FAILED;
|
||||
} else
|
||||
zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt);
|
||||
zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
|
||||
|
||||
zfcp_fsf_req_free(fsf_req);
|
||||
return retval;
|
||||
@@ -287,8 +277,8 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
|
||||
|
||||
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
|
||||
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
|
||||
int ret;
|
||||
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
|
||||
@@ -319,8 +309,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
||||
}
|
||||
|
||||
/* tell the SCSI stack some characteristics of this adapter */
|
||||
adapter->scsi_host->max_id = 1;
|
||||
adapter->scsi_host->max_lun = 1;
|
||||
adapter->scsi_host->max_id = 511;
|
||||
adapter->scsi_host->max_lun = 0xFFFFFFFF;
|
||||
adapter->scsi_host->max_channel = 0;
|
||||
adapter->scsi_host->unique_id = dev_id.devno;
|
||||
adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
|
||||
@@ -534,20 +524,6 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
|
||||
}
|
||||
}
|
||||
|
||||
static void zfcp_scsi_queue_unit_register(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 void zfcp_scsi_rport_register(struct zfcp_port *port)
|
||||
{
|
||||
struct fc_rport_identifiers ids;
|
||||
@@ -574,7 +550,7 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
|
||||
port->rport = rport;
|
||||
port->starget_id = rport->scsi_target_id;
|
||||
|
||||
zfcp_scsi_queue_unit_register(port);
|
||||
zfcp_unit_queue_scsi_scan(port);
|
||||
}
|
||||
|
||||
static void zfcp_scsi_rport_block(struct zfcp_port *port)
|
||||
@@ -637,29 +613,6 @@ void zfcp_scsi_rport_work(struct work_struct *work)
|
||||
put_device(&port->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_scsi_scan - Register LUN with SCSI midlayer
|
||||
* @unit: The LUN/unit to register
|
||||
*/
|
||||
void zfcp_scsi_scan(struct zfcp_unit *unit)
|
||||
{
|
||||
struct fc_rport *rport = unit->port->rport;
|
||||
|
||||
if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
|
||||
scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
|
||||
scsilun_to_int((struct scsi_lun *)
|
||||
&unit->fcp_lun), 0);
|
||||
}
|
||||
|
||||
void zfcp_scsi_scan_work(struct work_struct *work)
|
||||
{
|
||||
struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
|
||||
scsi_work);
|
||||
|
||||
zfcp_scsi_scan(unit);
|
||||
put_device(&unit->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host
|
||||
* @adapter: The adapter where to configure DIF/DIX for the SCSI host
|
||||
@@ -735,7 +688,6 @@ struct fc_function_template zfcp_transport_functions = {
|
||||
.show_host_port_type = 1,
|
||||
.show_host_speed = 1,
|
||||
.show_host_port_id = 1,
|
||||
.disable_target_scan = 1,
|
||||
.dd_bsg_size = sizeof(struct zfcp_fsf_ct_els),
|
||||
};
|
||||
|
||||
|
||||
+111
-110
@@ -68,63 +68,96 @@ ZFCP_DEFINE_ATTR(zfcp_port, port, access_denied, "%d\n",
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
|
||||
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n",
|
||||
atomic_read(&unit->status));
|
||||
zfcp_unit_sdev_status(unit));
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n",
|
||||
(atomic_read(&unit->status) &
|
||||
(zfcp_unit_sdev_status(unit) &
|
||||
ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n",
|
||||
(atomic_read(&unit->status) &
|
||||
(zfcp_unit_sdev_status(unit) &
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n",
|
||||
(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_UNIT_SHARED) != 0);
|
||||
(zfcp_unit_sdev_status(unit) &
|
||||
ZFCP_STATUS_LUN_SHARED) != 0);
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n",
|
||||
(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_UNIT_READONLY) != 0);
|
||||
(zfcp_unit_sdev_status(unit) &
|
||||
ZFCP_STATUS_LUN_READONLY) != 0);
|
||||
|
||||
#define ZFCP_SYSFS_FAILED(_feat_def, _feat, _adapter, _mod_id, _reopen_id) \
|
||||
static ssize_t zfcp_sysfs_##_feat##_failed_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \
|
||||
\
|
||||
if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED) \
|
||||
return sprintf(buf, "1\n"); \
|
||||
else \
|
||||
return sprintf(buf, "0\n"); \
|
||||
} \
|
||||
static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \
|
||||
struct device_attribute *attr,\
|
||||
const char *buf, size_t count)\
|
||||
{ \
|
||||
struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \
|
||||
unsigned long val; \
|
||||
int retval = 0; \
|
||||
\
|
||||
if (!(_feat && get_device(&_feat->dev))) \
|
||||
return -EBUSY; \
|
||||
\
|
||||
if (strict_strtoul(buf, 0, &val) || val != 0) { \
|
||||
retval = -EINVAL; \
|
||||
goto out; \
|
||||
} \
|
||||
\
|
||||
zfcp_erp_modify_##_feat##_status(_feat, _mod_id, NULL, \
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);\
|
||||
zfcp_erp_##_feat##_reopen(_feat, ZFCP_STATUS_COMMON_ERP_FAILED, \
|
||||
_reopen_id, NULL); \
|
||||
zfcp_erp_wait(_adapter); \
|
||||
out: \
|
||||
put_device(&_feat->dev); \
|
||||
return retval ? retval : (ssize_t) count; \
|
||||
} \
|
||||
static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \
|
||||
zfcp_sysfs_##_feat##_failed_show, \
|
||||
zfcp_sysfs_##_feat##_failed_store);
|
||||
static ssize_t zfcp_sysfs_port_failed_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
|
||||
|
||||
ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
|
||||
ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
||||
return sprintf(buf, "1\n");
|
||||
|
||||
return sprintf(buf, "0\n");
|
||||
}
|
||||
|
||||
static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
|
||||
unsigned long val;
|
||||
|
||||
if (strict_strtoul(buf, 0, &val) || val != 0)
|
||||
return -EINVAL;
|
||||
|
||||
zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2",
|
||||
NULL);
|
||||
zfcp_erp_wait(port->adapter);
|
||||
|
||||
return count;
|
||||
}
|
||||
static ZFCP_DEV_ATTR(port, failed, S_IWUSR | S_IRUGO,
|
||||
zfcp_sysfs_port_failed_show,
|
||||
zfcp_sysfs_port_failed_store);
|
||||
|
||||
static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
|
||||
struct scsi_device *sdev;
|
||||
unsigned int status, failed = 1;
|
||||
|
||||
sdev = zfcp_unit_sdev(unit);
|
||||
if (sdev) {
|
||||
status = atomic_read(&sdev_to_zfcp(sdev)->status);
|
||||
failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;
|
||||
scsi_device_put(sdev);
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", failed);
|
||||
}
|
||||
|
||||
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", NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
} else
|
||||
zfcp_unit_scsi_scan(unit);
|
||||
|
||||
return count;
|
||||
}
|
||||
static ZFCP_DEV_ATTR(unit, failed, S_IWUSR | S_IRUGO,
|
||||
zfcp_sysfs_unit_failed_show,
|
||||
zfcp_sysfs_unit_failed_store);
|
||||
|
||||
static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
@@ -163,8 +196,7 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"syafai2", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
@@ -257,28 +289,15 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
|
||||
struct zfcp_unit *unit;
|
||||
u64 fcp_lun;
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (!(port && get_device(&port->dev)))
|
||||
return -EBUSY;
|
||||
|
||||
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
|
||||
unit = zfcp_unit_enqueue(port, fcp_lun);
|
||||
if (IS_ERR(unit))
|
||||
goto out;
|
||||
else
|
||||
retval = 0;
|
||||
if (zfcp_unit_add(port, fcp_lun))
|
||||
return -EINVAL;
|
||||
|
||||
zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
zfcp_scsi_scan(unit);
|
||||
out:
|
||||
put_device(&port->dev);
|
||||
return retval ? retval : (ssize_t) count;
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
|
||||
|
||||
@@ -287,42 +306,15 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
|
||||
struct zfcp_unit *unit;
|
||||
u64 fcp_lun;
|
||||
int retval = -EINVAL;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
if (!(port && get_device(&port->dev)))
|
||||
return -EBUSY;
|
||||
|
||||
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
|
||||
unit = zfcp_get_unit_by_lun(port, fcp_lun);
|
||||
if (!unit)
|
||||
goto out;
|
||||
else
|
||||
retval = 0;
|
||||
if (zfcp_unit_remove(port, fcp_lun))
|
||||
return -EINVAL;
|
||||
|
||||
sdev = scsi_device_lookup(port->adapter->scsi_host, 0,
|
||||
port->starget_id,
|
||||
scsilun_to_int((struct scsi_lun *)&fcp_lun));
|
||||
if (sdev) {
|
||||
scsi_remove_device(sdev);
|
||||
scsi_device_put(sdev);
|
||||
}
|
||||
|
||||
write_lock_irq(&port->unit_list_lock);
|
||||
list_del(&unit->list);
|
||||
write_unlock_irq(&port->unit_list_lock);
|
||||
|
||||
put_device(&unit->dev);
|
||||
|
||||
zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
|
||||
zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
|
||||
out:
|
||||
put_device(&port->dev);
|
||||
return retval ? retval : (ssize_t) count;
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
|
||||
|
||||
@@ -363,9 +355,9 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) { \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
struct zfcp_unit *unit = sdev->hostdata; \
|
||||
struct zfcp_latencies *lat = &unit->latencies; \
|
||||
struct zfcp_adapter *adapter = unit->port->adapter; \
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
|
||||
struct zfcp_latencies *lat = &zfcp_sdev->latencies; \
|
||||
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; \
|
||||
unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \
|
||||
\
|
||||
spin_lock_bh(&lat->lock); \
|
||||
@@ -394,8 +386,8 @@ zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \
|
||||
const char *buf, size_t count) \
|
||||
{ \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
struct zfcp_unit *unit = sdev->hostdata; \
|
||||
struct zfcp_latencies *lat = &unit->latencies; \
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
|
||||
struct zfcp_latencies *lat = &zfcp_sdev->latencies; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
spin_lock_irqsave(&lat->lock, flags); \
|
||||
@@ -423,19 +415,28 @@ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
|
||||
struct device_attribute *attr,\
|
||||
char *buf) \
|
||||
{ \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
struct zfcp_unit *unit = sdev->hostdata; \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
|
||||
struct zfcp_port *port = zfcp_sdev->port; \
|
||||
\
|
||||
return sprintf(buf, _format, _value); \
|
||||
} \
|
||||
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
|
||||
|
||||
ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
|
||||
dev_name(&unit->port->adapter->ccw_device->dev));
|
||||
dev_name(&port->adapter->ccw_device->dev));
|
||||
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
|
||||
(unsigned long long) unit->port->wwpn);
|
||||
ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n",
|
||||
(unsigned long long) unit->fcp_lun);
|
||||
(unsigned long long) port->wwpn);
|
||||
|
||||
static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
|
||||
return sprintf(buf, "0x%016llx\n", zfcp_scsi_dev_lun(sdev));
|
||||
}
|
||||
static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL);
|
||||
|
||||
struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
|
||||
&dev_attr_fcp_lun,
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* zfcp device driver
|
||||
*
|
||||
* Tracking of manually configured LUNs and helper functions to
|
||||
* register the LUNs with the SCSI midlayer.
|
||||
*
|
||||
* Copyright IBM Corporation 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;
|
||||
unsigned int 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, 1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
put_device(&unit->port->dev);
|
||||
kfree(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_unit_enqueue - enqueue unit to unit list of a port.
|
||||
* @port: pointer to port where unit is added
|
||||
* @fcp_lun: FCP LUN of unit to be enqueued
|
||||
* 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;
|
||||
|
||||
unit = zfcp_unit_find(port, fcp_lun);
|
||||
if (unit) {
|
||||
put_device(&unit->dev);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
|
||||
if (!unit)
|
||||
return -ENOMEM;
|
||||
|
||||
unit->port = port;
|
||||
unit->fcp_lun = fcp_lun;
|
||||
unit->dev.parent = &port->dev;
|
||||
unit->dev.release = zfcp_unit_release;
|
||||
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);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (device_register(&unit->dev)) {
|
||||
put_device(&unit->dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) {
|
||||
device_unregister(&unit->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
get_device(&port->dev);
|
||||
|
||||
write_lock_irq(&port->unit_list_lock);
|
||||
list_add_tail(&unit->list, &port->unit_list);
|
||||
write_unlock_irq(&port->unit_list_lock);
|
||||
|
||||
zfcp_unit_scsi_scan(unit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
unsigned int 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);
|
||||
}
|
||||
|
||||
put_device(&unit->dev);
|
||||
|
||||
zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -316,7 +316,8 @@ config SCSI_ISCSI_ATTRS
|
||||
|
||||
config SCSI_SAS_ATTRS
|
||||
tristate "SAS Transport Attributes"
|
||||
depends on SCSI && BLK_DEV_BSG
|
||||
depends on SCSI
|
||||
select BLK_DEV_BSG
|
||||
help
|
||||
If you wish to export transport-specific information about
|
||||
each attached SAS device to sysfs, say Y.
|
||||
@@ -378,7 +379,7 @@ config ISCSI_BOOT_SYSFS
|
||||
via sysfs to userspace. If you wish to export this information,
|
||||
say Y. Otherwise, say N.
|
||||
|
||||
source "drivers/scsi/cxgb3i/Kconfig"
|
||||
source "drivers/scsi/cxgbi/Kconfig"
|
||||
source "drivers/scsi/bnx2i/Kconfig"
|
||||
source "drivers/scsi/be2iscsi/Kconfig"
|
||||
|
||||
|
||||
@@ -133,7 +133,8 @@ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
|
||||
obj-$(CONFIG_SCSI_STEX) += stex.o
|
||||
obj-$(CONFIG_SCSI_MVSAS) += mvsas/
|
||||
obj-$(CONFIG_PS3_ROM) += ps3rom.o
|
||||
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/
|
||||
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgbi/
|
||||
obj-$(CONFIG_SCSI_CXGB4_ISCSI) += libiscsi.o libiscsi_tcp.o cxgbi/
|
||||
obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
|
||||
obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
|
||||
obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
|
||||
|
||||
@@ -190,7 +190,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
||||
/*
|
||||
* Initialize the mutex used to wait for the next AIF.
|
||||
*/
|
||||
init_MUTEX_LOCKED(&fibctx->wait_sem);
|
||||
sema_init(&fibctx->wait_sem, 0);
|
||||
fibctx->wait = 0;
|
||||
/*
|
||||
* Initialize the fibs and set the count of fibs on
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user