home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * UNIT_DGR.C DATAGRAM PROTOCOL
- */
-
- #include "defs.h"
-
- void DGramBeginIO(Iob *);
- void DGramAbortIO(Iob *);
- void DGramClose(Iob *);
- void DGramData(int, Packet *, long);
-
- void UnitDGramOpen(Iob *, long, long);
-
- /*
- * Called under Forbid
- */
-
- void
- UnitDGramOpen(iob, unitnum, flags)
- Iob *iob;
- long unitnum;
- long flags;
- {
- Unit *unit;
-
- if (unit = FindUnitForPort(iob->io_Port)) {
- if (unit->BeginIO != DGramBeginIO) {
- iob->io_Error = PPERR_PORT_IN_USE;
- return;
- }
- } else {
- unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
- }
- iob->io_Unit = unit;
- ++unit->RefCnt;
- }
-
-
- void
- DGramClose(iob)
- Iob *iob;
- {
- Unit *unit = iob->io_Unit;
-
- if (--unit->RefCnt == 0) {
- FreeUnit(unit);
- }
- iob->io_Unit = NULL;
- }
-
- /*
- * UnitDGramData() is called whenever a low level network operation
- * completes for the given unit. cmd is:
- *
- * 'r' received data packet
- * 'w' wrote data packet
- * 'W' timeout writing data packet
- *
- * The routine is called with the unix locked.
- *
- * WARNING: This call may not requeue synchronous packets, a lockout
- * will result.
- */
-
- void
- DGramData(cmd, packet, actual)
- int cmd;
- Packet *packet;
- long actual; /* 'w', 'W' */
- {
- Unit *unit = packet->io_Unit;
- Iob *iob = packet->iob; /* NULL for 'r' */
- long n;
-
- switch(cmd) {
- case 'r':
- sprintf(StickyPort->DebugBuf, " RDDRG %d",actual);
-
- if (iob = (Iob *)RemHead(&unit->PendIOR)) {
- iob->io_Flags &= ~IOF_QUEUED;
-
- n = actual;
- if (n < 0)
- n = 0;
- if (n > iob->io_Length) {
- n = iob->io_Length;
- iob->io_Error = PPERR_WARN_OVFLOW;
- }
- actual -= n;
- movmem((char *)packet->Data1, (char *)iob->io_Data, n);
-
- if (iob->io_Length2 && actual > 0) { /* a second data buffer */
- if (actual > iob->io_Length2)
- actual = iob->io_Length2;
- movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
- n += actual;
- }
- iob->io_Actual = n;
-
- if ((iob->io_Flags & IOF_QUICK) == 0)
- ReplyMsg(&iob->io_Message);
- }
-
- /*
- * Note that if no read requests are pending the datagram is
- * thrown away.
- */
-
- FreeParPacket(packet);
- break;
- case 'W':
- sprintf(StickyPort->DebugBuf, " TMDRG %d",actual);
-
- Remove(iob);
- iob->io_Flags &= ~IOF_QUEUED;
- iob->io_Error = 1;
- iob->io_Actual = actual;
- if ((iob->io_Flags & IOF_QUICK) == 0)
- ReplyMsg(&iob->io_Message);
- FreeParPacket(packet);
- break;
- case 'w':
- sprintf(StickyPort->DebugBuf, " WRDRG %d",actual);
-
- Remove(iob);
- iob->io_Flags &= ~IOF_QUEUED;
- iob->io_Actual = actual;
- if ((iob->io_Flags & IOF_QUICK) == 0)
- ReplyMsg(&iob->io_Message);
- FreeParPacket(packet);
- break;
- }
- }
-
- void
- DGramBeginIO(iob)
- Iob *iob;
- {
- Unit *unit = iob->io_Unit;
- Packet *packet;
-
- iob->io_Error = 0;
- iob->io_Actual = 0;
- iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
-
- switch(iob->io_Command) {
- case CMD_READ:
- LockAddr(unit->UnitLock);
- iob->io_Flags &= ~IOF_QUICK;
- iob->io_Flags |= IOF_QUEUED;
- AddTail(&unit->PendIOR, iob);
- UnlockAddr(unit->UnitLock);
- return;
- case CMD_WRITE:
- packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
- LockAddr(unit->UnitLock);
- AddTail(&unit->PendIOW, iob);
- UnlockAddr(unit->UnitLock);
-
- QueuePacketForWrite(packet);
- return;
- default:
- CtlBeginIO(iob);
- return;
- }
- }
-
- /*
- * Abort a read or write request. Currently only read requests may be
- * aborted.
- */
-
- void
- DGramAbortIO(iob)
- Iob *iob;
- {
- if (iob->io_Command == CMD_READ) {
- LockAddr(iob->io_Unit->UnitLock);
- if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
- Remove(iob);
- UnlockAddr(iob->io_Unit->UnitLock);
- iob->io_Flags &= ~IOF_QUEUED;
- iob->io_Error = -1; /* ??? */
- ReplyMsg(&iob->io_Message);
- } else {
- UnlockAddr(iob->io_Unit->UnitLock);
- }
- }
- }
-
-