Changeset d1d7a92 in mainline
- Timestamp:
- 2017-10-21T10:34:45Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8ea7459
- Parents:
- 1252e81
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r1252e81 rd1d7a92 187 187 ret_dev->device = dev; 188 188 189 usb_log_ debug("Device(%d) registered to XHCI bus.", dev->address);189 usb_log_info("Device(%d) registered to XHCI bus.", dev->address); 190 190 191 191 hash_table_insert(&bus->devices, &ret_dev->link); … … 202 202 static int hashed_device_remove(xhci_bus_t *bus, hashed_device_t *hashed_dev) 203 203 { 204 usb_log_ debug("Device(%d) released from XHCI bus.", hashed_dev->device->address);204 usb_log_info("Device(%d) released from XHCI bus.", hashed_dev->device->address); 205 205 206 206 hash_table_remove(&bus->devices, &hashed_dev->device->address); … … 229 229 } 230 230 231 usb_log_ debug("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint);231 usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint); 232 232 233 233 return xhci_device_add_endpoint(hashed_dev->device, xhci_endpoint_get(ep)); … … 239 239 assert(bus); 240 240 241 usb_log_ debug("Endpoint(%d:%d) released from XHCI bus.", ep->target.address, ep->target.endpoint);241 usb_log_info("Endpoint(%d:%d) released from XHCI bus.", ep->target.address, ep->target.endpoint); 242 242 243 243 hashed_device_t *hashed_dev; -
uspace/drv/bus/usb/xhci/commands.c
r1252e81 rd1d7a92 443 443 assert(trb); 444 444 445 usb_log_debug ("HC(%p) Command completed.", hc);445 usb_log_debug2("HC(%p) Command completed.", hc); 446 446 447 447 int code; … … 454 454 if (command == NULL) { 455 455 // TODO: STOP & ABORT may not have command structs in the list! 456 usb_log_ debug("No command struct for this completion event found.");456 usb_log_warning("No command struct for this completion event found."); 457 457 458 458 if (code != XHCI_TRBC_SUCCESS) -
uspace/drv/bus/usb/xhci/transfers.c
r1252e81 rd1d7a92 155 155 } 156 156 157 xhci_trb_t trb_setup; 158 xhci_trb_clean(&trb_setup); 159 160 TRB_CTRL_SET_SETUP_WVALUE(trb_setup, setup->value); 161 TRB_CTRL_SET_SETUP_WLENGTH(trb_setup, setup->length); 162 TRB_CTRL_SET_SETUP_WINDEX(trb_setup, setup->index); 163 TRB_CTRL_SET_SETUP_BREQ(trb_setup, setup->request); 164 TRB_CTRL_SET_SETUP_BMREQTYPE(trb_setup, setup->request_type); 157 xhci_trb_t trbs[3]; 158 int trbs_used = 0; 159 160 xhci_trb_t *trb_setup = trbs + trbs_used++; 161 xhci_trb_clean(trb_setup); 162 163 TRB_CTRL_SET_SETUP_WVALUE(*trb_setup, setup->value); 164 TRB_CTRL_SET_SETUP_WLENGTH(*trb_setup, setup->length); 165 TRB_CTRL_SET_SETUP_WINDEX(*trb_setup, setup->index); 166 TRB_CTRL_SET_SETUP_BREQ(*trb_setup, setup->request); 167 TRB_CTRL_SET_SETUP_BMREQTYPE(*trb_setup, setup->request_type); 165 168 166 169 /* Size of the setup packet is always 8 */ 167 TRB_CTRL_SET_XFER_LEN(trb_setup, 8); 168 // if we want an interrupt after this td is done, use 169 // TRB_CTRL_SET_IOC(trb_setup, 1); 170 TRB_CTRL_SET_XFER_LEN(*trb_setup, 8); 170 171 171 172 /* Immediate data */ 172 TRB_CTRL_SET_IDT( trb_setup, 1);173 TRB_CTRL_SET_TRB_TYPE( trb_setup, XHCI_TRB_TYPE_SETUP_STAGE);174 TRB_CTRL_SET_TRT( trb_setup, get_transfer_type(&trb_setup, setup->request_type, setup->length));173 TRB_CTRL_SET_IDT(*trb_setup, 1); 174 TRB_CTRL_SET_TRB_TYPE(*trb_setup, XHCI_TRB_TYPE_SETUP_STAGE); 175 TRB_CTRL_SET_TRT(*trb_setup, get_transfer_type(trb_setup, setup->request_type, setup->length)); 175 176 176 177 /* Data stage */ 177 xhci_trb_t trb_data; 178 xhci_trb_clean(&trb_data); 179 178 xhci_trb_t *trb_data = NULL; 180 179 if (setup->length > 0) { 181 trb_data.parameter = addr_to_phys(transfer->hc_buffer); 180 trb_data = trbs + trbs_used++; 181 xhci_trb_clean(trb_data); 182 183 trb_data->parameter = addr_to_phys(transfer->hc_buffer); 182 184 183 185 // data size (sent for OUT, or buffer size) 184 TRB_CTRL_SET_XFER_LEN( trb_data, batch->buffer_size);186 TRB_CTRL_SET_XFER_LEN(*trb_data, batch->buffer_size); 185 187 // FIXME: TD size 4.11.2.4 186 TRB_CTRL_SET_TD_SIZE(trb_data, 1); 187 188 // if we want an interrupt after this td is done, use 189 // TRB_CTRL_SET_IOC(trb_data, 1); 188 TRB_CTRL_SET_TD_SIZE(*trb_data, 1); 190 189 191 190 // Some more fields here, no idea what they mean 192 TRB_CTRL_SET_TRB_TYPE( trb_data, XHCI_TRB_TYPE_DATA_STAGE);191 TRB_CTRL_SET_TRB_TYPE(*trb_data, XHCI_TRB_TYPE_DATA_STAGE); 193 192 194 193 transfer->direction = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type) 195 194 ? STAGE_IN : STAGE_OUT; 196 TRB_CTRL_SET_DIR( trb_data, transfer->direction);195 TRB_CTRL_SET_DIR(*trb_data, transfer->direction); 197 196 } 198 197 199 198 /* Status stage */ 200 xhci_trb_t trb_status;201 xhci_trb_clean( &trb_status);199 xhci_trb_t *trb_status = trbs + trbs_used++; 200 xhci_trb_clean(trb_status); 202 201 203 202 // FIXME: Evaluate next TRB? 4.12.3 204 // TRB_CTRL_SET_ENT(trb_status, 1); 205 206 // if we want an interrupt after this td is done, use 207 TRB_CTRL_SET_IOC(trb_status, 1); 208 209 TRB_CTRL_SET_TRB_TYPE(trb_status, XHCI_TRB_TYPE_STATUS_STAGE); 210 TRB_CTRL_SET_DIR(trb_status, get_status_direction_flag(&trb_setup, setup->request_type, setup->length)); 203 // TRB_CTRL_SET_ENT(*trb_status, 1); 204 205 TRB_CTRL_SET_IOC(*trb_status, 1); 206 TRB_CTRL_SET_TRB_TYPE(*trb_status, XHCI_TRB_TYPE_STATUS_STAGE); 207 TRB_CTRL_SET_DIR(*trb_status, get_status_direction_flag(trb_setup, setup->request_type, setup->length)); 211 208 212 209 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep); … … 214 211 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[batch->ep->target.endpoint]; 215 212 216 uintptr_t dummy = 0; 217 xhci_trb_ring_enqueue(ring, &trb_setup, &dummy); 218 if (setup->length > 0) { 219 xhci_trb_ring_enqueue(ring, &trb_data, &dummy); 220 } 221 xhci_trb_ring_enqueue(ring, &trb_status, &transfer->interrupt_trb_phys); 213 int err = xhci_trb_ring_enqueue_multiple(ring, trbs, trbs_used, &transfer->interrupt_trb_phys); 214 if (err != EOK) 215 return err; 222 216 223 217 list_append(&transfer->link, &hc->transfers); … … 226 220 if (configure_endpoint_needed(setup)) { 227 221 // TODO: figure out the best time to issue this command 228 // FIXME: ignoring return code 229 xhci_device_configure(xhci_ep->device, hc); 222 // FIXME: on fail, we need to "cancel" in-flight TRBs and remove transfer from the list 223 err = xhci_device_configure(xhci_ep->device, hc); 224 if (err != EOK) 225 return err; 230 226 } 231 227 -
uspace/drv/bus/usb/xhci/trb_ring.c
r1252e81 rd1d7a92 116 116 fibril_mutex_initialize(&ring->guard); 117 117 118 usb_log_debug ("Initialized new TRB ring.");118 usb_log_debug2("Initialized new TRB ring."); 119 119 120 120 return EOK; … … 156 156 157 157 /** 158 * Enqueue a TDcomposed of TRBs.159 * 160 * This will copy all TRBs chained together into the ring. The cycle flag in161 * TRBs may be changed.162 * 163 * The c hained TRBs must be contiguous in memory, and must not contain Link TRBs.158 * Enqueue TDs composed of TRBs. 159 * 160 * This will copy specified number of TRBs chained together into the ring. The 161 * cycle flag in TRBs may be changed. 162 * 163 * The copied TRBs must be contiguous in memory, and must not contain Link TRBs. 164 164 * 165 165 * We cannot avoid the copying, because the TRB in ring should be updated atomically. 166 166 * 167 * @param td the first TRB of TD 168 * @param phys returns address of the first TRB enqueued 167 * @param first_trb the first TRB 168 * @param trbs number of TRBS to enqueue 169 * @param phys returns address of the last TRB enqueued 169 170 * @return EOK on success, 170 171 * EAGAIN when the ring is too full to fit all TRBs (temporary) 171 172 */ 172 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys) 173 { 173 int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *ring, xhci_trb_t *first_trb, 174 size_t trbs, uintptr_t *phys) 175 { 176 assert(trbs > 0); 174 177 fibril_mutex_lock(&ring->guard); 175 178 … … 183 186 * be full anytime during the transaction. 184 187 */ 185 xhci_trb_t *trb = td;186 do{188 xhci_trb_t *trb = first_trb; 189 for (size_t i = 0; i < trbs; ++i, ++trb) { 187 190 ring->enqueue_trb++; 188 191 … … 192 195 if (trb_ring_enqueue_phys(ring) == ring->dequeue) 193 196 goto err_again; 194 } while (xhci_trb_is_chained(trb++));197 } 195 198 196 199 ring->enqueue_segment = saved_enqueue_segment; 197 200 ring->enqueue_trb = saved_enqueue_trb; 198 if (phys)199 *phys = trb_ring_enqueue_phys(ring);200 201 201 202 /* 202 203 * Now, copy the TRBs without further checking. 203 204 */ 204 trb = td; 205 do { 205 trb = first_trb; 206 for (size_t i = 0; i < trbs; ++i, ++trb) { 207 if (phys && i == trbs - 1) 208 *phys = trb_ring_enqueue_phys(ring); 209 206 210 xhci_trb_set_cycle(trb, ring->pcs); 207 211 xhci_trb_copy(ring->enqueue_trb, trb); … … 221 225 trb_ring_resolve_link(ring); 222 226 } 223 } while (xhci_trb_is_chained(trb++));227 } 224 228 225 229 fibril_mutex_unlock(&ring->guard); … … 234 238 235 239 /** 240 * Enqueue TD composed of a single TRB. See: `xhci_trb_ring_enqueue_multiple` 241 */ 242 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys) 243 { 244 return xhci_trb_ring_enqueue_multiple(ring, td, 1, phys); 245 } 246 247 /** 236 248 * Initializes an event ring. 237 249 * Even when it fails, the structure needs to be finalized. -
uspace/drv/bus/usb/xhci/trb_ring.h
r1252e81 rd1d7a92 76 76 int xhci_trb_ring_fini(xhci_trb_ring_t *); 77 77 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *); 78 int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *, xhci_trb_t *, size_t, uintptr_t *); 78 79 79 80 /**
Note:
See TracChangeset
for help on using the changeset viewer.