Changes in / [f1d6866:85ff862] in mainline
- Files:
-
- 15 added
- 16 deleted
- 60 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
rf1d6866 r85ff862 166 166 $(USPACE_PATH)/app/lsusb/lsusb \ 167 167 $(USPACE_PATH)/app/sbi/sbi \ 168 $(USPACE_PATH)/app/sportdmp/sportdmp \169 168 $(USPACE_PATH)/app/redir/redir \ 170 169 $(USPACE_PATH)/app/taskdump/taskdump \ -
kernel/arch/arm32/src/ras.c
rf1d6866 r85ff862 86 86 } 87 87 88 /** @}89 */ -
kernel/generic/include/adt/list.h
rf1d6866 r85ff862 173 173 * 174 174 */ 175 NO_TRACE static inline int list_empty( constlist_t *list)175 NO_TRACE static inline int list_empty(list_t *list) 176 176 { 177 177 return (list->head.next == &list->head); … … 186 186 * 187 187 */ 188 static inline link_t *list_first( constlist_t *list)188 static inline link_t *list_first(list_t *list) 189 189 { 190 190 return ((list->head.next == &list->head) ? NULL : list->head.next); -
kernel/generic/src/mm/frame.c
rf1d6866 r85ff862 1142 1142 size_t znum = find_zone(pfn, 1, 0); 1143 1143 1144 1144 1145 ASSERT(znum != (size_t) -1); 1145 1146 -
uspace/Makefile
rf1d6866 r85ff862 51 51 app/redir \ 52 52 app/sbi \ 53 app/sportdmp \54 53 app/stats \ 55 54 app/taskdump \ -
uspace/drv/bus/isa/isa.c
rf1d6866 r85ff862 405 405 static void fun_hw_res_alloc(isa_fun_t *fun) 406 406 { 407 fun->hw_resources.resources = 407 fun->hw_resources.resources = 408 408 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 409 409 } -
uspace/drv/bus/usb/ehci/hc_iface.c
rf1d6866 r85ff862 145 145 } 146 146 147 /** Schedule interrupt out transfer. 148 * 149 * The callback is supposed to be called once the transfer (on the wire) is 150 * complete regardless of the outcome. 151 * However, the callback could be called only when this function returns 152 * with success status (i.e. returns EOK). 153 * 154 * @param[in] fun Device function the action was invoked on. 155 * @param[in] target Target pipe (address and endpoint number) specification. 156 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 157 * by the caller). 158 * @param[in] size Size of the @p data buffer in bytes. 159 * @param[in] callback Callback to be issued once the transfer is complete. 160 * @param[in] arg Pass-through argument to the callback. 161 * @return Error code. 162 */ 163 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 164 void *data, size_t size, 165 usbhc_iface_transfer_out_callback_t callback, void *arg) 166 { 167 UNSUPPORTED("interrupt_out"); 168 169 return ENOTSUP; 170 } 171 172 /** Schedule interrupt in transfer. 173 * 174 * The callback is supposed to be called once the transfer (on the wire) is 175 * complete regardless of the outcome. 176 * However, the callback could be called only when this function returns 177 * with success status (i.e. returns EOK). 178 * 179 * @param[in] fun Device function the action was invoked on. 180 * @param[in] target Target pipe (address and endpoint number) specification. 181 * @param[in] data Buffer where to store the data (in USB endianess, 182 * allocated and deallocated by the caller). 183 * @param[in] size Size of the @p data buffer in bytes. 184 * @param[in] callback Callback to be issued once the transfer is complete. 185 * @param[in] arg Pass-through argument to the callback. 186 * @return Error code. 187 */ 188 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 189 void *data, size_t size, 190 usbhc_iface_transfer_in_callback_t callback, void *arg) 191 { 192 UNSUPPORTED("interrupt_in"); 193 194 return ENOTSUP; 195 } 196 197 /** Schedule bulk out transfer. 198 * 199 * The callback is supposed to be called once the transfer (on the wire) is 200 * complete regardless of the outcome. 201 * However, the callback could be called only when this function returns 202 * with success status (i.e. returns EOK). 203 * 204 * @param[in] fun Device function the action was invoked on. 205 * @param[in] target Target pipe (address and endpoint number) specification. 206 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 207 * by the caller). 208 * @param[in] size Size of the @p data buffer in bytes. 209 * @param[in] callback Callback to be issued once the transfer is complete. 210 * @param[in] arg Pass-through argument to the callback. 211 * @return Error code. 212 */ 213 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 214 void *data, size_t size, 215 usbhc_iface_transfer_out_callback_t callback, void *arg) 216 { 217 UNSUPPORTED("bulk_out"); 218 219 return ENOTSUP; 220 } 221 222 /** Schedule bulk in transfer. 223 * 224 * The callback is supposed to be called once the transfer (on the wire) is 225 * complete regardless of the outcome. 226 * However, the callback could be called only when this function returns 227 * with success status (i.e. returns EOK). 228 * 229 * @param[in] fun Device function the action was invoked on. 230 * @param[in] target Target pipe (address and endpoint number) specification. 231 * @param[in] data Buffer where to store the data (in USB endianess, 232 * allocated and deallocated by the caller). 233 * @param[in] size Size of the @p data buffer in bytes. 234 * @param[in] callback Callback to be issued once the transfer is complete. 235 * @param[in] arg Pass-through argument to the callback. 236 * @return Error code. 237 */ 238 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 239 void *data, size_t size, 240 usbhc_iface_transfer_in_callback_t callback, void *arg) 241 { 242 UNSUPPORTED("bulk_in"); 243 244 return ENOTSUP; 245 } 246 247 /** Schedule control write transfer. 248 * 249 * The callback is supposed to be called once the transfer (on the wire) is 250 * complete regardless of the outcome. 251 * However, the callback could be called only when this function returns 252 * with success status (i.e. returns EOK). 253 * 254 * @param[in] fun Device function the action was invoked on. 255 * @param[in] target Target pipe (address and endpoint number) specification. 256 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 257 * and deallocated by the caller). 258 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes. 259 * @param[in] data_buffer Data buffer (in USB endianess, allocated and 260 * deallocated by the caller). 261 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes. 262 * @param[in] callback Callback to be issued once the transfer is complete. 263 * @param[in] arg Pass-through argument to the callback. 264 * @return Error code. 265 */ 266 static int control_write(ddf_fun_t *fun, usb_target_t target, 267 void *setup_packet, size_t setup_packet_size, 268 void *data_buffer, size_t data_buffer_size, 269 usbhc_iface_transfer_out_callback_t callback, void *arg) 270 { 271 UNSUPPORTED("control_write"); 272 273 return ENOTSUP; 274 } 275 276 /** Schedule control read transfer. 277 * 278 * The callback is supposed to be called once the transfer (on the wire) is 279 * complete regardless of the outcome. 280 * However, the callback could be called only when this function returns 281 * with success status (i.e. returns EOK). 282 * 283 * @param[in] fun Device function the action was invoked on. 284 * @param[in] target Target pipe (address and endpoint number) specification. 285 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 286 * and deallocated by the caller). 287 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes. 288 * @param[in] data_buffer Buffer where to store the data (in USB endianess, 289 * allocated and deallocated by the caller). 290 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes. 291 * @param[in] callback Callback to be issued once the transfer is complete. 292 * @param[in] arg Pass-through argument to the callback. 293 * @return Error code. 294 */ 295 static int control_read(ddf_fun_t *fun, usb_target_t target, 296 void *setup_packet, size_t setup_packet_size, 297 void *data_buffer, size_t data_buffer_size, 298 usbhc_iface_transfer_in_callback_t callback, void *arg) 299 { 300 UNSUPPORTED("control_read"); 301 302 return ENOTSUP; 303 } 304 147 305 /** Host controller interface implementation for EHCI. */ 148 306 usbhc_iface_t ehci_hc_iface = { … … 154 312 .register_endpoint = register_endpoint, 155 313 .unregister_endpoint = unregister_endpoint, 314 315 .interrupt_out = interrupt_out, 316 .interrupt_in = interrupt_in, 317 318 .bulk_out = bulk_out, 319 .bulk_in = bulk_in, 320 321 .control_write = control_write, 322 .control_read = control_read 156 323 }; 157 324 -
uspace/drv/bus/usb/ohci/Makefile
rf1d6866 r85ff862 44 44 45 45 SOURCES = \ 46 batch.c \ 46 47 endpoint_list.c \ 47 48 hc.c \ 49 hcd_endpoint.c \ 50 iface.c \ 48 51 main.c \ 49 52 ohci.c \ 50 ohci_batch.c \51 ohci_endpoint.c \52 53 pci.c \ 53 54 root_hub.c \ -
uspace/drv/bus/usb/ohci/endpoint_list.c
rf1d6866 r85ff862 87 87 * The endpoint is added to the end of the list and queue. 88 88 */ 89 void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep)89 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) 90 90 { 91 91 assert(instance); 92 assert(ep); 93 usb_log_debug2("Queue %s: Adding endpoint(%p).\n", instance->name, ep); 92 assert(hcd_ep); 93 usb_log_debug2("Queue %s: Adding endpoint(%p).\n", 94 instance->name, hcd_ep); 94 95 95 96 fibril_mutex_lock(&instance->guard); … … 102 103 } else { 103 104 /* There are active EDs, get the last one */ 104 ohci_endpoint_t *last = list_get_instance(105 list_last(&instance->endpoint_list), ohci_endpoint_t, link);105 hcd_endpoint_t *last = list_get_instance( 106 list_last(&instance->endpoint_list), hcd_endpoint_t, link); 106 107 last_ed = last->ed; 107 108 } 108 109 /* Keep link */ 109 ep->ed->next = last_ed->next;110 hcd_ep->ed->next = last_ed->next; 110 111 /* Make sure ED is written to the memory */ 111 112 write_barrier(); 112 113 113 114 /* Add ed to the hw queue */ 114 ed_append_ed(last_ed, ep->ed);115 ed_append_ed(last_ed, hcd_ep->ed); 115 116 /* Make sure ED is updated */ 116 117 write_barrier(); 117 118 118 119 /* Add to the sw list */ 119 list_append(& ep->link, &instance->endpoint_list);120 list_append(&hcd_ep->link, &instance->endpoint_list); 120 121 121 ohci_endpoint_t *first = list_get_instance(122 list_first(&instance->endpoint_list), ohci_endpoint_t, link);122 hcd_endpoint_t *first = list_get_instance( 123 list_first(&instance->endpoint_list), hcd_endpoint_t, link); 123 124 usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n", 124 ep, instance->name, first, first->ed);125 hcd_ep, instance->name, first, first->ed); 125 126 if (last_ed == instance->list_head) { 126 127 usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x:%x:%x.\n", … … 137 138 * @param[in] endpoint Endpoint to remove. 138 139 */ 139 void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep)140 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) 140 141 { 141 142 assert(instance); 142 143 assert(instance->list_head); 143 assert( ep);144 assert( ep->ed);144 assert(hcd_ep); 145 assert(hcd_ep->ed); 145 146 146 147 fibril_mutex_lock(&instance->guard); 147 148 148 usb_log_debug2("Queue %s: removing endpoint(%p).\n", instance->name, ep); 149 usb_log_debug2( 150 "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep); 149 151 150 152 const char *qpos = NULL; 151 153 ed_t *prev_ed; 152 154 /* Remove from the hardware queue */ 153 if (list_first(&instance->endpoint_list) == & ep->link) {155 if (list_first(&instance->endpoint_list) == &hcd_ep->link) { 154 156 /* I'm the first one here */ 155 157 prev_ed = instance->list_head; 156 158 qpos = "FIRST"; 157 159 } else { 158 ohci_endpoint_t *prev =159 list_get_instance( ep->link.prev, ohci_endpoint_t, link);160 hcd_endpoint_t *prev = 161 list_get_instance(hcd_ep->link.prev, hcd_endpoint_t, link); 160 162 prev_ed = prev->ed; 161 163 qpos = "NOT FIRST"; 162 164 } 163 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys( ep->ed));164 prev_ed->next = ep->ed->next;165 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed)); 166 prev_ed->next = hcd_ep->ed->next; 165 167 /* Make sure ED is updated */ 166 168 write_barrier(); 167 169 168 170 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 169 ep, qpos, instance->name,ep->ed->next);171 hcd_ep, qpos, instance->name, hcd_ep->ed->next); 170 172 171 173 /* Remove from the endpoint list */ 172 list_remove(& ep->link);174 list_remove(&hcd_ep->link); 173 175 fibril_mutex_unlock(&instance->guard); 174 176 } -
uspace/drv/bus/usb/ohci/endpoint_list.h
rf1d6866 r85ff862 37 37 #include <fibril_synch.h> 38 38 39 #include " ohci_endpoint.h"39 #include "hcd_endpoint.h" 40 40 #include "hw_struct/endpoint_descriptor.h" 41 41 #include "utils/malloc32.h" … … 69 69 int endpoint_list_init(endpoint_list_t *instance, const char *name); 70 70 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 71 void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep);72 void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep);71 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 72 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 73 73 #endif 74 74 /** -
uspace/drv/bus/usb/ohci/hc.c
rf1d6866 r85ff862 42 42 43 43 #include "hc.h" 44 #include " ohci_endpoint.h"44 #include "hcd_endpoint.h" 45 45 46 46 #define OHCI_USED_INTERRUPTS \ … … 61 61 static int hc_init_memory(hc_t *instance); 62 62 static int interrupt_emulator(hc_t *instance); 63 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 63 64 64 /*----------------------------------------------------------------------------*/ 65 65 /** Get number of commands used in IRQ code. … … 128 128 129 129 const usb_address_t hub_address = 130 usb_device_manager_get_free_address( 131 &instance->generic.dev_manager, USB_SPEED_FULL); 130 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 132 131 if (hub_address <= 0) { 133 132 usb_log_error("Failed to get OHCI root hub address: %s\n", … … 136 135 } 137 136 instance->rh.address = hub_address; 138 usb_device_ manager_bind(139 &instance-> generic.dev_manager, hub_address, hub_fun->handle);140 141 #define CHECK_RET_ UNREG_RETURN(ret, message...) \137 usb_device_keeper_bind( 138 &instance->manager, hub_address, hub_fun->handle); 139 140 #define CHECK_RET_RELEASE(ret, message...) \ 142 141 if (ret != EOK) { \ 143 142 usb_log_error(message); \ 144 usb_endpoint_manager_unregister_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\ 146 usb_device_manager_release( \ 147 &instance->generic.dev_manager, hub_address); \ 143 hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \ 144 usb_device_keeper_release(&instance->manager, hub_address); \ 148 145 return ret; \ 149 146 } else (void)0 150 int ret = usb_endpoint_manager_add_ep( 151 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 152 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0); 153 CHECK_RET_UNREG_RETURN(ret, 154 "Failed to register root hub control endpoint: %s.\n", 155 str_error(ret)); 147 148 int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 149 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 150 CHECK_RET_RELEASE(ret, 151 "Failed to add OHCI root hub endpoint 0: %s.\n", str_error(ret)); 156 152 157 153 ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 158 CHECK_RET_ UNREG_RETURN(ret,154 CHECK_RET_RELEASE(ret, 159 155 "Failed to add root hub match-id: %s.\n", str_error(ret)); 160 156 161 157 ret = ddf_fun_bind(hub_fun); 162 CHECK_RET_ UNREG_RETURN(ret,158 CHECK_RET_RELEASE(ret, 163 159 "Failed to bind root hub function: %s.\n", str_error(ret)); 164 160 … … 191 187 192 188 list_initialize(&instance->pending_batches); 193 194 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n", 189 usb_device_keeper_init(&instance->manager); 190 191 ret = usb_endpoint_manager_init(&instance->ep_manager, 192 BANDWIDTH_AVAILABLE_USB11); 193 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 197 194 str_error(ret)); 198 instance->generic.private_data = instance;199 instance->generic.schedule = hc_schedule;200 instance->generic.ep_add_hook = ohci_endpoint_init;201 195 202 196 ret = hc_init_memory(instance); … … 221 215 } 222 216 /*----------------------------------------------------------------------------*/ 223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep) 224 { 225 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 226 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 227 /* Enqueue ep */ 217 /** Create and register endpoint structures. 218 * 219 * @param[in] instance OHCI driver structure. 220 * @param[in] address USB address of the device. 221 * @param[in] endpoint USB endpoint number. 222 * @param[in] speed Communication speeed of the device. 223 * @param[in] type Endpoint's transfer type. 224 * @param[in] direction Endpoint's direction. 225 * @param[in] mps Maximum packet size the endpoint accepts. 226 * @param[in] size Maximum allowed buffer size. 227 * @param[in] interval Time between transfers(interrupt transfers only). 228 * @return Error code 229 */ 230 int hc_add_endpoint( 231 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, 232 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 233 size_t mps, size_t size, unsigned interval) 234 { 235 endpoint_t *ep = 236 endpoint_get(address, endpoint, direction, type, speed, mps); 237 if (ep == NULL) 238 return ENOMEM; 239 240 hcd_endpoint_t *hcd_ep = hcd_endpoint_assign(ep); 241 if (hcd_ep == NULL) { 242 endpoint_destroy(ep); 243 return ENOMEM; 244 } 245 246 int ret = 247 usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size); 248 if (ret != EOK) { 249 hcd_endpoint_clear(ep); 250 endpoint_destroy(ep); 251 return ret; 252 } 253 254 /* Enqueue hcd_ep */ 228 255 switch (ep->transfer_type) { 229 256 case USB_TRANSFER_CONTROL: 230 257 instance->registers->control &= ~C_CLE; 231 endpoint_list_add_ep(list, ohci_ep); 258 endpoint_list_add_ep( 259 &instance->lists[ep->transfer_type], hcd_ep); 232 260 instance->registers->control_current = 0; 233 261 instance->registers->control |= C_CLE; … … 235 263 case USB_TRANSFER_BULK: 236 264 instance->registers->control &= ~C_BLE; 237 endpoint_list_add_ep(list, ohci_ep); 265 endpoint_list_add_ep( 266 &instance->lists[ep->transfer_type], hcd_ep); 238 267 instance->registers->control |= C_BLE; 239 268 break; … … 241 270 case USB_TRANSFER_INTERRUPT: 242 271 instance->registers->control &= (~C_PLE & ~C_IE); 243 endpoint_list_add_ep(list, ohci_ep); 272 endpoint_list_add_ep( 273 &instance->lists[ep->transfer_type], hcd_ep); 244 274 instance->registers->control |= C_PLE | C_IE; 245 275 break; 246 276 } 247 } 248 /*----------------------------------------------------------------------------*/ 249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep) 250 { 251 /* Dequeue ep */ 252 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 253 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 254 switch (ep->transfer_type) { 255 case USB_TRANSFER_CONTROL: 256 instance->registers->control &= ~C_CLE; 257 endpoint_list_remove_ep(list, ohci_ep); 258 instance->registers->control_current = 0; 259 instance->registers->control |= C_CLE; 260 break; 261 case USB_TRANSFER_BULK: 262 instance->registers->control &= ~C_BLE; 263 endpoint_list_remove_ep(list, ohci_ep); 264 instance->registers->control |= C_BLE; 265 break; 266 case USB_TRANSFER_ISOCHRONOUS: 267 case USB_TRANSFER_INTERRUPT: 268 instance->registers->control &= (~C_PLE & ~C_IE); 269 endpoint_list_remove_ep(list, ohci_ep); 270 instance->registers->control |= C_PLE | C_IE; 271 break; 272 default: 273 break; 274 } 277 278 return EOK; 279 } 280 /*----------------------------------------------------------------------------*/ 281 /** Dequeue and delete endpoint structures 282 * 283 * @param[in] instance OHCI hc driver structure. 284 * @param[in] address USB address of the device. 285 * @param[in] endpoint USB endpoint number. 286 * @param[in] direction Direction of the endpoint. 287 * @return Error code 288 */ 289 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 290 usb_endpoint_t endpoint, usb_direction_t direction) 291 { 292 assert(instance); 293 fibril_mutex_lock(&instance->guard); 294 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 295 address, endpoint, direction, NULL); 296 if (ep == NULL) { 297 usb_log_error("Endpoint unregister failed: No such EP.\n"); 298 fibril_mutex_unlock(&instance->guard); 299 return ENOENT; 300 } 301 302 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 303 if (hcd_ep) { 304 /* Dequeue hcd_ep */ 305 switch (ep->transfer_type) { 306 case USB_TRANSFER_CONTROL: 307 instance->registers->control &= ~C_CLE; 308 endpoint_list_remove_ep( 309 &instance->lists[ep->transfer_type], hcd_ep); 310 instance->registers->control_current = 0; 311 instance->registers->control |= C_CLE; 312 break; 313 case USB_TRANSFER_BULK: 314 instance->registers->control &= ~C_BLE; 315 endpoint_list_remove_ep( 316 &instance->lists[ep->transfer_type], hcd_ep); 317 instance->registers->control |= C_BLE; 318 break; 319 case USB_TRANSFER_ISOCHRONOUS: 320 case USB_TRANSFER_INTERRUPT: 321 instance->registers->control &= (~C_PLE & ~C_IE); 322 endpoint_list_remove_ep( 323 &instance->lists[ep->transfer_type], hcd_ep); 324 instance->registers->control |= C_PLE | C_IE; 325 break; 326 default: 327 break; 328 } 329 hcd_endpoint_clear(ep); 330 } else { 331 usb_log_warning("Endpoint without hcd equivalent structure.\n"); 332 } 333 int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager, 334 address, endpoint, direction); 335 fibril_mutex_unlock(&instance->guard); 336 return ret; 337 } 338 /*----------------------------------------------------------------------------*/ 339 /** Get access to endpoint structures 340 * 341 * @param[in] instance OHCI hc driver structure. 342 * @param[in] address USB address of the device. 343 * @param[in] endpoint USB endpoint number. 344 * @param[in] direction Direction of the endpoint. 345 * @param[out] bw Reserved bandwidth. 346 * @return Error code 347 */ 348 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 349 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) 350 { 351 assert(instance); 352 fibril_mutex_lock(&instance->guard); 353 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 354 address, endpoint, direction, bw); 355 fibril_mutex_unlock(&instance->guard); 356 return ep; 275 357 } 276 358 /*----------------------------------------------------------------------------*/ … … 281 363 * @return Error code. 282 364 */ 283 int hc_schedule(hc d_t *hcd, usb_transfer_batch_t *batch)284 { 285 assert( hcd);286 hc_t *instance = hcd->private_data;287 assert( instance);365 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 366 { 367 assert(instance); 368 assert(batch); 369 assert(batch->ep); 288 370 289 371 /* Check for root hub communication */ … … 292 374 return EOK; 293 375 } 294 ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);295 if (!ohci_batch)296 return ENOMEM;297 376 298 377 fibril_mutex_lock(&instance->guard); 299 list_append(& ohci_batch->link, &instance->pending_batches);300 ohci_transfer_batch_commit(ohci_batch);378 list_append(&batch->link, &instance->pending_batches); 379 batch_commit(batch); 301 380 302 381 /* Control and bulk schedules need a kick to start working */ … … 338 417 instance->registers->periodic_current); 339 418 340 link_t *current = list_first(&instance->pending_batches);341 while (current && current!= &instance->pending_batches.head) {419 link_t *current = instance->pending_batches.head.next; 420 while (current != &instance->pending_batches.head) { 342 421 link_t *next = current->next; 343 ohci_transfer_batch_t *batch =344 ohci_transfer_batch_from_link(current);345 346 if ( ohci_transfer_batch_is_complete(batch)) {422 usb_transfer_batch_t *batch = 423 usb_transfer_batch_from_link(current); 424 425 if (batch_is_complete(batch)) { 347 426 list_remove(current); 348 ohci_transfer_batch_finish_dispose(batch);427 usb_transfer_batch_finish(batch); 349 428 } 350 429 … … 355 434 356 435 if (status & I_UE) { 357 usb_log_fatal("Error like no other!\n");358 436 hc_start(instance); 359 437 } -
uspace/drv/bus/usb/ohci/hc.h
rf1d6866 r85ff862 41 41 42 42 #include <usb/usb.h> 43 #include <usb/host/hcd.h> 43 #include <usb/host/device_keeper.h> 44 #include <usb/host/usb_endpoint_manager.h> 45 #include <usbhc_iface.h> 44 46 45 #include " ohci_batch.h"47 #include "batch.h" 46 48 #include "ohci_regs.h" 47 49 #include "root_hub.h" … … 51 53 /** Main OHCI driver structure */ 52 54 typedef struct hc { 53 /** Generic USB hc driver */ 54 hcd_t generic; 55 /** USB bus driver, devices and addresses */ 56 usb_device_keeper_t manager; 57 /** USB bus driver, endpoints */ 58 usb_endpoint_manager_t ep_manager; 55 59 56 60 /** Memory mapped I/O registers area */ … … 77 81 int hc_get_irq_commands( 78 82 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size); 83 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 79 84 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 80 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);81 85 82 86 /** Safely dispose host controller internal structures … … 84 88 * @param[in] instance Host controller structure to use. 85 89 */ 86 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 90 static inline void hc_fini(hc_t *instance) 91 { /* TODO: implement*/ }; 87 92 88 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep); 89 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep); 93 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep, 94 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 95 size_t max_packet_size, size_t size, unsigned interval); 96 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 97 usb_endpoint_t endpoint, usb_direction_t direction); 98 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 99 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw); 90 100 101 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 91 102 void hc_interrupt(hc_t *instance, uint32_t status); 103 104 /** Get and cast pointer to the driver data 105 * 106 * @param[in] fun DDF function pointer 107 * @return cast pointer to driver_data 108 */ 109 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 110 { return fun->driver_data; } 92 111 #endif 93 112 /** -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
rf1d6866 r85ff862 39 39 static unsigned togg[2] = { TD_STATUS_T_0, TD_STATUS_T_1 }; 40 40 41 void td_init( td_t *instance,42 usb_direction_t dir, constvoid *buffer, size_t size, int toggle)41 void td_init( 42 td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle) 43 43 { 44 44 assert(instance); -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h
rf1d6866 r85ff862 75 75 } __attribute__((packed)) td_t; 76 76 77 void td_init( td_t *instance,78 usb_direction_t dir, constvoid *buffer, size_t size, int toggle);77 void td_init( 78 td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle); 79 79 80 80 inline static void td_set_next(td_t *instance, td_t *next) -
uspace/drv/bus/usb/ohci/ohci.c
rf1d6866 r85ff862 42 42 43 43 #include "ohci.h" 44 #include "iface.h" 44 45 #include "pci.h" 45 46 #include "hc.h" 47 #include "root_hub.h" 46 48 47 49 typedef struct ohci { … … 50 52 51 53 hc_t hc; 54 rh_t rh; 52 55 } ohci_t; 53 56 … … 86 89 { 87 90 assert(fun); 88 usb_device_manager_t *manager = 89 &dev_to_ohci(fun->dev)->hc.generic.dev_manager; 90 91 const usb_address_t addr = usb_device_manager_find(manager, handle); 91 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 92 93 usb_address_t addr = usb_device_keeper_find(manager, handle); 92 94 if (addr < 0) { 93 95 return addr; … … 127 129 /** Standard USB HC options (HC interface) */ 128 130 static ddf_dev_ops_t hc_ops = { 129 .interfaces[USBHC_DEV_IFACE] = &hc d_iface,131 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 130 132 }; 131 133 /*----------------------------------------------------------------------------*/ … … 148 150 int device_setup_ohci(ddf_dev_t *device) 149 151 { 150 assert(device);151 152 152 ohci_t *instance = malloc(sizeof(ohci_t)); 153 153 if (instance == NULL) { … … 155 155 return ENOMEM; 156 156 } 157 instance->rh_fun = NULL;158 instance->hc_fun = NULL;159 157 160 158 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 161 159 if (ret != EOK) { \ 162 160 if (instance->hc_fun) { \ 161 instance->hc_fun->ops = NULL; \ 162 instance->hc_fun->driver_data = NULL; \ 163 163 ddf_fun_destroy(instance->hc_fun); \ 164 164 } \ 165 165 if (instance->rh_fun) { \ 166 instance->rh_fun->ops = NULL; \ 167 instance->rh_fun->driver_data = NULL; \ 166 168 ddf_fun_destroy(instance->rh_fun); \ 167 169 } \ 168 170 free(instance); \ 171 device->driver_data = NULL; \ 169 172 usb_log_error(message); \ 170 173 return ret; \ 171 174 } else (void)0 172 175 176 instance->rh_fun = NULL; 173 177 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 174 178 int ret = instance->hc_fun ? EOK : ENOMEM; … … 190 194 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 191 195 CHECK_RET_DEST_FREE_RETURN(ret, 192 "Failed to get registermemory addresses for %" PRIun ": %s.\n",196 "Failed to get memory addresses for %" PRIun ": %s.\n", 193 197 device->handle, str_error(ret)); 194 198 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", … … 197 201 const size_t cmd_count = hc_irq_cmd_count(); 198 202 irq_cmd_t irq_cmds[cmd_count]; 199 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };200 201 203 ret = 202 204 hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size); … … 204 206 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 205 207 208 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds }; 206 209 207 210 /* Register handler to avoid interrupt lockup */ … … 231 234 #define CHECK_RET_FINI_RETURN(ret, message...) \ 232 235 if (ret != EOK) { \ 236 unregister_interrupt_handler(device, irq); \ 233 237 hc_fini(&instance->hc); \ 234 unregister_interrupt_handler(device, irq); \235 238 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 236 239 } else (void)0 … … 245 248 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 246 249 247 ret = hc_register_hub(&instance->hc, instance->rh_fun); 248 CHECK_RET_FINI_RETURN(ret, 249 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 250 return ret; 251 250 hc_register_hub(&instance->hc, instance->rh_fun); 251 return EOK; 252 253 #undef CHECK_RET_DEST_FUN_RETURN 252 254 #undef CHECK_RET_FINI_RETURN 253 255 } -
uspace/drv/bus/usb/ohci/pci.c
rf1d6866 r85ff862 70 70 if (!parent_sess) 71 71 return ENOMEM; 72 72 73 73 hw_resource_list_t hw_resources; 74 74 int rc = hw_res_get_resource_list(parent_sess, &hw_resources); 75 async_hangup(parent_sess);76 75 if (rc != EOK) { 76 async_hangup(parent_sess); 77 77 return rc; 78 78 } 79 79 80 80 uintptr_t mem_address = 0; 81 81 size_t mem_size = 0; 82 82 bool mem_found = false; 83 83 84 84 int irq = 0; 85 85 bool irq_found = false; 86 86 87 87 size_t i; 88 88 for (i = 0; i < hw_resources.count; i++) { … … 107 107 } 108 108 } 109 free(hw_resources.resources); 110 109 111 110 if (mem_found && irq_found) { 112 111 *mem_reg_address = mem_address; 113 112 *mem_reg_size = mem_size; 114 113 *irq_no = irq; 115 return EOK; 116 } 117 return ENOENT; 114 rc = EOK; 115 } else 116 rc = ENOENT; 117 118 async_hangup(parent_sess); 119 return rc; 118 120 } 119 121 -
uspace/drv/bus/usb/ohci/root_hub.c
rf1d6866 r85ff862 121 121 assert(request); 122 122 123 memcpy(request->data_buffer, &mask, size); 123 124 request->transfered_size = size; 124 usb_transfer_batch_finish_error(request, &mask, size,EOK);125 usb_transfer_batch_finish_error(request, EOK); 125 126 } 126 127 … … 205 206 usb_log_debug("Root hub got CONTROL packet\n"); 206 207 const int ret = control_request(instance, request); 207 usb_transfer_batch_finish_error(request, NULL, 0,ret);208 usb_transfer_batch_finish_error(request, ret); 208 209 break; 209 210 case USB_TRANSFER_INTERRUPT: … … 214 215 assert(instance->unfinished_interrupt_transfer == NULL); 215 216 instance->unfinished_interrupt_transfer = request; 216 return;217 break; 217 218 } 218 219 usb_log_debug("Processing changes...\n"); … … 222 223 default: 223 224 usb_log_error("Root hub got unsupported request.\n"); 224 usb_transfer_batch_finish_error(request, NULL, 0, EINVAL); 225 } 226 usb_transfer_batch_dispose(request); 225 usb_transfer_batch_finish_error(request, EINVAL); 226 } 227 227 } 228 228 /*----------------------------------------------------------------------------*/ … … 244 244 interrupt_request(instance->unfinished_interrupt_transfer, 245 245 mask, instance->interrupt_mask_size); 246 usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer);247 246 248 247 instance->unfinished_interrupt_transfer = NULL; … … 390 389 const uint32_t data = instance->registers->rh_status & 391 390 (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG); 392 memcpy(request-> buffer, &data, sizeof(data));393 TRANSFER_OK( sizeof(data));391 memcpy(request->data_buffer, &data, 4); 392 TRANSFER_OK(4); 394 393 } 395 394 … … 403 402 const uint32_t data = 404 403 instance->registers->rh_port_status[port - 1]; 405 memcpy(request-> buffer, &data, sizeof(data));406 TRANSFER_OK( sizeof(data));404 memcpy(request->data_buffer, &data, 4); 405 TRANSFER_OK(4); 407 406 } 408 407 … … 484 483 } 485 484 486 memcpy(request-> buffer, descriptor, size);485 memcpy(request->data_buffer, descriptor, size); 487 486 TRANSFER_OK(size); 488 487 } … … 714 713 if (request->buffer_size != 1) 715 714 return EINVAL; 716 request-> buffer[0] = 1;715 request->data_buffer[0] = 1; 717 716 TRANSFER_OK(1); 718 717 -
uspace/drv/bus/usb/ohci/root_hub.h
rf1d6866 r85ff862 37 37 #include <usb/usb.h> 38 38 #include <usb/dev/driver.h> 39 #include <usb/host/usb_transfer_batch.h>40 39 41 40 #include "ohci_regs.h" 41 #include "batch.h" 42 42 43 43 #define HUB_DESCRIPTOR_MAX_SIZE (7 + 2 + 2) … … 66 66 /** size of hub descriptor */ 67 67 size_t hub_descriptor_size; 68 68 69 } rh_t; 69 70 -
uspace/drv/bus/usb/ohci/utils/malloc32.h
rf1d6866 r85ff862 46 46 * @return Physical address if exists, NULL otherwise. 47 47 */ 48 static inline uintptr_t addr_to_phys( constvoid *addr)48 static inline uintptr_t addr_to_phys(void *addr) 49 49 { 50 50 uintptr_t result; -
uspace/drv/bus/usb/uhci/Makefile
rf1d6866 r85ff862 42 42 43 43 SOURCES = \ 44 hc.c \44 iface.c \ 45 45 main.c \ 46 pci.c \47 root_hub.c \48 46 transfer_list.c \ 49 47 uhci.c \ 50 uhci_batch.c \ 51 hw_struct/transfer_descriptor.c 48 hc.c \ 49 root_hub.c \ 50 hw_struct/transfer_descriptor.c \ 51 pci.c \ 52 batch.c 52 53 53 54 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/bus/usb/uhci/hc.c
rf1d6866 r85ff862 41 41 42 42 #include "hc.h" 43 #include "uhci_batch.h"44 43 45 44 #define UHCI_INTR_ALLOW_INTERRUPTS \ … … 47 46 #define UHCI_STATUS_USED_INTERRUPTS \ 48 47 (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT) 49 50 48 51 49 static const irq_cmd_t uhci_irq_commands[] = … … 59 57 }; 60 58 61 static void hc_init_hw(consthc_t *instance);59 static int hc_init_transfer_lists(hc_t *instance); 62 60 static int hc_init_mem_structures(hc_t *instance); 63 static int hc_init_transfer_lists(hc_t *instance); 64 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 61 static void hc_init_hw(hc_t *instance); 65 62 66 63 static int hc_interrupt_emulator(void *arg); … … 98 95 cmds[3].addr = (void*)®isters->usbsts; 99 96 return EOK; 100 }101 /*----------------------------------------------------------------------------*/102 /** Take action based on the interrupt cause.103 *104 * @param[in] instance UHCI structure to use.105 * @param[in] status Value of the status register at the time of interrupt.106 *107 * Interrupt might indicate:108 * - transaction completed, either by triggering IOC, SPD, or an error109 * - some kind of device error110 * - resume from suspend state (not implemented)111 */112 void hc_interrupt(hc_t *instance, uint16_t status)113 {114 assert(instance);115 /* Lower 2 bits are transaction error and transaction complete */116 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {117 LIST_INITIALIZE(done);118 transfer_list_remove_finished(119 &instance->transfers_interrupt, &done);120 transfer_list_remove_finished(121 &instance->transfers_control_slow, &done);122 transfer_list_remove_finished(123 &instance->transfers_control_full, &done);124 transfer_list_remove_finished(125 &instance->transfers_bulk_full, &done);126 127 while (!list_empty(&done)) {128 link_t *item = list_first(&done);129 list_remove(item);130 uhci_transfer_batch_t *batch =131 uhci_transfer_batch_from_link(item);132 uhci_transfer_batch_call_dispose(batch);133 }134 }135 /* Resume interrupts are not supported */136 if (status & UHCI_STATUS_RESUME) {137 usb_log_error("Resume interrupt!\n");138 }139 140 /* Bits 4 and 5 indicate hc error */141 if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {142 usb_log_error("UHCI hardware failure!.\n");143 ++instance->hw_failures;144 transfer_list_abort_all(&instance->transfers_interrupt);145 transfer_list_abort_all(&instance->transfers_control_slow);146 transfer_list_abort_all(&instance->transfers_control_full);147 transfer_list_abort_all(&instance->transfers_bulk_full);148 149 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {150 /* reinitialize hw, this triggers virtual disconnect*/151 hc_init_hw(instance);152 } else {153 usb_log_fatal("Too many UHCI hardware failures!.\n");154 hc_fini(instance);155 }156 }157 97 } 158 98 /*----------------------------------------------------------------------------*/ … … 192 132 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 193 133 194 ret = hc d_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,195 bandwidth_count_usb11);196 CHECK_RET_RETURN(ret, "Failed to initialize HCD generic driver: %s.\n",134 ret = hc_init_mem_structures(instance); 135 CHECK_RET_RETURN(ret, 136 "Failed to initialize UHCI memory structures: %s.\n", 197 137 str_error(ret)); 198 199 instance->generic.private_data = instance;200 instance->generic.schedule = hc_schedule;201 instance->generic.ep_add_hook = NULL;202 203 #undef CHECK_RET_DEST_FUN_RETURN204 205 ret = hc_init_mem_structures(instance);206 if (ret != EOK) {207 usb_log_error(208 "Failed to initialize UHCI memory structures: %s.\n",209 str_error(ret));210 hcd_destroy(&instance->generic);211 return ret;212 }213 138 214 139 hc_init_hw(instance); … … 221 146 222 147 return EOK; 148 #undef CHECK_RET_DEST_FUN_RETURN 223 149 } 224 150 /*----------------------------------------------------------------------------*/ … … 228 154 * For magic values see UHCI Design Guide 229 155 */ 230 void hc_init_hw( consthc_t *instance)156 void hc_init_hw(hc_t *instance) 231 157 { 232 158 assert(instance); … … 272 198 * 273 199 * Structures: 200 * - interrupt code (I/O addressses are customized per instance) 274 201 * - transfer lists (queue heads need to be accessible by the hw) 275 202 * - frame list page (needs to be one UHCI hw accessible 4K page) … … 278 205 { 279 206 assert(instance); 280 281 /* Init USB frame list page */ 207 #define CHECK_RET_RETURN(ret, message...) \ 208 if (ret != EOK) { \ 209 usb_log_error(message); \ 210 return ret; \ 211 } else (void) 0 212 213 /* Init transfer lists */ 214 int ret = hc_init_transfer_lists(instance); 215 CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n"); 216 usb_log_debug("Initialized transfer lists.\n"); 217 218 /* Init device keeper */ 219 usb_device_keeper_init(&instance->manager); 220 usb_log_debug("Initialized device keeper.\n"); 221 222 ret = usb_endpoint_manager_init(&instance->ep_manager, 223 BANDWIDTH_AVAILABLE_USB11); 224 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 225 str_error(ret)); 226 227 /* Init USB frame list page*/ 282 228 instance->frame_list = get_page(); 283 229 if (!instance->frame_list) { 230 usb_log_error("Failed to get frame list page.\n"); 231 usb_endpoint_manager_destroy(&instance->ep_manager); 284 232 return ENOMEM; 285 233 } 286 234 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); 287 288 /* Init transfer lists */289 int ret = hc_init_transfer_lists(instance);290 if (ret != EOK) {291 usb_log_error("Failed to initialize transfer lists.\n");292 return_page(instance->frame_list);293 return ENOMEM;294 }295 usb_log_debug("Initialized transfer lists.\n");296 297 235 298 236 /* Set all frames to point to the first queue head */ … … 305 243 306 244 return EOK; 245 #undef CHECK_RET_RETURN 307 246 } 308 247 /*----------------------------------------------------------------------------*/ … … 377 316 * Checks for bandwidth availability and appends the batch to the proper queue. 378 317 */ 379 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 380 { 381 assert(hcd); 382 hc_t *instance = hcd->private_data; 318 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 319 { 383 320 assert(instance); 384 321 assert(batch); 385 uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch);386 if (!uhci_batch) {387 usb_log_error("Failed to create UHCI transfer structures.\n");388 return ENOMEM;389 }390 322 391 323 transfer_list_t *list = 392 324 instance->transfers[batch->ep->speed][batch->ep->transfer_type]; 393 325 assert(list); 394 transfer_list_add_batch(list, uhci_batch); 395 396 return EOK; 326 transfer_list_add_batch(list, batch); 327 328 return EOK; 329 } 330 /*----------------------------------------------------------------------------*/ 331 /** Take action based on the interrupt cause. 332 * 333 * @param[in] instance UHCI structure to use. 334 * @param[in] status Value of the status register at the time of interrupt. 335 * 336 * Interrupt might indicate: 337 * - transaction completed, either by triggering IOC, SPD, or an error 338 * - some kind of device error 339 * - resume from suspend state (not implemented) 340 */ 341 void hc_interrupt(hc_t *instance, uint16_t status) 342 { 343 assert(instance); 344 /* Lower 2 bits are transaction error and transaction complete */ 345 if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) { 346 LIST_INITIALIZE(done); 347 transfer_list_remove_finished( 348 &instance->transfers_interrupt, &done); 349 transfer_list_remove_finished( 350 &instance->transfers_control_slow, &done); 351 transfer_list_remove_finished( 352 &instance->transfers_control_full, &done); 353 transfer_list_remove_finished( 354 &instance->transfers_bulk_full, &done); 355 356 while (!list_empty(&done)) { 357 link_t *item = list_first(&done); 358 list_remove(item); 359 usb_transfer_batch_t *batch = 360 list_get_instance(item, usb_transfer_batch_t, link); 361 usb_transfer_batch_finish(batch); 362 } 363 } 364 /* Resume interrupts are not supported */ 365 if (status & UHCI_STATUS_RESUME) { 366 usb_log_error("Resume interrupt!\n"); 367 } 368 369 /* Bits 4 and 5 indicate hc error */ 370 if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) { 371 usb_log_error("UHCI hardware failure!.\n"); 372 ++instance->hw_failures; 373 transfer_list_abort_all(&instance->transfers_interrupt); 374 transfer_list_abort_all(&instance->transfers_control_slow); 375 transfer_list_abort_all(&instance->transfers_control_full); 376 transfer_list_abort_all(&instance->transfers_bulk_full); 377 378 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) { 379 /* reinitialize hw, this triggers virtual disconnect*/ 380 hc_init_hw(instance); 381 } else { 382 usb_log_fatal("Too many UHCI hardware failures!.\n"); 383 hc_fini(instance); 384 } 385 } 397 386 } 398 387 /*----------------------------------------------------------------------------*/ … … 414 403 if (status != 0) 415 404 usb_log_debug2("UHCI status: %x.\n", status); 405 // Qemu fails to report stalled communication 406 // see https://bugs.launchpad.net/qemu/+bug/757654 407 // This is a simple workaround to force queue processing every time 408 // status |= 1; 416 409 hc_interrupt(instance, status); 417 410 async_usleep(UHCI_INT_EMULATOR_TIMEOUT); … … 419 412 return EOK; 420 413 } 421 /*--------------------------------------------------------------------------- -*/414 /*---------------------------------------------------------------------------*/ 422 415 /** Debug function, checks consistency of memory structures. 423 416 * -
uspace/drv/bus/usb/uhci/hc.h
rf1d6866 r85ff862 39 39 #include <ddi.h> 40 40 41 #include <usb/host/hcd.h> 41 #include <usb/host/device_keeper.h> 42 #include <usb/host/usb_endpoint_manager.h> 43 #include <usb/host/batch.h> 42 44 43 45 #include "transfer_list.h" … … 92 94 /** Main UHCI driver structure */ 93 95 typedef struct hc { 94 /** Generic HCD driver structure */ 95 hcd_t generic; 96 /** USB bus driver, devices and addresses */ 97 usb_device_keeper_t manager; 98 /** USB bus driver, endpoints */ 99 usb_endpoint_manager_t ep_manager; 96 100 97 101 /** Addresses of I/O registers */ … … 120 124 unsigned hw_failures; 121 125 } hc_t; 122 123 126 size_t hc_irq_cmd_count(void); 124 127 int hc_get_irq_commands( 125 128 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size); 129 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts); 130 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 126 131 void hc_interrupt(hc_t *instance, uint16_t status); 127 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);128 132 129 133 /** Safely dispose host controller internal structures … … 131 135 * @param[in] instance Host controller structure to use. 132 136 */ 133 static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/ 137 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 138 139 /** Get and cast pointer to the driver data 140 * 141 * @param[in] fun DDF function pointer 142 * @return cast pointer to driver_data 143 */ 144 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 145 { 146 assert(fun); 147 return fun->driver_data; 148 } 134 149 #endif 135 150 /** -
uspace/drv/bus/usb/uhci/hw_struct/link_pointer.h
rf1d6866 r85ff862 35 35 #define DRV_UHCI_HW_STRUCT_LINK_POINTER_H 36 36 37 /* *UHCI link pointer, used by many data structures */37 /* UHCI link pointer, used by many data structures */ 38 38 typedef uint32_t link_pointer_t; 39 39 -
uspace/drv/bus/usb/uhci/hw_struct/queue_head.h
rf1d6866 r85ff862 58 58 assert(instance); 59 59 60 instance->element = LINK_POINTER_TERM;61 instance->next = LINK_POINTER_TERM;60 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG; 61 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG; 62 62 } 63 63 /*----------------------------------------------------------------------------*/ … … 71 71 static inline void qh_set_next_qh(qh_t *instance, qh_t *next) 72 72 { 73 /* Physical address has to be below 4GB, 74 * it is an UHCI limitation and malloc32 75 * should guarantee this */ 76 const uint32_t pa = addr_to_phys(next); 73 uint32_t pa = addr_to_phys(next); 77 74 if (pa) { 78 75 instance->next = LINK_POINTER_QH(pa); … … 91 88 static inline void qh_set_element_td(qh_t *instance, td_t *td) 92 89 { 93 /* Physical address has to be below 4GB, 94 * it is an UHCI limitation and malloc32 95 * should guarantee this */ 96 const uint32_t pa = addr_to_phys(td); 90 uint32_t pa = addr_to_phys(td); 97 91 if (pa) { 98 92 instance->element = LINK_POINTER_TD(pa); -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.c
rf1d6866 r85ff862 61 61 */ 62 62 void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso, 63 bool low_speed, usb_target_t target, usb_packet_id pid, constvoid *buffer,64 consttd_t *next)63 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, 64 td_t *next) 65 65 { 66 66 assert(instance); … … 113 113 * @return Error code. 114 114 */ 115 int td_status( consttd_t *instance)115 int td_status(td_t *instance) 116 116 { 117 117 assert(instance); … … 119 119 /* This is hc internal error it should never be reported. */ 120 120 if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0) 121 return E IO;121 return EAGAIN; 122 122 123 123 /* CRC or timeout error, like device not present or bad data, … … 150 150 * @param[in] instance TD structure to use. 151 151 */ 152 void td_print_status( consttd_t *instance)152 void td_print_status(td_t *instance) 153 153 { 154 154 assert(instance); -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.h
rf1d6866 r85ff862 69 69 #define TD_STATUS_ACTLEN_MASK 0x7ff 70 70 71 /* * Double word with USB device specific info */71 /* double word with USB device specific info */ 72 72 volatile uint32_t device; 73 73 #define TD_DEVICE_MAXLEN_POS 21 … … 87 87 /* According to UHCI design guide, there is 16 bytes of 88 88 * data available here. 89 * According to Linux kernel the hardware does not care,90 * memoryjust needs to be aligned. We don't use it anyway.89 * According to linux kernel the hardware does not care, 90 * it just needs to be aligned. We don't use it anyway. 91 91 */ 92 92 } __attribute__((packed)) td_t; … … 95 95 void td_init(td_t *instance, int error_count, size_t size, bool toggle, 96 96 bool iso, bool low_speed, usb_target_t target, usb_packet_id pid, 97 const void *buffer, consttd_t *next);97 void *buffer, td_t *next); 98 98 99 int td_status( consttd_t *instance);99 int td_status(td_t *instance); 100 100 101 void td_print_status( consttd_t *instance);101 void td_print_status(td_t *instance); 102 102 /*----------------------------------------------------------------------------*/ 103 103 /** Helper function for parsing actual size out of TD. … … 106 106 * @return Parsed actual size. 107 107 */ 108 static inline size_t td_act_size( consttd_t *instance)108 static inline size_t td_act_size(td_t *instance) 109 109 { 110 110 assert(instance); 111 111 const uint32_t s = instance->status; 112 /* Actual size is encoded as n-1 (UHCI design guide p. 23) */113 112 return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 114 113 } … … 120 119 * false otherwise. 121 120 */ 122 static inline bool td_is_short( consttd_t *instance)121 static inline bool td_is_short(td_t *instance) 123 122 { 124 123 const size_t act_size = td_act_size(instance); … … 135 134 * @return Toggle bit value. 136 135 */ 137 static inline int td_toggle( consttd_t *instance)136 static inline int td_toggle(td_t *instance) 138 137 { 139 138 assert(instance); … … 146 145 * @return Active bit value. 147 146 */ 148 static inline bool td_is_active( consttd_t *instance)147 static inline bool td_is_active(td_t *instance) 149 148 { 150 149 assert(instance); -
uspace/drv/bus/usb/uhci/main.c
rf1d6866 r85ff862 64 64 assert(device); 65 65 66 constint ret = device_setup_uhci(device);66 int ret = device_setup_uhci(device); 67 67 if (ret != EOK) { 68 68 usb_log_error("Failed to initialize UHCI driver: %s.\n", 69 69 str_error(ret)); 70 } else { 71 usb_log_info("Controlling new UHCI device '%s'.\n", 72 device->name); 70 return ret; 73 71 } 72 usb_log_info("Controlling new UHCI device '%s'.\n", device->name); 74 73 75 return ret;74 return EOK; 76 75 } 77 76 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/uhci/pci.c
rf1d6866 r85ff862 61 61 assert(io_reg_size); 62 62 assert(irq_no); 63 63 64 64 async_sess_t *parent_sess = 65 65 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, … … 67 67 if (!parent_sess) 68 68 return ENOMEM; 69 69 70 70 hw_resource_list_t hw_resources; 71 const int rc = hw_res_get_resource_list(parent_sess, &hw_resources); 72 async_hangup(parent_sess); 71 int rc = hw_res_get_resource_list(parent_sess, &hw_resources); 73 72 if (rc != EOK) { 73 async_hangup(parent_sess); 74 74 return rc; 75 75 } 76 76 77 77 uintptr_t io_address = 0; 78 78 size_t io_size = 0; 79 79 bool io_found = false; 80 80 81 81 int irq = 0; 82 82 bool irq_found = false; 83 83 84 84 size_t i; 85 85 for (i = 0; i < hw_resources.count; i++) { … … 102 102 } 103 103 } 104 free(hw_resources.resources); 105 104 105 async_hangup(parent_sess); 106 106 107 if (!io_found || !irq_found) 107 108 return ENOENT; 108 109 109 110 *io_reg_address = io_address; 110 111 *io_reg_size = io_size; 111 112 *irq_no = irq; 112 113 113 114 return EOK; 114 115 } 115 /*----------------------------------------------------------------------------*/ 116 116 117 /** Call the PCI driver with a request to enable interrupts 117 118 * … … 126 127 if (!parent_sess) 127 128 return ENOMEM; 128 129 129 130 const bool enabled = hw_res_enable_interrupt(parent_sess); 130 131 async_hangup(parent_sess); 131 132 132 133 return enabled ? EOK : EIO; 133 134 } 134 /*----------------------------------------------------------------------------*/ 135 135 136 /** Call the PCI driver with a request to clear legacy support register 136 137 * … … 141 142 { 142 143 assert(device); 143 144 144 145 async_sess_t *parent_sess = 145 146 devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle, … … 147 148 if (!parent_sess) 148 149 return ENOMEM; 149 150 150 151 /* See UHCI design guide for these values p.45, 151 152 * write all WC bits in USB legacy register */ 152 153 const sysarg_t address = 0xc0; 153 154 const sysarg_t value = 0xaf00; 154 155 155 156 async_exch_t *exch = async_exchange_begin(parent_sess); 156 157 157 158 const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), 158 159 IPC_M_CONFIG_SPACE_WRITE_16, address, value); 159 160 160 161 async_exchange_end(exch); 161 162 async_hangup(parent_sess); 162 163 163 164 return rc; 164 165 } -
uspace/drv/bus/usb/uhci/root_hub.c
rf1d6866 r85ff862 50 50 int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 51 51 { 52 assert(instance); 52 int ret; 53 53 54 assert(fun); 55 56 ret = ddf_fun_add_match_id(fun, "usb&uhci&root-hub", 100); 57 if (ret != EOK) { 58 usb_log_error("Failed to add root hub match id: %s\n", 59 str_error(ret)); 60 return ret; 61 } 54 62 55 63 /* Initialize resource structure */ … … 62 70 instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN; 63 71 64 const int ret = ddf_fun_add_match_id(fun, "usb&uhci&root-hub", 100); 65 if (ret != EOK) { 66 usb_log_error("Failed to add root hub match id: %s\n", 67 str_error(ret)); 68 } 69 return ret; 72 return EOK; 70 73 } 71 74 /** -
uspace/drv/bus/usb/uhci/transfer_list.c
rf1d6866 r85ff862 37 37 #include <usb/debug.h> 38 38 #include <libarch/barrier.h> 39 40 39 #include "transfer_list.h" 40 #include "batch.h" 41 41 42 42 static void transfer_list_remove_batch( 43 transfer_list_t *instance, u hci_transfer_batch_t *uhci_batch);43 transfer_list_t *instance, usb_transfer_batch_t *batch); 44 44 /*----------------------------------------------------------------------------*/ 45 45 /** Initialize transfer list structures. … … 106 106 */ 107 107 void transfer_list_add_batch( 108 transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch) 109 { 110 assert(instance); 111 assert(uhci_batch); 112 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, 113 uhci_batch->usb_batch); 108 transfer_list_t *instance, usb_transfer_batch_t *batch) 109 { 110 assert(instance); 111 assert(batch); 112 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch); 114 113 115 114 fibril_mutex_lock(&instance->guard); 116 115 117 /* Assume there is nothing scheduled */ 118 qh_t *last_qh = instance->queue_head; 119 /* There is something scheduled */ 120 if (!list_empty(&instance->batch_list)) { 121 last_qh = uhci_transfer_batch_from_link( 122 list_last(&instance->batch_list))->qh; 123 } 116 qh_t *last_qh = NULL; 124 117 /* Add to the hardware queue. */ 125 const uint32_t pa = addr_to_phys(uhci_batch->qh); 118 if (list_empty(&instance->batch_list)) { 119 /* There is nothing scheduled */ 120 last_qh = instance->queue_head; 121 } else { 122 /* There is something scheduled */ 123 usb_transfer_batch_t *last = usb_transfer_batch_from_link( 124 list_last(&instance->batch_list)); 125 last_qh = batch_qh(last); 126 } 127 const uint32_t pa = addr_to_phys(batch_qh(batch)); 126 128 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 127 129 … … 130 132 131 133 /* keep link */ 132 uhci_batch->qh->next = last_qh->next;133 qh_set_next_qh(last_qh, uhci_batch->qh);134 batch_qh(batch)->next = last_qh->next; 135 qh_set_next_qh(last_qh, batch_qh(batch)); 134 136 135 137 /* Make sure the pointer is updated */ … … 137 139 138 140 /* Add to the driver's list */ 139 list_append(& uhci_batch->link, &instance->batch_list);141 list_append(&batch->link, &instance->batch_list); 140 142 141 143 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n", 142 uhci_batch, USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch), 143 instance->name); 144 batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name); 144 145 fibril_mutex_unlock(&instance->guard); 145 146 } … … 156 157 157 158 fibril_mutex_lock(&instance->guard); 158 link_t *current = list_first(&instance->batch_list);159 while (current && current!= &instance->batch_list.head) {159 link_t *current = instance->batch_list.head.next; 160 while (current != &instance->batch_list.head) { 160 161 link_t * const next = current->next; 161 u hci_transfer_batch_t *batch =162 u hci_transfer_batch_from_link(current);163 164 if ( uhci_transfer_batch_is_complete(batch)) {162 usb_transfer_batch_t *batch = 163 usb_transfer_batch_from_link(current); 164 165 if (batch_is_complete(batch)) { 165 166 /* Save for processing */ 166 167 transfer_list_remove_batch(instance, batch); … … 181 182 while (!list_empty(&instance->batch_list)) { 182 183 link_t * const current = list_first(&instance->batch_list); 183 u hci_transfer_batch_t *batch =184 u hci_transfer_batch_from_link(current);184 usb_transfer_batch_t *batch = 185 usb_transfer_batch_from_link(current); 185 186 transfer_list_remove_batch(instance, batch); 186 batch->usb_batch->error = EINTR; 187 uhci_transfer_batch_call_dispose(batch); 187 usb_transfer_batch_finish_error(batch, EINTR); 188 188 } 189 189 fibril_mutex_unlock(&instance->guard); … … 198 198 */ 199 199 void transfer_list_remove_batch( 200 transfer_list_t *instance, u hci_transfer_batch_t *uhci_batch)200 transfer_list_t *instance, usb_transfer_batch_t *batch) 201 201 { 202 202 assert(instance); 203 203 assert(instance->queue_head); 204 assert( uhci_batch);205 assert( uhci_batch->qh);204 assert(batch); 205 assert(batch_qh(batch)); 206 206 assert(fibril_mutex_is_locked(&instance->guard)); 207 207 208 usb_log_debug2("Queue %s: removing batch(%p).\n", 209 instance->name, uhci_batch->usb_batch); 210 211 /* Assume I'm the first */ 212 const char *qpos = "FIRST"; 213 qh_t *prev_qh = instance->queue_head; 208 usb_log_debug2( 209 "Queue %s: removing batch(%p).\n", instance->name, batch); 210 211 const char *qpos = NULL; 212 qh_t *prev_qh = NULL; 214 213 /* Remove from the hardware queue */ 215 if (list_first(&instance->batch_list) != &uhci_batch->link) { 216 /* There is a batch in front of me */ 217 prev_qh = 218 uhci_transfer_batch_from_link(uhci_batch->link.prev)->qh; 214 if (list_first(&instance->batch_list) == &batch->link) { 215 /* I'm the first one here */ 216 prev_qh = instance->queue_head; 217 qpos = "FIRST"; 218 } else { 219 /* The thing before me is a batch too */ 220 usb_transfer_batch_t *prev = 221 usb_transfer_batch_from_link(batch->link.prev); 222 prev_qh = batch_qh(prev); 219 223 qpos = "NOT FIRST"; 220 224 } 221 225 assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK) 222 == addr_to_phys( uhci_batch->qh));223 prev_qh->next = uhci_batch->qh->next;226 == addr_to_phys(batch_qh(batch))); 227 prev_qh->next = batch_qh(batch)->next; 224 228 225 229 /* Make sure the pointer is updated */ … … 227 231 228 232 /* Remove from the batch list */ 229 list_remove(& uhci_batch->link);233 list_remove(&batch->link); 230 234 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " removed (%s) " 231 235 "from %s, next: %x.\n", 232 uhci_batch, USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch),233 qpos, instance->name, uhci_batch->qh->next);236 batch, USB_TRANSFER_BATCH_ARGS(*batch), 237 qpos, instance->name, batch_qh(batch)->next); 234 238 } 235 239 /** -
uspace/drv/bus/usb/uhci/transfer_list.h
rf1d6866 r85ff862 36 36 37 37 #include <fibril_synch.h> 38 #include <usb/host/batch.h> 38 39 39 40 #include "hw_struct/queue_head.h" 40 #include "uhci_batch.h" 41 41 42 /** Structure maintaining both hw queue and software list 42 43 * of currently executed transfers … … 45 46 /** Guard against multiple add/remove races */ 46 47 fibril_mutex_t guard; 47 /** UHCI hw structure represe nting this queue */48 /** UHCI hw structure represeting this queue */ 48 49 qh_t *queue_head; 49 50 /** Assigned name, for nicer debug output */ … … 57 58 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 58 59 void transfer_list_add_batch( 59 transfer_list_t *instance, u hci_transfer_batch_t *batch);60 transfer_list_t *instance, usb_transfer_batch_t *batch); 60 61 void transfer_list_remove_finished(transfer_list_t *instance, list_t *done); 61 62 void transfer_list_abort_all(transfer_list_t *instance); -
uspace/drv/bus/usb/uhci/uhci.c
rf1d6866 r85ff862 41 41 42 42 #include "uhci.h" 43 #include "iface.h" 43 44 #include "pci.h" 44 45 … … 86 87 /** Operations supported by the HC driver */ 87 88 static ddf_dev_ops_t hc_ops = { 88 .interfaces[USBHC_DEV_IFACE] = &hc d_iface, /* see iface.h/c */89 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 89 90 }; 90 91 /*----------------------------------------------------------------------------*/ … … 99 100 { 100 101 assert(fun); 101 usb_device_manager_t *manager = 102 &dev_to_uhci(fun->dev)->hc.generic.dev_manager; 103 const usb_address_t addr = usb_device_manager_find(manager, handle); 102 usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager; 103 usb_address_t addr = usb_device_keeper_find(manager, handle); 104 104 105 105 if (addr < 0) { … … 202 202 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 203 203 instance->hc_fun->ops = &hc_ops; 204 instance->hc_fun->driver_data = &instance->hc .generic;204 instance->hc_fun->driver_data = &instance->hc; 205 205 206 206 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh"); -
uspace/drv/bus/usb/uhci/utils/malloc32.h
rf1d6866 r85ff862 50 50 * @return Physical address if exists, NULL otherwise. 51 51 */ 52 static inline uintptr_t addr_to_phys( constvoid *addr)52 static inline uintptr_t addr_to_phys(void *addr) 53 53 { 54 54 if (addr == NULL) … … 102 102 if (free_address == 0) 103 103 return NULL; 104 void * address= as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,104 void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 105 105 AS_AREA_READ | AS_AREA_WRITE); 106 if ( address!= free_address)106 if (ret != free_address) 107 107 return NULL; 108 return address; 109 } 110 /*----------------------------------------------------------------------------*/ 111 static inline void return_page(void *page) 112 { 113 if (page) 114 as_area_destroy(page); 108 return ret; 115 109 } 116 110 -
uspace/drv/bus/usb/vhc/connhost.c
rf1d6866 r85ff862 62 62 VHC_DATA(vhc, fun); 63 63 64 usb_address_t addr = usb_device_manager_get_free_address(65 &vhc->dev_manager,USB_SPEED_HIGH);64 usb_address_t addr = device_keeper_get_free_address(&vhc->dev_keeper, 65 USB_SPEED_HIGH); 66 66 if (addr < 0) { 67 67 return addr; … … 88 88 usb_log_debug("Binding handle %" PRIun " to address %d.\n", 89 89 handle, address); 90 usb_device_ manager_bind(&vhc->dev_manager, address, handle);90 usb_device_keeper_bind(&vhc->dev_keeper, address, handle); 91 91 92 92 return EOK; … … 105 105 VHC_DATA(vhc, fun); 106 106 bool found = 107 usb_device_ manager_find_by_address(&vhc->dev_manager, address, handle);107 usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle); 108 108 return found ? EOK : ENOENT; 109 109 } … … 119 119 VHC_DATA(vhc, fun); 120 120 usb_log_debug("Releasing address %d...\n", address); 121 usb_device_ manager_release(&vhc->dev_manager, address);121 usb_device_keeper_release(&vhc->dev_keeper, address); 122 122 123 123 return ENOTSUP; … … 172 172 VHC_DATA(vhc, fun); 173 173 174 endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager, 175 address, endpoint, direction, NULL); 176 if (ep == NULL) { 177 return ENOENT; 178 } 179 174 180 int rc = usb_endpoint_manager_unregister_ep(&vhc->ep_manager, 175 181 address, endpoint, direction); … … 177 183 return rc; 178 184 } 179 #if 0 185 180 186 /** Schedule interrupt out transfer. 181 187 * … … 407 413 return EOK; 408 414 } 409 #endif410 static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,411 uint8_t *data_buffer, size_t data_buffer_size,412 usbhc_iface_transfer_in_callback_t callback, void *arg)413 {414 VHC_DATA(vhc, fun);415 416 endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,417 target.address, target.endpoint, USB_DIRECTION_IN, NULL);418 if (ep == NULL) {419 return ENOENT;420 }421 const usb_transfer_type_t transfer_type = ep->transfer_type;422 423 424 vhc_transfer_t *transfer = vhc_transfer_create(target.address,425 target.endpoint, USB_DIRECTION_IN, transfer_type,426 fun, arg);427 if (transfer == NULL) {428 return ENOMEM;429 }430 if (transfer_type == USB_TRANSFER_CONTROL) {431 transfer->setup_buffer = malloc(sizeof(uint64_t));432 assert(transfer->setup_buffer);433 memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));434 transfer->setup_buffer_size = sizeof(uint64_t);435 }436 transfer->data_buffer = data_buffer;437 transfer->data_buffer_size = data_buffer_size;438 transfer->callback_in = callback;439 440 int rc = vhc_virtdev_add_transfer(vhc, transfer);441 if (rc != EOK) {442 free(transfer->setup_buffer);443 free(transfer);444 return rc;445 }446 447 return EOK;448 }449 450 static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,451 const uint8_t *data_buffer, size_t data_buffer_size,452 usbhc_iface_transfer_out_callback_t callback, void *arg)453 {454 VHC_DATA(vhc, fun);455 456 endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,457 target.address, target.endpoint, USB_DIRECTION_OUT, NULL);458 if (ep == NULL) {459 return ENOENT;460 }461 const usb_transfer_type_t transfer_type = ep->transfer_type;462 463 464 vhc_transfer_t *transfer = vhc_transfer_create(target.address,465 target.endpoint, USB_DIRECTION_OUT, transfer_type,466 fun, arg);467 if (transfer == NULL) {468 return ENOMEM;469 }470 if (transfer_type == USB_TRANSFER_CONTROL) {471 transfer->setup_buffer = malloc(sizeof(uint64_t));472 assert(transfer->setup_buffer);473 memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));474 transfer->setup_buffer_size = sizeof(uint64_t);475 }476 transfer->data_buffer = (void*)data_buffer;477 transfer->data_buffer_size = data_buffer_size;478 transfer->callback_out = callback;479 480 int rc = vhc_virtdev_add_transfer(vhc, transfer);481 if (rc != EOK) {482 free(transfer->setup_buffer);483 free(transfer);484 return rc;485 }486 487 return EOK;488 }489 415 490 416 static int tell_address(ddf_fun_t *fun, devman_handle_t handle, … … 516 442 517 443 usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle); 518 usb_address_t addr = usb_device_ manager_find(&vhc->dev_manager, handle);444 usb_address_t addr = usb_device_keeper_find(&vhc->dev_keeper, handle); 519 445 if (addr < 0) { 520 446 return addr; … … 534 460 .unregister_endpoint = unregister_endpoint, 535 461 536 .write = usb_write, 537 .read = usb_read, 462 .interrupt_out = interrupt_out, 463 .interrupt_in = interrupt_in, 464 465 .bulk_in = bulk_in, 466 .bulk_out = bulk_out, 467 468 .control_write = control_write, 469 .control_read = control_read 538 470 }; 539 471 -
uspace/drv/bus/usb/vhc/main.c
rf1d6866 r85ff862 73 73 } 74 74 data->magic = 0xDEADBEEF; 75 rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1, 76 bandwidth_count_usb11); 75 rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1); 77 76 if (rc != EOK) { 78 77 usb_log_fatal("Failed to initialize endpoint manager.\n"); … … 80 79 return rc; 81 80 } 82 usb_device_ manager_init(&data->dev_manager);81 usb_device_keeper_init(&data->dev_keeper); 83 82 84 83 ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc"); -
uspace/drv/bus/usb/vhc/vhcd.h
rf1d6866 r85ff862 39 39 #include <usbvirt/device.h> 40 40 #include <usb/host/usb_endpoint_manager.h> 41 #include <usb/host/ usb_device_manager.h>41 #include <usb/host/device_keeper.h> 42 42 #include <usbhc_iface.h> 43 43 #include <async.h> … … 60 60 fibril_mutex_t guard; 61 61 usb_endpoint_manager_t ep_manager; 62 usb_device_ manager_t dev_manager;62 usb_device_keeper_t dev_keeper; 63 63 usbvirt_device_t *hub; 64 64 ddf_fun_t *hc_fun; -
uspace/drv/char/ns8250/ns8250.c
rf1d6866 r85ff862 59 59 60 60 #include <devman.h> 61 #include <ns.h>62 61 #include <ipc/devman.h> 63 #include <ipc/services.h>64 #include <ipc/irc.h>65 62 #include <device/hw_res.h> 66 63 #include <ipc/serial_ctl.h> … … 412 409 static int ns8250_interrupt_enable(ns8250_t *ns) 413 410 { 414 /*415 * Enable interrupt using IRC service.416 * TODO: This is a temporary solution until the device framework417 * takes care of this itself.418 */419 async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,420 SERVICE_IRC, 0, 0);421 if (!irc_sess) {422 return EIO;423 }424 425 async_exch_t *exch = async_exchange_begin(irc_sess);426 if (!exch) {427 return EIO;428 }429 async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq);430 async_exchange_end(exch);431 432 411 /* Enable interrupt on the serial port. */ 433 412 ns8250_port_interrupts_enable(ns->port); -
uspace/lib/c/Makefile
rf1d6866 r85ff862 63 63 generic/as.c \ 64 64 generic/cap.c \ 65 generic/cfg.c \66 65 generic/clipboard.c \ 67 66 generic/devman.c \ -
uspace/lib/c/generic/adt/hash_table.c
rf1d6866 r85ff862 152 152 153 153 if (keys == h->max_keys) { 154 link_t *cur; 155 154 156 /* 155 157 * All keys are known, hash_table_find() can be used to find the … … 157 159 */ 158 160 159 link_t *cur = hash_table_find(h, key);161 cur = hash_table_find(h, key); 160 162 if (cur) { 161 163 list_remove(cur); … … 172 174 hash_index_t chain; 173 175 for (chain = 0; chain < h->entries; chain++) { 174 for (link_t *cur = h->entry[chain].head.next; 175 cur != &h->entry[chain].head; 176 link_t *cur; 177 178 for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head; 176 179 cur = cur->next) { 177 180 if (h->op->compare(key, keys, cur)) { -
uspace/lib/c/generic/as.c
rf1d6866 r85ff862 123 123 * @retval ENOENT Mapping not found. 124 124 */ 125 int as_get_physical_mapping( constvoid *address, uintptr_t *frame)125 int as_get_physical_mapping(void *address, uintptr_t *frame) 126 126 { 127 127 uintptr_t tmp_frame; -
uspace/lib/c/generic/io/io.c
rf1d6866 r85ff862 418 418 419 419 bytes_used = stream->buf_head - stream->buf_tail; 420 if (bytes_used == 0) 421 return; 420 422 421 423 /* If buffer has prefetched read data, we need to seek back. */ 422 if ( bytes_used > 0 &&stream->buf_state == _bs_read)424 if (stream->buf_state == _bs_read) 423 425 lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR); 424 426 425 427 /* If buffer has unwritten data, we need to write them out. */ 426 if ( bytes_used > 0 &&stream->buf_state == _bs_write)428 if (stream->buf_state == _bs_write) 427 429 (void) _fwrite(stream->buf_tail, 1, bytes_used, stream); 428 430 -
uspace/lib/c/generic/ns.c
rf1d6866 r85ff862 52 52 { 53 53 async_exch_t *exch = async_exchange_begin(session_ns); 54 if (!exch)55 return NULL;56 54 async_sess_t *sess = 57 55 async_connect_me_to(mgmt, exch, service, arg2, arg3); 58 56 async_exchange_end(exch); 59 60 if (!sess)61 return NULL;62 57 63 58 /* -
uspace/lib/c/include/adt/list.h
rf1d6866 r85ff862 173 173 * 174 174 */ 175 static inline int list_empty( constlist_t *list)175 static inline int list_empty(list_t *list) 176 176 { 177 177 return (list->head.next == &list->head); … … 186 186 * 187 187 */ 188 static inline link_t *list_first( constlist_t *list)188 static inline link_t *list_first(list_t *list) 189 189 { 190 190 return ((list->head.next == &list->head) ? NULL : list->head.next); -
uspace/lib/c/include/as.h
rf1d6866 r85ff862 60 60 extern void *set_maxheapsize(size_t); 61 61 extern void *as_get_mappable_page(size_t); 62 extern int as_get_physical_mapping( constvoid *, uintptr_t *);62 extern int as_get_physical_mapping(void *, uintptr_t *); 63 63 64 64 #endif -
uspace/lib/c/include/ipc/loc.h
rf1d6866 r85ff862 97 97 98 98 #endif 99 100 /** @}101 */ -
uspace/lib/drv/generic/dev_iface.c
rf1d6866 r85ff862 46 46 #include "remote_pci.h" 47 47 48 #include <stdio.h> 49 48 50 static iface_dipatch_table_t remote_ifaces = { 49 51 .ifaces = { … … 66 68 get_remote_method(remote_iface_t *rem_iface, sysarg_t iface_method_idx) 67 69 { 68 if (iface_method_idx >= rem_iface->method_count) 70 if (iface_method_idx >= rem_iface->method_count) { 69 71 return NULL; 70 72 } 73 71 74 return rem_iface->methods[iface_method_idx]; 72 75 } -
uspace/lib/drv/generic/driver.c
rf1d6866 r85ff862 271 271 272 272 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 273 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);273 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 274 274 275 275 ddf_dev_t *dev = create_device(); -
uspace/lib/drv/generic/remote_usbhc.c
rf1d6866 r85ff862 41 41 42 42 #define USB_MAX_PAYLOAD_SIZE 1020 43 43 #define HACK_MAX_PACKET_SIZE 8 44 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4 45 46 static void remote_usbhc_interrupt_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 47 static void remote_usbhc_interrupt_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 44 52 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 53 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 48 56 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 49 57 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);51 static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);52 58 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 53 59 54 60 /** Remote USB host controller interface operations. */ 55 static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = { 56 [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address, 57 [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address, 58 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_find_by_address, 59 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address, 60 61 [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, 62 [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint, 63 64 [IPC_M_USBHC_READ] = remote_usbhc_read, 65 [IPC_M_USBHC_WRITE] = remote_usbhc_write, 61 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 62 remote_usbhc_request_address, 63 remote_usbhc_bind_address, 64 remote_usbhc_find_by_address, 65 remote_usbhc_release_address, 66 67 remote_usbhc_interrupt_out, 68 remote_usbhc_interrupt_in, 69 70 remote_usbhc_bulk_out, 71 remote_usbhc_bulk_in, 72 73 remote_usbhc_control_write, 74 remote_usbhc_control_read, 75 76 remote_usbhc_register_endpoint, 77 remote_usbhc_unregister_endpoint 66 78 }; 67 79 … … 78 90 ipc_callid_t data_caller; 79 91 void *buffer; 92 void *setup_packet; 80 93 size_t size; 81 94 } async_transaction_t; … … 85 98 if (trans == NULL) { 86 99 return; 100 } 101 102 if (trans->setup_packet != NULL) { 103 free(trans->setup_packet); 87 104 } 88 105 if (trans->buffer != NULL) { … … 103 120 trans->data_caller = 0; 104 121 trans->buffer = NULL; 122 trans->setup_packet = NULL; 105 123 trans->size = 0; 106 124 … … 117 135 return; 118 136 } 119 137 120 138 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 121 139 … … 221 239 async_transaction_destroy(trans); 222 240 } 241 242 /** Process an outgoing transfer (both OUT and SETUP). 243 * 244 * @param device Target device. 245 * @param callid Initiating caller. 246 * @param call Initiating call. 247 * @param transfer_func Transfer function (might be NULL). 248 */ 249 static void remote_usbhc_out_transfer(ddf_fun_t *fun, 250 ipc_callid_t callid, ipc_call_t *call, 251 usbhc_iface_transfer_out_t transfer_func) 252 { 253 if (!transfer_func) { 254 async_answer_0(callid, ENOTSUP); 255 return; 256 } 257 258 usb_target_t target = { 259 .address = DEV_IPC_GET_ARG1(*call), 260 .endpoint = DEV_IPC_GET_ARG2(*call) 261 }; 262 263 size_t len = 0; 264 void *buffer = NULL; 265 266 int rc = async_data_write_accept(&buffer, false, 267 1, USB_MAX_PAYLOAD_SIZE, 268 0, &len); 269 270 if (rc != EOK) { 271 async_answer_0(callid, rc); 272 return; 273 } 274 275 async_transaction_t *trans = async_transaction_create(callid); 276 if (trans == NULL) { 277 if (buffer != NULL) { 278 free(buffer); 279 } 280 async_answer_0(callid, ENOMEM); 281 return; 282 } 283 284 trans->buffer = buffer; 285 trans->size = len; 286 287 rc = transfer_func(fun, target, 288 buffer, len, 289 callback_out, trans); 290 291 if (rc != EOK) { 292 async_answer_0(callid, rc); 293 async_transaction_destroy(trans); 294 } 295 } 296 297 /** Process an incoming transfer. 298 * 299 * @param device Target device. 300 * @param callid Initiating caller. 301 * @param call Initiating call. 302 * @param transfer_func Transfer function (might be NULL). 303 */ 304 static void remote_usbhc_in_transfer(ddf_fun_t *fun, 305 ipc_callid_t callid, ipc_call_t *call, 306 usbhc_iface_transfer_in_t transfer_func) 307 { 308 if (!transfer_func) { 309 async_answer_0(callid, ENOTSUP); 310 return; 311 } 312 313 usb_target_t target = { 314 .address = DEV_IPC_GET_ARG1(*call), 315 .endpoint = DEV_IPC_GET_ARG2(*call) 316 }; 317 318 size_t len; 319 ipc_callid_t data_callid; 320 if (!async_data_read_receive(&data_callid, &len)) { 321 async_answer_0(callid, EPARTY); 322 return; 323 } 324 325 async_transaction_t *trans = async_transaction_create(callid); 326 if (trans == NULL) { 327 async_answer_0(data_callid, ENOMEM); 328 async_answer_0(callid, ENOMEM); 329 return; 330 } 331 trans->data_caller = data_callid; 332 trans->buffer = malloc(len); 333 trans->size = len; 334 335 int rc = transfer_func(fun, target, 336 trans->buffer, len, 337 callback_in, trans); 338 339 if (rc != EOK) { 340 async_answer_0(data_callid, rc); 341 async_answer_0(callid, rc); 342 async_transaction_destroy(trans); 343 } 344 } 345 346 void remote_usbhc_interrupt_out(ddf_fun_t *fun, void *iface, 347 ipc_callid_t callid, ipc_call_t *call) 348 { 349 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 350 assert(usb_iface != NULL); 351 352 return remote_usbhc_out_transfer(fun, callid, call, 353 usb_iface->interrupt_out); 354 } 355 356 void remote_usbhc_interrupt_in(ddf_fun_t *fun, void *iface, 357 ipc_callid_t callid, ipc_call_t *call) 358 { 359 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 360 assert(usb_iface != NULL); 361 362 return remote_usbhc_in_transfer(fun, callid, call, 363 usb_iface->interrupt_in); 364 } 365 366 void remote_usbhc_bulk_out(ddf_fun_t *fun, void *iface, 367 ipc_callid_t callid, ipc_call_t *call) 368 { 369 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 370 assert(usb_iface != NULL); 371 372 return remote_usbhc_out_transfer(fun, callid, call, 373 usb_iface->bulk_out); 374 } 375 376 void remote_usbhc_bulk_in(ddf_fun_t *fun, void *iface, 377 ipc_callid_t callid, ipc_call_t *call) 378 { 379 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 380 assert(usb_iface != NULL); 381 382 return remote_usbhc_in_transfer(fun, callid, call, 383 usb_iface->bulk_in); 384 } 385 386 void remote_usbhc_control_write(ddf_fun_t *fun, void *iface, 387 ipc_callid_t callid, ipc_call_t *call) 388 { 389 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 390 assert(usb_iface != NULL); 391 392 if (!usb_iface->control_write) { 393 async_answer_0(callid, ENOTSUP); 394 return; 395 } 396 397 usb_target_t target = { 398 .address = DEV_IPC_GET_ARG1(*call), 399 .endpoint = DEV_IPC_GET_ARG2(*call) 400 }; 401 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 402 403 int rc; 404 405 void *setup_packet = NULL; 406 void *data_buffer = NULL; 407 size_t setup_packet_len = 0; 408 409 rc = async_data_write_accept(&setup_packet, false, 410 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 411 if (rc != EOK) { 412 async_answer_0(callid, rc); 413 return; 414 } 415 416 if (data_buffer_len > 0) { 417 rc = async_data_write_accept(&data_buffer, false, 418 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len); 419 if (rc != EOK) { 420 async_answer_0(callid, rc); 421 free(setup_packet); 422 return; 423 } 424 } 425 426 async_transaction_t *trans = async_transaction_create(callid); 427 if (trans == NULL) { 428 async_answer_0(callid, ENOMEM); 429 free(setup_packet); 430 free(data_buffer); 431 return; 432 } 433 trans->setup_packet = setup_packet; 434 trans->buffer = data_buffer; 435 trans->size = data_buffer_len; 436 437 rc = usb_iface->control_write(fun, target, 438 setup_packet, setup_packet_len, 439 data_buffer, data_buffer_len, 440 callback_out, trans); 441 442 if (rc != EOK) { 443 async_answer_0(callid, rc); 444 async_transaction_destroy(trans); 445 } 446 } 447 448 449 void remote_usbhc_control_read(ddf_fun_t *fun, void *iface, 450 ipc_callid_t callid, ipc_call_t *call) 451 { 452 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 453 assert(usb_iface != NULL); 454 455 if (!usb_iface->control_read) { 456 async_answer_0(callid, ENOTSUP); 457 return; 458 } 459 460 usb_target_t target = { 461 .address = DEV_IPC_GET_ARG1(*call), 462 .endpoint = DEV_IPC_GET_ARG2(*call) 463 }; 464 465 int rc; 466 467 void *setup_packet = NULL; 468 size_t setup_packet_len = 0; 469 size_t data_len = 0; 470 471 rc = async_data_write_accept(&setup_packet, false, 472 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 473 if (rc != EOK) { 474 async_answer_0(callid, rc); 475 return; 476 } 477 478 ipc_callid_t data_callid; 479 if (!async_data_read_receive(&data_callid, &data_len)) { 480 async_answer_0(callid, EPARTY); 481 free(setup_packet); 482 return; 483 } 484 485 async_transaction_t *trans = async_transaction_create(callid); 486 if (trans == NULL) { 487 async_answer_0(data_callid, ENOMEM); 488 async_answer_0(callid, ENOMEM); 489 free(setup_packet); 490 return; 491 } 492 trans->data_caller = data_callid; 493 trans->setup_packet = setup_packet; 494 trans->size = data_len; 495 trans->buffer = malloc(data_len); 496 if (trans->buffer == NULL) { 497 async_answer_0(data_callid, ENOMEM); 498 async_answer_0(callid, ENOMEM); 499 async_transaction_destroy(trans); 500 return; 501 } 502 503 rc = usb_iface->control_read(fun, target, 504 setup_packet, setup_packet_len, 505 trans->buffer, trans->size, 506 callback_in, trans); 507 508 if (rc != EOK) { 509 async_answer_0(data_callid, rc); 510 async_answer_0(callid, rc); 511 async_transaction_destroy(trans); 512 } 513 } 514 223 515 224 516 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface, … … 243 535 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 8) 244 536 245 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) }; 537 _INIT_FROM_HIGH_DATA2(usb_address_t, address, 1); 538 _INIT_FROM_LOW_DATA2(usb_endpoint_t, endpoint, 1); 246 539 247 540 _INIT_FROM_HIGH_DATA3(usb_speed_t, speed, 2); … … 258 551 #undef _INIT_FROM_LOW_DATA3 259 552 260 int rc = usb_iface->register_endpoint(fun, target.address, speed,261 t arget.endpoint, transfer_type, direction, max_packet_size, interval);553 int rc = usb_iface->register_endpoint(fun, address, speed, endpoint, 554 transfer_type, direction, max_packet_size, interval); 262 555 263 556 async_answer_0(callid, rc); 264 557 } 558 265 559 266 560 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface, … … 284 578 } 285 579 286 void remote_usbhc_read(287 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)288 {289 assert(fun);290 assert(iface);291 assert(call);292 293 const usbhc_iface_t *hc_iface = iface;294 295 if (!hc_iface->read) {296 async_answer_0(callid, ENOTSUP);297 return;298 }299 300 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };301 const uint64_t setup =302 ((uint64_t)DEV_IPC_GET_ARG2(*call)) |303 (((uint64_t)DEV_IPC_GET_ARG3(*call)) << 32);304 305 async_transaction_t *trans = async_transaction_create(callid);306 if (trans == NULL) {307 async_answer_0(callid, ENOMEM);308 return;309 }310 311 if (!async_data_read_receive(&trans->data_caller, &trans->size)) {312 async_answer_0(callid, EPARTY);313 return;314 }315 316 trans->buffer = malloc(trans->size);317 if (trans->buffer == NULL) {318 async_answer_0(trans->data_caller, ENOMEM);319 async_answer_0(callid, ENOMEM);320 async_transaction_destroy(trans);321 }322 323 const int rc = hc_iface->read(324 fun, target, setup, trans->buffer, trans->size, callback_in, trans);325 326 if (rc != EOK) {327 async_answer_0(trans->data_caller, rc);328 async_answer_0(callid, rc);329 async_transaction_destroy(trans);330 }331 }332 333 void remote_usbhc_write(334 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)335 {336 assert(fun);337 assert(iface);338 assert(call);339 340 const usbhc_iface_t *hc_iface = iface;341 342 if (!hc_iface->write) {343 async_answer_0(callid, ENOTSUP);344 return;345 }346 347 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };348 const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call);349 const uint64_t setup =350 ((uint64_t)DEV_IPC_GET_ARG3(*call)) |351 (((uint64_t)DEV_IPC_GET_ARG4(*call)) << 32);352 353 async_transaction_t *trans = async_transaction_create(callid);354 if (trans == NULL) {355 async_answer_0(callid, ENOMEM);356 return;357 }358 359 if (data_buffer_len > 0) {360 int rc = async_data_write_accept(&trans->buffer, false,361 1, USB_MAX_PAYLOAD_SIZE,362 0, &trans->size);363 364 if (rc != EOK) {365 async_answer_0(callid, rc);366 async_transaction_destroy(trans);367 return;368 }369 }370 371 int rc = hc_iface->write(372 fun, target, setup, trans->buffer, trans->size, callback_out, trans);373 374 if (rc != EOK) {375 async_answer_0(callid, rc);376 async_transaction_destroy(trans);377 }378 }379 380 580 381 581 /** -
uspace/lib/drv/include/usbhc_iface.h
rf1d6866 r85ff862 123 123 IPC_M_USBHC_RELEASE_ADDRESS, 124 124 125 126 /** Send interrupt data to device. 127 * See explanation at usb_iface_funcs_t (OUT transaction). 128 */ 129 IPC_M_USBHC_INTERRUPT_OUT, 130 131 /** Get interrupt data from device. 132 * See explanation at usb_iface_funcs_t (IN transaction). 133 */ 134 IPC_M_USBHC_INTERRUPT_IN, 135 136 /** Send bulk data to device. 137 * See explanation at usb_iface_funcs_t (OUT transaction). 138 */ 139 IPC_M_USBHC_BULK_OUT, 140 141 /** Get bulk data from device. 142 * See explanation at usb_iface_funcs_t (IN transaction). 143 */ 144 IPC_M_USBHC_BULK_IN, 145 146 /** Issue control WRITE transfer. 147 * See explanation at usb_iface_funcs_t (OUT transaction) for 148 * call parameters. 149 * This call is immediately followed by two IPC data writes 150 * from the caller (setup packet and actual data). 151 */ 152 IPC_M_USBHC_CONTROL_WRITE, 153 154 /** Issue control READ transfer. 155 * See explanation at usb_iface_funcs_t (IN transaction) for 156 * call parameters. 157 * This call is immediately followed by IPC data write from the caller 158 * (setup packet) and IPC data read (buffer that was read). 159 */ 160 IPC_M_USBHC_CONTROL_READ, 161 125 162 /** Register endpoint attributes at host controller. 126 163 * This is used to reserve portion of USB bandwidth. … … 148 185 * - ENOENT - unknown endpoint 149 186 */ 150 IPC_M_USBHC_UNREGISTER_ENDPOINT, 151 152 /** Get data from device. 153 * See explanation at usb_iface_funcs_t (IN transaction). 154 */ 155 IPC_M_USBHC_READ, 156 157 /** Send data to device. 158 * See explanation at usb_iface_funcs_t (OUT transaction). 159 */ 160 IPC_M_USBHC_WRITE, 187 IPC_M_USBHC_UNREGISTER_ENDPOINT 161 188 } usbhc_iface_funcs_t; 162 189 163 190 /** Callback for outgoing transfer. */ 164 typedef void (*usbhc_iface_transfer_out_callback_t)(ddf_fun_t *, int, void *); 191 typedef void (*usbhc_iface_transfer_out_callback_t)(ddf_fun_t *, 192 int, void *); 165 193 166 194 /** Callback for incoming transfer. */ 167 195 typedef void (*usbhc_iface_transfer_in_callback_t)(ddf_fun_t *, 168 196 int, size_t, void *); 197 198 199 /** Out transfer processing function prototype. */ 200 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, 201 void *, size_t, 202 usbhc_iface_transfer_out_callback_t, void *); 203 204 /** Setup transfer processing function prototype. @deprecated */ 205 typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t; 206 207 /** In transfer processing function prototype. */ 208 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, 209 void *, size_t, 210 usbhc_iface_transfer_in_callback_t, void *); 169 211 170 212 /** USB host controller communication interface. */ … … 181 223 usb_direction_t); 182 224 183 int (*read)(ddf_fun_t *, usb_target_t, uint64_t, uint8_t *, size_t, 225 usbhc_iface_transfer_out_t interrupt_out; 226 usbhc_iface_transfer_in_t interrupt_in; 227 228 usbhc_iface_transfer_out_t bulk_out; 229 usbhc_iface_transfer_in_t bulk_in; 230 231 int (*control_write)(ddf_fun_t *, usb_target_t, 232 void *, size_t, void *, size_t, 233 usbhc_iface_transfer_out_callback_t, void *); 234 235 int (*control_read)(ddf_fun_t *, usb_target_t, 236 void *, size_t, void *, size_t, 184 237 usbhc_iface_transfer_in_callback_t, void *); 185 186 int (*write)(ddf_fun_t *, usb_target_t, uint64_t, const uint8_t *,187 size_t, usbhc_iface_transfer_out_callback_t, void *);188 238 } usbhc_iface_t; 189 239 -
uspace/lib/usb/include/usb/hc.h
rf1d6866 r85ff862 62 62 devman_handle_t *); 63 63 64 usb_address_t usb_hc_get_address_by_handle(devman_handle_t);64 int usb_hc_get_address_by_handle(devman_handle_t); 65 65 66 66 int usb_hc_find(devman_handle_t, devman_handle_t *); -
uspace/lib/usb/include/usb/usb.h
rf1d6866 r85ff862 36 36 #define LIBUSB_USB_H_ 37 37 38 #include <bool.h>39 38 #include <sys/types.h> 40 39 #include <byteorder.h> … … 106 105 * Negative values could be used to indicate error. 107 106 */ 108 typedef int 16_tusb_address_t;107 typedef int usb_address_t; 109 108 110 109 /** Default USB address. */ … … 116 115 * Negative values could be used to indicate error. 117 116 */ 118 typedef int 16_tusb_endpoint_t;117 typedef int usb_endpoint_t; 119 118 120 119 /** Maximum endpoint number in USB 1.1. … … 126 125 * Pair address + endpoint is identification of transaction recipient. 127 126 */ 128 typedef union { 129 struct { 130 usb_address_t address; 131 usb_endpoint_t endpoint; 132 } __attribute__((packed)); 133 uint32_t packed; 127 typedef struct { 128 usb_address_t address; 129 usb_endpoint_t endpoint; 134 130 } usb_target_t; 135 136 /** Check USB target for allowed values (address and endpoint).137 *138 * @param target.139 * @return True, if values are wihtin limits, false otherwise.140 */141 static inline bool usb_target_is_valid(usb_target_t target)142 {143 return !(target.endpoint > 15 || target.endpoint < 0144 || target.address >= USB11_ADDRESS_MAX || target.address < 0);145 }146 131 147 132 /** Compare USB targets (addresses and endpoints). -
uspace/lib/usbdev/src/pipesinit.c
rf1d6866 r85ff862 486 486 return EBADF; 487 487 488 const usb_target_t target =489 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};490 488 #define _PACK2(high, low) (((high) << 16) + (low)) 491 489 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low)) … … 493 491 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 494 492 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 495 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 493 IPC_M_USBHC_REGISTER_ENDPOINT, 494 _PACK2(pipe->wire->address, pipe->endpoint_no), 496 495 _PACK3(speed, pipe->transfer_type, pipe->direction), 497 496 _PACK2(pipe->max_packet_size, interval)); -
uspace/lib/usbdev/src/pipesio.c
rf1d6866 r85ff862 65 65 void *buffer, size_t size, size_t *size_transfered) 66 66 { 67 /* Only interrupt and bulk transfers are supported */ 68 if (pipe->transfer_type != USB_TRANSFER_INTERRUPT && 69 pipe->transfer_type != USB_TRANSFER_BULK) 70 return ENOTSUP; 71 72 const usb_target_t target = 73 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }}; 67 /* 68 * Get corresponding IPC method. 69 * In future, replace with static array of mappings 70 * transfer type -> method. 71 */ 72 usbhc_iface_funcs_t ipc_method; 73 switch (pipe->transfer_type) { 74 case USB_TRANSFER_INTERRUPT: 75 ipc_method = IPC_M_USBHC_INTERRUPT_IN; 76 break; 77 case USB_TRANSFER_BULK: 78 ipc_method = IPC_M_USBHC_BULK_IN; 79 break; 80 default: 81 return ENOTSUP; 82 } 74 83 75 84 /* Ensure serialization over the phone. */ … … 80 89 * Make call identifying target USB device and type of transfer. 81 90 */ 82 aid_t opening_request = async_send_ 2(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),83 IPC_M_USBHC_READ, target.packed, NULL);91 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 92 ipc_method, pipe->wire->address, pipe->endpoint_no, NULL); 84 93 85 94 if (opening_request == 0) { … … 204 213 void *buffer, size_t size) 205 214 { 206 /* Only interrupt and bulk transfers are supported */ 207 if (pipe->transfer_type != USB_TRANSFER_INTERRUPT && 208 pipe->transfer_type != USB_TRANSFER_BULK) 209 return ENOTSUP; 210 211 const usb_target_t target = 212 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }}; 215 /* 216 * Get corresponding IPC method. 217 * In future, replace with static array of mappings 218 * transfer type -> method. 219 */ 220 usbhc_iface_funcs_t ipc_method; 221 switch (pipe->transfer_type) { 222 case USB_TRANSFER_INTERRUPT: 223 ipc_method = IPC_M_USBHC_INTERRUPT_OUT; 224 break; 225 case USB_TRANSFER_BULK: 226 ipc_method = IPC_M_USBHC_BULK_OUT; 227 break; 228 default: 229 return ENOTSUP; 230 } 213 231 214 232 /* Ensure serialization over the phone. */ … … 220 238 */ 221 239 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 222 IPC_M_USBHC_WRITE, target.packed, size, NULL);240 ipc_method, pipe->wire->address, pipe->endpoint_no, NULL); 223 241 224 242 if (opening_request == 0) { … … 334 352 pipe_start_transaction(pipe); 335 353 336 const usb_target_t target =337 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};338 339 assert(setup_buffer_size == 8);340 uint64_t setup_packet;341 memcpy(&setup_packet, setup_buffer, 8);342 354 /* 343 355 * Make call identifying target USB device and control transfer type. 344 356 */ 345 357 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 346 aid_t opening_request = async_send_ 4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),347 IPC_M_USBHC_ READ, target.packed,348 (setup_packet & UINT32_MAX), (setup_packet >> 32),NULL);349 358 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 359 IPC_M_USBHC_CONTROL_READ, pipe->wire->address, pipe->endpoint_no, 360 NULL); 361 350 362 if (opening_request == 0) { 351 363 async_exchange_end(exch); 352 364 return ENOMEM; 353 365 } 354 366 367 /* 368 * Send the setup packet. 369 */ 370 int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size); 371 if (rc != EOK) { 372 async_exchange_end(exch); 373 pipe_end_transaction(pipe); 374 async_wait_for(opening_request, NULL); 375 return rc; 376 } 377 355 378 /* 356 379 * Retrieve the data. … … 475 498 pipe_start_transaction(pipe); 476 499 477 const usb_target_t target =478 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};479 assert(setup_buffer_size == 8);480 uint64_t setup_packet;481 memcpy(&setup_packet, setup_buffer, 8);482 483 500 /* 484 501 * Make call identifying target USB device and control transfer type. 485 502 */ 486 503 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 487 aid_t opening_request = async_send_ 5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),488 IPC_M_USBHC_ WRITE, target.packed, data_buffer_size,489 (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL);504 aid_t opening_request = async_send_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 505 IPC_M_USBHC_CONTROL_WRITE, pipe->wire->address, pipe->endpoint_no, 506 data_buffer_size, NULL); 490 507 491 508 if (opening_request == 0) { … … 494 511 return ENOMEM; 495 512 } 496 513 514 /* 515 * Send the setup packet. 516 */ 517 int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size); 518 if (rc != EOK) { 519 async_exchange_end(exch); 520 pipe_end_transaction(pipe); 521 async_wait_for(opening_request, NULL); 522 return rc; 523 } 524 497 525 /* 498 526 * Send the data (if any). 499 527 */ 500 528 if (data_buffer_size > 0) { 501 intrc = async_data_write_start(exch, data_buffer, data_buffer_size);529 rc = async_data_write_start(exch, data_buffer, data_buffer_size); 502 530 503 531 /* All data sent, pipe can be released. */ -
uspace/lib/usbhost/Makefile
rf1d6866 r85ff862 32 32 -I$(LIBUSB_PREFIX)/include \ 33 33 -I$(LIBDRV_PREFIX)/include \ 34 -Iinclude 34 -Iinclude 35 35 36 36 SOURCES = \ 37 src/batch.c \ 38 src/device_keeper.c \ 37 39 src/endpoint.c \ 38 src/iface.c \ 39 src/usb_device_manager.c \ 40 src/usb_endpoint_manager.c \ 41 src/usb_transfer_batch.c 40 src/usb_endpoint_manager.c 42 41 43 42 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbhost/include/usb/host/endpoint.h
rf1d6866 r85ff862 54 54 fibril_condvar_t avail; 55 55 volatile bool active; 56 void (*destroy_hook)(struct endpoint *);57 56 struct { 58 57 void *data; … … 69 68 70 69 void endpoint_set_hc_data(endpoint_t *instance, 71 void *data, void (*destroy_hook)(endpoint_t *), 72 int (*toggle_get)(void *), void (*toggle_set)(void *, int)); 70 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)); 73 71 74 72 void endpoint_clear_hc_data(endpoint_t *instance); -
uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h
rf1d6866 r85ff862 38 38 */ 39 39 #ifndef LIBUSBHOST_HOST_USB_ENDPOINT_MANAGER_H 40 #define LIBUSBHOST_HOST_ USB_ENDPOINT_MANAGER_H40 #define LIBUSBHOST_HOST_YSB_ENDPOINT_MANAGER_H 41 41 42 42 #include <stdlib.h> … … 52 52 hash_table_t ep_table; 53 53 fibril_mutex_t guard; 54 fibril_condvar_t change; 54 55 size_t free_bw; 55 size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t);56 56 } usb_endpoint_manager_t; 57 57 … … 60 60 61 61 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 62 size_t available_bandwidth, 63 size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t)); 62 size_t available_bandwidth); 64 63 65 64 void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance); … … 78 77 usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data); 79 78 80 /** Wrapper combining allocation and insertion */81 79 static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance, 82 80 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, -
uspace/lib/usbhost/src/endpoint.c
rf1d6866 r85ff862 53 53 instance->toggle = 0; 54 54 instance->active = false; 55 instance->destroy_hook = NULL;56 instance->hc_data.data = NULL;57 instance->hc_data.toggle_get = NULL;58 instance->hc_data.toggle_set = NULL;59 55 fibril_mutex_initialize(&instance->guard); 60 56 fibril_condvar_initialize(&instance->avail); … … 68 64 assert(instance); 69 65 assert(!instance->active); 70 if (instance->hc_data.data) {71 assert(instance->destroy_hook);72 instance->destroy_hook(instance);73 }74 66 free(instance); 75 67 } 76 68 /*----------------------------------------------------------------------------*/ 77 69 void endpoint_set_hc_data(endpoint_t *instance, 78 void *data, void (*destroy_hook)(endpoint_t *), 79 int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 70 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 80 71 { 81 72 assert(instance); 82 instance->destroy_hook = destroy_hook;83 73 instance->hc_data.data = data; 84 74 instance->hc_data.toggle_get = toggle_get; … … 89 79 { 90 80 assert(instance); 91 instance->destroy_hook = NULL;92 81 instance->hc_data.data = NULL; 93 82 instance->hc_data.toggle_get = NULL; -
uspace/lib/usbhost/src/usb_endpoint_manager.c
rf1d6866 r85ff862 45 45 static hash_index_t node_hash(unsigned long key[]) 46 46 { 47 /* USB endpoints use 4 bits, thus ((key[0] << 4) | key[1]) 48 * produces unique value for every address.endpoint pair */ 49 return ((key[0] << 4) | key[1]) % BUCKET_COUNT; 47 hash_index_t hash = 0; 48 unsigned i = 0; 49 for (;i < MAX_KEYS; ++i) { 50 hash ^= key[i]; 51 } 52 hash %= BUCKET_COUNT; 53 return hash; 50 54 } 51 55 /*----------------------------------------------------------------------------*/ … … 59 63 switch (keys) { 60 64 case 3: 61 match = match && 62 ((key[2] == node->ep->direction) 63 || (node->ep->direction == USB_DIRECTION_BOTH)); 65 match = match && (key[2] == node->ep->direction); 64 66 case 2: 65 67 match = match && (key[1] == (unsigned long)node->ep->endpoint); … … 138 140 /*----------------------------------------------------------------------------*/ 139 141 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 140 size_t available_bandwidth, 141 size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t)) 142 size_t available_bandwidth) 142 143 { 143 144 assert(instance); 144 145 fibril_mutex_initialize(&instance->guard); 146 fibril_condvar_initialize(&instance->change); 145 147 instance->free_bw = available_bandwidth; 146 instance->bw_count = bw_count; 147 const bool ht = 148 bool ht = 148 149 hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op); 149 150 return ht ? EOK : ENOMEM; … … 158 159 endpoint_t *ep, size_t data_size) 159 160 { 160 assert(instance);161 assert(instance->bw_count);162 161 assert(ep); 163 const size_t bw = instance->bw_count(ep->speed, ep->transfer_type,162 size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 164 163 data_size, ep->max_packet_size); 165 166 fibril_mutex_lock(&instance->guard); 167 168 if (bw > instance->free_bw) { 169 fibril_mutex_unlock(&instance->guard); 170 return ENOSPC; 171 } 164 assert(instance); 172 165 173 166 unsigned long key[MAX_KEYS] = 174 167 {ep->address, ep->endpoint, ep->direction}; 175 176 const link_t *item = 168 fibril_mutex_lock(&instance->guard); 169 170 link_t *item = 177 171 hash_table_find(&instance->ep_table, key); 178 172 if (item != NULL) { 179 173 fibril_mutex_unlock(&instance->guard); 180 174 return EEXISTS; 175 } 176 177 if (bw > instance->free_bw) { 178 fibril_mutex_unlock(&instance->guard); 179 return ENOSPC; 181 180 } 182 181 … … 194 193 instance->free_bw -= bw; 195 194 fibril_mutex_unlock(&instance->guard); 195 fibril_condvar_broadcast(&instance->change); 196 196 return EOK; 197 197 } … … 211 211 212 212 node_t *node = hash_table_get_instance(item, node_t, link); 213 if (node->ep->active) { 214 fibril_mutex_unlock(&instance->guard); 213 if (node->ep->active) 215 214 return EBUSY; 216 }217 215 218 216 instance->free_bw += node->bw; … … 220 218 221 219 fibril_mutex_unlock(&instance->guard); 220 fibril_condvar_broadcast(&instance->change); 222 221 return EOK; 223 222 } … … 231 230 232 231 fibril_mutex_lock(&instance->guard); 233 constlink_t *item = hash_table_find(&instance->ep_table, key);232 link_t *item = hash_table_find(&instance->ep_table, key); 234 233 if (item == NULL) { 235 234 fibril_mutex_unlock(&instance->guard); 236 235 return NULL; 237 236 } 238 constnode_t *node = hash_table_get_instance(item, node_t, link);237 node_t *node = hash_table_get_instance(item, node_t, link); 239 238 if (bw) 240 239 *bw = node->bw; … … 256 255 { 257 256 assert(instance); 258 if (!usb_target_is_valid(target)) { 257 if (target.endpoint > 15 || target.endpoint < 0 258 || target.address >= USB11_ADDRESS_MAX || target.address < 0) { 259 259 usb_log_error("Invalid data when checking for toggle reset.\n"); 260 260 return; 261 261 } 262 262 263 assert(data);264 263 switch (data[1]) 265 264 { 266 case 0x01: /* Clear Feature -- resets only cleared ep*/267 /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */265 case 0x01: /*clear feature*/ 266 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */ 268 267 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 269 268 /* endpoint number is < 16, thus first byte is enough */ … … 277 276 break; 278 277 279 case 0x9: /* Set Configuration */280 case 0x11: /* Set Interface */281 /* Recipient must be device */278 case 0x9: /* set configuration */ 279 case 0x11: /* set interface */ 280 /* target must be device */ 282 281 if ((data[0] & 0xf) == 0) { 283 282 usb_target_t reset_target = -
uspace/srv/hid/console/console.c
rf1d6866 r85ff862 60 60 #define CONSOLE_MARGIN 12 61 61 62 #define STATE_START 1 0062 #define STATE_START 110 63 63 #define STATE_TOP 8 64 64 #define STATE_SPACE 4 … … 368 368 static console_t *cons_find_icon(sysarg_t x, sysarg_t y) 369 369 { 370 sysarg_t status_start = 371 STATE_START + (xres - 800) / 2 + CONSOLE_MARGIN; 370 sysarg_t status_start = STATE_START + (xres - 800) / 2; 372 371 373 372 if ((y < STATE_TOP) || (y >= STATE_TOP + STATE_HEIGHT)) … … 380 379 return NULL; 381 380 382 if (((x - status_start) % (STATE_WIDTH + STATE_SPACE)) >= STATE_WIDTH)381 if (((x - status_start) % (STATE_WIDTH + STATE_SPACE)) < STATE_SPACE) 383 382 return NULL; 384 383 … … 895 894 fb_vp_get_caps(fb_sess, console_vp, &ccaps); 896 895 897 mouse.x = xres / 2;898 mouse.y = yres / 2;899 896 mouse.pressed = false; 900 897 -
uspace/srv/hid/fb/port/kfb.c
rf1d6866 r85ff862 422 422 { 423 423 if (kfb.backbuf == NULL) { 424 kfb.backbuf = 425 malloc(kfb.width * kfb.height * kfb.pixel_bytes); 424 kfb.backbuf = malloc(kfb.size); 426 425 if (kfb.backbuf == NULL) 427 426 return ENOMEM; 428 427 } 429 428 430 for (sysarg_t y = 0; y < kfb.height; y++) 431 memcpy(kfb.backbuf + y * kfb.width * kfb.pixel_bytes, 432 kfb.addr + FB_POS(0, y), kfb.width * kfb.pixel_bytes); 433 429 memcpy(kfb.backbuf, kfb.addr, kfb.size); 434 430 return EOK; 435 431 } … … 440 436 return ENOENT; 441 437 442 for (sysarg_t y = 0; y < kfb.height; y++) 443 memcpy(kfb.addr + FB_POS(0, y), 444 kfb.backbuf + y * kfb.width * kfb.pixel_bytes, 445 kfb.width * kfb.pixel_bytes); 446 438 memcpy(kfb.addr, kfb.backbuf, kfb.size); 447 439 return EOK; 448 440 }
Note:
See TracChangeset
for help on using the changeset viewer.