Page MenuHomeFreeBSD

D21948.id63094.diff
No OneTemporary

D21948.id63094.diff

Index: sys/dev/acpica/acpi_pci.c
===================================================================
--- sys/dev/acpica/acpi_pci.c
+++ sys/dev/acpica/acpi_pci.c
@@ -71,9 +71,11 @@
CTASSERT(ACPI_STATE_D3 == PCI_POWERSTATE_D3);
static struct pci_devinfo *acpi_pci_alloc_devinfo(device_t dev);
+static int acpi_pci_attach(device_t dev);
static void acpi_pci_child_deleted(device_t dev, device_t child);
static int acpi_pci_child_location_str_method(device_t cbdev,
device_t child, char *buf, size_t buflen);
+static int acpi_pci_detach(device_t dev);
static int acpi_pci_probe(device_t dev);
static int acpi_pci_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result);
@@ -89,6 +91,8 @@
static device_method_t acpi_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_pci_probe),
+ DEVMETHOD(device_attach, acpi_pci_attach),
+ DEVMETHOD(device_detach, acpi_pci_detach),
/* Bus interface */
DEVMETHOD(bus_read_ivar, acpi_pci_read_ivar),
@@ -324,6 +328,139 @@
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (BUS_PROBE_DEFAULT);
+}
+
+static void
+acpi_pci_bus_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
+{
+ device_t dev;
+
+ dev = context;
+
+ switch (notify) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ mtx_lock(&Giant);
+ BUS_RESCAN(dev);
+ mtx_unlock(&Giant);
+ break;
+ default:
+ device_printf(dev, "unknown notify %#x\n", notify);
+ break;
+ }
+}
+
+static void
+acpi_pci_device_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
+{
+ device_t child, dev;
+ ACPI_STATUS status;
+ int error;
+
+ dev = context;
+
+ switch (notify) {
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ mtx_lock(&Giant);
+ BUS_RESCAN(dev);
+ mtx_unlock(&Giant);
+ break;
+ case ACPI_NOTIFY_DEVICE_EJECT_REQUEST:
+ child = acpi_get_device(handle);
+ if (child == NULL) {
+ device_printf(dev, "no device to eject for %s\n",
+ acpi_name(h));
+ return;
+ }
+ mtx_lock(&Giant);
+ error = device_detach(child);
+ if (error) {
+ mtx_unlock(&Giant);
+ device_printf(dev, "failed to detach %s: %d\n",
+ device_get_nameunit(child), error);
+ return;
+ }
+ status = AcpiEvaluateObject(h, "_EJ0", NULL, NULL);
+ if (ACPI_FAILURE(status)) {
+ mtx_unlock(&Giant);
+ device_printf(dev, "failed to eject %s: %s\n",
+ acpi_name(h), AcpiFormatException(status));
+ return;
+ }
+#ifdef notyet
+ error = device_delete_child(dev, child);
+ if (error) {
+ mtx_unlock(&Giant);
+ device_printf(dev, "failed to delete %s: %d\n",
+ acpi_name(h), error);
+ return;
+ }
+#endif
+ mtx_unlock(&Giant);
+ break;
+ default:
+ device_printf(dev, "unknown notify %#x for %s\n", notify,
+ acpi_name(h));
+ break;
+ }
+}
+
+static ACPI_STATUS
+acpi_pci_install_device_notify_handler(ACPI_HANDLE handle, UINT32 level,
+ void *context, void **status)
+{
+ ACPI_HANDLE h;
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+ if (ACPI_FAILURE(AcpiGetHandle(handle, "_EJ0", &h)))
+ return_ACPI_STATUS (AE_OK);
+
+ AcpiInstallNotifyHandler(handle, ACPI_SYSTEM_NOTIFY,
+ acpi_pci_device_notify_handler, context);
+ return_ACPI_STATUS (AE_OK);
+}
+
+static int
+acpi_pci_attach(device_t dev)
+{
+ int error;
+
+ error = pci_attach(dev);
+ if (error)
+ return (error);
+ AcpiInstallNotifyHandler(acpi_get_handle(dev), ACPI_SYSTEM_NOTIFY,
+ acpi_pci_bus_notify_handler, dev);
+ AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
+ acpi_pci_install_device_notify_handler, NULL, dev, NULL);
+
+ return (0);
+}
+
+static ACPI_STATUS
+acpi_pci_remove_notify_handler(ACPI_HANDLE handle, UINT32 level, void *context,
+ void **status)
+{
+ ACPI_HANDLE h;
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+ if (ACPI_FAILURE(AcpiGetHandle(handle, "_EJ0", &h)))
+ return_ACPI_STATUS (AE_OK);
+
+ AcpiRemoveNotifyHandler(handle, ACPI_SYSTEM_NOTIFY,
+ acpi_pci_device_notify_handler);
+ return_ACPI_STATUS (AE_OK);
+}
+
+static int
+acpi_pci_detach(device_t dev)
+{
+
+ AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
+ acpi_pci_remove_notify_handler, NULL, dev, NULL);
+ AcpiRemoveNotifyHandler(acpi_get_handle(dev), ACPI_SYSTEM_NOTIFY,
+ acpi_pci_bus_notify_handler);
+ return (pci_detach(dev));
}
#ifdef ACPI_DMAR
Index: sys/dev/pci/pci.c
===================================================================
--- sys/dev/pci/pci.c
+++ sys/dev/pci/pci.c
@@ -100,8 +100,6 @@
static int pci_add_map(device_t bus, device_t dev, int reg,
struct resource_list *rl, int force, int prefetch);
static int pci_probe(device_t dev);
-static int pci_attach(device_t dev);
-static int pci_detach(device_t dev);
static void pci_load_vendor_data(void);
static int pci_describe_parse_line(char **ptr, int *vendor,
int *device, char **desc);
@@ -4373,7 +4371,7 @@
return (0);
}
-static int
+int
pci_attach(device_t dev)
{
int busno, domain, error;
@@ -4394,7 +4392,7 @@
return (bus_generic_attach(dev));
}
-static int
+int
pci_detach(device_t dev)
{
#ifdef PCI_RES_BUS
Index: sys/dev/pci/pci_private.h
===================================================================
--- sys/dev/pci/pci_private.h
+++ sys/dev/pci/pci_private.h
@@ -58,7 +58,9 @@
uint32_t prefetchmask);
void pci_add_resources_ea(device_t bus, device_t dev, int alloc_iov);
struct pci_devinfo *pci_alloc_devinfo_method(device_t dev);
+int pci_attach(device_t dev);
int pci_attach_common(device_t dev);
+int pci_detach(device_t dev);
int pci_rescan_method(device_t dev);
void pci_driver_added(device_t dev, driver_t *driver);
int pci_ea_is_enabled(device_t dev, int rid);

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 7:37 PM (17 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37202235
Default Alt Text
D21948.id63094.diff (5 KB)

Event Timeline