📄 ezusbdevice.cpp
字号:
//
// This routine will set or clear the 8051 reset bit on the EZUSB chip.
// It issues the vendor command EZUSB_LOAD_INTERNAL. byResetBit = 1 will
// set the bit which will hold the 8051 in reset. byResetBit = 0 will
// clear the bit which will start the 8051 running again.
//
NTSTATUS EzUsbDevice::Reset8051(UCHAR byResetBit)
{
t << "Entering Reset8051\n";
NTSTATUS status = STATUS_SUCCESS;
PURB pUrb = m_Lower.BuildVendorRequest(
&byResetBit,
1,
0,
EZUSB_LOAD_INTERNAL,
EZUSB_CPU_CONTROL_STATUS_REG,
FALSE, //default
FALSE, //default
NULL, //default
0, //default
URB_FUNCTION_VENDOR_DEVICE //default
);
if( NULL == pUrb )
{
return STATUS_NO_MEMORY;
}
status = m_Lower.SubmitUrb(pUrb);
delete pUrb;
return status;
}
//=============================================================================
// EzUsbDevice::DownloadRAM
//
// This routine will download firmware to internal or external RAM of the
// EZUSB. It uses vendor commands EZUSB_LOAD_EXTERNAL or
// EZUSB_LOAD_INTERNAL.
//
NTSTATUS EzUsbDevice::DownloadRAM(PINTEL_HEX_RECORD pHexRecord, bool fExternal)
{
t << "Entering DownloadRAM\n";
NTSTATUS status = STATUS_SUCCESS;
URB Urb;
while( 0 == pHexRecord->Type )
{
if( fExternal ?
(! EZUSB_INTERNAL_RAM( pHexRecord->Address )) :
(EZUSB_INTERNAL_RAM( pHexRecord->Address ))
)
{
m_Lower.BuildVendorRequest(
pHexRecord->Data,
pHexRecord->Length,
0,
static_cast<UCHAR>(
fExternal ? EZUSB_LOAD_EXTERNAL : EZUSB_LOAD_INTERNAL),
pHexRecord->Address,
FALSE, //default
FALSE, //default
NULL, //default
0, //default
URB_FUNCTION_VENDOR_DEVICE, //default
&Urb
);
status = m_Lower.SubmitUrb(&Urb);
if( !NT_SUCCESS(status) )
{
break;
}
}
pHexRecord++;
}
return status;
}
//=============================================================================
// EzUsbDevice::DownloadIntelHex
//
// This routine will download firmware to the EZUSB.
//
NTSTATUS EzUsbDevice::DownloadIntelHex(PINTEL_HEX_RECORD pHexRecord)
{
t << "Entering DownloadIntelHex\n";
NTSTATUS status = STATUS_SUCCESS;
// Download external RAM
status = DownloadRAM(pHexRecord, true);
if( !NT_SUCCESS(status) )
return status;
Reset8051(1);
// Download internal RAM
status = DownloadRAM(pHexRecord, false);
return status;
}
//=============================================================================
// EzUsbDevice::AnchorDownload
//
// This routine will download firmware to the EZUSB. The download is
// accomplished by issuing an _URB_CONTROL_VENDOR_OR_CLASS_REQUEST with
// vendor specific command EZUSB_LOAD_INTERNAL. The buffer of firmware
// to download (pDownloadBuffer) will be split into nTransferLength
// requests of size nDownloadSize.
//
NTSTATUS EzUsbDevice::AnchorDownload(
USHORT wOffset,
PUCHAR pDownloadBuffer,
ULONG nDownloadSize,
ULONG nTransferLength,
ULONG nTransferCount
)
{
t << "Entering AnchorDownload\n";
NTSTATUS status = STATUS_SUCCESS;
URB u;
RtlZeroMemory(&u, sizeof(URB));
for (ULONG i = 0; i < nTransferCount; i++)
{
//Initialize the URB
m_Lower.BuildVendorRequest(
pDownloadBuffer,
( (i == (nTransferCount - 1)) &&
(nDownloadSize % nTransferLength) ) ?
(nDownloadSize % nTransferLength) :
nTransferLength,
0,
static_cast<UCHAR>( EZUSB_LOAD_INTERNAL ),
static_cast<USHORT>( (i * nTransferLength) + wOffset ),
FALSE, //default
FALSE, //default
NULL, //default
0, //default
URB_FUNCTION_VENDOR_DEVICE, //default
&u
);
status = m_Lower.SubmitUrb(&u);
if( !NT_SUCCESS(status) )
{
break;
}
pDownloadBuffer += nTransferLength;
}
return status;
}
//=============================================================================
// EzUsbDevice::InternalDeviceControl - Handler for IRP_MJ_INTERNAL_DEVICE_CONTROL
//
// This handler is implemented in case there is an upper filter driver
// which submits URBs to USBD for this USB device.
//
NTSTATUS EzUsbDevice::InternalDeviceControl(KIrp I)
{
t << "Entering InternalDeviceControl\n";
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
//=============================================================================
// EzUsbDevice::OnStopDevice - Handler for IRP_MJ_PNP / IRP_MN_STOP_DEVICE
//
// The system calls this when the device is stopped. The driver should
// unconfigure the USB device.
//
NTSTATUS EzUsbDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering OnStopDevice\n";
m_IntXfer.StopPolling();
m_Lower.DeActivateConfiguration();
return status;
UNREFERENCED_PARAMETER(I);
}
//=============================================================================
// EzUsbDevice::OnRemoveDevice - Handler for IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE
//
// The system calls this when the device is removed.
//
NTSTATUS EzUsbDevice::OnRemoveDevice(KIrp I)
{
t << "Entering OnRemoveDevice\n";
m_IntXfer.StopPolling();
return STATUS_SUCCESS;
UNREFERENCED_PARAMETER(I);
}
//=============================================================================
// EzUsbDevice::Create - Handler for IRP_MJ_CREATE
//
NTSTATUS EzUsbDevice::Create(KIrp I)
{
t << "Entering Create\n";
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
//=============================================================================
// EzUsbDevice::Close - Handler for IRP_MJ_CLOSE
//
NTSTATUS EzUsbDevice::Close(KIrp I)
{
t << "Entering Close\n";
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
//=============================================================================
// EzUsbDevice::DeviceControl - Handler for IRP_MJ_DEVICE_CONTROL
//
// The system calls this when an application issues DeviceIoControl
//
NTSTATUS EzUsbDevice::DeviceControl(KIrp I)
{
t << "Entering DeviceControl\n";
NTSTATUS status = STATUS_SUCCESS;
PVOID pBuffer = I.IoctlBuffer();
ULONG dwInputBufferSize = I.IoctlInputBufferSize();
ULONG dwOutputBufferSize = I.IoctlOutputBufferSize();
I.Information() = 0;
I.Status() = STATUS_SUCCESS;
switch( I.IoctlCode() )
{
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_PIPE_INFO:
t << "IOCTL_EZUSB_GET_PIPE_INFO \n";
if( m_UsbInterface.m_Information )
{
//Copy the USBD_INTERFACE_INFORMATION structure stored in the KUsbInterface object
//to the user's buffer
RtlCopyMemory(
reinterpret_cast<PUCHAR>( pBuffer ),
reinterpret_cast<PUCHAR>( m_UsbInterface.m_Information ),
m_UsbInterface.m_Information->Length
);
I.Information() = m_UsbInterface.m_Information->Length;
status = STATUS_SUCCESS;
}
else
{
status = STATUS_UNSUCCESSFUL;
}
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_DEVICE_DESCRIPTOR:
{
t << "IOCTL_EZUSB_GET_DEVICE_DESCRIPTOR \n";
status = m_Lower.GetDeviceDescriptor( PUSB_DEVICE_DESCRIPTOR(pBuffer) );
if( NT_SUCCESS(status) )
{
I.Information() = PUSB_DEVICE_DESCRIPTOR(pBuffer)->bLength;
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_CONFIG_DESCRIPTOR:
{
t << "IOCTL_EZUSB_GET_CONFIG_DESCRIPTOR \n";
// The KUsbLowerDevice object contains a pointer to the configuration descriptor.
// We simply copy the requested number of bytes from it to the IRP buffer.
RtlCopyMemory(pBuffer, m_Lower.m_Config, dwOutputBufferSize);
I.Information() = dwOutputBufferSize;
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_VENDOR_REQUEST:
t << "IOCTL_EZUSB_VENDOR_REQUEST \n";
VendorRequest(
reinterpret_cast<PVENDOR_REQUEST_IN>(pBuffer),
I.Information()
);
status = STATUS_SUCCESS; // This prevents error messages in EzMr when downloading firmware
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_ANCHOR_DOWNLOAD2:
t << "IOCTL_EZUSB_ANCHOR_DOWNLOAD2 \n";
status = AnchorDownload(
0,
reinterpret_cast<PUCHAR>(pBuffer),
dwInputBufferSize,
EZUSB_ANCHOR_DOWNLOAD2_SEGMENT_SIZE,
dwInputBufferSize / EZUSB_ANCHOR_DOWNLOAD2_SEGMENT_SIZE
);
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_RESET:
{
t << "IOCTL_EZUSB_RESET \n";
ULONG_PTR nInfo = NULL;
status = m_Lower.DeviceIoControl(
IOCTL_INTERNAL_USB_RESET_PORT,
NULL,
0,
NULL,
0,
TRUE,
&nInfo
);
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_RESETPIPE:
{
t << "IOCTL_EZUSB_RESETPIPE \n";
ULONG dwPipeNum = *( reinterpret_cast<PULONG>(pBuffer) );
KUsbPipe* pipe = FindPipe(dwPipeNum);
if(NULL == pipe)
{
status = STATUS_INVALID_PARAMETER;
}
else
{
status = pipe->Reset();
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_ABORTPIPE:
{
t << "IOCTL_EZUSB_ABORTPIPE \n";
ULONG dwPipeNum = *( reinterpret_cast<PULONG>(pBuffer) );
KUsbPipe* pipe = FindPipe(dwPipeNum);
if(NULL == pipe)
{
status = STATUS_INVALID_PARAMETER;
}
else
{
status = pipe->Abort();
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_SETINTERFACE:
{
t << "IOCTL_EZUSB_SETINTERFACE \n";
PSET_INTERFACE_IN p = reinterpret_cast<PSET_INTERFACE_IN>(pBuffer);
SA_STATUS saStatus = m_UsbInterface.SelectAlternate(p->alternateSetting);
if( SA_SUCCESS != saStatus )
{
t << "Error SelectAlternate returns " << static_cast<ULONG>(saStatus) << "\n";
status = STATUS_UNSUCCESSFUL;
}
else
{
status = STATUS_SUCCESS;
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_STRING_DESCRIPTOR:
t << "IOCTL_EZUSB_GET_STRING_DESCRIPTOR \n";
if( (dwInputBufferSize >= sizeof(GET_STRING_DESCRIPTOR_IN)) &&
(dwOutputBufferSize > 0)
)
{
PGET_STRING_DESCRIPTOR_IN p = reinterpret_cast<PGET_STRING_DESCRIPTOR_IN>(pBuffer);
URB u;
UsbBuildGetDescriptorRequest(
&u,
sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
USB_STRING_DESCRIPTOR_TYPE,
p->Index,
p->LanguageId,
p,
PMDL(0),
dwOutputBufferSize,
NULL
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -