Changeset 19a1800 in mainline for uspace/drv/vhc/connhost.c
- Timestamp:
- 2011-03-01T22:20:56Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e24e7b1
- Parents:
- 976f546 (diff), ac8285d (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/connhost.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 36 36 #include <errno.h> 37 37 #include <usb/usb.h> 38 #include <usb/hcd.h> 38 #include <usb/addrkeep.h> 39 #include <usb/ddfiface.h> 39 40 40 41 #include "vhcd.h" 41 42 #include "conn.h" 42 43 #include "hc.h" 44 43 45 44 46 typedef struct { … … 46 48 usbhc_iface_transfer_out_callback_t out_callback; 47 49 usbhc_iface_transfer_in_callback_t in_callback; 48 device_t *dev; 50 ddf_fun_t *fun; 51 size_t reported_size; 49 52 void *arg; 50 53 } transfer_info_t; 51 54 55 typedef struct { 56 usb_direction_t direction; 57 usb_target_t target; 58 usbhc_iface_transfer_out_callback_t out_callback; 59 usbhc_iface_transfer_in_callback_t in_callback; 60 ddf_fun_t *fun; 61 void *arg; 62 void *data_buffer; 63 size_t data_buffer_size; 64 } control_transfer_info_t; 65 52 66 static void universal_callback(void *buffer, size_t size, 53 usb_transaction_outcome_t outcome, void *arg)67 int outcome, void *arg) 54 68 { 55 69 transfer_info_t *transfer = (transfer_info_t *) arg; 70 71 if (transfer->reported_size != (size_t) -1) { 72 size = transfer->reported_size; 73 } 56 74 57 75 switch (transfer->direction) { 58 76 case USB_DIRECTION_IN: 59 transfer->in_callback(transfer-> dev,77 transfer->in_callback(transfer->fun, 60 78 outcome, size, 61 79 transfer->arg); 62 80 break; 63 81 case USB_DIRECTION_OUT: 64 transfer->out_callback(transfer-> dev,82 transfer->out_callback(transfer->fun, 65 83 outcome, 66 84 transfer->arg); … … 74 92 } 75 93 76 static transfer_info_t *create_transfer_info(d evice_t *dev,94 static transfer_info_t *create_transfer_info(ddf_fun_t *fun, 77 95 usb_direction_t direction, void *arg) 78 96 { … … 83 101 transfer->out_callback = NULL; 84 102 transfer->arg = arg; 85 transfer->dev = dev; 103 transfer->fun = fun; 104 transfer->reported_size = (size_t) -1; 86 105 87 106 return transfer; 88 107 } 89 108 90 static int enqueue_transfer_out(device_t *dev, 109 static void control_abort_prematurely(control_transfer_info_t *transfer, 110 size_t size, int outcome) 111 { 112 switch (transfer->direction) { 113 case USB_DIRECTION_IN: 114 transfer->in_callback(transfer->fun, 115 outcome, size, 116 transfer->arg); 117 break; 118 case USB_DIRECTION_OUT: 119 transfer->out_callback(transfer->fun, 120 outcome, 121 transfer->arg); 122 break; 123 default: 124 assert(false && "unreachable"); 125 break; 126 } 127 } 128 129 static void control_callback_two(void *buffer, size_t size, 130 int outcome, void *arg) 131 { 132 control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg; 133 134 if (outcome != EOK) { 135 control_abort_prematurely(ctrl_transfer, outcome, size); 136 free(ctrl_transfer); 137 return; 138 } 139 140 transfer_info_t *transfer = create_transfer_info(ctrl_transfer->fun, 141 ctrl_transfer->direction, ctrl_transfer->arg); 142 transfer->out_callback = ctrl_transfer->out_callback; 143 transfer->in_callback = ctrl_transfer->in_callback; 144 transfer->reported_size = size; 145 146 switch (ctrl_transfer->direction) { 147 case USB_DIRECTION_IN: 148 hc_add_transaction_to_device(false, ctrl_transfer->target, 149 USB_TRANSFER_CONTROL, 150 NULL, 0, 151 universal_callback, transfer); 152 break; 153 case USB_DIRECTION_OUT: 154 hc_add_transaction_from_device(ctrl_transfer->target, 155 USB_TRANSFER_CONTROL, 156 NULL, 0, 157 universal_callback, transfer); 158 break; 159 default: 160 assert(false && "unreachable"); 161 break; 162 } 163 164 free(ctrl_transfer); 165 } 166 167 static void control_callback_one(void *buffer, size_t size, 168 int outcome, void *arg) 169 { 170 control_transfer_info_t *transfer = (control_transfer_info_t *) arg; 171 172 if (outcome != EOK) { 173 control_abort_prematurely(transfer, outcome, size); 174 free(transfer); 175 return; 176 } 177 178 switch (transfer->direction) { 179 case USB_DIRECTION_IN: 180 hc_add_transaction_from_device(transfer->target, 181 USB_TRANSFER_CONTROL, 182 transfer->data_buffer, transfer->data_buffer_size, 183 control_callback_two, transfer); 184 break; 185 case USB_DIRECTION_OUT: 186 hc_add_transaction_to_device(false, transfer->target, 187 USB_TRANSFER_CONTROL, 188 transfer->data_buffer, transfer->data_buffer_size, 189 control_callback_two, transfer); 190 break; 191 default: 192 assert(false && "unreachable"); 193 break; 194 } 195 } 196 197 static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun, 198 usb_direction_t direction, usb_target_t target, 199 void *data_buffer, size_t data_buffer_size, 200 void *arg) 201 { 202 control_transfer_info_t *transfer 203 = malloc(sizeof(control_transfer_info_t)); 204 205 transfer->direction = direction; 206 transfer->target = target; 207 transfer->in_callback = NULL; 208 transfer->out_callback = NULL; 209 transfer->arg = arg; 210 transfer->fun = fun; 211 transfer->data_buffer = data_buffer; 212 transfer->data_buffer_size = data_buffer_size; 213 214 return transfer; 215 } 216 217 static int enqueue_transfer_out(ddf_fun_t *fun, 91 218 usb_target_t target, usb_transfer_type_t transfer_type, 92 219 void *buffer, size_t size, 93 220 usbhc_iface_transfer_out_callback_t callback, void *arg) 94 221 { 95 dprintf(3, "transfer OUT [%d.%d (%s); %zu]",222 usb_log_debug2("Transfer OUT [%d.%d (%s); %zu].\n", 96 223 target.address, target.endpoint, 97 224 usb_str_transfer_type(transfer_type), … … 99 226 100 227 transfer_info_t *transfer 101 = create_transfer_info( dev, USB_DIRECTION_OUT, arg);228 = create_transfer_info(fun, USB_DIRECTION_OUT, arg); 102 229 transfer->out_callback = callback; 103 230 … … 108 235 } 109 236 110 static int enqueue_transfer_ setup(device_t *dev,237 static int enqueue_transfer_in(ddf_fun_t *fun, 111 238 usb_target_t target, usb_transfer_type_t transfer_type, 112 239 void *buffer, size_t size, 113 usbhc_iface_transfer_ out_callback_t callback, void *arg)114 { 115 dprintf(3, "transfer SETUP [%d.%d (%s); %zu]",240 usbhc_iface_transfer_in_callback_t callback, void *arg) 241 { 242 usb_log_debug2("Transfer IN [%d.%d (%s); %zu].\n", 116 243 target.address, target.endpoint, 117 244 usb_str_transfer_type(transfer_type), … … 119 246 120 247 transfer_info_t *transfer 121 = create_transfer_info(dev, USB_DIRECTION_OUT, arg); 122 transfer->out_callback = callback; 123 124 hc_add_transaction_to_device(true, target, transfer_type, buffer, size, 125 universal_callback, transfer); 126 127 return EOK; 128 } 129 130 static int enqueue_transfer_in(device_t *dev, 131 usb_target_t target, usb_transfer_type_t transfer_type, 132 void *buffer, size_t size, 133 usbhc_iface_transfer_in_callback_t callback, void *arg) 134 { 135 dprintf(3, "transfer IN [%d.%d (%s); %zu]", 136 target.address, target.endpoint, 137 usb_str_transfer_type(transfer_type), 138 size); 139 140 transfer_info_t *transfer 141 = create_transfer_info(dev, USB_DIRECTION_IN, arg); 248 = create_transfer_info(fun, USB_DIRECTION_IN, arg); 142 249 transfer->in_callback = callback; 143 250 … … 149 256 150 257 151 static int interrupt_out(device_t *dev, usb_target_t target, 258 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 259 size_t max_packet_size, 152 260 void *data, size_t size, 153 261 usbhc_iface_transfer_out_callback_t callback, void *arg) 154 262 { 155 return enqueue_transfer_out( dev, target, USB_TRANSFER_INTERRUPT,263 return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT, 156 264 data, size, 157 265 callback, arg); 158 266 } 159 267 160 static int interrupt_in(device_t *dev, usb_target_t target, 268 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 269 size_t max_packet_size, 161 270 void *data, size_t size, 162 271 usbhc_iface_transfer_in_callback_t callback, void *arg) 163 272 { 164 return enqueue_transfer_in( dev, target, USB_TRANSFER_INTERRUPT,273 return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT, 165 274 data, size, 166 275 callback, arg); 167 276 } 168 277 169 static int control_write_setup(device_t *dev, usb_target_t target, 170 void *data, size_t size, 278 static int control_write(ddf_fun_t *fun, usb_target_t target, 279 size_t max_packet_size, 280 void *setup_packet, size_t setup_packet_size, 281 void *data, size_t data_size, 171 282 usbhc_iface_transfer_out_callback_t callback, void *arg) 172 283 { 173 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 174 data, size, 175 callback, arg); 176 } 177 178 static int control_write_data(device_t *dev, usb_target_t target, 179 void *data, size_t size, 180 usbhc_iface_transfer_out_callback_t callback, void *arg) 181 { 182 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 183 data, size, 184 callback, arg); 185 } 186 187 static int control_write_status(device_t *dev, usb_target_t target, 284 control_transfer_info_t *transfer 285 = create_control_transfer_info(fun, USB_DIRECTION_OUT, target, 286 data, data_size, arg); 287 transfer->out_callback = callback; 288 289 hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL, 290 setup_packet, setup_packet_size, 291 control_callback_one, transfer); 292 293 return EOK; 294 } 295 296 static int control_read(ddf_fun_t *fun, usb_target_t target, 297 size_t max_packet_size, 298 void *setup_packet, size_t setup_packet_size, 299 void *data, size_t data_size, 188 300 usbhc_iface_transfer_in_callback_t callback, void *arg) 189 301 { 190 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 191 NULL, 0, 192 callback, arg); 193 } 194 195 static int control_read_setup(device_t *dev, usb_target_t target, 196 void *data, size_t size, 197 usbhc_iface_transfer_out_callback_t callback, void *arg) 198 { 199 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 200 data, size, 201 callback, arg); 202 } 203 204 static int control_read_data(device_t *dev, usb_target_t target, 205 void *data, size_t size, 206 usbhc_iface_transfer_in_callback_t callback, void *arg) 207 { 208 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 209 data, size, 210 callback, arg); 211 } 212 213 static int control_read_status(device_t *dev, usb_target_t target, 214 usbhc_iface_transfer_out_callback_t callback, void *arg) 215 { 216 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 217 NULL, 0, 218 callback, arg); 302 control_transfer_info_t *transfer 303 = create_control_transfer_info(fun, USB_DIRECTION_IN, target, 304 data, data_size, arg); 305 transfer->in_callback = callback; 306 307 hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL, 308 setup_packet, setup_packet_size, 309 control_callback_one, transfer); 310 311 return EOK; 219 312 } 220 313 221 314 static usb_address_keeping_t addresses; 222 315 223 224 static int reserve_default_address(device_t *dev) 316 static int tell_address(ddf_fun_t *fun, devman_handle_t handle, 317 usb_address_t *address) 318 { 319 usb_log_debug("tell_address(fun \"%s\", handle %zu)\n", 320 fun->name, (size_t) fun->handle); 321 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 322 if (addr < 0) { 323 return addr; 324 } 325 326 *address = addr; 327 return EOK; 328 } 329 330 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored) 225 331 { 226 332 usb_address_keeping_reserve_default(&addresses); … … 228 334 } 229 335 230 static int release_default_address(d evice_t *dev)336 static int release_default_address(ddf_fun_t *fun) 231 337 { 232 338 usb_address_keeping_release_default(&addresses); … … 234 340 } 235 341 236 static int request_address(device_t *dev, usb_address_t *address) 342 static int request_address(ddf_fun_t *fun, usb_speed_t ignored, 343 usb_address_t *address) 237 344 { 238 345 usb_address_t addr = usb_address_keeping_request(&addresses); … … 245 352 } 246 353 247 static int release_address(d evice_t *dev, usb_address_t address)354 static int release_address(ddf_fun_t *fun, usb_address_t address) 248 355 { 249 356 return usb_address_keeping_release(&addresses, address); 250 357 } 251 358 252 static int bind_address(d evice_t *dev, usb_address_t address,359 static int bind_address(ddf_fun_t *fun, usb_address_t address, 253 360 devman_handle_t handle) 254 361 { … … 257 364 } 258 365 259 static int tell_address(device_t *dev, devman_handle_t handle, 366 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun, 367 devman_handle_t *handle) 368 { 369 ddf_fun_t *hc_fun = root_hub_fun->driver_data; 370 assert(hc_fun != NULL); 371 372 *handle = hc_fun->handle; 373 374 usb_log_debug("usb_iface_get_hc_handle_rh_impl returns %zu\n", *handle); 375 376 return EOK; 377 } 378 379 static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle, 260 380 usb_address_t *address) 261 381 { 262 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 263 if (addr < 0) { 264 return addr; 265 } 266 267 *address = addr; 268 return EOK; 382 ddf_fun_t *hc_fun = root_hub_fun->driver_data; 383 assert(hc_fun != NULL); 384 385 return tell_address(hc_fun, root_hub_fun->handle, address); 269 386 } 270 387 … … 275 392 276 393 usbhc_iface_t vhc_iface = { 277 .tell_address = tell_address,278 279 394 .reserve_default_address = reserve_default_address, 280 395 .release_default_address = release_default_address, … … 286 401 .interrupt_in = interrupt_in, 287 402 288 .control_write_setup = control_write_setup, 289 .control_write_data = control_write_data, 290 .control_write_status = control_write_status, 291 292 .control_read_setup = control_read_setup, 293 .control_read_data = control_read_data, 294 .control_read_status = control_read_status 403 .control_write = control_write, 404 .control_read = control_read 295 405 }; 406 407 usb_iface_t vhc_usb_iface = { 408 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 409 .get_address = tell_address 410 }; 411 412 usb_iface_t rh_usb_iface = { 413 .get_hc_handle = usb_iface_get_hc_handle_rh_impl, 414 .get_address = tell_address_rh 415 }; 416 296 417 297 418 /**
Note:
See TracChangeset
for help on using the changeset viewer.