win-pvdrivers

annotate xenusb/xenusb_huburb.c @ 1031:329b9b9d47ec

re-enable xenusb. compiles but untested.
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 21 20:37:38 2013 +1100 (2013-02-21)
parents ea3c61839ff5
children
rev   line source
james@655 1 /*
james@655 2 PV Drivers for Windows Xen HVM Domains
james@655 3 Copyright (C) 2007 James Harper
james@655 4
james@655 5 This program is free software; you can redistribute it and/or
james@655 6 modify it under the terms of the GNU General Public License
james@655 7 as published by the Free Software Foundation; either version 2
james@655 8 of the License, or (at your option) any later version.
james@655 9
james@655 10 This program is distributed in the hope that it will be useful,
james@655 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@655 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@655 13 GNU General Public License for more details.
james@655 14
james@655 15 You should have received a copy of the GNU General Public License
james@655 16 along with this program; if not, write to the Free Software
james@655 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@655 18 */
james@655 19
james@655 20 #include "xenusb.h"
james@655 21
james@655 22 VOID
james@655 23 XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB(
james@655 24 WDFQUEUE queue,
james@655 25 WDFREQUEST request,
james@655 26 size_t output_buffer_length,
james@655 27 size_t input_buffer_length,
james@655 28 ULONG io_control_code)
james@655 29 {
james@929 30 //NTSTATUS status;
james@655 31 WDFDEVICE device = WdfIoQueueGetDevice(queue);
james@655 32 PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
james@655 33 PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
james@655 34 WDF_REQUEST_PARAMETERS wrp;
james@655 35 PURB urb;
james@655 36 PUSBD_INTERFACE_INFORMATION interface_information;
james@655 37 ULONG i, j;
james@655 38 xenusb_device_t *usb_device;
james@655 39 xenusb_endpoint_t *endpoint;
james@929 40 //USB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
james@929 41 urb_decode_t decode_data;
james@929 42 ULONG decode_retval;
james@655 43
james@655 44 UNREFERENCED_PARAMETER(input_buffer_length);
james@655 45 UNREFERENCED_PARAMETER(output_buffer_length);
james@704 46 UNREFERENCED_PARAMETER(io_control_code);
james@655 47
james@930 48 //FUNCTION_ENTER();
james@655 49
james@655 50 WDF_REQUEST_PARAMETERS_INIT(&wrp);
james@655 51 WdfRequestGetParameters(request, &wrp);
james@655 52
james@655 53 urb = (PURB)wrp.Parameters.Others.Arg1;
james@655 54 ASSERT(urb);
james@930 55 #if 0
james@1031 56 FUNCTION_MSG("urb = %p\n", urb);
james@1031 57 FUNCTION_MSG(" Length = %d\n", urb->UrbHeader.Length);
james@1031 58 FUNCTION_MSG(" Function = %d\n", urb->UrbHeader.Function);
james@1031 59 FUNCTION_MSG(" Status = %d\n", urb->UrbHeader.Status);
james@1031 60 FUNCTION_MSG(" UsbdDeviceHandle = %p\n", urb->UrbHeader.UsbdDeviceHandle);
james@1031 61 FUNCTION_MSG(" UsbdFlags = %08x\n", urb->UrbHeader.UsbdFlags);
james@655 62 #endif
james@655 63 usb_device = urb->UrbHeader.UsbdDeviceHandle;
james@655 64
james@655 65 if (!usb_device)
james@655 66 usb_device = xupdd->usb_device;
james@655 67
james@929 68 decode_retval = XenUsb_DecodeControlUrb(urb, &decode_data);
james@929 69 if (decode_retval == URB_DECODE_UNKNOWN)
james@929 70 {
james@1031 71 FUNCTION_MSG("Unknown URB - Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL); //STATUS_UNSUCCESSFUL);
james@929 72 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
james@929 73 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
james@929 74 return;
james@929 75 }
james@929 76
james@929 77 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
james@929 78
james@929 79 if (decode_retval != URB_DECODE_NOT_CONTROL)
james@929 80 {
james@929 81 FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
james@929 82 FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@929 83 FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
james@929 84 FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
james@929 85 FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
james@929 86 FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@929 87 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
james@929 88 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
james@929 89 FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
james@929 90 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@929 91 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
james@929 92 FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
james@929 93 }
james@929 94
james@655 95 switch(urb->UrbHeader.Function)
james@655 96 {
james@655 97 case URB_FUNCTION_SELECT_CONFIGURATION:
james@1031 98 FUNCTION_MSG("URB_FUNCTION_SELECT_CONFIGURATION\n");
james@1031 99 FUNCTION_MSG(" ConfigurationDescriptor = %p\n", urb->UrbSelectConfiguration.ConfigurationDescriptor);
james@655 100 if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
james@655 101 {
james@1031 102 FUNCTION_MSG(" bLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength);
james@1031 103 FUNCTION_MSG(" bDescriptorType = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType);
james@1031 104 FUNCTION_MSG(" wTotalLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength);
james@1031 105 FUNCTION_MSG(" bNumInterfaces = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces);
james@1031 106 FUNCTION_MSG(" bConfigurationValue = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue);
james@1031 107 FUNCTION_MSG(" iConfiguration = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration);
james@1031 108 FUNCTION_MSG(" bmAttributes = %04x\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes);
james@1031 109 FUNCTION_MSG(" MaxPower = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
james@655 110 }
james@1031 111 FUNCTION_MSG(" ConfigurationHandle = %p\n", urb->UrbSelectConfiguration.ConfigurationHandle);
james@655 112 if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
james@655 113 {
james@662 114 urb->UrbSelectConfiguration.ConfigurationHandle = xupdd->usb_device->configs[0];
james@655 115 interface_information = &urb->UrbSelectConfiguration.Interface;
james@655 116 for (i = 0; i < urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; i++)
james@655 117 {
james@1031 118 FUNCTION_MSG("InterfaceInformation[%d]\n", i);
james@1031 119 FUNCTION_MSG(" Length = %d\n", interface_information->Length);
james@1031 120 FUNCTION_MSG(" InterfaceNumber = %d\n", interface_information->InterfaceNumber);
james@1031 121 FUNCTION_MSG(" AlternateSetting = %d\n", interface_information->AlternateSetting);
james@1031 122 FUNCTION_MSG(" Class = %02x\n", (ULONG)interface_information->Class);
james@1031 123 FUNCTION_MSG(" SubClass = %02x\n", (ULONG)interface_information->SubClass);
james@1031 124 FUNCTION_MSG(" Protocol = %02x\n", (ULONG)interface_information->Protocol);
james@1031 125 FUNCTION_MSG(" Reserved = %02x\n", (ULONG)interface_information->Reserved);
james@1031 126 FUNCTION_MSG(" InterfaceHandle = %p\n", interface_information->InterfaceHandle);
james@1031 127 FUNCTION_MSG(" NumberOfPipes = %d\n", interface_information->NumberOfPipes);
james@662 128 interface_information->InterfaceHandle = xupdd->usb_device->configs[0]->interfaces[0];
james@655 129 interface_information->Class = 0x09;
james@655 130 interface_information->SubClass = 0x00;
james@655 131 interface_information->SubClass = 0x00;
james@655 132 for (j = 0; j < interface_information->NumberOfPipes; j++)
james@655 133 {
james@1031 134 FUNCTION_MSG(" Pipe[%d]\n", i);
james@1031 135 FUNCTION_MSG(" MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize);
james@1031 136 FUNCTION_MSG(" EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress);
james@1031 137 FUNCTION_MSG(" Interval = %d\n", interface_information->Pipes[j].Interval);
james@1031 138 FUNCTION_MSG(" PipeType = %d\n", interface_information->Pipes[j].PipeType);
james@1031 139 FUNCTION_MSG(" PipeHandle = %d\n", interface_information->Pipes[j].PipeHandle);
james@1031 140 FUNCTION_MSG(" MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize);
james@1031 141 FUNCTION_MSG(" PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags);
james@655 142 interface_information->Pipes[j].MaximumPacketSize = 2;
james@655 143 interface_information->Pipes[j].EndpointAddress = 0x81;
james@655 144 interface_information->Pipes[j].Interval = 12;
james@655 145 interface_information->Pipes[j].PipeType = UsbdPipeTypeInterrupt;
james@662 146 interface_information->Pipes[j].PipeHandle = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[j];
james@655 147 interface_information->Pipes[j].MaximumTransferSize = 4096; /* made up number - possibly not used */
james@655 148 // this is input actually interface_information->Pipes[j].PipeFlags = 0;
james@655 149 }
james@655 150 interface_information = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)interface_information + interface_information->Length);
james@655 151 }
james@655 152 }
james@655 153 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@655 154 break;
james@655 155 case URB_FUNCTION_SELECT_INTERFACE:
james@1031 156 FUNCTION_MSG("URB_FUNCTION_SELECT_INTERFACE\n");
james@655 157 interface_information = &urb->UrbSelectInterface.Interface;
james@1031 158 FUNCTION_MSG("InterfaceInformation\n");
james@1031 159 FUNCTION_MSG(" Length = %d\n", interface_information->Length);
james@1031 160 FUNCTION_MSG(" InterfaceNumber = %d\n", interface_information->InterfaceNumber);
james@1031 161 FUNCTION_MSG(" AlternateSetting = %d\n", interface_information->AlternateSetting);
james@1031 162 FUNCTION_MSG(" Class = %02x\n", (ULONG)interface_information->Class);
james@1031 163 FUNCTION_MSG(" SubClass = %02x\n", (ULONG)interface_information->SubClass);
james@1031 164 FUNCTION_MSG(" Protocol = %02x\n", (ULONG)interface_information->Protocol);
james@1031 165 FUNCTION_MSG(" Reserved = %02x\n", (ULONG)interface_information->Reserved);
james@1031 166 FUNCTION_MSG(" InterfaceHandle = %p\n", interface_information->InterfaceHandle);
james@1031 167 FUNCTION_MSG(" NumberOfPipes = %d\n", interface_information->NumberOfPipes);
james@655 168 for (i = 0; i < interface_information->NumberOfPipes; i++)
james@655 169 {
james@1031 170 FUNCTION_MSG(" Pipe[%d]\n", i);
james@1031 171 FUNCTION_MSG(" MaximumPacketSize = %d\n", interface_information->Pipes[i].MaximumPacketSize);
james@1031 172 FUNCTION_MSG(" EndpointAddress = %d\n", interface_information->Pipes[i].EndpointAddress);
james@1031 173 FUNCTION_MSG(" Interval = %d\n", interface_information->Pipes[i].Interval);
james@1031 174 FUNCTION_MSG(" PipeType = %d\n", interface_information->Pipes[i].PipeType);
james@1031 175 FUNCTION_MSG(" PipeHandle = %d\n", interface_information->Pipes[i].PipeHandle);
james@1031 176 FUNCTION_MSG(" MaximumTransferSize = %d\n", interface_information->Pipes[i].MaximumTransferSize);
james@1031 177 FUNCTION_MSG(" PipeFlags = %08x\n", interface_information->Pipes[i].PipeFlags);
james@655 178 }
james@655 179 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
james@655 180 break;
james@930 181 #if (NTDDI_VERSION >= NTDDI_VISTA)
james@929 182 case URB_FUNCTION_CONTROL_TRANSFER_EX:
james@929 183 #endif
james@930 184 case URB_FUNCTION_CONTROL_TRANSFER:
james@930 185 case URB_FUNCTION_CLASS_DEVICE:
james@930 186 case URB_FUNCTION_CLASS_OTHER:
james@964 187 case URB_FUNCTION_CLASS_INTERFACE:
james@930 188 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
james@964 189 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
james@930 190 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
james@929 191 switch(decode_data.setup_packet.default_pipe_setup_packet.bRequest)
james@929 192 {
james@929 193 case USB_REQUEST_GET_STATUS:
james@929 194 // switch device, interface, endpoint
james@929 195 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type)
james@929 196 {
james@930 197 case BMREQUEST_STANDARD:
james@930 198 FUNCTION_MSG(" USB_REQUEST_GET_STATUS\n");
james@930 199 FUNCTION_MSG(" Type=Standard\n");
james@930 200 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@930 201 {
james@930 202 case BMREQUEST_TO_DEVICE:
james@1031 203 FUNCTION_MSG(" Recipient=Device\n");
james@930 204 ((PUSHORT)decode_data.buffer)[0] = 0x0001; /* self powered */
james@930 205 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 206 break;
james@930 207 default:
james@930 208 FUNCTION_MSG(" Recipient=%d\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@930 209 break;
james@930 210 }
james@929 211 break;
james@930 212 case BMREQUEST_CLASS:
james@930 213 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@930 214 {
james@930 215 case BMREQUEST_TO_DEVICE:
james@930 216 ((PUSHORT)decode_data.buffer)[0] = 0x0000;
james@930 217 ((PUSHORT)decode_data.buffer)[1] = 0x0000;
james@930 218 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 219 break;
james@930 220 case BMREQUEST_TO_OTHER:
james@930 221 FUNCTION_MSG(" USB_REQUEST_GET_STATUS\n");
james@930 222 FUNCTION_MSG(" Type=Class\n");
james@1031 223 FUNCTION_MSG(" Recipient=Other (port = %d)\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@930 224 ((PUSHORT)decode_data.buffer)[0] = xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status;
james@930 225 ((PUSHORT)decode_data.buffer)[1] = xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change;
james@930 226 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 227 FUNCTION_MSG(" status = %04x, change = %04x\n",
james@930 228 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status,
james@930 229 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change);
james@930 230 break;
james@930 231 default:
james@930 232 FUNCTION_MSG(" USB_REQUEST_GET_STATUS\n");
james@930 233 FUNCTION_MSG(" Type=Class\n");
james@930 234 FUNCTION_MSG(" Recipient=%d\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@930 235 break;
james@930 236 }
james@930 237 break;
james@930 238 default:
james@930 239 FUNCTION_MSG(" USB_REQUEST_GET_STATUS\n");
james@930 240 FUNCTION_MSG(" Type=%d\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
james@930 241 break;
james@929 242 }
james@930 243 break;
james@929 244 case USB_REQUEST_GET_DESCRIPTOR:
james@929 245 FUNCTION_MSG(" USB_REQUEST_GET_DESCRIPTOR\n");
james@930 246 // should separate into Standard and Class
james@929 247 switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte)
james@929 248 {
james@929 249 case USB_DEVICE_DESCRIPTOR_TYPE:
james@929 250 FUNCTION_MSG(" USB_DEVICE_DESCRIPTOR_TYPE\n");
james@930 251 FUNCTION_MSG(" length = %d\n", *decode_data.length);
james@930 252 memcpy(decode_data.buffer, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
james@930 253 *decode_data.length = sizeof(USB_DEVICE_DESCRIPTOR);
james@929 254 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 255 break;
james@929 256 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
james@929 257 {
james@929 258 xenusb_config_t *usb_config;
james@929 259 PUCHAR ptr;
james@929 260
james@929 261 FUNCTION_MSG(" USB_CONFIGURATION_DESCRIPTOR_TYPE\n");
james@930 262 FUNCTION_MSG(" length = %d\n", *decode_data.length);
james@929 263 usb_config = usb_device->active_config;
james@929 264 ptr = (PUCHAR)decode_data.buffer;
james@929 265 memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
james@929 266 ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
james@929 267 ((PUSB_CONFIGURATION_DESCRIPTOR)decode_data.buffer)->wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
james@929 268 if (*decode_data.length > 9)
james@929 269 {
james@929 270 for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
james@929 271 {
james@929 272 memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
james@929 273 ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
james@929 274 ((PUSB_CONFIGURATION_DESCRIPTOR)decode_data.buffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
james@929 275 for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
james@929 276 {
james@929 277 memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
james@929 278 ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
james@929 279 ((PUSB_CONFIGURATION_DESCRIPTOR)decode_data.buffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
james@929 280 }
james@929 281 }
james@929 282 }
james@929 283 *decode_data.length = ((PUSB_CONFIGURATION_DESCRIPTOR)decode_data.buffer)->wTotalLength;
james@929 284 //if (urb->UrbControlDescriptorRequest.TransferBufferLength == 9)
james@929 285 // ((PUSB_CONFIGURATION_DESCRIPTOR)decode_data.buffer)->wTotalLength = 32;
james@929 286 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 287 break;
james@929 288 }
james@930 289 case 0x00: // unknown... doing the same as 0x29 seems to work
james@930 290 FUNCTION_MSG(" USB_00_DESCRIPTOR_TYPE (doesn't exist)\n");
james@930 291 urb->UrbHeader.Status = USBD_STATUS_BAD_DESCRIPTOR;
james@930 292 break;
james@929 293 case 0x29: // Hub Descriptor
james@929 294 {
james@929 295 PUSB_HUB_DESCRIPTOR uhd;
james@929 296
james@930 297 FUNCTION_MSG(" USB_HUB_DESCRIPTOR_TYPE\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
james@930 298 FUNCTION_MSG(" length = %d\n", *decode_data.length);
james@930 299 uhd = decode_data.buffer;
james@930 300 // TODO adjust for real number of ports
james@930 301 *decode_data.length = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
james@930 302 uhd->bDescriptorLength = (UCHAR)*decode_data.length;
james@929 303 uhd->bDescriptorType = 0x29;
james@964 304 uhd->bNumberOfPorts = (UCHAR)xudd->num_ports;
james@929 305 uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
james@929 306 uhd->bPowerOnToPowerGood = 1; // 2ms units
james@929 307 uhd->bHubControlCurrent = 0;
james@929 308 // DeviceRemovable bits (includes an extra bit at the start)
james@929 309 uhd->bRemoveAndPowerMask[0] = 0;
james@929 310 uhd->bRemoveAndPowerMask[1] = 0;
james@929 311 // PortPwrCtrlMask
james@929 312 uhd->bRemoveAndPowerMask[2] = 0xFF;
james@929 313 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 314 break;
james@929 315 }
james@929 316 default:
james@929 317 FUNCTION_MSG(" USB_%02x_DESCRIPTOR_TYPE\n", (ULONG)decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
james@930 318 FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
james@930 319 FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@930 320 FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
james@930 321 FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
james@930 322 FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
james@930 323 FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@930 324 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
james@930 325 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
james@930 326 FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
james@930 327 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@930 328 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
james@930 329 FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
james@930 330 break;
james@930 331 }
james@930 332 break;
james@930 333 case USB_REQUEST_CLEAR_FEATURE:
james@930 334 FUNCTION_MSG(" USB_REQUEST_CLEAR_FEATURE\n");
james@930 335 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type)
james@930 336 {
james@930 337 case BMREQUEST_STANDARD: /* Standard */
james@1031 338 FUNCTION_MSG(" Type=Standard\n");
james@964 339 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@964 340 {
james@964 341 case BMREQUEST_TO_DEVICE:
james@1031 342 FUNCTION_MSG(" Recipient=Device\n");
james@964 343 switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.W)
james@964 344 {
james@964 345 case 1: /* DEVICE_REMOTE_WAKEUP */
james@1031 346 FUNCTION_MSG(" Feature=DEVICE_REMOTE_WAKEUP\n");
james@964 347 /* fake this */
james@964 348 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@964 349 break;
james@964 350 default:
james@964 351 FUNCTION_MSG(__DRIVER_NAME " Feature=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@964 352 break;
james@964 353 }
james@964 354 break;
james@964 355 default:
james@964 356 FUNCTION_MSG(__DRIVER_NAME " Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@964 357 break;
james@964 358 }
james@964 359 break;
james@930 360 break;
james@930 361 case BMREQUEST_CLASS: /* Class */
james@1031 362 FUNCTION_MSG(" Type=Class\n");
james@930 363 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@930 364 {
james@930 365 case BMREQUEST_TO_OTHER:
james@1031 366 FUNCTION_MSG(" Recipient=Other (port = %d)\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@930 367 switch (urb->UrbControlVendorClassRequest.Value)
james@930 368 {
james@930 369 case PORT_ENABLE:
james@1031 370 FUNCTION_MSG(" PORT_ENABLE\n");
james@930 371 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status &= ~(1 << PORT_ENABLE);
james@930 372 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 373 break;
james@964 374 case PORT_SUSPEND:
james@1031 375 FUNCTION_MSG(" PORT_SUSPEND (NOOP)\n");
james@964 376 /* do something here */
james@964 377 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@964 378 break;
james@930 379 case C_PORT_CONNECTION:
james@1031 380 FUNCTION_MSG(" C_PORT_CONNECTION\n");
james@930 381 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change &= ~(1 << PORT_CONNECTION);
james@930 382 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 383 break;
james@980 384 case C_PORT_ENABLE:
james@1031 385 FUNCTION_MSG(" C_PORT_ENABLE\n");
james@980 386 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change &= ~(1 << PORT_ENABLE);
james@980 387 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@980 388 break;
james@930 389 case C_PORT_RESET:
james@1031 390 FUNCTION_MSG(" C_PORT_RESET\n");
james@930 391 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change &= ~(1 << PORT_RESET);
james@930 392 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@930 393 break;
james@930 394 default:
james@1031 395 FUNCTION_MSG(" Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value);
james@930 396 break;
james@930 397 }
james@1031 398 FUNCTION_MSG(" status = %04x, change = %04x\n",
james@930 399 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status,
james@1031 400 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change);
james@930 401 break;
james@930 402 default:
james@930 403 FUNCTION_MSG(" Recipient=%d\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@930 404 break;
james@930 405 }
james@930 406 break;
james@930 407 default:
james@1031 408 FUNCTION_MSG(" Type=%d\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
james@929 409 break;
james@929 410 }
james@929 411 break;
james@929 412 case USB_REQUEST_SET_FEATURE:
james@1031 413 FUNCTION_MSG(" USB_REQUEST_SET_FEATURE\n");
james@1031 414 FUNCTION_MSG(" SetPortFeature\n");
james@929 415 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type)
james@929 416 {
james@929 417 case 0: /* Standard */
james@1031 418 FUNCTION_MSG(" Type=Standard\n");
james@964 419 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@964 420 {
james@964 421 case BMREQUEST_TO_DEVICE:
james@1031 422 FUNCTION_MSG(" Recipient=Device\n");
james@964 423 switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.W)
james@964 424 {
james@964 425 case 1: /* DEVICE_REMOTE_WAKEUP */
james@1031 426 FUNCTION_MSG(" Feature=DEVICE_REMOTE_WAKEUP\n");
james@964 427 /* fake this */
james@964 428 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@964 429 break;
james@964 430 default:
james@964 431 FUNCTION_MSG(__DRIVER_NAME " Feature=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@964 432 break;
james@964 433 }
james@964 434 break;
james@964 435 default:
james@964 436 FUNCTION_MSG(__DRIVER_NAME " Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@964 437 break;
james@964 438 }
james@929 439 break;
james@929 440 case 1: /* Class */
james@1031 441 FUNCTION_MSG(" Type=Class\n");
james@929 442 switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
james@929 443 {
james@929 444 case BMREQUEST_TO_OTHER:
james@1031 445 FUNCTION_MSG(" Recipient=Other (port = %d)\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@929 446 switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.W)
james@929 447 {
james@929 448 case PORT_ENABLE:
james@1031 449 FUNCTION_MSG(" PORT_ENABLE (NOOP)\n");
james@929 450 /* do something here */
james@929 451 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 452 break;
james@964 453 case PORT_SUSPEND:
james@1031 454 FUNCTION_MSG(" PORT_SUSPEND (NOOP)\n");
james@964 455 /* do something here */
james@964 456 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@964 457 break;
james@929 458 case PORT_RESET:
james@1031 459 FUNCTION_MSG(" PORT_RESET\n");
james@930 460 /* just fake the reset by setting the status bit to indicate that the reset is complete*/
james@964 461 //xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_RESET);
james@930 462 //xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].reset_counter = 10;
james@930 463 // TODO: maybe fake a 10ms time here...
james@930 464 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status &= ~(1 << PORT_RESET);
james@930 465 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_ENABLE);
james@929 466 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change |= (1 << PORT_RESET);
james@929 467 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@931 468 endpoint = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
james@931 469 XenUsbHub_ProcessHubInterruptEvent(endpoint);
james@929 470 break;
james@929 471 case PORT_POWER:
james@1031 472 FUNCTION_MSG(" PORT_POWER\n");
james@930 473 xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_POWER);
james@929 474 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 475 break;
james@929 476 default:
james@1031 477 FUNCTION_MSG(" PORT_%04X\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@929 478 break;
james@929 479 }
james@1031 480 FUNCTION_MSG(" status = %04x, change = %04x\n",
james@929 481 xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
james@1031 482 xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change);
james@929 483 break;
james@964 484 default:
james@964 485 FUNCTION_MSG(__DRIVER_NAME " Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@964 486 break;
james@929 487 }
james@929 488 break;
james@929 489 }
james@929 490 break;
james@929 491 default:
james@929 492 FUNCTION_MSG(" USB_REQUEST_%02x\n", (ULONG)decode_data.setup_packet.default_pipe_setup_packet.bRequest);
james@1031 493 FUNCTION_MSG(" TransferBufferLength returned = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength);
james@929 494 break;
james@929 495 }
james@929 496 break;
james@929 497 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
james@1031 498 FUNCTION_MSG("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n");
james@1031 499 FUNCTION_MSG(" PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle);
james@929 500 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@929 501 break;
james@964 502 case URB_FUNCTION_ABORT_PIPE:
james@1031 503 FUNCTION_MSG("URB_FUNCTION_ABORT_PIPE\n");
james@1031 504 FUNCTION_MSG(" PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle);
james@964 505 urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
james@964 506 break;
james@929 507 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
james@930 508 #if 0
james@1031 509 FUNCTION_MSG("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
james@1031 510 FUNCTION_MSG(" PipeHandle = %p\n", urb->UrbBulkOrInterruptTransfer.PipeHandle);
james@1031 511 FUNCTION_MSG(" TransferFlags = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags);
james@1031 512 FUNCTION_MSG(" TransferBufferLength = %d\n", urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
james@1031 513 FUNCTION_MSG(" TransferBuffer = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBuffer);
james@1031 514 FUNCTION_MSG(" TransferBufferMdl = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
james@929 515 #endif
james@929 516 endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;
james@931 517 //WdfSpinLockAcquire(endpoint->lock);
james@931 518 WdfRequestForwardToIoQueue(request, endpoint->queue);
james@931 519 XenUsbHub_ProcessHubInterruptEvent(endpoint);
james@931 520 //WdfSpinLockRelease(endpoint->lock);
james@930 521 //FUNCTION_EXIT();
james@929 522 return;
james@929 523
james@655 524 default:
james@929 525 FUNCTION_MSG("URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
james@930 526 if (decode_retval != URB_DECODE_NOT_CONTROL)
james@930 527 {
james@930 528 FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
james@930 529 FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
james@930 530 FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
james@930 531 FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
james@930 532 FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
james@930 533 FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
james@930 534 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
james@930 535 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
james@930 536 FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
james@930 537 FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
james@930 538 FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
james@930 539 FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
james@930 540 }
james@655 541 urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
james@655 542 break;
james@655 543 }
james@929 544 if (urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
james@929 545 {
james@930 546 //FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_SUCCESS);
james@929 547 WdfRequestComplete(request, STATUS_SUCCESS);
james@929 548 }
james@929 549 else
james@929 550 {
james@929 551 FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL);
james@929 552 WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
james@929 553 }
james@931 554
james@930 555 //FUNCTION_EXIT();
james@930 556 return;
james@655 557 }
james@655 558