Changeset fd07e526 in mainline for uspace/drv/bus/usb/ohci


Ignore:
Timestamp:
2011-09-16T14:50:20Z (15 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
432a269, d1e18573
Parents:
47fecbb (diff), 82a31261 (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.
Message:

Merge USB changes from bzr://krabicka.net/orome/helenos/usb/

  • Move common HC code from uhci/ohci drivers to libusbhost
  • Rewrite USB HC interface to have common read/write functions for all transfer types.
  • Restructure hc drivers to avoid some hooks and void* casts
  • Cleanup the code and remove unnecessary mallocs.
Location:
uspace/drv/bus/usb/ohci
Files:
1 added
3 deleted
11 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/Makefile

    r47fecbb rfd07e526  
    4444
    4545SOURCES = \
    46         batch.c \
    4746        endpoint_list.c \
    4847        hc.c \
    49         hcd_endpoint.c \
    50         iface.c \
    5148        main.c \
    5249        ohci.c \
     50        ohci_batch.c \
     51        ohci_endpoint.c \
    5352        pci.c \
    5453        root_hub.c \
  • uspace/drv/bus/usb/ohci/endpoint_list.c

    r47fecbb rfd07e526  
    8787 * The endpoint is added to the end of the list and queue.
    8888 */
    89 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
     89void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep)
    9090{
    9191        assert(instance);
    92         assert(hcd_ep);
    93         usb_log_debug2("Queue %s: Adding endpoint(%p).\n",
    94             instance->name, hcd_ep);
     92        assert(ep);
     93        usb_log_debug2("Queue %s: Adding endpoint(%p).\n", instance->name, ep);
    9594
    9695        fibril_mutex_lock(&instance->guard);
     
    103102        } else {
    104103                /* There are active EDs, get the last one */
    105                 hcd_endpoint_t *last = list_get_instance(
    106                     list_last(&instance->endpoint_list), hcd_endpoint_t, link);
     104                ohci_endpoint_t *last = list_get_instance(
     105                    list_last(&instance->endpoint_list), ohci_endpoint_t, link);
    107106                last_ed = last->ed;
    108107        }
    109108        /* Keep link */
    110         hcd_ep->ed->next = last_ed->next;
     109        ep->ed->next = last_ed->next;
    111110        /* Make sure ED is written to the memory */
    112111        write_barrier();
    113112
    114113        /* Add ed to the hw queue */
    115         ed_append_ed(last_ed, hcd_ep->ed);
     114        ed_append_ed(last_ed, ep->ed);
    116115        /* Make sure ED is updated */
    117116        write_barrier();
    118117
    119118        /* Add to the sw list */
    120         list_append(&hcd_ep->link, &instance->endpoint_list);
     119        list_append(&ep->link, &instance->endpoint_list);
    121120
    122         hcd_endpoint_t *first = list_get_instance(
    123             list_first(&instance->endpoint_list), hcd_endpoint_t, link);
     121        ohci_endpoint_t *first = list_get_instance(
     122            list_first(&instance->endpoint_list), ohci_endpoint_t, link);
    124123        usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
    125                 hcd_ep, instance->name, first, first->ed);
     124                ep, instance->name, first, first->ed);
    126125        if (last_ed == instance->list_head) {
    127126                usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x:%x:%x.\n",
     
    138137 * @param[in] endpoint Endpoint to remove.
    139138 */
    140 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
     139void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep)
    141140{
    142141        assert(instance);
    143142        assert(instance->list_head);
    144         assert(hcd_ep);
    145         assert(hcd_ep->ed);
     143        assert(ep);
     144        assert(ep->ed);
    146145
    147146        fibril_mutex_lock(&instance->guard);
    148147
    149         usb_log_debug2(
    150             "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep);
     148        usb_log_debug2("Queue %s: removing endpoint(%p).\n", instance->name, ep);
    151149
    152150        const char *qpos = NULL;
    153151        ed_t *prev_ed;
    154152        /* Remove from the hardware queue */
    155         if (list_first(&instance->endpoint_list) == &hcd_ep->link) {
     153        if (list_first(&instance->endpoint_list) == &ep->link) {
    156154                /* I'm the first one here */
    157155                prev_ed = instance->list_head;
    158156                qpos = "FIRST";
    159157        } else {
    160                 hcd_endpoint_t *prev =
    161                     list_get_instance(hcd_ep->link.prev, hcd_endpoint_t, link);
     158                ohci_endpoint_t *prev =
     159                    list_get_instance(ep->link.prev, ohci_endpoint_t, link);
    162160                prev_ed = prev->ed;
    163161                qpos = "NOT FIRST";
    164162        }
    165         assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed));
    166         prev_ed->next = hcd_ep->ed->next;
     163        assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(ep->ed));
     164        prev_ed->next = ep->ed->next;
    167165        /* Make sure ED is updated */
    168166        write_barrier();
    169167
    170168        usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n",
    171             hcd_ep, qpos, instance->name, hcd_ep->ed->next);
     169            ep, qpos, instance->name, ep->ed->next);
    172170
    173171        /* Remove from the endpoint list */
    174         list_remove(&hcd_ep->link);
     172        list_remove(&ep->link);
    175173        fibril_mutex_unlock(&instance->guard);
    176174}
  • uspace/drv/bus/usb/ohci/endpoint_list.h

    r47fecbb rfd07e526  
    3737#include <fibril_synch.h>
    3838
    39 #include "hcd_endpoint.h"
     39#include "ohci_endpoint.h"
    4040#include "hw_struct/endpoint_descriptor.h"
    4141#include "utils/malloc32.h"
     
    6969int endpoint_list_init(endpoint_list_t *instance, const char *name);
    7070void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next);
    71 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
    72 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
     71void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep);
     72void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep);
    7373#endif
    7474/**
  • uspace/drv/bus/usb/ohci/hc.c

    r47fecbb rfd07e526  
    4242
    4343#include "hc.h"
    44 #include "hcd_endpoint.h"
     44#include "ohci_endpoint.h"
    4545
    4646#define OHCI_USED_INTERRUPTS \
     
    6161static int hc_init_memory(hc_t *instance);
    6262static int interrupt_emulator(hc_t *instance);
    63 
     63static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6464/*----------------------------------------------------------------------------*/
    6565/** Get number of commands used in IRQ code.
     
    128128
    129129        const usb_address_t hub_address =
    130             device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
     130            usb_device_manager_get_free_address(
     131                &instance->generic.dev_manager, USB_SPEED_FULL);
    131132        if (hub_address <= 0) {
    132133                usb_log_error("Failed to get OHCI root hub address: %s\n",
     
    135136        }
    136137        instance->rh.address = hub_address;
    137         usb_device_keeper_bind(
    138             &instance->manager, hub_address, hub_fun->handle);
    139 
    140 #define CHECK_RET_RELEASE(ret, message...) \
     138        usb_device_manager_bind(
     139            &instance->generic.dev_manager, hub_address, hub_fun->handle);
     140
     141#define CHECK_RET_UNREG_RETURN(ret, message...) \
    141142if (ret != EOK) { \
    142143        usb_log_error(message); \
    143         hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \
    144         usb_device_keeper_release(&instance->manager, hub_address); \
     144        usb_endpoint_manager_unregister_ep( \
     145            &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\
     146        usb_device_manager_release( \
     147            &instance->generic.dev_manager, hub_address); \
    145148        return ret; \
    146149} else (void)0
    147 
    148         int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
    149             USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0);
    150         CHECK_RET_RELEASE(ret,
    151             "Failed to add OHCI root hub endpoint 0: %s.\n", str_error(ret));
     150        int ret = usb_endpoint_manager_add_ep(
     151            &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH,
     152            USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0);
     153        CHECK_RET_UNREG_RETURN(ret,
     154            "Failed to register root hub control endpoint: %s.\n",
     155            str_error(ret));
    152156
    153157        ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
    154         CHECK_RET_RELEASE(ret,
     158        CHECK_RET_UNREG_RETURN(ret,
    155159            "Failed to add root hub match-id: %s.\n", str_error(ret));
    156160
    157161        ret = ddf_fun_bind(hub_fun);
    158         CHECK_RET_RELEASE(ret,
     162        CHECK_RET_UNREG_RETURN(ret,
    159163            "Failed to bind root hub function: %s.\n", str_error(ret));
    160164
     
    187191
    188192        list_initialize(&instance->pending_batches);
    189         usb_device_keeper_init(&instance->manager);
    190 
    191         ret = usb_endpoint_manager_init(&instance->ep_manager,
    192             BANDWIDTH_AVAILABLE_USB11);
    193         CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
     193
     194        ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,
     195            bandwidth_count_usb11);
     196        CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n",
    194197            str_error(ret));
     198        instance->generic.private_data = instance;
     199        instance->generic.schedule = hc_schedule;
     200        instance->generic.ep_add_hook = ohci_endpoint_init;
    195201
    196202        ret = hc_init_memory(instance);
     
    215221}
    216222/*----------------------------------------------------------------------------*/
    217 /** Create and register endpoint structures.
    218  *
    219  * @param[in] instance OHCI driver structure.
    220  * @param[in] address USB address of the device.
    221  * @param[in] endpoint USB endpoint number.
    222  * @param[in] speed Communication speeed of the device.
    223  * @param[in] type Endpoint's transfer type.
    224  * @param[in] direction Endpoint's direction.
    225  * @param[in] mps Maximum packet size the endpoint accepts.
    226  * @param[in] size Maximum allowed buffer size.
    227  * @param[in] interval Time between transfers(interrupt transfers only).
    228  * @return Error code
    229  */
    230 int hc_add_endpoint(
    231     hc_t *instance, usb_address_t address, usb_endpoint_t endpoint,
    232     usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction,
    233     size_t mps, size_t size, unsigned interval)
    234 {
    235         endpoint_t *ep =
    236             endpoint_get(address, endpoint, direction, type, speed, mps);
    237         if (ep == NULL)
    238                 return ENOMEM;
    239 
    240         hcd_endpoint_t *hcd_ep = hcd_endpoint_assign(ep);
    241         if (hcd_ep == NULL) {
    242                 endpoint_destroy(ep);
    243                 return ENOMEM;
    244         }
    245 
    246         int ret =
    247             usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size);
    248         if (ret != EOK) {
    249                 hcd_endpoint_clear(ep);
    250                 endpoint_destroy(ep);
    251                 return ret;
    252         }
    253 
    254         /* Enqueue hcd_ep */
     223void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep)
     224{
     225        endpoint_list_t *list = &instance->lists[ep->transfer_type];
     226        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
     227        /* Enqueue ep */
    255228        switch (ep->transfer_type) {
    256229        case USB_TRANSFER_CONTROL:
    257230                instance->registers->control &= ~C_CLE;
    258                 endpoint_list_add_ep(
    259                     &instance->lists[ep->transfer_type], hcd_ep);
     231                endpoint_list_add_ep(list, ohci_ep);
    260232                instance->registers->control_current = 0;
    261233                instance->registers->control |= C_CLE;
     
    263235        case USB_TRANSFER_BULK:
    264236                instance->registers->control &= ~C_BLE;
    265                 endpoint_list_add_ep(
    266                     &instance->lists[ep->transfer_type], hcd_ep);
     237                endpoint_list_add_ep(list, ohci_ep);
    267238                instance->registers->control |= C_BLE;
    268239                break;
     
    270241        case USB_TRANSFER_INTERRUPT:
    271242                instance->registers->control &= (~C_PLE & ~C_IE);
    272                 endpoint_list_add_ep(
    273                     &instance->lists[ep->transfer_type], hcd_ep);
     243                endpoint_list_add_ep(list, ohci_ep);
    274244                instance->registers->control |= C_PLE | C_IE;
    275245                break;
    276246        }
    277 
    278         return EOK;
    279 }
    280 /*----------------------------------------------------------------------------*/
    281 /** Dequeue and delete endpoint structures
    282  *
    283  * @param[in] instance OHCI hc driver structure.
    284  * @param[in] address USB address of the device.
    285  * @param[in] endpoint USB endpoint number.
    286  * @param[in] direction Direction of the endpoint.
    287  * @return Error code
    288  */
    289 int hc_remove_endpoint(hc_t *instance, usb_address_t address,
    290     usb_endpoint_t endpoint, usb_direction_t direction)
    291 {
    292         assert(instance);
    293         fibril_mutex_lock(&instance->guard);
    294         endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager,
    295             address, endpoint, direction, NULL);
    296         if (ep == NULL) {
    297                 usb_log_error("Endpoint unregister failed: No such EP.\n");
    298                 fibril_mutex_unlock(&instance->guard);
    299                 return ENOENT;
    300         }
    301 
    302         hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
    303         if (hcd_ep) {
    304                 /* Dequeue hcd_ep */
    305                 switch (ep->transfer_type) {
    306                 case USB_TRANSFER_CONTROL:
    307                         instance->registers->control &= ~C_CLE;
    308                         endpoint_list_remove_ep(
    309                             &instance->lists[ep->transfer_type], hcd_ep);
    310                         instance->registers->control_current = 0;
    311                         instance->registers->control |= C_CLE;
    312                         break;
    313                 case USB_TRANSFER_BULK:
    314                         instance->registers->control &= ~C_BLE;
    315                         endpoint_list_remove_ep(
    316                             &instance->lists[ep->transfer_type], hcd_ep);
    317                         instance->registers->control |= C_BLE;
    318                         break;
    319                 case USB_TRANSFER_ISOCHRONOUS:
    320                 case USB_TRANSFER_INTERRUPT:
    321                         instance->registers->control &= (~C_PLE & ~C_IE);
    322                         endpoint_list_remove_ep(
    323                             &instance->lists[ep->transfer_type], hcd_ep);
    324                         instance->registers->control |= C_PLE | C_IE;
    325                         break;
    326                 default:
    327                         break;
    328                 }
    329                 hcd_endpoint_clear(ep);
    330         } else {
    331                 usb_log_warning("Endpoint without hcd equivalent structure.\n");
    332         }
    333         int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager,
    334             address, endpoint, direction);
    335         fibril_mutex_unlock(&instance->guard);
    336         return ret;
    337 }
    338 /*----------------------------------------------------------------------------*/
    339 /** Get access to endpoint structures
    340  *
    341  * @param[in] instance OHCI hc driver structure.
    342  * @param[in] address USB address of the device.
    343  * @param[in] endpoint USB endpoint number.
    344  * @param[in] direction Direction of the endpoint.
    345  * @param[out] bw Reserved bandwidth.
    346  * @return Error code
    347  */
    348 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,
    349     usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw)
    350 {
    351         assert(instance);
    352         fibril_mutex_lock(&instance->guard);
    353         endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager,
    354             address, endpoint, direction, bw);
    355         fibril_mutex_unlock(&instance->guard);
    356         return ep;
     247}
     248/*----------------------------------------------------------------------------*/
     249void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep)
     250{
     251        /* Dequeue ep */
     252        endpoint_list_t *list = &instance->lists[ep->transfer_type];
     253        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
     254        switch (ep->transfer_type) {
     255        case USB_TRANSFER_CONTROL:
     256                instance->registers->control &= ~C_CLE;
     257                endpoint_list_remove_ep(list, ohci_ep);
     258                instance->registers->control_current = 0;
     259                instance->registers->control |= C_CLE;
     260                break;
     261        case USB_TRANSFER_BULK:
     262                instance->registers->control &= ~C_BLE;
     263                endpoint_list_remove_ep(list, ohci_ep);
     264                instance->registers->control |= C_BLE;
     265                break;
     266        case USB_TRANSFER_ISOCHRONOUS:
     267        case USB_TRANSFER_INTERRUPT:
     268                instance->registers->control &= (~C_PLE & ~C_IE);
     269                endpoint_list_remove_ep(list, ohci_ep);
     270                instance->registers->control |= C_PLE | C_IE;
     271                break;
     272        default:
     273                break;
     274        }
    357275}
    358276/*----------------------------------------------------------------------------*/
     
    363281 * @return Error code.
    364282 */
    365 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
    366 {
    367         assert(instance);
    368         assert(batch);
    369         assert(batch->ep);
     283int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     284{
     285        assert(hcd);
     286        hc_t *instance = hcd->private_data;
     287        assert(instance);
    370288
    371289        /* Check for root hub communication */
     
    374292                return EOK;
    375293        }
     294        ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);
     295        if (!ohci_batch)
     296                return ENOMEM;
    376297
    377298        fibril_mutex_lock(&instance->guard);
    378         list_append(&batch->link, &instance->pending_batches);
    379         batch_commit(batch);
     299        list_append(&ohci_batch->link, &instance->pending_batches);
     300        ohci_transfer_batch_commit(ohci_batch);
    380301
    381302        /* Control and bulk schedules need a kick to start working */
     
    417338                    instance->registers->periodic_current);
    418339
    419                 link_t *current = instance->pending_batches.head.next;
    420                 while (current != &instance->pending_batches.head) {
     340                link_t *current = list_first(&instance->pending_batches);
     341                while (current && current != &instance->pending_batches.head) {
    421342                        link_t *next = current->next;
    422                         usb_transfer_batch_t *batch =
    423                             usb_transfer_batch_from_link(current);
    424 
    425                         if (batch_is_complete(batch)) {
     343                        ohci_transfer_batch_t *batch =
     344                            ohci_transfer_batch_from_link(current);
     345
     346                        if (ohci_transfer_batch_is_complete(batch)) {
    426347                                list_remove(current);
    427                                 usb_transfer_batch_finish(batch);
     348                                ohci_transfer_batch_finish_dispose(batch);
    428349                        }
    429350
     
    434355
    435356        if (status & I_UE) {
     357                usb_log_fatal("Error like no other!\n");
    436358                hc_start(instance);
    437359        }
  • uspace/drv/bus/usb/ohci/hc.h

    r47fecbb rfd07e526  
    4141
    4242#include <usb/usb.h>
    43 #include <usb/host/device_keeper.h>
    44 #include <usb/host/usb_endpoint_manager.h>
    45 #include <usbhc_iface.h>
     43#include <usb/host/hcd.h>
    4644
    47 #include "batch.h"
     45#include "ohci_batch.h"
    4846#include "ohci_regs.h"
    4947#include "root_hub.h"
     
    5351/** Main OHCI driver structure */
    5452typedef struct hc {
    55         /** USB bus driver, devices and addresses */
    56         usb_device_keeper_t manager;
    57         /** USB bus driver, endpoints */
    58         usb_endpoint_manager_t ep_manager;
     53        /** Generic USB hc driver */
     54        hcd_t generic;
    5955
    6056        /** Memory mapped I/O registers area */
     
    8177int hc_get_irq_commands(
    8278    irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     79int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8380int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
    84 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8581
    8682/** Safely dispose host controller internal structures
     
    8884 * @param[in] instance Host controller structure to use.
    8985 */
    90 static inline void hc_fini(hc_t *instance)
    91         { /* TODO: implement*/ };
     86static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
    9287
    93 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep,
    94     usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction,
    95     size_t max_packet_size, size_t size, unsigned interval);
    96 int hc_remove_endpoint(hc_t *instance, usb_address_t address,
    97     usb_endpoint_t endpoint, usb_direction_t direction);
    98 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,
    99     usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw);
     88void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep);
     89void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep);
    10090
    101 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
    10291void hc_interrupt(hc_t *instance, uint32_t status);
    103 
    104 /** Get and cast pointer to the driver data
    105  *
    106  * @param[in] fun DDF function pointer
    107  * @return cast pointer to driver_data
    108  */
    109 static inline hc_t * fun_to_hc(ddf_fun_t *fun)
    110         { return fun->driver_data; }
    11192#endif
    11293/**
  • uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c

    r47fecbb rfd07e526  
    3939static unsigned togg[2] = { TD_STATUS_T_0, TD_STATUS_T_1 };
    4040
    41 void td_init(
    42     td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle)
     41void td_init(td_t *instance,
     42    usb_direction_t dir, const void *buffer, size_t size, int toggle)
    4343{
    4444        assert(instance);
  • uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h

    r47fecbb rfd07e526  
    7575} __attribute__((packed)) td_t;
    7676
    77 void td_init(
    78     td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle);
     77void td_init(td_t *instance,
     78    usb_direction_t dir, const void *buffer, size_t size, int toggle);
    7979
    8080inline static void td_set_next(td_t *instance, td_t *next)
  • uspace/drv/bus/usb/ohci/ohci.c

    r47fecbb rfd07e526  
    4242
    4343#include "ohci.h"
    44 #include "iface.h"
    4544#include "pci.h"
    4645#include "hc.h"
    47 #include "root_hub.h"
    4846
    4947typedef struct ohci {
     
    5250
    5351        hc_t hc;
    54         rh_t rh;
    5552} ohci_t;
    5653
     
    8986{
    9087        assert(fun);
    91         usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
    92 
    93         usb_address_t addr = usb_device_keeper_find(manager, handle);
     88        usb_device_manager_t *manager =
     89            &dev_to_ohci(fun->dev)->hc.generic.dev_manager;
     90
     91        const usb_address_t addr = usb_device_manager_find(manager, handle);
    9492        if (addr < 0) {
    9593                return addr;
     
    129127/** Standard USB HC options (HC interface) */
    130128static ddf_dev_ops_t hc_ops = {
    131         .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
     129        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    132130};
    133131/*----------------------------------------------------------------------------*/
     
    150148int device_setup_ohci(ddf_dev_t *device)
    151149{
     150        assert(device);
     151
    152152        ohci_t *instance = malloc(sizeof(ohci_t));
    153153        if (instance == NULL) {
     
    155155                return ENOMEM;
    156156        }
     157        instance->rh_fun = NULL;
     158        instance->hc_fun = NULL;
    157159
    158160#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    159161if (ret != EOK) { \
    160162        if (instance->hc_fun) { \
    161                 instance->hc_fun->ops = NULL; \
    162                 instance->hc_fun->driver_data = NULL; \
    163163                ddf_fun_destroy(instance->hc_fun); \
    164164        } \
    165165        if (instance->rh_fun) { \
    166                 instance->rh_fun->ops = NULL; \
    167                 instance->rh_fun->driver_data = NULL; \
    168166                ddf_fun_destroy(instance->rh_fun); \
    169167        } \
    170168        free(instance); \
    171         device->driver_data = NULL; \
    172169        usb_log_error(message); \
    173170        return ret; \
    174171} else (void)0
    175172
    176         instance->rh_fun = NULL;
    177173        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    178174        int ret = instance->hc_fun ? EOK : ENOMEM;
     
    194190        ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
    195191        CHECK_RET_DEST_FREE_RETURN(ret,
    196             "Failed to get memory addresses for %" PRIun ": %s.\n",
     192            "Failed to get register memory addresses for %" PRIun ": %s.\n",
    197193            device->handle, str_error(ret));
    198194        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
     
    201197        const size_t cmd_count = hc_irq_cmd_count();
    202198        irq_cmd_t irq_cmds[cmd_count];
     199        irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
     200
    203201        ret =
    204202            hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
     
    206204            "Failed to generate IRQ commands: %s.\n", str_error(ret));
    207205
    208         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
    209206
    210207        /* Register handler to avoid interrupt lockup */
     
    234231#define CHECK_RET_FINI_RETURN(ret, message...) \
    235232if (ret != EOK) { \
     233        hc_fini(&instance->hc); \
    236234        unregister_interrupt_handler(device, irq); \
    237         hc_fini(&instance->hc); \
    238235        CHECK_RET_DEST_FREE_RETURN(ret, message); \
    239236} else (void)0
     
    248245            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    249246
    250         hc_register_hub(&instance->hc, instance->rh_fun);
    251         return EOK;
    252 
    253 #undef CHECK_RET_DEST_FUN_RETURN
     247        ret = hc_register_hub(&instance->hc, instance->rh_fun);
     248        CHECK_RET_FINI_RETURN(ret,
     249            "Failed to register OHCI root hub: %s.\n", str_error(ret));
     250        return ret;
     251
    254252#undef CHECK_RET_FINI_RETURN
    255253}
  • uspace/drv/bus/usb/ohci/ohci_batch.h

    r47fecbb rfd07e526  
    3535#define DRV_OHCI_BATCH_H
    3636
     37#include <adt/list.h>
    3738#include <usbhc_iface.h>
    3839#include <usb/usb.h>
    39 #include <usb/host/device_keeper.h>
    40 #include <usb/host/endpoint.h>
    41 #include <usb/host/batch.h>
     40#include <usb/host/usb_transfer_batch.h>
    4241
    43 usb_transfer_batch_t * batch_get(
    44     ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    45     const char *setup_buffer, size_t setup_size,
    46     usbhc_iface_transfer_in_callback_t func_in,
    47     usbhc_iface_transfer_out_callback_t func_out,
    48     void *arg);
     42#include "hw_struct/transfer_descriptor.h"
     43#include "hw_struct/endpoint_descriptor.h"
    4944
    50 bool batch_is_complete(usb_transfer_batch_t *instance);
     45/** OHCI specific data required for USB transfer */
     46typedef struct ohci_transfer_batch {
     47        /** Link */
     48        link_t link;
     49        /** Endpoint descriptor of the target endpoint. */
     50        ed_t *ed;
     51        /** List of TDs needed for the transfer */
     52        td_t **tds;
     53        /** Number of TDs used by the transfer */
     54        size_t td_count;
     55        /** Dummy TD to be left at the ED and used by the next transfer */
     56        size_t leave_td;
     57        /** Data buffer, must be accessible by the OHCI hw. */
     58        char *device_buffer;
     59        /** Generic USB transfer structure */
     60        usb_transfer_batch_t *usb_batch;
     61} ohci_transfer_batch_t;
    5162
    52 void batch_commit(usb_transfer_batch_t *instance);
    53 
    54 void batch_control_write(usb_transfer_batch_t *instance);
    55 
    56 void batch_control_read(usb_transfer_batch_t *instance);
    57 
    58 void batch_interrupt_in(usb_transfer_batch_t *instance);
    59 
    60 void batch_interrupt_out(usb_transfer_batch_t *instance);
    61 
    62 void batch_bulk_in(usb_transfer_batch_t *instance);
    63 
    64 void batch_bulk_out(usb_transfer_batch_t *instance);
     63ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *batch);
     64bool ohci_transfer_batch_is_complete(ohci_transfer_batch_t *batch);
     65void ohci_transfer_batch_commit(ohci_transfer_batch_t *batch);
     66void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *batch);
     67/*----------------------------------------------------------------------------*/
     68static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l)
     69{
     70        assert(l);
     71        return list_get_instance(l, ohci_transfer_batch_t, link);
     72}
    6573#endif
    6674/**
  • uspace/drv/bus/usb/ohci/ohci_endpoint.c

    r47fecbb rfd07e526  
    3333 */
    3434#include "utils/malloc32.h"
    35 #include "hcd_endpoint.h"
     35#include "ohci_endpoint.h"
     36#include "hc.h"
    3637
    3738/** Callback to set toggle on ED.
     
    4041 * @param[in] toggle new value of toggle bit
    4142 */
    42 static void hcd_ep_toggle_set(void *hcd_ep, int toggle)
     43static void ohci_ep_toggle_set(void *ohci_ep, int toggle)
    4344{
    44         hcd_endpoint_t *instance = hcd_ep;
     45        ohci_endpoint_t *instance = ohci_ep;
    4546        assert(instance);
    4647        assert(instance->ed);
     
    5354 * @return Current value of toggle bit.
    5455 */
    55 static int hcd_ep_toggle_get(void *hcd_ep)
     56static int ohci_ep_toggle_get(void *ohci_ep)
    5657{
    57         hcd_endpoint_t *instance = hcd_ep;
     58        ohci_endpoint_t *instance = ohci_ep;
    5859        assert(instance);
    5960        assert(instance->ed);
    6061        return ed_toggle_get(instance->ed);
     62}
     63/*----------------------------------------------------------------------------*/
     64/** Disposes hcd endpoint structure
     65 *
     66 * @param[in] hcd_ep endpoint structure
     67 */
     68static void ohci_endpoint_fini(endpoint_t *ep)
     69{
     70        ohci_endpoint_t *instance = ep->hc_data.data;
     71        hc_dequeue_endpoint(instance->hcd->private_data, ep);
     72        if (instance) {
     73                free32(instance->ed);
     74                free32(instance->td);
     75                free(instance);
     76        }
    6177}
    6278/*----------------------------------------------------------------------------*/
     
    6682 * @return pointer to a new hcd endpoint structure, NULL on failure.
    6783 */
    68 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep)
     84int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep)
    6985{
    7086        assert(ep);
    71         hcd_endpoint_t *hcd_ep = malloc(sizeof(hcd_endpoint_t));
    72         if (hcd_ep == NULL)
    73                 return NULL;
     87        ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t));
     88        if (ohci_ep == NULL)
     89                return ENOMEM;
    7490
    75         hcd_ep->ed = malloc32(sizeof(ed_t));
    76         if (hcd_ep->ed == NULL) {
    77                 free(hcd_ep);
    78                 return NULL;
     91        ohci_ep->ed = malloc32(sizeof(ed_t));
     92        if (ohci_ep->ed == NULL) {
     93                free(ohci_ep);
     94                return ENOMEM;
    7995        }
    8096
    81         hcd_ep->td = malloc32(sizeof(td_t));
    82         if (hcd_ep->td == NULL) {
    83                 free32(hcd_ep->ed);
    84                 free(hcd_ep);
    85                 return NULL;
     97        ohci_ep->td = malloc32(sizeof(td_t));
     98        if (ohci_ep->td == NULL) {
     99                free32(ohci_ep->ed);
     100                free(ohci_ep);
     101                return ENOMEM;
    86102        }
    87103
    88         ed_init(hcd_ep->ed, ep);
    89         ed_set_td(hcd_ep->ed, hcd_ep->td);
    90         endpoint_set_hc_data(ep, hcd_ep, hcd_ep_toggle_get, hcd_ep_toggle_set);
    91 
    92         return hcd_ep;
    93 }
    94 /*----------------------------------------------------------------------------*/
    95 /** Disposes assigned hcd endpoint structure
    96  *
    97  * @param[in] ep USBD endpoint structure
    98  */
    99 void hcd_endpoint_clear(endpoint_t *ep)
    100 {
    101         assert(ep);
    102         hcd_endpoint_t *hcd_ep = ep->hc_data.data;
    103         assert(hcd_ep);
    104         free32(hcd_ep->ed);
    105         free32(hcd_ep->td);
    106         free(hcd_ep);
     104        ed_init(ohci_ep->ed, ep);
     105        ed_set_td(ohci_ep->ed, ohci_ep->td);
     106        endpoint_set_hc_data(
     107            ep, ohci_ep, ohci_endpoint_fini, ohci_ep_toggle_get, ohci_ep_toggle_set);
     108        ohci_ep->hcd = hcd;
     109        hc_enqueue_endpoint(hcd->private_data, ep);
     110        return EOK;
    107111}
    108112/**
  • uspace/drv/bus/usb/ohci/ohci_endpoint.h

    r47fecbb rfd07e526  
    3838#include <adt/list.h>
    3939#include <usb/host/endpoint.h>
     40#include <usb/host/hcd.h>
    4041
    4142#include "hw_struct/endpoint_descriptor.h"
     
    4344
    4445/** Connector structure linking ED to to prepared TD. */
    45 typedef struct hcd_endpoint {
     46typedef struct ohci_endpoint {
    4647        /** OHCI endpoint descriptor */
    4748        ed_t *ed;
     
    5051        /** Linked list used by driver software */
    5152        link_t link;
    52 } hcd_endpoint_t;
     53        /** Device using this ep */
     54        hcd_t *hcd;
     55} ohci_endpoint_t;
    5356
    54 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep);
    55 void hcd_endpoint_clear(endpoint_t *ep);
     57int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep);
    5658
    57 /** Get and convert assigned hcd_endpoint_t structure
     59/** Get and convert assigned ohci_endpoint_t structure
    5860 * @param[in] ep USBD endpoint structure.
    5961 * @return Pointer to assigned hcd endpoint structure
    6062 */
    61 static inline hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep)
     63static inline ohci_endpoint_t * ohci_endpoint_get(endpoint_t *ep)
    6264{
    6365        assert(ep);
  • uspace/drv/bus/usb/ohci/root_hub.c

    r47fecbb rfd07e526  
    121121        assert(request);
    122122
    123         memcpy(request->data_buffer, &mask, size);
    124123        request->transfered_size = size;
    125         usb_transfer_batch_finish_error(request, EOK);
     124        usb_transfer_batch_finish_error(request, &mask, size, EOK);
    126125}
    127126
     
    206205                usb_log_debug("Root hub got CONTROL packet\n");
    207206                const int ret = control_request(instance, request);
    208                 usb_transfer_batch_finish_error(request, ret);
     207                usb_transfer_batch_finish_error(request, NULL, 0, ret);
    209208                break;
    210209        case USB_TRANSFER_INTERRUPT:
     
    215214                        assert(instance->unfinished_interrupt_transfer == NULL);
    216215                        instance->unfinished_interrupt_transfer = request;
    217                         break;
     216                        return;
    218217                }
    219218                usb_log_debug("Processing changes...\n");
     
    223222        default:
    224223                usb_log_error("Root hub got unsupported request.\n");
    225                 usb_transfer_batch_finish_error(request, EINVAL);
    226         }
     224                usb_transfer_batch_finish_error(request, NULL, 0, EINVAL);
     225        }
     226        usb_transfer_batch_dispose(request);
    227227}
    228228/*----------------------------------------------------------------------------*/
     
    244244        interrupt_request(instance->unfinished_interrupt_transfer,
    245245            mask, instance->interrupt_mask_size);
     246        usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer);
    246247
    247248        instance->unfinished_interrupt_transfer = NULL;
     
    389390                const uint32_t data = instance->registers->rh_status &
    390391                    (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG);
    391                 memcpy(request->data_buffer, &data, 4);
    392                 TRANSFER_OK(4);
     392                memcpy(request->buffer, &data, sizeof(data));
     393                TRANSFER_OK(sizeof(data));
    393394        }
    394395
     
    402403                const uint32_t data =
    403404                    instance->registers->rh_port_status[port - 1];
    404                 memcpy(request->data_buffer, &data, 4);
    405                 TRANSFER_OK(4);
     405                memcpy(request->buffer, &data, sizeof(data));
     406                TRANSFER_OK(sizeof(data));
    406407        }
    407408
     
    483484        }
    484485
    485         memcpy(request->data_buffer, descriptor, size);
     486        memcpy(request->buffer, descriptor, size);
    486487        TRANSFER_OK(size);
    487488}
     
    713714                if (request->buffer_size != 1)
    714715                        return EINVAL;
    715                 request->data_buffer[0] = 1;
     716                request->buffer[0] = 1;
    716717                TRANSFER_OK(1);
    717718
  • uspace/drv/bus/usb/ohci/root_hub.h

    r47fecbb rfd07e526  
    3737#include <usb/usb.h>
    3838#include <usb/dev/driver.h>
     39#include <usb/host/usb_transfer_batch.h>
    3940
    4041#include "ohci_regs.h"
    41 #include "batch.h"
    4242
    4343#define HUB_DESCRIPTOR_MAX_SIZE (7 + 2 + 2)
     
    6666        /** size of hub descriptor */
    6767        size_t hub_descriptor_size;
    68 
    6968} rh_t;
    7069
  • uspace/drv/bus/usb/ohci/utils/malloc32.h

    r47fecbb rfd07e526  
    4646 * @return Physical address if exists, NULL otherwise.
    4747 */
    48 static inline uintptr_t addr_to_phys(void *addr)
     48static inline uintptr_t addr_to_phys(const void *addr)
    4949{
    5050        uintptr_t result;
Note: See TracChangeset for help on using the changeset viewer.