[CMAKE]
[reactos.git] / drivers / usb / usbehci / transfer.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/transfer.c
5 * PURPOSE: Transfers to EHCI.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 */
9
10 #include "transfer.h"
11 #include <debug.h>
12
13 VOID
14 BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup)
15 {
16 switch (Urb->UrbHeader.Function)
17 {
18 /* CLEAR FEATURE */
19 case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:
20 case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
21 case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
22 DPRINT1("Not implemented!\n");
23 break;
24
25 /* GET CONFIG */
26 case URB_FUNCTION_GET_CONFIGURATION:
27 CtrlSetup->bRequest = USB_REQUEST_GET_CONFIGURATION;
28 CtrlSetup->bmRequestType.B = 0x80;
29 CtrlSetup->wLength = 1;
30 break;
31
32 /* GET DESCRIPTOR */
33 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
34 CtrlSetup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
35 CtrlSetup->wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
36 CtrlSetup->wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
37 CtrlSetup->wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
38 CtrlSetup->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
39 CtrlSetup->bmRequestType.B = 0x80;
40 break;
41
42 /* GET INTERFACE */
43 case URB_FUNCTION_GET_INTERFACE:
44 CtrlSetup->bRequest = USB_REQUEST_GET_CONFIGURATION;
45 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
46 CtrlSetup->bmRequestType.B = 0x80;
47 CtrlSetup->wLength = 1;
48 break;
49
50 /* GET STATUS */
51 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
52 CtrlSetup->bRequest = USB_REQUEST_GET_STATUS;
53 ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
54 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
55 CtrlSetup->bmRequestType.B = 0x80;
56 CtrlSetup->wLength = 2;
57 break;
58
59 case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
60 CtrlSetup->bRequest = USB_REQUEST_GET_STATUS;
61 ASSERT(Urb->UrbControlGetStatusRequest.Index != 0);
62 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
63 CtrlSetup->bmRequestType.B = 0x81;
64 CtrlSetup->wLength = 2;
65 break;
66
67 case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
68 CtrlSetup->bRequest = USB_REQUEST_GET_STATUS;
69 ASSERT(Urb->UrbControlGetStatusRequest.Index != 0);
70 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
71 CtrlSetup->bmRequestType.B = 0x82;
72 CtrlSetup->wLength = 2;
73 break;
74
75 /* SET ADDRESS */
76
77 /* SET CONFIG */
78 case URB_FUNCTION_SELECT_CONFIGURATION:
79 CtrlSetup->bRequest = USB_REQUEST_SET_CONFIGURATION;
80 CtrlSetup->bmRequestType.B = 0x00;
81 break;
82
83 /* SET DESCRIPTOR */
84 case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
85 case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
86 case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
87 DPRINT1("Not implemented\n");
88 break;
89
90 /* SET FEATURE */
91 case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
92 CtrlSetup->bRequest = USB_REQUEST_SET_FEATURE;
93 ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
94 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
95 CtrlSetup->bmRequestType.B = 0x80;
96 break;
97
98 case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
99 CtrlSetup->bRequest = USB_REQUEST_SET_FEATURE;
100 ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
101 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
102 CtrlSetup->bmRequestType.B = 0x81;
103 break;
104
105 case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
106 CtrlSetup->bRequest = USB_REQUEST_SET_FEATURE;
107 ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
108 CtrlSetup->wIndex.W = Urb->UrbControlGetStatusRequest.Index;
109 CtrlSetup->bmRequestType.B = 0x82;
110 break;
111
112 /* SET INTERFACE*/
113 case URB_FUNCTION_SELECT_INTERFACE:
114 DPRINT1("Not implemented\n");
115 break;
116
117 /* SYNC FRAME */
118 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
119 DPRINT1("Not implemented\n");
120 break;
121 default:
122 DPRINT1("Unknown USB Request!\n");
123 break;
124 }
125 }
126
127 BOOLEAN
128 SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
129 PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
130 PVOID TransferBuffer,
131 ULONG TransferBufferLength,
132 PIRP IrpToComplete)
133 {
134 PQUEUE_HEAD QueueHead;
135 PQUEUE_TRANSFER_DESCRIPTOR Descriptor[3];
136 ULONG MdlPhysicalAddr;
137 PKEVENT Event = NULL;
138 PMDL pMdl = NULL;
139 PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetupVA, CtrlPhysicalPA;
140
141 CtrlSetupVA = (PUSB_DEFAULT_PIPE_SETUP_PACKET)AllocateMemory(hcd,
142 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET),
143 (ULONG*)&CtrlPhysicalPA);
144
145 RtlCopyMemory(CtrlSetupVA, CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
146 /* If no Irp then wait on completion */
147 if (IrpToComplete == NULL)
148 {
149 Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
150 KeInitializeEvent(Event, NotificationEvent, FALSE);
151 }
152
153 /* Allocate Mdl for Buffer */
154 pMdl = IoAllocateMdl(TransferBuffer,
155 TransferBufferLength,
156 FALSE,
157 FALSE,
158 NULL);
159
160 /* Lock Physical Pages */
161 MmBuildMdlForNonPagedPool(pMdl);
162 //MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
163
164 MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
165
166 QueueHead = CreateQueueHead(hcd);
167
168 Descriptor[0] = CreateDescriptor(hcd,
169 PID_CODE_SETUP_TOKEN,
170 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
171
172 Descriptor[0]->Token.Bits.InterruptOnComplete = FALSE;
173 Descriptor[0]->Token.Bits.DataToggle = FALSE;
174
175 /* Save the first descriptor */
176 QueueHead->TransferDescriptor = Descriptor[0];
177
178 Descriptor[1] = CreateDescriptor(hcd,
179 PID_CODE_IN_TOKEN,
180 TransferBufferLength);
181
182 Descriptor[2] = CreateDescriptor(hcd,
183 PID_CODE_OUT_TOKEN,
184 0);
185
186 Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE;
187
188 /* Link the descriptors */
189 Descriptor[0]->NextDescriptor = Descriptor[1];
190 Descriptor[1]->NextDescriptor = Descriptor[2];
191 Descriptor[1]->PreviousDescriptor = Descriptor[0];
192 Descriptor[2]->PreviousDescriptor = Descriptor[1];
193
194 /* Assign the descritors buffers */
195 Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
196 Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
197
198 Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr;
199 Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
200 QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
201
202 QueueHead->IrpToComplete = IrpToComplete;
203 QueueHead->MdlToFree = pMdl;
204 QueueHead->Event = Event;
205
206 /* Link in the QueueHead */
207 LinkQueueHead(hcd, QueueHead);
208
209 if (IrpToComplete == NULL)
210 {
211 DPRINT1("Waiting For Completion %x!\n", Event);
212 KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
213 ExFreePool(Event);
214 }
215
216 return TRUE;
217 }