home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / Vector18.lha / ParNetExample / unit_dgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-18  |  4.0 KB  |  194 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_DGR.C            DATAGRAM PROTOCOL
  15.  */
  16.  
  17. #include "defs.h"
  18.  
  19. void DGramBeginIO();
  20. void DGramAbortIO();
  21. void DGramClose();
  22. void DGramData();
  23.  
  24. /*
  25.  *  Called under Forbid
  26.  */
  27.  
  28. void
  29. UnitDGramOpen(iob, unitnum, flags)
  30. Iob *iob;
  31. long unitnum;
  32. long flags;
  33. {
  34.     Unit *unit;
  35.  
  36.     if (unit = FindUnitForPort(iob->io_Port)) {
  37.     if (unit->BeginIO != DGramBeginIO) {
  38.         iob->io_Error = PPERR_PORT_IN_USE;
  39.         return;
  40.     }
  41.     } else {
  42.     unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
  43.     }
  44.     iob->io_Unit = unit;
  45.     ++unit->RefCnt;
  46. }
  47.  
  48.  
  49. void
  50. DGramClose(iob)
  51. Iob *iob;
  52. {
  53.     Unit *unit = iob->io_Unit;
  54.  
  55.     if (--unit->RefCnt == 0) {
  56.     FreeUnit(unit);
  57.     }
  58.     iob->io_Unit = NULL;
  59. }
  60.  
  61. /*
  62.  *  UnitDGramData() is called whenever a low level network operation
  63.  *            completes for the given unit.  cmd is:
  64.  *
  65.  *            'r'     received data packet
  66.  *            'w'     wrote data packet
  67.  *            'W'     timeout writing data packet
  68.  *
  69.  *            The routine is called with the unix locked.
  70.  *
  71.  *  WARNING:    This call may not requeue synchronous packets, a lockout
  72.  *        will result.
  73.  */
  74.  
  75. void
  76. DGramData(cmd, packet, actual)
  77. Packet *packet;
  78. long actual;    /*  'w', 'W'    */
  79. {
  80.     Unit *unit = packet->io_Unit;
  81.     Iob *iob = packet->iob;        /*    NULL for 'r'    */
  82.     long n;
  83.  
  84.     switch(cmd) {
  85.     case 'r':
  86.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  87.         iob->io_Flags &= ~IOF_QUEUED;
  88.  
  89.         n = 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.         actual -= n;
  97.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  98.  
  99.         if (iob->io_Length2 && actual > 0) {    /*  a second data buffer    */
  100.         if (actual > iob->io_Length2)
  101.             actual = iob->io_Length2;
  102.         movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
  103.         n += actual;
  104.         }
  105.         iob->io_Actual = n;
  106.  
  107.         if ((iob->io_Flags & IOF_QUICK) == 0)
  108.         ReplyMsg(&iob->io_Message);
  109.     }
  110.  
  111.     /*
  112.      *  Note that if no read requests are pending the datagram is
  113.      *  thrown away.
  114.      */
  115.  
  116.     FreeParPacket(packet);
  117.     break;
  118.     case 'W':
  119.     Remove(iob);
  120.     iob->io_Flags &= ~IOF_QUEUED;
  121.     iob->io_Error = 1;
  122.     iob->io_Actual = actual;
  123.     if ((iob->io_Flags & IOF_QUICK) == 0)
  124.         ReplyMsg(&iob->io_Message);
  125.     FreeParPacket(packet);
  126.     break;
  127.     case 'w':
  128.     Remove(iob);
  129.     iob->io_Flags &= ~IOF_QUEUED;
  130.     iob->io_Actual = actual;
  131.     if ((iob->io_Flags & IOF_QUICK) == 0)
  132.         ReplyMsg(&iob->io_Message);
  133.     FreeParPacket(packet);
  134.     break;
  135.     }
  136. }
  137.  
  138. void
  139. DGramBeginIO(iob)
  140. Iob *iob;
  141. {
  142.     Unit *unit = iob->io_Unit;
  143.     Packet *packet;
  144.  
  145.     iob->io_Error = 0;
  146.     iob->io_Actual = 0;
  147.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  148.  
  149.     switch(iob->io_Command) {
  150.     case CMD_READ:
  151.     LockAddr(unit->UnitLock);
  152.     iob->io_Flags &= ~IOF_QUICK;
  153.     iob->io_Flags |= IOF_QUEUED;
  154.     AddTail(&unit->PendIOR, iob);
  155.     UnlockAddr(unit->UnitLock);
  156.     return;
  157.     case CMD_WRITE:
  158.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
  159.     LockAddr(unit->UnitLock);
  160.     AddTail(&unit->PendIOW, iob);
  161.     UnlockAddr(unit->UnitLock);
  162.  
  163.     QueuePacketForWrite(packet);
  164.     return;
  165.     default:
  166.     CtlBeginIO(iob);
  167.     return;
  168.     }
  169. }
  170.  
  171. /*
  172.  *  Abort a read or write request.  Currently only read requests may be
  173.  *  aborted.
  174.  */
  175.  
  176. void
  177. DGramAbortIO(iob)
  178. Iob *iob;
  179. {
  180.     if (iob->io_Command == CMD_READ) {
  181.     LockAddr(iob->io_Unit->UnitLock);
  182.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  183.         Remove(iob);
  184.         UnlockAddr(iob->io_Unit->UnitLock);
  185.         iob->io_Flags &= ~IOF_QUEUED;
  186.         iob->io_Error = -1;     /*    ??? */
  187.         ReplyMsg(&iob->io_Message);
  188.     } else {
  189.         UnlockAddr(iob->io_Unit->UnitLock);
  190.     }
  191.     }
  192. }
  193.  
  194.