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

Changeset b724494 in mainline


Ignore:
Timestamp:
2017-10-23T21:26:22Z (4 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master
Children:
ec700c7
Parents:
327f147
Message:

Moved some code from RH to HC. Simplified device address process. Issuing deconfigure device command.

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

Legend:

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

    r327f147 rb724494  
    4646#define TRB_SET_TCS(trb, tcs)   (trb).control |= host2xhci(32, ((tcs &0x1) << 9))
    4747#define TRB_SET_TYPE(trb, type) (trb).control |= host2xhci(32, (type) << 10)
     48#define TRB_SET_DC(trb, dc)     (trb).control |= host2xhci(32, (dc) << 9)
    4849#define TRB_SET_EP(trb, ep)     (trb).control |= host2xhci(32, ((ep) & 0x5) << 16)
    4950#define TRB_SET_STREAM(trb, st) (trb).control |= host2xhci(32, ((st) & 0xFFFF) << 16)
     
    323324        assert(hc);
    324325        assert(cmd);
    325         assert(ictx);
    326 
    327         xhci_trb_clean(&cmd->trb);
    328 
    329         uint64_t phys_addr = (uint64_t) addr_to_phys(ictx);
    330         TRB_SET_ICTX(cmd->trb, phys_addr);
     326
     327        xhci_trb_clean(&cmd->trb);
     328
     329        if (!cmd->deconfigure) {
     330                /* If the DC flag is on, input context is not evaluated. */
     331                assert(ictx);
     332
     333                uint64_t phys_addr = (uint64_t) addr_to_phys(ictx);
     334                TRB_SET_ICTX(cmd->trb, phys_addr);
     335        }
    331336
    332337        TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_CONFIGURE_ENDPOINT_CMD);
    333338        TRB_SET_SLOT(cmd->trb, cmd->slot_id);
     339        TRB_SET_DC(cmd->trb, cmd->deconfigure);
    334340
    335341        return enqueue_command(hc, cmd, 0, 0);
  • uspace/drv/bus/usb/xhci/commands.h

    r327f147 rb724494  
    5858        uint32_t slot_id;
    5959        uint32_t status;
     60        bool deconfigure;
    6061
    6162        bool completed;
  • uspace/drv/bus/usb/xhci/endpoint.c

    r327f147 rb724494  
    242242};
    243243
    244 static int create_valid_input_ctx(xhci_input_ctx_t **out_ictx)
    245 {
    246         xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));
    247         if (!ictx) {
    248                 return ENOMEM;
    249         }
    250 
    251         memset(ictx, 0, sizeof(xhci_input_ctx_t));
    252 
    253         // Quoting sec. 4.6.6: A1, D0, D1 are down, A0 is up.
    254         XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ictx->ctrl_ctx, 1);
    255         XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 0);
    256         XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 1);
    257         XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);
    258 
    259         if (out_ictx) {
    260                 *out_ictx = ictx;
    261         }
    262 
    263         return EOK;
    264 }
    265 
    266244int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)
    267245{
     
    300278        }
    301279
    302         /* Issue configure endpoint command (sec 4.3.5). */
    303         xhci_input_ctx_t *ictx;
    304         if ((err = create_valid_input_ctx(&ictx))) {
     280        /* Add endpoint. */
     281        xhci_ep_ctx_t ep_ctx;
     282        memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t));
     283        setup_ep_ctx_helpers[ep->base.transfer_type](ep, &ep_ctx);
     284
     285        if ((err = hc_add_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx))) {
    305286                goto err_ds;
    306287        }
    307288
    308         const unsigned ep_idx = xhci_endpoint_index(ep);
    309         XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */
    310         setup_ep_ctx_helpers[ep->base.transfer_type](ep, &ictx->endpoint_ctx[ep_idx]);
    311 
    312         xhci_cmd_t cmd;
    313         xhci_cmd_init(&cmd);
    314 
    315         cmd.slot_id = dev->slot_id;
    316 
    317         if ((err = xhci_send_configure_endpoint_command(dev->hc, &cmd, ictx))) {
    318                 goto err_ictx;
    319         }
    320 
    321         if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
    322                 goto err_ictx;
    323         }
    324 
    325         xhci_cmd_fini(&cmd);
    326 
    327         free32(ictx);
    328         return EOK;
    329 
    330 err_ictx:
    331         free32(ictx);
     289        return EOK;
     290
    332291err_ds:
    333292        xhci_endpoint_free_transfer_ds(ep);
     
    356315        }
    357316
    358         /* Issue configure endpoint command to drop this endpoint. */
    359         xhci_input_ctx_t *ictx;
    360         if ((err = create_valid_input_ctx(&ictx))) {
     317        /* Drop the endpoint. */
     318        if ((err = hc_drop_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
    361319                goto err;
    362320        }
    363 
    364         const unsigned ep_idx = xhci_endpoint_index(ep);
    365         XHCI_INPUT_CTRL_CTX_DROP_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */
    366 
    367         xhci_cmd_t cmd;
    368         xhci_cmd_init(&cmd);
    369 
    370         cmd.slot_id = dev->slot_id;
    371 
    372         if ((err = xhci_send_configure_endpoint_command(dev->hc, &cmd, ictx))) {
    373                 goto err_ictx;
    374         }
    375 
    376         if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
    377                 goto err_ictx;
    378         }
    379 
    380         xhci_cmd_fini(&cmd);
    381321
    382322        /* Tear down TRB ring / PSA. */
     
    387327        */
    388328
    389         free32(ictx);
    390         return EOK;
    391 
    392 err_ictx:
    393         free32(ictx);
     329        return EOK;
     330
    394331err:
    395332        dev->endpoints[ep_num] = ep;
     
    403340}
    404341
    405 int xhci_device_configure(xhci_device_t *dev, xhci_hc_t *hc)
    406 {
    407         int err;
    408 
    409         /* Issue configure endpoint command (sec 4.3.5). */
    410         xhci_input_ctx_t *ictx;
    411         if ((err = create_valid_input_ctx(&ictx))) {
    412                 goto err;
    413         }
    414 
    415         // TODO: Set slot context and other flags. (probably forgot a lot of 'em)
    416 
    417         xhci_cmd_t cmd;
    418         xhci_cmd_init(&cmd);
    419 
    420         cmd.slot_id = dev->slot_id;
    421 
    422         if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) {
    423                 goto err_cmd;
    424         }
    425 
    426         if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
    427                 goto err_cmd;
    428         }
    429 
    430         xhci_cmd_fini(&cmd);
    431 
    432         free32(ictx);
    433         return EOK;
    434 
    435 err_cmd:
    436         free32(ictx);
    437 err:
    438         return err;
    439 }
    440 
    441342/**
    442343 * @}
  • uspace/drv/bus/usb/xhci/endpoint.h

    r327f147 rb724494  
    122122int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *);
    123123xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
    124 int xhci_device_configure(xhci_device_t *, xhci_hc_t *);
    125124
    126125static inline xhci_device_t * xhci_device_get(device_t *dev)
  • uspace/drv/bus/usb/xhci/hc.c

    r327f147 rb724494  
    652652}
    653653
     654static int create_valid_input_ctx(xhci_input_ctx_t **out_ictx)
     655{
     656        xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));
     657        if (!ictx) {
     658                return ENOMEM;
     659        }
     660
     661        memset(ictx, 0, sizeof(xhci_input_ctx_t));
     662
     663        // Quoting sec. 4.6.6: A1, D0, D1 are down, A0 is up.
     664        XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ictx->ctrl_ctx, 1);
     665        XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 0);
     666        XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 1);
     667        XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);
     668
     669        if (out_ictx) {
     670                *out_ictx = ictx;
     671        }
     672
     673        return EOK;
     674}
     675
     676int hc_address_rh_device(xhci_hc_t *hc, uint32_t slot_id, uint8_t port, xhci_ep_ctx_t *ep_ctx)
     677{
     678        int err;
     679
     680        /* Issue configure endpoint command (sec 4.3.5). */
     681        xhci_input_ctx_t *ictx;
     682        if ((err = create_valid_input_ctx(&ictx))) {
     683                goto err;
     684        }
     685
     686        /* Initialize slot_ctx according to section 4.3.3 point 3. */
     687        XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port);
     688        XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
     689
     690        /* Attaching to root hub port, root string equals to 0. */
     691        XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, 0);
     692
     693        /* Copy endpoint 0 context and set A1 flag. */
     694        memcpy(&ictx->endpoint_ctx[0], ep_ctx, sizeof(xhci_ep_ctx_t));
     695        XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1);
     696
     697        if ((err = hc_address_device(hc, slot_id, ictx))) {
     698                goto err_cmd;
     699        }
     700
     701        free32(ictx);
     702        return EOK;
     703
     704err_cmd:
     705        free32(ictx);
     706err:
     707        return err;
     708}
     709
     710int hc_configure_device(xhci_hc_t *hc, uint32_t slot_id)
     711{
     712        int err;
     713
     714        /* Issue configure endpoint command (sec 4.3.5). */
     715        xhci_input_ctx_t *ictx;
     716        if ((err = create_valid_input_ctx(&ictx))) {
     717                goto err;
     718        }
     719
     720        // TODO: Set slot context and other flags. (probably forgot a lot of 'em)
     721
     722        xhci_cmd_t cmd;
     723        xhci_cmd_init(&cmd);
     724
     725        cmd.slot_id = slot_id;
     726
     727        if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) {
     728                goto err_cmd;
     729        }
     730
     731        if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
     732                goto err_cmd;
     733        }
     734
     735        xhci_cmd_fini(&cmd);
     736
     737        free32(ictx);
     738        return EOK;
     739
     740err_cmd:
     741        free32(ictx);
     742err:
     743        return err;
     744}
     745
     746int hc_deconfigure_device(xhci_hc_t *hc, uint32_t slot_id)
     747{
     748        int err;
     749
     750        /* Issue configure endpoint command (sec 4.3.5) with the DC flag. */
     751        xhci_cmd_t cmd;
     752        xhci_cmd_init(&cmd);
     753
     754        cmd.slot_id = slot_id;
     755        cmd.deconfigure = true;
     756
     757        if ((err = xhci_send_configure_endpoint_command(hc, &cmd, NULL))) {
     758                return err;
     759        }
     760
     761        if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
     762                return err;
     763        }
     764
     765        xhci_cmd_fini(&cmd);
     766
     767        return EOK;
     768}
     769
     770int hc_add_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx)
     771{
     772        int err;
     773
     774        /* Issue configure endpoint command (sec 4.3.5). */
     775        xhci_input_ctx_t *ictx;
     776        if ((err = create_valid_input_ctx(&ictx))) {
     777                goto err;
     778        }
     779
     780        XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */
     781        memcpy(&ictx->endpoint_ctx[ep_idx], ep_ctx, sizeof(xhci_ep_ctx_t));
     782
     783        // TODO: Set slot context and other flags. (probably forgot a lot of 'em)
     784
     785        xhci_cmd_t cmd;
     786        xhci_cmd_init(&cmd);
     787
     788        cmd.slot_id = slot_id;
     789
     790        if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) {
     791                goto err_cmd;
     792        }
     793
     794        if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
     795                goto err_cmd;
     796        }
     797
     798        xhci_cmd_fini(&cmd);
     799
     800        free32(ictx);
     801        return EOK;
     802
     803err_cmd:
     804        free32(ictx);
     805err:
     806        return err;
     807}
     808
     809int hc_drop_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx)
     810{
     811        int err;
     812
     813        /* Issue configure endpoint command (sec 4.3.5). */
     814        xhci_input_ctx_t *ictx;
     815        if ((err = create_valid_input_ctx(&ictx))) {
     816                goto err;
     817        }
     818
     819        XHCI_INPUT_CTRL_CTX_DROP_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */
     820
     821        // TODO: Set slot context and other flags. (probably forgot a lot of 'em)
     822
     823        xhci_cmd_t cmd;
     824        xhci_cmd_init(&cmd);
     825
     826        cmd.slot_id = slot_id;
     827
     828        if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) {
     829                goto err_cmd;
     830        }
     831
     832        if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {
     833                goto err_cmd;
     834        }
     835
     836        xhci_cmd_fini(&cmd);
     837
     838        free32(ictx);
     839        return EOK;
     840
     841err_cmd:
     842        free32(ictx);
     843err:
     844        return err;
     845}
     846
    654847/**
    655848 * @}
  • uspace/drv/bus/usb/xhci/hc.h

    r327f147 rb724494  
    9696int hc_disable_slot(xhci_hc_t *, uint32_t);
    9797int hc_address_device(xhci_hc_t *, uint32_t, xhci_input_ctx_t *);
     98int hc_address_rh_device(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *);
     99int hc_configure_device(xhci_hc_t *, uint32_t);
     100int hc_deconfigure_device(xhci_hc_t *, uint32_t);
     101int hc_add_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *);
     102int hc_drop_endpoint(xhci_hc_t *, uint32_t, uint8_t);
    98103
    99104#endif
  • uspace/drv/bus/usb/xhci/rh.c

    r327f147 rb724494  
    9595{
    9696        int err;
     97
     98        const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
    9799        xhci_device_t *xhci_dev = xhci_device_get(dev);
    98 
    99         /* FIXME: Certainly not generic solution. */
    100         const uint32_t route_str = 0;
    101 
    102100        xhci_dev->hc = rh->hc;
    103 
    104         const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
    105101        xhci_dev->usb3 = speed->major == 3;
    106102
    107         /* Enable new slot */
     103        /* Enable new slot. */
    108104        if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK)
    109105                return err;
    110106        usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id);
    111107
    112         /* Setup input context */
    113         xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));
    114         if (!ictx)
    115                 return ENOMEM;
    116         memset(ictx, 0, sizeof(xhci_input_ctx_t));
    117 
    118         XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);
    119         XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1);
    120 
    121         /* Initialize slot_ctx according to section 4.3.3 point 3. */
    122         /* Attaching to root hub port, root string equals to 0. */
    123         XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->port);
    124         XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
    125         XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str);
    126 
     108        /* Create and configure control endpoint. */
    127109        endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base);
    128110        if (!ep0_base)
    129                 goto err_ictx;
     111                return ENOMEM;
     112
    130113        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    131 
    132         /* Control endpoints don't use streams. */
    133114        /* FIXME: Sync this with xhci_device_add_endpoint. */
    134115        ep0->max_streams = 0;
    135116        ep0->max_burst = 0;
    136117        ep0->mult = 0;
     118
    137119        if ((err = xhci_endpoint_alloc_transfer_ds(ep0)))
    138                 goto err_ictx;
    139 
    140         setup_control_ep0_ctx(&ictx->endpoint_ctx[0], &ep0->ring, speed);
     120                goto err_ep;
     121
     122        xhci_ep_ctx_t ep_ctx;
     123        memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t));
     124        setup_control_ep0_ctx(&ep_ctx, &ep0->ring, speed);
    141125
    142126        /* Setup and register device context */
    143         xhci_device_ctx_t *dctx = malloc32(sizeof(xhci_device_ctx_t));
    144         if (!dctx) {
     127        xhci_dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t));
     128        if (!xhci_dev->dev_ctx) {
    145129                err = ENOMEM;
    146                 goto err_ep;
    147         }
    148         xhci_dev->dev_ctx = dctx;
    149         rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(dctx);
    150         memset(dctx, 0, sizeof(xhci_device_ctx_t));
     130                goto err_ds;
     131        }
     132        rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(xhci_dev->dev_ctx);
     133        memset(xhci_dev->dev_ctx, 0, sizeof(xhci_device_ctx_t));
    151134
    152135        /* Address device */
    153         if ((err = hc_address_device(rh->hc, xhci_dev->slot_id, ictx)) != EOK)
     136        if ((err = hc_address_rh_device(rh->hc, xhci_dev->slot_id, dev->port, &ep_ctx)))
    154137                goto err_dctx;
    155         dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
     138        dev->address = XHCI_SLOT_DEVICE_ADDRESS(xhci_dev->dev_ctx->slot_ctx);
    156139        usb_log_debug2("Obtained USB address: %d.\n", dev->address);
    157140
     
    178161        }
    179162
    180         free32(ictx);
    181163        return EOK;
    182164
    183165err_dctx:
    184         free32(dctx);
     166        free32(xhci_dev->dev_ctx);
    185167        rh->hc->dcbaa[xhci_dev->slot_id] = 0;
     168err_ds:
     169        xhci_endpoint_free_transfer_ds(ep0);
    186170err_ep:
    187171        xhci_endpoint_fini(ep0);
    188172        free(ep0);
    189 err_ictx:
    190         free32(ictx);
    191173        return err;
    192174}
     
    316298
    317299        /* TODO: Figure out how to handle errors here. So far, they are reported and skipped. */
     300        /* TODO: Move parts of the code below to xhci_bus_remove_device() */
    318301
    319302        /* Make DDF (and all drivers) forget about the device. */
     
    323306        }
    324307
    325         // TODO: Remove EP0.
    326         // TODO: Deconfigure device.
     308        /* Unregister EP0. */
     309        if ((err = bus_unregister_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) {
     310                usb_log_warning("Failed to unregister configuration endpoint of device '%s' from XHCI bus: %s",
     311                    ddf_fun_get_name(dev->base.fun), str_error(err));
     312        }
     313
     314        /* Deconfigure device. */
     315        if ((err = hc_deconfigure_device(rh->hc, dev->slot_id))) {
     316                usb_log_warning("Failed to deconfigure detached device '%s': %s",
     317                    ddf_fun_get_name(dev->base.fun), str_error(err));
     318        }
     319
     320        /* TODO: Free EP0 structures. */
     321        /* TODO: Destroy EP0 by removing its last reference. */
    327322
    328323        /* Remove device from XHCI bus. */
  • uspace/drv/bus/usb/xhci/transfers.c

    r327f147 rb724494  
    191191        // Issue a Configure Endpoint command, if needed.
    192192        if (configure_endpoint_needed(setup)) {
    193                 const int err = xhci_device_configure(xhci_ep_to_dev(xhci_ep), hc);
     193                const int err = hc_configure_device(hc, xhci_ep_to_dev(xhci_ep)->slot_id);
    194194                if (err)
    195195                        return err;
Note: See TracChangeset for help on using the changeset viewer.