aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_ioctl.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-27 23:22:24 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:22 -0500
commit7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch)
tree1b5debcc86ff20bd5e11b42ea5c52da42214e376 /drivers/gpu/drm/drm_ioctl.c
parente7f7ab45ebcb54fd5f814ea15ea079e079662f67 (diff)
drm: move to kref per-master structures.
This is step one towards having multiple masters sharing a drm device in order to get fast-user-switching to work. It splits out the information associated with the drm master into a separate kref counted structure, and allocates this when a master opens the device node. It also allows the current master to abdicate (say while VT switched), and a new master to take over the hardware. It moves the Intel and radeon drivers to using the sarea from within the new master structures. 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.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 16829fb3089d..e35126a35093 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,37 @@ 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 = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER);
94 if (!dev->unique) 96 if (!master->unique)
95 return -ENOMEM; 97 return -ENOMEM;
96 if (copy_from_user(dev->unique, u->unique, dev->unique_len)) 98 if (copy_from_user(master->unique, u->unique, master->unique_len))
97 return -EFAULT; 99 return -EFAULT;
98 100
99 dev->unique[dev->unique_len] = '\0'; 101 master->unique[master->unique_len] = '\0';
100 102
101 dev->devname = 103 dev->devname =
102 drm_alloc(strlen(dev->driver->pci_driver.name) + 104 drm_alloc(strlen(dev->driver->pci_driver.name) +
103 strlen(dev->unique) + 2, DRM_MEM_DRIVER); 105 strlen(master->unique) + 2, DRM_MEM_DRIVER);
104 if (!dev->devname) 106 if (!dev->devname)
105 return -ENOMEM; 107 return -ENOMEM;
106 108
107 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, 109 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
108 dev->unique); 110 master->unique);
109 111
110 /* Return error if the busid submitted doesn't match the device's actual 112 /* Return error if the busid submitted doesn't match the device's actual
111 * busid. 113 * busid.
112 */ 114 */
113 ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func); 115 ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
114 if (ret != 3) 116 if (ret != 3)
115 return -EINVAL; 117 return -EINVAL;
116 domain = bus >> 8; 118 domain = bus >> 8;
@@ -125,34 +127,35 @@ int drm_setunique(struct drm_device *dev, void *data,
125 return 0; 127 return 0;
126} 128}
127 129
128static int drm_set_busid(struct drm_device * dev) 130static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
129{ 131{
132 struct drm_master *master = file_priv->master;
130 int len; 133 int len;
131 134
132 if (dev->unique != NULL) 135 if (master->unique != NULL)
133 return 0; 136 return -EBUSY;
134 137
135 dev->unique_len = 40; 138 master->unique_len = 40;
136 dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); 139 master->unique = drm_alloc(master->unique_len + 1, DRM_MEM_DRIVER);
137 if (dev->unique == NULL) 140 if (master->unique == NULL)
138 return -ENOMEM; 141 return -ENOMEM;
139 142
140 len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", 143 len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d",
141 drm_get_pci_domain(dev), dev->pdev->bus->number, 144 drm_get_pci_domain(dev),
145 dev->pdev->bus->number,
142 PCI_SLOT(dev->pdev->devfn), 146 PCI_SLOT(dev->pdev->devfn),
143 PCI_FUNC(dev->pdev->devfn)); 147 PCI_FUNC(dev->pdev->devfn));
144 148 if (len > master->unique_len)
145 if (len > dev->unique_len) 149 DRM_ERROR("buffer overflow");
146 DRM_ERROR("Unique buffer overflowed\n");
147 150
148 dev->devname = 151 dev->devname =
149 drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 152 drm_alloc(strlen(dev->driver->pci_driver.name) + master->unique_len +
150 2, DRM_MEM_DRIVER); 153 2, DRM_MEM_DRIVER);
151 if (dev->devname == NULL) 154 if (dev->devname == NULL)
152 return -ENOMEM; 155 return -ENOMEM;
153 156
154 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, 157 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
155 dev->unique); 158 master->unique);
156 159
157 return 0; 160 return 0;
158} 161}
@@ -276,7 +279,7 @@ int drm_getstats(struct drm_device *dev, void *data,
276 for (i = 0; i < dev->counters; i++) { 279 for (i = 0; i < dev->counters; i++) {
277 if (dev->types[i] == _DRM_STAT_LOCK) 280 if (dev->types[i] == _DRM_STAT_LOCK)
278 stats->data[i].value = 281 stats->data[i].value =
279 (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); 282 (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
280 else 283 else
281 stats->data[i].value = atomic_read(&dev->counts[i]); 284 stats->data[i].value = atomic_read(&dev->counts[i]);
282 stats->data[i].type = dev->types[i]; 285 stats->data[i].type = dev->types[i];
@@ -318,7 +321,7 @@ int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_pri
318 /* 321 /*
319 * Version 1.1 includes tying of DRM to specific device 322 * Version 1.1 includes tying of DRM to specific device
320 */ 323 */
321 drm_set_busid(dev); 324 drm_set_busid(dev, file_priv);
322 } 325 }
323 } 326 }
324 327