📄 usbnicadap.cpp
字号:
// Allocate and initialize the context block:
IRP_CONTEXT* Context = new (&m_ContextHeap) IRP_CONTEXT (this, NULL);
// Validate the new context
if(Context == NULL)
{
// Return failure so that send can queue the packet
return NDIS_STATUS_RESOURCES;
}
// Pass the URB to the bus driver at DISPATCH level
PURB pUrb = m_BusDevice.BuildVendorRequest(
NULL,
0,
0,
USBNIC_COMMAND_SET_PACKET_FILTER,
receive_filters,
USBD_TRANSFER_DIRECTION_OUT,
FALSE,
NULL,
0,
URB_FUNCTION_VENDOR_DEVICE,
NULL
);
// Validate the URB
if (pUrb==NULL)
{
delete Context;
return NDIS_STATUS_RESOURCES;
}
// Store the URB and allocate a Control Irp from the pool
Context->m_pUrb = pUrb;
KIrp I=m_CntrlIrpPool.Allocate();
// Validate the Irp
if (I.IsNull())
{
delete pUrb;
delete Context;
return NDIS_STATUS_RESOURCES;
}
// NOTES:To be fixed
// Store the adapter "this" pointer in the m_pClass param
// of the Context for the DriverWorks MEMBER_COMPLETEIRPWITHCONTEXT
// macro to work
Context->m_pClass = this;
// send the URB to the device
status = m_BusDevice.SubmitUrb(
I,
pUrb,
LinkTo(CompletionCntrlRoutine),
(void*)Context,
100
);
if(status == STATUS_PENDING)
status = STATUS_SUCCESS;
}
return status;
}
////////////////////////////////////////////////////////////////////
// USBNICAdapter::ActivateDevice()
//
// This routine is used to select the proper configuration of
// the USB device
//
// Parameters: None
//
// IRQL:
// PASSIVE_LEVEL
//
// Return Mode:
// SYNCHRONOUS
//
AC_STATUS USBNICAdapter::ActivateDevice()
{
AC_STATUS acStatus;
acStatus = m_BusDevice.ActivateConfiguration(1); // Configuration value 1
switch (acStatus)
{
case AC_SUCCESS:
TRACE("USB Configuration OK\n");
//GetStringDescriptors();
break;
case AC_COULD_NOT_LOCATE_INTERFACE:
TRACE("Could not locate the interface in the config descriptor\n");
//Check that the Interface Number and Alternate Setting
//for the KUsbInterface object initialized in the constructor match
//an interface descriptor reported by the hardware.
break;
case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
TRACE("Could not get configuration descriptor\n");
break;
case AC_CONFIGURATION_REQUEST_FAILED:
TRACE("Board did not accept configuration URB\n");
break;
case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
TRACE("Failed to initialize interface object\n");
break;
case AC_FAILED_TO_LOCATE_ENDPOINT_ADDRESS:
TRACE("Failed to locate endpoint address for pipe\n");
break;
case AC_FAILED_TO_OPEN_PIPE_OBJECT:
//NOTE: this may or may not be fatal. It could mean that
//the device has an endpoint for which a KUsbPipe object has
//not been instanced. If the intention is to not use this pipe,
//then it's ok. Otherwise, there is a failure. Clients can
//iterate through the pipe array in KUsbLowerDevice to check
//which pipes are open/closed.
TRACE("Failed to open pipe object \n");
break;
default:
TRACE("Unexpected error activating USB configuration\n");
// Possibly the device is disconnected
break;
}
return acStatus;
}
////////////////////////////////////////////////////////////////////
// USBNICAdapter::ConfigureAndProbeDevice()
//
// This is the main routine used to configure the USB NIC device.
// It downloads the firmware and configures the cards settings.
//
// Parameters: None
// IRQL:
// PASSIVE_LEVEL
//
// Return Mode:
// SYNCHRONOUS
//
NTSTATUS USBNICAdapter::ConfigureAndProbeDevice()
{
NTSTATUS status = STATUS_SUCCESS;
AC_STATUS acStatus;
status = DownLoadFirmware(new_code, new_code_size,0,0);
if (status!=NDIS_STATUS_SUCCESS)
return status;
TriggerFirmware();
if (status!=NDIS_STATUS_SUCCESS)
return status;
SetURBSize(BUF_SIZE);
if (status!=NDIS_STATUS_SUCCESS)
return status;
SetSOFSWait(SOFS_TO_WAIT);
if (status!=NDIS_STATUS_SUCCESS)
return status;
acStatus = ActivateDevice();
if (acStatus != AC_SUCCESS)
return STATUS_UNSUCCESSFUL;
NdisStallExecution(100000);
status = ReadConfiguration(&EthConfig);
if (status!=NDIS_STATUS_SUCCESS)
return status;
// Cache the MAC address
memcpy(&m_CurrentAddress.m_bytes[0], &EthConfig.MAC_Address.EthNodeAddress[0], 6);
memcpy(&m_PermanentAddress.m_bytes[0], &EthConfig.MAC_Address.EthNodeAddress[0], 6);
NdisStallExecution(100000);
m_uPacketFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST |
NDIS_PACKET_TYPE_BROADCAST;
SetReceiveFilter(m_uPacketFilter);
return status;
}
////////////////////////////////////////////////////////////////////
// USBNICAdapter::ControlCommand()
//
// This routine is used to submit all the SYNCHRONOUS URBS to the
// device.
//
// Parameters:
// Request - Device specific command request code
// Direction - IN/OUT
// Value - USB URB Value
// Index - USB URB Index
// Data - pointer to data that will be submitted
// Size - size of buffer pointed to by Data
// Timeout - unused
//
// IRQL:
// PASSIVE_LEVEL
// Return Mode:
// SYNCHRONOUS
NTSTATUS USBNICAdapter::ControlCommand (
UCHAR Request,
UCHAR Direction,
USHORT Value,
USHORT Index,
PUCHAR Data,
short Size,
short Timeout )
{
NTSTATUS status = STATUS_SUCCESS;
PURB pUrb = m_BusDevice.BuildVendorRequest(
Data,
Size,
0,
Request,
Value,
Direction,
FALSE,
NULL,
Index,
URB_FUNCTION_VENDOR_DEVICE,
NULL
);
status = m_BusDevice.SubmitUrb(pUrb);
delete pUrb;
return status;
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorInitialize
//
// Parameters:
// pWdmDesc - The descriptor to initialize
// pPhysAddr - Physycal Address Pointer
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
// Called by KNdisSystemReceiveArea to initialize each descriptor.
// This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorInitialize(
PWDM_RFD pWdmDesc,
PNDIS_PHYSICAL_ADDRESS pPhysAddr
)
{
TRACE("USBNICAdapter::DescriptorInitialize\n");
// Get an available IRP from the Rx Irp pool
KIrp I = m_RxIrpPool.Allocate();
// Validate the Irp
if (I.IsNull())
{
TRACE("USBNICAdapter::DescriptorInitialize() Irp allocation error\n");
ASSERT(!"Irp allocation error\n");
return;
}
pWdmDesc->m_Irp = I;
pWdmDesc->m_pAdapter = this;
// Create an BULK URB
pWdmDesc->m_pUrb = m_ReceivePipe.BuildBulkTransfer(
pWdmDesc->m_RfdBuffer,
BUF_SIZE,
TRUE,
NULL,
TRUE
);
// Validate the URB
if (pWdmDesc->m_pUrb == NULL)
{
TRACE("USBNICAdapter::DescriptorInitialize() Urb creation error\n");
m_RxIrpPool.Free(pWdmDesc->m_Irp);
ASSERT(!"Urb creation error\n");
return;
}
pWdmDesc->m_RfdActualCount= 0;
pWdmDesc->m_RfdSize = BUF_SIZE;
// Pass down the URB to the bus driver
NTSTATUS status = m_ReceivePipe.SubmitUrb (
pWdmDesc->m_Irp,
pWdmDesc->m_pUrb,
WdmCompletionRxRoutine(this),
pWdmDesc
);
// update the Rx Irp count
++m_RxIrpsOutstanding;
TRACE("IRP RX Outstanding Count++= %08X\n",(ULONG)m_RxIrpsOutstanding);
// Add the IRP to the RxIrp list
m_RxIrpList.InsertTail(pWdmDesc);
DumpWdmRfd(pWdmDesc);
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorInvalidate
//
// Parameters:
// pWdmDesc - The descriptor to invalidate
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
// Called by KNdisSystemReceiveArea to undo any initializations done
// during the Initialize step. The look aside list is flushed.
// This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorInvalidate(
PWDM_RFD pWdmDesc
)
{
TRACE("USBNICAdapter::DescriptorInvalidate\n");
m_RxIrpPool.Free(pWdmDesc->m_Irp);
delete pWdmDesc->m_pUrb;
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorComplete
//
// Parameters:
// pWdmDesc - The descriptor to complete
// pPhysAddr - Physycal Address Pointer
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
//
VOID USBNICAdapter::DescriptorComplete(
PWDM_RFD pWdmDesc,
PNDIS_PHYSICAL_ADDRESS pPhysAddr
)
{
//TRACE("USBNICAdapter::DescriptorComplete\n");
DumpWdmRfd(pWdmDesc);
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::ReSubmitRfd
//
// This member is used to pass the IRP and URB pair back to the
// bus driver.
//
// Parameters:
// pWdmDesc - The descriptor to reclaim
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
// Resubmit the URB to the bus driver for reuse
//
void USBNICAdapter::ReSubmitRfd(PWDM_RFD pWdmDesc)
{
//TRACE("USBNICAdapter::ReSubmitRfd\n");
KIrp Irp(pWdmDesc->m_Irp);
ASSERT(!Irp.IsNull());
ASSERT(pWdmDesc->m_pUrb);
Irp.Reuse();
*((short *)pWdmDesc->m_RfdBuffer) = 0;
// Reuse the existing URB. Notice that the 6th parameter is
// the pointer to the URB that was reclaimed. This call reinitializes
// the URB for reuse.
m_ReceivePipe.BuildBulkTransfer(
pWdmDesc->m_RfdBuffer,
BUF_SIZE,
TRUE,
NULL,
TRUE,
pWdmDesc->m_pUrb
);
// Pass down the URB to the bus driver
m_ReceivePipe.SubmitUrb (
pWdmDesc->m_Irp,
pWdmDesc->m_pUrb,
WdmCompletionRxRoutine(this),
pWdmDesc
);
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorReclaim
//
// Once a descriptor is reclaimed, then we create a new IRP and URB
// and submit it to the bus driver.
//
// Parameters:
// pWdmDesc - The descriptor to reclaim
// pPhysAddr - Physycal Address Pointer
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
// The packet descriptor returns to the "free list" in the Rx area.
// This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorReclaim(
PWDM_RFD pWdmDesc,
PNDIS_PHYSICAL_ADDRESS pPhysAddr
)
{
//TRACE("USBNICAdapter::DescriptorReclaim\n");
ReSubmitRfd(pWdmDesc);
DumpWdmRfd(pWdmDesc);
}
///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DumpWdmRfd
//
// Parameters:
// pWdmDesc - The descriptor to display
// IRQL:
// <= DISPATCH_LEVEL
// Returns:
// NONE
// Comments:
// Display some descriptor data in the softice window.
//
VOID USBNICAdapter::DumpWdmRfd(PWDM_RFD p)
{
//TRACE("USBNICAdapter::DumpWdmRfd\n");
//TRACE(" RFD_STRUC* p =%lx\n", p);
}
NTSTATUS KNdisWrapper<USBNICAdapter>::WdmCompletionRxRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID context)
{
UNREFERENCED_PARAMETER(pDevObj);
USBNICAdapter::PWDM_RFD pWdmRfd = (USBNICAdapter::PWDM_RFD) context;
USBNICAdapter* a = pWdmRfd->m_pAdapter; // maps irp => owner
ASSERT(a); // assert context had been alloc correctly
return a->CompletionRxRoutine(pIrp, reinterpret_cast<USBNICAdapter::IRP_CONTEXT*>(context));
}
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -