Ticket #8954: 0001-XHCI-Fixes.patch
File 0001-XHCI-Fixes.patch, 25.2 KB (added by , 10 years ago) |
---|
-
src/add-ons/kernel/bus_managers/usb/Hub.cpp
From fa65d07bccd74aa39413a44ec3aa611e96af642c Mon Sep 17 00:00:00 2001 From: Akshay Jaggi <akshay1994.leo@gmail.com> Date: Sat, 28 Jun 2014 17:03:12 +0000 Subject: [PATCH] XHCI Fixes -Add Hub Support -Prevent Page Fault in FinishThread -Setting fCapabilityLength -Correction in BIOS ownership code -Fix Context Errors in _InsertEndpointForPipe -Updated constants according to latest Specification (v1.1) -Fix SMI code -Fix Memory/Device-Slot leaks -Fix Allocate Area for TRBs -Fix for Intel Lynx Point and Panther Point Chipsets --- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 4 +- src/add-ons/kernel/bus_managers/usb/Stack.cpp | 2 +- src/add-ons/kernel/bus_managers/usb/usb_private.h | 3 +- src/add-ons/kernel/busses/usb/xhci.cpp | 297 ++++++++++++++++++---- src/add-ons/kernel/busses/usb/xhci.h | 2 + src/add-ons/kernel/busses/usb/xhci_hardware.h | 22 +- 6 files changed, 265 insertions(+), 65 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index a1f2d6b..3190018 100644
a b 17 17 18 18 Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort, 19 19 usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed, 20 bool isRootHub )20 bool isRootHub, void *controllerCookie) 21 21 : Device(parent, hubAddress, hubPort, desc, deviceAddress, speed, 22 isRootHub ),22 isRootHub, controllerCookie), 23 23 fInterruptPipe(NULL) 24 24 { 25 25 TRACE("creating hub\n"); -
src/add-ons/kernel/bus_managers/usb/Stack.cpp
diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 04ad075..7a562bc 100644
a b Stack::Stack() 61 61 // be enumerated as the last item. As this does not apply to us we have to 62 62 // ensure ordering using another method. 63 63 const char *moduleNames[] = { 64 "busses/usb/xhci", 64 65 "busses/usb/uhci", 65 66 "busses/usb/ohci", 66 67 "busses/usb/ehci", 67 "busses/usb/xhci",68 68 NULL 69 69 }; 70 70 -
src/add-ons/kernel/bus_managers/usb/usb_private.h
diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index 13c189b..8ca6b84 100644
a b public: 579 579 uint8 hubPort, 580 580 usb_device_descriptor &desc, 581 581 int8 deviceAddress, 582 usb_speed speed, bool isRootHub); 582 usb_speed speed, bool isRootHub, 583 void *controllerCookie = NULL); 583 584 virtual ~Hub(); 584 585 585 586 virtual status_t Changed(change_item **changeList, -
src/add-ons/kernel/busses/usb/xhci.cpp
diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index f53f721..2d1ca46 100644
a b 8 8 * Michael Lotz <mmlr@mlotz.ch> 9 9 * Jian Chiang <j.jian.chiang@gmail.com> 10 10 * Jérôme Duval <jerome.duval@gmail.com> 11 * Akshay Jaggi <akshay1994.leo@gmail.com> 11 12 */ 12 13 13 14 … … XHCI::XHCI(pci_info *info, Stack *stack) 174 175 175 176 uint32 hciCapLength = ReadCapReg32(XHCI_HCI_CAPLENGTH); 176 177 fCapabilityRegisters += offset; 178 fCapabilityLength = HCI_CAPLENGTH(hciCapLength); 177 179 TRACE("mapped capability length: 0x%" B_PRIx32 "\n", fCapabilityLength); 178 fOperationalRegisters = fCapabilityRegisters + HCI_CAPLENGTH(hciCapLength);180 fOperationalRegisters = fCapabilityRegisters + fCapabilityLength; 179 181 fRuntimeRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_RTSOFF); 180 182 fDoorbellRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_DBOFF); 181 183 TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters); … … XHCI::XHCI(pci_info *info, Stack *stack) 199 201 eec = ReadCapReg32(eecp); 200 202 if (XECP_ID(eec) != XHCI_LEGSUP_CAPID) 201 203 continue; 202 } 203 TRACE("eecp register: 0x%04" B_PRIx32 "\n", eecp); 204 if (eec & XHCI_LEGSUP_BIOSOWNED) { 205 TRACE_ALWAYS("the host controller is bios owned, claiming" 206 " ownership\n"); 207 WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED); 208 209 for (int32 i = 0; i < 20; i++) { 210 eec = ReadCapReg32(eecp); 211 212 if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0) 213 break; 214 215 TRACE_ALWAYS("controller is still bios owned, waiting\n"); 216 snooze(50000); 217 } 218 204 205 TRACE("eecp register: 0x%08" B_PRIx32 "\n", eecp); 219 206 if (eec & XHCI_LEGSUP_BIOSOWNED) { 220 TRACE_ERROR("bios won't give up control over the host " 221 "controller (ignoring)\n"); 222 } else if (eec & XHCI_LEGSUP_OSOWNED) { 223 TRACE_ALWAYS("successfully took ownership of the host " 224 "controller\n"); 207 TRACE_ALWAYS("the host controller is bios owned, claiming" 208 " ownership\n"); 209 WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED); 210 211 for (int32 i = 0; i < 20; i++) { 212 eec = ReadCapReg32(eecp); 213 214 if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0) 215 break; 216 217 TRACE_ALWAYS("controller is still bios owned, waiting\n"); 218 snooze(50000); 219 } 220 221 if (eec & XHCI_LEGSUP_BIOSOWNED) { 222 TRACE_ERROR("bios won't give up control over the host " 223 "controller (ignoring)\n"); 224 } else if (eec & XHCI_LEGSUP_OSOWNED) { 225 TRACE_ALWAYS("successfully took ownership of the host " 226 "controller\n"); 227 } 228 229 // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes 230 // do indicate a successful handover but do not remove their SMIs 231 // and then freeze the system when interrupts are generated. 232 WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED); 225 233 } 226 227 // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes 228 // do indicate a successful handover but do not remove their SMIs 229 // and then freeze the system when interrupts are generated. 230 WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED); 234 break; 235 } 236 uint32 legctlsts = ReadCapReg32(eecp + XHCI_LEGCTLSTS); 237 legctlsts &= XHCI_LEGCTLSTS_DISABLE_SMI; 238 legctlsts |= XHCI_LEGCTLSTS_EVENTS_SMI; 239 WriteCapReg32(eecp + XHCI_LEGCTLSTS, legctlsts); 240 241 // On Intel's Panther Point and Lynx Point Chipset taking ownership 242 // of EHCI owned ports, is what we do here. 243 if(fPCIInfo->vendor_id == PCI_VENDOR_ID_INTEL 244 && (fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_PANTHER_POINT_XHCI 245 || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 246 || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI)) { 247 248 TRACE("Intel xHC Controller\n"); 249 TRACE("Looking for EHCI owned ports\n"); 250 251 uint32 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 252 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3PRM, 4); 253 254 TRACE("Superspeed Ports: 0x%"B_PRIx32"\n", ports); 255 256 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 257 fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4, ports); 258 259 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 260 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4); 261 262 TRACE("Superspeed ports now under XHCI : 0x%"B_PRIx32"\n", ports); 263 264 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 265 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB2PRM, 4); 266 267 TRACE("USB 2.0 Ports : 0x%"B_PRIx32"\n", ports); 268 269 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 270 fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4, ports); 271 272 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 273 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4); 274 275 TRACE("USB 2.0 ports now under XHCI: 0x%"B_PRIx32"\n", ports); 231 276 } 232 WriteCapReg32(eecp + XHCI_LEGCTLSTS, XHCI_LEGCTLSTS_DISABLE_SMI);233 277 234 278 // halt the host controller 235 279 if (ControllerHalt() < B_OK) { … … XHCI::Start() 337 381 } 338 382 339 383 // read port count from capability register 340 uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1); 341 384 uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1); 342 385 fPortCount = HCS_MAX_PORTS(capabilities); 343 386 if (fPortCount == 0) { 344 387 TRACE_ERROR("Invalid number of ports: %u\n", fPortCount); … … XHCI::SubmitControlRequest(Transfer *transfer) 574 617 xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); 575 618 uint8 id = XHCI_ENDPOINT_ID(pipe); 576 619 if (id >= XHCI_MAX_ENDPOINTS) 620 { 621 TRACE_ERROR("Invalid Endpoint"); 577 622 return B_BAD_VALUE; 623 } 578 624 setupDescriptor->transfer = transfer; 625 transfer->InitKernelAccess(); 579 626 _LinkDescriptorForPipe(setupDescriptor, endpoint); 580 627 581 628 TRACE("SubmitControlRequest() request linked\n"); 582 629 630 TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n", 631 endpoint->device->device_ctx->endpoints[id-1].dwendpoint0, 632 endpoint->device->device_ctx->endpoints[id-1].dwendpoint1, 633 endpoint->device->device_ctx->endpoints[id-1].qwendpoint2 634 ); 583 635 Ring(endpoint->device->slot, id); 584 636 TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n", 637 endpoint->device->device_ctx->endpoints[id-1].dwendpoint0, 638 endpoint->device->device_ctx->endpoints[id-1].dwendpoint1, 639 endpoint->device->device_ctx->endpoints[id-1].qwendpoint2 640 ); 585 641 return B_OK; 586 642 } 587 643 … … XHCI::SubmitNormalRequest(Transfer *transfer) 625 681 626 682 xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); 627 683 descriptor->transfer = transfer; 684 transfer->InitKernelAccess(); 628 685 _LinkDescriptorForPipe(descriptor, endpoint); 629 686 630 687 TRACE("SubmitNormalRequest() request linked\n"); 631 688 689 TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n", 690 (endpoint->device->device_ctx->endpoints[id-1]).dwendpoint0, 691 endpoint->device->device_ctx->endpoints[id-1].dwendpoint1, 692 endpoint->device->device_ctx->endpoints[id-1].qwendpoint2 693 ); 632 694 Ring(endpoint->device->slot, id); 695 TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n", 696 endpoint->device->device_ctx->endpoints[id-1].dwendpoint0, 697 endpoint->device->device_ctx->endpoints[id-1].dwendpoint1, 698 endpoint->device->device_ctx->endpoints[id-1].qwendpoint2 699 ); 633 700 634 701 return B_OK; 635 702 } … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 994 1061 "XHCI input context"); 995 1062 if (device->input_ctx_area < B_OK) { 996 1063 TRACE_ERROR("unable to create a input context area\n"); 1064 device->state = XHCI_STATE_DISABLED; 997 1065 return NULL; 998 1066 } 999 1067 … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1003 1071 1004 1072 uint32 route = 0; 1005 1073 uint8 routePort = hubPort; 1006 uint8 rhPort = 0;1074 uint8 rhPort = hubPort; 1007 1075 for (Device *hubDevice = parent; hubDevice != RootObject(); 1008 1076 hubDevice = (Device *)hubDevice->Parent()) { 1009 1077 … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1020 1088 } 1021 1089 1022 1090 device->input_ctx->slot.dwslot0 = SLOT_0_NUM_ENTRIES(1) | SLOT_0_ROUTE(route); 1023 //device->input_ctx->slot.dwslot0 =1024 // SLOT_0_NUM_ENTRIES(XHCI_MAX_ENDPOINTS - 1) | SLOT_0_ROUTE(route);1025 1091 1026 1092 // add the speed 1027 1093 switch (speed) { … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1059 1125 "XHCI device context"); 1060 1126 if (device->device_ctx_area < B_OK) { 1061 1127 TRACE_ERROR("unable to create a device context area\n"); 1128 device->state = XHCI_STATE_DISABLED; 1062 1129 delete_area(device->input_ctx_area); 1063 1130 return NULL; 1064 1131 } 1065 1132 memset(device->device_ctx, 0, sizeof(*device->device_ctx)); 1066 1133 1067 1134 device->trb_area = fStack->AllocateArea((void **)&device->trbs, 1068 &device->trb_addr, sizeof(*device->trbs) , "XHCI endpoint trbs");1135 &device->trb_addr, sizeof(*device->trbs)*(XHCI_MAX_ENDPOINTS-1)*(XHCI_MAX_TRANSFERS), "XHCI endpoint trbs"); 1069 1136 if (device->trb_area < B_OK) { 1070 1137 TRACE_ERROR("unable to create a device trbs area\n"); 1138 device->state = XHCI_STATE_DISABLED; 1071 1139 delete_area(device->input_ctx_area); 1072 1140 delete_area(device->device_ctx_area); 1073 1141 return NULL; … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1102 1170 if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1, 1, 0, 1103 1171 maxPacketSize, maxPacketSize, speed) != B_OK) { 1104 1172 TRACE_ERROR("unable to configure default control endpoint\n"); 1173 device->state = XHCI_STATE_DISABLED; 1174 delete_area(device->input_ctx_area); 1175 delete_area(device->device_ctx_area); 1176 delete_area(device->trb_area); 1105 1177 return NULL; 1106 1178 } 1107 1179 … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1116 1188 // device should get to addressed state (bsr = 0) 1117 1189 if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) { 1118 1190 TRACE_ERROR("unable to set address\n"); 1191 device->state = XHCI_STATE_DISABLED; 1192 delete_area(device->input_ctx_area); 1193 delete_area(device->device_ctx_area); 1194 delete_area(device->trb_area); 1119 1195 return NULL; 1120 1196 } 1121 1197 … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1154 1230 1155 1231 if (actualLength != 8) { 1156 1232 TRACE_ERROR("error while getting the device descriptor\n"); 1233 device->state = XHCI_STATE_DISABLED; 1234 delete_area(device->input_ctx_area); 1235 delete_area(device->device_ctx_area); 1236 delete_area(device->trb_area); 1157 1237 return NULL; 1158 1238 } 1159 1239 … … XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1161 1241 deviceDescriptor.device_class, deviceDescriptor.device_subclass, 1162 1242 deviceDescriptor.device_protocol); 1163 1243 1244 if(deviceDescriptor.device_class==0x09) 1245 { 1246 TRACE("creating new HUB\n"); 1247 TRACE("getting the hub descriptor\n"); 1248 size_t actualLength = 0; 1249 usb_hub_descriptor hubDescriptor; 1250 pipe.SendRequest( 1251 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 1252 USB_REQUEST_GET_DESCRIPTOR, // request 1253 USB_DESCRIPTOR_HUB << 8, // value 1254 0, // index 1255 sizeof(usb_hub_descriptor), // length 1256 (void *)&hubDescriptor, // buffer 1257 sizeof(usb_hub_descriptor), // buffer length 1258 &actualLength); 1259 1260 if(actualLength!=sizeof(usb_hub_descriptor)) 1261 { 1262 TRACE_ERROR("error while getting the hub descriptor\n"); 1263 device->state = XHCI_STATE_DISABLED; 1264 delete_area(device->input_ctx_area); 1265 delete_area(device->device_ctx_area); 1266 delete_area(device->trb_area); 1267 return NULL; 1268 } 1269 1270 device->input_ctx->slot.dwslot0 |= SLOT_0_HUB_BIT; 1271 device->input_ctx->slot.dwslot1 |= SLOT_1_NUM_PORTS(hubDescriptor.num_ports); 1272 if(speed == USB_SPEED_HIGHSPEED) 1273 { 1274 device->input_ctx->slot.dwslot2 |= SLOT_2_TT_TIME(HUB_TTT_GET(hubDescriptor.characteristics)); 1275 } 1276 1277 Hub *hub = new(std::nothrow) Hub(parent, hubAddress, hubPort, 1278 deviceDescriptor, device->address + 1, speed, false, device); 1279 if(!hub) 1280 { 1281 TRACE_ERROR("no memory to allocate hub\n"); 1282 device->state = XHCI_STATE_DISABLED; 1283 delete_area(device->input_ctx_area); 1284 delete_area(device->device_ctx_area); 1285 delete_area(device->trb_area); 1286 return NULL; 1287 } 1288 fPortSlots[hubPort] = slot; 1289 TRACE("AllocateDevice() port %d slot %d\n", hubPort, slot); 1290 return (Device *)hub; 1291 } 1164 1292 TRACE("creating new device\n"); 1165 1293 Device *deviceObject = new(std::nothrow) Device(parent, hubAddress, hubPort, 1166 1294 deviceDescriptor, device->address + 1, speed, false, device); 1167 1295 if (!deviceObject) { 1168 1296 TRACE_ERROR("no memory to allocate device\n"); 1297 device->state = XHCI_STATE_DISABLED; 1298 delete_area(device->input_ctx_area); 1299 delete_area(device->device_ctx_area); 1300 delete_area(device->trb_area); 1169 1301 return NULL; 1170 1302 } 1171 1303 fPortSlots[hubPort] = slot; … … XHCI::FreeDevice(Device *device) 1193 1325 status_t 1194 1326 XHCI::_InsertEndpointForPipe(Pipe *pipe) 1195 1327 { 1328 TRACE("_InsertEndpointForPipe endpoint address %"B_PRId8"\n", pipe->EndpointAddress()); 1196 1329 if (pipe->ControllerCookie() != NULL 1197 1330 || pipe->Parent()->Type() != USB_OBJECT_DEVICE) { 1198 1331 // default pipe is already referenced … … XHCI::_InsertEndpointForPipe(Pipe *pipe) 1278 1411 TRACE("endpoint[%d] state 0x%" B_PRIx32 "\n", id, 1279 1412 ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[id].dwendpoint0)); 1280 1413 device->state = XHCI_STATE_CONFIGURED; 1414 1281 1415 } 1282 1416 pipe->SetControllerCookie(&device->endpoints[id]); 1283 1417 … … XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) 1304 1438 TRACE("_LinkDescriptorForPipe\n"); 1305 1439 MutexLocker endpointLocker(endpoint->lock); 1306 1440 if (endpoint->used >= XHCI_MAX_TRANSFERS) 1441 { 1442 TRACE_ERROR("MISS-FIRE MISS-FIRE\n"); 1307 1443 return B_BAD_VALUE; 1444 } 1308 1445 1309 1446 endpoint->used++; 1310 1447 if (endpoint->td_head == NULL) … … XHCI::GetPortStatus(uint8 index, usb_port_status *status) 1468 1605 1469 1606 status->status = status->change = 0; 1470 1607 uint32 portStatus = ReadOpReg(XHCI_PORTSC(index)); 1471 //TRACE("port status=0x%08lx\n", portStatus);1608 TRACE("port %" B_PRId8 " status=0x%08" B_PRIx32 "\n", index, portStatus); 1472 1609 1473 1610 // build the status 1474 1611 switch (PS_SPEED_GET(portStatus)) { … … XHCI::HandleTransferComplete(xhci_trb *trb) 1767 1904 { 1768 1905 TRACE("HandleTransferComplete trb %p\n", trb); 1769 1906 addr_t source = trb->qwtrb0; 1770 //uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2);1771 //uint32 remainder = TRB_2_REM_GET(trb->dwtrb2);1907 uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2); 1908 uint32 remainder = TRB_2_REM_GET(trb->dwtrb2); 1772 1909 uint8 endpointNumber = TRB_3_ENDPOINT_GET(trb->dwtrb3); 1773 1910 uint8 slot = TRB_3_SLOT_GET(trb->dwtrb3); 1774 1911 … … XHCI::HandleTransferComplete(xhci_trb *trb) 1785 1922 offset); 1786 1923 (void)offset; 1787 1924 _UnlinkDescriptorForPipe(td, endpoint); 1788 1925 td->trb_completion_code = completionCode; 1926 td->trb_left = remainder; 1789 1927 // add descriptor to finished list (to be processed and freed) 1790 1928 Lock(); 1791 1929 td->next = fFinishedHead; … … XHCI::DoCommand(xhci_trb *trb) 1838 1976 status_t 1839 1977 XHCI::Noop() 1840 1978 { 1979 TRACE("Noop\n"); 1841 1980 xhci_trb trb; 1842 1981 trb.qwtrb0 = 0; 1843 1982 trb.dwtrb2 = 0; … … XHCI::Noop() 1850 1989 status_t 1851 1990 XHCI::EnableSlot(uint8 *slot) 1852 1991 { 1992 TRACE("Enable Slot\n"); 1853 1993 xhci_trb trb; 1854 1994 trb.qwtrb0 = 0; 1855 1995 trb.dwtrb2 = 0; … … XHCI::EnableSlot(uint8 *slot) 1867 2007 status_t 1868 2008 XHCI::DisableSlot(uint8 slot) 1869 2009 { 2010 TRACE("Disable Slot\n"); 1870 2011 xhci_trb trb; 1871 2012 trb.qwtrb0 = 0; 1872 2013 trb.dwtrb2 = 0; … … XHCI::DisableSlot(uint8 slot) 1879 2020 status_t 1880 2021 XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot) 1881 2022 { 2023 TRACE("Set Address\n"); 1882 2024 xhci_trb trb; 1883 2025 trb.qwtrb0 = inputContext; 1884 2026 trb.dwtrb2 = 0; … … XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot) 1894 2036 status_t 1895 2037 XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot) 1896 2038 { 2039 TRACE("Configure Endpoint\n"); 1897 2040 xhci_trb trb; 1898 2041 trb.qwtrb0 = inputContext; 1899 2042 trb.dwtrb2 = 0; … … XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot) 1909 2052 status_t 1910 2053 XHCI::EvaluateContext(uint64 inputContext, uint8 slot) 1911 2054 { 2055 TRACE("Evaluate Context\n"); 1912 2056 xhci_trb trb; 1913 2057 trb.qwtrb0 = inputContext; 1914 2058 trb.dwtrb2 = 0; … … XHCI::EvaluateContext(uint64 inputContext, uint8 slot) 1921 2065 status_t 1922 2066 XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot) 1923 2067 { 2068 TRACE("Reset Endpoint\n"); 1924 2069 xhci_trb trb; 1925 2070 trb.qwtrb0 = 0; 1926 2071 trb.dwtrb2 = 0; … … XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot) 1936 2081 status_t 1937 2082 XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot) 1938 2083 { 2084 TRACE("Stop Endpoint\n"); 1939 2085 xhci_trb trb; 1940 2086 trb.qwtrb0 = 0; 1941 2087 trb.dwtrb2 = 0; … … XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot) 1951 2097 status_t 1952 2098 XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot) 1953 2099 { 2100 TRACE("Set TR Dequeue\n"); 1954 2101 xhci_trb trb; 1955 2102 trb.qwtrb0 = dequeue; 1956 2103 trb.dwtrb2 = TRB_2_STREAM(stream); … … XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot) 1964 2111 status_t 1965 2112 XHCI::ResetDevice(uint8 slot) 1966 2113 { 2114 TRACE("Reset Device\n"); 1967 2115 xhci_trb trb; 1968 2116 trb.qwtrb0 = 0; 1969 2117 trb.dwtrb2 = 0; … … XHCI::CompleteEvents() 2000 2148 2001 2149 while (1) { 2002 2150 uint32 temp = fEventRing[i].dwtrb3; 2151 TRACE_ALWAYS("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08" 2152 B_PRIx32 ")\n", i, (uint8)TRB_3_TYPE_GET(temp), fEventRing[i].qwtrb0, 2153 fEventRing[i].dwtrb2, fEventRing[i].dwtrb3); 2003 2154 uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0; 2004 2155 if (j != k) 2005 2156 break; … … XHCI::FinishTransfers() 2073 2224 td->next = NULL; 2074 2225 Unlock(); 2075 2226 2227 TRACE("finishing transfer td %p\n", td); 2228 2076 2229 Transfer* transfer = td->transfer; 2077 2230 bool directionIn = (transfer->TransferPipe()->Direction() != Pipe::Out); 2078 2231 usb_request_data *requestData = transfer->RequestData(); 2079 2080 // TODO check event 2232 2081 2233 status_t callbackStatus = B_OK; 2082 size_t actualLength = requestData ? requestData->Length 2083 : transfer->DataLength(); 2084 TRACE("finishing transfer td %p\n", td); 2085 if (directionIn && actualLength > 0) { 2086 if (requestData) { 2087 TRACE("copying in data %d bytes\n", requestData->Length); 2088 memcpy((uint8 *)transfer->Vector()[0].iov_base, 2089 td->buffer_log[0], requestData->Length); 2090 } else { 2091 TRACE("copying in iov count %ld\n", transfer->VectorCount()); 2092 ReadDescriptorChain(td, transfer->Vector(), 2093 transfer->VectorCount()); 2234 switch(td->trb_completion_code) 2235 { 2236 case COMP_SHORT_PACKET: 2237 case COMP_SUCCESS: 2238 callbackStatus = B_OK; 2239 break; 2240 case COMP_DATA_BUFFER: 2241 callbackStatus = directionIn ? B_DEV_DATA_OVERRUN : B_DEV_DATA_UNDERRUN; 2242 break; 2243 case COMP_BABBLE: 2244 callbackStatus = directionIn ? B_DEV_FIFO_OVERRUN : B_DEV_FIFO_UNDERRUN; 2245 break; 2246 case COMP_USB_TRANSACTION: 2247 callbackStatus = B_DEV_CRC_ERROR; 2248 break; 2249 case COMP_STALL: 2250 callbackStatus = B_DEV_STALLED; 2251 break; 2252 default: 2253 callbackStatus = B_DEV_STALLED; 2254 break; 2255 } 2256 2257 size_t actualLength = 0; 2258 2259 if(callbackStatus == B_OK) 2260 { 2261 actualLength = requestData ? requestData->Length 2262 : transfer->DataLength(); 2263 2264 if(td->trb_completion_code == COMP_SHORT_PACKET) 2265 actualLength -= td->trb_left; 2266 2267 if (directionIn && actualLength > 0) { 2268 if (requestData) { 2269 TRACE("copying in data %d bytes\n", requestData->Length); 2270 transfer->PrepareKernelAccess(); 2271 memcpy((uint8 *)transfer->Vector()[0].iov_base, 2272 td->buffer_log[0], requestData->Length); 2273 } else { 2274 TRACE("copying in iov count %ld\n", transfer->VectorCount()); 2275 transfer->PrepareKernelAccess(); 2276 ReadDescriptorChain(td, transfer->Vector(), 2277 transfer->VectorCount()); 2278 } 2094 2279 } 2095 2280 } 2096 transfer->Finished(callbackStatus, actualLength); 2097 2281 transfer->Finished(callbackStatus, actualLength); 2282 delete transfer; 2098 2283 FreeDescriptor(td); 2099 2284 Lock(); 2100 2285 } -
src/add-ons/kernel/busses/usb/xhci.h
diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h index df4a597..0b130f0 100644
a b typedef struct xhci_td { 45 45 struct xhci_td *next; 46 46 Transfer *transfer; 47 47 uint8 trb_count; 48 uint8 trb_completion_code; 49 uint32 trb_left; 48 50 } xhci_td __attribute__((__aligned__(16))); 49 51 50 52 -
src/add-ons/kernel/busses/usb/xhci_hardware.h
diff --git a/src/add-ons/kernel/busses/usb/xhci_hardware.h b/src/add-ons/kernel/busses/usb/xhci_hardware.h index ebd3d43..64c282a 100644
a b 5 5 * Authors: 6 6 * Jian Chiang <j.jian.chiang@gmail.com> 7 7 * Jérôme Duval <jerome.duval@gmail.com> 8 * Akshay Jaggi <akshay1994.leo@gmail.com> 8 9 */ 9 10 #ifndef XHCI_HARDWARE_H 10 11 #define XHCI_HARDWARE_H 11 12 13 // Intel quirks 14 #define XHCI_INTEL_USB3PRM 0xDC // USB 3.0 Port Routing Mask 15 #define XHCI_INTEL_USB3_PSSEN 0xD8 // USB 3.0 Port SuperSpeed Enable 16 #define XHCI_INTEL_USB2PRM 0xD4 // USB 2.0 Port Routing Mask 17 #define XHCI_INTEL_XUSB2PR 0xD0 // USB 2.0 Port Routing 18 #define PCI_DEVICE_ID_INTEL_PANTHER_POINT_XHCI 0x1E31 19 #define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31 20 #define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31 21 #define PCI_VENDOR_ID_INTEL 0x8086 12 22 13 23 // Host Controller Capability Registers 14 24 #define XHCI_HCI_CAPLENGTH 0x00 // HCI Capability Register Length … … 17 27 #define XHCI_HCSPARAMS1 0x04 // Structural Parameters 1 18 28 // HCSPARAMS1 19 29 #define HCS_MAX_SLOTS(p) (((p) >> 0) & 0xff) 20 #define HCS_MAX_PORTS(p) (((p) >> 24) & 0x 7f)30 #define HCS_MAX_PORTS(p) (((p) >> 24) & 0xff) 21 31 #define XHCI_HCSPARAMS2 0x08 // Structural Parameters 2 22 32 #define HCS_IST(p) (((p) >> 0) & 0xf) 23 33 #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) 24 34 #define HCS_SPR(p) (((p) >> 26) & 0x1) 25 #define HCS_MAX_SC_BUFFERS(p) ((( p) >> 27) & 0x1f)35 #define HCS_MAX_SC_BUFFERS(p) (((((p) >> 21) & 0x1f)<<5)|(((p) >> 27) & 0x1f)) 26 36 #define XHCI_HCSPARAMS3 0x0C // Structural Parameters 3 27 37 #define HCS_U1_DEVICE_LATENCY(p) (((p) >> 0) & 0xff) 28 38 #define HCS_U2_DEVICE_LATENCY(p) (((p) >> 16) & 0xffff) … … 98 108 #define XHCI_LEGSUP_BIOSOWNED (1 << 16) // BIOS Owned Semaphore 99 109 100 110 #define XHCI_LEGCTLSTS 0x04 101 #define XHCI_LEGCTLSTS_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) 111 #define XHCI_LEGCTLSTS_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) 112 #define XHCI_LEGCTLSTS_EVENTS_SMI (0x7 << 29) 102 113 103 114 #define XHCI_SUPPORTED_PROTOCOLS_CAPID 0x02 104 115 #define XHCI_SUPPORTED_PROTOCOLS_0_MINOR(x) (((x) >> 16) & 0xff) … … struct xhci_slot_ctx { 336 347 #define SLOT_2_PORT_NUM_GET(x) (((x) >> 8) & 0xFF) 337 348 #define SLOT_2_TT_TIME(x) (((x) & 0x3) << 16) 338 349 #define SLOT_2_TT_TIME_GET(x) (((x) >> 16) & 0x3) 339 #define SLOT_2_IRQ_TARGET(x) (((x) & 0x 1F) << 27)340 #define SLOT_2_IRQ_TARGET_GET(x) (((x) >> 2 7) & 0x1f)350 #define SLOT_2_IRQ_TARGET(x) (((x) & 0x7F) << 22) 351 #define SLOT_2_IRQ_TARGET_GET(x) (((x) >> 22) & 0x7F) 341 352 342 353 #define SLOT_3_DEVICE_ADDRESS(x) ((x) & 0xFF) 343 354 #define SLOT_3_DEVICE_ADDRESS_GET(x) ((x) & 0xFF) 344 355 #define SLOT_3_SLOT_STATE(x) (((x) & 0x1F) << 27) 345 356 #define SLOT_3_SLOT_STATE_GET(x) (((x) >> 27) & 0x1F) 346 357 358 #define HUB_TTT_GET(x) (((x) >> 5) & 0x3) 347 359 348 360 struct xhci_endpoint_ctx { 349 361 uint32 dwendpoint0;