superio: Handle conflicting devid via prefer/extid

Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/719
This commit is contained in:
Stéphane Rochoy 2023-07-01 11:19:44 -06:00 committed by Warner Losh
parent c94b4d460e
commit a0bcfa7831
2 changed files with 21 additions and 0 deletions

View file

@ -93,6 +93,7 @@ struct siosc {
superio_vendor_t vendor;
uint16_t devid;
uint8_t revid;
int extid;
uint8_t current_ldn;
uint8_t ldn_reg;
uint8_t enable_reg;
@ -292,6 +293,7 @@ static const struct {
superio_vendor_t vendor;
uint16_t devid;
uint16_t mask;
int extid; /* Extra ID: used to handle conflicting devid. */
const char *descr;
const struct sio_device *devices;
} superio_table[] = {
@ -483,6 +485,7 @@ superio_detect(device_t dev, bool claim, struct siosc *sc)
int error;
int rid;
int i, m;
int prefer;
error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port, &count);
if (error != 0)
@ -507,6 +510,11 @@ superio_detect(device_t dev, bool claim, struct siosc *sc)
return (ENXIO);
}
prefer = 0;
resource_int_value(device_get_name(dev), device_get_unit(dev), "prefer", &prefer);
if (bootverbose && prefer > 0)
device_printf(dev, "prefer extid %d\n", prefer);
for (m = 0; methods_table[m] != NULL; m++) {
methods_table[m]->enter(res, port);
if (methods_table[m]->vendor == SUPERIO_VENDOR_ITE) {
@ -533,6 +541,8 @@ superio_detect(device_t dev, bool claim, struct siosc *sc)
continue;
if ((superio_table[i].devid & ~mask) != (devid & ~mask))
continue;
if (prefer > 0 && prefer != superio_table[i].extid)
continue;
break;
}
@ -558,6 +568,7 @@ superio_detect(device_t dev, bool claim, struct siosc *sc)
sc->io_port = port;
sc->devid = devid;
sc->revid = revid;
sc->extid = superio_table[i].extid;
KASSERT(sc->vendor == SUPERIO_VENDOR_ITE ||
sc->vendor == SUPERIO_VENDOR_NUVOTON ||
@ -877,6 +888,15 @@ superio_revid(device_t dev)
return (sc->revid);
}
int
superio_extid(device_t dev)
{
device_t sio_dev = device_get_parent(dev);
struct siosc *sc = device_get_softc(sio_dev);
return (sc->extid);
}
uint8_t
superio_ldn_read(device_t dev, uint8_t ldn, uint8_t reg)
{

View file

@ -49,6 +49,7 @@ typedef enum superio_dev_type {
superio_vendor_t superio_vendor(device_t dev);
uint16_t superio_devid(device_t dev);
uint8_t superio_revid(device_t dev);
int superio_extid(device_t dev);
uint8_t superio_read(device_t dev, uint8_t reg);
uint8_t superio_ldn_read(device_t dev, uint8_t ldn, uint8_t reg);
void superio_write(device_t dev, uint8_t reg, uint8_t val);