win-pvdrivers

view xenusb/xenusb_devurb.c @ 1058:8b6500e0ebfc

Rename to fix case issue on shutdownmon directory
author James Harper <james.harper@bendigoit.com.au>
date Mon Sep 30 19:46:16 2013 +1000 (2013-09-30)
parents 329b9b9d47ec
children
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenusb.h"
22 #define EPROTO 71 /* Protocol error */
24 EVT_WDF_REQUEST_COMPLETION_ROUTINE XenUsb_CompletionBulkInterrupt;
26 static USBD_STATUS
27 XenUsb_GetUsbdStatusFromPvStatus(ULONG pvstatus) {
28 switch (pvstatus)
29 {
30 case 0:
31 return USBD_STATUS_SUCCESS;
32 case -EPROTO: /* -71 */
33 FUNCTION_MSG("pvstatus = -EPROTO\n");
34 return USBD_STATUS_CRC;
35 case -EPIPE: /* see linux code - EPIPE is when the HCD returned a stall */
36 FUNCTION_MSG("pvstatus = -EPIPE (USBD_STATUS_STALL_PID)\n");
37 return USBD_STATUS_STALL_PID;
38 #if 0
39 case -EOVERFLOW:
40 shadow->urb->UrbHeader.Status USBD_STATUS_DATA_OVERRUN;
41 break;
42 case -EREMOTEIO:
43 shadow->urb->UrbHeader.Status USBD_STATUS_ERROR_SHORT_TRANSFER;
44 break;
45 #endif
46 case -ESHUTDOWN: /* -108 */
47 FUNCTION_MSG("pvstatus = -ESHUTDOWN (USBD_STATUS_DEVICE_GONE)\n");
48 return USBD_STATUS_DEVICE_GONE;
49 default:
50 FUNCTION_MSG("pvstatus = %d\n", pvstatus);
51 return USBD_STATUS_INTERNAL_HC_ERROR;
52 }
53 }
55 VOID
56 XenUsb_CompletionBulkInterrupt(
57 WDFREQUEST request,
58 WDFIOTARGET target,
59 PWDF_REQUEST_COMPLETION_PARAMS params,
60 WDFCONTEXT context)
61 {
62 PURB urb;
63 pvurb_t *pvurb = context;
64 WDF_REQUEST_PARAMETERS wrp;
66 UNREFERENCED_PARAMETER(target);
68 FUNCTION_ENTER();
70 WDF_REQUEST_PARAMETERS_INIT(&wrp);
71 WdfRequestGetParameters(request, &wrp);
72 urb = (PURB)wrp.Parameters.Others.Arg1;
73 ASSERT(urb);
74 FUNCTION_MSG("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
75 FUNCTION_MSG("rsp id = %d\n", pvurb->rsp.id);
76 FUNCTION_MSG("rsp start_frame = %d\n", pvurb->rsp.start_frame);
77 FUNCTION_MSG("rsp status = %d\n", pvurb->rsp.status);
78 FUNCTION_MSG("rsp actual_length = %d\n", pvurb->rsp.actual_length);
79 FUNCTION_MSG("rsp error_count = %d\n", pvurb->rsp.error_count);
80 FUNCTION_MSG("total_length = %d\n", pvurb->total_length);
81 urb->UrbHeader.Status = XenUsb_GetUsbdStatusFromPvStatus(pvurb->rsp.status);
82 urb->UrbBulkOrInterruptTransfer.TransferBufferLength = (ULONG)params->IoStatus.Information;
83 if (urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
84 WdfRequestComplete(request, STATUS_SUCCESS);
85 else
86 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
87 FUNCTION_EXIT();
88 }
90 VOID
91 XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB(
92 WDFQUEUE queue,
93 WDFREQUEST request,
94 size_t output_buffer_length,
95 size_t input_buffer_length,
96 ULONG io_control_code)
97 {
98 NTSTATUS status;
99 WDFDEVICE device = WdfIoQueueGetDevice(queue);
100 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
101 WDF_REQUEST_PARAMETERS wrp;
102 WDF_MEMORY_DESCRIPTOR pvurb_descriptor;
103 WDFMEMORY pvurb_memory;
104 WDF_REQUEST_SEND_OPTIONS send_options;
105 PURB urb;
106 pvurb_t *pvurb;
107 pvurb_t local_pvurb; /* just use stack allocated space when submitting synchronously */
108 PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
109 PUSBD_INTERFACE_INFORMATION interface_information;
110 ULONG i, j;
111 xenusb_device_t *usb_device;
112 xenusb_endpoint_t *endpoint;
113 urb_decode_t decode_data;
114 ULONG decode_retval;
116 UNREFERENCED_PARAMETER(input_buffer_length);
117 UNREFERENCED_PARAMETER(output_buffer_length);
118 UNREFERENCED_PARAMETER(io_control_code);
120 FUNCTION_ENTER();
122 ASSERT(io_control_code == IOCTL_INTERNAL_USB_SUBMIT_URB);
124 status = STATUS_UNSUCCESSFUL;
126 WDF_REQUEST_PARAMETERS_INIT(&wrp);
127 WdfRequestGetParameters(request, &wrp);
129 urb = (PURB)wrp.Parameters.Others.Arg1;
130 ASSERT(urb);
131 #if 0
132 FUNCTION_MSG("urb = %p\n", urb);
133 FUNCTION_MSG(" Length = %d\n", urb->UrbHeader.Length);
134 FUNCTION_MSG(" Function = %d\n", urb->UrbHeader.Function);
135 FUNCTION_MSG(" Status = %d\n", urb->UrbHeader.Status);
136 FUNCTION_MSG(" UsbdDeviceHandle = %p\n", urb->UrbHeader.UsbdDeviceHandle);
137 FUNCTION_MSG(" UsbdFlags = %08x\n", urb->UrbHeader.UsbdFlags);
138 #endif
139 usb_device = urb->UrbHeader.UsbdDeviceHandle;
141 ASSERT(usb_device);
143 decode_retval = XenUsb_DecodeControlUrb(urb, &decode_data);
144 if (decode_retval == URB_DECODE_UNKNOWN)
145 {
146 FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL);
147 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
148 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
149 return;
150 }
152 #if 0
153 if (decode_retval != URB_DECODE_NOT_CONTROL)
154 {
155 FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
156 FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
157 FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
158 FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
159 FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
160 FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
161 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
162 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
163 FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
164 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
165 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
166 FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
167 }
168 #endif
170 switch(urb->UrbHeader.Function)
171 {
172 case URB_FUNCTION_SELECT_CONFIGURATION:
173 FUNCTION_MSG("URB_FUNCTION_SELECT_CONFIGURATION\n");
174 FUNCTION_MSG(" ConfigurationDescriptor = %p\n", urb->UrbSelectConfiguration.ConfigurationDescriptor);
175 if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
176 {
177 FUNCTION_MSG(" bLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength);
178 FUNCTION_MSG(" bDescriptorType = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType);
179 FUNCTION_MSG(" wTotalLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength);
180 FUNCTION_MSG(" bNumInterfaces = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces);
181 FUNCTION_MSG(" bConfigurationValue = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue);
182 FUNCTION_MSG(" iConfiguration = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration);
183 FUNCTION_MSG(" bmAttributes = %04x\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes);
184 FUNCTION_MSG(" MaxPower = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
185 }
186 if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
187 {
188 xenusb_config_t *usb_config = NULL;
189 for (i = 0; i < usb_device->device_descriptor.bNumConfigurations; i++)
190 {
191 if (usb_device->configs[i]->config_descriptor.bConfigurationValue == urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue)
192 usb_config = usb_device->configs[i];
193 }
194 urb->UrbSelectConfiguration.ConfigurationHandle = usb_config;
195 interface_information = &urb->UrbSelectConfiguration.Interface;
196 /* configuration is fully populated */
197 for (i = 0; i < urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; i++)
198 {
199 /* i think we need to pay attention to the alt setting here .. */
200 xenusb_interface_t *usb_interface = usb_config->interfaces[i];
201 interface_information->InterfaceNumber = usb_interface->interface_descriptor.bInterfaceNumber;
202 interface_information->AlternateSetting = usb_interface->interface_descriptor.bAlternateSetting;
203 interface_information->Class = usb_interface->interface_descriptor.bInterfaceClass;
204 interface_information->SubClass = usb_interface->interface_descriptor.bInterfaceSubClass;
205 interface_information->Protocol = usb_interface->interface_descriptor.bInterfaceProtocol;
206 interface_information->InterfaceHandle = usb_interface;
207 FUNCTION_MSG("InterfaceInformation[%d]\n", i);
208 FUNCTION_MSG(" Length = %d\n", interface_information->Length);
209 FUNCTION_MSG(" InterfaceNumber = %d\n", interface_information->InterfaceNumber);
210 FUNCTION_MSG(" AlternateSetting = %d\n", interface_information->AlternateSetting);
211 FUNCTION_MSG(" Class = %02x\n", (ULONG)interface_information->Class);
212 FUNCTION_MSG(" SubClass = %02x\n", (ULONG)interface_information->SubClass);
213 FUNCTION_MSG(" Protocol = %02x\n", (ULONG)interface_information->Protocol);
214 FUNCTION_MSG(" InterfaceHandle = %p\n", interface_information->InterfaceHandle);
215 FUNCTION_MSG(" NumberOfPipes = %d\n", interface_information->NumberOfPipes);
216 for (j = 0; j < interface_information->NumberOfPipes; j++)
217 {
218 xenusb_endpoint_t *usb_endpoint = usb_interface->endpoints[j];
219 FUNCTION_MSG(" Pipe[%d] (before)\n", j);
220 FUNCTION_MSG(" MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize);
221 FUNCTION_MSG(" EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress);
222 FUNCTION_MSG(" Interval = %d\n", interface_information->Pipes[j].Interval);
223 FUNCTION_MSG(" PipeType = %d\n", interface_information->Pipes[j].PipeType);
224 FUNCTION_MSG(" PipeHandle = %p\n", interface_information->Pipes[j].PipeHandle);
225 FUNCTION_MSG(" MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize);
226 FUNCTION_MSG(" PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags);
227 interface_information->Pipes[j].MaximumPacketSize = usb_endpoint->endpoint_descriptor.wMaxPacketSize;
228 interface_information->Pipes[j].EndpointAddress = usb_endpoint->endpoint_descriptor.bEndpointAddress;
229 interface_information->Pipes[j].Interval = usb_endpoint->endpoint_descriptor.bInterval;
230 switch (usb_endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
231 {
232 case USB_ENDPOINT_TYPE_CONTROL:
233 FUNCTION_MSG("USB_ENDPOINT_TYPE_CONTROL");
234 interface_information->Pipes[j].PipeType = UsbdPipeTypeControl;
235 break;
236 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
237 FUNCTION_MSG("USB_ENDPOINT_TYPE_ISOCHRONOUS");
238 interface_information->Pipes[j].PipeType = UsbdPipeTypeIsochronous;
239 break;
240 case USB_ENDPOINT_TYPE_BULK:
241 FUNCTION_MSG("USB_ENDPOINT_TYPE_BULK");
242 interface_information->Pipes[j].PipeType = UsbdPipeTypeBulk;
243 break;
244 case USB_ENDPOINT_TYPE_INTERRUPT:
245 FUNCTION_MSG("USB_ENDPOINT_TYPE_INTERRUPT");
246 interface_information->Pipes[j].PipeType = UsbdPipeTypeInterrupt;
247 break;
248 }
249 interface_information->Pipes[j].PipeHandle = usb_endpoint;
250 FUNCTION_MSG(" Pipe[%d] (after)\n", j);
251 FUNCTION_MSG(" MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize);
252 FUNCTION_MSG(" EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress);
253 FUNCTION_MSG(" Interval = %d\n", interface_information->Pipes[j].Interval);
254 FUNCTION_MSG(" PipeType = %d\n", interface_information->Pipes[j].PipeType);
255 FUNCTION_MSG(" PipeHandle = %p\n", interface_information->Pipes[j].PipeHandle);
256 FUNCTION_MSG(" MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize);
257 FUNCTION_MSG(" PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags);
258 }
259 interface_information = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)interface_information + interface_information->Length);
260 }
261 }
262 else
263 {
264 // ? unconfigure device here
265 }
266 pvurb = &local_pvurb; //ExAllocatePoolWithTag(NonPagedPool, sizeof(*pvurb), XENUSB_POOL_TAG);
267 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&pvurb_descriptor, pvurb, sizeof(*pvurb));
268 pvurb->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
269 pvurb->req.transfer_flags = 0;
270 pvurb->req.buffer_length = 0;
271 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb->req.u.ctrl;
272 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
273 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
274 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
275 setup_packet->bRequest = USB_REQUEST_SET_CONFIGURATION;
276 setup_packet->wLength = 0;
277 setup_packet->wValue.W = urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
278 setup_packet->wIndex.W = 0;
279 pvurb->mdl = NULL;
280 WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
281 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_SEC(10));
282 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, request, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
283 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
284 if (!NT_SUCCESS(status)) {
285 WdfRequestComplete(request, status);
286 } else {
287 FUNCTION_MSG("rsp start_frame = %d\n", pvurb->rsp.start_frame);
288 FUNCTION_MSG("rsp status = %d\n", pvurb->rsp.status);
289 FUNCTION_MSG("rsp actual_length = %d\n", pvurb->rsp.actual_length);
290 FUNCTION_MSG("rsp error_count = %d\n", pvurb->rsp.error_count);
291 urb->UrbHeader.Status = XenUsb_GetUsbdStatusFromPvStatus(pvurb->rsp.status);
292 WdfRequestComplete(request, pvurb->rsp.status?STATUS_UNSUCCESSFUL:STATUS_SUCCESS);
293 }
294 break;
295 case URB_FUNCTION_SELECT_INTERFACE:
296 FUNCTION_MSG("URB_FUNCTION_SELECT_INTERFACE\n");
297 interface_information = &urb->UrbSelectInterface.Interface;
298 FUNCTION_MSG("InterfaceInformation\n");
299 FUNCTION_MSG(" Length = %d\n", interface_information->Length);
300 FUNCTION_MSG(" InterfaceNumber = %d\n", interface_information->InterfaceNumber);
301 FUNCTION_MSG(" AlternateSetting = %d\n", interface_information->AlternateSetting);
302 FUNCTION_MSG(" Class = %02x\n", (ULONG)interface_information->Class);
303 FUNCTION_MSG(" SubClass = %02x\n", (ULONG)interface_information->SubClass);
304 FUNCTION_MSG(" Protocol = %02x\n", (ULONG)interface_information->Protocol);
305 FUNCTION_MSG(" Reserved = %02x\n", (ULONG)interface_information->Reserved);
306 FUNCTION_MSG(" InterfaceHandle = %p\n", interface_information->InterfaceHandle);
307 FUNCTION_MSG(" NumberOfPipes = %d\n", interface_information->NumberOfPipes);
308 for (i = 0; i < interface_information->NumberOfPipes; i++)
309 {
310 FUNCTION_MSG(" Pipe[%d]\n", i);
311 FUNCTION_MSG(" MaximumPacketSize = %d\n", interface_information->Pipes[i].MaximumPacketSize);
312 FUNCTION_MSG(" EndpointAddress = %d\n", interface_information->Pipes[i].EndpointAddress);
313 FUNCTION_MSG(" Interval = %d\n", interface_information->Pipes[i].Interval);
314 FUNCTION_MSG(" PipeType = %d\n", interface_information->Pipes[i].PipeType);
315 FUNCTION_MSG(" PipeHandle = %p\n", interface_information->Pipes[i].PipeHandle);
316 FUNCTION_MSG(" MaximumTransferSize = %d\n", interface_information->Pipes[i].MaximumTransferSize);
317 FUNCTION_MSG(" PipeFlags = %08x\n", interface_information->Pipes[i].PipeFlags);
318 }
320 pvurb = &local_pvurb; //ExAllocatePoolWithTag(NonPagedPool, sizeof(*pvurb), XENUSB_POOL_TAG);
321 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&pvurb_descriptor, pvurb, sizeof(*pvurb));
322 pvurb->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
323 pvurb->req.transfer_flags = 0;
324 pvurb->req.buffer_length = 0;
325 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb->req.u.ctrl;
326 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
327 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
328 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
329 setup_packet->bRequest = USB_REQUEST_SET_INTERFACE;
330 setup_packet->wLength = 0;
331 setup_packet->wValue.W = urb->UrbSelectInterface.Interface.AlternateSetting;
332 setup_packet->wIndex.W = urb->UrbSelectInterface.Interface.InterfaceNumber;
333 pvurb->mdl = NULL;
334 WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
335 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_SEC(10));
336 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, request, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
337 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
338 if (!NT_SUCCESS(status)) {
339 WdfRequestComplete(request, status);
340 } else {
341 FUNCTION_MSG("rsp start_frame = %d\n", pvurb->rsp.start_frame);
342 FUNCTION_MSG("rsp status = %d\n", pvurb->rsp.status);
343 FUNCTION_MSG("rsp actual_length = %d\n", pvurb->rsp.actual_length);
344 FUNCTION_MSG("rsp error_count = %d\n", pvurb->rsp.error_count);
345 urb->UrbHeader.Status = XenUsb_GetUsbdStatusFromPvStatus(pvurb->rsp.status);
346 WdfRequestComplete(request, pvurb->rsp.status?STATUS_UNSUCCESSFUL:STATUS_SUCCESS);
347 }
348 break;
349 #if (NTDDI_VERSION >= NTDDI_VISTA)
350 case URB_FUNCTION_CONTROL_TRANSFER_EX:
351 #endif
352 case URB_FUNCTION_CONTROL_TRANSFER:
353 case URB_FUNCTION_CLASS_DEVICE:
354 case URB_FUNCTION_CLASS_INTERFACE:
355 case URB_FUNCTION_CLASS_OTHER:
356 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
357 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
358 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
359 FUNCTION_MSG("URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
360 FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
361 FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
362 FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
363 FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
364 FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
365 FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
366 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
367 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
368 FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
369 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
370 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
371 FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
372 FUNCTION_MSG("decode_data.transfer_flags = %08x\n", decode_data.transfer_flags);
373 FUNCTION_MSG("*decode_data.length = %04x\n", *decode_data.length);
374 pvurb = &local_pvurb;
375 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&pvurb_descriptor, pvurb, sizeof(*pvurb));
376 pvurb->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
377 pvurb->req.transfer_flags = 0;
378 if (!(decode_data.transfer_flags & USBD_SHORT_TRANSFER_OK))
379 pvurb->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
380 if (decode_data.transfer_flags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
381 pvurb->req.pipe |= LINUX_PIPE_DIRECTION_IN;
382 else
383 pvurb->req.pipe |= LINUX_PIPE_DIRECTION_OUT;
384 memcpy(pvurb->req.u.ctrl, decode_data.setup_packet.raw, 8);
385 FUNCTION_MSG("req.pipe = %08x\n", pvurb->req.pipe);
386 FUNCTION_MSG("req.transfer_flags = %08x\n", pvurb->req.transfer_flags);
387 if (decode_data.buffer) {
388 FUNCTION_MSG("decode_data.buffer = %p\n", decode_data.buffer);
389 pvurb->mdl = IoAllocateMdl(decode_data.buffer, *decode_data.length, FALSE, FALSE, NULL);
390 FUNCTION_MSG("pvurb->mdl = %p\n", pvurb->mdl);
391 MmBuildMdlForNonPagedPool(pvurb->mdl);
392 } else {
393 FUNCTION_MSG("decode_data.mdl = %p\n", decode_data.mdl);
394 pvurb->mdl = decode_data.mdl;
395 }
396 WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
397 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_SEC(10));
398 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, request, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
399 if (decode_data.buffer)
400 IoFreeMdl(pvurb->mdl);
401 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
402 if (!NT_SUCCESS(status)) {
403 WdfRequestComplete(request, status);
404 } else {
405 FUNCTION_MSG("rsp start_frame = %d\n", pvurb->rsp.start_frame);
406 FUNCTION_MSG("rsp status = %d\n", pvurb->rsp.status);
407 FUNCTION_MSG("rsp actual_length = %d\n", pvurb->rsp.actual_length);
408 FUNCTION_MSG("rsp error_count = %d\n", pvurb->rsp.error_count);
409 urb->UrbHeader.Status = XenUsb_GetUsbdStatusFromPvStatus(pvurb->rsp.status);
410 WdfRequestComplete(request, pvurb->rsp.status?STATUS_UNSUCCESSFUL:STATUS_SUCCESS);
411 }
412 break;
413 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
414 endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;
415 FUNCTION_MSG("endpoint address = %02x\n", endpoint->endpoint_descriptor.bEndpointAddress);
416 FUNCTION_MSG("endpoint interval = %02x\n", endpoint->endpoint_descriptor.bInterval);
417 FUNCTION_MSG("pipe_direction_bit = %08x\n", endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN);
418 FUNCTION_MSG("short_ok_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK);
419 FUNCTION_MSG("flags_direction_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN);
420 FUNCTION_MSG("pipe_handle = %p\n", endpoint);
421 FUNCTION_MSG("pipe_value = %08x\n", endpoint->pipe_value);
423 pvurb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*pvurb), XENUSB_POOL_TAG);
424 status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES, pvurb, sizeof(*pvurb), &pvurb_memory);
425 ASSERT(NT_SUCCESS(status));
426 pvurb->req.pipe = endpoint->pipe_value;
427 pvurb->req.transfer_flags = 0;
428 if (!(urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK) && (endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN))
429 pvurb->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
430 pvurb->req.u.intr.interval = endpoint->endpoint_descriptor.bInterval; /* check this... maybe there is some overridden value that should be used? */
431 FUNCTION_MSG("req.pipe = %08x\n", pvurb->req.pipe);
432 FUNCTION_MSG("req.transfer_flags = %08x\n", pvurb->req.transfer_flags);
433 switch(endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
434 {
435 case USB_ENDPOINT_TYPE_BULK:
436 FUNCTION_MSG(" USB_ENDPOINT_TYPE_BULK\n");
437 break;
438 case USB_ENDPOINT_TYPE_INTERRUPT:
439 FUNCTION_MSG(" USB_ENDPOINT_TYPE_INTERRUPT\n");
440 break;
441 default:
442 FUNCTION_MSG(" USB_ENDPOINT_TYPE_%d\n", endpoint->endpoint_descriptor.bmAttributes);
443 break;
444 }
445 if (urb->UrbBulkOrInterruptTransfer.TransferBuffer) {
446 pvurb->mdl = IoAllocateMdl(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength, FALSE, FALSE, NULL);
447 MmBuildMdlForNonPagedPool(pvurb->mdl);
448 } else {
449 pvurb->mdl = urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
450 }
451 status = WdfIoTargetFormatRequestForInternalIoctlOthers(xupdd->bus_fdo_target, request, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, pvurb_memory, NULL, NULL, NULL, NULL, NULL);
452 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
453 if (!NT_SUCCESS(status)) {
454 if (urb->UrbBulkOrInterruptTransfer.TransferBuffer)
455 IoFreeMdl(pvurb->mdl);
456 WdfRequestComplete(request, status);
457 }
458 WdfRequestSetCompletionRoutine(request, XenUsb_CompletionBulkInterrupt, pvurb);
459 if (!WdfRequestSend(request, xupdd->bus_fdo_target, NULL)) {
460 FUNCTION_MSG("WdfRequestSend returned FALSE\n");
461 if (urb->UrbBulkOrInterruptTransfer.TransferBuffer)
462 IoFreeMdl(pvurb->mdl);
463 WdfRequestComplete(request, WdfRequestGetStatus(request));
464 }
465 break;
466 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
467 FUNCTION_MSG("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n");
468 FUNCTION_MSG(" PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle);
469 /* we only clear the stall here */
470 endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;
472 pvurb = &local_pvurb; //ExAllocatePoolWithTag(NonPagedPool, sizeof(*pvurb), XENUSB_POOL_TAG);
473 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&pvurb_descriptor, pvurb, sizeof(*pvurb));
474 pvurb->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
475 pvurb->req.transfer_flags = 0;
476 pvurb->req.buffer_length = 0;
477 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)pvurb->req.u.ctrl;
478 setup_packet->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
479 setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
480 setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
481 setup_packet->bRequest = USB_REQUEST_CLEAR_FEATURE;
482 setup_packet->wLength = 0;
483 setup_packet->wValue.W = 0; /* 0 == ENDPOINT_HALT */
484 setup_packet->wIndex.W = endpoint->endpoint_descriptor.bEndpointAddress;
485 pvurb->mdl = NULL;
486 WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
487 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_SEC(10));
488 status = WdfIoTargetSendInternalIoctlOthersSynchronously(xupdd->bus_fdo_target, request, IOCTL_INTERNAL_PVUSB_SUBMIT_URB, &pvurb_descriptor, NULL, NULL, &send_options, NULL);
489 FUNCTION_MSG("IOCTL_INTERNAL_PVUSB_SUBMIT_URB status = %08x\n", status);
490 if (!NT_SUCCESS(status)) {
491 WdfRequestComplete(request, status);
492 } else {
493 FUNCTION_MSG("rsp start_frame = %d\n", pvurb->rsp.start_frame);
494 FUNCTION_MSG("rsp status = %d\n", pvurb->rsp.status);
495 FUNCTION_MSG("rsp actual_length = %d\n", pvurb->rsp.actual_length);
496 FUNCTION_MSG("rsp error_count = %d\n", pvurb->rsp.error_count);
497 urb->UrbHeader.Status = XenUsb_GetUsbdStatusFromPvStatus(pvurb->rsp.status);
498 WdfRequestComplete(request, pvurb->rsp.status?STATUS_UNSUCCESSFUL:STATUS_SUCCESS);
499 }
500 break;
501 case URB_FUNCTION_ABORT_PIPE:
502 FUNCTION_MSG("URB_FUNCTION_ABORT_PIPE\n");
503 FUNCTION_MSG(" PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle);
504 /* just fake this.... i think we really need to flush any pending requests too */
505 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
506 WdfRequestComplete(request, STATUS_SUCCESS);
507 break;
508 default:
509 FUNCTION_MSG("URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
510 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
511 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
512 break;
513 }
514 FUNCTION_EXIT();
515 }