Changeset c6f82e5 in mainline for uspace/lib/usbhost
- 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
- Location:
- uspace/lib/usbhost
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/include/usb/host/bus.h
r69b2dfee rc6f82e5 115 115 void (*endpoint_unregister)(endpoint_t *); 116 116 void (*endpoint_destroy)(endpoint_t *); /**< Optional */ 117 void (*endpoint_toggle_reset)(endpoint_t *); /**< Optional */118 117 ssize_t (*endpoint_count_bw) (endpoint_t *, size_t); /**< Optional */ 119 118 usb_transfer_batch_t *(*batch_create)(endpoint_t *); /**< Optional */ -
uspace/lib/usbhost/include/usb/host/endpoint.h
r69b2dfee rc6f82e5 61 61 /** Reserved bandwidth. */ 62 62 size_t bandwidth; 63 /** Value of the toggle bit. Untouched by the library. */64 unsigned toggle:1;65 63 /** The currently active transfer batch. Write using methods, read under guard. */ 66 64 usb_transfer_batch_t *active_batch; -
uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
r69b2dfee rc6f82e5 52 52 typedef struct bus bus_t; 53 53 54 /** How many toggles need to be reset */55 typedef enum {56 RESET_NONE,57 RESET_EP,58 RESET_ALL59 } toggle_reset_mode_t;60 61 54 /** Structure stores additional data needed for communication with EP */ 62 55 typedef struct usb_transfer_batch { … … 81 74 uint64_t packed; 82 75 } setup; 83 84 /** Resetting the Toggle */85 toggle_reset_mode_t toggle_reset_mode;86 76 87 77 /** Place for data to send/receive */ -
uspace/lib/usbhost/include/usb/host/utility.h
r69b2dfee rc6f82e5 44 44 #include <usb/request.h> 45 45 46 typedef void (*endpoint_reset_toggle_t)(endpoint_t *); 47 46 48 int hc_get_ep0_max_packet_size(uint16_t *, bus_t *, device_t *); 47 toggle_reset_mode_t hc_get_request_toggle_reset_mode(const usb_device_request_setup_packet_t *request);49 void hc_reset_toggles(const usb_transfer_batch_t *batch, endpoint_reset_toggle_t); 48 50 int hc_setup_virtual_root_hub(hc_device_t *); 49 51 int hc_get_device_desc(device_t *, usb_standard_device_descriptor_t *); -
uspace/lib/usbhost/src/endpoint.c
r69b2dfee rc6f82e5 121 121 } 122 122 123 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode);124 125 123 /** 126 124 * Wait until the endpoint have no transfer scheduled. … … 166 164 assert(ep); 167 165 assert(fibril_mutex_is_locked(&ep->guard)); 168 169 if (ep->active_batch && ep->active_batch->error == EOK)170 endpoint_toggle_reset(ep, ep->active_batch->toggle_reset_mode);171 172 166 ep->active_batch = NULL; 173 167 fibril_condvar_signal(&ep->avail); 174 }175 176 /**177 * The transfer on an endpoint can trigger a reset of the toggle bit. This178 * function calls the respective bus callbacks to resolve it.179 *180 * @param ep The endpoint that triggered the reset181 * @param mode Whether to reset no, one or all endpoints on a device.182 */183 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode)184 {185 assert(ep);186 187 if (mode == RESET_NONE)188 return;189 190 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_toggle_reset);191 if (!ops)192 return;193 194 195 if (mode == RESET_ALL) {196 const device_t *dev = ep->device;197 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {198 if (dev->endpoints[i])199 ops->endpoint_toggle_reset(dev->endpoints[i]);200 }201 } else {202 ops->endpoint_toggle_reset(ep);203 }204 168 } 205 169 … … 282 246 batch->on_complete_data = arg; 283 247 284 /* Check for commands that reset toggle bit */285 if (ep->transfer_type == USB_TRANSFER_CONTROL)286 batch->toggle_reset_mode287 = hc_get_request_toggle_reset_mode(&batch->setup.packet);288 289 248 const int ret = ops->batch_schedule(batch); 290 249 if (ret != EOK) { -
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.