On Sat, Apr 03, 2021 at 01:48:57PM +0200, Pali Rohár wrote: > Hello! > > PCI Express Base Specification rev. 3.0 has the following definition for > the Slot Power Limit Value: FWIW, it's the same in rev 5. I had thought they might add even more power encodings, but no. > But the function power_limit() in ls-caps.c does not handle value above > EFh according to this definition. > > Here is a simple patch which fixes it for values F0h..F2h. But I'm not > sure how (reserved) values above F2h should be handled. > > diff --git a/ls-caps.c b/ls-caps.c > index db56556971cb..bc1eaa15017d 100644 > --- a/ls-caps.c > +++ b/ls-caps.c > @@ -659,6 +659,9 @@ static int exp_downstream_port(int type) > static float power_limit(int value, int scale) > { > static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 }; > + static const int scale0_values[3] = { 250, 275, 300 }; /* F3h to FFh = Reserved for Slot Power Limit values above 300 W */ > + if (scale == 0 && value >= 0xF0) > + value = scale0_values[(value > 0xF2 ? 0xF2 : value) & 0xF]; > return value * scales[scale]; > } How about ... if (scale == 0) { if (value > 0xf2) return 0.0f/0; if (value >= 0xf0) return scale0_values[value - 0xf0]; } (btw, a float is the same size as an int -- 32 bits, so there's no benefit to storing the values as an int and doing the conversion at runtime. may as well have the compiler put the right set of bits in the binary) in the caller: if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE)) { float power = power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18, (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26)); if (isnan(power)) printf(" SlotPowerLimit >300W"); else printf(" SlotPowerLimit %.3fW", power); }