544 lines
21 KiB
HTML
544 lines
21 KiB
HTML
<html>
|
|
<head>
|
|
<title>
|
|
Hook-based callback function extensions for SANA-II (SANA-IIR5)
|
|
</title>
|
|
</head>
|
|
|
|
<body>
|
|
<h1><p align=center>
|
|
Hook-based callback function extensions for SANA-II (SANA-IIR5)
|
|
<br>by <a href="mailto:sana2feedback@amiga.com?subject=Re: SANA-IIR5 proposal">Olaf Barthel</a> and Heinz Wrobel</p></h1></center>
|
|
|
|
<h2>1. Introduction</h2>
|
|
|
|
<p>The last changes proposed for the SANA-II networking driver standard were
|
|
intended to address the demands of dial-up networking. A new issue has come
|
|
up which concerns the application and deployment of PowerPC native
|
|
networking drivers. So far the SANA-II standard only caters well for the
|
|
Motorola 68000 platform, and the only way to support it on the PowerPC
|
|
involves a considerable overhead. This is what the following proposal
|
|
intends to address.</p>
|
|
|
|
<p>Please feel free to comment; you can contact me through the e-mail address
|
|
given in the headline of this document. Note that the issues discussed in
|
|
this document are just a list of proposed changes.</p>
|
|
|
|
<h2>2. The problem: parameter passing to the copying functions</h2>
|
|
|
|
<p>The SANA-II driver interface is intended to transform data between the
|
|
hardware layer and the link layer, to be used by networking software such
|
|
as TCP/IP stacks. This transformation is performed by call-back functions
|
|
which are supplied by the networking software at the time the device driver
|
|
is opened. The device driver then invokes these functions later in order to
|
|
transfer data received and data to be sent.</p>
|
|
|
|
<p>These copying functions are designed for low overhead. They use up to three
|
|
parameters and are documented in the <kbd>copybuff.doc</kbd> file which comes with
|
|
the SANA-II specification. Here is an excerpt which describes the
|
|
<code>CopyFromBuff</code> function, which is associated with the <code>S2_CopyFromBuff</code>
|
|
tag:</p>
|
|
|
|
<pre>
|
|
|
|
any_sana2_protocol/CopyFromBuff any_sana2_protocol/CopyFromBuff
|
|
|
|
NAME
|
|
CopyFromBuff -- Copy n bytes from an abstract data structure.
|
|
|
|
SYNOPSIS
|
|
success = CopyFromBuff(to, from, n)
|
|
d0 a0 a1 d0
|
|
|
|
BOOL CopyToBuff(VOID *, VOID *, ULONG);
|
|
|
|
FUNCTION
|
|
This function copies 'n' bytes of data in the abstract data structure
|
|
pointed to by 'from' into the contigous memory pointed to by 'to'.
|
|
'to' must contain at least 'n' bytes of usable memory or innocent
|
|
memory will be overwritten.
|
|
|
|
INPUTS
|
|
to - pointer to contiguous memory to copy to.
|
|
from - pointer to abstract structure to copy from.
|
|
n - number of bytes to copy.
|
|
|
|
RESULT
|
|
success - TRUE if operation was successful, else FALSE.
|
|
|
|
NOTES
|
|
This function must be callable from interupts. In particular, this
|
|
means that this function may not directly or indirectly call any
|
|
system memory functions (since those functions rely on Forbid() to
|
|
protect themselves) and that you must not compile this function
|
|
with stack checking enabled. See the RKM:Libraries Exec:Interupts
|
|
chapter for more details on what is legal in a routine called from
|
|
an interupt handler.
|
|
|
|
'C' programmers should not compile with stack checking (option '-v'
|
|
in SAS) and should geta4() or __saveds.
|
|
</pre>
|
|
|
|
<p>As one can see, the function parameters are passed in 68000 registers.
|
|
Compare this to the packet filter function, which is associated with the
|
|
<code>S2_PacketFilter</code> tag: it is intended to be invoked as a hook function, as
|
|
part of the <code>Hook</code> interface in <code>utility.library/CallHookPkt</code>.</p>
|
|
|
|
<p>The problem with 68000 register parameters is that on the PowerPC platform,
|
|
this form of parameter passing may require the use of emulation code. This
|
|
is costly and may incur a severe performance penalty. It is an even greater
|
|
problem if PowerPC native networking software is calling PowerPC native
|
|
networking driver software and the other way round. In both cases the
|
|
runtime environment will have to enter emulation mode, return to to PowerPC
|
|
native execution, dip into emulation mode and return to native PowerPC
|
|
execution. It would be much better if the chain of execution would stay in
|
|
PowerPC mode all the time.</p>
|
|
|
|
<p>However, if a hook function is used (such as for the packet filter), the
|
|
operating system may be able to decide whether the function to be invoked
|
|
needs emulating or could be called straight away. The <code>Hook</code> effectively
|
|
works as an abstraction which makes the function invocation platform
|
|
independent.</p>
|
|
|
|
<p>The following proposal therefore intends to wrap the copying functions into
|
|
the standardized <code>Hook</code> interface.</p>
|
|
|
|
|
|
<h2>3. New data structures and commands</h2>
|
|
|
|
<h3>3.1 Data structures</h3>
|
|
|
|
<p>The SANA-IIR4 proposal lists ten copying functions, which can be grouped
|
|
into two categories: data copying and direct memory access. These functions
|
|
are:</p>
|
|
|
|
<ul>
|
|
<li> Data copying:
|
|
<ul>
|
|
<li> <code>S2_CopyToBuff</code>
|
|
<li> <code>S2_CopyFromBuff</code>
|
|
<li> <code>S2_CopyToBuff16</code>
|
|
<li> <code>S2_CopyFromBuff16</code>
|
|
<li> <code>S2_CopyToBuff32</code>
|
|
<li> <code>S2_CopyFromBuff32</code>
|
|
</ul>
|
|
<li> Direct memory access:
|
|
<ul>
|
|
<li> <code>S2_DMACopyToBuff32</code>
|
|
<li> <code>S2_DMACopyFromBuff32</code>
|
|
<li> <code>S2_DMACopyToBuff64</code>
|
|
<li> <code>S2_DMACopyFromBuff64</code>
|
|
</ul>
|
|
</ul>
|
|
|
|
<p>There are three 'flavours' of the data copying functions. These cater for
|
|
certain buffer memory alignment requirements which the underlying hardware
|
|
requires or which can be used to boost transfer efficiency. For the direct
|
|
memory access functions there are two variants which cater for certain
|
|
memory alignment requirements in the same manner as the copying functions.</p>
|
|
|
|
<p>All these functions are using basically the same set of parameters and
|
|
68000 registers. The parameters and result codes are used for different
|
|
purposes, though. In order to translate the parameters for use with the
|
|
<code>Hook</code> interface one needs to define a 'hook message' and a set of parameters
|
|
the hook function is invoked with.</p>
|
|
|
|
<p>I propose the following hook messages to be used :</p>
|
|
|
|
<pre>
|
|
struct SANA2HookMsg
|
|
{
|
|
ULONG shm_Method;
|
|
ULONG shm_MsgSize;
|
|
};
|
|
</pre>
|
|
|
|
<p>In this data structure the <code>shm_Method</code> field would indicate the task to
|
|
be performed. This can a be request to copy data or to store a log message.
|
|
The <code>shm_MsgSize</code> field tells you how large the data structure is (for future
|
|
enhancements which may cause the data structure to grow).</p>
|
|
|
|
<p>For copying operations the message would look like this:</p>
|
|
|
|
<pre>
|
|
struct SANA2CopyHookMsg
|
|
{
|
|
ULONG schm_Method;
|
|
ULONG schm_MsgSize;
|
|
|
|
APTR schm_To;
|
|
APTR schm_From;
|
|
ULONG schm_Size;
|
|
};
|
|
</pre>
|
|
|
|
<p>The structure members would be used as follows:</p>
|
|
|
|
<ul>
|
|
<li> <p><code>schm_Method</code></p>
|
|
|
|
<p> This must be one <code>S2_CopyToBuff</code>, <code>S2_CopyFromBuff</code>, <code>S2_CopyToBuff16</code>,
|
|
<code>S2_CopyFromBuff16</code>, <code>S2_CopyToBuff32</code>, <code>S2_CopyFromBuff32</code>,
|
|
<code>S2_DMACopyToBuff32</code>, <code>S2_DMACopyFromBuff32</code>, <code>S2_DMACopyToBuff64</code>
|
|
or <code>S2_DMACopyFromBuff64</code> to identify the function to be performed.</p>
|
|
|
|
<li> <p><code>schm_MsgSize</code></p>
|
|
|
|
<p> Size of this message data structure in bytes. This must be >= 20
|
|
for this message type. </p>
|
|
|
|
<p> The driver shall set <code>schm_MsgSize</code> always correctly to be compliant.
|
|
The protocol stack shall use this field to validate the message and
|
|
to reject/ignore bad messages via a <code>FALSE</code> hook function return value.
|
|
For DMA related hooks, a <code>FALSE</code> return value is equivalent to a <code>NUL</code>L
|
|
pointer. </p>
|
|
|
|
<li> <p><code>schm_To</code></p>
|
|
|
|
<p> Equivalent to the <code>to</code> parameter of the <code>CopyFromBuff</code>, <code>CopyToBuff</code>
|
|
and <code>DMACopyToBuff</code> functions. </p>
|
|
|
|
<li> <p><code>schm_From</code></p>
|
|
|
|
<p> Equivalent to the <code>from</code> parameter of the <code>CopyFromBuff</code> and <code>CopyToBuff</code>
|
|
functions. </p>
|
|
|
|
<li> <p><code>schm_Size</code></p>
|
|
|
|
<p> Equivalent to the <code>n</code> parameter of the <code>CopyFromBuff</code>, <code>CopyToBuff</code>,
|
|
functions. </p>
|
|
|
|
</ul>
|
|
|
|
<p> For logging operations the message would look like this: </p>
|
|
|
|
<pre>
|
|
struct SANA2LogHookMsg
|
|
{
|
|
ULONG slhm_Method;
|
|
ULONG slhm_MsgSize;
|
|
|
|
ULONG slhm_Priority;
|
|
STRPTR slhm_Name;
|
|
STRPTR slhm_Message;
|
|
};
|
|
</pre>
|
|
|
|
<p> The structure members would be used as follows: </p>
|
|
|
|
<ul>
|
|
|
|
<li> <p><code>slhm_Method</code></p>
|
|
|
|
<p> This must be <code>S2_Log</code>, as defined in the SANA-IIR4 specification. </p>
|
|
|
|
<li> <p><code>slhm_MsgSize</code></p>
|
|
|
|
<p> Size of this message data structure in bytes. This must be >= 20
|
|
for this message type. </p>
|
|
|
|
<p> The driver shall set <code>slhm_MsgSize</code> always correctly to be compliant.
|
|
The protocol stack shall use this field to validate the message and
|
|
to reject/ignore bad messages via a <code>FALSE</code> hook function return value.
|
|
For DMA related hooks, a <code>FALSE</code> return value is equivalent to a <code>NULL</code>
|
|
pointer. </p>
|
|
|
|
<li> <p><code>slhm_Priority</code></p>
|
|
|
|
<p> The smaller this value, the more important the message to be logged or
|
|
displayed. The following priority levels are defined (similar to the
|
|
Unix syslog() mechanism): </p>
|
|
|
|
<ul>
|
|
|
|
<li> <p><code> #define S2LOG_Emergency 0 </code></p>
|
|
|
|
<p> A panic condition. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Alert 1 </code></p>
|
|
|
|
<p> A condition that should be corrected immediately. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Critical 2 </code></p>
|
|
|
|
<p> Critical conditions. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Error 3 </code></p>
|
|
|
|
<p> A plain error. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Warning 4 </code></p>
|
|
|
|
<p> A warning message. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Notice 5 </code></p>
|
|
|
|
<p> Conditions that are not error conditions, but should possibly be
|
|
handled specially. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Information 6 </code></p>
|
|
|
|
<p> An informational message. </p>
|
|
|
|
<li> <p><code> #define S2LOG_Debug 7 </code></p>
|
|
|
|
<p> Messages that contain information normally of use only when
|
|
debugging. </p>
|
|
|
|
</ul>
|
|
|
|
<p> Only these priority values may be used by a driver. It is suggested
|
|
that a driver is configurable to generate different types of messages
|
|
or not, e.g., a driver may be configured to only emit <code>S2LOG_Emergency</code>
|
|
and <code>S2LOG_Debug</code> messages. </p>
|
|
|
|
<li> <p><code> slhm_Name </code></p>
|
|
|
|
<p> Pointer to a <code>NUL</code>-terminated string which identifies the source of this
|
|
message. This can be <code>NULL</code> in which case the OS device name of the driver
|
|
shall be used by the protocol stack. </p>
|
|
|
|
<li> <p><code> slhm_Message </code></p>
|
|
|
|
<p> Pointer to a <code>NUL</code>-terminated string which contains the log message. The
|
|
text should not contain any formatting characters such as line feeds
|
|
or carriage returns. The <code>slhm_Message</code> member must never be <code>NULL</code>. </p>
|
|
|
|
<p> All message texts shall preferrably be formatted in the current user's
|
|
locale. If that is not possible, the english language shall be used.
|
|
<code>slhm_Name</code> and <code>slhm_Message</code> shall only contain printable characters. </p>
|
|
|
|
</ul>
|
|
|
|
<p> The hook function itself would be invoked with the following parameters: </p>
|
|
|
|
<pre>
|
|
result = hook_function(hook,sana2req,sana2hookmsg)
|
|
D0 A0 A2 A1
|
|
|
|
ULONG hook_function(struct Hook *hook,
|
|
struct IOSana2Req *sana2req,
|
|
struct SANA2HookMsg *sana2hookmsg);
|
|
</pre>
|
|
|
|
<p> Note that the result would not necessarily be of type <code>ULONG</code>. It would be
|
|
a 32 bit value, which would either be a boolean result code (for
|
|
<code>CopyFromBuff</code>, <code>CopyToBuff</code> and their like) or the pointer to a memory address
|
|
(for <code>DMACopyToBuff</code>, <code>DMACopyFromBuff</code> and their like). </p>
|
|
|
|
<h3>3.2 Commands</h3>
|
|
|
|
<p> The 'traditional' copy call-back functions are installed at <code>OpenDevice()</code> time,
|
|
and they are found in a <code>TagItem</code> list which is passed along with the
|
|
<code>IOSana2Req</code>. For the new <code>Hook</code>-based call-back functionality, I propose to
|
|
introduce a new command. This command would take care of installing one single
|
|
<code>Hook</code> which will be invoked with the parameters described in section 3.1. The
|
|
hook function can key off the <code>SANA2HookMsg->schm_Method</code> field to figure out
|
|
which function should be performed. Once the <code>Hook</code> is installed via the command
|
|
as follows, the driver shall ignore any and all tags passed to it during
|
|
<code>OpenDevice()</code> time. </p>
|
|
|
|
<p> The command is tentatively defined as follows: </p>
|
|
|
|
<pre>
|
|
sana2.device/S2_SANA2HOOK sana2.device/S2_SANA2HOOK
|
|
|
|
NAME
|
|
S2_SANA2HOOK -- Install a Hook to perform operations such as copying,
|
|
overriding the call-back functions installed at
|
|
OpenDevice() time.
|
|
|
|
FUNCTION
|
|
The S2_SANA2HOOK command is to replace the 'traditional' call-back
|
|
functions installed through the TagItem list found in the
|
|
IOSana2Req->ios2_BufferManagement field. Instead of assigning a
|
|
function pointer for each copying function, all operations are
|
|
to be performed through a Hook. This is intended to make the
|
|
interface more portable and less dependant on a certain hardware
|
|
architecture.
|
|
|
|
The hook message and the hook data structures allow for more than
|
|
copying to be done.
|
|
|
|
IO REQUEST
|
|
ios2_Command - S2_SANA2HOOK
|
|
ios2_Data - Points to a struct Sana2Hook, which looks
|
|
like this:
|
|
|
|
struct Sana2Hook
|
|
{
|
|
struct Hook s2h_Hook;
|
|
Tag * s2h_Methods;
|
|
};
|
|
|
|
The structure fields have the following purposes:
|
|
|
|
s2h_Hook
|
|
A standard Hook structure, ready to be
|
|
called. Once installed, the complete Hook
|
|
structure including its Node structure is
|
|
off limits! The s2h_Hook remains installed
|
|
until CloseDevice().
|
|
|
|
s2h_Methods
|
|
Points to a table of Tag values, each
|
|
identifying a copy method supported
|
|
(S2_CopyToBuff, S2_CopyFromBuff,
|
|
S2_CopyToBuff16, S2_CopyFromBuff16,
|
|
S2_CopyToBuff32, S2_CopyFromBuff32,
|
|
S2_DMACopyToBuff32, S2_DMACopyFromBuff32,
|
|
S2_DMACopyToBuff64 or S2_DMACopyFromBuff64)
|
|
or the logging facility (S2_Log).
|
|
The table must be terminated by TAG_END.
|
|
|
|
The driver will check the table and
|
|
verify that the mandatory S2_CopyToBuff
|
|
and S2_CopyFromBuff commands are present.
|
|
Additional functionality is used as
|
|
available if the driver supports it.
|
|
|
|
ios2_DataLength - Must be >= 20, which is the default length of
|
|
the Sana2Hook structure. This may grow in
|
|
the future, and larger values for ios2_DataLength
|
|
may indicate additional functionality associated
|
|
with the Sana2Hook.
|
|
|
|
RESULTS
|
|
ios2_Error - IOERR_NOCMD if this command is not supported
|
|
by the driver.
|
|
|
|
IOERR_BADLENGTH if IOSana2Req->ios2_DataLength
|
|
is < 20.
|
|
|
|
IOERR_UNITBUSY if the Hook was already
|
|
installed or if any of the CMD_READ, CMD_WRITE,
|
|
S2_MULTICAST or S2_BROADCAST have already been
|
|
invoked.
|
|
|
|
S2WERR_FUNCTIONS_MISSING if the table pointed
|
|
to by Sana2Hook->s2h_Methods does not
|
|
include the S2_CopyToBuff and S2_CopyFromBuff
|
|
tags.
|
|
|
|
NOTES
|
|
The S2_SANA2HOOK command shall be invoked right after OpenDevice()
|
|
as very first command.
|
|
|
|
When the command has been executed, the driver must use the
|
|
newly installed Hook for all its copying or logging and cease to
|
|
use the call-back functions provided at OpenDevice() time.
|
|
|
|
The contents of the Sana2Hook structure, as passed to the
|
|
driver, must not be modified. This includes the MinNode
|
|
at the beginning of the Hook structure which the driver may
|
|
need to use for its own purposes.
|
|
|
|
The table pointed to by Sana2Hook->s2h_Methods must
|
|
include at least the S2_CopyToBuff and S2_CopyFromBuff tags.
|
|
It must be valid until CloseDevice() is called.
|
|
|
|
This field is to be treated as private by a protocol stack.
|
|
IOSana2Req structures may be duplicated by copying
|
|
ios2_BufferManagement, io_Device, and io_Unit.
|
|
</pre>
|
|
|
|
<p> The new command value is defined as follows: </p>
|
|
|
|
<pre>
|
|
#define S2_SANA2HOOK 0xC008
|
|
</pre>
|
|
|
|
<p> The new error code is defined as follows: </p>
|
|
|
|
<pre>
|
|
#define S2WERR_FUNCTIONS_MISSING 24 /* mandatory copy functions are missing */
|
|
</pre>
|
|
|
|
<h2>4. Application and driver software use of the new functions</h2>
|
|
|
|
<p> Since plenty of software exists which uses the 'traditional' <code>TagItem</code> list
|
|
provided at <code>OpenDevice()</code> time it is recommend that drivers always examine
|
|
these parameters and do not expect a <code>S2_SANA2HOOK</code> command to be sent later. </p>
|
|
|
|
<p> If the new <code>Hook</code>-based callback functions are to be used, then the driver must
|
|
invoke the Hooks via <code>utility.library/CallHookPkt</code>. It must not invoke the hook
|
|
functions through local assembly language stubs or the <code>amiga.lib/CallHook</code> and
|
|
<code>amiga.lib/CallHookA</code> functions. </p>
|
|
|
|
<h2>5. Caveats</h2>
|
|
|
|
<p> The functionality proposed above suggests that one could do entirely without
|
|
the <code>TagItem</code> list passed in at <code>OpenDevice()</code> time. However, at this time it is
|
|
hard to tell how existing driver software will react to empty <code>TagItem</code> lists
|
|
or even a NULL pointer in the <code>IOSana2Req->ios2_BufferManagement</code> field. It
|
|
is therefore recommend to always provide for a <code>TagItem</code> list which includes
|
|
proper (i.e. they must point to working functions and may not be <code>NULL</code>) function
|
|
pointers for the <code>S2_CopyToBuff</code> and <code>S2_CopyFromBuff</code> tags. Once the device
|
|
has been opened successfully, the next step is to try and install the copy
|
|
<code>Hook</code> through the proposed <code>S2_SANA2HOOK</code> command. If the command fails, the
|
|
application can still expect that the <code>S2_CopyToBuff</code> and <code>S2_CopyFromBuff</code> tags
|
|
supplied at <code>OpenDevice()</code> time will work. </p>
|
|
|
|
<p> Note that the <code>ios2_BufferManagement</code> field provided by the driver on
|
|
<code>OpenDevice()</code> time in conjunction with <code>io_Device</code> and <code>io_Unit</code> is the unique
|
|
identifier for all requests coming from this protocol stack until
|
|
<code>CloseDevice()</code>. The driver must not ever change the <code>ios2_BufferManagement</code> field
|
|
for a protocol stack at run time, even if <code>S2_SANAHOOK</code> is called to request
|
|
extended features. </p>
|
|
|
|
<h2>6. Changes</h2>
|
|
|
|
<p>22-Mar-2004: </p>
|
|
|
|
<ul>
|
|
|
|
<li> Conversion to HTML
|
|
|
|
</ul>
|
|
|
|
<p>21-Jan-2004: </p>
|
|
|
|
<ul>
|
|
|
|
<li> Added clarifications for <code>schm_MsgSize</code>, <code>slhm_MsgSize</code>, <code>slhm_Priority</code>,
|
|
<code>slhm_Name</code>, <code>slhm_Message</code> and <code>s2h_Hook</code>.
|
|
|
|
<li> Updated the <code>S2_SANA2HOOK</code> documentation.
|
|
|
|
<li> Shortened section 4.
|
|
|
|
<li> Updated section 5.
|
|
|
|
</ul>
|
|
|
|
<p>30-Nov-2003:</p>
|
|
|
|
<ul>
|
|
|
|
<li> Extended the applicability of the <code>Hook</code> to logging.
|
|
|
|
<li> Renamed <code>S2_COPYHOOK</code> to <code>S2_SANA2HOOK</code>, which matches the extended
|
|
scope it should cover.
|
|
|
|
<li> The message passed to the <code>Hook</code> now includes a size field which
|
|
holds the size of the message, expressed in bytes.
|
|
|
|
</ul>
|
|
|
|
<p>06-Oct-2003:</p>
|
|
|
|
<ul>
|
|
|
|
<li> Replaced the list of new tag items with a single <code>Hook</code>, which
|
|
is installed through a new command.
|
|
|
|
<li> Added "Caveats" and "Changes" sections
|
|
|
|
<li> Removed the documentation for the originally proposed <code>TagItem</code>
|
|
(sections 3.2.1 through 3.2.10)
|
|
|
|
</ul>
|
|
|
|
</body>
|
|
<html>
|