Changeset d4beec3 in mainline


Ignore:
Timestamp:
2011-03-06T19:01:09Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
960bee9, c867a216
Parents:
24d5432 (diff), 8a20380 (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:

Fix toggle protocol implementation

Location:
uspace/drv/uhci-hcd
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/batch.c

    r24d5432 rd4beec3  
    5454static void batch_call_in_and_dispose(batch_t *instance);
    5555static void batch_call_out_and_dispose(batch_t *instance);
     56static void batch_dispose(batch_t *instance);
    5657
    5758
     
    6162    char* setup_buffer, size_t setup_size,
    6263    usbhc_iface_transfer_in_callback_t func_in,
    63     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     64    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     65    device_keeper_t *manager
     66    )
    6467{
    6568        assert(func_in == NULL || func_out == NULL);
     
    137140        instance->arg = arg;
    138141        instance->speed = speed;
     142        instance->manager = manager;
    139143
    140144        queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
     
    160164                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    161165                            instance, i, instance->tds[i].status);
     166
     167                        device_keeper_set_toggle(instance->manager, instance->target,
     168                            td_toggle(&instance->tds[i]));
    162169                        if (i > 0)
    163170                                goto substract_ret;
     
    232239}
    233240/*----------------------------------------------------------------------------*/
    234 static void batch_data(batch_t *instance, usb_packet_id pid)
     241void batch_data(batch_t *instance, usb_packet_id pid)
    235242{
    236243        assert(instance);
    237244        const bool low_speed = instance->speed == USB_SPEED_LOW;
    238         int toggle = 1;
     245        int toggle = device_keeper_get_toggle(instance->manager, instance->target);
     246        assert(toggle == 0 || toggle == 1);
    239247
    240248        size_t packet = 0;
     
    245253                    - remain_size;
    246254
    247                 toggle = 1 - toggle;
    248255
    249256                const size_t packet_size =
     
    256263                    &instance->tds[packet + 1]);
    257264
     265                toggle = 1 - toggle;
    258266                ++packet;
    259267                assert(packet <= instance->packets);
     
    261269                remain_size -= packet_size;
    262270        }
     271        device_keeper_set_toggle(instance->manager, instance->target, toggle);
    263272
    264273        instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     
    266275}
    267276/*----------------------------------------------------------------------------*/
    268 static void batch_control(batch_t *instance,
     277void batch_control(batch_t *instance,
    269278   usb_packet_id data_stage, usb_packet_id status_stage)
    270279{
     
    347356        assert(instance);
    348357        batch_call_in(instance);
     358        batch_dispose(instance);
     359}
     360/*----------------------------------------------------------------------------*/
     361void batch_call_out_and_dispose(batch_t *instance)
     362{
     363        assert(instance);
     364        batch_call_out(instance);
     365        batch_dispose(instance);
     366}
     367/*----------------------------------------------------------------------------*/
     368void batch_dispose(batch_t *instance)
     369{
     370        assert(instance);
    349371        usb_log_debug("Batch(%p) disposing.\n", instance);
    350372        free32(instance->tds);
     
    355377}
    356378/*----------------------------------------------------------------------------*/
    357 void batch_call_out_and_dispose(batch_t *instance)
    358 {
    359         assert(instance);
    360         batch_call_out(instance);
    361         usb_log_debug("Batch(%p) disposing.\n", instance);
    362         free32(instance->tds);
    363         free32(instance->qh);
    364         free32(instance->setup_buffer);
    365         free32(instance->transport_buffer);
    366         free(instance);
    367 }
    368 /*----------------------------------------------------------------------------*/
    369379int batch_schedule(batch_t *instance)
    370380{
  • uspace/drv/uhci-hcd/batch.h

    r24d5432 rd4beec3  
    4242#include "uhci_struct/transfer_descriptor.h"
    4343#include "uhci_struct/queue_head.h"
     44#include "utils/device_keeper.h"
    4445
    4546typedef struct batch
     
    6768        td_t *tds;
    6869        void (*next_step)(struct batch*);
     70        device_keeper_t *manager;
    6971} batch_t;
    7072
     
    7476                char *setup_buffer, size_t setup_size,
    7577    usbhc_iface_transfer_in_callback_t func_in,
    76     usbhc_iface_transfer_out_callback_t func_out, void *arg);
     78    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     79                device_keeper_t *manager
     80                );
    7781
    7882bool batch_is_complete(batch_t *instance);
  • uspace/drv/uhci-hcd/iface.c

    r24d5432 rd4beec3  
    114114
    115115        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    116             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     116            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     117            &hc->device_manager);
    117118        if (!batch)
    118119                return ENOMEM;
     
    133134
    134135        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    135             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     136            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     137                        &hc->device_manager);
    136138        if (!batch)
    137139                return ENOMEM;
     
    153155
    154156        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    155             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     157            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     158            &hc->device_manager);
    156159        if (!batch)
    157160                return ENOMEM;
     
    172175
    173176        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    174             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     177            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     178            &hc->device_manager);
    175179        if (!batch)
    176180                return ENOMEM;
     
    191195            target.address, target.endpoint, size, max_packet_size);
    192196
     197        if (setup_size != 8)
     198                return EINVAL;
     199
    193200        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    194201            max_packet_size, speed, data, size, setup_data, setup_size,
    195             NULL, callback, arg);
    196         if (!batch)
    197                 return ENOMEM;
     202            NULL, callback, arg, &hc->device_manager);
     203        if (!batch)
     204                return ENOMEM;
     205        device_keeper_reset_if_need(&hc->device_manager, target, setup_data);
    198206        batch_control_write(batch);
    199207        return EOK;
     
    214222        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    215223            max_packet_size, speed, data, size, setup_data, setup_size, callback,
    216             NULL, arg);
     224            NULL, arg, &hc->device_manager);
    217225        if (!batch)
    218226                return ENOMEM;
  • uspace/drv/uhci-hcd/uhci.c

    r24d5432 rd4beec3  
    167167        /* reset hc, all states and counters */
    168168        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
    169         while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
    170                 { async_usleep(10); }
     169        do { async_usleep(10); }
     170        while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
    171171
    172172        /* set framelist pointer */
     
    175175
    176176        /* enable all interrupts, but resume interrupt */
    177         pio_write_16(&instance->registers->usbintr,
    178             UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    179 
     177//      pio_write_16(&instance->registers->usbintr,
     178//          UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     179
     180        uint16_t status = pio_read_16(&instance->registers->usbcmd);
     181        usb_log_warning("Previous command value: %x.\n", status);
    180182        /* Start the hc with large(64B) packet FSBR */
    181183        pio_write_16(&instance->registers->usbcmd,
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r24d5432 rd4beec3  
    7575            instance->next, instance->status, instance->device,
    7676            instance->buffer_ptr, buffer);
     77        if (pid == USB_PID_SETUP) {
     78                usb_log_debug("SETUP BUFFER: %s\n",
     79                        usb_debug_str_buffer(buffer, 8, 8));
     80        }
    7781}
    7882/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r24d5432 rd4beec3  
    115115}
    116116
     117static inline int td_toggle(td_t *instance)
     118{
     119        assert(instance);
     120        return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0)
     121            ? 1 : 0;
     122}
     123
    117124static inline bool td_is_active(td_t *instance)
    118125{
  • uspace/drv/uhci-hcd/utils/device_keeper.c

    r24d5432 rd4beec3  
    4949                instance->devices[i].occupied = false;
    5050                instance->devices[i].handle = 0;
     51                instance->devices[i].toggle_status = 0;
    5152        }
    5253}
     
    7374        fibril_mutex_unlock(&instance->guard);
    7475        fibril_condvar_signal(&instance->default_address_occupied);
     76}
     77/*----------------------------------------------------------------------------*/
     78void device_keeper_reset_if_need(
     79    device_keeper_t *instance, usb_target_t target, const unsigned char *data)
     80{
     81        assert(instance);
     82        fibril_mutex_lock(&instance->guard);
     83        if (target.endpoint > 15 || target.endpoint < 0
     84            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     85            || !instance->devices[target.address].occupied) {
     86                goto the_end;
     87        }
     88
     89        switch (data[1])
     90        {
     91        case 0x01: /*clear feature*/
     92                /* recipient is enpoint, value is zero (ENDPOINT_STALL) */
     93                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     94                        /* enpoint number is < 16, thus first byte is enough */
     95                        instance->devices[target.address].toggle_status &= ~(1 << data[4]);
     96                }
     97        break;
     98
     99        case 0x9: /* set configuration */
     100        case 0x11: /* set interface */
     101                instance->devices[target.address].toggle_status = 0;
     102        break;
     103        }
     104the_end:
     105        fibril_mutex_unlock(&instance->guard);
     106}
     107/*----------------------------------------------------------------------------*/
     108int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
     109{
     110        assert(instance);
     111        int ret;
     112        fibril_mutex_lock(&instance->guard);
     113        if (target.endpoint > 15 || target.endpoint < 0
     114            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     115            || !instance->devices[target.address].occupied) {
     116                ret = EINVAL;
     117        } else {
     118                ret = (instance->devices[target.address].toggle_status >> target.endpoint) & 1;
     119        }
     120        fibril_mutex_unlock(&instance->guard);
     121        return ret;
     122}
     123/*----------------------------------------------------------------------------*/
     124int device_keeper_set_toggle(
     125    device_keeper_t *instance, usb_target_t target, bool toggle)
     126{
     127        assert(instance);
     128        int ret;
     129        fibril_mutex_lock(&instance->guard);
     130        if (target.endpoint > 15 || target.endpoint < 0
     131            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     132            || !instance->devices[target.address].occupied) {
     133                ret = EINVAL;
     134        } else {
     135                if (toggle) {
     136                        instance->devices[target.address].toggle_status |= (1 << target.endpoint);
     137                } else {
     138                        instance->devices[target.address].toggle_status &= ~(1 << target.endpoint);
     139                }
     140                ret = EOK;
     141        }
     142        fibril_mutex_unlock(&instance->guard);
     143        return ret;
    75144}
    76145/*----------------------------------------------------------------------------*/
     
    96165        instance->devices[new_address].occupied = true;
    97166        instance->devices[new_address].speed = speed;
     167        instance->devices[new_address].toggle_status = 0;
    98168        instance->last_address = new_address;
    99169        fibril_mutex_unlock(&instance->guard);
  • uspace/drv/uhci-hcd/utils/device_keeper.h

    r24d5432 rd4beec3  
    4444        usb_speed_t speed;
    4545        bool occupied;
     46        uint16_t toggle_status;
    4647        devman_handle_t handle;
    4748};
     
    5556
    5657void device_keeper_init(device_keeper_t *instance);
     58
    5759void device_keeper_reserve_default(
    5860    device_keeper_t *instance, usb_speed_t speed);
     61
    5962void device_keeper_release_default(device_keeper_t *instance);
     63
     64void device_keeper_reset_if_need(
     65    device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data);
     66
     67int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target);
     68
     69int device_keeper_set_toggle(
     70    device_keeper_t *instance, usb_target_t target, bool toggle);
    6071
    6172usb_address_t device_keeper_request(
    6273    device_keeper_t *instance, usb_speed_t speed);
     74
    6375void device_keeper_bind(
    6476    device_keeper_t *instance, usb_address_t address, devman_handle_t handle);
     77
    6578void device_keeper_release(device_keeper_t *instance, usb_address_t address);
     79
    6680usb_address_t device_keeper_find(
    6781    device_keeper_t *instance, devman_handle_t handle);
Note: See TracChangeset for help on using the changeset viewer.