Author: janderwald
Date: Thu May 26 02:15:11 2011
New Revision: 51917
URL:
http://svn.reactos.org/svn/reactos?rev=51917&view=rev
Log:
[USBOHCI]
- Remove dead code
- Silence traces
- Pass status & DoneHead as parameters to dpc routine
- Move IUSBRequest cleanup code into new function and use it for bulk / control transfer
cleanup
- Fix bugs in AllocateEndpointDescriptor. It did not take the device address into account.
It also did not respect the direction of the descriptor
- Implement support for bulk transfer requests
- Handle irp completion in CompletionCallback
- Tested in Windows XP SP3 + Vbox 4.04 + USB2.0 disabled + ReactOS usbstor + USB mass
storage device
- OHCI Mass storage support is now also ready
- Next interrupt transfers
Modified:
branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
branches/usb-bringup/drivers/usb/usbohci/hardware.h
branches/usb-bringup/drivers/usb/usbohci/interfaces.h
branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp
Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Thu May 26 02:15:11
2011
@@ -697,8 +697,6 @@
//
// notify controller
//
- //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_HEAD_ED_OFFSET),
m_ControlEndpointDescriptor->NextPhysicalEndpoint);
- //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_CURRENT_ED_OFFSET),
m_ControlEndpointDescriptor->NextPhysicalEndpoint);
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value
| OHCI_CONTROL_LIST_FILLED);
}
else if (Type == USB_ENDPOINT_TYPE_BULK)
@@ -708,12 +706,6 @@
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value
| OHCI_BULK_LIST_FILLED);
}
-
- Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET));
-
-
- DPRINT1("HeadEndpointDescriptorModified Value %x Type %x\n", Value, Type);
-
}
NTSTATUS
@@ -1191,7 +1183,7 @@
//
This = (CUSBHardwareDevice*) ServiceContext;
- DPRINT1("InterruptServiceRoutine\n");
+ DPRINT("InterruptServiceRoutine\n");
//
// get done head
@@ -1246,6 +1238,7 @@
// head completed
//
Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
+ This->m_HCCA->DoneHead = 0;
}
if (Status & OHCI_RESUME_DETECTED)
@@ -1296,8 +1289,8 @@
//
// defer processing
//
- DPRINT1("Status %x\n", Status);
- KeInsertQueueDpc(&This->m_IntDpcObject, This, (PVOID)Status);
+ DPRINT("Status %x Acknowledge %x\n", Status, Acknowledge);
+ KeInsertQueueDpc(&This->m_IntDpcObject, (PVOID)Status, (PVOID)(DoneHead &
~1));
//
// interrupt handled
@@ -1321,23 +1314,14 @@
//
// get parameters
//
- This = (CUSBHardwareDevice*) SystemArgument1;
- CStatus = (ULONG) SystemArgument2;
-
- DPRINT1("OhciDefferedRoutine Status %x\n", CStatus);
+ This = (CUSBHardwareDevice*)DeferredContext;
+ CStatus = (ULONG) SystemArgument1;
+ DoneHead = (ULONG)SystemArgument2;
+
+ DPRINT("OhciDefferedRoutine Status %x\n", CStatus);
if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
{
- //
- // descriptor completion, get done head
- //
- DoneHead = This->m_HCCA->DoneHead;
-
- //
- // clear out lower bits, ed are 16 byte aligned
- //
- DoneHead &= ~0xF;
-
//
// notify queue of event
//
Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] Thu May 26 02:15:11
2011
@@ -216,6 +216,8 @@
#define OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(s) ((s) << 16)
#define OHCI_ENDPOINT_LOW_SPEED 0x00002000
#define OHCI_ENDPOINT_FULL_SPEED 0x00000000
+#define OHCI_ENDPOINT_DIRECTION_OUT 0x00000800
+#define OHCI_ENDPOINT_DIRECTION_IN 0x00001000
//
// Maximum port count set by OHCI
Modified: branches/usb-bringup/drivers/usb/usbohci/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] Thu May 26 02:15:11
2011
@@ -443,6 +443,14 @@
// Description: notifies request that the endpoint descriptor is complete
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor) =
0;
+
+//-----------------------------------------------------------------------------------------
+//
+// FreeEndpointDescriptor
+//
+// Description: frees the associated endpoint descriptor and its general descriptors
+
+ virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
= 0;
};
Modified: branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] Thu May 26
02:15:11 2011
@@ -44,6 +44,7 @@
// local functions
BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT
POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR
*OutPreviousEndpointDescriptor);
+ VOID CleanupEndpointDescriptor(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor);
// constructor / destructor
CUSBQueue(IUnknown *OuterUnknown){}
@@ -127,7 +128,7 @@
POHCI_ENDPOINT_DESCRIPTOR HeadDescriptor;
POHCI_ENDPOINT_DESCRIPTOR Descriptor;
- DPRINT1("CUSBQueue::AddUSBRequest\n");
+ DPRINT("CUSBQueue::AddUSBRequest\n");
//
// sanity check
@@ -146,11 +147,11 @@
{
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
case USB_ENDPOINT_TYPE_INTERRUPT:
- case USB_ENDPOINT_TYPE_BULK:
/* NOT IMPLEMENTED IN QUEUE */
Status = STATUS_NOT_SUPPORTED;
break;
case USB_ENDPOINT_TYPE_CONTROL:
+ case USB_ENDPOINT_TYPE_BULK:
Status = STATUS_SUCCESS;
break;
default:
@@ -228,12 +229,14 @@
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
//HeadDescriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
+ DPRINT("Request %x Logical %x added to queue Queue %p Logical %x\n",
Descriptor, Descriptor->PhysicalAddress.LowPart, HeadDescriptor,
HeadDescriptor->PhysicalAddress.LowPart);
+
+
//
// notify hardware of our request
//
m_Hardware->HeadEndpointDescriptorModified(Type);
- DPRINT1("Request %x %x added to queue\n", Descriptor,
Descriptor->PhysicalAddress);
return STATUS_SUCCESS;
@@ -356,6 +359,47 @@
return FALSE;
}
+VOID
+CUSBQueue::CleanupEndpointDescriptor(
+ POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+ POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor)
+{
+ PUSBREQUEST Request;
+
+ //
+ // FIXME: verify unlinking process
+ //
+ PreviousEndpointDescriptor->NextDescriptor =
EndpointDescriptor->NextDescriptor;
+ PreviousEndpointDescriptor->NextPhysicalEndpoint =
EndpointDescriptor->NextPhysicalEndpoint;
+
+ //
+ // get corresponding request
+ //
+ Request = PUSBREQUEST(EndpointDescriptor->Request);
+ ASSERT(Request);
+
+ //
+ // notify of completion
+ //
+ Request->CompletionCallback(EndpointDescriptor);
+
+ //
+ // free endpoint descriptor
+ //
+ Request->FreeEndpointDescriptor(EndpointDescriptor);
+
+ //
+ // FIXME: check if complete
+ //
+ //ASSERT(Request->IsRequestComplete());
+
+ //
+ // release request
+ //
+ Request->Release();
+
+}
+
VOID
CUSBQueue::TransferDescriptorCompletionCallback(
@@ -363,7 +407,8 @@
{
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
NTSTATUS Status;
- PUSBREQUEST Request;
+
+ DPRINT("CUSBQueue::TransferDescriptorCompletionCallback transfer descriptor
%x\n", TransferDescriptorLogicalAddress);
//
// find transfer descriptor in control list
@@ -372,31 +417,38 @@
if (NT_SUCCESS(Status))
{
//
- // FIXME: make sure this is ok
- // unlink descriptor
- //
- PreviousEndpointDescriptor->NextDescriptor =
EndpointDescriptor->NextDescriptor;
- PreviousEndpointDescriptor->NextPhysicalEndpoint =
EndpointDescriptor->NextPhysicalEndpoint;
-
- //
- // get corresponding request
- //
- Request = PUSBREQUEST(EndpointDescriptor->Request);
-
- //
- // notify of completion
- //
- Request->CompletionCallback(EndpointDescriptor);
-
- //
- // FIXME: check if complete
- //
- ASSERT(Request->IsRequestComplete());
- //
- // release request
- //
- Request->Release();
- }
+ // cleanup endpoint
+ //
+ CleanupEndpointDescriptor(EndpointDescriptor, PreviousEndpointDescriptor);
+
+ //
+ // done
+ //
+ return;
+ }
+
+ //
+ // find transfer descriptor in bulk list
+ //
+ Status = FindTransferDescriptorInEndpoint(m_BulkHeadEndpointDescriptor,
TransferDescriptorLogicalAddress, &EndpointDescriptor,
&PreviousEndpointDescriptor);
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // cleanup endpoint
+ //
+ CleanupEndpointDescriptor(EndpointDescriptor, PreviousEndpointDescriptor);
+
+ //
+ // done
+ //
+ return;
+ }
+
+ //
+ // hardware reported dead endpoint completed
+ //
+ DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer
descriptor %x\n", TransferDescriptorLogicalAddress);
+ ASSERT(FALSE);
}
Modified: branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] Thu May 26
02:15:11 2011
@@ -45,6 +45,7 @@
virtual BOOLEAN IsRequestInitialized();
virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
+ virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR *
OutDescriptor);
// local functions
ULONG InternalGetTransferType();
@@ -53,6 +54,7 @@
NTSTATUS BuildSetupPacket();
NTSTATUS BuildSetupPacketFromURB();
NTSTATUS BuildControlTransferDescriptor(POHCI_ENDPOINT_DESCRIPTOR *
OutEndpointDescriptor);
+ NTSTATUS BuildBulkInterruptEndpoint(POHCI_ENDPOINT_DESCRIPTOR *
OutEndpointDescriptor);
NTSTATUS CreateGeneralTransferDescriptor(POHCI_GENERAL_TD* OutDescriptor, ULONG
BufferSize);
VOID FreeDescriptor(POHCI_GENERAL_TD Descriptor);
NTSTATUS AllocateEndpointDescriptor(OUT POHCI_ENDPOINT_DESCRIPTOR *OutDescriptor);
@@ -606,9 +608,35 @@
//
// append device address and endpoint number
//
- Descriptor->Flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(m_DeviceAddress);
+ Descriptor->Flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(GetDeviceAddress());
Descriptor->Flags |= OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(GetEndpointAddress());
Descriptor->Flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(GetMaxPacketSize());
+
+ //
+ // is there an endpoint descriptor
+ //
+ if (m_EndpointDescriptor)
+ {
+ //
+ // check direction
+ //
+ if (USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->bEndpointAddress))
+ {
+ //
+ // direction out
+ //
+ Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_OUT;
+ }
+ else
+ {
+ //
+ // direction in
+ //
+ Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_IN;
+ }
+
+ }
+
//
// FIXME: detect type
@@ -632,14 +660,204 @@
}
NTSTATUS
+CUSBRequest::BuildBulkInterruptEndpoint(
+ POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
+{
+ POHCI_GENERAL_TD FirstDescriptor, PreviousDescriptor = NULL, CurrentDescriptor,
LastDescriptor;
+ POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ ULONG BufferSize, CurrentSize, Direction, MaxLengthInPage;
+ NTSTATUS Status;
+ PVOID Buffer;
+
+ //
+ // allocate endpoint descriptor
+ //
+ Status = AllocateEndpointDescriptor(&EndpointDescriptor);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to create setup descriptor
+ //
+ return Status;
+ }
+
+ //
+ // allocate transfer descriptor for last descriptor
+ //
+ Status = CreateGeneralTransferDescriptor(&LastDescriptor, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to create transfer descriptor
+ //
+ m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
+ return Status;
+ }
+
+ //
+ // get buffer size
+ //
+ BufferSize = m_TransferBufferLength;
+ ASSERT(BufferSize);
+ ASSERT(m_TransferBufferMDL);
+
+ //
+ // get buffer
+ //
+ Buffer = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
+ ASSERT(Buffer);
+
+ if (InternalGetPidDirection())
+ {
+ //
+ // input direction
+ //
+ Direction = OHCI_TD_DIRECTION_PID_IN;
+ }
+ else
+ {
+ //
+ // output direction
+ //
+ Direction = OHCI_TD_DIRECTION_PID_OUT;
+ }
+
+ do
+ {
+ //
+ // get current buffersize
+ //
+ CurrentSize = min(8192, BufferSize);
+
+ //
+ // get page offset
+ //
+ MaxLengthInPage = PAGE_SIZE - BYTE_OFFSET(Buffer);
+
+ //
+ // get minimum from current page size
+ //
+ CurrentSize = min(CurrentSize, MaxLengthInPage);
+ ASSERT(CurrentSize);
+
+ //
+ // allocate transfer descriptor
+ //
+ Status = CreateGeneralTransferDescriptor(&CurrentDescriptor, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to create transfer descriptor
+ // TODO: cleanup
+ //
+ ASSERT(FALSE);
+ m_DmaManager->Release(EndpointDescriptor,
sizeof(OHCI_ENDPOINT_DESCRIPTOR));
+ FreeDescriptor(LastDescriptor);
+ return Status;
+ }
+
+ //
+ // initialize descriptor
+ //
+ CurrentDescriptor->Flags = Direction | OHCI_TD_BUFFER_ROUNDING |
OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) |
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY;
+
+ //
+ // store physical address of buffer
+ //
+ CurrentDescriptor->BufferPhysical = MmGetPhysicalAddress(Buffer).LowPart;
+ CurrentDescriptor->LastPhysicalByteAddress =
CurrentDescriptor->BufferPhysical + CurrentSize - 1;
+
+ //
+ // is there a previous descriptor
+ //
+ if (PreviousDescriptor)
+ {
+ //
+ // link descriptors
+ //
+ PreviousDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor;
+ PreviousDescriptor->NextPhysicalDescriptor =
CurrentDescriptor->PhysicalAddress.LowPart;
+ }
+ else
+ {
+ //
+ // it is the first descriptor
+ //
+ FirstDescriptor = CurrentDescriptor;
+ }
+
+ DPRINT("PreviousDescriptor %p CurrentDescriptor %p Buffer Logical %p
Physical %x Last Physical %x CurrentSize %lu\n", PreviousDescriptor,
CurrentDescriptor, CurrentDescriptor->BufferLogical,
CurrentDescriptor->BufferPhysical, CurrentDescriptor->LastPhysicalByteAddress,
CurrentSize);
+
+ //
+ // set previous descriptor
+ //
+ PreviousDescriptor = CurrentDescriptor;
+
+ //
+ // subtract buffer size
+ //
+ BufferSize -= CurrentSize;
+
+ //
+ // increment buffer offset
+ //
+ Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
+
+ }while(BufferSize);
+
+ //
+ // first descriptor has no carry bit
+ //
+ FirstDescriptor->Flags &= ~OHCI_TD_TOGGLE_CARRY;
+
+ //
+ // fixme: toggle
+ //
+ FirstDescriptor->Flags |= OHCI_TD_TOGGLE_0;
+
+ //
+ // clear interrupt mask for last transfer descriptor
+ //
+ CurrentDescriptor->Flags &= ~OHCI_TD_INTERRUPT_MASK;
+
+ //
+ // fire interrupt as soon transfer is finished
+ //
+ CurrentDescriptor->Flags |=
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
+
+ //
+ // link last data descriptor to last descriptor
+ //
+ CurrentDescriptor->NextLogicalDescriptor = LastDescriptor;
+ CurrentDescriptor->NextPhysicalDescriptor =
LastDescriptor->PhysicalAddress.LowPart;
+
+ //
+ // now link descriptor to endpoint
+ //
+ EndpointDescriptor->HeadPhysicalDescriptor =
FirstDescriptor->PhysicalAddress.LowPart;
+ EndpointDescriptor->TailPhysicalDescriptor =
LastDescriptor->PhysicalAddress.LowPart;
+ EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor;
+
+ //
+ // store result
+ //
+ *OutEndpointDescriptor = EndpointDescriptor;
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+
+}
+
+
+NTSTATUS
CUSBRequest::BuildControlTransferDescriptor(
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
{
POHCI_GENERAL_TD SetupDescriptor, StatusDescriptor, DataDescriptor = NULL,
LastDescriptor;
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
NTSTATUS Status;
-
- DPRINT1("CUSBRequest::BuildControlTransferDescriptor\n");
//
// allocate endpoint descriptor
@@ -694,7 +912,6 @@
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
return Status;
}
-
if (m_TransferBufferLength)
{
@@ -729,6 +946,7 @@
//
DataDescriptor->BufferPhysical =
MmGetPhysicalAddress(MmGetMdlVirtualAddress(m_TransferBufferMDL)).LowPart;
DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical +
m_TransferBufferLength - 1;
+
}
//
@@ -849,12 +1067,8 @@
Status =
BuildControlTransferDescriptor((POHCI_ENDPOINT_DESCRIPTOR*)OutDescriptor);
break;
case USB_ENDPOINT_TYPE_BULK:
- DPRINT1("USB_ENDPOINT_TYPE_BULK not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
//BuildBulkTransferQueueHead(OutDescriptor);
- break;
case USB_ENDPOINT_TYPE_INTERRUPT:
- DPRINT1("USB_ENDPOINT_TYPE_INTERRUPT not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ Status = BuildBulkInterruptEndpoint(OutDescriptor);
break;
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
DPRINT1("USB_ENDPOINT_TYPE_ISOCHRONOUS not implemented\n");
@@ -919,14 +1133,66 @@
}
+VOID
+CUSBRequest::FreeEndpointDescriptor(
+ struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
+{
+ POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
+
+ DPRINT("CUSBRequest::FreeEndpointDescriptor EndpointDescriptor %p Logical
%x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
+
+ //
+ // get first general transfer descriptor
+ //
+ TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
+
+ //
+ // release endpoint descriptor
+ //
+ m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
+
+ while(TransferDescriptor)
+ {
+ //
+ // get next
+ //
+ NextTransferDescriptor =
(POHCI_GENERAL_TD)TransferDescriptor->NextLogicalDescriptor;
+
+ //
+ // is there a buffer associated
+ //
+ if (TransferDescriptor->BufferSize)
+ {
+ //
+ // release buffer
+ //
+ m_DmaManager->Release(TransferDescriptor->BufferLogical,
TransferDescriptor->BufferSize);
+ }
+
+ DPRINT("CUSBRequest::FreeEndpointDescriptor Descriptor %p Logical %x Buffer
Physical %x EndAddress %x\n", TransferDescriptor,
TransferDescriptor->PhysicalAddress.LowPart, TransferDescriptor->BufferPhysical,
TransferDescriptor->LastPhysicalByteAddress);
+
+ //
+ // release descriptor
+ //
+ m_DmaManager->Release(TransferDescriptor, sizeof(OHCI_GENERAL_TD));
+
+ //
+ // move to next
+ //
+ TransferDescriptor = NextTransferDescriptor;
+ }
+
+}
VOID
CUSBRequest::CompletionCallback(
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
{
POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
-
- DPRINT1("CUSBRequest::CompletionCallback\n");
+ PIO_STACK_LOCATION IoStack;
+ PURB Urb;
+
+ DPRINT("CUSBRequest::CompletionCallback Descriptor %p PhysicalAddress
%x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
//
// set status code
@@ -934,56 +1200,57 @@
m_NtStatusCode = STATUS_SUCCESS;
m_UrbStatusCode = USBD_STATUS_SUCCESS;
- ASSERT(!m_Irp);
-
- //
- // FIXME: cleanup descriptors
- //
-
- //
- // get first general transfer descriptor
- //
- TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
-
- while(TransferDescriptor)
- {
- //
- // get next
- //
- NextTransferDescriptor =
(POHCI_GENERAL_TD)TransferDescriptor->NextLogicalDescriptor;
-
- //
- // is there a buffer associated
- //
- if (TransferDescriptor->BufferSize)
+ if (m_Irp)
+ {
+ //
+ // set irp completion status
+ //
+ m_Irp->IoStatus.Status = STATUS_SUCCESS; //FIXME
+
+ //
+ // get current irp stack location
+ //
+ IoStack = IoGetCurrentIrpStackLocation(m_Irp);
+
+ //
+ // get urb
+ //
+ Urb = (PURB)IoStack->Parameters.Others.Argument1;
+
+ //
+ // store urb status
+ //
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; //FIXME
+
+ //
+ // Check if the MDL was created
+ //
+ if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
{
//
- // release buffer
- //
- m_DmaManager->Release(TransferDescriptor->BufferLogical,
TransferDescriptor->BufferSize);
+ // Free Mdl
+ //
+ IoFreeMdl(m_TransferBufferMDL);
}
//
- // release descriptor
- //
- m_DmaManager->Release(TransferDescriptor, sizeof(OHCI_GENERAL_TD));
-
- //
- // move to next
- //
- TransferDescriptor = NextTransferDescriptor;
- }
-
- //
- // release endpoint descriptor
- //
- m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
-
- //
- // signal completion event
- //
- PC_ASSERT(m_CompletionEvent);
- KeSetEvent(m_CompletionEvent, 0, FALSE);
+ // FIXME: support status and calculate length
+ //
+
+ //
+ // FIXME: check if the transfer was split
+ // if yes dont complete irp yet
+ //
+ IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
+ }
+ else
+ {
+ //
+ // signal completion event
+ //
+ PC_ASSERT(m_CompletionEvent);
+ KeSetEvent(m_CompletionEvent, 0, FALSE);
+ }
}