Author: janderwald Date: Sat Apr 30 08:04:35 2011 New Revision: 51501
URL: http://svn.reactos.org/svn/reactos?rev=51501&view=rev Log: [USBEHCI_NEW] - Port URB_FUNCTION_CLASS_INTERFACE from mjmartin usbehci driver - Fix typo in interface declaration - Disable assert for now - Return irp status pending when irp is added to the queue - Fix bug in InternalGetPidDirection - More work on the bulk transfers, not yet working
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] Sat Apr 30 08:04:35 2011 @@ -65,6 +65,7 @@ NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb); + NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
friend VOID StatusChangeEndpointCallBack(PVOID Context); @@ -1355,6 +1356,70 @@ DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", Urb->UrbControlDescriptorRequest.DescriptorType); break; } + + // + // done + // + return Status; +} + +//----------------------------------------------------------------------------------------- +NTSTATUS +CHubController::HandleClassInterface( + IN OUT PIRP Irp, + IN OUT PURB Urb) +{ + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + NTSTATUS Status; + PUSBDEVICE UsbDevice; + + // + // sanity check + // + PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer); + PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength); + PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); + + // + // check if this is a valid usb device handle + // + PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + + + DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n"); + DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags); + DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength); + DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer); + DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL); + DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits); + DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request); + DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value); + DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index); + + // + // initialize setup packet + // + CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const. + CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request; + CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value; + CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index; + CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength; + + // + // issue request + // + Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer); + + // + // assert on failure + // + PC_ASSERT(NT_SUCCESS(Status)); +
// // done @@ -1419,6 +1484,9 @@ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: Status = HandleBulkOrInterruptTransfer(Irp, Urb); break; + case URB_FUNCTION_CLASS_INTERFACE: + Status = HandleClassInterface(Irp, Urb); + break; default: DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function); break;
Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Sat Apr 30 08:04:35 2011 @@ -785,7 +785,7 @@ // // Description: submits an irp containing an urb
- virtual NTSTATUS SubmitIrp(PIRP Urb) = 0; + virtual NTSTATUS SubmitIrp(PIRP Irp) = 0;
//----------------------------------------------------------------------------------------- //
Modified: branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] Sat Apr 30 08:04:35 2011 @@ -136,7 +136,7 @@ // sanity checks // ASSERT(Size < PAGE_SIZE); - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + //ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
// // align request
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] Sat Apr 30 08:04:35 2011 @@ -484,6 +484,11 @@ Status = Request->InitializeWithIrp(m_DmaManager, Irp);
// + // mark irp as pending + // + IoMarkIrpPending(Irp); + + // // now add the request // Status = m_Queue->AddUSBRequest(Request); @@ -500,7 +505,7 @@ // // done // - return Status; + return STATUS_PENDING; }
//---------------------------------------------------------------------------------------- @@ -1199,6 +1204,16 @@ // // copy pipe handle // + DPRINT1("PipeIndex %lu\n", PipeIndex); + DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress); + DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval); + DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize); + DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize); + DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags); + DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType); + DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress); + PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress); + InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] Sat Apr 30 08:04:35 2011 @@ -371,6 +371,8 @@ Urb->UrbHeader.Length = 0; }
+ DPRINT1("Request %p Completing Irp %p NtStatusCode %x UrbStatusCode %x\n", this, m_Irp, NtStatusCode, UrbStatusCode); + // // FIXME: check if the transfer was split // if yes dont complete irp yet @@ -604,9 +606,9 @@ EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
// - // end point is defined in the low byte of bmAttributes - // - return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK); + // end point is defined in the low byte of bEndpointAddress + // + return (EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; }
//---------------------------------------------------------------------------------------- @@ -779,8 +781,11 @@ PQUEUE_HEAD * OutHead) { NTSTATUS Status; - ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, FailIndex; PQUEUE_HEAD QueueHead; + ULONG TransferDescriptorCount, Index; + ULONG BytesAvailable, BufferIndex; + PVOID Base; + ULONG PageOffset;
// // Allocate the queue head @@ -801,38 +806,33 @@ PC_ASSERT(QueueHead);
// - // Determine number of transfer descriptors needed. Max size is 3 * 5 Pages - // FIXME: Do we need anything bigger? - // - TransferBufferRounded = ROUND_TO_PAGES(m_TransferBufferLength); - NumPages = Index = 0; - NumTransferDescriptors = 1; - while (TransferBufferRounded > 0) - { - TransferBufferRounded -= PAGE_SIZE; - NumPages++; - Index++; - if (Index == 5) - { - NumTransferDescriptors++; - Index = 0; - } - } - - DPRINT1("Need TransferDescriptors %x, Pages %x\n", NumTransferDescriptors, NumPages); - DPRINT1("This is the end of the line!!!!!!!!\n"); - return STATUS_NOT_IMPLEMENTED; - //FIXME: Below needs work. - - // - // FIXME: Handle transfers greater than 5 * PAGE_SIZE * 3 - // - if (NumTransferDescriptors > 3) NumTransferDescriptors = 3; + // FIXME: support more than one descriptor + // + PC_ASSERT(m_TransferBufferLength < PAGE_SIZE * 5); + PC_ASSERT(m_TransferBufferLength); + + TransferDescriptorCount = 1; + + // + // get virtual base of mdl + // + Base = MmGetMdlVirtualAddress(m_TransferBufferMDL); + BytesAvailable = m_TransferBufferLength; + + PC_ASSERT(m_EndpointDescriptor); + + DPRINT1("EndPointAddress %x\n", m_EndpointDescriptor->bEndpointAddress); + DPRINT1("EndPointDirection %x\n", USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress)); + + DPRINT1("Request %p Base Address %p TransferBytesLength %lu\n", this, Base, BytesAvailable); + DPRINT1("InternalGetPidDirection() %d EndPointAddress %x\n", InternalGetPidDirection(), m_EndpointDescriptor->bEndpointAddress & 0x0F); + + //PC_ASSERT(InternalGetPidDirection() == USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
// // Allocated transfer descriptors // - for (Index = 0; Index < NumTransferDescriptors; Index++) + for (Index = 0; Index < TransferDescriptorCount; Index++) { Status = CreateDescriptor(&m_TransferDescriptors[Index]); if (!NT_SUCCESS(Status)) @@ -850,10 +850,130 @@ // Free Descriptors // FIXME: Implement FreeDescriptors // - //for (FailIndex = 0; FailIndex < Index; FailIndex++) - //FreeDescriptor(m_TransferDescriptors[FailIndex]); - return Status; + } + + // + // sanity check + // + PC_ASSERT(BytesAvailable); + + // + // now setup transfer buffers + // + for(BufferIndex = 0; BufferIndex < 5; BufferIndex++) + { + // + // setup buffer + // + if (BufferIndex == 0) + { + // + // use physical address + // + m_TransferDescriptors[Index]->BufferPointer[0] = MmGetPhysicalAddress(Base).LowPart; + + // + // get offset within page + // + PageOffset = BYTE_OFFSET(m_TransferDescriptors[Index]->BufferPointer[0]); + + // + // check if request fills another page + // + if (PageOffset + BytesAvailable >= PAGE_SIZE) + { + // + // move to next page + // + Base = (PVOID)ROUND_TO_PAGES(Base); + + // + // increment transfer bytes + // + m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = PAGE_SIZE - PageOffset; + + // + // decrement available byte count + // + BytesAvailable -= m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer; + + DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex], + BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable); + } + else + { + // + // request ends on the first buffer page + // + m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = BytesAvailable; + BytesAvailable = 0; + + DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex], + BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable); + break; + } + } + else + { + // + // the following pages always start on byte zero of each page + // + PC_ASSERT(((ULONG_PTR)Base & (PAGE_SIZE-1)) == 0); + + if (BytesAvailable >= PAGE_SIZE) + { + // + // store address + // + m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart; + + // + // move to next page + // + Base = (PVOID)((ULONG_PTR)Base + PAGE_SIZE); + + // + // increment transfer descriptor bytes + // + m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += PAGE_SIZE; + + // + // decrement available byte count + // + BytesAvailable -= PAGE_SIZE; + + DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex], + BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable); + } + else + { + PC_ASSERT(BytesAvailable); + + // + // store address + // + m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart; + + // + // increment transfer descriptor bytes + // + m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += BytesAvailable; + + // + // decrement available byte count + // + BytesAvailable -= BytesAvailable; + + // + // done + // + DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex], + BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable); + + break; + } + } }
// @@ -863,8 +983,26 @@ { m_TransferDescriptors[Index - 1]->NextPointer = m_TransferDescriptors[Index]->PhysicalAddr; } - - } + + // + // setup direction + // + m_TransferDescriptors[Index]->Token.Bits.PIDCode = InternalGetPidDirection(); + + // + // FIXME: performance penality? + // + m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE; + + // + // FIXME need dead queue transfer descriptor? + // + } + + // + // all bytes should have been consumed + // + PC_ASSERT(BytesAvailable == 0);
// // Initialize the QueueHead @@ -881,19 +1019,20 @@ }
QueueHead->Token.Bits.DataToggle = TRUE; - - // - // Setup descriptors - // - m_TransferDescriptors[0]->Token.Bits.PIDCode = InternalGetPidDirection(); - //m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer = ??? - //m_TransferDescriptors[0]->Token.Bits.DataToggle = FALSE; - - m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE; - - ASSERT(m_TransferBufferMDL); - - + + // + // link descriptor with queue head + // + QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr; + + // + // store result + // + *OutHead = QueueHead; + + // + // done + // return STATUS_SUCCESS; }
@@ -1351,6 +1490,7 @@ // // release transfer descriptors // + DPRINT1("m_TransferDescriptor[0] Length %lu\n", m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer); m_DmaManager->Release(m_TransferDescriptors[0], sizeof(QUEUE_TRANSFER_DESCRIPTOR)); m_TransferDescriptors[0] = 0; }