home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * TASK.C
- *
- * -Accept packets to send to network
- * -Receive data from network
- *
- * ParWrite(destaddr, buf, bytes)
- */
-
- #include "defs.h"
-
- /* par.asm */
- extern int ParDataReady(void);
- extern int ParReadV();
- extern int ParWriteV();
-
- typedef struct {
- uword Port; /* destination port */
- uword ChkSum; /* data checksum */
- ulong Bytes; /* # of bytes */
- } Header;
-
- char DataBuf[MAXPKTSIZE];
- Header Hdr;
- long TLock[2] = { 0, 0 };
- static short Cnt = 0;
-
- /* prototyping */
- void CParNetTask(void);
- int OutputPacket(Packet *);
-
- void
- CParNetTask(void)
- {
- long mask;
- Unit *unit;
- Packet *packet;
- long n;
-
- for (;;) {
- mask = Wait(SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
- LockAddr(TLock);
- if (mask & SIGBREAKF_CTRL_F) { /* packet pending */
- data:
- if (ParDataReady() > 0) {
- n = ParReadV(&Hdr, sizeof(Hdr), DataBuf, MAXPKTSIZE, NULL, NULL);
-
- sprintf(StickyPort->DebugBuf, "%03d READ %6ld bytes port %d", Cnt++,n, Hdr.Port);
-
- if (n >= sizeof(Hdr) && n >= sizeof(Hdr) + Hdr.Bytes) {
- if (unit = FindUnitForPort(Hdr.Port)) {
- packet = AllocParPacket(NULL, unit, DataBuf, Hdr.Bytes, NULL, 0);
- LockAddr(unit->UnitLock);
- (*packet->io_Unit->DataFunc)('r', packet, n - sizeof(Hdr));
- UnlockAddr(unit->UnitLock);
- }
- }
- }
- }
- if (mask & SIGBREAKF_CTRL_E) { /* port */
- while (packet = (Packet *)GetMsg(&DevBase->Port)) {
- n = OutputPacket(packet);
- if (n == -2) {
- Forbid();
- AddHead(&DevBase->Port.mp_MsgList, (struct Node *)packet);
- Permit();
- goto data;
- }
- }
- }
- UnlockAddr(TLock);
- }
- }
-
- int
- OutputPacket(packet)
- Packet *packet;
- {
- long n;
- Unit *unit = packet->io_Unit;
-
- Hdr.Port = packet->DestPort;
- Hdr.ChkSum= 0;
- Hdr.Bytes = packet->DLen1 + packet->DLen2;
-
- n = ParWriteV(packet->DestAddr, &Hdr, sizeof(Hdr), packet->Data1, packet->DLen1, packet->Data2, packet->DLen2, NULL, NULL);
-
- sprintf(StickyPort->DebugBuf, "%03d WRITE %6ld to %d port %d", Cnt++,
- n,packet->DestAddr,packet->DestPort);
-
- if (n == -2) /* can't write, pending rcv */
- return(n);
- LockAddr(unit->UnitLock);
- if (n == sizeof(Hdr) + packet->DLen1 + packet->DLen2)
- (*unit->DataFunc)('w', packet, n - sizeof(Hdr));
- else
- (*unit->DataFunc)('W', packet, n - sizeof(Hdr));
- UnlockAddr(unit->UnitLock);
- return(n);
- }
-
-
- /*
- * Queue packet for write. If QUICKIO is requested and the packet can be
- * sent manually it is, else it is queued to the task.
- */
-
- void
- QueuePacketForWrite(packet)
- Packet *packet;
- {
- Iob *iob = packet->iob;
-
- if ((iob->io_Flags & IOF_QUICK) && TryLockAddr(TLock) > 0) {
- if (OutputPacket(packet) != -2) {
- UnlockAddr(TLock);
- return;
- }
- /*
- * Can't write packet, rcv packet pending.
- */
- UnlockAddr(TLock);
- }
- iob->io_Flags &= ~IOF_QUICK;
- iob->io_Flags |= IOF_QUEUED;
- PutMsg(&DevBase->Port, &packet->Msg);
- }
-
-