summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/madge/driver/drv_srb.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/madge/driver/drv_srb.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/madge/driver/drv_srb.c')
-rw-r--r--private/ntos/ndis/madge/driver/drv_srb.c1849
1 files changed, 1849 insertions, 0 deletions
diff --git a/private/ntos/ndis/madge/driver/drv_srb.c b/private/ntos/ndis/madge/driver/drv_srb.c
new file mode 100644
index 000000000..cd84d70d3
--- /dev/null
+++ b/private/ntos/ndis/madge/driver/drv_srb.c
@@ -0,0 +1,1849 @@
+/****************************************************************************
+*
+* DRV_SRB.C : Part of the FASTMAC TOOL-KIT (FTK)
+*
+* THE DRIVER MODULE (SRBs)
+*
+* Copyright (c) Madge Networks Ltd. 1991-1994
+*
+* COMPANY CONFIDENTIAL
+*
+*****************************************************************************
+*
+* The driver module provides a simple interface to allow the use of
+* Fastmac in as general a setting as possible. It handles the downloading
+* of the Fastmac code and the initialization of the adapter card. It
+* provides simple transmit and receive routines. It is desgined to
+* quickly allow the implementation of Fastmac applications. It is not
+* designed as the fastest or most memory efficient solution.
+*
+* The DRV_SRB.C module contains those routines that involve issuing SRBs,
+* such as open adapter and set functional address. It also contains the
+* code that calls the user when an SRB completes.
+*
+****************************************************************************/
+
+/*---------------------------------------------------------------------------
+|
+| DEFINITIONS
+|
+---------------------------------------------------------------------------*/
+
+#include "ftk_defs.h"
+
+/*---------------------------------------------------------------------------
+|
+| MODULE ENTRY POINTS
+|
+---------------------------------------------------------------------------*/
+
+#include "ftk_intr.h" /* routines internal to FTK */
+#include "ftk_extr.h" /* routines provided or used by external FTK user */
+
+/*---------------------------------------------------------------------------
+|
+| GLOBAL VARIABLES
+|
+---------------------------------------------------------------------------*/
+
+export char ftk_product_inst_id[SIZEOF_PRODUCT_ID] = FASTMAC_PRODUCT_ID;
+
+/*---------------------------------------------------------------------------
+|
+| LOCAL FUNCTIONS
+|
+---------------------------------------------------------------------------*/
+
+local void
+driver_issue_srb(
+ ADAPTER * adapter
+ );
+
+local WBOOLEAN
+get_open_and_ring_status(
+ void * ptr
+ );
+
+local WBOOLEAN
+issue_srb(
+ void * ptr
+ );
+
+/****************************************************************************
+*
+* driver_ring_speed
+* =================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter whose ring speed is to be returned.
+*
+* BODY :
+* ======
+*
+* This is a short helper function (that could easily be replaced by a
+* macro). It just digs out the stored ring speed from the adapter
+* structure, so that external users of the FTK have some way of getting at
+* this piece of information.
+*
+* RETURNS :
+* =========
+*
+* The current ring speed.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_ring_speed)
+#endif
+
+export UINT
+driver_ring_speed(
+ ADAPTER_HANDLE adapter_handle
+ )
+{
+ return adapter_record[adapter_handle]->ring_speed;
+}
+
+/****************************************************************************
+*
+* driver_max_frame_size
+* =====================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter whose maximum supported frame size is
+* to be returned.
+*
+* BODY :
+* ======
+*
+* This is a short helper function (that could easily be replaced by a
+* macro). It just digs out the stored maximum frame size from the adapter
+* structure, so that external users of the FTK have some way of getting at
+* this piece of information.
+*
+* RETURNS :
+* =========
+*
+* The current maximum frame size.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_max_frame_size)
+#endif
+
+export UINT
+driver_max_frame_size(
+ ADAPTER_HANDLE adapter_handle
+ )
+{
+ return adapter_record[adapter_handle]->max_frame_size;
+}
+
+/****************************************************************************
+*
+* driver_modify_open_options
+* ==========================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter on which to modify the open options.
+*
+* WORD open_options
+*
+* This gives the new modified open options for the adapter.
+*
+* BODY :
+* ======
+*
+* The driver_modify_open_options routine issues a modify open parms SRB.
+* The adapter must be open for this command to complete successfully. It
+* does not matter whether the adapter has been opened in auto-open mode or
+* using an open adapter SRB.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_modify_open_options)
+#endif
+
+export WBOOLEAN
+driver_modify_open_options(
+ ADAPTER_HANDLE adapter_handle,
+ WORD open_options
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_MODIFY_OPEN_PARMS));
+
+ /*
+ * Set up non-zero modify open parms SRB fields.
+ */
+
+ srb_gen->mod_parms.header.function = MODIFY_OPEN_PARMS_SRB;
+ srb_gen->mod_parms.open_options = open_options;
+
+ /*
+ * Save a copy of the open options in the fastmac init block, in
+ * case we later have to re-open the adapter with the same state. This
+ * is the case with NDIS3 MacReset(), which causes the card to be re-
+ * initialized, but the open options must be left as they were before
+ * the reset.
+ */
+
+ adapter->init_block->fastmac_parms.open_options = open_options;
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_MODIFY_OPEN_PARMS);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_open_adapter
+* ===================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter to be opened.
+*
+* PTR_OPEN_DATA open_data
+*
+* This points to a structure containing : the open options, the opening
+* node address, the opening functional address, and the opening group
+* address. If the opening node address is NULL, the BIA PROM node address
+* will be used instead.
+*
+* BODY :
+* ======
+*
+* The driver_open_adapter routine issues an open adapter SRB. This routine
+* is not needed when the Fastmac auto_open option is used.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_open_adapter)
+#endif
+
+export WBOOLEAN
+driver_open_adapter(
+ ADAPTER_HANDLE adapter_handle,
+ PTR_OPEN_DATA open_data
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+ UINT i;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter( adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_OPEN_ADAPTER));
+
+ /*
+ * Set up non-zero open adapter SRB fields.
+ */
+
+ srb_gen->open_adap.header.function = OPEN_ADAPTER_SRB;
+ srb_gen->open_adap.open_options = open_data->open_options;
+
+ /*
+ * Fill in opening node address field.
+ */
+
+ for (i = 0; i < sizeof(NODE_ADDRESS); i++)
+ {
+ if (open_data->opening_node_address.byte[i] != 0)
+ {
+ break;
+ }
+ }
+
+ if (i == sizeof(NODE_ADDRESS))
+ {
+ /*
+ * If opening node address not given then use BIA PROM address.
+ */
+
+ srb_gen->open_adap.open_address = adapter->permanent_address;
+ }
+ else
+ {
+ /*
+ * Otherwise use supplied node address.
+ */
+
+ srb_gen->open_adap.open_address = open_data->opening_node_address;
+ }
+
+ srb_gen->open_adap.group_address = open_data->group_address;
+ srb_gen->open_adap.functional_address = open_data->functional_address;
+
+ /*
+ * Byte swap node address before downloading to adapter.
+ */
+
+ util_byte_swap_structure(
+ (BYTE *) &srb_gen->open_adap.open_address,
+ sizeof(NODE_ADDRESS)
+ );
+
+ /*
+ * Fill in the product id with product ID string.
+ */
+
+ util_mem_copy(
+ srb_gen->open_adap.product_id,
+ ftk_product_inst_id,
+ SIZEOF_PRODUCT_ID
+ );
+
+ /*
+ * Byte swap the product id string before downloading.
+ */
+
+ util_byte_swap_structure(
+ (BYTE *) srb_gen->open_adap.product_id,
+ SIZEOF_PRODUCT_ID
+ );
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_OPEN_ADAPTER);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_close_adapter
+* ====================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter to be closed.
+*
+*
+* BODY :
+* ======
+*
+* The driver_close_adapter routine issues a close adapter SRB. If the
+* auto_open feature is being used then it is disabled by this call.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_close_adapter)
+#endif
+
+export WBOOLEAN
+driver_close_adapter(
+ ADAPTER_HANDLE adapter_handle
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_CLOSE_ADAPTER));
+
+ /*
+ * Place SRB type into header.
+ */
+
+ srb_gen->close_adap.header.function = CLOSE_ADAPTER_SRB;
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_CLOSE_ADAPTER);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_set_group_address
+* ========================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the required adapter.
+*
+* MULTI_ADDRESS * group_address
+*
+* The adapter is configured to receive frames sent to the group address
+* formed from this parameter with the prefix 0xC000 and logically ANDed
+* with 0x80000000. For example {0x12,0x34,0x56,0x78} gives the group
+* address 0xC00092345678.
+*
+* BODY :
+* ======
+*
+* The driver_set_group_address routine issues a set group address SRB. The
+* adapter must be open for the SRB to complete successfully.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_set_group_address)
+#endif
+
+export WBOOLEAN
+driver_set_group_address(
+ ADAPTER_HANDLE adapter_handle,
+ MULTI_ADDRESS * group_address
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_SET_GROUP_ADDRESS));
+
+ /*
+ * Place SRB type into header.
+ */
+
+ srb_gen->set_group.header.function = SET_GROUP_ADDRESS_SRB;
+
+ /*
+ * Byte swap group address (for downloading) when putting it in SRB.
+ */
+
+ srb_gen->set_group.multi_address = *group_address;
+
+ util_byte_swap_structure(
+ (BYTE *) &srb_gen->set_group.multi_address,
+ sizeof(MULTI_ADDRESS)
+ );
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_SET_GROUP_ADDRESS);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_set_functional_address
+* =============================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the required adapter.
+*
+* MULTI_ADDRESS * functional_address
+*
+* For each bit set in this parameter, the adapter is configured to receive
+* frames sent to that functional address (0xC000xxxxxxxx). For example, if
+* functional_address equals {0x40,0x00,0x00,0x80} then the corresponding
+* functional addresses are 0xC00040000000 and 0xC00000000080.
+*
+*
+* BODY :
+* ======
+*
+* The driver_set_functional_address routine issues a set functional
+* address SRB. The adapter must be open for the SRB to complete
+* successfully. The effects of this call are not cumulative - that is
+* each call must specify ALL functional addresses required.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_set_functional_address)
+#endif
+
+export WBOOLEAN
+driver_set_functional_address(
+ ADAPTER_HANDLE adapter_handle,
+ MULTI_ADDRESS * functional_address
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_SET_FUNCTIONAL_ADDRESS));
+
+ /*
+ * Place SRB type into header.
+ */
+
+ srb_gen->set_func.header.function = SET_FUNCTIONAL_ADDRESS_SRB;
+
+ /*
+ * Byte swap functional address (for downloading) when putting in SRB.
+ */
+
+ srb_gen->set_func.multi_address = *functional_address;
+
+ util_byte_swap_structure(
+ (BYTE *) &srb_gen->set_func.multi_address,
+ sizeof(MULTI_ADDRESS)
+ );
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_SET_FUNCTIONAL_ADDRESS);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_get_open_and_ring_status
+* ===============================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter to get the adapter status information
+* on.
+*
+* WORD * pwRingStatus
+* WORD * pwOpenStatus
+*
+* These OUT parameters are filled with the Open and Ring status values in
+* addition to them being written into the status structure. It is often
+* convenient to be able to have these values stored at the callers whim.
+* They can be NULL if the caller does not need these values directly.
+*
+* BODY :
+* ======
+*
+* The driver_get_open_and_ring_status routine accesses DIO space to get
+* the current adapter open status and the current ring status. These two
+* bits of information are filled into the status information structure in
+* the adapter structure, and written to the supplied locations.
+*
+* RETURNS :
+* =========
+*
+* Nothing. But see the status information structure in the current adapter
+* for the open status and ring status.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_get_open_and_ring_status)
+#endif
+
+export void
+driver_get_open_and_ring_status(
+ ADAPTER_HANDLE adapter_handle,
+ WORD * pwRingStatus,
+ WORD * pwOpenStatus
+ )
+{
+ ADAPTER * adapter;
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ if (adapter == NULL)
+ {
+ if (pwRingStatus != NULL)
+ {
+ *pwRingStatus = 0;
+ }
+ if (pwOpenStatus != NULL)
+ {
+ *pwOpenStatus = 0;
+ }
+ return;
+ }
+
+ /*
+ * Inform the system about the IO ports we are going to access.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_enable_io(adapter);
+#endif
+
+ /*
+ * Get adapter open status from the STB in DIO space.
+ */
+
+ sys_sync_with_interrupt(
+ adapter->adapter_handle,
+ get_open_and_ring_status,
+ adapter);
+
+ /*
+ * Let the system know we have finished accessing the IO ports.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_disable_io(adapter);
+#endif
+
+ if (pwRingStatus != NULL)
+ {
+ *pwRingStatus = adapter->status_info->ring_status;
+ }
+ if (pwOpenStatus != NULL)
+ {
+ *pwOpenStatus = adapter->status_info->adapter_open;
+ }
+}
+
+/****************************************************************************
+*
+* driver_get_status
+* =================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter to get the adapter status information
+* on.
+*
+* BODY :
+* ======
+*
+* The driver_get_status routine issues a read error log SRB in order to
+* get the error log maintained by the protocol handler. This routine also
+* accesses DIO space to get the current adapter open status and the
+* current ring status. These two bits of information are actually filled
+* into the status information structure immediately - they are available
+* before the user_completed_srb routine is called.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the actual SRB completes. It is this
+* user routine that is informed as to whether the SRB completed
+* successfully and it is at this time that the error log is filled into
+* the status information structure. Also, until the user_completed_srb
+* routine is called by the driver, no other driver routines involving the
+* issuing of SRBs for the given adapter will work. This is because there
+* is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* Note there is no need to worry about an interrupt occuring, (between the
+* setting of the EAGLE SIFADR register and the reading/writing of the
+* required DIO space data), that would alter the contents of the EAGLE
+* SIFADR register (and hence the SIFDAT and SIFDAT_INC registers too).
+* This is because the receive frame interrupt handler exits leaving the
+* contents of SIFADR as on entry.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds and will have filled in the
+* requested status information but not the error log. If this routine
+* fails (returns FALSE) then a subsequent call to driver_explain_error
+* with the same adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb. Also, in this particular case, it
+* is important to note that the error log is not filled in until the SRB
+* completes.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_get_status)
+#endif
+
+export WBOOLEAN
+driver_get_status(
+ ADAPTER_HANDLE adapter_handle
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Get the adapter open status and ring status.
+ */
+
+ driver_get_open_and_ring_status(adapter_handle, NULL, NULL);
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_READ_ERROR_LOG));
+
+ /*
+ * Place SRB type into header.
+ */
+
+ srb_gen->err_log.header.function = READ_ERROR_LOG_SRB;
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_READ_ERROR_LOG);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+
+
+/****************************************************************************
+*
+* driver_set_bridge_parms
+* =======================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter to get the adapter status information
+* on.
+*
+* WBOOLEAN single_route_bcast
+*
+* If this is TRUE, then single route broadcast frames will be rejected
+* by the SRA.
+*
+* UINT this_ring
+*
+* This is the ring number that the SRA will recognise as the source ring.
+* It must be the number of the ring to which this adapter is connected. It
+* will be matched against the source ring field in the routing information
+* section of frames received from this ring.
+*
+* UINT that_ring
+*
+* This is the ring number that the SRA will recognise as the destination
+* ring. It must be the number of the ring to which the other adapter in
+* this host is connected. It will be matched against the target ring field
+* in the routing information section of frames received from the source
+* ring.
+*
+* UINT bridge_num
+*
+* This is the number that identifies this bridge on both rings. It will be
+* matched against the bridge number field in the routing information field
+* of frames received from the source ring.
+*
+* BODY :
+* ======
+*
+* The driver_set_bridge_parms routine issues a set bridge parms SRB.
+* The adapter must be open for the SRB to complete successfully.
+* Two of the fields use default values to simplify the calling procedure a
+* little - these are the number of bridge bits and the maximum length of
+* the routing information field. The number of bridge bits defaults to 4
+* allowing bridge numbers between 0 and 0xF, and ring numbers between 0
+* and 0xFFF. All bridges on the network must agree on this value. The max.
+* routing field causes all frames with routing information fields longer
+* than the specified value to be rejected by the SRA. To be IBM compatible
+* this value should be 18, which is the default value.
+* These values are defined in FTK_SRB.H.
+*
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the SRB completes. It is this user
+* routine that is informed as to whether the SRB completed successfully.
+* Also, until this routine is called by the driver, no other driver
+* routines involving the issuing of SRBs for the given adapter will work.
+* This is because there is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_set_bridge_parms)
+#endif
+
+export WBOOLEAN
+driver_set_bridge_parms(
+ ADAPTER_HANDLE adapter_handle,
+ WBOOLEAN single_route_bcast,
+ UINT this_ring,
+ UINT that_ring,
+ UINT bridge_num
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+ WORD options;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_SET_BRIDGE_PARMS));
+
+ /*
+ * Place SRB type into header.
+ */
+
+ srb_gen->set_bridge_parms.header.function = SET_BRIDGE_PARMS_SRB;
+
+ /*
+ * Fill in the bridge parameters, using defaults from FTK_SRB.H and the
+ * user supplied values.
+ *
+ * Note that the bit fields in the options word are filled in here using
+ * shifts and ORs, because of the danger that different compilers will
+ * order bit fields in a structure differently.
+ */
+
+ options = ((single_route_bcast ? 0x8000 : 0)
+ | ((SRB_SBP_DFLT_ROUTE_LEN & 0x3f) << 4)
+ | (SRB_SBP_DFLT_BRIDGE_BITS & 0xf));
+
+ srb_gen->set_bridge_parms.options = options;
+ srb_gen->set_bridge_parms.this_ring = this_ring;
+ srb_gen->set_bridge_parms.that_ring = that_ring;
+ srb_gen->set_bridge_parms.bridge_num = bridge_num;
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_SET_BRIDGE_PARMS);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+
+/****************************************************************************
+*
+* driver_set_product_instance_id
+* ==============================
+*
+* PARAMETERS :
+* ============
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* This handle identifies the adapter on which to set the product instance
+* identification string.
+*
+* BYTE * product_id
+*
+* A pointer to an eighteen byte ASCII Identification string.
+*
+* BODY :
+* ======
+*
+* The driver_set_product_instance_id issues an SRB to set the product id
+* string. This string is written into certain MAC frames to report various
+* software and hardware conditions.
+* As with all the routines that involve issuing SRBs, the user routine
+* user_completed_srb is called when the actual SRB completes. It is this
+* user routine that is informed as to whether the SRB completed
+* successfully and it is at this time that the error log is filled into
+* the status information structure. Also, until the user_completed_srb
+* routine is called by the driver, no other driver routines involving the
+* issuing of SRBs for the given adapter will work. This is because there
+* is only one SRB per adapter.
+*
+* Note that only those fields that are used in the SRB (ie. have non-zero
+* values) that need to be byte swapped are byte swapped either in this
+* routine or in driver_issue_srb. Hence, if any adjustments are made to
+* the code it may be necessary to make sure that any newly used fields are
+* correctly byte swapped before downloading.
+*
+* Take special note of the fact that the user_completed_srb routine can be
+* called before this routine completes. This is because it is called out
+* of interrupts.
+*
+* RETURNS :
+* =========
+*
+* The routine returns TRUE if it succeeds. If this routine fails (returns
+* FALSE) then a subsequent call to driver_explain_error with the same
+* adapter handle will give an explanation.
+*
+* Note that a successful call to this routine only means that the SRB has
+* been issued successfully. It does not mean that it has completed
+* successfully. The success or failure of the SRB is indicated in a
+* subsequent call to user_completed_srb. Also, in this particular case, it
+* is important to note that the error log is not filled in until the SRB
+* completes.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_set_product_instance_id)
+#endif
+
+export WBOOLEAN
+driver_set_product_instance_id(
+ ADAPTER_HANDLE adapter_handle,
+ BYTE * product_id
+ )
+{
+ ADAPTER * adapter;
+ SRB_GENERAL * srb_gen;
+
+ /*
+ * Check adapter handle and status of adapter for validity.
+ * If routine fails return failure (error record already filled in).
+ */
+
+ if (!driver_check_adapter(adapter_handle, ADAPTER_RUNNING, SRB_FREE))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Get pointer to adapter structure.
+ */
+
+ adapter = adapter_record[adapter_handle];
+
+ /*
+ * Set adapter SRB status to show that SRB is now in use.
+ */
+
+ adapter->srb_status = SRB_NOT_FREE;
+
+ /*
+ * Get pointer to general SRB structure to be used.
+ */
+
+ srb_gen = &adapter->srb_general;
+
+ /*
+ * Clear part of general SRB to be used.
+ */
+
+ util_zero_memory((BYTE *) srb_gen, sizeof(SRB_SET_PROD_INST_ID));
+
+ /*
+ * Place SRB type into header - this is a Fastmac Plus specific one, so
+ * we have to set a subcode value too.
+ */
+
+ srb_gen->set_prod_inst_id.header.function = FMPLUS_SPECIFIC_SRB;
+ srb_gen->set_prod_inst_id.subcode = SET_PROD_INST_ID_SUBCODE;
+
+ /*
+ * Copy in the product instance id.
+ */
+
+ util_mem_copy(
+ srb_gen->set_prod_inst_id.product_id,
+ product_id,
+ SIZEOF_PRODUCT_ID
+ );
+
+ /*
+ * Byte swap the product instance id.
+ */
+
+ util_byte_swap_structure(
+ (BYTE *) srb_gen->set_prod_inst_id.product_id,
+ SIZEOF_PRODUCT_ID
+ );
+
+ /*
+ * Record size of SRB that is being issued.
+ */
+
+ adapter->size_of_srb = sizeof(SRB_SET_PROD_INST_ID);
+
+ /*
+ * Call routine to issue SRB.
+ */
+
+ driver_issue_srb(adapter);
+
+ /*
+ * SRB issued successfully.
+ */
+
+ return TRUE;
+}
+
+/****************************************************************************
+*
+* driver_issue_srb
+* ================
+*
+* The driver_issue_srb routine issues an SRB. It does this by copying it
+* into DIO space and issuing an SRB command interrupt to Fastmac via the
+* SIFINT register.
+*
+* Note there is no need to worry about an interrupt occuring, (between the
+* setting of the EAGLE SIFADR register and the reading/writing of the
+* required DIO space data), that would alter the contents of the EAGLE
+* SIFADR register (and hence the SIFDAT and SIFDAT_INC registers too).
+* This is because the receive frame interrupt handler exits leaving the
+* contents of SIFADR as on entry.
+*
+****************************************************************************/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(driver_issue_srb)
+#endif
+
+local void
+driver_issue_srb(
+ ADAPTER * adapter
+ )
+{
+ ADAPTER_HANDLE hnd = adapter->adapter_handle;
+ SRB_GENERAL * srb_gen = &adapter->srb_general;
+
+ /*
+ * Before downloading need to byte swap the SRB header.
+ */
+
+ util_byte_swap_structure(
+ (BYTE *) &srb_gen->header,
+ sizeof(SRB_HEADER)
+ );
+
+ /*
+ * Inform the system about the IO ports we are going to access.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_enable_io( adapter);
+#endif
+
+ sys_sync_with_interrupt(hnd, issue_srb, adapter);
+
+ /*
+ * Let the system know we have finished accessing the IO ports.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_disable_io( adapter);
+#endif
+}
+
+/****************************************************************************
+*
+* driver_completing_srb
+* =====================
+*
+* PARAMETERS (passed by driver_interrupt_entry) :
+* ===============================================
+*
+* ADAPTER_HANDLE adapter_handle
+*
+* The adapter handle for the adapter so it can be passed to the user
+* supplied user_completed_srb routine.
+*
+* ADAPTER * adapter
+*
+* The details of the adapter that the SRB has completed on.
+*
+* BODY :
+* ======
+*
+* The driver_completing_srb routine is called by driver_interrupt_entry.
+* It is called when Fastmac has generated an interrupt to say that the
+* SRB, associated with a particular adapter, has completed and further
+* SRBs can be issued.
+*
+* The routine reads the SRB out of DIO space into the SRB structure
+* maintained for the correct adapter. It then checks the SRB return code
+* to see if the SRB completed successfully and records the fact that the
+* SRB is now free. Then, it informs the user as to the success of the
+* completed SRB by calling user_completed_srb.
+*
+* The user_completed_srb routine should do a minimum amount of processing
+* because it is being called out of interrupts. Sensibly, it should just
+* set a flag, to say that the SRB has completed, that can be checked for
+* at strategy time when a further driver routine involving the use of the
+* SRB is called.
+*
+* Note that only those fields that are needed in the completed SRB that
+* need to be byte swapped back to Intel format are byte swapped. Hence,
+* if any adjustments are made to the code it may be necessary to make sure
+* that any newly used fields are correctly byte swapped back.
+*
+* RETURNS :
+* =========
+*
+* The routine always succeeds and returns control to the driver routine
+* driver_interrupt_entry.
+*
+****************************************************************************/
+
+#ifdef FTK_IRQ_FUNCTION
+#pragma FTK_IRQ_FUNCTION(driver_completing_srb)
+#endif
+
+export void
+driver_completing_srb(
+ ADAPTER_HANDLE adapter_handle,
+ ADAPTER * adapter
+ )
+{
+ SRB_GENERAL * srb_gen = &adapter->srb_general;
+ WORD saved_sifadr_value;
+ WBOOLEAN user_success_code;
+
+ /*
+ * Before accessing SIFADR, save current value for restoring on exit.
+ * Do this so interrupt not effect SIFADR value.
+ */
+
+ saved_sifadr_value = sys_insw(adapter_handle, adapter->sif_adr);
+
+ /*
+ * Copy SRB out of DIO space into adapter's SRB structure.
+ */
+
+ sys_outsw(
+ adapter_handle,
+ adapter->sif_adr,
+ (WORD) (card_t) adapter->srb_dio_addr
+ );
+
+ sys_rep_insw(
+ adapter_handle,
+ adapter->sif_datinc,
+ (BYTE *) srb_gen,
+ (WORD) (adapter->size_of_srb / 2)
+ );
+
+ if (adapter->size_of_srb & 1)
+ {
+ *(((BYTE * ) srb_gen) + adapter->size_of_srb - 1) =
+ sys_insb(adapter_handle, adapter->sif_datinc);
+ }
+
+ /*
+ * Once read from DIO space, byte swap SRB header back to Intel format.
+ */
+
+ util_byte_swap_structure((BYTE *) &srb_gen->header, sizeof(SRB_HEADER));
+
+ /*
+ * Check if SRB has completed successfully.
+ */
+
+ if (srb_gen->header.return_code == SRB_E_00_SUCCESS)
+ {
+ /*
+ * SRB completed successfully so record this to inform user.
+ */
+
+ user_success_code = TRUE;
+
+ /*
+ * If read error log SRB completed successfully
+ * then copy error log information into user's structure.
+ * Need to byte swap error log structure to Intel format first.
+ */
+
+ if (srb_gen->header.function == READ_ERROR_LOG_SRB)
+ {
+ util_byte_swap_structure(
+ (BYTE *) &srb_gen->err_log.error_log,
+ sizeof(ERROR_LOG)
+ );
+
+ adapter->status_info->error_log = srb_gen->err_log.error_log;
+ }
+ }
+ else
+ {
+ /*
+ * SRB not completed successfully so record this to inform user
+ * and fill in error record.
+ */
+
+ user_success_code = FALSE;
+ adapter->error_record.type = ERROR_TYPE_SRB;
+ adapter->error_record.value = srb_gen->header.return_code;
+ }
+
+ /*
+ * If issued an open adapter SRB and error is E_07_CMD_CANCELLED_FAIL
+ * then actually have an open error so change adapter error record.
+ */
+
+ if ((srb_gen->header.function == OPEN_ADAPTER_SRB) &&
+ (srb_gen->header.return_code == SRB_E_07_CMD_CANCELLED_FAIL))
+ {
+ /*
+ * Fill in error record with open error (not SRB error).
+ */
+
+ adapter->error_record.type = ERROR_TYPE_OPEN;
+ adapter->error_record.value = OPEN_E_01_OPEN_ERROR;
+ }
+
+ /*
+ * Set adapter SRB status to show that SRB is now free.
+ */
+
+ adapter->srb_status = SRB_FREE;
+
+ /*
+ * Inform user as to success of completed SRB.
+ * Disable and re-enable accessing IO locations around user call.
+ */
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_disable_io( adapter);
+#endif
+
+ user_completed_srb(adapter_handle, user_success_code);
+
+#ifndef FTK_NO_IO_ENABLE
+ macro_enable_io( adapter);
+#endif
+
+ /*
+ * Before finishing, restore saved value of EAGLE SIFADR register.
+ * Do this so interrupt does not effect SIFADR value.
+ */
+
+ sys_outsw(adapter_handle, adapter->sif_adr, saved_sifadr_value);
+}
+
+
+/*---------------------------------------------------------------------------
+|
+| Function - get_open_and_ring_status
+|
+| Paramters - ptr -> Pointer to our ADAPTER structure.
+|
+| Purpose - Reads status information from DIO space. This
+| function is called via NdisSynchronizeWithInterrupt when
+| in PIO mode so that we don't get SIF register contention
+| on a multiprocessor.
+|
+| Returns - Nothing.
+|
+|--------------------------------------------------------------------------*/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(get_open_and_ring_status)
+#endif
+
+local WBOOLEAN
+get_open_and_ring_status(
+ void * ptr
+ )
+{
+ ADAPTER * adapter = (ADAPTER *) ptr;
+ ADAPTER_HANDLE adapter_handle = adapter->adapter_handle;
+ WORD saved_sifadr;
+
+ /*
+ * Get adapter open status from the STB in DIO space.
+ */
+
+ saved_sifadr = sys_insw(adapter_handle, adapter->sif_adr);
+
+ sys_outsw(
+ adapter_handle,
+ adapter->sif_adr,
+ (WORD) (card_t) &adapter->stb_dio_addr->adapter_open
+ );
+
+ adapter->status_info->adapter_open =
+ sys_insw(adapter_handle, adapter->sif_dat);
+
+ /*
+ * Get ring status from the STB in DIO space.
+ */
+
+ sys_outsw(
+ adapter_handle,
+ adapter->sif_adr,
+ (WORD) (card_t) &adapter->stb_dio_addr->ring_status
+ );
+
+ adapter->status_info->ring_status =
+ sys_insw(adapter_handle, adapter->sif_dat);
+
+ sys_outsw(
+ adapter_handle,
+ adapter->sif_adr, saved_sifadr
+ );
+
+ return FALSE;
+}
+
+
+
+/*---------------------------------------------------------------------------
+|
+| Function - issue_srb
+|
+| Paramters - ptr -> Pointer to our ADAPTER structure.
+|
+| Purpose - Copy an SRB to the adapter. This
+| function is called via NdisSynchronizeWithInterrupt when
+| in PIO mode so that we don't get SIF register contention
+| on a multiprocessor.
+|
+| Returns - Nothing.
+|
+|--------------------------------------------------------------------------*/
+
+#ifdef FTK_RES_FUNCTION
+#pragma FTK_RES_FUNCTION(issue_srb)
+#endif
+
+local WBOOLEAN
+issue_srb(
+ void * ptr
+ )
+{
+ ADAPTER * adapter = (ADAPTER *) ptr;
+ ADAPTER_HANDLE hnd = adapter->adapter_handle;
+ SRB_GENERAL * srb_gen = &adapter->srb_general;
+ WORD sifint_value;
+
+ /*
+ * Copy the SRB into DIO space at Fastmac specified location.
+ * only copy the required amount for the specific type of SRB.
+ */
+
+ sys_outsw(
+ hnd,
+ adapter->sif_adr,
+ (WORD) (card_t) adapter->srb_dio_addr
+ );
+
+ sys_rep_outsw(
+ hnd,
+ adapter->sif_datinc,
+ (BYTE *) srb_gen,
+ (WORD) (adapter->size_of_srb / 2)
+ );
+
+ if (adapter->size_of_srb & 1)
+ {
+ sys_outsb(
+ hnd,
+ adapter->sif_datinc,
+ *(((BYTE * ) srb_gen) + adapter->size_of_srb - 1)
+ );
+ }
+
+ /*
+ * Set up SIFCMD value for SRB command interrupt.
+ */
+
+ sifint_value = DRIVER_SIFINT_SRB_COMMAND;
+
+ /*
+ * Set interrupt adapter bit in SIFCMD.
+ */
+
+ sifint_value = (sifint_value | DRIVER_SIFINT_IRQ_FASTMAC);
+
+ /*
+ * Mask SIFSTS so not clear interrupt if outstanding Fastmac interrupt.
+ */
+
+ sifint_value = (sifint_value | DRIVER_SIFINT_FASTMAC_IRQ_MASK);
+
+ /*
+ * Interrupt Fastmac.
+ */
+
+ sys_outsw(hnd, adapter->sif_int, sifint_value);
+
+ return FALSE;
+}
+
+/**** End of DRV_SRB.C file ************************************************/