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 >
Wrap
C/C++ Source or Header
|
1994-01-28
|
52KB
|
2,039 lines
/* $Id: device_funcs.c,v 38.9 1994/01/25 09:04:06 ppessi Exp $
** $Source: /m/lerppu/u3/projects/Dec93/ohtatcp/amitcp/src/devs/rhslip/RCS/device_funcs.c,v $
** $State: Exp $
** $Revision: 38.9 $
** $Date: 1994/01/25 09:04:06 $
** $Author: ppessi $
**
** Amiga SANA-II Example SLIP device driver.
**
** (C) Copyright 1992 Commodore-Amiga, Inc.
**
*/
#ifndef USEPRIORITY /* add write requests in priority order */
# define USEPRIORITY 1
#endif
#ifndef DEMANDREAD
# define DEMANDREAD 1
#endif
#include "slip_device.h"
#define DEBUG 0
#if DEBUG
#include "syslog.h"
#else
#define debug(x)
#endif
#include <dos/dostags.h>
#include <dos/rdargs.h>
#include <intuition/intuition.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/utility_protos.h>
#include <clib/timer_protos.h>
#include <clib/alib_stdio_protos.h>
#include <clib/intuition_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/timer_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <string.h>
#include "device_protos.h"
/* Correct prototype for the CheckIO.
* (The one in clib/exec_protos.h has wrong return value type: BOOL (16 bits)
* instead of a pointer (32 bits)!)
*/
struct IORequest * CheckIO(struct IORequest *req);
/*
** External variables and functions
**
*/
extern struct SLIPDevice *ExtDeviceBase;
extern ULONG IPToNum(STRPTR ipstr);
extern VOID kprintf(STRPTR fmt, ...);
const char SLIPName[] = SLIPDEVNAME;
/*
** Device Open vector
**
** a1 - SANA2 IO Request
** a6 - Pointer to our device base
** d0 - Unit number
** d1 - Flags
**
*/
ULONG ASM DevOpen(REG(a1) struct IOSana2Req *ios2,
REG(a6) struct SLIPDevice *SLIPDevice,
REG(d0) ULONG s2unit,
REG(d1) ULONG s2flags)
{
struct SLIPDevUnit *sdu;
struct TagItem *bufftag;
struct Library *UtilityBase;
struct BufferManagement *bm;
ULONG returncode;
BOOL status = FALSE;
/* Make sure our open remains single-threaded. */
ObtainSemaphore(&SLIPDevice->sd_Lock); /* Enforce single threading since we may need to
Wait() when starting up the Unit process */
#if DEBUG
initsyslog();
#endif
SLIPDevice->sd_Device.lib_OpenCnt++; /* So we won't expunge ourselves... */
if(s2unit < SD_MAXUNITS) /* Legal Unit? */
{
if(sdu = InitSLIPUnit(s2unit)) /* Initialize the Unit */
{
if(UtilityBase = OpenLibrary("utility.library",37L)) /* For Tag functions */
{
/* Allocate a structure to store the pointers to the callback routines. */
if(bm = AllocMem(sizeof(struct BufferManagement),MEMF_CLEAR|MEMF_PUBLIC))
{
/* Note: I don't complain if I can't find pointers to the callback routines.
This is because there are some programs that may need to open me, but
will never use any device commands that require the callbacks. */
if(bufftag = FindTagItem(S2_CopyToBuff, (struct TagItem *)ios2->ios2_BufferManagement))
{
bm->bm_CopyToBuffer = (SANA2_CTB) bufftag->ti_Data;
}
if(bufftag = FindTagItem(S2_CopyFromBuff, (struct TagItem *)ios2->ios2_BufferManagement))
{
bm->bm_CopyFromBuffer = (SANA2_CFB) bufftag->ti_Data;
}
AddTail((struct List *)&sdu->sdu_BuffMgmt,(struct Node *)bm);
/* Everything went okay. */
status = TRUE;
returncode = 0;
SLIPDevice->sd_Device.lib_OpenCnt++;
SLIPDevice->sd_Device.lib_Flags &=~LIBF_DELEXP;
sdu->sdu_Unit.unit_OpenCnt++;
/* Fix up the initial io request */
ios2->ios2_BufferManagement = (VOID *)bm;
ios2->ios2_Req.io_Error = 0;
ios2->ios2_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
ios2->ios2_Req.io_Unit = sdu;
ios2->ios2_Req.io_Device = SLIPDevice;
}
CloseLibrary(UtilityBase);
}
}
}
/* See if something went wrong. */
if(!status)
{
ios2->ios2_Req.io_Error = IOERR_OPENFAIL;
ios2->ios2_Req.io_Unit = (struct Unit *) -1;
ios2->ios2_Req.io_Device = (struct Device *) -1;
returncode = IOERR_OPENFAIL;
}
SLIPDevice->sd_Device.lib_OpenCnt--;
ReleaseSemaphore(&SLIPDevice->sd_Lock);
return(returncode);
}
/*
** Device Close vector.
**
** a1 - IOReq
** a6 - Device Pointer
**
*/
BPTR ASM DevClose(REG(a1) struct IOSana2Req *ios2,
REG(a6) struct SLIPDevice *SLIPDevice)
{
struct SLIPDevUnit *sdu;
BPTR seglist = 0L;
ObtainSemaphore(&SLIPDevice->sd_Lock);
sdu = (struct SLIPDevUnit *)ios2->ios2_Req.io_Unit;
/* Trash the io_Device and io_Unit fields so that any attempt to use this
request will die immediatly. */
ios2->ios2_Req.io_Device = (struct Device *) -1;
ios2->ios2_Req.io_Unit = (struct Unit *) -1;
/* I always shut the unit process down if the open count drops to zero.
That way, if I need to expunge, I never have to Wait(). */
sdu->sdu_Unit.unit_OpenCnt--;
if(!sdu->sdu_Unit.unit_OpenCnt)
{
ExpungeUnit(sdu);
}
SLIPDevice->sd_Device.lib_OpenCnt--;
ReleaseSemaphore(&SLIPDevice->sd_Lock);
/* Check to see if we've been asked to expunge. */
if(SLIPDevice->sd_Device.lib_Flags & LIBF_DELEXP)
seglist = DevExpunge(SLIPDevice);
return(seglist);
}
/*
** Device Expunge vector
**
** a6 - Device base
**
** Note: You may NEVER EVER Wait() in expunge. Period.
** Don't even *think* about it.
*/
BPTR ASM DevExpunge(REG(a6) struct SLIPDevice *SLIPDevice)
{
BPTR seglist;
ULONG devbase;
LONG devbasesize;
if(SLIPDevice->sd_Device.lib_OpenCnt)
{
/* Sorry, we're busy. We'll expunge later on
if we can. */
SLIPDevice->sd_Device.lib_Flags |= LIBF_DELEXP;
seglist = (BPTR)0L;
}
else
{
/* Free up our library base and function table after
removing ourselves from the library list. */
Remove((struct Node *)SLIPDevice);
seglist = SLIPDevice->sd_SegList;
devbase = (ULONG) SLIPDevice;
devbasesize = (ULONG)SLIPDevice->sd_Device.lib_NegSize;
devbase = devbase - devbasesize;
devbasesize += (ULONG)SLIPDevice->sd_Device.lib_PosSize;
#if DEBUG
uninitsyslog();
#endif
FreeMem((APTR)devbase,devbasesize);
ExtDeviceBase = NULL;
}
return(seglist);
}
/*
** InitSLIPUnit
**
** Initialize (if needed) a new SLIP device Unit and process.
**
*/
struct SLIPDevUnit *InitSLIPUnit(ULONG s2unit)
{
struct SLIPDevice *SLIPDevice = SLIPBase;
struct SLIPDevUnit *sdu;
struct TagItem NPTags[]={NP_Entry, 0, NP_Name, 0, NP_Priority, SLIP_PRI, TAG_DONE, 0};
struct MsgPort *replyport;
/* Check to see if the Unit is already up and running. If
it is, just drop through. If not, try to start it up. */
if(!SLIPDevice->sd_Units[s2unit])
{
/* Open up dos.library */
if(SLIPDevice->sd_DOSBase = OpenLibrary("dos.library",37L))
{
/* Allocate a new Unit structure */
if(sdu = AllocMem(sizeof(struct SLIPDevUnit), MEMF_CLEAR|MEMF_PUBLIC))
{
/* Do some initialization on the Unit structure */
NewList(&sdu->sdu_Unit.unit_MsgPort.mp_MsgList);
sdu->sdu_Unit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
sdu->sdu_Unit.unit_MsgPort.mp_Flags = PA_IGNORE;
sdu->sdu_Unit.unit_MsgPort.mp_Node.ln_Name = (char *)SLIPName;
sdu->sdu_UnitNum = s2unit;
sdu->sdu_Device = (struct Device *) SLIPDevice;
/* Try to read in our configuration file */
if(ReadConfig(sdu))
{
/* Start up the unit process */
if(replyport = CreateMsgPort())
{
SLIPDevice->sd_Startup.Msg.mn_ReplyPort = replyport;
SLIPDevice->sd_Startup.Device = (struct Device *) SLIPDevice;
SLIPDevice->sd_Startup.Unit = (struct Unit *)sdu;
NPTags[0].ti_Data = (ULONG) &DevProcCEntry;
NPTags[1].ti_Data = (ULONG) SLIPName; /* Process name */
/* Rhialto: use opener's priority */
NPTags[2].ti_Data = (ULONG) FindTask(NULL)->tc_Node.ln_Pri;
/*ExtDeviceBase = (struct Library *)SLIPDevice;*/
if(sdu->sdu_Proc = CreateNewProc(NPTags))
{
PutMsg(&sdu->sdu_Proc->pr_MsgPort,(struct Message *)&SLIPDevice->sd_Startup);
WaitPort(replyport);
GetMsg(replyport);
}
DeleteMsgPort(replyport);
}
}
if(!sdu->sdu_Proc)
{
/* The Unit process couldn't start for some reason, so free the Unit struc