Skip to content

Commit d8b2cce

Browse files
committed
[USBUHCI]
- Implement function to retrieve queue head for the specified transfer type - Pass device speed to IUSBRequest initialization routines - Implementing inserting the new queue head into the required queue head - Implement support for control transfers, not yet used svn path=/trunk/; revision=55787
1 parent a14929e commit d8b2cce

File tree

6 files changed

+628
-23
lines changed

6 files changed

+628
-23
lines changed

reactos/drivers/usb/usbuhci/hardware.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ class CUSBHardwareDevice : public IUSBHardwareDevice
7373
NTSTATUS GetPortStatus(ULONG PortId, OUT USHORT *PortStatus, OUT USHORT *PortChange);
7474
NTSTATUS ClearPortStatus(ULONG PortId, ULONG Status);
7575
NTSTATUS SetPortFeature(ULONG PortId, ULONG Feature);
76-
7776
VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context);
77+
VOID GetQueueHead(ULONG QueueHeadIndex, PUHCI_QUEUE_HEAD *OutQueueHead);
78+
7879

7980
KIRQL AcquireDeviceLock(void);
8081
VOID ReleaseDeviceLock(KIRQL OldLevel);
@@ -616,7 +617,7 @@ CUSBHardwareDevice::InitializeController()
616617
//
617618
// link queue heads
618619
//
619-
m_QueueHead[Index-1]->LinkPhysical = m_QueueHead[Index]->LinkPhysical | QH_NEXT_IS_QH;
620+
m_QueueHead[Index-1]->LinkPhysical = m_QueueHead[Index]->PhysicalAddress | QH_NEXT_IS_QH;
620621
m_QueueHead[Index-1]->NextLogicalDescriptor = m_QueueHead[Index];
621622
}
622623
}
@@ -1218,6 +1219,21 @@ CUSBHardwareDevice::ReadRegister32(
12181219
return READ_PORT_ULONG((PULONG)((ULONG)m_Base + Register));
12191220
}
12201221

1222+
VOID
1223+
CUSBHardwareDevice::GetQueueHead(
1224+
IN ULONG QueueHeadIndex,
1225+
OUT PUHCI_QUEUE_HEAD *OutQueueHead)
1226+
{
1227+
//
1228+
// sanity check
1229+
//
1230+
ASSERT(QueueHeadIndex < 5);
1231+
1232+
//
1233+
// store queue head
1234+
//
1235+
*OutQueueHead = m_QueueHead[QueueHeadIndex];
1236+
}
12211237

12221238
VOID
12231239
NTAPI

reactos/drivers/usb/usbuhci/hardware.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ UHCI_TRANSFER_DESCRIPTOR_LENGTH(PUHCI_TRANSFER_DESCRIPTOR Descriptor)
163163
}
164164

165165
// Represents a Queue Head (QH)
166-
typedef struct
166+
typedef struct _UHCI_QUEUE_HEAD
167167
{
168168
// hardware part
169169
ULONG LinkPhysical; // address
@@ -172,6 +172,8 @@ typedef struct
172172
// Software part
173173
ULONG PhysicalAddress;
174174
PVOID NextLogicalDescriptor;
175+
PVOID Request;
176+
PVOID NextElementDescriptor;
175177
}UHCI_QUEUE_HEAD, *PUHCI_QUEUE_HEAD;
176178

177179
#define QH_TERMINATE 0x01

reactos/drivers/usb/usbuhci/interfaces.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ DECLARE_INTERFACE_(IHCDController, IUnknown)
107107

108108
typedef IHCDController *PHCDCONTROLLER;
109109

110-
struct _UHCI_TRANSFER_DESCRIPTOR;
110+
struct _UHCI_QUEUE_HEAD;
111111
//=========================================================================================
112112
//
113113
// class IUSBHardwareDevice
@@ -251,6 +251,15 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
251251
//
252252
virtual VOID SetStatusChangeEndpointCallBack(PVOID CallBack,PVOID Context) = 0;
253253

254+
//-----------------------------------------------------------------------------------------
255+
//
256+
// GetQueueHead
257+
//
258+
// Description: gets a queue head with the specified queue head index
259+
//
260+
virtual VOID GetQueueHead(ULONG QueueHeadIndex, struct _UHCI_QUEUE_HEAD **OutQueueHead) = 0;
261+
262+
254263
//-----------------------------------------------------------------------------------------
255264
//
256265
// AcquireDeviceLock
@@ -350,6 +359,7 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
350359
virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager,
351360
IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
352361
IN UCHAR DeviceAddress,
362+
IN USB_DEVICE_SPEED DeviceSpeed,
353363
IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
354364
IN OUT ULONG TransferBufferLength,
355365
IN OUT PMDL TransferBuffer) = 0;
@@ -362,7 +372,8 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
362372
// The irp contains an URB block which contains all necessary information
363373

364374
virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager,
365-
IN OUT PIRP Irp) = 0;
375+
IN OUT PIRP Irp,
376+
IN USB_DEVICE_SPEED DeviceSpeed) = 0;
366377

367378
//-----------------------------------------------------------------------------------------
368379
//
@@ -390,7 +401,7 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
390401
//
391402
// Description: returns the general transfer descriptor
392403

