diff --git a/reactos/drivers/usb/usbuhci/usb_device.cpp b/reactos/drivers/usb/usbuhci/usb_device.cpp index 8dadc52468f..91cd8063475 100644 --- a/reactos/drivers/usb/usbuhci/usb_device.cpp +++ b/reactos/drivers/usb/usbuhci/usb_device.cpp @@ -1053,36 +1053,36 @@ CUSBDevice::GetConfigurationDescriptorsLength() VOID CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) { - DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor); - DPRINT1("bLength %x\n", DeviceDescriptor->bLength); - DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType); - DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB); - DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass); - DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass); - DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol); - DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0); - DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor); - DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct); - DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice); - DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer); - DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct); - DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber); - DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations); + DPRINT("Dumping Device Descriptor %x\n", DeviceDescriptor); + DPRINT("bLength %x\n", DeviceDescriptor->bLength); + DPRINT("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType); + DPRINT("bcdUSB %x\n", DeviceDescriptor->bcdUSB); + DPRINT("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass); + DPRINT("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass); + DPRINT("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol); + DPRINT("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0); + DPRINT("idVendor %x\n", DeviceDescriptor->idVendor); + DPRINT("idProduct %x\n", DeviceDescriptor->idProduct); + DPRINT("bcdDevice %x\n", DeviceDescriptor->bcdDevice); + DPRINT("iManufacturer %x\n", DeviceDescriptor->iManufacturer); + DPRINT("iProduct %x\n", DeviceDescriptor->iProduct); + DPRINT("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber); + DPRINT("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations); } //---------------------------------------------------------------------------------------- VOID CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) { - DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor); - DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength); - DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); - DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); - DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); - DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); - DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); - DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); - DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower); + DPRINT("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor); + DPRINT("bLength %x\n", ConfigurationDescriptor->bLength); + DPRINT("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); + DPRINT("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); + DPRINT("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); + DPRINT("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); + DPRINT("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); + DPRINT("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); + DPRINT("MaxPower %x\n", ConfigurationDescriptor->MaxPower); } //---------------------------------------------------------------------------------------- NTSTATUS diff --git a/reactos/drivers/usb/usbuhci/usb_queue.cpp b/reactos/drivers/usb/usbuhci/usb_queue.cpp index c00fe1c0570..2dc4cb902aa 100644 --- a/reactos/drivers/usb/usbuhci/usb_queue.cpp +++ b/reactos/drivers/usb/usbuhci/usb_queue.cpp @@ -220,8 +220,8 @@ CUSBQueue::AddUSBRequest( // // add queue head // - DPRINT1("AddUSBRequest Request %p\n", Request); - DPRINT1("NewQueueHead %p\n", NewQueueHead); + DPRINT("AddUSBRequest Request %p\n", Request); + DPRINT("NewQueueHead %p\n", NewQueueHead); return AddQueueHead(NewQueueHead); } @@ -260,9 +260,49 @@ CUSBQueue::AbortDevicePipe( IN UCHAR DeviceAddress, IN struct _USB_ENDPOINT *EndpointDescriptor) { - UNIMPLEMENTED - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; + KIRQL OldLevel; + PUHCI_TRANSFER_DESCRIPTOR Descriptor; + PUHCI_QUEUE_HEAD QueueHead, PreviousQueueHead = NULL; + UCHAR EndpointAddress, EndpointDeviceAddress; + + + // acquire lock + KeAcquireSpinLock(&m_Lock, &OldLevel); + + // get queue head + m_Hardware->GetQueueHead(UHCI_INTERRUPT_QUEUE, &QueueHead); + + while(QueueHead) + { + // get descriptor + Descriptor = (PUHCI_TRANSFER_DESCRIPTOR)QueueHead->NextElementDescriptor; + + if (Descriptor) + { + // extract endpoint address + EndpointAddress = (Descriptor->Token >> TD_TOKEN_ENDPTADDR_SHIFT) & 0x0F; + + // extract device address + EndpointDeviceAddress = (Descriptor->Token >> TD_TOKEN_DEVADDR_SHIFT) & 0x7F; + + // check if they match + if (EndpointAddress == (EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F) && + DeviceAddress == EndpointDeviceAddress) + { + // cleanup queue head + QueueHeadCleanup(QueueHead, PreviousQueueHead, &QueueHead); + continue; + } + } + + // move to next queue head + PreviousQueueHead = QueueHead; + QueueHead = (PUHCI_QUEUE_HEAD)QueueHead->NextLogicalDescriptor; + } + + // release lock + KeReleaseSpinLock(&m_Lock, OldLevel); + return STATUS_SUCCESS; } NTSTATUS @@ -295,7 +335,7 @@ CUSBQueue::IsQueueHeadComplete( // // empty queue head // - DPRINT1("QueueHead %p empty element physical\n", QueueHead); + DPRINT("QueueHead %p empty element physical\n", QueueHead); return FALSE; } @@ -396,7 +436,7 @@ CUSBQueue::QueueHeadCleanup( // // free queue head // - DPRINT1("Request %p\n", Request); + DPRINT("Request %p\n", Request); Request->FreeEndpointDescriptor(QueueHead); // @@ -467,7 +507,7 @@ CUSBQueue::TransferInterrupt( // // is queue head complete // - DPRINT1("QueueHead %p\n", QueueHead); + DPRINT("QueueHead %p\n", QueueHead); IsComplete = IsQueueHeadComplete(QueueHead); if (IsComplete) { diff --git a/reactos/drivers/usb/usbuhci/usb_request.cpp b/reactos/drivers/usb/usbuhci/usb_request.cpp index 6408694decf..a5fb7ac1ed5 100644 --- a/reactos/drivers/usb/usbuhci/usb_request.cpp +++ b/reactos/drivers/usb/usbuhci/usb_request.cpp @@ -59,6 +59,7 @@ public: USHORT GetMaxPacketSize(); NTSTATUS CreateDescriptor(PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor, IN UCHAR PidCode, ULONG BufferLength); NTSTATUS BuildControlTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead); + NTSTATUS BuildBulkInterruptTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead); NTSTATUS BuildQueueHead(OUT PUHCI_QUEUE_HEAD *OutQueueHead); VOID FreeDescriptor(IN PUHCI_TRANSFER_DESCRIPTOR Descriptor); NTSTATUS BuildTransferDescriptorChain(IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PUHCI_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PUHCI_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PULONG OutTransferBufferOffset, OUT PUCHAR OutDataToggle); @@ -139,6 +140,9 @@ protected: // USB_DEVICE_SPEED m_DeviceSpeed; + // base + PVOID m_Base; + }; //---------------------------------------------------------------------------------------- @@ -607,14 +611,25 @@ CUSBRequest::GetEndpointDescriptor( struct _UHCI_QUEUE_HEAD ** OutQueueHead) { NTSTATUS Status = STATUS_UNSUCCESSFUL; + ULONG TransferType; - if (InternalGetTransferType() == USB_ENDPOINT_TYPE_CONTROL) + // get transfer type + TransferType = InternalGetTransferType(); + + if (TransferType == USB_ENDPOINT_TYPE_CONTROL) { // // build queue head // Status = BuildControlTransferDescriptor(OutQueueHead); } + else if (TransferType == USB_ENDPOINT_TYPE_INTERRUPT || TransferType == USB_ENDPOINT_TYPE_BULK) + { + // + // build queue head + // + Status = BuildBulkInterruptTransferDescriptor(OutQueueHead); + } if (!NT_SUCCESS(Status)) { @@ -783,7 +798,7 @@ CUSBRequest::CreateDescriptor( // store address & endpoint number // Descriptor->Token |= GetEndpointAddress() << TD_TOKEN_ENDPTADDR_SHIFT; - Descriptor->Token |= GetDeviceAddress() << 8 | PidCode; + Descriptor->Token |= GetDeviceAddress() << TD_TOKEN_DEVADDR_SHIFT | PidCode; if (BufferLength) { @@ -991,6 +1006,70 @@ CUSBRequest::FreeDescriptor( m_DmaManager->Release(Descriptor, sizeof(UHCI_TRANSFER_DESCRIPTOR)); } +NTSTATUS +CUSBRequest::BuildBulkInterruptTransferDescriptor( + IN PUHCI_QUEUE_HEAD * OutQueueHead) +{ + NTSTATUS Status; + PUHCI_QUEUE_HEAD QueueHead; + PUHCI_TRANSFER_DESCRIPTOR FirstDescriptor, LastDescriptor; + ULONG ChainDescriptorLength; + BOOLEAN Direction; + PVOID Buffer; + ULONG BufferSize; + + // create queue head + Status = BuildQueueHead(&QueueHead); + if (!NT_SUCCESS(Status)) + { + // failed to allocate descriptor + DPRINT1("[UHCI] Failed to create queue head\n"); + return Status; + } + + // get direction + Direction = InternalGetPidDirection(); + + if (!m_Base) + { + // get buffer base + m_Base = MmGetMdlVirtualAddress(m_TransferBufferMDL); + } + + // get new buffer offset + Buffer = (PVOID)((ULONG_PTR)m_Base + m_TransferBufferLengthCompleted); + + // FIXME determine buffer limit + BufferSize = min(m_TransferBufferLength - m_TransferBufferLengthCompleted, PAGE_SIZE); + + // create descriptor chain + Status = BuildTransferDescriptorChain(Buffer, + BufferSize, + Direction ? TD_TOKEN_IN : TD_TOKEN_OUT, + m_EndpointDescriptor->DataToggle, + &FirstDescriptor, + &LastDescriptor, + &ChainDescriptorLength, + NULL); + + // adjust buffer offset + m_TransferBufferLengthCompleted += ChainDescriptorLength; + + // fire interrupt when the last descriptor is complete + LastDescriptor->Status |= TD_CONTROL_IOC; + LastDescriptor->LinkPhysical = TD_TERMINATE; + LastDescriptor->NextLogicalDescriptor = NULL; + + // link queue head with first data descriptor descriptor + QueueHead->NextElementDescriptor = (PVOID)FirstDescriptor; + QueueHead->ElementPhysical = FirstDescriptor->PhysicalAddress; + + // store result + *OutQueueHead = QueueHead; + return STATUS_SUCCESS; +} + + NTSTATUS CUSBRequest::BuildControlTransferDescriptor( IN PUHCI_QUEUE_HEAD * OutQueueHead) diff --git a/reactos/drivers/usb/usbuhci/usbuhci.h b/reactos/drivers/usb/usbuhci/usbuhci.h index ea9b8c2ad1e..a4545e40001 100644 --- a/reactos/drivers/usb/usbuhci/usbuhci.h +++ b/reactos/drivers/usb/usbuhci/usbuhci.h @@ -2,7 +2,7 @@ #define USBOHCI_H__ #include -#define YDEBUG +#define NDEBUG #include #include #include