source: mainline/uspace/drv/usbhub/utils.c@ 9ca0013

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

Add sample code for adding new device in hub

  • Property mode set to 100644
File size: 6.2 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 <driver.h>
36#include <usb/devreq.h>
37#include <usbhc_iface.h>
38#include <usb/usbdrv.h>
39#include <usb/descriptor.h>
40#include <driver.h>
41#include <bool.h>
42#include <errno.h>
43#include <usb/classes/hub.h>
44#include "usbhub.h"
45
46static void check_hub_changes(void);
47
48size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
49
50//*********************************************
51//
52// various utils
53//
54//*********************************************
55
56void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
57 //base size
58 size_t size = 7;
59 //variable size according to port count
60 size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8 > 0) ? 1 : 0);
61 size += 2 * var_size;
62 uint8_t * result = (uint8_t*) malloc(size);
63 //size
64 result[0] = size;
65 //descriptor type
66 result[1] = USB_DESCTYPE_HUB;
67 result[2] = descriptor->ports_count;
68 /// @fixme handling of endianness??
69 result[3] = descriptor->hub_characteristics / 256;
70 result[4] = descriptor->hub_characteristics % 256;
71 result[5] = descriptor->pwr_on_2_good_time;
72 result[6] = descriptor->current_requirement;
73
74 size_t i;
75 for (i = 0; i < var_size; ++i) {
76 result[7 + i] = descriptor->devices_removable[i];
77 }
78 for (i = 0; i < var_size; ++i) {
79 result[7 + var_size + i] = 255;
80 }
81 return result;
82}
83
84usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
85 uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
86 if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL;
87 usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t));
88 //uint8_t size = sdescriptor[0];
89 result->ports_count = sdescriptor[2];
90 /// @fixme handling of endianness??
91 result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
92 result->pwr_on_2_good_time = sdescriptor[5];
93 result->current_requirement = sdescriptor[6];
94 size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
95 result->devices_removable = (uint8_t*) malloc(var_size);
96
97 size_t i;
98 for (i = 0; i < var_size; ++i) {
99 result->devices_removable[i] = sdescriptor[7 + i];
100 }
101 return result;
102}
103
104
105//*********************************************
106//
107// hub driver code
108//
109//*********************************************
110
111usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
112 usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
113
114 return result;
115}
116
117/** Callback when new hub device is detected.
118 *
119 * @param dev New device.
120 * @return Error code.
121 */
122int usb_add_hub_device(device_t *dev) {
123 printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
124
125 check_hub_changes();
126
127 /*
128 * We are some (probably deeply nested) hub.
129 * Thus, assign our own operations and explore already
130 * connected devices.
131 */
132
133 //create the hub structure
134 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
135 (void)hub_info;
136
137 return EOK;
138 //return ENOTSUP;
139}
140
141
142/** Check changes on all known hubs.
143 */
144static void check_hub_changes(void) {
145 /*
146 * Iterate through all hubs.
147 */
148 for (; false; ) {
149 /*
150 * Check status change pipe of this hub.
151 */
152 usb_target_t target = {
153 .address = 5,
154 .endpoint = 1
155 };
156
157 size_t port_count = 7;
158
159 /*
160 * Connect to respective HC.
161 */
162 int hc = usb_drv_hc_connect(NULL, 0);
163 if (hc < 0) {
164 continue;
165 }
166
167 // FIXME: count properly
168 size_t byte_length = (port_count / 8) + 1;
169
170 void *change_bitmap = malloc(byte_length);
171 size_t actual_size;
172 usb_handle_t handle;
173
174 /*
175 * Send the request.
176 * FIXME: check returned value for possible errors
177 */
178 usb_drv_async_interrupt_in(hc, target,
179 change_bitmap, byte_length, &actual_size,
180 &handle);
181
182 usb_drv_async_wait_for(handle);
183
184 /*
185 * TODO: handle the changes.
186 */
187
188 /*
189 * WARNING: sample code, will not work out of the box.
190 * And does not contain code for checking for errors.
191 */
192#if 0
193 /*
194 * Before opening the port, we must acquire the default
195 * address.
196 */
197 usb_drv_reserve_default_address(hc);
198
199 usb_address_t new_device_address = usb_drv_request_address(hc);
200
201 // TODO: open the port
202
203 // TODO: send request for setting address to new_device_address
204
205 /*
206 * Once new address is set, we can release the default
207 * address.
208 */
209 usb_drv_release_default_address(hc);
210
211 /*
212 * Obtain descriptors and create match ids for devman.
213 */
214
215 // TODO: get device descriptors
216
217 // TODO: create match ids
218
219 // TODO: add child device
220
221 // child_device_register sets the device handle
222 // TODO: store it here
223 devman_handle_t new_device_handle = 0;
224
225 /*
226 * Inform the HC that the new device has devman handle
227 * assigned.
228 */
229 usb_drv_bind_address(hc, new_device_address, new_device_handle);
230
231 /*
232 * That's all.
233 */
234#endif
235
236
237 /*
238 * Hang-up the HC-connected phone.
239 */
240 ipc_hangup(hc);
241 }
242}
243
244/**
245 * @}
246 */
Note: See TracBrowser for help on using the repository browser.