Use implemented ports mask to check if maximum port count needs to be extended.
* This should fix #8953 * Also fix some harmless off-by-one errors
This commit is contained in:
@@ -131,12 +131,21 @@ AHCIController::Init()
|
||||
fPortCountMax = 1 + ((fRegs->cap >> CAP_NP_SHIFT) & CAP_NP_MASK);
|
||||
|
||||
fPortImplementedMask = fRegs->pi;
|
||||
// reported mask of implemented ports is sometimes empty
|
||||
if (fPortImplementedMask == 0) {
|
||||
fPortImplementedMask = 0xffffffff >> (32 - fPortCountMax);
|
||||
TRACE("ports-implemented mask is zero, using 0x%" B_PRIx32 " instead.\n",
|
||||
fPortImplementedMask);
|
||||
}
|
||||
|
||||
// reported number of ports is sometimes too small
|
||||
int maxPortIndex;
|
||||
maxPortIndex = fls(fPortImplementedMask);
|
||||
if (fPortCountMax < maxPortIndex) {
|
||||
TRACE("reported number of ports is wrong, using %d instead.\n", maxPortIndex);
|
||||
fPortCountMax = maxPortIndex;
|
||||
}
|
||||
|
||||
fPortCountAvail = count_bits_set(fPortImplementedMask);
|
||||
|
||||
TRACE("cap: Interface Speed Support: generation %" B_PRIu32 "\n", (fRegs->cap >> CAP_ISS_SHIFT) & CAP_ISS_MASK);
|
||||
@@ -169,7 +178,7 @@ AHCIController::Init()
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= fPortCountMax; i++) {
|
||||
for (int i = 0; i < fPortCountMax; i++) {
|
||||
if (fPortImplementedMask & (1 << i)) {
|
||||
fPort[i] = new (std::nothrow)AHCIPort(this, i);
|
||||
if (!fPort[i]) {
|
||||
@@ -189,7 +198,7 @@ AHCIController::Init()
|
||||
fRegs->ghc |= GHC_IE;
|
||||
FlushPostedWrites();
|
||||
|
||||
for (int i = 0; i <= fPortCountMax; i++) {
|
||||
for (int i = 0; i < fPortCountMax; i++) {
|
||||
if (fPort[i]) {
|
||||
status_t status = fPort[i]->Init2();
|
||||
if (status < B_OK) {
|
||||
@@ -215,7 +224,7 @@ AHCIController::Uninit()
|
||||
{
|
||||
TRACE("AHCIController::Uninit\n");
|
||||
|
||||
for (int i = 0; i <= fPortCountMax; i++) {
|
||||
for (int i = 0; i < fPortCountMax; i++) {
|
||||
if (fPort[i]) {
|
||||
fPort[i]->Uninit();
|
||||
delete fPort[i];
|
||||
|
||||
@@ -121,3 +121,17 @@ swap_words(void *data, size_t size)
|
||||
word++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fls(unsigned mask)
|
||||
{
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
int pos = 1;
|
||||
while (mask != 1) {
|
||||
mask >>= 1;
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ status_t sg_memcpy(const physical_entry *sgTable, int sgCount, const void *data,
|
||||
|
||||
void swap_words(void *data, size_t size);
|
||||
|
||||
int fls(unsigned mask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user