Changeset c6f82e5 in mainline for uspace/lib/usbhost/src/utility.c
- Timestamp:
- 2018-01-19T20:56:14Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7ec7b7e
- Parents:
- 69b2dfee
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/utility.c
r69b2dfee rc6f82e5 37 37 #include <usb/debug.h> 38 38 #include <usb/descriptor.h> 39 #include <usb/request.h> 39 40 40 41 #include "ddf_helpers.h" … … 101 102 } 102 103 103 /** Check setup packet data for signs of toggle reset. 104 * 105 * @param[in] requst Setup requst data. 106 * 107 * @retval -1 No endpoints need reset. 108 * @retval 0 All endpoints need reset. 109 * @retval >0 Specified endpoint needs reset. 110 * 111 */ 112 toggle_reset_mode_t hc_get_request_toggle_reset_mode(const usb_device_request_setup_packet_t *request) 113 { 114 assert(request); 104 int hc_get_device_desc(device_t *device, usb_standard_device_descriptor_t *desc) 105 { 106 const usb_target_t control_ep = {{ 107 .address = device->address, 108 .endpoint = 0, 109 }}; 110 111 /* Get std device descriptor */ 112 const usb_device_request_setup_packet_t get_device_desc = 113 GET_DEVICE_DESC(sizeof(*desc)); 114 115 usb_log_debug("Device(%d): Requesting full device descriptor.", 116 device->address); 117 ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN, 118 (char *) desc, sizeof(*desc), *(uint64_t *)&get_device_desc, 119 "read device descriptor"); 120 121 if (got < 0) 122 return got; 123 124 return got == sizeof(*desc) ? EOK : EOVERFLOW; 125 } 126 127 int hc_get_hub_desc(device_t *device, usb_hub_descriptor_header_t *desc) 128 { 129 const usb_target_t control_ep = {{ 130 .address = device->address, 131 .endpoint = 0, 132 }}; 133 134 const usb_device_request_setup_packet_t get_hub_desc = { 135 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST 136 | (USB_REQUEST_TYPE_CLASS << 5) 137 | USB_REQUEST_RECIPIENT_DEVICE, 138 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 139 .value = uint16_host2usb(USB_DESCTYPE_HUB << 8), \ 140 .length = sizeof(*desc), 141 }; 142 143 usb_log_debug("Device(%d): Requesting hub descriptor.", 144 device->address); 145 ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN, 146 (char *) desc, sizeof(*desc), *(uint64_t *)&get_hub_desc, 147 "get hub descriptor"); 148 149 if (got < 0) 150 return got; 151 152 return got == sizeof(*desc) ? EOK : EOVERFLOW; 153 } 154 155 int hc_device_explore(device_t *device) 156 { 157 int err; 158 usb_standard_device_descriptor_t desc = { 0 }; 159 160 if ((err = hc_get_device_desc(device, &desc))) { 161 usb_log_error("Device(%d): Failed to get dev descriptor: %s", 162 device->address, str_error(err)); 163 return err; 164 } 165 166 if ((err = hcd_ddf_setup_match_ids(device, &desc))) { 167 usb_log_error("Device(%d): Failed to setup match ids: %s", device->address, str_error(err)); 168 return err; 169 } 170 171 return EOK; 172 } 173 174 /** Announce root hub to the DDF 175 * 176 * @param[in] device Host controller ddf device 177 * @return Error code 178 */ 179 int hc_setup_virtual_root_hub(hc_device_t *hcd) 180 { 181 int err; 182 183 assert(hcd); 184 185 device_t *dev = hcd_ddf_fun_create(hcd, USB_SPEED_MAX); 186 if (!dev) { 187 usb_log_error("Failed to create function for the root hub."); 188 return ENOMEM; 189 } 190 191 ddf_fun_set_name(dev->fun, "roothub"); 192 193 /* Assign an address to the device */ 194 if ((err = bus_device_enumerate(dev))) { 195 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 196 goto err_usb_dev; 197 } 198 199 if ((err = ddf_fun_bind(dev->fun))) { 200 usb_log_error("Failed to register roothub: %s.", str_error(err)); 201 goto err_enumerated; 202 } 203 204 return EOK; 205 206 err_enumerated: 207 bus_device_gone(dev); 208 err_usb_dev: 209 hcd_ddf_fun_destroy(dev); 210 return err; 211 } 212 213 /** How many toggles need to be reset */ 214 typedef enum { 215 RESET_NONE, 216 RESET_EP, 217 RESET_ALL 218 } toggle_reset_mode_t; 219 220 /** 221 * Check setup packet data for signs of toggle reset. 222 * 223 * @param[in] batch USB batch 224 */ 225 static toggle_reset_mode_t get_request_toggle_reset_mode(const usb_transfer_batch_t *batch) 226 { 227 if (batch->ep->transfer_type != USB_TRANSFER_CONTROL 228 || batch->dir != USB_DIRECTION_OUT) 229 return RESET_NONE; 230 231 const usb_device_request_setup_packet_t *request = &batch->setup.packet; 232 115 233 switch (request->request) 116 234 { … … 139 257 } 140 258 141 int hc_get_device_desc(device_t *device, usb_standard_device_descriptor_t *desc) 142 { 143 const usb_target_t control_ep = {{ 144 .address = device->address, 145 .endpoint = 0, 146 }}; 147 148 /* Get std device descriptor */ 149 const usb_device_request_setup_packet_t get_device_desc = 150 GET_DEVICE_DESC(sizeof(*desc)); 151 152 usb_log_debug("Device(%d): Requesting full device descriptor.", 153 device->address); 154 ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN, 155 (char *) desc, sizeof(*desc), *(uint64_t *)&get_device_desc, 156 "read device descriptor"); 157 158 if (got < 0) 159 return got; 160 161 return got == sizeof(*desc) ? EOK : EOVERFLOW; 162 } 163 164 int hc_get_hub_desc(device_t *device, usb_hub_descriptor_header_t *desc) 165 { 166 const usb_target_t control_ep = {{ 167 .address = device->address, 168 .endpoint = 0, 169 }}; 170 171 const usb_device_request_setup_packet_t get_hub_desc = { 172 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST 173 | (USB_REQUEST_TYPE_CLASS << 5) 174 | USB_REQUEST_RECIPIENT_DEVICE, 175 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 176 .value = uint16_host2usb(USB_DESCTYPE_HUB << 8), \ 177 .length = sizeof(*desc), 178 }; 179 180 usb_log_debug("Device(%d): Requesting hub descriptor.", 181 device->address); 182 ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN, 183 (char *) desc, sizeof(*desc), *(uint64_t *)&get_hub_desc, 184 "get hub descriptor"); 185 186 if (got < 0) 187 return got; 188 189 return got == sizeof(*desc) ? EOK : EOVERFLOW; 190 } 191 192 int hc_device_explore(device_t *device) 193 { 194 int err; 195 usb_standard_device_descriptor_t desc = { 0 }; 196 197 if ((err = hc_get_device_desc(device, &desc))) { 198 usb_log_error("Device(%d): Failed to get dev descriptor: %s", 199 device->address, str_error(err)); 200 return err; 201 } 202 203 if ((err = hcd_ddf_setup_match_ids(device, &desc))) { 204 usb_log_error("Device(%d): Failed to setup match ids: %s", device->address, str_error(err)); 205 return err; 206 } 207 208 return EOK; 209 } 210 211 /** Announce root hub to the DDF 212 * 213 * @param[in] device Host controller ddf device 214 * @return Error code 215 */ 216 int hc_setup_virtual_root_hub(hc_device_t *hcd) 217 { 218 int err; 219 220 assert(hcd); 221 222 device_t *dev = hcd_ddf_fun_create(hcd, USB_SPEED_MAX); 223 if (!dev) { 224 usb_log_error("Failed to create function for the root hub."); 225 return ENOMEM; 226 } 227 228 ddf_fun_set_name(dev->fun, "roothub"); 229 230 /* Assign an address to the device */ 231 if ((err = bus_device_enumerate(dev))) { 232 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 233 goto err_usb_dev; 234 } 235 236 if ((err = ddf_fun_bind(dev->fun))) { 237 usb_log_error("Failed to register roothub: %s.", str_error(err)); 238 goto err_enumerated; 239 } 240 241 return EOK; 242 243 err_enumerated: 244 bus_device_gone(dev); 245 err_usb_dev: 246 hcd_ddf_fun_destroy(dev); 247 return err; 259 void hc_reset_toggles(const usb_transfer_batch_t *batch, endpoint_reset_toggle_t reset_cb) 260 { 261 assert(reset_cb); 262 assert(batch->ep); 263 assert(batch->ep->device); 264 265 if (batch->error != EOK) 266 return; 267 268 toggle_reset_mode_t mode = get_request_toggle_reset_mode(batch); 269 270 if (mode == RESET_NONE) 271 return; 272 273 if (mode == RESET_ALL) { 274 const device_t *dev = batch->ep->device; 275 for (usb_endpoint_t i = 0; i < 2 * USB_ENDPOINT_MAX; ++i) { 276 if (dev->endpoints[i]) 277 reset_cb(dev->endpoints[i]); 278 } 279 } else { 280 reset_cb(batch->ep); 281 } 248 282 } 249 283
Note:
See TracChangeset
for help on using the changeset viewer.