Locking around descriptors list handling isn't enough, locking is also needed when traversing the list: we instead lock the whole traversing/handling loop.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -835,20 +835,16 @@ isochronous_transfer_data *
|
|||||||
EHCI::FindIsochronousTransfer(ehci_itd *itd)
|
EHCI::FindIsochronousTransfer(ehci_itd *itd)
|
||||||
{
|
{
|
||||||
// Simply check every last descriptor of the isochronous transfer list
|
// Simply check every last descriptor of the isochronous transfer list
|
||||||
if (LockIsochronous()) {
|
isochronous_transfer_data *transfer = fFirstIsochronousTransfer;
|
||||||
isochronous_transfer_data *transfer = fFirstIsochronousTransfer;
|
if (transfer) {
|
||||||
if (transfer) {
|
while (transfer->descriptors[transfer->last_to_process]
|
||||||
while (transfer->descriptors[transfer->last_to_process]
|
!= itd) {
|
||||||
!= itd) {
|
transfer = transfer->link;
|
||||||
transfer = transfer->link;
|
if (!transfer)
|
||||||
if (!transfer)
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UnlockIsochronous();
|
|
||||||
return transfer;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1690,6 +1686,9 @@ EHCI::FinishIsochronousTransfers()
|
|||||||
" at frame %ld\n", itd, itd->this_phy, itd->prev,
|
" at frame %ld\n", itd, itd->this_phy, itd->prev,
|
||||||
itd->prev != NULL ? itd->prev->this_phy : 0, currentFrame);
|
itd->prev != NULL ? itd->prev->this_phy : 0, currentFrame);
|
||||||
|
|
||||||
|
if (!LockIsochronous())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Process the frame till it has isochronous descriptors in it.
|
// Process the frame till it has isochronous descriptors in it.
|
||||||
while (!(itd->next_phy & EHCI_ITEM_TERMINATE) && itd->prev != NULL) {
|
while (!(itd->next_phy & EHCI_ITEM_TERMINATE) && itd->prev != NULL) {
|
||||||
TRACE("FinishIsochronousTransfers checking itd %p last_token"
|
TRACE("FinishIsochronousTransfers checking itd %p last_token"
|
||||||
@@ -1720,25 +1719,22 @@ EHCI::FinishIsochronousTransfers()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the transfer
|
// Remove the transfer
|
||||||
if (LockIsochronous()) {
|
if (transfer == fFirstIsochronousTransfer) {
|
||||||
if (transfer == fFirstIsochronousTransfer) {
|
fFirstIsochronousTransfer = transfer->link;
|
||||||
fFirstIsochronousTransfer = transfer->link;
|
if (transfer == fLastIsochronousTransfer)
|
||||||
if (transfer == fLastIsochronousTransfer)
|
fLastIsochronousTransfer = NULL;
|
||||||
fLastIsochronousTransfer = NULL;
|
} else {
|
||||||
} else {
|
isochronous_transfer_data *temp
|
||||||
isochronous_transfer_data *temp
|
= fFirstIsochronousTransfer;
|
||||||
= fFirstIsochronousTransfer;
|
while (temp != NULL && transfer != temp->link)
|
||||||
while (temp != NULL && transfer != temp->link)
|
temp = temp->link;
|
||||||
temp = temp->link;
|
|
||||||
|
|
||||||
if (transfer == fLastIsochronousTransfer)
|
if (transfer == fLastIsochronousTransfer)
|
||||||
fLastIsochronousTransfer = temp;
|
fLastIsochronousTransfer = temp;
|
||||||
if (temp != NULL && temp->link != NULL)
|
if (temp != NULL && temp->link != NULL)
|
||||||
temp->link = temp->link->link;
|
temp->link = temp->link->link;
|
||||||
}
|
|
||||||
transfer->link = NULL;
|
|
||||||
UnlockIsochronous();
|
|
||||||
}
|
}
|
||||||
|
transfer->link = NULL;
|
||||||
|
|
||||||
transfer->transfer->Finished(B_OK, actualLength);
|
transfer->transfer->Finished(B_OK, actualLength);
|
||||||
|
|
||||||
@@ -1759,6 +1755,8 @@ EHCI::FinishIsochronousTransfers()
|
|||||||
itd = itd->prev;
|
itd = itd->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnlockIsochronous();
|
||||||
|
|
||||||
TRACE("FinishIsochronousTransfers next frame\n");
|
TRACE("FinishIsochronousTransfers next frame\n");
|
||||||
|
|
||||||
// Make sure to reset the frame bandwidth
|
// Make sure to reset the frame bandwidth
|
||||||
@@ -2243,7 +2241,6 @@ EHCI::LinkDescriptors(ehci_qtd *first, ehci_qtd *last, ehci_qtd *alt)
|
|||||||
void
|
void
|
||||||
EHCI::LinkITDescriptors(ehci_itd *itd, ehci_itd **_last)
|
EHCI::LinkITDescriptors(ehci_itd *itd, ehci_itd **_last)
|
||||||
{
|
{
|
||||||
LockIsochronous();
|
|
||||||
ehci_itd *last = *_last;
|
ehci_itd *last = *_last;
|
||||||
itd->next_phy = last->next_phy;
|
itd->next_phy = last->next_phy;
|
||||||
itd->next = NULL;
|
itd->next = NULL;
|
||||||
@@ -2251,14 +2248,12 @@ EHCI::LinkITDescriptors(ehci_itd *itd, ehci_itd **_last)
|
|||||||
last->next = itd;
|
last->next = itd;
|
||||||
last->next_phy = itd->this_phy;
|
last->next_phy = itd->this_phy;
|
||||||
*_last = itd;
|
*_last = itd;
|
||||||
UnlockIsochronous();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EHCI::LinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **_last)
|
EHCI::LinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **_last)
|
||||||
{
|
{
|
||||||
LockIsochronous();
|
|
||||||
ehci_sitd *last = *_last;
|
ehci_sitd *last = *_last;
|
||||||
sitd->next_phy = last->next_phy;
|
sitd->next_phy = last->next_phy;
|
||||||
sitd->next = NULL;
|
sitd->next = NULL;
|
||||||
@@ -2266,34 +2261,29 @@ EHCI::LinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **_last)
|
|||||||
last->next = sitd;
|
last->next = sitd;
|
||||||
last->next_phy = sitd->this_phy;
|
last->next_phy = sitd->this_phy;
|
||||||
*_last = sitd;
|
*_last = sitd;
|
||||||
UnlockIsochronous();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EHCI::UnlinkITDescriptors(ehci_itd *itd, ehci_itd **last)
|
EHCI::UnlinkITDescriptors(ehci_itd *itd, ehci_itd **last)
|
||||||
{
|
{
|
||||||
LockIsochronous();
|
|
||||||
itd->prev->next_phy = itd->next_phy;
|
itd->prev->next_phy = itd->next_phy;
|
||||||
itd->prev->next = itd->next;
|
itd->prev->next = itd->next;
|
||||||
if (itd->next != NULL)
|
if (itd->next != NULL)
|
||||||
itd->next->prev = itd->prev;
|
itd->next->prev = itd->prev;
|
||||||
if (itd == *last)
|
if (itd == *last)
|
||||||
*last = itd->prev;
|
*last = itd->prev;
|
||||||
UnlockIsochronous();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EHCI::UnlinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **last)
|
EHCI::UnlinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **last)
|
||||||
{
|
{
|
||||||
LockIsochronous();
|
|
||||||
sitd->prev->next_phy = sitd->next_phy;
|
sitd->prev->next_phy = sitd->next_phy;
|
||||||
sitd->prev->next = sitd->next;
|
sitd->prev->next = sitd->next;
|
||||||
if (sitd->next != NULL)
|
if (sitd->next != NULL)
|
||||||
sitd->next->prev = sitd->prev;
|
sitd->next->prev = sitd->prev;
|
||||||
if (sitd == *last)
|
if (sitd == *last)
|
||||||
*last = sitd->prev;
|
*last = sitd->prev;
|
||||||
UnlockIsochronous();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user