/* * Through message handle for read side stream * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : M [RW_READER] * -. uinst_t->u_lock : A * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ int oplmsu_rcmn_through_hndl(queue_t *q, mblk_t *mp, int pri_flag) { lpath_t *lpath; ctrl_t *ctrl; queue_t *dst_queue = NULL; int act_flag; ASSERT(RW_READ_HELD(&oplmsu_uinst->lock)); mutex_enter(&oplmsu_uinst->l_lock); lpath = (lpath_t *)q->q_ptr; if (lpath->uinst != NULL) { act_flag = ACTIVE_RES; } else { act_flag = NOT_ACTIVE_RES; } mutex_exit(&oplmsu_uinst->l_lock); mutex_enter(&oplmsu_uinst->c_lock); if (((ctrl = oplmsu_uinst->user_ctrl) != NULL) && (((mp->b_datap->db_type == M_IOCACK) || (mp->b_datap->db_type == M_IOCNAK)) || (act_flag == ACTIVE_RES))) { dst_queue = RD(ctrl->queue); } else { mutex_exit(&oplmsu_uinst->c_lock); freemsg(mp); return (SUCCESS); } if (pri_flag == MSU_HIGH) { putq(dst_queue, mp); } else { if (canput(dst_queue)) { putq(dst_queue, mp); } else { /* * Place a normal priority message at the head of * read queue */ ctrl = (ctrl_t *)dst_queue->q_ptr; ctrl->lrq_flag = 1; ctrl->lrq_queue = q; mutex_exit(&oplmsu_uinst->c_lock); putbq(q, mp); return (FAILURE); } } mutex_exit(&oplmsu_uinst->c_lock); return (SUCCESS); }
/* * move unrecognized stuff upward */ static int parsersvc( queue_t *q ) { mblk_t *mp; while ((mp = getq(q))) { if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); parseprintf(DD_RSVC,("parse: RSVC - putnext\n")); } else { putbq(q, mp); parseprintf(DD_RSVC,("parse: RSVC - flow control wait\n")); break; } } return 0; }
/* * convert incoming data */ static int parserput( queue_t *q, mblk_t *mp ) { unsigned char type; switch (type = mp->b_datap->db_type) { default: /* * anything we don't know will be put on queue * the service routine will move it to the next one */ parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type)); if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); break; case M_BREAK: case M_DATA: { register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr; register mblk_t *nmp; register unsigned long ch; timestamp_t ctime; /* * get time on packet delivery */ uniqtime(&ctime.tv); if (!(parse->parse_status & PARSE_ENABLE)) { parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type)); if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); } else { parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK")); if (type == M_DATA) { /* * parse packet looking for start an end characters */ while (mp != (mblk_t *)NULL) { ch = rdchar(&mp); if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime)) { /* * up up and away (hopefully ...) * don't press it if resources are tight or nobody wants it */ nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); } } } else { if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime)) { /* * up up and away (hopefully ...) * don't press it if resources are tight or nobody wants it */ nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); } freemsg(mp); } break; } } /* * CD PPS support for non direct ISR hack */ case M_HANGUP: case M_UNHANGUP: { register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr; timestamp_t ctime; register mblk_t *nmp; register int status = cd_invert ^ (type == M_UNHANGUP); uniqtime(&ctime.tv); parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN")); if ((parse->parse_status & PARSE_ENABLE) && parse_iopps(&parse->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &ctime)) { nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); freemsg(mp); } else if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); if (status) { parse->parse_ppsclockev.tv = ctime.tv; ++(parse->parse_ppsclockev.serial); } } } return 0; }
void log_sendmsg(mblk_t *mp, zoneid_t zoneid) { log_t *lp; char *src, *dst; mblk_t *mp2 = mp->b_cont; log_ctl_t *lc = (log_ctl_t *)mp->b_rptr; int flags, fac; off_t facility = 0; off_t body = 0; zone_t *zptr = NULL; log_zone_t *lzp; int i; int backlog; /* * Need to special case the global zone here since this may be * called before zone_init. */ if (zoneid == GLOBAL_ZONEID) { lzp = &log_global; } else if ((zptr = zone_find_by_id(zoneid)) == NULL) { /* specified zone doesn't exist, free message and return */ log_freemsg(mp); return; } else { lzp = zone_getspecific(log_zone_key, zptr); } ASSERT(lzp != NULL); if ((lc->flags & lzp->lz_active) == 0) { if (zptr) zone_rele(zptr); log_freemsg(mp); return; } if (panicstr) { /* * Raise the console queue's q_hiwat to ensure that we * capture all panic messages. */ log_consq->q_hiwat = 2 * LOG_HIWAT; log_consq->q_flag &= ~QFULL; /* Message was created while panicking. */ lc->flags |= SL_PANICMSG; } src = (char *)mp2->b_rptr; dst = strstr(src, "FACILITY_AND_PRIORITY] "); if (dst != NULL) { facility = dst - src; body = facility + 23; /* strlen("FACILITY_AND_PRIORITY] ") */ } log_enter(); /* * In the early boot phase hrestime is invalid, then timechanged is 0. * If hrestime is not valid, the ttime is set to 0 here and the correct * ttime is calculated in log_conswitch() later. The log_conswitch() * calculation to determine the correct ttime does not use ttime data * from these log_ctl_t structures; it only uses ttime from log_ctl_t's * that contain good data. * */ lc->ltime = ddi_get_lbolt(); if (timechanged) { lc->ttime = gethrestime_sec(); } else { lc->ttime = 0; } flags = lc->flags & lzp->lz_active; log_seq_no[flags & SL_ERROR]++; log_seq_no[flags & SL_TRACE]++; log_seq_no[flags & SL_CONSOLE]++; /* * If this is in the global zone, start with the backlog, then * walk through the clone logs. If not, just do the clone logs. */ backlog = (zoneid == GLOBAL_ZONEID); i = LOG_LOGMINIDX; while (i <= LOG_LOGMAXIDX) { if (backlog) { /* * Do the backlog this time, then start on the * others. */ backlog = 0; lp = &log_backlog; } else { lp = &lzp->lz_clones[i++]; } if ((lp->log_flags & flags) && lp->log_wanted(lp, lc)) { if (canput(lp->log_q)) { lp->log_overflow = 0; lc->seq_no = log_seq_no[lp->log_flags]; if ((mp2 = copymsg(mp)) == NULL) break; if (facility != 0) { src = (char *)mp2->b_cont->b_rptr; dst = src + facility; fac = (lc->pri & LOG_FACMASK) >> 3; dst += snprintf(dst, LOG_FACSIZE + LOG_PRISIZE, "%s.%s", log_fac[MIN(fac, LOG_NFACILITIES)], log_pri[lc->pri & LOG_PRIMASK]); src += body - 2; /* copy "] " too */ while (*src != '\0') *dst++ = *src++; *dst++ = '\0'; mp2->b_cont->b_wptr = (uchar_t *)dst; } (void) putq(lp->log_q, mp2); } else if (++lp->log_overflow == 1) {
/* * MTP_UNITDATA_IND 20 - Connection-less data receive indication * ------------------------------------------------------------------------- * N_UNITDATA_IND (MTP_TRANSFER_IND) * ------------------------------------------------------------------------- * This covers only the MTP-TRANSFER-Indication primitive. * * Let me ask a question here: why dont we just pass the unitdata on to the * ASP and let the ASP translate it into an M3UA message. That way, if there * are different ASPs supporting different versions, that can be handled at * the ASP instead of here. Also, we don't know the transport type. If it * is an SCTP transport, it can do other things with the message, like select * stream. */ static int mtpp_unitdata_ind(queue_t *q, mblk_t *msg) { sls_t *sls; queue_t *wq; mtpp_t *mtp = Q_MTP(q); mblk_t *mp, *db = msg->b_cont; size_t dlen = msgdsize(db); N_unitdata_ind_t *p = (N_unitdata_req_t *) msg->b_rptr; struct mtp_rl *rl = (mtp_rt *) (((caddr_t) p) + p->SRC_offset); static const size_t mlen = M3UA_MHDR_SIZE + M3UA_PARM_SIZE_RC + M3UA_PARM_SIZE_RL + M3UA_PHDR_SIZE; /* * First let's find out where the data is going. The AS should have * this all set up for us in the SLS tables. */ ensure(mtp, return (-EFAULT)); ensure(mtp->rc, return (-EFAULT)); ensure(mtp->rc->as, return (-EFAULT)); sls = &mtp->rc->as->sls[(rl->sls & UA_SLS_MASK)]; ensure(sls->sp, return (-EFAULT)); ensure(sls->sp->lp, return (-EFAULT)); ensure(sls->sp->lp->q, return (-EFAULT)); if (!(sls->flags & UA_SLS_BUFFERING)) if (!(canput((wq = WR(sls->sp->lp->q))))) return (-EBUSY); /* apply backpressure! */ if ((mp = allocb(mlen, BPRI_MED))) { mp->b_datap->db_type = M_DATA; *((uint32_t *) mp->b_wptr)++ = M3UA_MAUP_DATA; *((uint32_t *) mp->b_wptr)++ = htonl(mlen + dlen); *((uint32_t *) mp->b_wptr)++ = M3UA_PARM_NA; *((uint32_t *) mp->b_wptr)++ = htonl(mtp->na); *((uint32_t *) mp->b_wptr)++ = M3UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = htonl(mtp->rc); /* * A couple of big arguments on what should be in the * messages here... */ *((uint32_t *) mp->b_wptr)++ = M3UA_PARM_RL; *((uint32_t *) mp->b_wptr)++ = hotnl(rl->opc); *((uint32_t *) mp->b_wptr)++ = hotnl(rl->dpc); *((uint8_t *) mp->b_wptr)++ = 0; *((uint8_t *) mp->b_wptr)++ = hotnl(rl->sls); *((uint8_t *) mp->b_wptr)++ = hotnl(rl->ni); *((uint8_t *) mp->b_wptr)++ = hotnl(rl->mp); *((uint32_t *) mp->b_wptr)++ = M3UA_PARM_DATA; mp->b_cont = db; freeb(msg); if (sls->flags & UA_SLS_BUFFERING) /* hold back data for this sls */ bufq_queue(&sls->buf, mp); else putq(wq, mp); return (0); } return (-ENOBUFS); /* try again later */ }
/* * Through message handle for write side stream * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : M [RW_READER or RW_WRITER] * -. uinst_t->u_lock : P * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ int oplmsu_wcmn_through_hndl(queue_t *q, mblk_t *mp, int pri_flag, krw_t rw) { queue_t *usr_queue = NULL, *dst_queue = NULL; ctrl_t *ctrl; ASSERT(RW_LOCK_HELD(&oplmsu_uinst->lock)); mutex_enter(&oplmsu_uinst->c_lock); if ((ctrl = oplmsu_uinst->user_ctrl) != NULL) { usr_queue = ctrl->queue; mutex_exit(&oplmsu_uinst->c_lock); } else { mutex_exit(&oplmsu_uinst->c_lock); if (mp->b_datap->db_type == M_IOCTL) { rw_exit(&oplmsu_uinst->lock); oplmsu_iocack(q, mp, ENODEV); rw_enter(&oplmsu_uinst->lock, rw); } else { freemsg(mp); } return (SUCCESS); } if (oplmsu_uinst->lower_queue != NULL) { dst_queue = WR(oplmsu_uinst->lower_queue); } else { cmn_err(CE_WARN, "!oplmsu: through-lwq: " "Active path doesn't exist"); if (mp->b_datap->db_type == M_IOCTL) { rw_exit(&oplmsu_uinst->lock); oplmsu_iocack(q, mp, ENODEV); rw_enter(&oplmsu_uinst->lock, rw); } else { freemsg(mp); } return (SUCCESS); } if ((usr_queue == WR(q)) || (usr_queue == RD(q))) { if (pri_flag == MSU_HIGH) { putq(dst_queue, mp); } else { if (canput(dst_queue)) { putq(dst_queue, mp); } else { oplmsu_wcmn_norm_putbq(WR(q), mp, dst_queue); return (FAILURE); } } } else { cmn_err(CE_WARN, "oplmsu: through-lwq: " "Inappropriate message for this node"); if (mp->b_datap->db_type == M_IOCTL) { rw_exit(&oplmsu_uinst->lock); oplmsu_iocack(q, mp, ENODEV); rw_enter(&oplmsu_uinst->lock, rw); } else { freemsg(mp); } } return (SUCCESS); }