Updated Zorro-LAN-IDE Driver to 2.15
- Multicast fixes - new Microchip OUIs added to verification table
This commit is contained in:
+140
-36
@@ -120,6 +120,8 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
|
||||
db->db_SegList = seglist;
|
||||
db->db_Flags = 0;
|
||||
|
||||
InitSemaphore( &db->db_Sem ); /* server start/stop/online/offline */
|
||||
|
||||
dbNewList( &db->db_BufferManagement );
|
||||
|
||||
for(i=0 ; i < MAX_UNITS ; i++ )
|
||||
@@ -137,9 +139,12 @@ ASM SAVEDS struct Device *DevInit( ASMR(d0) DEVBASEP ASMREG(d0)
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
if( (DOSBase = OpenLibrary("dos.library", 36)) )
|
||||
if( (DOSBase = OpenLibrary( (STRPTR)"dos.library", 36)) )
|
||||
{
|
||||
if( (UtilityBase = OpenLibrary("utility.library", 37)) )
|
||||
#ifdef USEMMU
|
||||
MMUBase = OpenLibrary( (STRPTR)"mmu.library",46 );
|
||||
#endif
|
||||
if( (UtilityBase = OpenLibrary( (STRPTR)"utility.library", 37)) )
|
||||
{
|
||||
/* Search HW */
|
||||
ok = hw_Find_Boards( db );
|
||||
@@ -182,10 +187,16 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
|
||||
D(("DevOpen for %ld\n",unit));
|
||||
|
||||
db->db_Lib.lib_OpenCnt++; /* avoid Expunge, see below for separate "unit" open count */
|
||||
/* avoid Expunge, see below for separate "unit" open count */
|
||||
//ObtainSemaphore( &db->db_Sem ); /* probably overkill */
|
||||
db->db_Lib.lib_OpenCnt++;
|
||||
//ReleaseSemaphore( &db->db_Sem );
|
||||
|
||||
db->db_ID++; /* opener ID (always >0) */
|
||||
|
||||
if( unit < db->db_NBoards )
|
||||
if( (unit < db->db_NBoards) &&
|
||||
(ioreq->ios2_Req.io_Message.mn_Length >= sizeof( struct IOSana2Req ) )
|
||||
)
|
||||
{
|
||||
ObtainSemaphore( &db->db_Units[unit].du_Sem ); /* lock current board */
|
||||
|
||||
@@ -222,9 +233,6 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
if( flags & SANA2OPF_PROM ) /* implies _MINE by spec */
|
||||
db->db_Units[unit].du_Flags |= DUF_PROMISC;
|
||||
|
||||
hw_GetMacAddress( db, unit, &db->db_Units[unit].du_HWAddr[0] );
|
||||
hw_GetMacAddress( db, unit, &db->db_Units[unit].du_CFGAddr[0] );
|
||||
|
||||
ok = 0;
|
||||
dbm = (struct db_BufferManagement *)AllocMem( sizeof(struct db_BufferManagement),MEMF_ANY|MEMF_CLEAR);
|
||||
if( dbm )
|
||||
@@ -246,7 +254,7 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
/* v1.95: disabled CopyToBuffer32 due to problems with MiamiDX */
|
||||
/* v1.99: try identifying Miami */
|
||||
/* MiamiDX requires byte count to be a multiple of 4 */
|
||||
if( FindPort("MIAMI.1") ) /* Miami active ? */
|
||||
if( FindPort( (STRPTR)"MIAMI.1") ) /* Miami active ? */
|
||||
{
|
||||
dbm->dbm_CopyToBuffer32 = (0);
|
||||
dbm->dbm_CopyFromBuffer32 = (0);
|
||||
@@ -269,11 +277,19 @@ ASM SAVEDS LONG DevOpen( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
dbm->dbm_ID = db->db_ID;
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
/* the server is started with the Semaphore locked, to avoid
|
||||
the race condition of getting instantiated twice
|
||||
*/
|
||||
if( ok )
|
||||
{
|
||||
/* start server if necessary */
|
||||
ok = dbStartServer( db, unit );
|
||||
}
|
||||
|
||||
hw_GetMacAddress( db, unit, &db->db_Units[unit].du_HWAddr[0] );
|
||||
hw_GetMacAddress( db, unit, &db->db_Units[unit].du_CFGAddr[0] );
|
||||
|
||||
if( ok )
|
||||
{
|
||||
ret = 0;
|
||||
@@ -352,8 +368,12 @@ ASM SAVEDS BPTR DevClose( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
(db->db_Units[unit].du_Flags & DUF_ONLINE )
|
||||
)
|
||||
{
|
||||
#if 1
|
||||
dbSignalServer( db , SIGBREAKF_CTRL_D, 1 ); /* signal server to shut down unit (and lock the semaphore while doing so) */
|
||||
#else
|
||||
Signal( (struct Task*)db->db_ServerProc, SIGBREAKF_CTRL_D);
|
||||
Delay(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
ObtainSemaphore( &db->db_Units[unit].du_Sem ); /* lock current board */
|
||||
@@ -365,6 +385,30 @@ ASM SAVEDS BPTR DevClose( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
|
||||
ReleaseSemaphore( &db->db_Units[unit].du_Sem );
|
||||
|
||||
#if 1
|
||||
/* now check if the device is no longer in use in any unit (=global OpenCnt)
|
||||
and shut down server if that is the case
|
||||
*/
|
||||
ObtainSemaphore( &db->db_Sem );
|
||||
if( db->db_Lib.lib_OpenCnt == 0 )
|
||||
{
|
||||
ULONG i;
|
||||
struct SanaReadType *type;
|
||||
|
||||
dbStopServer(db,0);
|
||||
|
||||
for( i=0 ; i < db->db_NBoards ; i++ )
|
||||
{
|
||||
while( (type = GetHead( &db->db_Units[i].du_ReadTypes ) ))
|
||||
{
|
||||
dbDeleteType( db, i, type->srt_Type );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ReleaseSemaphore( &db->db_Sem );
|
||||
#endif
|
||||
|
||||
if (db->db_Lib.lib_Flags & LIBF_DELEXP)
|
||||
ret = DevExpunge(db);
|
||||
|
||||
@@ -375,10 +419,9 @@ ASM SAVEDS BPTR DevClose( ASMR(a1) struct IOSana2Req *ioreq ASMREG(a1),
|
||||
ASM SAVEDS BPTR DevExpunge( ASMR(a6) DEVBASEP ASMREG(a6) )
|
||||
{
|
||||
BPTR seglist = db->db_SegList;
|
||||
ULONG i;
|
||||
struct SanaReadType *type;
|
||||
|
||||
if( db->db_Lib.lib_OpenCnt )
|
||||
/* don't go if the server is still up (for whatever reason) */
|
||||
if( (db->db_Lib.lib_OpenCnt) || (db->db_ServerProc) )
|
||||
{
|
||||
db->db_Lib.lib_Flags |= LIBF_DELEXP;
|
||||
return (0);
|
||||
@@ -388,6 +431,8 @@ ASM SAVEDS BPTR DevExpunge( ASMR(a6) DEVBASEP ASMREG(a6)
|
||||
Remove((struct Node*)db); /* remove device node from system */
|
||||
Permit();
|
||||
|
||||
#if 0
|
||||
/* moved to CloseDevice() */
|
||||
dbStopServer(db,0);
|
||||
|
||||
for( i=0 ; i < db->db_NBoards ; i++ )
|
||||
@@ -398,6 +443,7 @@ ASM SAVEDS BPTR DevExpunge( ASMR(a6) DEVBASEP ASMREG(a6)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* last steps: libraries */
|
||||
CloseLibrary(DOSBase);
|
||||
@@ -816,9 +862,9 @@ LONG Need_HighPri( DEVBASEP )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( FindPort("Services Manager") )
|
||||
if( FindPort( (STRPTR)"Services Manager") )
|
||||
return 1;
|
||||
if( FindPort("Accounts Manager") )
|
||||
if( FindPort( (STRPTR)"Accounts Manager") )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -833,34 +879,43 @@ static LONG dbStartServer( DEVBASEP, LONG unit )
|
||||
LONG ret = 0,i,pri;
|
||||
struct TagItem sv_tags[5];
|
||||
|
||||
/* server running ? */
|
||||
if( db->db_ServerProc )
|
||||
ObtainSemaphore( &db->db_Sem );
|
||||
|
||||
do
|
||||
{
|
||||
/* server running ? */
|
||||
if( db->db_ServerProc )
|
||||
{
|
||||
if( Need_HighPri( db ) )
|
||||
SetTaskPri((struct Task*)db->db_ServerProc,HIGHPRI);
|
||||
return 1;
|
||||
}
|
||||
ret = 1;
|
||||
break; /* ReleaseSemaphore */
|
||||
}
|
||||
|
||||
if(!(port = CreateMsgPort() ))
|
||||
return 0;
|
||||
|
||||
pri = 0;
|
||||
if( Need_HighPri( db ) )
|
||||
if(!(port = CreateMsgPort() ))
|
||||
break; /* ReleaseSemaphore */
|
||||
|
||||
pri = 0;
|
||||
if( Need_HighPri( db ) )
|
||||
pri = HIGHPRI;
|
||||
else
|
||||
if( FindPort("AMITCP") ) /* AmiTCP active ? */
|
||||
else
|
||||
{
|
||||
if( FindPort( (STRPTR)"AMITCP") ) /* AmiTCP active ? */
|
||||
pri = 6;
|
||||
if( FindPort( (STRPTR)"BAXTCP") ) /* BaxTCP active ? */
|
||||
pri = 6;
|
||||
}
|
||||
|
||||
sv_tags[i=0].ti_Tag = NP_Entry;
|
||||
sv_tags[i++].ti_Data = (ULONG)ServerTask;
|
||||
sv_tags[i ].ti_Tag = NP_Name;
|
||||
sv_tags[i++].ti_Data = (ULONG)db->db_Lib.lib_Node.ln_Name;
|
||||
sv_tags[i ].ti_Tag = NP_Priority;
|
||||
sv_tags[i++].ti_Data = (ULONG)pri;
|
||||
sv_tags[i ].ti_Tag = TAG_DONE;
|
||||
sv_tags[i=0].ti_Tag = NP_Entry;
|
||||
sv_tags[i++].ti_Data = (ULONG)ServerTask;
|
||||
sv_tags[i ].ti_Tag = NP_Name;
|
||||
sv_tags[i++].ti_Data = (ULONG)db->db_Lib.lib_Node.ln_Name;
|
||||
sv_tags[i ].ti_Tag = NP_Priority;
|
||||
sv_tags[i++].ti_Data = (ULONG)pri;
|
||||
sv_tags[i ].ti_Tag = TAG_DONE;
|
||||
|
||||
if( (db->db_ServerProc = CreateNewProc(sv_tags)))
|
||||
{
|
||||
if( (db->db_ServerProc = CreateNewProc(sv_tags)))
|
||||
{
|
||||
/* server is running, wait for response */
|
||||
volatile struct ServerMsg msg;
|
||||
|
||||
@@ -874,11 +929,15 @@ static LONG dbStartServer( DEVBASEP, LONG unit )
|
||||
WaitPort( port );
|
||||
ret = msg.sm_result; /* should be 1 */
|
||||
D(("Server answered with %ld\n",ret));
|
||||
}
|
||||
if( !ret )
|
||||
}
|
||||
if( !ret )
|
||||
db->db_ServerProc = (0);
|
||||
|
||||
DeleteMsgPort( port );
|
||||
DeleteMsgPort( port );
|
||||
|
||||
} while(0);
|
||||
|
||||
ReleaseSemaphore( &db->db_Sem );
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -886,12 +945,16 @@ static LONG dbStartServer( DEVBASEP, LONG unit )
|
||||
|
||||
/* stop Server function */
|
||||
/* note: server is global right now */
|
||||
/* note: this code assumes to run with locked Semaphore (db_Sem) */
|
||||
static LONG dbStopServer( DEVBASEP, LONG unit )
|
||||
{
|
||||
ULONG i=1;
|
||||
volatile struct Task *P;
|
||||
|
||||
/* server deletes itself from devbase */
|
||||
dbSignalServer( db, SIGBREAKF_CTRL_C, 0 );
|
||||
|
||||
/* failsafe: when the server does not come down, hammer it with CTRL_C */
|
||||
while( (P=(volatile struct Task*)db->db_ServerProc) )
|
||||
{
|
||||
Signal( (struct Task*)P, SIGBREAKF_CTRL_C);
|
||||
@@ -902,6 +965,47 @@ static LONG dbStopServer( DEVBASEP, LONG unit )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Signal server and wait for response */
|
||||
/* notes:
|
||||
- server is global right now
|
||||
- a Semaphore is used to ensure one signal per call only
|
||||
- a signal is allocated, if possible
|
||||
*/
|
||||
static LONG dbSignalServer( DEVBASEP, ULONG sig, ULONG flags )
|
||||
{
|
||||
ULONG mysig = SIGBREAKF_CTRL_D; /* failsafe */
|
||||
LONG sigbit=-1;
|
||||
|
||||
sigbit = AllocSignal(-1);
|
||||
if( sigbit >= 0 )
|
||||
mysig = 1<<sigbit;
|
||||
|
||||
if( flags & 1 )
|
||||
ObtainSemaphore( &db->db_Sem ); /* lock access to server state */
|
||||
if( db->db_ServerProc )
|
||||
{
|
||||
/* important: we might land here from various tasks/procs: always update
|
||||
task pointer, always lock semaphore
|
||||
*/
|
||||
db->db_ServerSigMask = mysig;
|
||||
db->db_Task = FindTask(NULL);
|
||||
|
||||
Signal( (struct Task*)db->db_ServerProc, sig );
|
||||
|
||||
/* TODO: check "sig" for valid server signals,
|
||||
currently: SIGBREAKF_CTRL_D,SIGBREAKF_CTRL_F,SIGBREAKF_CTRL_C
|
||||
and otherwise don't wait */
|
||||
Wait( mysig );
|
||||
db->db_Task = NULL; /* no waiting is pending */
|
||||
}
|
||||
if( flags & 1 )
|
||||
ReleaseSemaphore( &db->db_Sem ); /* unlock access to server state */
|
||||
|
||||
if( sigbit >= 0 )
|
||||
FreeSignal(sigbit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
delete all buffers (type references) associated with device opener
|
||||
|
||||
Reference in New Issue
Block a user