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.
181 lines
5.4 KiB
181 lines
5.4 KiB
/*++
|
|
|
|
Copyright (c) 1987-93 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
fdr.c
|
|
|
|
Abstract:
|
|
|
|
Contains RpldFileDataResponse() entry point.
|
|
|
|
Author:
|
|
|
|
Vladimir Z. Vulovic (vladimv) 03 - February - 1993
|
|
|
|
Revision History:
|
|
|
|
03-Feb-1993 vladimv
|
|
Ported to NT
|
|
|
|
--*/
|
|
|
|
#include "local.h"
|
|
|
|
BOOL RplDlcFdr(
|
|
POPEN_INFO pOpenInfo,
|
|
PRCB pRcb,
|
|
PBYTE data_ptr,
|
|
WORD length,
|
|
DWORD locate_addr,
|
|
DWORD start_addr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
This function sends FILE.DATA.RESPONSE frames to the workstation.
|
|
|
|
Arguments:
|
|
pOpenInfo pointer to the OPEN_INFO structure
|
|
pRcb pointer to the RESOURCE CONTROL BLOCK structure
|
|
data_ptr pointer to the data to be send
|
|
length length of the data
|
|
xfer_addr addr to place data on workstation
|
|
start_addr addr to start execution at
|
|
|
|
Return Value:
|
|
ERROR_SUCCESS if success, else failure.
|
|
|
|
--*/
|
|
{
|
|
DWORD status;
|
|
PFDR pFrame;
|
|
PLLC_CCB pBadCcb;
|
|
PLAN_RESOURCE pLanResource;
|
|
PADAPTER_INFO pAdapterInfo;
|
|
|
|
pAdapterInfo = (PADAPTER_INFO)pOpenInfo->adapt_info_ptr;
|
|
pLanResource = (PLAN_RESOURCE)pRcb->lan_rcb_ptr;
|
|
|
|
pFrame = (PFDR)pLanResource->frame;
|
|
|
|
pLanResource->xmit_error_cnt = 0; // Zero consecutive xmit error counter
|
|
pLanResource->retry_count = 0; // allow retries
|
|
|
|
transmit_retry:
|
|
(void)memset( (LPVOID)&pLanResource->ccb, '\0', sizeof( pLanResource->ccb));
|
|
|
|
pLanResource->TransmitParms.cbBuffer2 = length;
|
|
pLanResource->TransmitParms.pBuffer2 = data_ptr;
|
|
|
|
// len = 0x1d + len data bit
|
|
pFrame->program_length = HILO(length + (sizeof (*pFrame)));
|
|
|
|
pFrame->data_hdr = HILO(length + 4); // set len part of data hdr
|
|
// #define RPL_ELNK
|
|
#ifdef RPL_ELNK
|
|
if ( length < 0x544) {
|
|
pFrame->data_hdr |= 0xFFFF0000;
|
|
}
|
|
#endif
|
|
pFrame->seq_num = HILO2(pRcb->fdr_seq_number);
|
|
pFrame->flags = *((PBYTE)&pRcb->send_flags);
|
|
pFrame->locate_addr = HILO2(locate_addr);
|
|
pFrame->xfer_addr = HILO2(start_addr);
|
|
|
|
|
|
if ( !ResetEvent( pRcb->txsemhdl)) {
|
|
status = GetLastError();
|
|
RplDump( ++RG_Assert,( "status=%d", status));
|
|
RplDlcReportEvent( status, SEM_SET);
|
|
return( FALSE);
|
|
}
|
|
|
|
pLanResource->ccb.hCompletionEvent = pRcb->txsemhdl;
|
|
pLanResource->ccb.uchAdapterNumber = pAdapterInfo->adapter_number;
|
|
pLanResource->ccb.uchDlcCommand = LLC_TRANSMIT_UI_FRAME;
|
|
pLanResource->ccb.u.pParameterTable = (PLLC_PARMS)&pLanResource->TransmitParms;
|
|
|
|
if ( !ResetEvent( pRcb->SF_wakeup)) {
|
|
status = GetLastError();
|
|
RplDump( ++RG_Assert,( "status=%d", status));
|
|
RplDlcReportEvent( status, SEM_SET);
|
|
pRcb->RcbIsBad = TRUE;
|
|
return( FALSE);
|
|
}
|
|
|
|
status = AcsLan( &pLanResource->ccb, &pBadCcb);
|
|
if ( pAdapterInfo->Closing == TRUE) {
|
|
(VOID)SetEvent( pRcb->txsemhdl);
|
|
return( FALSE);
|
|
}
|
|
|
|
if ( status != ACSLAN_STATUS_COMMAND_ACCEPTED) {
|
|
RplDump( ++RG_Assert,( "pCcb=0x%x pBadCcb=0x%x status=%d",
|
|
&pLanResource->ccb, pBadCcb, status));
|
|
RplDlcReportEvent( status, LLC_TRANSMIT_UI_FRAME);
|
|
(VOID)SetEvent( pRcb->txsemhdl);
|
|
return( FALSE);
|
|
}
|
|
|
|
status = WaitForSingleObject( pRcb->txsemhdl, INFINITE);
|
|
if ( pAdapterInfo->Closing == TRUE) {
|
|
return( FALSE);
|
|
}
|
|
|
|
if ((status != WAIT_OBJECT_0) || (pLanResource->ccb.uchDlcStatus)) {
|
|
if ( status != WAIT_OBJECT_0) {
|
|
if ( status == WAIT_FAILED) {
|
|
status = GetLastError();
|
|
}
|
|
RplDlcReportEvent( status, SEM_WAIT);
|
|
}
|
|
if ( pLanResource->retry_count++ < MAXRETRY) {
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_MISC,(
|
|
"FDR(%ws): retry_count=%d, status=%d, DlcStatus=0x%x",
|
|
pRcb->AdapterName, pLanResource->retry_count, status,
|
|
pLanResource->ccb.uchDlcStatus));
|
|
Sleep( 100L * pLanResource->retry_count); // for NETWORK to recover
|
|
goto transmit_retry;
|
|
}
|
|
RplDump( ++RG_Assert,(
|
|
"pCcb=0x%x pBadCcb=0x%x AdapterName=%ws status=%d DlcStatus=0x%x",
|
|
&pLanResource->ccb, pBadCcb, pRcb->AdapterName, status, pLanResource->ccb.uchDlcStatus));
|
|
|
|
pLanResource->retry_count = 0; // no more attempts, reset retry count
|
|
|
|
if ( status != ERROR_SUCCESS) {
|
|
RplDlcReportEvent( status, SEM_WAIT);
|
|
(void)SetEvent( pRcb->txsemhdl);
|
|
return( FALSE);
|
|
|
|
}
|
|
|
|
if ( pLanResource->ccb.uchDlcStatus == LLC_STATUS_TRANSMIT_ERROR_FS
|
|
||
|
|
pLanResource->ccb.uchDlcStatus == LLC_STATUS_TRANSMIT_ERROR) {
|
|
//
|
|
// Workstation is not receiving anymore. ?? Rebooted
|
|
// during boot, power failure or etc. OR real transmit
|
|
// failure ??
|
|
|
|
if ( pLanResource->xmit_error_cnt++ <= MAX_CONSECUTIVE_ERROR) {
|
|
return( FALSE);
|
|
}
|
|
|
|
//
|
|
// Too many consecutive transmit errors. Tell that there is a
|
|
// problem with transmitting.
|
|
//
|
|
|
|
RplDlcReportEvent( pLanResource->ccb.uchDlcStatus, LLC_TRANSMIT_UI_FRAME);
|
|
return( FALSE);
|
|
}
|
|
|
|
RplDlcReportEvent( pLanResource->ccb.uchDlcStatus, LLC_TRANSMIT_UI_FRAME);
|
|
return( FALSE);
|
|
}
|
|
|
|
return( TRUE);
|
|
}
|