@ -138,7 +138,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
* @ phba : Driver private structure
* @ tag : Tag for the MBX Command
* @ wrb : the WRB used for the MBX Command
* @ cmd_hdr : IOCTL Hdr for the MBX Cmd
* @ mbx_cmd_mem : ptr to memory allocated for MBX Cmd
*
* Waits for MBX completion with the passed TAG .
*
@ -148,21 +148,26 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
* */
int beiscsi_mccq_compl ( struct beiscsi_hba * phba ,
uint32_t tag , struct be_mcc_wrb * * wrb ,
void * cmd_hdr )
struct be_dma_mem * mbx_cmd_mem )
{
int rc = 0 ;
uint32_t mcc_tag_response ;
uint16_t status = 0 , addl_status = 0 , wrb_num = 0 ;
struct be_mcc_wrb * temp_wrb ;
struct be_cmd_req_hdr * ioctl _hdr;
struct be_cmd_resp_hdr * ioctl _resp_hdr;
struct be_cmd_req_hdr * mbx _hdr;
struct be_cmd_resp_hdr * mbx _resp_hdr;
struct be_queue_info * mccq = & phba - > ctrl . mcc_obj . q ;
if ( beiscsi_error ( phba ) ) {
free_mcc_tag ( & phba - > ctrl , tag ) ;
return - EIO ;
return - EPERM ;
}
/* Set MBX Tag state to Active */
spin_lock ( & phba - > ctrl . mbox_lock ) ;
phba - > ctrl . ptag_state [ tag ] . tag_state = MCC_TAG_STATE_RUNNING ;
spin_unlock ( & phba - > ctrl . mbox_lock ) ;
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout (
phba - > ctrl . mcc_wait [ tag ] ,
@ -171,56 +176,71 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
BEISCSI_HOST_MBX_TIMEOUT ) ) ;
if ( rc < = 0 ) {
struct be_dma_mem * tag_mem ;
/* Set MBX Tag state to timeout */
spin_lock ( & phba - > ctrl . mbox_lock ) ;
phba - > ctrl . ptag_state [ tag ] . tag_state = MCC_TAG_STATE_TIMEOUT ;
spin_unlock ( & phba - > ctrl . mbox_lock ) ;
/* Store resource addr to be freed later */
tag_mem = & phba - > ctrl . ptag_state [ tag ] . tag_mem_state ;
if ( mbx_cmd_mem ) {
tag_mem - > size = mbx_cmd_mem - > size ;
tag_mem - > va = mbx_cmd_mem - > va ;
tag_mem - > dma = mbx_cmd_mem - > dma ;
} else
tag_mem - > size = 0 ;
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG ,
" BC_%d : MBX Cmd Completion timed out \n " ) ;
rc = - EBUSY ;
/* decrement the mccq used count */
atomic_dec ( & phba - > ctrl . mcc_obj . q . used ) ;
goto release_mcc_tag ;
} else
return - EBUSY ;
} else {
rc = 0 ;
/* Set MBX Tag state to completed */
spin_lock ( & phba - > ctrl . mbox_lock ) ;
phba - > ctrl . ptag_state [ tag ] . tag_state = MCC_TAG_STATE_COMPLETED ;
spin_unlock ( & phba - > ctrl . mbox_lock ) ;
}
mcc_tag_response = phba - > ctrl . mcc_numtag [ tag ] ;
status = ( mcc_tag_response & CQE_STATUS_MASK ) ;
addl_status = ( ( mcc_tag_response & CQE_STATUS_ADDL_MASK ) > >
CQE_STATUS_ADDL_SHIFT ) ;
if ( cmd_hdr ) {
ioctl _hdr = ( struct be_cmd_req_hdr * ) cmd_hdr ;
if ( mbx_cmd_mem ) {
mbx _hdr = ( struct be_cmd_req_hdr * ) mbx_cmd_mem - > va ;
} else {
wrb_num = ( mcc_tag_response & CQE_STATUS_WRB_MASK ) > >
CQE_STATUS_WRB_SHIFT ;
temp_wrb = ( struct be_mcc_wrb * ) queue_get_wrb ( mccq , wrb_num ) ;
ioctl _hdr = embedded_payload ( temp_wrb ) ;
mbx _hdr = embedded_payload ( temp_wrb ) ;
if ( wrb )
* wrb = temp_wrb ;
}
if ( status | | addl_status ) {
beiscsi_log ( phba , KERN_ERR ,
beiscsi_log ( phba , KERN_WARNING ,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG ,
" BC_%d : MBX Cmd Failed for "
" Subsys : %d Opcode : %d with "
" Status : %d and Extd_Status : %d \n " ,
ioctl _hdr- > subsystem ,
ioctl _hdr- > opcode ,
mbx _hdr- > subsystem ,
mbx _hdr- > opcode ,
status , addl_status ) ;
if ( status = = MCC_STATUS_INSUFFICIENT_BUFFER ) {
ioctl _resp_hdr = ( struct be_cmd_resp_hdr * ) ioctl _hdr;
mbx _resp_hdr = ( struct be_cmd_resp_hdr * ) mbx _hdr;
beiscsi_log ( phba , KERN_WARNING ,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG ,
" BC_%d : Insufficent Buffer Error "
" Resp_Len : %d Actual_Resp_Len : %d \n " ,
ioctl _resp_hdr- > response_length ,
ioctl _resp_hdr- > actual_resp_len ) ;
mbx _resp_hdr- > response_length ,
mbx _resp_hdr- > actual_resp_len ) ;
rc = - EAGAIN ;
goto release_mcc_tag ;
@ -319,6 +339,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
int be_mcc_compl_process_isr ( struct be_ctrl_info * ctrl ,
struct be_mcc_compl * compl )
{
struct beiscsi_hba * phba = pci_get_drvdata ( ctrl - > pdev ) ;
u16 compl_status , extd_status ;
unsigned short tag ;
@ -338,7 +359,32 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
ctrl - > mcc_numtag [ tag ] | = ( compl - > tag0 & 0x00FF0000 ) ;
ctrl - > mcc_numtag [ tag ] | = ( extd_status & 0x000000FF ) < < 8 ;
ctrl - > mcc_numtag [ tag ] | = ( compl_status & 0x000000FF ) ;
wake_up_interruptible ( & ctrl - > mcc_wait [ tag ] ) ;
if ( ctrl - > ptag_state [ tag ] . tag_state = = MCC_TAG_STATE_RUNNING ) {
wake_up_interruptible ( & ctrl - > mcc_wait [ tag ] ) ;
} else if ( ctrl - > ptag_state [ tag ] . tag_state = = MCC_TAG_STATE_TIMEOUT ) {
struct be_dma_mem * tag_mem ;
tag_mem = & ctrl - > ptag_state [ tag ] . tag_mem_state ;
beiscsi_log ( phba , KERN_WARNING ,
BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
BEISCSI_LOG_CONFIG ,
" BC_%d : MBX Completion for timeout Command "
" from FW \n " ) ;
/* Check if memory needs to be freed */
if ( tag_mem - > size )
pci_free_consistent ( ctrl - > pdev , tag_mem - > size ,
tag_mem - > va , tag_mem - > dma ) ;
/* Change tag state */
spin_lock ( & phba - > ctrl . mbox_lock ) ;
ctrl - > ptag_state [ tag ] . tag_state = MCC_TAG_STATE_COMPLETED ;
spin_unlock ( & phba - > ctrl . mbox_lock ) ;
/* Free MCC Tag */
free_mcc_tag ( ctrl , tag ) ;
}
return 0 ;
}