#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 <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>
int FillSendQueue(CCBPtr, struct adspcmd *);
int FillSendQueue(
register CCBPtr sp,
register struct adspcmd *pb)
{
gbuf_t *mb, *nmb;
int eom;
int cnt;
int err = 0;
cnt = pb->u.ioParams.reqCount - pb->u.ioParams.actCount;
eom = pb->u.ioParams.eom ? F_EOM : 0;
if (cnt == 0 && eom == 0)
goto unlink;
mb = pb->mp;
nmb = gbuf_cont(mb);
if (gbuf_len(mb) > sizeof(struct adspcmd)) {
if ((nmb = gbuf_dupb(mb)) == 0) {
gbuf_wset(mb,sizeof(struct adspcmd));
err = errDSPQueueSize;
goto unlink;
}
gbuf_wset(mb,sizeof(struct adspcmd));
gbuf_rinc(nmb,sizeof(struct adspcmd));
gbuf_cont(nmb) = gbuf_cont(mb);
} else if (nmb == 0) {
if ((nmb = gbuf_alloc(1, PRI_LO)) == 0) {
err = errENOBUFS;
goto unlink;
}
}
gbuf_cont(mb) = 0;
sp->sData = 1;
if ((mb = sp->csbuf_mb)) {
gbuf_linkb(mb, nmb);
} else
sp->csbuf_mb = nmb;
if (eom) {
if ((mb = sp->sbuf_mb)) {
while (gbuf_next(mb))
mb = gbuf_next(mb);
gbuf_next(mb) = sp->csbuf_mb;
} else
sp->sbuf_mb = sp->csbuf_mb;
sp->csbuf_mb = 0;
}
pb->u.ioParams.actCount += cnt;
if (pb->u.ioParams.actCount == pb->u.ioParams.reqCount) {
unlink:
if (pb->u.ioParams.flush)
sp->writeFlush = 1;
pb->ioResult = err;
if (err)
atalk_notify(sp->gref, EIO);
gbuf_freem(pb->mp);
}
return 0;
}
int adspWrite(sp, pb)
CCBPtr sp;
struct adspcmd *pb;
{
if (sp == 0) {
pb->ioResult = errRefNum;
return EINVAL;
}
if (sp->state != sOpen) {
pb->ioResult = errState;
atalk_notify(sp->gref, ENOTCONN);
gbuf_freem(pb->mp);
return 0;
}
pb->u.ioParams.actCount = 0;
FillSendQueue(sp, pb);
CheckSend(sp);
return 0;
}
#ifdef notdef
int adsp_check = 1;
CheckQueue(sp)
CCBPtr sp;
{
register gbuf_t *mp, *tmp;
unsigned char current;
int current_valid = 0;
if (adsp_check == 0)
return;
if (mp = sp->sbuf_mb) {
current = *mp->b_rptr;
current_valid = 1;
while (mp) {
tmp = mp;
while (tmp) {
current = CheckData(tmp->b_rptr, tmp->b_wptr - tmp->b_rptr,
current);
tmp = tmp->b_cont;
}
mp = mp->b_next;
}
}
if (mp = sp->csbuf_mb) {
if (current_valid == 0)
current = *mp->b_rptr;
tmp = mp;
while (tmp) {
current = CheckData(tmp->b_rptr, tmp->b_wptr - tmp->b_rptr,
current);
tmp = tmp->b_cont;
}
}
}
int adsp_bad_block_count;
char *adsp_bad_block;
CheckData(block, size, current)
char *block;
int size;
u_char current;
{
register int anError = 0;
register int i;
for (i = 0; i < size; i++) {
if ((block[i] & 0xff) != (current & 0xff)) {
if (!anError) {
adsp_bad_block = block;
}
anError++;
}
current++;
}
if (anError) {
adsp_bad_block_count++;
}
return current;
}
#endif