Commit 52ef11a7 authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley

[SCSI] zfcp: cleanup, separation of ERP, non ERP-version for exchange_ functions

cleanup, using ERP request mempool for all ERP versions of
the exchange functions (exchange_config (ECD), exchange_port (EPD) )
providing individual versions of the ECD, EPD functions for ERP
and other purposes (_sync).
Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 03f002f7
...@@ -2197,7 +2197,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) ...@@ -2197,7 +2197,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
zfcp_erp_action_to_running(erp_action); zfcp_erp_action_to_running(erp_action);
write_unlock_irq(&adapter->erp_lock); write_unlock_irq(&adapter->erp_lock);
ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); ret = zfcp_fsf_exchange_port_data(erp_action);
if (ret == -EOPNOTSUPP) { if (ret == -EOPNOTSUPP) {
debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
......
...@@ -82,8 +82,10 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); ...@@ -82,8 +82,10 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *, extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *,
struct zfcp_adapter *, struct fsf_qtcb_bottom_config *);
extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *,
struct fsf_qtcb_bottom_port *); struct fsf_qtcb_bottom_port *);
extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *); u32, u32, struct zfcp_sg_list *);
......
...@@ -1941,20 +1941,23 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1941,20 +1941,23 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
{ {
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req; struct zfcp_fsf_req *fsf_req;
struct zfcp_adapter *adapter = erp_action->adapter;
unsigned long lock_flags; unsigned long lock_flags;
int retval = 0; int retval;
/* setup new FSF request */ /* setup new FSF request */
retval = zfcp_fsf_req_create(erp_action->adapter, retval = zfcp_fsf_req_create(adapter,
FSF_QTCB_EXCHANGE_CONFIG_DATA, FSF_QTCB_EXCHANGE_CONFIG_DATA,
ZFCP_REQ_AUTO_CLEANUP, ZFCP_REQ_AUTO_CLEANUP,
erp_action->adapter->pool.fsf_req_erp, adapter->pool.fsf_req_erp,
&lock_flags, &fsf_req); &lock_flags, &fsf_req);
if (retval < 0) { if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration " ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n", "data request for adapter %s.\n",
zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_get_busid_by_adapter(adapter));
goto out; write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
return retval;
} }
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
...@@ -1971,24 +1974,72 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1971,24 +1974,72 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
zfcp_erp_start_timer(fsf_req); zfcp_erp_start_timer(fsf_req);
retval = zfcp_fsf_req_send(fsf_req); retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
if (retval) { if (retval) {
ZFCP_LOG_INFO ZFCP_LOG_INFO("error: Could not send exchange configuration "
("error: Could not send exchange configuration data " "data command on the adapter %s\n",
"command on the adapter %s\n", zfcp_get_busid_by_adapter(adapter));
zfcp_get_busid_by_adapter(erp_action->adapter));
zfcp_fsf_req_free(fsf_req); zfcp_fsf_req_free(fsf_req);
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
goto out;
} }
else
ZFCP_LOG_DEBUG("exchange configuration data request initiated " ZFCP_LOG_DEBUG("exchange configuration data request initiated "
"(adapter %s)\n", "(adapter %s)\n",
zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_get_busid_by_adapter(adapter));
out: return retval;
write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, }
int
zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_config *data)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
unsigned long lock_flags;
int retval;
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
0, NULL, &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags); lock_flags);
return retval; return retval;
}
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
fsf_req->qtcb->bottom.config.feature_selection =
FSF_FEATURE_CFDC |
FSF_FEATURE_LUN_SHARING |
FSF_FEATURE_NOTIFICATION_LOST |
FSF_FEATURE_UPDATE_ALERT;
if (data)
fsf_req->data = (unsigned long) data;
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
if (retval)
ZFCP_LOG_INFO("error: Could not send exchange configuration "
"data command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
else
wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
zfcp_fsf_req_free(fsf_req);
return retval;
} }
/** /**
...@@ -2016,11 +2067,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) ...@@ -2016,11 +2067,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
adapter->peer_d_id = 0; adapter->peer_d_id = 0;
if (xchg_ok) { if (xchg_ok) {
if (fsf_req->data)
memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data,
bottom, sizeof (struct fsf_qtcb_bottom_config));
fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
fc_host_speed(shost) = bottom->fc_link_speed; fc_host_speed(shost) = bottom->fc_link_speed;
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; fc_host_supported_classes(shost) =
FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->hydra_version = bottom->adapter_type; adapter->hydra_version = bottom->adapter_type;
if (fc_host_permanent_port_name(shost) == -1) if (fc_host_permanent_port_name(shost) == -1)
fc_host_permanent_port_name(shost) = fc_host_permanent_port_name(shost) =
...@@ -2053,7 +2110,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) ...@@ -2053,7 +2110,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
min(FC_SERIAL_NUMBER_SIZE, 17)); min(FC_SERIAL_NUMBER_SIZE, 17));
} }
ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" ZFCP_LOG_NORMAL("The adapter %s reported the following "
"characteristics:\n"
"WWNN 0x%016Lx, " "WWNN 0x%016Lx, "
"WWPN 0x%016Lx, " "WWPN 0x%016Lx, "
"S_ID 0x%06x,\n" "S_ID 0x%06x,\n"
...@@ -2090,7 +2148,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) ...@@ -2090,7 +2148,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
return 0; return 0;
} }
/* /**
* function: zfcp_fsf_exchange_config_data_handler * function: zfcp_fsf_exchange_config_data_handler
* *
* purpose: is called for finished Exchange Configuration Data command * purpose: is called for finished Exchange Configuration Data command
...@@ -2179,7 +2237,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2179,7 +2237,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
return -EIO; return -EIO;
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
&adapter->status);
zfcp_fsf_link_down_info_eval(adapter, zfcp_fsf_link_down_info_eval(adapter,
&qtcb->header.fsf_status_qual.link_down_info); &qtcb->header.fsf_status_qual.link_down_info);
...@@ -2187,7 +2246,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2187,7 +2246,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
default: default:
debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng");
debug_event(fsf_req->adapter->erp_dbf, 0, debug_event(fsf_req->adapter->erp_dbf, 0,
&fsf_req->qtcb->header.fsf_status, sizeof (u32)); &fsf_req->qtcb->header.fsf_status, sizeof(u32));
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO; return -EIO;
} }
...@@ -2197,18 +2256,15 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2197,18 +2256,15 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
/** /**
* zfcp_fsf_exchange_port_data - request information about local port * zfcp_fsf_exchange_port_data - request information about local port
* @erp_action: ERP action for the adapter for which port data is requested * @erp_action: ERP action for the adapter for which port data is requested
* @adapter: for which port data is requested
* @data: response to exchange port data request
*/ */
int int
zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{ {
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req; struct zfcp_fsf_req *fsf_req;
struct zfcp_adapter *adapter = erp_action->adapter;
unsigned long lock_flags; unsigned long lock_flags;
int retval = 0; int retval;
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
ZFCP_LOG_INFO("error: exchange port data " ZFCP_LOG_INFO("error: exchange port data "
...@@ -2219,9 +2275,10 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, ...@@ -2219,9 +2275,10 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
/* setup new FSF request */ /* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0, ZFCP_REQ_AUTO_CLEANUP,
NULL, &lock_flags, &fsf_req); adapter->pool.fsf_req_erp,
if (retval < 0) { &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Out of resources. Could not create an " ZFCP_LOG_INFO("error: Out of resources. Could not create an "
"exchange port data request for" "exchange port data request for"
"the adapter %s.\n", "the adapter %s.\n",
...@@ -2231,40 +2288,86 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, ...@@ -2231,40 +2288,86 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
return retval; return retval;
} }
if (data)
fsf_req->data = (unsigned long) data;
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
if (erp_action) {
erp_action->fsf_req = fsf_req; erp_action->fsf_req = fsf_req;
fsf_req->erp_action = erp_action; fsf_req->erp_action = erp_action;
zfcp_erp_start_timer(fsf_req); zfcp_erp_start_timer(fsf_req);
} else
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(fsf_req); retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
if (retval) { if (retval) {
ZFCP_LOG_INFO("error: Could not send an exchange port data " ZFCP_LOG_INFO("error: Could not send an exchange port data "
"command on the adapter %s\n", "command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
zfcp_fsf_req_free(fsf_req); zfcp_fsf_req_free(fsf_req);
if (erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
}
else
ZFCP_LOG_DEBUG("exchange port data request initiated "
"(adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
return retval;
}
/**
* zfcp_fsf_exchange_port_data_sync - request information about local port
* and wait until information is ready
*/
int
zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
unsigned long lock_flags;
int retval;
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
ZFCP_LOG_INFO("error: exchange port data "
"command not supported by adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
return -EOPNOTSUPP;
}
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
0, NULL, &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Out of resources. Could not create an "
"exchange port data request for"
"the adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
write_unlock_irqrestore(&adapter->request_queue.queue_lock, write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags); lock_flags);
return retval; return retval;
} }
if (data)
fsf_req->data = (unsigned long) data;
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
if (!erp_action) { if (retval)
ZFCP_LOG_INFO("error: Could not send an exchange port data "
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
else
wait_event(fsf_req->completion_wq, wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
zfcp_fsf_req_free(fsf_req); zfcp_fsf_req_free(fsf_req);
}
return retval; return retval;
} }
...@@ -2277,18 +2380,16 @@ static void ...@@ -2277,18 +2380,16 @@ static void
zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter;
struct fsf_qtcb *qtcb; struct fsf_qtcb_bottom_port *bottom;
struct fsf_qtcb_bottom_port *bottom, *data;
struct Scsi_Host *shost; struct Scsi_Host *shost;
adapter = fsf_req->adapter; adapter = fsf_req->adapter;
qtcb = fsf_req->qtcb; bottom = &fsf_req->qtcb->bottom.port;
bottom = &qtcb->bottom.port;
shost = adapter->scsi_host; shost = adapter->scsi_host;
data = (struct fsf_qtcb_bottom_port*) fsf_req->data; if (fsf_req->data)
if (data) memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom,
memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); sizeof(struct fsf_qtcb_bottom_port));
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
fc_host_permanent_port_name(shost) = bottom->wwpn; fc_host_permanent_port_name(shost) = bottom->wwpn;
......
...@@ -731,7 +731,7 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost) ...@@ -731,7 +731,7 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost)
if (!data) if (!data)
return NULL; return NULL;
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
if (ret) { if (ret) {
kfree(data); kfree(data);
return NULL; /* XXX return zeroed fc_stats? */ return NULL; /* XXX return zeroed fc_stats? */
...@@ -761,7 +761,7 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) ...@@ -761,7 +761,7 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
if (!data) if (!data)
return; return;
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
if (ret) { if (ret) {
kfree(data); kfree(data);
} else { } else {
...@@ -800,6 +800,7 @@ struct fc_function_template zfcp_transport_functions = { ...@@ -800,6 +800,7 @@ struct fc_function_template zfcp_transport_functions = {
.show_host_port_type = 1, .show_host_port_type = 1,
.show_host_speed = 1, .show_host_speed = 1,
.show_host_port_id = 1, .show_host_port_id = 1,
.disable_target_scan = 1,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment