Changeset 432a269 in mainline for uspace/drv/bus/usb/ohci/hc.c


Ignore:
Timestamp:
2011-09-16T21:13:57Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3a11f17
Parents:
c0e53ff (diff), fd07e526 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/hc.c

    rc0e53ff r432a269  
    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        }
Note: See TracChangeset for help on using the changeset viewer.