/* ARGSUSED */ static void emlxs_pkt_thread(emlxs_hba_t *hba, void *arg1, void *arg2) { emlxs_port_t *port; fc_packet_t *pkt = (fc_packet_t *)arg1; int32_t rval; emlxs_buf_t *sbp; sbp = PKT2PRIV(pkt); port = sbp->port; /* Send the pkt now */ rval = emlxs_pkt_send(pkt, 1); if (rval != FC_SUCCESS) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, "Deferred emlxs_pkt_send failed: status=%x pkt=%p", rval, pkt); if (pkt->pkt_comp) { emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 0, 1); ((CHANNEL *)sbp->channel)->ulpCmplCmd++; (*pkt->pkt_comp) (pkt); } else { emlxs_pkt_free(pkt); } } return; } /* emlxs_pkt_thread() */
/* Default pkt callback routine */ extern void emlxs_pkt_callback(fc_packet_t *pkt) { emlxs_pkt_free(pkt); return; } /* emlxs_pkt_callback() */
/* * Process a create_xri command completion. */ extern int32_t emlxs_handle_create_xri(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) { emlxs_port_t *port = &PPORT; IOCB *cmd; NODELIST *ndlp; fc_packet_t *pkt; emlxs_buf_t *sbp; cmd = &iocbq->iocb; sbp = (emlxs_buf_t *)iocbq->sbp; if (!sbp) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg, "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS, cmd->un.ulpWord[4]); return (EIO); } /* check for first xmit completion in sequence */ ndlp = (NODELIST *)sbp->node; if (cmd->ULPSTATUS) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg, "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x", cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS, cmd->un.ulpWord[4]); mutex_enter(&EMLXS_TX_CHANNEL_LOCK); ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; mutex_exit(&EMLXS_TX_CHANNEL_LOCK); return (EIO); } mutex_enter(&EMLXS_TX_CHANNEL_LOCK); ndlp->nlp_Xri = cmd->ULPCONTEXT; ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; mutex_exit(&EMLXS_TX_CHANNEL_LOCK); EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, "create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ULPIOTAG); pkt = sbp->pkt; emlxs_pkt_free(pkt); return (0); } /* emlxs_handle_create_xri() */
/* * Issue an iocb command to create an exchange with the remote Nport * specified by the NODELIST entry. */ extern int32_t emlxs_create_xri(emlxs_port_t *port, CHANNEL *cp, NODELIST *ndlp) { emlxs_hba_t *hba = HBA; IOCB *icmd; IOCBQ *iocbq; fc_packet_t *pkt; emlxs_buf_t *sbp; uint16_t iotag; /* Check if an XRI has already been requested */ mutex_enter(&EMLXS_TX_CHANNEL_LOCK); if (ndlp->nlp_Xri != 0 || (ndlp->nlp_flag[cp->channelno] & NLP_RPI_XRI)) { mutex_exit(&EMLXS_TX_CHANNEL_LOCK); return (0); } ndlp->nlp_flag[cp->channelno] |= NLP_RPI_XRI; mutex_exit(&EMLXS_TX_CHANNEL_LOCK); if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, "create_xri failed: Unable to allocate pkt. did=0x%x", ndlp->nlp_DID); goto fail; } sbp = (emlxs_buf_t *)pkt->pkt_fca_private; iocbq = &sbp->iocbq; /* Clear the PACKET_ULP_OWNED flag */ sbp->pkt_flags &= ~PACKET_ULP_OWNED; /* Get the iotag by registering the packet */ iotag = emlxs_register_pkt(cp, sbp); if (!iotag) { /* * No more command slots available, retry later */ emlxs_pkt_free(pkt); EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, "create_xri failed: Unable to allocate IOTAG. did=0x%x", ndlp->nlp_DID); goto fail; } icmd = &iocbq->iocb; icmd->ULPIOTAG = iotag; icmd->ULPCONTEXT = ndlp->nlp_Rpi; icmd->ULPLE = 1; icmd->ULPCOMMAND = CMD_CREATE_XRI_CR; icmd->ULPOWNER = OWN_CHIP; /* Initalize iocbq */ iocbq->port = (void *)port; iocbq->node = (void *)ndlp; iocbq->channel = (void *)cp; mutex_enter(&sbp->mtx); sbp->node = (void *)ndlp; sbp->channel = cp; mutex_exit(&sbp->mtx); EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg, "create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID, ndlp->nlp_Xri, iotag); EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq); return (0); fail: /* Clear the XRI flag */ mutex_enter(&EMLXS_TX_CHANNEL_LOCK); ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI; mutex_exit(&EMLXS_TX_CHANNEL_LOCK); return (1); } /* emlxs_create_xri() */