1/**
2 * \brief this file contains functions to setup the different xfers
3 */
4
5/*
6 * Copyright (c) 2007-2013 ETH Zurich.
7 * All rights reserved.
8 *
9 * This file is distributed under the terms in the attached LICENSE file.
10 * If you do not find this file, copies can be found by writing to:
11 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
12 */
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <string.h>
17#include <barrelfish/barrelfish.h>
18
19#include <usb/usb.h>
20#include <usb/usb_descriptor.h>
21#include <usb/usb_error.h>
22
23#include <usb_device.h>
24#include <usb_controller.h>
25#include <usb_memory.h>
26#include <usb_xfer.h>
27
28/**
29 * \brief   this function adds a usb xfer to a wait queue if it is not already
30 *          in one.
31 *
32 * \param   queue   the queue the xfer should be added to
33 * \param   xfer    the transfer to add to the queue
34 *
35 * Note: a transfer is put on a queue, iff it cannot be handled directly,
36 *       therefore a transfer can only be on one wait queue.
37 */
38void usb_xfer_enqueue(struct usb_xfer_queue *queue, struct usb_xfer *xfer)
39{
40    USB_DEBUG_TR_ENTER;
41
42    if (xfer->wait_queue == NULL) {
43
44        USB_DEBUG_XFER("add: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n",
45                xfer->xfer_id, queue, &queue->head.first,
46                queue->head.last_next, xfer->wait_entry.next,
47                &xfer->wait_entry.next, xfer->wait_entry.prev_next);
48
49        assert(queue != NULL);
50
51        xfer->wait_queue = queue;
52
53        xfer->wait_entry.next = NULL;
54        xfer->wait_entry.prev_next = queue->head.last_next;
55
56        *(queue->head.last_next) = xfer;
57        queue->head.last_next = &(xfer->wait_entry.next);
58
59    }
60
61    USB_DEBUG_TR_RETURN;
62}
63
64/**
65 * \brief   this function removes the usb xfer from the wait queue queue
66 *
67 * \param   xfer    the transfer to remove to the queue
68 *
69 */
70void usb_xfer_dequeue(struct usb_xfer *xfer)
71{
72    USB_DEBUG_TR_ENTER;
73
74    struct usb_xfer_queue *queue;
75
76    queue = xfer->wait_queue;
77
78    if (queue) {
79
80        USB_DEBUG_XFER("removing the transfer from the wait queue\n");
81
82        if ((xfer->wait_entry.next) != NULL)
83            xfer->wait_entry.next->wait_entry.prev_next = xfer->wait_entry
84                    .prev_next;
85        else {
86            queue->head.last_next = xfer->wait_entry.prev_next;
87        }
88
89        *xfer->wait_entry.prev_next = xfer->wait_entry.next;
90
91        xfer->wait_queue = NULL;
92
93        USB_DEBUG_XFER("rem: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n",
94                xfer->xfer_id, queue, &queue->head.first,
95                queue->head.last_next, xfer->wait_entry.next,
96                &xfer->wait_entry.next, xfer->wait_entry.prev_next);
97
98    }
99
100    USB_DEBUG_TR_RETURN;
101}
102
103/**
104 * \brief   this function handles complete transfers by removing them from
105 *          the interrupt queue and inserting them into the done queue.
106 *
107 * \param   xfer   the completed usb transfer
108 * \param   err    error condition of the transfer
109 *
110 */
111void usb_xfer_done(struct usb_xfer *xfer, usb_error_t err)
112{
113    USB_DEBUG_TR_ENTER;
114
115    /*
116     * if the transfer started, this flag has to be set to 1. Therefore
117     * the transfer may be canceled. Just return then.
118     */
119    if (!xfer->flags_internal.transferring && !xfer->flags_internal.done) {
120        USB_DEBUG_XFER("NOTICE: transfer was not transferring..\n");
121        // clear the control active flag and return
122        xfer->flags_internal.ctrl_active = 0;
123
124        USB_DEBUG_TR_RETURN;
125        return;
126    }
127
128    if (!xfer->flags_internal.transferring && !xfer->flags_internal.started) {
129        /* the transfer is not transferring and not started nothing to do */
130        return;
131    }
132
133    if ((!xfer->flags_internal.pipe_open)
134            && (!xfer->flags_internal.transfer_closed)) {
135        /* check if the pipe was opened and close it */
136        xfer->endpoint->pipe_fn->close(xfer);
137        xfer->flags_internal.transfer_closed = 1;
138
139    }
140
141    // update error condition
142    xfer->error = err;
143
144    if (err != USB_ERR_OK) {
145        USB_DEBUG_XFER("Transfer done with error: %s\n", usb_get_error_string(err));
146    }
147
148    /*
149     * the transfer was enqueued and is waiting on the interrupt queue
150     * so we have to dequeue it
151     */
152
153    usb_xfer_dequeue(xfer);
154
155    /*
156     * check the number of actual frames this should not be bigger than
157     * the maximum number of frames
158     */
159    if (xfer->actual_frames > xfer->num_frames) {
160        if (xfer->error == USB_ERR_OK) {
161            USER_PANIC("WARNING: actual frames bigger than num frames! PANIC!");
162        } else {
163            xfer->actual_frames = xfer->num_frames;
164        }
165    }
166
167    /* calculate the actual size of the transferred data */uint32_t frame = 0;
168    xfer->actual_bytes = 0;
169    for (frame = 0; frame < xfer->actual_frames; frame++) {
170        xfer->actual_bytes += xfer->frame_lengths[frame];
171    }
172
173    /* set frame length of the unused frames to be zero */
174    while (frame < xfer->num_frames) {
175        xfer->frame_lengths[frame] = 0;
176        frame++;
177    }
178
179    if (xfer->actual_bytes > xfer->sum_bytes) {
180        if (xfer->error == USB_ERR_OK) {
181            USER_PANIC("WARNING: actual bytes biggar than sum bytes! PANIC!");
182        } else {
183            xfer->actual_frames = xfer->num_frames;
184        }
185    }
186
187    /* clear the flags */
188    xfer->flags_internal.ctrl_active = 0;
189    xfer->flags_internal.transferring = 0;
190
191    /*
192     * start the next transfer on this endpoint if there is any
193     */
194    struct usb_endpoint *ep = xfer->endpoint;
195    struct usb_xfer_queue *q = &ep->transfers;
196
197    if (q->current == xfer || q->current == NULL) {
198        q->current = NULL;
199        if (!q->recurse_1) {
200            q->recurse_1 = 1;
201            /* get the first transfer of the queue */
202            struct usb_xfer *next_xfer = q->head.first;
203
204            if (next_xfer) {
205                /* dequeue it */
206                if (next_xfer->wait_entry.next != NULL) {
207                    (*next_xfer->wait_entry.prev_next)->wait_entry.prev_next =
208                            next_xfer->wait_entry.prev_next;
209                    *next_xfer->wait_entry.prev_next = next_xfer->wait_entry
210                            .next;
211                } else {
212                    q->head.last_next = &(q->head.first);
213                    q->head.first = NULL;
214                }
215                /* the transfer is not on a wait queue anymore */
216                next_xfer->wait_queue = NULL;
217                q->current = next_xfer;
218
219                USB_DEBUG_XFER(
220                        "rem2: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n",
221                        xfer->xfer_id, q, &q->head.first, q->head.last_next,
222                        xfer->wait_entry.next, &xfer->wait_entry.next,
223                        xfer->wait_entry.prev_next);
224
225                /* start the transfer */
226                (q->command)(q);
227
228            } else {
229                /* reset the queue */
230                (&q->head)->last_next = &q->head.first;
231                (&q->head)->first = NULL;
232            }
233            q->recurse_1 = 0;
234        }
235        if (!(ep->transfers.current || ep->transfers.head.first)) {
236            xfer->endpoint->is_sync = 0;
237        }
238
239    }
240
241    /* send the transfer done notification */
242    if (xfer->xfer_done_cb && xfer->flags_internal.notify) {
243        xfer->flags_internal.notify = 0;
244        (xfer->xfer_done_cb)(xfer, err);
245    }
246
247    USB_DEBUG_TR_RETURN;
248    return;
249}
250
251/// struct for the packet sizes
252struct usb_std_packet_size {
253    struct {
254        uint16_t min; /* inclusive */
255        uint16_t max; /* inclusive */
256    } range;
257
258    uint16_t fixed[4];
259};
260
261/**
262 * \brief checks the standard packet sizes according to the transfer speed
263 *        and the endpoint type
264 *
265 * \param ptr pointer to the memory location to store the size information
266 * \param type the type of the endpoint
267 * \param speed the endpoint speed
268 */
269static void usb_xfer_get_packet_size(struct usb_std_packet_size *ptr,
270        uint8_t type, enum usb_speed speed)
271{
272    /* interrupt type */
273    static const uint16_t intr_range_max[USB_SPEED_MAX] = {
274        [USB_SPEED_LOW] = 8,
275        [USB_SPEED_FULL] = 64,
276        [USB_SPEED_HIGH] = 1024,
277        [USB_SPEED_VARIABLE] = 1024,
278        [USB_SPEED_SUPER] = 1024,
279    };
280
281    /* isochronus type */
282    static const uint16_t isoc_range_max[USB_SPEED_MAX] = {
283        [USB_SPEED_LOW] = 0, /* invalid */
284        [USB_SPEED_FULL] = 1023,
285        [USB_SPEED_HIGH] = 1024,
286        [USB_SPEED_VARIABLE] = 3584,
287        [USB_SPEED_SUPER] = 1024,
288    };
289
290    /* control type */
291    static const uint16_t control_min[USB_SPEED_MAX] = {
292        [USB_SPEED_LOW] = 8,
293        [USB_SPEED_FULL] = 8,
294        [USB_SPEED_HIGH] = 64,
295        [USB_SPEED_VARIABLE] = 512,
296        [USB_SPEED_SUPER] = 512,
297    };
298
299    /* bulk type */
300    static const uint16_t bulk_min[USB_SPEED_MAX] = {
301        [USB_SPEED_LOW] = 8,
302        [USB_SPEED_FULL] = 8,
303        [USB_SPEED_HIGH] = 512,
304        [USB_SPEED_VARIABLE] = 512,
305        [USB_SPEED_SUPER] = 1024,
306    };
307
308    uint16_t temp;
309
310    /* reset the fields */
311    memset(ptr, 0, sizeof(*ptr));
312
313    switch (type) {
314        case USB_ENDPOINT_TYPE_INTR:
315            ptr->range.max = intr_range_max[speed];
316            break;
317        case USB_ENDPOINT_TYPE_ISOCHR:
318            ptr->range.max = isoc_range_max[speed];
319            break;
320        default:
321            if (type == USB_ENDPOINT_TYPE_BULK)
322                temp = bulk_min[speed];
323            else
324                temp = control_min[speed];
325
326            ptr->fixed[0] = temp;
327            ptr->fixed[1] = temp;
328            ptr->fixed[2] = temp;
329            ptr->fixed[3] = temp;
330
331            if (speed == USB_SPEED_FULL) {
332                ptr->fixed[1] = 16;
333                ptr->fixed[2] = 32;
334                ptr->fixed[3] = 64;
335            }
336            break;
337    }
338}
339
340/**
341 * \brief   this function is called from the xfer_setup function of the
342 *          respective USB host controller driver. This function sets the
343 *          correct values in the usb_xfer struct.
344 *
345 * \param   param   USB transfer setup parameters
346 *
347 */
348void usb_xfer_setup_struct(struct usb_xfer_setup_params *param)
349{
350    USB_DEBUG_TR_ENTER;
351
352    struct usb_xfer *xfer = param->curr_xfer;
353
354    /* do a parameter check */
355    if ((param->hc_max_packet_size == 0) || (param->hc_max_packet_count == 0)
356            || (param->hc_max_frame_size == 0)) {
357        USB_DEBUG("WARNING: Invaid setup parameter\n");
358        param->err = USB_ERR_INVAL;
359
360        xfer->max_hc_frame_size = 1;
361        xfer->max_frame_size = 1;
362        xfer->max_packet_size = 1;
363        xfer->max_data_length = 0;
364        xfer->num_frames = 0;
365        xfer->max_frame_count = 0;
366        USB_DEBUG_TR_RETURN;
367        return;
368    }
369
370    const struct usb_xfer_config *setup_config = param->xfer_setup;
371    struct usb_endpoint_descriptor *ep_desc = xfer->endpoint->descriptor;
372
373    assert(setup_config);
374    assert(ep_desc);
375
376    xfer->max_packet_size = xfer->endpoint->max_packet_size;
377
378    usb_speed_t ep_speed = param->speed;
379    uint8_t type = ep_desc->bmAttributes.xfer_type;
380    xfer->endpoint_number = ep_desc->bEndpointAddress.ep_number;
381    xfer->ed_direction = ep_desc->bEndpointAddress.direction;
382
383    xfer->max_packet_count = 1;
384
385    /* adjust maximum packet count and size */
386    switch (ep_speed) {
387        case USB_SPEED_HIGH:
388            if (type == USB_ENDPOINT_TYPE_ISOCHR
389                    || type == USB_ENDPOINT_TYPE_INTR) {
390                xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
391                if (xfer->max_packet_count > 3) {
392                    xfer->max_packet_count = 3;
393                }
394            }
395            xfer->max_packet_size &= 0x7FF;
396            break;
397        case USB_SPEED_SUPER:
398            assert(!"NYI: No super speed support right now.");
399            break;
400        default:
401            /* noop */
402            break;
403    }
404
405    uint32_t num_frlengths;
406    uint32_t num_frbuffers;
407
408    /* setup some values of the xfer struct */
409    xfer->flags = setup_config->flags;
410    xfer->num_frames = setup_config->frames;
411    xfer->timeout = setup_config->timeout;
412    xfer->interval = setup_config->interval;
413    param->bufsize = setup_config->bufsize;
414
415    xfer->flags_internal.usb_mode = param->device->flags.usb_mode;
416
417
418    struct usb_std_packet_size size;
419    usb_xfer_get_packet_size(&size, type, param->speed);
420
421    if (size.range.min || size.range.max) {
422        if (xfer->max_packet_size < size.range.min) {
423            xfer->max_packet_size = size.range.min;
424        }
425        if (xfer->max_packet_size > size.range.max) {
426            xfer->max_packet_size = size.range.max;
427        }
428    } else {
429        if (xfer->max_packet_size >= size.fixed[3]) {
430            xfer->max_packet_size = size.fixed[3];
431        } else if (xfer->max_packet_size >= size.fixed[2]) {
432            xfer->max_packet_size = size.fixed[2];
433        } else if (xfer->max_packet_size >= size.fixed[1]) {
434            xfer->max_packet_size = size.fixed[1];
435        } else {
436            /* only one possibility left */
437            xfer->max_packet_size = size.fixed[0];
438        }
439    }
440
441    /*
442     * range checks and filter values according to the host controller
443     * values. Maximum packet size and count must not be bigger than supported
444     * by the host controller.
445     */
446
447    if (xfer->max_packet_count > param->hc_max_packet_count) {
448        xfer->max_packet_count = param->hc_max_packet_count;
449    }
450
451    if ((xfer->max_packet_size > param->hc_max_packet_size)
452            || (xfer->max_packet_size == 0)) {
453        xfer->max_packet_size = param->hc_max_packet_size;
454    }
455
456    /*
457     * compute the maximum frame size as the maximum number of packets
458     * multiplied by the maximum packet size
459     */
460    xfer->max_frame_size = xfer->max_packet_size * xfer->max_packet_count;
461
462    /*
463     * isochronus and interrupt transfer need to be checked very INTERVALL ms
464     * so we need to setup the interval for this to transfer types
465     */
466    switch (type) {
467        case USB_TYPE_ISOC:
468            /* TODO: ISOCHRONUS IMPLEMENTATION */
469            assert(!"NYI: isochronus support not yet implemented");
470            break;
471        case USB_TYPE_INTR:
472            if (xfer->interval == 0) {
473                /* interval is not set, get it from the endpoint descriptor */
474                xfer->interval = ep_desc->bInterval;
475                /*
476                 * since the frames have different durations for FULL/LOW speed
477                 * and high speed devices we have to do conversion
478                 * from 125 us -> 1 ms
479                 */
480                if (param->speed != USB_SPEED_FULL
481                        && param->speed != USB_SPEED_LOW) {
482                    if (xfer->interval < 4) {
483                        /* smallest interval 1 ms*/
484                        xfer->interval = 1;
485                    } else if (xfer->interval > 16) {
486                        /* maximum interval 32ms */
487                        xfer->interval = (0x1 << (16 - 4));
488                    } else {
489                        /* normal interval */
490                        xfer->interval = (0x1 << (xfer->interval - 4));
491                    }
492                }
493            }
494
495            /* ensure that the interval is at least 1 */
496            xfer->interval += (xfer->interval ? 0 : 1);
497
498            /* calculate the frame down shift value */
499            xfer->frame_shift = 0;
500            uint32_t tmp = 1;
501            while ((tmp != 0) && (tmp < xfer->interval)) {
502                xfer->frame_shift++;
503                tmp *= 2;
504            }
505
506            if (param->speed != USB_SPEED_FULL
507                    && param->speed != USB_SPEED_LOW) {
508                xfer->frame_shift += 3;
509            }
510
511            break;
512        default:
513            /* noop */
514            break;
515    }
516    uint8_t max_length_zero = 0;
517
518    if ((xfer->max_frame_size == 0) || (xfer->max_packet_size == 0)) {
519
520        max_length_zero = 1;
521
522        /* check for minimum packet size */
523        if ((param->bufsize <= 8) && (type != USB_TYPE_CTRL)
524                && (type != USB_TYPE_BULK)) {
525            xfer->max_packet_size = 8;
526            xfer->max_packet_count = 1;
527            param->bufsize = 0;
528            xfer->max_frame_size = xfer->max_packet_size
529                    * xfer->max_packet_count;
530        } else {
531            /* error condition */
532            USB_DEBUG("WARNING: Invalid zero max length.\n");
533            param->err = USB_ERR_ZERO_MAXP;
534            xfer->max_hc_frame_size = 1;
535            xfer->max_frame_size = 1;
536            xfer->max_packet_size = 1;
537            xfer->max_data_length = 0;
538            xfer->num_frames = 0;
539            xfer->max_frame_count = 0;
540            USB_DEBUG_TR_RETURN;
541            return;
542        }
543    }
544
545    /*
546     * if the buffer size is not given, we set it to the default size
547     * such that the maximum frame fits into it. For isochronus we have
548     * to multiply this by the expected number of frames.
549     */
550    if (param->bufsize == 0) {
551        param->bufsize = xfer->max_frame_size;
552
553        if (type == USB_ENDPOINT_TYPE_ISOCHR) {
554            param->bufsize *= xfer->num_frames;
555        }
556    }
557
558    if (xfer->flags.ext_buffer) {
559        param->bufsize += (xfer->max_frame_size - 1);
560
561        if (param->bufsize < xfer->max_frame_size) {
562            param->err = USB_ERR_INVAL;
563            USB_DEBUG("WARNING: Invalid buffer size.\n");
564            xfer->max_hc_frame_size = 1;
565            xfer->max_frame_size = 1;
566            xfer->max_packet_size = 1;
567            xfer->max_data_length = 0;
568            xfer->num_frames = 0;
569            xfer->max_frame_count = 0;
570            USB_DEBUG_TR_RETURN;
571            return;
572        }
573        param->bufsize -= (param->bufsize % xfer->max_frame_size);
574        if (type == USB_ENDPOINT_TYPE_CONTROL) {
575            /* add the device request size for the setup message
576             *  to the buffer length
577             */
578            param->bufsize += 8;
579        }
580    }
581
582    xfer->max_data_length = param->bufsize;
583
584    /* calculate the number of required frames depending on the transfer type */
585    switch (type) {
586        case USB_TYPE_ISOC:
587            num_frlengths = xfer->num_frames;
588            num_frbuffers = 1;
589            break;
590
591        case USB_TYPE_CTRL:
592            /*
593             * control transfers are special, since they may have a data stage
594             * or not, the number of frames depends on this.
595             *
596             * If the buffer size is 8 bytes, this is just the size of the
597             * device request and thus there is no data stage.
598             *
599             * Set the flag indicating that this is a control transfer
600             */
601
602            xfer->flags_internal.ctrl_xfer = 1;
603
604            if (xfer->num_frames == 0) {
605                if (param->bufsize <= 8) {
606                    /* no data stage of this control request */
607                    xfer->num_frames = 1;
608                } else {
609                    /* there is a data stage of this control request */
610                    xfer->num_frames = 2;
611                }
612            }
613
614
615            num_frlengths = xfer->num_frames;
616            num_frbuffers = xfer->num_frames;
617
618            if (xfer->max_data_length < 8) {
619                /* too small length: wrap around or too small buffer size */
620                param->err = USB_ERR_INVAL;
621                USB_DEBUG("WARNING: invalid max_data_length.\n");
622                xfer->max_hc_frame_size = 1;
623                xfer->max_frame_size = 1;
624                xfer->max_packet_size = 1;
625                xfer->max_data_length = 0;
626                xfer->num_frames = 0;
627                xfer->max_frame_count = 0;
628                USB_DEBUG_TR_RETURN;
629                return;
630            }
631
632            /* subtract the request size */
633
634            xfer->max_data_length -= 8;
635            break;
636
637        default:
638            /* the num frames is at least one */
639            xfer->num_frames = (xfer->num_frames) ? (xfer->num_frames) : 1;
640            num_frlengths = xfer->num_frames;
641            num_frbuffers = xfer->num_frames;
642            break;
643    }
644
645
646    /* allocate the frame buffers and the frame length array */
647    xfer->max_frame_count = xfer->num_frames;
648
649    xfer->frame_lengths = malloc(2 * xfer->num_frames * sizeof(uint32_t));
650    xfer->frame_buffers = malloc(
651            xfer->num_frames * sizeof(struct usb_dma_page));
652
653    for (uint32_t i = 0; i < xfer->num_frames; i++) {
654        xfer->frame_lengths[i] = xfer->max_data_length;
655        xfer->frame_buffers[i] = usb_mem_dma_alloc(
656                param->num_pages * USB_PAGE_SIZE, USB_PAGE_SIZE);
657    }
658
659    /*
660     * we expect to have no data stage, so set it to the correct value
661     */
662    if (max_length_zero) {
663        xfer->max_data_length = 0;
664    }
665
666    /* round up maximum buf size */
667    if (param->bufsize_max < param->bufsize) {
668        param->bufsize_max = param->bufsize;
669    }
670
671    xfer->max_hc_frame_size = (param->hc_max_frame_size
672            - (param->hc_max_frame_size % xfer->max_frame_size));
673
674    if (xfer->max_hc_frame_size == 0) {
675        USB_DEBUG("WARNING: Invalid max_hc_frame_size.\n");
676        param->err = USB_ERR_INVAL;
677        xfer->max_hc_frame_size = 1;
678        xfer->max_frame_size = 1;
679        xfer->max_packet_size = 1;
680        xfer->max_data_length = 0;
681        xfer->num_frames = 0;
682        xfer->max_frame_count = 0;
683        USB_DEBUG_TR_RETURN;
684        return;
685    }
686
687    USB_DEBUG_TR_RETURN;
688}
689
690