Changeset c6f82e5 in mainline
- Timestamp:
- 2018-01-19T20:56:14Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7ec7b7e
- Parents:
- 69b2dfee
- Location:
- uspace
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_bus.c
r69b2dfee rc6f82e5 43 43 #include "hc.h" 44 44 45 /** Callback to set toggle on ED. 45 /** 46 * Callback to set toggle on ED. 46 47 * 47 48 * @param[in] hcd_ep hcd endpoint structure 48 49 * @param[in] toggle new value of toggle bit 49 50 */ 50 staticvoid ehci_ep_toggle_reset(endpoint_t *ep)51 void ehci_ep_toggle_reset(endpoint_t *ep) 51 52 { 52 53 ehci_endpoint_t *instance = ehci_endpoint_get(ep); … … 54 55 usb_log_warning("EP(%p): Resetting toggle bit for transfer directed EP", instance); 55 56 qh_toggle_set(instance->qh, 0); 56 ep->toggle = 0;57 57 } 58 58 … … 169 169 .interrupt = ehci_hc_interrupt, 170 170 .status = ehci_hc_status, 171 171 172 .endpoint_destroy = ehci_endpoint_destroy, 172 173 .endpoint_create = ehci_endpoint_create, 173 174 .endpoint_register = ehci_register_ep, 174 175 .endpoint_unregister = ehci_unregister_ep, 175 .endpoint_toggle_reset = ehci_ep_toggle_reset,176 176 .endpoint_count_bw = bandwidth_count_usb20, 177 177 178 .batch_create = ehci_create_batch, 178 179 .batch_destroy = ehci_destroy_batch, -
uspace/drv/bus/usb/ehci/ehci_bus.h
r69b2dfee rc6f82e5 68 68 } ehci_bus_t; 69 69 70 void ehci_ep_toggle_reset(endpoint_t *); 70 71 void ehci_bus_prepare_ops(void); 71 72 -
uspace/drv/bus/usb/ehci/hc.c
r69b2dfee rc6f82e5 45 45 #include <usb/debug.h> 46 46 #include <usb/usb.h> 47 #include <usb/host/utility.h> 47 48 48 49 #include "ehci_batch.h" … … 379 380 list_remove(current); 380 381 endpoint_del_ref(&ep->base); 382 hc_reset_toggles(&batch->base, &ehci_ep_toggle_reset); 381 383 usb_transfer_batch_finish(&batch->base); 382 384 } -
uspace/drv/bus/usb/ohci/hc.c
r69b2dfee rc6f82e5 45 45 46 46 #include <usb/debug.h> 47 #include <usb/host/utility.h> 47 48 #include <usb/usb.h> 48 49 … … 377 378 list_remove(current); 378 379 endpoint_del_ref(&ep->base); 380 hc_reset_toggles(&batch->base, &ohci_ep_toggle_reset); 379 381 usb_transfer_batch_finish(&batch->base); 380 382 } -
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c
r69b2dfee rc6f82e5 100 100 OHCI_MEM32_WR(instance->td_head, pa & ED_TDHEAD_PTR_MASK); 101 101 OHCI_MEM32_WR(instance->td_tail, pa & ED_TDTAIL_PTR_MASK); 102 103 /* Set toggle bit */104 if (ep->toggle)105 OHCI_MEM32_SET(instance->td_head, ED_TDHEAD_TOGGLE_CARRY);106 107 102 } 108 103 /** -
uspace/drv/bus/usb/ohci/ohci_bus.c
r69b2dfee rc6f82e5 43 43 #include "hc.h" 44 44 45 /** Callback to reset toggle on ED. 45 /** 46 * Callback to reset toggle on ED. 46 47 * 47 48 * @param[in] hcd_ep hcd endpoint structure 48 49 * @param[in] toggle new value of toggle bit 49 50 */ 50 staticvoid ohci_ep_toggle_reset(endpoint_t *ep)51 void ohci_ep_toggle_reset(endpoint_t *ep) 51 52 { 52 53 ohci_endpoint_t *instance = ohci_endpoint_get(ep); 53 54 assert(instance); 54 55 assert(instance->ed); 55 ep->toggle = 0;56 56 ed_toggle_set(instance->ed, 0); 57 57 } … … 179 179 .endpoint_unregister = ohci_unregister_ep, 180 180 .endpoint_count_bw = bandwidth_count_usb11, 181 .endpoint_toggle_reset = ohci_ep_toggle_reset, 181 182 182 .batch_create = ohci_create_batch, 183 183 .batch_destroy = ohci_destroy_batch, -
uspace/drv/bus/usb/ohci/ohci_bus.h
r69b2dfee rc6f82e5 65 65 66 66 int ohci_bus_init(ohci_bus_t *, hc_t *); 67 void ohci_ep_toggle_reset(endpoint_t *); 67 68 68 69 /** Get and convert assigned ohci_endpoint_t structure -
uspace/drv/bus/usb/uhci/hc.h
r69b2dfee rc6f82e5 127 127 } hc_t; 128 128 129 typedef struct uhci_endpoint { 130 endpoint_t base; 131 132 bool toggle; 133 } uhci_endpoint_t; 134 129 135 static inline hc_t *hcd_to_hc(hc_device_t *hcd) 130 136 { -
uspace/drv/bus/usb/uhci/transfer_list.c
r69b2dfee rc6f82e5 41 41 #include <usb/host/usb_transfer_batch.h> 42 42 #include <usb/host/utils/malloc32.h> 43 #include <usb/host/utility.h> 43 44 44 45 #include "hw_struct/link_pointer.h" 45 46 #include "transfer_list.h" 47 #include "hc.h" 46 48 47 49 /** Initialize transfer list structures. … … 155 157 } 156 158 159 /** 160 * Reset toggle on endpoint callback. 161 */ 162 static void uhci_reset_toggle(endpoint_t *ep) 163 { 164 uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) ep; 165 uhci_ep->toggle = 0; 166 } 167 157 168 /** Add completed batches to the provided list. 158 169 * … … 176 187 fibril_mutex_lock(&batch->base.ep->guard); 177 188 assert(batch->base.ep->active_batch == &batch->base); 189 hc_reset_toggles(&batch->base, &uhci_reset_toggle); 178 190 endpoint_deactivate_locked(batch->base.ep); 179 191 transfer_list_remove_batch(instance, batch); -
uspace/drv/bus/usb/uhci/uhci_batch.c
r69b2dfee rc6f82e5 46 46 47 47 #include "uhci_batch.h" 48 #include "hc.h" 48 49 #include "hw_struct/transfer_descriptor.h" 49 50 … … 164 165 batch->transfered_size = 0; 165 166 167 uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) batch->ep; 168 166 169 for (size_t i = 0;i < uhci_batch->td_count; ++i) { 167 170 if (td_is_active(&uhci_batch->tds[i])) { … … 178 181 td_print_status(&uhci_batch->tds[i]); 179 182 180 batch->ep->toggle = td_toggle(&uhci_batch->tds[i]);183 uhci_ep->toggle = td_toggle(&uhci_batch->tds[i]); 181 184 goto substract_ret; 182 185 } … … 230 233 const size_t mps = uhci_batch->base.ep->max_packet_size; 231 234 232 int toggle = uhci_batch->base.ep->toggle; 235 uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) uhci_batch->base.ep; 236 237 int toggle = uhci_ep->toggle; 233 238 assert(toggle == 0 || toggle == 1); 234 239 … … 254 259 } 255 260 td_set_ioc(&uhci_batch->tds[td - 1]); 256 uhci_ batch->base.ep->toggle = toggle;261 uhci_ep->toggle = toggle; 257 262 usb_log_debug2( 258 263 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.", \ -
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.