Changeset eaf5e86 in mainline
- Timestamp:
- 2017-10-11T13:18:54Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63adb18
- Parents:
- ac18b08
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/endpoint.h
rac18b08 reaf5e86 56 56 /** Connector structure linking endpoint context to the endpoint. */ 57 57 typedef struct xhci_endpoint { 58 58 uint32_t slot_id; 59 59 } xhci_endpoint_t; 60 60 … … 64 64 static inline xhci_endpoint_t * endpoint_get(const endpoint_t *ep) 65 65 { 66 67 66 assert(ep); 67 return ep->hc_data.data; 68 68 } 69 69 -
uspace/drv/bus/usb/xhci/hc.h
rac18b08 reaf5e86 45 45 46 46 typedef struct xhci_virt_device_ctx { 47 48 47 xhci_device_ctx_t *dev_ctx; 48 xhci_trb_ring_t *trs[XHCI_EP_COUNT]; 49 49 } xhci_virt_device_ctx_t; 50 50 -
uspace/drv/bus/usb/xhci/hw_struct/common.h
rac18b08 reaf5e86 83 83 static inline void xhci_qword_set_bits(xhci_qword_t *storage, uint64_t value, unsigned hi, unsigned lo) 84 84 { 85 86 87 85 const uint64_t mask = host2xhci(64, BIT_RANGE(uint64_t, hi, lo)); 86 const uint64_t set = host2xhci(64, value << lo); 87 *storage = (*storage & ~mask) | set; 88 88 } 89 89 -
uspace/drv/bus/usb/xhci/hw_struct/context.h
rac18b08 reaf5e86 65 65 66 66 #define XHCI_EP_TYPE_SET(ctx, val) \ 67 67 xhci_dword_set_bits(&(ctx).data[1], val, 5, 3) 68 68 #define XHCI_EP_MAX_PACKET_SIZE_SET(ctx, val) \ 69 69 xhci_dword_set_bits(&(ctx).data[1], val, 31, 16) 70 70 #define XHCI_EP_MAX_BURST_SIZE_SET(ctx, val) \ 71 71 xhci_dword_set_bits(&(ctx).data[1], val, 15, 8) 72 72 #define XHCI_EP_TR_DPTR_SET(ctx, val) \ 73 73 xhci_qword_set_bits(&(ctx).data2, (val >> 4), 63, 4) 74 74 #define XHCI_EP_DCS_SET(ctx, val) \ 75 75 xhci_qword_set_bits(&(ctx).data2, val, 0, 0) 76 76 #define XHCI_EP_INTERVAL_SET(ctx, val) \ 77 77 xhci_dword_set_bits(&(ctx).data[0], val, 23, 16) 78 78 #define XHCI_EP_MAX_P_STREAMS_SET(ctx, val) \ 79 79 xhci_dword_set_bits(&(ctx).data[0], val, 14, 10) 80 80 #define XHCI_EP_MULT_SET(ctx, val) \ 81 81 xhci_dword_set_bits(&(ctx).data[0], val, 9, 8) 82 82 #define XHCI_EP_ERROR_COUNT_SET(ctx, val) \ 83 83 xhci_dword_set_bits(&(ctx).data[1], val, 2, 1) 84 84 85 85 #define XHCI_EP_STATE(ctx) XHCI_DWORD_EXTRACT((ctx).data[0], 2, 0) … … 108 108 109 109 #define XHCI_SLOT_ROOT_HUB_PORT_SET(ctx, val) \ 110 110 xhci_dword_set_bits(&(ctx).data[1], val, 23, 16) 111 111 #define XHCI_SLOT_CTX_ENTRIES_SET(ctx, val) \ 112 112 xhci_dword_set_bits(&(ctx).data[0], val, 31, 27) 113 113 #define XHCI_SLOT_ROUTE_STRING_SET(ctx, val) \ 114 114 xhci_dword_set_bits(&(ctx).data[0], (val & 0xFFFFF), 19, 0) -
uspace/drv/bus/usb/xhci/hw_struct/regs.h
rac18b08 reaf5e86 499 499 */ 500 500 typedef struct xhci_psi { 501 501 xhci_dword_t psi; 502 502 } xhci_psi_t; 503 503 … … 547 547 548 548 static const xhci_sp_name_t xhci_name_usb = { 549 549 .str = "USB " 550 550 }; 551 551 -
uspace/drv/bus/usb/xhci/hw_struct/trb.h
rac18b08 reaf5e86 170 170 static inline void xhci_trb_copy(xhci_trb_t *dst, xhci_trb_t *src) 171 171 { 172 173 174 175 176 177 178 172 /* 173 * As we do not know, whether our architecture is capable of copying 16 174 * bytes atomically, let's copy the fields one by one. 175 */ 176 dst->parameter = src->parameter; 177 dst->status = src->status; 178 dst->control = src->control; 179 179 } 180 180 -
uspace/drv/bus/usb/xhci/main.c
rac18b08 reaf5e86 66 66 .schedule = hcd_schedule, 67 67 .irq_hook = hcd_interrupt, 68 69 68 .ep_add_hook = endpoint_init, 69 .ep_remove_hook = endpoint_fini, 70 70 .status_hook = hcd_status, 71 71 } -
uspace/drv/bus/usb/xhci/rh.c
rac18b08 reaf5e86 1 1 /* 2 * Copyright (c) 2017 Michal Staruch2 n * Copyright (c) 2017 Michal Staruch 3 3 * All rights reserved. 4 4 * … … 317 317 */ 318 318 static int req_clear_hub_feature(usbvirt_device_t *device, 319 320 319 const usb_device_request_setup_packet_t *setup_packet, 320 uint8_t *data, size_t *act_size) 321 321 { 322 322 /* TODO: Implement me! */ … … 337 337 */ 338 338 static int req_get_port_status(usbvirt_device_t *device, 339 340 339 const usb_device_request_setup_packet_t *setup_packet, 340 uint8_t *data, size_t *act_size) 341 341 { 342 342 xhci_rh_t *hub = virthub_get_data(device); … … 380 380 */ 381 381 static int req_clear_port_feature(usbvirt_device_t *device, 382 383 382 const usb_device_request_setup_packet_t *setup_packet, 383 uint8_t *data, size_t *act_size) 384 384 { 385 385 xhci_rh_t *hub = virthub_get_data(device); … … 437 437 */ 438 438 static int req_set_port_feature(usbvirt_device_t *device, 439 440 439 const usb_device_request_setup_packet_t *setup_packet, 440 uint8_t *data, size_t *act_size) 441 441 { 442 442 xhci_rh_t *hub = virthub_get_data(device); … … 478 478 */ 479 479 static int req_status_change_handler(usbvirt_device_t *device, 480 481 480 usb_endpoint_t endpoint, usb_transfer_type_t tr_type, 481 void *buffer, size_t buffer_size, size_t *actual_size) 482 482 { 483 483 xhci_rh_t *hub = virthub_get_data(device); … … 574 574 /** Virtual XHCI root hub ops */ 575 575 static usbvirt_device_ops_t ops = { 576 577 576 .control = control_transfer_handlers, 577 .data_in[HUB_STATUS_CHANGE_PIPE] = req_status_change_handler, 578 578 }; 579 579 -
uspace/drv/bus/usb/xhci/rh.h
rac18b08 reaf5e86 76 76 usb_transfer_batch_t *unfinished_interrupt_transfer; 77 77 78 78 /* Number of hub ports. */ 79 79 uint8_t max_ports; 80 80 } xhci_rh_t; -
uspace/drv/bus/usb/xhci/transfers.c
rac18b08 reaf5e86 150 150 (usb_device_request_setup_packet_t*) batch->setup_buffer; 151 151 152 152 /* For the TRB formats, see xHCI specification 6.4.1.2 */ 153 153 xhci_transfer_t *transfer = xhci_transfer_alloc(batch); 154 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 155 xhci_trb_t trb_setup; 156 memset(&trb_setup, 0, sizeof(xhci_trb_t)); 157 158 TRB_CTRL_SET_SETUP_WVALUE(trb_setup, setup->value); 159 TRB_CTRL_SET_SETUP_WLENGTH(trb_setup, setup->length); 160 TRB_CTRL_SET_SETUP_WINDEX(trb_setup, setup->index); 161 TRB_CTRL_SET_SETUP_BREQ(trb_setup, setup->request); 162 TRB_CTRL_SET_SETUP_BMREQTYPE(trb_setup, setup->request_type); 163 164 /* Size of the setup packet is always 8 */ 165 TRB_CTRL_SET_XFER_LEN(trb_setup, 8); 166 // if we want an interrupt after this td is done, use 167 // TRB_CTRL_SET_IOC(trb_setup, 1); 168 169 /* Immediate data */ 170 TRB_CTRL_SET_IDT(trb_setup, 1); 171 TRB_CTRL_SET_TRB_TYPE(trb_setup, XHCI_TRB_TYPE_SETUP_STAGE); 172 TRB_CTRL_SET_TRT(trb_setup, get_transfer_type(&trb_setup, setup->request_type, setup->length)); 173 174 /* Data stage */ 175 175 xhci_trb_t trb_data; 176 176 memset(&trb_data, 0, sizeof(xhci_trb_t)); 177 177 178 179 180 181 182 183 184 185 186 187 188 189 190 178 if (setup->length > 0) { 179 trb_data.parameter = (uintptr_t) addr_to_phys(batch->buffer); 180 181 // data size (sent for OUT, or buffer size) 182 TRB_CTRL_SET_XFER_LEN(trb_data, batch->buffer_size); 183 // FIXME: TD size 4.11.2.4 184 TRB_CTRL_SET_TD_SIZE(trb_data, 1); 185 186 // if we want an interrupt after this td is done, use 187 // TRB_CTRL_SET_IOC(trb_data, 1); 188 189 // Some more fields here, no idea what they mean 190 TRB_CTRL_SET_TRB_TYPE(trb_data, XHCI_TRB_TYPE_DATA_STAGE); 191 191 192 192 transfer->direction = get_data_direction(&trb_setup, setup->request_type, setup->length); 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 193 TRB_CTRL_SET_DIR(trb_data, transfer->direction); 194 } 195 196 /* Status stage */ 197 xhci_trb_t trb_status; 198 memset(&trb_status, 0, sizeof(xhci_trb_t)); 199 200 // FIXME: Evaluate next TRB? 4.12.3 201 // TRB_CTRL_SET_ENT(trb_status, 1); 202 203 // if we want an interrupt after this td is done, use 204 TRB_CTRL_SET_IOC(trb_status, 1); 205 206 TRB_CTRL_SET_TRB_TYPE(trb_status, XHCI_TRB_TYPE_STATUS_STAGE); 207 TRB_CTRL_SET_DIR(trb_status, get_status_direction(&trb_setup, setup->request_type, setup->length)); 208 208 209 209 uintptr_t dummy = 0; 210 210 xhci_trb_ring_enqueue(ring, &trb_setup, &dummy); 211 211 if (setup->length > 0) { 212 212 xhci_trb_ring_enqueue(ring, &trb_data, &dummy); 213 213 } 214 214 xhci_trb_ring_enqueue(ring, &trb_status, &transfer->interrupt_trb_phys); 215 215 216 216 list_append(&transfer->link, &hc->transfers); 217 217 218 219 218 /* For control transfers, the target is always 1. */ 219 hc_ring_doorbell(hc, slot_id, 1); 220 220 return EOK; 221 221 } … … 236 236 237 237 // data size (sent for OUT, or buffer size) 238 239 240 238 TRB_CTRL_SET_XFER_LEN(trb, batch->buffer_size); 239 // FIXME: TD size 4.11.2.4 240 TRB_CTRL_SET_TD_SIZE(trb, 1); 241 241 242 242 // we want an interrupt after this td is done … … 245 245 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 246 246 247 247 xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 248 248 list_append(&transfer->link, &hc->transfers); 249 249 250 251 250 /* For control transfers, the target is always 1. */ 251 hc_ring_doorbell(hc, slot_id, 1); 252 252 return EOK; 253 253 }
Note:
See TracChangeset
for help on using the changeset viewer.