My current problem is that when I try to perform Address Command with BSR=0, it return Completion Code 0x11 (context parameter error), but I can't find out the mistake.
The structure of my code:
1.Detect USB Device Attachment and reset the port(for USB2)
2.Enable the slot
3.Initialite the input context
4.Perform Address Command with BSR=1
5.Perform Address Command with BSR=0
...
When I try to delete step 4, the controller returns the code 0x4 (USB Transaction Error)
And I have tried hundreds of methods to sovle the problem, but I failed.
Here is my code:
Code: Select all
struct xHCI_EXTRA *xHCI_extra = du->spe.xhci.xhci_extra;
struct Message_reader *mr = get_currunt_process_message_addr();
char num_64_msg[] = "xxxxxxxxxxxxxxxx";
// print(0xffffffff, 0xff000000, a);
if ((xHCIportinf[portID] & 0xff) < 0x30)
{
// USB2 PORT
xHCI_extra->opr->PRS[portID].PORTSC |= 1 << 4; // reset
while ((xHCI_extra->opr->PRS[portID].PORTSC & (1 << 4)) || (xHCI_extra->opr->PRS[portID].PORTSC & 0x1e0))
{
/* code */
}
// m = (*wait_for_message_p)(mr, &m, 0b111);
// (*print_p)(INF (*long_longToChar16_p)(portID, num_64_msg));
if (xHCI_extra->opr->PRS[portID].PORTSC & 0x200000)
{
xHCI_extra->opr->PRS[portID].PORTSC = xHCI_extra->opr->PRS[portID].PORTSC;
}
char usb2_msg[] = "USB2 Port Attachment\n";
print(INF usb2_msg);
// break; // error
}
else
{
// USB3 PORT
while (((xHCI_extra->opr->PRS[portID].PORTSC >> 5) & 0xf) != 0)
{
// active_switch();
}
char usb3_msg[] = "USB3 Port Attachment\n";
print(INF usb3_msg);
}
struct xHCIEnableSlotCommandTRB cmd_es = {0};
// cmd_es.SlotType = (xHCI_port_usb_type[portID] >> 8) & 0xff;
cmd_es.SlotType = portID;
cmd_es.TRBType = 9;
xHCI_place_trb(&du->spe.xhci.xhci_extra->crcr, &cmd_es);
xHCI_extra->db[0] = 0;
struct Message escmd_m = {
.message_type = MSG_TYPE_XHCI,
.message_content = 9, // Enable Slot Command
.message_status = 0
};
escmd_m = wait_for_message(mr, &escmd_m, 0b1110);
char msg_cmd[] = "[PDD] Enabled Slot!\n";
print(0xffffffff, 0xff000000, msg_cmd);
print(INF long_longToChar16(escmd_m.message_content, num_64_msg));
struct xHCICommandCompletionEventTRB t_event = *((struct xHCICommandCompletionEventTRB *) escmd_m.extra);
struct xHCILinkTRB *TRDequeuePointer = alloc_ring(1);
void *input_context_addr = kernelMalloc(_4KB, WB);
unsigned int MaxPacketSize = xHCIget_MaxPacketSize_byPortID(du, portID);
MaxPacketSize = 16;
if (xHCI_extra->cap->HCCPARAMS1 & 4)
{
// 64 Byte
struct xHCIInputContext64 *input_context = input_context_addr;
input_context->InputControlContext.A |= 0b11;
input_context->DeviceContext.SlotContext.RootHubPortNumber = portID + 1;
input_context->DeviceContext.SlotContext.ContextEntries = 1;
input_context->DeviceContext.EPContext0BiDir.EPType = 4;
input_context->DeviceContext.SlotContext.Speed = (xHCI_extra->opr->PRS[portID].PORTSC >> 10) & 0xf;
input_context->DeviceContext.EPContext0BiDir.MaxPacketSize = MaxPacketSize;
input_context->DeviceContext.SlotContext.SlotState = 1;
input_context->DeviceContext.EPContext0BiDir.TRDequeuePointer = ((unsigned long long) GetPaddr(TRDequeuePointer)) | 1;
input_context->DeviceContext.EPContext0BiDir.CErr = 3;
input_context->DeviceContext.EPContext0BiDir.AverageTRBLength = 8;
xHCI_extra->DCBAAP[t_event.SlotID] = GetPaddr(input_context) + (((unsigned long long) &input_context->DeviceContext) & 0xfff);
}
else
{
// 32 Byte
input_context_addr += 32; // To Ensure Boundary
struct xHCIInputContext32 *input_context = input_context_addr;
input_context->InputControlContext.A |= 0b11;
input_context->DeviceContext.SlotContext.RootHubPortNumber = portID + 1;
input_context->DeviceContext.SlotContext.ContextEntries = 1;
input_context->DeviceContext.EPContext0BiDir.EPType = 4;
input_context->DeviceContext.SlotContext.Speed = (xHCI_extra->opr->PRS[portID].PORTSC >> 10) & 0xf;
input_context->DeviceContext.SlotContext.SlotState = 1;
input_context->DeviceContext.EPContext0BiDir.MaxPacketSize = MaxPacketSize;
input_context->DeviceContext.EPContext0BiDir.TRDequeuePointer = ((unsigned long long) GetPaddr(TRDequeuePointer)) | 1;
input_context->DeviceContext.EPContext0BiDir.CErr = 3;
input_context->DeviceContext.EPContext0BiDir.AverageTRBLength = 8;
xHCI_extra->DCBAAP[t_event.SlotID] = GetPaddr(input_context) + (((unsigned long long) &input_context->DeviceContext) & 0xfff);
}
struct xHCIAddressDeviceCommandTRB cmd_ad = {0};
cmd_ad.InputContextPointer = GetPaddr(input_context_addr) + (((unsigned long long) input_context_addr) & 0xfff);
cmd_ad.SlotID = t_event.SlotID;
cmd_ad.TRBType = 11;
cmd_ad.BSR = 1;
xHCI_place_trb(&du->spe.xhci.xhci_extra->crcr, &cmd_ad);
xHCI_extra->db[0] = 0;
struct Message adcmd_m = {
.message_type = MSG_TYPE_XHCI,
.message_content = 11,
.message_status = 0
};
wait_for_message(mr, &adcmd_m, 0b1110);
if (xHCI_extra->cap->HCCPARAMS1 & 4)
{
struct xHCIInputContext64 *input_context = input_context_addr;
input_context->DeviceContext.SlotContext.USBDeviceAddress = 0;
}
else
{
struct xHCIInputContext32 *input_context = input_context_addr;
input_context->DeviceContext.SlotContext.USBDeviceAddress = 0;
}
cmd_ad.BSR = 0;
xHCI_place_trb(&du->spe.xhci.xhci_extra->crcr, &cmd_ad);
xHCI_extra->db[0] = 0;
......