📄 minimux.c
字号:
{ cmn_err(CE_CONT, "mux_ioctl: I_UNLINK muxid %u: unknown muxid\n", lk->l_index) ; error = EINVAL ; goto iocnak ; } cmn_err(CE_CONT, "mux_ioctl: I_UNLINK minor=%u -> muxid=%u\n", muxp->minor_dev, lk->l_index) ; if (prev == NULL) /* 1st in list */ mux_head = lwr->list ; /* link around it */ else /* middle of list */ prev->list = lwr->list ; /* link around it */ if (lwr->othermux != NULL && lwr->othermux->othermux == lwr) lwr->othermux->othermux = NULL ;/* detach from lower */ if (muxp->othermux == lwr) muxp->othermux = NULL ; /* detach from lower */ RD(lwr->outq)->q_ptr = NULL ; /* clobber q ptr */ WR(lwr->outq)->q_ptr = NULL ; FREE(lwr) ; /* free structure */ } break ; case MINIMUX_UP: /* point lower to upper */ uplink = 1 ; case MINIMUX_DOWN: /* point upper to lower */ { mux_tbl_t *lwr ; int l_index ; if (iocb->ioc_count != sizeof(int)) { error = EINVAL ; goto iocnak ; } l_index = *( (int *) mp->b_cont->b_rptr ) ; for (lwr = mux_head; lwr != NULL; lwr = lwr->list) { if (lwr->ctl_strm == muxp && lwr->muxid == l_index) break ; } if (lwr == NULL) /* not found */ { cmn_err(CE_CONT, "mux_ioctl: MINIMUX_DOWN muxid %u: unknown muxid\n", l_index) ; error = EINVAL ; goto iocnak ; } if (uplink) /* point lwr to upper */ lwr->othermux = muxp ; /* lwr point up at us */ else /* point upper to lower */ muxp->othermux = lwr ; /* we point down to lower */ /* this lower does not */ /* necessarily point back */ /* up to us. */ } break ; default: error = EINVAL; iocnak: mp->b_datap->db_type = M_IOCNAK; iocb->ioc_error = error; iocb->ioc_count = rtn_count; putnext (muxp->outq, mp); /* send back upstream */ return ; } /* end of switch on ioc_cmd */ mp->b_datap->db_type = M_IOCACK; iocb->ioc_count = rtn_count; putnext (muxp->outq, mp);} /* mux_ioctl *//************************************************************************* mux_wput *************************************************************************** ** Upper wput routine. ** *************************************************************************/static intmux_wput (queue_t *q, mblk_t *mp){ queue_t *fwdq ; mux_tbl_t *muxp ; if (q->q_ptr == NULL) { freemsg(mp) ; return(0) ; } muxp = q->q_ptr ; if (muxp->othermux != NULL) /* linked to downstream queue */ fwdq = muxp->othermux->outq ; /* forward downstream */ else /* no downstream linkage */ fwdq = muxp->outq ; /* forwared back upstream */ switch (mp->b_datap->db_type) { case M_DATA: case M_PROTO: case M_PCPROTO: if (canputnext(fwdq)) /* check flow control */ putnext(fwdq, mp) ; else putq(fwdq, mp) ; break ; case M_IOCTL: mux_ioctl(muxp, mp) ; break ; case M_FLUSH: /* flush upper queue */ if (*mp->b_rptr & FLUSHW) flushq (q, FLUSHDATA); if (muxp->othermux != NULL && muxp->othermux->outq != NULL) { /* if connected, pass downstream */ flushq (muxp->othermux->outq, FLUSHDATA); /* lwr write q */ putnext(muxp->othermux->outq, mp); } else /* not connected */ if (*mp->b_rptr & FLUSHR) { flushq (RD(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHW; qreply (q, mp); /* reply as lowest driver */ } else freemsg (mp); break; } return(0) ;} /* mux_wput *//************************************************************************* mux_messenger_service *************************************************************************** ** Service a queue by attempting to forward messages subject to flow ** control constraints. ** *************************************************************************/static voidmux_messenger_service(queue_t *q){ mux_tbl_t *muxp ; mblk_t *mp; muxp = (mux_tbl_t *) q->q_ptr; while ((mp = getq(q)) != NULL) { if ( mp->b_datap->db_type <= QPCTL && !canputnext(q) ) { putbq(q, mp); break; } putnext(q, mp); }} /* mux_messenger_service */#if 0/************************************************************************* mux_wsrv *************************************************************************** ** Upper write service routine. Unused. ** *************************************************************************/static intmux_wsrv (queue_t *q){ return(0) ;} /* mux_wsrv */#endif/************************************************************************* mux_rsrv *************************************************************************** ** Upper read service procedure. ** *************************************************************************/static intmux_rsrv (queue_t *q){ mux_messenger_service(q) ; return(0) ;} /* mux_rsrv *//************************************************************************* mux_close *************************************************************************** ** Close routine. ** *************************************************************************/static intmux_close (queue_t *q, int dummy, cred_t *credp){ mux_tbl_t *muxp ; mux_tbl_t *prev ; if (q->q_ptr == NULL) return(0) ; prev = NULL ; for (muxp = mux_head; muxp != NULL; muxp = muxp->list) { if (muxp == (mux_tbl_t *) q->q_ptr) break ; /* found it */ prev = muxp ; } if (muxp == NULL) return(0) ; /* not found */ cmn_err(CE_CONT, "mux_close: minor=%d", muxp->minor_dev) ; if (muxp->othermux != NULL) cmn_err(CE_CONT, " -> muxid=%d\n", muxp->othermux->muxid) ; else cmn_err(CE_CONT, " no lower\n") ; if (prev == NULL) /* 1st in list */ mux_head = muxp->list ; /* link around it */ else /* middle of list */ prev->list = muxp->list ; /* link around it */ if (muxp->othermux != NULL && muxp->othermux->othermux == muxp) muxp->othermux->othermux = NULL ;/* detach from upper */ /* maybe orphans the lower */ RD(muxp->outq)->q_ptr = NULL ; /* clobber q ptr (cheap insurance) */ WR(muxp->outq)->q_ptr = NULL ; q->q_ptr = NULL ; mux_minors[muxp->minor_dev] = 0 ; /* make minor available */ FREE(muxp) ; /* free structure */ return 0 ;} /* mux_close *//************************************************************************* mux_lrput *************************************************************************** ** Lower read put procedure. Receives messages from driver below. ** *************************************************************************/static intmux_lrput (queue_t *q, mblk_t *mp){ queue_t *fwdq ; mux_tbl_t *muxp ; if (q->q_ptr == NULL) { freemsg(mp) ; return(0) ; } muxp = q->q_ptr ; if (muxp->othermux != NULL) /* linked to upstream queue */ fwdq = muxp->othermux->outq ; /* forward upstream */ else /* no upstream linkage */ fwdq = muxp->outq ; /* forwared back downstream */ switch (mp->b_datap->db_type) { case M_DATA: case M_PROTO: case M_PCPROTO: if (canputnext(fwdq)) /* check flow control */ putnext(fwdq, mp) ; else putq(fwdq, mp) ; break ; case M_IOCTL: freemsg(mp) ; /* ioctl from below */ break ; case M_FLUSH: /* flush lower queue */ if (*mp->b_rptr & FLUSHR) flushq (q, FLUSHDATA); if (muxp->othermux != NULL && muxp->othermux->outq != NULL) { /* if connected, pass upstream */ flushq (muxp->othermux->outq, FLUSHDATA); /* upper rd queue */ putnext(muxp->othermux->outq, mp); } else /* not connected */ if (*mp->b_rptr & FLUSHW) { flushq (WR(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHR; qreply (q, mp); /* reply as highest driver */ } else freemsg (mp); break; default: freemsg(mp) ; /* drop unknown messages */ break ; } return(0) ;} /* mux_lrput *//************************************************************************* mux_lwsrv *************************************************************************** ** Lower write service routine. ** *************************************************************************/static intmux_lwsrv (queue_t *q){ mux_messenger_service(q) ; return(0) ;} /* mux_lwsrv */#if 0/************************************************************************* mux_lrsrv *************************************************************************** ** Lower read service procedure. Unused. ** *************************************************************************/static intmux_lrsrv (queue_t *q){ return(0) ;} /* mux_lrsrv */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -