home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * UNIT_STR.C STREAM PROTOCOL (not impl yet)
- *
- * currently just datagram proto.
- */
-
- #include "defs.h"
-
- void StreamBeginIO(Iob *);
- void StreamAbortIO(Iob *);
- void StreamClose(Iob *);
- void StreamData(int, Packet *, long);
-
- void UnitStreamOpen(Iob *, long, long);
-
- /*
- * Called under Forbid
- */
-
- void
- UnitStreamOpen(iob, unitnum, flags)
- Iob *iob;
- long unitnum;
- long flags;
- {
- Unit *unit;
-
- if (unit = FindUnitForPort(iob->io_Port)) {
- if (unit->BeginIO != StreamBeginIO) {
- iob->io_Error = PPERR_PORT_IN_USE;
- return;
- }
- } else {
- unit = AllocUnit(iob, StreamBeginIO, StreamAbortIO, StreamData, StreamClose);
- }
- iob->io_Unit = unit;
- ++unit->RefCnt;
- }
-
-
- void
- StreamClose(iob)
- Iob *iob;
- {
- Unit *unit = iob->io_Unit;
-
- if (--unit->RefCnt == 0) {
- FreeUnit(unit);
- }
- iob->io_Unit = NULL;
- }
-
- /*
- * UnitStreamData() 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 unit locked.
- */
-
- void
- StreamData(cmd, packet, actual)
- int cmd;
- Packet *packet;
- long actual; /* 'w', 'W' */
- {
- Unit *unit = packet->io_Unit;
- Iob *iob;
- long n;
-
- switch(cmd) {
- case 'r':
- sprintf(StickyPort->DebugBuf, " RDSTR %d",actual);
-
- if (iob = (Iob *)RemHead(&unit->PendIOR)) {
- iob->io_Flags &= ~IOF_QUEUED;
-
- n = actual;
- iob->io_Actual = actual;
- if (n < 0)
- n = 0;
- if (n > iob->io_Length) {
- n = iob->io_Length;
- iob->io_Error = PPERR_WARN_OVFLOW;
- }
- movmem((char *)packet->Data1, (char *)iob->io_Data, 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, " TMSTR %d",actual);
-
- Remove(packet->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, " WRSTR %d",actual);
-
- Remove(packet->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
- StreamBeginIO(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, NULL, 0);
- 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
- StreamAbortIO(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);
- }
- }
- }
-
-