[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
//
Status = CreateQueueHead(&QueueHead);
Status = CreateQueueHead(&QueueHead);
if (!NT_SUCCESS(Status))
{
//
// 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();
if (!NT_SUCCESS(Status))
{
//
// failed to allocate setup packet
//
ASSERT(FALSE);
return STATUS_INSUFFICIENT_RESOURCES;
// failed to create setup packet
DPRINT1("[EHCI] Failed to create setup packet\n");
// release queue head
m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
return Status;
}
//
@ -869,10 +871,17 @@ CUSBRequest::BuildControlTransferQueueHead(
Status = CreateDescriptor(&SetupDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to allocate transfer descriptor
//
ASSERT(FALSE);
// failed to create setup transfer descriptor
DPRINT1("[EHCI] Failed to create setup descriptor\n");
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;
}
@ -882,10 +891,20 @@ CUSBRequest::BuildControlTransferQueueHead(
Status = CreateDescriptor(&StatusDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to allocate transfer descriptor
//
ASSERT(FALSE);
// failed to create status transfer descriptor
DPRINT1("[EHCI] Failed to create status descriptor\n");
// 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;
}
@ -928,11 +947,28 @@ CUSBRequest::BuildControlTransferQueueHead(
&LastDescriptor,
NULL,
&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)
{
DPRINT1("DescriptorChainLength %x\n", DescriptorChainLength);
@ -1075,13 +1111,13 @@ CUSBRequest::BuildBulkInterruptTransferQueueHead(
// Allocate the queue head
//
Status = CreateQueueHead(&QueueHead);
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,
&m_EndpointDescriptor->DataToggle,
&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
//
m_TransferBufferLengthCompleted += ChainDescriptorLength;
ASSERT(Status == STATUS_SUCCESS);
//
// init queue head
//
@ -1228,7 +1271,6 @@ CUSBRequest::CreateQueueHead(
// allocate queue head
//
Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysicalAddress);
if (!NT_SUCCESS(Status))
{
//

View file

@ -1288,6 +1288,14 @@ CUSBRequest::BuildBulkInterruptEndpoint(
&FirstDescriptor,
&LastDescriptor,
&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

View file

@ -1008,7 +1008,7 @@ CUSBRequest::BuildBulkInterruptTransferDescriptor(
Status = BuildQueueHead(&QueueHead);
if (!NT_SUCCESS(Status))
{
// failed to allocate descriptor
// failed to allocate queue head
DPRINT1("[UHCI] Failed to create queue head\n");
return Status;
}
@ -1040,6 +1040,15 @@ CUSBRequest::BuildBulkInterruptTransferDescriptor(
&LastDescriptor,
&ChainDescriptorLength,
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
m_TransferBufferLengthCompleted += ChainDescriptorLength;
@ -1076,7 +1085,7 @@ CUSBRequest::BuildControlTransferDescriptor(
if (!NT_SUCCESS(Status))
{
//
// failed to allocate descriptor
// failed to allocate queue head
//
DPRINT1("[UHCI] Failed to create queue head\n");
return Status;