mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1849 lines
51 KiB
1849 lines
51 KiB
/****************************************************************************
|
|
*
|
|
* 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 ************************************************/
|