#include <sys/param.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/file.h>
#include <sys/errno.h>
#include <sys/stream.h>
#include <sys/strsubr.h>
#include <sys/vnode.h>
#include <sys/ioctl.h>
#include <sys/stropts.h>
#include <sys/tihdr.h>
#include <sys/timod.h>
#include <sys/tiuser.h>
#include <sys/t_kuser.h>
#include <sys/debug.h>
int
t_ksndudata(TIUSER *tiptr, struct t_kunitdata *unitdata, frtn_t *frtn)
{
int msgsz;
file_t *fp;
mblk_t *bp;
mblk_t *dbp;
struct T_unitdata_req *udreq;
int error;
int flag;
error = 0;
fp = tiptr->fp;
msgsz = unitdata->udata.len;
if (frtn != NULL) {
ASSERT(unitdata->udata.udata_mp == NULL);
ASSERT(unitdata->udata.buf != NULL);
if ((dbp = (mblk_t *)esballoc((uchar_t *)unitdata->udata.buf,
(size_t)msgsz, BPRI_LO, frtn)) == NULL)
return (ENOSR);
dbp->b_datap->db_type = M_DATA;
KTLILOG(2, "t_ksndudata: bp %x, ", dbp);
KTLILOG(2, "len %d, ", msgsz);
KTLILOG(2, "free func %x\n", frtn->free_func);
} else if (unitdata->udata.buf) {
ASSERT(unitdata->udata.udata_mp == NULL);
while (!(dbp = allocb(msgsz, BPRI_LO)))
if (strwaitbuf((size_t)msgsz, BPRI_LO))
return (ENOSR);
bcopy(unitdata->udata.buf, dbp->b_wptr, unitdata->udata.len);
dbp->b_datap->db_type = M_DATA;
} else if (unitdata->udata.udata_mp) {
ASSERT(unitdata->udata.buf == NULL);
dbp = unitdata->udata.udata_mp;
goto gotdp;
} else {
dbp = NULL;
}
if (dbp)
dbp->b_wptr += msgsz;
gotdp:
msgsz = (int)TUNITDATAREQSZ;
while (!(bp = allocb_cred(msgsz + unitdata->addr.len +
unitdata->opt.len, fp->f_cred, NOPID))) {
if (strwaitbuf(msgsz + unitdata->addr.len + unitdata->opt.len,
BPRI_LO)) {
if (dbp && (dbp != unitdata->udata.udata_mp))
freeb(dbp);
return (ENOSR);
}
}
udreq = (struct T_unitdata_req *)bp->b_wptr;
udreq->PRIM_type = T_UNITDATA_REQ;
udreq->DEST_length = unitdata->addr.len;
if (unitdata->addr.len) {
bcopy(unitdata->addr.buf, bp->b_wptr + msgsz,
unitdata->addr.len);
udreq->DEST_offset = (t_scalar_t)msgsz;
msgsz += unitdata->addr.len;
} else
udreq->DEST_offset = 0;
udreq->OPT_length = unitdata->opt.len;
if (unitdata->opt.len) {
bcopy(unitdata->opt.buf, bp->b_wptr + msgsz, unitdata->opt.len);
udreq->OPT_offset = (t_scalar_t)msgsz;
msgsz += unitdata->opt.len;
} else
udreq->OPT_offset = 0;
bp->b_datap->db_type = M_PROTO;
bp->b_wptr += msgsz;
linkb(bp, dbp);
flag = fp->f_flag;
error = tli_send(tiptr, bp, flag);
unitdata->udata.udata_mp = NULL;
return (error);
}