Changes in uspace/lib/usb/src/hcdhubd.c [dac43be:e4dbfda] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
rdac43be re4dbfda 31 31 */ 32 32 /** @file 33 * @brief Common stuff for both HC driver and hub driver.33 * @brief HC driver and hub driver (implementation). 34 34 */ 35 35 #include <usb/hcdhubd.h> 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb/descriptor.h>39 38 #include <driver.h> 40 39 #include <bool.h> 41 40 #include <errno.h> 42 #include <usb/classes/hub.h> 43 44 #include "hcdhubd_private.h" 41 42 #define USB_HUB_DEVICE_NAME "usbhub" 43 44 /** List of handled host controllers. */ 45 static LIST_INITIALIZE(hc_list); 46 47 /** Our HC driver. */ 48 static usb_hc_driver_t *hc_driver = NULL; 49 50 static usbhc_iface_t usb_interface = { 51 .interrupt_out = NULL, 52 .interrupt_in = NULL 53 }; 54 55 static device_ops_t usb_device_ops = { 56 .interfaces[USBHC_DEV_IFACE] = &usb_interface 57 }; 58 59 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 45 60 46 61 /** Callback when new device is detected and must be handled by this driver. … … 49 64 * @return Error code. 50 65 */ 51 static int add_device(device_t *dev) { 66 static int add_device(device_t *dev) 67 { 68 /* 69 * FIXME: use some magic to determine whether hub or another HC 70 * was connected. 71 */ 52 72 bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0; 53 73 printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name); … … 57 77 * We are the HC itself. 58 78 */ 59 return usb_add_hc_device(dev); 79 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t)); 80 list_initialize(&hc_dev->link); 81 hc_dev->transfer_ops = NULL; 82 83 hc_dev->generic = dev; 84 dev->ops = &usb_device_ops; 85 hc_dev->generic->driver_data = hc_dev; 86 87 int rc = hc_driver->add_hc(hc_dev); 88 if (rc != EOK) { 89 free(hc_dev); 90 return rc; 91 } 92 93 /* 94 * FIXME: The following line causes devman to hang. 95 * Will investigate later why. 96 */ 97 // add_device_to_class(dev, "usbhc"); 98 99 list_append(&hc_dev->link, &hc_list); 100 101 return EOK; 60 102 } else { 103 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); 104 set_hub_address(hc, 5); 105 61 106 /* 62 * We are some ( maybedeeply nested) hub.107 * We are some (probably deeply nested) hub. 63 108 * Thus, assign our own operations and explore already 64 109 * connected devices. 65 110 */ 66 return usb_add_hub_device(dev); 111 112 return ENOTSUP; 113 } 114 } 115 116 /** Sample usage of usb_hc_async functions. 117 * This function sets hub address using standard SET_ADDRESS request. 118 * 119 * @warning This function shall be removed once you are familiar with 120 * the usb_hc_ API. 121 * 122 * @param hc Host controller the hub belongs to. 123 * @param address New hub address. 124 */ 125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) 126 { 127 printf("%s: setting hub address to %d\n", hc->generic->name, address); 128 usb_target_t target = {0, 0}; 129 usb_handle_t handle; 130 int rc; 131 132 usb_device_request_setup_packet_t setup_packet = { 133 .request_type = 0, 134 .request = USB_DEVREQ_SET_ADDRESS, 135 .index = 0, 136 .length = 0, 137 }; 138 setup_packet.value = address; 139 140 rc = usb_hc_async_control_write_setup(hc, target, 141 &setup_packet, sizeof(setup_packet), &handle); 142 if (rc != EOK) { 143 return; 144 } 145 146 rc = usb_hc_async_wait_for(handle); 147 if (rc != EOK) { 148 return; 149 } 150 151 rc = usb_hc_async_control_write_status(hc, target, &handle); 152 if (rc != EOK) { 153 return; 154 } 155 156 rc = usb_hc_async_wait_for(handle); 157 if (rc != EOK) { 158 return; 159 } 160 161 printf("%s: hub address changed\n", hc->generic->name); 162 } 163 164 /** Check changes on all known hubs. 165 */ 166 static void check_hub_changes(void) 167 { 168 /* 169 * Iterate through all HCs. 170 */ 171 link_t *link_hc; 172 for (link_hc = hc_list.next; 173 link_hc != &hc_list; 174 link_hc = link_hc->next) { 175 usb_hc_device_t *hc = list_get_instance(link_hc, 176 usb_hc_device_t, link); 177 /* 178 * Iterate through all their hubs. 179 */ 180 link_t *link_hub; 181 for (link_hub = hc->hubs.next; 182 link_hub != &hc->hubs; 183 link_hub = link_hub->next) { 184 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 185 usb_hcd_hub_info_t, link); 186 187 /* 188 * Check status change pipe of this hub. 189 */ 190 usb_target_t target = { 191 .address = hub->device->address, 192 .endpoint = 1 193 }; 194 195 // FIXME: count properly 196 size_t byte_length = (hub->port_count / 8) + 1; 197 198 void *change_bitmap = malloc(byte_length); 199 size_t actual_size; 200 usb_handle_t handle; 201 202 /* 203 * Send the request. 204 * FIXME: check returned value for possible errors 205 */ 206 usb_hc_async_interrupt_in(hc, target, 207 change_bitmap, byte_length, &actual_size, 208 &handle); 209 210 usb_hc_async_wait_for(handle); 211 212 /* 213 * TODO: handle the changes. 214 */ 215 } 67 216 } 68 217 } … … 85 234 * @return Error code. 86 235 */ 87 int usb_hcd_main(usb_hc_driver_t *hc) { 236 int usb_hcd_main(usb_hc_driver_t *hc) 237 { 88 238 hc_driver = hc; 89 239 hc_driver_generic.name = hc->name; 240 241 /* 242 * Launch here fibril that will periodically check all 243 * attached hubs for status change. 244 * WARN: This call will effectively do nothing. 245 */ 246 check_hub_changes(); 90 247 91 248 /*
Note:
See TracChangeset
for help on using the changeset viewer.