mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04: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: (37 commits) [SCSI] zfcp: fix double dbf id usage [SCSI] zfcp: wait on SCSI work to be finished before proceeding with init dev [SCSI] zfcp: fix erp list usage without using locks [SCSI] zfcp: prevent fc_remote_port_delete calls for unregistered rport [SCSI] zfcp: fix deadlock caused by shared work queue tasks [SCSI] zfcp: put threshold data in hba trace [SCSI] zfcp: Simplify zfcp data structures [SCSI] zfcp: Simplify get_adapter_by_busid [SCSI] zfcp: remove all typedefs and replace them with standards [SCSI] zfcp: attach and release SAN nameserver port on demand [SCSI] zfcp: remove unused references, declarations and flags [SCSI] zfcp: Update message with input from review [SCSI] zfcp: add queue_full sysfs attribute [SCSI] scsi_dh: suppress comparison warning [SCSI] scsi_dh: add Dell product information into rdac device handler [SCSI] qla2xxx: remove the unused SCSI_QLOGIC_FC_FIRMWARE option [SCSI] qla2xxx: fix printk format warnings [SCSI] qla2xxx: Update version number to 8.02.01-k8. [SCSI] qla2xxx: Ignore payload reserved-bits during RSCN processing. [SCSI] qla2xxx: Additional residual-count corrections during UNDERRUN handling. ...
This commit is contained in:
commit
ef5bef357c
50 changed files with 2107 additions and 1112 deletions
|
|
@ -88,11 +88,13 @@ static int __init zfcp_device_setup(char *devstr)
|
|||
strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE);
|
||||
|
||||
token = strsep(&str, ",");
|
||||
if (!token || strict_strtoull(token, 0, &zfcp_data.init_wwpn))
|
||||
if (!token || strict_strtoull(token, 0,
|
||||
(unsigned long long *) &zfcp_data.init_wwpn))
|
||||
goto err_out;
|
||||
|
||||
token = strsep(&str, ",");
|
||||
if (!token || strict_strtoull(token, 0, &zfcp_data.init_fcp_lun))
|
||||
if (!token || strict_strtoull(token, 0,
|
||||
(unsigned long long *) &zfcp_data.init_fcp_lun))
|
||||
goto err_out;
|
||||
|
||||
kfree(str);
|
||||
|
|
@ -100,24 +102,10 @@ static int __init zfcp_device_setup(char *devstr)
|
|||
|
||||
err_out:
|
||||
kfree(str);
|
||||
pr_err("zfcp: Parse error for device parameter string %s, "
|
||||
"device not attached.\n", devstr);
|
||||
pr_err("zfcp: %s is not a valid SCSI device\n", devstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct zfcp_adapter *zfcp_get_adapter_by_busid(char *bus_id)
|
||||
{
|
||||
struct zfcp_adapter *adapter;
|
||||
|
||||
list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list)
|
||||
if ((strncmp(bus_id, adapter->ccw_device->dev.bus_id,
|
||||
BUS_ID_SIZE) == 0) &&
|
||||
!(atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_COMMON_REMOVE))
|
||||
return adapter;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __init zfcp_init_device_configure(void)
|
||||
{
|
||||
struct zfcp_adapter *adapter;
|
||||
|
|
@ -141,7 +129,12 @@ static void __init zfcp_init_device_configure(void)
|
|||
goto out_unit;
|
||||
up(&zfcp_data.config_sema);
|
||||
ccw_device_set_online(adapter->ccw_device);
|
||||
|
||||
zfcp_erp_wait(adapter);
|
||||
wait_event(adapter->erp_done_wqh,
|
||||
!(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_UNIT_SCSI_WORK_PENDING));
|
||||
|
||||
down(&zfcp_data.config_sema);
|
||||
zfcp_unit_put(unit);
|
||||
out_unit:
|
||||
|
|
@ -180,9 +173,9 @@ static int __init zfcp_module_init(void)
|
|||
if (!zfcp_data.gid_pn_cache)
|
||||
goto out_gid_cache;
|
||||
|
||||
INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
|
||||
INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);
|
||||
zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
|
||||
|
||||
INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
|
||||
sema_init(&zfcp_data.config_sema, 1);
|
||||
rwlock_init(&zfcp_data.config_lock);
|
||||
|
||||
|
|
@ -193,13 +186,14 @@ static int __init zfcp_module_init(void)
|
|||
|
||||
retval = misc_register(&zfcp_cfdc_misc);
|
||||
if (retval) {
|
||||
pr_err("zfcp: registration of misc device zfcp_cfdc failed\n");
|
||||
pr_err("zfcp: Registering the misc device zfcp_cfdc failed\n");
|
||||
goto out_misc;
|
||||
}
|
||||
|
||||
retval = zfcp_ccw_register();
|
||||
if (retval) {
|
||||
pr_err("zfcp: Registration with common I/O layer failed.\n");
|
||||
pr_err("zfcp: The zfcp device driver could not register with "
|
||||
"the common I/O layer\n");
|
||||
goto out_ccw_register;
|
||||
}
|
||||
|
||||
|
|
@ -231,8 +225,7 @@ module_init(zfcp_module_init);
|
|||
*
|
||||
* Returns: pointer to zfcp_unit or NULL
|
||||
*/
|
||||
struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port,
|
||||
fcp_lun_t fcp_lun)
|
||||
struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
|
||||
|
|
@ -251,7 +244,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port,
|
|||
* Returns: pointer to zfcp_port or NULL
|
||||
*/
|
||||
struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
|
||||
wwn_t wwpn)
|
||||
u64 wwpn)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
||||
|
|
@ -276,7 +269,7 @@ static void zfcp_sysfs_unit_release(struct device *dev)
|
|||
*
|
||||
* Sets up some unit internal structures and creates sysfs entry.
|
||||
*/
|
||||
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
||||
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
|
||||
|
|
@ -290,7 +283,8 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
|||
unit->port = port;
|
||||
unit->fcp_lun = fcp_lun;
|
||||
|
||||
snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun);
|
||||
snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx",
|
||||
(unsigned long long) fcp_lun);
|
||||
unit->sysfs_device.parent = &port->sysfs_device;
|
||||
unit->sysfs_device.release = zfcp_sysfs_unit_release;
|
||||
dev_set_drvdata(&unit->sysfs_device, unit);
|
||||
|
|
@ -323,7 +317,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
|||
}
|
||||
|
||||
zfcp_unit_get(unit);
|
||||
unit->scsi_lun = scsilun_to_int((struct scsi_lun *)&unit->fcp_lun);
|
||||
|
||||
write_lock_irq(&zfcp_data.config_lock);
|
||||
list_add_tail(&unit->list, &port->unit_list_head);
|
||||
|
|
@ -332,7 +325,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
|||
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
port->units++;
|
||||
zfcp_port_get(port);
|
||||
|
||||
return unit;
|
||||
|
|
@ -351,11 +343,10 @@ err_out_free:
|
|||
*/
|
||||
void zfcp_unit_dequeue(struct zfcp_unit *unit)
|
||||
{
|
||||
zfcp_unit_wait(unit);
|
||||
wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
|
||||
write_lock_irq(&zfcp_data.config_lock);
|
||||
list_del(&unit->list);
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
unit->port->units--;
|
||||
zfcp_port_put(unit->port);
|
||||
sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
|
||||
device_unregister(&unit->sysfs_device);
|
||||
|
|
@ -416,11 +407,6 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
|
|||
mempool_destroy(adapter->pool.data_gid_pn);
|
||||
}
|
||||
|
||||
static void zfcp_dummy_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_status_read_refill - refill the long running status_read_requests
|
||||
* @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled
|
||||
|
|
@ -450,19 +436,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work)
|
|||
stat_work));
|
||||
}
|
||||
|
||||
static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
||||
port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,
|
||||
ZFCP_DID_DIRECTORY_SERVICE);
|
||||
if (IS_ERR(port))
|
||||
return PTR_ERR(port);
|
||||
zfcp_port_put(port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_adapter_enqueue - enqueue a new adapter to the list
|
||||
* @ccw_device: pointer to the struct cc_device
|
||||
|
|
@ -508,7 +481,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
init_waitqueue_head(&adapter->erp_done_wqh);
|
||||
|
||||
INIT_LIST_HEAD(&adapter->port_list_head);
|
||||
INIT_LIST_HEAD(&adapter->port_remove_lh);
|
||||
INIT_LIST_HEAD(&adapter->erp_ready_head);
|
||||
INIT_LIST_HEAD(&adapter->erp_running_head);
|
||||
|
||||
|
|
@ -518,7 +490,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
spin_lock_init(&adapter->san_dbf_lock);
|
||||
spin_lock_init(&adapter->scsi_dbf_lock);
|
||||
spin_lock_init(&adapter->rec_dbf_lock);
|
||||
spin_lock_init(&adapter->req_q.lock);
|
||||
spin_lock_init(&adapter->req_q_lock);
|
||||
|
||||
rwlock_init(&adapter->erp_lock);
|
||||
rwlock_init(&adapter->abort_lock);
|
||||
|
|
@ -537,28 +509,15 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
&zfcp_sysfs_adapter_attrs))
|
||||
goto sysfs_failed;
|
||||
|
||||
adapter->generic_services.parent = &adapter->ccw_device->dev;
|
||||
adapter->generic_services.release = zfcp_dummy_release;
|
||||
snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE,
|
||||
"generic_services");
|
||||
|
||||
if (device_register(&adapter->generic_services))
|
||||
goto generic_services_failed;
|
||||
|
||||
write_lock_irq(&zfcp_data.config_lock);
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
|
||||
list_add_tail(&adapter->list, &zfcp_data.adapter_list_head);
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
zfcp_data.adapters++;
|
||||
|
||||
zfcp_nameserver_enqueue(adapter);
|
||||
zfcp_fc_nameserver_init(adapter);
|
||||
|
||||
return 0;
|
||||
|
||||
generic_services_failed:
|
||||
sysfs_remove_group(&ccw_device->dev.kobj,
|
||||
&zfcp_sysfs_adapter_attrs);
|
||||
sysfs_failed:
|
||||
zfcp_adapter_debug_unregister(adapter);
|
||||
debug_register_failed:
|
||||
|
|
@ -585,7 +544,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
|
|||
cancel_work_sync(&adapter->scan_work);
|
||||
cancel_work_sync(&adapter->stat_work);
|
||||
zfcp_adapter_scsi_unregister(adapter);
|
||||
device_unregister(&adapter->generic_services);
|
||||
sysfs_remove_group(&adapter->ccw_device->dev.kobj,
|
||||
&zfcp_sysfs_adapter_attrs);
|
||||
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
|
||||
|
|
@ -603,9 +561,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
|
|||
list_del(&adapter->list);
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
/* decrease number of adapters in list */
|
||||
zfcp_data.adapters--;
|
||||
|
||||
zfcp_qdio_free(adapter);
|
||||
|
||||
zfcp_free_low_mem_buffers(adapter);
|
||||
|
|
@ -633,21 +588,19 @@ static void zfcp_sysfs_port_release(struct device *dev)
|
|||
* d_id is used to enqueue ports with a well known address like the Directory
|
||||
* Service for nameserver lookup.
|
||||
*/
|
||||
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
|
||||
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
|
||||
u32 status, u32 d_id)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
int retval;
|
||||
char *bus_id;
|
||||
|
||||
port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init_waitqueue_head(&port->remove_wq);
|
||||
|
||||
INIT_LIST_HEAD(&port->unit_list_head);
|
||||
INIT_LIST_HEAD(&port->unit_remove_lh);
|
||||
INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);
|
||||
|
||||
port->adapter = adapter;
|
||||
port->d_id = d_id;
|
||||
|
|
@ -657,34 +610,9 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
|
|||
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||
atomic_set(&port->refcount, 0);
|
||||
|
||||
if (status & ZFCP_STATUS_PORT_WKA) {
|
||||
switch (d_id) {
|
||||
case ZFCP_DID_DIRECTORY_SERVICE:
|
||||
bus_id = "directory";
|
||||
break;
|
||||
case ZFCP_DID_MANAGEMENT_SERVICE:
|
||||
bus_id = "management";
|
||||
break;
|
||||
case ZFCP_DID_KEY_DISTRIBUTION_SERVICE:
|
||||
bus_id = "key_distribution";
|
||||
break;
|
||||
case ZFCP_DID_ALIAS_SERVICE:
|
||||
bus_id = "alias";
|
||||
break;
|
||||
case ZFCP_DID_TIME_SERVICE:
|
||||
bus_id = "time";
|
||||
break;
|
||||
default:
|
||||
kfree(port);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id);
|
||||
port->sysfs_device.parent = &adapter->generic_services;
|
||||
} else {
|
||||
snprintf(port->sysfs_device.bus_id,
|
||||
BUS_ID_SIZE, "0x%016llx", wwpn);
|
||||
port->sysfs_device.parent = &adapter->ccw_device->dev;
|
||||
}
|
||||
snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx",
|
||||
(unsigned long long) wwpn);
|
||||
port->sysfs_device.parent = &adapter->ccw_device->dev;
|
||||
|
||||
port->sysfs_device.release = zfcp_sysfs_port_release;
|
||||
dev_set_drvdata(&port->sysfs_device, port);
|
||||
|
|
@ -700,12 +628,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
|
|||
if (device_register(&port->sysfs_device))
|
||||
goto err_out_free;
|
||||
|
||||
if (status & ZFCP_STATUS_PORT_WKA)
|
||||
retval = sysfs_create_group(&port->sysfs_device.kobj,
|
||||
&zfcp_sysfs_ns_port_attrs);
|
||||
else
|
||||
retval = sysfs_create_group(&port->sysfs_device.kobj,
|
||||
&zfcp_sysfs_port_attrs);
|
||||
retval = sysfs_create_group(&port->sysfs_device.kobj,
|
||||
&zfcp_sysfs_port_attrs);
|
||||
|
||||
if (retval) {
|
||||
device_unregister(&port->sysfs_device);
|
||||
|
|
@ -718,10 +642,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
|
|||
list_add_tail(&port->list, &adapter->port_list_head);
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
|
||||
if (d_id == ZFCP_DID_DIRECTORY_SERVICE)
|
||||
if (!adapter->nameserver_port)
|
||||
adapter->nameserver_port = port;
|
||||
adapter->ports++;
|
||||
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
|
|
@ -740,21 +660,15 @@ err_out:
|
|||
*/
|
||||
void zfcp_port_dequeue(struct zfcp_port *port)
|
||||
{
|
||||
zfcp_port_wait(port);
|
||||
wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
|
||||
write_lock_irq(&zfcp_data.config_lock);
|
||||
list_del(&port->list);
|
||||
port->adapter->ports--;
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
if (port->rport)
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
zfcp_adapter_put(port->adapter);
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
|
||||
sysfs_remove_group(&port->sysfs_device.kobj,
|
||||
&zfcp_sysfs_ns_port_attrs);
|
||||
else
|
||||
sysfs_remove_group(&port->sysfs_device.kobj,
|
||||
&zfcp_sysfs_port_attrs);
|
||||
sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
|
||||
device_unregister(&port->sysfs_device);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ static int zfcp_ccw_probe(struct ccw_device *ccw_device)
|
|||
down(&zfcp_data.config_sema);
|
||||
if (zfcp_adapter_enqueue(ccw_device)) {
|
||||
dev_err(&ccw_device->dev,
|
||||
"Setup of data structures failed.\n");
|
||||
"Setting up data structures for the "
|
||||
"FCP adapter failed\n");
|
||||
retval = -EINVAL;
|
||||
}
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
@ -46,6 +47,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
|
|||
struct zfcp_adapter *adapter;
|
||||
struct zfcp_port *port, *p;
|
||||
struct zfcp_unit *unit, *u;
|
||||
LIST_HEAD(unit_remove_lh);
|
||||
LIST_HEAD(port_remove_lh);
|
||||
|
||||
ccw_device_set_offline(ccw_device);
|
||||
down(&zfcp_data.config_sema);
|
||||
|
|
@ -54,26 +57,26 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
|
|||
write_lock_irq(&zfcp_data.config_lock);
|
||||
list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
|
||||
list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
|
||||
list_move(&unit->list, &port->unit_remove_lh);
|
||||
list_move(&unit->list, &unit_remove_lh);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
|
||||
&unit->status);
|
||||
}
|
||||
list_move(&port->list, &adapter->port_remove_lh);
|
||||
list_move(&port->list, &port_remove_lh);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||
}
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) {
|
||||
list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) {
|
||||
if (atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED,
|
||||
&unit->status))
|
||||
list_for_each_entry_safe(port, p, &port_remove_lh, list) {
|
||||
list_for_each_entry_safe(unit, u, &unit_remove_lh, list) {
|
||||
if (atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_UNIT_REGISTERED)
|
||||
scsi_remove_device(unit->device);
|
||||
zfcp_unit_dequeue(unit);
|
||||
}
|
||||
zfcp_port_dequeue(port);
|
||||
}
|
||||
zfcp_adapter_wait(adapter);
|
||||
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
|
||||
zfcp_adapter_dequeue(adapter);
|
||||
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
@ -156,15 +159,18 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
|
|||
|
||||
switch (event) {
|
||||
case CIO_GONE:
|
||||
dev_warn(&adapter->ccw_device->dev, "device gone\n");
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"The FCP device has been detached\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
|
||||
break;
|
||||
case CIO_NO_PATH:
|
||||
dev_warn(&adapter->ccw_device->dev, "no path\n");
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"The CHPID for the FCP device is offline\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
|
||||
break;
|
||||
case CIO_OPER:
|
||||
dev_info(&adapter->ccw_device->dev, "operational again\n");
|
||||
dev_info(&adapter->ccw_device->dev,
|
||||
"The FCP device is operational again\n");
|
||||
zfcp_erp_modify_adapter_status(adapter, 11, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
|
|
@ -220,3 +226,20 @@ int __init zfcp_ccw_register(void)
|
|||
{
|
||||
return ccw_driver_register(&zfcp_ccw_driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_get_adapter_by_busid - find zfcp_adapter struct
|
||||
* @busid: bus id string of zfcp adapter to find
|
||||
*/
|
||||
struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
|
||||
{
|
||||
struct ccw_device *ccw_device;
|
||||
struct zfcp_adapter *adapter = NULL;
|
||||
|
||||
ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
|
||||
if (ccw_device) {
|
||||
adapter = dev_get_drvdata(&ccw_device->dev);
|
||||
put_device(&ccw_device->dev);
|
||||
}
|
||||
return adapter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,6 +318,26 @@ void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter,
|
|||
spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_hba_dbf_event_berr - trace event for bit error threshold
|
||||
* @adapter: adapter affected by this QDIO related event
|
||||
* @req: fsf request
|
||||
*/
|
||||
void zfcp_hba_dbf_event_berr(struct zfcp_adapter *adapter,
|
||||
struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
|
||||
struct fsf_status_read_buffer *sr_buf = req->data;
|
||||
struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
|
||||
memset(r, 0, sizeof(*r));
|
||||
strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
|
||||
memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
|
||||
debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
|
||||
spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
|
||||
}
|
||||
static void zfcp_hba_dbf_view_response(char **p,
|
||||
struct zfcp_hba_dbf_record_response *r)
|
||||
{
|
||||
|
|
@ -399,6 +419,30 @@ static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r)
|
|||
zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
|
||||
}
|
||||
|
||||
static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r)
|
||||
{
|
||||
zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
|
||||
zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
|
||||
zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count);
|
||||
zfcp_dbf_out(p, "prim_seq_err", "%d",
|
||||
r->primitive_sequence_error_count);
|
||||
zfcp_dbf_out(p, "inval_trans_word_err", "%d",
|
||||
r->invalid_transmission_word_error_count);
|
||||
zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count);
|
||||
zfcp_dbf_out(p, "prim_seq_event_to", "%d",
|
||||
r->primitive_sequence_event_timeout_count);
|
||||
zfcp_dbf_out(p, "elast_buf_overrun_err", "%d",
|
||||
r->elastic_buffer_overrun_error_count);
|
||||
zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d",
|
||||
r->advertised_receive_b2b_credit);
|
||||
zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d",
|
||||
r->current_receive_b2b_credit);
|
||||
zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d",
|
||||
r->advertised_transmit_b2b_credit);
|
||||
zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d",
|
||||
r->current_transmit_b2b_credit);
|
||||
}
|
||||
|
||||
static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
|
||||
char *out_buf, const char *in_buf)
|
||||
{
|
||||
|
|
@ -418,6 +462,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
|
|||
zfcp_hba_dbf_view_status(&p, &r->u.status);
|
||||
else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
|
||||
zfcp_hba_dbf_view_qdio(&p, &r->u.qdio);
|
||||
else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
|
||||
zfcp_hba_dbf_view_berr(&p, &r->u.berr);
|
||||
|
||||
p += sprintf(p, "\n");
|
||||
return p - out_buf;
|
||||
|
|
@ -519,14 +565,14 @@ static const char *zfcp_rec_dbf_ids[] = {
|
|||
[75] = "physical port recovery escalation after failed port "
|
||||
"recovery",
|
||||
[76] = "port recovery escalation after failed unit recovery",
|
||||
[77] = "recovery opening nameserver port",
|
||||
[77] = "",
|
||||
[78] = "duplicate request id",
|
||||
[79] = "link down",
|
||||
[80] = "exclusive read-only unit access unsupported",
|
||||
[81] = "shared read-write unit access unsupported",
|
||||
[82] = "incoming rscn",
|
||||
[83] = "incoming wwpn",
|
||||
[84] = "",
|
||||
[84] = "wka port handle not valid close port",
|
||||
[85] = "online",
|
||||
[86] = "offline",
|
||||
[87] = "ccw device gone",
|
||||
|
|
@ -570,7 +616,7 @@ static const char *zfcp_rec_dbf_ids[] = {
|
|||
[125] = "need newer zfcp",
|
||||
[126] = "need newer microcode",
|
||||
[127] = "arbitrated loop not supported",
|
||||
[128] = "unknown topology",
|
||||
[128] = "",
|
||||
[129] = "qtcb size mismatch",
|
||||
[130] = "unknown fsf status ecd",
|
||||
[131] = "fcp request too big",
|
||||
|
|
@ -829,9 +875,9 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
|
|||
void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
|
||||
struct zfcp_port *port = ct->port;
|
||||
struct zfcp_adapter *adapter = port->adapter;
|
||||
struct ct_hdr *hdr = zfcp_sg_to_address(ct->req);
|
||||
struct zfcp_wka_port *wka_port = ct->wka_port;
|
||||
struct zfcp_adapter *adapter = wka_port->adapter;
|
||||
struct ct_hdr *hdr = sg_virt(ct->req);
|
||||
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
|
||||
struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
|
||||
unsigned long flags;
|
||||
|
|
@ -842,7 +888,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
|
|||
r->fsf_reqid = (unsigned long)fsf_req;
|
||||
r->fsf_seqno = fsf_req->seq_no;
|
||||
r->s_id = fc_host_port_id(adapter->scsi_host);
|
||||
r->d_id = port->d_id;
|
||||
r->d_id = wka_port->d_id;
|
||||
oct->cmd_req_code = hdr->cmd_rsp_code;
|
||||
oct->revision = hdr->revision;
|
||||
oct->gs_type = hdr->gs_type;
|
||||
|
|
@ -863,9 +909,9 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
|
|||
void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
|
||||
struct zfcp_port *port = ct->port;
|
||||
struct zfcp_adapter *adapter = port->adapter;
|
||||
struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp);
|
||||
struct zfcp_wka_port *wka_port = ct->wka_port;
|
||||
struct zfcp_adapter *adapter = wka_port->adapter;
|
||||
struct ct_hdr *hdr = sg_virt(ct->resp);
|
||||
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
|
||||
struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
|
||||
unsigned long flags;
|
||||
|
|
@ -875,7 +921,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
|
|||
strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
|
||||
r->fsf_reqid = (unsigned long)fsf_req;
|
||||
r->fsf_seqno = fsf_req->seq_no;
|
||||
r->s_id = port->d_id;
|
||||
r->s_id = wka_port->d_id;
|
||||
r->d_id = fc_host_port_id(adapter->scsi_host);
|
||||
rct->cmd_rsp_code = hdr->cmd_rsp_code;
|
||||
rct->revision = hdr->revision;
|
||||
|
|
@ -922,8 +968,8 @@ void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
|
|||
|
||||
zfcp_san_dbf_event_els("oels", 2, fsf_req,
|
||||
fc_host_port_id(els->adapter->scsi_host),
|
||||
els->d_id, *(u8 *) zfcp_sg_to_address(els->req),
|
||||
zfcp_sg_to_address(els->req), els->req->length);
|
||||
els->d_id, *(u8 *) sg_virt(els->req),
|
||||
sg_virt(els->req), els->req->length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -936,8 +982,7 @@ void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
|
|||
|
||||
zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id,
|
||||
fc_host_port_id(els->adapter->scsi_host),
|
||||
*(u8 *)zfcp_sg_to_address(els->req),
|
||||
zfcp_sg_to_address(els->resp),
|
||||
*(u8 *)sg_virt(els->req), sg_virt(els->resp),
|
||||
els->resp->length);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ struct zfcp_hba_dbf_record {
|
|||
struct zfcp_hba_dbf_record_response response;
|
||||
struct zfcp_hba_dbf_record_status status;
|
||||
struct zfcp_hba_dbf_record_qdio qdio;
|
||||
struct fsf_bit_error_payload berr;
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
|
|
|||
|
|
@ -39,29 +39,6 @@
|
|||
|
||||
/********************* GENERAL DEFINES *********************************/
|
||||
|
||||
/**
|
||||
* zfcp_sg_to_address - determine kernel address from struct scatterlist
|
||||
* @list: struct scatterlist
|
||||
* Return: kernel address
|
||||
*/
|
||||
static inline void *
|
||||
zfcp_sg_to_address(struct scatterlist *list)
|
||||
{
|
||||
return sg_virt(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_address_to_sg - set up struct scatterlist from kernel address
|
||||
* @address: kernel address
|
||||
* @list: struct scatterlist
|
||||
* @size: buffer size
|
||||
*/
|
||||
static inline void
|
||||
zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
|
||||
{
|
||||
sg_set_buf(list, address, size);
|
||||
}
|
||||
|
||||
#define REQUEST_LIST_SIZE 128
|
||||
|
||||
/********************* SCSI SPECIFIC DEFINES *********************************/
|
||||
|
|
@ -101,11 +78,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
|
|||
|
||||
/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
|
||||
|
||||
typedef unsigned long long wwn_t;
|
||||
typedef unsigned long long fcp_lun_t;
|
||||
/* data length field may be at variable position in FCP-2 FCP_CMND IU */
|
||||
typedef unsigned int fcp_dl_t;
|
||||
|
||||
/* timeout for name-server lookup (in seconds) */
|
||||
#define ZFCP_NS_GID_PN_TIMEOUT 10
|
||||
|
||||
|
|
@ -129,7 +101,7 @@ typedef unsigned int fcp_dl_t;
|
|||
|
||||
/* FCP(-2) FCP_CMND IU */
|
||||
struct fcp_cmnd_iu {
|
||||
fcp_lun_t fcp_lun; /* FCP logical unit number */
|
||||
u64 fcp_lun; /* FCP logical unit number */
|
||||
u8 crn; /* command reference number */
|
||||
u8 reserved0:5; /* reserved */
|
||||
u8 task_attribute:3; /* task attribute */
|
||||
|
|
@ -204,7 +176,7 @@ struct fcp_rscn_element {
|
|||
struct fcp_logo {
|
||||
u32 command;
|
||||
u32 nport_did;
|
||||
wwn_t nport_wwpn;
|
||||
u64 nport_wwpn;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
|
|
@ -218,13 +190,6 @@ struct fcp_logo {
|
|||
#define ZFCP_LS_RSCN 0x61
|
||||
#define ZFCP_LS_RNID 0x78
|
||||
|
||||
struct zfcp_ls_rjt_par {
|
||||
u8 action;
|
||||
u8 reason_code;
|
||||
u8 reason_expl;
|
||||
u8 vendor_unique;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_ls_adisc {
|
||||
u8 code;
|
||||
u8 field[3];
|
||||
|
|
@ -234,20 +199,6 @@ struct zfcp_ls_adisc {
|
|||
u32 nport_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_ls_adisc_acc {
|
||||
u8 code;
|
||||
u8 field[3];
|
||||
u32 hard_nport_id;
|
||||
u64 wwpn;
|
||||
u64 wwnn;
|
||||
u32 nport_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rc_entry {
|
||||
u8 code;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
/*
|
||||
* FC-GS-2 stuff
|
||||
*/
|
||||
|
|
@ -281,9 +232,7 @@ struct zfcp_rc_entry {
|
|||
#define ZFCP_STATUS_COMMON_RUNNING 0x40000000
|
||||
#define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000
|
||||
#define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000
|
||||
#define ZFCP_STATUS_COMMON_OPENING 0x08000000
|
||||
#define ZFCP_STATUS_COMMON_OPEN 0x04000000
|
||||
#define ZFCP_STATUS_COMMON_CLOSING 0x02000000
|
||||
#define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000
|
||||
#define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000
|
||||
#define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000
|
||||
|
|
@ -291,16 +240,15 @@ struct zfcp_rc_entry {
|
|||
|
||||
/* adapter status */
|
||||
#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
|
||||
#define ZFCP_STATUS_ADAPTER_REGISTERED 0x00000004
|
||||
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
|
||||
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
|
||||
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020
|
||||
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080
|
||||
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
|
||||
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
|
||||
#define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800
|
||||
|
||||
/* FC-PH/FC-GS well-known address identifiers for generic services */
|
||||
#define ZFCP_DID_WKA 0xFFFFF0
|
||||
#define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA
|
||||
#define ZFCP_DID_TIME_SERVICE 0xFFFFFB
|
||||
#define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC
|
||||
|
|
@ -312,29 +260,27 @@ struct zfcp_rc_entry {
|
|||
#define ZFCP_STATUS_PORT_DID_DID 0x00000002
|
||||
#define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004
|
||||
#define ZFCP_STATUS_PORT_NO_WWPN 0x00000008
|
||||
#define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010
|
||||
#define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020
|
||||
|
||||
/* for ports with well known addresses */
|
||||
#define ZFCP_STATUS_PORT_WKA \
|
||||
(ZFCP_STATUS_PORT_NO_WWPN | \
|
||||
ZFCP_STATUS_PORT_NO_SCSI_ID)
|
||||
/* well known address (WKA) port status*/
|
||||
enum zfcp_wka_status {
|
||||
ZFCP_WKA_PORT_OFFLINE,
|
||||
ZFCP_WKA_PORT_CLOSING,
|
||||
ZFCP_WKA_PORT_OPENING,
|
||||
ZFCP_WKA_PORT_ONLINE,
|
||||
};
|
||||
|
||||
/* logical unit status */
|
||||
#define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002
|
||||
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
|
||||
#define ZFCP_STATUS_UNIT_READONLY 0x00000008
|
||||
#define ZFCP_STATUS_UNIT_REGISTERED 0x00000010
|
||||
#define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020
|
||||
|
||||
/* FSF request status (this does not have a common part) */
|
||||
#define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000
|
||||
#define ZFCP_STATUS_FSFREQ_POOL 0x00000001
|
||||
#define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002
|
||||
#define ZFCP_STATUS_FSFREQ_COMPLETED 0x00000004
|
||||
#define ZFCP_STATUS_FSFREQ_ERROR 0x00000008
|
||||
#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010
|
||||
#define ZFCP_STATUS_FSFREQ_ABORTING 0x00000020
|
||||
#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040
|
||||
#define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080
|
||||
#define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100
|
||||
|
|
@ -379,7 +325,7 @@ struct ct_hdr {
|
|||
* a port name is required */
|
||||
struct ct_iu_gid_pn_req {
|
||||
struct ct_hdr header;
|
||||
wwn_t wwpn;
|
||||
u64 wwpn;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* FS_ACC IU and data unit for GID_PN nameserver request */
|
||||
|
|
@ -388,11 +334,9 @@ struct ct_iu_gid_pn_resp {
|
|||
u32 d_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
typedef void (*zfcp_send_ct_handler_t)(unsigned long);
|
||||
|
||||
/**
|
||||
* struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
|
||||
* @port: port where the request is sent to
|
||||
* @wka_port: port where the request is sent to
|
||||
* @req: scatter-gather list for request
|
||||
* @resp: scatter-gather list for response
|
||||
* @req_count: number of elements in request scatter-gather list
|
||||
|
|
@ -404,12 +348,12 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long);
|
|||
* @status: used to pass error status to calling function
|
||||
*/
|
||||
struct zfcp_send_ct {
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_wka_port *wka_port;
|
||||
struct scatterlist *req;
|
||||
struct scatterlist *resp;
|
||||
unsigned int req_count;
|
||||
unsigned int resp_count;
|
||||
zfcp_send_ct_handler_t handler;
|
||||
void (*handler)(unsigned long);
|
||||
unsigned long handler_data;
|
||||
int timeout;
|
||||
struct completion *completion;
|
||||
|
|
@ -426,8 +370,6 @@ struct zfcp_gid_pn_data {
|
|||
struct zfcp_port *port;
|
||||
};
|
||||
|
||||
typedef void (*zfcp_send_els_handler_t)(unsigned long);
|
||||
|
||||
/**
|
||||
* struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
|
||||
* @adapter: adapter where request is sent from
|
||||
|
|
@ -451,22 +393,28 @@ struct zfcp_send_els {
|
|||
struct scatterlist *resp;
|
||||
unsigned int req_count;
|
||||
unsigned int resp_count;
|
||||
zfcp_send_els_handler_t handler;
|
||||
void (*handler)(unsigned long);
|
||||
unsigned long handler_data;
|
||||
struct completion *completion;
|
||||
int ls_code;
|
||||
int status;
|
||||
};
|
||||
|
||||
struct zfcp_wka_port {
|
||||
struct zfcp_adapter *adapter;
|
||||
wait_queue_head_t completion_wq;
|
||||
enum zfcp_wka_status status;
|
||||
atomic_t refcount;
|
||||
u32 d_id;
|
||||
u32 handle;
|
||||
struct mutex mutex;
|
||||
struct delayed_work work;
|
||||
};
|
||||
|
||||
struct zfcp_qdio_queue {
|
||||
struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
|
||||
u8 first; /* index of next free bfr
|
||||
in queue (free_count>0) */
|
||||
atomic_t count; /* number of free buffers
|
||||
in queue */
|
||||
spinlock_t lock; /* lock for operations on queue */
|
||||
int pci_batch; /* SBALs since PCI indication
|
||||
was last set */
|
||||
struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
|
||||
u8 first; /* index of next free bfr in queue */
|
||||
atomic_t count; /* number of free buffers in queue */
|
||||
};
|
||||
|
||||
struct zfcp_erp_action {
|
||||
|
|
@ -475,7 +423,7 @@ struct zfcp_erp_action {
|
|||
struct zfcp_adapter *adapter; /* device which should be recovered */
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_unit *unit;
|
||||
volatile u32 status; /* recovery status */
|
||||
u32 status; /* recovery status */
|
||||
u32 step; /* active step of this erp action */
|
||||
struct zfcp_fsf_req *fsf_req; /* fsf request currently pending
|
||||
for this action */
|
||||
|
|
@ -506,8 +454,8 @@ struct zfcp_adapter {
|
|||
atomic_t refcount; /* reference count */
|
||||
wait_queue_head_t remove_wq; /* can be used to wait for
|
||||
refcount drop to zero */
|
||||
wwn_t peer_wwnn; /* P2P peer WWNN */
|
||||
wwn_t peer_wwpn; /* P2P peer WWPN */
|
||||
u64 peer_wwnn; /* P2P peer WWNN */
|
||||
u64 peer_wwpn; /* P2P peer WWPN */
|
||||
u32 peer_d_id; /* P2P peer D_ID */
|
||||
struct ccw_device *ccw_device; /* S/390 ccw device */
|
||||
u32 hydra_version; /* Hydra version */
|
||||
|
|
@ -518,13 +466,13 @@ struct zfcp_adapter {
|
|||
u16 timer_ticks; /* time int for a tick */
|
||||
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
|
||||
struct list_head port_list_head; /* remote port list */
|
||||
struct list_head port_remove_lh; /* head of ports to be
|
||||
removed */
|
||||
u32 ports; /* number of remote ports */
|
||||
unsigned long req_no; /* unique FSF req number */
|
||||
struct list_head *req_list; /* list of pending reqs */
|
||||
spinlock_t req_list_lock; /* request list lock */
|
||||
struct zfcp_qdio_queue req_q; /* request queue */
|
||||
spinlock_t req_q_lock; /* for operations on queue */
|
||||
int req_q_pci_batch; /* SBALs since PCI indication
|
||||
was last set */
|
||||
u32 fsf_req_seq_no; /* FSF cmnd seq number */
|
||||
wait_queue_head_t request_wq; /* can be used to wait for
|
||||
more avaliable SBALs */
|
||||
|
|
@ -548,7 +496,7 @@ struct zfcp_adapter {
|
|||
actions */
|
||||
u32 erp_low_mem_count; /* nr of erp actions waiting
|
||||
for memory */
|
||||
struct zfcp_port *nameserver_port; /* adapter's nameserver */
|
||||
struct zfcp_wka_port nsp; /* adapter's nameserver */
|
||||
debug_info_t *rec_dbf;
|
||||
debug_info_t *hba_dbf;
|
||||
debug_info_t *san_dbf; /* debug feature areas */
|
||||
|
|
@ -563,11 +511,11 @@ struct zfcp_adapter {
|
|||
struct zfcp_scsi_dbf_record scsi_dbf_buf;
|
||||
struct zfcp_adapter_mempool pool; /* Adapter memory pools */
|
||||
struct qdio_initialize qdio_init_data; /* for qdio_establish */
|
||||
struct device generic_services; /* directory for WKA ports */
|
||||
struct fc_host_statistics *fc_stats;
|
||||
struct fsf_qtcb_bottom_port *stats_reset_data;
|
||||
unsigned long stats_reset;
|
||||
struct work_struct scan_work;
|
||||
atomic_t qdio_outb_full; /* queue full incidents */
|
||||
};
|
||||
|
||||
struct zfcp_port {
|
||||
|
|
@ -579,18 +527,16 @@ struct zfcp_port {
|
|||
refcount drop to zero */
|
||||
struct zfcp_adapter *adapter; /* adapter used to access port */
|
||||
struct list_head unit_list_head; /* head of logical unit list */
|
||||
struct list_head unit_remove_lh; /* head of luns to be removed
|
||||
list */
|
||||
u32 units; /* # of logical units in list */
|
||||
atomic_t status; /* status of this remote port */
|
||||
wwn_t wwnn; /* WWNN if known */
|
||||
wwn_t wwpn; /* WWPN */
|
||||
u64 wwnn; /* WWNN if known */
|
||||
u64 wwpn; /* WWPN */
|
||||
u32 d_id; /* D_ID */
|
||||
u32 handle; /* handle assigned by FSF */
|
||||
struct zfcp_erp_action erp_action; /* pending error recovery */
|
||||
atomic_t erp_counter;
|
||||
u32 maxframe_size;
|
||||
u32 supported_classes;
|
||||
struct work_struct gid_pn_work;
|
||||
};
|
||||
|
||||
struct zfcp_unit {
|
||||
|
|
@ -601,8 +547,7 @@ struct zfcp_unit {
|
|||
refcount drop to zero */
|
||||
struct zfcp_port *port; /* remote port of unit */
|
||||
atomic_t status; /* status of this logical unit */
|
||||
unsigned int scsi_lun; /* own SCSI LUN */
|
||||
fcp_lun_t fcp_lun; /* own FCP_LUN */
|
||||
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 */
|
||||
|
|
@ -625,7 +570,7 @@ struct zfcp_fsf_req {
|
|||
u8 sbal_response; /* SBAL used in interrupt */
|
||||
wait_queue_head_t completion_wq; /* can be used by a routine
|
||||
to wait for completion */
|
||||
volatile u32 status; /* status of this request */
|
||||
u32 status; /* status of this request */
|
||||
u32 fsf_command; /* FSF Command copy */
|
||||
struct fsf_qtcb *qtcb; /* address of associated QTCB */
|
||||
u32 seq_no; /* Sequence number of request */
|
||||
|
|
@ -644,11 +589,7 @@ struct zfcp_fsf_req {
|
|||
struct zfcp_data {
|
||||
struct scsi_host_template scsi_host_template;
|
||||
struct scsi_transport_template *scsi_transport_template;
|
||||
atomic_t status; /* Module status flags */
|
||||
struct list_head adapter_list_head; /* head of adapter list */
|
||||
struct list_head adapter_remove_lh; /* head of adapters to be
|
||||
removed */
|
||||
u32 adapters; /* # of adapters in list */
|
||||
rwlock_t config_lock; /* serialises changes
|
||||
to adapter/port/unit
|
||||
lists */
|
||||
|
|
@ -656,11 +597,12 @@ struct zfcp_data {
|
|||
changes */
|
||||
atomic_t loglevel; /* current loglevel */
|
||||
char init_busid[BUS_ID_SIZE];
|
||||
wwn_t init_wwpn;
|
||||
fcp_lun_t init_fcp_lun;
|
||||
struct kmem_cache *fsf_req_qtcb_cache;
|
||||
struct kmem_cache *sr_buffer_cache;
|
||||
struct kmem_cache *gid_pn_cache;
|
||||
u64 init_wwpn;
|
||||
u64 init_fcp_lun;
|
||||
struct kmem_cache *fsf_req_qtcb_cache;
|
||||
struct kmem_cache *sr_buffer_cache;
|
||||
struct kmem_cache *gid_pn_cache;
|
||||
struct workqueue_struct *work_queue;
|
||||
};
|
||||
|
||||
/* struct used by memory pools for fsf_requests */
|
||||
|
|
@ -677,14 +619,7 @@ struct zfcp_fsf_req_qtcb {
|
|||
#define ZFCP_SET 0x00000100
|
||||
#define ZFCP_CLEAR 0x00000200
|
||||
|
||||
#ifndef atomic_test_mask
|
||||
#define atomic_test_mask(mask, target) \
|
||||
((atomic_read(target) & mask) == mask)
|
||||
#endif
|
||||
|
||||
#define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id)
|
||||
#define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter))
|
||||
#define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port))
|
||||
|
||||
/*
|
||||
* Helper functions for request ID management.
|
||||
|
|
@ -744,12 +679,6 @@ zfcp_unit_put(struct zfcp_unit *unit)
|
|||
wake_up(&unit->remove_wq);
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfcp_unit_wait(struct zfcp_unit *unit)
|
||||
{
|
||||
wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfcp_port_get(struct zfcp_port *port)
|
||||
{
|
||||
|
|
@ -763,12 +692,6 @@ zfcp_port_put(struct zfcp_port *port)
|
|||
wake_up(&port->remove_wq);
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfcp_port_wait(struct zfcp_port *port)
|
||||
{
|
||||
wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfcp_adapter_get(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
|
@ -782,10 +705,4 @@ zfcp_adapter_put(struct zfcp_adapter *adapter)
|
|||
wake_up(&adapter->remove_wq);
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfcp_adapter_wait(struct zfcp_adapter *adapter)
|
||||
{
|
||||
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
|
||||
}
|
||||
|
||||
#endif /* ZFCP_DEF_H */
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ enum zfcp_erp_steps {
|
|||
ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001,
|
||||
ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
|
||||
ZFCP_ERP_STEP_PORT_CLOSING = 0x0100,
|
||||
ZFCP_ERP_STEP_NAMESERVER_OPEN = 0x0200,
|
||||
ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400,
|
||||
ZFCP_ERP_STEP_PORT_OPENING = 0x0800,
|
||||
ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000,
|
||||
|
|
@ -532,8 +531,7 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
|
|||
struct zfcp_port *port;
|
||||
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA))
|
||||
_zfcp_erp_port_reopen(port, clear, id, ref);
|
||||
_zfcp_erp_port_reopen(port, clear, id, ref);
|
||||
}
|
||||
|
||||
static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id,
|
||||
|
|
@ -669,8 +667,6 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
|
|||
int ret;
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
|
||||
|
||||
write_lock_irq(&adapter->erp_lock);
|
||||
zfcp_erp_action_to_running(act);
|
||||
write_unlock_irq(&adapter->erp_lock);
|
||||
|
|
@ -741,8 +737,7 @@ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
|
|||
ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
|
||||
failed_qdio:
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
ZFCP_STATUS_ADAPTER_XPORT_OK,
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
|
||||
&act->adapter->status);
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -751,15 +746,11 @@ static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
|
|||
{
|
||||
int retval;
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status);
|
||||
zfcp_erp_adapter_strategy_generic(act, 1); /* close */
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status);
|
||||
if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
|
||||
return ZFCP_ERP_EXIT;
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status);
|
||||
retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status);
|
||||
|
||||
if (retval == ZFCP_ERP_FAILED)
|
||||
ssleep(8);
|
||||
|
|
@ -783,10 +774,7 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
|
|||
|
||||
static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
|
||||
{
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
|
||||
ZFCP_STATUS_COMMON_CLOSING |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_PORT_DID_DID |
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_PORT_PHYS_CLOSING |
|
||||
ZFCP_STATUS_PORT_INVALID_WWPN,
|
||||
&port->status);
|
||||
|
|
@ -839,73 +827,12 @@ static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
|
|||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
|
||||
static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct zfcp_adapter *adapter = ns_act->adapter;
|
||||
struct zfcp_erp_action *act, *tmp;
|
||||
int status;
|
||||
|
||||
read_lock_irqsave(&adapter->erp_lock, flags);
|
||||
list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) {
|
||||
if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
|
||||
status = atomic_read(&adapter->nameserver_port->status);
|
||||
if (status & ZFCP_STATUS_COMMON_ERP_FAILED)
|
||||
zfcp_erp_port_failed(act->port, 27, NULL);
|
||||
zfcp_erp_action_ready(act);
|
||||
}
|
||||
}
|
||||
read_unlock_irqrestore(&adapter->erp_lock, flags);
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act)
|
||||
{
|
||||
int retval;
|
||||
|
||||
switch (act->step) {
|
||||
case ZFCP_ERP_STEP_UNINITIALIZED:
|
||||
case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
|
||||
case ZFCP_ERP_STEP_PORT_CLOSING:
|
||||
return zfcp_erp_port_strategy_open_port(act);
|
||||
|
||||
case ZFCP_ERP_STEP_PORT_OPENING:
|
||||
if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN)
|
||||
retval = ZFCP_ERP_SUCCEEDED;
|
||||
else
|
||||
retval = ZFCP_ERP_FAILED;
|
||||
/* this is needed anyway */
|
||||
zfcp_erp_port_strategy_open_ns_wake(act);
|
||||
return retval;
|
||||
|
||||
default:
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = zfcp_fc_ns_gid_pn_request(act);
|
||||
if (retval == -ENOMEM)
|
||||
return ZFCP_ERP_NOMEM;
|
||||
act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
|
||||
if (retval)
|
||||
return ZFCP_ERP_FAILED;
|
||||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
|
||||
static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
|
||||
{
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
struct zfcp_port *port = act->port;
|
||||
|
||||
if (port->wwpn != adapter->peer_wwpn) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Failed to open port 0x%016Lx, "
|
||||
"Peer WWPN 0x%016Lx does not "
|
||||
"match.\n", port->wwpn,
|
||||
adapter->peer_wwpn);
|
||||
zfcp_erp_port_failed(port, 25, NULL);
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
|
@ -914,11 +841,25 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
|
|||
return zfcp_erp_port_strategy_open_port(act);
|
||||
}
|
||||
|
||||
void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
|
||||
{
|
||||
int retval;
|
||||
struct zfcp_port *port = container_of(work, struct zfcp_port,
|
||||
gid_pn_work);
|
||||
|
||||
retval = zfcp_fc_ns_gid_pn(&port->erp_action);
|
||||
if (retval == -ENOMEM)
|
||||
zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM);
|
||||
port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
|
||||
if (retval)
|
||||
zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
|
||||
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
|
||||
{
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
struct zfcp_port *port = act->port;
|
||||
struct zfcp_port *ns_port = adapter->nameserver_port;
|
||||
int p_status = atomic_read(&port->status);
|
||||
|
||||
switch (act->step) {
|
||||
|
|
@ -927,28 +868,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
|
|||
case ZFCP_ERP_STEP_PORT_CLOSING:
|
||||
if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
|
||||
return zfcp_erp_open_ptp_port(act);
|
||||
if (!ns_port) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Nameserver port unavailable.\n");
|
||||
return ZFCP_ERP_FAILED;
|
||||
if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
|
||||
queue_work(zfcp_data.work_queue, &port->gid_pn_work);
|
||||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
if (!(atomic_read(&ns_port->status) &
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED)) {
|
||||
/* nameserver port may live again */
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
|
||||
&ns_port->status);
|
||||
if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) {
|
||||
act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN;
|
||||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
/* else nameserver port is already open, fall through */
|
||||
case ZFCP_ERP_STEP_NAMESERVER_OPEN:
|
||||
if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN))
|
||||
return ZFCP_ERP_FAILED;
|
||||
return zfcp_erp_port_strategy_open_lookup(act);
|
||||
|
||||
case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
|
||||
if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
|
||||
if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
|
||||
|
|
@ -961,25 +884,26 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
|
|||
|
||||
case ZFCP_ERP_STEP_PORT_OPENING:
|
||||
/* D_ID might have changed during open */
|
||||
if ((p_status & ZFCP_STATUS_COMMON_OPEN) &&
|
||||
(p_status & ZFCP_STATUS_PORT_DID_DID))
|
||||
return ZFCP_ERP_SUCCEEDED;
|
||||
if (p_status & ZFCP_STATUS_COMMON_OPEN) {
|
||||
if (p_status & ZFCP_STATUS_PORT_DID_DID)
|
||||
return ZFCP_ERP_SUCCEEDED;
|
||||
else {
|
||||
act->step = ZFCP_ERP_STEP_PORT_CLOSING;
|
||||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
/* fall through otherwise */
|
||||
}
|
||||
}
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act)
|
||||
{
|
||||
if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA))
|
||||
return zfcp_erp_port_strategy_open_nameserver(act);
|
||||
return zfcp_erp_port_strategy_open_common(act);
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
struct zfcp_port *port = erp_action->port;
|
||||
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
|
||||
goto close_init_done;
|
||||
|
||||
switch (erp_action->step) {
|
||||
case ZFCP_ERP_STEP_UNINITIALIZED:
|
||||
zfcp_erp_port_strategy_clearstati(port);
|
||||
|
|
@ -992,19 +916,17 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
|
|||
return ZFCP_ERP_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
close_init_done:
|
||||
if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
|
||||
return ZFCP_ERP_EXIT;
|
||||
else
|
||||
return zfcp_erp_port_strategy_open(erp_action);
|
||||
|
||||
return ZFCP_ERP_FAILED;
|
||||
return zfcp_erp_port_strategy_open_common(erp_action);
|
||||
}
|
||||
|
||||
static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
|
||||
{
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
|
||||
ZFCP_STATUS_COMMON_CLOSING |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_UNIT_SHARED |
|
||||
ZFCP_STATUS_UNIT_READONLY,
|
||||
&unit->status);
|
||||
|
|
@ -1065,8 +987,14 @@ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
|
|||
break;
|
||||
case ZFCP_ERP_FAILED :
|
||||
atomic_inc(&unit->erp_counter);
|
||||
if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
|
||||
if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) {
|
||||
dev_err(&unit->port->adapter->ccw_device->dev,
|
||||
"ERP failed for unit 0x%016Lx on "
|
||||
"port 0x%016Lx\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_failed(unit, 21, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1091,8 +1019,12 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
|
|||
result = ZFCP_ERP_EXIT;
|
||||
}
|
||||
atomic_inc(&port->erp_counter);
|
||||
if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
|
||||
if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) {
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"ERP failed for remote port 0x%016Lx\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
zfcp_erp_port_failed(port, 22, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1114,8 +1046,12 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
|
|||
|
||||
case ZFCP_ERP_FAILED :
|
||||
atomic_inc(&adapter->erp_counter);
|
||||
if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
|
||||
if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"ERP cannot recover an error "
|
||||
"on the FCP device\n");
|
||||
zfcp_erp_adapter_failed(adapter, 23, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1250,9 +1186,10 @@ static void zfcp_erp_scsi_scan(struct work_struct *work)
|
|||
struct zfcp_unit *unit = p->unit;
|
||||
struct fc_rport *rport = unit->port->rport;
|
||||
scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
|
||||
unit->scsi_lun, 0);
|
||||
scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0);
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
|
||||
zfcp_unit_put(unit);
|
||||
wake_up(&unit->port->adapter->erp_done_wqh);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
|
|
@ -1263,9 +1200,9 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
|
|||
p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
if (!p) {
|
||||
dev_err(&unit->port->adapter->ccw_device->dev,
|
||||
"Out of resources. Could not register unit "
|
||||
"0x%016Lx on port 0x%016Lx with SCSI stack.\n",
|
||||
unit->fcp_lun, unit->port->wwpn);
|
||||
"Registering unit 0x%016Lx on port 0x%016Lx failed\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1273,7 +1210,7 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
|
|||
atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
|
||||
INIT_WORK(&p->work, zfcp_erp_scsi_scan);
|
||||
p->unit = unit;
|
||||
schedule_work(&p->work);
|
||||
queue_work(zfcp_data.work_queue, &p->work);
|
||||
}
|
||||
|
||||
static void zfcp_erp_rport_register(struct zfcp_port *port)
|
||||
|
|
@ -1286,8 +1223,8 @@ static void zfcp_erp_rport_register(struct zfcp_port *port)
|
|||
port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
|
||||
if (!port->rport) {
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"Failed registration of rport "
|
||||
"0x%016Lx.\n", port->wwpn);
|
||||
"Registering port 0x%016Lx failed\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1299,12 +1236,12 @@ static void zfcp_erp_rport_register(struct zfcp_port *port)
|
|||
static void zfcp_erp_rports_del(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if (port->rport && !(atomic_read(&port->status) &
|
||||
ZFCP_STATUS_PORT_WKA)) {
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
list_for_each_entry(port, &adapter->port_list_head, list) {
|
||||
if (!port->rport)
|
||||
continue;
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
|
|
@ -1459,9 +1396,9 @@ static int zfcp_erp_thread(void *data)
|
|||
zfcp_erp_wakeup(adapter);
|
||||
}
|
||||
|
||||
zfcp_rec_dbf_event_thread(4, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock(4, adapter);
|
||||
down_interruptible(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread(5, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock(5, adapter);
|
||||
}
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
|
||||
|
|
@ -1484,7 +1421,7 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
|
|||
retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
|
||||
if (retval < 0) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Creation of ERP thread failed.\n");
|
||||
"Creating an ERP thread for the FCP device failed.\n");
|
||||
return retval;
|
||||
}
|
||||
wait_event(adapter->erp_thread_wqh,
|
||||
|
|
@ -1506,7 +1443,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
|
|||
{
|
||||
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
|
||||
up(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread_lock(2, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock(3, adapter);
|
||||
|
||||
wait_event(adapter->erp_thread_wqh,
|
||||
!(atomic_read(&adapter->status) &
|
||||
|
|
@ -1526,7 +1463,6 @@ void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
|
|||
{
|
||||
zfcp_erp_modify_adapter_status(adapter, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1539,15 +1475,6 @@ void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
|
|||
{
|
||||
zfcp_erp_modify_port_status(port, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"Port ERP failed for WKA port d_id=0x%06x.\n",
|
||||
port->d_id);
|
||||
else
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"Port ERP failed for port wwpn=0x%016Lx.\n",
|
||||
port->wwpn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1560,10 +1487,6 @@ void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref)
|
|||
{
|
||||
zfcp_erp_modify_unit_status(unit, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
|
||||
dev_err(&unit->port->adapter->ccw_device->dev,
|
||||
"Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n",
|
||||
unit->fcp_lun, unit->port->wwpn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1754,9 +1677,8 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
|
|||
|
||||
if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
|
||||
if (!(status & ZFCP_STATUS_PORT_WKA))
|
||||
list_for_each_entry(unit, &port->unit_list_head, list)
|
||||
zfcp_erp_unit_access_changed(unit, id, ref);
|
||||
list_for_each_entry(unit, &port->unit_list_head, list)
|
||||
zfcp_erp_unit_access_changed(unit, id, ref);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1779,10 +1701,7 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
|
|||
return;
|
||||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
if (adapter->nameserver_port)
|
||||
zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref);
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if (port != adapter->nameserver_port)
|
||||
zfcp_erp_port_access_changed(port, id, ref);
|
||||
zfcp_erp_port_access_changed(port, id, ref);
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,16 +12,14 @@
|
|||
#include "zfcp_def.h"
|
||||
|
||||
/* zfcp_aux.c */
|
||||
extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *,
|
||||
fcp_lun_t);
|
||||
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *,
|
||||
wwn_t);
|
||||
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 int zfcp_adapter_enqueue(struct ccw_device *);
|
||||
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
|
||||
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, u32,
|
||||
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
|
||||
u32);
|
||||
extern void zfcp_port_dequeue(struct zfcp_port *);
|
||||
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t);
|
||||
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
|
||||
extern void zfcp_unit_dequeue(struct zfcp_unit *);
|
||||
extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
|
||||
extern void zfcp_sg_free_table(struct scatterlist *, int);
|
||||
|
|
@ -29,6 +27,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int);
|
|||
|
||||
/* zfcp_ccw.c */
|
||||
extern int zfcp_ccw_register(void);
|
||||
extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *);
|
||||
|
||||
/* zfcp_cfdc.c */
|
||||
extern struct miscdevice zfcp_cfdc_misc;
|
||||
|
|
@ -50,6 +49,8 @@ extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
|
|||
struct fsf_status_read_buffer *);
|
||||
extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int,
|
||||
int);
|
||||
extern void zfcp_hba_dbf_event_berr(struct zfcp_adapter *,
|
||||
struct zfcp_fsf_req *);
|
||||
extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *);
|
||||
extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *);
|
||||
extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *);
|
||||
|
|
@ -91,17 +92,21 @@ extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *);
|
|||
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *);
|
||||
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *);
|
||||
extern void zfcp_erp_timeout_handler(unsigned long);
|
||||
extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
|
||||
|
||||
/* zfcp_fc.c */
|
||||
extern int zfcp_scan_ports(struct zfcp_adapter *);
|
||||
extern void _zfcp_scan_ports_later(struct work_struct *);
|
||||
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
|
||||
extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *);
|
||||
extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *);
|
||||
extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
|
||||
extern void zfcp_test_link(struct zfcp_port *);
|
||||
extern void zfcp_fc_nameserver_init(struct zfcp_adapter *);
|
||||
|
||||
/* zfcp_fsf.c */
|
||||
extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *);
|
||||
extern int zfcp_fsf_close_wka_port(struct zfcp_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 *);
|
||||
|
|
@ -135,10 +140,8 @@ extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
|
|||
extern int zfcp_qdio_allocate(struct zfcp_adapter *);
|
||||
extern void zfcp_qdio_free(struct zfcp_adapter *);
|
||||
extern int zfcp_qdio_send(struct zfcp_fsf_req *);
|
||||
extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req(
|
||||
struct zfcp_fsf_req *);
|
||||
extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr(
|
||||
struct zfcp_fsf_req *);
|
||||
extern struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *);
|
||||
extern struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *);
|
||||
extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long,
|
||||
struct scatterlist *, int);
|
||||
extern int zfcp_qdio_open(struct zfcp_adapter *);
|
||||
|
|
@ -148,14 +151,12 @@ extern void zfcp_qdio_close(struct zfcp_adapter *);
|
|||
extern struct zfcp_data zfcp_data;
|
||||
extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
|
||||
extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
|
||||
extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t);
|
||||
extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
|
||||
extern struct fc_function_template zfcp_transport_functions;
|
||||
|
||||
/* zfcp_sysfs.c */
|
||||
extern struct attribute_group zfcp_sysfs_unit_attrs;
|
||||
extern struct attribute_group zfcp_sysfs_adapter_attrs;
|
||||
extern struct attribute_group zfcp_sysfs_ns_port_attrs;
|
||||
extern struct attribute_group zfcp_sysfs_port_attrs;
|
||||
extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
|
||||
extern struct device_attribute *zfcp_sysfs_shost_attrs[];
|
||||
|
|
|
|||
|
|
@ -39,6 +39,84 @@ struct zfcp_gpn_ft {
|
|||
struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
|
||||
};
|
||||
|
||||
struct zfcp_fc_ns_handler_data {
|
||||
struct completion done;
|
||||
void (*handler)(unsigned long);
|
||||
unsigned long handler_data;
|
||||
};
|
||||
|
||||
static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
|
||||
{
|
||||
if (mutex_lock_interruptible(&wka_port->mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (wka_port->status != ZFCP_WKA_PORT_ONLINE) {
|
||||
wka_port->status = ZFCP_WKA_PORT_OPENING;
|
||||
if (zfcp_fsf_open_wka_port(wka_port))
|
||||
wka_port->status = ZFCP_WKA_PORT_OFFLINE;
|
||||
}
|
||||
|
||||
mutex_unlock(&wka_port->mutex);
|
||||
|
||||
wait_event_timeout(
|
||||
wka_port->completion_wq,
|
||||
wka_port->status == ZFCP_WKA_PORT_ONLINE ||
|
||||
wka_port->status == ZFCP_WKA_PORT_OFFLINE,
|
||||
HZ >> 1);
|
||||
|
||||
if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {
|
||||
atomic_inc(&wka_port->refcount);
|
||||
return 0;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void zfcp_wka_port_offline(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dw = container_of(work, struct delayed_work, work);
|
||||
struct zfcp_wka_port *wka_port =
|
||||
container_of(dw, struct zfcp_wka_port, work);
|
||||
|
||||
wait_event(wka_port->completion_wq,
|
||||
atomic_read(&wka_port->refcount) == 0);
|
||||
|
||||
mutex_lock(&wka_port->mutex);
|
||||
if ((atomic_read(&wka_port->refcount) != 0) ||
|
||||
(wka_port->status != ZFCP_WKA_PORT_ONLINE))
|
||||
goto out;
|
||||
|
||||
wka_port->status = ZFCP_WKA_PORT_CLOSING;
|
||||
if (zfcp_fsf_close_wka_port(wka_port)) {
|
||||
wka_port->status = ZFCP_WKA_PORT_OFFLINE;
|
||||
wake_up(&wka_port->completion_wq);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&wka_port->mutex);
|
||||
}
|
||||
|
||||
static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
|
||||
{
|
||||
if (atomic_dec_return(&wka_port->refcount) != 0)
|
||||
return;
|
||||
/* wait 10 miliseconds, other reqs might pop in */
|
||||
schedule_delayed_work(&wka_port->work, HZ / 100);
|
||||
}
|
||||
|
||||
void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_wka_port *wka_port = &adapter->nsp;
|
||||
|
||||
init_waitqueue_head(&wka_port->completion_wq);
|
||||
|
||||
wka_port->adapter = adapter;
|
||||
wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE;
|
||||
|
||||
wka_port->status = ZFCP_WKA_PORT_OFFLINE;
|
||||
atomic_set(&wka_port->refcount, 0);
|
||||
mutex_init(&wka_port->mutex);
|
||||
INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline);
|
||||
}
|
||||
|
||||
static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
|
||||
struct fcp_rscn_element *elem)
|
||||
{
|
||||
|
|
@ -47,10 +125,8 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
|
|||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
|
||||
if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
|
||||
continue;
|
||||
/* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */
|
||||
if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status))
|
||||
if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID))
|
||||
/* Try to connect to unused ports anyway. */
|
||||
zfcp_erp_port_reopen(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
|
|
@ -102,7 +178,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
|
|||
schedule_work(&fsf_req->adapter->scan_work);
|
||||
}
|
||||
|
||||
static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn)
|
||||
static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
|
||||
{
|
||||
struct zfcp_adapter *adapter = req->adapter;
|
||||
struct zfcp_port *port;
|
||||
|
|
@ -157,7 +233,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
|
|||
zfcp_fc_incoming_rscn(fsf_req);
|
||||
}
|
||||
|
||||
static void zfcp_ns_gid_pn_handler(unsigned long data)
|
||||
static void zfcp_fc_ns_handler(unsigned long data)
|
||||
{
|
||||
struct zfcp_fc_ns_handler_data *compl_rec =
|
||||
(struct zfcp_fc_ns_handler_data *) data;
|
||||
|
||||
if (compl_rec->handler)
|
||||
compl_rec->handler(compl_rec->handler_data);
|
||||
|
||||
complete(&compl_rec->done);
|
||||
}
|
||||
|
||||
static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
|
||||
{
|
||||
struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data;
|
||||
struct zfcp_send_ct *ct = &gid_pn->ct;
|
||||
|
|
@ -166,43 +253,31 @@ static void zfcp_ns_gid_pn_handler(unsigned long data)
|
|||
struct zfcp_port *port = gid_pn->port;
|
||||
|
||||
if (ct->status)
|
||||
goto out;
|
||||
return;
|
||||
if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) {
|
||||
atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
/* paranoia */
|
||||
if (ct_iu_req->wwpn != port->wwpn)
|
||||
goto out;
|
||||
return;
|
||||
/* looks like a valid d_id */
|
||||
port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
|
||||
atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
|
||||
out:
|
||||
mempool_free(gid_pn, port->adapter->pool.data_gid_pn);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
|
||||
* @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
|
||||
* return: -ENOMEM on error, 0 otherwise
|
||||
*/
|
||||
int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action)
|
||||
int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
|
||||
struct zfcp_gid_pn_data *gid_pn)
|
||||
{
|
||||
int ret;
|
||||
struct zfcp_gid_pn_data *gid_pn;
|
||||
struct zfcp_adapter *adapter = erp_action->adapter;
|
||||
|
||||
gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
|
||||
if (!gid_pn)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(gid_pn, 0, sizeof(*gid_pn));
|
||||
struct zfcp_fc_ns_handler_data compl_rec;
|
||||
int ret;
|
||||
|
||||
/* setup parameters for send generic command */
|
||||
gid_pn->port = erp_action->port;
|
||||
gid_pn->ct.port = adapter->nameserver_port;
|
||||
gid_pn->ct.handler = zfcp_ns_gid_pn_handler;
|
||||
gid_pn->ct.handler_data = (unsigned long) gid_pn;
|
||||
gid_pn->ct.wka_port = &adapter->nsp;
|
||||
gid_pn->ct.handler = zfcp_fc_ns_handler;
|
||||
gid_pn->ct.handler_data = (unsigned long) &compl_rec;
|
||||
gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
|
||||
gid_pn->ct.req = &gid_pn->req;
|
||||
gid_pn->ct.resp = &gid_pn->resp;
|
||||
|
|
@ -222,10 +297,42 @@ int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action)
|
|||
gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE;
|
||||
gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
|
||||
|
||||
init_completion(&compl_rec.done);
|
||||
compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
|
||||
compl_rec.handler_data = (unsigned long) gid_pn;
|
||||
ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp,
|
||||
erp_action);
|
||||
if (!ret)
|
||||
wait_for_completion(&compl_rec.done);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
|
||||
* @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
|
||||
* return: -ENOMEM on error, 0 otherwise
|
||||
*/
|
||||
int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
int ret;
|
||||
struct zfcp_gid_pn_data *gid_pn;
|
||||
struct zfcp_adapter *adapter = erp_action->adapter;
|
||||
|
||||
gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
|
||||
if (!gid_pn)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(gid_pn, 0, sizeof(*gid_pn));
|
||||
|
||||
ret = zfcp_wka_port_get(&adapter->nsp);
|
||||
if (ret)
|
||||
mempool_free(gid_pn, adapter->pool.data_gid_pn);
|
||||
goto out;
|
||||
|
||||
ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn);
|
||||
|
||||
zfcp_wka_port_put(&adapter->nsp);
|
||||
out:
|
||||
mempool_free(gid_pn, adapter->pool.data_gid_pn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -255,14 +362,14 @@ struct zfcp_els_adisc {
|
|||
struct scatterlist req;
|
||||
struct scatterlist resp;
|
||||
struct zfcp_ls_adisc ls_adisc;
|
||||
struct zfcp_ls_adisc_acc ls_adisc_acc;
|
||||
struct zfcp_ls_adisc ls_adisc_acc;
|
||||
};
|
||||
|
||||
static void zfcp_fc_adisc_handler(unsigned long data)
|
||||
{
|
||||
struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data;
|
||||
struct zfcp_port *port = adisc->els.port;
|
||||
struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc;
|
||||
struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc;
|
||||
|
||||
if (adisc->els.status) {
|
||||
/* request rejected or timed out */
|
||||
|
|
@ -295,7 +402,7 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
|
|||
sg_init_one(adisc->els.req, &adisc->ls_adisc,
|
||||
sizeof(struct zfcp_ls_adisc));
|
||||
sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
|
||||
sizeof(struct zfcp_ls_adisc_acc));
|
||||
sizeof(struct zfcp_ls_adisc));
|
||||
|
||||
adisc->els.req_count = 1;
|
||||
adisc->els.resp_count = 1;
|
||||
|
|
@ -338,30 +445,6 @@ void zfcp_test_link(struct zfcp_port *port)
|
|||
zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
|
||||
}
|
||||
|
||||
static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!adapter->nameserver_port)
|
||||
return -EINTR;
|
||||
|
||||
if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
|
||||
&adapter->nameserver_port->status)) {
|
||||
ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
zfcp_erp_wait(adapter);
|
||||
}
|
||||
return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
|
||||
&adapter->nameserver_port->status);
|
||||
}
|
||||
|
||||
static void zfcp_gpn_ft_handler(unsigned long _done)
|
||||
{
|
||||
complete((struct completion *)_done);
|
||||
}
|
||||
|
||||
static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft)
|
||||
{
|
||||
struct scatterlist *sg = &gpn_ft->sg_req;
|
||||
|
|
@ -403,7 +486,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
|
|||
{
|
||||
struct zfcp_send_ct *ct = &gpn_ft->ct;
|
||||
struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
|
||||
struct completion done;
|
||||
struct zfcp_fc_ns_handler_data compl_rec;
|
||||
int ret;
|
||||
|
||||
/* prepare CT IU for GPN_FT */
|
||||
|
|
@ -420,19 +503,20 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
|
|||
req->fc4_type = ZFCP_CT_SCSI_FCP;
|
||||
|
||||
/* prepare zfcp_send_ct */
|
||||
ct->port = adapter->nameserver_port;
|
||||
ct->handler = zfcp_gpn_ft_handler;
|
||||
ct->handler_data = (unsigned long)&done;
|
||||
ct->wka_port = &adapter->nsp;
|
||||
ct->handler = zfcp_fc_ns_handler;
|
||||
ct->handler_data = (unsigned long)&compl_rec;
|
||||
ct->timeout = 10;
|
||||
ct->req = &gpn_ft->sg_req;
|
||||
ct->resp = gpn_ft->sg_resp;
|
||||
ct->req_count = 1;
|
||||
ct->resp_count = ZFCP_GPN_FT_BUFFERS;
|
||||
|
||||
init_completion(&done);
|
||||
init_completion(&compl_rec.done);
|
||||
compl_rec.handler = NULL;
|
||||
ret = zfcp_fsf_send_ct(ct, NULL, NULL);
|
||||
if (!ret)
|
||||
wait_for_completion(&done);
|
||||
wait_for_completion(&compl_rec.done);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -442,9 +526,8 @@ static void zfcp_validate_port(struct zfcp_port *port)
|
|||
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
|
||||
|
||||
if (port == adapter->nameserver_port)
|
||||
return;
|
||||
if ((port->supported_classes != 0) || (port->units != 0)) {
|
||||
if ((port->supported_classes != 0) ||
|
||||
!list_empty(&port->unit_list_head)) {
|
||||
zfcp_port_put(port);
|
||||
return;
|
||||
}
|
||||
|
|
@ -460,7 +543,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
|
|||
struct scatterlist *sg = gpn_ft->sg_resp;
|
||||
struct ct_hdr *hdr = sg_virt(sg);
|
||||
struct gpn_ft_resp_acc *acc = sg_virt(sg);
|
||||
struct zfcp_adapter *adapter = ct->port->adapter;
|
||||
struct zfcp_adapter *adapter = ct->wka_port->adapter;
|
||||
struct zfcp_port *port, *tmp;
|
||||
u32 d_id;
|
||||
int ret = 0, x, last = 0;
|
||||
|
|
@ -490,6 +573,9 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
|
|||
d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
|
||||
acc->port_id[2];
|
||||
|
||||
/* don't attach ports with a well known address */
|
||||
if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA)
|
||||
continue;
|
||||
/* skip the adapter's port and known remote ports */
|
||||
if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
|
||||
continue;
|
||||
|
|
@ -528,13 +614,15 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
|
|||
if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT)
|
||||
return 0;
|
||||
|
||||
ret = zfcp_scan_get_nameserver(adapter);
|
||||
ret = zfcp_wka_port_get(&adapter->nsp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gpn_ft = zfcp_alloc_sg_env();
|
||||
if (!gpn_ft)
|
||||
return -ENOMEM;
|
||||
if (!gpn_ft) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter);
|
||||
|
|
@ -547,7 +635,8 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
|
|||
}
|
||||
}
|
||||
zfcp_free_sg_env(gpn_ft);
|
||||
|
||||
out:
|
||||
zfcp_wka_port_put(&adapter->nsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -71,13 +71,6 @@
|
|||
#define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED 0x00000041
|
||||
#define FSF_ELS_COMMAND_REJECTED 0x00000050
|
||||
#define FSF_GENERIC_COMMAND_REJECTED 0x00000051
|
||||
#define FSF_OPERATION_PARTIALLY_SUCCESSFUL 0x00000052
|
||||
#define FSF_AUTHORIZATION_FAILURE 0x00000053
|
||||
#define FSF_CFDC_ERROR_DETECTED 0x00000054
|
||||
#define FSF_CONTROL_FILE_UPDATE_ERROR 0x00000055
|
||||
#define FSF_CONTROL_FILE_TOO_LARGE 0x00000056
|
||||
#define FSF_ACCESS_CONFLICT_DETECTED 0x00000057
|
||||
#define FSF_CONFLICTS_OVERRULED 0x00000058
|
||||
#define FSF_PORT_BOXED 0x00000059
|
||||
#define FSF_LUN_BOXED 0x0000005A
|
||||
#define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE 0x0000005B
|
||||
|
|
@ -85,9 +78,7 @@
|
|||
#define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061
|
||||
#define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062
|
||||
#define FSF_SBAL_MISMATCH 0x00000063
|
||||
#define FSF_OPEN_PORT_WITHOUT_PRLI 0x00000064
|
||||
#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD
|
||||
#define FSF_FCP_RSP_AVAILABLE 0x000000AF
|
||||
#define FSF_UNKNOWN_COMMAND 0x000000E2
|
||||
#define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3
|
||||
#define FSF_INVALID_COMMAND_OPTION 0x000000E5
|
||||
|
|
@ -102,20 +93,9 @@
|
|||
#define FSF_SQ_RETRY_IF_POSSIBLE 0x02
|
||||
#define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED 0x03
|
||||
#define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE 0x04
|
||||
#define FSF_SQ_ULP_PROGRAMMING_ERROR 0x05
|
||||
#define FSF_SQ_COMMAND_ABORTED 0x06
|
||||
#define FSF_SQ_NO_RETRY_POSSIBLE 0x07
|
||||
|
||||
/* FSF status qualifier for CFDC commands */
|
||||
#define FSF_SQ_CFDC_HARDENED_ON_SE 0x00000000
|
||||
#define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE 0x00000001
|
||||
#define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2 0x00000002
|
||||
/* CFDC subtable codes */
|
||||
#define FSF_SQ_CFDC_SUBTABLE_OS 0x0001
|
||||
#define FSF_SQ_CFDC_SUBTABLE_PORT_WWPN 0x0002
|
||||
#define FSF_SQ_CFDC_SUBTABLE_PORT_DID 0x0003
|
||||
#define FSF_SQ_CFDC_SUBTABLE_LUN 0x0004
|
||||
|
||||
/* FSF status qualifier (most significant 4 bytes), local link down */
|
||||
#define FSF_PSQ_LINK_NO_LIGHT 0x00000004
|
||||
#define FSF_PSQ_LINK_WRAP_PLUG 0x00000008
|
||||
|
|
@ -145,7 +125,6 @@
|
|||
#define FSF_STATUS_READ_LINK_UP 0x00000006
|
||||
#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009
|
||||
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
|
||||
#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B
|
||||
#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
|
||||
|
||||
/* status subtypes in status read buffer */
|
||||
|
|
@ -159,20 +138,9 @@
|
|||
|
||||
/* status subtypes for unsolicited status notification lost */
|
||||
#define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001
|
||||
#define FSF_STATUS_READ_SUB_SENSE_DATA 0x00000002
|
||||
#define FSF_STATUS_READ_SUB_LINK_STATUS 0x00000004
|
||||
#define FSF_STATUS_READ_SUB_PORT_CLOSED 0x00000008
|
||||
#define FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD 0x00000010
|
||||
#define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020
|
||||
#define FSF_STATUS_READ_SUB_ACT_HARDENED 0x00000040
|
||||
#define FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT 0x00000080
|
||||
|
||||
/* status subtypes for CFDC */
|
||||
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
|
||||
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
|
||||
|
||||
/* topologie that is detected by the adapter */
|
||||
#define FSF_TOPO_ERROR 0x00000000
|
||||
#define FSF_TOPO_P2P 0x00000001
|
||||
#define FSF_TOPO_FABRIC 0x00000002
|
||||
#define FSF_TOPO_AL 0x00000003
|
||||
|
|
@ -180,17 +148,13 @@
|
|||
/* data direction for FCP commands */
|
||||
#define FSF_DATADIR_WRITE 0x00000001
|
||||
#define FSF_DATADIR_READ 0x00000002
|
||||
#define FSF_DATADIR_READ_WRITE 0x00000003
|
||||
#define FSF_DATADIR_CMND 0x00000004
|
||||
|
||||
/* fc service class */
|
||||
#define FSF_CLASS_1 0x00000001
|
||||
#define FSF_CLASS_2 0x00000002
|
||||
#define FSF_CLASS_3 0x00000003
|
||||
|
||||
/* SBAL chaining */
|
||||
#define FSF_MAX_SBALS_PER_REQ 36
|
||||
#define FSF_MAX_SBALS_PER_ELS_REQ 2
|
||||
|
||||
/* logging space behind QTCB */
|
||||
#define FSF_QTCB_LOG_SIZE 1024
|
||||
|
|
@ -200,50 +164,16 @@
|
|||
#define FSF_FEATURE_LUN_SHARING 0x00000004
|
||||
#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008
|
||||
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
|
||||
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
|
||||
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
|
||||
#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
|
||||
|
||||
/* host connection features */
|
||||
#define FSF_FEATURE_NPIV_MODE 0x00000001
|
||||
#define FSF_FEATURE_VM_ASSIGNED_WWPN 0x00000002
|
||||
|
||||
/* option */
|
||||
#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001
|
||||
#define FSF_OPEN_LUN_REPLICATE_SENSE 0x00000002
|
||||
|
||||
/* adapter types */
|
||||
#define FSF_ADAPTER_TYPE_FICON 0x00000001
|
||||
#define FSF_ADAPTER_TYPE_FICON_EXPRESS 0x00000002
|
||||
|
||||
/* port types */
|
||||
#define FSF_HBA_PORTTYPE_UNKNOWN 0x00000001
|
||||
#define FSF_HBA_PORTTYPE_NOTPRESENT 0x00000003
|
||||
#define FSF_HBA_PORTTYPE_NPORT 0x00000005
|
||||
#define FSF_HBA_PORTTYPE_PTP 0x00000021
|
||||
/* following are not defined and used by FSF Spec
|
||||
but are additionally defined by FC-HBA */
|
||||
#define FSF_HBA_PORTTYPE_OTHER 0x00000002
|
||||
#define FSF_HBA_PORTTYPE_NOTPRESENT 0x00000003
|
||||
#define FSF_HBA_PORTTYPE_NLPORT 0x00000006
|
||||
#define FSF_HBA_PORTTYPE_FLPORT 0x00000007
|
||||
#define FSF_HBA_PORTTYPE_FPORT 0x00000008
|
||||
#define FSF_HBA_PORTTYPE_LPORT 0x00000020
|
||||
|
||||
/* port states */
|
||||
#define FSF_HBA_PORTSTATE_UNKNOWN 0x00000001
|
||||
#define FSF_HBA_PORTSTATE_ONLINE 0x00000002
|
||||
#define FSF_HBA_PORTSTATE_OFFLINE 0x00000003
|
||||
#define FSF_HBA_PORTSTATE_LINKDOWN 0x00000006
|
||||
#define FSF_HBA_PORTSTATE_ERROR 0x00000007
|
||||
|
||||
/* IO states of adapter */
|
||||
#define FSF_IOSTAT_NPORT_RJT 0x00000004
|
||||
#define FSF_IOSTAT_FABRIC_RJT 0x00000005
|
||||
#define FSF_IOSTAT_LS_RJT 0x00000009
|
||||
|
||||
/* open LUN access flags*/
|
||||
#define FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED 0x01000000
|
||||
#define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000
|
||||
#define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000
|
||||
|
||||
|
|
@ -265,11 +195,6 @@ struct fsf_queue_designator {
|
|||
u32 res1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fsf_port_closed_payload {
|
||||
struct fsf_queue_designator queue_designator;
|
||||
u32 port_handle;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fsf_bit_error_payload {
|
||||
u32 res1;
|
||||
u32 link_failure_error_count;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static volatile struct qdio_buffer_element *
|
||||
static struct qdio_buffer_element *
|
||||
zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
|
||||
{
|
||||
return &q->sbal[sbal_idx]->element[sbale_idx];
|
||||
|
|
@ -57,7 +57,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
|
|||
|
||||
static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id)
|
||||
{
|
||||
dev_warn(&adapter->ccw_device->dev, "QDIO problem occurred.\n");
|
||||
dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
|
||||
|
||||
zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
|
|
@ -145,7 +145,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
|
|||
{
|
||||
struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
|
||||
struct zfcp_qdio_queue *queue = &adapter->resp_q;
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
int sbal_idx, sbale_idx, sbal_no;
|
||||
|
||||
if (unlikely(qdio_err)) {
|
||||
|
|
@ -174,8 +174,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
|
|||
|
||||
if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY)))
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"Protocol violation by adapter. "
|
||||
"Continuing operations.\n");
|
||||
"A QDIO protocol error occurred, "
|
||||
"operations continue\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -190,8 +190,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
|
|||
* @fsf_req: pointer to struct fsf_req
|
||||
* Returns: pointer to qdio_buffer_element (SBALE) structure
|
||||
*/
|
||||
volatile struct qdio_buffer_element *
|
||||
zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
|
||||
struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
|
||||
{
|
||||
return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0);
|
||||
}
|
||||
|
|
@ -201,8 +200,7 @@ zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
|
|||
* @fsf_req: pointer to struct fsf_req
|
||||
* Returns: pointer to qdio_buffer_element (SBALE) structure
|
||||
*/
|
||||
volatile struct qdio_buffer_element *
|
||||
zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req)
|
||||
struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req)
|
||||
{
|
||||
return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last,
|
||||
req->sbale_curr);
|
||||
|
|
@ -216,10 +214,10 @@ static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
|
|||
% QDIO_MAX_BUFFERS_PER_Q;
|
||||
}
|
||||
|
||||
static volatile struct qdio_buffer_element *
|
||||
static struct qdio_buffer_element *
|
||||
zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
|
||||
{
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
|
||||
/* set last entry flag in current SBALE of current SBAL */
|
||||
sbale = zfcp_qdio_sbale_curr(fsf_req);
|
||||
|
|
@ -250,7 +248,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
|
|||
return sbale;
|
||||
}
|
||||
|
||||
static volatile struct qdio_buffer_element *
|
||||
static struct qdio_buffer_element *
|
||||
zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
|
||||
{
|
||||
if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
|
||||
|
|
@ -273,7 +271,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
|
|||
unsigned int sbtype, void *start_addr,
|
||||
unsigned int total_length)
|
||||
{
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
unsigned long remaining, length;
|
||||
void *addr;
|
||||
|
||||
|
|
@ -282,6 +280,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
|
|||
addr += length, remaining -= length) {
|
||||
sbale = zfcp_qdio_sbale_next(fsf_req, sbtype);
|
||||
if (!sbale) {
|
||||
atomic_inc(&fsf_req->adapter->qdio_outb_full);
|
||||
zfcp_qdio_undo_sbals(fsf_req);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -307,7 +306,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
|
|||
int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
|
||||
struct scatterlist *sg, int max_sbals)
|
||||
{
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
int retval, bytes = 0;
|
||||
|
||||
/* figure out last allowed SBAL */
|
||||
|
|
@ -344,10 +343,10 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
|
|||
int first = fsf_req->sbal_first;
|
||||
int count = fsf_req->sbal_number;
|
||||
int retval, pci, pci_batch;
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
|
||||
/* acknowledgements for transferred buffers */
|
||||
pci_batch = req_q->pci_batch + count;
|
||||
pci_batch = adapter->req_q_pci_batch + count;
|
||||
if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) {
|
||||
pci_batch %= ZFCP_QDIO_PCI_INTERVAL;
|
||||
pci = first + count - (pci_batch + 1);
|
||||
|
|
@ -367,7 +366,7 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
|
|||
atomic_sub(count, &req_q->count);
|
||||
req_q->first += count;
|
||||
req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
|
||||
req_q->pci_batch = pci_batch;
|
||||
adapter->req_q_pci_batch = pci_batch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -418,14 +417,14 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
|
|||
struct zfcp_qdio_queue *req_q;
|
||||
int first, count;
|
||||
|
||||
if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status))
|
||||
if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
|
||||
return;
|
||||
|
||||
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
|
||||
req_q = &adapter->req_q;
|
||||
spin_lock_bh(&req_q->lock);
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
|
||||
spin_unlock_bh(&req_q->lock);
|
||||
spin_unlock_bh(&adapter->req_q_lock);
|
||||
|
||||
qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
|
||||
|
||||
|
|
@ -438,7 +437,7 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
|
|||
}
|
||||
req_q->first = 0;
|
||||
atomic_set(&req_q->count, 0);
|
||||
req_q->pci_batch = 0;
|
||||
adapter->req_q_pci_batch = 0;
|
||||
adapter->resp_q.first = 0;
|
||||
atomic_set(&adapter->resp_q.count, 0);
|
||||
}
|
||||
|
|
@ -450,23 +449,17 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
|
|||
*/
|
||||
int zfcp_qdio_open(struct zfcp_adapter *adapter)
|
||||
{
|
||||
volatile struct qdio_buffer_element *sbale;
|
||||
struct qdio_buffer_element *sbale;
|
||||
int cc;
|
||||
|
||||
if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status))
|
||||
if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
|
||||
return -EIO;
|
||||
|
||||
if (qdio_establish(&adapter->qdio_init_data)) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Establish of QDIO queues failed.\n");
|
||||
return -EIO;
|
||||
}
|
||||
if (qdio_establish(&adapter->qdio_init_data))
|
||||
goto failed_establish;
|
||||
|
||||
if (qdio_activate(adapter->ccw_device)) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Activate of QDIO queues failed.\n");
|
||||
if (qdio_activate(adapter->ccw_device))
|
||||
goto failed_qdio;
|
||||
}
|
||||
|
||||
for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
|
||||
sbale = &(adapter->resp_q.sbal[cc]->element[0]);
|
||||
|
|
@ -476,20 +469,20 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
|
|||
}
|
||||
|
||||
if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0,
|
||||
QDIO_MAX_BUFFERS_PER_Q)) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Init of QDIO response queue failed.\n");
|
||||
QDIO_MAX_BUFFERS_PER_Q))
|
||||
goto failed_qdio;
|
||||
}
|
||||
|
||||
/* set index of first avalable SBALS / number of available SBALS */
|
||||
adapter->req_q.first = 0;
|
||||
atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
|
||||
adapter->req_q.pci_batch = 0;
|
||||
adapter->req_q_pci_batch = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
failed_qdio:
|
||||
qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
|
||||
failed_establish:
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Setting up the QDIO connection to the FCP adapter failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,20 +21,6 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
|
|||
return fcp_sns_info_ptr;
|
||||
}
|
||||
|
||||
void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl)
|
||||
{
|
||||
fcp_dl_t *fcp_dl_ptr;
|
||||
|
||||
/*
|
||||
* fcp_dl_addr = start address of fcp_cmnd structure +
|
||||
* size of fixed part + size of dynamically sized add_dcp_cdb field
|
||||
* SEE FCP-2 documentation
|
||||
*/
|
||||
fcp_dl_ptr = (fcp_dl_t *) ((unsigned char *) &fcp_cmd[1] +
|
||||
(fcp_cmd->add_fcp_cdb_length << 2));
|
||||
*fcp_dl_ptr = fcp_dl;
|
||||
}
|
||||
|
||||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
||||
{
|
||||
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
|
||||
|
|
@ -119,13 +105,17 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
|
|||
{
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_unit *unit;
|
||||
int scsi_lun;
|
||||
|
||||
list_for_each_entry(port, &adapter->port_list_head, list) {
|
||||
if (!port->rport || (id != port->rport->scsi_target_id))
|
||||
continue;
|
||||
list_for_each_entry(unit, &port->unit_list_head, list)
|
||||
if (lun == unit->scsi_lun)
|
||||
list_for_each_entry(unit, &port->unit_list_head, list) {
|
||||
scsi_lun = scsilun_to_int(
|
||||
(struct scsi_lun *)&unit->fcp_lun);
|
||||
if (lun == scsi_lun)
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -183,7 +173,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
|||
return retval;
|
||||
}
|
||||
fsf_req->data = NULL;
|
||||
fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
|
||||
|
||||
/* don't access old fsf_req after releasing the abort_lock */
|
||||
write_unlock_irqrestore(&adapter->abort_lock, flags);
|
||||
|
|
@ -294,7 +283,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
|||
sizeof (struct zfcp_adapter *));
|
||||
if (!adapter->scsi_host) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"registration with SCSI stack failed.");
|
||||
"Registering the FCP device with the "
|
||||
"SCSI stack failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +302,6 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
|||
scsi_host_put(adapter->scsi_host);
|
||||
return -EIO;
|
||||
}
|
||||
atomic_set_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -336,7 +325,6 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
|
|||
scsi_remove_host(shost);
|
||||
scsi_host_put(shost);
|
||||
adapter->scsi_host = NULL;
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \
|
|||
ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n",
|
||||
atomic_read(&adapter->status));
|
||||
ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n",
|
||||
adapter->peer_wwnn);
|
||||
(unsigned long long) adapter->peer_wwnn);
|
||||
ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n",
|
||||
adapter->peer_wwpn);
|
||||
(unsigned long long) adapter->peer_wwpn);
|
||||
ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n",
|
||||
adapter->peer_d_id);
|
||||
ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n",
|
||||
|
|
@ -135,8 +135,9 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
|
|||
{
|
||||
struct zfcp_adapter *adapter = dev_get_drvdata(dev);
|
||||
struct zfcp_port *port;
|
||||
wwn_t wwpn;
|
||||
u64 wwpn;
|
||||
int retval = 0;
|
||||
LIST_HEAD(port_remove_lh);
|
||||
|
||||
down(&zfcp_data.config_sema);
|
||||
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
|
||||
|
|
@ -144,7 +145,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (strict_strtoull(buf, 0, &wwpn)) {
|
||||
if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -154,7 +155,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
|
|||
if (port && (atomic_read(&port->refcount) == 0)) {
|
||||
zfcp_port_get(port);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||
list_move(&port->list, &adapter->port_remove_lh);
|
||||
list_move(&port->list, &port_remove_lh);
|
||||
} else
|
||||
port = NULL;
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
|
|
@ -200,7 +201,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
|
|||
{
|
||||
struct zfcp_port *port = dev_get_drvdata(dev);
|
||||
struct zfcp_unit *unit;
|
||||
fcp_lun_t fcp_lun;
|
||||
u64 fcp_lun;
|
||||
int retval = -EINVAL;
|
||||
|
||||
down(&zfcp_data.config_sema);
|
||||
|
|
@ -209,7 +210,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (strict_strtoull(buf, 0, &fcp_lun))
|
||||
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
|
||||
goto out;
|
||||
|
||||
unit = zfcp_unit_enqueue(port, fcp_lun);
|
||||
|
|
@ -233,8 +234,9 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
|
|||
{
|
||||
struct zfcp_port *port = dev_get_drvdata(dev);
|
||||
struct zfcp_unit *unit;
|
||||
fcp_lun_t fcp_lun;
|
||||
u64 fcp_lun;
|
||||
int retval = 0;
|
||||
LIST_HEAD(unit_remove_lh);
|
||||
|
||||
down(&zfcp_data.config_sema);
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
|
||||
|
|
@ -242,7 +244,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (strict_strtoull(buf, 0, &fcp_lun)) {
|
||||
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -252,7 +254,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
|
|||
if (unit && (atomic_read(&unit->refcount) == 0)) {
|
||||
zfcp_unit_get(unit);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
|
||||
list_move(&unit->list, &port->unit_remove_lh);
|
||||
list_move(&unit->list, &unit_remove_lh);
|
||||
} else
|
||||
unit = NULL;
|
||||
|
||||
|
|
@ -273,22 +275,7 @@ out:
|
|||
}
|
||||
static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
|
||||
|
||||
static struct attribute *zfcp_port_ns_attrs[] = {
|
||||
&dev_attr_port_failed.attr,
|
||||
&dev_attr_port_in_recovery.attr,
|
||||
&dev_attr_port_status.attr,
|
||||
&dev_attr_port_access_denied.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* zfcp_sysfs_ns_port_attrs - sysfs attributes for nameserver
|
||||
*/
|
||||
struct attribute_group zfcp_sysfs_ns_port_attrs = {
|
||||
.attrs = zfcp_port_ns_attrs,
|
||||
};
|
||||
|
||||
static struct attribute *zfcp_port_no_ns_attrs[] = {
|
||||
static struct attribute *zfcp_port_attrs[] = {
|
||||
&dev_attr_unit_add.attr,
|
||||
&dev_attr_unit_remove.attr,
|
||||
&dev_attr_port_failed.attr,
|
||||
|
|
@ -302,7 +289,7 @@ static struct attribute *zfcp_port_no_ns_attrs[] = {
|
|||
* zfcp_sysfs_port_attrs - sysfs attributes for all other ports
|
||||
*/
|
||||
struct attribute_group zfcp_sysfs_port_attrs = {
|
||||
.attrs = zfcp_port_no_ns_attrs,
|
||||
.attrs = zfcp_port_attrs,
|
||||
};
|
||||
|
||||
static struct attribute *zfcp_unit_attrs[] = {
|
||||
|
|
@ -395,8 +382,10 @@ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
|
|||
|
||||
ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
|
||||
unit->port->adapter->ccw_device->dev.bus_id);
|
||||
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn);
|
||||
ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun);
|
||||
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);
|
||||
|
||||
struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
|
||||
&dev_attr_fcp_lun,
|
||||
|
|
@ -487,10 +476,23 @@ ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n",
|
|||
ZFCP_SHOST_ATTR(seconds_active, "%llu\n",
|
||||
(unsigned long long) stat_info.seconds_act);
|
||||
|
||||
static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct Scsi_Host *scsi_host = class_to_shost(dev);
|
||||
struct zfcp_adapter *adapter =
|
||||
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||
|
||||
return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full));
|
||||
}
|
||||
static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
|
||||
|
||||
struct device_attribute *zfcp_sysfs_shost_attrs[] = {
|
||||
&dev_attr_utilization,
|
||||
&dev_attr_requests,
|
||||
&dev_attr_megabytes,
|
||||
&dev_attr_seconds_active,
|
||||
&dev_attr_queue_full,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue