aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_ioctl.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2010-12-14 12:16:38 -0500
committerDave Airlie <airlied@redhat.com>2011-02-06 22:09:36 -0500
commit8410ea3b95d105a5be5db501656f44bbb91197c1 (patch)
tree6cd27f207e50c13ba2f4a78d6323bc23f751e380 /drivers/gpu/drm/drm_ioctl.c
parentff72145badb834e8051719ea66e024784d000cb4 (diff)
drm: rework PCI/platform driver interface.
This abstracts the pci/platform interface out a step further, we can go further but this is far enough for now to allow USB to be plugged in. The drivers now just call the init code directly for their device type. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_ioctl.c')
-rw-r--r--drivers/gpu/drm/drm_ioctl.c115
1 files changed, 9 insertions, 106 deletions
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 47db4df37a69..117490590f56 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -96,7 +96,7 @@ int drm_setunique(struct drm_device *dev, void *data,
96{ 96{
97 struct drm_unique *u = data; 97 struct drm_unique *u = data;
98 struct drm_master *master = file_priv->master; 98 struct drm_master *master = file_priv->master;
99 int domain, bus, slot, func, ret; 99 int ret;
100 100
101 if (master->unique_len || master->unique) 101 if (master->unique_len || master->unique)
102 return -EBUSY; 102 return -EBUSY;
@@ -104,50 +104,12 @@ int drm_setunique(struct drm_device *dev, void *data,
104 if (!u->unique_len || u->unique_len > 1024) 104 if (!u->unique_len || u->unique_len > 1024)
105 return -EINVAL; 105 return -EINVAL;
106 106
107 master->unique_len = u->unique_len; 107 if (!dev->driver->bus->set_unique)
108 master->unique_size = u->unique_len + 1; 108 return -EINVAL;
109 master->unique = kmalloc(master->unique_size, GFP_KERNEL);
110 if (!master->unique) {
111 ret = -ENOMEM;
112 goto err;
113 }
114
115 if (copy_from_user(master->unique, u->unique, master->unique_len)) {
116 ret = -EFAULT;
117 goto err;
118 }
119
120 master->unique[master->unique_len] = '\0';
121
122 dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
123 strlen(master->unique) + 2, GFP_KERNEL);
124 if (!dev->devname) {
125 ret = -ENOMEM;
126 goto err;
127 }
128
129 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
130 master->unique);
131
132 /* Return error if the busid submitted doesn't match the device's actual
133 * busid.
134 */
135 ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
136 if (ret != 3) {
137 ret = -EINVAL;
138 goto err;
139 }
140
141 domain = bus >> 8;
142 bus &= 0xff;
143 109
144 if ((domain != drm_get_pci_domain(dev)) || 110 ret = dev->driver->bus->set_unique(dev, master, u);
145 (bus != dev->pdev->bus->number) || 111 if (ret)
146 (slot != PCI_SLOT(dev->pdev->devfn)) ||
147 (func != PCI_FUNC(dev->pdev->devfn))) {
148 ret = -EINVAL;
149 goto err; 112 goto err;
150 }
151 113
152 return 0; 114 return 0;
153 115
@@ -159,74 +121,15 @@ err:
159static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) 121static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
160{ 122{
161 struct drm_master *master = file_priv->master; 123 struct drm_master *master = file_priv->master;
162 int len, ret; 124 int ret;
163 125
164 if (master->unique != NULL) 126 if (master->unique != NULL)
165 drm_unset_busid(dev, master); 127 drm_unset_busid(dev, master);
166 128
167 if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { 129 ret = dev->driver->bus->set_busid(dev, master);
168 master->unique_len = 10 + strlen(dev->platformdev->name); 130 if (ret)
169 master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); 131 goto err;
170
171 if (master->unique == NULL)
172 return -ENOMEM;
173
174 len = snprintf(master->unique, master->unique_len,
175 "platform:%s", dev->platformdev->name);
176
177 if (len > master->unique_len) {
178 DRM_ERROR("Unique buffer overflowed\n");
179 ret = -EINVAL;
180 goto err;
181 }
182
183 dev->devname =
184 kmalloc(strlen(dev->platformdev->name) +
185 master->unique_len + 2, GFP_KERNEL);
186
187 if (dev->devname == NULL) {
188 ret = -ENOMEM;
189 goto err;
190 }
191
192 sprintf(dev->devname, "%s@%s", dev->platformdev->name,
193 master->unique);
194
195 } else {
196 master->unique_len = 40;
197 master->unique_size = master->unique_len;
198 master->unique = kmalloc(master->unique_size, GFP_KERNEL);
199 if (master->unique == NULL)
200 return -ENOMEM;
201
202 len = snprintf(master->unique, master->unique_len,
203 "pci:%04x:%02x:%02x.%d",
204 drm_get_pci_domain(dev),
205 dev->pdev->bus->number,
206 PCI_SLOT(dev->pdev->devfn),
207 PCI_FUNC(dev->pdev->devfn));
208 if (len >= master->unique_len) {
209 DRM_ERROR("buffer overflow");
210 ret = -EINVAL;
211 goto err;
212 } else
213 master->unique_len = len;
214
215 dev->devname =
216 kmalloc(strlen(dev->driver->pci_driver.name) +
217 master->unique_len + 2, GFP_KERNEL);
218
219 if (dev->devname == NULL) {
220 ret = -ENOMEM;
221 goto err;
222 }
223
224 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
225 master->unique);
226 }
227
228 return 0; 132 return 0;
229
230err: 133err:
231 drm_unset_busid(dev, master); 134 drm_unset_busid(dev, master);
232 return ret; 135 return ret;