mirror of
https://github.com/X11Libre/xserver.git
synced 2026-04-14 17:18:09 +00:00
xfree86/common: introduce generic xf86CheckSlot() function
This function will be used by xf86Claim{Fb,Pci,Platform}Slot()
to prevent them from claiming already used slots.
Fixes: https://github.com/X11Libre/xserver/issues/1505
Fixes: d3fd8c385b
Fixes: d09b3dae3e
Signed-off-by: Oleh Nykyforchyn <oleh.nyk@gmail.com>
This commit is contained in:
committed by
Enrico Weigelt
parent
90c8af27bd
commit
9307a252c9
@@ -655,3 +655,225 @@ xf86GetEntityPrivate(int entityIndex, int privIndex)
|
||||
|
||||
return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the slot requested is free. If it is already in use, return FALSE.
|
||||
*/
|
||||
|
||||
Bool
|
||||
xf86CheckSlot(const void *ptr, BusType type)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef XSERVER_LIBPCIACCESS
|
||||
const struct pci_device *pci_ptr = (type == BUS_PCI ?
|
||||
(const struct pci_device *)ptr : NULL);
|
||||
#endif
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
const struct xf86_platform_device *plat_ptr = (type == BUS_PLATFORM ?
|
||||
(const struct xf86_platform_device *)ptr : NULL);
|
||||
#endif
|
||||
|
||||
GDevPtr fb_ptr = (type == BUS_NONE ?
|
||||
(GDevPtr)ptr : NULL);
|
||||
const char *msPath = NULL;
|
||||
const char *fbPath = NULL;
|
||||
|
||||
if (ptr == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
/* XSERVER_PLATFORM_BUS assumes XSERVER_LIBPCIACCESS */
|
||||
if (plat_ptr) {
|
||||
pci_ptr = plat_ptr->pdev;
|
||||
msPath = plat_ptr->attribs->path;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type == BUS_NONE) {
|
||||
if (!strcasecmp(fb_ptr->driver, "modesetting")) {
|
||||
/*
|
||||
* If xf86ClaimFbSlot() is called by modesetting driver,
|
||||
* busID has not been set and the device name was not specified
|
||||
* via "kmsdev" option, the default "/dev/dri/card0" is used.
|
||||
*
|
||||
* We have to check whether a platform device has previously
|
||||
* grabbed the device we are going to claim.
|
||||
*/
|
||||
msPath = xf86FindOptionValue(fb_ptr->options, "kmsdev");
|
||||
if (msPath == NULL) {
|
||||
/* Autoconfigured */
|
||||
msPath = "/dev/dri/card0";
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(fb_ptr->driver, "fbdev")) {
|
||||
/*
|
||||
* fbdev driver can also call xf86ClaimFbSlot() for
|
||||
* an autoconfigured device, or the device name can be set
|
||||
* via "fbdev" option.
|
||||
*/
|
||||
fbPath = xf86FindOptionValue(fb_ptr->options, "fbdev");
|
||||
if (fbPath == NULL) {
|
||||
/* Autoconfigured */
|
||||
fbPath = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Having prepared all data about a candidate, we walk
|
||||
* through all previous entities to check for a collision.
|
||||
*/
|
||||
|
||||
for (i = 0; i < xf86NumEntities; i++) {
|
||||
const EntityPtr pent = xf86Entities[i];
|
||||
#ifdef XSERVER_LIBPCIACCESS
|
||||
struct pci_device *pci_other;
|
||||
#endif
|
||||
const char *msOther = NULL;
|
||||
const char *fbOther = NULL;
|
||||
|
||||
if (pent->numInstances <= 0) {
|
||||
/* All devices are unclaimed, ignore this entity */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((fbPath != NULL) && (*fbPath == '\0')) {
|
||||
/* Autoconfigured fbdev device is incompatible with anything */
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
"\"%s\" must be the only device, but \"%s\" is present.\n",
|
||||
fb_ptr->identifier, pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef XSERVER_LIBPCIACCESS
|
||||
pci_other = xf86GetPciInfoForEntity(i);
|
||||
/* First compare PCI addresses */
|
||||
if (pci_ptr && pci_other) {
|
||||
if (MATCH_PCI_DEVICES(pci_other, pci_ptr)) {
|
||||
/* This PCI slot has been claimed, fail */
|
||||
if (msPath) {
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Platform device \"%s\" skipped because\n",
|
||||
msPath);
|
||||
}
|
||||
else {
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" PCI device skipped because\n");
|
||||
}
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" PCI bus id %u@%u:%u:%u has already been claimed by \"%s\".\n",
|
||||
pci_ptr->domain, pci_ptr->bus, pci_ptr->dev, pci_ptr->func,
|
||||
pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
/* This is another device, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pent->bus.type == BUS_PCI) {
|
||||
/* No other means to compare, accept */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pent->bus.type == BUS_NONE) {
|
||||
if (!strcasecmp(pent->driver->driverName, "fbdev")) {
|
||||
if ((type != BUS_NONE) || (fbPath == NULL)) {
|
||||
/* fbdev without busID is incompatible with other types */
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Only fbdev without PCI bus id can be claimed after \"%s\".\n",
|
||||
pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
/* Examine the first device only */
|
||||
fbOther = xf86FindOptionValue(pent->devices[0]->options, "fbdev");
|
||||
if (fbOther == NULL) {
|
||||
/* Autoconfigured, reject */
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Can\'t claim anything after \"%s\".\n",
|
||||
pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
if (strcmp(fbPath, fbOther)) {
|
||||
/* No conflict */
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/* This framebuffer device has been claimed already */
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Framebuffer device \"%s\" has already been claimed by \"%s\".\n",
|
||||
fbPath, pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
if (pent->bus.type == BUS_PLATFORM) {
|
||||
msOther = pent->bus.id.plat->attribs->path;
|
||||
} else
|
||||
#endif
|
||||
if (pent->bus.type == BUS_NONE) {
|
||||
if (!strcasecmp(pent->driver->driverName, "modesetting")) {
|
||||
/* Examine the first device only */
|
||||
msOther = xf86FindOptionValue(pent->devices[0]->options, "kmsdev");
|
||||
if ((msOther == NULL) && (pci_other == NULL)) {
|
||||
/* Autoconfigured */
|
||||
msOther = "/dev/dri/card0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((msPath != NULL) && (msOther != NULL) && !strcmp(msPath, msOther)) {
|
||||
/* This DRI device has been claimed already */
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" DRI device \"%s\" has already been claimed by \"%s\".\n",
|
||||
msPath, pent->devices[0]->identifier);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
if (type == BUS_PLATFORM) {
|
||||
if (pci_ptr)
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Platform device \"%s\" at %u@%u:%u:%u can be claimed.\n",
|
||||
msPath, pci_ptr->domain, pci_ptr->bus, pci_ptr->dev, pci_ptr->func);
|
||||
else
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" Platform device \"%s\" can be claimed.\n",
|
||||
msPath);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef XSERVER_LIBPCIACCESS
|
||||
if (type == BUS_PCI) {
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
" PCI device %u@%u:%u:%u can be claimed.\n",
|
||||
pci_ptr->domain, pci_ptr->bus, pci_ptr->dev, pci_ptr->func);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (type == BUS_NONE) {
|
||||
if (msPath)
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
"\"%s\" can be claimed by modesetting driver as \"%s\".\n",
|
||||
msPath, fb_ptr->identifier);
|
||||
else
|
||||
if (fbPath)
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
"\"%s\" can be claimed by fbdev driver as \"%s\".\n",
|
||||
fbPath, fb_ptr->identifier);
|
||||
else
|
||||
LogMessageVerb(X_INFO, 1,
|
||||
"\"%s\" can be claimed.\n",
|
||||
fb_ptr->identifier);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -83,4 +83,5 @@ void xf86RemoveDevFromEntity(int entityIndex, GDevPtr dev);
|
||||
|
||||
Bool xf86CallDriverProbe(struct _DriverRec *drv, Bool detect_only);
|
||||
|
||||
Bool xf86CheckSlot(const void *ptr, BusType type);
|
||||
#endif /* _XF86_BUS_H */
|
||||
|
||||
@@ -50,14 +50,18 @@ xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active)
|
||||
EntityPtr p;
|
||||
int num;
|
||||
|
||||
num = xf86AllocateEntity();
|
||||
p = xf86Entities[num];
|
||||
p->driver = drvp;
|
||||
p->chipset = 0;
|
||||
p->bus.type = BUS_NONE;
|
||||
p->active = active;
|
||||
p->inUse = FALSE;
|
||||
xf86AddDevToEntity(num, dev);
|
||||
if (xf86CheckSlot(dev, BUS_NONE)) {
|
||||
num = xf86AllocateEntity();
|
||||
p = xf86Entities[num];
|
||||
p->driver = drvp;
|
||||
p->chipset = 0;
|
||||
p->bus.type = BUS_NONE;
|
||||
p->active = active;
|
||||
p->inUse = FALSE;
|
||||
xf86AddDevToEntity(num, dev);
|
||||
|
||||
return num;
|
||||
return num;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,23 +411,7 @@ xf86CheckPciMemBase(struct pci_device *pPci, memType base)
|
||||
Bool
|
||||
xf86CheckPciSlot(const struct pci_device *d)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xf86NumEntities; i++) {
|
||||
const EntityPtr p = xf86Entities[i];
|
||||
|
||||
if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef XSERVER_PLATFORM_BUS
|
||||
if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat->pdev)) {
|
||||
struct pci_device *ud = p->bus.id.plat->pdev;
|
||||
if (MATCH_PCI_DEVICES(ud, d))
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
return xf86CheckSlot(d, BUS_PCI);
|
||||
}
|
||||
|
||||
#define END_OF_MATCHES(m) \
|
||||
|
||||
@@ -155,25 +155,6 @@ platform_find_pci_info(struct xf86_platform_device *pd, char *busid)
|
||||
pci_iterator_destroy(iter);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86_check_platform_slot(const struct xf86_platform_device *pd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xf86NumEntities; i++) {
|
||||
const EntityPtr u = xf86Entities[i];
|
||||
|
||||
if (pd->pdev && u->bus.type == BUS_PCI &&
|
||||
MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci)) {
|
||||
return FALSE;
|
||||
}
|
||||
if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
OutputClassMatches(const XF86ConfOutputClassPtr oclass,
|
||||
struct xf86_platform_device *dev)
|
||||
@@ -465,7 +446,7 @@ xf86ClaimPlatformSlot(struct xf86_platform_device * d, DriverPtr drvp,
|
||||
EntityPtr p = NULL;
|
||||
int num;
|
||||
|
||||
if (xf86_check_platform_slot(d)) {
|
||||
if (xf86CheckSlot(d, BUS_PLATFORM)) {
|
||||
num = xf86AllocateEntity();
|
||||
p = xf86Entities[num];
|
||||
p->driver = drvp;
|
||||
@@ -511,27 +492,29 @@ static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
|
||||
Bool foundScreen = FALSE;
|
||||
int entity;
|
||||
|
||||
if (gdev && gdev->screen == 0 && !xf86_check_platform_slot(dev))
|
||||
return FALSE;
|
||||
|
||||
entity = xf86ClaimPlatformSlot(dev, drvp, 0,
|
||||
gdev, gdev ? gdev->active : 0);
|
||||
|
||||
if ((entity == -1) && gdev && (gdev->screen > 0)) {
|
||||
unsigned nent;
|
||||
if ((entity == -1) && gdev) {
|
||||
if (gdev->screen == 0)
|
||||
return FALSE;
|
||||
else { /* gdev->screen > 0 */
|
||||
unsigned nent;
|
||||
|
||||
for (nent = 0; nent < xf86NumEntities; nent++) {
|
||||
EntityPtr pEnt = xf86Entities[nent];
|
||||
for (nent = 0; nent < xf86NumEntities; nent++) {
|
||||
EntityPtr pEnt = xf86Entities[nent];
|
||||
|
||||
if (pEnt->bus.type != BUS_PLATFORM)
|
||||
continue;
|
||||
if (pEnt->bus.id.plat == dev) {
|
||||
entity = nent;
|
||||
xf86AddDevToEntity(nent, gdev);
|
||||
break;
|
||||
if (pEnt->bus.type != BUS_PLATFORM)
|
||||
continue;
|
||||
if (pEnt->bus.id.plat == dev) {
|
||||
entity = nent;
|
||||
xf86AddDevToEntity(nent, gdev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != -1) {
|
||||
if ((dev->flags & XF86_PDEV_SERVER_FD) && (!drvp->driverFunc ||
|
||||
!drvp->driverFunc(NULL, SUPPORTS_SERVER_FDS, NULL))) {
|
||||
|
||||
Reference in New Issue
Block a user