Changeset b8d453ec in mainline


Ignore:
Timestamp:
2011-03-25T17:18:46Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9a2923d
Parents:
da3dafc (diff), 095b2017 (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:

Fixes issue #122.

New allocator on not cached memory.
Only one control transfer per device as allowed

Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    rda3dafc rb8d453ec  
    19491949sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
    19501950{
    1951         if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
     1951        if (as_area_create(AS, flags, size, address,
    19521952            AS_AREA_ATTR_NONE, &anon_backend, NULL))
    19531953                return (sysarg_t) address;
  • uspace/drv/uhci-hcd/Makefile

    rda3dafc rb8d453ec  
    4040        root_hub.c \
    4141        hw_struct/transfer_descriptor.c \
     42        utils/slab.c \
    4243        pci.c \
    4344        batch.c
  • uspace/drv/uhci-hcd/hc.c

    rda3dafc rb8d453ec  
    223223        ret = instance ? EOK : ENOMEM;
    224224        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    225         usb_log_debug("Initialized frame list.\n");
     225        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    226226
    227227        /* Set all frames to point to the first queue head */
     
    336336            instance->transfers[batch->speed][batch->transfer_type];
    337337        assert(list);
     338        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     339                usb_device_keeper_use_control(
     340                    &instance->manager, batch->target.address);
     341        }
    338342        transfer_list_add_batch(list, batch);
    339343
     
    357361        /* Lower 2 bits are transaction error and transaction complete */
    358362        if (status & 0x3) {
    359                 transfer_list_remove_finished(&instance->transfers_interrupt);
    360                 transfer_list_remove_finished(&instance->transfers_control_slow);
    361                 transfer_list_remove_finished(&instance->transfers_control_full);
    362                 transfer_list_remove_finished(&instance->transfers_bulk_full);
     363                LIST_INITIALIZE(done);
     364                transfer_list_remove_finished(
     365                    &instance->transfers_interrupt, &done);
     366                transfer_list_remove_finished(
     367                    &instance->transfers_control_slow, &done);
     368                transfer_list_remove_finished(
     369                    &instance->transfers_control_full, &done);
     370                transfer_list_remove_finished(
     371                    &instance->transfers_bulk_full, &done);
     372
     373                while (!list_empty(&done)) {
     374                        link_t *item = done.next;
     375                        list_remove(item);
     376                        usb_transfer_batch_t *batch =
     377                            list_get_instance(item, usb_transfer_batch_t, link);
     378                        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     379                                usb_device_keeper_release_control(
     380                                    &instance->manager, batch->target.address);
     381                        }
     382                        batch->next_step(batch);
     383                }
    363384        }
    364385        /* bits 4 and 5 indicate hc error */
  • uspace/drv/uhci-hcd/transfer_list.c

    rda3dafc rb8d453ec  
    5858        }
    5959        instance->queue_head_pa = addr_to_phys(instance->queue_head);
     60        usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",
     61            name, instance->queue_head, instance->queue_head_pa);
    6062
    6163        qh_init(instance->queue_head);
     
    118120        qh_set_next_qh(last_qh, pa);
    119121
     122        asm volatile ("": : :"memory");
     123
    120124        /* Add to the driver list */
    121125        list_append(&batch->link, &instance->batch_list);
     
    137141 * this transfer list leading to the deadlock if its done inline.
    138142 */
    139 void transfer_list_remove_finished(transfer_list_t *instance)
    140 {
    141         assert(instance);
    142 
    143         LIST_INITIALIZE(done);
     143void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     144{
     145        assert(instance);
     146        assert(done);
    144147
    145148        fibril_mutex_lock(&instance->guard);
     
    153156                        /* Save for post-processing */
    154157                        transfer_list_remove_batch(instance, batch);
    155                         list_append(current, &done);
     158                        list_append(current, done);
    156159                }
    157160                current = next;
     
    159162        fibril_mutex_unlock(&instance->guard);
    160163
    161         while (!list_empty(&done)) {
    162                 link_t *item = done.next;
    163                 list_remove(item);
    164                 usb_transfer_batch_t *batch =
    165                     list_get_instance(item, usb_transfer_batch_t, link);
    166                 batch->next_step(batch);
    167         }
    168164}
    169165/*----------------------------------------------------------------------------*/
     
    222218                qpos = "NOT FIRST";
    223219        }
     220        asm volatile ("": : :"memory");
    224221        /* Remove from the batch list */
    225222        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    rda3dafc rb8d453ec  
    6767void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
    6868
    69 void transfer_list_remove_finished(transfer_list_t *instance);
     69void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
    7070
    7171void transfer_list_abort_all(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/utils/malloc32.h

    rda3dafc rb8d453ec  
    4040#include <as.h>
    4141
     42#include "slab.h"
     43
    4244#define UHCI_STRCUTURES_ALIGNMENT 16
    4345#define UHCI_REQUIRED_PAGE_SIZE 4096
     46
    4447
    4548/** Get physical address translation
     
    5457
    5558        uintptr_t result;
    56         int ret = as_get_physical_mapping(addr, &result);
     59        const int ret = as_get_physical_mapping(addr, &result);
     60        assert(ret == EOK);
    5761
    5862        if (ret != EOK)
     
    6670 * @return Address of the alligned and big enough memory place, NULL on failure.
    6771 */
    68 static inline void * malloc32(size_t size)
    69         { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); }
     72static inline void * malloc32(size_t size) {
     73        if (size <= SLAB_ELEMENT_SIZE)
     74                return slab_malloc_g();
     75        assert(false);
     76        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
     77}
    7078/*----------------------------------------------------------------------------*/
    7179/** Physical mallocator simulator
     
    7381 * @param[in] addr Address of the place allocated by malloc32
    7482 */
    75 static inline void free32(void *addr)
    76         { if (addr) free(addr); }
     83static inline void free32(void *addr) {
     84        if (!addr)
     85                return;
     86        if (slab_in_range_g(addr))
     87                return slab_free_g(addr);
     88        free(addr);
     89}
    7790/*----------------------------------------------------------------------------*/
    7891/** Create 4KB page mapping
     
    8295static inline void * get_page(void)
    8396{
    84         void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
    85         assert(free_address);
     97        void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
     98        assert(free_address); /* TODO: remove this assert */
    8699        if (free_address == 0)
    87100                return NULL;
    88         void* ret =
    89           as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     101        void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    90102                  AS_AREA_READ | AS_AREA_WRITE);
    91103        if (ret != free_address)
  • uspace/lib/c/generic/malloc.c

    rda3dafc rb8d453ec  
    240240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
    241241       
    242         astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
    243243        if (astart == (void *) -1)
    244244                return false;
  • uspace/lib/usb/include/usb/host/device_keeper.h

    rda3dafc rb8d453ec  
    5151        usb_speed_t speed;
    5252        bool occupied;
     53        bool control_used;
    5354        uint16_t toggle_status[2];
    5455        devman_handle_t handle;
     
    6162        struct usb_device_info devices[USB_ADDRESS_COUNT];
    6263        fibril_mutex_t guard;
    63         fibril_condvar_t default_address_occupied;
     64        fibril_condvar_t change;
    6465        usb_address_t last_address;
    6566} usb_device_keeper_t;
     
    9798    usb_address_t address);
    9899
     100void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     101    usb_address_t address);
     102
     103void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     104    usb_address_t address);
     105
    99106#endif
    100107/**
  • uspace/lib/usb/src/host/device_keeper.c

    rda3dafc rb8d453ec  
    4949        assert(instance);
    5050        fibril_mutex_initialize(&instance->guard);
    51         fibril_condvar_initialize(&instance->default_address_occupied);
     51        fibril_condvar_initialize(&instance->change);
    5252        instance->last_address = 0;
    5353        unsigned i = 0;
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
     56                instance->devices[i].control_used = false;
    5657                instance->devices[i].handle = 0;
    5758                instance->devices[i].toggle_status[0] = 0;
     
    7172        fibril_mutex_lock(&instance->guard);
    7273        while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {
    73                 fibril_condvar_wait(&instance->default_address_occupied,
    74                     &instance->guard);
     74                fibril_condvar_wait(&instance->change, &instance->guard);
    7575        }
    7676        instance->devices[USB_ADDRESS_DEFAULT].occupied = true;
     
    9090        instance->devices[USB_ADDRESS_DEFAULT].occupied = false;
    9191        fibril_mutex_unlock(&instance->guard);
    92         fibril_condvar_signal(&instance->default_address_occupied);
     92        fibril_condvar_signal(&instance->change);
    9393}
    9494/*----------------------------------------------------------------------------*/
     
    309309        return instance->devices[address].speed;
    310310}
    311 
     311/*----------------------------------------------------------------------------*/
     312void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     313    usb_address_t address)
     314{
     315        assert(instance);
     316        fibril_mutex_lock(&instance->guard);
     317        while (instance->devices[address].control_used) {
     318                fibril_condvar_wait(&instance->change, &instance->guard);
     319        }
     320        instance->devices[address].control_used = true;
     321        fibril_mutex_unlock(&instance->guard);
     322}
     323/*----------------------------------------------------------------------------*/
     324void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     325    usb_address_t address)
     326{
     327        assert(instance);
     328        fibril_mutex_lock(&instance->guard);
     329        instance->devices[address].control_used = false;
     330        fibril_mutex_unlock(&instance->guard);
     331        fibril_condvar_signal(&instance->change);
     332}
    312333/**
    313334 * @}
Note: See TracChangeset for help on using the changeset viewer.