Changeset d1d7a92 in mainline for uspace/drv/bus/usb/xhci/transfers.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.