home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / comm / amitcp-3.0ß2.lha / AmiTCP / src / devs / rhslip / device_funcs.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  52KB  |  2,039 lines

  1. /* $Id: device_funcs.c,v 38.9 1994/01/25 09:04:06 ppessi Exp $
  2. ** $Source: /m/lerppu/u3/projects/Dec93/ohtatcp/amitcp/src/devs/rhslip/RCS/device_funcs.c,v $
  3. ** $State: Exp $
  4. ** $Revision: 38.9 $
  5. ** $Date: 1994/01/25 09:04:06 $
  6. ** $Author: ppessi $
  7. **
  8. ** Amiga SANA-II Example SLIP device driver.
  9. **
  10. ** (C) Copyright 1992 Commodore-Amiga, Inc.
  11. **
  12. */
  13.  
  14. #ifndef USEPRIORITY /* add write requests in priority order */
  15. # define USEPRIORITY    1
  16. #endif
  17. #ifndef DEMANDREAD
  18. # define DEMANDREAD    1
  19. #endif
  20.  
  21. #include "slip_device.h"
  22. #define DEBUG 0
  23. #if DEBUG
  24. #include "syslog.h"
  25. #else
  26. #define debug(x)
  27. #endif
  28.  
  29. #include <dos/dostags.h>
  30. #include <dos/rdargs.h>
  31. #include <intuition/intuition.h>
  32.  
  33. #include <clib/exec_protos.h>
  34. #include <clib/dos_protos.h>
  35. #include <clib/utility_protos.h>
  36. #include <clib/timer_protos.h>
  37. #include <clib/alib_stdio_protos.h>
  38. #include <clib/intuition_protos.h>
  39.  
  40. #include <pragmas/exec_pragmas.h>
  41. #include <pragmas/dos_pragmas.h>
  42. #include <pragmas/utility_pragmas.h>
  43. #include <pragmas/timer_pragmas.h>
  44. #include <pragmas/intuition_pragmas.h>
  45.  
  46. #include <string.h>
  47. #include "device_protos.h"
  48.  
  49. /* Correct prototype for the CheckIO.
  50.  * (The one in clib/exec_protos.h has wrong return value type: BOOL (16 bits) 
  51.  * instead of a pointer (32 bits)!)
  52.  */
  53. struct IORequest * CheckIO(struct IORequest *req);
  54.  
  55. /*
  56. ** External variables and functions
  57. **
  58. */
  59.  
  60. extern struct SLIPDevice *ExtDeviceBase;
  61. extern ULONG IPToNum(STRPTR ipstr);
  62. extern VOID kprintf(STRPTR fmt, ...);
  63.  
  64. const char SLIPName[] = SLIPDEVNAME;
  65.  
  66. /*
  67. ** Device Open vector
  68. **
  69. ** a1 - SANA2 IO Request
  70. ** a6 - Pointer to our device base
  71. ** d0 - Unit number
  72. ** d1 - Flags
  73. **
  74. */
  75.  
  76. ULONG ASM DevOpen(REG(a1) struct IOSana2Req *ios2,
  77.           REG(a6) struct SLIPDevice *SLIPDevice,
  78.           REG(d0) ULONG s2unit,
  79.           REG(d1) ULONG s2flags)
  80. {
  81.     struct SLIPDevUnit *sdu;
  82.     struct TagItem *bufftag;
  83.     struct Library *UtilityBase;
  84.     struct BufferManagement *bm;
  85.     ULONG returncode;
  86.     BOOL status = FALSE;
  87.  
  88.     /* Make sure our open remains single-threaded. */
  89.     ObtainSemaphore(&SLIPDevice->sd_Lock);      /* Enforce single threading since we may need to
  90.                            Wait() when starting up the Unit process */
  91.  
  92. #if DEBUG
  93.     initsyslog();
  94. #endif
  95.     SLIPDevice->sd_Device.lib_OpenCnt++;    /* So we won't expunge ourselves... */
  96.  
  97.     if(s2unit < SD_MAXUNITS)    /* Legal Unit? */
  98.     {
  99.     if(sdu = InitSLIPUnit(s2unit))  /* Initialize the Unit */
  100.     {
  101.         if(UtilityBase = OpenLibrary("utility.library",37L)) /* For Tag functions */
  102.         {
  103.         /* Allocate a structure to store the pointers to the callback routines. */
  104.  
  105.         if(bm = AllocMem(sizeof(struct BufferManagement),MEMF_CLEAR|MEMF_PUBLIC))
  106.         {
  107.             /* Note: I don't complain if I can't find pointers to the callback routines.
  108.                  This is because there are some programs that may need to open me, but
  109.                  will never use any device commands that require the callbacks. */
  110.  
  111.             if(bufftag = FindTagItem(S2_CopyToBuff, (struct TagItem *)ios2->ios2_BufferManagement))
  112.             {
  113.             bm->bm_CopyToBuffer = (SANA2_CTB) bufftag->ti_Data;
  114.             }
  115.  
  116.             if(bufftag = FindTagItem(S2_CopyFromBuff, (struct TagItem *)ios2->ios2_BufferManagement))
  117.             {
  118.             bm->bm_CopyFromBuffer = (SANA2_CFB) bufftag->ti_Data;
  119.             }
  120.  
  121.             AddTail((struct List *)&sdu->sdu_BuffMgmt,(struct Node *)bm);
  122.  
  123.             /* Everything went okay. */
  124.             status = TRUE;
  125.             returncode = 0;
  126.             SLIPDevice->sd_Device.lib_OpenCnt++;
  127.             SLIPDevice->sd_Device.lib_Flags &=~LIBF_DELEXP;
  128.             sdu->sdu_Unit.unit_OpenCnt++;
  129.  
  130.             /* Fix up the initial io request */
  131.             ios2->ios2_BufferManagement = (VOID *)bm;
  132.             ios2->ios2_Req.io_Error = 0;
  133.             ios2->ios2_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
  134.             ios2->ios2_Req.io_Unit = sdu;
  135.             ios2->ios2_Req.io_Device = SLIPDevice;
  136.         }
  137.         CloseLibrary(UtilityBase);
  138.         }
  139.     }
  140.     }
  141.     /* See if something went wrong. */
  142.     if(!status)
  143.     {
  144.     ios2->ios2_Req.io_Error = IOERR_OPENFAIL;
  145.     ios2->ios2_Req.io_Unit = (struct Unit *) -1;
  146.     ios2->ios2_Req.io_Device = (struct Device *) -1;
  147.     returncode = IOERR_OPENFAIL;
  148.     }
  149.     SLIPDevice->sd_Device.lib_OpenCnt--;
  150.     ReleaseSemaphore(&SLIPDevice->sd_Lock);
  151.  
  152.     return(returncode);
  153. }
  154.  
  155. /*
  156. ** Device Close vector.
  157. **
  158. ** a1 - IOReq
  159. ** a6 - Device Pointer
  160. **
  161. */
  162.  
  163. BPTR ASM DevClose(REG(a1) struct IOSana2Req *ios2,
  164.           REG(a6) struct SLIPDevice *SLIPDevice)
  165. {
  166.     struct SLIPDevUnit *sdu;
  167.     BPTR seglist = 0L;
  168.  
  169.     ObtainSemaphore(&SLIPDevice->sd_Lock);
  170.  
  171.     sdu = (struct SLIPDevUnit *)ios2->ios2_Req.io_Unit;
  172.  
  173.     /* Trash the io_Device and io_Unit fields so that any attempt to use this
  174.        request will die immediatly. */
  175.  
  176.     ios2->ios2_Req.io_Device = (struct Device *) -1;
  177.     ios2->ios2_Req.io_Unit = (struct Unit *) -1;
  178.  
  179.     /* I always shut the unit process down if the open count drops to zero.
  180.        That way, if I need to expunge, I never have to Wait(). */
  181.  
  182.     sdu->sdu_Unit.unit_OpenCnt--;
  183.     if(!sdu->sdu_Unit.unit_OpenCnt)
  184.     {
  185.     ExpungeUnit(sdu);
  186.     }
  187.  
  188.     SLIPDevice->sd_Device.lib_OpenCnt--;
  189.  
  190.     ReleaseSemaphore(&SLIPDevice->sd_Lock);
  191.  
  192.     /* Check to see if we've been asked to expunge. */
  193.     if(SLIPDevice->sd_Device.lib_Flags & LIBF_DELEXP)
  194.     seglist = DevExpunge(SLIPDevice);
  195.  
  196.     return(seglist);
  197. }
  198.  
  199.  
  200. /*
  201. ** Device Expunge vector
  202. **
  203. ** a6 - Device base
  204. **
  205. ** Note: You may NEVER EVER Wait() in expunge. Period.
  206. **     Don't even *think* about it.
  207. */
  208.  
  209. BPTR ASM DevExpunge(REG(a6) struct SLIPDevice *SLIPDevice)
  210. {
  211.     BPTR seglist;
  212.     ULONG devbase;
  213.     LONG devbasesize;
  214.  
  215.     if(SLIPDevice->sd_Device.lib_OpenCnt)
  216.     {
  217.     /* Sorry, we're busy.  We'll expunge later on
  218.        if we can. */
  219.     SLIPDevice->sd_Device.lib_Flags |= LIBF_DELEXP;
  220.     seglist = (BPTR)0L;
  221.     }
  222.     else
  223.     {
  224.     /* Free up our library base and function table after
  225.        removing ourselves from the library list. */
  226.     Remove((struct Node *)SLIPDevice);
  227.     seglist = SLIPDevice->sd_SegList;
  228.  
  229.     devbase = (ULONG) SLIPDevice;
  230.  
  231.     devbasesize = (ULONG)SLIPDevice->sd_Device.lib_NegSize;
  232.     devbase = devbase - devbasesize;
  233.  
  234.     devbasesize += (ULONG)SLIPDevice->sd_Device.lib_PosSize;
  235.  
  236. #if DEBUG
  237.     uninitsyslog();
  238. #endif
  239.     FreeMem((APTR)devbase,devbasesize);
  240.     ExtDeviceBase = NULL;
  241.     }
  242.     return(seglist);
  243. }
  244.  
  245. /*
  246. ** InitSLIPUnit
  247. **
  248. ** Initialize (if needed) a new SLIP device Unit and process.
  249. **
  250. */
  251.  
  252. struct SLIPDevUnit *InitSLIPUnit(ULONG s2unit)
  253. {
  254.     struct SLIPDevice *SLIPDevice = SLIPBase;
  255.     struct SLIPDevUnit *sdu;
  256.     struct TagItem NPTags[]={NP_Entry, 0, NP_Name, 0, NP_Priority, SLIP_PRI, TAG_DONE, 0};
  257.     struct MsgPort *replyport;
  258.  
  259.     /* Check to see if the Unit is already up and running.  If
  260.        it is, just drop through.  If not, try to start it up. */
  261.  
  262.     if(!SLIPDevice->sd_Units[s2unit])
  263.     {
  264.     /* Open up dos.library */
  265.     if(SLIPDevice->sd_DOSBase = OpenLibrary("dos.library",37L))
  266.     {
  267.         /* Allocate a new Unit structure */
  268.         if(sdu = AllocMem(sizeof(struct SLIPDevUnit), MEMF_CLEAR|MEMF_PUBLIC))
  269.         {
  270.         /* Do some initialization on the Unit structure */
  271.  
  272.         NewList(&sdu->sdu_Unit.unit_MsgPort.mp_MsgList);
  273.         sdu->sdu_Unit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
  274.         sdu->sdu_Unit.unit_MsgPort.mp_Flags = PA_IGNORE;
  275.         sdu->sdu_Unit.unit_MsgPort.mp_Node.ln_Name = (char *)SLIPName;
  276.  
  277.         sdu->sdu_UnitNum = s2unit;
  278.         sdu->sdu_Device = (struct Device *) SLIPDevice;
  279.  
  280.         /* Try to read in our configuration file */
  281.         if(ReadConfig(sdu))
  282.         {
  283.             /* Start up the unit process */
  284.             if(replyport = CreateMsgPort())
  285.             {
  286.             SLIPDevice->sd_Startup.Msg.mn_ReplyPort = replyport;
  287.             SLIPDevice->sd_Startup.Device = (struct Device *) SLIPDevice;
  288.             SLIPDevice->sd_Startup.Unit = (struct Unit *)sdu;
  289.  
  290.             NPTags[0].ti_Data = (ULONG) &DevProcCEntry;
  291.             NPTags[1].ti_Data = (ULONG) SLIPName;      /* Process name */
  292.             /* Rhialto: use opener's priority */
  293.             NPTags[2].ti_Data = (ULONG) FindTask(NULL)->tc_Node.ln_Pri;
  294.  
  295.             /*ExtDeviceBase = (struct Library *)SLIPDevice;*/
  296.  
  297.             if(sdu->sdu_Proc = CreateNewProc(NPTags))
  298.             {
  299.                 PutMsg(&sdu->sdu_Proc->pr_MsgPort,(struct Message *)&SLIPDevice->sd_Startup);
  300.                 WaitPort(replyport);
  301.                 GetMsg(replyport);
  302.             }
  303.             DeleteMsgPort(replyport);
  304.             }
  305.         }
  306.  
  307.         if(!sdu->sdu_Proc)
  308.         {
  309.             /* The Unit process couldn't start for some reason, so free the Unit struc