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

Changeset 04df063 in mainline


Ignore:
Timestamp:
2017-10-02T19:16:29Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
1f76b7d
Parents:
370a1c8
Message:

xhci commands: enable (and encourage) keeping commands on the stack

It is now not necessary to use the heap for simple commands.

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

Legend:

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

    r370a1c8 r04df063  
    7373        // Note: Untested.
    7474        assert(hc);
    75 
    76         // We assume that the hc is dying/stopping, so we ignore
    77         // the ownership of the commands.
    78         list_foreach(hc->commands, link, xhci_cmd_t, cmd) {
    79                 xhci_free_command(cmd);
    80         }
    81 }
    82 
    83 int xhci_wait_for_command(xhci_cmd_t *cmd, suseconds_t timeout)
     75}
     76
     77int xhci_cmd_wait(xhci_cmd_t *cmd, suseconds_t timeout)
    8478{
    8579        int rv = EOK;
     
    9993}
    10094
    101 xhci_cmd_t *xhci_alloc_command(void)
     95xhci_cmd_t *xhci_cmd_alloc(void)
    10296{
    10397        xhci_cmd_t *cmd = malloc32(sizeof(xhci_cmd_t));
    10498        xhci_cmd_init(cmd);
     99
     100        usb_log_debug2("Allocating cmd on the heap. Don't forget to deallocate it!");
    105101        return cmd;
    106102}
     
    114110        fibril_mutex_initialize(&cmd->completed_mtx);
    115111        fibril_condvar_initialize(&cmd->completed_cv);
    116 
    117         /**
    118          * Internal functions will set this to false, other are implicit
    119          * owners unless they overwrite this field.
    120          * TODO: Is this wise?
    121          */
    122         cmd->has_owner = true;
    123 }
    124 
    125 void xhci_free_command(xhci_cmd_t *cmd)
     112}
     113
     114void xhci_cmd_fini(xhci_cmd_t *cmd)
    126115{
    127116        list_remove(&cmd->link);
    128 
    129         if (cmd->ictx)
    130                 free32(cmd->ictx);
    131 
     117}
     118
     119void xhci_cmd_free(xhci_cmd_t *cmd)
     120{
     121        xhci_cmd_fini(cmd);
    132122        free32(cmd);
    133123}
     
    299289}
    300290
    301 int xhci_send_address_device_command(xhci_hc_t *hc, xhci_cmd_t *cmd)
    302 {
    303         assert(hc);
    304         assert(cmd);
    305         assert(cmd->ictx);
     291int xhci_send_address_device_command(xhci_hc_t *hc, xhci_cmd_t *cmd, xhci_input_ctx_t *ictx)
     292{
     293        assert(hc);
     294        assert(cmd);
     295        assert(ictx);
    306296
    307297        /**
     
    311301         *           other should be ignored at this point (see section 4.6.5).
    312302         */
    313         xhci_trb_clean(&cmd->trb);
    314 
    315         uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx);
     303
     304        xhci_trb_clean(&cmd->trb);
     305
     306        uint64_t phys_addr = (uint64_t) addr_to_phys(ictx);
    316307        TRB_SET_ICTX(cmd->trb, phys_addr);
    317308
     
    329320}
    330321
    331 int xhci_send_configure_endpoint_command(xhci_hc_t *hc, xhci_cmd_t *cmd)
    332 {
    333         assert(hc);
    334         assert(cmd);
    335         assert(cmd->ictx);
    336 
    337         xhci_trb_clean(&cmd->trb);
    338 
    339         uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx);
     322int xhci_send_configure_endpoint_command(xhci_hc_t *hc, xhci_cmd_t *cmd, xhci_input_ctx_t *ictx)
     323{
     324        assert(hc);
     325        assert(cmd);
     326        assert(ictx);
     327
     328        xhci_trb_clean(&cmd->trb);
     329
     330        uint64_t phys_addr = (uint64_t) addr_to_phys(ictx);
    340331        TRB_SET_ICTX(cmd->trb, phys_addr);
    341332
     
    346337}
    347338
    348 int xhci_send_evaluate_context_command(xhci_hc_t *hc, xhci_cmd_t *cmd)
    349 {
    350         assert(hc);
    351         assert(cmd);
    352         assert(cmd->ictx);
     339int xhci_send_evaluate_context_command(xhci_hc_t *hc, xhci_cmd_t *cmd, xhci_input_ctx_t *ictx)
     340{
     341        assert(hc);
     342        assert(cmd);
     343        assert(ictx);
    353344
    354345        /**
     
    360351        xhci_trb_clean(&cmd->trb);
    361352
    362         uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx);
     353        uint64_t phys_addr = (uint64_t) addr_to_phys(ictx);
    363354        TRB_SET_ICTX(cmd->trb, phys_addr);
    364355
     
    455446        if (command == NULL) {
    456447                // TODO: STOP & ABORT may not have command structs in the list!
    457                 usb_log_error("No command struct for this completion event");
     448                usb_log_debug("No command struct for this completion event found.");
    458449
    459450                if (code != XHCI_TRBC_SUCCESS)
     
    509500        fibril_mutex_unlock(&command->completed_mtx);
    510501
    511 
    512         if (!command->has_owner) {
    513                 usb_log_debug2("Command has no owner, deallocating.");
    514                 xhci_free_command(command);
    515         } else {
    516                 usb_log_debug2("Command has owner, don't forget to deallocate!");
    517         }
    518 
    519502        return EOK;
    520503}
  • uspace/drv/bus/usb/xhci/commands.h

    r370a1c8 r04df063  
    5050        xhci_trb_t trb;
    5151        uintptr_t trb_phys;
    52         xhci_input_ctx_t *ictx;
     52
    5353        uint32_t slot_id;
    5454        uint32_t status;
    5555
    5656        bool completed;
    57         bool has_owner;
    58         bool owns_trb;
    5957
    60         /* Will be unlocked after command completes */
     58        /* Will broadcast after command completes. */
    6159        fibril_mutex_t completed_mtx;
    6260        fibril_condvar_t completed_cv;
     
    6563int xhci_init_commands(xhci_hc_t *);
    6664void xhci_fini_commands(xhci_hc_t *);
    67 int xhci_wait_for_command(xhci_cmd_t *, uint32_t);
    68 xhci_cmd_t *xhci_alloc_command(void);
     65
     66xhci_cmd_t *xhci_cmd_alloc(void);
    6967void xhci_cmd_init(xhci_cmd_t *);
    70 void xhci_free_command(xhci_cmd_t *);
     68int xhci_cmd_wait(xhci_cmd_t *, suseconds_t);
     69void xhci_cmd_fini(xhci_cmd_t *);
     70void xhci_cmd_free(xhci_cmd_t *);
    7171
    7272void xhci_stop_command_ring(xhci_hc_t *);
     
    7777int xhci_send_enable_slot_command(xhci_hc_t *, xhci_cmd_t *);
    7878int xhci_send_disable_slot_command(xhci_hc_t *, xhci_cmd_t *);
    79 int xhci_send_address_device_command(xhci_hc_t *, xhci_cmd_t *);
    80 int xhci_send_configure_endpoint_command(xhci_hc_t *, xhci_cmd_t *);
    81 int xhci_send_evaluate_context_command(xhci_hc_t *, xhci_cmd_t *);
     79int xhci_send_address_device_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
     80int xhci_send_configure_endpoint_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
     81int xhci_send_evaluate_context_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
    8282int xhci_send_reset_endpoint_command(xhci_hc_t *, xhci_cmd_t *, uint32_t, uint8_t);
    8383int xhci_send_stop_endpoint_command(xhci_hc_t *, xhci_cmd_t *, uint32_t, uint8_t);
  • uspace/drv/bus/usb/xhci/rh.c

    r370a1c8 r04df063  
    6363        int err;
    6464
    65         xhci_cmd_t *cmd = xhci_alloc_command();
    66         if (!cmd)
    67                 return ENOMEM;
    68 
    69         xhci_send_enable_slot_command(hc, cmd);
    70         if ((err = xhci_wait_for_command(cmd, 100000)) != EOK) {
    71                 usb_log_error("Failed to enable a slot for the device.");
    72                 goto err_command;
    73         }
    74 
    75         uint32_t slot_id = cmd->slot_id;
     65        xhci_cmd_t cmd;
     66        xhci_cmd_init(&cmd);
     67
     68        xhci_send_enable_slot_command(hc, &cmd);
     69        if ((err = xhci_cmd_wait(&cmd, 100000)) != EOK)
     70                return err;
     71
     72        uint32_t slot_id = cmd.slot_id;
     73
    7674        usb_log_debug2("Obtained slot ID: %u.\n", slot_id);
    77 
    78         xhci_free_command(cmd);
    79         cmd = NULL;
     75        xhci_cmd_fini(&cmd);
    8076
    8177        xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));
    8278        if (!ictx) {
    83                 err = ENOMEM;
    84                 goto err_command;
     79                return ENOMEM;
    8580        }
    8681
     
    9085        XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1);
    9186
    92         /* Initialize slot_ctx according to section 4.3.3 point 3. */
     87        /* Initialize slot_ctx according to section 4.3.3 point 3. */
    9388        /* Attaching to root hub port, root string equals to 0. */
    9489        XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port);
     
    133128        hc->dcbaa_virt[slot_id].dev_ctx = dctx;
    134129
    135         cmd = xhci_alloc_command();
    136         cmd->ictx = ictx;
    137         xhci_send_address_device_command(hc, cmd);
    138         if ((err = xhci_wait_for_command(cmd, 100000)) != EOK)
     130        xhci_cmd_init(&cmd);
     131        xhci_send_address_device_command(hc, &cmd, ictx);
     132        if ((err = xhci_cmd_wait(&cmd, 100000)) != EOK)
    139133                goto err_dctx;
    140134
    141         xhci_free_command(cmd);
    142         ictx = NULL;
     135        xhci_cmd_fini(&cmd);
    143136
    144137        // TODO: Issue configure endpoint commands (sec 4.3.5).
     
    158151        }
    159152err_ictx:
    160         if (ictx) {
    161                 /* Avoid double free. */
    162                 if (cmd && cmd->ictx && cmd->ictx == ictx)
    163                         cmd->ictx = NULL;
    164                 free32(ictx);
    165         }
    166 err_command:
    167         if (cmd)
    168                 xhci_free_command(cmd);
     153        free32(ictx);
    169154        return err;
    170155}
Note: See TracChangeset for help on using the changeset viewer.