Changeset a43f1d18 in mainline
- Timestamp:
- 2011-04-09T18:26:22Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2ad98fd
- Parents:
- f35b294 (diff), 97e7e8a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 6 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/dev.c
rf35b294 ra43f1d18 50 50 51 51 int rc; 52 bool transfer_started = false; 52 53 53 54 rc = usb_device_connection_initialize(&dev->wire, hc_handle, dev_addr); … … 76 77 } 77 78 78 rc = usb_pipe_start_ session(&dev->ctrl_pipe);79 rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe); 79 80 if (rc != EOK) { 80 81 fprintf(stderr, 81 NAME ": failed to start sessionon control pipe: %s.\n",82 NAME ": failed to start transfer on control pipe: %s.\n", 82 83 str_error(rc)); 83 84 goto leave; 84 85 } 86 transfer_started = true; 85 87 86 88 rc = usb_request_get_device_descriptor(&dev->ctrl_pipe, … … 107 109 108 110 leave: 109 if ( usb_pipe_is_session_started(&dev->ctrl_pipe)) {110 usb_pipe_end_ session(&dev->ctrl_pipe);111 if (transfer_started) { 112 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 111 113 } 112 114 … … 118 120 void destroy_device(usbinfo_device_t *dev) 119 121 { 120 usb_pipe_end_ session(&dev->ctrl_pipe);122 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 121 123 free(dev); 122 124 } -
uspace/doc/doxygroups.h
rf35b294 ra43f1d18 269 269 270 270 /** 271 * @defgroup drvusbohci OHCI driver 272 * @ingroup usb 273 * @brief Driver for OHCI host controller. 274 */ 275 276 /** 271 277 * @defgroup drvusbehci EHCI driver 272 278 * @ingroup usb … … 275 281 276 282 /** 277 * @defgroup drvusbfallback USB fallback driver .283 * @defgroup drvusbfallback USB fallback driver 278 284 * @ingroup usb 279 285 * @brief Fallback driver for any USB device. -
uspace/drv/ehci-hcd/hc_iface.c
rf35b294 ra43f1d18 123 123 * @param[in] fun Device function the action was invoked on. 124 124 * @param[in] address USB address of the device. 125 * @param[in] speed Endpoint speed (invalid means to use device one). 125 126 * @param[in] endpoint Endpoint number. 126 127 * @param[in] transfer_type USB transfer type. … … 131 132 */ 132 133 static int register_endpoint(ddf_fun_t *fun, 133 usb_address_t address, usb_ endpoint_t endpoint,134 usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint, 134 135 usb_transfer_type_t transfer_type, usb_direction_t direction, 135 136 size_t max_packet_size, unsigned int interval) … … 165 166 * @param[in] fun Device function the action was invoked on. 166 167 * @param[in] target Target pipe (address and endpoint number) specification. 167 * @param[in] max_packet_size Max packet size for the transfer.168 168 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 169 169 * by the caller). … … 174 174 */ 175 175 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 176 size_t max_packet_size,void *data, size_t size,176 void *data, size_t size, 177 177 usbhc_iface_transfer_out_callback_t callback, void *arg) 178 178 { … … 191 191 * @param[in] fun Device function the action was invoked on. 192 192 * @param[in] target Target pipe (address and endpoint number) specification. 193 * @param[in] max_packet_size Max packet size for the transfer.194 193 * @param[in] data Buffer where to store the data (in USB endianess, 195 194 * allocated and deallocated by the caller). … … 200 199 */ 201 200 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 202 size_t max_packet_size,void *data, size_t size,201 void *data, size_t size, 203 202 usbhc_iface_transfer_in_callback_t callback, void *arg) 204 203 { … … 217 216 * @param[in] fun Device function the action was invoked on. 218 217 * @param[in] target Target pipe (address and endpoint number) specification. 219 * @param[in] max_packet_size Max packet size for the transfer.220 218 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 221 219 * by the caller). … … 226 224 */ 227 225 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 228 size_t max_packet_size,void *data, size_t size,226 void *data, size_t size, 229 227 usbhc_iface_transfer_out_callback_t callback, void *arg) 230 228 { … … 243 241 * @param[in] fun Device function the action was invoked on. 244 242 * @param[in] target Target pipe (address and endpoint number) specification. 245 * @param[in] max_packet_size Max packet size for the transfer.246 243 * @param[in] data Buffer where to store the data (in USB endianess, 247 244 * allocated and deallocated by the caller). … … 252 249 */ 253 250 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 254 size_t max_packet_size,void *data, size_t size,251 void *data, size_t size, 255 252 usbhc_iface_transfer_in_callback_t callback, void *arg) 256 253 { … … 269 266 * @param[in] fun Device function the action was invoked on. 270 267 * @param[in] target Target pipe (address and endpoint number) specification. 271 * @param[in] max_packet_size Max packet size for the transfer.272 268 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 273 269 * and deallocated by the caller). … … 281 277 */ 282 278 static int control_write(ddf_fun_t *fun, usb_target_t target, 283 size_t max_packet_size,284 279 void *setup_packet, size_t setup_packet_size, 285 280 void *data_buffer, size_t data_buffer_size, … … 300 295 * @param[in] fun Device function the action was invoked on. 301 296 * @param[in] target Target pipe (address and endpoint number) specification. 302 * @param[in] max_packet_size Max packet size for the transfer.303 297 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 304 298 * and deallocated by the caller). … … 312 306 */ 313 307 static int control_read(ddf_fun_t *fun, usb_target_t target, 314 size_t max_packet_size,315 308 void *setup_packet, size_t setup_packet_size, 316 309 void *data_buffer, size_t data_buffer_size, -
uspace/drv/ohci/Makefile
rf35b294 ra43f1d18 33 33 34 34 SOURCES = \ 35 batch.c \ 36 hc.c \ 35 37 iface.c \ 36 batch.c \37 38 main.c \ 38 hc.c \39 39 ohci.c \ 40 pci.c \ 40 41 root_hub.c \ 41 pci.c 42 transfer_list.c \ 43 hw_struct/endpoint_descriptor.c \ 44 hw_struct/transfer_descriptor.c 45 42 46 43 47 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/ohci/batch.c
rf35b294 ra43f1d18 40 40 #include "batch.h" 41 41 #include "utils/malloc32.h" 42 42 #include "hw_struct/endpoint_descriptor.h" 43 #include "hw_struct/transfer_descriptor.h" 44 45 typedef struct ohci_batch { 46 ed_t *ed; 47 td_t *tds; 48 size_t td_count; 49 } ohci_batch_t; 50 51 static void batch_control(usb_transfer_batch_t *instance, 52 usb_direction_t data_dir, usb_direction_t status_dir); 43 53 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance); 44 54 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance); 45 55 46 56 #define DEFAULT_ERROR_COUNT 3 47 usb_transfer_batch_t * batch_get( 48 ddf_fun_t *fun, 49 usb_target_t target, 50 usb_transfer_type_t transfer_type, 51 size_t max_packet_size, 52 usb_speed_t speed, 53 char *buffer, 54 size_t buffer_size, 55 char *setup_buffer, 56 size_t setup_size, 57 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 58 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 57 59 usbhc_iface_transfer_in_callback_t func_in, 58 usbhc_iface_transfer_out_callback_t func_out, 59 void *arg, 60 usb_device_keeper_t *manager 61 ) 60 usbhc_iface_transfer_out_callback_t func_out, void *arg) 62 61 { 63 62 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ … … 73 72 CHECK_NULL_DISPOSE_RETURN(instance, 74 73 "Failed to allocate batch instance.\n"); 75 usb_transfer_batch_init(instance, target, transfer_type, speed, 76 max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 77 func_in, func_out, arg, fun, NULL, NULL); 74 usb_target_t target = 75 { .address = ep->address, .endpoint = ep->endpoint }; 76 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 77 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 78 func_in, func_out, arg, fun, ep, NULL); 79 80 ohci_batch_t *data = malloc(sizeof(ohci_batch_t)); 81 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n"); 82 bzero(data, sizeof(ohci_batch_t)); 83 instance->private_data = data; 84 85 /* we needs + 1 transfer descriptor as the last one won't be executed */ 86 data->td_count = 1 + 87 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER); 88 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 89 data->td_count += 2; 90 } 91 92 data->tds = malloc32(sizeof(td_t) * data->td_count); 93 CHECK_NULL_DISPOSE_RETURN(data->tds, 94 "Failed to allocate transfer descriptors.\n"); 95 bzero(data->tds, sizeof(td_t) * data->td_count); 96 97 data->ed = malloc32(sizeof(ed_t)); 98 CHECK_NULL_DISPOSE_RETURN(data->ed, 99 "Failed to allocate endpoint descriptor.\n"); 78 100 79 101 if (buffer_size > 0) { … … 90 112 } 91 113 92 93 114 return instance; 94 115 } … … 97 118 { 98 119 assert(instance); 120 ohci_batch_t *data = instance->private_data; 121 assert(data); 122 free32(data->ed); 123 free32(data->tds); 124 free32(instance->setup_buffer); 99 125 free32(instance->transport_buffer); 100 free 32(instance->setup_buffer);126 free(data); 101 127 free(instance); 128 } 129 /*----------------------------------------------------------------------------*/ 130 bool batch_is_complete(usb_transfer_batch_t *instance) 131 { 132 assert(instance); 133 ohci_batch_t *data = instance->private_data; 134 assert(data); 135 size_t tds = data->td_count - 1; 136 usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n", 137 instance, tds); 138 size_t i = 0; 139 for (; i < tds; ++i) { 140 if (!td_is_finished(&data->tds[i])) 141 return false; 142 instance->error = td_error(&data->tds[i]); 143 /* FIXME: calculate real transfered size */ 144 instance->transfered_size = instance->buffer_size; 145 if (instance->error != EOK) { 146 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 147 instance, i, data->tds[i].status); 148 return true; 149 // endpoint_toggle_set(instance->ep, 150 } 151 } 152 return true; 102 153 } 103 154 /*----------------------------------------------------------------------------*/ … … 109 160 instance->buffer_size); 110 161 instance->next_step = batch_call_out_and_dispose; 111 /* TODO: implement */162 batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN); 112 163 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 113 164 } … … 117 168 assert(instance); 118 169 instance->next_step = batch_call_in_and_dispose; 119 /* TODO: implement */170 batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT); 120 171 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 121 172 } … … 124 175 { 125 176 assert(instance); 126 instance->direction = USB_DIRECTION_IN;177 assert(instance->direction == USB_DIRECTION_IN); 127 178 instance->next_step = batch_call_in_and_dispose; 128 179 /* TODO: implement */ … … 133 184 { 134 185 assert(instance); 135 instance->direction = USB_DIRECTION_OUT;186 assert(instance->direction == USB_DIRECTION_OUT); 136 187 /* We are data out, we are supposed to provide data */ 137 188 memcpy(instance->transport_buffer, instance->buffer, … … 160 211 } 161 212 /*----------------------------------------------------------------------------*/ 213 ed_t * batch_ed(usb_transfer_batch_t *instance) 214 { 215 assert(instance); 216 ohci_batch_t *data = instance->private_data; 217 assert(data); 218 return data->ed; 219 } 220 /*----------------------------------------------------------------------------*/ 221 void batch_control(usb_transfer_batch_t *instance, 222 usb_direction_t data_dir, usb_direction_t status_dir) 223 { 224 assert(instance); 225 ohci_batch_t *data = instance->private_data; 226 assert(data); 227 ed_init(data->ed, instance->ep); 228 ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]); 229 usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status, 230 data->ed->td_tail, data->ed->td_head, data->ed->next); 231 int toggle = 0; 232 /* setup stage */ 233 td_init(&data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer, 234 instance->setup_size, toggle); 235 td_set_next(&data->tds[0], &data->tds[1]); 236 usb_log_debug("Created SETUP TD: %x:%x:%x:%x.\n", data->tds[0].status, 237 data->tds[0].cbp, data->tds[0].next, data->tds[0].be); 238 239 /* data stage */ 240 size_t td_current = 1; 241 size_t remain_size = instance->buffer_size; 242 char *transfer_buffer = instance->transport_buffer; 243 while (remain_size > 0) { 244 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ? 245 OHCI_TD_MAX_TRANSFER : remain_size; 246 toggle = 1 - toggle; 247 248 td_init(&data->tds[td_current], data_dir, transfer_buffer, 249 transfer_size, toggle); 250 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]); 251 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n", 252 data->tds[td_current].status, data->tds[td_current].cbp, 253 data->tds[td_current].next, data->tds[td_current].be); 254 255 transfer_buffer += transfer_size; 256 remain_size -= transfer_size; 257 assert(td_current < data->td_count - 2); 258 ++td_current; 259 } 260 261 /* status stage */ 262 assert(td_current == data->td_count - 2); 263 td_init(&data->tds[td_current], status_dir, NULL, 0, 1); 264 usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n", 265 data->tds[td_current].status, data->tds[td_current].cbp, 266 data->tds[td_current].next, data->tds[td_current].be); 267 } 268 /*----------------------------------------------------------------------------*/ 162 269 /** Helper function calls callback and correctly disposes of batch structure. 163 270 * -
uspace/drv/ohci/batch.h
rf35b294 ra43f1d18 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusb ohci28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief OHCI driver USB transaction structure32 * @brief UHCI driver USB transaction structure 33 33 */ 34 #ifndef DRV_OHCI_BATCH_H 35 #define DRV_OHCI_BATCH_H 36 34 #ifndef DRV_UHCI_BATCH_H 35 #define DRV_UHCI_BATCH_H 37 36 38 37 #include <usbhc_iface.h> 39 38 #include <usb/usb.h> 40 39 #include <usb/host/device_keeper.h> 40 #include <usb/host/endpoint.h> 41 41 #include <usb/host/batch.h> 42 42 43 #include "hw_struct/endpoint_descriptor.h" 44 43 45 usb_transfer_batch_t * batch_get( 44 ddf_fun_t *fun, 45 usb_target_t target, 46 usb_transfer_type_t transfer_type, 47 size_t max_packet_size, 48 usb_speed_t speed, 49 char *buffer, 50 size_t size, 51 char *setup_buffer, 52 size_t setup_size, 46 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 47 char *setup_buffer, size_t setup_size, 53 48 usbhc_iface_transfer_in_callback_t func_in, 54 49 usbhc_iface_transfer_out_callback_t func_out, 55 void *arg, 56 usb_device_keeper_t *manager 57 ); 50 void *arg); 58 51 59 52 void batch_dispose(usb_transfer_batch_t *instance); 53 54 bool batch_is_complete(usb_transfer_batch_t *instance); 60 55 61 56 void batch_control_write(usb_transfer_batch_t *instance); … … 70 65 71 66 void batch_bulk_out(usb_transfer_batch_t *instance); 67 68 ed_t * batch_ed(usb_transfer_batch_t *instance); 72 69 #endif 73 70 /** -
uspace/drv/ohci/hc.c
rf35b294 ra43f1d18 47 47 static void hc_gain_control(hc_t *instance); 48 48 static void hc_init_hw(hc_t *instance); 49 static int hc_init_transfer_lists(hc_t *instance); 50 static int hc_init_memory(hc_t *instance); 49 51 /*----------------------------------------------------------------------------*/ 50 52 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) … … 59 61 &instance->manager, hub_address, hub_fun->handle); 60 62 63 endpoint_t *ep = malloc(sizeof(endpoint_t)); 64 assert(ep); 65 int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH, 66 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64); 67 assert(ret == EOK); 68 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0); 69 assert(ret == EOK); 70 61 71 char *match_str = NULL; 62 intret = asprintf(&match_str, "usb&class=hub");63 ret = (match_str == NULL) ? ret : EOK;72 ret = asprintf(&match_str, "usb&class=hub"); 73 // ret = (match_str == NULL) ? ret : EOK; 64 74 if (ret < 0) { 65 usb_log_error("Failed to create root hub match-id string.\n"); 75 usb_log_error( 76 "Failed(%d) to create root hub match-id string.\n", ret); 66 77 return ret; 67 78 } … … 107 118 rh_init(&instance->rh, dev, instance->registers); 108 119 120 hc_init_memory(instance); 109 121 hc_init_hw(instance); 110 122 … … 117 129 assert(instance); 118 130 assert(batch); 131 132 /* check for root hub communication */ 119 133 if (batch->target.address == instance->rh.address) { 120 134 return rh_request(&instance->rh, batch); 121 135 } 122 /* TODO: implement */ 123 return ENOTSUP; 136 137 transfer_list_add_batch( 138 instance->transfers[batch->transfer_type], batch); 139 140 switch (batch->transfer_type) { 141 case USB_TRANSFER_CONTROL: 142 instance->registers->command_status |= CS_CLF; 143 break; 144 case USB_TRANSFER_BULK: 145 instance->registers->command_status |= CS_BLF; 146 break; 147 default: 148 break; 149 } 150 return EOK; 124 151 } 125 152 /*----------------------------------------------------------------------------*/ … … 134 161 usb_log_info("OHCI interrupt: %x.\n", status); 135 162 136 /* TODO: Check for further interrupt causes */ 137 /* TODO: implement */ 163 LIST_INITIALIZE(done); 164 transfer_list_remove_finished(&instance->transfers_interrupt, &done); 165 transfer_list_remove_finished(&instance->transfers_isochronous, &done); 166 transfer_list_remove_finished(&instance->transfers_control, &done); 167 transfer_list_remove_finished(&instance->transfers_bulk, &done); 168 169 while (!list_empty(&done)) { 170 link_t *item = done.next; 171 list_remove(item); 172 usb_transfer_batch_t *batch = 173 list_get_instance(item, usb_transfer_batch_t, link); 174 usb_transfer_batch_finish(batch); 175 } 138 176 } 139 177 /*----------------------------------------------------------------------------*/ … … 197 235 assert(instance); 198 236 const uint32_t fm_interval = instance->registers->fm_interval; 237 238 /* reset hc */ 199 239 instance->registers->command_status = CS_HCR; 200 240 async_usleep(10); 241 242 /* restore fm_interval */ 201 243 instance->registers->fm_interval = fm_interval; 202 244 assert((instance->registers->command_status & CS_HCR) == 0); 245 203 246 /* hc is now in suspend state */ 204 /* TODO: init HCCA block */ 205 /* TODO: initqueues */206 /* TODO: enable queues */247 248 /* enable queues */ 249 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE); 207 250 /* TODO: enable interrupts */ 208 /* TODO: set periodic start to 90% */ 251 /* set periodic start to 90% */ 252 instance->registers->periodic_start = (fm_interval / 10) * 9; 209 253 210 254 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 211 255 usb_log_info("OHCI HC up and running.\n"); 256 } 257 /*----------------------------------------------------------------------------*/ 258 int hc_init_transfer_lists(hc_t *instance) 259 { 260 assert(instance); 261 262 #define SETUP_TRANSFER_LIST(type, name) \ 263 do { \ 264 int ret = transfer_list_init(&instance->type, name); \ 265 if (ret != EOK) { \ 266 usb_log_error("Failed(%d) to setup %s transfer list.\n", \ 267 ret, name); \ 268 transfer_list_fini(&instance->transfers_isochronous); \ 269 transfer_list_fini(&instance->transfers_interrupt); \ 270 transfer_list_fini(&instance->transfers_control); \ 271 transfer_list_fini(&instance->transfers_bulk); \ 272 } \ 273 } while (0) 274 275 SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS"); 276 SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT"); 277 SETUP_TRANSFER_LIST(transfers_control, "CONTROL"); 278 SETUP_TRANSFER_LIST(transfers_bulk, "BULK"); 279 280 transfer_list_set_next(&instance->transfers_interrupt, 281 &instance->transfers_isochronous); 282 283 /* Assign pointers to be used during scheduling */ 284 instance->transfers[USB_TRANSFER_INTERRUPT] = 285 &instance->transfers_interrupt; 286 instance->transfers[USB_TRANSFER_ISOCHRONOUS] = 287 &instance->transfers_interrupt; 288 instance->transfers[USB_TRANSFER_CONTROL] = 289 &instance->transfers_control; 290 instance->transfers[USB_TRANSFER_BULK] = 291 &instance->transfers_bulk; 292 293 return EOK; 294 #undef CHECK_RET_CLEAR_RETURN 295 } 296 /*----------------------------------------------------------------------------*/ 297 int hc_init_memory(hc_t *instance) 298 { 299 assert(instance); 300 /* init queues */ 301 hc_init_transfer_lists(instance); 302 303 /* init HCCA */ 304 instance->hcca = malloc32(sizeof(hcca_t)); 305 if (instance->hcca == NULL) 306 return ENOMEM; 307 bzero(instance->hcca, sizeof(hcca_t)); 308 instance->registers->hcca = addr_to_phys(instance->hcca); 309 310 /* use queues */ 311 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 312 instance->registers->control_head = 313 instance->transfers_control.list_head_pa; 314 315 unsigned i = 0; 316 for (; i < 32; ++i) { 317 instance->hcca->int_ep[i] = 318 instance->transfers_interrupt.list_head_pa; 319 } 320 321 return EOK; 212 322 } 213 323 /** -
uspace/drv/ohci/hc.h
rf35b294 ra43f1d18 48 48 #include "ohci_regs.h" 49 49 #include "root_hub.h" 50 #include "transfer_list.h" 50 51 #include "hw_struct/hcca.h" 51 52 … … 54 55 usb_address_t rh_address; 55 56 rh_t rh; 57 58 hcca_t *hcca; 59 60 transfer_list_t transfers_isochronous; 61 transfer_list_t transfers_interrupt; 62 transfer_list_t transfers_control; 63 transfer_list_t transfers_bulk; 64 65 transfer_list_t *transfers[4]; 66 56 67 ddf_fun_t *ddf_instance; 57 68 usb_device_keeper_t manager; -
uspace/drv/ohci/hw_struct/completion_codes.h
rf35b294 ra43f1d18 35 35 #define DRV_OHCI_HW_STRUCT_COMPLETION_CODES_H 36 36 37 #include <errno.h> 38 37 39 #define CC_NOERROR (0x0) 38 40 #define CC_CRC (0x1) … … 50 52 #define CC_NOACCESS2 (0xf) 51 53 54 inline static int cc_to_rc(int cc) 55 { 56 switch (cc) { 57 case CC_NOERROR: 58 return EOK; 59 60 case CC_CRC: 61 return EBADCHECKSUM; 62 63 case CC_PIDUNEXPECTED: 64 case CC_PIDFAIL: 65 case CC_BITSTUFF: 66 return EIO; 67 68 case CC_TOGGLE: 69 case CC_STALL: 70 return ESTALL; 71 72 case CC_NORESPONSE: 73 return ETIMEOUT; 74 75 case CC_DATAOVERRRUN: 76 case CC_DATAUNDERRRUN: 77 case CC_BUFFEROVERRRUN: 78 case CC_BUFFERUNDERRUN: 79 return EOVERFLOW; 80 81 case CC_NOACCESS1: 82 case CC_NOACCESS2: 83 default: 84 return ENOTSUP; 85 } 86 } 87 52 88 #endif 53 89 /** -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
rf35b294 ra43f1d18 35 35 #define DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H 36 36 37 #include <assert.h> 37 38 #include <stdint.h> 39 40 #include <usb/host/endpoint.h> 41 42 #include "utils/malloc32.h" 43 #include "transfer_descriptor.h" 38 44 39 45 #include "completion_codes.h" … … 44 50 #define ED_STATUS_FA_SHIFT (0) 45 51 #define ED_STATUS_EN_MASK (0xf) /* USB endpoint address */ 46 #define ED_STATUS_EN_SHIFT ( 6)52 #define ED_STATUS_EN_SHIFT (7) 47 53 #define ED_STATUS_D_MASK (0x3) /* direction */ 48 #define ED_STATUS_D_SHIFT (1 0)54 #define ED_STATUS_D_SHIFT (11) 49 55 #define ED_STATUS_D_IN (0x1) 50 56 #define ED_STATUS_D_OUT (0x2) 57 #define ED_STATUS_D_TRANSFER (0x3) 51 58 52 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag */59 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag: 1 = low */ 53 60 #define ED_STATUS_K_FLAG (1 << 14) /* skip flag (no not execute this ED) */ 54 61 #define ED_STATUS_F_FLAG (1 << 15) /* format: 1 = isochronous*/ … … 71 78 #define ED_NEXT_PTR_SHIFT (0) 72 79 } __attribute__((packed)) ed_t; 80 81 void ed_init(ed_t *instance, endpoint_t *ep); 82 83 static inline void ed_add_tds(ed_t *instance, td_t *head, td_t *tail) 84 { 85 assert(instance); 86 instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK; 87 instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK; 88 } 89 90 static inline void ed_append_ed(ed_t *instance, ed_t *next) 91 { 92 assert(instance); 93 assert(next); 94 uint32_t pa = addr_to_phys(next); 95 assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa); 96 instance->next = pa; 97 } 98 73 99 #endif 74 100 /** -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
rf35b294 ra43f1d18 35 35 #define DRV_OHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H 36 36 37 #include <bool.h> 37 38 #include <stdint.h> 39 #include "utils/malloc32.h" 38 40 39 41 #include "completion_codes.h" 42 43 /* OHCI TDs can handle up to 8KB buffers */ 44 #define OHCI_TD_MAX_TRANSFER (8 * 1024) 40 45 41 46 typedef struct td { … … 52 57 #define TD_STATUS_T_MASK (0x3) /* data toggle 1x = use ED toggle carry */ 53 58 #define TD_STATUS_T_SHIFT (24) 59 #define TD_STATUS_T_0 (0x2) 60 #define TD_STATUS_T_1 (0x3) 54 61 #define TD_STATUS_EC_MASK (0x3) /* error count */ 55 62 #define TD_STATUS_EC_SHIFT (26) … … 64 71 volatile uint32_t be; /* buffer end, address of the last byte */ 65 72 } __attribute__((packed)) td_t; 73 74 void td_init( 75 td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle); 76 77 inline static void td_set_next(td_t *instance, td_t *next) 78 { 79 assert(instance); 80 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK; 81 } 82 83 inline static bool td_is_finished(td_t *instance) 84 { 85 assert(instance); 86 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 87 /* something went wrong, error code is set */ 88 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) { 89 return true; 90 } 91 /* everything done */ 92 if (cc == CC_NOERROR && instance->cbp == 0) { 93 return true; 94 } 95 return false; 96 } 97 98 static inline int td_error(td_t *instance) 99 { 100 assert(instance); 101 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 102 return cc_to_rc(cc); 103 } 66 104 #endif 67 105 /** -
uspace/drv/ohci/iface.c
rf35b294 ra43f1d18 1 1 /* 2 * Copyright (c) 2011 Vojtech Horky 2 * Copyright (c) 2011 Vojtech Horky, Jan Vesely 3 3 * All rights reserved. 4 4 * … … 30 30 */ 31 31 /** @file 32 * USB-HC interface implementation.32 * @brief OHCI driver hc interface implementation 33 33 */ 34 34 #include <ddf/driver.h> … … 36 36 37 37 #include <usb/debug.h> 38 #include <usb/host/endpoint.h> 38 39 39 40 #include "iface.h" 40 41 #include "hc.h" 41 42 42 #define UNSUPPORTED(methodname) \ 43 usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \ 44 methodname, __FILE__, __LINE__) 45 46 /** Reserve default address. 47 * 48 * This function may block the caller. 49 * 50 * @param[in] fun Device function the action was invoked on. 51 * @param[in] speed Speed of the device for which the default address is 52 * reserved. 43 static inline int setup_batch( 44 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, 45 void *data, size_t size, void * setup_data, size_t setup_size, 46 usbhc_iface_transfer_in_callback_t in, 47 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name, 48 hc_t **hc, usb_transfer_batch_t **batch) 49 { 50 assert(hc); 51 assert(batch); 52 assert(fun); 53 *hc = fun_to_hc(fun); 54 assert(*hc); 55 56 size_t res_bw; 57 endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager, 58 target.address, target.endpoint, direction, &res_bw); 59 if (ep == NULL) { 60 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", 61 target.address, target.endpoint, name); 62 return ENOENT; 63 } 64 65 const size_t bw = bandwidth_count_usb11( 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); 67 if (res_bw < bw) { 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 69 "but only %zu is reserved.\n", 70 name, target.address, target.endpoint, bw, res_bw); 71 return ENOSPC; 72 } 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 76 assert(ep->speed == 77 usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 92 * @param[in] fun DDF function that was called. 93 * @param[in] speed Speed to associate with the new default address. 53 94 * @return Error code. 54 95 */ … … 61 102 usb_device_keeper_reserve_default_address(&hc->manager, speed); 62 103 return EOK; 63 } 64 /*----------------------------------------------------------------------------*/ 65 /** Release default address. 66 * 67 * @param[in] fun Device function the action was invoked on. 104 #if 0 105 endpoint_t *ep = malloc(sizeof(endpoint_t)); 106 if (ep == NULL) 107 return ENOMEM; 108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64; 109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size); 110 int ret; 111 try_retgister: 112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, 113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0); 114 if (ret == EEXISTS) { 115 async_usleep(1000); 116 goto try_retgister; 117 } 118 if (ret != EOK) { 119 endpoint_destroy(ep); 120 } 121 return ret; 122 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 127 * @param[in] fun DDF function that was called. 68 128 * @return Error code. 69 129 */ … … 74 134 assert(hc); 75 135 usb_log_debug("Default address release.\n"); 136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager, 137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH); 76 138 usb_device_keeper_release_default_address(&hc->manager); 77 139 return EOK; 78 140 } 79 141 /*----------------------------------------------------------------------------*/ 80 /** Found free USB address.81 * 82 * @param[in] fun D evice function the action was invoked on.83 * @param[in] speed Speed of the device that will get thisaddress.84 * @param[out] address Non-null pointer where to store the freeaddress.142 /** Request address interface function 143 * 144 * @param[in] fun DDF function that was called. 145 * @param[in] speed Speed to associate with the new default address. 146 * @param[out] address Place to write a new address. 85 147 * @return Error code. 86 148 */ … … 101 163 } 102 164 /*----------------------------------------------------------------------------*/ 103 /** Bind USB address with device devman handle.104 * 105 * @param[in] fun D evice function the action was invoked on.106 * @param[in] address USB address of the device.107 * @param[in] handle Devman handle of the device .165 /** Bind address interface function 166 * 167 * @param[in] fun DDF function that was called. 168 * @param[in] address Address of the device 169 * @param[in] handle Devman handle of the device driver. 108 170 * @return Error code. 109 171 */ 110 172 static int bind_address( 111 173 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 112 174 { 113 175 assert(fun); … … 119 181 } 120 182 /*----------------------------------------------------------------------------*/ 121 /** Release previously requested address.122 * 123 * @param[in] fun D evice function the action was invoked on.183 /** Release address interface function 184 * 185 * @param[in] fun DDF function that was called. 124 186 * @param[in] address USB address to be released. 125 187 * @return Error code. … … 139 201 * @param[in] fun Device function the action was invoked on. 140 202 * @param[in] address USB address of the device. 203 * @param[in] ep_speed Endpoint speed (invalid means to use device one). 141 204 * @param[in] endpoint Endpoint number. 142 205 * @param[in] transfer_type USB transfer type. … … 146 209 * @return Error code. 147 210 */ 148 static int register_endpoint( 149 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,211 static int register_endpoint(ddf_fun_t *fun, 212 usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint, 150 213 usb_transfer_type_t transfer_type, usb_direction_t direction, 151 214 size_t max_packet_size, unsigned int interval) 152 215 { 153 assert(fun);154 216 hc_t *hc = fun_to_hc(fun); 155 217 assert(hc); 156 218 if (address == hc->rh.address) 157 219 return EOK; 158 const usb_speed_t speed = 159 usb_device_keeper_get_speed(&hc->manager, address); 160 const size_t size = max_packet_size; 220 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 221 if (speed >= USB_SPEED_MAX) { 222 speed = ep_speed; 223 } 224 const size_t size = 225 (transfer_type == USB_TRANSFER_INTERRUPT 226 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 227 max_packet_size : 0; 228 int ret; 229 230 endpoint_t *ep = malloc(sizeof(endpoint_t)); 231 if (ep == NULL) 232 return ENOMEM; 233 ret = endpoint_init(ep, address, endpoint, direction, 234 transfer_type, speed, max_packet_size); 235 if (ret != EOK) { 236 free(ep); 237 return ret; 238 } 239 161 240 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 162 241 address, endpoint, usb_str_transfer_type(transfer_type), 163 242 usb_str_speed(speed), direction, size, max_packet_size, interval); 164 // TODO use real endpoint here! 165 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 166 } 167 /*----------------------------------------------------------------------------*/ 168 /** Unregister endpoint (free some bandwidth reservation). 169 * 170 * @param[in] fun Device function the action was invoked on. 171 * @param[in] address USB address of the device. 172 * @param[in] endpoint Endpoint number. 173 * @param[in] direction Endpoint data direction. 174 * @return Error code. 175 */ 243 244 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 245 if (ret != EOK) { 246 endpoint_destroy(ep); 247 } else { 248 usb_device_keeper_add_ep(&hc->manager, address, ep); 249 } 250 return ret; 251 } 252 /*----------------------------------------------------------------------------*/ 176 253 static int unregister_endpoint( 177 254 ddf_fun_t *fun, usb_address_t address, 178 255 usb_endpoint_t endpoint, usb_direction_t direction) 179 256 { 180 assert(fun);181 257 hc_t *hc = fun_to_hc(fun); 182 258 assert(hc); 183 259 usb_log_debug("Unregister endpoint %d:%d %d.\n", 184 260 address, endpoint, direction); 261 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 262 address, endpoint, direction, NULL); 263 if (ep != NULL) { 264 usb_device_keeper_del_ep(&hc->manager, address, ep); 265 } 185 266 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 186 267 endpoint, direction); … … 196 277 * @param[in] fun Device function the action was invoked on. 197 278 * @param[in] target Target pipe (address and endpoint number) specification. 198 * @param[in] max_packet_size Max packet size for the transfer.199 279 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 200 280 * by the caller). … … 205 285 */ 206 286 static int interrupt_out( 207 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,287 ddf_fun_t *fun, usb_target_t target, void *data, 208 288 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 209 289 { 210 assert(fun); 211 hc_t *hc = fun_to_hc(fun); 212 assert(hc); 213 usb_speed_t speed = 214 usb_device_keeper_get_speed(&hc->manager, target.address); 215 216 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 217 target.address, target.endpoint, size, max_packet_size); 218 219 usb_transfer_batch_t *batch = 220 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 221 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 222 if (!batch) 223 return ENOMEM; 290 usb_transfer_batch_t *batch = NULL; 291 hc_t *hc = NULL; 292 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 293 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 294 if (ret != EOK) 295 return ret; 224 296 batch_interrupt_out(batch); 225 const intret = hc_schedule(hc, batch);297 ret = hc_schedule(hc, batch); 226 298 if (ret != EOK) { 227 299 batch_dispose(batch); … … 239 311 * @param[in] fun Device function the action was invoked on. 240 312 * @param[in] target Target pipe (address and endpoint number) specification. 241 * @param[in] max_packet_size Max packet size for the transfer.242 313 * @param[in] data Buffer where to store the data (in USB endianess, 243 314 * allocated and deallocated by the caller). … … 248 319 */ 249 320 static int interrupt_in( 250 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,321 ddf_fun_t *fun, usb_target_t target, void *data, 251 322 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 252 323 { 253 assert(fun); 254 hc_t *hc = fun_to_hc(fun); 255 assert(hc); 256 usb_speed_t speed = 257 usb_device_keeper_get_speed(&hc->manager, target.address); 258 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 259 target.address, target.endpoint, size, max_packet_size); 260 261 usb_transfer_batch_t *batch = 262 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 263 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 264 if (!batch) 265 return ENOMEM; 324 usb_transfer_batch_t *batch = NULL; 325 hc_t *hc = NULL; 326 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 327 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 328 if (ret != EOK) 329 return ret; 266 330 batch_interrupt_in(batch); 267 const intret = hc_schedule(hc, batch);331 ret = hc_schedule(hc, batch); 268 332 if (ret != EOK) { 269 333 batch_dispose(batch); … … 281 345 * @param[in] fun Device function the action was invoked on. 282 346 * @param[in] target Target pipe (address and endpoint number) specification. 283 * @param[in] max_packet_size Max packet size for the transfer.284 347 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 285 348 * by the caller). … … 290 353 */ 291 354 static int bulk_out( 292 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,355 ddf_fun_t *fun, usb_target_t target, void *data, 293 356 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 294 357 { 295 assert(fun); 296 hc_t *hc = fun_to_hc(fun); 297 assert(hc); 298 usb_speed_t speed = 299 usb_device_keeper_get_speed(&hc->manager, target.address); 300 301 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 302 target.address, target.endpoint, size, max_packet_size); 303 304 usb_transfer_batch_t *batch = 305 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 306 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 307 if (!batch) 308 return ENOMEM; 358 usb_transfer_batch_t *batch = NULL; 359 hc_t *hc = NULL; 360 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 361 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 362 if (ret != EOK) 363 return ret; 309 364 batch_bulk_out(batch); 310 const intret = hc_schedule(hc, batch);365 ret = hc_schedule(hc, batch); 311 366 if (ret != EOK) { 312 367 batch_dispose(batch); … … 324 379 * @param[in] fun Device function the action was invoked on. 325 380 * @param[in] target Target pipe (address and endpoint number) specification. 326 * @param[in] max_packet_size Max packet size for the transfer.327 381 * @param[in] data Buffer where to store the data (in USB endianess, 328 382 * allocated and deallocated by the caller). … … 333 387 */ 334 388 static int bulk_in( 335 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,389 ddf_fun_t *fun, usb_target_t target, void *data, 336 390 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 337 391 { 338 assert(fun); 339 hc_t *hc = fun_to_hc(fun); 340 assert(hc); 341 usb_speed_t speed = 342 usb_device_keeper_get_speed(&hc->manager, target.address); 343 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 344 target.address, target.endpoint, size, max_packet_size); 345 346 usb_transfer_batch_t *batch = 347 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 348 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 349 if (!batch) 350 return ENOMEM; 392 usb_transfer_batch_t *batch = NULL; 393 hc_t *hc = NULL; 394 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 395 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 396 if (ret != EOK) 397 return ret; 351 398 batch_bulk_in(batch); 352 const intret = hc_schedule(hc, batch);399 ret = hc_schedule(hc, batch); 353 400 if (ret != EOK) { 354 401 batch_dispose(batch); … … 366 413 * @param[in] fun Device function the action was invoked on. 367 414 * @param[in] target Target pipe (address and endpoint number) specification. 368 * @param[in] max_packet_size Max packet size for the transfer.369 415 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 370 416 * and deallocated by the caller). … … 378 424 */ 379 425 static int control_write( 380 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,426 ddf_fun_t *fun, usb_target_t target, 381 427 void *setup_data, size_t setup_size, void *data, size_t size, 382 428 usbhc_iface_transfer_out_callback_t callback, void *arg) 383 429 { 384 assert(fun); 385 hc_t *hc = fun_to_hc(fun); 386 assert(hc); 387 usb_speed_t speed = 388 usb_device_keeper_get_speed(&hc->manager, target.address); 389 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 390 speed, target.address, target.endpoint, size, max_packet_size); 391 392 if (setup_size != 8) 393 return EINVAL; 394 395 usb_transfer_batch_t *batch = 396 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 397 speed, data, size, setup_data, setup_size, NULL, callback, arg, 398 &hc->manager); 399 if (!batch) 400 return ENOMEM; 430 usb_transfer_batch_t *batch = NULL; 431 hc_t *hc = NULL; 432 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 433 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 434 &hc, &batch); 435 if (ret != EOK) 436 return ret; 401 437 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 402 438 batch_control_write(batch); 403 const intret = hc_schedule(hc, batch);439 ret = hc_schedule(hc, batch); 404 440 if (ret != EOK) { 405 441 batch_dispose(batch); … … 417 453 * @param[in] fun Device function the action was invoked on. 418 454 * @param[in] target Target pipe (address and endpoint number) specification. 419 * @param[in] max_packet_size Max packet size for the transfer.420 455 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 421 456 * and deallocated by the caller). … … 429 464 */ 430 465 static int control_read( 431 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,466 ddf_fun_t *fun, usb_target_t target, 432 467 void *setup_data, size_t setup_size, void *data, size_t size, 433 468 usbhc_iface_transfer_in_callback_t callback, void *arg) 434 469 { 435 assert(fun); 436 hc_t *hc = fun_to_hc(fun); 437 assert(hc); 438 usb_speed_t speed = 439 usb_device_keeper_get_speed(&hc->manager, target.address); 440 441 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 442 speed, target.address, target.endpoint, size, max_packet_size); 443 usb_transfer_batch_t *batch = 444 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 445 speed, data, size, setup_data, setup_size, callback, NULL, arg, 446 &hc->manager); 447 if (!batch) 448 return ENOMEM; 470 usb_transfer_batch_t *batch = NULL; 471 hc_t *hc = NULL; 472 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 473 setup_data, setup_size, callback, NULL, arg, "Control READ", 474 &hc, &batch); 475 if (ret != EOK) 476 return ret; 449 477 batch_control_read(batch); 450 const intret = hc_schedule(hc, batch);478 ret = hc_schedule(hc, batch); 451 479 if (ret != EOK) { 452 480 batch_dispose(batch); … … 455 483 } 456 484 /*----------------------------------------------------------------------------*/ 457 /** Host controller interface implementation for OHCI. */458 485 usbhc_iface_t hc_iface = { 459 486 .reserve_default_address = reserve_default_address, … … 475 502 .control_read = control_read, 476 503 }; 477 478 504 /** 479 505 * @} -
uspace/drv/ohci/ohci_regs.h
rf35b294 ra43f1d18 41 41 const volatile uint32_t revision; 42 42 volatile uint32_t control; 43 #define C_CSBR_MASK (0x3) 43 #define C_CSBR_MASK (0x3) /* Control-bulk service ratio */ 44 #define C_CSBR_1_1 (0x0) 45 #define C_CSBR_1_2 (0x1) 46 #define C_CSBR_1_3 (0x2) 47 #define C_CSBR_1_4 (0x3) 44 48 #define C_CSBR_SHIFT (0) 45 #define C_PLE (1 << 2) 46 #define C_ IE (1 << 3)47 #define C_ CLE (1 << 4)48 #define C_ BLE (1 << 5)49 50 #define C_HCFS_MASK (0x3) 51 #define C_HCFS_ SHIFT (6)52 #define C_HCFS_RESET (0x0)49 50 #define C_PLE (1 << 2) /* Periodic list enable */ 51 #define C_IE (1 << 3) /* Isochronous enable */ 52 #define C_CLE (1 << 4) /* Control list enable */ 53 #define C_BLE (1 << 5) /* Bulk list enable */ 54 55 #define C_HCFS_MASK (0x3) /* Host controller functional state */ 56 #define C_HCFS_RESET (0x0) 53 57 #define C_HCFS_OPERATIONAL (0x1) 54 #define C_HCFS_RESUME (0x2) 55 #define C_HCFS_SUSPEND (0x3) 56 57 #define C_IR (1 << 8) 58 #define C_RWC (1 << 9) 59 #define C_RWE (1 << 10) 58 #define C_HCFS_RESUME (0x2) 59 #define C_HCFS_SUSPEND (0x3) 60 #define C_HCFS_SHIFT (6) 61 62 #define C_IR (1 << 8) /* Interrupt routing, make sure it's 0 */ 63 #define C_RWC (1 << 9) /* Remote wakeup connected, host specific */ 64 #define C_RWE (1 << 10) /* Remote wakeup enable */ 60 65 61 66 volatile uint32_t command_status; 62 #define CS_HCR (1 << 0) 63 #define CS_CLF (1 << 1) 64 #define CS_BLF (1 << 2) 65 #define CS_OCR (1 << 3) 66 #define CS_SOC_MASK (0x3) 67 #define CS_HCR (1 << 0) /* Host controller reset */ 68 #define CS_CLF (1 << 1) /* Control list filled */ 69 #define CS_BLF (1 << 2) /* Bulk list filled */ 70 #define CS_OCR (1 << 3) /* Ownership change request */ 71 #define CS_SOC_MASK (0x3) /* Scheduling overrun count */ 67 72 #define CS_SOC_SHIFT (16) 68 73 69 74 volatile uint32_t interrupt_status; 70 #define IS_SO (1 << 0) 71 #define IS_WDH (1 << 1) 72 #define IS_SF (1 << 2) 73 #define IS_RD (1 << 3) 74 #define IS_UE (1 << 4) 75 #define IS_FNO (1 << 5) 76 #define IS_RHSC (1 << 6) 77 #define IS_OC (1 << 30) 78 75 #define IS_SO (1 << 0) /* Scheduling overrun */ 76 #define IS_WDH (1 << 1) /* Write-back done head */ 77 #define IS_SF (1 << 2) /* Start of frame */ 78 #define IS_RD (1 << 3) /* Resume detected */ 79 #define IS_UE (1 << 4) /* Unrecoverable error */ 80 #define IS_FNO (1 << 5) /* Frame number overflow */ 81 #define IS_RHSC (1 << 6) /* Root hub status change */ 82 #define IS_OC (1 << 30) /* Ownership change */ 83 84 /** Interupt enable/disable, reads give the same value, writing causes 85 * enable/disable */ 79 86 volatile uint32_t interupt_enable; 80 #define IE_SO (1 << 0)81 #define IE_WDH (1 << 1)82 #define IE_SF (1 << 2)83 #define IE_RD (1 << 3)84 #define IE_UE (1 << 4)85 #define IE_FNO (1 << 5)86 #define IE_RHSC (1 << 6)87 #define IE_OC (1 << 30)88 #define IE_MIE (1 << 31)89 90 87 volatile uint32_t interrupt_disable; 88 #define I_SO (1 << 0) /* Scheduling overrun */ 89 #define I_WDH (1 << 1) /* Done head write-back */ 90 #define I_SF (1 << 2) /* Start of frame */ 91 #define I_RD (1 << 3) /* Resume detect */ 92 #define I_UE (1 << 4) /* Unrecoverable error */ 93 #define I_FNO (1 << 5) /* Frame number overflow */ 94 #define I_RHSC (1 << 6) /* Root hub status change */ 95 #define I_OC (1 << 30) /* Ownership change */ 96 #define I_MI (1 << 31) /* Master interrupt (all/any interrupts) */ 97 98 /** HCCA pointer (see hw_struct hcca.h) */ 91 99 volatile uint32_t hcca; 92 volatile uint32_t period_corrent; 100 #define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */ 101 102 /** Currently executed period endpoint */ 103 const volatile uint32_t period_current; 104 105 /** The first control endpoint */ 93 106 volatile uint32_t control_head; 107 108 /** Currently executed control endpoint */ 94 109 volatile uint32_t control_current; 110 111 /** The first bulk endpoint */ 95 112 volatile uint32_t bulk_head; 113 114 /** Currently executed bulk endpoint */ 96 115 volatile uint32_t bulk_current; 97 volatile uint32_t done_head; 116 117 /** Done TD list, this value is periodically written to HCCA */ 118 const volatile uint32_t done_head; 119 120 /** Frame time and max packet size for all transfers */ 98 121 volatile uint32_t fm_interval; 99 volatile uint32_t fm_remaining; 100 volatile uint32_t fm_number; 122 #define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/ 123 #define FMI_FI_SHIFT (0) 124 #define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */ 125 #define FMI_FSMPS_SHIFT (16) 126 #define FMI_TOGGLE_FLAG (1 << 31) 127 128 /** Bit times remaining in current frame */ 129 const volatile uint32_t fm_remaining; 130 #define FMR_FR_MASK FMI_FI_MASK 131 #define FMR_FR_SHIFT FMI_FI_SHIFT 132 #define FMR_TOGGLE_FLAG FMI_TOGGLE_FLAG 133 134 /** Frame number */ 135 const volatile uint32_t fm_number; 136 #define FMN_NUMBER_MASK (0xffff) 137 138 /** Remaining bit time in frame to start periodic transfers */ 101 139 volatile uint32_t periodic_start; 140 #define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */ 141 142 /** Threshold for starting LS transaction */ 102 143 volatile uint32_t ls_threshold; 144 #define LST_LST_MASK (0x7fff) 145 146 /** The first root hub control register */ 103 147 volatile uint32_t rh_desc_a; 148 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */ 149 #define RHDA_NDS_SHIFT (0) 150 #define RHDA_PSM_FLAG (1 << 8) /* Power switching mode: 0-global, 1-per port*/ 151 #define RHDA_NPS_FLAG (1 << 9) /* No power switch: 1-power on, 0-use PSM*/ 152 #define RHDA_DT_FLAG (1 << 10) /* 1-Compound device, must be 0 */ 153 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */ 154 #define RHDA_NOCP (1 << 12) /* OC control: 0-use OCPM, 1-OC off */ 155 #define RHDA_POTPGT_MASK (0xff) /* Power on to power good time */ 156 #define RHDA_POTPGT_SHIFT (24) 157 158 /** The other root hub control register */ 104 159 volatile uint32_t rh_desc_b; 160 #define RHDB_DR_MASK (0xffff) /* Device removable mask */ 161 #define RHDB_DR_SHIFT (0) 162 #define RHDB_PCC_MASK (0xffff) /* Power control mask */ 163 #define RHDB_PCC_SHIFT (16) 164 165 /* Port device removable status */ 166 #define RHDB_DR_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT) 167 /* Port power control status: 1-per port power control, 0-global power switch */ 168 #define RHDB_PPC_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT) 169 170 /** Root hub status register */ 105 171 volatile uint32_t rh_status; 172 #define RHS_LPS_FLAG (1 << 0)/* read: 0, 173 * write: 0-no effect, 174 * 1-turn off port power for ports 175 * specified in PPCM(RHDB), or all ports, 176 * if power is set globally */ 177 #define RHS_CLEAR_PORT_POWER RHS_LPS_FLAG /* synonym for the above */ 178 #define RHS_OCI_FLAG (1 << 1)/* Over-current indicator, if per-port: 0 */ 179 #define RHS_DRWE_FLAG (1 << 15)/* read: 0-connect status change does not wake HC 180 * 1-connect status change wakes HC 181 * write: 1-set DRWE, 0-no effect */ 182 #define RHS_SET_DRWE RHS_DRWE_FLAG 183 #define RHS_LPSC_FLAG (1 << 16)/* read: 0, 184 * write: 0-no effect 185 * 1-turn on port power for ports 186 * specified in PPCM(RHDB), or all ports, 187 * if power is set globally */ 188 #define RHS_SET_PORT_POWER RHS_LPSC_FLAG /* synonym for the above */ 189 #define RHS_OCIC_FLAG (1 << 17)/* Over-current indicator change */ 190 #define RHS_CLEAR_DRWE (1 << 31) 191 192 /** Root hub per port status */ 106 193 volatile uint32_t rh_port_status[]; 194 #define RHPS_CCS_FLAG (1 << 0) /* r: current connect status, 195 * w: 1-clear port enable, 0-nothing */ 196 #define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG 197 #define RHPS_PES_FLAG (1 << 1) /* r: port enable status 198 * w: 1-set port enable, 0-nothing */ 199 #define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG 200 #define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status 201 * w: 1-set port suspend, 0-nothing */ 202 #define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG 203 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current (if reports are per-port 204 * w: 1-clear port suspend (start resume 205 * if suspened) 206 * 0-nothing */ 207 #define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG 208 #define RHPS_PRS_FLAG (1 << 4) /* r: port reset status 209 * w: 1-set port reset, 0-nothing */ 210 #define RHPS_SET_PORT_RESET RHPS_PRS_FLAG 211 #define RHPS_PPS_FLAG (1 << 8) /* r: port power status 212 * w: 1-set port power, 0-nothing */ 213 #define RHPS_SET_PORT_POWER RHPS_PPS_FLAG 214 #define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached 215 * w: 1-clear port power, 0-nothing */ 216 #define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG 217 #define RHPS_CSC_FLAG (1 << 16) /* connect status change Write-Clean */ 218 #define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */ 219 #define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */ 220 #define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */ 221 #define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */ 222 #define RHPS_CHANGE_WC_MASK 0x1f0000 107 223 } __attribute__((packed)) ohci_regs_t; 108 224 #endif -
uspace/drv/ohci/utils/malloc32.h
rf35b294 ra43f1d18 37 37 #include <assert.h> 38 38 #include <malloc.h> 39 #include <errno.h> 39 40 #include <mem.h> 40 41 #include <as.h> -
uspace/drv/uhci-hcd/batch.c
rf35b294 ra43f1d18 103 103 usb_target_t target = 104 104 { .address = ep->address, .endpoint = ep->endpoint }; 105 usb_transfer_batch_init(instance, target, 106 ep->transfer_type, ep->speed, ep->max_packet_size, 107 buffer, NULL, buffer_size, NULL, setup_size, func_in, 108 func_out, arg, fun, ep, NULL); 105 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 106 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 107 func_in, func_out, arg, fun, ep, NULL); 109 108 110 109 111 110 uhci_batch_t *data = malloc(sizeof(uhci_batch_t)); 112 CHECK_NULL_DISPOSE_RETURN(instance, 113 "Failed to allocate batch instance.\n"); 111 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n"); 114 112 bzero(data, sizeof(uhci_batch_t)); 115 113 instance->private_data = data; -
uspace/drv/uhci-hcd/hc.c
rf35b294 ra43f1d18 240 240 usb_log_debug("Initialized device manager.\n"); 241 241 242 ret = 243 usb_endpoint_manager_init(&instance->ep_manager, 244 BANDWIDTH_AVAILABLE_USB11); 242 ret = usb_endpoint_manager_init(&instance->ep_manager, 243 BANDWIDTH_AVAILABLE_USB11); 245 244 assert(ret == EOK); 246 245 -
uspace/drv/uhci-hcd/iface.c
rf35b294 ra43f1d18 74 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 75 76 assert(ep->speed ==77 usb_device_keeper_get_speed(&(*hc)->manager, target.address));76 // assert(ep->speed == 77 // usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 78 // assert(ep->max_packet_size == max_packet_size); 79 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); … … 198 198 /*----------------------------------------------------------------------------*/ 199 199 static int register_endpoint( 200 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 200 ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed, 201 usb_endpoint_t endpoint, 201 202 usb_transfer_type_t transfer_type, usb_direction_t direction, 202 203 size_t max_packet_size, unsigned int interval) … … 204 205 hc_t *hc = fun_to_hc(fun); 205 206 assert(hc); 206 const usb_speed_t speed = 207 usb_device_keeper_get_speed(&hc->manager, address); 207 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 208 if (speed >= USB_SPEED_MAX) { 209 speed = ep_speed; 210 } 208 211 const size_t size = 209 212 (transfer_type == USB_TRANSFER_INTERRUPT … … 243 246 usb_log_debug("Unregister endpoint %d:%d %d.\n", 244 247 address, endpoint, direction); 248 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 249 address, endpoint, direction, NULL); 250 if (ep != NULL) { 251 usb_device_keeper_del_ep(&hc->manager, address, ep); 252 } 245 253 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 246 254 endpoint, direction); … … 251 259 * @param[in] fun DDF function that was called. 252 260 * @param[in] target USB device to write to. 253 * @param[in] max_packet_size maximum size of data packet the device accepts254 261 * @param[in] data Source of data. 255 262 * @param[in] size Size of data source. … … 259 266 */ 260 267 static int interrupt_out( 261 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,268 ddf_fun_t *fun, usb_target_t target, void *data, 262 269 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 263 270 { … … 280 287 * @param[in] fun DDF function that was called. 281 288 * @param[in] target USB device to write to. 282 * @param[in] max_packet_size maximum size of data packet the device accepts283 289 * @param[out] data Data destination. 284 290 * @param[in] size Size of data source. … … 288 294 */ 289 295 static int interrupt_in( 290 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,296 ddf_fun_t *fun, usb_target_t target, void *data, 291 297 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 292 298 { … … 309 315 * @param[in] fun DDF function that was called. 310 316 * @param[in] target USB device to write to. 311 * @param[in] max_packet_size maximum size of data packet the device accepts312 317 * @param[in] data Source of data. 313 318 * @param[in] size Size of data source. … … 317 322 */ 318 323 static int bulk_out( 319 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,324 ddf_fun_t *fun, usb_target_t target, void *data, 320 325 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 321 326 { … … 338 343 * @param[in] fun DDF function that was called. 339 344 * @param[in] target USB device to write to. 340 * @param[in] max_packet_size maximum size of data packet the device accepts341 345 * @param[out] data Data destination. 342 346 * @param[in] size Size of data source. … … 346 350 */ 347 351 static int bulk_in( 348 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,352 ddf_fun_t *fun, usb_target_t target, void *data, 349 353 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 350 354 { … … 367 371 * @param[in] fun DDF function that was called. 368 372 * @param[in] target USB device to write to. 369 * @param[in] max_packet_size maximum size of data packet the device accepts.370 373 * @param[in] setup_data Data to send with SETUP transfer. 371 374 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B). … … 377 380 */ 378 381 static int control_write( 379 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,382 ddf_fun_t *fun, usb_target_t target, 380 383 void *setup_data, size_t setup_size, void *data, size_t size, 381 384 usbhc_iface_transfer_out_callback_t callback, void *arg) … … 401 404 * @param[in] fun DDF function that was called. 402 405 * @param[in] target USB device to write to. 403 * @param[in] max_packet_size maximum size of data packet the device accepts.404 406 * @param[in] setup_data Data to send with SETUP packet. 405 407 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B). … … 411 413 */ 412 414 static int control_read( 413 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,415 ddf_fun_t *fun, usb_target_t target, 414 416 void *setup_data, size_t setup_size, void *data, size_t size, 415 417 usbhc_iface_transfer_in_callback_t callback, void *arg) -
uspace/drv/usbmid/main.c
rf35b294 ra43f1d18 55 55 int rc; 56 56 57 rc = usb_pipe_start_ session(&dev->ctrl_pipe);57 rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe); 58 58 if (rc != EOK) { 59 usb_log_error("Failed to start sessionon control pipe: %s.\n",59 usb_log_error("Failed to start transfer on control pipe: %s.\n", 60 60 str_error(rc)); 61 61 return rc; … … 64 64 bool accept = usbmid_explore_device(dev); 65 65 66 rc = usb_pipe_end_session(&dev->ctrl_pipe); 67 if (rc != EOK) { 68 usb_log_warning("Failed to end session on control pipe: %s.\n", 69 str_error(rc)); 70 } 66 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 71 67 72 68 if (!accept) { -
uspace/drv/vhc/connhost.c
rf35b294 ra43f1d18 257 257 258 258 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 259 size_t max_packet_size,260 259 void *data, size_t size, 261 260 usbhc_iface_transfer_out_callback_t callback, void *arg) … … 267 266 268 267 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 269 size_t max_packet_size,270 268 void *data, size_t size, 271 269 usbhc_iface_transfer_in_callback_t callback, void *arg) … … 277 275 278 276 static int control_write(ddf_fun_t *fun, usb_target_t target, 279 size_t max_packet_size,280 277 void *setup_packet, size_t setup_packet_size, 281 278 void *data, size_t data_size, … … 295 292 296 293 static int control_read(ddf_fun_t *fun, usb_target_t target, 297 size_t max_packet_size,298 294 void *setup_packet, size_t setup_packet_size, 299 295 void *data, size_t data_size, -
uspace/lib/drv/generic/remote_usbhc.c
rf35b294 ra43f1d18 270 270 } 271 271 272 size_t max_packet_size = DEV_IPC_GET_ARG3(*call);273 272 usb_target_t target = { 274 273 .address = DEV_IPC_GET_ARG1(*call), … … 300 299 trans->size = len; 301 300 302 rc = transfer_func(fun, target, max_packet_size,301 rc = transfer_func(fun, target, 303 302 buffer, len, 304 303 callback_out, trans); … … 326 325 } 327 326 328 size_t max_packet_size = DEV_IPC_GET_ARG3(*call);329 327 usb_target_t target = { 330 328 .address = DEV_IPC_GET_ARG1(*call), … … 348 346 trans->size = len; 349 347 350 int rc = transfer_func(fun, target, max_packet_size,348 int rc = transfer_func(fun, target, 351 349 trans->buffer, len, 352 350 callback_in, trans); … … 414 412 }; 415 413 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 416 size_t max_packet_size = DEV_IPC_GET_ARG4(*call);417 414 418 415 int rc; … … 450 447 trans->size = data_buffer_len; 451 448 452 rc = usb_iface->control_write(fun, target, max_packet_size,449 rc = usb_iface->control_write(fun, target, 453 450 setup_packet, setup_packet_len, 454 451 data_buffer, data_buffer_len, … … 477 474 .endpoint = DEV_IPC_GET_ARG2(*call) 478 475 }; 479 size_t max_packet_size = DEV_IPC_GET_ARG3(*call);480 476 481 477 int rc; … … 515 511 } 516 512 517 rc = usb_iface->control_read(fun, target, max_packet_size,513 rc = usb_iface->control_read(fun, target, 518 514 setup_packet, setup_packet_len, 519 515 trans->buffer, trans->size, … … 537 533 } 538 534 539 #define INIT_FROM_HIGH_DATA(type, var, arg_no) \ 540 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256 541 #define INIT_FROM_LOW_DATA(type, var, arg_no) \ 542 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256 543 544 INIT_FROM_HIGH_DATA(usb_address_t, address, 1); 545 INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1); 546 INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2); 547 INIT_FROM_LOW_DATA(usb_direction_t, direction, 2); 548 549 #undef INIT_FROM_HIGH_DATA 550 #undef INIT_FROM_LOW_DATA 551 552 size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call); 553 unsigned int interval = (unsigned int) DEV_IPC_GET_ARG4(*call); 554 555 int rc = usb_iface->register_endpoint(fun, address, endpoint, 535 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \ 536 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16) 537 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \ 538 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 16) 539 #define _INIT_FROM_HIGH_DATA3(type, var, arg_no) \ 540 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16) 541 #define _INIT_FROM_MIDDLE_DATA3(type, var, arg_no) \ 542 type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) / (1 << 8)) % (1 << 8) 543 #define _INIT_FROM_LOW_DATA3(type, var, arg_no) \ 544 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 8) 545 546 _INIT_FROM_HIGH_DATA2(usb_address_t, address, 1); 547 _INIT_FROM_LOW_DATA2(usb_endpoint_t, endpoint, 1); 548 549 _INIT_FROM_HIGH_DATA3(usb_speed_t, speed, 2); 550 _INIT_FROM_MIDDLE_DATA3(usb_transfer_type_t, transfer_type, 2); 551 _INIT_FROM_LOW_DATA3(usb_direction_t, direction, 2); 552 553 _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3); 554 _INIT_FROM_LOW_DATA2(unsigned int, interval, 3); 555 556 #undef _INIT_FROM_HIGH_DATA2 557 #undef _INIT_FROM_LOW_DATA2 558 #undef _INIT_FROM_HIGH_DATA3 559 #undef _INIT_FROM_MIDDLE_DATA3 560 #undef _INIT_FROM_LOW_DATA3 561 562 int rc = usb_iface->register_endpoint(fun, address, speed, endpoint, 556 563 transfer_type, direction, max_packet_size, interval); 557 564 -
uspace/lib/drv/include/usbhc_iface.h
rf35b294 ra43f1d18 66 66 * - argument #1 is target address 67 67 * - argument #2 is target endpoint 68 * - argument #3 is max packet size of the endpoint69 68 * - this call is immediately followed by IPC data read (async version) 70 69 * - the call is not answered until the device returns some data (or until … … 169 168 /** Register endpoint attributes at host controller. 170 169 * This is used to reserve portion of USB bandwidth. 170 * When speed is invalid, speed of the device is used. 171 171 * Parameters: 172 * - USB address + endpoint number (ADDR * 256 + EP) 173 * - transfer type + direction (TYPE * 256 + DIR) 174 * - maximum packet size 175 * - interval (in milliseconds) 172 * - USB address + endpoint number 173 * - packed as ADDR << 16 + EP 174 * - speed + transfer type + direction 175 * - packed as ( SPEED << 8 + TYPE ) << 8 + DIR 176 * - maximum packet size + interval (in milliseconds) 177 * - packed as MPS << 16 + INT 176 178 * Answer: 177 179 * - EOK - reservation successful … … 202 204 203 205 /** Out transfer processing function prototype. */ 204 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,206 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, 205 207 void *, size_t, 206 208 usbhc_iface_transfer_out_callback_t, void *); … … 210 212 211 213 /** In transfer processing function prototype. */ 212 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,214 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, 213 215 void *, size_t, 214 216 usbhc_iface_transfer_in_callback_t, void *); … … 222 224 int (*release_address)(ddf_fun_t *, usb_address_t); 223 225 224 int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t, 226 int (*register_endpoint)(ddf_fun_t *, 227 usb_address_t, usb_speed_t, usb_endpoint_t, 225 228 usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 226 229 int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t, … … 234 237 235 238 int (*control_write)(ddf_fun_t *, usb_target_t, 236 size_t,237 239 void *, size_t, void *, size_t, 238 240 usbhc_iface_transfer_out_callback_t, void *); 239 241 240 242 int (*control_read)(ddf_fun_t *, usb_target_t, 241 size_t,242 243 void *, size_t, void *, size_t, 243 244 usbhc_iface_transfer_in_callback_t, void *); -
uspace/lib/usb/Makefile
rf35b294 ra43f1d18 43 43 src/hidparser.c \ 44 44 src/hub.c \ 45 src/pipepriv.c \ 45 46 src/pipes.c \ 46 47 src/pipesinit.c \ -
uspace/lib/usb/include/usb/devdrv.h
rf35b294 ra43f1d18 169 169 usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *); 170 170 171 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *); 172 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *, 173 usb_endpoint_description_t **, uint8_t *, size_t, int, int, 174 usb_endpoint_mapping_t **, size_t *); 175 int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t); 176 177 size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t); 178 171 179 #endif 172 180 /** -
uspace/lib/usb/include/usb/host/device_keeper.h
rf35b294 ra43f1d18 73 73 void usb_device_keeper_add_ep( 74 74 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep); 75 void usb_device_keeper_del_ep( 76 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep); 75 77 76 78 void usb_device_keeper_reserve_default_address( -
uspace/lib/usb/include/usb/pipes.h
rf35b294 ra43f1d18 42 42 #include <ipc/devman.h> 43 43 #include <ddf/driver.h> 44 #include <fibril_synch.h> 44 45 45 46 /** Abstraction of a physical connection to the device. … … 59 60 * This endpoint must be bound with existing usb_device_connection_t 60 61 * (i.e. the wire to send data over). 62 * 63 * Locking order: if you want to lock both mutexes 64 * (@c guard and @c hc_phone_mutex), lock @c guard first. 65 * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex 66 * only. 61 67 */ 62 68 typedef struct { 69 /** Guard of the whole pipe. */ 70 fibril_mutex_t guard; 71 63 72 /** The connection used for sending the data. */ 64 73 usb_device_connection_t *wire; … … 78 87 /** Phone to the host controller. 79 88 * Negative when no session is active. 89 * It is an error to access this member without @c hc_phone_mutex 90 * being locked. 91 * If call over the phone is to be made, it must be preceeded by 92 * call to pipe_add_ref() [internal libusb function]. 80 93 */ 81 94 int hc_phone; 95 96 /** Guard for serialization of requests over the phone. */ 97 fibril_mutex_t hc_phone_mutex; 98 99 /** Number of active transfers over the pipe. */ 100 int refcount; 82 101 } usb_pipe_t; 83 102 … … 134 153 int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 135 154 size_t, uint8_t *, size_t, usb_device_connection_t *); 155 int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t, 156 unsigned int, usb_hc_connection_t *); 136 157 int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *); 137 158 int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *); … … 140 161 int usb_pipe_end_session(usb_pipe_t *); 141 162 bool usb_pipe_is_session_started(usb_pipe_t *); 163 164 int usb_pipe_start_long_transfer(usb_pipe_t *); 165 void usb_pipe_end_long_transfer(usb_pipe_t *); 142 166 143 167 int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *); -
uspace/lib/usb/include/usb/usb.h
rf35b294 ra43f1d18 77 77 USB_SPEED_FULL, 78 78 /** USB 2.0 high speed (480Mbits/s). */ 79 USB_SPEED_HIGH 79 USB_SPEED_HIGH, 80 /** Psuedo-speed serving as a boundary. */ 81 USB_SPEED_MAX 80 82 } usb_speed_t; 81 83 -
uspace/lib/usb/src/devdrv.c
rf35b294 ra43f1d18 72 72 } 73 73 74 /** Log out of memory error on given device.75 *76 * @param dev Device causing the trouble.77 */78 static void usb_log_oom(ddf_dev_t *dev)79 {80 usb_log_error("Out of memory when adding device `%s'.\n",81 dev->name);82 }83 84 74 /** Count number of pipes the driver expects. 85 75 * … … 108 98 */ 109 99 static int initialize_other_pipes(usb_endpoint_description_t **endpoints, 110 usb_device_t *dev) 111 { 112 int rc; 113 114 size_t pipe_count = count_other_pipes(endpoints); 115 if (pipe_count == 0) { 116 return EOK; 117 } 118 119 dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count); 120 if (dev->pipes == NULL) { 121 usb_log_oom(dev->ddf_dev); 122 return ENOMEM; 123 } 124 125 size_t i; 126 127 /* Initialize to NULL first for rollback purposes. */ 128 for (i = 0; i < pipe_count; i++) { 129 dev->pipes[i].pipe = NULL; 130 } 131 132 for (i = 0; i < pipe_count; i++) { 133 dev->pipes[i].pipe = malloc(sizeof(usb_pipe_t)); 134 if (dev->pipes[i].pipe == NULL) { 135 usb_log_oom(dev->ddf_dev); 136 rc = ENOMEM; 137 goto rollback; 138 } 139 140 dev->pipes[i].description = endpoints[i]; 141 dev->pipes[i].interface_no = dev->interface_no; 142 dev->pipes[i].interface_setting = 0; 143 } 144 145 rc = usb_pipe_initialize_from_configuration(dev->pipes, pipe_count, 100 usb_device_t *dev, int alternate_setting) 101 { 102 usb_endpoint_mapping_t *pipes; 103 size_t pipes_count; 104 105 int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints, 146 106 dev->descriptors.configuration, dev->descriptors.configuration_size, 147 &dev->wire); 148 if (rc != EOK) { 149 usb_log_error("Failed initializing USB endpoints: %s.\n", 150 str_error(rc)); 151 goto rollback; 152 } 153 154 /* Register the endpoints. */ 155 usb_hc_connection_t hc_conn; 156 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev); 107 dev->interface_no, alternate_setting, 108 &pipes, &pipes_count); 109 157 110 if (rc != EOK) { 158 111 usb_log_error( 159 "Failed initializing connection to host controller: %s.\n", 160 str_error(rc)); 161 goto rollback; 162 } 163 rc = usb_hc_connection_open(&hc_conn); 164 if (rc != EOK) { 165 usb_log_error("Failed to connect to host controller: %s.\n", 166 str_error(rc)); 167 goto rollback; 168 } 169 for (i = 0; i < pipe_count; i++) { 170 if (dev->pipes[i].present) { 171 rc = usb_pipe_register(dev->pipes[i].pipe, 172 dev->pipes[i].descriptor->poll_interval, 173 &hc_conn); 174 /* Ignore error when operation not supported by HC. */ 175 if ((rc != EOK) && (rc != ENOTSUP)) { 176 /* FIXME: what shall we do? */ 177 dev->pipes[i].present = false; 178 free(dev->pipes[i].pipe); 179 dev->pipes[i].pipe = NULL; 180 } 181 } 182 } 183 /* Ignoring errors here. */ 184 usb_hc_connection_close(&hc_conn); 185 186 dev->pipes_count = pipe_count; 112 "Failed to create endpoint pipes for `%s': %s.\n", 113 dev->ddf_dev->name, str_error(rc)); 114 return rc; 115 } 116 117 dev->pipes = pipes; 118 dev->pipes_count = pipes_count; 187 119 188 120 return EOK; 189 190 rollback:191 for (i = 0; i < pipe_count; i++) {192 if (dev->pipes[i].pipe != NULL) {193 free(dev->pipes[i].pipe);194 }195 }196 free(dev->pipes);197 198 return rc;199 121 } 200 122 … … 239 161 240 162 /* 241 * For further actions, we need open session on default control pipe. 163 * We will do some querying of the device, it is worth to prepare 164 * the long transfer. 242 165 */ 243 rc = usb_pipe_start_ session(&dev->ctrl_pipe);244 if (rc != EOK) { 245 usb_log_error("Failed to start an IPC session: %s.\n",166 rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe); 167 if (rc != EOK) { 168 usb_log_error("Failed to start transfer: %s.\n", 246 169 str_error(rc)); 247 170 return rc; 248 171 } 249 172 250 /* Get the device descriptor. */ 251 rc = usb_request_get_device_descriptor(&dev->ctrl_pipe, 252 &dev->descriptors.device); 253 if (rc != EOK) { 254 usb_log_error("Failed to retrieve device descriptor: %s.\n", 255 str_error(rc)); 256 return rc; 257 } 258 259 /* Get the full configuration descriptor. */ 260 rc = usb_request_get_full_configuration_descriptor_alloc( 261 &dev->ctrl_pipe, 0, (void **) &dev->descriptors.configuration, 262 &dev->descriptors.configuration_size); 263 if (rc != EOK) { 264 usb_log_error("Failed retrieving configuration descriptor: %s. %s\n", 173 /* Retrieve the descriptors. */ 174 rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe, 175 &dev->descriptors); 176 if (rc != EOK) { 177 usb_log_error("Failed to retrieve standard device " \ 178 "descriptors of %s: %s.\n", 265 179 dev->ddf_dev->name, str_error(rc)); 266 180 return rc; 267 181 } 268 182 183 269 184 if (driver->endpoints != NULL) { 270 rc = initialize_other_pipes(driver->endpoints, dev); 271 } 272 273 /* No checking here. */ 274 usb_pipe_end_session(&dev->ctrl_pipe); 185 rc = initialize_other_pipes(driver->endpoints, dev, 0); 186 } 187 188 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 275 189 276 190 /* Rollback actions. */ … … 291 205 * @return Number of alternate interfaces for @p interface_no interface. 292 206 */ 293 s tatic size_t count_alternate_interfaces(uint8_t *config_descr,294 size_t config_descr_size, int interface_no)207 size_t usb_interface_count_alternates(uint8_t *config_descr, 208 size_t config_descr_size, uint8_t interface_no) 295 209 { 296 210 assert(config_descr != NULL); 211 assert(config_descr_size > 0); 212 297 213 usb_dp_parser_t dp_parser = { 298 214 .nesting = usb_dp_standard_descriptor_nesting … … 343 259 344 260 alternates->alternative_count 345 = count_alternate_interfaces(dev->descriptors.configuration,261 = usb_interface_count_alternates(dev->descriptors.configuration, 346 262 dev->descriptors.configuration_size, dev->interface_no); 347 263 … … 457 373 static int destroy_current_pipes(usb_device_t *dev) 458 374 { 459 size_t i; 460 int rc; 461 462 /* TODO: this shall be done under some device mutex. */ 463 464 /* First check that no session is opened. */ 465 for (i = 0; i < dev->pipes_count; i++) { 466 if (usb_pipe_is_session_started(dev->pipes[i].pipe)) { 467 return EBUSY; 468 } 469 } 470 471 /* Prepare connection to HC. */ 472 usb_hc_connection_t hc_conn; 473 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev); 474 if (rc != EOK) { 475 return rc; 476 } 477 rc = usb_hc_connection_open(&hc_conn); 478 if (rc != EOK) { 479 return rc; 480 } 481 482 /* Destroy the pipes. */ 483 for (i = 0; i < dev->pipes_count; i++) { 484 usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn); 485 free(dev->pipes[i].pipe); 486 } 487 488 usb_hc_connection_close(&hc_conn); 489 490 free(dev->pipes); 375 int rc = usb_device_destroy_pipes(dev->ddf_dev, 376 dev->pipes, dev->pipes_count); 377 if (rc != EOK) { 378 return rc; 379 } 380 491 381 dev->pipes = NULL; 492 382 dev->pipes_count = 0; … … 535 425 536 426 /* Create new pipes. */ 537 rc = initialize_other_pipes(endpoints, dev );427 rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting); 538 428 539 429 return rc; 430 } 431 432 /** Retrieve basic descriptors from the device. 433 * 434 * @param[in] ctrl_pipe Control pipe with opened session. 435 * @param[out] descriptors Where to store the descriptors. 436 * @return Error code. 437 */ 438 int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe, 439 usb_device_descriptors_t *descriptors) 440 { 441 assert(descriptors != NULL); 442 assert(usb_pipe_is_session_started(ctrl_pipe)); 443 444 descriptors->configuration = NULL; 445 446 int rc; 447 448 /* Get the device descriptor. */ 449 rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device); 450 if (rc != EOK) { 451 return rc; 452 } 453 454 /* Get the full configuration descriptor. */ 455 rc = usb_request_get_full_configuration_descriptor_alloc( 456 ctrl_pipe, 0, (void **) &descriptors->configuration, 457 &descriptors->configuration_size); 458 if (rc != EOK) { 459 return rc; 460 } 461 462 return EOK; 463 } 464 465 /** Create pipes for a device. 466 * 467 * This is more or less a wrapper that does following actions: 468 * - allocate and initialize pipes 469 * - map endpoints to the pipes based on the descriptions 470 * - registers endpoints with the host controller 471 * 472 * @param[in] dev Generic DDF device backing the USB one. 473 * @param[in] wire Initialized backing connection to the host controller. 474 * @param[in] endpoints Endpoints description, NULL terminated. 475 * @param[in] config_descr Configuration descriptor of active configuration. 476 * @param[in] config_descr_size Size of @p config_descr in bytes. 477 * @param[in] interface_no Interface to map from. 478 * @param[in] interface_setting Interface setting (default is usually 0). 479 * @param[out] pipes_ptr Where to store array of created pipes 480 * (not NULL terminated). 481 * @param[out] pipes_count_ptr Where to store number of pipes 482 * (set to if you wish to ignore the count). 483 * @return Error code. 484 */ 485 int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire, 486 usb_endpoint_description_t **endpoints, 487 uint8_t *config_descr, size_t config_descr_size, 488 int interface_no, int interface_setting, 489 usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr) 490 { 491 assert(dev != NULL); 492 assert(wire != NULL); 493 assert(endpoints != NULL); 494 assert(config_descr != NULL); 495 assert(config_descr_size > 0); 496 assert(pipes_ptr != NULL); 497 498 size_t i; 499 int rc; 500 501 size_t pipe_count = count_other_pipes(endpoints); 502 if (pipe_count == 0) { 503 *pipes_ptr = NULL; 504 return EOK; 505 } 506 507 usb_endpoint_mapping_t *pipes 508 = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count); 509 if (pipes == NULL) { 510 return ENOMEM; 511 } 512 513 /* Initialize to NULL to allow smooth rollback. */ 514 for (i = 0; i < pipe_count; i++) { 515 pipes[i].pipe = NULL; 516 } 517 518 /* Now allocate and fully initialize. */ 519 for (i = 0; i < pipe_count; i++) { 520 pipes[i].pipe = malloc(sizeof(usb_pipe_t)); 521 if (pipes[i].pipe == NULL) { 522 rc = ENOMEM; 523 goto rollback_free_only; 524 } 525 pipes[i].description = endpoints[i]; 526 pipes[i].interface_no = interface_no; 527 pipes[i].interface_setting = interface_setting; 528 } 529 530 /* Find the mapping from configuration descriptor. */ 531 rc = usb_pipe_initialize_from_configuration(pipes, pipe_count, 532 config_descr, config_descr_size, wire); 533 if (rc != EOK) { 534 goto rollback_free_only; 535 } 536 537 /* Register the endpoints with HC. */ 538 usb_hc_connection_t hc_conn; 539 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev); 540 if (rc != EOK) { 541 goto rollback_free_only; 542 } 543 544 rc = usb_hc_connection_open(&hc_conn); 545 if (rc != EOK) { 546 goto rollback_free_only; 547 } 548 549 for (i = 0; i < pipe_count; i++) { 550 if (pipes[i].present) { 551 rc = usb_pipe_register(pipes[i].pipe, 552 pipes[i].descriptor->poll_interval, &hc_conn); 553 if (rc != EOK) { 554 goto rollback_unregister_endpoints; 555 } 556 } 557 } 558 559 usb_hc_connection_close(&hc_conn); 560 561 *pipes_ptr = pipes; 562 if (pipes_count_ptr != NULL) { 563 *pipes_count_ptr = pipe_count; 564 } 565 566 return EOK; 567 568 /* 569 * Jump here if something went wrong after endpoints have 570 * been registered. 571 * This is also the target when the registration of 572 * endpoints fails. 573 */ 574 rollback_unregister_endpoints: 575 for (i = 0; i < pipe_count; i++) { 576 if (pipes[i].present) { 577 usb_pipe_unregister(pipes[i].pipe, &hc_conn); 578 } 579 } 580 581 usb_hc_connection_close(&hc_conn); 582 583 /* 584 * Jump here if something went wrong before some actual communication 585 * with HC. Then the only thing that needs to be done is to free 586 * allocated memory. 587 */ 588 rollback_free_only: 589 for (i = 0; i < pipe_count; i++) { 590 if (pipes[i].pipe != NULL) { 591 free(pipes[i].pipe); 592 } 593 } 594 free(pipes); 595 596 return rc; 597 } 598 599 /** Destroy pipes previously created by usb_device_create_pipes. 600 * 601 * @param[in] dev Generic DDF device backing the USB one. 602 * @param[in] pipes Endpoint mapping to be destroyed. 603 * @param[in] pipes_count Number of endpoints. 604 */ 605 int usb_device_destroy_pipes(ddf_dev_t *dev, 606 usb_endpoint_mapping_t *pipes, size_t pipes_count) 607 { 608 assert(dev != NULL); 609 assert(((pipes != NULL) && (pipes_count > 0)) 610 || ((pipes == NULL) && (pipes_count == 0))); 611 612 if (pipes_count == 0) { 613 return EOK; 614 } 615 616 int rc; 617 618 /* Prepare connection to HC to allow endpoint unregistering. */ 619 usb_hc_connection_t hc_conn; 620 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev); 621 if (rc != EOK) { 622 return rc; 623 } 624 rc = usb_hc_connection_open(&hc_conn); 625 if (rc != EOK) { 626 return rc; 627 } 628 629 /* Destroy the pipes. */ 630 size_t i; 631 for (i = 0; i < pipes_count; i++) { 632 usb_pipe_unregister(pipes[i].pipe, &hc_conn); 633 free(pipes[i].pipe); 634 } 635 636 usb_hc_connection_close(&hc_conn); 637 638 free(pipes); 639 640 return EOK; 540 641 } 541 642 -
uspace/lib/usb/src/devpoll.c
rf35b294 ra43f1d18 77 77 int rc; 78 78 79 rc = usb_pipe_start_session(pipe);80 if (rc != EOK) {81 failed_attempts++;82 continue;83 }84 85 79 size_t actual_size; 86 80 rc = usb_pipe_read(pipe, polling_data->buffer, 87 81 polling_data->request_size, &actual_size); 88 82 89 /* Quit the session regardless of errors. */90 usb_pipe_end_session(pipe);91 83 92 84 // if (rc == ESTALL) { -
uspace/lib/usb/src/host/batch.c
rf35b294 ra43f1d18 63 63 instance->transfer_type = transfer_type; 64 64 instance->speed = speed; 65 instance->direction = USB_DIRECTION_BOTH;65 instance->direction = ep->direction; 66 66 instance->callback_in = func_in; 67 67 instance->callback_out = func_out; -
uspace/lib/usb/src/host/device_keeper.c
rf35b294 ra43f1d18 56 56 instance->devices[i].control_used = 0; 57 57 instance->devices[i].handle = 0; 58 instance->devices[i].speed = USB_SPEED_MAX; 58 59 list_initialize(&instance->devices[i].endpoints); 59 60 } 61 // TODO: is this hack enough? 62 // (it is needed to allow smooth registration at default address) 63 instance->devices[0].occupied = true; 60 64 } 61 65 /*----------------------------------------------------------------------------*/ … … 67 71 assert(instance->devices[address].occupied); 68 72 list_append(&ep->same_device_eps, &instance->devices[address].endpoints); 73 fibril_mutex_unlock(&instance->guard); 74 } 75 /*----------------------------------------------------------------------------*/ 76 void usb_device_keeper_del_ep( 77 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep) 78 { 79 assert(instance); 80 fibril_mutex_lock(&instance->guard); 81 assert(instance->devices[address].occupied); 82 list_remove(&ep->same_device_eps); 83 list_initialize(&ep->same_device_eps); 69 84 fibril_mutex_unlock(&instance->guard); 70 85 } -
uspace/lib/usb/src/hub.c
rf35b294 ra43f1d18 40 40 #include <errno.h> 41 41 #include <assert.h> 42 #include <usb/debug.h> 42 43 43 44 /** Check that HC connection is alright. … … 55 56 56 57 /** Tell host controller to reserve default address. 58 * @deprecated 57 59 * 58 60 * @param connection Opened connection to host controller. … … 65 67 CHECK_CONNECTION(connection); 66 68 69 usb_log_warning("usb_hc_reserve_default_address() considered obsolete"); 70 67 71 return async_req_2_0(connection->hc_phone, 68 72 DEV_IFACE_ID(USBHC_DEV_IFACE), … … 71 75 72 76 /** Tell host controller to release default address. 77 * @deprecated 73 78 * 74 79 * @param connection Opened connection to host controller. … … 78 83 { 79 84 CHECK_CONNECTION(connection); 85 86 usb_log_warning("usb_hc_release_default_address() considered obsolete"); 80 87 81 88 return async_req_1_0(connection->hc_phone, … … 235 242 } 236 243 237 238 /* 239 * Reserve the default address. 240 */ 241 rc = usb_hc_reserve_default_address(&hc_conn, dev_speed); 242 if (rc != EOK) { 243 rc = EBUSY; 244 goto leave_release_free_address; 245 } 246 247 /* 248 * Enable the port (i.e. allow signaling through this port). 249 */ 250 rc = enable_port(port_no, arg); 251 if (rc != EOK) { 252 goto leave_release_default_address; 253 } 254 255 /* 256 * Change the address from default to the free one. 257 * We need to create a new control pipe for that. 244 /* 245 * We will not register control pipe on default address. 246 * The registration might fail. That means that someone else already 247 * registered that endpoint. We will simply wait and try again. 248 * (Someone else already wants to add a new device.) 258 249 */ 259 250 usb_device_connection_t dev_conn; … … 262 253 if (rc != EOK) { 263 254 rc = ENOTCONN; 264 goto leave_release_ default_address;255 goto leave_release_free_address; 265 256 } 266 257 … … 270 261 if (rc != EOK) { 271 262 rc = ENOTCONN; 263 goto leave_release_free_address; 264 } 265 266 do { 267 rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0, 268 &hc_conn); 269 if (rc != EOK) { 270 /* Do not overheat the CPU ;-). */ 271 async_usleep(10); 272 } 273 } while (rc != EOK); 274 275 /* 276 * Endpoint is registered. We can enable the port and change 277 * device address. 278 */ 279 rc = enable_port(port_no, arg); 280 if (rc != EOK) { 272 281 goto leave_release_default_address; 273 282 } 274 283 275 /* Before sending any traffic, we need to register this 276 * endpoint. 284 rc = usb_pipe_probe_default_control(&ctrl_pipe); 285 if (rc != EOK) { 286 rc = ESTALL; 287 goto leave_release_default_address; 288 } 289 290 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 291 if (rc != EOK) { 292 rc = ESTALL; 293 goto leave_release_default_address; 294 } 295 296 /* 297 * Address changed. We can release the original endpoint, thus 298 * allowing other to access the default address. 299 */ 300 unregister_control_endpoint_on_default_address(&hc_conn); 301 302 /* 303 * Time to register the new endpoint. 277 304 */ 278 305 rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn); 279 306 if (rc != EOK) { 280 rc = EREFUSED; 281 goto leave_release_default_address; 282 } 283 rc = usb_pipe_probe_default_control(&ctrl_pipe); 284 if (rc != EOK) { 285 rc = ENOTCONN; 286 goto leave_release_default_address; 287 } 288 289 rc = usb_pipe_start_session(&ctrl_pipe); 290 if (rc != EOK) { 291 rc = ENOTCONN; 292 goto leave_unregister_endpoint; 293 } 294 295 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 296 if (rc != EOK) { 297 rc = ESTALL; 298 goto leave_stop_session; 299 } 300 301 usb_pipe_end_session(&ctrl_pipe); 302 303 /* 304 * Register the control endpoint for the new device. 305 */ 306 rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn); 307 if (rc != EOK) { 308 rc = EREFUSED; 309 goto leave_unregister_endpoint; 310 } 311 312 /* 313 * Release the original endpoint. 314 */ 315 unregister_control_endpoint_on_default_address(&hc_conn); 316 317 /* 318 * Once the address is changed, we can return the default address. 319 */ 320 usb_hc_release_default_address(&hc_conn); 321 307 goto leave_release_free_address; 308 } 322 309 323 310 /* … … 334 321 } 335 322 336 337 338 323 /* 339 324 * And now inform the host controller about the handle. … … 367 352 * Completely ignoring errors here. 368 353 */ 369 370 leave_stop_session: 371 usb_pipe_end_session(&ctrl_pipe); 372 373 leave_unregister_endpoint: 354 leave_release_default_address: 374 355 usb_pipe_unregister(&ctrl_pipe, &hc_conn); 375 376 leave_release_default_address:377 usb_hc_release_default_address(&hc_conn);378 356 379 357 leave_release_free_address: -
uspace/lib/usb/src/pipes.c
rf35b294 ra43f1d18 41 41 #include <errno.h> 42 42 #include <assert.h> 43 #include "pipepriv.h" 43 44 44 45 #define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */ … … 241 242 * necessary. 242 243 * 244 * @deprecated 245 * Obsoleted with introduction of usb_pipe_start_long_transfer 246 * 243 247 * @param pipe Endpoint pipe to start the session on. 244 248 * @return Error code. … … 246 250 int usb_pipe_start_session(usb_pipe_t *pipe) 247 251 { 248 assert(pipe); 249 250 if (usb_pipe_is_session_started(pipe)) { 251 return EBUSY; 252 } 253 254 int phone = devman_device_connect(pipe->wire->hc_handle, 0); 255 if (phone < 0) { 256 return phone; 257 } 258 259 pipe->hc_phone = phone; 260 252 usb_log_warning("usb_pipe_start_session() was deprecated.\n"); 261 253 return EOK; 262 254 } … … 265 257 /** Ends a session on the endpoint pipe. 266 258 * 259 * @deprecated 260 * Obsoleted with introduction of usb_pipe_end_long_transfer 261 * 267 262 * @see usb_pipe_start_session 268 263 * … … 272 267 int usb_pipe_end_session(usb_pipe_t *pipe) 273 268 { 274 assert(pipe); 275 276 if (!usb_pipe_is_session_started(pipe)) { 277 return ENOENT; 278 } 279 280 int rc = async_hangup(pipe->hc_phone); 281 if (rc != EOK) { 282 return rc; 283 } 284 285 pipe->hc_phone = -1; 286 269 usb_log_warning("usb_pipe_end_session() was deprecated.\n"); 287 270 return EOK; 288 271 } … … 298 281 bool usb_pipe_is_session_started(usb_pipe_t *pipe) 299 282 { 300 return (pipe->hc_phone >= 0); 283 pipe_acquire(pipe); 284 bool started = pipe->refcount > 0; 285 pipe_release(pipe); 286 return started; 287 } 288 289 /** Prepare pipe for a long transfer. 290 * 291 * By a long transfer is mean transfer consisting of several 292 * requests to the HC. 293 * Calling such function is optional and it has positive effect of 294 * improved performance because IPC session is initiated only once. 295 * 296 * @param pipe Pipe over which the transfer will happen. 297 * @return Error code. 298 */ 299 int usb_pipe_start_long_transfer(usb_pipe_t *pipe) 300 { 301 return pipe_add_ref(pipe); 302 } 303 304 /** Terminate a long transfer on a pipe. 305 * 306 * @see usb_pipe_start_long_transfer 307 * 308 * @param pipe Pipe where to end the long transfer. 309 */ 310 void usb_pipe_end_long_transfer(usb_pipe_t *pipe) 311 { 312 pipe_drop_ref(pipe); 301 313 } 302 314 -
uspace/lib/usb/src/pipesinit.c
rf35b294 ra43f1d18 356 356 assert(connection); 357 357 358 fibril_mutex_initialize(&pipe->guard); 358 359 pipe->wire = connection; 359 360 pipe->hc_phone = -1; 361 fibril_mutex_initialize(&pipe->hc_phone_mutex); 360 362 pipe->endpoint_no = endpoint_no; 361 363 pipe->transfer_type = transfer_type; 362 364 pipe->max_packet_size = max_packet_size; 363 365 pipe->direction = direction; 366 pipe->refcount = 0; 364 367 365 368 return EOK; … … 413 416 int rc; 414 417 415 TRY_LOOP(failed_attempts) { 416 rc = usb_pipe_start_session(pipe); 417 if (rc == EOK) { 418 break; 419 } 420 } 418 rc = usb_pipe_start_long_transfer(pipe); 421 419 if (rc != EOK) { 422 420 return rc; … … 439 437 } 440 438 } 441 usb_pipe_end_ session(pipe);439 usb_pipe_end_long_transfer(pipe); 442 440 if (rc != EOK) { 443 441 return rc; … … 461 459 usb_hc_connection_t *hc_connection) 462 460 { 461 return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1, 462 interval, hc_connection); 463 } 464 465 /** Register endpoint with a speed at the host controller. 466 * 467 * You will rarely need to use this function because it is needed only 468 * if the registered endpoint is of address 0 and there is no other way 469 * to tell speed of the device at address 0. 470 * 471 * @param pipe Pipe to be registered. 472 * @param speed Speed of the device 473 * (invalid speed means use previously specified one). 474 * @param interval Polling interval. 475 * @param hc_connection Connection to the host controller (must be opened). 476 * @return Error code. 477 */ 478 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed, 479 unsigned int interval, 480 usb_hc_connection_t *hc_connection) 481 { 463 482 assert(pipe); 464 483 assert(hc_connection); … … 468 487 } 469 488 470 #define _PACK(high, low) ((high) * 256 + (low)) 471 472 return async_req_5_0(hc_connection->hc_phone, 489 #define _PACK2(high, low) (((high) << 16) + (low)) 490 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low)) 491 492 return async_req_4_0(hc_connection->hc_phone, 473 493 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT, 474 _PACK(pipe->wire->address, pipe->endpoint_no), 475 _PACK(pipe->transfer_type, pipe->direction), 476 pipe->max_packet_size, interval); 477 478 #undef _PACK 494 _PACK2(pipe->wire->address, pipe->endpoint_no), 495 _PACK3(speed, pipe->transfer_type, pipe->direction), 496 _PACK2(pipe->max_packet_size, interval)); 497 498 #undef _PACK2 499 #undef _PACK3 479 500 } 480 501 -
uspace/lib/usb/src/pipesio.c
rf35b294 ra43f1d18 49 49 #include <assert.h> 50 50 #include <usbhc_iface.h> 51 #include "pipepriv.h" 51 52 52 53 /** Request an in transfer, no checking of input parameters. … … 78 79 } 79 80 81 /* Ensure serialization over the phone. */ 82 pipe_start_transaction(pipe); 83 80 84 /* 81 85 * Make call identifying target USB device and type of transfer. 82 86 */ 83 aid_t opening_request = async_send_ 4(pipe->hc_phone,87 aid_t opening_request = async_send_3(pipe->hc_phone, 84 88 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 85 89 pipe->wire->address, pipe->endpoint_no, 86 pipe->max_packet_size,87 90 NULL); 88 91 if (opening_request == 0) { 92 pipe_end_transaction(pipe); 89 93 return ENOMEM; 90 94 } … … 96 100 aid_t data_request = async_data_read(pipe->hc_phone, buffer, size, 97 101 &data_request_call); 102 103 /* 104 * Since now on, someone else might access the backing phone 105 * without breaking the transfer IPC protocol. 106 */ 107 pipe_end_transaction(pipe); 98 108 99 109 if (data_request == 0) { … … 146 156 147 157 if (buffer == NULL) { 148 158 return EINVAL; 149 159 } 150 160 151 161 if (size == 0) { 152 162 return EINVAL; 153 }154 155 if (!usb_pipe_is_session_started(pipe)) {156 return EBADF;157 163 } 158 164 … … 165 171 } 166 172 173 int rc; 174 rc = pipe_add_ref(pipe); 175 if (rc != EOK) { 176 return rc; 177 } 178 179 167 180 size_t act_size = 0; 168 int rc;169 181 170 182 rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size); 183 184 pipe_drop_ref(pipe); 185 171 186 if (rc != EOK) { 172 187 return rc; … … 210 225 } 211 226 227 /* Ensure serialization over the phone. */ 228 pipe_start_transaction(pipe); 229 212 230 /* 213 231 * Make call identifying target USB device and type of transfer. 214 232 */ 215 aid_t opening_request = async_send_ 4(pipe->hc_phone,233 aid_t opening_request = async_send_3(pipe->hc_phone, 216 234 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 217 235 pipe->wire->address, pipe->endpoint_no, 218 pipe->max_packet_size,219 236 NULL); 220 237 if (opening_request == 0) { 238 pipe_end_transaction(pipe); 221 239 return ENOMEM; 222 240 } … … 226 244 */ 227 245 int rc = async_data_write_start(pipe->hc_phone, buffer, size); 246 247 /* 248 * Since now on, someone else might access the backing phone 249 * without breaking the transfer IPC protocol. 250 */ 251 pipe_end_transaction(pipe); 252 228 253 if (rc != EOK) { 229 254 async_wait_for(opening_request, NULL); … … 260 285 } 261 286 262 if (!usb_pipe_is_session_started(pipe)) {263 return EBADF;264 }265 266 287 if (pipe->direction != USB_DIRECTION_OUT) { 267 288 return EBADF; … … 272 293 } 273 294 274 int rc = usb_pipe_write_no_check(pipe, buffer, size); 295 int rc; 296 297 rc = pipe_add_ref(pipe); 298 if (rc != EOK) { 299 return rc; 300 } 301 302 rc = usb_pipe_write_no_check(pipe, buffer, size); 303 304 pipe_drop_ref(pipe); 275 305 276 306 return rc; … … 293 323 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size) 294 324 { 325 /* Ensure serialization over the phone. */ 326 pipe_start_transaction(pipe); 327 295 328 /* 296 329 * Make call identifying target USB device and control transfer type. 297 330 */ 298 aid_t opening_request = async_send_ 4(pipe->hc_phone,331 aid_t opening_request = async_send_3(pipe->hc_phone, 299 332 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ, 300 333 pipe->wire->address, pipe->endpoint_no, 301 pipe->max_packet_size,302 334 NULL); 303 335 if (opening_request == 0) { … … 311 343 setup_buffer, setup_buffer_size); 312 344 if (rc != EOK) { 345 pipe_end_transaction(pipe); 313 346 async_wait_for(opening_request, NULL); 314 347 return rc; … … 322 355 data_buffer, data_buffer_size, 323 356 &data_request_call); 357 358 /* 359 * Since now on, someone else might access the backing phone 360 * without breaking the transfer IPC protocol. 361 */ 362 pipe_end_transaction(pipe); 363 364 324 365 if (data_request == 0) { 325 366 async_wait_for(opening_request, NULL); … … 379 420 } 380 421 381 if (!usb_pipe_is_session_started(pipe)) {382 return EBADF;383 }384 385 422 if ((pipe->direction != USB_DIRECTION_BOTH) 386 423 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { … … 388 425 } 389 426 427 int rc; 428 429 rc = pipe_add_ref(pipe); 430 if (rc != EOK) { 431 return rc; 432 } 433 390 434 size_t act_size = 0; 391 intrc = usb_pipe_control_read_no_check(pipe,435 rc = usb_pipe_control_read_no_check(pipe, 392 436 setup_buffer, setup_buffer_size, 393 437 data_buffer, data_buffer_size, &act_size); 438 439 pipe_drop_ref(pipe); 394 440 395 441 if (rc != EOK) { … … 418 464 void *data_buffer, size_t data_buffer_size) 419 465 { 466 /* Ensure serialization over the phone. */ 467 pipe_start_transaction(pipe); 468 420 469 /* 421 470 * Make call identifying target USB device and control transfer type. 422 471 */ 423 aid_t opening_request = async_send_ 5(pipe->hc_phone,472 aid_t opening_request = async_send_4(pipe->hc_phone, 424 473 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE, 425 474 pipe->wire->address, pipe->endpoint_no, 426 475 data_buffer_size, 427 pipe->max_packet_size,428 476 NULL); 429 477 if (opening_request == 0) { 478 pipe_end_transaction(pipe); 430 479 return ENOMEM; 431 480 } … … 437 486 setup_buffer, setup_buffer_size); 438 487 if (rc != EOK) { 488 pipe_end_transaction(pipe); 439 489 async_wait_for(opening_request, NULL); 440 490 return rc; … … 447 497 rc = async_data_write_start(pipe->hc_phone, 448 498 data_buffer, data_buffer_size); 499 500 /* All data sent, pipe can be released. */ 501 pipe_end_transaction(pipe); 502 449 503 if (rc != EOK) { 450 504 async_wait_for(opening_request, NULL); 451 505 return rc; 452 506 } 507 } else { 508 /* No data to send, we can release the pipe for others. */ 509 pipe_end_transaction(pipe); 453 510 } 454 511 … … 491 548 } 492 549 493 if (!usb_pipe_is_session_started(pipe)) {494 return EBADF;495 }496 497 550 if ((pipe->direction != USB_DIRECTION_BOTH) 498 551 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { … … 500 553 } 501 554 502 int rc = usb_pipe_control_write_no_check(pipe, 555 int rc; 556 557 rc = pipe_add_ref(pipe); 558 if (rc != EOK) { 559 return rc; 560 } 561 562 rc = usb_pipe_control_write_no_check(pipe, 503 563 setup_buffer, setup_buffer_size, data_buffer, data_buffer_size); 564 565 pipe_drop_ref(pipe); 504 566 505 567 return rc; -
uspace/lib/usb/src/recognise.c
rf35b294 ra43f1d18 404 404 child->driver_data = dev_data; 405 405 406 rc = usb_pipe_start_session(&ctrl_pipe);407 if (rc != EOK) {408 goto failure;409 }410 411 406 rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids); 412 if (rc != EOK) {413 goto failure;414 }415 416 rc = usb_pipe_end_session(&ctrl_pipe);417 407 if (rc != EOK) { 418 408 goto failure;
Note:
See TracChangeset
for help on using the changeset viewer.