source: mainline/uspace/lib/usb/src/hubdrv.c@ fe5e00d6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fe5e00d6 was dac43be, checked in by Vojtech Horky <vojtechhorky@…>, 15 years ago

File reorganization

The hcdhubd.c file was splitted into three source files and a common
header was added.

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*
2 * Copyright (c) 2010 Matus Dekanek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libusb usb
30 * @{
31 */
32/** @file
33 * @brief Hub driver.
34 */
35#include <usb/hcdhubd.h>
36#include <usb/devreq.h>
37#include <usbhc_iface.h>
38#include <usb/descriptor.h>
39#include <driver.h>
40#include <bool.h>
41#include <errno.h>
42#include <usb/classes/hub.h>
43#include "hcdhubd_private.h"
44
45static void check_hub_changes(void);
46
47size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
48
49//*********************************************
50//
51// various utils
52//
53//*********************************************
54
55void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
56 //base size
57 size_t size = 7;
58 //variable size according to port count
59 size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8 > 0) ? 1 : 0);
60 size += 2 * var_size;
61 uint8_t * result = (uint8_t*) malloc(size);
62 //size
63 result[0] = size;
64 //descriptor type
65 result[1] = USB_DESCTYPE_HUB;
66 result[2] = descriptor->ports_count;
67 /// @fixme handling of endianness??
68 result[3] = descriptor->hub_characteristics / 256;
69 result[4] = descriptor->hub_characteristics % 256;
70 result[5] = descriptor->pwr_on_2_good_time;
71 result[6] = descriptor->current_requirement;
72
73 size_t i;
74 for (i = 0; i < var_size; ++i) {
75 result[7 + i] = descriptor->devices_removable[i];
76 }
77 for (i = 0; i < var_size; ++i) {
78 result[7 + var_size + i] = 255;
79 }
80 return result;
81}
82
83usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
84 uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
85 if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL;
86 usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t));
87 //uint8_t size = sdescriptor[0];
88 result->ports_count = sdescriptor[2];
89 /// @fixme handling of endianness??
90 result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
91 result->pwr_on_2_good_time = sdescriptor[5];
92 result->current_requirement = sdescriptor[6];
93 size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
94 result->devices_removable = (uint8_t*) malloc(var_size);
95
96 size_t i;
97 for (i = 0; i < var_size; ++i) {
98 result->devices_removable[i] = sdescriptor[7 + i];
99 }
100 return result;
101}
102
103
104//*********************************************
105//
106// hub driver code
107//
108//*********************************************
109
110static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
111
112usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
113 usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
114 //get parent device
115 /// @TODO this code is not correct
116 device_t * my_hcd = device;
117 while (my_hcd->parent)
118 my_hcd = my_hcd->parent;
119 //dev->
120 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
121 //we add the hub into the first hc
122 //link_t *link_hc = hc_list.next;
123 //usb_hc_device_t *hc = list_get_instance(link_hc,
124 // usb_hc_device_t, link);
125 //must get generic device info
126
127
128 return result;
129}
130
131/** Callback when new hub device is detected.
132 *
133 * @param dev New device.
134 * @return Error code.
135 */
136int usb_add_hub_device(device_t *dev) {
137 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
138 set_hub_address(hc, 5);
139
140 check_hub_changes();
141
142 /*
143 * We are some (probably deeply nested) hub.
144 * Thus, assign our own operations and explore already
145 * connected devices.
146 */
147 //insert hub into list
148 //find owner hcd
149 device_t * my_hcd = dev;
150 while (my_hcd->parent)
151 my_hcd = my_hcd->parent;
152 //dev->
153 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
154 my_hcd = dev;
155 while (my_hcd->parent)
156 my_hcd = my_hcd->parent;
157 //dev->
158
159 printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
160
161 //create the hub structure
162 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
163
164
165 //append into the list
166 //we add the hub into the first hc
167 list_append(&hub_info->link, &hc->hubs);
168
169
170
171 return EOK;
172 //return ENOTSUP;
173}
174
175/** Sample usage of usb_hc_async functions.
176 * This function sets hub address using standard SET_ADDRESS request.
177 *
178 * @warning This function shall be removed once you are familiar with
179 * the usb_hc_ API.
180 *
181 * @param hc Host controller the hub belongs to.
182 * @param address New hub address.
183 */
184static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
185 printf("%s: setting hub address to %d\n", hc->generic->name, address);
186 usb_target_t target = {0, 0};
187 usb_handle_t handle;
188 int rc;
189
190 usb_device_request_setup_packet_t setup_packet = {
191 .request_type = 0,
192 .request = USB_DEVREQ_SET_ADDRESS,
193 .index = 0,
194 .length = 0,
195 };
196 setup_packet.value = address;
197
198 rc = usb_hc_async_control_write_setup(hc, target,
199 &setup_packet, sizeof (setup_packet), &handle);
200 if (rc != EOK) {
201 return;
202 }
203
204 rc = usb_hc_async_wait_for(handle);
205 if (rc != EOK) {
206 return;
207 }
208
209 rc = usb_hc_async_control_write_status(hc, target, &handle);
210 if (rc != EOK) {
211 return;
212 }
213
214 rc = usb_hc_async_wait_for(handle);
215 if (rc != EOK) {
216 return;
217 }
218
219 printf("%s: hub address changed\n", hc->generic->name);
220}
221
222/** Check changes on all known hubs.
223 */
224static void check_hub_changes(void) {
225 /*
226 * Iterate through all HCs.
227 */
228 link_t *link_hc;
229 for (link_hc = hc_list.next;
230 link_hc != &hc_list;
231 link_hc = link_hc->next) {
232 usb_hc_device_t *hc = list_get_instance(link_hc,
233 usb_hc_device_t, link);
234 /*
235 * Iterate through all their hubs.
236 */
237 link_t *link_hub;
238 for (link_hub = hc->hubs.next;
239 link_hub != &hc->hubs;
240 link_hub = link_hub->next) {
241 usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
242 usb_hcd_hub_info_t, link);
243
244 /*
245 * Check status change pipe of this hub.
246 */
247 usb_target_t target = {
248 .address = hub->device->address,
249 .endpoint = 1
250 };
251
252 // FIXME: count properly
253 size_t byte_length = (hub->port_count / 8) + 1;
254
255 void *change_bitmap = malloc(byte_length);
256 size_t actual_size;
257 usb_handle_t handle;
258
259 /*
260 * Send the request.
261 * FIXME: check returned value for possible errors
262 */
263 usb_hc_async_interrupt_in(hc, target,
264 change_bitmap, byte_length, &actual_size,
265 &handle);
266
267 usb_hc_async_wait_for(handle);
268
269 /*
270 * TODO: handle the changes.
271 */
272 }
273 }
274}
275
276/**
277 * @}
278 */
Note: See TracBrowser for help on using the repository browser.