Error checking for USB interrupt transfer
[minix3.git] / drivers / usbd / hcd / hcd.c
blob216eaa5282ee1d287f987f5033ee4a6e0a1d5ab8
1 /*
2 * Implementation of generic HCD
3 */
5 #include <string.h> /* memcpy */
7 #include <minix/drivers.h> /* errno with sign */
8 #include <minix/usb.h> /* USB_TRANSFER_CTL... */
10 #include <usb/hcd_common.h>
11 #include <usb/hcd_ddekit.h>
12 #include <usb/hcd_interface.h>
13 #include <usb/usb_common.h>
16 /*===========================================================================*
17 * Local declarations *
18 *===========================================================================*/
19 /* Thread to handle device logic */
20 static void hcd_device_thread(void *);
22 /* Procedure that locks device thread forever in case of error/completion */
23 static void hcd_device_finish(hcd_device_state *, const char *);
25 /* Typical USD device communication procedures */
26 static int hcd_enumerate(hcd_device_state *);
27 static int hcd_get_device_descriptor(hcd_device_state *);
28 static int hcd_set_address(hcd_device_state *, int);
29 static int hcd_get_descriptor_tree(hcd_device_state *);
30 static int hcd_set_configuration(hcd_device_state *, int);
31 static int hcd_handle_urb(hcd_device_state *);
32 static int hcd_control_urb(hcd_device_state *);
33 static int hcd_non_control_urb(hcd_device_state *, int);
35 /* For internal use by more general methods */
36 static int hcd_setup_packet(hcd_device_state *, hcd_ctrlrequest *);
37 static int hcd_data_transfer(hcd_device_state *, hcd_datarequest *);
40 /*===========================================================================*
41 * Local definitions *
42 *===========================================================================*/
43 /* TODO: Only one device at a time
44 * If ever HUB functionality is added, one must remember that disconnecting
45 * HUB, means disconnecting every device attached to it, so data structure may
46 * have to be altered to allow that */
47 static hcd_device_state hcd_device[1];
50 /*===========================================================================*
51 * hcd_handle_event *
52 *===========================================================================*/
53 void
54 hcd_handle_event(hcd_driver_state * driver)
56 hcd_device_state * this_device;
58 DEBUG_DUMP;
60 /* TODO: Finding which hcd_device is in use should be performed here */
61 this_device = &(hcd_device[0]);
63 /* Sometimes interrupts occur in a weird order (EP after disconnect)
64 * This helps finding ordering errors in DEBUG */
65 USB_DBG("Event: 0x%02X, state: 0x%02X",
66 driver->current_event, this_device->state);
68 /* Set what was received for device thread to use */
69 this_device->driver = driver;
71 /* Handle event and forward control to device thread when required */
72 switch (driver->current_event) {
73 case HCD_EVENT_CONNECTED:
74 if (HCD_STATE_DISCONNECTED == this_device->state) {
75 if (EXIT_SUCCESS != hcd_connect_device(
76 this_device,
77 hcd_device_thread))
78 USB_MSG("Device creation failed");
79 } else
80 USB_MSG("Device not marked as 'disconnected' "
81 "for 'connection' event");
83 break;
85 case HCD_EVENT_DISCONNECTED:
86 if (HCD_STATE_DISCONNECTED != this_device->state) {
87 /* If connect callback was used before, call
88 * it's equivalent to signal disconnection */
89 if (HCD_STATE_CONNECTED == this_device->state)
90 hcd_disconnect_cb(this_device);
91 hcd_disconnect_device(this_device);
92 this_device->state = HCD_STATE_DISCONNECTED;
93 } else
94 USB_MSG("Device is marked as 'disconnected' "
95 "for 'disconnection' event");
97 break;
99 case HCD_EVENT_ENDPOINT:
100 case HCD_EVENT_URB:
101 /* Allow device thread to continue with it's logic */
102 if (HCD_STATE_DISCONNECTED != this_device->state)
103 hcd_device_continue(this_device);
104 else
105 USB_MSG("Device is marked as 'disconnected' "
106 "for 'EP' event");
108 break;
110 default:
111 USB_ASSERT(0, "Illegal HCD event");
112 break;
117 /*===========================================================================*
118 * hcd_device_thread *
119 *===========================================================================*/
120 static void
121 hcd_device_thread(void * thread_args)
123 hcd_device_state * this_device;
125 DEBUG_DUMP;
127 /* Retrieve structures from generic data */
128 this_device = (hcd_device_state *)thread_args;
130 /* Plugged in */
131 this_device->state = HCD_STATE_CONNECTION_PENDING;
133 /* Enumeration sequence */
134 if (EXIT_SUCCESS != hcd_enumerate(this_device))
135 hcd_device_finish(this_device, "USB device enumeration failed");
137 /* Tell everyone that device was connected */
138 hcd_connect_cb(this_device);
140 /* Fully configured */
141 this_device->state = HCD_STATE_CONNECTED;
143 USB_DBG("Waiting for URBs");
145 /* Start handling URB's */
146 for(;;) {
147 /* No URB's yet */
148 this_device->urb = NULL;
150 /* Block and wait for something like 'submit URB' */
151 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_NO_ENDPOINT);
153 if (EXIT_SUCCESS != hcd_handle_urb(this_device))
154 hcd_device_finish(this_device, "URB handling failed");
157 /* Finish device handling to avoid leaving thread */
158 hcd_device_finish(this_device, "USB device handling completed");
162 /*===========================================================================*
163 * hcd_device_finish *
164 *===========================================================================*/
165 static void
166 hcd_device_finish(hcd_device_state * this_device, const char * finish_msg)
168 DEBUG_DUMP;
170 USB_MSG("USB device handling finished with message: '%s'", finish_msg);
172 /* Lock forever */
173 for (;;) {
174 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_NO_ENDPOINT);
175 USB_MSG("Failed attempt to continue finished thread");
180 /*===========================================================================*
181 * hcd_enumerate *
182 *===========================================================================*/
183 static int
184 hcd_enumerate(hcd_device_state * this_device)
186 hcd_driver_state * d;
188 DEBUG_DUMP;
190 d = this_device->driver;
192 /* First let driver reset device */
193 if (EXIT_SUCCESS != d->reset_device(d->private_data,
194 &(this_device->speed))) {
195 USB_MSG("Failed to reset device");
196 return EXIT_FAILURE;
199 /* Get device descriptor */
200 if (EXIT_SUCCESS != hcd_get_device_descriptor(this_device)) {
201 USB_MSG("Failed to get device descriptor");
202 return EXIT_FAILURE;
205 /* TODO: dynamic device address when more devices are available */
207 /* Set address */
208 if (EXIT_SUCCESS != hcd_set_address(this_device, HCD_ATTACHED_ADDR)) {
209 USB_MSG("Failed to set device address");
210 return EXIT_FAILURE;
213 /* Set parameters for further communication */
214 d->setup_device(d->private_data, HCD_DEFAULT_EP, this_device->address);
216 /* Get other descriptors */
217 if (EXIT_SUCCESS != hcd_get_descriptor_tree(this_device)) {
218 USB_MSG("Failed to get configuration descriptor tree");
219 return EXIT_FAILURE;
222 /* TODO: always first configuration */
223 /* Set configuration */
224 if (EXIT_SUCCESS != hcd_set_configuration(this_device, 0x01)) {
225 USB_MSG("Failed to set configuration");
226 return EXIT_FAILURE;
229 USB_DBG("Enumeration completed");
231 return EXIT_SUCCESS;
235 /*===========================================================================*
236 * hcd_get_device_descriptor *
237 *===========================================================================*/
238 static int
239 hcd_get_device_descriptor(hcd_device_state * this_device)
241 hcd_ctrlrequest setup;
243 DEBUG_DUMP;
245 /* TODO: magic numbers, no header for these */
247 /* Format setup packet */
248 setup.bRequestType = 0x80; /* IN */
249 setup.bRequest = 0x06; /* Get descriptor */
250 setup.wValue = 0x0100; /* Device */
251 setup.wIndex = 0x0000;
252 setup.wLength = sizeof(this_device->device_desc);
254 /* Handle formatted setup packet */
255 if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup)) {
256 USB_MSG("Handling setup packet failed");
257 return EXIT_FAILURE;
260 /* Put what was read in device descriptor */
261 memcpy(&(this_device->device_desc), this_device->buffer,
262 sizeof(this_device->device_desc));
264 /* Remember max packet size from device descriptor */
265 this_device->max_packet_size = this_device->device_desc.bMaxPacketSize;
267 /* Dump device descriptor in debug mode */
268 #ifdef DEBUG
270 hcd_device_descriptor * d;
271 d = &(this_device->device_desc);
273 USB_DBG("<<DEVICE>>");
274 USB_DBG("bLength %02X", d->bLength);
275 USB_DBG("bDescriptorType %02X", d->bDescriptorType);
276 USB_DBG("bcdUSB %04X", UGETW(d->bcdUSB));
277 USB_DBG("bDeviceClass %02X", d->bDeviceClass);
278 USB_DBG("bDeviceSubClass %02X", d->bDeviceSubClass);
279 USB_DBG("bDeviceProtocol %02X", d->bDeviceProtocol);
280 USB_DBG("bMaxPacketSize %02X", d->bMaxPacketSize);
281 USB_DBG("idVendor %04X", UGETW(d->idVendor));
282 USB_DBG("idProduct %04X", UGETW(d->idProduct));
283 USB_DBG("bcdDevice %04X", UGETW(d->bcdDevice));
284 USB_DBG("iManufacturer %02X", d->iManufacturer);
285 USB_DBG("iProduct %02X", d->iProduct);
286 USB_DBG("iSerialNumber %02X", d->iSerialNumber);
287 USB_DBG("bNumConfigurations %02X", d->bNumConfigurations);
289 #endif
291 return EXIT_SUCCESS;
295 /*===========================================================================*
296 * hcd_set_address *
297 *===========================================================================*/
298 static int
299 hcd_set_address(hcd_device_state * this_device, int address)
301 hcd_ctrlrequest setup;
303 DEBUG_DUMP;
305 USB_ASSERT((address > 0) && (address < 128), "Illegal address");
307 /* TODO: magic numbers, no header for these */
308 setup.bRequestType = 0x00; /* OUT */
309 setup.bRequest = 0x05; /* Set address */
310 setup.wValue = address;
311 setup.wIndex = 0x0000;
312 setup.wLength = 0x0000;
314 /* Handle formatted setup packet */
315 if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup)) {
316 USB_MSG("Handling setup packet failed");
317 return EXIT_FAILURE;
320 /* Sleep 5msec to allow addressing */
321 hcd_os_nanosleep(HCD_NANOSLEEP_MSEC(5));
323 /* Remember what was assigned in hardware */
324 this_device->address = address;
326 return EXIT_SUCCESS;
330 /*===========================================================================*
331 * hcd_get_descriptor_tree *
332 *===========================================================================*/
333 static int
334 hcd_get_descriptor_tree(hcd_device_state * this_device)
336 hcd_config_descriptor config_descriptor;
337 hcd_ctrlrequest setup;
338 int completed;
339 int total_length;
340 int buffer_length;
342 DEBUG_DUMP;
344 /* First, ask only for configuration itself to get length info */
345 buffer_length = sizeof(config_descriptor);
346 completed = 0;
348 do {
349 /* TODO: configuration 0 is hard-coded
350 * but others are rarely used anyway */
351 /* TODO: magic numbers, no header for these */
352 setup.bRequestType = 0x80; /* IN */
353 setup.bRequest = 0x06; /* Get descriptor */
354 setup.wValue = 0x0200; /* Configuration 0 */
355 setup.wIndex = 0x0000;
356 setup.wLength = buffer_length;
358 /* Handle formatted setup packet */
359 if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup)) {
360 USB_MSG("Handling setup packet failed");
361 return EXIT_FAILURE;
364 /* If we only asked for configuration itself
365 * then ask again for other descriptors */
366 if (sizeof(config_descriptor) == buffer_length) {
368 /* Put what was read in configuration descriptor */
369 memcpy(&config_descriptor, this_device->buffer,
370 sizeof(config_descriptor));
372 /* Continue only if there is more data */
373 total_length = config_descriptor.wTotalLength[0] +
374 (config_descriptor.wTotalLength[1] << 8);
376 if (total_length < (int)sizeof(config_descriptor)) {
377 /* This should never happen for a fine device */
378 USB_MSG("Illegal wTotalLength value");
379 return EXIT_FAILURE;
381 else if (sizeof(config_descriptor) == total_length) {
382 /* Nothing more was in descriptor anyway */
383 completed = 1;
385 else {
386 /* Read whatever is needed */
387 buffer_length = total_length;
390 } else {
391 /* All data for given configuration was read */
392 completed = 1;
395 while (!completed);
397 /* Create tree based on received buffer */
398 if (EXIT_SUCCESS != hcd_buffer_to_tree(this_device->buffer,
399 this_device->data_len,
400 &(this_device->config_tree))) {
401 /* This should never happen for a fine device */
402 USB_MSG("Illegal descriptor values");
403 return EXIT_FAILURE;
406 return EXIT_SUCCESS;
410 /*===========================================================================*
411 * hcd_set_configuration *
412 *===========================================================================*/
413 static int
414 hcd_set_configuration(hcd_device_state * this_device, int configuration)
416 hcd_ctrlrequest setup;
418 DEBUG_DUMP;
420 /* TODO: magic numbers, no header for these */
421 setup.bRequestType = 0x00; /* OUT */
422 setup.bRequest = 0x09; /* Set configuration */
423 setup.wValue = configuration;
424 setup.wIndex = 0x0000;
425 setup.wLength = 0x0000;
427 /* Handle formatted setup packet */
428 if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup)) {
429 USB_MSG("Handling setup packet failed");
430 return EXIT_FAILURE;
433 return EXIT_SUCCESS;
437 /*===========================================================================*
438 * hcd_handle_urb *
439 *===========================================================================*/
440 static int
441 hcd_handle_urb(hcd_device_state * this_device)
443 hcd_urb * urb;
444 int transfer_status;
446 DEBUG_DUMP;
448 transfer_status = EXIT_FAILURE;
449 urb = this_device->urb;
451 USB_ASSERT(NULL != urb, "NULL URB given");
452 /* TODO: One device only */
453 USB_ASSERT((void *)this_device != (void *)urb->dev,
454 "Unknown device for URB");
456 switch (urb->type) {
458 case USB_TRANSFER_CTL:
459 transfer_status = hcd_control_urb(this_device);
460 break;
462 case USB_TRANSFER_BLK:
463 case USB_TRANSFER_INT:
464 transfer_status = hcd_non_control_urb(this_device,
465 urb->type);
466 break;
468 case USB_TRANSFER_ISO:
469 /* TODO: ISO transfer */
470 USB_MSG("ISO transfer not supported");
471 break;
473 default:
474 USB_MSG("Invalid transfer type 0x%X", urb->type);
475 break;
478 if (EXIT_SUCCESS != transfer_status)
479 USB_MSG("USB transfer failed");
481 /* Call completion regardless of status */
482 hcd_completion_cb(urb->priv);
484 /* TODO: Only critical failures should ever yield EXIT_FAILURE, so
485 * return is not bound to transfer_status for now, to let device
486 * driver act accordingly */
487 return EXIT_SUCCESS;
491 /*===========================================================================*
492 * hcd_control_urb *
493 *===========================================================================*/
494 static int
495 hcd_control_urb(hcd_device_state * this_device)
497 hcd_urb * urb;
498 hcd_ctrlrequest setup;
500 DEBUG_DUMP;
502 urb = this_device->urb;
504 /* Assume bad values unless something different occurs later */
505 urb->status = EINVAL;
507 /* Must have setup packet */
508 if (NULL == urb->setup_packet) {
509 USB_MSG("No setup packet in URB, for control transfer");
510 return EXIT_FAILURE;
513 /* TODO: Only EP0 can have control transfer */
514 if (0 != urb->endpoint) {
515 USB_MSG("Control transfer for non zero EP");
516 return EXIT_FAILURE;
519 /* Hold setup packet and analyze it */
520 memcpy(&setup, urb->setup_packet, sizeof(setup));
522 /* TODO: broken constants for urb->direction (USB_OUT...) */
523 if (((setup.bRequestType >> 7) & 0x01) != urb->direction) {
524 USB_MSG("URB Direction mismatch");
525 return EXIT_FAILURE;
528 /* Send setup packet */
529 if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup)) {
530 USB_MSG("Sending URB setup packet, failed");
531 urb->status = EPIPE;
532 return EXIT_FAILURE;
535 urb->status = EXIT_SUCCESS;
536 return EXIT_SUCCESS;
540 /*===========================================================================*
541 * hcd_non_control_urb *
542 *===========================================================================*/
543 static int
544 hcd_non_control_urb(hcd_device_state * this_device, int type)
546 hcd_endpoint * e;
547 hcd_datarequest request;
548 hcd_urb * urb;
550 DEBUG_DUMP;
552 urb = this_device->urb;
554 /* Assume bad values unless something different occurs later */
555 urb->status = EINVAL;
557 if (NULL == urb->data) {
558 USB_MSG("No data packet in URB");
559 return EXIT_FAILURE;
562 if ((UE_GET_ADDR(urb->endpoint) >= 16) ||
563 (UE_GET_ADDR(urb->endpoint) <= 0)) {
564 USB_MSG("Illegal EP number");
565 return EXIT_FAILURE;
568 /* TODO: broken USB_IN... constants */
569 if ((1 != urb->direction) && (0 != urb->direction)) {
570 USB_MSG("Illegal EP direction");
571 return EXIT_FAILURE;
574 /* TODO: usb.h constants to type mapping */
575 switch (type) {
576 case USB_TRANSFER_BLK:
577 request.type = HCD_TRANSFER_BULK;
578 break;
579 case USB_TRANSFER_INT:
580 request.type = HCD_TRANSFER_INTERRUPT;
581 break;
582 default:
583 /* TODO: ISO transfer */
584 USB_MSG("Invalid transfer type");
585 return EXIT_FAILURE;
588 /* TODO: Any additional checks? (sane size?) */
590 /* Assign to data request structure */
591 request.endpoint = urb->endpoint;
592 request.direction = urb->direction;
593 request.size = (int)urb->size;
594 request.data = urb->data;
595 request.interval = urb->interval;
597 /* Check if EP number is valid */
598 e = hcd_tree_find_ep(&(this_device->config_tree), request.endpoint);
600 if (NULL == e) {
601 USB_MSG("Invalid EP value");
602 return EXIT_FAILURE;
605 /* TODO: broken constants for urb->direction (USB_OUT...) */
606 /* Check if remembered direction matches */
607 if (((e->descriptor.bEndpointAddress >> 7) & 0x01) != urb->direction) {
608 USB_MSG("EP direction mismatch");
609 return EXIT_FAILURE;
612 /* Check if remembered type matches */
613 if (UE_GET_XFERTYPE(e->descriptor.bmAttributes) != (int)request.type) {
614 USB_MSG("EP type mismatch");
615 return EXIT_FAILURE;
618 /* Assign to let know how much data can be transfered at a time */
619 request.max_packet_size = UGETW(e->descriptor.wMaxPacketSize);
621 /* Let know how to configure EP for speed */
622 request.speed = this_device->speed;
624 /* Start sending data */
625 if (EXIT_SUCCESS != hcd_data_transfer(this_device, &request)) {
626 USB_MSG("URB non-control transfer, failed");
627 urb->status = EPIPE;
628 return EXIT_FAILURE;
631 /* Transfer successfully completed */
632 urb->status = EXIT_SUCCESS;
633 return EXIT_SUCCESS;
637 /*===========================================================================*
638 * hcd_setup_packet *
639 *===========================================================================*/
640 static int
641 hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup)
643 hcd_driver_state * d;
644 hcd_reg1 * current_byte;
645 int expected_len;
646 int received_len;
648 DEBUG_DUMP;
650 /* Initially... */
651 d = this_device->driver;
652 expected_len = (int)setup->wLength;
653 current_byte = this_device->buffer;
655 /* Send setup packet */
656 d->setup_stage(d->private_data, setup);
658 /* Wait for response */
659 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, HCD_ENDPOINT_0);
661 /* Check response */
662 if (EXIT_SUCCESS != d->check_error(d->private_data,
663 HCD_TRANSFER_CONTROL,
664 HCD_DIRECTION_UNUSED))
665 return EXIT_FAILURE;
667 /* For data packets... */
668 if (expected_len > 0) {
670 /* TODO: magic number */
671 /* ...IN data packets */
672 if (setup->bRequestType & 0x80) {
674 /* What was received until now */
675 this_device->data_len = 0;
677 do {
678 /* Try getting data */
679 d->in_data_stage(d->private_data);
681 /* Wait for response */
682 hcd_device_wait(this_device,
683 HCD_EVENT_ENDPOINT,
684 HCD_ENDPOINT_0);
686 /* Check response */
687 if (EXIT_SUCCESS != d->check_error(
688 d->private_data,
689 HCD_TRANSFER_CONTROL,
690 HCD_DIRECTION_UNUSED))
691 return EXIT_FAILURE;
693 /* Read data received as response */
694 received_len = d->read_data(d->private_data,
695 current_byte, 0);
697 /* Data reading should always yield positive
698 * results for proper setup packet */
699 if (received_len > 0) {
700 /* Try next packet */
701 this_device->data_len += received_len;
702 current_byte += received_len;
703 } else
704 return EXIT_FAILURE;
706 } while (expected_len > this_device->data_len);
708 /* Should be exactly what we requested, no more */
709 if (this_device->data_len != expected_len) {
710 USB_MSG("Received more data than expected");
711 return EXIT_FAILURE;
714 } else {
715 /* TODO: unimplemented */
716 USB_MSG("Illegal non-zero length OUT setup packet");
717 return EXIT_FAILURE;
721 /* Status stages */
722 if (setup->bRequestType & 0x80) {
724 /* Try confirming data receive */
725 d->out_status_stage(d->private_data);
727 /* Wait for response */
728 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
729 HCD_ENDPOINT_0);
731 /* Check response */
732 if (EXIT_SUCCESS != d->check_error(d->private_data,
733 HCD_TRANSFER_CONTROL,
734 HCD_DIRECTION_UNUSED))
735 return EXIT_FAILURE;
737 } else {
739 /* Try getting status confirmation */
740 d->in_status_stage(d->private_data);
742 /* Wait for response */
743 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
744 HCD_ENDPOINT_0);
746 /* Check response */
747 if (EXIT_SUCCESS != d->check_error(d->private_data,
748 HCD_TRANSFER_CONTROL,
749 HCD_DIRECTION_UNUSED))
750 return EXIT_FAILURE;
752 /* Read zero data from response to clear registers */
753 if (0 != d->read_data(d->private_data, NULL, 0))
754 return EXIT_FAILURE;
757 return EXIT_SUCCESS;
761 /*===========================================================================*
762 * hcd_data_transfer *
763 *===========================================================================*/
764 static int
765 hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request)
767 hcd_driver_state * d;
768 hcd_datarequest temp_req;
769 int transfer_len;
771 DEBUG_DUMP;
773 /* Initially... */
774 d = this_device->driver;
776 /* Set parameters for further communication */
777 d->setup_device(d->private_data,
778 request->endpoint,
779 this_device->address);
781 /* TODO: broken USB_IN... constants */
782 if (1 == request->direction) {
784 do {
785 /* Start actual data transfer */
786 d->rx_stage(d->private_data, request);
788 /* Wait for response */
789 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
790 request->endpoint);
792 /* Check response */
793 if (EXIT_SUCCESS != d->check_error(d->private_data,
794 request->type,
795 HCD_DIRECTION_IN))
796 return EXIT_FAILURE;
798 /* Read data received as response */
799 transfer_len = d->read_data(d->private_data,
800 (hcd_reg1 *)request->data,
801 request->endpoint);
803 request->size -= transfer_len;
804 request->data += transfer_len;
806 /* Total length shall not become negative */
807 if (request->size < 0) {
808 USB_MSG("Invalid amount of data received");
809 return EXIT_FAILURE;
812 #ifdef DEBUG
813 /* TODO: REMOVEME (dumping of data transfer) */
815 int i;
816 USB_MSG("RECEIVED: %d", transfer_len);
817 for (i = 0; i < transfer_len; i++)
818 USB_MSG("0x%02X: %c",
819 (request->data-transfer_len)[i],
820 (request->data-transfer_len)[i]);
822 #endif
824 } while (0 != request->size);
826 } else if (0 == request->direction) {
828 do {
829 temp_req = *request;
831 /* Decide transfer size */
832 if (temp_req.size > (int)temp_req.max_packet_size) {
833 temp_req.size = temp_req.max_packet_size;
836 request->data += temp_req.size;
837 request->size -= temp_req.size;
839 /* Total length shall not become negative */
840 USB_ASSERT(request->size >= 0,
841 "Invalid amount of transfer data calculated");
843 /* Start actual data transfer */
844 d->tx_stage(d->private_data, &temp_req);
846 /* Wait for response */
847 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
848 request->endpoint);
850 /* Check response */
851 if (EXIT_SUCCESS != d->check_error(d->private_data,
852 request->type,
853 HCD_DIRECTION_OUT))
854 return EXIT_FAILURE;
856 } while (0 != request->size);
858 } else
859 USB_ASSERT(0, "Invalid transfer direction");
861 return EXIT_SUCCESS;