static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
-static void zfcp_fsf_req_free(struct zfcp_fsf_req *);
/* association between FSF command and FSF QTCB type */
static u32 fsf_qtcb_type[] = {
*
* locks: none
*/
-static void
+void
zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
{
if (likely(fsf_req->pool != NULL))
mempool_free(fsf_req, fsf_req->pool);
- else
- kfree(fsf_req);
+ else
+ kfree(fsf_req);
}
/*
int
zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
- int retval = 0;
struct zfcp_fsf_req *fsf_req, *tmp;
+ unsigned long flags;
+ LIST_HEAD(remove_queue);
- list_for_each_entry_safe(fsf_req, tmp, &adapter->fsf_req_list_head,
- list)
- zfcp_fsf_req_dismiss(fsf_req);
- /* wait_event_timeout? */
- while (!list_empty(&adapter->fsf_req_list_head)) {
- ZFCP_LOG_DEBUG("fsf req list of adapter %s not yet empty\n",
- zfcp_get_busid_by_adapter(adapter));
- /* wait for woken intiators to clean up their requests */
- msleep(jiffies_to_msecs(ZFCP_FSFREQ_CLEANUP_TIMEOUT));
- }
+ spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+ list_splice_init(&adapter->fsf_req_list_head, &remove_queue);
+ atomic_set(&adapter->fsf_reqs_active, 0);
+ spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
- /* consistency check */
- if (atomic_read(&adapter->fsf_reqs_active)) {
- ZFCP_LOG_NORMAL("bug: There are still %d FSF requests pending "
- "on adapter %s after cleanup.\n",
- atomic_read(&adapter->fsf_reqs_active),
- zfcp_get_busid_by_adapter(adapter));
- atomic_set(&adapter->fsf_reqs_active, 0);
+ list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+ list_del(&fsf_req->list);
+ zfcp_fsf_req_dismiss(fsf_req);
}
- return retval;
+ return 0;
}
/*
{
int retval = 0;
int cleanup;
- struct zfcp_adapter *adapter = fsf_req->adapter;
-
- /* do some statistics */
- atomic_dec(&adapter->fsf_reqs_active);
if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
ZFCP_LOG_DEBUG("Status read response received\n");
* lock must not be held here since it will be
* grabed by the called routine, too
*/
- zfcp_fsf_req_cleanup(fsf_req);
+ zfcp_fsf_req_free(fsf_req);
} else {
/* notify initiator waiting for the requests completion */
ZFCP_LOG_TRACE("waking initiator of FSF request %p\n",fsf_req);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
mempool_free(status_buffer, adapter->pool.data_status_read);
- zfcp_fsf_req_cleanup(fsf_req);
+ zfcp_fsf_req_free(fsf_req);
goto out;
}
break;
}
mempool_free(status_buffer, adapter->pool.data_status_read);
- zfcp_fsf_req_cleanup(fsf_req);
+ zfcp_fsf_req_free(fsf_req);
/*
* recycle buffer and start new request repeat until outbound
* queue is empty or adapter shutdown is requested
zfcp_get_busid_by_unit(unit));
debug_text_event(new_fsf_req->adapter->erp_dbf, 2,
"fsf_s_pboxed");
- zfcp_erp_port_reopen(unit->port, 0);
+ zfcp_erp_port_boxed(unit->port);
new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
| ZFCP_STATUS_FSFREQ_RETRY;
break;
unit->fcp_lun, unit->port->wwpn,
zfcp_get_busid_by_unit(unit));
debug_text_event(new_fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
- zfcp_erp_unit_reopen(unit, 0);
- zfcp_cmd_dbf_event_fsf("unitbox", new_fsf_req,
- &new_fsf_req->qtcb->header.fsf_status_qual,
- sizeof(union fsf_status_qual));
+ zfcp_erp_unit_boxed(unit);
new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
| ZFCP_STATUS_FSFREQ_RETRY;
break;
"(adapter %s, port d_id=0x%08x)\n",
zfcp_get_busid_by_port(port), port->d_id);
debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
- zfcp_erp_port_reopen(port, 0);
+ zfcp_erp_port_boxed(port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
| ZFCP_STATUS_FSFREQ_RETRY;
break;
static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter;
- fc_id_t d_id;
struct zfcp_port *port;
+ fc_id_t d_id;
struct fsf_qtcb_header *header;
struct fsf_qtcb_bottom_support *bottom;
struct zfcp_send_els *send_els;
send_els = fsf_req->data.send_els;
adapter = send_els->adapter;
+ port = send_els->port;
d_id = send_els->d_id;
header = &fsf_req->qtcb->header;
bottom = &fsf_req->qtcb->bottom.support;
switch (header->fsf_status_qual.word[0]){
case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");
- if (send_els->ls_code != ZFCP_LS_ADISC) {
- read_lock(&zfcp_data.config_lock);
- port = zfcp_get_port_by_did(adapter, d_id);
- if (port)
- zfcp_test_link(port);
- read_unlock(&zfcp_data.config_lock);
- }
+ if (port && (send_els->ls_code != ZFCP_LS_ADISC))
+ zfcp_test_link(port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
}
}
debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");
- read_lock(&zfcp_data.config_lock);
- port = zfcp_get_port_by_did(adapter, d_id);
if (port != NULL)
zfcp_erp_port_access_denied(port);
- read_unlock(&zfcp_data.config_lock);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
}
+ zfcp_set_fc_host_attrs(adapter);
return 0;
}
wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
del_timer_sync(timer);
- zfcp_fsf_req_cleanup(fsf_req);
+ zfcp_fsf_req_free(fsf_req);
out:
kfree(timer);
return retval;
/* mark port as open */
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN |
ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
+ atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
+ ZFCP_STATUS_COMMON_ACCESS_BOXED,
+ &port->status);
retval = 0;
/* check whether D_ID has changed during open */
/*
port->wwpn,
zfcp_get_busid_by_port(port));
debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_pboxed");
- zfcp_erp_port_reopen(port, 0);
+ zfcp_erp_port_boxed(port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
"needs to be reopened\n",
unit->port->wwpn, zfcp_get_busid_by_unit(unit));
debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
- zfcp_erp_port_reopen(unit->port, 0);
+ zfcp_erp_port_boxed(unit->port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
unit->handle);
/* mark unit as open */
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
-
+ atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
+ ZFCP_STATUS_COMMON_ACCESS_BOXED,
+ &unit->status);
if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){
if (!exclusive)
atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
unit->port->wwpn,
zfcp_get_busid_by_unit(unit));
debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
- zfcp_erp_port_reopen(unit->port, 0);
+ zfcp_erp_port_boxed(unit->port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
"needs to be reopened\n",
unit->port->wwpn, zfcp_get_busid_by_unit(unit));
debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
- zfcp_erp_port_reopen(unit->port, 0);
- zfcp_cmd_dbf_event_fsf("portbox", fsf_req,
- &header->fsf_status_qual,
- sizeof (union fsf_status_qual));
+ zfcp_erp_port_boxed(unit->port);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
zfcp_get_busid_by_unit(unit),
unit->port->wwpn, unit->fcp_lun);
debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
- zfcp_erp_unit_reopen(unit, 0);
- zfcp_cmd_dbf_event_fsf("unitbox", fsf_req,
- &header->fsf_status_qual,
- sizeof(union fsf_status_qual));
+ zfcp_erp_unit_boxed(unit);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
| ZFCP_STATUS_FSFREQ_RETRY;
break;
*status = fsf_req->status;
/* cleanup request */
- zfcp_fsf_req_cleanup(fsf_req);
+ zfcp_fsf_req_free(fsf_req);
out:
return retval;
}
inc_seq_no = 0;
/* put allocated FSF request at list tail */
- write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+ spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
- write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+ spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
/* figure out expiration time of timeout and start timeout */
if (unlikely(timer)) {
*/
if (timer)
del_timer(timer);
- write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+ spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
list_del(&fsf_req->list);
- write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+ spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
/*
* adjust the number of free SBALs in request queue as well as
* position of first one
return retval;
}
-/*
- * function: zfcp_fsf_req_cleanup
- *
- * purpose: cleans up an FSF request and removes it from the specified list
- *
- * returns:
- *
- * assumption: no pending SB in SBALEs other than QTCB
- */
-void
-zfcp_fsf_req_cleanup(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- unsigned long flags;
-
- write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
- list_del(&fsf_req->list);
- write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
- zfcp_fsf_req_free(fsf_req);
-}
-
#undef ZFCP_LOG_AREA