Changeset 36c410e in mainline
- Timestamp:
- 2010-12-04T15:52:12Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6f04905
- Parents:
- 4317827 (diff), 2cb6571 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/utils.c
r4317827 r36c410e 109 109 //********************************************* 110 110 111 static void set_hub_address(device_t *dev, usb_address_t address);112 113 111 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) { 114 112 usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t)); … … 124 122 int usb_add_hub_device(device_t *dev) { 125 123 printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle); 126 set_hub_address(dev, 5);127 124 128 125 check_hub_changes(); … … 142 139 } 143 140 144 /** Sample usage of usb_hc_async functions.145 * This function sets hub address using standard SET_ADDRESS request.146 *147 * @warning This function shall be removed once you are familiar with148 * the usb_hc_ API.149 *150 * @param hc Host controller the hub belongs to.151 * @param address New hub address.152 */153 static void set_hub_address(device_t *dev, usb_address_t address) {154 printf(NAME ": setting hub address to %d\n", address);155 usb_target_t target = {0, 0};156 usb_handle_t handle;157 int rc;158 159 usb_device_request_setup_packet_t setup_packet = {160 .request_type = 0,161 .request = USB_DEVREQ_SET_ADDRESS,162 .index = 0,163 .length = 0,164 };165 setup_packet.value = address;166 167 int hc = usb_drv_hc_connect(dev, 0);168 169 rc = usb_drv_async_control_write_setup(hc, target,170 &setup_packet, sizeof (setup_packet), &handle);171 if (rc != EOK) {172 return;173 }174 175 rc = usb_drv_async_wait_for(handle);176 if (rc != EOK) {177 return;178 }179 180 rc = usb_drv_async_control_write_status(hc, target, &handle);181 if (rc != EOK) {182 return;183 }184 185 rc = usb_drv_async_wait_for(handle);186 if (rc != EOK) {187 return;188 }189 190 printf(NAME ": hub address changed\n");191 }192 141 193 142 /** Check changes on all known hubs. -
uspace/lib/usb/include/usb/hcdhubd.h
r4317827 r36c410e 116 116 } usb_hcd_transfer_ops_t; 117 117 118 /** 119 * @brief structure holding information about free and used addresses 120 * 121 * This structure should not be used outside usb hcd driver. 122 * You better consider it to be 'private'. 123 */ 124 typedef struct { 125 /** lower bound included in the interval */ 126 usb_address_t lower_bound; 127 128 /** upper bound, excluded from the interval */ 129 usb_address_t upper_bound; 130 131 /** */ 132 link_t link; 133 }usb_address_list_t; 134 118 135 struct usb_hc_device { 119 136 /** Transfer operations. */ … … 131 148 /** List of hubs operating from this HC. */ 132 149 link_t hubs; 150 151 /** Structure with free and used addresses */ 152 link_t addresses; 133 153 134 154 /** Link to other driven HCs. */ … … 148 168 int usb_hcd_add_root_hub(device_t *dev); 149 169 170 /** 171 * find first not yet used address on this host controller and use it 172 * @param this_hcd 173 * @return number in the range of allowed usb addresses or 174 * a negative number if not succesful 175 */ 176 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd); 177 178 /** 179 * @brief free the address in the address space of this hcd. 180 * 181 * if address is not used, nothing happens 182 * @param this_hcd 183 * @param addr 184 */ 185 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr ); 186 150 187 151 188 /* -
uspace/lib/usb/src/hcdhubd.c
r4317827 r36c410e 114 114 115 115 /** Adds a child device fibril worker. */ 116 static int fibril_add_child_device(void *arg) 117 { 116 static int fibril_add_child_device(void *arg) { 118 117 struct child_device_info *child_info 119 118 = (struct child_device_info *) arg; 120 119 int rc; 121 120 … … 141 140 142 141 printf("%s: adding child device `%s' with match \"%s\"\n", 143 142 hc_driver->name, child->name, match_id->id); 144 143 rc = child_device_register(child, child_info->parent); 145 144 printf("%s: child device `%s' registration: %s\n", 146 145 hc_driver->name, child->name, str_error(rc)); 147 146 148 147 if (rc != EOK) { … … 182 181 */ 183 182 int usb_hc_add_child_device(device_t *parent, const char *name, 184 const char *match_id, bool create_fibril) 185 { 183 const char *match_id, bool create_fibril) { 186 184 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 187 185 name, match_id); 188 186 189 187 /* … … 194 192 195 193 struct child_device_info *child_info 196 = malloc(sizeof(struct child_device_info));194 = malloc(sizeof (struct child_device_info)); 197 195 198 196 child_info->parent = parent; … … 218 216 * @return USB device address or error code. 219 217 */ 220 usb_address_t usb_get_address_by_handle(devman_handle_t handle) 221 { 218 usb_address_t usb_get_address_by_handle(devman_handle_t handle) { 222 219 /* TODO: search list of attached devices. */ 223 220 return ENOENT; 224 221 } 225 222 223 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) { 224 //is there free address? 225 link_t * addresses = &this_hcd->addresses; 226 if (list_empty(addresses)) return -1; 227 link_t * link_addr = addresses; 228 bool found = false; 229 usb_address_list_t * range = NULL; 230 while (!found) { 231 link_addr = link_addr->next; 232 if (link_addr == addresses) return -2; 233 range = list_get_instance(link_addr, 234 usb_address_list_t, link); 235 if (range->upper_bound - range->lower_bound > 0) { 236 found = true; 237 } 238 } 239 //now we have interval 240 int result = range->lower_bound; 241 ++(range->lower_bound); 242 if (range->upper_bound - range->lower_bound == 0) { 243 list_remove(&range->link); 244 free(range); 245 } 246 return result; 247 } 248 249 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) { 250 //check range 251 if (addr < usb_lowest_address || addr > usb_highest_address) 252 return; 253 link_t * addresses = &this_hcd->addresses; 254 link_t * link_addr = addresses; 255 //find 'good' interval 256 usb_address_list_t * found_range = NULL; 257 bool found = false; 258 while (!found) { 259 link_addr = link_addr->next; 260 if (link_addr == addresses) { 261 found = true; 262 } else { 263 usb_address_list_t * range = list_get_instance(link_addr, 264 usb_address_list_t, link); 265 if ( (range->lower_bound - 1 == addr) || 266 (range->upper_bound == addr)) { 267 found = true; 268 found_range = range; 269 } 270 if (range->lower_bound - 1 > addr) { 271 found = true; 272 } 273 274 } 275 } 276 if (found_range == NULL) { 277 //no suitable range found 278 usb_address_list_t * result_range = 279 (usb_address_list_t*) malloc(sizeof (usb_address_list_t)); 280 result_range->lower_bound = addr; 281 result_range->upper_bound = addr + 1; 282 list_insert_before(&result_range->link, link_addr); 283 } else { 284 //we have good range 285 if (found_range->lower_bound - 1 == addr) { 286 --found_range->lower_bound; 287 } else { 288 //only one possible case 289 ++found_range->upper_bound; 290 if (found_range->link.next != addresses) { 291 usb_address_list_t * next_range = 292 list_get_instance( &found_range->link.next, 293 usb_address_list_t, link); 294 //check neighbour range 295 if (next_range->lower_bound == addr + 1) { 296 //join ranges 297 found_range->upper_bound = next_range->upper_bound; 298 list_remove(&next_range->link); 299 free(next_range); 300 } 301 } 302 } 303 } 304 305 } 306 226 307 /** 227 308 * @} -
uspace/lib/usb/src/hcdhubd_private.h
r4317827 r36c410e 47 47 int usb_add_hc_device(device_t *); 48 48 49 /** lowest allowed usb address */ 50 extern int usb_lowest_address; 51 52 /** highest allowed usb address */ 53 extern int usb_highest_address; 54 55 /** 56 * @brief initialize address list of given hcd 57 * 58 * This function should be used only for hcd initialization. 59 * It creates interval list of free addresses, thus it is initialized as 60 * list with one interval with whole address space. Using an address shrinks 61 * the interval, freeing an address extends an interval or creates a 62 * new one. 63 * 64 * @param hcd 65 * @return 66 */ 67 void usb_create_address_list(usb_hc_device_t * hcd); 68 69 70 71 72 73 49 74 #endif 50 75 /** -
uspace/lib/usb/src/hcdrv.c
r4317827 r36c410e 55 55 usb_hc_driver_t *hc_driver = &hc_driver_fake; 56 56 57 int usb_lowest_address = 1; 58 59 int usb_highest_address = 255; 60 57 61 static device_ops_t usb_device_ops = { 58 62 .interfaces[USBHC_DEV_IFACE] = &usbhc_interface 59 63 }; 64 65 66 void usb_create_address_list(usb_hc_device_t * hcd){ 67 list_initialize(&hcd->addresses); 68 usb_address_list_t * range = 69 (usb_address_list_t*)malloc(sizeof(usb_address_list_t)); 70 range->lower_bound = usb_lowest_address; 71 range->upper_bound = usb_highest_address + 1; 72 list_append(&range->link, &hcd->addresses); 73 } 60 74 61 75 static usb_hc_device_t *usb_hc_device_create(device_t *dev) { … … 64 78 list_initialize(&hc_dev->link); 65 79 list_initialize(&hc_dev->hubs); 80 usb_create_address_list(hc_dev); 66 81 list_initialize(&hc_dev->attached_devices); 67 82 hc_dev->transfer_ops = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.