diff options
Diffstat (limited to 'drivers/gpu/drm/drm_ioctl.c')
-rw-r--r-- | drivers/gpu/drm/drm_ioctl.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 16829fb3089d..1fad76289e66 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -53,12 +53,13 @@ int drm_getunique(struct drm_device *dev, void *data, | |||
53 | struct drm_file *file_priv) | 53 | struct drm_file *file_priv) |
54 | { | 54 | { |
55 | struct drm_unique *u = data; | 55 | struct drm_unique *u = data; |
56 | struct drm_master *master = file_priv->master; | ||
56 | 57 | ||
57 | if (u->unique_len >= dev->unique_len) { | 58 | if (u->unique_len >= master->unique_len) { |
58 | if (copy_to_user(u->unique, dev->unique, dev->unique_len)) | 59 | if (copy_to_user(u->unique, master->unique, master->unique_len)) |
59 | return -EFAULT; | 60 | return -EFAULT; |
60 | } | 61 | } |
61 | u->unique_len = dev->unique_len; | 62 | u->unique_len = master->unique_len; |
62 | 63 | ||
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
@@ -81,36 +82,38 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
81 | struct drm_file *file_priv) | 82 | struct drm_file *file_priv) |
82 | { | 83 | { |
83 | struct drm_unique *u = data; | 84 | struct drm_unique *u = data; |
85 | struct drm_master *master = file_priv->master; | ||
84 | int domain, bus, slot, func, ret; | 86 | int domain, bus, slot, func, ret; |
85 | 87 | ||
86 | if (dev->unique_len || dev->unique) | 88 | if (master->unique_len || master->unique) |
87 | return -EBUSY; | 89 | return -EBUSY; |
88 | 90 | ||
89 | if (!u->unique_len || u->unique_len > 1024) | 91 | if (!u->unique_len || u->unique_len > 1024) |
90 | return -EINVAL; | 92 | return -EINVAL; |
91 | 93 | ||
92 | dev->unique_len = u->unique_len; | 94 | master->unique_len = u->unique_len; |
93 | dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER); | 95 | master->unique_size = u->unique_len + 1; |
94 | if (!dev->unique) | 96 | master->unique = drm_alloc(master->unique_size, DRM_MEM_DRIVER); |
97 | if (!master->unique) | ||
95 | return -ENOMEM; | 98 | return -ENOMEM; |
96 | if (copy_from_user(dev->unique, u->unique, dev->unique_len)) | 99 | if (copy_from_user(master->unique, u->unique, master->unique_len)) |
97 | return -EFAULT; | 100 | return -EFAULT; |
98 | 101 | ||
99 | dev->unique[dev->unique_len] = '\0'; | 102 | master->unique[master->unique_len] = '\0'; |
100 | 103 | ||
101 | dev->devname = | 104 | dev->devname = |
102 | drm_alloc(strlen(dev->driver->pci_driver.name) + | 105 | drm_alloc(strlen(dev->driver->pci_driver.name) + |
103 | strlen(dev->unique) + 2, DRM_MEM_DRIVER); | 106 | strlen(master->unique) + 2, DRM_MEM_DRIVER); |
104 | if (!dev->devname) | 107 | if (!dev->devname) |
105 | return -ENOMEM; | 108 | return -ENOMEM; |
106 | 109 | ||
107 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, | 110 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, |
108 | dev->unique); | 111 | master->unique); |
109 | 112 | ||
110 | /* Return error if the busid submitted doesn't match the device's actual | 113 | /* Return error if the busid submitted doesn't match the device's actual |
111 | * busid. | 114 | * busid. |
112 | */ | 115 | */ |
113 | ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func); | 116 | ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); |
114 | if (ret != 3) | 117 | if (ret != 3) |
115 | return -EINVAL; | 118 | return -EINVAL; |
116 | domain = bus >> 8; | 119 | domain = bus >> 8; |
@@ -125,34 +128,38 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
125 | return 0; | 128 | return 0; |
126 | } | 129 | } |
127 | 130 | ||
128 | static int drm_set_busid(struct drm_device * dev) | 131 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) |
129 | { | 132 | { |
133 | struct drm_master *master = file_priv->master; | ||
130 | int len; | 134 | int len; |
131 | 135 | ||
132 | if (dev->unique != NULL) | 136 | if (master->unique != NULL) |
133 | return 0; | 137 | return -EBUSY; |
134 | 138 | ||
135 | dev->unique_len = 40; | 139 | master->unique_len = 40; |
136 | dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); | 140 | master->unique_size = master->unique_len; |
137 | if (dev->unique == NULL) | 141 | master->unique = drm_alloc(master->unique_size, DRM_MEM_DRIVER); |
142 | if (master->unique == NULL) | ||
138 | return -ENOMEM; | 143 | return -ENOMEM; |
139 | 144 | ||
140 | len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", | 145 | len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d", |
141 | drm_get_pci_domain(dev), dev->pdev->bus->number, | 146 | drm_get_pci_domain(dev), |
147 | dev->pdev->bus->number, | ||
142 | PCI_SLOT(dev->pdev->devfn), | 148 | PCI_SLOT(dev->pdev->devfn), |
143 | PCI_FUNC(dev->pdev->devfn)); | 149 | PCI_FUNC(dev->pdev->devfn)); |
144 | 150 | if (len >= master->unique_len) | |
145 | if (len > dev->unique_len) | 151 | DRM_ERROR("buffer overflow"); |
146 | DRM_ERROR("Unique buffer overflowed\n"); | 152 | else |
153 | master->unique_len = len; | ||
147 | 154 | ||
148 | dev->devname = | 155 | dev->devname = |
149 | drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + | 156 | drm_alloc(strlen(dev->driver->pci_driver.name) + master->unique_len + |
150 | 2, DRM_MEM_DRIVER); | 157 | 2, DRM_MEM_DRIVER); |
151 | if (dev->devname == NULL) | 158 | if (dev->devname == NULL) |
152 | return -ENOMEM; | 159 | return -ENOMEM; |
153 | 160 | ||
154 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, | 161 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, |
155 | dev->unique); | 162 | master->unique); |
156 | 163 | ||
157 | return 0; | 164 | return 0; |
158 | } | 165 | } |
@@ -276,7 +283,7 @@ int drm_getstats(struct drm_device *dev, void *data, | |||
276 | for (i = 0; i < dev->counters; i++) { | 283 | for (i = 0; i < dev->counters; i++) { |
277 | if (dev->types[i] == _DRM_STAT_LOCK) | 284 | if (dev->types[i] == _DRM_STAT_LOCK) |
278 | stats->data[i].value = | 285 | stats->data[i].value = |
279 | (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); | 286 | (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0); |
280 | else | 287 | else |
281 | stats->data[i].value = atomic_read(&dev->counts[i]); | 288 | stats->data[i].value = atomic_read(&dev->counts[i]); |
282 | stats->data[i].type = dev->types[i]; | 289 | stats->data[i].type = dev->types[i]; |
@@ -318,7 +325,7 @@ int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
318 | /* | 325 | /* |
319 | * Version 1.1 includes tying of DRM to specific device | 326 | * Version 1.1 includes tying of DRM to specific device |
320 | */ | 327 | */ |
321 | drm_set_busid(dev); | 328 | drm_set_busid(dev, file_priv); |
322 | } | 329 | } |
323 | } | 330 | } |
324 | 331 | ||