393-
virtual NTSTATUS GetEndpointDescriptor(struct _UHCI_TRANSFER_DESCRIPTOR ** OutDescriptor) = 0;
404+
virtual NTSTATUS GetEndpointDescriptor(struct _UHCI_QUEUE_HEAD ** OutDescriptor) = 0;
394405

395406
//-----------------------------------------------------------------------------------------
396407
//
@@ -418,6 +429,14 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
418429

419430
virtual UCHAR GetInterval() = 0;
420431

432+
//-----------------------------------------------------------------------------------------
433+
//
434+
// GetDeviceSpeed
435+
//
436+
// Description: returns device speed
437+
438+
virtual USB_DEVICE_SPEED GetDeviceSpeed() = 0;
439+
421440
};
422441

423442

reactos/drivers/usb/usbuhci/usb_device.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ CUSBDevice::CommitIrp(
462462
//
463463
// initialize request
464464
//
465-
Status = Request->InitializeWithIrp(m_DmaManager, Irp);
465+
Status = Request->InitializeWithIrp(m_DmaManager, Irp, GetSpeed());
466466

467467
//
468468
// mark irp as pending
@@ -550,7 +550,7 @@ CUSBDevice::CommitSetupPacket(
550550
//
551551
// initialize request
552552
//
553-
Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, EndpointDescriptor, BufferLength, Mdl);
553+
Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, GetSpeed(), EndpointDescriptor, BufferLength, Mdl);
554554
if (!NT_SUCCESS(Status))
555555
{
556556
//

reactos/drivers/usb/usbuhci/usb_queue.cpp

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class CUSBQueue : public IUSBQueue
4040
virtual NTSTATUS CancelRequests();
4141
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
4242

43+
// local
44+
VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead);
45+
4346
// constructor / destructor
4447
CUSBQueue(IUnknown *OuterUnknown){}
4548
virtual ~CUSBQueue(){}
@@ -104,11 +107,95 @@ NTSTATUS
104107
CUSBQueue::AddUSBRequest(
105108
IUSBRequest * Request)
106109
{
110+
PUHCI_QUEUE_HEAD NewQueueHead, QueueHead = NULL;
111+
NTSTATUS Status;
112+
107113
DPRINT("CUSBQueue::AddUSBRequest\n");
108-
ASSERT(FALSE);
114+
115+
//
116+
// get queue head
117+
//
118+
Status = Request->GetEndpointDescriptor(&NewQueueHead);
119+
if (!NT_SUCCESS(Status))
120+
{
121+
//
122+
// failed to create queue head
123+
//
124+
DPRINT1("[USBUHCI] Failed to create queue head %x\n", Status);
125+
return Status;
126+
}
127+
128+
if (Request->GetTransferType() == USB_ENDPOINT_TYPE_CONTROL)
129+
{
130+
//
131+
// get device speed
132+
//
133+
if (Request->GetDeviceSpeed() == UsbLowSpeed)
134+
{
135+
//
136+
// use low speed queue
137+
//
138+
m_Hardware->GetQueueHead(UHCI_LOW_SPEED_CONTROL_QUEUE, &QueueHead);
139+
}
140+
else
141+
{
142+
//
143+
// use full speed queue
144+
//
145+
m_Hardware->GetQueueHead(UHCI_FULL_SPEED_CONTROL_QUEUE, &QueueHead);
146+
}
147+
}
148+
else if (Request->GetTransferType() == USB_ENDPOINT_TYPE_BULK)
149+
{
150+
//
151+
// use full speed queue
152+
//
153+
m_Hardware->GetQueueHead(UHCI_BULK_QUEUE, &QueueHead);
154+
}
155+
else if (Request->GetTransferType() == USB_ENDPOINT_TYPE_INTERRUPT)
156+
{
157+
//
158+
// use full speed queue
159+
//
160+
m_Hardware->GetQueueHead(UHCI_INTERRUPT_QUEUE, &QueueHead);
161+
}
162+
else if (Request->GetTransferType() == USB_ENDPOINT_TYPE_INTERRUPT)
163+
{
164+
//
165+
// use full speed queue
166+
//
167+
m_Hardware->GetQueueHead(UHCI_INTERRUPT_QUEUE, &QueueHead);
168+
}
169+
170+
//
171+
// FIXME support isochronous
172+
//
173+
ASSERT(QueueHead);
174+
175+
//
176+
// add reference
177+
//
178+
Request->AddRef();
179+
180+
//
181+
// now link the new queue head
182+
//
183+
LinkQueueHead(QueueHead, NewQueueHead);
109184
return STATUS_SUCCESS;
110185
}
111186

187+
VOID
188+
CUSBQueue::LinkQueueHead(
189+
IN PUHCI_QUEUE_HEAD QueueHead,
190+
IN PUHCI_QUEUE_HEAD NextQueueHead)
191+
{
192+
NextQueueHead->LinkPhysical = QueueHead->LinkPhysical;
193+
NextQueueHead->NextLogicalDescriptor = QueueHead->NextLogicalDescriptor;
194+
195+
QueueHead->LinkPhysical = NextQueueHead->PhysicalAddress | QH_NEXT_IS_QH;
196+
QueueHead->NextLogicalDescriptor = (PVOID)NextQueueHead;
197+
}
198+
112199
NTSTATUS
113200
CUSBQueue::CancelRequests()
114201
{

0 commit comments

Comments
 (0)