Ignore:
File:
1 edited

Legend:

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

    r8b54fe6 ref9460b  
    4242
    4343#include "hc.h"
    44 #include "ohci_endpoint.h"
     44#include "hcd_endpoint.h"
    4545
    4646#define OHCI_USED_INTERRUPTS \
     
    6161static int hc_init_memory(hc_t *instance);
    6262static int interrupt_emulator(hc_t *instance);
    63 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
     63
    6464/*----------------------------------------------------------------------------*/
    6565/** Get number of commands used in IRQ code.
     
    128128
    129129        const usb_address_t hub_address =
    130             usb_device_manager_get_free_address(
    131                 &instance->generic.dev_manager, USB_SPEED_FULL);
     130            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
    132131        if (hub_address <= 0) {
    133132                usb_log_error("Failed to get OHCI root hub address: %s\n",
     
    136135        }
    137136        instance->rh.address = hub_address;
    138         usb_device_manager_bind(
    139             &instance->generic.dev_manager, hub_address, hub_fun->handle);
    140 
    141 #define CHECK_RET_UNREG_RETURN(ret, message...) \
     137        usb_device_keeper_bind(
     138            &instance->manager, hub_address, hub_fun->handle);
     139
     140#define CHECK_RET_RELEASE(ret, message...) \
    142141if (ret != EOK) { \
    143142        usb_log_error(message); \
    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); \
     143        hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \
     144        usb_device_keeper_release(&instance->manager, hub_address); \
    148145        return ret; \
    149146} else (void)0
    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));
     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));
    156152
    157153        ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
    158         CHECK_RET_UNREG_RETURN(ret,
     154        CHECK_RET_RELEASE(ret,
    159155            "Failed to add root hub match-id: %s.\n", str_error(ret));
    160156
    161157        ret = ddf_fun_bind(hub_fun);
    162         CHECK_RET_UNREG_RETURN(ret,
     158        CHECK_RET_RELEASE(ret,
    163159            "Failed to bind root hub function: %s.\n", str_error(ret));
    164160
     
    191187
    192188        list_initialize(&instance->pending_batches);
    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",
     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",
    197194            str_error(ret));
    198         instance->generic.private_data = instance;
    199         instance->generic.schedule = hc_schedule;
    200         instance->generic.ep_add_hook = ohci_endpoint_init;
    201195
    202196        ret = hc_init_memory(instance);
     
    221215}
    222216/*----------------------------------------------------------------------------*/
    223 void 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 */
     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 */
     230int 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 */
    228255        switch (ep->transfer_type) {
    229256        case USB_TRANSFER_CONTROL:
    230257                instance->registers->control &= ~C_CLE;
    231                 endpoint_list_add_ep(list, ohci_ep);
     258                endpoint_list_add_ep(
     259                    &instance->lists[ep->transfer_type], hcd_ep);
    232260                instance->registers->control_current = 0;
    233261                instance->registers->control |= C_CLE;
     
    235263        case USB_TRANSFER_BULK:
    236264                instance->registers->control &= ~C_BLE;
    237                 endpoint_list_add_ep(list, ohci_ep);
     265                endpoint_list_add_ep(
     266                    &instance->lists[ep->transfer_type], hcd_ep);
    238267                instance->registers->control |= C_BLE;
    239268                break;
     
    241270        case USB_TRANSFER_INTERRUPT:
    242271                instance->registers->control &= (~C_PLE & ~C_IE);
    243                 endpoint_list_add_ep(list, ohci_ep);
     272                endpoint_list_add_ep(
     273                    &instance->lists[ep->transfer_type], hcd_ep);
    244274                instance->registers->control |= C_PLE | C_IE;
    245275                break;
    246276        }
    247 }
    248 /*----------------------------------------------------------------------------*/
    249 void 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         }
     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 */
     289int 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 */
     348endpoint_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;
    275357}
    276358/*----------------------------------------------------------------------------*/
     
    281363 * @return Error code.
    282364 */
    283 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    284 {
    285         assert(hcd);
    286         hc_t *instance = hcd->private_data;
    287         assert(instance);
     365int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
     366{
     367        assert(instance);
     368        assert(batch);
     369        assert(batch->ep);
    288370
    289371        /* Check for root hub communication */
     
    292374                return EOK;
    293375        }
    294         ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);
    295         if (!ohci_batch)
    296                 return ENOMEM;
    297376
    298377        fibril_mutex_lock(&instance->guard);
    299         list_append(&ohci_batch->link, &instance->pending_batches);
    300         ohci_transfer_batch_commit(ohci_batch);
     378        list_append(&batch->link, &instance->pending_batches);
     379        batch_commit(batch);
    301380
    302381        /* Control and bulk schedules need a kick to start working */
     
    338417                    instance->registers->periodic_current);
    339418
    340                 link_t *current = list_first(&instance->pending_batches);
    341                 while (current && current != &instance->pending_batches.head) {
     419                link_t *current = instance->pending_batches.head.next;
     420                while (current != &instance->pending_batches.head) {
    342421                        link_t *next = current->next;
    343                         ohci_transfer_batch_t *batch =
    344                             ohci_transfer_batch_from_link(current);
    345 
    346                         if (ohci_transfer_batch_is_complete(batch)) {
     422                        usb_transfer_batch_t *batch =
     423                            usb_transfer_batch_from_link(current);
     424
     425                        if (batch_is_complete(batch)) {
    347426                                list_remove(current);
    348                                 ohci_transfer_batch_finish_dispose(batch);
     427                                usb_transfer_batch_finish(batch);
    349428                        }
    350429
     
    355434
    356435        if (status & I_UE) {
    357                 usb_log_fatal("Error like no other!\n");
    358436                hc_start(instance);
    359437        }
Note: See TracChangeset for help on using the changeset viewer.