Changes in / [ec4538d:f16a76b] in mainline


Ignore:
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rec4538d rf16a76b  
    7777./uspace/dist/srv/*
    7878./uspace/drv/root/root
     79./uspace/drv/ehci-hcd/ehci-hcd
    7980./uspace/drv/isa/isa
    8081./uspace/drv/ns8250/ns8250
     
    8485./uspace/drv/test1/test1
    8586./uspace/drv/test2/test2
    86 ./uspace/drv/ehci-hcd/ehci-hcd
    8787./uspace/drv/uhci-hcd/uhci-hcd
    8888./uspace/drv/uhci-rhd/uhci-rhd
  • uspace/drv/ehci-hcd/main.c

    rec4538d rf16a76b  
    5757};
    5858/*----------------------------------------------------------------------------*/
    59 /** Initializes a new ddf driver instance of EHCI hcd.
    60  *
    61  * @param[in] device DDF instance of the device to initialize.
    62  * @return Error code.
    63  */
    6459static int ehci_add_device(ddf_dev_t *device)
    6560{
     
    9287}
    9388/*----------------------------------------------------------------------------*/
    94 /** Initializes global driver structures (NONE).
    95  *
    96  * @param[in] argc Nmber of arguments in argv vector (ignored).
    97  * @param[in] argv Cmdline argument vector (ignored).
    98  * @return Error code.
    99  *
    100  * Driver debug level is set here.
    101  */
    10289int main(int argc, char *argv[])
    10390{
  • uspace/drv/ehci-hcd/pci.c

    rec4538d rf16a76b  
    4848
    4949#define PAGE_SIZE_MASK 0xfffff000
    50 
    5150#define HCC_PARAMS_OFFSET 0x8
    5251#define HCC_PARAMS_EECP_MASK 0xff
    5352#define HCC_PARAMS_EECP_OFFSET 8
    54 
    55 #define CMD_OFFSET 0x0
    56 #define CONFIGFLAG_OFFSET 0x40
    5753
    5854#define USBCMD_RUN 1
     
    6662#define WAIT_STEP 10
    6763
     64
    6865/** Get address of registers and IRQ for given device.
    6966 *
    7067 * @param[in] dev Device asking for the addresses.
    71  * @param[out] mem_reg_address Base address of the memory range.
    72  * @param[out] mem_reg_size Size of the memory range.
     68 * @param[out] io_reg_address Base address of the I/O range.
     69 * @param[out] io_reg_size Size of the I/O range.
    7370 * @param[out] irq_no IRQ assigned to the device.
    7471 * @return Error code.
     
    9087        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
    9188        if (rc != EOK) {
    92                 async_hangup(parent_phone);
    93                 return rc;
     89                goto leave;
    9490        }
    9591
     
    104100        for (i = 0; i < hw_resources.count; i++) {
    105101                hw_resource_t *res = &hw_resources.resources[i];
    106                 switch (res->type)
    107                 {
    108                 case INTERRUPT:
    109                         irq = res->res.interrupt.irq;
    110                         irq_found = true;
    111                         usb_log_debug2("Found interrupt: %d.\n", irq);
    112                         break;
    113 
    114                 case MEM_RANGE:
    115                         if (res->res.mem_range.address != 0
    116                             && res->res.mem_range.size != 0 ) {
    117                                 mem_address = res->res.mem_range.address;
    118                                 mem_size = res->res.mem_range.size;
    119                                 usb_log_debug2("Found mem: %llx %zu.\n",
    120                                     mem_address, mem_size);
    121                                 mem_found = true;
     102                switch (res->type) {
     103                        case INTERRUPT:
     104                                irq = res->res.interrupt.irq;
     105                                irq_found = true;
     106                                usb_log_debug2("Found interrupt: %d.\n", irq);
     107                                break;
     108                        case MEM_RANGE:
     109                                if (res->res.mem_range.address != 0
     110                                    && res->res.mem_range.size != 0 ) {
     111                                        mem_address = res->res.mem_range.address;
     112                                        mem_size = res->res.mem_range.size;
     113                                        usb_log_debug2("Found mem: %llx %zu.\n",
     114                                                        res->res.mem_range.address, res->res.mem_range.size);
     115                                        mem_found = true;
    122116                                }
    123                 default:
    124                         break;
     117                                break;
     118                        default:
     119                                break;
    125120                }
    126121        }
    127122
    128         if (mem_found && irq_found) {
    129                 *mem_reg_address = mem_address;
    130                 *mem_reg_size = mem_size;
    131                 *irq_no = irq;
    132                 rc = EOK;
    133         } else {
     123        if (!mem_found) {
    134124                rc = ENOENT;
    135         }
    136 
     125                goto leave;
     126        }
     127
     128        if (!irq_found) {
     129                rc = ENOENT;
     130                goto leave;
     131        }
     132
     133        *mem_reg_address = mem_address;
     134        *mem_reg_size = mem_size;
     135        *irq_no = irq;
     136
     137        rc = EOK;
     138leave:
    137139        async_hangup(parent_phone);
     140
    138141        return rc;
    139142}
    140143/*----------------------------------------------------------------------------*/
    141 /** Calls the PCI driver with a request to enable interrupts
    142  *
    143  * @param[in] device Device asking for interrupts
    144  * @return Error code.
    145  */
    146144int pci_enable_interrupts(ddf_dev_t *device)
    147145{
    148         int parent_phone =
    149             devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
    150         if (parent_phone < 0) {
    151                 return parent_phone;
    152         }
     146        int parent_phone = devman_parent_device_connect(device->handle,
     147            IPC_FLAG_BLOCKING);
    153148        bool enabled = hw_res_enable_interrupt(parent_phone);
    154149        async_hangup(parent_phone);
     
    156151}
    157152/*----------------------------------------------------------------------------*/
    158 /** Implements BIOS handoff routine as decribed in EHCI spec
    159  *
    160  * @param[in] device Device asking for interrupts
    161  * @return Error code.
    162  */
    163153int pci_disable_legacy(ddf_dev_t *device)
    164154{
     
    170160        }
    171161
    172 #define CHECK_RET_HANGUP_RETURN(ret, message...) \
    173         if (ret != EOK) { \
    174                 usb_log_error(message); \
    175                 async_hangup(parent_phone); \
    176                 return ret; \
    177         } else (void)0
    178 
    179 
    180         /* read register space BASE BAR */
     162        /* read register space BAR */
    181163        sysarg_t address = 0x10;
    182164        sysarg_t value;
    183165
    184         int ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     166  int ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    185167            IPC_M_CONFIG_SPACE_READ_32, address, &value);
    186         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n",
    187             ret);
    188168        usb_log_info("Register space BAR at %p:%x.\n", address, value);
    189169
    190         /* clear lower byte, it's not part of the BASE address */
     170        /* clear lower byte, it's not part of the address */
    191171        uintptr_t registers = (value & 0xffffff00);
    192         usb_log_info("Memory registers BASE address:%p.\n", registers);
    193 
    194         /* if nothing setup the hc, we don't need to turn it off */
     172        usb_log_info("Mem register address:%p.\n", registers);
     173
     174        /* if nothing setup the hc, the we don't need to to turn it off */
    195175        if (registers == 0)
    196176                return ENOTSUP;
    197177
    198         /* map EHCI registers */
     178        /* EHCI registers need 20 bytes*/
    199179        void *regs = as_get_mappable_page(4096);
    200180        ret = physmem_map((void*)(registers & PAGE_SIZE_MASK), regs, 1,
    201181            AS_AREA_READ | AS_AREA_WRITE);
    202         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to map registers %p:%p.\n",
    203             ret, regs, registers);
    204 
     182        if (ret != EOK) {
     183                usb_log_error("Failed(%d) to map registers %p:%p.\n",
     184                    ret, regs, registers);
     185        }
    205186        /* calculate value of BASE */
    206187        registers = (registers & 0xf00) | (uintptr_t)regs;
    207188
    208         const uint32_t hcc_params =
    209             *(uint32_t*)(registers + HCC_PARAMS_OFFSET);
     189        uint32_t hcc_params = *(uint32_t*)(registers + HCC_PARAMS_OFFSET);
     190
    210191        usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
    211 
    212         /* Read value of EHCI Extended Capabilities Pointer
    213          * (points to PCI config space) */
    214         uint32_t eecp =
    215             (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
     192        uint32_t eecp = (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
    216193        usb_log_debug("Value of EECP: %x.\n", eecp);
    217194
    218         /* Read the second EEC. i.e. Legacy Support and Control register */
    219         /* TODO: Check capability type here */
    220195        ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    221196            IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGCTLSTS_OFFSET, &value);
    222         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read USBLEGCTLSTS.\n", ret);
    223         usb_log_debug("USBLEGCTLSTS: %x.\n", value);
    224 
    225         /* Read the first EEC. i.e. Legacy Support register */
    226         /* TODO: Check capability type here */
     197        if (ret != EOK) {
     198                usb_log_error("Failed(%d) to read USBLEGCTLSTS.\n", ret);
     199                return ret;
     200        }
     201        usb_log_debug2("USBLEGCTLSTS: %x.\n", value);
     202
    227203        ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    228204            IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGSUP_OFFSET, &value);
    229         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read USBLEGSUP.\n", ret);
     205        if (ret != EOK) {
     206                usb_log_error("Failed(%d) to read USBLEGSUP.\n", ret);
     207                return ret;
     208        }
    230209        usb_log_debug2("USBLEGSUP: %x.\n", value);
    231210
    232         /* Request control from firmware/BIOS, by writing 1 to highest byte.
    233          * (OS Control semaphore)*/
     211        /* request control from firmware/BIOS, by writing 1 to highest byte */
    234212        ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    235213           IPC_M_CONFIG_SPACE_WRITE_8, eecp + USBLEGSUP_OFFSET + 3, 1);
    236         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to request OS EHCI control.\n",
    237             ret);
    238 
    239         size_t wait = 0;
    240         /* Wait for BIOS to release control. */
     214        if (ret != EOK) {
     215                usb_log_error("Failed(%d) request OS EHCI control.\n", ret);
     216                return ret;
     217        }
     218
     219        size_t wait = 0; /* might be anything */
     220        /* wait for BIOS to release control */
    241221        while ((wait < DEFAULT_WAIT) && (value & USBLEGSUP_BIOS_CONTROL)) {
    242222                async_usleep(WAIT_STEP);
    243223                ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    244                     IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGSUP_OFFSET, &value);
     224                                IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGSUP_OFFSET, &value);
    245225                wait += WAIT_STEP;
    246226        }
    247227
    248 
    249228        if ((value & USBLEGSUP_BIOS_CONTROL) != 0) {
    250                 usb_log_info("BIOS released control after %d usec.\n", wait);
     229                usb_log_warning(
     230                    "BIOS failed to release control after %d usecs, force it.\n",
     231                    wait);
     232                ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     233                          IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGSUP_OFFSET,
     234                    USBLEGSUP_OS_CONTROL);
     235                if (ret != EOK) {
     236                        usb_log_error("Failed(%d) to force OS EHCI control.\n", ret);
     237                        return ret;
     238                }
    251239        } else {
    252                 /* BIOS failed to hand over control, this should not happen. */
    253                 usb_log_warning( "BIOS failed to release control after"
    254                     "%d usecs, force it.\n", wait);
    255                 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    256                     IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGSUP_OFFSET,
    257                     USBLEGSUP_OS_CONTROL);
    258                 CHECK_RET_HANGUP_RETURN(ret,
    259                     "Failed(%d) to force OS EHCI control.\n", ret);
    260                 /* TODO: This does not seem to work on my machine */
    261         }
    262 
    263         /* Zero SMI enables in legacy control register.
    264          * It would prevent pre-OS code from interfering. */
     240                usb_log_info("BIOS released control after %d usec.\n",
     241                    wait);
     242        }
     243
     244
     245        /* zero SMI enables in legacy control register */
    265246        ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    266247           IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0);
    267         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
     248        if (ret != EOK) {
     249                usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", ret);
     250                return ret;
     251        }
    268252        usb_log_debug("Zeroed USBLEGCTLSTS register.\n");
    269253
    270         /* Read again Legacy Support and Control register */
    271254        ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    272255            IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGCTLSTS_OFFSET, &value);
    273         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read USBLEGCTLSTS.\n", ret);
     256        if (ret != EOK) {
     257                usb_log_error("Failed(%d) to read USBLEGCTLSTS.\n", ret);
     258                return ret;
     259        }
    274260        usb_log_debug2("USBLEGCTLSTS: %x.\n", value);
    275261
    276         /* Read again Legacy Support register */
    277262        ret = async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    278263            IPC_M_CONFIG_SPACE_READ_32, eecp + USBLEGSUP_OFFSET, &value);
    279         CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read USBLEGSUP.\n", ret);
     264        if (ret != EOK) {
     265                usb_log_error("Failed(%d) to read USBLEGSUP.\n", ret);
     266                return ret;
     267        }
    280268        usb_log_debug2("USBLEGSUP: %x.\n", value);
    281269
     
    284272 */
    285273
    286         /* Get size of capability registers in memory space. */
     274        /* size of capability registers in memory space */
    287275        uint8_t operation_offset = *(uint8_t*)registers;
    288276        usb_log_debug("USBCMD offset: %d.\n", operation_offset);
    289 
    290         /* Zero USBCMD register. */
     277        /* zero USBCMD register */
    291278        volatile uint32_t *usbcmd =
    292             (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET);
    293         volatile uint32_t *usbconfigured =
    294             (uint32_t*)((uint8_t*)registers + operation_offset
    295             + CONFIGFLAG_OFFSET);
     279         (uint32_t*)((uint8_t*)registers + operation_offset);
    296280        usb_log_debug("USBCMD value: %x.\n", *usbcmd);
    297281        if (*usbcmd & USBCMD_RUN) {
    298282                *usbcmd = 0;
    299                 *usbconfigured = 0;
    300283                usb_log_info("EHCI turned off.\n");
    301284        } else {
     
    303286        }
    304287
     288
    305289        async_hangup(parent_phone);
    306         return ret;
    307 #undef CHECK_RET_HANGUP_RETURN
     290
     291  return ret;
    308292}
    309293/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/batch.c

    rec4538d rf16a76b  
    5757
    5858
    59 /** Allocates memory and initializes internal data structures.
    60  *
    61  * @param[in] fun DDF function to pass to callback.
    62  * @param[in] target Device and endpoint target of the transaction.
    63  * @param[in] transfer_type Interrupt, Control or Bulk.
    64  * @param[in] max_packet_size maximum allowed size of data packets.
    65  * @param[in] speed Speed of the transaction.
    66  * @param[in] buffer Data source/destination.
    67  * @param[in] size Size of the buffer.
    68  * @param[in] setup_buffer Setup data source (if not NULL)
    69  * @param[in] setup_size Size of setup_buffer (should be always 8)
    70  * @param[in] func_in function to call on inbound transaction completion
    71  * @param[in] func_out function to call on outbound transaction completion
    72  * @param[in] arg additional parameter to func_in or func_out
    73  * @param[in] manager Pointer to toggle management structure.
    74  * @return False, if there is an active TD, true otherwise.
    75  */
    7659batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    7760    usb_transfer_type_t transfer_type, size_t max_packet_size,
     
    8669        assert(func_in != NULL || func_out != NULL);
    8770
    88 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    89         if (ptr == NULL) { \
    90                 usb_log_error(message); \
    91                 if (instance) { \
    92                         batch_dispose(instance); \
    93                 } \
    94                 return NULL; \
    95         } else (void)0
    96 
    9771        batch_t *instance = malloc(sizeof(batch_t));
    98         CHECK_NULL_DISPOSE_RETURN(instance,
    99             "Failed to allocate batch instance.\n");
    100         bzero(instance, sizeof(batch_t));
    101 
    102         instance->qh = malloc32(sizeof(queue_head_t));
    103         CHECK_NULL_DISPOSE_RETURN(instance->qh,
    104             "Failed to allocate batch queue head.\n");
    105         queue_head_init(instance->qh);
     72        if (instance == NULL) {
     73                usb_log_error("Failed to allocate batch instance.\n");
     74                return NULL;
     75        }
     76
     77        instance->qh = queue_head_get();
     78        if (instance->qh == NULL) {
     79                usb_log_error("Failed to allocate queue head.\n");
     80                free(instance);
     81                return NULL;
     82        }
    10683
    10784        instance->packets = (size + max_packet_size - 1) / max_packet_size;
     
    11188
    11289        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    113         CHECK_NULL_DISPOSE_RETURN(
    114             instance->tds, "Failed to allocate transfer descriptors.\n");
     90        if (instance->tds == NULL) {
     91                usb_log_error("Failed to allocate transfer descriptors.\n");
     92                queue_head_dispose(instance->qh);
     93                free(instance);
     94                return NULL;
     95        }
    11596        bzero(instance->tds, sizeof(td_t) * instance->packets);
    11697
    117 //      const size_t transport_size = max_packet_size * instance->packets;
    118 
    119         if (size > 0) {
    120                 instance->transport_buffer = malloc32(size);
    121                 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    122                     "Failed to allocate device accessible buffer.\n");
    123         }
    124 
    125         if (setup_size > 0) {
    126                 instance->setup_buffer = malloc32(setup_size);
    127                 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
    128                     "Failed to allocate device accessible setup buffer.\n");
     98        const size_t transport_size = max_packet_size * instance->packets;
     99
     100        instance->transport_buffer =
     101           (size > 0) ? malloc32(transport_size) : NULL;
     102
     103        if ((size > 0) && (instance->transport_buffer == NULL)) {
     104                usb_log_error("Failed to allocate device accessible buffer.\n");
     105                queue_head_dispose(instance->qh);
     106                free32(instance->tds);
     107                free(instance);
     108                return NULL;
     109        }
     110
     111        instance->setup_buffer = setup_buffer ? malloc32(setup_size) : NULL;
     112        if ((setup_size > 0) && (instance->setup_buffer == NULL)) {
     113                usb_log_error("Failed to allocate device accessible setup buffer.\n");
     114                queue_head_dispose(instance->qh);
     115                free32(instance->tds);
     116                free32(instance->transport_buffer);
     117                free(instance);
     118                return NULL;
     119        }
     120        if (instance->setup_buffer) {
    129121                memcpy(instance->setup_buffer, setup_buffer, setup_size);
    130122        }
    131123
     124        instance->max_packet_size = max_packet_size;
    132125
    133126        link_initialize(&instance->link);
    134127
    135         instance->max_packet_size = max_packet_size;
    136128        instance->target = target;
    137129        instance->transfer_type = transfer_type;
     130
     131        if (func_out)
     132                instance->callback_out = func_out;
     133        if (func_in)
     134                instance->callback_in = func_in;
     135
    138136        instance->buffer = buffer;
    139137        instance->buffer_size = size;
     
    144142        instance->manager = manager;
    145143
    146         if (func_out)
    147                 instance->callback_out = func_out;
    148         if (func_in)
    149                 instance->callback_in = func_in;
    150 
    151         queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds));
    152 
     144        queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
    153145        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    154146            instance, target.address, target.endpoint);
     
    156148}
    157149/*----------------------------------------------------------------------------*/
    158 /** Checks batch TDs for activity.
    159  *
    160  * @param[in] instance Batch structure to use.
    161  * @return False, if there is an active TD, true otherwise.
    162  */
    163150bool batch_is_complete(batch_t *instance)
    164151{
     
    178165                            instance, i, instance->tds[i].status);
    179166
    180                         device_keeper_set_toggle(instance->manager,
    181                             instance->target, td_toggle(&instance->tds[i]));
     167                        device_keeper_set_toggle(instance->manager, instance->target,
     168                            td_toggle(&instance->tds[i]));
    182169                        if (i > 0)
    183170                                goto substract_ret;
     
    194181}
    195182/*----------------------------------------------------------------------------*/
    196 /** Prepares control write transaction.
    197  *
    198  * @param[in] instance Batch structure to use.
    199  */
    200183void batch_control_write(batch_t *instance)
    201184{
    202185        assert(instance);
    203186        /* we are data out, we are supposed to provide data */
    204         memcpy(instance->transport_buffer, instance->buffer,
    205             instance->buffer_size);
     187        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    206188        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    207189        instance->next_step = batch_call_out_and_dispose;
     
    210192}
    211193/*----------------------------------------------------------------------------*/
    212 /** Prepares control read transaction.
    213  *
    214  * @param[in] instance Batch structure to use.
    215  */
    216194void batch_control_read(batch_t *instance)
    217195{
     
    223201}
    224202/*----------------------------------------------------------------------------*/
    225 /** Prepares interrupt in transaction.
    226  *
    227  * @param[in] instance Batch structure to use.
    228  */
    229203void batch_interrupt_in(batch_t *instance)
    230204{
     
    236210}
    237211/*----------------------------------------------------------------------------*/
    238 /** Prepares interrupt out transaction.
    239  *
    240  * @param[in] instance Batch structure to use.
    241  */
    242212void batch_interrupt_out(batch_t *instance)
    243213{
    244214        assert(instance);
    245         /* we are data out, we are supposed to provide data */
    246215        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    247216        batch_data(instance, USB_PID_OUT);
     
    251220}
    252221/*----------------------------------------------------------------------------*/
    253 /** Prepares bulk in transaction.
    254  *
    255  * @param[in] instance Batch structure to use.
    256  */
    257222void batch_bulk_in(batch_t *instance)
    258223{
     
    264229}
    265230/*----------------------------------------------------------------------------*/
    266 /** Prepares bulk out transaction.
    267  *
    268  * @param[in] instance Batch structure to use.
    269  */
    270231void batch_bulk_out(batch_t *instance)
    271232{
     
    278239}
    279240/*----------------------------------------------------------------------------*/
    280 /** Prepares generic data transaction
    281  *
    282  * @param[in] instance Batch structure to use.
    283  * @param[in] pid to use for data packets.
    284  */
    285241void batch_data(batch_t *instance, usb_packet_id pid)
    286242{
    287243        assert(instance);
    288244        const bool low_speed = instance->speed == USB_SPEED_LOW;
    289         int toggle =
    290             device_keeper_get_toggle(instance->manager, instance->target);
     245        int toggle = device_keeper_get_toggle(instance->manager, instance->target);
    291246        assert(toggle == 0 || toggle == 1);
    292247
     
    298253                    - remain_size;
    299254
     255
    300256                const size_t packet_size =
    301257                    (instance->max_packet_size > remain_size) ?
    302258                    remain_size : instance->max_packet_size;
    303259
    304                 td_t *next_packet = (packet + 1 < instance->packets)
    305                     ? &instance->tds[packet + 1] : NULL;
    306 
    307                 assert(packet < instance->packets);
     260                td_init(&instance->tds[packet],
     261                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
     262                    instance->target, pid, data,
     263                    &instance->tds[packet + 1]);
     264
     265                toggle = 1 - toggle;
     266                ++packet;
     267                assert(packet <= instance->packets);
    308268                assert(packet_size <= remain_size);
    309 
    310                 td_init(
    311                     &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    312                     toggle, false, low_speed, instance->target, pid, data,
    313                     next_packet);
    314 
    315 
    316                 toggle = 1 - toggle;
    317269                remain_size -= packet_size;
    318                 ++packet;
    319270        }
    320271        device_keeper_set_toggle(instance->manager, instance->target, toggle);
    321 }
    322 /*----------------------------------------------------------------------------*/
    323 /** Prepares generic control transaction
    324  *
    325  * @param[in] instance Batch structure to use.
    326  * @param[in] data_stage to use for data packets.
    327  * @param[in] status_stage to use for data packets.
    328  */
     272
     273        instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     274        instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG;
     275}
     276/*----------------------------------------------------------------------------*/
    329277void batch_control(batch_t *instance,
    330278   usb_packet_id data_stage, usb_packet_id status_stage)
     
    353301                    remain_size : instance->max_packet_size;
    354302
    355                 td_init(
    356                     &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    357                     toggle, false, low_speed, instance->target, data_stage,
    358                     data, &instance->tds[packet + 1]);
     303                td_init(&instance->tds[packet],
     304                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
     305                    instance->target, data_stage, data,
     306                    &instance->tds[packet + 1]);
    359307
    360308                ++packet;
     
    375323}
    376324/*----------------------------------------------------------------------------*/
    377 /** Prepares data, gets error status and calls callback in.
    378  *
    379  * @param[in] instance Batch structure to use.
    380  */
    381325void batch_call_in(batch_t *instance)
    382326{
     
    384328        assert(instance->callback_in);
    385329
    386         /* we are data in, we need data */
    387         memcpy(instance->buffer, instance->transport_buffer,
    388             instance->buffer_size);
     330        memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size);
    389331
    390332        int err = instance->error;
     
    393335            instance->transfered_size);
    394336
    395         instance->callback_in(
    396             instance->fun, err, instance->transfered_size, instance->arg);
    397 }
    398 /*----------------------------------------------------------------------------*/
    399 /** Gets error status and calls callback out.
    400  *
    401  * @param[in] instance Batch structure to use.
    402  */
     337        instance->callback_in(instance->fun,
     338            err, instance->transfered_size,
     339            instance->arg);
     340}
     341/*----------------------------------------------------------------------------*/
    403342void batch_call_out(batch_t *instance)
    404343{
     
    413352}
    414353/*----------------------------------------------------------------------------*/
    415 /** Prepares data, gets error status, calls callback in and dispose.
    416  *
    417  * @param[in] instance Batch structure to use.
    418  */
    419354void batch_call_in_and_dispose(batch_t *instance)
    420355{
     
    424359}
    425360/*----------------------------------------------------------------------------*/
    426 /** Gets error status, calls callback out and dispose.
    427  *
    428  * @param[in] instance Batch structure to use.
    429  */
    430361void batch_call_out_and_dispose(batch_t *instance)
    431362{
     
    435366}
    436367/*----------------------------------------------------------------------------*/
    437 /** Correctly disposes all used data structures.
    438  *
    439  * @param[in] instance Batch structure to use.
    440  */
    441368void batch_dispose(batch_t *instance)
    442369{
    443370        assert(instance);
    444371        usb_log_debug("Batch(%p) disposing.\n", instance);
    445         /* free32 is NULL safe */
    446372        free32(instance->tds);
    447373        free32(instance->qh);
  • uspace/drv/uhci-hcd/iface.c

    rec4538d rf16a76b  
    4343#include "utils/device_keeper.h"
    4444
    45 /** Reserve default address interface function
    46  *
    47  * @param[in] fun DDF function that was called.
    48  * @param[in] speed Speed to associate with the new default address.
    49  * @return Error code.
    50  */
    5145/*----------------------------------------------------------------------------*/
    5246static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
     
    6054}
    6155/*----------------------------------------------------------------------------*/
    62 /** Release default address interface function
    63  *
    64  * @param[in] fun DDF function that was called.
    65  * @return Error code.
    66  */
    6756static int release_default_address(ddf_fun_t *fun)
    6857{
     
    7564}
    7665/*----------------------------------------------------------------------------*/
    77 /** Request address interface function
    78  *
    79  * @param[in] fun DDF function that was called.
    80  * @param[in] speed Speed to associate with the new default address.
    81  * @param[out] address Place to write a new address.
    82  * @return Error code.
    83  */
    8466static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    8567    usb_address_t *address)
     
    9880}
    9981/*----------------------------------------------------------------------------*/
    100 /** Bind address interface function
    101  *
    102  * @param[in] fun DDF function that was called.
    103  * @param[in] address Address of the device
    104  * @param[in] handle Devman handle of the device driver.
    105  * @return Error code.
    106  */
    10782static int bind_address(
    10883  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     
    11691}
    11792/*----------------------------------------------------------------------------*/
    118 /** Release address interface function
    119  *
    120  * @param[in] fun DDF function that was called.
    121  * @param[in] address USB address to be released.
    122  * @return Error code.
    123  */
    12493static int release_address(ddf_fun_t *fun, usb_address_t address)
    12594{
     
    132101}
    133102/*----------------------------------------------------------------------------*/
    134 /** Interrupt out transaction interface function
    135  *
    136  * @param[in] fun DDF function that was called.
    137  * @param[in] target USB device to write to.
    138  * @param[in] max_packet_size maximum size of data packet the device accepts
    139  * @param[in] data Source of data.
    140  * @param[in] size Size of data source.
    141  * @param[in] callback Function to call on transaction completion
    142  * @param[in] arg Additional for callback function.
    143  * @return Error code.
    144  */
    145103static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    146104    size_t max_packet_size, void *data, size_t size,
     
    164122}
    165123/*----------------------------------------------------------------------------*/
    166 /** Interrupt in transaction interface function
    167  *
    168  * @param[in] fun DDF function that was called.
    169  * @param[in] target USB device to write to.
    170  * @param[in] max_packet_size maximum size of data packet the device accepts
    171  * @param[out] data Data destination.
    172  * @param[in] size Size of data source.
    173  * @param[in] callback Function to call on transaction completion
    174  * @param[in] arg Additional for callback function.
    175  * @return Error code.
    176  */
    177124static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    178125    size_t max_packet_size, void *data, size_t size,
     
    195142}
    196143/*----------------------------------------------------------------------------*/
    197 /** Bulk out transaction interface function
    198  *
    199  * @param[in] fun DDF function that was called.
    200  * @param[in] target USB device to write to.
    201  * @param[in] max_packet_size maximum size of data packet the device accepts
    202  * @param[in] data Source of data.
    203  * @param[in] size Size of data source.
    204  * @param[in] callback Function to call on transaction completion
    205  * @param[in] arg Additional for callback function.
    206  * @return Error code.
    207  */
    208144static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    209145    size_t max_packet_size, void *data, size_t size,
     
    227163}
    228164/*----------------------------------------------------------------------------*/
    229 /** Bulk in transaction interface function
    230  *
    231  * @param[in] fun DDF function that was called.
    232  * @param[in] target USB device to write to.
    233  * @param[in] max_packet_size maximum size of data packet the device accepts
    234  * @param[out] data Data destination.
    235  * @param[in] size Size of data source.
    236  * @param[in] callback Function to call on transaction completion
    237  * @param[in] arg Additional for callback function.
    238  * @return Error code.
    239  */
    240165static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    241166    size_t max_packet_size, void *data, size_t size,
     
    258183}
    259184/*----------------------------------------------------------------------------*/
    260 /** Control write transaction interface function
    261  *
    262  * @param[in] fun DDF function that was called.
    263  * @param[in] target USB device to write to.
    264  * @param[in] max_packet_size maximum size of data packet the device accepts.
    265  * @param[in] setup_data Data to send with SETUP packet.
    266  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
    267  * @param[in] data Source of data.
    268  * @param[in] size Size of data source.
    269  * @param[in] callback Function to call on transaction completion.
    270  * @param[in] arg Additional for callback function.
    271  * @return Error code.
    272  */
    273185static int control_write(ddf_fun_t *fun, usb_target_t target,
    274186    size_t max_packet_size,
     
    296208}
    297209/*----------------------------------------------------------------------------*/
    298 /** Control read transaction interface function
    299  *
    300  * @param[in] fun DDF function that was called.
    301  * @param[in] target USB device to write to.
    302  * @param[in] max_packet_size maximum size of data packet the device accepts.
    303  * @param[in] setup_data Data to send with SETUP packet.
    304  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
    305  * @param[out] data Source of data.
    306  * @param[in] size Size of data source.
    307  * @param[in] callback Function to call on transaction completion.
    308  * @param[in] arg Additional for callback function.
    309  * @return Error code.
    310  */
    311210static int control_read(ddf_fun_t *fun, usb_target_t target,
    312211    size_t max_packet_size,
  • uspace/drv/uhci-hcd/main.c

    rec4538d rf16a76b  
    6060};
    6161/*----------------------------------------------------------------------------*/
    62 /** IRQ handling callback, identifies devic
    63  *
    64  * @param[in] dev DDF instance of the device to use.
    65  * @param[in] iid (Unused).
    66  * @param[in] call Pointer to the call that represents interrupt.
    67  */
    6862static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    6963{
     
    7569}
    7670/*----------------------------------------------------------------------------*/
    77 /** Initializes a new ddf driver instance of UHCI hcd.
    78  *
    79  * @param[in] device DDF instance of the device to initialize.
    80  * @return Error code.
    81  *
    82  * Gets and initialies hardware resources, disables any legacy support,
    83  * and reports root hub device.
    84  */
    85 int uhci_add_device(ddf_dev_t *device)
     71static int uhci_add_device(ddf_dev_t *device)
    8672{
    8773        assert(device);
     
    11096        ret = pci_disable_legacy(device);
    11197        CHECK_RET_FREE_HC_RETURN(ret,
    112             "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
     98            "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
    11399
    114100#if 0
     
    127113
    128114        ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
    129         CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
     115        CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",
     116            ret);
    130117#undef CHECK_RET_FREE_HC_RETURN
    131118
     
    168155}
    169156/*----------------------------------------------------------------------------*/
    170 /** Initializes global driver structures (NONE).
    171  *
    172  * @param[in] argc Nmber of arguments in argv vector (ignored).
    173  * @param[in] argv Cmdline argument vector (ignored).
    174  * @return Error code.
    175  *
    176  * Driver debug level is set here.
    177  */
    178157int main(int argc, char *argv[])
    179158{
  • uspace/drv/uhci-hcd/pci.c

    rec4538d rf16a76b  
    6565
    6666        int rc;
     67
    6768        hw_resource_list_t hw_resources;
    6869        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     
    8182        for (i = 0; i < hw_resources.count; i++) {
    8283                hw_resource_t *res = &hw_resources.resources[i];
    83                 switch (res->type)
    84                 {
    85                 case INTERRUPT:
    86                         irq = res->res.interrupt.irq;
    87                         irq_found = true;
    88                         usb_log_debug2("Found interrupt: %d.\n", irq);
    89                         break;
    90 
    91                 case IO_RANGE:
    92                         io_address = res->res.io_range.address;
    93                         io_size = res->res.io_range.size;
    94                         usb_log_debug2("Found io: %llx %zu.\n",
    95                             res->res.io_range.address, res->res.io_range.size);
    96                         io_found = true;
    97 
    98                 default:
    99                         break;
     84                switch (res->type) {
     85                        case INTERRUPT:
     86                                irq = res->res.interrupt.irq;
     87                                irq_found = true;
     88                                usb_log_debug2("Found interrupt: %d.\n", irq);
     89                                break;
     90                        case IO_RANGE:
     91                                io_address = res->res.io_range.address;
     92                                io_size = res->res.io_range.size;
     93                                usb_log_debug2("Found io: %llx %zu.\n",
     94                                    res->res.io_range.address, res->res.io_range.size);
     95                                io_found = true;
     96                                break;
     97                        default:
     98                                break;
    10099                }
    101100        }
    102101
    103         if (!io_found || !irq_found) {
     102        if (!io_found) {
     103                rc = ENOENT;
     104                goto leave;
     105        }
     106
     107        if (!irq_found) {
    104108                rc = ENOENT;
    105109                goto leave;
     
    117121}
    118122/*----------------------------------------------------------------------------*/
    119 /** Calls the PCI driver with a request to enable interrupts
    120  *
    121  * @param[in] device Device asking for interrupts
    122  * @return Error code.
    123  */
    124123int pci_enable_interrupts(ddf_dev_t *device)
    125124{
     
    131130}
    132131/*----------------------------------------------------------------------------*/
    133 /** Calls the PCI driver with a request to clear legacy support register
    134  *
    135  * @param[in] device Device asking to disable interrupts
    136  * @return Error code.
    137  */
    138132int pci_disable_legacy(ddf_dev_t *device)
    139133{
    140134        assert(device);
    141         int parent_phone =
    142             devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
     135        int parent_phone = devman_parent_device_connect(device->handle,
     136                IPC_FLAG_BLOCKING);
    143137        if (parent_phone < 0) {
    144138                return parent_phone;
     
    150144        sysarg_t value = 0x8f00;
    151145
    152         int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     146  int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    153147            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    154148        async_hangup(parent_phone);
    155149
    156         return rc;
     150  return rc;
    157151}
    158152/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/root_hub.c

    rec4538d rf16a76b  
    4545
    4646/*----------------------------------------------------------------------------*/
    47 /** Gets handle of the respective hc (parent device).
    48  *
    49  * @param[in] root_hub_fun Root hub function seeking hc handle.
    50  * @param[out] handle Place to write the handle.
    51  * @return Error code.
    52  */
    53 static int usb_iface_get_hc_handle_rh_impl(
    54     ddf_fun_t *root_hub_fun, devman_handle_t *handle)
     47static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
     48    devman_handle_t *handle)
    5549{
    56         /* TODO: Can't this use parent pointer? */
    5750        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
    5851        assert(hc_fun != NULL);
     
    6356}
    6457/*----------------------------------------------------------------------------*/
    65 /** Gets USB address of the calling device.
    66  *
    67  * @param[in] fun Root hub function.
    68  * @param[in] handle Handle of the device seeking address.
    69  * @param[out] address Place to store found address.
    70  * @return Error code.
    71  */
    72 static int usb_iface_get_address_rh_impl(
    73     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
     58static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle,
     59    usb_address_t *address)
    7460{
    75         /* TODO: What does this do? Is it neccessary? Can't it use implemented
    76          * hc function?*/
    7761        assert(fun);
    7862        ddf_fun_t *hc_fun = fun->driver_data;
     
    8165        assert(hc);
    8266
    83         usb_address_t addr = device_keeper_find(&hc->device_manager, handle);
     67        usb_address_t addr = device_keeper_find(&hc->device_manager,
     68            handle);
    8469        if (addr < 0) {
    8570                return addr;
     
    9883};
    9984/*----------------------------------------------------------------------------*/
    100 /** Gets root hub hw resources.
    101  *
    102  * @param[in] fun Root hub function.
    103  * @return Pointer to the resource list used by the root hub.
    104  */
    10585static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)
    10686{
     
    11191        assert(hc);
    11292
    113         /* TODO: fix memory leak */
     93        //TODO: fix memory leak
    11494        hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t));
    11595        assert(resource_list);
  • uspace/drv/uhci-hcd/transfer_list.c

    rec4538d rf16a76b  
    3838#include "transfer_list.h"
    3939
    40 static void transfer_list_remove_batch(
    41     transfer_list_t *instance, batch_t *batch);
    42 /*----------------------------------------------------------------------------*/
    43 /** Initializes transfer list structures.
    44  *
    45  * @param[in] instance Memory place to use.
    46  * @param[in] name Name of te new list.
    47  * @return Error code
    48  *
    49  * Allocates memory for internat queue_head_t structure.
    50  */
    5140int transfer_list_init(transfer_list_t *instance, const char *name)
    5241{
     
    5443        instance->next = NULL;
    5544        instance->name = name;
    56         instance->queue_head = malloc32(sizeof(queue_head_t));
     45        instance->queue_head = queue_head_get();
    5746        if (!instance->queue_head) {
    5847                usb_log_error("Failed to allocate queue head.\n");
    5948                return ENOMEM;
    6049        }
    61         instance->queue_head_pa = addr_to_phys(instance->queue_head);
     50        instance->queue_head_pa = (uintptr_t)addr_to_phys(instance->queue_head);
    6251
    6352        queue_head_init(instance->queue_head);
     
    6756}
    6857/*----------------------------------------------------------------------------*/
    69 /** Set the next list in chain.
    70  *
    71  * @param[in] instance List to lead.
    72  * @param[in] next List to append.
    73  * @return Error code
    74  */
    7558void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
    7659{
     
    8366}
    8467/*----------------------------------------------------------------------------*/
    85 /** Submits a new transfer batch to list and queue.
    86  *
    87  * @param[in] instance List to use.
    88  * @param[in] batch Transfer batch to submit.
    89  * @return Error code
    90  */
    9168void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch)
    9269{
    9370        assert(instance);
    9471        assert(batch);
    95         usb_log_debug2(
    96             "Adding batch(%p) to queue %s.\n", batch, instance->name);
     72        usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name);
    9773
    9874        uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     
    12197        queue_head_append_qh(last->qh, pa);
    12298        list_append(&batch->link, &instance->batch_list);
    123 
    12499        usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
    125                 batch, instance->name, first);
     100                batch, instance->name, first );
    126101        fibril_mutex_unlock(&instance->guard);
    127102}
    128103/*----------------------------------------------------------------------------*/
    129 /** Removes a transfer batch from list and queue.
    130  *
    131  * @param[in] instance List to use.
    132  * @param[in] batch Transfer batch to remove.
    133  * @return Error code
    134  */
    135 void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch)
     104static void transfer_list_remove_batch(
     105    transfer_list_t *instance, batch_t *batch)
    136106{
    137107        assert(instance);
     
    139109        assert(instance->queue_head);
    140110        assert(batch->qh);
    141         usb_log_debug2(
    142             "Removing batch(%p) from queue %s.\n", batch, instance->name);
     111        usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name);
    143112
     113        /* I'm the first one here */
    144114        if (batch->link.prev == &instance->batch_list) {
    145                 /* I'm the first one here */
    146                 usb_log_debug(
    147                     "Batch(%p) removed (FIRST) from %s, next element %x.\n",
    148                     batch, instance->name, batch->qh->next_queue);
     115                usb_log_debug("Batch(%p) removed (FIRST) from queue %s, next element %x.\n",
     116                        batch, instance->name, batch->qh->next_queue);
    149117                instance->queue_head->element = batch->qh->next_queue;
    150118        } else {
    151                 usb_log_debug(
    152                     "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",
    153                     batch, instance->name, batch->qh->next_queue);
    154                 batch_t *prev =
    155                     list_get_instance(batch->link.prev, batch_t, link);
     119                usb_log_debug("Batch(%p) removed (NOT FIRST) from queue, next element %x.\n",
     120                        batch, instance->name, batch->qh->next_queue);
     121                batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
    156122                prev->qh->next_queue = batch->qh->next_queue;
    157123        }
     
    159125}
    160126/*----------------------------------------------------------------------------*/
    161 /** Checks list for finished transfers.
    162  *
    163  * @param[in] instance List to use.
    164  * @return Error code
    165  */
    166127void transfer_list_remove_finished(transfer_list_t *instance)
    167128{
  • uspace/drv/uhci-hcd/transfer_list.h

    rec4538d rf16a76b  
    5858{
    5959        assert(instance);
    60         free32(instance->queue_head);
     60        queue_head_dispose(instance->queue_head);
    6161}
    6262void transfer_list_remove_finished(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/uhci.c

    rec4538d rf16a76b  
    6161};
    6262
    63 /** Gets USB address of the calling device.
    64  *
    65  * @param[in] fun UHCI hc function.
    66  * @param[in] handle Handle of the device seeking address.
    67  * @param[out] address Place to store found address.
    68  * @return Error code.
    69  */
    70 static int usb_iface_get_address(
    71     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
     63static int usb_iface_get_address(ddf_fun_t *fun, devman_handle_t handle,
     64    usb_address_t *address)
    7265{
    7366        assert(fun);
     
    10699
    107100static bool allowed_usb_packet(
    108     bool low_speed, usb_transfer_type_t transfer, size_t size);
    109 /*----------------------------------------------------------------------------*/
    110 /** Initializes UHCI hcd driver structure
    111  *
    112  * @param[in] instance Memory place to initialize.
    113  * @param[in] dev DDF device.
    114  * @param[in] regs Address of I/O control registers.
    115  * @param[in] size Size of I/O control registers.
    116  * @return Error code.
    117  * @note Should be called only once on any structure.
    118  */
     101        bool low_speed, usb_transfer_type_t, size_t size);
     102
     103
    119104int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size)
    120105{
     
    171156}
    172157/*----------------------------------------------------------------------------*/
    173 /** Initializes UHCI hcd hw resources.
    174  *
    175  * @param[in] instance UHCI structure to use.
    176  */
    177158void uhci_init_hw(uhci_t *instance)
    178159{
    179160        assert(instance);
    180         regs_t *registers = instance->registers;
    181 
    182         /* Reset everything, who knows what touched it before us */
    183         pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     161
     162        /* reset everything, who knows what touched it before us */
     163        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
    184164        async_usleep(10000); /* 10ms according to USB spec */
    185         pio_write_16(&registers->usbcmd, 0);
    186 
    187         /* Reset hc, all states and counters */
    188         pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
     165        pio_write_16(&instance->registers->usbcmd, 0);
     166
     167        /* reset hc, all states and counters */
     168        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
    189169        do { async_usleep(10); }
    190         while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
    191 
    192         /* Set framelist pointer */
     170        while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
     171
     172        /* set framelist pointer */
    193173        const uint32_t pa = addr_to_phys(instance->frame_list);
    194         pio_write_32(&registers->flbaseadd, pa);
    195 
    196         /* Enable all interrupts, but resume interrupt */
     174        pio_write_32(&instance->registers->flbaseadd, pa);
     175
     176        /* enable all interrupts, but resume interrupt */
    197177//      pio_write_16(&instance->registers->usbintr,
    198178//          UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    199179
    200         uint16_t status = pio_read_16(&registers->usbcmd);
    201         if (status != 0)
    202                 usb_log_warning("Previous command value: %x.\n", status);
    203 
     180        uint16_t status = pio_read_16(&instance->registers->usbcmd);
     181        usb_log_warning("Previous command value: %x.\n", status);
    204182        /* Start the hc with large(64B) packet FSBR */
    205         pio_write_16(&registers->usbcmd,
     183        pio_write_16(&instance->registers->usbcmd,
    206184            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    207185}
    208186/*----------------------------------------------------------------------------*/
    209 /** Initializes UHCI hcd memory structures.
    210  *
    211  * @param[in] instance UHCI structure to use.
    212  * @return Error code
    213  * @note Should be called only once on any structure.
    214  */
    215187int uhci_init_mem_structures(uhci_t *instance)
    216188{
     
    224196        } else (void) 0
    225197
    226         /* Init interrupt code */
     198        /* init interrupt code */
    227199        instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
    228200        int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
    229         CHECK_RET_DEST_CMDS_RETURN(ret,
    230             "Failed to allocate interrupt cmds space.\n");
     201        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n");
    231202
    232203        {
    233204                irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
    234205                memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
    235                 interrupt_commands[0].addr =
    236                     (void*)&instance->registers->usbsts;
    237                 interrupt_commands[1].addr =
    238                     (void*)&instance->registers->usbsts;
     206                interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
     207                interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
    239208                instance->interrupt_code.cmdcount =
    240209                    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
    241210        }
    242211
    243         /* Init transfer lists */
     212        /* init transfer lists */
    244213        ret = uhci_init_transfer_lists(instance);
    245         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
     214        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to initialize transfer lists.\n");
    246215        usb_log_debug("Initialized transfer lists.\n");
    247216
    248         /* Init USB frame list page*/
     217        /* frame list initialization */
    249218        instance->frame_list = get_page();
    250219        ret = instance ? EOK : ENOMEM;
     
    252221        usb_log_debug("Initialized frame list.\n");
    253222
    254         /* Set all frames to point to the first queue head */
     223        /* initialize all frames to point to the first queue head */
    255224        const uint32_t queue =
    256225          instance->transfers_interrupt.queue_head_pa
     
    262231        }
    263232
    264         /* Init device keeper*/
     233        /* init address keeper(libusb) */
    265234        device_keeper_init(&instance->device_manager);
    266235        usb_log_debug("Initialized device manager.\n");
     
    270239}
    271240/*----------------------------------------------------------------------------*/
    272 /** Initializes UHCI hcd transfer lists.
    273  *
    274  * @param[in] instance UHCI structure to use.
    275  * @return Error code
    276  * @note Should be called only once on any structure.
    277  */
    278241int uhci_init_transfer_lists(uhci_t *instance)
    279242{
     
    294257        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
    295258
    296         ret = transfer_list_init(
    297             &instance->transfers_control_full, "CONTROL_FULL");
     259        ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL");
    298260        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
    299261
    300         ret = transfer_list_init(
    301             &instance->transfers_control_slow, "CONTROL_SLOW");
     262        ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW");
    302263        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
    303264
     
    318279#endif
    319280
    320         /* Assign pointers to be used during scheduling */
    321         instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] =
     281        instance->transfers[0][USB_TRANSFER_INTERRUPT] =
    322282          &instance->transfers_interrupt;
    323         instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] =
     283        instance->transfers[1][USB_TRANSFER_INTERRUPT] =
    324284          &instance->transfers_interrupt;
    325         instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] =
     285        instance->transfers[0][USB_TRANSFER_CONTROL] =
    326286          &instance->transfers_control_full;
    327         instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] =
     287        instance->transfers[1][USB_TRANSFER_CONTROL] =
    328288          &instance->transfers_control_slow;
    329         instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
     289        instance->transfers[0][USB_TRANSFER_BULK] =
    330290          &instance->transfers_bulk_full;
    331291
     
    334294}
    335295/*----------------------------------------------------------------------------*/
    336 /** Schedules batch for execution.
    337  *
    338  * @param[in] instance UHCI structure to use.
    339  * @param[in] batch Transfer batch to schedule.
    340  * @return Error code
    341  */
    342296int uhci_schedule(uhci_t *instance, batch_t *batch)
    343297{
     
    347301        if (!allowed_usb_packet(
    348302            low_speed, batch->transfer_type, batch->max_packet_size)) {
    349                 usb_log_warning(
    350                     "Invalid USB packet specified %s SPEED %d %zu.\n",
     303                usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
    351304                    low_speed ? "LOW" : "FULL" , batch->transfer_type,
    352305                    batch->max_packet_size);
     
    363316}
    364317/*----------------------------------------------------------------------------*/
    365 /** Takes action based on the interrupt cause.
    366  *
    367  * @param[in] instance UHCI structure to use.
    368  * @param[in] status Value of the stsatus regiser at the time of interrupt.
    369  */
    370318void uhci_interrupt(uhci_t *instance, uint16_t status)
    371319{
    372320        assert(instance);
    373         /* TODO: Check interrupt cause here */
    374321        transfer_list_remove_finished(&instance->transfers_interrupt);
    375322        transfer_list_remove_finished(&instance->transfers_control_slow);
     
    378325}
    379326/*----------------------------------------------------------------------------*/
    380 /** Polling function, emulates interrupts.
    381  *
    382  * @param[in] arg UHCI structure to use.
    383  * @return EOK
    384  */
    385327int uhci_interrupt_emulator(void* arg)
    386328{
     
    401343}
    402344/*---------------------------------------------------------------------------*/
    403 /** Debug function, checks consistency of memory structures.
    404  *
    405  * @param[in] arg UHCI structure to use.
    406  * @return EOK
    407  */
    408345int uhci_debug_checker(void *arg)
    409346{
     
    464401                async_usleep(UHCI_DEBUGER_TIMEOUT);
    465402        }
    466         return EOK;
     403        return 0;
    467404#undef QH
    468405}
    469406/*----------------------------------------------------------------------------*/
    470 /** Checks transfer packets, for USB validity
    471  *
    472  * @param[in] low_speed Transfer speed.
    473  * @param[in] transfer Transer type
    474  * @param[in] size Maximum size of used packets
    475  * @return EOK
    476  */
    477407bool allowed_usb_packet(
    478408    bool low_speed, usb_transfer_type_t transfer, size_t size)
  • uspace/drv/uhci-hcd/uhci.h

    rec4538d rf16a76b  
    8484        device_keeper_t device_manager;
    8585
    86         regs_t *registers;
     86        volatile regs_t *registers;
    8787
    8888        link_pointer_t *frame_list;
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

    rec4538d rf16a76b  
    7171}
    7272
    73 static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa)
     73static inline void queue_head_element_td(queue_head_t *instance, uint32_t pa)
    7474{
    7575        if (pa) {
     
    7878}
    7979
     80static inline queue_head_t * queue_head_get() {
     81        queue_head_t *ret = malloc32(sizeof(queue_head_t));
     82        if (ret)
     83                queue_head_init(ret);
     84        return ret;
     85}
     86
     87static inline void queue_head_dispose(queue_head_t *head)
     88        { free32(head); }
     89
     90
    8091#endif
    8192/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    rec4538d rf16a76b  
    3838#include "utils/malloc32.h"
    3939
    40 /** Initializes Transfer Descriptor
    41  *
    42  * @param[in] instance Memory place to initialize.
    43  * @param[in] err_count Number of retries hc should attempt.
    44  * @param[in] size Size of data source.
    45  * @param[in] toggle Value of toggle bit.
    46  * @param[in] iso True if TD is for Isochronous transfer.
    47  * @param[in] low_speed Target device's speed.
    48  * @param[in] target Address and endpoint receiving the transfer.
    49  * @param[in] pid Packet identification (SETUP, IN or OUT).
    50  * @param[in] buffer Source of data.
    51  * @param[in] next Net TD in transaction.
    52  * @return Error code.
    53  */
    5440void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
    55     bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
    56     td_t *next)
     41    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, td_t *next)
    5742{
    5843        assert(instance);
    5944        assert(size < 1024);
    60         assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
    61             || (pid == USB_PID_OUT));
     45        assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN) || (pid == USB_PID_OUT));
    6246
    6347        instance->next = 0
     
    9781}
    9882/*----------------------------------------------------------------------------*/
    99 /** Converts TD status into standard error code
    100  *
    101  * @param[in] instance TD structure to use.
    102  * @return Error code.
    103  */
    10483int td_status(td_t *instance)
    10584{
  • uspace/drv/uhci-hcd/utils/device_keeper.c

    rec4538d rf16a76b  
    3939
    4040/*----------------------------------------------------------------------------*/
    41 /** Initializes device keeper structure.
    42  *
    43  * @param[in] instance Memory place to initialize.
    44  */
    4541void device_keeper_init(device_keeper_t *instance)
    4642{
     
    5753}
    5854/*----------------------------------------------------------------------------*/
    59 /** Attempts to obtain address 0, blocks.
    60  *
    61  * @param[in] instance Device keeper structure to use.
    62  * @param[in] speed Speed of the device requesting default address.
    63  */
    64 void device_keeper_reserve_default(device_keeper_t *instance, usb_speed_t speed)
     55void device_keeper_reserve_default(
     56    device_keeper_t *instance, usb_speed_t speed)
    6557{
    6658        assert(instance);
     
    7567}
    7668/*----------------------------------------------------------------------------*/
    77 /** Attempts to obtain address 0, blocks.
    78  *
    79  * @param[in] instance Device keeper structure to use.
    80  * @param[in] speed Speed of the device requesting default address.
    81  */
    8269void device_keeper_release_default(device_keeper_t *instance)
    8370{
     
    8976}
    9077/*----------------------------------------------------------------------------*/
    91 /** Checks setup data for signs of toggle reset.
    92  *
    93  * @param[in] instance Device keeper structure to use.
    94  * @param[in] target Device to receive setup packet.
    95  * @param[in] data Setup packet data.
    96  */
    9778void device_keeper_reset_if_need(
    9879    device_keeper_t *instance, usb_target_t target, const unsigned char *data)
     
    10384            || target.address >= USB_ADDRESS_COUNT || target.address < 0
    10485            || !instance->devices[target.address].occupied) {
    105                 fibril_mutex_unlock(&instance->guard);
    106                 return;
     86                goto the_end;
    10787        }
    10888
     
    11090        {
    11191        case 0x01: /*clear feature*/
    112                 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     92                /* recipient is enpoint, value is zero (ENDPOINT_STALL) */
    11393                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    114                         /* endpoint number is < 16, thus first byte is enough */
    115                         instance->devices[target.address].toggle_status &=
    116                             ~(1 << data[4]);
     94                        /* enpoint number is < 16, thus first byte is enough */
     95                        instance->devices[target.address].toggle_status &= ~(1 << data[4]);
    11796                }
    11897        break;
     
    123102        break;
    124103        }
    125         fibril_mutex_unlock(&instance->guard);
    126 }
    127 /*----------------------------------------------------------------------------*/
    128 /** Gets current value of endpoint toggle.
    129  *
    130  * @param[in] instance Device keeper structure to use.
    131  * @param[in] target Device and endpoint used.
    132  * @return Error code
    133  */
     104the_end:
     105        fibril_mutex_unlock(&instance->guard);
     106}
     107/*----------------------------------------------------------------------------*/
    134108int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
    135109{
     
    142116                ret = EINVAL;
    143117        } else {
    144                 ret =
    145                     (instance->devices[target.address].toggle_status
    146                         >> target.endpoint) & 1;
     118                ret = (instance->devices[target.address].toggle_status >> target.endpoint) & 1;
    147119        }
    148120        fibril_mutex_unlock(&instance->guard);
     
    150122}
    151123/*----------------------------------------------------------------------------*/
    152 /** Sets current value of endpoint toggle.
    153  *
    154  * @param[in] instance Device keeper structure to use.
    155  * @param[in] target Device and endpoint used.
    156  * @param[in] toggle Current toggle value.
    157  * @return Error code.
    158  */
    159124int device_keeper_set_toggle(
    160125    device_keeper_t *instance, usb_target_t target, bool toggle)
     
    179144}
    180145/*----------------------------------------------------------------------------*/
    181 /** Gets a free USB address
    182  *
    183  * @param[in] instance Device keeper structure to use.
    184  * @param[in] speed Speed of the device requiring address.
    185  * @return Free address, or error code.
    186  */
    187146usb_address_t device_keeper_request(
    188147    device_keeper_t *instance, usb_speed_t speed)
     
    212171}
    213172/*----------------------------------------------------------------------------*/
    214 /** Binds USB address to devman handle.
    215  *
    216  * @param[in] instance Device keeper structure to use.
    217  * @param[in] address Device address
    218  * @param[in] handle Devman handle of the device.
    219  */
    220173void device_keeper_bind(
    221174    device_keeper_t *instance, usb_address_t address, devman_handle_t handle)
     
    230183}
    231184/*----------------------------------------------------------------------------*/
    232 /** Releases used USB address.
    233  *
    234  * @param[in] instance Device keeper structure to use.
    235  * @param[in] address Device address
    236  */
    237185void device_keeper_release(device_keeper_t *instance, usb_address_t address)
    238186{
     
    247195}
    248196/*----------------------------------------------------------------------------*/
    249 /** Finds USB address associated with the device
    250  *
    251  * @param[in] instance Device keeper structure to use.
    252  * @param[in] handle Devman handle of the device seeking its address.
    253  * @return USB Address, or error code.
    254  */
    255197usb_address_t device_keeper_find(
    256198    device_keeper_t *instance, devman_handle_t handle)
     
    270212}
    271213/*----------------------------------------------------------------------------*/
    272 /** Gets speed associated with the address
    273  *
    274  * @param[in] instance Device keeper structure to use.
    275  * @param[in] address Address of the device.
    276  * @return USB speed.
    277  */
    278214usb_speed_t device_keeper_speed(
    279215    device_keeper_t *instance, usb_address_t address)
  • uspace/drv/uhci-rhd/main.c

    rec4538d rf16a76b  
    3535#include <devman.h>
    3636#include <device/hw_res.h>
    37 #include <errno.h>
    3837#include <usb_iface.h>
    3938#include <usb/ddfiface.h>
     39
     40#include <errno.h>
     41
    4042#include <usb/debug.h>
    41 
    42 
    4343
    4444#include "root_hub.h"
     
    4747static int hc_get_my_registers(ddf_dev_t *dev,
    4848    uintptr_t *io_reg_address, size_t *io_reg_size);
    49 /*----------------------------------------------------------------------------*/
     49
    5050static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    5151{
     
    5858        return EOK;
    5959}
    60 /*----------------------------------------------------------------------------*/
     60
    6161static usb_iface_t uhci_rh_usb_iface = {
    6262        .get_hc_handle = usb_iface_get_hc_handle,
    6363        .get_address = usb_iface_get_address_hub_impl
    6464};
    65 /*----------------------------------------------------------------------------*/
     65
    6666static ddf_dev_ops_t uhci_rh_ops = {
    6767        .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface,
    6868};
    69 /*----------------------------------------------------------------------------*/
    70 /** Initializes a new ddf driver instance of UHCI root hub.
    71  *
    72  * @param[in] device DDF instance of the device to initialize.
    73  * @return Error code.
    74  */
     69
    7570static int uhci_rh_add_device(ddf_dev_t *device)
    7671{
     
    109104        return EOK;
    110105}
    111 /*----------------------------------------------------------------------------*/
     106
    112107static driver_ops_t uhci_rh_driver_ops = {
    113108        .add_device = uhci_rh_add_device,
    114109};
    115 /*----------------------------------------------------------------------------*/
     110
    116111static driver_t uhci_rh_driver = {
    117112        .name = NAME,
     
    119114};
    120115/*----------------------------------------------------------------------------*/
    121 /** Initializes global driver structures (NONE).
    122  *
    123  * @param[in] argc Nmber of arguments in argv vector (ignored).
    124  * @param[in] argv Cmdline argument vector (ignored).
    125  * @return Error code.
    126  *
    127  * Driver debug level is set here.
    128  */
    129116int main(int argc, char *argv[])
    130117{
     
    133120}
    134121/*----------------------------------------------------------------------------*/
    135 /** Get address of I/O registers.
    136  *
    137  * @param[in] dev Device asking for the addresses.
    138  * @param[out] io_reg_address Base address of the memory range.
    139  * @param[out] io_reg_size Size of the memory range.
    140  * @return Error code.
    141  */
    142 int hc_get_my_registers(
    143     ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
     122int hc_get_my_registers(ddf_dev_t *dev,
     123    uintptr_t *io_reg_address, size_t *io_reg_size)
    144124{
    145125        assert(dev != NULL);
     
    166146        for (i = 0; i < hw_resources.count; i++) {
    167147                hw_resource_t *res = &hw_resources.resources[i];
    168                 switch (res->type)
    169                 {
    170                 case IO_RANGE:
    171                         io_address = (uintptr_t) res->res.io_range.address;
    172                         io_size = res->res.io_range.size;
    173                         io_found = true;
    174 
    175                 default:
    176                         break;
     148                switch (res->type) {
     149                        case IO_RANGE:
     150                                io_address = (uintptr_t)
     151                                    res->res.io_range.address;
     152                                io_size = res->res.io_range.size;
     153                                io_found = true;
     154                                break;
     155                        default:
     156                                break;
    177157                }
    178158        }
     
    190170        }
    191171        rc = EOK;
    192 
    193172leave:
    194173        async_hangup(parent_phone);
     174
    195175        return rc;
    196176}
  • uspace/drv/uhci-rhd/port.c

    rec4538d rf16a76b  
    4646#include "port_status.h"
    4747
    48 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
     48static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
    4949static int uhci_port_remove_device(uhci_port_t *port);
    5050static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5151static int uhci_port_check(void *port);
    52 static int uhci_port_reset_enable(int portno, void *arg);
    53 /*----------------------------------------------------------------------------*/
    54 /** Initializes UHCI root hub port instance.
    55  *
    56  * @param[in] port Memory structure to use.
    57  * @param[in] addr Address of I/O register.
    58  * @param[in] number Port number.
    59  * @param[in] usec Polling interval.
    60  * @param[in] rh Pointer to ddf instance fo the root hub driver.
    61  * @return Error code.
    62  *
    63  * Starts the polling fibril.
    64  */
    65 int uhci_port_init(uhci_port_t *port,
    66     port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
     52static int new_device_enable_port(int portno, void *arg);
     53
     54int uhci_port_init(
     55  uhci_port_t *port, port_status_t *address, unsigned number,
     56  unsigned usec, ddf_dev_t *rh)
    6757{
    6858        assert(port);
    69 
    7059        port->address = address;
    7160        port->number = number;
     
    7362        port->attached_device = 0;
    7463        port->rh = rh;
    75 
    7664        int rc = usb_hc_connection_initialize_from_device(
    7765            &port->hc_connection, rh);
     
    8775                return ENOMEM;
    8876        }
    89 
    9077        fibril_add_ready(port->checker);
    9178        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     
    9481}
    9582/*----------------------------------------------------------------------------*/
    96 /** Finishes UHCI root hub port instance.
    97  *
    98  * @param[in] port Memory structure to use.
    99  *
    100  * Stops the polling fibril.
    101  */
    10283void uhci_port_fini(uhci_port_t *port)
    10384{
    104         /* TODO: Kill fibril here */
     85// TODO: destroy fibril
     86// TODO: hangup phone
     87//      fibril_teardown(port->checker);
    10588        return;
    10689}
    10790/*----------------------------------------------------------------------------*/
    108 /** Periodically checks port status and reports new devices.
    109  *
    110  * @param[in] port Memory structure to use.
    111  * @return Error code.
    112  */
    11391int uhci_port_check(void *port)
    11492{
    115         uhci_port_t *instance = port;
    116         assert(instance);
    117 
    118         /* Iteration count, for debug purposes only */
     93        uhci_port_t *port_instance = port;
     94        assert(port_instance);
     95//      port_status_write(port_instance->address, 0);
     96
    11997        unsigned count = 0;
    12098
    12199        while (1) {
    122                 async_usleep(instance->wait_period_usec);
     100                async_usleep(port_instance->wait_period_usec);
    123101
    124102                /* read register value */
    125                 port_status_t port_status = port_status_read(instance->address);
    126 
    127                 /* debug print mutex */
    128                 static fibril_mutex_t dbg_mtx =
    129                     FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     103                port_status_t port_status =
     104                        port_status_read(port_instance->address);
     105
     106                /* debug print */
     107                static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
    130108                fibril_mutex_lock(&dbg_mtx);
    131109                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
    132                   instance->address, instance->number, port_status, count++);
     110                  port_instance->address, port_instance->number, port_status, count++);
    133111//              print_port_status(port_status);
    134112                fibril_mutex_unlock(&dbg_mtx);
    135113
    136                 if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
    137                         continue;
    138 
    139                 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
    140                     instance->address, instance->number, port_status);
    141 
    142                 int rc =
    143                     usb_hc_connection_open(&instance->hc_connection);
    144                 if (rc != EOK) {
    145                         usb_log_error("Port(%p - %d): Failed to connect to HC.",
    146                             instance->address, instance->number);
    147                         continue;
     114                if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
     115                        usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
     116                            port_instance->address, port_instance->number, port_status);
     117
     118
     119                        int rc = usb_hc_connection_open(
     120                            &port_instance->hc_connection);
     121                        if (rc != EOK) {
     122                                usb_log_error("Port(%p - %d): Failed to connect to HC.",
     123                                    port_instance->address, port_instance->number);
     124                                continue;
     125                        }
     126
     127                        /* remove any old device */
     128                        if (port_instance->attached_device) {
     129                                usb_log_debug("Port(%p - %d): Removing device.\n",
     130                                    port_instance->address, port_instance->number);
     131                                uhci_port_remove_device(port_instance);
     132                        }
     133
     134                        if ((port_status & STATUS_CONNECTED) != 0) {
     135                                /* new device */
     136                                uhci_port_new_device(port_instance, port_status);
     137                        } else {
     138                                /* ack changes by writing one to WC bits */
     139                                port_status_write(port_instance->address, port_status);
     140                                usb_log_debug("Port(%p - %d): Change status ACK.\n",
     141                                                port_instance->address, port_instance->number);
     142                        }
     143
     144                        rc = usb_hc_connection_close(
     145                            &port_instance->hc_connection);
     146                        if (rc != EOK) {
     147                                usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
     148                                    port_instance->address, port_instance->number);
     149                        }
    148150                }
    149 
    150                 /* Remove any old device */
    151                 if (instance->attached_device) {
    152                         usb_log_debug2("Port(%p - %d): Removing device.\n",
    153                             instance->address, instance->number);
    154                         uhci_port_remove_device(instance);
    155                 }
    156 
    157                 if ((port_status & STATUS_CONNECTED) != 0) {
    158                         /* New device */
    159                         const usb_speed_t speed =
    160                             ((port_status & STATUS_LOW_SPEED) != 0) ?
    161                             USB_SPEED_LOW : USB_SPEED_FULL;
    162                         uhci_port_new_device(instance, speed);
    163                 } else {
    164                         /* Write one to WC bits, to ack changes */
    165                         port_status_write(instance->address, port_status);
    166                         usb_log_debug("Port(%p - %d): Change status ACK.\n",
    167                             instance->address, instance->number);
    168                 }
    169 
    170                 rc = usb_hc_connection_close(&instance->hc_connection);
    171                 if (rc != EOK) {
    172                         usb_log_error("Port(%p - %d): Failed to disconnect.",
    173                             instance->address, instance->number);
    174                 }
    175         }
    176         return EOK;
    177 }
    178 /*----------------------------------------------------------------------------*/
     151        }
     152        return EOK;
     153}
     154
    179155/** Callback for enabling port during adding a new device.
    180156 *
     
    183159 * @return Error code.
    184160 */
    185 int uhci_port_reset_enable(int portno, void *arg)
     161static int new_device_enable_port(int portno, void *arg)
    186162{
    187163        uhci_port_t *port = (uhci_port_t *) arg;
     
    208184                port_status_write(port->address, port_status);
    209185                async_usleep(10000);
    210                 port_status = port_status_read(port->address);
     186                port_status =
     187                        port_status_read(port->address);
    211188                port_status &= ~STATUS_IN_RESET;
    212189                port_status_write(port->address, port_status);
     
    217194        /* Enable the port. */
    218195        uhci_port_set_enabled(port, true);
    219         return EOK;
    220 }
    221 /*----------------------------------------------------------------------------*/
    222 /** Initializes and reports connected device.
    223  *
    224  * @param[in] port Memory structure to use.
    225  * @param[in] speed Detected speed.
    226  * @return Error code.
    227  *
    228  * Uses libUSB function to do the actual work.
    229  */
    230 int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
     196
     197        return EOK;
     198}
     199
     200/*----------------------------------------------------------------------------*/
     201static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
    231202{
    232203        assert(port);
     
    238209        usb_address_t dev_addr;
    239210        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    240             speed, uhci_port_reset_enable, port->number, port,
     211            ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
     212            new_device_enable_port, port->number, port,
    241213            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    242214
    243215        if (rc != EOK) {
    244                 usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n",
     216                usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
    245217                    port->address, port->number, rc, str_error(rc));
    246218                uhci_port_set_enabled(port, false);
     
    253225        return EOK;
    254226}
    255 /*----------------------------------------------------------------------------*/
    256 /** Removes device.
    257  *
    258  * @param[in] port Memory structure to use.
    259  * @return Error code.
    260  *
    261  * Does not work DDF does not support device removal.
    262  */
    263 int uhci_port_remove_device(uhci_port_t *port)
     227
     228/*----------------------------------------------------------------------------*/
     229static int uhci_port_remove_device(uhci_port_t *port)
    264230{
    265231        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
    266             port->address, port->number, (unsigned int)port->attached_device);
    267         return EOK;
    268 }
    269 /*----------------------------------------------------------------------------*/
    270 /** Enables and disables port.
    271  *
    272  * @param[in] port Memory structure to use.
    273  * @return Error code. (Always EOK)
    274  */
    275 int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
     232                port->address, port->number, (unsigned int)port->attached_device);
     233//      uhci_port_set_enabled(port, false);
     234        return EOK;
     235}
     236/*----------------------------------------------------------------------------*/
     237static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
    276238{
    277239        assert(port);
    278240
    279         /* Read register value */
    280         port_status_t port_status = port_status_read(port->address);
    281 
    282         /* Set enabled bit */
     241        /* read register value */
     242        port_status_t port_status
     243                = port_status_read(port->address);
     244
     245        /* enable port: register write */
    283246        if (enabled) {
    284247                port_status |= STATUS_ENABLED;
     
    286249                port_status &= ~STATUS_ENABLED;
    287250        }
    288 
    289         /* Write new value. */
    290251        port_status_write(port->address, port_status);
    291252
  • uspace/drv/uhci-rhd/port_status.c

    rec4538d rf16a76b  
    6060};
    6161
    62 /** Prints portr status in a human readable way.
    63  *
    64  * @param[in] value Port value to print.
    65  * @return Error code.
    66  */
    6762void print_port_status(port_status_t value)
    6863{
  • uspace/drv/uhci-rhd/root_hub.c

    rec4538d rf16a76b  
    4040#include "root_hub.h"
    4141
    42 /** Initializes UHCI root hub instance.
    43  *
    44  * @param[in] instance Driver memory structure to use.
    45  * @param[in] addr Address of I/O registers.
    46  * @param[in] size Size of available I/O space.
    47  * @param[in] rh Pointer to ddf instance fo the root hub driver.
    48  * @return Error code.
    49  */
    5042int uhci_root_hub_init(
    5143  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
     
    5547        int ret;
    5648
    57         /* Allow access to root hub port registers */
    58         assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
     49        /* allow access to root hub registers */
     50        assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);
    5951        port_status_t *regs;
    6052        ret = pio_enable(addr, size, (void**)&regs);
     53
    6154        if (ret < 0) {
    62                 usb_log_error(
    63                     "Failed to gain access to port registers at %p\n", regs);
     55                usb_log_error("Failed to gain access to port registers at %p\n", regs);
    6456                return ret;
    6557        }
     
    6860        unsigned i = 0;
    6961        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    70                 /* NOTE: mind pointer arithmetics here */
     62                /* mind pointer arithmetics */
    7163                ret = uhci_port_init(
    72                     &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
     64                  &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
    7365                if (ret != EOK) {
    7466                        unsigned j = 0;
     
    8274}
    8375/*----------------------------------------------------------------------------*/
    84 /** Finishes UHCI root hub instance.
    85  *
    86  * @param[in] instance Driver memory structure to use.
    87  * @return Error code.
    88  */
    89 int uhci_root_hub_fini(uhci_root_hub_t* instance)
     76int uhci_root_hub_fini( uhci_root_hub_t* instance )
    9077{
    91         assert(instance);
    92         unsigned i = 0;
    93         for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    94                 uhci_port_fini(&instance->ports[i]);
    95         }
     78        assert( instance );
     79        // TODO:
     80        //destroy fibril here
     81        //disable access to registers
    9682        return EOK;
    9783}
Note: See TracChangeset for help on using the changeset viewer.