win-pvdrivers

view xenusb/xenusb_decode.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 DECODE_COMPUTE 0x40000000 /* calculate the value - not applicable to all fields */
23 #define DECODE_COPY 0x80000000 /* copy from URB */
24 /* otherwise literal value */
26 typedef struct {
27 PCHAR urb_function_name;
28 BOOLEAN is_simple_control;
29 ULONG bmRequestTypeRecipient;
30 ULONG bmRequestTypeType;
31 ULONG bmRequestTypeDir;
32 ULONG bRequest;
33 ULONG wValueLow;
34 ULONG wValueHigh;
35 ULONG wIndexLow;
36 ULONG wIndexHigh;
37 ULONG wLength;
38 ULONG transfer_flags;
39 } decode_t;
41 static decode_t decodes[] = {
42 /* 0000 */
43 {"URB_FUNCTION_SELECT_CONFIGURATION", FALSE},
44 {"URB_FUNCTION_SELECT_INTERFACE", FALSE},
45 {"URB_FUNCTION_ABORT_PIPE", FALSE},
46 {"URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL", FALSE},
47 {"URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL", FALSE},
48 {"URB_FUNCTION_GET_FRAME_LENGTH", FALSE},
49 {"URB_FUNCTION_SET_FRAME_LENGTH", FALSE},
50 {"URB_FUNCTION_GET_CURRENT_FRAME_NUMBER", FALSE},
51 {"URB_FUNCTION_CONTROL_TRANSFER", TRUE, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
52 {"URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER", FALSE},
53 {"URB_FUNCTION_ISOCH_TRANSFER", FALSE},
54 {"URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE", TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
55 {"URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE", FALSE},
56 {"URB_FUNCTION_SET_FEATURE_TO_DEVICE", FALSE},
57 {"URB_FUNCTION_SET_FEATURE_TO_INTERFACE", FALSE},
58 {"URB_FUNCTION_SET_FEATURE_TO_ENDPOINT", FALSE},
59 /* 0010 */
60 {"URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE", FALSE},
61 {"URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE", FALSE},
62 {"URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT", FALSE},
63 {"URB_FUNCTION_GET_STATUS_FROM_DEVICE", FALSE},
64 {"URB_FUNCTION_GET_STATUS_FROM_INTERFACE", FALSE},
65 {"URB_FUNCTION_GET_STATUS_FROM_ENDPOINT", FALSE},
66 {"URB_FUNCTION_RESERVED_0X0016", FALSE},
67 {"URB_FUNCTION_VENDOR_DEVICE", TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
68 {"URB_FUNCTION_VENDOR_INTERFACE", TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
69 {"URB_FUNCTION_VENDOR_ENDPOINT", TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
70 {"URB_FUNCTION_CLASS_DEVICE", TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
71 {"URB_FUNCTION_CLASS_INTERFACE", TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
72 {"URB_FUNCTION_CLASS_ENDPOINT", TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
73 {"URB_FUNCTION_RESERVE_0X001D", FALSE},
74 {"URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL", FALSE},
75 {"URB_FUNCTION_CLASS_OTHER", TRUE, BMREQUEST_TO_OTHER, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
76 /* 0020 */
77 {"URB_FUNCTION_VENDOR_OTHER", TRUE, BMREQUEST_TO_OTHER, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
78 {"URB_FUNCTION_GET_STATUS_FROM_OTHER", FALSE},
79 {"URB_FUNCTION_CLEAR_FEATURE_TO_OTHER", FALSE},
80 {"URB_FUNCTION_SET_FEATURE_TO_OTHER", FALSE},
81 {"URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT", TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
82 {"URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT", FALSE},
83 {"URB_FUNCTION_GET_CONFIGURATION", FALSE},
84 {"URB_FUNCTION_GET_INTERFACE", FALSE},
85 {"URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE", TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
86 {"URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE", FALSE},
87 {"URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR", FALSE},
88 {"URB_FUNCTION_RESERVE_0X002B", FALSE},
89 {"URB_FUNCTION_RESERVE_0X002C", FALSE},
90 {"URB_FUNCTION_RESERVE_0X002D", FALSE},
91 {"URB_FUNCTION_RESERVE_0X002E", FALSE},
92 {"URB_FUNCTION_RESERVE_0X002F", FALSE},
93 /* 0030 */
94 {"URB_FUNCTION_SYNC_RESET_PIPE", FALSE},
95 {"URB_FUNCTION_SYNC_CLEAR_STALL", FALSE},
96 {"URB_FUNCTION_CONTROL_TRANSFER_EX", TRUE, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
97 {"URB_FUNCTION_RESERVE_0X0033", FALSE},
98 {"URB_FUNCTION_RESERVE_0X0034", FALSE},
99 };
101 /*
102 decode all the funky URB_Xxx functions into a basic 8 byte SetupPacket
103 */
104 ULONG
105 XenUsb_DecodeControlUrb(PURB urb, urb_decode_t *decode_data)
106 {
107 ULONG retval;
108 decode_t *decode;
109 PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
111 if (urb->UrbHeader.Function > ARRAY_SIZE(decodes)) {
112 FUNCTION_MSG("Unknown URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
113 return URB_DECODE_UNKNOWN;
114 }
115 decode = &decodes[urb->UrbHeader.Function];
116 FUNCTION_MSG("decoding %s\n", decode->urb_function_name);
118 if (decode->is_simple_control) {
119 FUNCTION_MSG("is a simple control URB\n");
121 setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)urb->UrbControlTransfer.SetupPacket;
123 if (decode->bmRequestTypeRecipient == DECODE_COPY)
124 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = setup_packet->bmRequestType.Recipient;
125 else
126 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = (UCHAR)decode->bmRequestTypeRecipient;
127 if (decode->bmRequestTypeType == DECODE_COPY)
128 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = setup_packet->bmRequestType.Type;
129 else
130 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = (UCHAR)decode->bmRequestTypeType;
131 if (decode->bmRequestTypeDir == DECODE_COPY)
132 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = setup_packet->bmRequestType.Dir;
133 else
134 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = (UCHAR)decode->bmRequestTypeDir;
136 if (decode->bRequest == DECODE_COPY)
137 decode_data->setup_packet.default_pipe_setup_packet.bRequest = setup_packet->bRequest;
138 else
139 decode_data->setup_packet.default_pipe_setup_packet.bRequest = (UCHAR)decode->bRequest;
141 if (decode->wValueLow == DECODE_COPY)
142 decode_data->setup_packet.default_pipe_setup_packet.wValue.LowByte = setup_packet->wValue.LowByte;
143 else
144 decode_data->setup_packet.default_pipe_setup_packet.wValue.LowByte = (UCHAR)decode->wValueLow;
146 if (decode->wValueHigh == DECODE_COPY)
147 decode_data->setup_packet.default_pipe_setup_packet.wValue.HiByte = setup_packet->wValue.HiByte;
148 else
149 decode_data->setup_packet.default_pipe_setup_packet.wValue.HiByte = (UCHAR)decode->wValueHigh;
151 if (decode->wIndexLow == DECODE_COPY)
152 decode_data->setup_packet.default_pipe_setup_packet.wIndex.LowByte = setup_packet->wIndex.LowByte;
153 else
154 decode_data->setup_packet.default_pipe_setup_packet.wIndex.LowByte = (UCHAR)decode->wIndexLow;
156 if (decode->wIndexHigh == DECODE_COPY)
157 decode_data->setup_packet.default_pipe_setup_packet.wIndex.HiByte = setup_packet->wIndex.HiByte;
158 else
159 decode_data->setup_packet.default_pipe_setup_packet.wIndex.HiByte = (UCHAR)decode->wIndexHigh;
161 if (decode->wLength == DECODE_COMPUTE)
162 /* use buffer length */
163 decode_data->setup_packet.default_pipe_setup_packet.wLength = (USHORT)urb->UrbControlTransfer.TransferBufferLength;
164 else if (decode->wLength == DECODE_COPY)
165 decode_data->setup_packet.default_pipe_setup_packet.wLength = setup_packet->wLength;
166 else
167 decode_data->setup_packet.default_pipe_setup_packet.wLength = (UCHAR)decode->wLength;
169 if (decode->transfer_flags == DECODE_COMPUTE) {
170 /* Fix up transfer_flags based on direction in bmRequest */
171 if (decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST)
172 decode_data->transfer_flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
173 else
174 decode_data->transfer_flags = 0;
175 } else if (decode->transfer_flags == DECODE_COPY) {
176 decode_data->transfer_flags = urb->UrbControlTransfer.TransferFlags;
177 } else {
178 decode_data->transfer_flags = decode->transfer_flags;
179 }
182 decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
183 decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
184 decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
186 return URB_DECODE_COMPLETE;
187 }
189 //FUNCTION_ENTER();
190 switch(urb->UrbHeader.Function)
191 {
192 case URB_FUNCTION_SELECT_CONFIGURATION:
193 FUNCTION_MSG("URB_FUNCTION_SELECT_CONFIGURATION\n");
194 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
195 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = BMREQUEST_STANDARD;
196 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
197 decode_data->setup_packet.default_pipe_setup_packet.bRequest = USB_REQUEST_SET_CONFIGURATION;
198 decode_data->setup_packet.default_pipe_setup_packet.wLength = 0;
199 decode_data->setup_packet.default_pipe_setup_packet.wValue.W = urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
200 decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = 0;
201 decode_data->transfer_flags = 0;
202 decode_data->buffer = NULL;
203 decode_data->mdl = NULL;
204 retval = URB_DECODE_INCOMPLETE;
205 break;
206 case URB_FUNCTION_SELECT_INTERFACE:
207 FUNCTION_MSG("URB_FUNCTION_SELECT_INTERFACE\n");
208 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
209 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = BMREQUEST_STANDARD;
210 decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
211 decode_data->setup_packet.default_pipe_setup_packet.bRequest = USB_REQUEST_SET_INTERFACE;
212 decode_data->setup_packet.default_pipe_setup_packet.wLength = 0;
213 decode_data->setup_packet.default_pipe_setup_packet.wValue.W = urb->UrbSelectInterface.Interface.AlternateSetting;
214 decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = urb->UrbSelectInterface.Interface.InterfaceNumber;
215 decode_data->transfer_flags = 0;
216 decode_data->buffer = NULL;
217 decode_data->mdl = NULL;
218 retval = URB_DECODE_INCOMPLETE;
219 break;
220 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
221 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
222 case URB_FUNCTION_ABORT_PIPE:
223 FUNCTION_MSG("NOT_CONTROL URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
224 retval = URB_DECODE_NOT_CONTROL;
225 break;
226 default:
227 FUNCTION_MSG("NOT IMPLEMENTED\n", urb->UrbHeader.Function);
228 retval = URB_DECODE_UNKNOWN;
229 break;
230 }
231 //FUNCTION_EXIT();
232 return retval;
233 }