> +int ocrdma_qp_state_machine(struct ocrdma_qp *qp, enum ib_qp_state > new_ib_state, > + enum ib_qp_state *old_ib_state) > +{ > + unsigned long flags; > + int status = 0; > + enum ocrdma_qp_state new_state; > + new_state = get_ocrdma_qp_state(new_ib_state); > + > + /* sync with wqe and rqe posting */ > + spin_lock_irqsave(&qp->q_lock, flags); > + > + if (old_ib_state) > + *old_ib_state = get_ibqp_state(qp->state); > + if (new_state == qp->state) { > + spin_unlock_irqrestore(&qp->q_lock, flags); > + return 1; > + } > + > + switch (qp->state) { > + case OCRDMA_QPS_RST: > + switch (new_state) { > + case OCRDMA_QPS_RST: > + case OCRDMA_QPS_INIT: > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_INIT: > + /* qps: INIT->XXX */ > + switch (new_state) { > + case OCRDMA_QPS_INIT: > + case OCRDMA_QPS_RTR: > + break; > + case OCRDMA_QPS_ERR: > + ocrdma_flush_qp(qp); > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_RTR: > + /* qps: RTS->XXX */ > + switch (new_state) { > + case OCRDMA_QPS_RTS: > + break; > + case OCRDMA_QPS_ERR: > + ocrdma_flush_qp(qp); > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_RTS: > + /* qps: RTS->XXX */ > + switch (new_state) { > + case OCRDMA_QPS_SQD: > + case OCRDMA_QPS_SQE: > + break; > + case OCRDMA_QPS_ERR: > + ocrdma_flush_qp(qp); > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_SQD: > + /* qps: SQD->XXX */ > + switch (new_state) { > + case OCRDMA_QPS_RTS: > + case OCRDMA_QPS_SQE: > + case OCRDMA_QPS_ERR: > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_SQE: > + switch (new_state) { > + case OCRDMA_QPS_RTS: > + case OCRDMA_QPS_ERR: > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + case OCRDMA_QPS_ERR: > + /* qps: ERR->XXX */ > + switch (new_state) { > + case OCRDMA_QPS_RST: > + break; > + default: > + status = -EINVAL; > + break; > + }; > + break; > + default: > + status = -EINVAL; > + break; > + }; > + if (!status) > + qp->state = new_state; > + > + spin_unlock_irqrestore(&qp->q_lock, flags); > + return status; > +}
The switch statement here seems to largely reimpliment ib_modify_qp_is_ok() (which is exported from the rdma midlayer). Is there some reason that doesn't work for your driver? I'd rather fix / generalize the core helper function instead of having something mostly duplicate in a hardware driver.