mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -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: (119 commits) [SCSI] scsi_dh_rdac: Retry for NOT_READY check condition [SCSI] mpt2sas: make global symbols unique [SCSI] sd: Make revalidate less chatty [SCSI] sd: Try READ CAPACITY 16 first for SBC-2 devices [SCSI] sd: Refactor sd_read_capacity() [SCSI] mpt2sas v00.100.11.15 [SCSI] mpt2sas: add MPT2SAS_MINOR(221) to miscdevice.h [SCSI] ch: Add scsi type modalias [SCSI] 3w-9xxx: add power management support [SCSI] bsg: add linux/types.h include to bsg.h [SCSI] cxgb3i: fix function descriptions [SCSI] libiscsi: fix possbile null ptr session command cleanup [SCSI] iscsi class: remove host no argument from session creation callout [SCSI] libiscsi: pass session failure a session struct [SCSI] iscsi lib: remove qdepth param from iscsi host allocation [SCSI] iscsi lib: have lib create work queue for transmitting IO [SCSI] iscsi class: fix lock dep warning on logout [SCSI] libiscsi: don't cap queue depth in iscsi modules [SCSI] iscsi_tcp: replace scsi_debug/tcp_debug logging with iscsi conn logging [SCSI] libiscsi_tcp: replace tcp_debug/scsi_debug logging with session/conn logging ...
This commit is contained in:
commit
d54b3538b0
118 changed files with 28866 additions and 1889 deletions
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Module interface and handling of zfcp data structures.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -249,8 +249,8 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
|
|||
struct zfcp_port *port;
|
||||
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if ((port->wwpn == wwpn) && !(atomic_read(&port->status) &
|
||||
(ZFCP_STATUS_PORT_NO_WWPN | ZFCP_STATUS_COMMON_REMOVE)))
|
||||
if ((port->wwpn == wwpn) &&
|
||||
!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE))
|
||||
return port;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -421,7 +421,8 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter)
|
|||
while (atomic_read(&adapter->stat_miss) > 0)
|
||||
if (zfcp_fsf_status_read(adapter)) {
|
||||
if (atomic_read(&adapter->stat_miss) >= 16) {
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 103, NULL);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "axsref1",
|
||||
NULL);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -501,6 +502,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
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->qdio_stat_lock);
|
||||
|
||||
rwlock_init(&adapter->erp_lock);
|
||||
rwlock_init(&adapter->abort_lock);
|
||||
|
|
@ -522,7 +524,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
goto sysfs_failed;
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
|
||||
zfcp_fc_nameserver_init(adapter);
|
||||
|
||||
if (!zfcp_adapter_scsi_register(adapter))
|
||||
return 0;
|
||||
|
|
@ -552,6 +553,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
|
|||
|
||||
cancel_work_sync(&adapter->scan_work);
|
||||
cancel_work_sync(&adapter->stat_work);
|
||||
cancel_delayed_work_sync(&adapter->nsp.work);
|
||||
zfcp_adapter_scsi_unregister(adapter);
|
||||
sysfs_remove_group(&adapter->ccw_device->dev.kobj,
|
||||
&zfcp_sysfs_adapter_attrs);
|
||||
|
|
@ -603,10 +605,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
|
|||
init_waitqueue_head(&port->remove_wq);
|
||||
INIT_LIST_HEAD(&port->unit_list_head);
|
||||
INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);
|
||||
INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
|
||||
INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
|
||||
|
||||
port->adapter = adapter;
|
||||
port->d_id = d_id;
|
||||
port->wwpn = wwpn;
|
||||
port->rport_task = RPORT_NONE;
|
||||
|
||||
/* mark port unusable as long as sysfs registration is not complete */
|
||||
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||
|
|
@ -620,11 +625,10 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
|
|||
dev_set_drvdata(&port->sysfs_device, port);
|
||||
|
||||
read_lock_irq(&zfcp_data.config_lock);
|
||||
if (!(status & ZFCP_STATUS_PORT_NO_WWPN))
|
||||
if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
|
||||
read_unlock_irq(&zfcp_data.config_lock);
|
||||
goto err_out_free;
|
||||
}
|
||||
if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
|
||||
read_unlock_irq(&zfcp_data.config_lock);
|
||||
goto err_out_free;
|
||||
}
|
||||
read_unlock_irq(&zfcp_data.config_lock);
|
||||
|
||||
if (device_register(&port->sysfs_device))
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Registration and callback for the s390 common I/O layer.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
|
|
@ -72,8 +72,7 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
|
|||
|
||||
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)
|
||||
if (unit->device)
|
||||
scsi_remove_device(unit->device);
|
||||
zfcp_unit_dequeue(unit);
|
||||
}
|
||||
|
|
@ -109,11 +108,12 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
|
|||
/* initialize request counter */
|
||||
BUG_ON(!zfcp_reqlist_isempty(adapter));
|
||||
adapter->req_no = 0;
|
||||
zfcp_fc_nameserver_init(adapter);
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, 10, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
|
||||
NULL);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"ccsonl2", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
up(&zfcp_data.config_sema);
|
||||
flush_work(&adapter->scan_work);
|
||||
|
|
@ -137,7 +137,7 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
|
|||
|
||||
down(&zfcp_data.config_sema);
|
||||
adapter = dev_get_drvdata(&ccw_device->dev);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
zfcp_erp_thread_kill(adapter);
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
@ -160,21 +160,21 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
|
|||
case CIO_GONE:
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"The FCP device has been detached\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
|
||||
break;
|
||||
case CIO_NO_PATH:
|
||||
dev_warn(&adapter->ccw_device->dev,
|
||||
"The CHPID for the FCP device is offline\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
|
||||
break;
|
||||
case CIO_OPER:
|
||||
dev_info(&adapter->ccw_device->dev,
|
||||
"The FCP device is operational again\n");
|
||||
zfcp_erp_modify_adapter_status(adapter, 11, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
89, NULL);
|
||||
"ccnoti4", NULL);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -190,7 +190,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
|
|||
|
||||
down(&zfcp_data.config_sema);
|
||||
adapter = dev_get_drvdata(&cdev->dev);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
up(&zfcp_data.config_sema);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,172 +490,17 @@ static const char *zfcp_rec_dbf_tags[] = {
|
|||
[ZFCP_REC_DBF_ID_ACTION] = "action",
|
||||
};
|
||||
|
||||
static const char *zfcp_rec_dbf_ids[] = {
|
||||
[1] = "new",
|
||||
[2] = "ready",
|
||||
[3] = "kill",
|
||||
[4] = "down sleep",
|
||||
[5] = "down wakeup",
|
||||
[6] = "down sleep ecd",
|
||||
[7] = "down wakeup ecd",
|
||||
[8] = "down sleep epd",
|
||||
[9] = "down wakeup epd",
|
||||
[10] = "online",
|
||||
[11] = "operational",
|
||||
[12] = "scsi slave destroy",
|
||||
[13] = "propagate failed adapter",
|
||||
[14] = "propagate failed port",
|
||||
[15] = "block adapter",
|
||||
[16] = "unblock adapter",
|
||||
[17] = "block port",
|
||||
[18] = "unblock port",
|
||||
[19] = "block unit",
|
||||
[20] = "unblock unit",
|
||||
[21] = "unit recovery failed",
|
||||
[22] = "port recovery failed",
|
||||
[23] = "adapter recovery failed",
|
||||
[24] = "qdio queues down",
|
||||
[25] = "p2p failed",
|
||||
[26] = "nameserver lookup failed",
|
||||
[27] = "nameserver port failed",
|
||||
[28] = "link up",
|
||||
[29] = "link down",
|
||||
[30] = "link up status read",
|
||||
[31] = "open port failed",
|
||||
[32] = "",
|
||||
[33] = "close port",
|
||||
[34] = "open unit failed",
|
||||
[35] = "exclusive open unit failed",
|
||||
[36] = "shared open unit failed",
|
||||
[37] = "link down",
|
||||
[38] = "link down status read no link",
|
||||
[39] = "link down status read fdisc login",
|
||||
[40] = "link down status read firmware update",
|
||||
[41] = "link down status read unknown reason",
|
||||
[42] = "link down ecd incomplete",
|
||||
[43] = "link down epd incomplete",
|
||||
[44] = "sysfs adapter recovery",
|
||||
[45] = "sysfs port recovery",
|
||||
[46] = "sysfs unit recovery",
|
||||
[47] = "port boxed abort",
|
||||
[48] = "unit boxed abort",
|
||||
[49] = "port boxed ct",
|
||||
[50] = "port boxed close physical",
|
||||
[51] = "port boxed open unit",
|
||||
[52] = "port boxed close unit",
|
||||
[53] = "port boxed fcp",
|
||||
[54] = "unit boxed fcp",
|
||||
[55] = "port access denied",
|
||||
[56] = "",
|
||||
[57] = "",
|
||||
[58] = "",
|
||||
[59] = "unit access denied",
|
||||
[60] = "shared unit access denied open unit",
|
||||
[61] = "",
|
||||
[62] = "request timeout",
|
||||
[63] = "adisc link test reject or timeout",
|
||||
[64] = "adisc link test d_id changed",
|
||||
[65] = "adisc link test failed",
|
||||
[66] = "recovery out of memory",
|
||||
[67] = "adapter recovery repeated after state change",
|
||||
[68] = "port recovery repeated after state change",
|
||||
[69] = "unit recovery repeated after state change",
|
||||
[70] = "port recovery follow-up after successful adapter recovery",
|
||||
[71] = "adapter recovery escalation after failed adapter recovery",
|
||||
[72] = "port recovery follow-up after successful physical port "
|
||||
"recovery",
|
||||
[73] = "adapter recovery escalation after failed physical port "
|
||||
"recovery",
|
||||
[74] = "unit recovery follow-up after successful port recovery",
|
||||
[75] = "physical port recovery escalation after failed port "
|
||||
"recovery",
|
||||
[76] = "port recovery escalation after failed unit recovery",
|
||||
[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] = "wka port handle not valid close port",
|
||||
[85] = "online",
|
||||
[86] = "offline",
|
||||
[87] = "ccw device gone",
|
||||
[88] = "ccw device no path",
|
||||
[89] = "ccw device operational",
|
||||
[90] = "ccw device shutdown",
|
||||
[91] = "sysfs port addition",
|
||||
[92] = "sysfs port removal",
|
||||
[93] = "sysfs adapter recovery",
|
||||
[94] = "sysfs unit addition",
|
||||
[95] = "sysfs unit removal",
|
||||
[96] = "sysfs port recovery",
|
||||
[97] = "sysfs unit recovery",
|
||||
[98] = "sequence number mismatch",
|
||||
[99] = "link up",
|
||||
[100] = "error state",
|
||||
[101] = "status read physical port closed",
|
||||
[102] = "link up status read",
|
||||
[103] = "too many failed status read buffers",
|
||||
[104] = "port handle not valid abort",
|
||||
[105] = "lun handle not valid abort",
|
||||
[106] = "port handle not valid ct",
|
||||
[107] = "port handle not valid close port",
|
||||
[108] = "port handle not valid close physical port",
|
||||
[109] = "port handle not valid open unit",
|
||||
[110] = "port handle not valid close unit",
|
||||
[111] = "lun handle not valid close unit",
|
||||
[112] = "port handle not valid fcp",
|
||||
[113] = "lun handle not valid fcp",
|
||||
[114] = "handle mismatch fcp",
|
||||
[115] = "lun not valid fcp",
|
||||
[116] = "qdio send failed",
|
||||
[117] = "version mismatch",
|
||||
[118] = "incompatible qtcb type",
|
||||
[119] = "unknown protocol status",
|
||||
[120] = "unknown fsf command",
|
||||
[121] = "no recommendation for status qualifier",
|
||||
[122] = "status read physical port closed in error",
|
||||
[123] = "fc service class not supported",
|
||||
[124] = "",
|
||||
[125] = "need newer zfcp",
|
||||
[126] = "need newer microcode",
|
||||
[127] = "arbitrated loop not supported",
|
||||
[128] = "",
|
||||
[129] = "qtcb size mismatch",
|
||||
[130] = "unknown fsf status ecd",
|
||||
[131] = "fcp request too big",
|
||||
[132] = "",
|
||||
[133] = "data direction not valid fcp",
|
||||
[134] = "command length not valid fcp",
|
||||
[135] = "status read act update",
|
||||
[136] = "status read cfdc update",
|
||||
[137] = "hbaapi port open",
|
||||
[138] = "hbaapi unit open",
|
||||
[139] = "hbaapi unit shutdown",
|
||||
[140] = "qdio error outbound",
|
||||
[141] = "scsi host reset",
|
||||
[142] = "dismissing fsf request for recovery action",
|
||||
[143] = "recovery action timed out",
|
||||
[144] = "recovery action gone",
|
||||
[145] = "recovery action being processed",
|
||||
[146] = "recovery action ready for next step",
|
||||
[147] = "qdio error inbound",
|
||||
[148] = "nameserver needed for port scan",
|
||||
[149] = "port scan",
|
||||
[150] = "ptp attach",
|
||||
[151] = "port validation failed",
|
||||
};
|
||||
|
||||
static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
|
||||
char *buf, const char *_rec)
|
||||
{
|
||||
struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
|
||||
char *p = buf;
|
||||
char hint[ZFCP_DBF_ID_SIZE + 1];
|
||||
|
||||
memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE);
|
||||
hint[ZFCP_DBF_ID_SIZE] = 0;
|
||||
zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
|
||||
zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]);
|
||||
zfcp_dbf_out(&p, "id", "%d", r->id2);
|
||||
zfcp_dbf_outs(&p, "hint", hint);
|
||||
switch (r->id) {
|
||||
case ZFCP_REC_DBF_ID_THREAD:
|
||||
zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
|
||||
|
|
@ -707,7 +552,7 @@ static struct debug_view zfcp_rec_dbf_view = {
|
|||
* @adapter: adapter
|
||||
* This function assumes that the caller is holding erp_lock.
|
||||
*/
|
||||
void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
|
||||
void zfcp_rec_dbf_event_thread(char *id2, struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
|
||||
unsigned long flags = 0;
|
||||
|
|
@ -723,7 +568,7 @@ void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
|
|||
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->id = ZFCP_REC_DBF_ID_THREAD;
|
||||
r->id2 = id2;
|
||||
memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
|
||||
r->u.thread.total = total;
|
||||
r->u.thread.ready = ready;
|
||||
r->u.thread.running = running;
|
||||
|
|
@ -737,7 +582,7 @@ void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
|
|||
* @adapter: adapter
|
||||
* This function assumes that the caller does not hold erp_lock.
|
||||
*/
|
||||
void zfcp_rec_dbf_event_thread_lock(u8 id2, struct zfcp_adapter *adapter)
|
||||
void zfcp_rec_dbf_event_thread_lock(char *id2, struct zfcp_adapter *adapter)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -746,7 +591,7 @@ void zfcp_rec_dbf_event_thread_lock(u8 id2, struct zfcp_adapter *adapter)
|
|||
read_unlock_irqrestore(&adapter->erp_lock, flags);
|
||||
}
|
||||
|
||||
static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
|
||||
static void zfcp_rec_dbf_event_target(char *id2, void *ref,
|
||||
struct zfcp_adapter *adapter,
|
||||
atomic_t *status, atomic_t *erp_count,
|
||||
u64 wwpn, u32 d_id, u64 fcp_lun)
|
||||
|
|
@ -757,7 +602,7 @@ static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
|
|||
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->id = ZFCP_REC_DBF_ID_TARGET;
|
||||
r->id2 = id2;
|
||||
memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
|
||||
r->u.target.ref = (unsigned long)ref;
|
||||
r->u.target.status = atomic_read(status);
|
||||
r->u.target.wwpn = wwpn;
|
||||
|
|
@ -774,7 +619,8 @@ static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
|
|||
* @ref: additional reference (e.g. request)
|
||||
* @adapter: adapter
|
||||
*/
|
||||
void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
|
||||
void zfcp_rec_dbf_event_adapter(char *id, void *ref,
|
||||
struct zfcp_adapter *adapter)
|
||||
{
|
||||
zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
|
||||
&adapter->erp_counter, 0, 0, 0);
|
||||
|
|
@ -786,7 +632,7 @@ void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
|
|||
* @ref: additional reference (e.g. request)
|
||||
* @port: port
|
||||
*/
|
||||
void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
|
||||
void zfcp_rec_dbf_event_port(char *id, void *ref, struct zfcp_port *port)
|
||||
{
|
||||
struct zfcp_adapter *adapter = port->adapter;
|
||||
|
||||
|
|
@ -801,7 +647,7 @@ void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
|
|||
* @ref: additional reference (e.g. request)
|
||||
* @unit: unit
|
||||
*/
|
||||
void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
|
||||
void zfcp_rec_dbf_event_unit(char *id, void *ref, struct zfcp_unit *unit)
|
||||
{
|
||||
struct zfcp_port *port = unit->port;
|
||||
struct zfcp_adapter *adapter = port->adapter;
|
||||
|
|
@ -822,7 +668,7 @@ void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
|
|||
* @port: port
|
||||
* @unit: unit
|
||||
*/
|
||||
void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
|
||||
void zfcp_rec_dbf_event_trigger(char *id2, void *ref, u8 want, u8 need,
|
||||
void *action, struct zfcp_adapter *adapter,
|
||||
struct zfcp_port *port, struct zfcp_unit *unit)
|
||||
{
|
||||
|
|
@ -832,7 +678,7 @@ void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
|
|||
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->id = ZFCP_REC_DBF_ID_TRIGGER;
|
||||
r->id2 = id2;
|
||||
memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
|
||||
r->u.trigger.ref = (unsigned long)ref;
|
||||
r->u.trigger.want = want;
|
||||
r->u.trigger.need = need;
|
||||
|
|
@ -855,7 +701,7 @@ void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
|
|||
* @id2: identifier
|
||||
* @erp_action: error recovery action struct pointer
|
||||
*/
|
||||
void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
|
||||
void zfcp_rec_dbf_event_action(char *id2, struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
struct zfcp_adapter *adapter = erp_action->adapter;
|
||||
struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
|
||||
|
|
@ -864,7 +710,7 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
|
|||
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->id = ZFCP_REC_DBF_ID_ACTION;
|
||||
r->id2 = id2;
|
||||
memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
|
||||
r->u.action.action = (unsigned long)erp_action;
|
||||
r->u.action.status = erp_action->status;
|
||||
r->u.action.step = erp_action->step;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "zfcp_fsf.h"
|
||||
|
||||
#define ZFCP_DBF_TAG_SIZE 4
|
||||
#define ZFCP_DBF_ID_SIZE 7
|
||||
|
||||
struct zfcp_dbf_dump {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
|
|
@ -70,7 +71,7 @@ struct zfcp_rec_dbf_record_action {
|
|||
|
||||
struct zfcp_rec_dbf_record {
|
||||
u8 id;
|
||||
u8 id2;
|
||||
char id2[7];
|
||||
union {
|
||||
struct zfcp_rec_dbf_record_action action;
|
||||
struct zfcp_rec_dbf_record_thread thread;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Global definitions for the zfcp device driver.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_DEF_H
|
||||
|
|
@ -243,9 +243,6 @@ struct zfcp_ls_adisc {
|
|||
|
||||
/* remote port status */
|
||||
#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
|
||||
#define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004
|
||||
#define ZFCP_STATUS_PORT_NO_WWPN 0x00000008
|
||||
#define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020
|
||||
|
||||
/* well known address (WKA) port status*/
|
||||
enum zfcp_wka_status {
|
||||
|
|
@ -258,7 +255,6 @@ enum zfcp_wka_status {
|
|||
/* logical unit status */
|
||||
#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) */
|
||||
|
|
@ -447,8 +443,9 @@ struct zfcp_adapter {
|
|||
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 */
|
||||
ktime_t req_q_time; /* time of last fill level change */
|
||||
u64 req_q_util; /* for accounting */
|
||||
spinlock_t qdio_stat_lock;
|
||||
u32 fsf_req_seq_no; /* FSF cmnd seq number */
|
||||
wait_queue_head_t request_wq; /* can be used to wait for
|
||||
more avaliable SBALs */
|
||||
|
|
@ -514,6 +511,9 @@ struct zfcp_port {
|
|||
u32 maxframe_size;
|
||||
u32 supported_classes;
|
||||
struct work_struct gid_pn_work;
|
||||
struct work_struct test_link_work;
|
||||
struct work_struct rport_work;
|
||||
enum { RPORT_NONE, RPORT_ADD, RPORT_DEL } rport_task;
|
||||
};
|
||||
|
||||
struct zfcp_unit {
|
||||
|
|
@ -587,9 +587,6 @@ struct zfcp_fsf_req_qtcb {
|
|||
|
||||
/********************** ZFCP SPECIFIC DEFINES ********************************/
|
||||
|
||||
#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
|
||||
#define ZFCP_REQ_NO_QTCB 0x00000008
|
||||
|
||||
#define ZFCP_SET 0x00000100
|
||||
#define ZFCP_CLEAR 0x00000200
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Error Recovery Procedures (ERP).
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
|
|
@ -55,7 +55,7 @@ enum zfcp_erp_act_result {
|
|||
|
||||
static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int mask)
|
||||
{
|
||||
zfcp_erp_modify_adapter_status(adapter, 15, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "erablk1", NULL,
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED | mask,
|
||||
ZFCP_CLEAR);
|
||||
}
|
||||
|
|
@ -75,9 +75,9 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
|
|||
struct zfcp_adapter *adapter = act->adapter;
|
||||
|
||||
list_move(&act->list, &act->adapter->erp_ready_head);
|
||||
zfcp_rec_dbf_event_action(146, act);
|
||||
zfcp_rec_dbf_event_action("erardy1", act);
|
||||
up(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread(2, adapter);
|
||||
zfcp_rec_dbf_event_thread("erardy2", adapter);
|
||||
}
|
||||
|
||||
static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
|
||||
|
|
@ -208,7 +208,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
|
|||
|
||||
static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
|
||||
struct zfcp_port *port,
|
||||
struct zfcp_unit *unit, u8 id, void *ref)
|
||||
struct zfcp_unit *unit, char *id, void *ref)
|
||||
{
|
||||
int retval = 1, need;
|
||||
struct zfcp_erp_action *act = NULL;
|
||||
|
|
@ -228,7 +228,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
|
|||
++adapter->erp_total_count;
|
||||
list_add_tail(&act->list, &adapter->erp_ready_head);
|
||||
up(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread(1, adapter);
|
||||
zfcp_rec_dbf_event_thread("eracte1", adapter);
|
||||
retval = 0;
|
||||
out:
|
||||
zfcp_rec_dbf_event_trigger(id, ref, want, need, act,
|
||||
|
|
@ -237,13 +237,14 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
|
|||
}
|
||||
|
||||
static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
|
||||
int clear_mask, u8 id, void *ref)
|
||||
int clear_mask, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_adapter_block(adapter, clear_mask);
|
||||
zfcp_scsi_schedule_rports_block(adapter);
|
||||
|
||||
/* ensure propagation of failed status to new devices */
|
||||
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
|
||||
zfcp_erp_adapter_failed(adapter, 13, NULL);
|
||||
zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
|
||||
return -EIO;
|
||||
}
|
||||
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
|
||||
|
|
@ -258,7 +259,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
|
|||
* @ref: Reference for debug trace event.
|
||||
*/
|
||||
void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
|
||||
u8 id, void *ref)
|
||||
char *id, void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -277,7 +278,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
|
|||
* @ref: Reference for debug trace event.
|
||||
*/
|
||||
void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
|
||||
u8 id, void *ref)
|
||||
char *id, void *ref)
|
||||
{
|
||||
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
|
||||
zfcp_erp_adapter_reopen(adapter, clear | flags, id, ref);
|
||||
|
|
@ -290,7 +291,8 @@ void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
|
|||
* @id: Id for debug trace event.
|
||||
* @ref: Reference for debug trace event.
|
||||
*/
|
||||
void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, u8 id, void *ref)
|
||||
void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
|
||||
zfcp_erp_port_reopen(port, clear | flags, id, ref);
|
||||
|
|
@ -303,7 +305,8 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, u8 id, void *ref)
|
|||
* @id: Id for debug trace event.
|
||||
* @ref: Reference for debug trace event.
|
||||
*/
|
||||
void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, u8 id, void *ref)
|
||||
void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
|
||||
zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
|
||||
|
|
@ -311,15 +314,16 @@ void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, u8 id, void *ref)
|
|||
|
||||
static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
|
||||
{
|
||||
zfcp_erp_modify_port_status(port, 17, NULL,
|
||||
zfcp_erp_modify_port_status(port, "erpblk1", NULL,
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED | clear,
|
||||
ZFCP_CLEAR);
|
||||
}
|
||||
|
||||
static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
|
||||
int clear, u8 id, void *ref)
|
||||
int clear, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_port_block(port, clear);
|
||||
zfcp_scsi_schedule_rport_block(port);
|
||||
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
||||
return;
|
||||
|
|
@ -334,7 +338,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
|
|||
* @id: Id for debug trace event.
|
||||
* @ref: Reference for debug trace event.
|
||||
*/
|
||||
void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, u8 id,
|
||||
void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
@ -347,14 +351,15 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, u8 id,
|
|||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
||||
static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id,
|
||||
static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
zfcp_erp_port_block(port, clear);
|
||||
zfcp_scsi_schedule_rport_block(port);
|
||||
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
|
||||
/* ensure propagation of failed status to new devices */
|
||||
zfcp_erp_port_failed(port, 14, NULL);
|
||||
zfcp_erp_port_failed(port, "erpreo1", NULL);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +374,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id,
|
|||
*
|
||||
* Returns 0 if recovery has been triggered, < 0 if not.
|
||||
*/
|
||||
int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, void *ref)
|
||||
int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
int retval;
|
||||
|
|
@ -386,12 +391,12 @@ int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, void *ref)
|
|||
|
||||
static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
|
||||
{
|
||||
zfcp_erp_modify_unit_status(unit, 19, NULL,
|
||||
zfcp_erp_modify_unit_status(unit, "erublk1", NULL,
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
|
||||
ZFCP_CLEAR);
|
||||
}
|
||||
|
||||
static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id,
|
||||
static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
|
|
@ -411,7 +416,8 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id,
|
|||
* @clear_mask: specifies flags in unit status to be cleared
|
||||
* Return: 0 on success, < 0 on error
|
||||
*/
|
||||
void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id, void *ref)
|
||||
void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
|
||||
void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct zfcp_port *port = unit->port;
|
||||
|
|
@ -437,28 +443,28 @@ static int status_change_clear(unsigned long mask, atomic_t *status)
|
|||
static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
|
||||
{
|
||||
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
|
||||
zfcp_rec_dbf_event_adapter(16, NULL, adapter);
|
||||
zfcp_rec_dbf_event_adapter("eraubl1", NULL, adapter);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
|
||||
}
|
||||
|
||||
static void zfcp_erp_port_unblock(struct zfcp_port *port)
|
||||
{
|
||||
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
|
||||
zfcp_rec_dbf_event_port(18, NULL, port);
|
||||
zfcp_rec_dbf_event_port("erpubl1", NULL, port);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
|
||||
}
|
||||
|
||||
static void zfcp_erp_unit_unblock(struct zfcp_unit *unit)
|
||||
{
|
||||
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))
|
||||
zfcp_rec_dbf_event_unit(20, NULL, unit);
|
||||
zfcp_rec_dbf_event_unit("eruubl1", NULL, unit);
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
|
||||
}
|
||||
|
||||
static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
|
||||
zfcp_rec_dbf_event_action(145, erp_action);
|
||||
zfcp_rec_dbf_event_action("erator1", erp_action);
|
||||
}
|
||||
|
||||
static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
|
||||
|
|
@ -474,11 +480,11 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
|
|||
if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
|
||||
ZFCP_STATUS_ERP_TIMEDOUT)) {
|
||||
act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
|
||||
zfcp_rec_dbf_event_action(142, act);
|
||||
zfcp_rec_dbf_event_action("erscf_1", act);
|
||||
act->fsf_req->erp_action = NULL;
|
||||
}
|
||||
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
|
||||
zfcp_rec_dbf_event_action(143, act);
|
||||
zfcp_rec_dbf_event_action("erscf_2", act);
|
||||
if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
|
||||
ZFCP_STATUS_FSFREQ_DISMISSED))
|
||||
act->fsf_req = NULL;
|
||||
|
|
@ -530,7 +536,7 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
|
|||
}
|
||||
|
||||
static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
|
||||
int clear, u8 id, void *ref)
|
||||
int clear, char *id, void *ref)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
||||
|
|
@ -538,8 +544,8 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
|
|||
_zfcp_erp_port_reopen(port, clear, id, ref);
|
||||
}
|
||||
|
||||
static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id,
|
||||
void *ref)
|
||||
static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
|
||||
char *id, void *ref)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
|
||||
|
|
@ -559,28 +565,28 @@ static void zfcp_erp_strategy_followup_actions(struct zfcp_erp_action *act)
|
|||
|
||||
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
|
||||
if (status == ZFCP_ERP_SUCCEEDED)
|
||||
_zfcp_erp_port_reopen_all(adapter, 0, 70, NULL);
|
||||
_zfcp_erp_port_reopen_all(adapter, 0, "ersfa_1", NULL);
|
||||
else
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, 71, NULL);
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_2", NULL);
|
||||
break;
|
||||
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
|
||||
if (status == ZFCP_ERP_SUCCEEDED)
|
||||
_zfcp_erp_port_reopen(port, 0, 72, NULL);
|
||||
_zfcp_erp_port_reopen(port, 0, "ersfa_3", NULL);
|
||||
else
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, 73, NULL);
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_4", NULL);
|
||||
break;
|
||||
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT:
|
||||
if (status == ZFCP_ERP_SUCCEEDED)
|
||||
_zfcp_erp_unit_reopen_all(port, 0, 74, NULL);
|
||||
_zfcp_erp_unit_reopen_all(port, 0, "ersfa_5", NULL);
|
||||
else
|
||||
_zfcp_erp_port_forced_reopen(port, 0, 75, NULL);
|
||||
_zfcp_erp_port_forced_reopen(port, 0, "ersfa_6", NULL);
|
||||
break;
|
||||
|
||||
case ZFCP_ERP_ACTION_REOPEN_UNIT:
|
||||
if (status != ZFCP_ERP_SUCCEEDED)
|
||||
_zfcp_erp_port_reopen(unit->port, 0, 76, NULL);
|
||||
_zfcp_erp_port_reopen(unit->port, 0, "ersfa_7", NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -617,7 +623,7 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
|
|||
adapter->peer_d_id);
|
||||
if (IS_ERR(port)) /* error or port already attached */
|
||||
return;
|
||||
_zfcp_erp_port_reopen(port, 0, 150, NULL);
|
||||
_zfcp_erp_port_reopen(port, 0, "ereptp1", NULL);
|
||||
}
|
||||
|
||||
static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
|
||||
|
|
@ -640,9 +646,9 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
|
|||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
||||
zfcp_rec_dbf_event_thread_lock(6, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erasfx1", adapter);
|
||||
down(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread_lock(7, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erasfx2", adapter);
|
||||
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
|
||||
break;
|
||||
|
||||
|
|
@ -681,9 +687,9 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
|
|||
if (ret)
|
||||
return ZFCP_ERP_FAILED;
|
||||
|
||||
zfcp_rec_dbf_event_thread_lock(8, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erasox1", adapter);
|
||||
down(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread_lock(9, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erasox2", adapter);
|
||||
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
|
||||
return ZFCP_ERP_FAILED;
|
||||
|
||||
|
|
@ -705,60 +711,59 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act)
|
|||
return ZFCP_ERP_SUCCEEDED;
|
||||
}
|
||||
|
||||
static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
|
||||
int close)
|
||||
static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
|
||||
{
|
||||
int retval = ZFCP_ERP_SUCCEEDED;
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
|
||||
if (close)
|
||||
goto close_only;
|
||||
|
||||
retval = zfcp_erp_adapter_strategy_open_qdio(act);
|
||||
if (retval != ZFCP_ERP_SUCCEEDED)
|
||||
goto failed_qdio;
|
||||
|
||||
retval = zfcp_erp_adapter_strategy_open_fsf(act);
|
||||
if (retval != ZFCP_ERP_SUCCEEDED)
|
||||
goto failed_openfcp;
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status);
|
||||
|
||||
return ZFCP_ERP_SUCCEEDED;
|
||||
|
||||
close_only:
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
|
||||
&act->adapter->status);
|
||||
|
||||
failed_openfcp:
|
||||
/* close queues to ensure that buffers are not accessed by adapter */
|
||||
zfcp_qdio_close(adapter);
|
||||
zfcp_fsf_req_dismiss_all(adapter);
|
||||
adapter->fsf_req_seq_no = 0;
|
||||
/* all ports and units are closed */
|
||||
zfcp_erp_modify_adapter_status(adapter, 24, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL,
|
||||
ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
|
||||
failed_qdio:
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
|
||||
&act->adapter->status);
|
||||
return retval;
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
|
||||
}
|
||||
|
||||
static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
|
||||
{
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
|
||||
if (zfcp_erp_adapter_strategy_open_qdio(act)) {
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
|
||||
&adapter->status);
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
||||
if (zfcp_erp_adapter_strategy_open_fsf(act)) {
|
||||
zfcp_erp_adapter_strategy_close(act);
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &adapter->status);
|
||||
|
||||
return ZFCP_ERP_SUCCEEDED;
|
||||
}
|
||||
|
||||
static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
|
||||
{
|
||||
int retval;
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
|
||||
zfcp_erp_adapter_strategy_generic(act, 1); /* close */
|
||||
if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
|
||||
return ZFCP_ERP_EXIT;
|
||||
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN) {
|
||||
zfcp_erp_adapter_strategy_close(act);
|
||||
if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
|
||||
return ZFCP_ERP_EXIT;
|
||||
}
|
||||
|
||||
retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */
|
||||
|
||||
if (retval == ZFCP_ERP_FAILED)
|
||||
if (zfcp_erp_adapter_strategy_open(act)) {
|
||||
ssleep(8);
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return ZFCP_ERP_SUCCEEDED;
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
|
||||
|
|
@ -777,10 +782,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_ACCESS_DENIED |
|
||||
ZFCP_STATUS_PORT_PHYS_CLOSING |
|
||||
ZFCP_STATUS_PORT_INVALID_WWPN,
|
||||
&port->status);
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &port->status);
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
|
||||
|
|
@ -836,7 +838,7 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
|
|||
struct zfcp_port *port = act->port;
|
||||
|
||||
if (port->wwpn != adapter->peer_wwpn) {
|
||||
zfcp_erp_port_failed(port, 25, NULL);
|
||||
zfcp_erp_port_failed(port, "eroptp1", NULL);
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
port->d_id = adapter->peer_d_id;
|
||||
|
|
@ -855,7 +857,7 @@ void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
|
|||
port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
|
||||
if (retval)
|
||||
zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
|
||||
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
|
||||
|
|
@ -871,17 +873,15 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
|
|||
if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
|
||||
return zfcp_erp_open_ptp_port(act);
|
||||
if (!port->d_id) {
|
||||
queue_work(zfcp_data.work_queue, &port->gid_pn_work);
|
||||
zfcp_port_get(port);
|
||||
if (!queue_work(zfcp_data.work_queue,
|
||||
&port->gid_pn_work))
|
||||
zfcp_port_put(port);
|
||||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
|
||||
if (!port->d_id) {
|
||||
if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
|
||||
zfcp_erp_port_failed(port, 26, NULL);
|
||||
return ZFCP_ERP_EXIT;
|
||||
}
|
||||
if (!port->d_id)
|
||||
return ZFCP_ERP_FAILED;
|
||||
}
|
||||
return zfcp_erp_port_strategy_open_port(act);
|
||||
|
||||
case ZFCP_ERP_STEP_PORT_OPENING:
|
||||
|
|
@ -995,7 +995,7 @@ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
|
|||
"port 0x%016Lx\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_failed(unit, 21, NULL);
|
||||
zfcp_erp_unit_failed(unit, "erusck1", NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1025,7 +1025,7 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
|
|||
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);
|
||||
zfcp_erp_port_failed(port, "erpsck1", NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1052,7 +1052,7 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
|
|||
dev_err(&adapter->ccw_device->dev,
|
||||
"ERP cannot recover an error "
|
||||
"on the FCP device\n");
|
||||
zfcp_erp_adapter_failed(adapter, 23, NULL);
|
||||
zfcp_erp_adapter_failed(adapter, "erasck1", NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1117,7 +1117,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
|
|||
if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
|
||||
_zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
67, NULL);
|
||||
"ersscg1", NULL);
|
||||
return ZFCP_ERP_EXIT;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1127,7 +1127,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
|
|||
if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
|
||||
_zfcp_erp_port_reopen(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
68, NULL);
|
||||
"ersscg2", NULL);
|
||||
return ZFCP_ERP_EXIT;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1136,7 +1136,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
|
|||
if (zfcp_erp_strat_change_det(&unit->status, erp_status)) {
|
||||
_zfcp_erp_unit_reopen(unit,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
69, NULL);
|
||||
"ersscg3", NULL);
|
||||
return ZFCP_ERP_EXIT;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1155,7 +1155,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
|
|||
}
|
||||
|
||||
list_del(&erp_action->list);
|
||||
zfcp_rec_dbf_event_action(144, erp_action);
|
||||
zfcp_rec_dbf_event_action("eractd1", erp_action);
|
||||
|
||||
switch (erp_action->action) {
|
||||
case ZFCP_ERP_ACTION_REOPEN_UNIT:
|
||||
|
|
@ -1214,38 +1214,8 @@ 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;
|
||||
queue_work(zfcp_data.work_queue, &p->work);
|
||||
}
|
||||
|
||||
static void zfcp_erp_rport_register(struct zfcp_port *port)
|
||||
{
|
||||
struct fc_rport_identifiers ids;
|
||||
ids.node_name = port->wwnn;
|
||||
ids.port_name = port->wwpn;
|
||||
ids.port_id = port->d_id;
|
||||
ids.roles = FC_RPORT_ROLE_FCP_TARGET;
|
||||
port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
|
||||
if (!port->rport) {
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"Registering port 0x%016Lx failed\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
return;
|
||||
}
|
||||
|
||||
scsi_target_unblock(&port->rport->dev);
|
||||
port->rport->maxframe_size = port->maxframe_size;
|
||||
port->rport->supported_classes = port->supported_classes;
|
||||
}
|
||||
|
||||
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)
|
||||
continue;
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
if (!queue_work(zfcp_data.work_queue, &p->work))
|
||||
zfcp_unit_put(unit);
|
||||
}
|
||||
|
||||
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
|
|
@ -1256,10 +1226,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
|||
|
||||
switch (act->action) {
|
||||
case ZFCP_ERP_ACTION_REOPEN_UNIT:
|
||||
if ((result == ZFCP_ERP_SUCCEEDED) &&
|
||||
!unit->device && port->rport) {
|
||||
atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
|
||||
&unit->status);
|
||||
flush_work(&port->rport_work);
|
||||
if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
|
||||
if (!(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_UNIT_SCSI_WORK_PENDING))
|
||||
zfcp_erp_schedule_work(unit);
|
||||
|
|
@ -1269,27 +1237,17 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
|||
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT:
|
||||
if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) {
|
||||
zfcp_port_put(port);
|
||||
return;
|
||||
}
|
||||
if ((result == ZFCP_ERP_SUCCEEDED) && !port->rport)
|
||||
zfcp_erp_rport_register(port);
|
||||
if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) {
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
if (result == ZFCP_ERP_SUCCEEDED)
|
||||
zfcp_scsi_schedule_rport_register(port);
|
||||
zfcp_port_put(port);
|
||||
break;
|
||||
|
||||
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
|
||||
if (result != ZFCP_ERP_SUCCEEDED) {
|
||||
unregister_service_level(&adapter->service_level);
|
||||
zfcp_erp_rports_del(adapter);
|
||||
} else {
|
||||
if (result == ZFCP_ERP_SUCCEEDED) {
|
||||
register_service_level(&adapter->service_level);
|
||||
schedule_work(&adapter->scan_work);
|
||||
}
|
||||
} else
|
||||
unregister_service_level(&adapter->service_level);
|
||||
zfcp_adapter_put(adapter);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1346,7 +1304,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
|
|||
erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
|
||||
}
|
||||
if (adapter->erp_total_count == adapter->erp_low_mem_count)
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, 66, NULL);
|
||||
_zfcp_erp_adapter_reopen(adapter, 0, "erstgy1", NULL);
|
||||
else {
|
||||
zfcp_erp_strategy_memwait(erp_action);
|
||||
retval = ZFCP_ERP_CONTINUES;
|
||||
|
|
@ -1406,9 +1364,9 @@ static int zfcp_erp_thread(void *data)
|
|||
zfcp_erp_wakeup(adapter);
|
||||
}
|
||||
|
||||
zfcp_rec_dbf_event_thread_lock(4, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
|
||||
ignore = down_interruptible(&adapter->erp_ready_sem);
|
||||
zfcp_rec_dbf_event_thread_lock(5, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
|
||||
}
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
|
||||
|
|
@ -1453,7 +1411,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(3, adapter);
|
||||
zfcp_rec_dbf_event_thread_lock("erthrk1", adapter);
|
||||
|
||||
wait_event(adapter->erp_thread_wqh,
|
||||
!(atomic_read(&adapter->status) &
|
||||
|
|
@ -1469,7 +1427,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
|
|||
* @id: Event id for debug trace.
|
||||
* @ref: Reference for debug trace.
|
||||
*/
|
||||
void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
|
||||
void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_modify_adapter_status(adapter, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
|
|
@ -1481,7 +1439,7 @@ void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
|
|||
* @id: Event id for debug trace.
|
||||
* @ref: Reference for debug trace.
|
||||
*/
|
||||
void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
|
||||
void zfcp_erp_port_failed(struct zfcp_port *port, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_modify_port_status(port, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
|
|
@ -1493,7 +1451,7 @@ void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
|
|||
* @id: Event id for debug trace.
|
||||
* @ref: Reference for debug trace.
|
||||
*/
|
||||
void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref)
|
||||
void zfcp_erp_unit_failed(struct zfcp_unit *unit, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_modify_unit_status(unit, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
|
||||
|
|
@ -1520,7 +1478,7 @@ void zfcp_erp_wait(struct zfcp_adapter *adapter)
|
|||
*
|
||||
* Changes in common status bits are propagated to attached ports and units.
|
||||
*/
|
||||
void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id,
|
||||
void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
|
||||
void *ref, u32 mask, int set_or_clear)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
|
@ -1554,7 +1512,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id,
|
|||
*
|
||||
* Changes in common status bits are propagated to attached units.
|
||||
*/
|
||||
void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref,
|
||||
void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
|
||||
u32 mask, int set_or_clear)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
|
|
@ -1586,7 +1544,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref,
|
|||
* @mask: status bits to change
|
||||
* @set_or_clear: ZFCP_SET or ZFCP_CLEAR
|
||||
*/
|
||||
void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref,
|
||||
void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref,
|
||||
u32 mask, int set_or_clear)
|
||||
{
|
||||
if (set_or_clear == ZFCP_SET) {
|
||||
|
|
@ -1609,7 +1567,7 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref,
|
|||
* @id: The debug trace id.
|
||||
* @id: Reference for the debug trace.
|
||||
*/
|
||||
void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref)
|
||||
void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -1626,7 +1584,7 @@ void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref)
|
|||
* @id: The debug trace id.
|
||||
* @id: Reference for the debug trace.
|
||||
*/
|
||||
void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref)
|
||||
void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_modify_unit_status(unit, id, ref,
|
||||
ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
|
||||
|
|
@ -1642,7 +1600,7 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref)
|
|||
* Since the adapter has denied access, stop using the port and the
|
||||
* attached units.
|
||||
*/
|
||||
void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref)
|
||||
void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -1661,14 +1619,14 @@ void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref)
|
|||
*
|
||||
* Since the adapter has denied access, stop using the unit.
|
||||
*/
|
||||
void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref)
|
||||
void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, char *id, void *ref)
|
||||
{
|
||||
zfcp_erp_modify_unit_status(unit, id, ref,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
|
||||
}
|
||||
|
||||
static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id,
|
||||
static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, char *id,
|
||||
void *ref)
|
||||
{
|
||||
int status = atomic_read(&unit->status);
|
||||
|
|
@ -1679,7 +1637,7 @@ static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id,
|
|||
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
|
||||
}
|
||||
|
||||
static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
|
||||
static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
|
||||
void *ref)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
|
|
@ -1701,7 +1659,7 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
|
|||
* @id: Id for debug trace
|
||||
* @ref: Reference for debug trace
|
||||
*/
|
||||
void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
|
||||
void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
|
||||
void *ref)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* External function declarations.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_EXT_H
|
||||
|
|
@ -35,15 +35,15 @@ extern struct miscdevice zfcp_cfdc_misc;
|
|||
/* zfcp_dbf.c */
|
||||
extern int zfcp_adapter_debug_register(struct zfcp_adapter *);
|
||||
extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_thread(u8, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_thread_lock(u8, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_adapter(u8, void *, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_port(u8, void *, struct zfcp_port *);
|
||||
extern void zfcp_rec_dbf_event_unit(u8, void *, struct zfcp_unit *);
|
||||
extern void zfcp_rec_dbf_event_trigger(u8, void *, u8, u8, void *,
|
||||
extern void zfcp_rec_dbf_event_thread(char *, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_thread_lock(char *, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_adapter(char *, void *, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_port(char *, void *, struct zfcp_port *);
|
||||
extern void zfcp_rec_dbf_event_unit(char *, void *, struct zfcp_unit *);
|
||||
extern void zfcp_rec_dbf_event_trigger(char *, void *, u8, u8, void *,
|
||||
struct zfcp_adapter *,
|
||||
struct zfcp_port *, struct zfcp_unit *);
|
||||
extern void zfcp_rec_dbf_event_action(u8, struct zfcp_erp_action *);
|
||||
extern void zfcp_rec_dbf_event_action(char *, struct zfcp_erp_action *);
|
||||
extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
|
||||
extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
|
||||
struct fsf_status_read_buffer *);
|
||||
|
|
@ -66,31 +66,34 @@ extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
|
|||
struct scsi_cmnd *);
|
||||
|
||||
/* zfcp_erp.c */
|
||||
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *,
|
||||
u32, int);
|
||||
extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *);
|
||||
extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *);
|
||||
extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *);
|
||||
extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32,
|
||||
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
|
||||
void *, u32, int);
|
||||
extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
|
||||
extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, char *, void *);
|
||||
extern void zfcp_erp_modify_port_status(struct zfcp_port *, char *, void *, u32,
|
||||
int);
|
||||
extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *);
|
||||
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *);
|
||||
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *);
|
||||
extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *);
|
||||
extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32,
|
||||
extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
|
||||
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
|
||||
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32,
|
||||
int);
|
||||
extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *);
|
||||
extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *);
|
||||
extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *);
|
||||
extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
|
||||
extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
|
||||
extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
|
||||
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_wait(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
|
||||
extern void zfcp_erp_port_boxed(struct zfcp_port *, u8, void *);
|
||||
extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8, void *);
|
||||
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_port_boxed(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_unit_boxed(struct zfcp_unit *, char *, void *);
|
||||
extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *);
|
||||
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
|
||||
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
|
||||
void *);
|
||||
extern void zfcp_erp_timeout_handler(unsigned long);
|
||||
extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
|
||||
|
||||
|
|
@ -101,6 +104,7 @@ extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
|
|||
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_link_test_work(struct work_struct *);
|
||||
extern void zfcp_fc_nameserver_init(struct zfcp_adapter *);
|
||||
|
||||
/* zfcp_fsf.c */
|
||||
|
|
@ -125,16 +129,13 @@ extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
|
|||
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
|
||||
struct zfcp_erp_action *);
|
||||
extern int zfcp_fsf_send_els(struct zfcp_send_els *);
|
||||
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
|
||||
struct zfcp_unit *,
|
||||
struct scsi_cmnd *, int, int);
|
||||
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
|
||||
struct scsi_cmnd *);
|
||||
extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
|
||||
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *,
|
||||
struct zfcp_unit *, u8, int);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
|
||||
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
|
||||
struct zfcp_adapter *,
|
||||
struct zfcp_unit *, int);
|
||||
struct zfcp_unit *);
|
||||
|
||||
/* zfcp_qdio.c */
|
||||
extern int zfcp_qdio_allocate(struct zfcp_adapter *);
|
||||
|
|
@ -153,6 +154,10 @@ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
|
|||
extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
|
||||
extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
|
||||
extern struct fc_function_template zfcp_transport_functions;
|
||||
extern void zfcp_scsi_rport_work(struct work_struct *);
|
||||
extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
|
||||
extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
|
||||
extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
|
||||
|
||||
/* zfcp_sysfs.c */
|
||||
extern struct attribute_group zfcp_sysfs_unit_attrs;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Fibre Channel related functions for the zfcp device driver.
|
||||
*
|
||||
* Copyright IBM Corporation 2008
|
||||
* Copyright IBM Corporation 2008, 2009
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
|
|
@ -98,8 +98,12 @@ static void zfcp_wka_port_offline(struct work_struct *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);
|
||||
/* Don't wait forvever. If the wka_port is too busy take it offline
|
||||
through a new call later */
|
||||
if (!wait_event_timeout(wka_port->completion_wq,
|
||||
atomic_read(&wka_port->refcount) == 0,
|
||||
HZ >> 1))
|
||||
return;
|
||||
|
||||
mutex_lock(&wka_port->mutex);
|
||||
if ((atomic_read(&wka_port->refcount) != 0) ||
|
||||
|
|
@ -145,16 +149,10 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
|
|||
struct zfcp_port *port;
|
||||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
|
||||
if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_PHYS_OPEN))
|
||||
/* Try to connect to unused ports anyway. */
|
||||
zfcp_erp_port_reopen(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
82, fsf_req);
|
||||
else if ((port->d_id & range) == (elem->nport_did & range))
|
||||
/* Check connection status for connected ports */
|
||||
list_for_each_entry(port, &fsf_req->adapter->port_list_head, list)
|
||||
if ((port->d_id & range) == (elem->nport_did & range))
|
||||
zfcp_test_link(port);
|
||||
}
|
||||
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +194,7 @@ static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
|
|||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
|
||||
if (port && (port->wwpn == wwpn))
|
||||
zfcp_erp_port_forced_reopen(port, 0, 83, req);
|
||||
zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
|
||||
}
|
||||
|
||||
static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
|
||||
|
|
@ -259,10 +257,9 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
|
|||
|
||||
if (ct->status)
|
||||
return;
|
||||
if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) {
|
||||
atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
|
||||
if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT)
|
||||
return;
|
||||
}
|
||||
|
||||
/* paranoia */
|
||||
if (ct_iu_req->wwpn != port->wwpn)
|
||||
return;
|
||||
|
|
@ -375,16 +372,22 @@ static void zfcp_fc_adisc_handler(unsigned long data)
|
|||
|
||||
if (adisc->els.status) {
|
||||
/* request rejected or timed out */
|
||||
zfcp_erp_port_forced_reopen(port, 0, 63, NULL);
|
||||
zfcp_erp_port_forced_reopen(port, 0, "fcadh_1", NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!port->wwnn)
|
||||
port->wwnn = ls_adisc->wwnn;
|
||||
|
||||
if (port->wwpn != ls_adisc->wwpn)
|
||||
zfcp_erp_port_reopen(port, 0, 64, NULL);
|
||||
if ((port->wwpn != ls_adisc->wwpn) ||
|
||||
!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
|
||||
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"fcadh_2", NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* port is good, unblock rport without going through erp */
|
||||
zfcp_scsi_schedule_rport_register(port);
|
||||
out:
|
||||
zfcp_port_put(port);
|
||||
kfree(adisc);
|
||||
|
|
@ -422,6 +425,31 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
|
|||
return zfcp_fsf_send_els(&adisc->els);
|
||||
}
|
||||
|
||||
void zfcp_fc_link_test_work(struct work_struct *work)
|
||||
{
|
||||
struct zfcp_port *port =
|
||||
container_of(work, struct zfcp_port, test_link_work);
|
||||
int retval;
|
||||
|
||||
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_UNBLOCKED)) {
|
||||
zfcp_port_put(port);
|
||||
return; /* port erp is running and will update rport status */
|
||||
}
|
||||
|
||||
zfcp_port_get(port);
|
||||
port->rport_task = RPORT_DEL;
|
||||
zfcp_scsi_rport_work(&port->rport_work);
|
||||
|
||||
retval = zfcp_fc_adisc(port);
|
||||
if (retval == 0)
|
||||
return;
|
||||
|
||||
/* send of ADISC was not possible */
|
||||
zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
|
||||
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_test_link - lightweight link test procedure
|
||||
* @port: port to be tested
|
||||
|
|
@ -432,17 +460,9 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
|
|||
*/
|
||||
void zfcp_test_link(struct zfcp_port *port)
|
||||
{
|
||||
int retval;
|
||||
|
||||
zfcp_port_get(port);
|
||||
retval = zfcp_fc_adisc(port);
|
||||
if (retval == 0)
|
||||
return;
|
||||
|
||||
/* send of ADISC was not possible */
|
||||
zfcp_port_put(port);
|
||||
if (retval != -EBUSY)
|
||||
zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
|
||||
if (!queue_work(zfcp_data.work_queue, &port->test_link_work))
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
|
||||
|
|
@ -529,7 +549,7 @@ static void zfcp_validate_port(struct zfcp_port *port)
|
|||
zfcp_port_put(port);
|
||||
return;
|
||||
}
|
||||
zfcp_erp_port_shutdown(port, 0, 151, NULL);
|
||||
zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
zfcp_port_put(port);
|
||||
zfcp_port_dequeue(port);
|
||||
|
|
@ -592,7 +612,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
|
|||
if (IS_ERR(port))
|
||||
ret = PTR_ERR(port);
|
||||
else
|
||||
zfcp_erp_port_reopen(port, 0, 149, NULL);
|
||||
zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
|
||||
}
|
||||
|
||||
zfcp_erp_wait(adapter);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Implementation of FSF commands.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
|
|
@ -12,11 +12,14 @@
|
|||
#include <linux/blktrace_api.h>
|
||||
#include "zfcp_ext.h"
|
||||
|
||||
#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
|
||||
#define ZFCP_REQ_NO_QTCB 0x00000008
|
||||
|
||||
static void zfcp_fsf_request_timeout_handler(unsigned long data)
|
||||
{
|
||||
struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62,
|
||||
NULL);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"fsrth_1", NULL);
|
||||
}
|
||||
|
||||
static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req,
|
||||
|
|
@ -75,7 +78,7 @@ static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req,
|
|||
(unsigned long long)port->wwpn);
|
||||
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
|
||||
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
|
||||
zfcp_erp_port_access_denied(port, 55, req);
|
||||
zfcp_erp_port_access_denied(port, "fspad_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +92,7 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req,
|
|||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
|
||||
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
|
||||
zfcp_erp_unit_access_denied(unit, 59, req);
|
||||
zfcp_erp_unit_access_denied(unit, "fsuad_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +100,7 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
|
|||
{
|
||||
dev_err(&req->adapter->ccw_device->dev, "FCP device not "
|
||||
"operational because of an unsupported FC class\n");
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req);
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -159,20 +162,13 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
|
|||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if (port->d_id == d_id) {
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
switch (sr_buf->status_subtype) {
|
||||
case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:
|
||||
zfcp_erp_port_reopen(port, 0, 101, req);
|
||||
break;
|
||||
case FSF_STATUS_READ_SUB_ERROR_PORT:
|
||||
zfcp_erp_port_shutdown(port, 0, 122, req);
|
||||
break;
|
||||
}
|
||||
zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
|
||||
return;
|
||||
}
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
||||
static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
|
||||
static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
|
||||
struct fsf_link_down_info *link_down)
|
||||
{
|
||||
struct zfcp_adapter *adapter = req->adapter;
|
||||
|
|
@ -181,6 +177,7 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
|
|||
return;
|
||||
|
||||
atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
|
||||
zfcp_scsi_schedule_rports_block(adapter);
|
||||
|
||||
if (!link_down)
|
||||
goto out;
|
||||
|
|
@ -261,13 +258,13 @@ static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req)
|
|||
|
||||
switch (sr_buf->status_subtype) {
|
||||
case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
|
||||
zfcp_fsf_link_down_info_eval(req, 38, ldi);
|
||||
zfcp_fsf_link_down_info_eval(req, "fssrld1", ldi);
|
||||
break;
|
||||
case FSF_STATUS_READ_SUB_FDISC_FAILED:
|
||||
zfcp_fsf_link_down_info_eval(req, 39, ldi);
|
||||
zfcp_fsf_link_down_info_eval(req, "fssrld2", ldi);
|
||||
break;
|
||||
case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
|
||||
zfcp_fsf_link_down_info_eval(req, 40, NULL);
|
||||
zfcp_fsf_link_down_info_eval(req, "fssrld3", NULL);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -307,22 +304,23 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
|
|||
dev_info(&adapter->ccw_device->dev,
|
||||
"The local link has been restored\n");
|
||||
/* All ports should be marked as ready to run again */
|
||||
zfcp_erp_modify_adapter_status(adapter, 30, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "fssrh_1", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
102, req);
|
||||
"fssrh_2", req);
|
||||
break;
|
||||
case FSF_STATUS_READ_NOTIFICATION_LOST:
|
||||
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
|
||||
zfcp_erp_adapter_access_changed(adapter, 135, req);
|
||||
zfcp_erp_adapter_access_changed(adapter, "fssrh_3",
|
||||
req);
|
||||
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
|
||||
schedule_work(&adapter->scan_work);
|
||||
break;
|
||||
case FSF_STATUS_READ_CFDC_UPDATED:
|
||||
zfcp_erp_adapter_access_changed(adapter, 136, req);
|
||||
zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req);
|
||||
break;
|
||||
case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
|
||||
adapter->adapter_features = sr_buf->payload.word[0];
|
||||
|
|
@ -351,7 +349,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
|
|||
dev_err(&req->adapter->ccw_device->dev,
|
||||
"The FCP adapter reported a problem "
|
||||
"that cannot be recovered\n");
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req);
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req);
|
||||
break;
|
||||
}
|
||||
/* all non-return stats set FSFREQ_ERROR*/
|
||||
|
|
@ -368,7 +366,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
|
|||
dev_err(&req->adapter->ccw_device->dev,
|
||||
"The FCP adapter does not recognize the command 0x%x\n",
|
||||
req->qtcb->header.fsf_command);
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req);
|
||||
zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_ADAPTER_STATUS_AVAILABLE:
|
||||
|
|
@ -400,17 +398,17 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
|
|||
"QTCB version 0x%x not supported by FCP adapter "
|
||||
"(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
|
||||
psq->word[0], psq->word[1]);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 117, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1", req);
|
||||
break;
|
||||
case FSF_PROT_ERROR_STATE:
|
||||
case FSF_PROT_SEQ_NUMB_ERROR:
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 98, req);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
case FSF_PROT_UNSUPP_QTCB_TYPE:
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"The QTCB type is not supported by the FCP adapter\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 118, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3", req);
|
||||
break;
|
||||
case FSF_PROT_HOST_CONNECTION_INITIALIZING:
|
||||
atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
|
||||
|
|
@ -420,27 +418,29 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
|
|||
dev_err(&adapter->ccw_device->dev,
|
||||
"0x%Lx is an ambiguous request identifier\n",
|
||||
(unsigned long long)qtcb->bottom.support.req_handle);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 78, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4", req);
|
||||
break;
|
||||
case FSF_PROT_LINK_DOWN:
|
||||
zfcp_fsf_link_down_info_eval(req, 37, &psq->link_down_info);
|
||||
zfcp_fsf_link_down_info_eval(req, "fspse_5",
|
||||
&psq->link_down_info);
|
||||
/* FIXME: reopening adapter now? better wait for link up */
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 79, req);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req);
|
||||
break;
|
||||
case FSF_PROT_REEST_QUEUE:
|
||||
/* All ports should be marked as ready to run again */
|
||||
zfcp_erp_modify_adapter_status(adapter, 28, NULL,
|
||||
zfcp_erp_modify_adapter_status(adapter, "fspse_7", NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, 99, req);
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"fspse_8", req);
|
||||
break;
|
||||
default:
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"0x%x is not a valid transfer protocol status\n",
|
||||
qtcb->prefix.prot_status);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 119, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req);
|
||||
}
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
|
|
@ -526,7 +526,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
|
|||
dev_err(&adapter->ccw_device->dev,
|
||||
"Unknown or unsupported arbitrated loop "
|
||||
"fibre channel topology detected\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 127, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1", req);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +560,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
|
|||
"FCP adapter maximum QTCB size (%d bytes) "
|
||||
"is too small\n",
|
||||
bottom->max_qtcb_size);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 129, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1", req);
|
||||
return;
|
||||
}
|
||||
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
|
||||
|
|
@ -577,11 +577,11 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
|
|||
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
|
||||
&adapter->status);
|
||||
|
||||
zfcp_fsf_link_down_info_eval(req, 42,
|
||||
zfcp_fsf_link_down_info_eval(req, "fsecdh2",
|
||||
&qtcb->header.fsf_status_qual.link_down_info);
|
||||
break;
|
||||
default:
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 130, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3", req);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -597,14 +597,14 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
|
|||
dev_err(&adapter->ccw_device->dev,
|
||||
"The FCP adapter only supports newer "
|
||||
"control block versions\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 125, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4", req);
|
||||
return;
|
||||
}
|
||||
if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"The FCP adapter only supports older "
|
||||
"control block versions\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 126, req);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5", req);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -617,9 +617,10 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
|
|||
if (req->data)
|
||||
memcpy(req->data, bottom, sizeof(*bottom));
|
||||
|
||||
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
|
||||
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
|
||||
fc_host_permanent_port_name(shost) = bottom->wwpn;
|
||||
else
|
||||
fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
|
||||
} else
|
||||
fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
|
||||
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
|
||||
fc_host_supported_speeds(shost) = bottom->supported_speed;
|
||||
|
|
@ -638,20 +639,12 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
|
|||
break;
|
||||
case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
|
||||
zfcp_fsf_exchange_port_evaluate(req);
|
||||
zfcp_fsf_link_down_info_eval(req, 43,
|
||||
zfcp_fsf_link_down_info_eval(req, "fsepdh1",
|
||||
&qtcb->header.fsf_status_qual.link_down_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
|
||||
{
|
||||
if (atomic_read(&adapter->req_q.count) > 0)
|
||||
return 1;
|
||||
atomic_inc(&adapter->qdio_outb_full);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
|
||||
__releases(&adapter->req_q_lock)
|
||||
__acquires(&adapter->req_q_lock)
|
||||
|
|
@ -735,7 +728,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
|
|||
|
||||
req->adapter = adapter;
|
||||
req->fsf_command = fsf_cmd;
|
||||
req->req_id = adapter->req_no++;
|
||||
req->req_id = adapter->req_no;
|
||||
req->sbal_number = 1;
|
||||
req->sbal_first = req_q->first;
|
||||
req->sbal_last = req_q->first;
|
||||
|
|
@ -791,13 +784,14 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
|
|||
if (zfcp_reqlist_find_safe(adapter, req))
|
||||
zfcp_reqlist_remove(adapter, req);
|
||||
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 116, req);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1", req);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Don't increase for unsolicited status */
|
||||
if (req->qtcb)
|
||||
adapter->fsf_req_seq_no++;
|
||||
adapter->req_no++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -870,14 +864,14 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
switch (req->qtcb->header.fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
if (fsq->word[0] == fsq->word[1]) {
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104,
|
||||
req);
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0,
|
||||
"fsafch1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
break;
|
||||
case FSF_LUN_HANDLE_NOT_VALID:
|
||||
if (fsq->word[0] == fsq->word[1]) {
|
||||
zfcp_erp_port_reopen(unit->port, 0, 105, req);
|
||||
zfcp_erp_port_reopen(unit->port, 0, "fsafch2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
}
|
||||
break;
|
||||
|
|
@ -885,12 +879,12 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
|
||||
break;
|
||||
case FSF_PORT_BOXED:
|
||||
zfcp_erp_port_boxed(unit->port, 47, req);
|
||||
zfcp_erp_port_boxed(unit->port, "fsafch3", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
case FSF_LUN_BOXED:
|
||||
zfcp_erp_unit_boxed(unit, 48, req);
|
||||
zfcp_erp_unit_boxed(unit, "fsafch4", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
|
|
@ -912,27 +906,22 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
/**
|
||||
* zfcp_fsf_abort_fcp_command - abort running SCSI command
|
||||
* @old_req_id: unsigned long
|
||||
* @adapter: pointer to struct zfcp_adapter
|
||||
* @unit: pointer to struct zfcp_unit
|
||||
* @req_flags: integer specifying the request flags
|
||||
* Returns: pointer to struct zfcp_fsf_req
|
||||
*
|
||||
* FIXME(design): should be watched by a timeout !!!
|
||||
*/
|
||||
|
||||
struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
|
||||
struct zfcp_adapter *adapter,
|
||||
struct zfcp_unit *unit,
|
||||
int req_flags)
|
||||
struct zfcp_unit *unit)
|
||||
{
|
||||
struct qdio_buffer_element *sbale;
|
||||
struct zfcp_fsf_req *req = NULL;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
|
||||
spin_lock(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
|
||||
req_flags, adapter->pool.fsf_req_abort);
|
||||
0, adapter->pool.fsf_req_abort);
|
||||
if (IS_ERR(req)) {
|
||||
req = NULL;
|
||||
goto out;
|
||||
|
|
@ -960,7 +949,7 @@ out_error_free:
|
|||
zfcp_fsf_req_free(req);
|
||||
req = NULL;
|
||||
out:
|
||||
spin_unlock(&adapter->req_q_lock);
|
||||
spin_unlock_bh(&adapter->req_q_lock);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
|
@ -998,7 +987,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
|
|||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 106, req);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
|
||||
case FSF_GENERIC_COMMAND_REJECTED:
|
||||
case FSF_PAYLOAD_SIZE_MISMATCH:
|
||||
case FSF_REQUEST_SIZE_TOO_LARGE:
|
||||
|
|
@ -1174,12 +1163,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
|
|||
struct fsf_qtcb_bottom_support *bottom;
|
||||
int ret = -EIO;
|
||||
|
||||
if (unlikely(!(atomic_read(&els->port->status) &
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED)))
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
|
||||
ZFCP_REQ_AUTO_CLEANUP, NULL);
|
||||
|
|
@ -1212,7 +1197,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
|
|||
failed_send:
|
||||
zfcp_fsf_req_free(req);
|
||||
out:
|
||||
spin_unlock(&adapter->req_q_lock);
|
||||
spin_unlock_bh(&adapter->req_q_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1224,7 +1209,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
|
|||
int retval = -EIO;
|
||||
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter,
|
||||
FSF_QTCB_EXCHANGE_CONFIG_DATA,
|
||||
|
|
@ -1320,7 +1305,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
|
||||
ZFCP_REQ_AUTO_CLEANUP,
|
||||
|
|
@ -1366,7 +1351,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
|
||||
|
|
@ -1416,7 +1401,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
|
|||
"Not enough FCP adapter resources to open "
|
||||
"remote port 0x%016Lx\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
zfcp_erp_port_failed(port, 31, req);
|
||||
zfcp_erp_port_failed(port, "fsoph_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_ADAPTER_STATUS_AVAILABLE:
|
||||
|
|
@ -1522,13 +1507,13 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
|
|||
|
||||
switch (req->qtcb->header.fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(port->adapter, 0, 107, req);
|
||||
zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_ADAPTER_STATUS_AVAILABLE:
|
||||
break;
|
||||
case FSF_GOOD:
|
||||
zfcp_erp_modify_port_status(port, 33, req,
|
||||
zfcp_erp_modify_port_status(port, "fscph_2", req,
|
||||
ZFCP_STATUS_COMMON_OPEN,
|
||||
ZFCP_CLEAR);
|
||||
break;
|
||||
|
|
@ -1657,7 +1642,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
|
|||
|
||||
if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
zfcp_erp_adapter_reopen(wka_port->adapter, 0, 84, req);
|
||||
zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
|
||||
}
|
||||
|
||||
wka_port->status = ZFCP_WKA_PORT_OFFLINE;
|
||||
|
|
@ -1712,18 +1697,18 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
|
|||
struct zfcp_unit *unit;
|
||||
|
||||
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
|
||||
goto skip_fsfstatus;
|
||||
return;
|
||||
|
||||
switch (header->fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(port->adapter, 0, 108, req);
|
||||
zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_ACCESS_DENIED:
|
||||
zfcp_fsf_access_denied_port(req, port);
|
||||
break;
|
||||
case FSF_PORT_BOXED:
|
||||
zfcp_erp_port_boxed(port, 50, req);
|
||||
zfcp_erp_port_boxed(port, "fscpph2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
/* can't use generic zfcp_erp_modify_port_status because
|
||||
|
|
@ -1752,8 +1737,6 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
|
|||
&unit->status);
|
||||
break;
|
||||
}
|
||||
skip_fsfstatus:
|
||||
atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, &port->status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1789,8 +1772,6 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
|
|||
req->erp_action = erp_action;
|
||||
req->handler = zfcp_fsf_close_physical_port_handler;
|
||||
erp_action->fsf_req = req;
|
||||
atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
|
||||
&erp_action->port->status);
|
||||
|
||||
zfcp_fsf_start_erp_timer(req);
|
||||
retval = zfcp_fsf_req_send(req);
|
||||
|
|
@ -1825,7 +1806,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
switch (header->fsf_status) {
|
||||
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, req);
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fsouh_1", req);
|
||||
/* fall through */
|
||||
case FSF_LUN_ALREADY_OPEN:
|
||||
break;
|
||||
|
|
@ -1835,7 +1816,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
|
||||
break;
|
||||
case FSF_PORT_BOXED:
|
||||
zfcp_erp_port_boxed(unit->port, 51, req);
|
||||
zfcp_erp_port_boxed(unit->port, "fsouh_2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
|
|
@ -1851,7 +1832,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
else
|
||||
zfcp_act_eval_err(adapter,
|
||||
header->fsf_status_qual.word[2]);
|
||||
zfcp_erp_unit_access_denied(unit, 60, req);
|
||||
zfcp_erp_unit_access_denied(unit, "fsouh_3", req);
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
|
|
@ -1862,7 +1843,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
"0x%016Lx on port 0x%016Lx\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_failed(unit, 34, req);
|
||||
zfcp_erp_unit_failed(unit, "fsouh_4", req);
|
||||
/* fall through */
|
||||
case FSF_INVALID_COMMAND_OPTION:
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
|
|
@ -1911,9 +1892,9 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
"port 0x%016Lx)\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_failed(unit, 35, req);
|
||||
zfcp_erp_unit_failed(unit, "fsouh_5", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
zfcp_erp_unit_shutdown(unit, 0, 80, req);
|
||||
zfcp_erp_unit_shutdown(unit, 0, "fsouh_6", req);
|
||||
} else if (!exclusive && readwrite) {
|
||||
dev_err(&adapter->ccw_device->dev,
|
||||
"Shared read-write access not "
|
||||
|
|
@ -1921,9 +1902,9 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
|
|||
"0x%016Lx)\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_failed(unit, 36, req);
|
||||
zfcp_erp_unit_failed(unit, "fsouh_7", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
zfcp_erp_unit_shutdown(unit, 0, 81, req);
|
||||
zfcp_erp_unit_shutdown(unit, 0, "fsouh_8", req);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1988,15 +1969,15 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
|
|||
|
||||
switch (req->qtcb->header.fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, req);
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fscuh_1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_LUN_HANDLE_NOT_VALID:
|
||||
zfcp_erp_port_reopen(unit->port, 0, 111, req);
|
||||
zfcp_erp_port_reopen(unit->port, 0, "fscuh_2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_PORT_BOXED:
|
||||
zfcp_erp_port_boxed(unit->port, 52, req);
|
||||
zfcp_erp_port_boxed(unit->port, "fscuh_3", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
|
|
@ -2073,7 +2054,6 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
|
|||
struct fsf_qual_latency_info *lat_inf;
|
||||
struct latency_cont *lat;
|
||||
struct zfcp_unit *unit = req->unit;
|
||||
unsigned long flags;
|
||||
|
||||
lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info;
|
||||
|
||||
|
|
@ -2091,11 +2071,11 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
|
|||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&unit->latencies.lock, flags);
|
||||
spin_lock(&unit->latencies.lock);
|
||||
zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat);
|
||||
zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat);
|
||||
lat->counter++;
|
||||
spin_unlock_irqrestore(&unit->latencies.lock, flags);
|
||||
spin_unlock(&unit->latencies.lock);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||
|
|
@ -2147,7 +2127,6 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
|
|||
|
||||
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) {
|
||||
set_host_byte(scpnt, DID_SOFT_ERROR);
|
||||
set_driver_byte(scpnt, SUGGEST_RETRY);
|
||||
goto skip_fsfstatus;
|
||||
}
|
||||
|
||||
|
|
@ -2237,12 +2216,12 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
switch (header->fsf_status) {
|
||||
case FSF_HANDLE_MISMATCH:
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, req);
|
||||
zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fssfch1", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_FCPLUN_NOT_VALID:
|
||||
case FSF_LUN_HANDLE_NOT_VALID:
|
||||
zfcp_erp_port_reopen(unit->port, 0, 113, req);
|
||||
zfcp_erp_port_reopen(unit->port, 0, "fssfch2", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
|
||||
|
|
@ -2258,7 +2237,8 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
req->qtcb->bottom.io.data_direction,
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req);
|
||||
zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch3",
|
||||
req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_CMND_LENGTH_NOT_VALID:
|
||||
|
|
@ -2268,16 +2248,17 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
|
|||
req->qtcb->bottom.io.fcp_cmnd_length,
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req);
|
||||
zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch4",
|
||||
req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
|
||||
break;
|
||||
case FSF_PORT_BOXED:
|
||||
zfcp_erp_port_boxed(unit->port, 53, req);
|
||||
zfcp_erp_port_boxed(unit->port, "fssfch5", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
case FSF_LUN_BOXED:
|
||||
zfcp_erp_unit_boxed(unit, 54, req);
|
||||
zfcp_erp_unit_boxed(unit, "fssfch6", req);
|
||||
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
|
||||
ZFCP_STATUS_FSFREQ_RETRY;
|
||||
break;
|
||||
|
|
@ -2314,30 +2295,29 @@ static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
|
|||
|
||||
/**
|
||||
* zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
|
||||
* @adapter: adapter where scsi command is issued
|
||||
* @unit: unit where command is sent to
|
||||
* @scsi_cmnd: scsi command to be sent
|
||||
* @timer: timer to be started when request is initiated
|
||||
* @req_flags: flags for fsf_request
|
||||
*/
|
||||
int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
|
||||
struct zfcp_unit *unit,
|
||||
struct scsi_cmnd *scsi_cmnd,
|
||||
int use_timer, int req_flags)
|
||||
int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
|
||||
struct scsi_cmnd *scsi_cmnd)
|
||||
{
|
||||
struct zfcp_fsf_req *req;
|
||||
struct fcp_cmnd_iu *fcp_cmnd_iu;
|
||||
unsigned int sbtype;
|
||||
int real_bytes, retval = -EIO;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
|
||||
if (unlikely(!(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED)))
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
if (atomic_read(&adapter->req_q.count) <= 0) {
|
||||
atomic_inc(&adapter->qdio_outb_full);
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
|
||||
}
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND,
|
||||
ZFCP_REQ_AUTO_CLEANUP,
|
||||
adapter->pool.fsf_req_scsi);
|
||||
if (IS_ERR(req)) {
|
||||
retval = PTR_ERR(req);
|
||||
|
|
@ -2411,7 +2391,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
|
|||
"on port 0x%016Lx closed\n",
|
||||
(unsigned long long)unit->fcp_lun,
|
||||
(unsigned long long)unit->port->wwpn);
|
||||
zfcp_erp_unit_shutdown(unit, 0, 131, req);
|
||||
zfcp_erp_unit_shutdown(unit, 0, "fssfct1", req);
|
||||
retval = -EINVAL;
|
||||
}
|
||||
goto failed_scsi_cmnd;
|
||||
|
|
@ -2419,9 +2399,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
|
|||
|
||||
zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);
|
||||
|
||||
if (use_timer)
|
||||
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
|
||||
|
||||
retval = zfcp_fsf_req_send(req);
|
||||
if (unlikely(retval))
|
||||
goto failed_scsi_cmnd;
|
||||
|
|
@ -2439,28 +2416,25 @@ out:
|
|||
|
||||
/**
|
||||
* zfcp_fsf_send_fcp_ctm - send SCSI task management command
|
||||
* @adapter: pointer to struct zfcp-adapter
|
||||
* @unit: pointer to struct zfcp_unit
|
||||
* @tm_flags: unsigned byte for task management flags
|
||||
* @req_flags: int request flags
|
||||
* Returns: on success pointer to struct fsf_req, NULL otherwise
|
||||
*/
|
||||
struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
|
||||
struct zfcp_unit *unit,
|
||||
u8 tm_flags, int req_flags)
|
||||
struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
|
||||
{
|
||||
struct qdio_buffer_element *sbale;
|
||||
struct zfcp_fsf_req *req = NULL;
|
||||
struct fcp_cmnd_iu *fcp_cmnd_iu;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
|
||||
if (unlikely(!(atomic_read(&unit->status) &
|
||||
ZFCP_STATUS_COMMON_UNBLOCKED)))
|
||||
return NULL;
|
||||
|
||||
spin_lock(&adapter->req_q_lock);
|
||||
if (!zfcp_fsf_sbal_available(adapter))
|
||||
spin_lock_bh(&adapter->req_q_lock);
|
||||
if (zfcp_fsf_req_sbal_get(adapter))
|
||||
goto out;
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
|
||||
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0,
|
||||
adapter->pool.fsf_req_scsi);
|
||||
if (IS_ERR(req)) {
|
||||
req = NULL;
|
||||
|
|
@ -2492,7 +2466,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
|
|||
zfcp_fsf_req_free(req);
|
||||
req = NULL;
|
||||
out:
|
||||
spin_unlock(&adapter->req_q_lock);
|
||||
spin_unlock_bh(&adapter->req_q_lock);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,10 +127,6 @@
|
|||
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
|
||||
#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
|
||||
|
||||
/* status subtypes in status read buffer */
|
||||
#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001
|
||||
#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002
|
||||
|
||||
/* status subtypes for link down */
|
||||
#define FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK 0x00000000
|
||||
#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
|
||||
#include "zfcp_ext.h"
|
||||
|
||||
/* FIXME(tune): free space should be one max. SBAL chain plus what? */
|
||||
#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \
|
||||
- (FSF_MAX_SBALS_PER_REQ + 4))
|
||||
#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
|
||||
|
||||
static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
|
||||
|
|
@ -58,7 +55,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
|
|||
}
|
||||
}
|
||||
|
||||
static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id)
|
||||
static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id)
|
||||
{
|
||||
dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
|
||||
|
||||
|
|
@ -77,6 +74,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
|
|||
}
|
||||
}
|
||||
|
||||
/* this needs to be called prior to updating the queue fill level */
|
||||
static void zfcp_qdio_account(struct zfcp_adapter *adapter)
|
||||
{
|
||||
ktime_t now;
|
||||
s64 span;
|
||||
int free, used;
|
||||
|
||||
spin_lock(&adapter->qdio_stat_lock);
|
||||
now = ktime_get();
|
||||
span = ktime_us_delta(now, adapter->req_q_time);
|
||||
free = max(0, atomic_read(&adapter->req_q.count));
|
||||
used = QDIO_MAX_BUFFERS_PER_Q - free;
|
||||
adapter->req_q_util += used * span;
|
||||
adapter->req_q_time = now;
|
||||
spin_unlock(&adapter->qdio_stat_lock);
|
||||
}
|
||||
|
||||
static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
|
||||
int queue_no, int first, int count,
|
||||
unsigned long parm)
|
||||
|
|
@ -86,13 +100,14 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
|
|||
|
||||
if (unlikely(qdio_err)) {
|
||||
zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
|
||||
zfcp_qdio_handler_error(adapter, 140);
|
||||
zfcp_qdio_handler_error(adapter, "qdireq1");
|
||||
return;
|
||||
}
|
||||
|
||||
/* cleanup all SBALs being program-owned now */
|
||||
zfcp_qdio_zero_sbals(queue->sbal, first, count);
|
||||
|
||||
zfcp_qdio_account(adapter);
|
||||
atomic_add(count, &queue->count);
|
||||
wake_up(&adapter->request_wq);
|
||||
}
|
||||
|
|
@ -154,7 +169,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
|
|||
|
||||
if (unlikely(qdio_err)) {
|
||||
zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
|
||||
zfcp_qdio_handler_error(adapter, 147);
|
||||
zfcp_qdio_handler_error(adapter, "qdires1");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -346,21 +361,12 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
|
|||
struct zfcp_qdio_queue *req_q = &adapter->req_q;
|
||||
int first = fsf_req->sbal_first;
|
||||
int count = fsf_req->sbal_number;
|
||||
int retval, pci, pci_batch;
|
||||
struct qdio_buffer_element *sbale;
|
||||
int retval;
|
||||
unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
|
||||
|
||||
/* acknowledgements for transferred buffers */
|
||||
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);
|
||||
pci %= QDIO_MAX_BUFFERS_PER_Q;
|
||||
sbale = zfcp_qdio_sbale(req_q, pci, 0);
|
||||
sbale->flags |= SBAL_FLAGS0_PCI;
|
||||
}
|
||||
zfcp_qdio_account(adapter);
|
||||
|
||||
retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first,
|
||||
count);
|
||||
retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count);
|
||||
if (unlikely(retval)) {
|
||||
zfcp_qdio_zero_sbals(req_q->sbal, first, count);
|
||||
return retval;
|
||||
|
|
@ -370,7 +376,6 @@ 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;
|
||||
adapter->req_q_pci_batch = pci_batch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +446,6 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
|
|||
}
|
||||
req_q->first = 0;
|
||||
atomic_set(&req_q->count, 0);
|
||||
adapter->req_q_pci_batch = 0;
|
||||
adapter->resp_q.first = 0;
|
||||
atomic_set(&adapter->resp_q.count, 0);
|
||||
}
|
||||
|
|
@ -479,7 +483,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
|
|||
/* 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;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Interface to Linux SCSI midlayer.
|
||||
*
|
||||
* Copyright IBM Corporation 2002, 2008
|
||||
* Copyright IBM Corporation 2002, 2009
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
|
|
@ -27,9 +27,7 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
|
|||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
||||
{
|
||||
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
|
||||
unit->device = NULL;
|
||||
zfcp_erp_unit_failed(unit, 12, NULL);
|
||||
zfcp_unit_put(unit);
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +56,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
|||
{
|
||||
struct zfcp_unit *unit;
|
||||
struct zfcp_adapter *adapter;
|
||||
int status;
|
||||
int ret;
|
||||
int status, scsi_result, ret;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
|
||||
|
||||
/* reset the status for this request */
|
||||
scpnt->result = 0;
|
||||
|
|
@ -81,6 +79,14 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
scsi_result = fc_remote_port_chkready(rport);
|
||||
if (unlikely(scsi_result)) {
|
||||
scpnt->result = scsi_result;
|
||||
zfcp_scsi_dbf_event_result("fail", 4, adapter, scpnt, NULL);
|
||||
scpnt->scsi_done(scpnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = atomic_read(&unit->status);
|
||||
if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
|
||||
!(status & ZFCP_STATUS_COMMON_RUNNING))) {
|
||||
|
|
@ -88,8 +94,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
|||
return 0;;
|
||||
}
|
||||
|
||||
ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0,
|
||||
ZFCP_REQ_AUTO_CLEANUP);
|
||||
ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
|
||||
if (unlikely(ret == -EBUSY))
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
else if (unlikely(ret < 0))
|
||||
|
|
@ -133,8 +138,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
|
|||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun);
|
||||
if (unit &&
|
||||
(atomic_read(&unit->status) & ZFCP_STATUS_UNIT_REGISTERED)) {
|
||||
if (unit) {
|
||||
sdp->hostdata = unit;
|
||||
unit->device = sdp;
|
||||
zfcp_unit_get(unit);
|
||||
|
|
@ -147,79 +151,91 @@ out:
|
|||
|
||||
static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
struct Scsi_Host *scsi_host;
|
||||
struct zfcp_adapter *adapter;
|
||||
struct zfcp_unit *unit;
|
||||
struct zfcp_fsf_req *fsf_req;
|
||||
struct Scsi_Host *scsi_host = scpnt->device->host;
|
||||
struct zfcp_adapter *adapter =
|
||||
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_fsf_req *old_req, *abrt_req;
|
||||
unsigned long flags;
|
||||
unsigned long old_req_id = (unsigned long) scpnt->host_scribble;
|
||||
int retval = SUCCESS;
|
||||
|
||||
scsi_host = scpnt->device->host;
|
||||
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||
unit = scpnt->device->hostdata;
|
||||
int retry = 3;
|
||||
|
||||
/* avoid race condition between late normal completion and abort */
|
||||
write_lock_irqsave(&adapter->abort_lock, flags);
|
||||
|
||||
/* Check whether corresponding fsf_req is still pending */
|
||||
spin_lock(&adapter->req_list_lock);
|
||||
fsf_req = zfcp_reqlist_find(adapter, old_req_id);
|
||||
old_req = zfcp_reqlist_find(adapter, old_req_id);
|
||||
spin_unlock(&adapter->req_list_lock);
|
||||
if (!fsf_req) {
|
||||
if (!old_req) {
|
||||
write_unlock_irqrestore(&adapter->abort_lock, flags);
|
||||
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0);
|
||||
return retval;
|
||||
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL,
|
||||
old_req_id);
|
||||
return SUCCESS;
|
||||
}
|
||||
fsf_req->data = NULL;
|
||||
old_req->data = NULL;
|
||||
|
||||
/* don't access old fsf_req after releasing the abort_lock */
|
||||
write_unlock_irqrestore(&adapter->abort_lock, flags);
|
||||
|
||||
fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0);
|
||||
if (!fsf_req) {
|
||||
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
|
||||
old_req_id);
|
||||
retval = FAILED;
|
||||
return retval;
|
||||
while (retry--) {
|
||||
abrt_req = zfcp_fsf_abort_fcp_command(old_req_id, unit);
|
||||
if (abrt_req)
|
||||
break;
|
||||
|
||||
zfcp_erp_wait(adapter);
|
||||
if (!(atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_COMMON_RUNNING)) {
|
||||
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
|
||||
old_req_id);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
if (!abrt_req)
|
||||
return FAILED;
|
||||
|
||||
__wait_event(fsf_req->completion_wq,
|
||||
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
|
||||
wait_event(abrt_req->completion_wq,
|
||||
abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
|
||||
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
|
||||
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0);
|
||||
} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
|
||||
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0);
|
||||
} else {
|
||||
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0);
|
||||
if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
|
||||
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, abrt_req, 0);
|
||||
else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED)
|
||||
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, abrt_req, 0);
|
||||
else {
|
||||
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, abrt_req, 0);
|
||||
retval = FAILED;
|
||||
}
|
||||
zfcp_fsf_req_free(fsf_req);
|
||||
|
||||
zfcp_fsf_req_free(abrt_req);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
|
||||
struct scsi_cmnd *scpnt)
|
||||
static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
{
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
struct zfcp_fsf_req *fsf_req;
|
||||
int retval = SUCCESS;
|
||||
int retry = 3;
|
||||
|
||||
/* issue task management function */
|
||||
fsf_req = zfcp_fsf_send_fcp_ctm(adapter, unit, tm_flags, 0);
|
||||
if (!fsf_req) {
|
||||
zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);
|
||||
return FAILED;
|
||||
while (retry--) {
|
||||
fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags);
|
||||
if (fsf_req)
|
||||
break;
|
||||
|
||||
zfcp_erp_wait(adapter);
|
||||
if (!(atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_COMMON_RUNNING)) {
|
||||
zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit,
|
||||
scpnt);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
if (!fsf_req)
|
||||
return FAILED;
|
||||
|
||||
__wait_event(fsf_req->completion_wq,
|
||||
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
|
||||
wait_event(fsf_req->completion_wq,
|
||||
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
|
||||
|
||||
/*
|
||||
* check completion status of task management function
|
||||
*/
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
|
||||
zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
|
||||
retval = FAILED;
|
||||
|
|
@ -230,40 +246,25 @@ static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
|
|||
zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);
|
||||
|
||||
zfcp_fsf_req_free(fsf_req);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
|
||||
if (!unit) {
|
||||
WARN_ON(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
return zfcp_task_mgmt_function(unit, FCP_LOGICAL_UNIT_RESET, scpnt);
|
||||
return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET);
|
||||
}
|
||||
|
||||
static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
|
||||
if (!unit) {
|
||||
WARN_ON(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
return zfcp_task_mgmt_function(unit, FCP_TARGET_RESET, scpnt);
|
||||
return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET);
|
||||
}
|
||||
|
||||
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
struct zfcp_unit *unit;
|
||||
struct zfcp_adapter *adapter;
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
struct zfcp_adapter *adapter = unit->port->adapter;
|
||||
|
||||
unit = scpnt->device->hostdata;
|
||||
adapter = unit->port->adapter;
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
|
||||
zfcp_erp_wait(adapter);
|
||||
|
||||
return SUCCESS;
|
||||
|
|
@ -479,6 +480,109 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
|
|||
rport->dev_loss_tmo = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport
|
||||
* @rport: The rport that is about to be deleted.
|
||||
*/
|
||||
static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
{
|
||||
struct zfcp_port *port = rport->dd_data;
|
||||
|
||||
write_lock_irq(&zfcp_data.config_lock);
|
||||
port->rport = NULL;
|
||||
write_unlock_irq(&zfcp_data.config_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport
|
||||
* @rport: The FC rport where to teminate I/O
|
||||
*
|
||||
* Abort all pending SCSI commands for a port by closing the
|
||||
* port. Using a reopen for avoids a conflict with a shutdown
|
||||
* overwriting a reopen.
|
||||
*/
|
||||
static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
|
||||
{
|
||||
struct zfcp_port *port = rport->dd_data;
|
||||
|
||||
zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
|
||||
}
|
||||
|
||||
static void zfcp_scsi_rport_register(struct zfcp_port *port)
|
||||
{
|
||||
struct fc_rport_identifiers ids;
|
||||
struct fc_rport *rport;
|
||||
|
||||
ids.node_name = port->wwnn;
|
||||
ids.port_name = port->wwpn;
|
||||
ids.port_id = port->d_id;
|
||||
ids.roles = FC_RPORT_ROLE_FCP_TARGET;
|
||||
|
||||
rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
|
||||
if (!rport) {
|
||||
dev_err(&port->adapter->ccw_device->dev,
|
||||
"Registering port 0x%016Lx failed\n",
|
||||
(unsigned long long)port->wwpn);
|
||||
return;
|
||||
}
|
||||
|
||||
rport->dd_data = port;
|
||||
rport->maxframe_size = port->maxframe_size;
|
||||
rport->supported_classes = port->supported_classes;
|
||||
port->rport = rport;
|
||||
}
|
||||
|
||||
static void zfcp_scsi_rport_block(struct zfcp_port *port)
|
||||
{
|
||||
if (port->rport)
|
||||
fc_remote_port_delete(port->rport);
|
||||
}
|
||||
|
||||
void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
|
||||
{
|
||||
zfcp_port_get(port);
|
||||
port->rport_task = RPORT_ADD;
|
||||
|
||||
if (!queue_work(zfcp_data.work_queue, &port->rport_work))
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
|
||||
{
|
||||
zfcp_port_get(port);
|
||||
port->rport_task = RPORT_DEL;
|
||||
|
||||
if (!queue_work(zfcp_data.work_queue, &port->rport_work))
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
zfcp_scsi_schedule_rport_block(port);
|
||||
}
|
||||
|
||||
void zfcp_scsi_rport_work(struct work_struct *work)
|
||||
{
|
||||
struct zfcp_port *port = container_of(work, struct zfcp_port,
|
||||
rport_work);
|
||||
|
||||
while (port->rport_task) {
|
||||
if (port->rport_task == RPORT_ADD) {
|
||||
port->rport_task = RPORT_NONE;
|
||||
zfcp_scsi_rport_register(port);
|
||||
} else {
|
||||
port->rport_task = RPORT_NONE;
|
||||
zfcp_scsi_rport_block(port);
|
||||
}
|
||||
}
|
||||
|
||||
zfcp_port_put(port);
|
||||
}
|
||||
|
||||
|
||||
struct fc_function_template zfcp_transport_functions = {
|
||||
.show_starget_port_id = 1,
|
||||
.show_starget_port_name = 1,
|
||||
|
|
@ -497,6 +601,8 @@ struct fc_function_template zfcp_transport_functions = {
|
|||
.reset_fc_host_stats = zfcp_reset_fc_host_stats,
|
||||
.set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo,
|
||||
.get_host_port_state = zfcp_get_host_port_state,
|
||||
.dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk,
|
||||
.terminate_rport_io = zfcp_scsi_terminate_rport_io,
|
||||
.show_host_port_state = 1,
|
||||
/* no functions registered for following dynamic attributes but
|
||||
directly set by LLDD */
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \
|
|||
zfcp_sysfs_##_feat##_failed_show, \
|
||||
zfcp_sysfs_##_feat##_failed_store);
|
||||
|
||||
ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, 44, 93);
|
||||
ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, 45, 96);
|
||||
ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, 46, 97);
|
||||
ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, "syafai1", "syafai2");
|
||||
ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
|
||||
ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
|
||||
|
||||
static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
|
|
@ -168,7 +168,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_port_shutdown(port, 0, 92, NULL);
|
||||
zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
zfcp_port_put(port);
|
||||
zfcp_port_dequeue(port);
|
||||
|
|
@ -222,7 +222,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
|
|||
|
||||
retval = 0;
|
||||
|
||||
zfcp_erp_unit_reopen(unit, 0, 94, NULL);
|
||||
zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
zfcp_unit_put(unit);
|
||||
out:
|
||||
|
|
@ -268,7 +268,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_unit_shutdown(unit, 0, 95, NULL);
|
||||
zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
zfcp_unit_put(unit);
|
||||
zfcp_unit_dequeue(unit);
|
||||
|
|
@ -318,10 +318,9 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
|
|||
struct zfcp_unit *unit = sdev->hostdata; \
|
||||
struct zfcp_latencies *lat = &unit->latencies; \
|
||||
struct zfcp_adapter *adapter = unit->port->adapter; \
|
||||
unsigned long flags; \
|
||||
unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \
|
||||
\
|
||||
spin_lock_irqsave(&lat->lock, flags); \
|
||||
spin_lock_bh(&lat->lock); \
|
||||
fsum = lat->_name.fabric.sum * adapter->timer_ticks; \
|
||||
fmin = lat->_name.fabric.min * adapter->timer_ticks; \
|
||||
fmax = lat->_name.fabric.max * adapter->timer_ticks; \
|
||||
|
|
@ -329,7 +328,7 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
|
|||
cmin = lat->_name.channel.min * adapter->timer_ticks; \
|
||||
cmax = lat->_name.channel.max * adapter->timer_ticks; \
|
||||
cc = lat->_name.counter; \
|
||||
spin_unlock_irqrestore(&lat->lock, flags); \
|
||||
spin_unlock_bh(&lat->lock); \
|
||||
\
|
||||
do_div(fsum, 1000); \
|
||||
do_div(fmin, 1000); \
|
||||
|
|
@ -487,7 +486,8 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
|
|||
struct zfcp_adapter *adapter =
|
||||
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||
|
||||
return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full));
|
||||
return sprintf(buf, "%d %llu\n", atomic_read(&adapter->qdio_outb_full),
|
||||
(unsigned long long)adapter->req_q_util);
|
||||
}
|
||||
static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue