Changeset f1d6866 in mainline for uspace/drv


Ignore:
Timestamp:
2011-09-18T21:22:59Z (14 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
dcc44ca1
Parents:
85ff862 (diff), 45a9cf4 (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 mainline changes

Location:
uspace/drv
Files:
3 added
7 deleted
32 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/isa/isa.c

    r85ff862 rf1d6866  
    405405static void fun_hw_res_alloc(isa_fun_t *fun)
    406406{
    407         fun->hw_resources.resources = 
     407        fun->hw_resources.resources =
    408408            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    409409}
  • uspace/drv/bus/usb/ehci/hc_iface.c

    r85ff862 rf1d6866  
    145145}
    146146
    147 /** Schedule interrupt out transfer.
    148  *
    149  * The callback is supposed to be called once the transfer (on the wire) is
    150  * complete regardless of the outcome.
    151  * However, the callback could be called only when this function returns
    152  * with success status (i.e. returns EOK).
    153  *
    154  * @param[in] fun Device function the action was invoked on.
    155  * @param[in] target Target pipe (address and endpoint number) specification.
    156  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    157  *      by the caller).
    158  * @param[in] size Size of the @p data buffer in bytes.
    159  * @param[in] callback Callback to be issued once the transfer is complete.
    160  * @param[in] arg Pass-through argument to the callback.
    161  * @return Error code.
    162  */
    163 static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    164     void *data, size_t size,
    165     usbhc_iface_transfer_out_callback_t callback, void *arg)
    166 {
    167         UNSUPPORTED("interrupt_out");
    168 
    169         return ENOTSUP;
    170 }
    171 
    172 /** Schedule interrupt in transfer.
    173  *
    174  * The callback is supposed to be called once the transfer (on the wire) is
    175  * complete regardless of the outcome.
    176  * However, the callback could be called only when this function returns
    177  * with success status (i.e. returns EOK).
    178  *
    179  * @param[in] fun Device function the action was invoked on.
    180  * @param[in] target Target pipe (address and endpoint number) specification.
    181  * @param[in] data Buffer where to store the data (in USB endianess,
    182  *      allocated and deallocated by the caller).
    183  * @param[in] size Size of the @p data buffer in bytes.
    184  * @param[in] callback Callback to be issued once the transfer is complete.
    185  * @param[in] arg Pass-through argument to the callback.
    186  * @return Error code.
    187  */
    188 static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    189     void *data, size_t size,
    190     usbhc_iface_transfer_in_callback_t callback, void *arg)
    191 {
    192         UNSUPPORTED("interrupt_in");
    193 
    194         return ENOTSUP;
    195 }
    196 
    197 /** Schedule bulk out transfer.
    198  *
    199  * The callback is supposed to be called once the transfer (on the wire) is
    200  * complete regardless of the outcome.
    201  * However, the callback could be called only when this function returns
    202  * with success status (i.e. returns EOK).
    203  *
    204  * @param[in] fun Device function the action was invoked on.
    205  * @param[in] target Target pipe (address and endpoint number) specification.
    206  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    207  *      by the caller).
    208  * @param[in] size Size of the @p data buffer in bytes.
    209  * @param[in] callback Callback to be issued once the transfer is complete.
    210  * @param[in] arg Pass-through argument to the callback.
    211  * @return Error code.
    212  */
    213 static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    214     void *data, size_t size,
    215     usbhc_iface_transfer_out_callback_t callback, void *arg)
    216 {
    217         UNSUPPORTED("bulk_out");
    218 
    219         return ENOTSUP;
    220 }
    221 
    222 /** Schedule bulk in transfer.
    223  *
    224  * The callback is supposed to be called once the transfer (on the wire) is
    225  * complete regardless of the outcome.
    226  * However, the callback could be called only when this function returns
    227  * with success status (i.e. returns EOK).
    228  *
    229  * @param[in] fun Device function the action was invoked on.
    230  * @param[in] target Target pipe (address and endpoint number) specification.
    231  * @param[in] data Buffer where to store the data (in USB endianess,
    232  *      allocated and deallocated by the caller).
    233  * @param[in] size Size of the @p data buffer in bytes.
    234  * @param[in] callback Callback to be issued once the transfer is complete.
    235  * @param[in] arg Pass-through argument to the callback.
    236  * @return Error code.
    237  */
    238 static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    239     void *data, size_t size,
    240     usbhc_iface_transfer_in_callback_t callback, void *arg)
    241 {
    242         UNSUPPORTED("bulk_in");
    243 
    244         return ENOTSUP;
    245 }
    246 
    247 /** Schedule control write transfer.
    248  *
    249  * The callback is supposed to be called once the transfer (on the wire) is
    250  * complete regardless of the outcome.
    251  * However, the callback could be called only when this function returns
    252  * with success status (i.e. returns EOK).
    253  *
    254  * @param[in] fun Device function the action was invoked on.
    255  * @param[in] target Target pipe (address and endpoint number) specification.
    256  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    257  *      and deallocated by the caller).
    258  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    259  * @param[in] data_buffer Data buffer (in USB endianess, allocated and
    260  *      deallocated by the caller).
    261  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    262  * @param[in] callback Callback to be issued once the transfer is complete.
    263  * @param[in] arg Pass-through argument to the callback.
    264  * @return Error code.
    265  */
    266 static int control_write(ddf_fun_t *fun, usb_target_t target,
    267     void *setup_packet, size_t setup_packet_size,
    268     void *data_buffer, size_t data_buffer_size,
    269     usbhc_iface_transfer_out_callback_t callback, void *arg)
    270 {
    271         UNSUPPORTED("control_write");
    272 
    273         return ENOTSUP;
    274 }
    275 
    276 /** Schedule control read transfer.
    277  *
    278  * The callback is supposed to be called once the transfer (on the wire) is
    279  * complete regardless of the outcome.
    280  * However, the callback could be called only when this function returns
    281  * with success status (i.e. returns EOK).
    282  *
    283  * @param[in] fun Device function the action was invoked on.
    284  * @param[in] target Target pipe (address and endpoint number) specification.
    285  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    286  *      and deallocated by the caller).
    287  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    288  * @param[in] data_buffer Buffer where to store the data (in USB endianess,
    289  *      allocated and deallocated by the caller).
    290  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    291  * @param[in] callback Callback to be issued once the transfer is complete.
    292  * @param[in] arg Pass-through argument to the callback.
    293  * @return Error code.
    294  */
    295 static int control_read(ddf_fun_t *fun, usb_target_t target,
    296     void *setup_packet, size_t setup_packet_size,
    297     void *data_buffer, size_t data_buffer_size,
    298     usbhc_iface_transfer_in_callback_t callback, void *arg)
    299 {
    300         UNSUPPORTED("control_read");
    301 
    302         return ENOTSUP;
    303 }
    304 
    305147/** Host controller interface implementation for EHCI. */
    306148usbhc_iface_t ehci_hc_iface = {
     
    312154        .register_endpoint = register_endpoint,
    313155        .unregister_endpoint = unregister_endpoint,
    314 
    315         .interrupt_out = interrupt_out,
    316         .interrupt_in = interrupt_in,
    317 
    318         .bulk_out = bulk_out,
    319         .bulk_in = bulk_in,
    320 
    321         .control_write = control_write,
    322         .control_read = control_read
    323156};
    324157
  • uspace/drv/bus/usb/ohci/Makefile

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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/pci.c

    r85ff862 rf1d6866  
    7070        if (!parent_sess)
    7171                return ENOMEM;
    72        
     72
    7373        hw_resource_list_t hw_resources;
    7474        int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
     75        async_hangup(parent_sess);
    7576        if (rc != EOK) {
    76                 async_hangup(parent_sess);
    7777                return rc;
    7878        }
    79        
     79
    8080        uintptr_t mem_address = 0;
    8181        size_t mem_size = 0;
    8282        bool mem_found = false;
    83        
     83
    8484        int irq = 0;
    8585        bool irq_found = false;
    86        
     86
    8787        size_t i;
    8888        for (i = 0; i < hw_resources.count; i++) {
     
    107107                }
    108108        }
    109        
     109        free(hw_resources.resources);
     110
    110111        if (mem_found && irq_found) {
    111112                *mem_reg_address = mem_address;
    112113                *mem_reg_size = mem_size;
    113114                *irq_no = irq;
    114                 rc = EOK;
    115         } else
    116                 rc = ENOENT;
    117        
    118         async_hangup(parent_sess);
    119         return rc;
     115                return EOK;
     116        }
     117        return ENOENT;
    120118}
    121119
  • uspace/drv/bus/usb/ohci/root_hub.c

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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

    r85ff862 rf1d6866  
    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;
  • uspace/drv/bus/usb/uhci/Makefile

    r85ff862 rf1d6866  
    4242
    4343SOURCES = \
    44         iface.c \
     44        hc.c \
    4545        main.c \
     46        pci.c \
     47        root_hub.c \
    4648        transfer_list.c \
    4749        uhci.c \
    48         hc.c \
    49         root_hub.c \
    50         hw_struct/transfer_descriptor.c \
    51         pci.c \
    52         batch.c
     50        uhci_batch.c \
     51        hw_struct/transfer_descriptor.c
    5352
    5453include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/bus/usb/uhci/hc.c

    r85ff862 rf1d6866  
    4141
    4242#include "hc.h"
     43#include "uhci_batch.h"
    4344
    4445#define UHCI_INTR_ALLOW_INTERRUPTS \
     
    4647#define UHCI_STATUS_USED_INTERRUPTS \
    4748    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
     49
    4850
    4951static const irq_cmd_t uhci_irq_commands[] =
     
    5759};
    5860
     61static void hc_init_hw(const hc_t *instance);
     62static int hc_init_mem_structures(hc_t *instance);
    5963static int hc_init_transfer_lists(hc_t *instance);
    60 static int hc_init_mem_structures(hc_t *instance);
    61 static void hc_init_hw(hc_t *instance);
     64static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6265
    6366static int hc_interrupt_emulator(void *arg);
     
    9598        cmds[3].addr = (void*)&registers->usbsts;
    9699        return EOK;
     100}
     101/*----------------------------------------------------------------------------*/
     102/** Take action based on the interrupt cause.
     103 *
     104 * @param[in] instance UHCI structure to use.
     105 * @param[in] status Value of the status register at the time of interrupt.
     106 *
     107 * Interrupt might indicate:
     108 * - transaction completed, either by triggering IOC, SPD, or an error
     109 * - some kind of device error
     110 * - resume from suspend state (not implemented)
     111 */
     112void hc_interrupt(hc_t *instance, uint16_t status)
     113{
     114        assert(instance);
     115        /* Lower 2 bits are transaction error and transaction complete */
     116        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     117                LIST_INITIALIZE(done);
     118                transfer_list_remove_finished(
     119                    &instance->transfers_interrupt, &done);
     120                transfer_list_remove_finished(
     121                    &instance->transfers_control_slow, &done);
     122                transfer_list_remove_finished(
     123                    &instance->transfers_control_full, &done);
     124                transfer_list_remove_finished(
     125                    &instance->transfers_bulk_full, &done);
     126
     127                while (!list_empty(&done)) {
     128                        link_t *item = list_first(&done);
     129                        list_remove(item);
     130                        uhci_transfer_batch_t *batch =
     131                            uhci_transfer_batch_from_link(item);
     132                        uhci_transfer_batch_call_dispose(batch);
     133                }
     134        }
     135        /* Resume interrupts are not supported */
     136        if (status & UHCI_STATUS_RESUME) {
     137                usb_log_error("Resume interrupt!\n");
     138        }
     139
     140        /* Bits 4 and 5 indicate hc error */
     141        if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
     142                usb_log_error("UHCI hardware failure!.\n");
     143                ++instance->hw_failures;
     144                transfer_list_abort_all(&instance->transfers_interrupt);
     145                transfer_list_abort_all(&instance->transfers_control_slow);
     146                transfer_list_abort_all(&instance->transfers_control_full);
     147                transfer_list_abort_all(&instance->transfers_bulk_full);
     148
     149                if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
     150                        /* reinitialize hw, this triggers virtual disconnect*/
     151                        hc_init_hw(instance);
     152                } else {
     153                        usb_log_fatal("Too many UHCI hardware failures!.\n");
     154                        hc_fini(instance);
     155                }
     156        }
    97157}
    98158/*----------------------------------------------------------------------------*/
     
    132192            "Device registers at %p (%zuB) accessible.\n", io, reg_size);
    133193
     194        ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,
     195            bandwidth_count_usb11);
     196        CHECK_RET_RETURN(ret, "Failed to initialize HCD generic driver: %s.\n",
     197            str_error(ret));
     198
     199        instance->generic.private_data = instance;
     200        instance->generic.schedule = hc_schedule;
     201        instance->generic.ep_add_hook = NULL;
     202
     203#undef CHECK_RET_DEST_FUN_RETURN
     204
    134205        ret = hc_init_mem_structures(instance);
    135         CHECK_RET_RETURN(ret,
    136             "Failed to initialize UHCI memory structures: %s.\n",
    137             str_error(ret));
     206        if (ret != EOK) {
     207                usb_log_error(
     208                    "Failed to initialize UHCI memory structures: %s.\n",
     209                    str_error(ret));
     210                hcd_destroy(&instance->generic);
     211                return ret;
     212        }
    138213
    139214        hc_init_hw(instance);
     
    146221
    147222        return EOK;
    148 #undef CHECK_RET_DEST_FUN_RETURN
    149223}
    150224/*----------------------------------------------------------------------------*/
     
    154228 * For magic values see UHCI Design Guide
    155229 */
    156 void hc_init_hw(hc_t *instance)
     230void hc_init_hw(const hc_t *instance)
    157231{
    158232        assert(instance);
     
    198272 *
    199273 * Structures:
    200  *  - interrupt code (I/O addressses are customized per instance)
    201274 *  - transfer lists (queue heads need to be accessible by the hw)
    202275 *  - frame list page (needs to be one UHCI hw accessible 4K page)
     
    205278{
    206279        assert(instance);
    207 #define CHECK_RET_RETURN(ret, message...) \
    208         if (ret != EOK) { \
    209                 usb_log_error(message); \
    210                 return ret; \
    211         } else (void) 0
     280
     281        /* Init USB frame list page */
     282        instance->frame_list = get_page();
     283        if (!instance->frame_list) {
     284                return ENOMEM;
     285        }
     286        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    212287
    213288        /* Init transfer lists */
    214289        int ret = hc_init_transfer_lists(instance);
    215         CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     290        if (ret != EOK) {
     291                usb_log_error("Failed to initialize transfer lists.\n");
     292                return_page(instance->frame_list);
     293                return ENOMEM;
     294        }
    216295        usb_log_debug("Initialized transfer lists.\n");
    217296
    218         /* Init device keeper */
    219         usb_device_keeper_init(&instance->manager);
    220         usb_log_debug("Initialized device keeper.\n");
    221 
    222         ret = usb_endpoint_manager_init(&instance->ep_manager,
    223             BANDWIDTH_AVAILABLE_USB11);
    224         CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
    225             str_error(ret));
    226 
    227         /* Init USB frame list page*/
    228         instance->frame_list = get_page();
    229         if (!instance->frame_list) {
    230                 usb_log_error("Failed to get frame list page.\n");
    231                 usb_endpoint_manager_destroy(&instance->ep_manager);
    232                 return ENOMEM;
    233         }
    234         usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    235297
    236298        /* Set all frames to point to the first queue head */
     
    243305
    244306        return EOK;
    245 #undef CHECK_RET_RETURN
    246307}
    247308/*----------------------------------------------------------------------------*/
     
    316377 * Checks for bandwidth availability and appends the batch to the proper queue.
    317378 */
    318 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
    319 {
     379int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     380{
     381        assert(hcd);
     382        hc_t *instance = hcd->private_data;
    320383        assert(instance);
    321384        assert(batch);
     385        uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch);
     386        if (!uhci_batch) {
     387                usb_log_error("Failed to create UHCI transfer structures.\n");
     388                return ENOMEM;
     389        }
    322390
    323391        transfer_list_t *list =
    324392            instance->transfers[batch->ep->speed][batch->ep->transfer_type];
    325393        assert(list);
    326         transfer_list_add_batch(list, batch);
    327 
    328         return EOK;
    329 }
    330 /*----------------------------------------------------------------------------*/
    331 /** Take action based on the interrupt cause.
    332  *
    333  * @param[in] instance UHCI structure to use.
    334  * @param[in] status Value of the status register at the time of interrupt.
    335  *
    336  * Interrupt might indicate:
    337  * - transaction completed, either by triggering IOC, SPD, or an error
    338  * - some kind of device error
    339  * - resume from suspend state (not implemented)
    340  */
    341 void hc_interrupt(hc_t *instance, uint16_t status)
    342 {
    343         assert(instance);
    344         /* Lower 2 bits are transaction error and transaction complete */
    345         if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
    346                 LIST_INITIALIZE(done);
    347                 transfer_list_remove_finished(
    348                     &instance->transfers_interrupt, &done);
    349                 transfer_list_remove_finished(
    350                     &instance->transfers_control_slow, &done);
    351                 transfer_list_remove_finished(
    352                     &instance->transfers_control_full, &done);
    353                 transfer_list_remove_finished(
    354                     &instance->transfers_bulk_full, &done);
    355 
    356                 while (!list_empty(&done)) {
    357                         link_t *item = list_first(&done);
    358                         list_remove(item);
    359                         usb_transfer_batch_t *batch =
    360                             list_get_instance(item, usb_transfer_batch_t, link);
    361                         usb_transfer_batch_finish(batch);
    362                 }
    363         }
    364         /* Resume interrupts are not supported */
    365         if (status & UHCI_STATUS_RESUME) {
    366                 usb_log_error("Resume interrupt!\n");
    367         }
    368 
    369         /* Bits 4 and 5 indicate hc error */
    370         if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
    371                 usb_log_error("UHCI hardware failure!.\n");
    372                 ++instance->hw_failures;
    373                 transfer_list_abort_all(&instance->transfers_interrupt);
    374                 transfer_list_abort_all(&instance->transfers_control_slow);
    375                 transfer_list_abort_all(&instance->transfers_control_full);
    376                 transfer_list_abort_all(&instance->transfers_bulk_full);
    377 
    378                 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
    379                         /* reinitialize hw, this triggers virtual disconnect*/
    380                         hc_init_hw(instance);
    381                 } else {
    382                         usb_log_fatal("Too many UHCI hardware failures!.\n");
    383                         hc_fini(instance);
    384                 }
    385         }
     394        transfer_list_add_batch(list, uhci_batch);
     395
     396        return EOK;
    386397}
    387398/*----------------------------------------------------------------------------*/
     
    403414                if (status != 0)
    404415                        usb_log_debug2("UHCI status: %x.\n", status);
    405 // Qemu fails to report stalled communication
    406 // see https://bugs.launchpad.net/qemu/+bug/757654
    407 // This is a simple workaround to force queue processing every time
    408         //      status |= 1;
    409416                hc_interrupt(instance, status);
    410417                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     
    412419        return EOK;
    413420}
    414 /*---------------------------------------------------------------------------*/
     421/*----------------------------------------------------------------------------*/
    415422/** Debug function, checks consistency of memory structures.
    416423 *
  • uspace/drv/bus/usb/uhci/hc.h

    r85ff862 rf1d6866  
    3939#include <ddi.h>
    4040
    41 #include <usb/host/device_keeper.h>
    42 #include <usb/host/usb_endpoint_manager.h>
    43 #include <usb/host/batch.h>
     41#include <usb/host/hcd.h>
    4442
    4543#include "transfer_list.h"
     
    9492/** Main UHCI driver structure */
    9593typedef struct hc {
    96         /** USB bus driver, devices and addresses */
    97         usb_device_keeper_t manager;
    98         /** USB bus driver, endpoints */
    99         usb_endpoint_manager_t ep_manager;
     94        /** Generic HCD driver structure */
     95        hcd_t generic;
    10096
    10197        /** Addresses of I/O registers */
     
    124120        unsigned hw_failures;
    125121} hc_t;
     122
    126123size_t hc_irq_cmd_count(void);
    127124int hc_get_irq_commands(
    128125    irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     126void hc_interrupt(hc_t *instance, uint16_t status);
    129127int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
    130 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
    131 void hc_interrupt(hc_t *instance, uint16_t status);
    132128
    133129/** Safely dispose host controller internal structures
     
    135131 * @param[in] instance Host controller structure to use.
    136132 */
    137 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
    138 
    139 /** Get and cast pointer to the driver data
    140  *
    141  * @param[in] fun DDF function pointer
    142  * @return cast pointer to driver_data
    143  */
    144 static inline hc_t * fun_to_hc(ddf_fun_t *fun)
    145 {
    146         assert(fun);
    147         return fun->driver_data;
    148 }
     133static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/
    149134#endif
    150135/**
  • uspace/drv/bus/usb/uhci/hw_struct/link_pointer.h

    r85ff862 rf1d6866  
    3535#define DRV_UHCI_HW_STRUCT_LINK_POINTER_H
    3636
    37 /* UHCI link pointer, used by many data structures */
     37/** UHCI link pointer, used by many data structures */
    3838typedef uint32_t link_pointer_t;
    3939
  • uspace/drv/bus/usb/uhci/hw_struct/queue_head.h

    r85ff862 rf1d6866  
    5858        assert(instance);
    5959
    60         instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
    61         instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
     60        instance->element = LINK_POINTER_TERM;
     61        instance->next = LINK_POINTER_TERM;
    6262}
    6363/*----------------------------------------------------------------------------*/
     
    7171static inline void qh_set_next_qh(qh_t *instance, qh_t *next)
    7272{
    73         uint32_t pa = addr_to_phys(next);
     73        /* Physical address has to be below 4GB,
     74         * it is an UHCI limitation and malloc32
     75         * should guarantee this */
     76        const uint32_t pa = addr_to_phys(next);
    7477        if (pa) {
    7578                instance->next = LINK_POINTER_QH(pa);
     
    8891static inline void qh_set_element_td(qh_t *instance, td_t *td)
    8992{
    90         uint32_t pa = addr_to_phys(td);
     93        /* Physical address has to be below 4GB,
     94         * it is an UHCI limitation and malloc32
     95         * should guarantee this */
     96        const uint32_t pa = addr_to_phys(td);
    9197        if (pa) {
    9298                instance->element = LINK_POINTER_TD(pa);
  • uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.c

    r85ff862 rf1d6866  
    6161 */
    6262void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
    63     bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
    64     td_t *next)
     63    bool low_speed, usb_target_t target, usb_packet_id pid, const void *buffer,
     64    const td_t *next)
    6565{
    6666        assert(instance);
     
    113113 * @return Error code.
    114114 */
    115 int td_status(td_t *instance)
     115int td_status(const td_t *instance)
    116116{
    117117        assert(instance);
     
    119119        /* This is hc internal error it should never be reported. */
    120120        if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
    121                 return EAGAIN;
     121                return EIO;
    122122
    123123        /* CRC or timeout error, like device not present or bad data,
     
    150150 * @param[in] instance TD structure to use.
    151151 */
    152 void td_print_status(td_t *instance)
     152void td_print_status(const td_t *instance)
    153153{
    154154        assert(instance);
  • uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.h

    r85ff862 rf1d6866  
    6969#define TD_STATUS_ACTLEN_MASK 0x7ff
    7070
    71         /* double word with USB device specific info */
     71        /** Double word with USB device specific info */
    7272        volatile uint32_t device;
    7373#define TD_DEVICE_MAXLEN_POS 21
     
    8787        /* According to UHCI design guide, there is 16 bytes of
    8888         * data available here.
    89          * According to linux kernel the hardware does not care,
    90          * it just needs to be aligned. We don't use it anyway.
     89         * According to Linux kernel the hardware does not care,
     90         * memory just needs to be aligned. We don't use it anyway.
    9191         */
    9292} __attribute__((packed)) td_t;
     
    9595void td_init(td_t *instance, int error_count, size_t size, bool toggle,
    9696    bool iso, bool low_speed, usb_target_t target, usb_packet_id pid,
    97     void *buffer, td_t *next);
     97    const void *buffer, const td_t *next);
    9898
    99 int td_status(td_t *instance);
     99int td_status(const td_t *instance);
    100100
    101 void td_print_status(td_t *instance);
     101void td_print_status(const td_t *instance);
    102102/*----------------------------------------------------------------------------*/
    103103/** Helper function for parsing actual size out of TD.
     
    106106 * @return Parsed actual size.
    107107 */
    108 static inline size_t td_act_size(td_t *instance)
     108static inline size_t td_act_size(const td_t *instance)
    109109{
    110110        assert(instance);
    111111        const uint32_t s = instance->status;
     112        /* Actual size is encoded as n-1 (UHCI design guide p. 23) */
    112113        return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK;
    113114}
     
    119120 * false otherwise.
    120121 */
    121 static inline bool td_is_short(td_t *instance)
     122static inline bool td_is_short(const td_t *instance)
    122123{
    123124        const size_t act_size = td_act_size(instance);
     
    134135 * @return Toggle bit value.
    135136 */
    136 static inline int td_toggle(td_t *instance)
     137static inline int td_toggle(const td_t *instance)
    137138{
    138139        assert(instance);
     
    145146 * @return Active bit value.
    146147 */
    147 static inline bool td_is_active(td_t *instance)
     148static inline bool td_is_active(const td_t *instance)
    148149{
    149150        assert(instance);
  • uspace/drv/bus/usb/uhci/main.c

    r85ff862 rf1d6866  
    6464        assert(device);
    6565
    66         int ret = device_setup_uhci(device);
     66        const int ret = device_setup_uhci(device);
    6767        if (ret != EOK) {
    6868                usb_log_error("Failed to initialize UHCI driver: %s.\n",
    6969                    str_error(ret));
    70                 return ret;
     70        } else {
     71                usb_log_info("Controlling new UHCI device '%s'.\n",
     72                    device->name);
    7173        }
    72         usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
    7374
    74         return EOK;
     75        return ret;
    7576}
    7677/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/uhci/pci.c

    r85ff862 rf1d6866  
    6161        assert(io_reg_size);
    6262        assert(irq_no);
    63        
     63
    6464        async_sess_t *parent_sess =
    6565            devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
     
    6767        if (!parent_sess)
    6868                return ENOMEM;
    69        
     69
    7070        hw_resource_list_t hw_resources;
    71         int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
     71        const int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
     72        async_hangup(parent_sess);
    7273        if (rc != EOK) {
    73                 async_hangup(parent_sess);
    7474                return rc;
    7575        }
    76        
     76
    7777        uintptr_t io_address = 0;
    7878        size_t io_size = 0;
    7979        bool io_found = false;
    80        
     80
    8181        int irq = 0;
    8282        bool irq_found = false;
    83        
     83
    8484        size_t i;
    8585        for (i = 0; i < hw_resources.count; i++) {
     
    102102                }
    103103        }
    104        
    105         async_hangup(parent_sess);
    106        
     104        free(hw_resources.resources);
     105
    107106        if (!io_found || !irq_found)
    108107                return ENOENT;
    109        
     108
    110109        *io_reg_address = io_address;
    111110        *io_reg_size = io_size;
    112111        *irq_no = irq;
    113        
     112
    114113        return EOK;
    115114}
    116 
     115/*----------------------------------------------------------------------------*/
    117116/** Call the PCI driver with a request to enable interrupts
    118117 *
     
    127126        if (!parent_sess)
    128127                return ENOMEM;
    129        
     128
    130129        const bool enabled = hw_res_enable_interrupt(parent_sess);
    131130        async_hangup(parent_sess);
    132        
     131
    133132        return enabled ? EOK : EIO;
    134133}
    135 
     134/*----------------------------------------------------------------------------*/
    136135/** Call the PCI driver with a request to clear legacy support register
    137136 *
     
    142141{
    143142        assert(device);
    144        
     143
    145144        async_sess_t *parent_sess =
    146145            devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
     
    148147        if (!parent_sess)
    149148                return ENOMEM;
    150        
     149
    151150        /* See UHCI design guide for these values p.45,
    152151         * write all WC bits in USB legacy register */
    153152        const sysarg_t address = 0xc0;
    154153        const sysarg_t value = 0xaf00;
    155        
     154
    156155        async_exch_t *exch = async_exchange_begin(parent_sess);
    157        
     156
    158157        const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
    159158            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    160        
     159
    161160        async_exchange_end(exch);
    162161        async_hangup(parent_sess);
    163        
     162
    164163        return rc;
    165164}
  • uspace/drv/bus/usb/uhci/root_hub.c

    r85ff862 rf1d6866  
    5050int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
    5151{
    52         int ret;
    53 
     52        assert(instance);
    5453        assert(fun);
    55 
    56         ret = ddf_fun_add_match_id(fun, "usb&uhci&root-hub", 100);
    57         if (ret != EOK) {
    58                 usb_log_error("Failed to add root hub match id: %s\n",
    59                     str_error(ret));
    60                 return ret;
    61         }
    6254
    6355        /* Initialize resource structure */
     
    7062        instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN;
    7163
    72         return EOK;
     64        const int ret = ddf_fun_add_match_id(fun, "usb&uhci&root-hub", 100);
     65        if (ret != EOK) {
     66                usb_log_error("Failed to add root hub match id: %s\n",
     67                    str_error(ret));
     68        }
     69        return ret;
    7370}
    7471/**
  • uspace/drv/bus/usb/uhci/transfer_list.c

    r85ff862 rf1d6866  
    3737#include <usb/debug.h>
    3838#include <libarch/barrier.h>
     39
    3940#include "transfer_list.h"
    40 #include "batch.h"
    4141
    4242static void transfer_list_remove_batch(
    43     transfer_list_t *instance, usb_transfer_batch_t *batch);
     43    transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch);
    4444/*----------------------------------------------------------------------------*/
    4545/** Initialize transfer list structures.
     
    106106 */
    107107void transfer_list_add_batch(
    108     transfer_list_t *instance, usb_transfer_batch_t *batch)
    109 {
    110         assert(instance);
    111         assert(batch);
    112         usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
     108    transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch)
     109{
     110        assert(instance);
     111        assert(uhci_batch);
     112        usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name,
     113            uhci_batch->usb_batch);
    113114
    114115        fibril_mutex_lock(&instance->guard);
    115116
    116         qh_t *last_qh = NULL;
     117        /* Assume there is nothing scheduled */
     118        qh_t *last_qh = instance->queue_head;
     119        /* There is something scheduled */
     120        if (!list_empty(&instance->batch_list)) {
     121                last_qh = uhci_transfer_batch_from_link(
     122                    list_last(&instance->batch_list))->qh;
     123        }
    117124        /* Add to the hardware queue. */
    118         if (list_empty(&instance->batch_list)) {
    119                 /* There is nothing scheduled */
    120                 last_qh = instance->queue_head;
    121         } else {
    122                 /* There is something scheduled */
    123                 usb_transfer_batch_t *last = usb_transfer_batch_from_link(
    124                     list_last(&instance->batch_list));
    125                 last_qh = batch_qh(last);
    126         }
    127         const uint32_t pa = addr_to_phys(batch_qh(batch));
     125        const uint32_t pa = addr_to_phys(uhci_batch->qh);
    128126        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    129127
     
    132130
    133131        /* keep link */
    134         batch_qh(batch)->next = last_qh->next;
    135         qh_set_next_qh(last_qh, batch_qh(batch));
     132        uhci_batch->qh->next = last_qh->next;
     133        qh_set_next_qh(last_qh, uhci_batch->qh);
    136134
    137135        /* Make sure the pointer is updated */
     
    139137
    140138        /* Add to the driver's list */
    141         list_append(&batch->link, &instance->batch_list);
     139        list_append(&uhci_batch->link, &instance->batch_list);
    142140
    143141        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
    144             batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name);
     142            uhci_batch, USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch),
     143            instance->name);
    145144        fibril_mutex_unlock(&instance->guard);
    146145}
     
    157156
    158157        fibril_mutex_lock(&instance->guard);
    159         link_t *current = instance->batch_list.head.next;
    160         while (current != &instance->batch_list.head) {
     158        link_t *current = list_first(&instance->batch_list);
     159        while (current && current != &instance->batch_list.head) {
    161160                link_t * const next = current->next;
    162                 usb_transfer_batch_t *batch =
    163                     usb_transfer_batch_from_link(current);
    164 
    165                 if (batch_is_complete(batch)) {
     161                uhci_transfer_batch_t *batch =
     162                    uhci_transfer_batch_from_link(current);
     163
     164                if (uhci_transfer_batch_is_complete(batch)) {
    166165                        /* Save for processing */
    167166                        transfer_list_remove_batch(instance, batch);
     
    182181        while (!list_empty(&instance->batch_list)) {
    183182                link_t * const current = list_first(&instance->batch_list);
    184                 usb_transfer_batch_t *batch =
    185                     usb_transfer_batch_from_link(current);
     183                uhci_transfer_batch_t *batch =
     184                    uhci_transfer_batch_from_link(current);
    186185                transfer_list_remove_batch(instance, batch);
    187                 usb_transfer_batch_finish_error(batch, EINTR);
     186                batch->usb_batch->error = EINTR;
     187                uhci_transfer_batch_call_dispose(batch);
    188188        }
    189189        fibril_mutex_unlock(&instance->guard);
     
    198198 */
    199199void transfer_list_remove_batch(
    200     transfer_list_t *instance, usb_transfer_batch_t *batch)
     200    transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch)
    201201{
    202202        assert(instance);
    203203        assert(instance->queue_head);
    204         assert(batch);
    205         assert(batch_qh(batch));
     204        assert(uhci_batch);
     205        assert(uhci_batch->qh);
    206206        assert(fibril_mutex_is_locked(&instance->guard));
    207207
    208         usb_log_debug2(
    209             "Queue %s: removing batch(%p).\n", instance->name, batch);
    210 
    211         const char *qpos = NULL;
    212         qh_t *prev_qh = NULL;
     208        usb_log_debug2("Queue %s: removing batch(%p).\n",
     209            instance->name, uhci_batch->usb_batch);
     210
     211        /* Assume I'm the first */
     212        const char *qpos = "FIRST";
     213        qh_t *prev_qh = instance->queue_head;
    213214        /* Remove from the hardware queue */
    214         if (list_first(&instance->batch_list) == &batch->link) {
    215                 /* I'm the first one here */
    216                 prev_qh = instance->queue_head;
    217                 qpos = "FIRST";
    218         } else {
    219                 /* The thing before me is a batch too */
    220                 usb_transfer_batch_t *prev =
    221                     usb_transfer_batch_from_link(batch->link.prev);
    222                 prev_qh = batch_qh(prev);
     215        if (list_first(&instance->batch_list) != &uhci_batch->link) {
     216                /* There is a batch in front of me */
     217                prev_qh =
     218                    uhci_transfer_batch_from_link(uhci_batch->link.prev)->qh;
    223219                qpos = "NOT FIRST";
    224220        }
    225221        assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK)
    226             == addr_to_phys(batch_qh(batch)));
    227         prev_qh->next = batch_qh(batch)->next;
     222            == addr_to_phys(uhci_batch->qh));
     223        prev_qh->next = uhci_batch->qh->next;
    228224
    229225        /* Make sure the pointer is updated */
     
    231227
    232228        /* Remove from the batch list */
    233         list_remove(&batch->link);
     229        list_remove(&uhci_batch->link);
    234230        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " removed (%s) "
    235231            "from %s, next: %x.\n",
    236             batch, USB_TRANSFER_BATCH_ARGS(*batch),
    237             qpos, instance->name, batch_qh(batch)->next);
     232            uhci_batch, USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch),
     233            qpos, instance->name, uhci_batch->qh->next);
    238234}
    239235/**
  • uspace/drv/bus/usb/uhci/transfer_list.h

    r85ff862 rf1d6866  
    3636
    3737#include <fibril_synch.h>
    38 #include <usb/host/batch.h>
    3938
    4039#include "hw_struct/queue_head.h"
    41 
     40#include "uhci_batch.h"
    4241/** Structure maintaining both hw queue and software list
    4342 * of currently executed transfers
     
    4645        /** Guard against multiple add/remove races */
    4746        fibril_mutex_t guard;
    48         /** UHCI hw structure represeting this queue */
     47        /** UHCI hw structure representing this queue */
    4948        qh_t *queue_head;
    5049        /** Assigned name, for nicer debug output */
     
    5857void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
    5958void transfer_list_add_batch(
    60     transfer_list_t *instance, usb_transfer_batch_t *batch);
     59    transfer_list_t *instance, uhci_transfer_batch_t *batch);
    6160void transfer_list_remove_finished(transfer_list_t *instance, list_t *done);
    6261void transfer_list_abort_all(transfer_list_t *instance);
  • uspace/drv/bus/usb/uhci/uhci.c

    r85ff862 rf1d6866  
    4141
    4242#include "uhci.h"
    43 #include "iface.h"
    4443#include "pci.h"
    4544
     
    8786/** Operations supported by the HC driver */
    8887static ddf_dev_ops_t hc_ops = {
    89         .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
     88        .interfaces[USBHC_DEV_IFACE] = &hcd_iface, /* see iface.h/c */
    9089};
    9190/*----------------------------------------------------------------------------*/
     
    10099{
    101100        assert(fun);
    102         usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
    103         usb_address_t addr = usb_device_keeper_find(manager, handle);
     101        usb_device_manager_t *manager =
     102            &dev_to_uhci(fun->dev)->hc.generic.dev_manager;
     103        const usb_address_t addr = usb_device_manager_find(manager, handle);
    104104
    105105        if (addr < 0) {
     
    202202        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
    203203        instance->hc_fun->ops = &hc_ops;
    204         instance->hc_fun->driver_data = &instance->hc;
     204        instance->hc_fun->driver_data = &instance->hc.generic;
    205205
    206206        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
  • uspace/drv/bus/usb/uhci/utils/malloc32.h

    r85ff862 rf1d6866  
    5050 * @return Physical address if exists, NULL otherwise.
    5151 */
    52 static inline uintptr_t addr_to_phys(void *addr)
     52static inline uintptr_t addr_to_phys(const void *addr)
    5353{
    5454        if (addr == NULL)
     
    102102        if (free_address == 0)
    103103                return NULL;
    104         void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     104        void *address = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    105105                  AS_AREA_READ | AS_AREA_WRITE);
    106         if (ret != free_address)
     106        if (address != free_address)
    107107                return NULL;
    108         return ret;
     108        return address;
     109}
     110/*----------------------------------------------------------------------------*/
     111static inline void return_page(void *page)
     112{
     113        if (page)
     114                as_area_destroy(page);
    109115}
    110116
  • uspace/drv/bus/usb/vhc/connhost.c

    r85ff862 rf1d6866  
    6262        VHC_DATA(vhc, fun);
    6363
    64         usb_address_t addr = device_keeper_get_free_address(&vhc->dev_keeper,
    65             USB_SPEED_HIGH);
     64        usb_address_t addr = usb_device_manager_get_free_address(
     65            &vhc->dev_manager, USB_SPEED_HIGH);
    6666        if (addr < 0) {
    6767                return addr;
     
    8888        usb_log_debug("Binding handle %" PRIun " to address %d.\n",
    8989            handle, address);
    90         usb_device_keeper_bind(&vhc->dev_keeper, address, handle);
     90        usb_device_manager_bind(&vhc->dev_manager, address, handle);
    9191
    9292        return EOK;
     
    105105        VHC_DATA(vhc, fun);
    106106        bool found =
    107             usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle);
     107            usb_device_manager_find_by_address(&vhc->dev_manager, address, handle);
    108108        return found ? EOK : ENOENT;
    109109}
     
    119119        VHC_DATA(vhc, fun);
    120120        usb_log_debug("Releasing address %d...\n", address);
    121         usb_device_keeper_release(&vhc->dev_keeper, address);
     121        usb_device_manager_release(&vhc->dev_manager, address);
    122122
    123123        return ENOTSUP;
     
    172172        VHC_DATA(vhc, fun);
    173173
    174         endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
    175             address, endpoint, direction, NULL);
    176         if (ep == NULL) {
    177                 return ENOENT;
    178         }
    179 
    180174        int rc = usb_endpoint_manager_unregister_ep(&vhc->ep_manager,
    181175            address, endpoint, direction);
     
    183177        return rc;
    184178}
    185 
     179#if 0
    186180/** Schedule interrupt out transfer.
    187181 *
     
    413407        return EOK;
    414408}
     409#endif
     410static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,
     411    uint8_t *data_buffer, size_t data_buffer_size,
     412    usbhc_iface_transfer_in_callback_t callback, void *arg)
     413{
     414        VHC_DATA(vhc, fun);
     415
     416        endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
     417            target.address, target.endpoint, USB_DIRECTION_IN, NULL);
     418        if (ep == NULL) {
     419                return ENOENT;
     420        }
     421        const usb_transfer_type_t transfer_type = ep->transfer_type;
     422
     423
     424        vhc_transfer_t *transfer = vhc_transfer_create(target.address,
     425            target.endpoint, USB_DIRECTION_IN, transfer_type,
     426            fun, arg);
     427        if (transfer == NULL) {
     428                return ENOMEM;
     429        }
     430        if (transfer_type == USB_TRANSFER_CONTROL) {
     431                transfer->setup_buffer = malloc(sizeof(uint64_t));
     432                assert(transfer->setup_buffer);
     433                memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));
     434                transfer->setup_buffer_size = sizeof(uint64_t);
     435        }
     436        transfer->data_buffer = data_buffer;
     437        transfer->data_buffer_size = data_buffer_size;
     438        transfer->callback_in = callback;
     439
     440        int rc = vhc_virtdev_add_transfer(vhc, transfer);
     441        if (rc != EOK) {
     442                free(transfer->setup_buffer);
     443                free(transfer);
     444                return rc;
     445        }
     446
     447        return EOK;
     448}
     449
     450static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,
     451    const uint8_t *data_buffer, size_t data_buffer_size,
     452    usbhc_iface_transfer_out_callback_t callback, void *arg)
     453{
     454        VHC_DATA(vhc, fun);
     455
     456        endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
     457            target.address, target.endpoint, USB_DIRECTION_OUT, NULL);
     458        if (ep == NULL) {
     459                return ENOENT;
     460        }
     461        const usb_transfer_type_t transfer_type = ep->transfer_type;
     462
     463
     464        vhc_transfer_t *transfer = vhc_transfer_create(target.address,
     465            target.endpoint, USB_DIRECTION_OUT, transfer_type,
     466            fun, arg);
     467        if (transfer == NULL) {
     468                return ENOMEM;
     469        }
     470        if (transfer_type == USB_TRANSFER_CONTROL) {
     471                transfer->setup_buffer = malloc(sizeof(uint64_t));
     472                assert(transfer->setup_buffer);
     473                memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));
     474                transfer->setup_buffer_size = sizeof(uint64_t);
     475        }
     476        transfer->data_buffer = (void*)data_buffer;
     477        transfer->data_buffer_size = data_buffer_size;
     478        transfer->callback_out = callback;
     479
     480        int rc = vhc_virtdev_add_transfer(vhc, transfer);
     481        if (rc != EOK) {
     482                free(transfer->setup_buffer);
     483                free(transfer);
     484                return rc;
     485        }
     486
     487        return EOK;
     488}
    415489
    416490static int tell_address(ddf_fun_t *fun, devman_handle_t handle,
     
    442516
    443517        usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle);
    444         usb_address_t addr = usb_device_keeper_find(&vhc->dev_keeper, handle);
     518        usb_address_t addr = usb_device_manager_find(&vhc->dev_manager, handle);
    445519        if (addr < 0) {
    446520                return addr;
     
    460534        .unregister_endpoint = unregister_endpoint,
    461535
    462         .interrupt_out = interrupt_out,
    463         .interrupt_in = interrupt_in,
    464 
    465         .bulk_in = bulk_in,
    466         .bulk_out = bulk_out,
    467 
    468         .control_write = control_write,
    469         .control_read = control_read
     536        .write = usb_write,
     537        .read = usb_read,
    470538};
    471539
  • uspace/drv/bus/usb/vhc/main.c

    r85ff862 rf1d6866  
    7373        }
    7474        data->magic = 0xDEADBEEF;
    75         rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1);
     75        rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1,
     76            bandwidth_count_usb11);
    7677        if (rc != EOK) {
    7778                usb_log_fatal("Failed to initialize endpoint manager.\n");
     
    7980                return rc;
    8081        }
    81         usb_device_keeper_init(&data->dev_keeper);
     82        usb_device_manager_init(&data->dev_manager);
    8283
    8384        ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
  • uspace/drv/bus/usb/vhc/vhcd.h

    r85ff862 rf1d6866  
    3939#include <usbvirt/device.h>
    4040#include <usb/host/usb_endpoint_manager.h>
    41 #include <usb/host/device_keeper.h>
     41#include <usb/host/usb_device_manager.h>
    4242#include <usbhc_iface.h>
    4343#include <async.h>
     
    6060        fibril_mutex_t guard;
    6161        usb_endpoint_manager_t ep_manager;
    62         usb_device_keeper_t dev_keeper;
     62        usb_device_manager_t dev_manager;
    6363        usbvirt_device_t *hub;
    6464        ddf_fun_t *hc_fun;
  • uspace/drv/char/ns8250/ns8250.c

    r85ff862 rf1d6866  
    5959
    6060#include <devman.h>
     61#include <ns.h>
    6162#include <ipc/devman.h>
     63#include <ipc/services.h>
     64#include <ipc/irc.h>
    6265#include <device/hw_res.h>
    6366#include <ipc/serial_ctl.h>
     
    409412static int ns8250_interrupt_enable(ns8250_t *ns)
    410413{
     414        /*
     415         * Enable interrupt using IRC service.
     416         * TODO: This is a temporary solution until the device framework
     417         * takes care of this itself.
     418         */
     419        async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     420            SERVICE_IRC, 0, 0);
     421        if (!irc_sess) {
     422                return EIO;
     423        }
     424
     425        async_exch_t *exch = async_exchange_begin(irc_sess);
     426        if (!exch) {
     427                return EIO;
     428        }
     429        async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq);
     430        async_exchange_end(exch);
     431
    411432        /* Enable interrupt on the serial port. */
    412433        ns8250_port_interrupts_enable(ns->port);
Note: See TracChangeset for help on using the changeset viewer.