diff options
author | Jon Smirl <jonsmirl@yahoo.com> | 2004-07-31 15:45:00 +0000 |
---|---|---|
committer | Jon Smirl <jonsmirl@yahoo.com> | 2004-07-31 15:45:00 +0000 |
commit | 5e7e41819eb4d4b18201bbb46d0c6e359c4039cd (patch) | |
tree | c43aed0c568554569354715a6c2d1e98b7350233 | |
parent | bd71ba642890856aff339482a9422ecea1ef55d1 (diff) |
Add a hotplug event to DRM. Parameters match the ones from the general PCI
hotplug event plus the addition of one requesting RESET. Put your
scripts in /etc/hotplug.d/drm to run. kernel class_simple generates the
ADD/REMOVE events. No cards currently request RESET, the flag is there
to stop you from resetting your boot display.
-rw-r--r-- | linux-core/drmP.h | 8 | ||||
-rw-r--r-- | linux-core/drm_stub.c | 68 | ||||
-rw-r--r-- | linux/drmP.h | 8 | ||||
-rw-r--r-- | linux/drm_stub.h | 68 |
4 files changed, 146 insertions, 6 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 23c6854c..dfa56d90 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -696,11 +696,13 @@ typedef struct drm_device { struct pci_controller *hose; #endif #endif - drm_sg_mem_t *sg; /**< Scatter gather memory */ + drm_sg_mem_t *sg; /**< Scatter gather memory */ unsigned long *ctx_bitmap; /**< context bitmap */ - void *dev_private; /**< device private data */ - drm_sigdata_t sigdata; /**< For block_all_signals */ + void *dev_private; /**< device private data */ + drm_sigdata_t sigdata; /**< For block_all_signals */ sigset_t sigmask; + + int need_reset; /**< secondary device needing reset */ } drm_device_t; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 7ab5e427..a1b45a92 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -78,6 +78,73 @@ static struct file_operations DRM(stub_fops) = { .open = DRM(stub_open) }; +static int drm_hotplug (struct class_device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + drm_device_t *ddev; + struct pci_dev *pdev; + char *scratch; + int i = 0; + int length = 0; + + DRM_DEBUG("\n"); + if (!dev) + return -ENODEV; + + pdev = to_pci_dev(dev->dev); + if (!pdev) + return -ENODEV; + + scratch = buffer; + + /* stuff we want to pass to /sbin/hotplug */ + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X", + pdev->class); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X", + pdev->vendor, pdev->device); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, + "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, + pdev->subsystem_device); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s", + pci_name(pdev)); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + ddev = pci_get_drvdata(pdev); + if (ddev) { + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, + "RESET=%s", (ddev->need_reset ? "true" : "false")); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + } + envp[i] = 0; + DRM_DEBUG(" - ok\n"); + + return 0; +} + /** * Get a device minor number. * @@ -202,6 +269,7 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, } DRM(stub_info).drm_class = class_simple_create(THIS_MODULE, "drm"); + class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); if (IS_ERR(DRM(stub_info).drm_class)) { printk (KERN_ERR "Error creating drm class.\n"); unregister_chrdev(DRM_MAJOR, "drm"); diff --git a/linux/drmP.h b/linux/drmP.h index 23c6854c..dfa56d90 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -696,11 +696,13 @@ typedef struct drm_device { struct pci_controller *hose; #endif #endif - drm_sg_mem_t *sg; /**< Scatter gather memory */ + drm_sg_mem_t *sg; /**< Scatter gather memory */ unsigned long *ctx_bitmap; /**< context bitmap */ - void *dev_private; /**< device private data */ - drm_sigdata_t sigdata; /**< For block_all_signals */ + void *dev_private; /**< device private data */ + drm_sigdata_t sigdata; /**< For block_all_signals */ sigset_t sigmask; + + int need_reset; /**< secondary device needing reset */ } drm_device_t; diff --git a/linux/drm_stub.h b/linux/drm_stub.h index 7ab5e427..a1b45a92 100644 --- a/linux/drm_stub.h +++ b/linux/drm_stub.h @@ -78,6 +78,73 @@ static struct file_operations DRM(stub_fops) = { .open = DRM(stub_open) }; +static int drm_hotplug (struct class_device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + drm_device_t *ddev; + struct pci_dev *pdev; + char *scratch; + int i = 0; + int length = 0; + + DRM_DEBUG("\n"); + if (!dev) + return -ENODEV; + + pdev = to_pci_dev(dev->dev); + if (!pdev) + return -ENODEV; + + scratch = buffer; + + /* stuff we want to pass to /sbin/hotplug */ + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X", + pdev->class); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X", + pdev->vendor, pdev->device); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, + "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, + pdev->subsystem_device); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s", + pci_name(pdev)); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + ddev = pci_get_drvdata(pdev); + if (ddev) { + envp[i++] = scratch; + length += snprintf (scratch, buffer_size - length, + "RESET=%s", (ddev->need_reset ? "true" : "false")); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + } + envp[i] = 0; + DRM_DEBUG(" - ok\n"); + + return 0; +} + /** * Get a device minor number. * @@ -202,6 +269,7 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, } DRM(stub_info).drm_class = class_simple_create(THIS_MODULE, "drm"); + class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); if (IS_ERR(DRM(stub_info).drm_class)) { printk (KERN_ERR "Error creating drm class.\n"); unregister_chrdev(DRM_MAJOR, "drm"); |