void USBDevice::FreeDevice() { // Close the device handle // if handle is invalid (NULL), has no effect UsbK_Free(m_usbDeviceHandle); }
DWORD __cdecl main(int argc, char* argv[]) { KLST_HANDLE deviceList = NULL; KLST_DEVINFO_HANDLE deviceInfo = NULL; KUSB_HANDLE usbHandle = NULL; DWORD errorCode = ERROR_SUCCESS; BM_TEST_TYPE testType; UCHAR interfaceIndex; BOOL success; memset(&gXfers, 0, sizeof(gXfers)); #ifdef ISO_LOG_FILENAME // Create a new log file. gOutFile = fopen("xfer-iso-read.txt", "w"); #else gOutFile = NULL; #endif /* Find the test device. Uses "vid=hhhh pid=hhhh" arguments supplied on the command line. (default is: vid=04D8 pid=FA2E) */ if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv)) return GetLastError(); /* Initialize the device. This creates the physical usb handle. */ if (!UsbK_Init(&usbHandle, deviceInfo)) { errorCode = GetLastError(); printf("UsbK_Init failed. ErrorCode: %08Xh\n", errorCode); goto Done; } printf("Device opened successfully!\n"); /* Select interface by pipe id and get descriptors. */ interfaceIndex = (UCHAR) - 1; while(UsbK_SelectInterface(usbHandle, ++interfaceIndex, TRUE)) { memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor)); memset(&gPipeInfo, 0, sizeof(gPipeInfo)); gAltsettingNumber = (UCHAR) - 1; while(UsbK_QueryInterfaceSettings(usbHandle, ++gAltsettingNumber, &gInterfaceDescriptor)) { UCHAR pipeIndex = (UCHAR) - 1; if (EP_ALTF == -1 || gInterfaceDescriptor.bAlternateSetting == EP_ALTF) { while(UsbK_QueryPipe(usbHandle, gAltsettingNumber, ++pipeIndex, &gPipeInfo)) { if (gPipeInfo.PipeType == UsbdPipeTypeIsochronous && gPipeInfo.MaximumPacketSize && (gPipeInfo.PipeId & 0x80)) { if (EP_READ== -1 || EP_READ == gPipeInfo.PipeId) break; } memset(&gPipeInfo, 0, sizeof(gPipeInfo)); } } if (gPipeInfo.PipeId) break; memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor)); } } if (!gPipeInfo.PipeId) { printf("Pipe not found.\n"); goto Done; } /* Set the desired alternate setting. */ success = UsbK_SetAltInterface( usbHandle, gInterfaceDescriptor.bInterfaceNumber, FALSE, gInterfaceDescriptor.bAlternateSetting); if (!success) { printf("UsbK_SetAltInterface failed.\n"); goto Done; } // Configure the benchmark test device to send data. testType = USB_ENDPOINT_DIRECTION_IN(gPipeInfo.PipeId) ? BM_TEST_TYPE_READ : BM_TEST_TYPE_WRITE; success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, NULL, &testType); if (!success) { errorCode = GetLastError(); printf("Bench_Configure failed. ErrorCode: %08Xh\n", errorCode); goto Done; } printf("Device hardware fully prepared..\n"); /* Allocate the iso buffer resources. */ do { int pos; gXfers.DataBufferSize = ISO_PACKETS_PER_TRANSFER * gPipeInfo.MaximumPacketSize; success = OvlK_Init(&gXfers.OvlPool, usbHandle, MAX_OUTSTANDING_TRANSFERS, KOVL_POOL_FLAG_NONE); for (pos = 0; pos < MAX_OUTSTANDING_TRANSFERS; pos++) { PMY_ISO_BUFFER_EL bufferEL = malloc(sizeof(MY_ISO_BUFFER_EL)); memset(bufferEL, 0, sizeof(*bufferEL)); bufferEL->DataBuffer = malloc(gXfers.DataBufferSize); IsoK_Init(&bufferEL->IsoContext, ISO_PACKETS_PER_TRANSFER, 0); IsoK_SetPackets(bufferEL->IsoContext, gPipeInfo.MaximumPacketSize); //bufferEL->IsoContext->Flags = KISO_FLAG_SET_START_FRAME; bufferEL->IsoPackets = bufferEL->IsoContext->IsoPackets; OvlK_Acquire(&bufferEL->OvlHandle, gXfers.OvlPool); DL_APPEND(gXfers.BufferList, bufferEL); DL_APPEND(gXfers.Completed, bufferEL); } } while(0); /* Reset the pipe. */ UsbK_ResetPipe(usbHandle, (UCHAR)gPipeInfo.PipeId); /* Set a start frame (not used) see KISO_FLAG_SET_START_FRAME. */ UsbK_GetCurrentFrameNumber(usbHandle, &gXfers.FrameNumber); gXfers.FrameNumber += ISO_PACKETS_PER_TRANSFER * 2; gXfers.FrameNumber -= gXfers.FrameNumber % ISO_PACKETS_PER_TRANSFER; mDcs_Init(&Dcs); /* Start reading until an error occurs or MAX_TRANSFERS_TOTAL is reached. */ do { PMY_ISO_BUFFER_EL nextXfer; ULONG transferred; while(errorCode == ERROR_SUCCESS && gXfers.Completed && gXfers.SubmittedCount < MAX_TRANSFERS_TOTAL) { nextXfer = gXfers.Completed; DL_DELETE(gXfers.Completed, nextXfer); DL_APPEND(gXfers.Outstanding, nextXfer); OvlK_ReUse(nextXfer->OvlHandle); SetNextFrameNumber(&gXfers, nextXfer); success = UsbK_IsoReadPipe( usbHandle, gPipeInfo.PipeId, nextXfer->DataBuffer, gXfers.DataBufferSize, nextXfer->OvlHandle, nextXfer->IsoContext); errorCode = GetLastError(); if (errorCode != ERROR_IO_PENDING) { printf("UsbK_IsoReadPipe failed. ErrorCode: %08Xh\n", errorCode); goto Done; } gXfers.SubmittedCount++; errorCode = ERROR_SUCCESS; } nextXfer = gXfers.Outstanding; if (!nextXfer) { printf("Done!\n"); goto Done; } success = OvlK_Wait(nextXfer->OvlHandle, 1000, KOVL_WAIT_FLAG_NONE, &transferred); if (!success) { errorCode = GetLastError(); printf("OvlK_Wait failed. ErrorCode: %08Xh\n", errorCode); goto Done; } DL_DELETE(gXfers.Outstanding, nextXfer); DL_APPEND(gXfers.Completed, nextXfer); IsoXferComplete(&gXfers, nextXfer, transferred); } while(errorCode == ERROR_SUCCESS); Done: /* Cancel all transfers left outstanding. */ while(gXfers.Outstanding) { PMY_ISO_BUFFER_EL nextBufferEL = gXfers.Outstanding; ULONG transferred; OvlK_WaitOrCancel(nextBufferEL->OvlHandle, 0, &transferred); DL_DELETE(gXfers.Outstanding, nextBufferEL); } /* Free the iso buffer resources. */ while(gXfers.BufferList) { PMY_ISO_BUFFER_EL nextBufferEL = gXfers.BufferList; DL_DELETE(gXfers.BufferList, nextBufferEL); OvlK_Release(nextBufferEL->OvlHandle); IsoK_Free(nextBufferEL->IsoContext); free(nextBufferEL->DataBuffer); free(nextBufferEL); } // Free the overlapped pool. OvlK_Free(gXfers.OvlPool); // Close the device handle. UsbK_Free(usbHandle); // Free the device list. LstK_Free(deviceList); // Close the log file. if (gOutFile) { fflush(gOutFile); fclose(gOutFile); gOutFile = NULL; } return errorCode; }
bool USBDevice::InitDevice() { BYTE configDescriptorBuffer[4096]; ULONG lengthTransferred; m_deviceMutex = CreateMutex(NULL, FALSE, "Global\\ASIOUAC2"); if(GetLastError() == ERROR_ALREADY_EXISTS) { #ifdef _DEBUG debugPrintf("ASIOUAC: Can't start device! Device already used!\n"); #endif if(m_deviceMutex) { CloseHandle(m_deviceMutex); m_deviceMutex = NULL; m_errorCode = ERROR_BUSY; } return FALSE; } FreeDevice(); InitDescriptors(); m_usbDeviceHandle = FindDevice(); if(m_usbDeviceHandle == NULL) return FALSE; lengthTransferred = sizeof(configDescriptorBuffer); if(!UsbK_QueryDeviceInformation( m_usbDeviceHandle, DEVICE_SPEED, &lengthTransferred, configDescriptorBuffer)) { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: UsbK_QueryDeviceInformation failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } m_deviceSpeed = (int)configDescriptorBuffer[0]; #ifdef _DEBUG if(m_deviceSpeed == HighSpeed) debugPrintf("ASIOUAC: Device speed: high\n"); else debugPrintf("ASIOUAC: Device speed: low/full\n"); #endif if(!UsbK_GetDescriptor(m_usbDeviceHandle, USB_DESCRIPTOR_TYPE_DEVICE, 0, 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: Get device descriptor failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } memcpy(&m_deviceDescriptor, configDescriptorBuffer, sizeof(USB_DEVICE_DESCRIPTOR)); if(SendUsbControl(BMREQUEST_DIR_DEVICE_TO_HOST, BMREQUEST_TYPE_STANDARD, BMREQUEST_RECIPIENT_DEVICE, USB_REQUEST_GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8), 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) { ParseDescriptors(configDescriptorBuffer, lengthTransferred); return m_usbDeviceHandle != NULL; } else { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: Get config descriptor failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } }