Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset dbf32b1 in mainline


Ignore:
Timestamp:
2017-10-17T10:09:40Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
95c675b
Parents:
bb784ae
Message:

xhci: cleanup

And by the way… the USB mouse is now working :)

Location:
uspace/drv/bus/usb/xhci
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/endpoint.c

    rbb784ae rdbf32b1  
    8181}
    8282
    83 uint8_t xhci_endpoint_ctx_offset(xhci_endpoint_t *ep)
    84 {
    85         /* 0 is slot ctx, 1 is EP0, then it's EP1 out, in, EP2 out, in, etc. */
    86 
    87         uint8_t off = 2 * (ep->base.target.endpoint);
    88         if (ep->base.direction == USB_DIRECTION_IN || ep->base.target.endpoint == 0)
    89                 ++off;
    90 
    91         return off;
     83/** Return an index to the endpoint array. The indices are assigned as follows:
     84 * 0    EP0 BOTH
     85 * 1    EP1 OUT
     86 * 2    EP1 IN
     87 *
     88 * For control endpoints >0, the IN endpoint index is used.
     89 *
     90 * The index returned must be usually offset by a number of contexts preceding
     91 * the endpoint contexts themselves.
     92 */
     93uint8_t xhci_endpoint_index(xhci_endpoint_t *ep)
     94{
     95        return  (2 * ep->base.target.endpoint)
     96            - (ep->base.direction == USB_DIRECTION_OUT);
    9297}
    9398
     
    211216                XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);
    212217
    213                 const uint8_t ep_offset = xhci_endpoint_ctx_offset(ep);
    214                 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_offset);
     218                const uint8_t ep_idx = xhci_endpoint_index(ep);
     219                XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */
    215220
    216221                ep_ring = malloc(sizeof(xhci_trb_ring_t));
     
    227232                switch (ep->base.transfer_type) {
    228233                case USB_TRANSFER_CONTROL:
    229                         setup_control_ep_ctx(ep, &ictx->endpoint_ctx[ep_offset - 1], ep_ring);
     234                        setup_control_ep_ctx(ep, &ictx->endpoint_ctx[ep_idx], ep_ring);
    230235                        break;
    231236
    232237                case USB_TRANSFER_BULK:
    233                         setup_bulk_ep_ctx(ep, &ictx->endpoint_ctx[ep_offset - 1], ep_ring, &ss_desc);
     238                        setup_bulk_ep_ctx(ep, &ictx->endpoint_ctx[ep_idx], ep_ring, &ss_desc);
    234239                        break;
    235240
    236241                case USB_TRANSFER_ISOCHRONOUS:
    237                         setup_isoch_ep_ctx(ep, &ictx->endpoint_ctx[ep_offset - 1], ep_ring, &ss_desc);
     242                        setup_isoch_ep_ctx(ep, &ictx->endpoint_ctx[ep_idx], ep_ring, &ss_desc);
    238243                        break;
    239244
    240245                case USB_TRANSFER_INTERRUPT:
    241                         setup_interrupt_ep_ctx(ep, &ictx->endpoint_ctx[ep_offset - 1], ep_ring, &ss_desc);
     246                        setup_interrupt_ep_ctx(ep, &ictx->endpoint_ctx[ep_idx], ep_ring, &ss_desc);
    242247                        break;
    243248
  • uspace/drv/bus/usb/xhci/endpoint.h

    rbb784ae rdbf32b1  
    9797void xhci_device_fini(xhci_device_t *);
    9898
    99 uint8_t xhci_endpoint_ctx_offset(xhci_endpoint_t *);
     99uint8_t xhci_endpoint_index(xhci_endpoint_t *);
    100100
    101101int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);
  • uspace/drv/bus/usb/xhci/hc.c

    rbb784ae rdbf32b1  
    634634        uint32_t v = host2xhci(32, target & BIT_RRANGE(uint32_t, 7));
    635635        pio_write_32(&hc->db_arry[doorbell], v);
     636        usb_log_debug("Ringing doorbell %d, target = %d", doorbell, target);
    636637        return EOK;
    637638}
  • uspace/drv/bus/usb/xhci/transfers.c

    rbb784ae rdbf32b1  
    4343#include "trb_ring.h"
    4444
    45 static inline uint8_t get_transfer_type(xhci_trb_t* trb, uint8_t bmRequestType, uint16_t wLength)
     45typedef enum {
     46    STAGE_OUT,
     47    STAGE_IN,
     48} stage_dir_flag_t;
     49
     50#define REQUEST_TYPE_DTD (0x80)
     51#define REQUEST_TYPE_IS_DEVICE_TO_HOST(rq) ((rq) & REQUEST_TYPE_DTD)
     52
     53
     54/** Get direction flag of data stage.
     55 *  See Table 7 of xHCI specification.
     56 */
     57static inline stage_dir_flag_t get_status_direction_flag(xhci_trb_t* trb,
     58        uint8_t bmRequestType, uint16_t wLength)
    4659{
    4760        /* See Table 7 of xHCI specification */
    48         if (bmRequestType & 0x80) {
    49                 /* Device-to-host transfer */
    50                 if (wLength) {
    51                         /* IN data stage */
    52                         return 3;
    53                 }
    54                 else {
    55                         /* No data stage */
    56                         return 0;
    57                 }
    58         }
    59         else {
    60                 /* Host-to-device transfer */
    61                 if (wLength) {
    62                         /* OUT data stage */
    63                         return 2;
    64                 }
    65                 else {
    66                         /* No data stage */
    67                         return 0;
    68                 }
    69         }
    70 }
    71 
    72 static inline uint8_t get_data_direction(xhci_trb_t* trb, uint8_t bmRequestType, uint16_t wLength)
    73 {
     61        return REQUEST_TYPE_IS_DEVICE_TO_HOST(bmRequestType) && (wLength > 0)
     62                ? STAGE_OUT
     63                : STAGE_IN;
     64}
     65
     66typedef enum {
     67    DATA_STAGE_NO = 0,
     68    DATA_STAGE_OUT = 2,
     69    DATA_STAGE_IN = 3,
     70} data_stage_type_t;
     71
     72/** Get transfer type flag.
     73 *  See Table 8 of xHCI specification.
     74 */
     75static inline data_stage_type_t get_transfer_type(xhci_trb_t* trb, uint8_t
     76        bmRequestType, uint16_t wLength)
     77{
     78        if (wLength == 0)
     79                return DATA_STAGE_NO;
     80
    7481        /* See Table 7 of xHCI specification */
    75         if (bmRequestType & 0x80) {
    76                 /* Device-to-host transfer */
    77                 return 1;
    78         }
    79         else {
    80                 /* Host-to-device transfer */
    81                 return 0;
    82         }
    83 }
    84 
    85 static inline uint8_t get_status_direction(xhci_trb_t* trb, uint8_t bmRequestType, uint16_t wLength)
    86 {
    87         /* See Table 7 of xHCI specification */
    88         if (bmRequestType & 0x80) {
    89                 /* Device-to-host transfer */
    90                 if (wLength) {
    91                         /* Out direction */
    92                         return 0;
    93                 }
    94                 else {
    95                         /* In direction */
    96                         return 1;
    97                 }
    98         }
    99         else {
    100                 /* Host-to-device transfer, always IN direction */
    101                 return 1;
    102         }
     82        return REQUEST_TYPE_IS_DEVICE_TO_HOST(bmRequestType)
     83                ? DATA_STAGE_IN
     84                : DATA_STAGE_NO;
    10385}
    10486
     
    10789        usb_request_type_t request_type = SETUP_REQUEST_TYPE_GET_TYPE(setup->request_type);
    10890
    109         if (request_type == USB_REQUEST_TYPE_STANDARD) {
    110                 usb_stddevreq_t request = setup->request;
    111 
    112                 switch (request) {
    113                 case USB_DEVREQ_SET_CONFIGURATION:
    114                 case USB_DEVREQ_SET_INTERFACE:
    115                         return true;
    116 
    117                 default:
    118                         return false;
    119                 }
    120         }
    121 
    122         return false;
     91        return request_type == USB_REQUEST_TYPE_STANDARD &&
     92                (setup->request == USB_DEVREQ_SET_CONFIGURATION
     93                || setup->request == USB_DEVREQ_SET_INTERFACE);
    12394}
    12495
     
    190161
    191162        xhci_trb_t trb_setup;
    192         memset(&trb_setup, 0, sizeof(xhci_trb_t));
     163        xhci_trb_clean(&trb_setup);
    193164
    194165        TRB_CTRL_SET_SETUP_WVALUE(trb_setup, setup->value);
     
    210181        /* Data stage */
    211182        xhci_trb_t trb_data;
    212         memset(&trb_data, 0, sizeof(xhci_trb_t));
     183        xhci_trb_clean(&trb_data);
    213184
    214185        if (setup->length > 0) {
     
    226197                TRB_CTRL_SET_TRB_TYPE(trb_data, XHCI_TRB_TYPE_DATA_STAGE);
    227198
    228                 transfer->direction = get_data_direction(&trb_setup, setup->request_type, setup->length);
     199                transfer->direction = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type)
     200                                        ? STAGE_IN : STAGE_OUT;
    229201                TRB_CTRL_SET_DIR(trb_data, transfer->direction);
    230202        }
     
    232204        /* Status stage */
    233205        xhci_trb_t trb_status;
    234         memset(&trb_status, 0, sizeof(xhci_trb_t));
     206        xhci_trb_clean(&trb_status);
    235207
    236208        // FIXME: Evaluate next TRB? 4.12.3
     
    241213
    242214        TRB_CTRL_SET_TRB_TYPE(trb_status, XHCI_TRB_TYPE_STATUS_STAGE);
    243         TRB_CTRL_SET_DIR(trb_status, get_status_direction(&trb_setup, setup->request_type, setup->length));
     215        TRB_CTRL_SET_DIR(trb_status, get_status_direction_flag(&trb_setup, setup->request_type, setup->length));
    244216
    245217        uintptr_t dummy = 0;
     
    251223
    252224        list_append(&transfer->link, &hc->transfers);
    253 
    254         /* For control transfers, the target is always 1. */
    255         // FIXME: ignoring return code
    256         const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
    257         hc_ring_doorbell(hc, slot_id, target);
    258225
    259226        // Issue a Configure Endpoint command, if needed.
     
    264231        }
    265232
    266         return EOK;
     233        const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbels start at 1 */
     234        return hc_ring_doorbell(hc, slot_id, target);
    267235}
    268236
     
    284252
    285253        xhci_trb_t trb;
    286         memset(&trb, 0, sizeof(xhci_trb_t));
     254        xhci_trb_clean(&trb);
    287255        trb.parameter = addr_to_phys(transfer->hc_buffer);
    288256
     
    301269
    302270        // TODO: target = endpoint | stream_id << 16
    303         const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
    304         hc_ring_doorbell(hc, slot_id, target);
    305         return EOK;
     271        const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
     272        return hc_ring_doorbell(hc, slot_id, target);
    306273}
    307274
     
    323290
    324291        xhci_trb_t trb;
    325         memset(&trb, 0, sizeof(xhci_trb_t));
     292        xhci_trb_clean(&trb);
    326293        trb.parameter = addr_to_phys(transfer->hc_buffer);
    327294
     
    339306        list_append(&transfer->link, &hc->transfers);
    340307
    341         const uint8_t target = xhci_endpoint_ctx_offset(xhci_ep);
    342         usb_log_debug("Ringing doorbell for slot_id = %d, target = %d", slot_id, target);
     308        const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
    343309        return hc_ring_doorbell(hc, slot_id, target);
    344310}
     
    367333        usb_transfer_batch_t *batch = transfer->batch;
    368334
    369         batch->error = (TRB_COMPLETION_CODE(*trb) == XHCI_TRBC_SUCCESS) ? EOK : ENAK;
    370         batch->transfered_size = batch->buffer_size - TRB_TRANSFER_LENGTH(*trb);
    371         if (transfer->direction) {
    372                 memcpy(batch->buffer, transfer->hc_buffer, batch->buffer_size);
    373 
    374                 /* Device-to-host, IN */
    375                 if (batch->callback_in)
    376                         batch->callback_in(batch->error, batch->transfered_size, batch->arg);
    377         }
    378         else {
    379                 /* Host-to-device, OUT */
    380                 if (batch->callback_out)
    381                         batch->callback_out(batch->error, batch->arg);
    382         }
    383 
     335        const int err = (TRB_COMPLETION_CODE(*trb) == XHCI_TRBC_SUCCESS) ? EOK : ENAK;
     336        const size_t size = batch->buffer_size - TRB_TRANSFER_LENGTH(*trb);
     337        usb_transfer_batch_finish_error(batch, transfer->hc_buffer, size, err);
    384338        xhci_transfer_fini(transfer);
    385339        return EOK;
Note: See TracChangeset for help on using the changeset viewer.