Changeset 48fe0c9 in mainline
- Timestamp:
- 2011-03-21T13:43:27Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 361e61b, 5971dd3, 8a951ca
- Parents:
- 0e45e7f (diff), 925e099 (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:
-
- 1 added
- 9 edited
- 5 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/Makefile
r0e45e7f r48fe0c9 33 33 34 34 SOURCES = \ 35 hc_iface.c \35 iface.c \ 36 36 batch.c \ 37 37 main.c \ 38 ohci_hc.c \39 ohci_rh.c \38 hc.c \ 39 root_hub.c \ 40 40 pci.c 41 41 -
uspace/drv/ohci/batch.c
r0e45e7f r48fe0c9 39 39 40 40 #include "batch.h" 41 #include "utils/malloc32.h" 42 43 static void batch_call_in_and_dispose(batch_t *instance); 44 static void batch_call_out_and_dispose(batch_t *instance); 41 45 42 46 #define DEFAULT_ERROR_COUNT 3 47 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 usbhc_iface_transfer_in_callback_t func_in, 58 usbhc_iface_transfer_out_callback_t func_out, 59 void *arg, 60 device_keeper_t *manager 61 ) 62 { 63 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ 64 if (ptr == NULL) { \ 65 usb_log_error(message); \ 66 if (instance) { \ 67 batch_dispose(instance); \ 68 } \ 69 return NULL; \ 70 } else (void)0 43 71 72 batch_t *instance = malloc(sizeof(batch_t)); 73 CHECK_NULL_DISPOSE_RETURN(instance, 74 "Failed to allocate batch instance.\n"); 75 batch_init(instance, target, transfer_type, speed, max_packet_size, 76 buffer, NULL, buffer_size, NULL, setup_size, func_in, 77 func_out, arg, fun, NULL); 78 79 if (buffer_size > 0) { 80 instance->transport_buffer = malloc32(buffer_size); 81 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer, 82 "Failed to allocate device accessible buffer.\n"); 83 } 84 85 if (setup_size > 0) { 86 instance->setup_buffer = malloc32(setup_size); 87 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer, 88 "Failed to allocate device accessible setup buffer.\n"); 89 memcpy(instance->setup_buffer, setup_buffer, setup_size); 90 } 91 92 93 return instance; 94 } 95 /*----------------------------------------------------------------------------*/ 96 void batch_dispose(batch_t *instance) 97 { 98 assert(instance); 99 free32(instance->transport_buffer); 100 free32(instance->setup_buffer); 101 free(instance); 102 } 103 /*----------------------------------------------------------------------------*/ 104 void batch_control_write(batch_t *instance) 105 { 106 assert(instance); 107 /* We are data out, we are supposed to provide data */ 108 memcpy(instance->transport_buffer, instance->buffer, 109 instance->buffer_size); 110 instance->next_step = batch_call_out_and_dispose; 111 /* TODO: implement */ 112 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 113 } 114 /*----------------------------------------------------------------------------*/ 115 void batch_control_read(batch_t *instance) 116 { 117 assert(instance); 118 instance->next_step = batch_call_in_and_dispose; 119 /* TODO: implement */ 120 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 121 } 122 /*----------------------------------------------------------------------------*/ 123 void batch_interrupt_in(batch_t *instance) 124 { 125 assert(instance); 126 instance->direction = USB_DIRECTION_IN; 127 instance->next_step = batch_call_in_and_dispose; 128 /* TODO: implement */ 129 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 130 } 131 /*----------------------------------------------------------------------------*/ 132 void batch_interrupt_out(batch_t *instance) 133 { 134 assert(instance); 135 instance->direction = USB_DIRECTION_OUT; 136 /* We are data out, we are supposed to provide data */ 137 memcpy(instance->transport_buffer, instance->buffer, 138 instance->buffer_size); 139 instance->next_step = batch_call_out_and_dispose; 140 /* TODO: implement */ 141 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 142 } 143 /*----------------------------------------------------------------------------*/ 144 void batch_bulk_in(batch_t *instance) 145 { 146 assert(instance); 147 instance->direction = USB_DIRECTION_IN; 148 instance->next_step = batch_call_in_and_dispose; 149 /* TODO: implement */ 150 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 151 } 152 /*----------------------------------------------------------------------------*/ 153 void batch_bulk_out(batch_t *instance) 154 { 155 assert(instance); 156 instance->direction = USB_DIRECTION_IN; 157 instance->next_step = batch_call_in_and_dispose; 158 /* TODO: implement */ 159 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 160 } 161 /*----------------------------------------------------------------------------*/ 162 /** Helper function calls callback and correctly disposes of batch structure. 163 * 164 * @param[in] instance Batch structure to use. 165 */ 166 void batch_call_in_and_dispose(batch_t *instance) 167 { 168 assert(instance); 169 batch_call_in(instance); 170 batch_dispose(instance); 171 } 172 /*----------------------------------------------------------------------------*/ 173 /** Helper function calls callback and correctly disposes of batch structure. 174 * 175 * @param[in] instance Batch structure to use. 176 */ 177 void batch_call_out_and_dispose(batch_t *instance) 178 { 179 assert(instance); 180 batch_call_out(instance); 181 batch_dispose(instance); 182 } 44 183 /** 45 184 * @} -
uspace/drv/ohci/hc.c
r0e45e7f r48fe0c9 39 39 #include <usb/debug.h> 40 40 #include <usb/usb.h> 41 #include <usb/hub.h> 41 42 #include <usb/ddfiface.h> 42 #include <usb _iface.h>43 #include <usb/usbdevice.h> 43 44 44 #include " ohci_hc.h"45 #include "hc.h" 45 46 46 int ohci_hc_init(ohci_hc_t *instance, ddf_fun_t *fun, 47 static int dummy_reset(int foo, void *arg) 48 { 49 hc_t *hc = (hc_t*)arg; 50 assert(hc); 51 hc->rh.address = 0; 52 return EOK; 53 } 54 /*----------------------------------------------------------------------------*/ 55 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 47 56 uintptr_t regs, size_t reg_size, bool interrupts) 48 57 { 49 58 assert(instance); 50 int ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers); 59 int ret = EOK; 60 61 ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers); 51 62 if (ret != EOK) { 52 63 usb_log_error("Failed to gain access to device registers.\n"); 53 64 return ret; 54 65 } 55 instance->registers->interrupt_disable = 0; 56 /* enable interrupt on root hub status change */ 57 instance->registers->interupt_enable |= IE_RHSC | IE_MIE; 66 instance->ddf_instance = fun; 67 device_keeper_init(&instance->manager); 58 68 59 69 60 ohci_rh_init(&instance->rh, instance->registers);70 rh_init(&instance->rh, dev, instance->registers); 61 71 /* TODO: implement */ 62 /* TODO: register root hub */63 72 return EOK; 64 73 } 65 74 /*----------------------------------------------------------------------------*/ 66 int ohci_hc_schedule(ohci_hc_t *instance, batch_t *batch) 75 int hc_register_hub(hc_t *instance) 76 { 77 async_usleep(1000000); 78 #define CHECK_RET_RETURN(ret, msg...) \ 79 if (ret != EOK) { \ 80 usb_log_error(msg); \ 81 return ret; \ 82 } else (void)0 83 assert(instance); 84 assert(instance->ddf_instance); 85 assert(instance->ddf_instance->handle); 86 ddf_dev_t *dev = instance->rh.device; 87 int ret = EOK; 88 89 usb_hc_connection_t conn; 90 ret = 91 usb_hc_connection_initialize(&conn, instance->ddf_instance->handle); 92 CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n"); 93 94 ret = usb_hc_connection_open(&conn); 95 CHECK_RET_RETURN(ret, "Failed to open hc connection.\n"); 96 97 usb_address_t address; 98 devman_handle_t handle; 99 ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset, 100 0, instance, &address, &handle, NULL, NULL, NULL); 101 CHECK_RET_RETURN(ret, "Failed to add rh device.\n"); 102 103 ret = usb_hc_connection_close(&conn); 104 CHECK_RET_RETURN(ret, "Failed to close hc connection.\n"); 105 return EOK; 106 } 107 /*----------------------------------------------------------------------------*/ 108 int hc_schedule(hc_t *instance, batch_t *batch) 67 109 { 68 110 assert(instance); 69 111 assert(batch); 70 112 if (batch->target.address == instance->rh.address) { 71 ohci_rh_request(&instance->rh, batch); 72 return EOK; 113 return rh_request(&instance->rh, batch); 73 114 } 74 115 /* TODO: implement */ 75 return E OK;116 return ENOTSUP; 76 117 } 77 118 /*----------------------------------------------------------------------------*/ 78 void ohci_hc_interrupt(ohci_hc_t *instance, uint16_t status)119 void hc_interrupt(hc_t *instance, uint16_t status) 79 120 { 80 121 assert(instance); 81 122 /* TODO: Check for interrupt cause */ 82 ohci_rh_interrupt(&instance->rh);123 rh_interrupt(&instance->rh); 83 124 /* TODO: implement */ 84 125 } -
uspace/drv/ohci/hc.h
r0e45e7f r48fe0c9 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup drvusbohcihc 28 /** @addtogroup drvusbohci 30 29 * @{ 31 30 */ … … 33 32 * @brief OHCI host controller driver structure 34 33 */ 35 #ifndef DRV_OHCI_ OHCI_HC_H36 #define DRV_OHCI_ OHCI_HC_H34 #ifndef DRV_OHCI_HC_H 35 #define DRV_OHCI_HC_H 37 36 38 37 #include <fibril.h> … … 42 41 43 42 #include <usb/usb.h> 43 #include <usb/host/device_keeper.h> 44 44 #include <usbhc_iface.h> 45 45 46 46 #include "batch.h" 47 47 #include "ohci_regs.h" 48 #include " ohci_rh.h"48 #include "root_hub.h" 49 49 50 typedef struct ohci_hc {50 typedef struct hc { 51 51 ohci_regs_t *registers; 52 52 usb_address_t rh_address; 53 ohci_rh_t rh;53 rh_t rh; 54 54 ddf_fun_t *ddf_instance; 55 } ohci_hc_t; 55 device_keeper_t manager; 56 } hc_t; 56 57 57 int ohci_hc_init(ohci_hc_t *instance, ddf_fun_t *fun,58 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 58 59 uintptr_t regs, size_t reg_size, bool interrupts); 59 60 60 int ohci_hc_schedule(ohci_hc_t *instance, batch_t *batch);61 int hc_register_hub(hc_t *instance); 61 62 62 void ohci_hc_interrupt(ohci_hc_t *instance, uint16_t status); 63 int hc_schedule(hc_t *instance, batch_t *batch); 64 65 void hc_interrupt(hc_t *instance, uint16_t status); 63 66 64 67 /** Safely dispose host controller internal structures … … 66 69 * @param[in] instance Host controller structure to use. 67 70 */ 68 static inline void ohci_hc_fini(ohci_hc_t *instance) { /* TODO: implement*/ };71 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 69 72 70 73 /** Get and cast pointer to the driver data … … 73 76 * @return cast pointer to driver_data 74 77 */ 75 static inline ohci_hc_t * fun_to_ohci_hc(ddf_fun_t *fun)76 { return ( ohci_hc_t*)fun->driver_data; }78 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 79 { return (hc_t*)fun->driver_data; } 77 80 #endif 78 81 /** -
uspace/drv/ohci/iface.c
r0e45e7f r48fe0c9 43 43 44 44 #include "iface.h" 45 #include "hc.h" 45 46 46 47 #define UNSUPPORTED(methodname) \ … … 59 60 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 60 61 { 61 UNSUPPORTED("reserve_default_address"); 62 63 return ENOTSUP; 64 } 65 62 assert(fun); 63 hc_t *hc = fun_to_hc(fun); 64 assert(hc); 65 usb_log_debug("Default address request with speed %d.\n", speed); 66 device_keeper_reserve_default(&hc->manager, speed); 67 return EOK; 68 } 69 /*----------------------------------------------------------------------------*/ 66 70 /** Release default address. 67 71 * … … 71 75 static int release_default_address(ddf_fun_t *fun) 72 76 { 73 UNSUPPORTED("release_default_address"); 74 75 return ENOTSUP; 76 } 77 77 assert(fun); 78 hc_t *hc = fun_to_hc(fun); 79 assert(hc); 80 usb_log_debug("Default address release.\n"); 81 device_keeper_release_default(&hc->manager); 82 return EOK; 83 } 84 /*----------------------------------------------------------------------------*/ 78 85 /** Found free USB address. 79 86 * … … 86 93 usb_address_t *address) 87 94 { 88 UNSUPPORTED("request_address"); 89 90 return ENOTSUP; 91 } 92 95 assert(fun); 96 hc_t *hc = fun_to_hc(fun); 97 assert(hc); 98 assert(address); 99 100 usb_log_debug("Address request with speed %d.\n", speed); 101 *address = device_keeper_request(&hc->manager, speed); 102 usb_log_debug("Address request with result: %d.\n", *address); 103 if (*address <= 0) 104 return *address; 105 return EOK; 106 } 107 /*----------------------------------------------------------------------------*/ 93 108 /** Bind USB address with device devman handle. 94 109 * … … 101 116 usb_address_t address, devman_handle_t handle) 102 117 { 103 UNSUPPORTED("bind_address"); 104 105 return ENOTSUP; 106 } 107 118 assert(fun); 119 hc_t *hc = fun_to_hc(fun); 120 assert(hc); 121 usb_log_debug("Address bind %d-%d.\n", address, handle); 122 device_keeper_bind(&hc->manager, address, handle); 123 return EOK; 124 } 125 /*----------------------------------------------------------------------------*/ 108 126 /** Release previously requested address. 109 127 * … … 114 132 static int release_address(ddf_fun_t *fun, usb_address_t address) 115 133 { 116 UNSUPPORTED("release_address"); 117 118 return ENOTSUP; 134 assert(fun); 135 hc_t *hc = fun_to_hc(fun); 136 assert(hc); 137 usb_log_debug("Address release %d.\n", address); 138 device_keeper_release(&hc->manager, address); 139 return EOK; 119 140 } 120 141 … … 155 176 return ENOTSUP; 156 177 } 157 178 /*----------------------------------------------------------------------------*/ 158 179 /** Schedule interrupt out transfer. 159 180 * … … 177 198 usbhc_iface_transfer_out_callback_t callback, void *arg) 178 199 { 179 UNSUPPORTED("interrupt_out"); 180 181 return ENOTSUP; 182 } 183 200 hc_t *hc = fun_to_hc(fun); 201 assert(hc); 202 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 203 204 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 205 target.address, target.endpoint, size, max_packet_size); 206 207 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 208 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 209 &hc->manager); 210 if (!batch) 211 return ENOMEM; 212 batch_interrupt_out(batch); 213 const int ret = hc_schedule(hc, batch); 214 if (ret != EOK) { 215 batch_dispose(batch); 216 return ret; 217 } 218 return EOK; 219 } 220 /*----------------------------------------------------------------------------*/ 184 221 /** Schedule interrupt in transfer. 185 222 * … … 203 240 usbhc_iface_transfer_in_callback_t callback, void *arg) 204 241 { 205 UNSUPPORTED("interrupt_in"); 206 207 return ENOTSUP; 208 } 209 242 assert(fun); 243 hc_t *hc = fun_to_hc(fun); 244 assert(hc); 245 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 246 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 247 target.address, target.endpoint, size, max_packet_size); 248 249 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 250 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 251 &hc->manager); 252 if (!batch) 253 return ENOMEM; 254 batch_interrupt_in(batch); 255 const int ret = hc_schedule(hc, batch); 256 if (ret != EOK) { 257 batch_dispose(batch); 258 return ret; 259 } 260 return EOK; 261 } 262 /*----------------------------------------------------------------------------*/ 210 263 /** Schedule bulk out transfer. 211 264 * … … 229 282 usbhc_iface_transfer_out_callback_t callback, void *arg) 230 283 { 231 UNSUPPORTED("bulk_out"); 232 233 return ENOTSUP; 234 } 235 284 assert(fun); 285 hc_t *hc = fun_to_hc(fun); 286 assert(hc); 287 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 288 289 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 290 target.address, target.endpoint, size, max_packet_size); 291 292 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 293 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 294 &hc->manager); 295 if (!batch) 296 return ENOMEM; 297 batch_bulk_out(batch); 298 const int ret = hc_schedule(hc, batch); 299 if (ret != EOK) { 300 batch_dispose(batch); 301 return ret; 302 } 303 return EOK; 304 305 } 306 /*----------------------------------------------------------------------------*/ 236 307 /** Schedule bulk in transfer. 237 308 * … … 255 326 usbhc_iface_transfer_in_callback_t callback, void *arg) 256 327 { 257 UNSUPPORTED("bulk_in"); 258 259 return ENOTSUP; 260 } 261 328 assert(fun); 329 hc_t *hc = fun_to_hc(fun); 330 assert(hc); 331 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 332 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 333 target.address, target.endpoint, size, max_packet_size); 334 335 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 336 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 337 &hc->manager); 338 if (!batch) 339 return ENOMEM; 340 batch_bulk_in(batch); 341 const int ret = hc_schedule(hc, batch); 342 if (ret != EOK) { 343 batch_dispose(batch); 344 return ret; 345 } 346 return EOK; 347 } 348 /*----------------------------------------------------------------------------*/ 262 349 /** Schedule control write transfer. 263 350 * … … 282 369 static int control_write(ddf_fun_t *fun, usb_target_t target, 283 370 size_t max_packet_size, 284 void *setup_ packet, size_t setup_packet_size,285 void *data _buffer, size_t data_buffer_size,371 void *setup_data, size_t setup_size, 372 void *data, size_t size, 286 373 usbhc_iface_transfer_out_callback_t callback, void *arg) 287 374 { 288 UNSUPPORTED("control_write"); 289 290 return ENOTSUP; 291 } 292 375 assert(fun); 376 hc_t *hc = fun_to_hc(fun); 377 assert(hc); 378 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 379 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 380 speed, target.address, target.endpoint, size, max_packet_size); 381 382 if (setup_size != 8) 383 return EINVAL; 384 385 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 386 max_packet_size, speed, data, size, setup_data, setup_size, 387 NULL, callback, arg, &hc->manager); 388 if (!batch) 389 return ENOMEM; 390 device_keeper_reset_if_need(&hc->manager, target, setup_data); 391 batch_control_write(batch); 392 const int ret = hc_schedule(hc, batch); 393 if (ret != EOK) { 394 batch_dispose(batch); 395 return ret; 396 } 397 return EOK; 398 } 399 /*----------------------------------------------------------------------------*/ 293 400 /** Schedule control read transfer. 294 401 * … … 313 420 static int control_read(ddf_fun_t *fun, usb_target_t target, 314 421 size_t max_packet_size, 315 void *setup_ packet, size_t setup_packet_size,316 void *data _buffer, size_t data_buffer_size,422 void *setup_data, size_t setup_size, 423 void *data, size_t size, 317 424 usbhc_iface_transfer_in_callback_t callback, void *arg) 318 425 { 319 UNSUPPORTED("control_read"); 320 321 return ENOTSUP; 322 } 323 426 assert(fun); 427 hc_t *hc = fun_to_hc(fun); 428 assert(hc); 429 usb_speed_t speed = device_keeper_speed(&hc->manager, target.address); 430 431 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 432 speed, target.address, target.endpoint, size, max_packet_size); 433 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 434 max_packet_size, speed, data, size, setup_data, setup_size, callback, 435 NULL, arg, &hc->manager); 436 if (!batch) 437 return ENOMEM; 438 batch_control_read(batch); 439 const int ret = hc_schedule(hc, batch); 440 if (ret != EOK) { 441 batch_dispose(batch); 442 return ret; 443 } 444 return EOK; 445 } 446 /*----------------------------------------------------------------------------*/ 324 447 /** Host controller interface implementation for OHCI. */ 325 usbhc_iface_t ohci_hc_iface = {448 usbhc_iface_t hc_iface = { 326 449 .reserve_default_address = reserve_default_address, 327 450 .release_default_address = release_default_address, -
uspace/drv/ohci/iface.h
r0e45e7f r48fe0c9 40 40 #define NAME "ohci" 41 41 42 extern usbhc_iface_t ohci_hc_iface;42 extern usbhc_iface_t hc_iface; 43 43 44 44 #endif -
uspace/drv/ohci/main.c
r0e45e7f r48fe0c9 45 45 #include "pci.h" 46 46 #include "iface.h" 47 #include " ohci_hc.h"47 #include "hc.h" 48 48 49 49 static int ohci_add_device(ddf_dev_t *device); 50 static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) 51 { 52 assert(handle); 53 assert(fun != NULL); 54 55 *handle = fun->handle; 56 return EOK; 57 } 58 /*----------------------------------------------------------------------------*/ 59 static int get_address( 60 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) 61 { 62 assert(fun); 63 device_keeper_t *manager = &fun_to_hc(fun)->manager; 64 usb_address_t addr = device_keeper_find(manager, handle); 65 if (addr < 0) { 66 return addr; 67 } 68 69 if (address != NULL) { 70 *address = addr; 71 } 72 73 return EOK; 74 } 50 75 /*----------------------------------------------------------------------------*/ 51 76 /** IRQ handling callback, identifies device … … 58 83 { 59 84 assert(dev); 60 ohci_hc_t *hc = (ohci_hc_t*)dev->driver_data;85 hc_t *hc = (hc_t*)dev->driver_data; 61 86 assert(hc); 62 ohci_hc_interrupt(hc, 0);87 hc_interrupt(hc, 0); 63 88 } 64 89 /*----------------------------------------------------------------------------*/ … … 71 96 .driver_ops = &ohci_driver_ops 72 97 }; 98 /*----------------------------------------------------------------------------*/ 99 static usb_iface_t hc_usb_iface = { 100 .get_address = get_address, 101 .get_hc_handle = get_hc_handle, 102 }; 103 /*----------------------------------------------------------------------------*/ 73 104 static ddf_dev_ops_t hc_ops = { 74 .interfaces[USB HC_DEV_IFACE] = &ohci_hc_iface,75 }; 76 105 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 106 .interfaces[USBHC_DEV_IFACE] = &hc_iface, 107 }; 77 108 /*----------------------------------------------------------------------------*/ 78 109 /** Initializes a new ddf driver instance of OHCI hcd. … … 105 136 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 106 137 107 ohci_hc_t *hcd = malloc(sizeof(ohci_hc_t));138 hc_t *hcd = malloc(sizeof(hc_t)); 108 139 if (hcd == NULL) { 109 140 usb_log_error("Failed to allocate OHCI driver.\n"); … … 129 160 } 130 161 131 ret = ohci_hc_init(hcd, hc_fun, mem_reg_base, mem_reg_size, interrupts);162 ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts); 132 163 if (ret != EOK) { 133 164 usb_log_error("Failed to initialize OHCI driver.\n"); … … 148 179 hc_fun->driver_data = hcd; 149 180 150 /* TODO: register interrupt handler */ 181 fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd); 182 fibril_add_ready(later); 151 183 152 184 usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n", -
uspace/drv/ohci/root_hub.c
r0e45e7f r48fe0c9 38 38 #include <usb/debug.h> 39 39 40 #include " ohci_rh.h"40 #include "root_hub.h" 41 41 42 42 /** Root hub initialization 43 43 * @return Error code. 44 44 */ 45 int ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs)45 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) 46 46 { 47 47 assert(instance); 48 instance->address = 0;48 instance->address = -1; 49 49 instance->registers = regs; 50 instance->device = dev; 50 51 51 52 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); … … 55 56 } 56 57 /*----------------------------------------------------------------------------*/ 57 void ohci_rh_request(ohci_rh_t *instance, batch_t *request)58 int rh_request(rh_t *instance, batch_t *request) 58 59 { 60 assert(instance); 61 assert(request); 59 62 /* TODO: implement */ 63 if (request->setup_buffer) { 64 usb_log_info("Root hub got SETUP packet: %s.\n", 65 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 66 } 67 usb_log_error("Root hub request processing not implemented.\n"); 68 batch_finish(request, ENOTSUP); 69 return EOK; 60 70 } 61 71 /*----------------------------------------------------------------------------*/ 62 void ohci_rh_interrupt(ohci_rh_t *instance)72 void rh_interrupt(rh_t *instance) 63 73 { 64 usb_log_ info("Interrupt!!.\n");74 usb_log_error("Root hub interrupt not implemented.\n"); 65 75 /* TODO: implement */ 66 76 } -
uspace/drv/ohci/root_hub.h
r0e45e7f r48fe0c9 33 33 * @brief OHCI driver 34 34 */ 35 #ifndef DRV_OHCI_ OHCI_RH_H36 #define DRV_OHCI_ OHCI_RH_H35 #ifndef DRV_OHCI_ROOT_HUB_H 36 #define DRV_OHCI_ROOT_HUB_H 37 37 38 38 #include <usb/usb.h> … … 41 41 #include "batch.h" 42 42 43 typedef struct ohci_rh {43 typedef struct rh { 44 44 ohci_regs_t *registers; 45 45 usb_address_t address; 46 } ohci_rh_t; 46 ddf_dev_t *device; 47 } rh_t; 47 48 48 int ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs);49 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs); 49 50 50 void ohci_rh_request(ohci_rh_t *instance, batch_t *request);51 int rh_request(rh_t *instance, batch_t *request); 51 52 52 void ohci_rh_interrupt(ohci_rh_t *instance);53 void rh_interrupt(rh_t *instance); 53 54 #endif 54 55 /** -
uspace/drv/uhci-hcd/batch.c
r0e45e7f r48fe0c9 183 183 184 184 device_keeper_set_toggle(data->manager, 185 instance->target, td_toggle(&data->tds[i])); 185 instance->target, instance->direction, 186 td_toggle(&data->tds[i])); 186 187 if (i > 0) 187 188 goto substract_ret; … … 238 239 { 239 240 assert(instance); 241 instance->direction = USB_DIRECTION_IN; 240 242 batch_data(instance, USB_PID_IN); 241 243 instance->next_step = batch_call_in_and_dispose; … … 252 254 { 253 255 assert(instance); 256 instance->direction = USB_DIRECTION_OUT; 254 257 /* We are data out, we are supposed to provide data */ 255 258 memcpy(instance->transport_buffer, instance->buffer, … … 270 273 assert(instance); 271 274 batch_data(instance, USB_PID_IN); 275 instance->direction = USB_DIRECTION_IN; 272 276 instance->next_step = batch_call_in_and_dispose; 273 277 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); … … 283 287 { 284 288 assert(instance); 289 instance->direction = USB_DIRECTION_OUT; 285 290 /* We are data out, we are supposed to provide data */ 286 291 memcpy(instance->transport_buffer, instance->buffer, … … 306 311 307 312 const bool low_speed = instance->speed == USB_SPEED_LOW; 308 int toggle = device_keeper_get_toggle(data->manager, instance->target); 313 int toggle = device_keeper_get_toggle( 314 data->manager, instance->target, instance->direction); 309 315 assert(toggle == 0 || toggle == 1); 310 316 … … 337 343 } 338 344 td_set_ioc(&data->tds[packet - 1]); 339 device_keeper_set_toggle(data->manager, instance->target, toggle); 345 device_keeper_set_toggle(data->manager, instance->target, 346 instance->direction, toggle); 340 347 } 341 348 /*----------------------------------------------------------------------------*/ -
uspace/lib/usb/include/usb/host/batch.h
r0e45e7f r48fe0c9 46 46 usb_transfer_type_t transfer_type; 47 47 usb_speed_t speed; 48 usb_direction_t direction; 48 49 usbhc_iface_transfer_in_callback_t callback_in; 49 50 usbhc_iface_transfer_out_callback_t callback_out; -
uspace/lib/usb/include/usb/host/device_keeper.h
r0e45e7f r48fe0c9 44 44 usb_speed_t speed; 45 45 bool occupied; 46 uint16_t toggle_status ;46 uint16_t toggle_status[2]; 47 47 devman_handle_t handle; 48 48 }; … … 63 63 64 64 void device_keeper_reset_if_need( 65 device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data); 65 device_keeper_t *instance, usb_target_t target, 66 const unsigned char *setup_data); 66 67 67 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target); 68 int device_keeper_get_toggle( 69 device_keeper_t *instance, usb_target_t target, usb_direction_t direction); 68 70 69 int device_keeper_set_toggle( 70 device_keeper_t *instance, usb_target_t target, bool toggle);71 int device_keeper_set_toggle(device_keeper_t *instance, 72 usb_target_t target, usb_direction_t direction, bool toggle); 71 73 72 74 usb_address_t device_keeper_request( -
uspace/lib/usb/src/host/batch.c
r0e45e7f r48fe0c9 62 62 instance->transfer_type = transfer_type; 63 63 instance->speed = speed; 64 instance->direction = USB_DIRECTION_BOTH; 64 65 instance->callback_in = func_in; 65 66 instance->callback_out = func_out; -
uspace/lib/usb/src/host/device_keeper.c
r0e45e7f r48fe0c9 55 55 instance->devices[i].occupied = false; 56 56 instance->devices[i].handle = 0; 57 instance->devices[i].toggle_status = 0; 57 instance->devices[i].toggle_status[0] = 0; 58 instance->devices[i].toggle_status[1] = 0; 58 59 } 59 60 } … … 118 119 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 119 120 /* endpoint number is < 16, thus first byte is enough */ 120 instance->devices[target.address].toggle_status &= 121 instance->devices[target.address].toggle_status[0] &= 122 ~(1 << data[4]); 123 instance->devices[target.address].toggle_status[1] &= 121 124 ~(1 << data[4]); 122 125 } … … 127 130 /* target must be device */ 128 131 if ((data[0] & 0xf) == 0) { 129 instance->devices[target.address].toggle_status = 0; 132 instance->devices[target.address].toggle_status[0] = 0; 133 instance->devices[target.address].toggle_status[1] = 0; 130 134 } 131 135 break; … … 140 144 * @return Error code 141 145 */ 142 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target) 143 { 144 assert(instance); 146 int device_keeper_get_toggle( 147 device_keeper_t *instance, usb_target_t target, usb_direction_t direction) 148 { 149 assert(instance); 150 /* only control pipes are bi-directional and those do not need toggle */ 151 if (direction == USB_DIRECTION_BOTH) 152 return ENOENT; 145 153 int ret; 146 154 fibril_mutex_lock(&instance->guard); … … 151 159 ret = EINVAL; 152 160 } else { 153 ret = (instance->devices[target.address].toggle_status 161 ret = (instance->devices[target.address].toggle_status[direction] 154 162 >> target.endpoint) & 1; 155 163 } … … 165 173 * @return Error code. 166 174 */ 167 int device_keeper_set_toggle( 168 device_keeper_t *instance, usb_target_t target, bool toggle) 169 { 170 assert(instance); 175 int device_keeper_set_toggle(device_keeper_t *instance, 176 usb_target_t target, usb_direction_t direction, bool toggle) 177 { 178 assert(instance); 179 /* only control pipes are bi-directional and those do not need toggle */ 180 if (direction == USB_DIRECTION_BOTH) 181 return ENOENT; 171 182 int ret; 172 183 fibril_mutex_lock(&instance->guard); … … 178 189 } else { 179 190 if (toggle) { 180 instance->devices[target.address].toggle_status |= (1 << target.endpoint); 191 instance->devices[target.address].toggle_status[direction] 192 |= (1 << target.endpoint); 181 193 } else { 182 instance->devices[target.address].toggle_status &= ~(1 << target.endpoint); 194 instance->devices[target.address].toggle_status[direction] 195 &= ~(1 << target.endpoint); 183 196 } 184 197 ret = EOK; … … 215 228 instance->devices[new_address].occupied = true; 216 229 instance->devices[new_address].speed = speed; 217 instance->devices[new_address].toggle_status = 0; 230 instance->devices[new_address].toggle_status[0] = 0; 231 instance->devices[new_address].toggle_status[1] = 0; 218 232 instance->last_address = new_address; 219 233 fibril_mutex_unlock(&instance->guard);
Note:
See TracChangeset
for help on using the changeset viewer.