mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
agp: Handle multiple devices more gracefully
Currently agp(4) effectively assumes that only one driver instance exists, as the generic attach routine attempts to create /dev/agpgart and triggers a panic if it already exists. Instead, handle this situation by creating /dev/agpgart<unit> and making /dev/agpgart an alias of /dev/agpgart0 for compatibility. PR: 187015 Reviewed by: imp, kib Tested by: Yoshihiro Ota <ota@j.email.ne.jp> (earlier version) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D33068
This commit is contained in:
parent
52d973f52c
commit
437ea82ce7
2 changed files with 29 additions and 5 deletions
|
|
@ -205,8 +205,9 @@ agp_set_aperture_resource(device_t dev, int rid)
|
||||||
int
|
int
|
||||||
agp_generic_attach(device_t dev)
|
agp_generic_attach(device_t dev)
|
||||||
{
|
{
|
||||||
|
struct make_dev_args mdargs;
|
||||||
struct agp_softc *sc = device_get_softc(dev);
|
struct agp_softc *sc = device_get_softc(dev);
|
||||||
int i;
|
int error, i, unit;
|
||||||
u_int memsize;
|
u_int memsize;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -250,11 +251,31 @@ agp_generic_attach(device_t dev)
|
||||||
TAILQ_INIT(&sc->as_memory);
|
TAILQ_INIT(&sc->as_memory);
|
||||||
sc->as_nextid = 1;
|
sc->as_nextid = 1;
|
||||||
|
|
||||||
sc->as_devnode = make_dev(&agp_cdevsw,
|
sc->as_devalias = NULL;
|
||||||
0, UID_ROOT, GID_WHEEL, 0600, "agpgart");
|
|
||||||
sc->as_devnode->si_drv1 = dev;
|
|
||||||
|
|
||||||
return 0;
|
make_dev_args_init(&mdargs);
|
||||||
|
mdargs.mda_devsw = &agp_cdevsw;
|
||||||
|
mdargs.mda_uid = UID_ROOT;
|
||||||
|
mdargs.mda_gid = GID_WHEEL;
|
||||||
|
mdargs.mda_mode = 0600;
|
||||||
|
mdargs.mda_si_drv1 = sc;
|
||||||
|
mdargs.mda_si_drv2 = NULL;
|
||||||
|
|
||||||
|
unit = device_get_unit(dev);
|
||||||
|
error = make_dev_s(&mdargs, &sc->as_devnode, "agpgart%d", unit);
|
||||||
|
if (error == 0) {
|
||||||
|
/*
|
||||||
|
* Create an alias for the first device that shows up.
|
||||||
|
*/
|
||||||
|
if (unit == 0) {
|
||||||
|
(void)make_dev_alias_p(MAKEDEV_CHECKNAME,
|
||||||
|
&sc->as_devalias, sc->as_devnode, "agpgart");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
agp_free_res(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -263,6 +284,8 @@ agp_free_cdev(device_t dev)
|
||||||
struct agp_softc *sc = device_get_softc(dev);
|
struct agp_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
destroy_dev(sc->as_devnode);
|
destroy_dev(sc->as_devnode);
|
||||||
|
if (sc->as_devalias != NULL)
|
||||||
|
destroy_dev(sc->as_devalias);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct agp_softc {
|
||||||
int as_nextid; /* next memory block id */
|
int as_nextid; /* next memory block id */
|
||||||
int as_isopen; /* user device is open */
|
int as_isopen; /* user device is open */
|
||||||
struct cdev *as_devnode; /* from make_dev */
|
struct cdev *as_devnode; /* from make_dev */
|
||||||
|
struct cdev *as_devalias;
|
||||||
struct mtx as_lock; /* lock for access to GATT */
|
struct mtx as_lock; /* lock for access to GATT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue