#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <machine/spl.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/fcntl.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netat/sysglue.h>
#include <netat/appletalk.h>
#include <netat/at_pcb.h>
#include <netat/debug.h>
#include <netat/adsp.h>
#include <netat/adsp_internal.h>
extern int adsp_check;
int CheckReadQueue(sp)
register CCBPtr sp;
{
register struct adspcmd *pb;
unsigned short cnt;
char eom = 0;
register gbuf_t *mp;
register gbuf_t *tmp;
gref_t *gref;
dPrintf(D_M_ADSP, D_L_TRACE, ("CheckReadQueue: sp=0x%x\n", (unsigned)sp));
KERNEL_DEBUG(DBG_ADSP_READ, 0, sp, sp->rbuf_mb, sp->rpb, sp->delay);
trace_mbufs(D_M_ADSP_LOW, " bCQR m", sp->rbuf_mb);
while (sp->rData && (pb = sp->rpb)) {
dPrintf(D_M_ADSP, D_L_TRACE,
(" pb=0x%x, gref=0x%x, ioc=0x%x, reqCount=%d (have data)\n",
pb, pb->gref, pb->ioc, pb->u.ioParams.reqCount));
KERNEL_DEBUG(DBG_ADSP_READ, 1, pb, pb->gref, pb->ioc, pb->u.ioParams.reqCount);
if (pb->u.ioParams.reqCount == 0) {
pb->ioResult = 0;
sp->rpb = pb->qLink;
if (pb->ioc) {
KERNEL_DEBUG(DBG_ADSP_READ, 2, pb, pb->gref, pb->ioc, 0);
adspioc_ack(0, pb->ioc, pb->gref);
} else {
KERNEL_DEBUG(DBG_ADSP_READ, 3, pb, pb->gref, 0, 0);
completepb(sp, pb);
}
continue;
}
if (mp = sp->rbuf_mb) {
KERNEL_DEBUG(DBG_ADSP_READ, 4, pb, mp, gbuf_msgsize(mp), gbuf_next(mp));
sp->rbuf_mb = gbuf_next(mp);
gbuf_next(mp) = 0;
eom = 1;
} else if (mp = sp->crbuf_mb) {
KERNEL_DEBUG(DBG_ADSP_READ, 5, pb, mp, gbuf_msgsize(mp), gbuf_next(mp));
sp->crbuf_mb = 0;
eom = 0;
}
cnt = gbuf_msgsize(mp);
if (cnt > (unsigned short)(pb->u.ioParams.reqCount - pb->u.ioParams.actCount)) {
cnt = pb->u.ioParams.reqCount - pb->u.ioParams.actCount;
if (!(tmp = (gbuf_t *)m_split(mp, cnt, M_DONTWAIT))) {
cnt = 0;
tmp = mp;
}
if (eom) {
gbuf_next(tmp) = sp->rbuf_mb;
sp->rbuf_mb = tmp;
eom = 0;
} else
sp->crbuf_mb = tmp;
}
if (cnt) {
pb->u.ioParams.actCount += cnt;
gbuf_linkb(pb->mp, mp);
}
pb->u.ioParams.eom = eom;
if ((sp->rbuf_mb == 0) &&
(sp->crbuf_mb == 0))
sp->rData = 0;
if (eom || (pb->u.ioParams.actCount >= pb->u.ioParams.reqCount) ||
((sp->state == sClosed) && (!sp->rData)) ) {
pb->ioResult = 0;
sp->rpb = pb->qLink;
if (pb->ioc) {
mp = gbuf_cont(pb->mp);
gbuf_cont(pb->mp) = 0;
gref = (gref_t *)pb->gref;
adspioc_ack(0, pb->ioc, pb->gref);
dPrintf(D_M_ADSP, D_L_TRACE, (" (pb->ioc) mp=%x\n", mp));
KERNEL_DEBUG(DBG_ADSP_READ, 0x0A, pb, mp,
gbuf_next(mp), gbuf_cont(mp));
SndMsgUp(gref, mp);
dPrintf(D_M_ADSP, D_L_TRACE,
(" (data) size req=%d\n", pb->u.ioParams.actCount));
KERNEL_DEBUG(DBG_ADSP_READ, 0x0B, pb, pb->ioc,
pb->u.ioParams.reqCount, pb->u.ioParams.actCount);
} else {
KERNEL_DEBUG(DBG_ADSP_READ, 0x0C, pb, sp,
pb->u.ioParams.actCount, sp->delay);
completepb(sp, pb);
}
}
}
if (pb = sp->rpb) {
dPrintf(D_M_ADSP, D_L_TRACE,
(" pb=0x%x, ioc=0x%x, reqCount=%d (no more data)\n",
pb, pb->ioc, pb->u.ioParams.reqCount));
KERNEL_DEBUG(DBG_ADSP_READ, 0x0D, pb, pb->ioc,
pb->u.ioParams.reqCount, pb->u.ioParams.actCount);
if (sp->state == sClosed) {
while (pb) {
KERNEL_DEBUG(DBG_ADSP_READ, 0x0E, pb, sp, pb->ioc, 0);
pb->ioResult = 0;
pb->u.ioParams.actCount = 0;
pb->u.ioParams.eom = 0;
sp->rpb = pb->qLink;
if (pb->ioc) {
adspioc_ack(0, pb->ioc, pb->gref);
} else {
completepb(sp, pb);
}
pb = sp->rpb;
}
} else if (pb->ioc) {
sp->rpb = pb->qLink;
pb->ioResult = 1;
tmp = gbuf_cont(pb->mp);
gbuf_cont(pb->mp) = 0;
if (mp = gbuf_copym(pb->mp)) {
KERNEL_DEBUG(DBG_ADSP_READ, 0x0F, pb, sp, pb->mp, 0);
adspioc_ack(0, pb->ioc, pb->gref);
pb = (struct adspcmd *)gbuf_rptr(mp);
pb->ioc = 0;
pb->mp = mp;
gbuf_cont(pb->mp) = tmp;
pb->qLink = sp->rpb;
sp->rpb = pb;
} else {
KERNEL_DEBUG(DBG_ADSP_READ, 0x10, pb, sp, pb->mp, 0);
if (tmp) {
sp->crbuf_mb = tmp;
sp->rData = 1;
}
pb->ioResult = errDSPQueueSize;
adspioc_ack(ENOBUFS, pb->ioc, pb->gref);
}
}
}
if (sp->rbufFull && (CalcRecvWdw(sp) > (sp->rbuflen >> 2))) {
sp->rbufFull = 0;
sp->sendDataAck = 1;
sp->callSend = 1;
}
KERNEL_DEBUG(DBG_ADSP_READ, 0x11, sp, 0, 0, 0);
trace_mbufs(D_M_ADSP_LOW, " eCQR m", sp->rbuf_mb);
return 0;
}
int CheckAttn(sp, pb)
register CCBPtr sp;
register struct adspcmd *pb;
{
gbuf_t *mp;
gref_t *gref;
dPrintf(D_M_ADSP, D_L_TRACE,
("CheckAttn: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
if (mp = sp->attn_mb) {
gref = (gref_t *)pb->gref;
pb->u.attnParams.attnSize = sp->attnSize;
pb->u.attnParams.attnCode = sp->attnCode;
if (!sp->attnSize) {
gbuf_freem(mp);
mp = 0;
}
sp->userFlags &= ~eAttention;
sp->attn_mb = 0;
pb->ioResult = 0;
} else {
pb->u.attnParams.attnSize = 0;
pb->u.attnParams.attnCode = 0;
pb->ioResult = 1;
}
adspioc_ack(0, pb->ioc, pb->gref);
if (mp) {
SndMsgUp(gref, mp);
}
return 0;
}
int adspRead(sp, pb)
register CCBPtr sp;
register struct adspcmd *pb;
{
register gbuf_t *mp;
dPrintf(D_M_ADSP, D_L_TRACE,
("adspRead: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
KERNEL_DEBUG(DBG_ADSP_READ, 0x12, sp, pb, sp->state, sp->rData);
if (sp == 0) {
pb->ioResult = errRefNum;
return EINVAL;
}
if (sp->state != sOpen && sp->state != sClosing && sp->state != sClosed) {
pb->ioResult = errState;
return EINVAL;
}
if (sp->rData && (sp->rpb == 0)) {
qAddToEnd(&sp->rpb, pb);
CheckReadQueue(sp);
} else if ((pb->u.ioParams.reqCount == 0) && (sp->rpb == 0)) {
pb->ioResult = 0;
adspioc_ack(0, pb->ioc, pb->gref);
return 0;
} else {
pb->ioResult = 1;
if (mp = gbuf_copym(pb->mp)) {
adspioc_ack(0, pb->ioc, pb->gref);
pb = (struct adspcmd *)gbuf_rptr(mp);
pb->ioc = 0;
pb->mp = mp;
qAddToEnd(&sp->rpb, pb);
} else {
pb->ioResult = errDSPQueueSize;
return ENOBUFS;
}
}
if (sp->callSend) {
CheckSend(sp);
}
return 0;
}
int adspReadAttention(sp, pb)
register CCBPtr sp;
register struct adspcmd *pb;
{
dPrintf(D_M_ADSP, D_L_TRACE,
("adspReadAttention: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
if (sp == 0) {
pb->ioResult = errRefNum;
return EINVAL;
}
if (sp->state != sOpen && sp->state != sClosing && sp->state != sClosed) {
pb->ioResult = errState;
return EINVAL;
}
CheckAttn(sp, pb);
CheckReadQueue(sp);
if (sp->callSend) {
CheckSend(sp);
}
return 0;
}