Changes in / [8e8b84f:61727bf] in mainline


Ignore:
Location:
uspace
Files:
4 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/Makefile

    r8e8b84f r61727bf  
    3333
    3434SOURCES = \
     35        iface.c \
    3536        batch.c \
     37        main.c \
    3638        hc.c \
    37         iface.c \
    38         main.c \
    3939        ohci.c \
    40         pci.c \
    4140        root_hub.c \
    42         transfer_list.c \
    43         hw_struct/endpoint_descriptor.c \
    44         hw_struct/transfer_descriptor.c
    45 
     41        pci.c
    4642
    4743include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/ohci/batch.c

    r8e8b84f r61727bf  
    4040#include "batch.h"
    4141#include "utils/malloc32.h"
    42 #include "hw_struct/endpoint_descriptor.h"
    43 #include "hw_struct/transfer_descriptor.h"
    4442
    45 typedef struct ohci_batch {
    46         ed_t *ed;
    47         td_t *tds;
    48         size_t td_count;
    49 } ohci_batch_t;
    50 
    51 static void batch_control(usb_transfer_batch_t *instance,
    52     usb_direction_t data_dir, usb_direction_t status_dir);
    5343static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
    5444static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    5545
    5646#define DEFAULT_ERROR_COUNT 3
    57 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    58     char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
     47usb_transfer_batch_t * batch_get(
     48    ddf_fun_t *fun,
     49                usb_target_t target,
     50    usb_transfer_type_t transfer_type,
     51                size_t max_packet_size,
     52    usb_speed_t speed,
     53                char *buffer,
     54                size_t buffer_size,
     55                char *setup_buffer,
     56                size_t setup_size,
    5957    usbhc_iface_transfer_in_callback_t func_in,
    60     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     58    usbhc_iface_transfer_out_callback_t func_out,
     59                void *arg,
     60                usb_device_keeper_t *manager
     61                )
    6162{
    6263#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     
    7273        CHECK_NULL_DISPOSE_RETURN(instance,
    7374            "Failed to allocate batch instance.\n");
    74         usb_target_t target =
    75             { .address = ep->address, .endpoint = ep->endpoint };
    76         usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
    77             ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
    78             func_in, func_out, arg, fun, ep, NULL);
    79 
    80         ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
    81         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
    82         bzero(data, sizeof(ohci_batch_t));
    83         instance->private_data = data;
    84 
    85         /* we needs + 1 transfer descriptor as the last one won't be executed */
    86         data->td_count = 1 +
    87             ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
    88         if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    89                 data->td_count += 2;
    90         }
    91 
    92         data->tds = malloc32(sizeof(td_t) * data->td_count);
    93         CHECK_NULL_DISPOSE_RETURN(data->tds,
    94             "Failed to allocate transfer descriptors.\n");
    95         bzero(data->tds, sizeof(td_t) * data->td_count);
    96 
    97         data->ed = malloc32(sizeof(ed_t));
    98         CHECK_NULL_DISPOSE_RETURN(data->ed,
    99             "Failed to allocate endpoint descriptor.\n");
     75        usb_transfer_batch_init(instance, target, transfer_type, speed,
     76            max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
     77            func_in, func_out, arg, fun, NULL, NULL);
    10078
    10179        if (buffer_size > 0) {
     
    11290        }
    11391
     92
    11493        return instance;
    11594}
     
    11897{
    11998        assert(instance);
    120         ohci_batch_t *data = instance->private_data;
    121         assert(data);
    122         free32(data->ed);
    123         free32(data->tds);
     99        free32(instance->transport_buffer);
    124100        free32(instance->setup_buffer);
    125         free32(instance->transport_buffer);
    126         free(data);
    127101        free(instance);
    128 }
    129 /*----------------------------------------------------------------------------*/
    130 bool batch_is_complete(usb_transfer_batch_t *instance)
    131 {
    132         assert(instance);
    133         ohci_batch_t *data = instance->private_data;
    134         assert(data);
    135         size_t tds = data->td_count - 1;
    136         usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n",
    137             instance, tds);
    138         size_t i = 0;
    139         for (; i < tds; ++i) {
    140                 if (!td_is_finished(&data->tds[i]))
    141                         return false;
    142                 instance->error = td_error(&data->tds[i]);
    143                 /* FIXME: calculate real transfered size */
    144                 instance->transfered_size = instance->buffer_size;
    145                 if (instance->error != EOK) {
    146                         usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    147                             instance, i, data->tds[i].status);
    148                         return true;
    149 //                      endpoint_toggle_set(instance->ep,
    150                 }
    151         }
    152         return true;
    153102}
    154103/*----------------------------------------------------------------------------*/
     
    160109            instance->buffer_size);
    161110        instance->next_step = batch_call_out_and_dispose;
    162         batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
     111        /* TODO: implement */
    163112        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    164113}
     
    168117        assert(instance);
    169118        instance->next_step = batch_call_in_and_dispose;
    170         batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);
     119        /* TODO: implement */
    171120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    172121}
     
    175124{
    176125        assert(instance);
    177         assert(instance->direction == USB_DIRECTION_IN);
     126        instance->direction = USB_DIRECTION_IN;
    178127        instance->next_step = batch_call_in_and_dispose;
    179128        /* TODO: implement */
     
    184133{
    185134        assert(instance);
    186         assert(instance->direction == USB_DIRECTION_OUT);
     135        instance->direction = USB_DIRECTION_OUT;
    187136        /* We are data out, we are supposed to provide data */
    188137        memcpy(instance->transport_buffer, instance->buffer,
     
    211160}
    212161/*----------------------------------------------------------------------------*/
    213 ed_t * batch_ed(usb_transfer_batch_t *instance)
    214 {
    215         assert(instance);
    216         ohci_batch_t *data = instance->private_data;
    217         assert(data);
    218         return data->ed;
    219 }
    220 /*----------------------------------------------------------------------------*/
    221 void batch_control(usb_transfer_batch_t *instance,
    222     usb_direction_t data_dir, usb_direction_t status_dir)
    223 {
    224         assert(instance);
    225         ohci_batch_t *data = instance->private_data;
    226         assert(data);
    227         ed_init(data->ed, instance->ep);
    228         ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);
    229         usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status,
    230             data->ed->td_tail, data->ed->td_head, data->ed->next);
    231         int toggle = 0;
    232         /* setup stage */
    233         td_init(&data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer,
    234                 instance->setup_size, toggle);
    235         td_set_next(&data->tds[0], &data->tds[1]);
    236         usb_log_debug("Created SETUP TD: %x:%x:%x:%x.\n", data->tds[0].status,
    237             data->tds[0].cbp, data->tds[0].next, data->tds[0].be);
    238 
    239         /* data stage */
    240         size_t td_current = 1;
    241         size_t remain_size = instance->buffer_size;
    242         char *transfer_buffer = instance->transport_buffer;
    243         while (remain_size > 0) {
    244                 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
    245                     OHCI_TD_MAX_TRANSFER : remain_size;
    246                 toggle = 1 - toggle;
    247 
    248                 td_init(&data->tds[td_current], data_dir, transfer_buffer,
    249                     transfer_size, toggle);
    250                 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
    251                 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
    252                     data->tds[td_current].status, data->tds[td_current].cbp,
    253                     data->tds[td_current].next, data->tds[td_current].be);
    254 
    255                 transfer_buffer += transfer_size;
    256                 remain_size -= transfer_size;
    257                 assert(td_current < data->td_count - 2);
    258                 ++td_current;
    259         }
    260 
    261         /* status stage */
    262         assert(td_current == data->td_count - 2);
    263         td_init(&data->tds[td_current], status_dir, NULL, 0, 1);
    264         usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n",
    265             data->tds[td_current].status, data->tds[td_current].cbp,
    266             data->tds[td_current].next, data->tds[td_current].be);
    267 }
    268 /*----------------------------------------------------------------------------*/
    269162/** Helper function calls callback and correctly disposes of batch structure.
    270163 *
  • uspace/drv/ohci/batch.h

    r8e8b84f r61727bf  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbuhcihc
     28/** @addtogroup drvusbohci
    2929 * @{
    3030 */
    3131/** @file
    32  * @brief UHCI driver USB transaction structure
     32 * @brief OHCI driver USB transaction structure
    3333 */
    34 #ifndef DRV_UHCI_BATCH_H
    35 #define DRV_UHCI_BATCH_H
     34#ifndef DRV_OHCI_BATCH_H
     35#define DRV_OHCI_BATCH_H
     36
    3637
    3738#include <usbhc_iface.h>
    3839#include <usb/usb.h>
    3940#include <usb/host/device_keeper.h>
    40 #include <usb/host/endpoint.h>
    4141#include <usb/host/batch.h>
    4242
    43 #include "hw_struct/endpoint_descriptor.h"
    44 
    4543usb_transfer_batch_t * batch_get(
    46     ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    47     char *setup_buffer, size_t setup_size,
     44    ddf_fun_t *fun,
     45                usb_target_t target,
     46    usb_transfer_type_t transfer_type,
     47                size_t max_packet_size,
     48    usb_speed_t speed,
     49                char *buffer,
     50                size_t size,
     51                char *setup_buffer,
     52                size_t setup_size,
    4853    usbhc_iface_transfer_in_callback_t func_in,
    4954    usbhc_iface_transfer_out_callback_t func_out,
    50     void *arg);
     55                void *arg,
     56                usb_device_keeper_t *manager
     57                );
    5158
    5259void batch_dispose(usb_transfer_batch_t *instance);
    53 
    54 bool batch_is_complete(usb_transfer_batch_t *instance);
    5560
    5661void batch_control_write(usb_transfer_batch_t *instance);
     
    6570
    6671void batch_bulk_out(usb_transfer_batch_t *instance);
    67 
    68 ed_t * batch_ed(usb_transfer_batch_t *instance);
    6972#endif
    7073/**
  • uspace/drv/ohci/hc.c

    r8e8b84f r61727bf  
    4747static void hc_gain_control(hc_t *instance);
    4848static void hc_init_hw(hc_t *instance);
    49 static int hc_init_transfer_lists(hc_t *instance);
    50 static int hc_init_memory(hc_t *instance);
    5149/*----------------------------------------------------------------------------*/
    5250int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     
    6159            &instance->manager, hub_address, hub_fun->handle);
    6260
    63         endpoint_t *ep = malloc(sizeof(endpoint_t));
    64         assert(ep);
    65         int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH,
    66             USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64);
    67         assert(ret == EOK);
    68         ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0);
    69         assert(ret == EOK);
    70 
    7161        char *match_str = NULL;
    72         ret = asprintf(&match_str, "usb&class=hub");
    73 //      ret = (match_str == NULL) ? ret : EOK;
     62        int ret = asprintf(&match_str, "usb&class=hub");
     63        ret = (match_str == NULL) ? ret : EOK;
    7464        if (ret < 0) {
    75                 usb_log_error(
    76                     "Failed(%d) to create root hub match-id string.\n", ret);
     65                usb_log_error("Failed to create root hub match-id string.\n");
    7766                return ret;
    7867        }
     
    118107        rh_init(&instance->rh, dev, instance->registers);
    119108
    120         hc_init_memory(instance);
    121109        hc_init_hw(instance);
    122110
     
    129117        assert(instance);
    130118        assert(batch);
    131 
    132         /* check for root hub communication */
    133119        if (batch->target.address == instance->rh.address) {
    134120                return rh_request(&instance->rh, batch);
    135121        }
    136 
    137         transfer_list_add_batch(
    138             instance->transfers[batch->transfer_type], batch);
    139 
    140         switch (batch->transfer_type) {
    141         case USB_TRANSFER_CONTROL:
    142                 instance->registers->command_status |= CS_CLF;
    143                 break;
    144         case USB_TRANSFER_BULK:
    145                 instance->registers->command_status |= CS_BLF;
    146                 break;
    147         default:
    148                 break;
    149         }
    150         return EOK;
     122        /* TODO: implement */
     123        return ENOTSUP;
    151124}
    152125/*----------------------------------------------------------------------------*/
     
    161134        usb_log_info("OHCI interrupt: %x.\n", status);
    162135
    163         LIST_INITIALIZE(done);
    164         transfer_list_remove_finished(&instance->transfers_interrupt, &done);
    165         transfer_list_remove_finished(&instance->transfers_isochronous, &done);
    166         transfer_list_remove_finished(&instance->transfers_control, &done);
    167         transfer_list_remove_finished(&instance->transfers_bulk, &done);
    168 
    169         while (!list_empty(&done)) {
    170                 link_t *item = done.next;
    171                 list_remove(item);
    172                 usb_transfer_batch_t *batch =
    173                     list_get_instance(item, usb_transfer_batch_t, link);
    174                 usb_transfer_batch_finish(batch);
    175         }
     136        /* TODO: Check for further interrupt causes */
     137        /* TODO: implement */
    176138}
    177139/*----------------------------------------------------------------------------*/
     
    235197        assert(instance);
    236198        const uint32_t fm_interval = instance->registers->fm_interval;
    237 
    238         /* reset hc */
    239199        instance->registers->command_status = CS_HCR;
    240200        async_usleep(10);
    241 
    242         /* restore fm_interval */
    243201        instance->registers->fm_interval = fm_interval;
    244202        assert((instance->registers->command_status & CS_HCR) == 0);
    245 
    246203        /* hc is now in suspend state */
    247 
    248         /* enable queues */
    249         instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
     204        /* TODO: init HCCA block */
     205        /* TODO: init queues */
     206        /* TODO: enable queues */
    250207        /* TODO: enable interrupts */
    251         /* set periodic start to 90% */
    252         instance->registers->periodic_start = (fm_interval / 10) * 9;
     208        /* TODO: set periodic start to 90% */
    253209
    254210        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    255211        usb_log_info("OHCI HC up and running.\n");
    256212}
    257 /*----------------------------------------------------------------------------*/
    258 int hc_init_transfer_lists(hc_t *instance)
    259 {
    260         assert(instance);
    261 
    262 #define SETUP_TRANSFER_LIST(type, name) \
    263 do { \
    264         int ret = transfer_list_init(&instance->type, name); \
    265         if (ret != EOK) { \
    266                 usb_log_error("Failed(%d) to setup %s transfer list.\n", \
    267                     ret, name); \
    268                 transfer_list_fini(&instance->transfers_isochronous); \
    269                 transfer_list_fini(&instance->transfers_interrupt); \
    270                 transfer_list_fini(&instance->transfers_control); \
    271                 transfer_list_fini(&instance->transfers_bulk); \
    272         } \
    273 } while (0)
    274 
    275         SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");
    276         SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");
    277         SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
    278         SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
    279 
    280         transfer_list_set_next(&instance->transfers_interrupt,
    281             &instance->transfers_isochronous);
    282 
    283         /* Assign pointers to be used during scheduling */
    284         instance->transfers[USB_TRANSFER_INTERRUPT] =
    285           &instance->transfers_interrupt;
    286         instance->transfers[USB_TRANSFER_ISOCHRONOUS] =
    287           &instance->transfers_interrupt;
    288         instance->transfers[USB_TRANSFER_CONTROL] =
    289           &instance->transfers_control;
    290         instance->transfers[USB_TRANSFER_BULK] =
    291           &instance->transfers_bulk;
    292 
    293         return EOK;
    294 #undef CHECK_RET_CLEAR_RETURN
    295 }
    296 /*----------------------------------------------------------------------------*/
    297 int hc_init_memory(hc_t *instance)
    298 {
    299         assert(instance);
    300         /* init queues */
    301         hc_init_transfer_lists(instance);
    302 
    303         /* init HCCA */
    304         instance->hcca = malloc32(sizeof(hcca_t));
    305         if (instance->hcca == NULL)
    306                 return ENOMEM;
    307         bzero(instance->hcca, sizeof(hcca_t));
    308         instance->registers->hcca = addr_to_phys(instance->hcca);
    309 
    310         /* use queues */
    311         instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
    312         instance->registers->control_head =
    313             instance->transfers_control.list_head_pa;
    314 
    315         unsigned i = 0;
    316         for (; i < 32; ++i) {
    317                 instance->hcca->int_ep[i] =
    318                     instance->transfers_interrupt.list_head_pa;
    319         }
    320 
    321         return EOK;
    322 }
    323213/**
    324214 * @}
  • uspace/drv/ohci/hc.h

    r8e8b84f r61727bf  
    4848#include "ohci_regs.h"
    4949#include "root_hub.h"
    50 #include "transfer_list.h"
    5150#include "hw_struct/hcca.h"
    5251
     
    5554        usb_address_t rh_address;
    5655        rh_t rh;
    57 
    58         hcca_t *hcca;
    59 
    60         transfer_list_t transfers_isochronous;
    61         transfer_list_t transfers_interrupt;
    62         transfer_list_t transfers_control;
    63         transfer_list_t transfers_bulk;
    64 
    65         transfer_list_t *transfers[4];
    66 
    6756        ddf_fun_t *ddf_instance;
    6857        usb_device_keeper_t manager;
  • uspace/drv/ohci/hw_struct/completion_codes.h

    r8e8b84f r61727bf  
    3535#define DRV_OHCI_HW_STRUCT_COMPLETION_CODES_H
    3636
    37 #include <errno.h>
    38 
    3937#define CC_NOERROR (0x0)
    4038#define CC_CRC (0x1)
     
    5250#define CC_NOACCESS2 (0xf)
    5351
    54 inline static int cc_to_rc(int cc)
    55 {
    56         switch (cc) {
    57         case CC_NOERROR:
    58                 return EOK;
    59 
    60         case CC_CRC:
    61                 return EBADCHECKSUM;
    62 
    63         case CC_PIDUNEXPECTED:
    64         case CC_PIDFAIL:
    65         case CC_BITSTUFF:
    66                 return EIO;
    67 
    68         case CC_TOGGLE:
    69         case CC_STALL:
    70                 return ESTALL;
    71 
    72         case CC_NORESPONSE:
    73                 return ETIMEOUT;
    74 
    75         case CC_DATAOVERRRUN:
    76         case CC_DATAUNDERRRUN:
    77         case CC_BUFFEROVERRRUN:
    78         case CC_BUFFERUNDERRUN:
    79                 return EOVERFLOW;
    80 
    81         case CC_NOACCESS1:
    82         case CC_NOACCESS2:
    83         default:
    84                 return ENOTSUP;
    85         }
    86 }
    87 
    8852#endif
    8953/**
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.h

    r8e8b84f r61727bf  
    3535#define DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H
    3636
    37 #include <assert.h>
    3837#include <stdint.h>
    39 
    40 #include <usb/host/endpoint.h>
    41 
    42 #include "utils/malloc32.h"
    43 #include "transfer_descriptor.h"
    4438
    4539#include "completion_codes.h"
     
    5044#define ED_STATUS_FA_SHIFT (0)
    5145#define ED_STATUS_EN_MASK (0xf)    /* USB endpoint address */
    52 #define ED_STATUS_EN_SHIFT (7)
     46#define ED_STATUS_EN_SHIFT (6)
    5347#define ED_STATUS_D_MASK (0x3)     /* direction */
    54 #define ED_STATUS_D_SHIFT (11)
     48#define ED_STATUS_D_SHIFT (10)
    5549#define ED_STATUS_D_IN (0x1)
    5650#define ED_STATUS_D_OUT (0x2)
    57 #define ED_STATUS_D_TRANSFER (0x3)
    5851
    59 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag: 1 = low */
     52#define ED_STATUS_S_FLAG (1 << 13) /* speed flag */
    6053#define ED_STATUS_K_FLAG (1 << 14) /* skip flag (no not execute this ED) */
    6154#define ED_STATUS_F_FLAG (1 << 15) /* format: 1 = isochronous*/
     
    7871#define ED_NEXT_PTR_SHIFT (0)
    7972} __attribute__((packed)) ed_t;
    80 
    81 void ed_init(ed_t *instance, endpoint_t *ep);
    82 
    83 static inline void ed_add_tds(ed_t *instance, td_t *head, td_t *tail)
    84 {
    85         assert(instance);
    86         instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK;
    87         instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK;
    88 }
    89 
    90 static inline void ed_append_ed(ed_t *instance, ed_t *next)
    91 {
    92         assert(instance);
    93         assert(next);
    94         uint32_t pa = addr_to_phys(next);
    95         assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa);
    96         instance->next = pa;
    97 }
    98 
    9973#endif
    10074/**
  • uspace/drv/ohci/hw_struct/transfer_descriptor.h

    r8e8b84f r61727bf  
    3535#define DRV_OHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
    3636
    37 #include <bool.h>
    3837#include <stdint.h>
    39 #include "utils/malloc32.h"
    4038
    4139#include "completion_codes.h"
    42 
    43 /* OHCI TDs can handle up to 8KB buffers */
    44 #define OHCI_TD_MAX_TRANSFER (8 * 1024)
    4540
    4641typedef struct td {
     
    5752#define TD_STATUS_T_MASK (0x3)  /* data toggle 1x = use ED toggle carry */
    5853#define TD_STATUS_T_SHIFT (24)
    59 #define TD_STATUS_T_0 (0x2)
    60 #define TD_STATUS_T_1 (0x3)
    6154#define TD_STATUS_EC_MASK (0x3) /* error count */
    6255#define TD_STATUS_EC_SHIFT (26)
     
    7164        volatile uint32_t be; /* buffer end, address of the last byte */
    7265} __attribute__((packed)) td_t;
    73 
    74 void td_init(
    75     td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle);
    76 
    77 inline static void td_set_next(td_t *instance, td_t *next)
    78 {
    79         assert(instance);
    80         instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK;
    81 }
    82 
    83 inline static bool td_is_finished(td_t *instance)
    84 {
    85         assert(instance);
    86         int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;
    87         /* something went wrong, error code is set */
    88         if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) {
    89                 return true;
    90         }
    91         /* everything done */
    92         if (cc == CC_NOERROR && instance->cbp == 0) {
    93                 return true;
    94         }
    95         return false;
    96 }
    97 
    98 static inline int td_error(td_t *instance)
    99 {
    100         assert(instance);
    101         int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;
    102         return cc_to_rc(cc);
    103 }
    10466#endif
    10567/**
  • uspace/drv/ohci/iface.c

    r8e8b84f r61727bf  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky, Jan Vesely
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    3030 */
    3131/** @file
    32  * @brief OHCI driver hc interface implementation
     32 * USB-HC interface implementation.
    3333 */
    3434#include <ddf/driver.h>
     
    3636
    3737#include <usb/debug.h>
    38 #include <usb/host/endpoint.h>
    3938
    4039#include "iface.h"
    4140#include "hc.h"
    4241
    43 static inline int setup_batch(
    44     ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
    45     void *data, size_t size, void * setup_data, size_t setup_size,
    46     usbhc_iface_transfer_in_callback_t in,
    47     usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
    48     hc_t **hc, usb_transfer_batch_t **batch)
    49 {
    50         assert(hc);
    51         assert(batch);
    52         assert(fun);
    53         *hc = fun_to_hc(fun);
    54         assert(*hc);
    55 
    56         size_t res_bw;
    57         endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
    58             target.address, target.endpoint, direction, &res_bw);
    59         if (ep == NULL) {
    60                 usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
    61                     target.address, target.endpoint, name);
    62                 return ENOENT;
    63         }
    64 
    65         const size_t bw = bandwidth_count_usb11(
    66             ep->speed, ep->transfer_type, size, ep->max_packet_size);
    67         if (res_bw < bw) {
    68                 usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    69                     "but only %zu is reserved.\n",
    70                     name, target.address, target.endpoint, bw, res_bw);
    71                 return ENOSPC;
    72         }
    73         usb_log_debug("%s %d:%d %zu(%zu).\n",
    74             name, target.address, target.endpoint, size, ep->max_packet_size);
    75 
    76         assert(ep->speed ==
    77             usb_device_keeper_get_speed(&(*hc)->manager, target.address));
    78 //      assert(ep->max_packet_size == max_packet_size);
    79 //      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
    80 
    81         *batch =
    82             batch_get(fun, ep, data, size, setup_data, setup_size,
    83                 in, out, arg);
    84         if (!batch)
    85                 return ENOMEM;
    86         return EOK;
    87 }
    88 
    89 
    90 /** Reserve default address interface function
    91  *
    92  * @param[in] fun DDF function that was called.
    93  * @param[in] speed Speed to associate with the new default address.
     42#define UNSUPPORTED(methodname) \
     43        usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \
     44            methodname, __FILE__, __LINE__)
     45
     46/** Reserve default address.
     47 *
     48 * This function may block the caller.
     49 *
     50 * @param[in] fun Device function the action was invoked on.
     51 * @param[in] speed Speed of the device for which the default address is
     52 *      reserved.
    9453 * @return Error code.
    9554 */
     
    10261        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    10362        return EOK;
    104 #if 0
    105         endpoint_t *ep = malloc(sizeof(endpoint_t));
    106         if (ep == NULL)
    107                 return ENOMEM;
    108         const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
    109         endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
    110         int ret;
    111 try_retgister:
    112         ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
    113             USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
    114         if (ret == EEXISTS) {
    115                 async_usleep(1000);
    116                 goto try_retgister;
    117         }
    118         if (ret != EOK) {
    119                 endpoint_destroy(ep);
    120         }
    121         return ret;
    122 #endif
    123 }
    124 /*----------------------------------------------------------------------------*/
    125 /** Release default address interface function
    126  *
    127  * @param[in] fun DDF function that was called.
     63}
     64/*----------------------------------------------------------------------------*/
     65/** Release default address.
     66 *
     67 * @param[in] fun Device function the action was invoked on.
    12868 * @return Error code.
    12969 */
     
    13474        assert(hc);
    13575        usb_log_debug("Default address release.\n");
    136 //      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
    137 //          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
    13876        usb_device_keeper_release_default_address(&hc->manager);
    13977        return EOK;
    14078}
    14179/*----------------------------------------------------------------------------*/
    142 /** Request address interface function
    143  *
    144  * @param[in] fun DDF function that was called.
    145  * @param[in] speed Speed to associate with the new default address.
    146  * @param[out] address Place to write a new address.
     80/** Found free USB address.
     81 *
     82 * @param[in] fun Device function the action was invoked on.
     83 * @param[in] speed Speed of the device that will get this address.
     84 * @param[out] address Non-null pointer where to store the free address.
    14785 * @return Error code.
    14886 */
     
    163101}
    164102/*----------------------------------------------------------------------------*/
    165 /** Bind address interface function
    166  *
    167  * @param[in] fun DDF function that was called.
    168  * @param[in] address Address of the device
    169  * @param[in] handle Devman handle of the device driver.
     103/** Bind USB address with device devman handle.
     104 *
     105 * @param[in] fun Device function the action was invoked on.
     106 * @param[in] address USB address of the device.
     107 * @param[in] handle Devman handle of the device.
    170108 * @return Error code.
    171109 */
    172110static int bind_address(
    173   ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     111    ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    174112{
    175113        assert(fun);
     
    181119}
    182120/*----------------------------------------------------------------------------*/
    183 /** Release address interface function
    184  *
    185  * @param[in] fun DDF function that was called.
     121/** Release previously requested address.
     122 *
     123 * @param[in] fun Device function the action was invoked on.
    186124 * @param[in] address USB address to be released.
    187125 * @return Error code.
     
    197135}
    198136/*----------------------------------------------------------------------------*/
     137/** Register endpoint for bandwidth reservation.
     138 *
     139 * @param[in] fun Device function the action was invoked on.
     140 * @param[in] address USB address of the device.
     141 * @param[in] endpoint Endpoint number.
     142 * @param[in] transfer_type USB transfer type.
     143 * @param[in] direction Endpoint data direction.
     144 * @param[in] max_packet_size Max packet size of the endpoint.
     145 * @param[in] interval Polling interval.
     146 * @return Error code.
     147 */
    199148static int register_endpoint(
    200149    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
     
    202151    size_t max_packet_size, unsigned int interval)
    203152{
    204         hc_t *hc = fun_to_hc(fun);
    205         assert(hc);
     153        assert(fun);
     154        hc_t *hc = fun_to_hc(fun);
     155        assert(hc);
     156        if (address == hc->rh.address)
     157                return EOK;
    206158        const usb_speed_t speed =
    207             usb_device_keeper_get_speed(&hc->manager, address);
    208         const size_t size =
    209             (transfer_type == USB_TRANSFER_INTERRUPT
    210             || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
    211             max_packet_size : 0;
    212         int ret;
    213 
    214         endpoint_t *ep = malloc(sizeof(endpoint_t));
    215         if (ep == NULL)
    216                 return ENOMEM;
    217         ret = endpoint_init(ep, address, endpoint, direction,
    218             transfer_type, speed, max_packet_size);
    219         if (ret != EOK) {
    220                 free(ep);
    221                 return ret;
    222         }
    223 
     159                usb_device_keeper_get_speed(&hc->manager, address);
     160        const size_t size = max_packet_size;
    224161        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    225162            address, endpoint, usb_str_transfer_type(transfer_type),
    226163            usb_str_speed(speed), direction, size, max_packet_size, interval);
    227 
    228         ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    229         if (ret != EOK) {
    230                 endpoint_destroy(ep);
    231         } else {
    232                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    233         }
    234         return ret;
    235 }
    236 /*----------------------------------------------------------------------------*/
     164        // TODO use real endpoint here!
     165        return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0);
     166}
     167/*----------------------------------------------------------------------------*/
     168/** Unregister endpoint (free some bandwidth reservation).
     169 *
     170 * @param[in] fun Device function the action was invoked on.
     171 * @param[in] address USB address of the device.
     172 * @param[in] endpoint Endpoint number.
     173 * @param[in] direction Endpoint data direction.
     174 * @return Error code.
     175 */
    237176static int unregister_endpoint(
    238177    ddf_fun_t *fun, usb_address_t address,
    239178    usb_endpoint_t endpoint, usb_direction_t direction)
    240179{
     180        assert(fun);
    241181        hc_t *hc = fun_to_hc(fun);
    242182        assert(hc);
     
    247187}
    248188/*----------------------------------------------------------------------------*/
    249 /** Interrupt out transaction interface function
    250  *
    251  * @param[in] fun DDF function that was called.
    252  * @param[in] target USB device to write to.
    253  * @param[in] max_packet_size maximum size of data packet the device accepts
    254  * @param[in] data Source of data.
    255  * @param[in] size Size of data source.
    256  * @param[in] callback Function to call on transaction completion
    257  * @param[in] arg Additional for callback function.
     189/** Schedule interrupt out transfer.
     190 *
     191 * The callback is supposed to be called once the transfer (on the wire) is
     192 * complete regardless of the outcome.
     193 * However, the callback could be called only when this function returns
     194 * with success status (i.e. returns EOK).
     195 *
     196 * @param[in] fun Device function the action was invoked on.
     197 * @param[in] target Target pipe (address and endpoint number) specification.
     198 * @param[in] max_packet_size Max packet size for the transfer.
     199 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
     200 *      by the caller).
     201 * @param[in] size Size of the @p data buffer in bytes.
     202 * @param[in] callback Callback to be issued once the transfer is complete.
     203 * @param[in] arg Pass-through argument to the callback.
    258204 * @return Error code.
    259205 */
     
    262208    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    263209{
    264         usb_transfer_batch_t *batch = NULL;
    265         hc_t *hc = NULL;
    266         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    267             NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
    268         if (ret != EOK)
    269                 return ret;
     210        assert(fun);
     211        hc_t *hc = fun_to_hc(fun);
     212        assert(hc);
     213        usb_speed_t speed =
     214            usb_device_keeper_get_speed(&hc->manager, target.address);
     215
     216        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     217            target.address, target.endpoint, size, max_packet_size);
     218
     219        usb_transfer_batch_t *batch =
     220            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     221                speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     222        if (!batch)
     223                return ENOMEM;
    270224        batch_interrupt_out(batch);
    271         ret = hc_schedule(hc, batch);
    272         if (ret != EOK) {
    273                 batch_dispose(batch);
    274         }
    275         return ret;
    276 }
    277 /*----------------------------------------------------------------------------*/
    278 /** Interrupt in transaction interface function
    279  *
    280  * @param[in] fun DDF function that was called.
    281  * @param[in] target USB device to write to.
    282  * @param[in] max_packet_size maximum size of data packet the device accepts
    283  * @param[out] data Data destination.
    284  * @param[in] size Size of data source.
    285  * @param[in] callback Function to call on transaction completion
    286  * @param[in] arg Additional for callback function.
     225        const int ret = hc_schedule(hc, batch);
     226        if (ret != EOK) {
     227                batch_dispose(batch);
     228        }
     229        return ret;
     230}
     231/*----------------------------------------------------------------------------*/
     232/** Schedule interrupt in transfer.
     233 *
     234 * The callback is supposed to be called once the transfer (on the wire) is
     235 * complete regardless of the outcome.
     236 * However, the callback could be called only when this function returns
     237 * with success status (i.e. returns EOK).
     238 *
     239 * @param[in] fun Device function the action was invoked on.
     240 * @param[in] target Target pipe (address and endpoint number) specification.
     241 * @param[in] max_packet_size Max packet size for the transfer.
     242 * @param[in] data Buffer where to store the data (in USB endianess,
     243 *      allocated and deallocated by the caller).
     244 * @param[in] size Size of the @p data buffer in bytes.
     245 * @param[in] callback Callback to be issued once the transfer is complete.
     246 * @param[in] arg Pass-through argument to the callback.
    287247 * @return Error code.
    288248 */
     
    291251    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    292252{
    293         usb_transfer_batch_t *batch = NULL;
    294         hc_t *hc = NULL;
    295         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    296             NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
    297         if (ret != EOK)
    298                 return ret;
     253        assert(fun);
     254        hc_t *hc = fun_to_hc(fun);
     255        assert(hc);
     256        usb_speed_t speed =
     257            usb_device_keeper_get_speed(&hc->manager, target.address);
     258        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     259            target.address, target.endpoint, size, max_packet_size);
     260
     261        usb_transfer_batch_t *batch =
     262            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     263                speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     264        if (!batch)
     265                return ENOMEM;
    299266        batch_interrupt_in(batch);
    300         ret = hc_schedule(hc, batch);
    301         if (ret != EOK) {
    302                 batch_dispose(batch);
    303         }
    304         return ret;
    305 }
    306 /*----------------------------------------------------------------------------*/
    307 /** Bulk out transaction interface function
    308  *
    309  * @param[in] fun DDF function that was called.
    310  * @param[in] target USB device to write to.
    311  * @param[in] max_packet_size maximum size of data packet the device accepts
    312  * @param[in] data Source of data.
    313  * @param[in] size Size of data source.
    314  * @param[in] callback Function to call on transaction completion
    315  * @param[in] arg Additional for callback function.
     267        const int ret = hc_schedule(hc, batch);
     268        if (ret != EOK) {
     269                batch_dispose(batch);
     270        }
     271        return ret;
     272}
     273/*----------------------------------------------------------------------------*/
     274/** Schedule bulk out transfer.
     275 *
     276 * The callback is supposed to be called once the transfer (on the wire) is
     277 * complete regardless of the outcome.
     278 * However, the callback could be called only when this function returns
     279 * with success status (i.e. returns EOK).
     280 *
     281 * @param[in] fun Device function the action was invoked on.
     282 * @param[in] target Target pipe (address and endpoint number) specification.
     283 * @param[in] max_packet_size Max packet size for the transfer.
     284 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
     285 *      by the caller).
     286 * @param[in] size Size of the @p data buffer in bytes.
     287 * @param[in] callback Callback to be issued once the transfer is complete.
     288 * @param[in] arg Pass-through argument to the callback.
    316289 * @return Error code.
    317290 */
     
    320293    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    321294{
    322         usb_transfer_batch_t *batch = NULL;
    323         hc_t *hc = NULL;
    324         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    325             NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
    326         if (ret != EOK)
    327                 return ret;
     295        assert(fun);
     296        hc_t *hc = fun_to_hc(fun);
     297        assert(hc);
     298        usb_speed_t speed =
     299            usb_device_keeper_get_speed(&hc->manager, target.address);
     300
     301        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     302            target.address, target.endpoint, size, max_packet_size);
     303
     304        usb_transfer_batch_t *batch =
     305            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     306                data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     307        if (!batch)
     308                return ENOMEM;
    328309        batch_bulk_out(batch);
    329         ret = hc_schedule(hc, batch);
    330         if (ret != EOK) {
    331                 batch_dispose(batch);
    332         }
    333         return ret;
    334 }
    335 /*----------------------------------------------------------------------------*/
    336 /** Bulk in transaction interface function
    337  *
    338  * @param[in] fun DDF function that was called.
    339  * @param[in] target USB device to write to.
    340  * @param[in] max_packet_size maximum size of data packet the device accepts
    341  * @param[out] data Data destination.
    342  * @param[in] size Size of data source.
    343  * @param[in] callback Function to call on transaction completion
    344  * @param[in] arg Additional for callback function.
     310        const int ret = hc_schedule(hc, batch);
     311        if (ret != EOK) {
     312                batch_dispose(batch);
     313        }
     314        return ret;
     315}
     316/*----------------------------------------------------------------------------*/
     317/** Schedule bulk in transfer.
     318 *
     319 * The callback is supposed to be called once the transfer (on the wire) is
     320 * complete regardless of the outcome.
     321 * However, the callback could be called only when this function returns
     322 * with success status (i.e. returns EOK).
     323 *
     324 * @param[in] fun Device function the action was invoked on.
     325 * @param[in] target Target pipe (address and endpoint number) specification.
     326 * @param[in] max_packet_size Max packet size for the transfer.
     327 * @param[in] data Buffer where to store the data (in USB endianess,
     328 *      allocated and deallocated by the caller).
     329 * @param[in] size Size of the @p data buffer in bytes.
     330 * @param[in] callback Callback to be issued once the transfer is complete.
     331 * @param[in] arg Pass-through argument to the callback.
    345332 * @return Error code.
    346333 */
     
    349336    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    350337{
    351         usb_transfer_batch_t *batch = NULL;
    352         hc_t *hc = NULL;
    353         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    354             NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
    355         if (ret != EOK)
    356                 return ret;
     338        assert(fun);
     339        hc_t *hc = fun_to_hc(fun);
     340        assert(hc);
     341        usb_speed_t speed =
     342            usb_device_keeper_get_speed(&hc->manager, target.address);
     343        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     344            target.address, target.endpoint, size, max_packet_size);
     345
     346        usb_transfer_batch_t *batch =
     347            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     348                data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     349        if (!batch)
     350                return ENOMEM;
    357351        batch_bulk_in(batch);
    358         ret = hc_schedule(hc, batch);
    359         if (ret != EOK) {
    360                 batch_dispose(batch);
    361         }
    362         return ret;
    363 }
    364 /*----------------------------------------------------------------------------*/
    365 /** Control write transaction interface function
    366  *
    367  * @param[in] fun DDF function that was called.
    368  * @param[in] target USB device to write to.
    369  * @param[in] max_packet_size maximum size of data packet the device accepts.
    370  * @param[in] setup_data Data to send with SETUP transfer.
    371  * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
    372  * @param[in] data Source of data.
    373  * @param[in] size Size of data source.
    374  * @param[in] callback Function to call on transaction completion.
    375  * @param[in] arg Additional for callback function.
     352        const int ret = hc_schedule(hc, batch);
     353        if (ret != EOK) {
     354                batch_dispose(batch);
     355        }
     356        return ret;
     357}
     358/*----------------------------------------------------------------------------*/
     359/** Schedule control write transfer.
     360 *
     361 * The callback is supposed to be called once the transfer (on the wire) is
     362 * complete regardless of the outcome.
     363 * However, the callback could be called only when this function returns
     364 * with success status (i.e. returns EOK).
     365 *
     366 * @param[in] fun Device function the action was invoked on.
     367 * @param[in] target Target pipe (address and endpoint number) specification.
     368 * @param[in] max_packet_size Max packet size for the transfer.
     369 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
     370 *      and deallocated by the caller).
     371 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
     372 * @param[in] data_buffer Data buffer (in USB endianess, allocated and
     373 *      deallocated by the caller).
     374 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
     375 * @param[in] callback Callback to be issued once the transfer is complete.
     376 * @param[in] arg Pass-through argument to the callback.
    376377 * @return Error code.
    377378 */
     
    381382    usbhc_iface_transfer_out_callback_t callback, void *arg)
    382383{
    383         usb_transfer_batch_t *batch = NULL;
    384         hc_t *hc = NULL;
    385         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    386             setup_data, setup_size, NULL, callback, arg, "Control WRITE",
    387             &hc, &batch);
    388         if (ret != EOK)
    389                 return ret;
     384        assert(fun);
     385        hc_t *hc = fun_to_hc(fun);
     386        assert(hc);
     387        usb_speed_t speed =
     388            usb_device_keeper_get_speed(&hc->manager, target.address);
     389        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
     390            speed, target.address, target.endpoint, size, max_packet_size);
     391
     392        if (setup_size != 8)
     393                return EINVAL;
     394
     395        usb_transfer_batch_t *batch =
     396            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     397                speed, data, size, setup_data, setup_size, NULL, callback, arg,
     398                &hc->manager);
     399        if (!batch)
     400                return ENOMEM;
    390401        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    391402        batch_control_write(batch);
    392         ret = hc_schedule(hc, batch);
    393         if (ret != EOK) {
    394                 batch_dispose(batch);
    395         }
    396         return ret;
    397 }
    398 /*----------------------------------------------------------------------------*/
    399 /** Control read transaction interface function
    400  *
    401  * @param[in] fun DDF function that was called.
    402  * @param[in] target USB device to write to.
    403  * @param[in] max_packet_size maximum size of data packet the device accepts.
    404  * @param[in] setup_data Data to send with SETUP packet.
    405  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
    406  * @param[out] data Source of data.
    407  * @param[in] size Size of data source.
    408  * @param[in] callback Function to call on transaction completion.
    409  * @param[in] arg Additional for callback function.
     403        const int ret = hc_schedule(hc, batch);
     404        if (ret != EOK) {
     405                batch_dispose(batch);
     406        }
     407        return ret;
     408}
     409/*----------------------------------------------------------------------------*/
     410/** Schedule control read transfer.
     411 *
     412 * The callback is supposed to be called once the transfer (on the wire) is
     413 * complete regardless of the outcome.
     414 * However, the callback could be called only when this function returns
     415 * with success status (i.e. returns EOK).
     416 *
     417 * @param[in] fun Device function the action was invoked on.
     418 * @param[in] target Target pipe (address and endpoint number) specification.
     419 * @param[in] max_packet_size Max packet size for the transfer.
     420 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
     421 *      and deallocated by the caller).
     422 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
     423 * @param[in] data_buffer Buffer where to store the data (in USB endianess,
     424 *      allocated and deallocated by the caller).
     425 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
     426 * @param[in] callback Callback to be issued once the transfer is complete.
     427 * @param[in] arg Pass-through argument to the callback.
    410428 * @return Error code.
    411429 */
     
    415433    usbhc_iface_transfer_in_callback_t callback, void *arg)
    416434{
    417         usb_transfer_batch_t *batch = NULL;
    418         hc_t *hc = NULL;
    419         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    420             setup_data, setup_size, callback, NULL, arg, "Control READ",
    421             &hc, &batch);
    422         if (ret != EOK)
    423                 return ret;
     435        assert(fun);
     436        hc_t *hc = fun_to_hc(fun);
     437        assert(hc);
     438        usb_speed_t speed =
     439            usb_device_keeper_get_speed(&hc->manager, target.address);
     440
     441        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
     442            speed, target.address, target.endpoint, size, max_packet_size);
     443        usb_transfer_batch_t *batch =
     444            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     445                speed, data, size, setup_data, setup_size, callback, NULL, arg,
     446                &hc->manager);
     447        if (!batch)
     448                return ENOMEM;
    424449        batch_control_read(batch);
    425         ret = hc_schedule(hc, batch);
    426         if (ret != EOK) {
    427                 batch_dispose(batch);
    428         }
    429         return ret;
    430 }
    431 /*----------------------------------------------------------------------------*/
     450        const int ret = hc_schedule(hc, batch);
     451        if (ret != EOK) {
     452                batch_dispose(batch);
     453        }
     454        return ret;
     455}
     456/*----------------------------------------------------------------------------*/
     457/** Host controller interface implementation for OHCI. */
    432458usbhc_iface_t hc_iface = {
    433459        .reserve_default_address = reserve_default_address,
     
    449475        .control_read = control_read,
    450476};
     477
    451478/**
    452479 * @}
  • uspace/drv/ohci/ohci_regs.h

    r8e8b84f r61727bf  
    4141        const volatile uint32_t revision;
    4242        volatile uint32_t control;
    43 #define C_CSBR_MASK (0x3) /* Control-bulk service ratio */
    44 #define C_CSBR_1_1  (0x0)
    45 #define C_CSBR_1_2  (0x1)
    46 #define C_CSBR_1_3  (0x2)
    47 #define C_CSBR_1_4  (0x3)
     43#define C_CSBR_MASK (0x3)
    4844#define C_CSBR_SHIFT (0)
     45#define C_PLE (1 << 2)
     46#define C_IE (1 << 3)
     47#define C_CLE (1 << 4)
     48#define C_BLE (1 << 5)
    4949
    50 #define C_PLE (1 << 2)   /* Periodic list enable */
    51 #define C_IE  (1 << 3)   /* Isochronous enable */
    52 #define C_CLE (1 << 4)   /* Control list enable */
    53 #define C_BLE (1 << 5)   /* Bulk list enable */
     50#define C_HCFS_MASK (0x3)
     51#define C_HCFS_SHIFT (6)
     52#define C_HCFS_RESET (0x0)
     53#define C_HCFS_OPERATIONAL (0x1)
     54#define C_HCFS_RESUME (0x2)
     55#define C_HCFS_SUSPEND (0x3)
    5456
    55 #define C_HCFS_MASK        (0x3) /* Host controller functional state */
    56 #define C_HCFS_RESET       (0x0)
    57 #define C_HCFS_OPERATIONAL (0x1)
    58 #define C_HCFS_RESUME      (0x2)
    59 #define C_HCFS_SUSPEND     (0x3)
    60 #define C_HCFS_SHIFT       (6)
    61 
    62 #define C_IR  (1 << 8)   /* Interrupt routing, make sure it's 0 */
    63 #define C_RWC (1 << 9)   /* Remote wakeup connected, host specific */
    64 #define C_RWE (1 << 10)  /* Remote wakeup enable */
     57#define C_IR (1 << 8)
     58#define C_RWC (1 << 9)
     59#define C_RWE (1 << 10)
    6560
    6661        volatile uint32_t command_status;
    67 #define CS_HCR (1 << 0)   /* Host controller reset */
    68 #define CS_CLF (1 << 1)   /* Control list filled */
    69 #define CS_BLF (1 << 2)   /* Bulk list filled */
    70 #define CS_OCR (1 << 3)   /* Ownership change request */
    71 #define CS_SOC_MASK (0x3) /* Scheduling overrun count */
     62#define CS_HCR (1 << 0)
     63#define CS_CLF (1 << 1)
     64#define CS_BLF (1 << 2)
     65#define CS_OCR (1 << 3)
     66#define CS_SOC_MASK (0x3)
    7267#define CS_SOC_SHIFT (16)
    7368
    7469        volatile uint32_t interrupt_status;
    75 #define IS_SO   (1 << 0)  /* Scheduling overrun */
    76 #define IS_WDH  (1 << 1)  /* Write-back done head */
    77 #define IS_SF   (1 << 2)  /* Start of frame */
    78 #define IS_RD   (1 << 3)  /* Resume detected */
    79 #define IS_UE   (1 << 4)  /* Unrecoverable error */
    80 #define IS_FNO  (1 << 5)  /* Frame number overflow */
    81 #define IS_RHSC (1 << 6)  /* Root hub status change */
    82 #define IS_OC   (1 << 30) /* Ownership change */
     70#define IS_SO (1 << 0)
     71#define IS_WDH (1 << 1)
     72#define IS_SF (1 << 2)
     73#define IS_RD (1 << 3)
     74#define IS_UE (1 << 4)
     75#define IS_FNO (1 << 5)
     76#define IS_RHSC (1 << 6)
     77#define IS_OC (1 << 30)
    8378
    84         /** Interupt enable/disable, reads give the same value, writing causes
    85          * enable/disable */
    8679        volatile uint32_t interupt_enable;
     80#define IE_SO   (1 << 0)
     81#define IE_WDH  (1 << 1)
     82#define IE_SF   (1 << 2)
     83#define IE_RD   (1 << 3)
     84#define IE_UE   (1 << 4)
     85#define IE_FNO  (1 << 5)
     86#define IE_RHSC (1 << 6)
     87#define IE_OC   (1 << 30)
     88#define IE_MIE  (1 << 31)
     89
    8790        volatile uint32_t interrupt_disable;
    88 #define I_SO   (1 << 0)   /* Scheduling overrun */
    89 #define I_WDH  (1 << 1)   /* Done head write-back */
    90 #define I_SF   (1 << 2)   /* Start of frame */
    91 #define I_RD   (1 << 3)   /* Resume detect */
    92 #define I_UE   (1 << 4)   /* Unrecoverable error */
    93 #define I_FNO  (1 << 5)   /* Frame number overflow */
    94 #define I_RHSC (1 << 6)   /* Root hub status change */
    95 #define I_OC   (1 << 30)  /* Ownership change */
    96 #define I_MI   (1 << 31)  /* Master interrupt (all/any interrupts) */
    97 
    98         /** HCCA pointer (see hw_struct hcca.h) */
    9991        volatile uint32_t hcca;
    100 #define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */
    101 
    102         /** Currently executed period endpoint */
    103         const volatile uint32_t period_current;
    104 
    105         /** The first control endpoint */
     92        volatile uint32_t period_corrent;
    10693        volatile uint32_t control_head;
    107 
    108         /** Currently executed control endpoint */
    10994        volatile uint32_t control_current;
    110 
    111         /** The first bulk endpoint */
    11295        volatile uint32_t bulk_head;
    113 
    114         /** Currently executed bulk endpoint */
    11596        volatile uint32_t bulk_current;
    116 
    117         /** Done TD list, this value is periodically written to HCCA */
    118         const volatile uint32_t done_head;
    119 
    120         /** Frame time and max packet size for all transfers */
     97        volatile uint32_t done_head;
    12198        volatile uint32_t fm_interval;
    122 #define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/
    123 #define FMI_FI_SHIFT (0)
    124 #define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */
    125 #define FMI_FSMPS_SHIFT (16)
    126 #define FMI_TOGGLE_FLAG (1 << 31)
    127 
    128         /** Bit times remaining in current frame */
    129         const volatile uint32_t fm_remaining;
    130 #define FMR_FR_MASK FMI_FI_MASK
    131 #define FMR_FR_SHIFT FMI_FI_SHIFT
    132 #define FMR_TOGGLE_FLAG FMI_TOGGLE_FLAG
    133 
    134         /** Frame number */
    135         const volatile uint32_t fm_number;
    136 #define FMN_NUMBER_MASK (0xffff)
    137 
    138         /** Remaining bit time in frame to start periodic transfers */
     99        volatile uint32_t fm_remaining;
     100        volatile uint32_t fm_number;
    139101        volatile uint32_t periodic_start;
    140 #define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */
    141 
    142         /** Threshold for starting LS transaction */
    143102        volatile uint32_t ls_threshold;
    144 #define LST_LST_MASK (0x7fff)
    145 
    146         /** The first root hub control register */
    147103        volatile uint32_t rh_desc_a;
    148 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */
    149 #define RHDA_NDS_SHIFT (0)
    150 #define RHDA_PSM_FLAG  (1 << 8)  /* Power switching mode: 0-global, 1-per port*/
    151 #define RHDA_NPS_FLAG  (1 << 9)  /* No power switch: 1-power on, 0-use PSM*/
    152 #define RHDA_DT_FLAG   (1 << 10) /* 1-Compound device, must be 0 */
    153 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */
    154 #define RHDA_NOCP      (1 << 12) /* OC control: 0-use OCPM, 1-OC off */
    155 #define RHDA_POTPGT_MASK (0xff)  /* Power on to power good time */
    156 #define RHDA_POTPGT_SHIFT (24)
    157 
    158         /** The other root hub control register */
    159104        volatile uint32_t rh_desc_b;
    160 #define RHDB_DR_MASK (0xffff) /* Device removable mask */
    161 #define RHDB_DR_SHIFT (0)
    162 #define RHDB_PCC_MASK (0xffff) /* Power control mask */
    163 #define RHDB_PCC_SHIFT (16)
    164 
    165 /* Port device removable status */
    166 #define RHDB_DR_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
    167 /* Port power control status: 1-per port power control, 0-global power switch */
    168 #define RHDB_PPC_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
    169 
    170         /** Root hub status register */
    171105        volatile uint32_t rh_status;
    172 #define RHS_LPS_FLAG  (1 <<  0)/* read: 0,
    173                                 * write: 0-no effect,
    174                                 *        1-turn off port power for ports
    175                                 *        specified in PPCM(RHDB), or all ports,
    176                                 *        if power is set globally */
    177 #define RHS_CLEAR_PORT_POWER RHS_LPS_FLAG /* synonym for the above */
    178 #define RHS_OCI_FLAG  (1 <<  1)/* Over-current indicator, if per-port: 0 */
    179 #define RHS_DRWE_FLAG (1 << 15)/* read: 0-connect status change does not wake HC
    180                                 *       1-connect status change wakes HC
    181                                 * write: 1-set DRWE, 0-no effect */
    182 #define RHS_SET_DRWE RHS_DRWE_FLAG
    183 #define RHS_LPSC_FLAG (1 << 16)/* read: 0,
    184                                 * write: 0-no effect
    185                                 *        1-turn on port power for ports
    186                                 *        specified in PPCM(RHDB), or all ports,
    187                                 *        if power is set globally */
    188 #define RHS_SET_PORT_POWER RHS_LPSC_FLAG /* synonym for the above */
    189 #define RHS_OCIC_FLAG (1 << 17)/* Over-current indicator change   */
    190 #define RHS_CLEAR_DRWE (1 << 31)
    191 
    192         /** Root hub per port status */
    193106        volatile uint32_t rh_port_status[];
    194 #define RHPS_CCS_FLAG (1 << 0) /* r: current connect status,
    195                                 * w: 1-clear port enable, 0-nothing */
    196 #define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG
    197 #define RHPS_PES_FLAG (1 << 1) /* r: port enable status
    198                                 * w: 1-set port enable, 0-nothing */
    199 #define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG
    200 #define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status
    201                                 * w: 1-set port suspend, 0-nothing */
    202 #define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG
    203 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current (if reports are per-port
    204                                  * w: 1-clear port suspend (start resume
    205                                  *      if suspened)
    206                                  *    0-nothing */
    207 #define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG
    208 #define RHPS_PRS_FLAG (1 << 4) /* r: port reset status
    209                                 * w: 1-set port reset, 0-nothing */
    210 #define RHPS_SET_PORT_RESET RHPS_PRS_FLAG
    211 #define RHPS_PPS_FLAG (1 << 8) /* r: port power status
    212                                 * w: 1-set port power, 0-nothing */
    213 #define RHPS_SET_PORT_POWER RHPS_PPS_FLAG
    214 #define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached
    215                                  * w: 1-clear port power, 0-nothing */
    216 #define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG
    217 #define RHPS_CSC_FLAG  (1 << 16) /* connect status change Write-Clean */
    218 #define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */
    219 #define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */
    220 #define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */
    221 #define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */
    222 #define RHPS_CHANGE_WC_MASK 0x1f0000
    223107} __attribute__((packed)) ohci_regs_t;
    224108#endif
  • uspace/drv/ohci/utils/malloc32.h

    r8e8b84f r61727bf  
    3737#include <assert.h>
    3838#include <malloc.h>
    39 #include <errno.h>
    4039#include <mem.h>
    4140#include <as.h>
  • uspace/drv/uhci-hcd/batch.c

    r8e8b84f r61727bf  
    103103        usb_target_t target =
    104104            { .address = ep->address, .endpoint = ep->endpoint };
    105         usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
    106             ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
    107             func_in, func_out, arg, fun, ep, NULL);
     105        usb_transfer_batch_init(instance, target,
     106            ep->transfer_type, ep->speed, ep->max_packet_size,
     107            buffer, NULL, buffer_size, NULL, setup_size, func_in,
     108            func_out, arg, fun, ep, NULL);
    108109
    109110
    110111        uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
    111         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
     112        CHECK_NULL_DISPOSE_RETURN(instance,
     113            "Failed to allocate batch instance.\n");
    112114        bzero(data, sizeof(uhci_batch_t));
    113115        instance->private_data = data;
  • uspace/drv/uhci-hcd/hc.c

    r8e8b84f r61727bf  
    240240        usb_log_debug("Initialized device manager.\n");
    241241
    242         ret = usb_endpoint_manager_init(&instance->ep_manager,
    243             BANDWIDTH_AVAILABLE_USB11);
     242        ret =
     243            usb_endpoint_manager_init(&instance->ep_manager,
     244                BANDWIDTH_AVAILABLE_USB11);
    244245        assert(ret == EOK);
    245246
  • uspace/drv/uhci-hcd/iface.c

    r8e8b84f r61727bf  
    206206        const usb_speed_t speed =
    207207            usb_device_keeper_get_speed(&hc->manager, address);
    208         const size_t size = max_packet_size;
     208        const size_t size =
     209            (transfer_type == USB_TRANSFER_INTERRUPT
     210            || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
     211            max_packet_size : 0;
    209212        int ret;
    210213
  • uspace/lib/usb/src/host/batch.c

    r8e8b84f r61727bf  
    6363        instance->transfer_type = transfer_type;
    6464        instance->speed = speed;
    65         instance->direction = ep->direction;
     65        instance->direction = USB_DIRECTION_BOTH;
    6666        instance->callback_in = func_in;
    6767        instance->callback_out = func_out;
Note: See TracChangeset for help on using the changeset viewer.