Changeset 62066b4 in mainline


Ignore:
Timestamp:
2011-02-20T21:47:23Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ace12560
Parents:
6bb83c7 (diff), 423e8c81 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge with usb/development

Location:
uspace
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/pciintel/pci.c

    r6bb83c7 r62066b4  
    4949#include <ipc/devman.h>
    5050#include <ipc/dev_iface.h>
     51#include <ipc/irc.h>
     52#include <ipc/ns.h>
     53#include <ipc/services.h>
     54#include <sysinfo.h>
    5155#include <ops/hw_res.h>
    5256#include <device/hw_res.h>
     
    7276static bool pciintel_enable_child_interrupt(device_t *dev)
    7377{
    74         /* TODO */
    75        
    76         return false;
     78        /* This is an old ugly way, copied from ne2000 driver */
     79        assert(dev);
     80        pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     81
     82  sysarg_t apic;
     83  sysarg_t i8259;
     84        int irc_phone = -1;
     85        int irc_service = 0;
     86
     87  if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     88    irc_service = SERVICE_APIC;
     89        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     90    irc_service = SERVICE_I8259;
     91        }
     92
     93  if (irc_service) {
     94    while (irc_phone < 0)
     95      irc_phone = service_connect_blocking(irc_service, 0, 0);
     96  } else {
     97                return false;
     98        }
     99
     100        size_t i;
     101  for (i = 0; i < dev_data->hw_resources.count; i++) {
     102                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
     103                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
     104                        async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     105                }
     106        }
     107
     108        async_hangup(irc_phone);
     109        return true;
    77110}
    78111
  • uspace/drv/uhci-hcd/batch.c

    r6bb83c7 r62066b4  
    141141        usb_log_debug("Checking(%p) %d packet for completion.\n",
    142142            instance, instance->packets);
    143         /* This is just an ugly trick to support the old API */
    144143        instance->transfered_size = 0;
    145144        size_t i = 0;
     
    157156                    transfer_descriptor_actual_size(&instance->tds[i]);
    158157        }
     158        /* This is just an ugly trick to support the old API */
    159159        instance->transfered_size -= instance->setup_size;
    160160        return true;
     
    191191            0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    192192
     193        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     194
    193195        instance->next_step = batch_call_out_and_dispose;
    194196        batch_schedule(instance);
     
    221223        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    222224            0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
     225
     226        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    223227
    224228        instance->next_step = batch_call_in_and_dispose;
     
    244248        }
    245249
     250        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     251
    246252        instance->next_step = batch_call_in_and_dispose;
    247253        batch_schedule(instance);
     
    268274        }
    269275
     276        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     277
    270278        instance->next_step = batch_call_out_and_dispose;
    271279        batch_schedule(instance);
  • uspace/drv/uhci-hcd/iface.c

    r6bb83c7 r62066b4  
    5454}
    5555/*----------------------------------------------------------------------------*/
    56 static int reserve_default_address(device_t *dev, bool full_speed)
     56static int reserve_default_address(device_t *dev, usb_speed_t speed)
    5757{
    5858        assert(dev);
     
    7272}
    7373/*----------------------------------------------------------------------------*/
    74 static int request_address(device_t *dev, bool full_speed,
     74static int request_address(device_t *dev, usb_speed_t speed,
    7575    usb_address_t *address)
    7676{
     
    164164        return EOK;
    165165}
    166 /*----------------------------------------------------------------------------*/
    167 static int control_write_setup(device_t *dev, usb_target_t target,
    168     size_t max_packet_size,
    169     void *data, size_t size,
    170     usbhc_iface_transfer_out_callback_t callback, void *arg)
    171 {
    172         dev_speed_t speed = FULL_SPEED;
    173166
    174         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    175         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    176             max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    177         if (!batch)
    178                 return ENOMEM;
    179         batch_control_setup_old(batch);
    180         return EOK;
    181 }
    182 /*----------------------------------------------------------------------------*/
    183 static int control_write_data(device_t *dev, usb_target_t target,
    184     size_t max_packet_size,
    185     void *data, size_t size,
    186     usbhc_iface_transfer_out_callback_t callback, void *arg)
    187 {
    188         dev_speed_t speed = FULL_SPEED;
    189167
    190         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    191         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    192             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
    193         if (!batch)
    194                 return ENOMEM;
    195         batch_control_write_data_old(batch);
    196         return EOK;
    197 }
    198 /*----------------------------------------------------------------------------*/
    199 static int control_write_status(device_t *dev, usb_target_t target,
    200     usbhc_iface_transfer_in_callback_t callback, void *arg)
    201 {
    202         size_t max_packet_size = 8;
    203         dev_speed_t speed = FULL_SPEED;
    204 
    205         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    206         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    207             max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
    208         if (!batch)
    209                 return ENOMEM;
    210         batch_control_write_status_old(batch);
    211         return EOK;
    212 }
    213 /*----------------------------------------------------------------------------*/
    214 static int control_read_setup(device_t *dev, usb_target_t target,
    215     size_t max_packet_size,
    216     void *data, size_t size,
    217     usbhc_iface_transfer_out_callback_t callback, void *arg)
    218 {
    219         dev_speed_t speed = FULL_SPEED;
    220 
    221         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    222         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    223             max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    224         if (!batch)
    225                 return ENOMEM;
    226         batch_control_setup_old(batch);
    227         return EOK;
    228 }
    229 /*----------------------------------------------------------------------------*/
    230 static int control_read_data(device_t *dev, usb_target_t target,
    231     size_t max_packet_size,
    232     void *data, size_t size,
    233     usbhc_iface_transfer_in_callback_t callback, void *arg)
    234 {
    235         dev_speed_t speed = FULL_SPEED;
    236 
    237         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    238         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    239             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
    240         if (!batch)
    241                 return ENOMEM;
    242         batch_control_read_data_old(batch);
    243         return EOK;
    244 }
    245 /*----------------------------------------------------------------------------*/
    246 static int control_read_status(device_t *dev, usb_target_t target,
    247     usbhc_iface_transfer_out_callback_t callback, void *arg)
    248 {
    249         size_t max_packet_size = 8;
    250         dev_speed_t speed = FULL_SPEED;
    251 
    252         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    253         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    254             max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg);
    255         if (!batch)
    256                 return ENOMEM;
    257         batch_control_read_status_old(batch);
    258         return EOK;
    259 }
    260168/*----------------------------------------------------------------------------*/
    261169usbhc_iface_t uhci_iface = {
     
    273181        .control_read = control_read,
    274182        .control_write = control_write,
    275 
    276         .control_write_setup = control_write_setup,
    277         .control_write_data = control_write_data,
    278         .control_write_status = control_write_status,
    279 
    280         .control_read_setup = control_read_setup,
    281         .control_read_data = control_read_data,
    282         .control_read_status = control_read_status
    283183};
    284184/**
  • uspace/drv/uhci-hcd/main.c

    r6bb83c7 r62066b4  
    3434#include <driver.h>
    3535#include <usb_iface.h>
     36#include <device/hw_res.h>
    3637
    3738#include <errno.h>
     
    4647#define NAME "uhci-hcd"
    4748
     49static int uhci_add_device(device_t *device);
     50static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
     51/*----------------------------------------------------------------------------*/
    4852static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    4953{
     
    5458        return EOK;
    5559}
    56 
     60/*----------------------------------------------------------------------------*/
    5761static usb_iface_t hc_usb_iface = {
    5862        .get_hc_handle = usb_iface_get_hc_handle
    5963};
    60 
     64/*----------------------------------------------------------------------------*/
    6165static device_ops_t uhci_ops = {
    6266        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    6367        .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    6468};
     69/*----------------------------------------------------------------------------*/
     70static driver_ops_t uhci_driver_ops = {
     71        .add_device = uhci_add_device,
     72};
     73/*----------------------------------------------------------------------------*/
     74static driver_t uhci_driver = {
     75        .name = NAME,
     76        .driver_ops = &uhci_driver_ops
     77};
     78/*----------------------------------------------------------------------------*/
     79static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
     80{
     81        assert(device);
     82        uhci_t *hc = dev_to_uhci(device);
     83        uint16_t status = IPC_GET_ARG1(*call);
     84        assert(hc);
     85        uhci_interrupt(hc, status);
     86}
     87/*----------------------------------------------------------------------------*/
     88#define CHECK_RET_RETURN(ret, message...) \
     89if (ret != EOK) { \
     90        usb_log_error(message); \
     91        return ret; \
     92}
    6593
    6694static int uhci_add_device(device_t *device)
     
    75103        int irq;
    76104
    77         int rc = pci_get_my_registers(device,
    78             &io_reg_base, &io_reg_size, &irq);
     105        int ret =
     106            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
    79107
    80         if (rc != EOK) {
    81                 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n",
    82                     rc, device->handle);
    83                 return rc;
    84         }
    85 
     108        CHECK_RET_RETURN(ret,
     109            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
    86110        usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
    87111            io_reg_base, io_reg_size, irq);
    88112
     113        ret = pci_enable_interrupts(device);
     114        CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
     115
    89116        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    90         if (!uhci_hc) {
    91                 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
    92                 return ENOMEM;
     117        ret = (uhci_hc != NULL) ? EOK : ENOMEM;
     118        CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
     119
     120        ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     121        if (ret != EOK) {
     122                usb_log_error("Failed to init uhci-hcd.\n");
     123                free(uhci_hc);
     124                return ret;
    93125        }
    94126
    95         int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     127        ret = register_interrupt_handler(device, irq, irq_handler,
     128            &uhci_hc->interrupt_code);
    96129        if (ret != EOK) {
    97                 usb_log_error("Failed to init uhci-hcd.\n");
     130                usb_log_error("Failed to register interrupt handler.\n");
     131                uhci_fini(uhci_hc);
     132                free(uhci_hc);
    98133                return ret;
    99134        }
     135
    100136        device_t *rh;
    101137        ret = setup_root_hub(&rh, device);
    102 
    103138        if (ret != EOK) {
    104139                usb_log_error("Failed to setup uhci root hub.\n");
    105                 /* TODO: destroy uhci here */
     140                uhci_fini(uhci_hc);
     141                free(uhci_hc);
    106142                return ret;
    107143        }
     
    110146        if (ret != EOK) {
    111147                usb_log_error("Failed to register root hub.\n");
    112                 /* TODO: destroy uhci here */
     148                uhci_fini(uhci_hc);
     149                free(uhci_hc);
     150                free(rh);
    113151                return ret;
    114152        }
    115153
    116154        device->driver_data = uhci_hc;
    117 
    118155        return EOK;
    119156}
    120 
    121 static driver_ops_t uhci_driver_ops = {
    122         .add_device = uhci_add_device,
    123 };
    124 
    125 static driver_t uhci_driver = {
    126         .name = NAME,
    127         .driver_ops = &uhci_driver_ops
    128 };
    129 
     157/*----------------------------------------------------------------------------*/
    130158int main(int argc, char *argv[])
    131159{
    132         /*
    133          * Do some global initializations.
    134          */
    135         sleep(5);
    136         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     160        sleep(3);
     161        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    137162
    138163        return driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/pci.c

    r6bb83c7 r62066b4  
    121121        return rc;
    122122}
    123 
     123/*----------------------------------------------------------------------------*/
     124int pci_enable_interrupts(device_t *device)
     125{
     126        int parent_phone = devman_parent_device_connect(device->handle,
     127            IPC_FLAG_BLOCKING);
     128        bool enabled = hw_res_enable_interrupt(parent_phone);
     129        return enabled ? EOK : EIO;
     130}
    124131/**
    125132 * @}
  • uspace/drv/uhci-hcd/pci.h

    r6bb83c7 r62066b4  
    3939
    4040int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(device_t *device);
    4142
    4243#endif
  • uspace/drv/uhci-hcd/transfer_list.c

    r6bb83c7 r62066b4  
    111111        /* I'm the first one here */
    112112        if (batch->link.prev == &instance->batch_list) {
    113                 usb_log_debug("Removing tracer %p was first, next element %x.\n",
     113                usb_log_debug("Removing batch %p was first, next element %x.\n",
    114114                        batch, batch->qh->next_queue);
    115115                instance->queue_head->element = batch->qh->next_queue;
    116116        } else {
    117                 usb_log_debug("Removing tracer %p was NOT first, next element %x.\n",
     117                usb_log_debug("Removing batch %p was NOT first, next element %x.\n",
    118118                        batch, batch->qh->next_queue);
    119119                batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    r6bb83c7 r62066b4  
    1110 pci/ven=8086&dev=7020
    2 
     210 pci/ven=8086&dev=7112
  • uspace/drv/uhci-hcd/uhci.c

    r6bb83c7 r62066b4  
    3939
    4040#include "uhci.h"
     41static irq_cmd_t uhci_cmds[] = {
     42        {
     43                .cmd = CMD_PIO_READ_16,
     44                .addr = (void*)0xc022,
     45                .dstarg = 1
     46        },
     47        {
     48                .cmd = CMD_PIO_WRITE_16,
     49                .addr = (void*)0xc022,
     50                .value = 0x1f
     51        },
     52        {
     53                .cmd = CMD_ACCEPT
     54        }
     55};
    4156
    4257static int uhci_init_transfer_lists(uhci_t *instance);
    43 static int uhci_clean_finished(void *arg);
     58static int uhci_init_mem_structures(uhci_t *instance);
     59static void uhci_init_hw(uhci_t *instance);
     60
     61static int uhci_interrupt_emulator(void *arg);
    4462static int uhci_debug_checker(void *arg);
     63
    4564static bool allowed_usb_packet(
    4665        bool low_speed, usb_transfer_type_t, size_t size);
    4766
    48 int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
    49 {
    50 #define CHECK_RET_RETURN(message...) \
     67#define CHECK_RET_RETURN(ret, message...) \
    5168        if (ret != EOK) { \
    5269                usb_log_error(message); \
     
    5471        } else (void) 0
    5572
    56         /* init address keeper(libusb) */
    57         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    58         usb_log_debug("Initialized address manager.\n");
     73int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     74{
     75        assert(reg_size >= sizeof(regs_t));
    5976
    6077        /* allow access to hc control registers */
    6178        regs_t *io;
    62         assert(reg_size >= sizeof(regs_t));
    6379        int ret = pio_enable(regs, reg_size, (void**)&io);
    64         CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
     80        CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
    6581        instance->registers = io;
    6682        usb_log_debug("Device registers accessible.\n");
    6783
     84        ret = uhci_init_mem_structures(instance);
     85        CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
     86
     87        uhci_init_hw(instance);
     88
     89        instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
     90//      fibril_add_ready(instance->cleaner);
     91
     92        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
     93        fibril_add_ready(instance->debug_checker);
     94
     95        return EOK;
     96}
     97/*----------------------------------------------------------------------------*/
     98void uhci_init_hw(uhci_t *instance)
     99{
     100
     101        /* set framelist pointer */
     102        const uint32_t pa = addr_to_phys(instance->frame_list);
     103        pio_write_32(&instance->registers->flbaseadd, pa);
     104
     105        /* enable all interrupts, but resume interrupt */
     106        pio_write_16(&instance->registers->usbintr,
     107                  UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     108
     109        /* Start the hc with large(64B) packet FSBR */
     110        pio_write_16(&instance->registers->usbcmd,
     111            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
     112        usb_log_debug("Started UHCI HC.\n");
     113}
     114/*----------------------------------------------------------------------------*/
     115int uhci_init_mem_structures(uhci_t *instance)
     116{
     117        assert(instance);
     118
     119        /* init interrupt code */
     120        irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
     121        if (interrupt_commands == NULL) {
     122                return ENOMEM;
     123        }
     124        memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
     125        interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
     126        interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
     127        instance->interrupt_code.cmds = interrupt_commands;
     128        instance->interrupt_code.cmdcount =
     129            sizeof(uhci_cmds) / sizeof(irq_cmd_t);
     130
    68131        /* init transfer lists */
    69         ret = uhci_init_transfer_lists(instance);
    70         CHECK_RET_RETURN("Failed to initialize transfer lists.\n");
    71         usb_log_debug("Transfer lists initialized.\n");
    72 
    73 
    74         usb_log_debug("Initializing frame list.\n");
     132        int ret = uhci_init_transfer_lists(instance);
     133        CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     134        usb_log_debug("Initialized transfer lists.\n");
     135
     136        /* frame list initialization */
    75137        instance->frame_list = get_page();
    76138        ret = instance ? EOK : ENOMEM;
    77         CHECK_RET_RETURN("Failed to get frame list page.\n");
     139        CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
     140        usb_log_debug("Initialized frame list.\n");
    78141
    79142        /* initialize all frames to point to the first queue head */
     
    86149        }
    87150
    88         const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
    89         pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
    90 
    91         list_initialize(&instance->batch_list);
    92         fibril_mutex_initialize(&instance->batch_list_mutex);
    93 
    94         instance->cleaner = fibril_create(uhci_clean_finished, instance);
    95         fibril_add_ready(instance->cleaner);
    96 
    97         instance->debug_checker = fibril_create(uhci_debug_checker, instance);
    98         fibril_add_ready(instance->debug_checker);
    99 
    100         /* Start the hc with large(64B) packet FSBR */
    101         pio_write_16(&instance->registers->usbcmd,
    102             UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
    103         usb_log_debug("Started UHCI HC.\n");
    104 
    105         uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    106         cmd |= UHCI_CMD_DEBUG;
    107         pio_write_16(&instance->registers->usbcmd, cmd);
     151        /* init address keeper(libusb) */
     152        usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
     153        usb_log_debug("Initialized address manager.\n");
    108154
    109155        return EOK;
     
    114160        assert(instance);
    115161
    116         /* initialize */
     162        /* initialize TODO: check errors */
    117163        int ret;
    118164        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     
    146192        instance->transfers[1][USB_TRANSFER_CONTROL] =
    147193          &instance->transfers_control_slow;
    148         instance->transfers[0][USB_TRANSFER_CONTROL] =
    149           &instance->transfers_control_full;
     194        instance->transfers[0][USB_TRANSFER_BULK] =
     195          &instance->transfers_bulk_full;
    150196
    151197        return EOK;
     
    174220}
    175221/*----------------------------------------------------------------------------*/
    176 int uhci_clean_finished(void* arg)
    177 {
    178         usb_log_debug("Started cleaning fibril.\n");
     222void uhci_interrupt(uhci_t *instance, uint16_t status)
     223{
     224        assert(instance);
     225        if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
     226                return;
     227        usb_log_debug("UHCI interrupt: %X.\n", status);
     228        transfer_list_check(&instance->transfers_interrupt);
     229        transfer_list_check(&instance->transfers_control_slow);
     230        transfer_list_check(&instance->transfers_control_full);
     231        transfer_list_check(&instance->transfers_bulk_full);
     232}
     233/*----------------------------------------------------------------------------*/
     234int uhci_interrupt_emulator(void* arg)
     235{
     236        usb_log_debug("Started interrupt emulator.\n");
    179237        uhci_t *instance = (uhci_t*)arg;
    180238        assert(instance);
    181239
    182240        while(1) {
    183                 transfer_list_check(&instance->transfers_interrupt);
    184                 transfer_list_check(&instance->transfers_control_slow);
    185                 transfer_list_check(&instance->transfers_control_full);
    186                 transfer_list_check(&instance->transfers_bulk_full);
     241                uint16_t status = pio_read_16(&instance->registers->usbsts);
     242                uhci_interrupt(instance, status);
    187243                async_usleep(UHCI_CLEANER_TIMEOUT);
    188244        }
     
    195251        assert(instance);
    196252        while (1) {
    197                 uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    198                 uint16_t sts = pio_read_16(&instance->registers->usbsts);
    199                 usb_log_debug("Command register: %X Status register: %X\n", cmd, sts);
     253                const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
     254                const uint16_t sts = pio_read_16(&instance->registers->usbsts);
     255                const uint16_t intr = pio_read_16(&instance->registers->usbintr);
     256                usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
     257                    cmd, sts, intr);
    200258
    201259                uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
    202                 if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
     260                if (frame_list != addr_to_phys(instance->frame_list)) {
    203261                        usb_log_debug("Framelist address: %p vs. %p.\n",
    204262                                frame_list, addr_to_phys(instance->frame_list));
  • uspace/drv/uhci-hcd/uhci.h

    r6bb83c7 r62066b4  
    6666
    6767        uint16_t usbintr;
     68#define UHCI_INTR_SHORT_PACKET (1 << 3)
     69#define UHCI_INTR_COMPLETE (1 << 2)
     70#define UHCI_INTR_RESUME (1 << 1)
     71#define UHCI_INTR_CRC (1 << 0)
     72
    6873        uint16_t frnum;
    6974        uint32_t flbaseadd;
     
    8186        link_pointer_t *frame_list;
    8287
    83         link_t batch_list;
    84         fibril_mutex_t batch_list_mutex;
    85 
    8688        transfer_list_t transfers_bulk_full;
    8789        transfer_list_t transfers_control_full;
     
    9092
    9193        transfer_list_t *transfers[2][4];
     94
     95        irq_code_t interrupt_code;
    9296
    9397        fid_t cleaner;
     
    98102int uhci_init(uhci_t *instance, void *regs, size_t reg_size);
    99103
    100 int uhci_fini(uhci_t *device);
    101 
    102 int uhci_transfer(
    103   uhci_t *instance,
    104   device_t *dev,
    105   usb_target_t target,
    106   usb_transfer_type_t transfer_type,
    107         bool toggle,
    108   usb_packet_id pid,
    109         bool low_speed,
    110   void *buffer, size_t size,
    111   usbhc_iface_transfer_out_callback_t callback_out,
    112   usbhc_iface_transfer_in_callback_t callback_in,
    113   void *arg );
     104static inline void uhci_fini(uhci_t *instance) {};
    114105
    115106int uhci_schedule(uhci_t *instance, batch_t *batch);
    116107
     108void uhci_interrupt(uhci_t *instance, uint16_t status);
     109
    117110static inline uhci_t * dev_to_uhci(device_t *dev)
    118111        { return (uhci_t*)dev->driver_data; }
     112
    119113
    120114#endif
  • uspace/drv/uhci-rhd/port.c

    r6bb83c7 r62066b4  
    131131        return EOK;
    132132}
    133 /*----------------------------------------------------------------------------*/
    134 static int uhci_port_new_device(uhci_port_t *port)
    135 {
    136         assert(port);
    137         assert(usb_hc_connection_is_opened(&port->hc_connection));
    138 
    139         usb_log_info("Adding new device on port %d.\n", port->number);
    140 
    141         /* get address of the future device */
    142         const usb_address_t usb_address = usb_hc_request_address(
    143             &port->hc_connection, true);
    144 
    145         if (usb_address <= 0) {
    146                 usb_log_error("Recieved invalid address(%d).\n", usb_address);
    147                 return usb_address;
    148         }
    149         usb_log_debug("Sucessfully obtained address %d for port %d.\n",
    150             usb_address, port->number);
    151 
    152         /* get default address */
    153         int ret = usb_hc_reserve_default_address(&port->hc_connection, true);
    154         if (ret != EOK) {
    155                 usb_log_error("Failed to reserve default address on port %d.\n",
    156                     port->number);
    157                 int ret2 = usb_hc_unregister_device(&port->hc_connection,
    158                     usb_address);
    159                 if (ret2 != EOK) {
    160                         usb_log_fatal("Failed to return requested address on port %d.\n",
    161                            port->number);
    162                         return ret2;
    163                 }
    164                 usb_log_debug("Successfully returned reserved address on port %d.\n",
    165                         port->number);
    166                 return ret;
    167         }
    168         usb_log_debug("Sucessfully obtained default address for port %d.\n",
    169             port->number);
     133
     134/** Callback for enabling port during adding a new device.
     135 *
     136 * @param portno Port number (unused).
     137 * @param arg Pointer to uhci_port_t of port with the new device.
     138 * @return Error code.
     139 */
     140static int new_device_enable_port(int portno, void *arg)
     141{
     142        uhci_port_t *port = (uhci_port_t *) arg;
     143
     144        usb_log_debug("new_device_enable_port(%d)\n", port->number);
    170145
    171146        /*
    172          * the host then waits for at least 100 ms to allow completion of
     147         * The host then waits for at least 100 ms to allow completion of
    173148         * an insertion process and for power at the device to become stable.
    174149         */
    175150        async_usleep(100000);
    176151
    177         /* enable port */
     152        /* Enable the port. */
    178153        uhci_port_set_enabled(port, true);
    179154
     
    197172        }
    198173
    199         /*
    200          * Initialize connection to the device.
    201          */
    202         /* FIXME: check for errors. */
    203         usb_device_connection_t new_dev_connection;
    204         usb_endpoint_pipe_t new_dev_ctrl_pipe;
    205         usb_device_connection_initialize_on_default_address(
    206             &new_dev_connection, &port->hc_connection);
    207         usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
    208             &new_dev_connection);
    209 
    210         /*
    211          * Assign new address to the device. This function updates
    212          * the backing connection to still point to the same device.
    213          */
    214         /* FIXME: check for errors. */
    215         usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
    216         ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
    217         usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
    218 
    219         if (ret != EOK) { /* address assigning went wrong */
    220                 usb_log_error("Failed(%d) to assign address to the device.\n", ret);
     174        return EOK;
     175}
     176
     177/*----------------------------------------------------------------------------*/
     178static int uhci_port_new_device(uhci_port_t *port)
     179{
     180        assert(port);
     181        assert(usb_hc_connection_is_opened(&port->hc_connection));
     182
     183        usb_log_info("Detected new device on port %u.\n", port->number);
     184
     185        usb_address_t dev_addr;
     186        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
     187            USB_SPEED_FULL,
     188            new_device_enable_port, port->number, port,
     189            &dev_addr, &port->attached_device);
     190        if (rc != EOK) {
     191                usb_log_error("Failed adding new device on port %u: %s.\n",
     192                    port->number, str_error(rc));
    221193                uhci_port_set_enabled(port, false);
    222                 int release = usb_hc_release_default_address(&port->hc_connection);
    223                 if (release != EOK) {
    224                         usb_log_error("Failed to release default address on port %d.\n",
    225                             port->number);
    226                         return release;
    227                 }
    228                 usb_log_debug("Sucessfully released default address on port %d.\n",
    229                     port->number);
    230                 return ret;
    231         }
    232         usb_log_debug("Sucessfully assigned address %d for port %d.\n",
    233             usb_address, port->number);
    234 
    235         /* release default address */
    236         ret = usb_hc_release_default_address(&port->hc_connection);
    237         if (ret != EOK) {
    238                 usb_log_error("Failed to release default address on port %d.\n",
    239                     port->number);
    240                 return ret;
    241         }
    242         usb_log_debug("Sucessfully released default address on port %d.\n",
    243             port->number);
    244 
    245         /* communicate and possibly report to devman */
    246         assert(port->attached_device == 0);
    247 
    248         ret = usb_device_register_child_in_devman(new_dev_connection.address,
    249             new_dev_connection.hc_handle, port->rh, &port->attached_device);
    250 
    251         if (ret != EOK) { /* something went wrong */
    252                 usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
    253                 uhci_port_set_enabled(port, false);
    254                 return ENOMEM;
    255         }
    256         usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
    257                 port->number, usb_address, port->attached_device);
    258 
    259         /*
    260          * Register the device in the host controller.
    261          */
    262         usb_hc_attached_device_t new_device = {
    263                 .address = new_dev_connection.address,
    264                 .handle = port->attached_device
    265         };
    266 
    267         ret = usb_hc_register_device(&port->hc_connection, &new_device);
    268         // TODO: proper error check here
    269         assert(ret == EOK);
    270 
    271         return EOK;
    272 }
     194                return rc;
     195        }
     196
     197        usb_log_info("New device on port %u has address %d (handle %zu).\n",
     198            port->number, dev_addr, port->attached_device);
     199
     200        return EOK;
     201}
     202
    273203/*----------------------------------------------------------------------------*/
    274204static int uhci_port_remove_device(uhci_port_t *port)
  • uspace/drv/uhci-rhd/root_hub.c

    r6bb83c7 r62066b4  
    4747        assert(rh);
    4848        int ret;
    49         ret = usb_drv_find_hc(rh, &instance->hc_handle);
     49        ret = usb_hc_find(rh->handle, &instance->hc_handle);
    5050        usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
    5151        if (ret != EOK) {
  • uspace/drv/usbhub/usbhub.c

    r6bb83c7 r62066b4  
    5252#include "usb/pipes.h"
    5353
     54static int iface_get_hc_handle(device_t *device, devman_handle_t *handle)
     55{
     56        return usb_hc_find(device->handle, handle);
     57}
     58
    5459static usb_iface_t hub_usb_iface = {
    55         .get_hc_handle = usb_drv_find_hc
     60        .get_hc_handle = iface_get_hc_handle
    5661};
    5762
     
    263268        //get default address
    264269        //opResult = usb_drv_reserve_default_address(hc);
    265         opResult = usb_hc_reserve_default_address(&hub->connection, false);
     270        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
    266271        if (opResult != EOK) {
    267272                dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
     
    320325        usb_address_t new_device_address = usb_hc_request_address(
    321326                        &hub->connection,
    322                         false/// \TODO fullspeed??
     327                        USB_SPEED_LOW/// \TODO fullspeed??
    323328                        );
    324329        if (new_device_address < 0) {
  • uspace/drv/vhc/connhost.c

    r6bb83c7 r62066b4  
    234234}
    235235
    236 static int enqueue_transfer_setup(device_t *dev,
    237     usb_target_t target, usb_transfer_type_t transfer_type,
    238     void *buffer, size_t size,
    239     usbhc_iface_transfer_out_callback_t callback, void *arg)
    240 {
    241         usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",
    242             target.address, target.endpoint,
    243             usb_str_transfer_type(transfer_type),
    244             size);
    245 
    246         transfer_info_t *transfer
    247             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    248         transfer->out_callback = callback;
    249 
    250         hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    251             universal_callback, transfer);
    252 
    253         return EOK;
    254 }
    255 
    256236static int enqueue_transfer_in(device_t *dev,
    257237    usb_target_t target, usb_transfer_type_t transfer_type,
     
    292272        return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
    293273            data, size,
    294             callback, arg);
    295 }
    296 
    297 static int control_write_setup(device_t *dev, usb_target_t target,
    298     size_t max_packet_size,
    299     void *data, size_t size,
    300     usbhc_iface_transfer_out_callback_t callback, void *arg)
    301 {
    302         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    303             data, size,
    304             callback, arg);
    305 }
    306 
    307 static int control_write_data(device_t *dev, usb_target_t target,
    308     size_t max_packet_size,
    309     void *data, size_t size,
    310     usbhc_iface_transfer_out_callback_t callback, void *arg)
    311 {
    312         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    313             data, size,
    314             callback, arg);
    315 }
    316 
    317 static int control_write_status(device_t *dev, usb_target_t target,
    318     usbhc_iface_transfer_in_callback_t callback, void *arg)
    319 {
    320         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    321             NULL, 0,
    322274            callback, arg);
    323275}
     
    341293}
    342294
    343 static int control_read_setup(device_t *dev, usb_target_t target,
    344     size_t max_packet_size,
    345     void *data, size_t size,
    346     usbhc_iface_transfer_out_callback_t callback, void *arg)
    347 {
    348         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    349             data, size,
    350             callback, arg);
    351 }
    352 
    353 static int control_read_data(device_t *dev, usb_target_t target,
    354     size_t max_packet_size,
    355     void *data, size_t size,
    356     usbhc_iface_transfer_in_callback_t callback, void *arg)
    357 {
    358         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    359             data, size,
    360             callback, arg);
    361 }
    362 
    363 static int control_read_status(device_t *dev, usb_target_t target,
    364     usbhc_iface_transfer_out_callback_t callback, void *arg)
    365 {
    366         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    367             NULL, 0,
    368             callback, arg);
    369 }
    370 
    371295static int control_read(device_t *dev, usb_target_t target,
    372296    size_t max_packet_size,
     
    390314
    391315
    392 static int reserve_default_address(device_t *dev, bool ignored)
     316static int reserve_default_address(device_t *dev, usb_speed_t ignored)
    393317{
    394318        usb_address_keeping_reserve_default(&addresses);
     
    402326}
    403327
    404 static int request_address(device_t *dev, bool ignored, usb_address_t *address)
     328static int request_address(device_t *dev, usb_speed_t ignored,
     329    usb_address_t *address)
    405330{
    406331        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    454379        .interrupt_in = interrupt_in,
    455380
    456         .control_write_setup = control_write_setup,
    457         .control_write_data = control_write_data,
    458         .control_write_status = control_write_status,
    459 
    460381        .control_write = control_write,
    461 
    462         .control_read_setup = control_read_setup,
    463         .control_read_data = control_read_data,
    464         .control_read_status = control_read_status,
    465 
    466382        .control_read = control_read
    467383};
  • uspace/lib/c/generic/str_error.c

    r6bb83c7 r62066b4  
    7373                case EBADCHECKSUM:
    7474                        return "Bad checksum";
     75                case ESTALL:
     76                        return "Operation stalled";
    7577                case EAGAIN:
    7678                        return "Resource temporarily unavailable";
  • uspace/lib/c/include/errno.h

    r6bb83c7 r62066b4  
    5959#define EBADCHECKSUM  (-300)
    6060
     61/** USB: stalled operation. */
     62#define ESTALL (-301)
     63
    6164/** An API function is called while another blocking function is in progress. */
    6265#define EINPROGRESS  (-10036)
  • uspace/lib/drv/generic/remote_usbhc.c

    r6bb83c7 r62066b4  
    4646static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4747static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
    48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
    49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
    52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    53 static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5448static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5549static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    7569        remote_usbhc_interrupt_in,
    7670
    77         remote_usbhc_control_write_setup,
    78         remote_usbhc_control_write_data,
    79         remote_usbhc_control_write_status,
    80 
    81         remote_usbhc_control_read_setup,
    82         remote_usbhc_control_read_data,
    83         remote_usbhc_control_read_status,
    84 
    8571        remote_usbhc_control_write,
    8672        remote_usbhc_control_read
     
    166152        }
    167153       
    168         bool full_speed = DEV_IPC_GET_ARG1(*call);
     154        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    169155       
    170         int rc = usb_iface->reserve_default_address(device, full_speed);
     156        int rc = usb_iface->reserve_default_address(device, speed);
    171157
    172158        async_answer_0(callid, rc);
     
    198184        }
    199185       
    200         bool full_speed = DEV_IPC_GET_ARG1(*call);
     186        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    201187
    202188        usb_address_t address;
    203         int rc = usb_iface->request_address(device, full_speed, &address);
     189        int rc = usb_iface->request_address(device, speed, &address);
    204190        if (rc != EOK) {
    205191                async_answer_0(callid, rc);
     
    297283        }
    298284
    299         size_t expected_len = DEV_IPC_GET_ARG3(*call);
     285        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    300286        usb_target_t target = {
    301287                .address = DEV_IPC_GET_ARG1(*call),
     
    305291        size_t len = 0;
    306292        void *buffer = NULL;
    307         if (expected_len > 0) {
    308                 int rc = async_data_write_accept(&buffer, false,
    309                     1, USB_MAX_PAYLOAD_SIZE,
    310                     0, &len);
    311 
    312                 if (rc != EOK) {
    313                         async_answer_0(callid, rc);
    314                         return;
    315                 }
     293
     294        int rc = async_data_write_accept(&buffer, false,
     295            1, USB_MAX_PAYLOAD_SIZE,
     296            0, &len);
     297
     298        if (rc != EOK) {
     299                async_answer_0(callid, rc);
     300                return;
    316301        }
    317302
     
    328313        trans->size = len;
    329314
    330         int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE,
     315        rc = transfer_func(device, target, max_packet_size,
    331316            buffer, len,
    332317            callback_out, trans);
     
    354339        }
    355340
    356         size_t len = DEV_IPC_GET_ARG3(*call);
     341        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    357342        usb_target_t target = {
    358343                .address = DEV_IPC_GET_ARG1(*call),
     
    360345        };
    361346
     347        size_t len;
    362348        ipc_callid_t data_callid;
    363349        if (!async_data_read_receive(&data_callid, &len)) {
     
    375361        trans->size = len;
    376362
    377         int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN,
     363        int rc = transfer_func(device, target, max_packet_size,
    378364            trans->buffer, len,
    379365            callback_in, trans);
     
    385371}
    386372
    387 /** Process status part of control transfer.
    388  *
    389  * @param device Target device.
    390  * @param callid Initiating caller.
    391  * @param call Initiating call.
    392  * @param direction Transfer direction (read ~ in, write ~ out).
    393  * @param transfer_in_func Transfer function for control read (might be NULL).
    394  * @param transfer_out_func Transfer function for control write (might be NULL).
    395  */
    396 static void remote_usbhc_status_transfer(device_t *device,
    397     ipc_callid_t callid, ipc_call_t *call,
    398     usb_direction_t direction,
    399     int (*transfer_in_func)(device_t *, usb_target_t,
    400         usbhc_iface_transfer_in_callback_t, void *),
    401     int (*transfer_out_func)(device_t *, usb_target_t,
    402         usbhc_iface_transfer_out_callback_t, void *))
    403 {
    404         switch (direction) {
    405                 case USB_DIRECTION_IN:
    406                         if (!transfer_in_func) {
    407                                 async_answer_0(callid, ENOTSUP);
    408                                 return;
    409                         }
    410                         break;
    411                 case USB_DIRECTION_OUT:
    412                         if (!transfer_out_func) {
    413                                 async_answer_0(callid, ENOTSUP);
    414                                 return;
    415                         }
    416                         break;
    417                 default:
    418                         assert(false && "unreachable code");
    419                         break;
    420         }
    421 
    422         usb_target_t target = {
    423                 .address = DEV_IPC_GET_ARG1(*call),
    424                 .endpoint = DEV_IPC_GET_ARG2(*call)
    425         };
    426 
    427         async_transaction_t *trans = async_transaction_create(callid);
    428         if (trans == NULL) {
    429                 async_answer_0(callid, ENOMEM);
    430                 return;
    431         }
    432 
    433         int rc;
    434         switch (direction) {
    435                 case USB_DIRECTION_IN:
    436                         rc = transfer_in_func(device, target,
    437                             callback_in, trans);
    438                         break;
    439                 case USB_DIRECTION_OUT:
    440                         rc = transfer_out_func(device, target,
    441                             callback_out, trans);
    442                         break;
    443                 default:
    444                         assert(false && "unreachable code");
    445                         break;
    446         }
    447 
    448         if (rc != EOK) {
    449                 async_answer_0(callid, rc);
    450                 async_transaction_destroy(trans);
    451         }
    452 }
    453 
    454 
    455373void remote_usbhc_interrupt_out(device_t *device, void *iface,
    456374    ipc_callid_t callid, ipc_call_t *call)
     
    471389        return remote_usbhc_in_transfer(device, callid, call,
    472390            usb_iface->interrupt_in);
    473 }
    474 
    475 void remote_usbhc_control_write_setup(device_t *device, void *iface,
    476     ipc_callid_t callid, ipc_call_t *call)
    477 {
    478         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    479         assert(usb_iface != NULL);
    480 
    481         return remote_usbhc_out_transfer(device, callid, call,
    482             usb_iface->control_write_setup);
    483 }
    484 
    485 void remote_usbhc_control_write_data(device_t *device, void *iface,
    486     ipc_callid_t callid, ipc_call_t *call)
    487 {
    488         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    489         assert(usb_iface != NULL);
    490 
    491         return remote_usbhc_out_transfer(device, callid, call,
    492             usb_iface->control_write_data);
    493 }
    494 
    495 void remote_usbhc_control_write_status(device_t *device, void *iface,
    496     ipc_callid_t callid, ipc_call_t *call)
    497 {
    498         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    499         assert(usb_iface != NULL);
    500 
    501         return remote_usbhc_status_transfer(device, callid, call,
    502             USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
    503 }
    504 
    505 void remote_usbhc_control_read_setup(device_t *device, void *iface,
    506     ipc_callid_t callid, ipc_call_t *call)
    507 {
    508         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    509         assert(usb_iface != NULL);
    510 
    511         return remote_usbhc_out_transfer(device, callid, call,
    512             usb_iface->control_read_setup);
    513 }
    514 
    515 void remote_usbhc_control_read_data(device_t *device, void *iface,
    516             ipc_callid_t callid, ipc_call_t *call)
    517 {
    518         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    519         assert(usb_iface != NULL);
    520 
    521         return remote_usbhc_in_transfer(device, callid, call,
    522             usb_iface->control_read_data);
    523 }
    524 
    525 void remote_usbhc_control_read_status(device_t *device, void *iface,
    526             ipc_callid_t callid, ipc_call_t *call)
    527 {
    528         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    529         assert(usb_iface != NULL);
    530 
    531         return remote_usbhc_status_transfer(device, callid, call,
    532             USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
    533391}
    534392
     
    549407        };
    550408        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
     409        size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    551410
    552411        int rc;
     
    584443        trans->size = data_buffer_len;
    585444
    586         rc = usb_iface->control_write(device, target, HACK_MAX_PACKET_SIZE,
     445        rc = usb_iface->control_write(device, target, max_packet_size,
    587446            setup_packet, setup_packet_len,
    588447            data_buffer, data_buffer_len,
     
    611470                .endpoint = DEV_IPC_GET_ARG2(*call)
    612471        };
     472        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    613473
    614474        int rc;
     
    648508        }
    649509
    650         rc = usb_iface->control_read(device, target, HACK_MAX_PACKET_SIZE,
     510        rc = usb_iface->control_read(device, target, max_packet_size,
    651511            setup_packet, setup_packet_len,
    652512            trans->buffer, trans->size,
  • uspace/lib/drv/include/usbhc_iface.h

    r6bb83c7 r62066b4  
    5353 *   - argument #1 is target address
    5454 *   - argument #2 is target endpoint
    55  *   - argument #3 is buffer size
     55 *   - argument #3 is max packet size of the endpoint
    5656 * - this call is immediately followed by IPC data write (from caller)
    5757 * - the initial call (and the whole transaction) is answer after the
     
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
    68  *   - argument #3 is buffer size
     68 *   - argument #3 is max packet size of the endpoint
    6969 * - this call is immediately followed by IPC data read (async version)
    7070 * - the call is not answered until the device returns some data (or until
     
    153153        IPC_M_USBHC_INTERRUPT_IN,
    154154
    155 
    156         /** Start WRITE control transfer.
    157          * See explanation at usb_iface_funcs_t (OUT transaction).
    158          */
    159         IPC_M_USBHC_CONTROL_WRITE_SETUP,
    160 
    161         /** Send control-transfer data to device.
    162          * See explanation at usb_iface_funcs_t (OUT transaction).
    163          */
    164         IPC_M_USBHC_CONTROL_WRITE_DATA,
    165 
    166         /** Terminate WRITE control transfer.
    167          * See explanation at usb_iface_funcs_t (NO-DATA transaction).
    168          */
    169         IPC_M_USBHC_CONTROL_WRITE_STATUS,
    170 
    171 
    172 
    173         /** Start READ control transfer.
    174          * See explanation at usb_iface_funcs_t (OUT transaction).
    175          */
    176         IPC_M_USBHC_CONTROL_READ_SETUP,
    177 
    178         /** Get control-transfer data from device.
    179          * See explanation at usb_iface_funcs_t (IN transaction).
    180          */
    181         IPC_M_USBHC_CONTROL_READ_DATA,
    182 
    183         /** Terminate READ control transfer.
    184          * See explanation at usb_iface_funcs_t (NO-DATA transaction).
    185          */
    186         IPC_M_USBHC_CONTROL_READ_STATUS,
    187 
    188155        /** Issue control WRITE transfer.
    189156         * See explanation at usb_iface_funcs_t (OUT transaction) for
     
    194161        IPC_M_USBHC_CONTROL_WRITE,
    195162
    196         /** Issue control WRITE transfer.
     163        /** Issue control READ transfer.
    197164         * See explanation at usb_iface_funcs_t (IN transaction) for
    198165         * call parameters.
    199          * This call is immediately followed by IPC data read from the caller
    200          * (setup packet).
    201          * Actual data are retrieved through IPC_M_USBHC_GET_BUFFER.
     166         * This call is immediately followed by IPC data write from the caller
     167         * (setup packet) and IPC data read (buffer that was read).
    202168         */
    203169        IPC_M_USBHC_CONTROL_READ,
     
    232198        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    233199
    234         int (*reserve_default_address)(device_t *, bool);
     200        int (*reserve_default_address)(device_t *, usb_speed_t);
    235201        int (*release_default_address)(device_t *);
    236         int (*request_address)(device_t *, bool, usb_address_t *);
     202        int (*request_address)(device_t *, usb_speed_t, usb_address_t *);
    237203        int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
    238204        int (*release_address)(device_t *, usb_address_t);
     
    240206        usbhc_iface_transfer_out_t interrupt_out;
    241207        usbhc_iface_transfer_in_t interrupt_in;
    242 
    243         usbhc_iface_transfer_setup_t control_write_setup;
    244         usbhc_iface_transfer_out_t control_write_data;
    245         int (*control_write_status)(device_t *, usb_target_t,
    246             usbhc_iface_transfer_in_callback_t, void *);
    247 
    248         usbhc_iface_transfer_setup_t control_read_setup;
    249         usbhc_iface_transfer_in_t control_read_data;
    250         int (*control_read_status)(device_t *, usb_target_t,
    251             usbhc_iface_transfer_out_callback_t, void *);
    252208
    253209        int (*control_write)(device_t *, usb_target_t,
  • uspace/lib/usb/include/usb/hub.h

    r6bb83c7 r62066b4  
    3939#include <usb/usbdevice.h>
    4040
     41int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t,
     42    int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *);
    4143
    4244/** Info about device attached to host controller.
     
    5355} usb_hc_attached_device_t;
    5456
    55 int usb_hc_reserve_default_address(usb_hc_connection_t *, bool);
     57int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t);
    5658int usb_hc_release_default_address(usb_hc_connection_t *);
    5759
    58 usb_address_t usb_hc_request_address(usb_hc_connection_t *, bool);
     60usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
    5961int usb_hc_register_device(usb_hc_connection_t *,
    6062    const usb_hc_attached_device_t *);
  • uspace/lib/usb/include/usb/usb.h

    r6bb83c7 r62066b4  
    6868        USB_DIRECTION_BOTH
    6969} usb_direction_t;
     70
     71/** USB speeds. */
     72typedef enum {
     73        /** USB 1.1 low speed (1.5Mbits/s). */
     74        USB_SPEED_LOW,
     75        /** USB 1.1 full speed (12Mbits/s). */
     76        USB_SPEED_FULL,
     77        /** USB 2.0 high speed (480Mbits/s). */
     78        USB_SPEED_HIGH
     79} usb_speed_t;
    7080
    7181/** USB request type target. */
  • uspace/lib/usb/src/hub.c

    r6bb83c7 r62066b4  
    3434 */
    3535#include <usb/hub.h>
     36#include <usb/pipes.h>
     37#include <usb/request.h>
     38#include <usb/recognise.h>
    3639#include <usbhc_iface.h>
    3740#include <errno.h>
     
    5659 */
    5760int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
    58     bool full_speed)
     61    usb_speed_t speed)
    5962{
    6063        CHECK_CONNECTION(connection);
     
    6265        return async_req_2_0(connection->hc_phone,
    6366            DEV_IFACE_ID(USBHC_DEV_IFACE),
    64             IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, full_speed);
     67            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
    6568}
    6669
     
    8588 */
    8689usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
    87     bool full_speed)
     90    usb_speed_t speed)
    8891{
    8992        CHECK_CONNECTION(connection);
     
    9295        int rc = async_req_2_1(connection->hc_phone,
    9396            DEV_IFACE_ID(USBHC_DEV_IFACE),
    94             IPC_M_USBHC_REQUEST_ADDRESS, full_speed,
     97            IPC_M_USBHC_REQUEST_ADDRESS, speed,
    9598            &address);
    9699        if (rc != EOK) {
     
    138141
    139142
     143/** Wrapper for registering attached device to the hub.
     144 *
     145 * The @p enable_port function is expected to enable singalling on given
     146 * port.
     147 * The two arguments to it can have arbitrary meaning
     148 * (the @p port_no is only a suggestion)
     149 * and are not touched at all by this function
     150 * (they are passed as is to the @p enable_port function).
     151 *
     152 * If the @p enable_port fails (i.e. does not return EOK), the device
     153 * addition is cancelled.
     154 * The return value is then returned (it is good idea to use different
     155 * error codes than those listed as return codes by this function itself).
     156 *
     157 * @param parent Parent device (i.e. the hub device).
     158 * @param connection Opened connection to host controller.
     159 * @param dev_speed New device speed.
     160 * @param enable_port Function for enabling signalling through the port the
     161 *      device is attached to.
     162 * @param port_no Port number (passed through to @p enable_port).
     163 * @param arg Any data argument to @p enable_port.
     164 * @param[out] assigned_address USB address of the device.
     165 * @param[out] assigned_handle Devman handle of the new device.
     166 * @return Error code.
     167 * @retval ENOENT Connection to HC not opened.
     168 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
     169 * @retval EBUSY Failed reserving default USB address.
     170 * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
     171 * @retval ESTALL Problem communication with device (either SET_ADDRESS
     172 *      request or requests for descriptors when creating match ids).
     173 */
     174int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
     175    usb_speed_t dev_speed,
     176    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
     177    usb_address_t *assigned_address, devman_handle_t *assigned_handle)
     178{
     179        CHECK_CONNECTION(connection);
     180
     181        /*
     182         * Request new address.
     183         */
     184        usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
     185        if (dev_addr < 0) {
     186                return EADDRNOTAVAIL;
     187        }
     188
     189        int rc;
     190
     191        /*
     192         * Reserve the default address.
     193         */
     194        rc = usb_hc_reserve_default_address(connection, dev_speed);
     195        if (rc != EOK) {
     196                rc = EBUSY;
     197                goto leave_release_free_address;
     198        }
     199
     200        /*
     201         * Enable the port (i.e. allow signalling through this port).
     202         */
     203        rc = enable_port(port_no, arg);
     204        if (rc != EOK) {
     205                goto leave_release_default_address;
     206        }
     207
     208        /*
     209         * Change the address from default to the free one.
     210         * We need to create a new control pipe for that.
     211         */
     212        usb_device_connection_t dev_conn;
     213        rc = usb_device_connection_initialize_on_default_address(&dev_conn,
     214            connection);
     215        if (rc != EOK) {
     216                rc = ENOTCONN;
     217                goto leave_release_default_address;
     218        }
     219
     220        usb_endpoint_pipe_t ctrl_pipe;
     221        rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe,
     222            &dev_conn);
     223        if (rc != EOK) {
     224                rc = ENOTCONN;
     225                goto leave_release_default_address;
     226        }
     227
     228        rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
     229        if (rc != EOK) {
     230                rc = ENOTCONN;
     231                goto leave_release_default_address;
     232        }
     233
     234        rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     235        if (rc != EOK) {
     236                rc = ESTALL;
     237                goto leave_stop_session;
     238        }
     239
     240        usb_endpoint_pipe_end_session(&ctrl_pipe);
     241
     242        /*
     243         * Once the address is changed, we can return the default address.
     244         */
     245        usb_hc_release_default_address(connection);
     246
     247        /*
     248         * It is time to register the device with devman.
     249         */
     250        /* FIXME: create device_register that will get opened ctrl pipe. */
     251        devman_handle_t child_handle;
     252        rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
     253            parent, &child_handle);
     254        if (rc != EOK) {
     255                rc = ESTALL;
     256                goto leave_release_free_address;
     257        }
     258
     259        /*
     260         * And now inform the host controller about the handle.
     261         */
     262        usb_hc_attached_device_t new_device = {
     263                .address = dev_addr,
     264                .handle = child_handle
     265        };
     266        rc = usb_hc_register_device(connection, &new_device);
     267        if (rc != EOK) {
     268                rc = EDESTADDRREQ;
     269                goto leave_release_free_address;
     270        }
     271
     272        /*
     273         * And we are done.
     274         */
     275        if (assigned_address != NULL) {
     276                *assigned_address = dev_addr;
     277        }
     278        if (assigned_handle != NULL) {
     279                *assigned_handle = child_handle;
     280        }
     281
     282        return EOK;
     283
     284
     285
     286        /*
     287         * Error handling (like nested exceptions) starts here.
     288         * Completely ignoring errors here.
     289         */
     290
     291leave_stop_session:
     292        usb_endpoint_pipe_end_session(&ctrl_pipe);
     293
     294leave_release_default_address:
     295        usb_hc_release_default_address(connection);
     296
     297leave_release_free_address:
     298        usb_hc_unregister_device(connection, dev_addr);
     299
     300        return rc;
     301}
     302
     303
    140304/**
    141305 * @}
  • uspace/lib/usb/src/pipes.c

    r6bb83c7 r62066b4  
    3535#include <usb/usb.h>
    3636#include <usb/pipes.h>
     37#include <usbhc_iface.h>
    3738#include <errno.h>
    3839#include <assert.h>
    39 #include <usb/usbdrv.h>
     40
     41/** Tell USB address assigned to given device.
     42 *
     43 * @param phone Phone to my HC.
     44 * @param dev Device in question.
     45 * @return USB address or error code.
     46 */
     47static usb_address_t get_my_address(int phone, device_t *dev)
     48{
     49        sysarg_t address;
     50        int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     51            IPC_M_USBHC_GET_ADDRESS,
     52            dev->handle, &address);
     53
     54        if (rc != EOK) {
     55                return rc;
     56        }
     57
     58        return (usb_address_t) address;
     59}
    4060
    4161/** Initialize connection to USB device.
     
    5575        usb_address_t my_address;
    5676
    57         rc = usb_drv_find_hc(device, &hc_handle);
     77        rc = usb_hc_find(device->handle, &hc_handle);
    5878        if (rc != EOK) {
    5979                return rc;
     
    6585        }
    6686
    67         my_address = usb_drv_get_my_address(hc_phone, device);
     87        my_address = get_my_address(hc_phone, device);
    6888        if (my_address < 0) {
    6989                rc = my_address;
  • uspace/lib/usb/src/pipesio.c

    r6bb83c7 r62066b4  
    7878         * Make call identifying target USB device and type of transfer.
    7979         */
    80         aid_t opening_request = async_send_3(pipe->hc_phone,
     80        aid_t opening_request = async_send_4(pipe->hc_phone,
    8181            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    8282            pipe->wire->address, pipe->endpoint_no,
     83            pipe->max_packet_size,
    8384            NULL);
    8485        if (opening_request == 0) {
     
    201202         * Make call identifying target USB device and type of transfer.
    202203         */
    203         aid_t opening_request = async_send_3(pipe->hc_phone,
     204        aid_t opening_request = async_send_4(pipe->hc_phone,
    204205            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    205206            pipe->wire->address, pipe->endpoint_no,
     207            pipe->max_packet_size,
    206208            NULL);
    207209        if (opening_request == 0) {
     
    283285         * Make call identifying target USB device and control transfer type.
    284286         */
    285         aid_t opening_request = async_send_3(pipe->hc_phone,
     287        aid_t opening_request = async_send_4(pipe->hc_phone,
    286288            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
    287289            pipe->wire->address, pipe->endpoint_no,
     290            pipe->max_packet_size,
    288291            NULL);
    289292        if (opening_request == 0) {
     
    402405         * Make call identifying target USB device and control transfer type.
    403406         */
    404         aid_t opening_request = async_send_4(pipe->hc_phone,
     407        aid_t opening_request = async_send_5(pipe->hc_phone,
    405408            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
    406409            pipe->wire->address, pipe->endpoint_no,
    407410            data_buffer_size,
     411            pipe->max_packet_size,
    408412            NULL);
    409413        if (opening_request == 0) {
  • uspace/lib/usb/src/usbdrv.c

    r6bb83c7 r62066b4  
    3434 */
    3535#include <usb/usbdrv.h>
    36 #include <usbhc_iface.h>
    37 #include <usb_iface.h>
    3836#include <errno.h>
    39 #include <str_error.h>
    40 
    41 /** Information about pending transaction on HC. */
    42 typedef struct {
    43         /** Phone to host controller driver. */
    44         int phone;
    45         /** Data buffer. */
    46         void *buffer;
    47         /** Buffer size. */
    48         size_t size;
    49         /** Storage for actual number of bytes transferred. */
    50         size_t *size_transferred;
    51         /** Initial call reply data. */
    52         ipc_call_t reply;
    53         /** Initial call identifier. */
    54         aid_t request;
    55         /** Reply data for data read call. */
    56         ipc_call_t read_reply;
    57         /** Data read call identifier. */
    58         aid_t read_request;
    59 } transfer_info_t;
     37
    6038
    6139/** Find handle of host controller the device is physically attached to.
     
    6745int usb_drv_find_hc(device_t *dev, devman_handle_t *handle)
    6846{
    69         if (dev == NULL) {
    70                 return EBADMEM;
    71         }
    72         if (handle == NULL) {
    73                 return EBADMEM;
    74         }
    75 
    76         int parent_phone = devman_parent_device_connect(dev->handle,
    77             IPC_FLAG_BLOCKING);
    78         if (parent_phone < 0) {
    79                 return parent_phone;
    80         }
    81 
    82         devman_handle_t h;
    83         int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
    84             IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
    85 
    86         async_hangup(parent_phone);
    87 
    88         if (rc != EOK) {
    89                 return rc;
    90         }
    91 
    92         *handle = h;
    93 
    94         return EOK;
     47        return ENOTSUP;
    9548}
    9649
     
    10558    unsigned int flags)
    10659{
    107         return devman_device_connect(hc_handle, flags);
     60        return ENOTSUP;
    10861}
    10962
     
    11669int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags)
    11770{
    118         int rc;
    119         devman_handle_t hc_handle;
    120 
    121         /*
    122          * Call parent hub to obtain device handle of respective HC.
    123          */
    124         rc = usb_drv_find_hc(dev, &hc_handle);
    125         if (rc != EOK) {
    126                 return rc;
    127         }
    128        
    129         return usb_drv_hc_connect(dev, hc_handle, flags);
     71        return ENOTSUP;
    13072}
    13173
     
    13880usb_address_t usb_drv_get_my_address(int phone, device_t *dev)
    13981{
    140         sysarg_t address;
    141         int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    142             IPC_M_USBHC_GET_ADDRESS,
    143             dev->handle, &address);
    144 
    145         if (rc != EOK) {
    146                 return rc;
    147         }
    148 
    149         return (usb_address_t) address;
     82        return ENOTSUP;
    15083}
    15184
     
    15790int usb_drv_reserve_default_address(int phone)
    15891{
    159         return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    160             IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
     92        return ENOTSUP;
    16193}
    16294
     
    168100int usb_drv_release_default_address(int phone)
    169101{
    170         return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    171             IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
     102        return ENOTSUP;
    172103}
    173104
     
    179110usb_address_t usb_drv_request_address(int phone)
    180111{
    181         sysarg_t address;
    182         int rc = async_req_1_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    183             IPC_M_USBHC_REQUEST_ADDRESS, &address);
    184         if (rc != EOK) {
    185                 return rc;
    186         } else {
    187                 return (usb_address_t) address;
    188         }
     112        return ENOTSUP;
    189113}
    190114
     
    199123    devman_handle_t handle)
    200124{
    201         int rc = async_req_3_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    202             IPC_M_USBHC_BIND_ADDRESS,
    203             address, handle);
    204 
    205         return rc;
     125        return ENOTSUP;
    206126}
    207127
     
    214134int usb_drv_release_address(int phone, usb_address_t address)
    215135{
    216         return async_req_2_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    217             IPC_M_USBHC_RELEASE_ADDRESS, address);
    218 }
    219 
    220 /** Send data to HCD.
    221  *
    222  * @param phone Phone to HC.
    223  * @param method Method used for calling.
    224  * @param target Targeted device.
    225  * @param buffer Data buffer (NULL to skip data transfer phase).
    226  * @param size Buffer size (must be zero when @p buffer is NULL).
    227  * @param handle Storage for transaction handle (cannot be NULL).
    228  * @return Error status.
    229  * @retval EINVAL Invalid parameter.
    230  * @retval ENOMEM Not enough memory to complete the operation.
    231  */
    232 static int async_send_buffer(int phone, int method,
    233     usb_target_t target,
    234     void *buffer, size_t size,
    235     usb_handle_t *handle)
    236 {
    237         if (phone < 0) {
    238                 return EINVAL;
    239         }
    240 
    241         if ((buffer == NULL) && (size > 0)) {
    242                 return EINVAL;
    243         }
    244 
    245         if (handle == NULL) {
    246                 return EINVAL;
    247         }
    248 
    249         transfer_info_t *transfer
    250             = (transfer_info_t *) malloc(sizeof(transfer_info_t));
    251         if (transfer == NULL) {
    252                 return ENOMEM;
    253         }
    254 
    255         transfer->read_request = 0;
    256         transfer->size_transferred = NULL;
    257         transfer->buffer = NULL;
    258         transfer->size = 0;
    259         transfer->phone = phone;
    260 
    261         int rc;
    262 
    263         transfer->request = async_send_4(phone,
    264             DEV_IFACE_ID(USBHC_DEV_IFACE),
    265             method,
    266             target.address, target.endpoint,
    267             size,
    268             &transfer->reply);
    269 
    270         if (size > 0) {
    271                 rc = async_data_write_start(phone, buffer, size);
    272                 if (rc != EOK) {
    273                         async_wait_for(transfer->request, NULL);
    274                         return rc;
    275                 }
    276         }
    277 
    278         *handle = (usb_handle_t) transfer;
    279 
    280         return EOK;
    281 }
    282 
    283 /** Prepare data retrieval.
    284  *
    285  * @param phone Opened phone to HCD.
    286  * @param method Method used for calling.
    287  * @param target Targeted device.
    288  * @param buffer Buffer where to store retrieved data
    289  *      (NULL to skip data transfer phase).
    290  * @param size Buffer size (must be zero when @p buffer is NULL).
    291  * @param actual_size Storage where actual number of bytes transferred will
    292  *      be stored.
    293  * @param handle Storage for transaction handle (cannot be NULL).
    294  * @return Error status.
    295  * @retval EINVAL Invalid parameter.
    296  * @retval ENOMEM Not enough memory to complete the operation.
    297  */
    298 static int async_recv_buffer(int phone, int method,
    299     usb_target_t target,
    300     void *buffer, size_t size, size_t *actual_size,
    301     usb_handle_t *handle)
    302 {
    303         if (phone < 0) {
    304                 return EINVAL;
    305         }
    306 
    307         if ((buffer == NULL) && (size > 0)) {
    308                 return EINVAL;
    309         }
    310 
    311         if (handle == NULL) {
    312                 return EINVAL;
    313         }
    314 
    315         transfer_info_t *transfer
    316             = (transfer_info_t *) malloc(sizeof(transfer_info_t));
    317         if (transfer == NULL) {
    318                 return ENOMEM;
    319         }
    320 
    321         transfer->read_request = 0;
    322         transfer->size_transferred = actual_size;
    323         transfer->buffer = buffer;
    324         transfer->size = size;
    325         transfer->phone = phone;
    326 
    327         transfer->request = async_send_4(phone,
    328             DEV_IFACE_ID(USBHC_DEV_IFACE),
    329             method,
    330             target.address, target.endpoint,
    331             size,
    332             &transfer->reply);
    333 
    334         if (buffer != NULL) {
    335                 transfer->read_request = async_data_read(phone, buffer, size,
    336                     &transfer->read_reply);
    337         }
    338 
    339         *handle = (usb_handle_t) transfer;
    340 
    341         return EOK;
    342 }
    343 
     136        return ENOTSUP;
     137}
    344138
    345139/** Blocks caller until given USB transaction is finished.
     
    355149int usb_drv_async_wait_for(usb_handle_t handle)
    356150{
    357         if (handle == 0) {
    358                 return EBADMEM;
    359         }
    360 
    361         int rc = EOK;
    362 
    363         transfer_info_t *transfer = (transfer_info_t *) handle;
    364 
    365         sysarg_t answer_rc;
    366 
    367         /*
    368          * If the buffer is not NULL, we must accept some data.
    369          */
    370         if ((transfer->buffer != NULL) && (transfer->size > 0)) {
    371                 async_wait_for(transfer->read_request, &answer_rc);
    372 
    373                 if (answer_rc != EOK) {
    374                         rc = (int) answer_rc;
    375                         goto leave;
    376                 }
    377 
    378                 if (transfer->size_transferred != NULL) {
    379                         *(transfer->size_transferred)
    380                             = IPC_GET_ARG2(transfer->read_reply);
    381                 }
    382         }
    383 
    384         async_wait_for(transfer->request, &answer_rc);
    385 
    386         if (answer_rc != EOK) {
    387                 rc = (int) answer_rc;
    388                 goto leave;
    389         }
    390 
    391 leave:
    392         free(transfer);
    393 
    394         return rc;
     151        return ENOTSUP;
    395152}
    396153
     
    400157    usb_handle_t *handle)
    401158{
    402         return async_send_buffer(phone,
    403             IPC_M_USBHC_INTERRUPT_OUT,
    404             target,
    405             buffer, size,
    406             handle);
     159        return ENOTSUP;
    407160}
    408161
     
    412165    usb_handle_t *handle)
    413166{
    414         return async_recv_buffer(phone,
    415             IPC_M_USBHC_INTERRUPT_IN,
    416             target,
    417             buffer, size, actual_size,
    418             handle);
     167        return ENOTSUP;
    419168}
    420169
     
    424173    usb_handle_t *handle)
    425174{
    426         return async_send_buffer(phone,
    427             IPC_M_USBHC_CONTROL_WRITE_SETUP,
    428             target,
    429             buffer, size,
    430             handle);
     175        return ENOTSUP;
    431176}
    432177
     
    436181    usb_handle_t *handle)
    437182{
    438         return async_send_buffer(phone,
    439             IPC_M_USBHC_CONTROL_WRITE_DATA,
    440             target,
    441             buffer, size,
    442             handle);
     183        return ENOTSUP;
    443184}
    444185
     
    447188    usb_handle_t *handle)
    448189{
    449         return async_recv_buffer(phone,
    450             IPC_M_USBHC_CONTROL_WRITE_STATUS,
    451             target,
    452             NULL, 0, NULL,
    453             handle);
     190        return ENOTSUP;
    454191}
    455192
     
    460197    usb_handle_t *handle)
    461198{
    462         // FIXME - check input parameters instead of asserting them
    463         assert(phone > 0);
    464         assert(setup_packet != NULL);
    465         assert(setup_packet_size > 0);
    466         assert(((buffer != NULL) && (buffer_size > 0))
    467             || ((buffer == NULL) && (buffer_size == 0)));
    468         assert(handle != NULL);
    469 
    470         transfer_info_t *transfer
    471             = (transfer_info_t *) malloc(sizeof(transfer_info_t));
    472         if (transfer == NULL) {
    473                 return ENOMEM;
    474         }
    475 
    476         transfer->read_request = 0;
    477         transfer->size_transferred = NULL;
    478         transfer->buffer = NULL;
    479         transfer->size = 0;
    480         transfer->phone = phone;
    481 
    482         int rc;
    483 
    484         transfer->request = async_send_3(phone,
    485             DEV_IFACE_ID(USBHC_DEV_IFACE),
    486             IPC_M_USBHC_CONTROL_WRITE,
    487             target.address, target.endpoint,
    488             &transfer->reply);
    489 
    490         rc = async_data_write_start(phone, setup_packet, setup_packet_size);
    491         if (rc != EOK) {
    492                 async_wait_for(transfer->request, NULL);
    493                 return rc;
    494         }
    495 
    496         if (buffer_size > 0) {
    497                 rc = async_data_write_start(phone, buffer, buffer_size);
    498                 if (rc != EOK) {
    499                         async_wait_for(transfer->request, NULL);
    500                         return rc;
    501                 }
    502         }
    503 
    504         *handle = (usb_handle_t) transfer;
    505 
    506         return EOK;
     199        return ENOTSUP;
    507200}
    508201
     
    512205    usb_handle_t *handle)
    513206{
    514         return async_send_buffer(phone,
    515             IPC_M_USBHC_CONTROL_READ_SETUP,
    516             target,
    517             buffer, size,
    518             handle);
     207        return ENOTSUP;
    519208}
    520209
     
    524213    usb_handle_t *handle)
    525214{
    526         return async_recv_buffer(phone,
    527             IPC_M_USBHC_CONTROL_READ_DATA,
    528             target,
    529             buffer, size, actual_size,
    530             handle);
     215        return ENOTSUP;
    531216}
    532217
     
    535220    usb_handle_t *handle)
    536221{
    537         return async_send_buffer(phone,
    538             IPC_M_USBHC_CONTROL_READ_STATUS,
    539             target,
    540             NULL, 0,
    541             handle);
     222        return ENOTSUP;
    542223}
    543224
     
    548229    usb_handle_t *handle)
    549230{
    550         // FIXME - check input parameters instead of asserting them
    551         assert(phone > 0);
    552         assert(setup_packet != NULL);
    553         assert(setup_packet_size > 0);
    554         assert(buffer != NULL);
    555         assert(buffer_size > 0);
    556         assert(handle != NULL);
    557 
    558         transfer_info_t *transfer
    559             = (transfer_info_t *) malloc(sizeof(transfer_info_t));
    560         if (transfer == NULL) {
    561                 return ENOMEM;
    562         }
    563 
    564         transfer->size_transferred = actual_size;
    565         transfer->buffer = buffer;
    566         transfer->size = buffer_size;
    567         transfer->phone = phone;
    568 
    569         int rc;
    570 
    571         transfer->request = async_send_4(phone,
    572             DEV_IFACE_ID(USBHC_DEV_IFACE),
    573             IPC_M_USBHC_CONTROL_READ,
    574             target.address, target.endpoint,
    575             buffer_size,
    576             &transfer->reply);
    577 
    578         rc = async_data_write_start(phone, setup_packet, setup_packet_size);
    579         if (rc != EOK) {
    580                 async_wait_for(transfer->request, NULL);
    581                 return rc;
    582         }
    583 
    584         transfer->read_request = async_data_read(phone, buffer, buffer_size,
    585             &transfer->read_reply);
    586 
    587         *handle = (usb_handle_t) transfer;
    588 
    589         return EOK;
     231        return ENOTSUP;
    590232}
    591233
Note: See TracChangeset for help on using the changeset viewer.