source: mainline/uspace/lib/usbhost/src/bandwidth.c@ 02fe42e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 02fe42e was d1582b50, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Fix spacing in single-line comments using latest ccheck

This found incorrectly formatted section comments (with blocks of
asterisks or dashes). I strongly believe against using section comments
but I am not simply removing them since that would probably be
controversial.

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[41924f30]1/*
2 * Copyright (c) 2011 Jan Vesely
[e0a5d4c]3 * Copyright (c) 2018 Ondrej Hlavaty
[41924f30]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/** @addtogroup libusbhost
30 * @{
31 */
32/** @file
33 *
34 * Bandwidth calculation functions. Shared among uhci, ohci and ehci drivers.
35 */
36
37#include <assert.h>
38#include <stdlib.h>
39
[64fea02]40#include "endpoint.h"
41#include "bus.h"
42
43#include "bandwidth.h"
44
[b357377]45/** Bytes per second in FULL SPEED */
46#define BANDWIDTH_TOTAL_USB11 (12000000 / 8)
47/** 90% of total bandwidth is available for periodic transfers */
48#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 * 9) / 10)
49
[1102eca]50/**
51 * Calculate bandwidth that needs to be reserved for communication with EP.
[41924f30]52 * Calculation follows USB 1.1 specification.
[b357377]53 *
54 * @param ep An endpoint for which the bandwidth is to be counted
[41924f30]55 */
[b357377]56static size_t bandwidth_count_usb11(endpoint_t *ep)
[41924f30]57{
[fc0271a5]58 assert(ep);
[888238e9]59 assert(ep->device);
[fc0271a5]60
61 const usb_transfer_type_t type = ep->transfer_type;
62
[41924f30]63 /* We care about bandwidth only for interrupt and isochronous. */
[3bacee1]64 if ((type != USB_TRANSFER_INTERRUPT) &&
65 (type != USB_TRANSFER_ISOCHRONOUS)) {
[41924f30]66 return 0;
67 }
68
[fc0271a5]69 const size_t max_packet_size = ep->max_packet_size;
[b357377]70 const size_t packet_count = ep->packets_per_uframe;
[fc0271a5]71
[7c3fb9b]72 /*
73 * TODO: It may be that ISO and INT transfers use only one packet per
74 * transaction, but I did not find text in USB spec to confirm this
75 */
[41924f30]76 /* NOTE: All data packets will be considered to be max_packet_size */
[ae3a941]77 switch (ep->device->speed) {
[41924f30]78 case USB_SPEED_LOW:
79 assert(type == USB_TRANSFER_INTERRUPT);
[7c3fb9b]80 /*
81 * Protocol overhead 13B
[41924f30]82 * (3 SYNC bytes, 3 PID bytes, 2 Endpoint + CRC bytes, 2
83 * CRC bytes, and a 3-byte interpacket delay)
[7c3fb9b]84 * see USB spec page 45-46.
85 */
[d1582b50]86 /* Speed penalty 8: low speed is 8-times slower */
[41924f30]87 return packet_count * (13 + max_packet_size) * 8;
88 case USB_SPEED_FULL:
[7c3fb9b]89 /*
90 * Interrupt transfer overhead see above
91 * or page 45 of USB spec
92 */
[41924f30]93 if (type == USB_TRANSFER_INTERRUPT)
94 return packet_count * (13 + max_packet_size);
95
96 assert(type == USB_TRANSFER_ISOCHRONOUS);
[7c3fb9b]97 /*
98 * Protocol overhead 9B
[41924f30]99 * (2 SYNC bytes, 2 PID bytes, 2 Endpoint + CRC bytes, 2 CRC
100 * bytes, and a 1-byte interpacket delay)
[7c3fb9b]101 * see USB spec page 42
102 */
[41924f30]103 return packet_count * (9 + max_packet_size);
104 default:
105 return 0;
106 }
107}
108
[b357377]109const bandwidth_accounting_t bandwidth_accounting_usb11 = {
110 .available_bandwidth = BANDWIDTH_AVAILABLE_USB11,
111 .count_bw = &bandwidth_count_usb11,
112};
113
114/** Number of nanoseconds in one microframe */
115#define BANDWIDTH_TOTAL_USB2 (125000)
116/** 90% of total bandwidth is available for periodic transfers */
117#define BANDWIDTH_AVAILABLE_USB2 ((BANDWIDTH_TOTAL_USB2 * 9) / 10)
118
119/**
[1102eca]120 * Calculate bandwidth that needs to be reserved for communication with EP.
[ecbad17]121 * Calculation follows USB 2.0 specification, chapter 5.11.3.
122 *
[b357377]123 * FIXME: Interrupt transfers shall be probably divided by their polling interval.
124 *
125 * @param ep An endpoint for which the bandwidth is to be counted
[ecbad17]126 * @return Number of nanoseconds transaction with @c size bytes payload will
127 * take.
[41924f30]128 */
[b357377]129static size_t bandwidth_count_usb2(endpoint_t *ep)
[41924f30]130{
[fc0271a5]131 assert(ep);
[b357377]132 assert(ep->device);
[fc0271a5]133
134 const usb_transfer_type_t type = ep->transfer_type;
135
[41924f30]136 /* We care about bandwidth only for interrupt and isochronous. */
[3bacee1]137 if ((type != USB_TRANSFER_INTERRUPT) &&
138 (type != USB_TRANSFER_ISOCHRONOUS)) {
[41924f30]139 return 0;
140 }
[ecbad17]141
142 // FIXME: Come up with some upper bound for these (in ns).
143 const size_t host_delay = 0;
144 const size_t hub_ls_setup = 0;
145
146 // Approx. Floor(3.167 + BitStuffTime(Data_bc))
[b357377]147 const size_t base_time = (ep->max_transfer_size * 8 + 19) / 6;
[ecbad17]148
149 switch (ep->device->speed) {
150 case USB_SPEED_LOW:
151 if (ep->direction == USB_DIRECTION_IN)
[ae3a941]152 return 64060 + (2 * hub_ls_setup) +
[3bacee1]153 (677 * base_time) + host_delay;
[ecbad17]154 else
[ae3a941]155 return 64107 + (2 * hub_ls_setup) +
[3bacee1]156 (667 * base_time) + host_delay;
[ecbad17]157
158 case USB_SPEED_FULL:
159 if (ep->transfer_type == USB_TRANSFER_INTERRUPT)
160 return 9107 + 84 * base_time + host_delay;
161
162 if (ep->direction == USB_DIRECTION_IN)
163 return 7268 + 84 * base_time + host_delay;
164 else
165 return 6265 + 84 * base_time + host_delay;
166
167 case USB_SPEED_HIGH:
168 if (ep->transfer_type == USB_TRANSFER_INTERRUPT)
169 return (3648 + 25 * base_time + 11) / 12 + host_delay;
170 else
171 return (5280 + 25 * base_time + 11) / 12 + host_delay;
172
173 default:
174 return 0;
175 }
[41924f30]176}
[b357377]177
178const bandwidth_accounting_t bandwidth_accounting_usb2 = {
179 .available_bandwidth = BANDWIDTH_AVAILABLE_USB2,
180 .count_bw = &bandwidth_count_usb2,
181};
Note: See TracBrowser for help on using the repository browser.