[USB(E|O|U)HCI]: Handle failure cases of BuildTransferDescriptorChain. By contributor 'vgal'. This is needed for gracefully handling failure cases hit during diagnosing CORE-8046.

CORE-10776

svn path=/trunk/; revision=70511
This commit is contained in:
Hermès Bélusca-Maïto 2016-01-06 23:43:38 +00:00
parent b932a314ce
commit 0f3e09ea77
3 changed files with 86 additions and 27 deletions

View file

@ -836,13 +836,14 @@ CUSBRequest::BuildControlTransferQueueHead(
// //
// first allocate the queue head // first allocate the queue head
// //
Status = CreateQueueHead(&QueueHead); Status = CreateQueueHead(&QueueHead);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
// failed to allocate queue head // failed to allocate queue head
// //
return STATUS_INSUFFICIENT_RESOURCES; DPRINT1("[EHCI] Failed to create queue head\n");
return Status;
} }
// //
@ -856,11 +857,12 @@ CUSBRequest::BuildControlTransferQueueHead(
Status = BuildSetupPacket(); Status = BuildSetupPacket();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// // failed to create setup packet
// failed to allocate setup packet DPRINT1("[EHCI] Failed to create setup packet\n");
//
ASSERT(FALSE); // release queue head
return STATUS_INSUFFICIENT_RESOURCES; m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status;
} }
// //
@ -869,10 +871,17 @@ CUSBRequest::BuildControlTransferQueueHead(
Status = CreateDescriptor(&SetupDescriptor); Status = CreateDescriptor(&SetupDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// // failed to create setup transfer descriptor
// failed to allocate transfer descriptor DPRINT1("[EHCI] Failed to create setup descriptor\n");
//
ASSERT(FALSE); if (m_DescriptorPacket)
{
// release packet descriptor
m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
}
// release queue head
m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status; return Status;
} }
@ -882,10 +891,20 @@ CUSBRequest::BuildControlTransferQueueHead(
Status = CreateDescriptor(&StatusDescriptor); Status = CreateDescriptor(&StatusDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// // failed to create status transfer descriptor
// failed to allocate transfer descriptor DPRINT1("[EHCI] Failed to create status descriptor\n");
//
ASSERT(FALSE); // release setup transfer descriptor
m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
if (m_DescriptorPacket)
{
// release packet descriptor
m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
}
// release queue head
m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status; return Status;
} }
@ -928,11 +947,28 @@ CUSBRequest::BuildControlTransferQueueHead(
&LastDescriptor, &LastDescriptor,
NULL, NULL,
&DescriptorChainLength); &DescriptorChainLength);
if (!NT_SUCCESS(Status))
{
// failed to create descriptor chain
DPRINT1("[EHCI] Failed to create status descriptor\n");
// release status transfer descriptor
m_DmaManager->Release(StatusDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
// release setup transfer descriptor
m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
if (m_DescriptorPacket)
{
// release packet descriptor
m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
}
// release queue head
m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status;
}
//
// FIXME handle errors
//
ASSERT(Status == STATUS_SUCCESS);
if (m_TransferBufferLength != DescriptorChainLength) if (m_TransferBufferLength != DescriptorChainLength)
{ {
DPRINT1("DescriptorChainLength %x\n", DescriptorChainLength); DPRINT1("DescriptorChainLength %x\n", DescriptorChainLength);
@ -1075,13 +1111,13 @@ CUSBRequest::BuildBulkInterruptTransferQueueHead(
// Allocate the queue head // Allocate the queue head
// //
Status = CreateQueueHead(&QueueHead); Status = CreateQueueHead(&QueueHead);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
// failed to allocate queue heads // failed to allocate queue head
// //
return STATUS_INSUFFICIENT_RESOURCES; DPRINT1("[EHCI] Failed to create queue head\n");
return Status;
} }
// //
@ -1128,14 +1164,21 @@ CUSBRequest::BuildBulkInterruptTransferQueueHead(
&LastDescriptor, &LastDescriptor,
&m_EndpointDescriptor->DataToggle, &m_EndpointDescriptor->DataToggle,
&ChainDescriptorLength); &ChainDescriptorLength);
if (!NT_SUCCESS(Status))
{
//
// failed to build transfer descriptor chain
//
DPRINT1("[EHCI] Failed to create descriptor chain\n");
m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status;
}
// //
// move to next offset // move to next offset
// //
m_TransferBufferLengthCompleted += ChainDescriptorLength; m_TransferBufferLengthCompleted += ChainDescriptorLength;
ASSERT(Status == STATUS_SUCCESS);
// //
// init queue head // init queue head
// //
@ -1228,7 +1271,6 @@ CUSBRequest::CreateQueueHead(
// allocate queue head // allocate queue head
// //
Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysicalAddress); Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysicalAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //

View file

@ -1288,6 +1288,14 @@ CUSBRequest::BuildBulkInterruptEndpoint(
&FirstDescriptor, &FirstDescriptor,
&LastDescriptor, &LastDescriptor,
&ChainDescriptorLength); &ChainDescriptorLength);
if (!NT_SUCCESS(Status))
{
//
// failed to build transfer descriptor chain
//
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
return Status;
}
// //
// move to next offset // move to next offset

View file

@ -1008,7 +1008,7 @@ CUSBRequest::BuildBulkInterruptTransferDescriptor(
Status = BuildQueueHead(&QueueHead); Status = BuildQueueHead(&QueueHead);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to allocate descriptor // failed to allocate queue head
DPRINT1("[UHCI] Failed to create queue head\n"); DPRINT1("[UHCI] Failed to create queue head\n");
return Status; return Status;
} }
@ -1040,6 +1040,15 @@ CUSBRequest::BuildBulkInterruptTransferDescriptor(
&LastDescriptor, &LastDescriptor,
&ChainDescriptorLength, &ChainDescriptorLength,
NULL); NULL);
if (!NT_SUCCESS(Status))
{
//
// failed to allocate descriptor
//
DPRINT1("[UHCI] Failed to create descriptor chain\n");
m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
return Status;
}
// adjust buffer offset // adjust buffer offset
m_TransferBufferLengthCompleted += ChainDescriptorLength; m_TransferBufferLengthCompleted += ChainDescriptorLength;
@ -1076,7 +1085,7 @@ CUSBRequest::BuildControlTransferDescriptor(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
// failed to allocate descriptor // failed to allocate queue head
// //
DPRINT1("[UHCI] Failed to create queue head\n"); DPRINT1("[UHCI] Failed to create queue head\n");
return Status; return Status;