1 /* 2 * (C) Copyright 2003 3 * Gerry Hamel, geh@ti.com, Texas Instruments 4 * 5 * (C) Copyright 2006 6 * Bryan O'Donoghue, deckard@CodeHermit.ie 7 * 8 * Based on 9 * linux/drivers/usbd/ep0.c 10 * 11 * Copyright (c) 2000, 2001, 2002 Lineo 12 * Copyright (c) 2001 Hewlett Packard 13 * 14 * By: 15 * Stuart Lynne <sl@lineo.com>, 16 * Tom Rushworth <tbr@lineo.com>, 17 * Bruce Balden <balden@lineo.com> 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License 30 * along with this program; if not, write to the Free Software 31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 33 */ 34 35 /* 36 * This is the builtin ep0 control function. It implements all required functionality 37 * for responding to control requests (SETUP packets). 38 * 39 * XXX 40 * 41 * Currently we do not pass any SETUP packets (or other) to the configured 42 * function driver. This may need to change. 43 * 44 * XXX 45 * 46 * As alluded to above, a simple callback cdc_recv_setup has been implemented 47 * in the usb_device data structure to facilicate passing 48 * Common Device Class packets to a function driver. 49 * 50 * XXX 51 */ 52 53 #include <common.h> 54 #include <usbdevice.h> 55 56 #if 0 57 #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args) 58 #else 59 #define dbg_ep0(lvl,fmt,args...) 60 #endif 61 62 /* EP0 Configuration Set ********************************************************************* */ 63 64 65 /** 66 * ep0_get_status - fill in URB data with appropriate status 67 * @device: 68 * @urb: 69 * @index: 70 * @requesttype: 71 * 72 */ 73 static int ep0_get_status (struct usb_device_instance *device, 74 struct urb *urb, int index, int requesttype) 75 { 76 char *cp; 77 78 urb->actual_length = 2; 79 cp = (char*)urb->buffer; 80 cp[0] = cp[1] = 0; 81 82 switch (requesttype) { 83 case USB_REQ_RECIPIENT_DEVICE: 84 cp[0] = USB_STATUS_SELFPOWERED; 85 break; 86 case USB_REQ_RECIPIENT_INTERFACE: 87 break; 88 case USB_REQ_RECIPIENT_ENDPOINT: 89 cp[0] = usbd_endpoint_halted (device, index); 90 break; 91 case USB_REQ_RECIPIENT_OTHER: 92 urb->actual_length = 0; 93 default: 94 break; 95 } 96 dbg_ep0 (2, "%02x %02x", cp[0], cp[1]); 97 return 0; 98 } 99 100 /** 101 * ep0_get_one 102 * @device: 103 * @urb: 104 * @result: 105 * 106 * Set a single byte value in the urb send buffer. Return non-zero to signal 107 * a request error. 108 */ 109 static int ep0_get_one (struct usb_device_instance *device, struct urb *urb, 110 __u8 result) 111 { 112 urb->actual_length = 1; /* XXX 2? */ 113 ((char *) urb->buffer)[0] = result; 114 return 0; 115 } 116 117 /** 118 * copy_config 119 * @urb: pointer to urb 120 * @data: pointer to configuration data 121 * @length: length of data 122 * 123 * Copy configuration data to urb transfer buffer if there is room for it. 124 */ 125 void copy_config (struct urb *urb, void *data, int max_length, 126 int max_buf) 127 { 128 int available; 129 int length; 130 131 /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */ 132 /* urb->actual_length, urb->buffer_length, max_buf, max_length, data); */ 133 134 if (!data) { 135 dbg_ep0 (1, "data is NULL"); 136 return; 137 } 138 length = max_length; 139 140 if (length > max_length) { 141 dbg_ep0 (1, "length: %d >= max_length: %d", length, 142 max_length); 143 return; 144 } 145 /*dbg_ep0(1, " actual: %d buf: %d max_buf: %d max_length: %d length: %d", */ 146 /* urb->actual_length, urb->buffer_length, max_buf, max_length, length); */ 147 148 if ((available = 149 /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) { 150 return; 151 } 152 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */ 153 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */ 154 155 if (length > available) { 156 length = available; 157 } 158 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */ 159 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */ 160 161 memcpy (urb->buffer + urb->actual_length, data, length); 162 urb->actual_length += length; 163 164 dbg_ep0 (3, 165 "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d", 166 urb->actual_length, urb->buffer_length, max_buf, max_length, 167 available); 168 } 169 170 /** 171 * ep0_get_descriptor 172 * @device: 173 * @urb: 174 * @max: 175 * @descriptor_type: 176 * @index: 177 * 178 * Called by ep0_rx_process for a get descriptor device command. Determine what 179 * descriptor is being requested, copy to send buffer. Return zero if ok to send, 180 * return non-zero to signal a request error. 181 */ 182 static int ep0_get_descriptor (struct usb_device_instance *device, 183 struct urb *urb, int max, int descriptor_type, 184 int index) 185 { 186 int port = 0; /* XXX compound device */ 187 188 /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */ 189 190 if (!urb || !urb->buffer || !urb->buffer_length 191 || (urb->buffer_length < 255)) { 192 dbg_ep0 (2, "invalid urb %p", urb); 193 return -1L; 194 } 195 196 /* setup tx urb */ 197 urb->actual_length = 0; 198 199 dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type)); 200 201 switch (descriptor_type) { 202 case USB_DESCRIPTOR_TYPE_DEVICE: 203 { 204 struct usb_device_descriptor *device_descriptor; 205 if (! 206 (device_descriptor = 207 usbd_device_device_descriptor (device, port))) { 208 return -1; 209 } 210 /* copy descriptor for this device */ 211 copy_config (urb, device_descriptor, 212 sizeof (struct usb_device_descriptor), 213 max); 214 215 /* correct the correct control endpoint 0 max packet size into the descriptor */ 216 device_descriptor = 217 (struct usb_device_descriptor *) urb->buffer; 218 219 } 220 dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length); 221 break; 222 223 case USB_DESCRIPTOR_TYPE_CONFIGURATION: 224 { 225 struct usb_configuration_descriptor 226 *configuration_descriptor; 227 struct usb_device_descriptor *device_descriptor; 228 if (! 229 (device_descriptor = 230 usbd_device_device_descriptor (device, port))) { 231 return -1; 232 } 233 /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */ 234 if (index >= device_descriptor->bNumConfigurations) { 235 dbg_ep0 (0, "index too large: %d >= %d", index, 236 device_descriptor-> 237 bNumConfigurations); 238 return -1; 239 } 240 241 if (! 242 (configuration_descriptor = 243 usbd_device_configuration_descriptor (device, 244 port, 245 index))) { 246 dbg_ep0 (0, 247 "usbd_device_configuration_descriptor failed: %d", 248 index); 249 return -1; 250 } 251 dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength)); 252 copy_config (urb, configuration_descriptor, 253 254 cpu_to_le16(configuration_descriptor->wTotalLength), 255 max); 256 } 257 258 break; 259 260 case USB_DESCRIPTOR_TYPE_STRING: 261 { 262 struct usb_string_descriptor *string_descriptor; 263 if (!(string_descriptor = usbd_get_string (index))) { 264 serial_printf("Invalid string index %d\n", index); 265 return -1; 266 } 267 dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength); 268 copy_config (urb, string_descriptor, string_descriptor->bLength, max); 269 } 270 break; 271 case USB_DESCRIPTOR_TYPE_INTERFACE: 272 serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n"); 273 return -1; 274 case USB_DESCRIPTOR_TYPE_ENDPOINT: 275 serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n"); 276 return -1; 277 case USB_DESCRIPTOR_TYPE_HID: 278 { 279 serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n"); 280 return -1; /* unsupported at this time */ 281 #if 0 282 int bNumInterface = 283 le16_to_cpu (urb->device_request.wIndex); 284 int bAlternateSetting = 0; 285 int class = 0; 286 struct usb_class_descriptor *class_descriptor; 287 288 if (!(class_descriptor = 289 usbd_device_class_descriptor_index (device, 290 port, 0, 291 bNumInterface, 292 bAlternateSetting, 293 class)) 294 || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) { 295 dbg_ep0 (3, "[%d] interface is not HID", 296 bNumInterface); 297 return -1; 298 } 299 /* copy descriptor for this class */ 300 copy_config (urb, class_descriptor, 301 class_descriptor->descriptor.hid.bLength, 302 max); 303 #endif 304 } 305 break; 306 case USB_DESCRIPTOR_TYPE_REPORT: 307 { 308 serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n"); 309 return -1; /* unsupported at this time */ 310 #if 0 311 int bNumInterface = 312 le16_to_cpu (urb->device_request.wIndex); 313 int bAlternateSetting = 0; 314 int class = 0; 315 struct usb_class_report_descriptor *report_descriptor; 316 317 if (!(report_descriptor = 318 usbd_device_class_report_descriptor_index 319 (device, port, 0, bNumInterface, 320 bAlternateSetting, class)) 321 || report_descriptor->bDescriptorType != 322 USB_DT_REPORT) { 323 dbg_ep0 (3, "[%d] descriptor is not REPORT", 324 bNumInterface); 325 return -1; 326 } 327 /* copy report descriptor for this class */ 328 /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */ 329 if (max - urb->actual_length > 0) { 330 int length = 331 MIN (report_descriptor->wLength, 332 max - urb->actual_length); 333 memcpy (urb->buffer + urb->actual_length, 334 &report_descriptor->bData[0], length); 335 urb->actual_length += length; 336 } 337 #endif 338 } 339 break; 340 case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: 341 { 342 /* If a USB device supports both a full speed and low speed operation 343 * we must send a Device_Qualifier descriptor here 344 */ 345 return -1; 346 } 347 default: 348 return -1; 349 } 350 351 352 dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d", 353 urb->buffer, urb->buffer_length, urb->actual_length, 354 device->bus->endpoint_array[0].tx_packetSize); 355 /* 356 if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) { 357 dbg_ep0(0, "adding null byte"); 358 urb->buffer[urb->actual_length++] = 0; 359 dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d", 360 urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize); 361 } 362 */ 363 return 0; 364 365 } 366 367 /** 368 * ep0_recv_setup - called to indicate URB has been received 369 * @urb: pointer to struct urb 370 * 371 * Check if this is a setup packet, process the device request, put results 372 * back into the urb and return zero or non-zero to indicate success (DATA) 373 * or failure (STALL). 374 * 375 */ 376 int ep0_recv_setup (struct urb *urb) 377 { 378 /*struct usb_device_request *request = urb->buffer; */ 379 /*struct usb_device_instance *device = urb->device; */ 380 381 struct usb_device_request *request; 382 struct usb_device_instance *device; 383 int address; 384 385 dbg_ep0 (0, "entering ep0_recv_setup()"); 386 if (!urb || !urb->device) { 387 dbg_ep0 (3, "invalid URB %p", urb); 388 return -1; 389 } 390 391 request = &urb->device_request; 392 device = urb->device; 393 394 dbg_ep0 (3, "urb: %p device: %p", urb, urb->device); 395 396 397 /*dbg_ep0(2, "- - - - - - - - - -"); */ 398 399 dbg_ep0 (2, 400 "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s", 401 request->bmRequestType, request->bRequest, 402 le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex), 403 le16_to_cpu (request->wLength), 404 USBD_DEVICE_REQUESTS (request->bRequest)); 405 406 /* handle USB Standard Request (c.f. USB Spec table 9-2) */ 407 if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) { 408 if(device->device_state <= STATE_CONFIGURED){ 409 /* Attempt to handle a CDC specific request if we are 410 * in the configured state. 411 */ 412 return device->cdc_recv_setup(request,urb); 413 } 414 dbg_ep0 (1, "non standard request: %x", 415 request->bmRequestType & USB_REQ_TYPE_MASK); 416 return -1; /* Stall here */ 417 } 418 419 switch (device->device_state) { 420 case STATE_CREATED: 421 case STATE_ATTACHED: 422 case STATE_POWERED: 423 /* It actually is important to allow requests in these states, 424 * Windows will request descriptors before assigning an 425 * address to the client. 426 */ 427 428 /*dbg_ep0 (1, "request %s not allowed in this state: %s", */ 429 /* USBD_DEVICE_REQUESTS(request->bRequest), */ 430 /* usbd_device_states[device->device_state]); */ 431 /*return -1; */ 432 break; 433 434 case STATE_INIT: 435 case STATE_DEFAULT: 436 switch (request->bRequest) { 437 case USB_REQ_GET_STATUS: 438 case USB_REQ_GET_INTERFACE: 439 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */ 440 case USB_REQ_CLEAR_FEATURE: 441 case USB_REQ_SET_FEATURE: 442 case USB_REQ_SET_DESCRIPTOR: 443 /* case USB_REQ_SET_CONFIGURATION: */ 444 case USB_REQ_SET_INTERFACE: 445 dbg_ep0 (1, 446 "request %s not allowed in DEFAULT state: %s", 447 USBD_DEVICE_REQUESTS (request->bRequest), 448 usbd_device_states[device->device_state]); 449 return -1; 450 451 case USB_REQ_SET_CONFIGURATION: 452 case USB_REQ_SET_ADDRESS: 453 case USB_REQ_GET_DESCRIPTOR: 454 case USB_REQ_GET_CONFIGURATION: 455 break; 456 } 457 case STATE_ADDRESSED: 458 case STATE_CONFIGURED: 459 break; 460 case STATE_UNKNOWN: 461 dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s", 462 USBD_DEVICE_REQUESTS (request->bRequest), 463 usbd_device_states[device->device_state]); 464 return -1; 465 } 466 467 /* handle all requests that return data (direction bit set on bm RequestType) */ 468 if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) { 469 470 dbg_ep0 (3, "Device-to-Host"); 471 472 switch (request->bRequest) { 473 474 case USB_REQ_GET_STATUS: 475 return ep0_get_status (device, urb, request->wIndex, 476 request->bmRequestType & 477 USB_REQ_RECIPIENT_MASK); 478 479 case USB_REQ_GET_DESCRIPTOR: 480 return ep0_get_descriptor (device, urb, 481 le16_to_cpu (request->wLength), 482 le16_to_cpu (request->wValue) >> 8, 483 le16_to_cpu (request->wValue) & 0xff); 484 485 case USB_REQ_GET_CONFIGURATION: 486 serial_printf("get config %d\n", device->configuration); 487 return ep0_get_one (device, urb, 488 device->configuration); 489 490 case USB_REQ_GET_INTERFACE: 491 return ep0_get_one (device, urb, device->alternate); 492 493 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */ 494 return -1; 495 496 case USB_REQ_CLEAR_FEATURE: 497 case USB_REQ_SET_FEATURE: 498 case USB_REQ_SET_ADDRESS: 499 case USB_REQ_SET_DESCRIPTOR: 500 case USB_REQ_SET_CONFIGURATION: 501 case USB_REQ_SET_INTERFACE: 502 return -1; 503 } 504 } 505 /* handle the requests that do not return data */ 506 else { 507 508 509 /*dbg_ep0(3, "Host-to-Device"); */ 510 switch (request->bRequest) { 511 512 case USB_REQ_CLEAR_FEATURE: 513 case USB_REQ_SET_FEATURE: 514 dbg_ep0 (0, "Host-to-Device"); 515 switch (request-> 516 bmRequestType & USB_REQ_RECIPIENT_MASK) { 517 case USB_REQ_RECIPIENT_DEVICE: 518 /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */ 519 /* XXX fall through for now as we do not support either */ 520 case USB_REQ_RECIPIENT_INTERFACE: 521 case USB_REQ_RECIPIENT_OTHER: 522 dbg_ep0 (0, "request %s not", 523 USBD_DEVICE_REQUESTS (request->bRequest)); 524 default: 525 return -1; 526 527 case USB_REQ_RECIPIENT_ENDPOINT: 528 dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue)); 529 if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) { 530 /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */ 531 /* request->bRequest == USB_REQ_SET_FEATURE); */ 532 /* NEED TO IMPLEMENT THIS!!! */ 533 return -1; 534 } else { 535 dbg_ep0 (1, "request %s bad wValue: %04x", 536 USBD_DEVICE_REQUESTS 537 (request->bRequest), 538 le16_to_cpu (request->wValue)); 539 return -1; 540 } 541 } 542 543 case USB_REQ_SET_ADDRESS: 544 /* check if this is a re-address, reset first if it is (this shouldn't be possible) */ 545 if (device->device_state != STATE_DEFAULT) { 546 dbg_ep0 (1, "set_address: %02x state: %s", 547 le16_to_cpu (request->wValue), 548 usbd_device_states[device->device_state]); 549 return -1; 550 } 551 address = le16_to_cpu (request->wValue); 552 if ((address & 0x7f) != address) { 553 dbg_ep0 (1, "invalid address %04x %04x", 554 address, address & 0x7f); 555 return -1; 556 } 557 device->address = address; 558 559 /*dbg_ep0(2, "address: %d %d %d", */ 560 /* request->wValue, le16_to_cpu(request->wValue), device->address); */ 561 562 return 0; 563 564 case USB_REQ_SET_DESCRIPTOR: /* XXX should we support this? */ 565 dbg_ep0 (0, "set descriptor: NOT SUPPORTED"); 566 return -1; 567 568 case USB_REQ_SET_CONFIGURATION: 569 /* c.f. 9.4.7 - the top half of wValue is reserved */ 570 device->configuration = le16_to_cpu(request->wValue) & 0xff; 571 572 /* reset interface and alternate settings */ 573 device->interface = device->alternate = 0; 574 575 /*dbg_ep0(2, "set configuration: %d", device->configuration); */ 576 /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */ 577 return 0; 578 579 case USB_REQ_SET_INTERFACE: 580 device->interface = le16_to_cpu (request->wIndex); 581 device->alternate = le16_to_cpu (request->wValue); 582 /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */ 583 serial_printf ("DEVICE_SET_INTERFACE.. event?\n"); 584 return 0; 585 586 case USB_REQ_GET_STATUS: 587 case USB_REQ_GET_DESCRIPTOR: 588 case USB_REQ_GET_CONFIGURATION: 589 case USB_REQ_GET_INTERFACE: 590 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */ 591 return -1; 592 } 593 } 594 return -1; 595 } 596