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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4144630 was 4144630, checked in by smekideki@…>, 15 years ago

usb adresses assigning

  • Property mode set to 100644
File size: 7.7 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 device_t * my_hcd = device;
116 while (my_hcd->parent)
117 my_hcd = my_hcd->parent;
118 //dev->
119 printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
120 //we add the hub into the first hc
121 //link_t *link_hc = hc_list.next;
122 //usb_hc_device_t *hc = list_get_instance(link_hc,
123 // usb_hc_device_t, link);
124 //must get generic device info
125
126
127 return result;
128}
129
130/** Callback when new hub device is detected.
131 *
132 * @param dev New device.
133 * @return Error code.
134 */
135int usb_add_hub_device(device_t *dev) {
136 //usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
137 assert(dev->parent);
138 usb_hc_device_t *hc = (usb_hc_device_t*)dev->parent->driver_data;
139 usb_address_t addr =usb_use_free_address(hc);
140 if(addr<0){
141 printf("[hcdhubd] ERROR: cannot find an address \n");
142 }
143 set_hub_address(hc, addr);
144
145 check_hub_changes();
146
147 /*
148 * We are some (probably deeply nested) hub.
149 * Thus, assign our own operations and explore already
150 * connected devices.
151 */
152 //insert hub into list
153 //find owner hcd
154 device_t * my_hcd = dev;
155 while (my_hcd->parent)
156 my_hcd = my_hcd->parent;
157 //dev->
158 printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
159 my_hcd = dev;
160 while (my_hcd->parent)
161 my_hcd = my_hcd->parent;
162 //dev->
163
164 printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
165
166 //create the hub structure
167 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
168
169
170 //append into the list
171 //we add the hub into the first hc
172 list_append(&hub_info->link, &hc->hubs);
173
174
175
176 return EOK;
177 //return ENOTSUP;
178}
179
180/** Sample usage of usb_hc_async functions.
181 * This function sets hub address using standard SET_ADDRESS request.
182 *
183 * @warning This function shall be removed once you are familiar with
184 * the usb_hc_ API.
185 *
186 * @param hc Host controller the hub belongs to.
187 * @param address New hub address.
188 */
189static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
190 printf("[hcdhubd]%s: setting hub address to %d\n", hc->generic->name, address);
191 usb_target_t target = {0, 0};
192 usb_handle_t handle;
193 int rc;
194
195 usb_device_request_setup_packet_t setup_packet = {
196 .request_type = 0,
197 .request = USB_DEVREQ_SET_ADDRESS,
198 .index = 0,
199 .length = 0,
200 };
201 setup_packet.value = address;
202
203 rc = usb_hc_async_control_write_setup(hc, target,
204 &setup_packet, sizeof (setup_packet), &handle);
205 if (rc != EOK) {
206 return;
207 }
208
209 rc = usb_hc_async_wait_for(handle);
210 if (rc != EOK) {
211 return;
212 }
213
214 rc = usb_hc_async_control_write_status(hc, target, &handle);
215 if (rc != EOK) {
216 return;
217 }
218
219 rc = usb_hc_async_wait_for(handle);
220 if (rc != EOK) {
221 return;
222 }
223
224 printf("[hcdhubd]%s: hub address changed successfully to %d\n",
225 hc->generic->name, address);
226}
227
228/** Check changes on all known hubs.
229 */
230static void check_hub_changes(void) {
231 /*
232 * Iterate through all HCs.
233 */
234 link_t *link_hc;
235 for (link_hc = hc_list.next;
236 link_hc != &hc_list;
237 link_hc = link_hc->next) {
238 usb_hc_device_t *hc = list_get_instance(link_hc,
239 usb_hc_device_t, link);
240 /*
241 * Iterate through all their hubs.
242 */
243 link_t *link_hub;
244 for (link_hub = hc->hubs.next;
245 link_hub != &hc->hubs;
246 link_hub = link_hub->next) {
247 usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
248 usb_hcd_hub_info_t, link);
249
250 /*
251 * Check status change pipe of this hub.
252 */
253 usb_target_t target = {
254 .address = hub->device->address,
255 .endpoint = 1
256 };
257
258 // FIXME: count properly
259 size_t byte_length = (hub->port_count / 8) + 1;
260
261 void *change_bitmap = malloc(byte_length);
262 size_t actual_size;
263 usb_handle_t handle;
264
265 /*
266 * Send the request.
267 * FIXME: check returned value for possible errors
268 */
269 usb_hc_async_interrupt_in(hc, target,
270 change_bitmap, byte_length, &actual_size,
271 &handle);
272
273 usb_hc_async_wait_for(handle);
274
275 /*
276 * TODO: handle the changes.
277 */
278 }
279 }
280}
281
282/**
283 * @}
284 */
Note: See TracBrowser for help on using the repository browser.