1/**
2 * \brief this file contains functions for handling the different transfers
3 *        as well as handling different flounder requests
4 */
5
6/*
7 * Copyright (c) 2007-2013 ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
18#include <barrelfish/barrelfish.h>
19
20#include <if/usb_driver_defs.h>
21
22#include <usb/usb_error.h>
23#include <usb/usb_request.h>
24
25#include <usb_controller.h>
26#include <usb_transfer.h>
27#include <usb_device.h>
28#include <usb_request.h>
29#include <usb_xfer.h>
30#include <usb_endpoint.h>
31#include <usb_pipe.h>
32#include <usb_memory.h>
33
34/**
35 * this struct contains the default setup information for the control transfers
36 */
37static const struct usb_xfer_config usb_control_ep_cfg[USB_DEVICE_CTRL_XFER_MAX] =
38        {
39            /*
40             * setup information for the default control endpoint
41             * This endpoint is used for device requests
42             *
43             */
44            [0] = {
45                .type = USB_TYPE_CTRL,
46                .endpoint = USB_ENDPOINT_CONTROL,
47                .direction = USB_ENDPOINT_DIRECTION_ANY,
48                .bufsize = 1024,
49                .flags = {
50                    .ext_buffer = 1,
51                },
52                .usb_mode = USB_MODE_DUAL,
53                .usb_type = USB_TYPE_CTRL,
54            },
55
56            /*
57             * this is the setup information for the clear stall requests
58             * TODO: clearing up stalls is NYI.
59             */
60
61            [1] = {
62                .type = USB_TYPE_CTRL,
63                .endpoint = USB_ENDPOINT_CONTROL, /* Control pipe */
64                .direction = USB_ENDPOINT_DIRECTION_ANY,
65                .bufsize = sizeof(struct usb_device_request),
66                .timeout = 1000, /* 1 second */
67                .interval = 50, /* 50ms */
68                .usb_mode = USB_MODE_HOST,
69                .usb_type = USB_TYPE_CTRL
70            },
71        };
72
73/*
74 * --------------------------------------------------------------------------
75 * transfer done notification
76 */
77
78/// struct containing the transfer done state
79struct usb_tdone_state {
80    struct usb_driver_binding *bind;
81    struct usb_xfer *xfer;
82    void *buf;
83};
84
85/**
86 * \brief transfer complete callback that frees up the state
87 */
88static void usb_transfer_complete_cb(void *a)
89{
90    free(a);
91}
92
93/**
94 * \brief handles the transmission of the transfer done notification
95 *
96 * \param a pointer to the transfer done state
97 */
98static void usb_transfer_complete_tx(void *a)
99{
100    struct usb_tdone_state *st = a;
101    errval_t err;
102
103    struct event_closure txcont = MKCONT(usb_transfer_complete_cb, st);
104
105    err = usb_driver_transfer_done_notify__tx(st->bind, txcont,
106            st->xfer->xfer_id, st->xfer->error, st->buf,
107            st->xfer->actual_bytes);
108
109    USB_TX_TRANSER_ERR(usb_transfer_complete_tx);
110}
111
112/**
113 * \brief callback function that initiates the sending the transfer done msg
114 *
115 * \param xfer the transfer that was done
116 * \param err the outcome of the transfer
117 *
118 * NOTE: this function sends xfer done notification to the device driver
119 *       interrupt transfers may automatically be restarted
120 */
121static void usb_transfer_complete_notify(struct usb_xfer *xfer, usb_error_t err)
122{
123    uint32_t data_length = xfer->actual_bytes;
124
125    xfer->error = err;
126
127    switch (xfer->type) {
128        case USB_TYPE_INTR:
129            xfer->frame_lengths[0] = xfer->max_data_length;
130            if (data_length > 0) {
131                struct usb_tdone_state *st = malloc(
132                        sizeof(struct usb_tdone_state));
133                st->xfer = xfer;
134                st->buf = xfer->frame_buffers[0]->buffer;
135                st->bind = xfer->usb_driver_binding;
136                usb_transfer_complete_tx(st);
137
138            }
139            /* autorestart if the transfer completed successfully */
140            if (xfer->flags.auto_restart && (err == USB_ERR_OK)) {
141                usb_transfer_start(xfer);
142            }
143            break;
144        default:
145            /* noop */
146            break;
147    }
148}
149
150/*
151 * transfer done notification
152 * --------------------------------------------------------------------------
153 */
154
155/**
156 * \brief handles the start of a control transfer
157 */
158static uint8_t usb_transfer_ctrl_start(struct usb_xfer *xfer)
159{
160    USB_DEBUG_TR_ENTER;
161
162    uint16_t length;
163
164    /* check if the control transfer ended up in a stalled state while active */
165    if (xfer->flags.pipe_stalled && xfer->flags_internal.ctrl_active) {
166        xfer->flags_internal.ctrl_stall = 1;
167        xfer->flags_internal.ctrl_active = 0;
168    } else {
169        xfer->flags_internal.ctrl_stall = 1;
170    }
171
172    if (xfer->num_frames > 2) {
173        USB_DEBUG("ERROR: too many frames %"PRIu32"", xfer->num_frames);
174        USB_DEBUG_TR_RETURN;
175        return (1);
176    }
177
178    /* if the ctrl transfer is already active the header was sent, so reset
179     * the control header flag
180     */
181    if (xfer->flags_internal.ctrl_active) {
182        if (xfer->flags_internal.ctrl_header) {
183            xfer->flags_internal.ctrl_header = 0;
184        }
185        length = xfer->sum_bytes;
186    } else {
187        if (xfer->frame_lengths[0] != sizeof(struct usb_device_request)) {
188            /*
189             * the first frame must be of size device request, otherwise
190             * this is an error
191             */
192            USB_DEBUG("ERROR: wrong frame length: %"PRIu32" / %zx",
193                   xfer->frame_lengths[0], sizeof(struct usb_device_request));
194            USB_DEBUG_TR_RETURN;
195            return (1);
196        }
197
198        /* get the device request to have access to the length information */
199        struct usb_device_request req;
200
201        usb_mem_copy_out(xfer->frame_buffers[0], 0, &req, sizeof(req));
202
203        xfer->flags_internal.remaining_bytes = req.wLength;
204
205        xfer->flags_internal.ctrl_header = 1;
206
207        length = xfer->sum_bytes - sizeof(struct usb_device_request);
208    }
209
210    if (length > xfer->flags_internal.remaining_bytes) {
211        USB_DEBUG("ERROR: length (%u) remaining length is greater than "
212        "remaining length (%u)", length, xfer->flags_internal.remaining_bytes);
213        USB_DEBUG_TR_RETURN;
214        return (1);
215    }
216
217    /* check for short transfers i.e. too less data than expected */
218    if (xfer->flags.short_xfer_forced) {
219        xfer->flags_internal.remaining_bytes = 0;
220    } else {
221        if ((length != xfer->max_data_length)
222                && (length != xfer->flags_internal.remaining_bytes)
223                && (xfer->num_frames != 1)) {
224            USB_DEBUG("ERROR: short xfer w/o force_short_xfer\n");
225            USB_DEBUG_TR_RETURN;
226            return (1);
227        }
228        xfer->flags_internal.remaining_bytes -= length;
229    }
230
231    if ((xfer->flags_internal.remaining_bytes > 0)
232            || xfer->flags.manual_status) {
233        xfer->flags_internal.ctrl_active = 1;
234
235        if ((!xfer->flags_internal.ctrl_header) && (xfer->num_frames == 1)) {
236            USB_DEBUG("ERROR: invalid parameter combination!\n");
237            USB_DEBUG_TR_RETURN;
238            return (1);
239        }
240    } else {
241        xfer->flags_internal.ctrl_active = 0;
242    }
243
244    /* all fine */
245    return (0);
246}
247
248/**
249 * \brief   this function is used to allocate the structure and resources
250 *          needed for the default USB control endpoint transfer
251 *
252 * \param   device  the usb device we want to setup a usb transfer
253 */
254void usb_transfer_setup_ctrl_default(struct usb_device *device,
255        struct usb_request_state *st)
256{
257    USB_DEBUG_TR_ENTER;
258    /* setting up transfers for the USB root hub is not allowed */
259    if (device->parent_hub == NULL) {
260        USB_DEBUG("ERROR: setting up transfers for root hub not allowed\n");
261        return;
262    }
263
264    /*
265     * since the control transfers are always on the special control
266     * ep, we can cache them and reuse later
267     */
268    struct usb_xfer *xfer = device->ctrl_xfer[0];
269
270    uint8_t xfer_reuse = 0;
271
272    if (xfer) {
273        xfer_reuse = ((xfer->device_address == device->device_address)
274                && (device->ctrl_ep_desc.wMaxPacketSize
275                        == device->device_desc.bMaxPacketSize0));
276
277        if ((device->flags.usb_mode == USB_MODE_DEVICE) && xfer_reuse) {
278            assert(!"NYI: device mode\n");
279            usb_transfer_start(xfer);
280            return;
281        }
282    }
283
284    if (xfer_reuse) {
285        USB_DEBUG_XFER("reusing the xfer... return.\n");
286        return;
287    }
288
289    /*
290     * we cannot reuse the USB transfer so we have to update the fields
291     */
292    device->ctrl_ep_desc.wMaxPacketSize = device->device_desc.bMaxPacketSize0;
293    device->ctrl_ep.descriptor = &device->ctrl_ep_desc;
294
295    usb_transfer_unsetup(device->ctrl_xfer, USB_DEVICE_CTRL_XFER_MAX);
296
297    USB_DEBUG_XFER("setting up device ctrl xfer[0]\n");
298
299    if (usb_transfer_setup(device, 0, &(device->ctrl_xfer[0]),
300            usb_control_ep_cfg)) {
301        USB_DEBUG("usb_transfer_setup_ctrl_default(): "
302        "ERROR: could not allocate default control transfer\n");
303        return;
304    }
305
306    USB_DEBUG_XFER("setting up device ctrl xfer[1]\n");
307
308    if (usb_transfer_setup(device, 0, &(device->ctrl_xfer[1]),
309            usb_control_ep_cfg)) {
310        debug_printf("usb_transfer_setup_ctrl_default(): "
311                "ERROR: could not allocate default control transfer\n");
312        return;
313    }
314
315    USB_DEBUG_TR_RETURN;
316}
317
318/**
319 * \brief   starts a USB transfer
320 *
321 * \param   xfer    the USB transfer to start
322 */
323void usb_transfer_start(struct usb_xfer *xfer)
324{
325
326    USB_DEBUG_TR_ENTER;
327
328    if (xfer == NULL) {
329        USB_DEBUG_XFER("NOTICE: No xfer to start...\n");
330        return;
331    }
332
333    /*
334     * set the started flag
335     */
336
337    xfer->flags_internal.started = 1;
338
339    /*
340     * if the transfer is already transferring, then we do not
341     * have to do sth.
342     */
343    if (xfer->flags_internal.transferring) {
344        USB_DEBUG_XFER("NOTICE: already transferring\n");
345
346        USB_DEBUG_TR_RETURN;
347        return;
348    }
349
350    /* struct usb_xfer_queue *queue = &(xfer->host_controller->done_queue);
351
352     if (queue->current != xfer) {
353     usb_xfer_enqueue(queue, xfer);
354     }*/
355
356    /*
357     * submitting the transfer to start the USB hardware for the given
358     * transfer
359     */
360
361    if (!xfer->flags_internal.pipe_open) {
362        xfer->flags_internal.pipe_open = 1;
363        (xfer->endpoint->pipe_fn->open)(xfer);
364    }
365
366    xfer->flags_internal.transferring = 1;
367    xfer->flags_internal.done = 0;
368
369    /*
370     * check if the transfer is waiting on a queue, and dequeue it
371     */
372    /* if (xfer->wait_queue) {
373     usb_xfer_dequeue(xfer);
374     }*/
375
376    // clear the closed flag
377    xfer->flags_internal.transfer_closed = 0;
378
379    // clear the DMA delay flag
380    xfer->flags_internal.dma_wait = 0;
381
382    // transfers are not immediate cancellable
383    xfer->flags_internal.cancellable = 0;
384
385    /*
386     * update the status fields of the transfer
387     */
388    xfer->sum_bytes = 0;
389    xfer->actual_bytes = 0;
390    xfer->actual_frames = 0;
391
392    xfer->error = USB_ERR_OK;
393
394    if (xfer->device->state < USB_DEVICE_STATE_POWERED) {
395        USB_DEBUG("NOTICE: device is not alive anymore...\n");
396        usb_xfer_done(xfer, USB_ERR_CANCELLED);
397        return;
398    }
399
400    if (xfer->num_frames == 0) {
401        if (xfer->flags.pipe_stalled) {
402            USB_DEBUG_XFER("Want to stall w/o transferring...\n");
403            xfer->flags_internal.cancellable = 1;
404            assert(!"NYI: stalling\n");
405            /* TODO: usb_command_wrapper(&xfer->endpoint->endpoint_q, xfer); */
406            return;
407        }
408        USB_DEBUG(
409                "ERROR: invalid number of frames (0) in usb_transfer_start()\n");
410        usb_xfer_done(xfer, USB_ERR_INVAL);
411        USB_DEBUG_TR_RETURN;
412        return;
413    }
414
415    for (uint32_t frame = 0; frame < xfer->num_frames; frame++) {
416        xfer->frame_lengths[frame + xfer->max_frame_count] =
417                xfer->frame_lengths[frame];
418
419        xfer->sum_bytes += xfer->frame_lengths[frame];
420        if (xfer->sum_bytes < xfer->frame_lengths[frame]) {
421            USB_DEBUG("WARNING: total length wrapped arroud!\n");
422            usb_xfer_done(xfer, USB_ERR_INVAL);
423            USB_DEBUG_TR_RETURN;
424            return;
425        }
426    }
427
428    xfer->flags_internal.short_frames_ok = 0;
429    xfer->flags_internal.short_transfer_ok = 0;
430
431    if (xfer->flags_internal.ctrl_xfer) {
432        USB_DEBUG_XFER("usb_transfer_start() - is ctrl transfer...\n");
433        if (usb_transfer_ctrl_start(xfer)) {
434            debug_printf("WARNING: starting usb ctrl transfer failed..\n");
435            usb_xfer_done(xfer, USB_ERR_STALLED);
436            USB_DEBUG_TR_RETURN;
437            return;
438        }
439    }
440
441    if ((((xfer)->endpoint_number & 0x80) ? 1 : 0)) {
442        if (xfer->flags.short_frames_ok) {
443            xfer->flags_internal.short_frames_ok = 1;
444            xfer->flags_internal.short_transfer_ok = 1;
445        } else if (xfer->flags.short_xfer_ok) {
446            xfer->flags_internal.short_transfer_ok = 1;
447            if (xfer->flags_internal.ctrl_xfer) {
448                xfer->flags_internal.short_frames_ok = 1;
449            }
450        }
451    }
452
453    usb_pipe_enter(xfer);
454    USB_DEBUG_TR_RETURN;
455}
456
457/**
458 * \brief   stops an usb transfer
459 *
460 * \param   xfer    the usb transfer to stop
461 *
462 */
463void usb_transfer_stop(struct usb_xfer *xfer)
464{
465    if (xfer == NULL) {
466        return;
467    }
468
469    /*
470     * check if the pipe has already been opened.
471     * if not we simply reset the started flag and return
472     */
473    if (!xfer->flags_internal.pipe_open) {
474        if (xfer->flags_internal.started) {
475            xfer->flags_internal.started = 0;
476        }
477        xfer->flags_internal.transferring = 0;
478        return;
479    }
480    xfer->error = USB_ERR_CANCELLED;
481
482    // clear the flags
483    xfer->flags_internal.pipe_open = 0;
484    xfer->flags_internal.started = 0;
485    xfer->flags_internal.done = 0;
486
487    /*
488     * now stop the transfer, depending on whether we are
489     * currently transferring or not
490     */
491    if (xfer->flags_internal.transferring) {
492        if (xfer->flags_internal.cancellable) {
493            if (!xfer->flags_internal.transfer_closed) {
494                (xfer->endpoint->pipe_fn->close)(xfer);
495                xfer->flags_internal.transfer_closed = 1;
496            }
497            xfer->flags_internal.transferring = 0;
498        }
499    } else {
500        (xfer->endpoint->pipe_fn->close)(xfer);
501        xfer->flags_internal.transferring = 0;
502        struct usb_endpoint *ep = xfer->endpoint;
503        struct usb_xfer_queue *queue = &(ep->transfers);
504
505        /*
506         * check if we need to start the next transfer
507         * i.e. dequeue it from the wait queue
508         */
509        if (queue->current == xfer) {
510            if (!queue->recurse_1) {
511                queue->recurse_1 = 1;
512                xfer = ((&queue->head)->first);
513
514                if (xfer) {
515                    if ((xfer->wait_entry.next) != NULL) {
516                        (xfer->wait_entry.next)->wait_entry.prev_next = xfer
517                                ->wait_entry.prev_next;
518                        *(xfer)->wait_entry.prev_next = (xfer->wait_entry.next);
519                    } else {
520                        (&queue->head)->last_next = &(&queue->head)->first;
521                        (&queue->head)->first = NULL;
522                        // (&queue->head)->last_next = xfer->wait_entry.prev_next;
523                    }
524
525                    xfer->wait_queue = NULL;
526                    queue->current = xfer;
527                    USB_DEBUG_XFER("calling (queue->command)(queue)\n");
528                    (queue->command)(queue);
529                }
530                queue->recurse_1 = 0;
531            }
532        }
533    }
534
535}
536
537/**
538 * \brief   this function undoes the setup of the usb transfers
539 *
540 * \param   xfers       array of pointers to usb transfers to unsetup
541 * \param   xfer_count  the number of xfers to unsetup
542 */
543void usb_transfer_unsetup(struct usb_xfer **xfers, uint16_t xfer_count)
544{
545    USB_DEBUG_TR_ENTER;
546
547    if (*xfers == NULL || xfer_count == 0) {
548        return;
549    }
550
551    struct usb_xfer *xfer;
552
553    while (xfer_count > 0) {
554        xfer_count--;
555        xfer = xfers[xfer_count];
556
557        if (xfer == NULL) {
558            continue;
559        }
560
561        xfers[xfer_count] = NULL;
562
563        usb_transfer_stop(xfer);
564
565        while (!usb_transfer_completed(xfer)) {
566            xfer->flags_internal.draining = 1;
567            event_dispatch(get_default_waitset());
568        }
569
570        xfer->endpoint->ref_allocation--;
571
572        (xfer->host_controller->hcdi_bus_fn->xfer_unsetup)(xfer);
573
574        struct usb_device *dev = xfer->device;
575        struct usb_xfer *prev = dev->xfers;
576        while (prev != NULL) {
577            if (dev->xfers == xfer) {
578                dev->xfers = xfer->device_xfers_next;
579                break;
580            } else if (prev->device_xfers_next == xfer) {
581                debug_printf("removing from device xfers..\n");
582                prev->device_xfers_next = xfer->device_xfers_next;
583                break;
584            }
585            prev = prev->device_xfers_next;
586        }
587
588        free(xfer);
589    }
590
591    USB_DEBUG_TR_RETURN;
592}
593
594/**
595 * \brief   this function allocates the resources for a number of usb transfers
596 *
597 * \param   device      the device we want to allocate the transfers
598 * \param   ifaces      array of interfaces
599 * \param   usb_xfers   pointer to an array of usb_xfer
600 * \param   setups      setup parameter array
601 * \para    setup_count the number of setups we have to do
602 * \
603 */
604usb_error_t usb_transfer_setup(struct usb_device *device, const uint8_t iface,
605        struct usb_xfer **ret_xfer, const struct usb_xfer_config *setup)
606{
607    USB_DEBUG_TR_ENTER;
608
609    struct usb_xfer_setup_params params;
610    memset(&params, 0, sizeof(params));
611
612    params.device = device;
613    params.speed = device->speed;
614    params.hc_max_packet_count = 1;
615    params.err = USB_ERR_OK;
616    params.type = setup->usb_type;
617    params.size[0] = 0;
618    params.buf = NULL;
619    params.xfer_setup = setup;
620
621    struct usb_endpoint *ep = usb_endpoint_lookup(device, iface, setup);
622
623    if ((ep == NULL) || (ep->pipe_fn == NULL)) {
624        USB_DEBUG_XFER("WARNING: No associated pipe!\n");USB_DEBUG_TR_RETURN;
625        return (USB_ERR_NO_PIPE);
626    }
627
628    struct usb_xfer *xfer = malloc(sizeof(struct usb_xfer));
629    memset(xfer, 0, sizeof(*xfer));
630    xfer->xfer_id = device->xfer_id++;
631    xfer->device_xfers_next = device->xfers;
632    device->xfers = xfer;
633    xfer->xfer_done_cb = setup->xfer_done_cb;
634    xfer->type = setup->usb_type;
635    xfer->device_address = device->device_address;
636    xfer->host_controller = device->controller;
637    xfer->device = device;
638    xfer->endpoint = ep;
639    params.curr_xfer = xfer;
640    params.pipe_fn = xfer->endpoint->pipe_fn;
641
642    (device->controller->hcdi_bus_fn->xfer_setup)(&params);
643
644    if (params.err != USB_ERR_OK) {
645        USB_DEBUG(
646                "ERROR: hcdi_xfer_setup failed: %s\n", usb_get_error_string(params.err));
647        return (params.err);
648    }
649
650    xfer->endpoint->ref_allocation++;
651    assert(xfer->endpoint->ref_allocation);
652
653    *ret_xfer = xfer;
654
655    USB_DEBUG_TR_RETURN;
656    return (USB_ERR_OK);
657}
658
659/**
660 * \brief   checks if the transfer is completed
661 *
662 * \param   xfer    the USB transer we want to check
663 *
664 * \return  1:  the transfer is completed
665 *          0:  the transfer is in progress
666 */
667uint8_t usb_transfer_completed(struct usb_xfer *xfer)
668{
669    /*
670     * there is no transfer, so it is completed
671     */
672    if (xfer == NULL) {
673        USB_DEBUG_XFER("usb_transfer_completed() - transfer is null\n");
674        return (1);
675    }
676
677    /*
678     * call poll. this updates the state of the current transfers...
679     */
680    //(xfer->host_controller->hcdi_bus_fn->xfer_poll)(xfer->host_controller);
681    (xfer->host_controller->hcdi_bus_fn->xfer_finished)(xfer);
682
683    /*
684     * if the flags say we are transferring at the moment,
685     * then we are not completed
686     */
687    if (xfer->flags_internal.transferring) {
688        USB_DEBUG_XFER("usb_transfer_completed() - is transferring\n");
689        return (0);
690    }
691
692    /*
693     * if we are waiting on a queue then we are not finished
694     */
695    if (xfer->wait_queue) {
696        USB_DEBUG_XFER("usb_transfer_completed() - on wait queue\n");
697        return (0);
698    }
699
700    return (1);
701    /*
702     * checking the done queue now
703     */
704    struct usb_xfer_queue *queue;
705    queue = &(xfer->host_controller->done_queue);
706
707    /*
708     * we are scheduled for callback so not quite finished yet
709     */
710    if (queue->current == xfer) {
711        USB_DEBUG_XFER("usb_transfer_completed() - scheduled for callback\n");
712        return (0);
713    }USB_DEBUG_XFER("usb_transfer_completed() - transfer is completed.\n");
714    return (1);
715}
716
717/*
718 * --------------------------------------------------------------------------
719 * Flounder Callbacks
720 * --------------------------------------------------------------------------
721 */
722
723static void usb_tx_transfer_generic_cb(void *a)
724{
725    /// XXX: Pagefaults... free(a);
726}
727
728/* ------------------------- transfer setup ------------------------- */
729
730struct usb_tsetup_state {
731    uint32_t tid;
732    struct usb_manager_binding *bind;
733    usb_error_t error;
734
735};
736
737static void usb_tx_transfer_setup_response(void *a)
738{
739    errval_t err;
740    struct usb_tsetup_state *st = (struct usb_tsetup_state *) a;
741
742    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
743
744    err = usb_manager_transfer_setup_response__tx(st->bind, txcont,
745            (uint32_t) st->error, st->tid);
746
747    USB_TX_TRANSER_ERR(usb_tx_transfer_setup_response);
748}
749
750/**
751 *
752 */
753void usb_rx_transfer_setup_call(struct usb_manager_binding *bind, uint8_t type,
754        usb_manager_setup_param_t params)
755{
756    struct usb_tsetup_state *st = malloc(sizeof(struct usb_tsetup_state));
757
758    if (st == NULL) {
759        debug_printf("WARNING: Cannot reply, out of memory!\n");
760        return;
761    }
762
763    struct usb_xfer_config setup;
764
765    st->bind = bind;
766    struct usb_xfer *xfer;
767    struct usb_device *dev = (struct usb_device *) bind->st;
768
769    memcpy(&setup, &params, sizeof(params));
770    if (dev == NULL) {
771        st->tid = 0;
772        st->error = USB_ERR_BAD_CONTEXT;
773        usb_tx_transfer_setup_response(st);
774        return;
775    }
776
777    setup.xfer_done_cb = &usb_transfer_complete_notify;
778
779    switch ((usb_type_t) type) {
780        case USB_TYPE_BULK:
781            USB_DEBUG_IDC("received usb_rx_transfer_setup_call [bulk type]\n");
782            /* TODO: Handle transfer setup */
783            setup.usb_type = USB_TYPE_BULK;
784            st->error = USB_ERR_OK;
785            xfer->usb_manager_binding = st->bind;
786            xfer->usb_driver_binding = dev->usb_driver_binding;
787            st->tid = 123;
788            break;
789        case USB_TYPE_CTRL:
790            USB_DEBUG_IDC("received usb_rx_transfer_setup_call [ctrl type]\n");
791            /* TODO: Handle transfer setup */
792            setup.usb_type = USB_TYPE_CTRL;
793            st->error = USB_ERR_OK;
794            xfer->usb_manager_binding = st->bind;
795            xfer->usb_driver_binding = dev->usb_driver_binding;
796            st->tid = 234;
797            break;
798        case USB_TYPE_ISOC:
799            USB_DEBUG_IDC("received usb_rx_transfer_setup_call [isoc type]\n");
800            /* TODO: Handle transfer setup */
801            setup.usb_type = USB_TYPE_ISOC;
802            st->error = USB_ERR_OK;
803            xfer->usb_manager_binding = st->bind;
804            xfer->usb_driver_binding = dev->usb_driver_binding;
805            st->tid = 345;
806            break;
807        case USB_TYPE_INTR:
808            USB_DEBUG_IDC("received usb_rx_transfer_setup_call [intr type]\n");
809            /* TODO: Handle transfer setup */
810            setup.usb_type = USB_TYPE_INTR;
811            st->error = usb_transfer_setup(dev, params.iface, &xfer, &setup);
812            xfer->usb_manager_binding = st->bind;
813            xfer->usb_driver_binding = dev->usb_driver_binding;
814            st->tid = xfer->xfer_id;
815            break;
816        default:
817            USB_DEBUG("received usb_rx_transfer_setup_call [invalid type]\n");
818            st->error = USB_ERR_INVAL;
819            break;
820    }
821    usb_tx_transfer_setup_response(st);
822}
823
824/* ------------------------- transfer unsetup ------------------------- */
825
826struct usb_tunsetup_state {
827    usb_error_t error;
828    struct usb_manager_binding *bind;
829};
830
831static void usb_tx_transfer_unsetup_response(void *a)
832{
833    errval_t err;
834    struct usb_tunsetup_state *st = (struct usb_tunsetup_state *) a;
835
836    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
837
838    err = usb_manager_transfer_unsetup_response__tx(st->bind, txcont,
839            (uint32_t) st->error);
840
841    USB_TX_TRANSER_ERR(usb_tx_transfer_unsetup_response);
842}
843
844/**
845 *
846 */
847void usb_rx_transfer_unsetup_call(struct usb_manager_binding *bind,
848        uint32_t tid)
849{
850    struct usb_tunsetup_state *st = malloc(sizeof(struct usb_tunsetup_state));
851
852    if (st == NULL) {
853        debug_printf("WARNING: Cannot reply, out of memory!\n");
854        return;
855    }
856
857    st->bind = bind;
858
859    usb_tx_transfer_unsetup_response(st);
860}
861
862/* ------------------------- transfer start ------------------------- */
863
864struct usb_tstart_state {
865    usb_error_t error;
866    struct usb_manager_binding *bind;
867};
868
869static void usb_tx_transfer_start_response(void *a)
870{
871    errval_t err;
872    struct usb_tstart_state *st = (struct usb_tstart_state *) a;
873
874    USB_DEBUG_IDC("usb_tx_transfer_start_response()\n\n");
875
876    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
877
878    err = usb_manager_transfer_start_response__tx(st->bind, txcont,
879            (uint32_t) st->error);
880
881    USB_TX_TRANSER_ERR(usb_tx_transfer_start_response);
882}
883
884void usb_rx_transfer_start_call(struct usb_manager_binding *bind, uint32_t tid)
885{
886    USB_DEBUG_IDC("usb_rx_transfer_start_call()\n");
887
888    struct usb_tstart_state *st = malloc(sizeof(struct usb_tstart_state));
889
890    if (st == NULL) {
891        debug_printf("WARNING: Cannot reply, out of memory!\n");
892    }
893    st->bind = bind;
894
895    struct usb_device *dev = (struct usb_device *) (bind->st);
896
897    assert(dev != NULL);
898
899    struct usb_xfer *xfer = dev->xfers;
900
901    while (xfer) {
902        if (xfer->xfer_id == tid) {
903            break;
904        }
905        xfer = xfer->device_xfers_next;
906    }
907
908    if (xfer == NULL) {
909        USB_DEBUG("no xfer!\n");
910        st->error = USB_ERR_BAD_CONTEXT;
911        usb_tx_transfer_start_response(st);
912    }
913
914    usb_transfer_start(xfer);
915
916    st->error = xfer->error;
917
918    usb_tx_transfer_start_response(st);
919}
920
921/* ------------------------- transfer stop ------------------------- */
922
923struct usb_tstop_state {
924    struct usb_manager_binding *bind;
925    usb_error_t error;
926};
927
928static void usb_tx_transfer_stop_response(void *a)
929{
930    errval_t err;
931    struct usb_tstop_state *st = (struct usb_tstop_state *) a;
932
933    USB_DEBUG_IDC("usb_tx_transfer_stop_response()\n");
934
935    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
936
937    err = usb_manager_transfer_stop_response__tx(st->bind, txcont,
938            (uint32_t) st->error);
939
940    USB_TX_TRANSER_ERR(usb_tx_transfer_stop_response);
941}
942
943void usb_rx_transfer_stop_call(struct usb_manager_binding *bind, uint32_t tid)
944{
945    struct usb_tstop_state *st = malloc(sizeof(struct usb_tstop_state));
946
947    if (st == NULL) {
948        debug_printf("WARNING: Cannot reply, out of memory!\n");
949    }
950
951    st->bind = bind;
952
953    usb_tx_transfer_stop_response(st);
954}
955
956/* ------------------------- transfer status ------------------------- */
957
958struct usb_tstatus_state {
959    struct usb_manager_binding *bind;
960    usb_error_t error;
961    uint32_t actlen;
962    uint32_t length;
963    uint32_t actframes;
964    uint32_t numframes;
965};
966
967static void usb_tx_transfer_status_response(void *a)
968{
969    errval_t err;
970    struct usb_tstatus_state *st = (struct usb_tstatus_state *) a;
971
972    USB_DEBUG_IDC("usb_tx_transfer_status_response()\n");
973
974    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
975
976    err = usb_manager_transfer_status_response__tx(st->bind, txcont,
977            (uint32_t) st->error, st->actlen, st->length, st->actframes,
978            st->numframes);
979
980    USB_TX_TRANSER_ERR(usb_tx_transfer_status_response);
981}
982
983void usb_rx_transfer_status_call(struct usb_manager_binding *bind, uint32_t tid)
984{
985    struct usb_tstatus_state *st = malloc(sizeof(struct usb_tstatus_state));
986
987    if (st == NULL) {
988        debug_printf("WARNING: Cannot reply, out of memory!\n");
989        return;
990    }
991
992    st->bind = bind;
993
994    usb_tx_transfer_status_response(st);
995}
996
997/* ------------------------- transfer state ------------------------- */
998
999struct usb_tstate_state {
1000    struct usb_manager_binding *bind;
1001    usb_error_t error;
1002    uint32_t state;
1003};
1004
1005static void usb_tx_transfer_state_response(void *a)
1006{
1007    errval_t err;
1008    struct usb_tstate_state *st = (struct usb_tstate_state *) a;
1009
1010    USB_DEBUG_IDC("usb_tx_transfer_state_response()\n");
1011
1012    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
1013
1014    err = usb_manager_transfer_state_response__tx(st->bind, txcont,
1015            (uint32_t) st->error, st->state);
1016
1017    USB_TX_TRANSER_ERR(usb_tx_transfer_state_response);
1018}
1019
1020void usb_rx_transfer_state_call(struct usb_manager_binding *bind, uint32_t tid)
1021{
1022    struct usb_tstate_state *st = malloc(sizeof(struct usb_tstate_state));
1023
1024    if (st == NULL) {
1025        USB_DEBUG_IDC("WARNING: Cannot reply, out of memory!\n");
1026        return;
1027    }
1028
1029    st->bind = bind;
1030
1031    usb_tx_transfer_state_response(st);
1032}
1033
1034/* ------------------------- transfer clear stall ------------------------- */
1035
1036struct usb_tclearstall_state {
1037    struct usb_manager_binding *bind;
1038    usb_error_t error;
1039};
1040
1041static void usb_tx_transfer_clear_stall_response(void *a)
1042{
1043    errval_t err;
1044    struct usb_tclearstall_state *st = (struct usb_tclearstall_state *) a;
1045
1046    USB_DEBUG_IDC("usb_tx_transfer_clear_stall_response()\n");
1047
1048    struct event_closure txcont = MKCONT(usb_tx_transfer_generic_cb, st);
1049
1050    err = usb_manager_transfer_clear_stall_response__tx(st->bind, txcont,
1051            (uint32_t) st->error);
1052
1053    USB_TX_TRANSER_ERR(usb_tx_transfer_clear_stall_response);
1054}
1055
1056void usb_rx_transfer_clear_stall_call(struct usb_manager_binding *bind,
1057        uint32_t tid)
1058{
1059    struct usb_tclearstall_state *st = malloc(
1060            sizeof(struct usb_tclearstall_state));
1061
1062    if (st == NULL) {
1063        debug_printf("WARNING: Cannot reply, out of memory!\n");
1064        return;
1065    }
1066
1067    st->bind = bind;
1068
1069    usb_tx_transfer_clear_stall_response(st);
1070}
1071
1072