diff --git a/sys/dev/agp/agp_amd64.c b/sys/dev/agp/agp_amd64.c index 3d19e640..66b1a34f 100644 --- a/sys/dev/agp/agp_amd64.c +++ b/sys/dev/agp/agp_amd64.c @@ -204,14 +204,18 @@ agp_amd64_attach(device_t dev) switch (pci_get_vendor(dev)) { case 0x10b9: /* ULi */ agp_amd64_uli_init(dev); - if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture)) - return (ENXIO); + if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture)) { + error = ENXIO; + goto err; + } break; case 0x10de: /* nVidia */ agp_amd64_nvidia_init(dev); - if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture)) - return (ENXIO); + if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture)) { + error = ENXIO; + goto err; + } break; case 0x1106: /* VIA */ @@ -219,8 +223,10 @@ agp_amd64_attach(device_t dev) if (sc->via_agp) { agp_amd64_via_init(dev); if (agp_amd64_via_set_aperture(dev, - sc->initial_aperture)) - return (ENXIO); + sc->initial_aperture)) { + error = ENXIO; + goto err; + } } break; } @@ -240,6 +246,18 @@ agp_amd64_attach(device_t dev) agp_flush_cache(); return (0); + +err: + /* + * agp_generic_attach() already published /dev/agpgart and + * allocated the aperture resource; sc->gatt is allocated. + * Undo everything or the cdev/resource/GATT leak on an + * unattached device. + */ + agp_free_gatt(sc->gatt); + sc->gatt = NULL; + agp_generic_detach(dev); + return (error); } static int