home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / Vector18.lha / ParNetExample / unit_str.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-18  |  3.7 KB  |  184 lines

  1. /*
  2.  * This code was originally written by Matthew Dillon and put into Public Domain
  3.  *
  4.  * All changes concerning the adaption of Matt's original code to the
  5.  * Vector Connection I/O board are © 1991-1993 by Henning Schmiedehausen
  6.  * All rights for this changes are reserved. The original code is Public Domain
  7.  *
  8.  * This code is distributed with the expressed written permission of Matthew
  9.  * Dillon (Thank you very much, Matt)
  10.  *
  11.  */
  12.  
  13. /*
  14.  *  UNIT_STR.C            STREAM PROTOCOL (not impl yet)
  15.  *
  16.  *                currently just datagram proto.
  17.  */
  18.  
  19. #include "defs.h"
  20.  
  21. void StreamBeginIO();
  22. void StreamAbortIO();
  23. void StreamClose();
  24. void StreamData();
  25.  
  26. /*
  27.  *  Called under Forbid
  28.  */
  29.  
  30. void
  31. UnitStreamOpen(iob, unitnum, flags)
  32. Iob *iob;
  33. long unitnum;
  34. long flags;
  35. {
  36.     Unit *unit;
  37.  
  38.     if (unit = FindUnitForPort(iob->io_Port)) {
  39.     if (unit->BeginIO != StreamBeginIO) {
  40.         iob->io_Error = PPERR_PORT_IN_USE;
  41.         return;
  42.     }
  43.     } else {
  44.     unit = AllocUnit(iob, StreamBeginIO, StreamAbortIO, StreamData, StreamClose);
  45.     }
  46.     iob->io_Unit = unit;
  47.     ++unit->RefCnt;
  48. }
  49.  
  50.  
  51. void
  52. StreamClose(iob)
  53. Iob *iob;
  54. {
  55.     Unit *unit = iob->io_Unit;
  56.  
  57.     if (--unit->RefCnt == 0) {
  58.     FreeUnit(unit);
  59.     }
  60.     iob->io_Unit = NULL;
  61. }
  62.  
  63. /*
  64.  *  UnitStreamData() is called whenever a low level network operation
  65.  *            completes for the given unit.  cmd is:
  66.  *
  67.  *            'r'     received data packet
  68.  *            'w'     wrote data packet
  69.  *            'W'     timeout writing data packet
  70.  *
  71.  *            The routine is called with the unit locked.
  72.  */
  73.  
  74. void
  75. StreamData(cmd, packet, actual)
  76. Packet *packet;
  77. long actual;    /*  'w', 'W'    */
  78. {
  79.     Unit *unit = packet->io_Unit;
  80.     Iob *iob;
  81.     long n;
  82.  
  83.     switch(cmd) {
  84.     case 'r':
  85.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  86.         iob->io_Flags &= ~IOF_QUEUED;
  87.  
  88.         n = actual;
  89.         iob->io_Actual = actual;
  90.         if (n < 0)
  91.         n = 0;
  92.         if (n > iob->io_Length) {
  93.         n = iob->io_Length;
  94.         iob->io_Error = PPERR_WARN_OVFLOW;
  95.         }
  96.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  97.         if ((iob->io_Flags & IOF_QUICK) == 0)
  98.         ReplyMsg(&iob->io_Message);
  99.     }
  100.  
  101.     /*
  102.      *  Note that if no read requests are pending the datagram is
  103.      *  thrown away.
  104.      */
  105.  
  106.     FreeParPacket(packet);
  107.     break;
  108.     case 'W':
  109.     Remove(packet->iob);
  110.     iob->io_Flags &= ~IOF_QUEUED;
  111.     iob->io_Error = 1;
  112.     iob->io_Actual = actual;
  113.     if ((iob->io_Flags & IOF_QUICK) == 0)
  114.         ReplyMsg(&iob->io_Message);
  115.     FreeParPacket(packet);
  116.     break;
  117.     case 'w':
  118.     Remove(packet->iob);
  119.     iob->io_Flags &= ~IOF_QUEUED;
  120.     iob->io_Actual = actual;
  121.     if ((iob->io_Flags & IOF_QUICK) == 0)
  122.         ReplyMsg(&iob->io_Message);
  123.     FreeParPacket(packet);
  124.     break;
  125.     }
  126. }
  127.  
  128. void
  129. StreamBeginIO(iob)
  130. Iob *iob;
  131. {
  132.     Unit *unit = iob->io_Unit;
  133.     Packet *packet;
  134.  
  135.     iob->io_Error = 0;
  136.     iob->io_Actual = 0;
  137.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  138.  
  139.     switch(iob->io_Command) {
  140.     case CMD_READ:
  141.     LockAddr(unit->UnitLock);
  142.     iob->io_Flags &= ~IOF_QUICK;
  143.     iob->io_Flags |= IOF_QUEUED;
  144.     AddTail(&unit->PendIOR, iob);
  145.     UnlockAddr(unit->UnitLock);
  146.     return;
  147.     case CMD_WRITE:
  148.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, NULL, 0);
  149.     LockAddr(unit->UnitLock);
  150.     AddTail(&unit->PendIOW, iob);
  151.     UnlockAddr(unit->UnitLock);
  152.  
  153.     QueuePacketForWrite(packet);
  154.     return;
  155.     default:
  156.     CtlBeginIO(iob);
  157.     return;
  158.     }
  159. }
  160.  
  161. /*
  162.  *  Abort a read or write request.  Currently only read requests may be
  163.  *  aborted.
  164.  */
  165.  
  166. void
  167. StreamAbortIO(iob)
  168. Iob *iob;
  169. {
  170.     if (iob->io_Command == CMD_READ) {
  171.     LockAddr(iob->io_Unit->UnitLock);
  172.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  173.         Remove(iob);
  174.         UnlockAddr(iob->io_Unit->UnitLock);
  175.         iob->io_Flags &= ~IOF_QUEUED;
  176.         iob->io_Error = -1;     /*    ??? */
  177.         ReplyMsg(&iob->io_Message);
  178.     } else {
  179.         UnlockAddr(iob->io_Unit->UnitLock);
  180.     }
  181.     }
  182. }
  183.  
  184.