hrev50146 adds 5 changesets to branch 'master'
old head: e3338b15f5065cb4321cce1ce6e7d6c66d385f66
new head: 91ea4fb48a104ad60aa279910434462c26e84d13
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=91ea4fb48a10+%5Ee3338b15f506
----------------------------------------------------------------------------
3648dc87090f: EHCI: Style cleanup only, no functional change.
Change < B_OK to != B_OK for status_t results and to < 0 for ids.
ad72f4caed8e: EHCI: Fix alignment check, the mask wasn't wide enough.
As this is only an assert that shouldn't ever be triggered, this doesn't
change anything in normal operation.
3da7be22fb19: EHCI: Current qtd field in qh overlay has no terminate bit.
Don't initialize the current qtd field with the terminate bit as it does
not exist in this field. While the lower 5 bits are documented as being
ignored anyway, this is more correct. Should cause no functional change.
b62bb24fe4f2: USB: Force spec mandated control pipe max packet sizes.
While the USB descriptors are specifically built in such a way that it's
always possible to correctly query the max packet size, some devices
unfortunatley use bogus values in their descriptors and rely on the
stack to use the mandated values.
This fixes USB devices in VirtualBox when EHCI emulation is used. This
really is a bug in their descriptor emulation though.
91ea4fb48a10: usb_ecm: Use the current configuration instead of a fixed one.
This allows usb_ecm to work in case it is part of a device using
different configurations for different types of interfaces and ECM is
not the first configuration.
[ Michael Lotz <mmlr@xxxxxxxx> ]
----------------------------------------------------------------------------
4 files changed, 76 insertions(+), 41 deletions(-)
src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 29 ++++++++
.../kernel/bus_managers/usb/usb_private.h | 8 +++
src/add-ons/kernel/busses/usb/ehci.cpp | 70 ++++++++++----------
.../kernel/drivers/network/usb_ecm/ECMDevice.cpp | 10 +--
############################################################################
Commit: 3648dc87090fcb07f92a86bfeb62bc0719b70937
URL: http://cgit.haiku-os.org/haiku/commit/?id=3648dc87090f
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Sat Jan 30 12:21:05 2016 UTC
EHCI: Style cleanup only, no functional change.
Change < B_OK to != B_OK for status_t results and to < 0 for ids.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp
b/src/add-ons/kernel/busses/usb/ehci.cpp
index dfa51f8..7bd4997c 100644
--- a/src/add-ons/kernel/busses/usb/ehci.cpp
+++ b/src/add-ons/kernel/busses/usb/ehci.cpp
@@ -153,7 +153,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
// Create a lock for the isochronous transfer list
mutex_init(&fIsochronousLock, "EHCI isochronous lock");
- if (BusManager::InitCheck() < B_OK) {
+ if (BusManager::InitCheck() != B_OK) {
TRACE_ERROR("bus manager failed to init\n");
return;
}
@@ -173,7 +173,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
// only apply on certain chipsets, determined by SMBus
revision
pci_info smbus;
int32 index = 0;
- while (sPCIModule->get_nth_pci_info(index++, &smbus) >=
B_OK) {
+ while (sPCIModule->get_nth_pci_info(index++, &smbus) ==
B_OK) {
if (smbus.vendor_id == AMD_SBX00_VENDOR
&& smbus.device_id ==
AMD_SBX00_SMBUS_CONTROLLER) {
@@ -227,8 +227,8 @@ EHCI::EHCI(pci_info *info, Stack *stack)
physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA |
B_WRITE_AREA,
(void **)&fCapabilityRegisters);
- if (fRegisterArea < B_OK) {
- TRACE("failed to map register memory\n");
+ if (fRegisterArea < 0) {
+ TRACE_ERROR("failed to map register memory\n");
return;
}
@@ -306,7 +306,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
WriteOpReg(EHCI_USBINTR, 0);
// reset the host controller
- if (ControllerReset() < B_OK) {
+ if (ControllerReset() != B_OK) {
TRACE_ERROR("host controller failed to reset\n");
return;
}
@@ -318,8 +318,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
fAsyncAdvanceSem = create_sem(0, "EHCI Async Advance");
fFinishTransfersSem = create_sem(0, "EHCI Finish Transfers");
fCleanupSem = create_sem(0, "EHCI Cleanup");
- if (fFinishTransfersSem < B_OK || fAsyncAdvanceSem < B_OK
- || fCleanupSem < B_OK) {
+ if (fFinishTransfersSem < 0 || fAsyncAdvanceSem < 0 || fCleanupSem < 0)
{
TRACE_ERROR("failed to create semaphores\n");
return;
}
@@ -332,7 +331,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
// Create semaphore the isochronous finisher thread will wait for
fFinishIsochronousTransfersSem = create_sem(0,
"EHCI Isochronous Finish Transfers");
- if (fFinishIsochronousTransfersSem < B_OK) {
+ if (fFinishIsochronousTransfersSem < 0) {
TRACE_ERROR("failed to create isochronous finisher
semaphore\n");
return;
}
@@ -412,7 +411,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
// allocate the periodic frame list
fPeriodicFrameListArea = fStack->AllocateArea((void
**)&fPeriodicFrameList,
&physicalAddress, frameListSize, "USB EHCI Periodic Framelist");
- if (fPeriodicFrameListArea < B_OK) {
+ if (fPeriodicFrameListArea < 0) {
TRACE_ERROR("unable to allocate periodic framelist\n");
return;
}
@@ -680,7 +679,7 @@ EHCI::Start()
return B_NO_MEMORY;
}
- if (fRootHub->InitCheck() < B_OK) {
+ if (fRootHub->InitCheck() != B_OK) {
TRACE_ERROR("root hub failed init check\n");
return fRootHub->InitCheck();
}
@@ -895,7 +894,7 @@ EHCI::SubmitTransfer(Transfer *transfer)
}
status_t result = InitQueueHead(queueHead, pipe);
- if (result < B_OK) {
+ if (result != B_OK) {
TRACE_ERROR("failed to init queue head\n");
FreeQueueHead(queueHead);
return result;
@@ -911,7 +910,7 @@ EHCI::SubmitTransfer(Transfer *transfer)
&directionIn);
}
- if (result < B_OK) {
+ if (result != B_OK) {
TRACE_ERROR("failed to fill transfer queue with data\n");
FreeQueueHead(queueHead);
return result;
@@ -919,7 +918,7 @@ EHCI::SubmitTransfer(Transfer *transfer)
result = AddPendingTransfer(transfer, queueHead, dataDescriptor,
directionIn);
- if (result < B_OK) {
+ if (result != B_OK) {
TRACE_ERROR("failed to add pending transfer\n");
FreeQueueHead(queueHead);
return result;
@@ -935,7 +934,7 @@ EHCI::SubmitTransfer(Transfer *transfer)
else
result = LinkQueueHead(queueHead);
- if (result < B_OK) {
+ if (result != B_OK) {
TRACE_ERROR("failed to link queue head\n");
FreeQueueHead(queueHead);
return result;
@@ -1023,7 +1022,7 @@ EHCI::SubmitIsochronous(Transfer *transfer)
size_t dataLength = transfer->DataLength();
void* bufferLog;
phys_addr_t bufferPhy;
- if (fStack->AllocateChunk(&bufferLog, &bufferPhy, dataLength) < B_OK) {
+ if (fStack->AllocateChunk(&bufferLog, &bufferPhy, dataLength) != B_OK) {
TRACE_ERROR("unable to allocate itd buffer\n");
delete[] isoRequest;
return B_NO_MEMORY;
@@ -1092,7 +1091,7 @@ EHCI::SubmitIsochronous(Transfer *transfer)
status_t result = AddPendingIsochronousTransfer(transfer, isoRequest,
itdIndex - 1, directionIn, bufferPhy, bufferLog,
transfer->DataLength());
- if (result < B_OK) {
+ if (result != B_OK) {
TRACE_ERROR("failed to add pending isochronous transfer\n");
for (uint32 i = 0; i < itdIndex; i++)
FreeDescriptor(isoRequest[i]);
@@ -1165,7 +1164,7 @@ EHCI::AddTo(Stack *stack)
if (!sPCIModule) {
status_t status = get_module(B_PCI_MODULE_NAME,
(module_info **)&sPCIModule);
- if (status < B_OK) {
+ if (status != B_OK) {
TRACE_MODULE_ERROR("getting pci module failed! 0x%08"
B_PRIx32
"\n", status);
return status;
@@ -1212,7 +1211,7 @@ EHCI::AddTo(Stack *stack)
return B_NO_MEMORY;
}
- if (bus->InitCheck() < B_OK) {
+ if (bus->InitCheck() != B_OK) {
TRACE_MODULE_ERROR("bus failed init check\n");
delete bus;
continue;
@@ -1537,7 +1536,7 @@ EHCI::AddPendingTransfer(Transfer *transfer, ehci_qh
*queueHead,
return B_NO_MEMORY;
status_t result = transfer->InitKernelAccess();
- if (result < B_OK) {
+ if (result != B_OK) {
delete data;
return result;
}
@@ -1580,7 +1579,7 @@ EHCI::AddPendingIsochronousTransfer(Transfer *transfer,
ehci_itd **isoRequest,
return B_NO_MEMORY;
status_t result = transfer->InitKernelAccess();
- if (result < B_OK) {
+ if (result != B_OK) {
delete data;
return result;
}
@@ -1734,7 +1733,7 @@ void
EHCI::FinishTransfers()
{
while (!fStopThreads) {
- if (acquire_sem(fFinishTransfersSem) < B_OK)
+ if (acquire_sem(fFinishTransfersSem) != B_OK)
continue;
// eat up sems that have been released by multiple interrupts
@@ -1960,7 +1959,7 @@ EHCI::Cleanup()
ehci_qh *lastFreeListHead = NULL;
while (!fStopThreads) {
- if (acquire_sem(fCleanupSem) < B_OK)
+ if (acquire_sem(fCleanupSem) != B_OK)
continue;
ehci_qh *freeListHead = fFreeListHead;
@@ -1969,7 +1968,7 @@ EHCI::Cleanup()
// set the doorbell and wait for the host controller to notify
us
WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) |
EHCI_USBCMD_INTONAAD);
- if (acquire_sem(fAsyncAdvanceSem) < B_OK)
+ if (acquire_sem(fAsyncAdvanceSem) != B_OK)
continue;
ehci_qh *current = freeListHead;
@@ -2000,8 +1999,8 @@ EHCI::FinishIsochronousTransfers()
* of a transfer, it processes the entire transfer.
*/
while (!fStopThreads) {
- // Go to sleep if there are not isochronous transfer to process
- if (acquire_sem(fFinishIsochronousTransfersSem) < B_OK)
+ // Go to sleep if there are no isochronous transfers to process
+ if (acquire_sem(fFinishIsochronousTransfersSem) != B_OK)
return;
bool transferDone = false;
@@ -2119,7 +2118,7 @@ EHCI::CreateQueueHead()
ehci_qh *result;
phys_addr_t physicalAddress;
if (fStack->AllocateChunk((void **)&result, &physicalAddress,
- sizeof(ehci_qh)) < B_OK) {
+ sizeof(ehci_qh)) != B_OK) {
TRACE_ERROR("failed to allocate queue head\n");
return NULL;
}
@@ -2331,7 +2330,7 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh
*queueHead,
&lastDescriptor, statusDescriptor,
transfer->VectorLength(),
directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT);
- if (result < B_OK) {
+ if (result != B_OK) {
FreeDescriptor(setupDescriptor);
FreeDescriptor(statusDescriptor);
return result;
@@ -2373,7 +2372,7 @@ EHCI::FillQueueWithData(Transfer *transfer, ehci_qh
*queueHead,
&lastDescriptor, strayDescriptor, transfer->VectorLength(),
directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT);
- if (result < B_OK)
+ if (result != B_OK)
return result;
lastDescriptor->token |= EHCI_QTD_IOC;
@@ -2399,7 +2398,7 @@ EHCI::CreateDescriptor(size_t bufferSize, uint8 pid)
ehci_qtd *result;
phys_addr_t physicalAddress;
if (fStack->AllocateChunk((void **)&result, &physicalAddress,
- sizeof(ehci_qtd)) < B_OK) {
+ sizeof(ehci_qtd)) != B_OK) {
TRACE_ERROR("failed to allocate a qtd\n");
return NULL;
}
@@ -2425,7 +2424,7 @@ EHCI::CreateDescriptor(size_t bufferSize, uint8 pid)
}
if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress,
- bufferSize) < B_OK) {
+ bufferSize) != B_OK) {
TRACE_ERROR("unable to allocate qtd buffer\n");
fStack->FreeChunk(result, (phys_addr_t)result->this_phy,
sizeof(ehci_qtd));
@@ -2519,7 +2518,7 @@ EHCI::CreateItdDescriptor()
ehci_itd *result;
phys_addr_t physicalAddress;
if (fStack->AllocateChunk((void **)&result, &physicalAddress,
- sizeof(ehci_itd)) < B_OK) {
+ sizeof(ehci_itd)) != B_OK) {
TRACE_ERROR("failed to allocate a itd\n");
return NULL;
}
@@ -2538,7 +2537,7 @@ EHCI::CreateSitdDescriptor()
ehci_sitd *result;
phys_addr_t physicalAddress;
if (fStack->AllocateChunk((void **)&result, &physicalAddress,
- sizeof(ehci_sitd)) < B_OK) {
+ sizeof(ehci_sitd)) != B_OK) {
TRACE_ERROR("failed to allocate a sitd\n");
return NULL;
}
############################################################################
Commit: ad72f4caed8e0176da8642c71cd61ce17bfc4cfb
URL: http://cgit.haiku-os.org/haiku/commit/?id=ad72f4caed8e
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Sat Jan 30 12:24:29 2016 UTC
EHCI: Fix alignment check, the mask wasn't wide enough.
As this is only an assert that shouldn't ever be triggered, this doesn't
change anything in normal operation.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp
b/src/add-ons/kernel/busses/usb/ehci.cpp
index 7bd4997c..c3d7157 100644
--- a/src/add-ons/kernel/busses/usb/ehci.cpp
+++ b/src/add-ons/kernel/busses/usb/ehci.cpp
@@ -447,7 +447,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
| (0xff << EHCI_QH_CAPS_ISM_SHIFT);
physicalBase += sizeof(interrupt_entry);
- if ((physicalBase & 0x10) != 0) {
+ if ((physicalBase & 0x1f) != 0) {
panic("physical base for interrupt entry %" B_PRId32
" not aligned on 32, interrupt entry structure
size %lu\n",
i, sizeof(interrupt_entry));
############################################################################
Commit: 3da7be22fb191c94e0160cde82b1020d094de752
URL: http://cgit.haiku-os.org/haiku/commit/?id=3da7be22fb19
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Sat Jan 30 12:40:42 2016 UTC
EHCI: Current qtd field in qh overlay has no terminate bit.
Don't initialize the current qtd field with the terminate bit as it does
not exist in this field. While the lower 5 bits are documented as being
ignored anyway, this is more correct. Should cause no functional change.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp
b/src/add-ons/kernel/busses/usb/ehci.cpp
index c3d7157..977951a 100644
--- a/src/add-ons/kernel/busses/usb/ehci.cpp
+++ b/src/add-ons/kernel/busses/usb/ehci.cpp
@@ -434,7 +434,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
for (int32 i = 0; i < EHCI_INTERRUPT_ENTRIES_COUNT; i++) {
ehci_qh *queueHead = &fInterruptEntries[i].queue_head;
queueHead->this_phy = physicalBase | EHCI_ITEM_TYPE_QH;
- queueHead->current_qtd_phy = EHCI_ITEM_TERMINATE;
+ queueHead->current_qtd_phy = 0;
queueHead->overlay.next_phy = EHCI_ITEM_TERMINATE;
queueHead->overlay.alt_next_phy = EHCI_ITEM_TERMINATE;
queueHead->overlay.token = EHCI_QTD_STATUS_HALTED;
@@ -549,7 +549,6 @@ EHCI::EHCI(pci_info *info, Stack *stack)
fAsyncQueueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH
| EHCI_QH_CHARS_RECHEAD;
fAsyncQueueHead->endpoint_caps = 1 << EHCI_QH_CAPS_MULT_SHIFT;
- fAsyncQueueHead->current_qtd_phy = EHCI_ITEM_TERMINATE;
fAsyncQueueHead->overlay.next_phy = EHCI_ITEM_TERMINATE;
WriteOpReg(EHCI_ASYNCLISTADDR, (uint32)fAsyncQueueHead->this_phy);
@@ -2138,7 +2137,7 @@ EHCI::CreateQueueHead()
descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE;
result->stray_log = descriptor;
result->element_log = descriptor;
- result->current_qtd_phy = EHCI_ITEM_TERMINATE;
+ result->current_qtd_phy = 0;
result->overlay.next_phy = descriptor->this_phy;
result->overlay.alt_next_phy = EHCI_ITEM_TERMINATE;
result->overlay.token = 0;
############################################################################
Commit: b62bb24fe4f2a2829bb584f7c1e5c687f7eae2f1
URL: http://cgit.haiku-os.org/haiku/commit/?id=b62bb24fe4f2
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Sat Jan 30 13:01:29 2016 UTC
USB: Force spec mandated control pipe max packet sizes.
While the USB descriptors are specifically built in such a way that it's
always possible to correctly query the max packet size, some devices
unfortunatley use bogus values in their descriptors and rely on the
stack to use the mandated values.
This fixes USB devices in VirtualBox when EHCI emulation is used. This
really is a bug in their descriptor emulation though.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp
b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp
index f317028..96525ac 100644
--- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp
+++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp
@@ -328,6 +328,35 @@ ControlPipe::~ControlPipe()
}
+void
+ControlPipe::InitCommon(int8 deviceAddress, uint8 endpointAddress,
+ usb_speed speed, pipeDirection direction, size_t maxPacketSize,
+ uint8 interval, int8 hubAddress, uint8 hubPort)
+{
+ // The USB 2.0 spec section 5.5.3 gives fixed max packet sizes for the
+ // different speeds. The USB 3.1 specs defines the max packet size to a
+ // fixed 512 for control endpoints in 9.6.6. Some devices ignore these
+ // values and use bogus ones, so we restrict them here.
+ switch (speed) {
+ case USB_SPEED_LOWSPEED:
+ maxPacketSize = 8;
+ break;
+ case USB_SPEED_HIGHSPEED:
+ maxPacketSize = 64;
+ break;
+ case USB_SPEED_SUPER:
+ maxPacketSize = 512;
+ break;
+
+ default:
+ break;
+ }
+
+ Pipe::InitCommon(deviceAddress, endpointAddress, speed, direction,
+ maxPacketSize, interval, hubAddress, hubPort);
+}
+
+
status_t
ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
uint16 index, uint16 length, void *data, size_t dataLength,
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 2e20979..49f7e18 100644
--- a/src/add-ons/kernel/bus_managers/usb/usb_private.h
+++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h
@@ -355,6 +355,14 @@ public:
ControlPipe(Object *parent);
virtual
~ControlPipe();
+virtual void
InitCommon(int8 deviceAddress,
+
uint8 endpointAddress,
+
usb_speed speed,
+
pipeDirection direction,
+
size_t maxPacketSize,
+
uint8 interval,
+
int8 hubAddress, uint8 hubPort);
+
virtual uint32 Type()
const { return USB_OBJECT_PIPE
| USB_OBJECT_CONTROL_PIPE; }
virtual const char * TypeName() const
############################################################################
Revision: hrev50146
Commit: 91ea4fb48a104ad60aa279910434462c26e84d13
URL: http://cgit.haiku-os.org/haiku/commit/?id=91ea4fb48a10
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Sat Mar 12 11:59:40 2016 UTC
usb_ecm: Use the current configuration instead of a fixed one.
This allows usb_ecm to work in case it is part of a device using
different configurations for different types of interfaces and ECM is
not the first configuration.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.cpp
b/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.cpp
index f9f0092..7150927 100644
--- a/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.cpp
+++ b/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.cpp
@@ -103,18 +103,18 @@ ECMDevice::Open()
// reset the device by switching the data interface to the disabled
first
// interface and then enable it by setting the second actual data
interface
const usb_configuration_info *config
- = gUSBModule->get_nth_configuration(fDevice, 0);
+ = gUSBModule->get_configuration(fDevice);
gUSBModule->set_alt_interface(fDevice,
&config->interface[fDataInterfaceIndex].alt[0]);
// update to the changed config
- config = gUSBModule->get_nth_configuration(fDevice, 0);
+ config = gUSBModule->get_configuration(fDevice);
gUSBModule->set_alt_interface(fDevice,
&config->interface[fDataInterfaceIndex].alt[1]);
// update again
- config = gUSBModule->get_nth_configuration(fDevice, 0);
+ config = gUSBModule->get_configuration(fDevice);
usb_interface_info *interface =
config->interface[fDataInterfaceIndex].active;
if (interface->endpoint_count < 2) {
TRACE_ALWAYS("setting the data alternate interface failed\n");
@@ -156,7 +156,7 @@ ECMDevice::Close()
// put the device into non-connected mode again by switching the data
// interface to the disabled alternate
const usb_configuration_info *config
- = gUSBModule->get_nth_configuration(fDevice, 0);
+ = gUSBModule->get_configuration(fDevice);
gUSBModule->set_alt_interface(fDevice,
&config->interface[fDataInterfaceIndex].alt[0]);
@@ -368,7 +368,7 @@ status_t
ECMDevice::_SetupDevice()
{
const usb_configuration_info *config
- = gUSBModule->get_nth_configuration(fDevice, 0);
+ = gUSBModule->get_configuration(fDevice);
if (config == NULL) {
TRACE_ALWAYS("failed to get device configuration\n");