Changeset 62ba2cbe in mainline
- Timestamp:
- 2017-06-16T01:25:16Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cb89430
- Parents:
- ce6e001
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/debug.c
rce6e001 r62ba2cbe 38 38 39 39 #include "debug.h" 40 #include "hc.h" 41 42 #define PX "\t%-21s = " 40 43 41 44 #define DUMP_REG_FIELD(ptr, title, size, ...) \ 42 usb_log_debug2( title "%" PRIu##size, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__))45 usb_log_debug2(PX "%" PRIu##size, title, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__)) 43 46 44 47 #define DUMP_REG_RANGE(ptr, title, size, ...) \ 45 usb_log_debug2( title "%" PRIu##size, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__))48 usb_log_debug2(PX "%" PRIu##size, title, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__)) 46 49 47 50 #define DUMP_REG_FLAG(ptr, title, size, ...) \ 48 usb_log_debug2( title "%s", XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false")51 usb_log_debug2(PX "%s", title, XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false") 49 52 50 53 #define DUMP_REG_INNER(set, title, field, size, type, ...) \ 51 54 DUMP_REG_##type(&(set)->field, title, size, ##__VA_ARGS__) 52 55 53 #define DUMP_REG(set, c) DUMP_REG_INNER(set, "\t" #c ": ", c)56 #define DUMP_REG(set, c) DUMP_REG_INNER(set, #c, c) 54 57 55 58 /** … … 92 95 } 93 96 97 void xhci_dump_port(xhci_port_regs_t *port) 98 { 99 DUMP_REG(port, XHCI_PORT_CCS); 100 DUMP_REG(port, XHCI_PORT_PED); 101 DUMP_REG(port, XHCI_PORT_OCA); 102 DUMP_REG(port, XHCI_PORT_PR); 103 DUMP_REG(port, XHCI_PORT_PLS); 104 DUMP_REG(port, XHCI_PORT_PP); 105 DUMP_REG(port, XHCI_PORT_PIC); 106 DUMP_REG(port, XHCI_PORT_LWS); 107 DUMP_REG(port, XHCI_PORT_CSC); 108 DUMP_REG(port, XHCI_PORT_PEC); 109 DUMP_REG(port, XHCI_PORT_WRC); 110 DUMP_REG(port, XHCI_PORT_OCC); 111 DUMP_REG(port, XHCI_PORT_PRC); 112 DUMP_REG(port, XHCI_PORT_PLC); 113 DUMP_REG(port, XHCI_PORT_CEC); 114 DUMP_REG(port, XHCI_PORT_CAS); 115 DUMP_REG(port, XHCI_PORT_WCE); 116 DUMP_REG(port, XHCI_PORT_WDE); 117 DUMP_REG(port, XHCI_PORT_WOE); 118 DUMP_REG(port, XHCI_PORT_DR); 119 DUMP_REG(port, XHCI_PORT_WPR); 120 } 121 122 void xhci_dump_state(xhci_hc_t *hc) 123 { 124 usb_log_debug2("Operational registers:"); 125 126 DUMP_REG(hc->op_regs, XHCI_OP_RS); 127 DUMP_REG(hc->op_regs, XHCI_OP_RS); 128 DUMP_REG(hc->op_regs, XHCI_OP_HCRST); 129 DUMP_REG(hc->op_regs, XHCI_OP_INTE); 130 DUMP_REG(hc->op_regs, XHCI_OP_HSEE); 131 DUMP_REG(hc->op_regs, XHCI_OP_LHCRST); 132 DUMP_REG(hc->op_regs, XHCI_OP_CSS); 133 DUMP_REG(hc->op_regs, XHCI_OP_CRS); 134 DUMP_REG(hc->op_regs, XHCI_OP_EWE); 135 DUMP_REG(hc->op_regs, XHCI_OP_EU3S); 136 DUMP_REG(hc->op_regs, XHCI_OP_CME); 137 DUMP_REG(hc->op_regs, XHCI_OP_HCH); 138 DUMP_REG(hc->op_regs, XHCI_OP_HSE); 139 DUMP_REG(hc->op_regs, XHCI_OP_EINT); 140 DUMP_REG(hc->op_regs, XHCI_OP_PCD); 141 DUMP_REG(hc->op_regs, XHCI_OP_SSS); 142 DUMP_REG(hc->op_regs, XHCI_OP_RSS); 143 DUMP_REG(hc->op_regs, XHCI_OP_SRE); 144 DUMP_REG(hc->op_regs, XHCI_OP_CNR); 145 DUMP_REG(hc->op_regs, XHCI_OP_HCE); 146 DUMP_REG(hc->op_regs, XHCI_OP_PAGESIZE); 147 DUMP_REG(hc->op_regs, XHCI_OP_NOTIFICATION); 148 DUMP_REG(hc->op_regs, XHCI_OP_RCS); 149 DUMP_REG(hc->op_regs, XHCI_OP_CS); 150 DUMP_REG(hc->op_regs, XHCI_OP_CA); 151 DUMP_REG(hc->op_regs, XHCI_OP_CRR); 152 DUMP_REG(hc->op_regs, XHCI_OP_CRCR_LO); 153 DUMP_REG(hc->op_regs, XHCI_OP_CRCR_HI); 154 155 const size_t num_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS); 156 for (size_t i = 0; i < num_ports; i++) { 157 usb_log_debug2("Port %zu state:", i); 158 159 xhci_dump_port(&hc->op_regs->portrs[i]); 160 } 161 } 94 162 /** 95 163 * @} -
uspace/drv/bus/usb/xhci/debug.h
rce6e001 r62ba2cbe 40 40 #include "hw_struct/regs.h" 41 41 42 typedef struct xhci_hc xhci_hc_t; 43 42 44 void xhci_dump_cap_regs(xhci_cap_regs_t *); 45 void xhci_dump_port(xhci_port_regs_t *); 46 void xhci_dump_state(xhci_hc_t *); 43 47 44 48 #endif -
uspace/drv/bus/usb/xhci/hc.c
rce6e001 r62ba2cbe 36 36 #include <errno.h> 37 37 #include <usb/debug.h> 38 #include <usb/host/ddf_helpers.h> 38 39 #include "debug.h" 39 40 #include "hc.h" 40 41 41 int xhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res) 42 const ddf_hc_driver_t xhci_ddf_hc_driver = { 43 .hc_speed = USB_SPEED_SUPER, 44 .init = xhci_hc_init, 45 .fini = xhci_hc_fini, 46 .name = "XHCI-PCI", 47 .ops = { 48 .schedule = xhci_hc_schedule, 49 .irq_hook = xhci_hc_interrupt, 50 .status_hook = xhci_hc_status, 51 } 52 }; 53 54 int xhci_hc_init(hcd_t *hcd, const hw_res_list_parsed_t *hw_res, bool irq) 42 55 { 43 assert(code); 44 assert(hw_res); 56 int err; 45 57 46 usb_log_debug("Gen IRQ code, got %zu IRQs, %zu DMA chs, %zu mem rngs, %zu IO rngs", 47 hw_res->irqs.count, 48 hw_res->dma_channels.count, 49 hw_res->mem_ranges.count, 50 hw_res->io_ranges.count); 51 52 if (hw_res->irqs.count != 1 53 || hw_res->dma_channels.count != 0 54 || hw_res->mem_ranges.count != 1 55 || hw_res->io_ranges.count != 0) { 56 usb_log_debug("Unexpected HW resources, bailing out."); 58 assert(hcd); 59 assert(hcd_get_driver_data(hcd) == NULL); 60 61 if (hw_res->mem_ranges.count != 1) { 62 usb_log_debug("Unexpected MMIO area, bailing out."); 57 63 return EINVAL; 58 64 } 59 65 66 xhci_hc_t *hc = malloc(sizeof(xhci_hc_t)); 67 if (!hc) 68 return ENOMEM; 69 60 70 addr_range_t mmio_range = hw_res->mem_ranges.ranges[0]; 61 71 62 usb_log_debug("M emory mapped regsat %p (size %zu), IRQ %d.\n",72 usb_log_debug("MMIO area at %p (size %zu), IRQ %d.\n", 63 73 RNGABSPTR(mmio_range), RNGSZ(mmio_range), hw_res->irqs.irqs[0]); 64 74 65 xhci_cap_regs_t *cap_regs = NULL; 66 int ret = pio_enable_range(&mmio_range, (void **)&cap_regs); 67 if (ret != EOK) 68 return ret; 75 if ((err = pio_enable_range(&mmio_range, (void **)&hc->cap_regs))) 76 goto err_hc; 69 77 70 xhci_dump_cap_regs( cap_regs);78 xhci_dump_cap_regs(hc->cap_regs); 71 79 72 /* 73 * XHCI uses an Interrupter mechanism. Possibly, we want to set it up here. 74 */ 75 code->rangecount = 0; 76 code->ranges = NULL; 77 code->cmdcount = 0; 78 code->cmds = NULL; 80 uintptr_t base = (uintptr_t) hc->cap_regs; 81 82 hc->op_regs = (xhci_op_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH)); 83 hc->rt_regs = (xhci_rt_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF)); 84 hc->db_arry = (xhci_doorbell_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_DBOFF)); 85 86 usb_log_debug("Initialized MMIO reg areas:"); 87 usb_log_debug("\tCapability regs: %p", hc->cap_regs); 88 usb_log_debug("\tOperational regs: %p", hc->op_regs); 89 usb_log_debug("\tRuntime regs: %p", hc->rt_regs); 90 usb_log_debug("\tDoorbell array base: %p", hc->db_arry); 91 92 xhci_dump_state(hc); 93 94 hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops); 95 96 // TODO: check if everything fits into the mmio_area 79 97 80 98 return EOK; 99 100 err_hc: 101 free(hc); 102 return err; 81 103 } 82 104 … … 98 120 } 99 121 122 void xhci_hc_fini(hcd_t *hcd) 123 { 124 assert(hcd); 125 usb_log_info("Finishing"); 126 127 xhci_hc_t *hc = hcd_get_driver_data(hcd); 128 free(hc); 129 hcd_set_implementation(hcd, NULL, NULL); 130 } 131 100 132 101 133 /** -
uspace/drv/bus/usb/xhci/hc.h
rce6e001 r62ba2cbe 40 40 xhci_cap_regs_t *cap_regs; 41 41 xhci_op_regs_t *op_regs; 42 xhci_rt_regs_t *rt_regs; 43 xhci_doorbell_t *db_arry; 42 44 } xhci_hc_t; 43 45 46 extern const ddf_hc_driver_t xhci_ddf_hc_driver; 47 48 int xhci_hc_init(hcd_t *, const hw_res_list_parsed_t *, bool irq); 44 49 int xhci_hc_gen_irq_code(irq_code_t *, const hw_res_list_parsed_t *); 45 50 int xhci_hc_status(hcd_t *, uint32_t *); 46 51 int xhci_hc_schedule(hcd_t *, usb_transfer_batch_t *); 47 52 void xhci_hc_interrupt(hcd_t *, uint32_t); 53 void xhci_hc_fini(hcd_t *); 48 54 49 55 -
uspace/drv/bus/usb/xhci/hw_struct/regs.h
rce6e001 r62ba2cbe 32 32 /** @file 33 33 * Memory-mapped register structures of the xHC. 34 * 35 * The main pr 34 36 */ 35 37 … … 42 44 43 45 /* 44 * The macros XHCI_REG_* might seem a bit magic. It is the most compact way to45 * provide flexible interface abstracting from the real storage of given46 * register, but to avoid having to specify several constants per register.47 46 */ 48 47 … … 134 133 135 134 /* 136 * 0:3- IST135 * 3:0 - IST 137 136 * 7:4 - ERST Max 138 * 2 1:25- Max Scratchpad Bufs Hi137 * 24:21 - Max Scratchpad Bufs Hi 139 138 * 26 - SPR 140 139 * 31:27 - Max Scratchpad Bufs Lo … … 188 187 #define XHCI_CAP_IST hcsparams2, 32, RANGE, 3, 0 189 188 #define XHCI_CAP_ERST_MAX hcsparams2, 32, RANGE, 7, 4 190 #define XHCI_CAP_SPR hcsparams2, 32, RANGE, 26, 26 189 #define XHCI_CAP_MAX_SPBUF_LO hcsparams2, 32, RANGE, 25, 4 190 #define XHCI_CAP_SPR hcsparams2, 32, FLAG, 26 191 #define XHCI_CAP_MAX_SPBUF_HI hcsparams2, 32, RANGE, 31, 27 191 192 #define XHCI_CAP_U1EL hcsparams3, 32, RANGE, 7, 0 192 193 #define XHCI_CAP_U2EL hcsparams3, 32, RANGE, 31, 16 … … 203 204 #define XHCI_CAP_SEC hccparams1, 32, FLAG, 10 204 205 #define XHCI_CAP_CFC hccparams1, 32, FLAG, 11 205 #define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, FLAG, 12206 #define XHCI_CAP_XECP hccparams1, 32, FLAG, 13206 #define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, RANGE, 15, 12 207 #define XHCI_CAP_XECP hccparams1, 32, RANGE, 31, 16 207 208 #define XHCI_CAP_DBOFF dboff, 32, FIELD 208 209 #define XHCI_CAP_RTSOFF rtsoff, 32, FIELD … … 450 451 #define XHCI_RT_MFINDEX mfindex, 32, FIELD 451 452 453 /** 454 * XHCI Doorbel Registers: section 5.6 455 * 456 * These registers are write-only, thus convenience macros are useless. 457 */ 458 typedef ioport32_t xhci_doorbell_t; 459 452 460 #endif 453 461 /** -
uspace/drv/bus/usb/xhci/main.c
rce6e001 r62ba2cbe 45 45 #define NAME "xhci" 46 46 47 static int xhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);48 static void xhci_driver_fini(hcd_t *);49 50 static const ddf_hc_driver_t xhci_ddf_hc_driver = {51 .hc_speed = USB_SPEED_SUPER,52 .irq_code_gen = xhci_hc_gen_irq_code,53 .init = xhci_driver_init,54 .fini = xhci_driver_fini,55 .name = "XHCI-PCI",56 .ops = {57 .schedule = xhci_hc_schedule,58 .irq_hook = xhci_hc_interrupt,59 .status_hook = xhci_hc_status,60 }61 };62 63 static int xhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)64 {65 usb_log_info("Initializing");66 return ENOTSUP;67 }68 69 static void xhci_driver_fini(hcd_t *hcd)70 {71 usb_log_info("Finishing");72 assert(hcd);73 }74 75 47 /** Initializes a new ddf driver instance of XHCI hcd. 76 48 *
Note:
See TracChangeset
for help on using the changeset viewer.