0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/dma-mapping.h>
0026 #include <linux/export.h>
0027 #include <linux/list.h>
0028 #include <linux/mutex.h>
0029 #include <linux/pci.h>
0030 #include <linux/slab.h>
0031
0032 #include <drm/drm.h>
0033 #include <drm/drm_drv.h>
0034 #include <drm/drm_print.h>
0035
0036 #include "drm_internal.h"
0037 #include "drm_legacy.h"
0038
0039 #ifdef CONFIG_DRM_LEGACY
0040
0041 static LIST_HEAD(legacy_dev_list);
0042 static DEFINE_MUTEX(legacy_dev_list_lock);
0043 #endif
0044
0045 static int drm_get_pci_domain(struct drm_device *dev)
0046 {
0047 #ifndef __alpha__
0048
0049
0050
0051
0052 if (dev->if_version < 0x10004)
0053 return 0;
0054 #endif
0055
0056 return pci_domain_nr(to_pci_dev(dev->dev)->bus);
0057 }
0058
0059 int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
0060 {
0061 struct pci_dev *pdev = to_pci_dev(dev->dev);
0062
0063 master->unique = kasprintf(GFP_KERNEL, "pci:%04x:%02x:%02x.%d",
0064 drm_get_pci_domain(dev),
0065 pdev->bus->number,
0066 PCI_SLOT(pdev->devfn),
0067 PCI_FUNC(pdev->devfn));
0068 if (!master->unique)
0069 return -ENOMEM;
0070
0071 master->unique_len = strlen(master->unique);
0072 return 0;
0073 }
0074
0075 #ifdef CONFIG_DRM_LEGACY
0076
0077 static int drm_legacy_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
0078 {
0079 struct pci_dev *pdev = to_pci_dev(dev->dev);
0080
0081 if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
0082 (p->busnum & 0xff) != pdev->bus->number ||
0083 p->devnum != PCI_SLOT(pdev->devfn) || p->funcnum != PCI_FUNC(pdev->devfn))
0084 return -EINVAL;
0085
0086 p->irq = pdev->irq;
0087
0088 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
0089 p->irq);
0090 return 0;
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 int drm_legacy_irq_by_busid(struct drm_device *dev, void *data,
0106 struct drm_file *file_priv)
0107 {
0108 struct drm_irq_busid *p = data;
0109
0110 if (!drm_core_check_feature(dev, DRIVER_LEGACY))
0111 return -EOPNOTSUPP;
0112
0113
0114 if (WARN_ON(!dev_is_pci(dev->dev)))
0115 return -EINVAL;
0116
0117 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
0118 return -EOPNOTSUPP;
0119
0120 return drm_legacy_pci_irq_by_busid(dev, p);
0121 }
0122
0123 void drm_legacy_pci_agp_destroy(struct drm_device *dev)
0124 {
0125 if (dev->agp) {
0126 arch_phys_wc_del(dev->agp->agp_mtrr);
0127 drm_legacy_agp_clear(dev);
0128 kfree(dev->agp);
0129 dev->agp = NULL;
0130 }
0131 }
0132
0133 static void drm_legacy_pci_agp_init(struct drm_device *dev)
0134 {
0135 if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
0136 if (pci_find_capability(to_pci_dev(dev->dev), PCI_CAP_ID_AGP))
0137 dev->agp = drm_legacy_agp_init(dev);
0138 if (dev->agp) {
0139 dev->agp->agp_mtrr = arch_phys_wc_add(
0140 dev->agp->agp_info.aper_base,
0141 dev->agp->agp_info.aper_size *
0142 1024 * 1024);
0143 }
0144 }
0145 }
0146
0147 static int drm_legacy_get_pci_dev(struct pci_dev *pdev,
0148 const struct pci_device_id *ent,
0149 const struct drm_driver *driver)
0150 {
0151 struct drm_device *dev;
0152 int ret;
0153
0154 DRM_DEBUG("\n");
0155
0156 dev = drm_dev_alloc(driver, &pdev->dev);
0157 if (IS_ERR(dev))
0158 return PTR_ERR(dev);
0159
0160 ret = pci_enable_device(pdev);
0161 if (ret)
0162 goto err_free;
0163
0164 #ifdef __alpha__
0165 dev->hose = pdev->sysdata;
0166 #endif
0167
0168 drm_legacy_pci_agp_init(dev);
0169
0170 ret = drm_dev_register(dev, ent->driver_data);
0171 if (ret)
0172 goto err_agp;
0173
0174 if (drm_core_check_feature(dev, DRIVER_LEGACY)) {
0175 mutex_lock(&legacy_dev_list_lock);
0176 list_add_tail(&dev->legacy_dev_list, &legacy_dev_list);
0177 mutex_unlock(&legacy_dev_list_lock);
0178 }
0179
0180 return 0;
0181
0182 err_agp:
0183 drm_legacy_pci_agp_destroy(dev);
0184 pci_disable_device(pdev);
0185 err_free:
0186 drm_dev_put(dev);
0187 return ret;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 int drm_legacy_pci_init(const struct drm_driver *driver,
0200 struct pci_driver *pdriver)
0201 {
0202 struct pci_dev *pdev = NULL;
0203 const struct pci_device_id *pid;
0204 int i;
0205
0206 DRM_DEBUG("\n");
0207
0208 if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY)))
0209 return -EINVAL;
0210
0211
0212 for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
0213 pid = &pdriver->id_table[i];
0214
0215
0216
0217
0218
0219
0220
0221 pdev = NULL;
0222 while ((pdev =
0223 pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
0224 pid->subdevice, pdev)) != NULL) {
0225 if ((pdev->class & pid->class_mask) != pid->class)
0226 continue;
0227
0228
0229 pci_dev_get(pdev);
0230 drm_legacy_get_pci_dev(pdev, pid, driver);
0231 }
0232 }
0233 return 0;
0234 }
0235 EXPORT_SYMBOL(drm_legacy_pci_init);
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 void drm_legacy_pci_exit(const struct drm_driver *driver,
0246 struct pci_driver *pdriver)
0247 {
0248 struct drm_device *dev, *tmp;
0249
0250 DRM_DEBUG("\n");
0251
0252 if (!(driver->driver_features & DRIVER_LEGACY)) {
0253 WARN_ON(1);
0254 } else {
0255 mutex_lock(&legacy_dev_list_lock);
0256 list_for_each_entry_safe(dev, tmp, &legacy_dev_list,
0257 legacy_dev_list) {
0258 if (dev->driver == driver) {
0259 list_del(&dev->legacy_dev_list);
0260 drm_put_dev(dev);
0261 }
0262 }
0263 mutex_unlock(&legacy_dev_list_lock);
0264 }
0265 DRM_INFO("Module unloaded\n");
0266 }
0267 EXPORT_SYMBOL(drm_legacy_pci_exit);
0268
0269 #endif