Changeset 32fb6bce in mainline for uspace/drv/bus/usb/uhci


Ignore:
Timestamp:
2017-12-18T22:50:21Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7f70d1c
Parents:
1ea0bbf
git-author:
Ondřej Hlavatý <aearsis@…> (2017-12-18 22:04:50)
git-committer:
Ondřej Hlavatý <aearsis@…> (2017-12-18 22:50:21)
Message:

usbhost: refactoring

This commit moves interrupt, status and schedule to bus
operations. Then the purpose of hcd_t is better defined, and split into
hc_driver_t and hc_device_t. hc_driver_t is used to wrap driver
implementation by the library (similar to how usb_driver_t is used to
wrap usb device drivers). hc_device_t is used as a parent for hc_t
inside drivers, and is allocated inside the DDF device node.

To support these changes, some local identifiers were renamed, some
functions were moved and/or renamed and their arguments changed. The
most notable one being hcd_send_batch → bus_device_send_batch.

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

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/uhci/hc.c

    r1ea0bbf r32fb6bce  
    9595
    9696static void hc_init_hw(const hc_t *instance);
    97 static int hc_init_mem_structures(hc_t *instance, hcd_t *);
     97static int hc_init_mem_structures(hc_t *instance, hc_device_t *);
    9898static int hc_init_transfer_lists(hc_t *instance);
    9999
     
    107107 * @return Error code.
    108108 */
    109 int uhci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     109int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
    110110{
    111111        assert(code);
     
    156156 * - resume from suspend state (not implemented)
    157157 */
    158 void uhci_hc_interrupt(hcd_t *hcd, uint32_t status)
    159 {
    160         assert(hcd);
    161         hc_t *instance = hcd_get_driver_data(hcd);
    162         assert(instance);
     158static void hc_interrupt(bus_t *bus, uint32_t status)
     159{
     160        hc_t *instance = bus_to_hc(bus);
     161
    163162        /* Lower 2 bits are transaction error and transaction complete */
    164163        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     
    199198                } else {
    200199                        usb_log_fatal("Too many UHCI hardware failures!.\n");
    201                         hc_fini(instance);
     200                        hc_gone(&instance->base);
    202201                }
    203202        }
     
    215214 * interrupt fibrils.
    216215 */
    217 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    218 {
    219         assert(instance);
     216int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     217{
     218        hc_t *instance = hcd_to_hc(hcd);
    220219        assert(hw_res);
    221220        if (hw_res->io_ranges.count != 1 ||
     
    249248}
    250249
    251 void hc_start(hc_t *instance)
    252 {
     250int hc_start(hc_device_t *hcd)
     251{
     252        hc_t *instance = hcd_to_hc(hcd);
    253253        hc_init_hw(instance);
    254254        (void)hc_debug_checker;
    255255
    256         uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
     256        return uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
    257257}
    258258
     
    261261 * @param[in] instance Host controller structure to use.
    262262 */
    263 void hc_fini(hc_t *instance)
     263int hc_gone(hc_device_t *instance)
    264264{
    265265        assert(instance);
    266266        //TODO Implement
     267        return ENOTSUP;
    267268}
    268269
     
    294295        pio_write_32(&registers->flbaseadd, pa);
    295296
    296         if (instance->hw_interrupts) {
     297        if (instance->base.irq_cap >= 0) {
    297298                /* Enable all interrupts, but resume interrupt */
    298299                pio_write_16(&instance->registers->usbintr,
     
    320321}
    321322
     323static int hc_status(bus_t *, uint32_t *);
     324static int hc_schedule(usb_transfer_batch_t *);
     325
    322326static const bus_ops_t uhci_bus_ops = {
    323327        .parent = &usb2_bus_ops,
    324328
     329        .interrupt = hc_interrupt,
     330        .status = hc_status,
     331
    325332        .endpoint_count_bw = bandwidth_count_usb11,
    326333        .batch_create = create_transfer_batch,
     334        .batch_schedule = hc_schedule,
    327335        .batch_destroy = destroy_transfer_batch,
    328336};
     
    338346 *  - frame list page (needs to be one UHCI hw accessible 4K page)
    339347 */
    340 int hc_init_mem_structures(hc_t *instance, hcd_t *hcd)
     348int hc_init_mem_structures(hc_t *instance, hc_device_t *hcd)
    341349{
    342350        int err;
    343351        assert(instance);
    344352
    345         if ((err = usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11)))
     353        if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11)))
    346354                return err;
    347355
    348356        bus_t *bus = (bus_t *) &instance->bus;
    349357        bus->ops = &uhci_bus_ops;
     358
     359        hc_device_setup(&instance->base, bus);
    350360
    351361        /* Init USB frame list page */
     
    438448}
    439449
    440 int uhci_hc_status(hcd_t *hcd, uint32_t *status)
    441 {
    442         assert(hcd);
     450static int hc_status(bus_t *bus, uint32_t *status)
     451{
     452        hc_t *instance = bus_to_hc(bus);
    443453        assert(status);
    444         hc_t *instance = hcd_get_driver_data(hcd);
    445         assert(instance);
    446454
    447455        *status = 0;
     
    462470 * Checks for bandwidth availability and appends the batch to the proper queue.
    463471 */
    464 int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    465 {
    466         assert(hcd);
    467         hc_t *instance = hcd_get_driver_data(hcd);
    468         assert(instance);
     472static int hc_schedule(usb_transfer_batch_t *batch)
     473{
     474        hc_t *instance = bus_to_hc(endpoint_get_bus(batch->ep));
    469475        assert(batch);
    470476
  • uspace/drv/bus/usb/uhci/hc.h

    r1ea0bbf r32fb6bce  
    100100/** Main UHCI driver structure */
    101101typedef struct hc {
     102        /* Common hc_device header */
     103        hc_device_t base;
     104
    102105        uhci_rh_t rh;
    103106        usb2_bus_t bus;
     
    119122        /** Pointer table to the above lists, helps during scheduling */
    120123        transfer_list_t *transfers[2][4];
    121         /** Indicator of hw interrupts availability */
    122         bool hw_interrupts;
    123124
    124125        /** Number of hw failures detected. */
     
    126127} hc_t;
    127128
    128 extern int hc_init(hc_t *, hcd_t *, const hw_res_list_parsed_t *);
    129 extern void hc_start(hc_t *);
    130 extern void hc_fini(hc_t *);
     129static inline hc_t *hcd_to_hc(hc_device_t *hcd)
     130{
     131        assert(hcd);
     132        return (hc_t *) hcd;
     133}
    131134
    132 extern int uhci_hc_gen_irq_code(irq_code_t *, hcd_t *,const hw_res_list_parsed_t *);
     135static inline hc_t *bus_to_hc(bus_t *bus)
     136{
     137        assert(bus);
     138        return member_to_inst(bus, hc_t, bus);
     139}
    133140
    134 extern void uhci_hc_interrupt(hcd_t *, uint32_t);
    135 extern int uhci_hc_status(hcd_t *, uint32_t *);
    136 extern int uhci_hc_schedule(hcd_t *, usb_transfer_batch_t *);
     141extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *);
     142extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
     143extern int hc_start(hc_device_t *);
     144extern int hc_gone(hc_device_t *);
    137145
    138146#endif
  • uspace/drv/bus/usb/uhci/main.c

    r1ea0bbf r32fb6bce  
    4949#define NAME "uhci"
    5050
    51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
    52 static int uhci_driver_start(hcd_t *, bool);
    53 static void uhci_driver_fini(hcd_t *);
    54 static int disable_legacy(hcd_t *, ddf_dev_t *);
     51static int disable_legacy(hc_device_t *);
    5552
    56 static const ddf_hc_driver_t uhci_hc_driver = {
    57         .claim = disable_legacy,
    58         .irq_code_gen = uhci_hc_gen_irq_code,
    59         .init = uhci_driver_init,
    60         .start = uhci_driver_start,
     53static const hc_driver_t uhci_driver = {
     54        .name = NAME,
     55        .hc_device_size = sizeof(hc_t),
     56        .claim = disable_legacy,
     57        .irq_code_gen = hc_gen_irq_code,
     58        .hc_add = hc_add,
     59        .start = hc_start,
    6160        .setup_root_hub = hcd_setup_virtual_root_hub,
    62         .fini = uhci_driver_fini,
    63         .name = "UHCI",
    64         .ops = {
    65                 .schedule    = uhci_hc_schedule,
    66                 .irq_hook    = uhci_hc_interrupt,
    67                 .status_hook = uhci_hc_status,
    68         },
     61        .hc_gone = hc_gone,
    6962};
    70 
    71 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    72 {
    73         int err;
    74 
    75         assert(hcd);
    76         assert(hcd_get_driver_data(hcd) == NULL);
    77 
    78         hc_t *instance = malloc(sizeof(hc_t));
    79         if (!instance)
    80                 return ENOMEM;
    81 
    82         if ((err = hc_init(instance, hcd, res)) != EOK)
    83                 goto err;
    84 
    85         hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops, &instance->bus.base);
    86 
    87         return EOK;
    88 
    89 err:
    90         free(instance);
    91         return err;
    92 }
    93 
    94 static int uhci_driver_start(hcd_t *hcd, bool interrupts)
    95 {
    96         assert(hcd);
    97         hc_t *hc = hcd_get_driver_data(hcd);
    98 
    99         hc->hw_interrupts = interrupts;
    100         hc_start(hc);
    101         return EOK;
    102 }
    103 
    104 static void uhci_driver_fini(hcd_t *hcd)
    105 {
    106         assert(hcd);
    107         hc_t *hc = hcd_get_driver_data(hcd);
    108         if (hc)
    109                 hc_fini(hc);
    110 
    111         hcd_set_implementation(hcd, NULL, NULL, NULL);
    112         free(hc);
    113 }
    11463
    11564/** Call the PCI driver with a request to clear legacy support register
     
    11867 * @return Error code.
    11968 */
    120 static int disable_legacy(hcd_t *hcd, ddf_dev_t *device)
     69static int disable_legacy(hc_device_t *hcd)
    12170{
    122         assert(device);
     71        assert(hcd);
    12372
    124         async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
     73        async_sess_t *parent_sess = ddf_dev_parent_sess_get(hcd->ddf_dev);
    12574        if (parent_sess == NULL)
    12675                return ENOMEM;
     
    13079        return pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
    13180}
    132 
    133 /** Initialize a new ddf driver instance for uhci hc and hub.
    134  *
    135  * @param[in] device DDF instance of the device to initialize.
    136  * @return Error code.
    137  */
    138 static int uhci_dev_add(ddf_dev_t *device)
    139 {
    140         usb_log_debug2("uhci_dev_add() called\n");
    141         assert(device);
    142         return hcd_ddf_add_hc(device, &uhci_hc_driver);
    143 }
    144 
    145 static int uhci_fun_online(ddf_fun_t *fun)
    146 {
    147         return hcd_ddf_device_online(fun);
    148 }
    149 
    150 static int uhci_fun_offline(ddf_fun_t *fun)
    151 {
    152         return hcd_ddf_device_offline(fun);
    153 }
    154 
    155 static const driver_ops_t uhci_driver_ops = {
    156         .dev_add = uhci_dev_add,
    157         .fun_online = uhci_fun_online,
    158         .fun_offline = uhci_fun_offline
    159 };
    160 
    161 static const driver_t uhci_driver = {
    162         .name = NAME,
    163         .driver_ops = &uhci_driver_ops
    164 };
    165 
    16681
    16782/** Initialize global driver structures (NONE).
     
    17893        log_init(NAME);
    17994        logctl_set_log_level(NAME, LVL_DEBUG2);
    180         return ddf_driver_main(&uhci_driver);
     95        return hc_driver_main(&uhci_driver);
    18196}
    18297/**
Note: See TracChangeset for help on using the changeset viewer.