diff options
-rw-r--r-- | drivers/char/drm/drmP.h | 42 | ||||
-rw-r--r-- | drivers/char/drm/drm_agpsupport.c | 2 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 60 | ||||
-rw-r--r-- | drivers/char/drm/drm_fops.c | 37 | ||||
-rw-r--r-- | drivers/char/drm/drm_proc.c | 61 | ||||
-rw-r--r-- | drivers/char/drm/drm_stub.c | 138 | ||||
-rw-r--r-- | drivers/char/drm/drm_sysfs.c | 46 | ||||
-rw-r--r-- | drivers/char/drm/drm_vm.c | 20 | ||||
-rw-r--r-- | drivers/char/drm/i810_dma.c | 4 | ||||
-rw-r--r-- | drivers/char/drm/i830_dma.c | 4 |
10 files changed, 230 insertions, 184 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 6540948d5176..5446235094d8 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -379,13 +379,12 @@ struct drm_buf_entry { | |||
379 | struct drm_file { | 379 | struct drm_file { |
380 | int authenticated; | 380 | int authenticated; |
381 | int master; | 381 | int master; |
382 | int minor; | ||
383 | pid_t pid; | 382 | pid_t pid; |
384 | uid_t uid; | 383 | uid_t uid; |
385 | drm_magic_t magic; | 384 | drm_magic_t magic; |
386 | unsigned long ioctl_count; | 385 | unsigned long ioctl_count; |
387 | struct list_head lhead; | 386 | struct list_head lhead; |
388 | struct drm_head *head; | 387 | struct drm_minor *minor; |
389 | int remove_auth_on_close; | 388 | int remove_auth_on_close; |
390 | unsigned long lock_count; | 389 | unsigned long lock_count; |
391 | struct file *filp; | 390 | struct file *filp; |
@@ -630,16 +629,19 @@ struct drm_driver { | |||
630 | struct pci_driver pci_driver; | 629 | struct pci_driver pci_driver; |
631 | }; | 630 | }; |
632 | 631 | ||
632 | #define DRM_MINOR_UNASSIGNED 0 | ||
633 | #define DRM_MINOR_LEGACY 1 | ||
634 | |||
633 | /** | 635 | /** |
634 | * DRM head structure. This structure represent a video head on a card | 636 | * DRM minor structure. This structure represents a drm minor number. |
635 | * that may contain multiple heads. Embed one per head of these in the | ||
636 | * private drm_device structure. | ||
637 | */ | 637 | */ |
638 | struct drm_head { | 638 | struct drm_minor { |
639 | int minor; /**< Minor device number */ | 639 | int index; /**< Minor device number */ |
640 | int type; /**< Control or render */ | ||
641 | dev_t device; /**< Device number for mknod */ | ||
642 | struct device kdev; /**< Linux device */ | ||
640 | struct drm_device *dev; | 643 | struct drm_device *dev; |
641 | struct proc_dir_entry *dev_root; /**< proc directory entry */ | 644 | struct proc_dir_entry *dev_root; /**< proc directory entry */ |
642 | dev_t device; /**< Device number for mknod */ | ||
643 | }; | 645 | }; |
644 | 646 | ||
645 | /** | 647 | /** |
@@ -647,7 +649,6 @@ struct drm_head { | |||
647 | * may contain multiple heads. | 649 | * may contain multiple heads. |
648 | */ | 650 | */ |
649 | struct drm_device { | 651 | struct drm_device { |
650 | struct device dev; /**< Linux device */ | ||
651 | char *unique; /**< Unique identifier: e.g., busid */ | 652 | char *unique; /**< Unique identifier: e.g., busid */ |
652 | int unique_len; /**< Length of unique field */ | 653 | int unique_len; /**< Length of unique field */ |
653 | char *devname; /**< For /proc/interrupts */ | 654 | char *devname; /**< For /proc/interrupts */ |
@@ -763,7 +764,7 @@ struct drm_device { | |||
763 | struct drm_driver *driver; | 764 | struct drm_driver *driver; |
764 | drm_local_map_t *agp_buffer_map; | 765 | drm_local_map_t *agp_buffer_map; |
765 | unsigned int agp_buffer_token; | 766 | unsigned int agp_buffer_token; |
766 | struct drm_head primary; /**< primary screen head */ | 767 | struct drm_minor *primary; /**< render type primary screen head */ |
767 | 768 | ||
768 | /** \name Drawable information */ | 769 | /** \name Drawable information */ |
769 | /*@{ */ | 770 | /*@{ */ |
@@ -1030,23 +1031,20 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); | |||
1030 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | 1031 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, |
1031 | struct drm_driver *driver); | 1032 | struct drm_driver *driver); |
1032 | extern int drm_put_dev(struct drm_device *dev); | 1033 | extern int drm_put_dev(struct drm_device *dev); |
1033 | extern int drm_put_head(struct drm_head *head); | 1034 | extern int drm_put_minor(struct drm_minor **minor); |
1034 | extern unsigned int drm_debug; | 1035 | extern unsigned int drm_debug; |
1035 | extern unsigned int drm_cards_limit; | 1036 | |
1036 | extern struct drm_head **drm_heads; | ||
1037 | extern struct class *drm_class; | 1037 | extern struct class *drm_class; |
1038 | extern struct proc_dir_entry *drm_proc_root; | 1038 | extern struct proc_dir_entry *drm_proc_root; |
1039 | 1039 | ||
1040 | extern struct idr drm_minors_idr; | ||
1041 | |||
1040 | extern drm_local_map_t *drm_getsarea(struct drm_device *dev); | 1042 | extern drm_local_map_t *drm_getsarea(struct drm_device *dev); |
1041 | 1043 | ||
1042 | /* Proc support (drm_proc.h) */ | 1044 | /* Proc support (drm_proc.h) */ |
1043 | extern int drm_proc_init(struct drm_device *dev, | 1045 | extern int drm_proc_init(struct drm_minor *minor, int minor_id, |
1044 | int minor, | 1046 | struct proc_dir_entry *root); |
1045 | struct proc_dir_entry *root, | 1047 | extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); |
1046 | struct proc_dir_entry **dev_root); | ||
1047 | extern int drm_proc_cleanup(int minor, | ||
1048 | struct proc_dir_entry *root, | ||
1049 | struct proc_dir_entry *dev_root); | ||
1050 | 1048 | ||
1051 | /* Scatter Gather Support (drm_scatter.h) */ | 1049 | /* Scatter Gather Support (drm_scatter.h) */ |
1052 | extern void drm_sg_cleanup(struct drm_sg_mem * entry); | 1050 | extern void drm_sg_cleanup(struct drm_sg_mem * entry); |
@@ -1071,8 +1069,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); | |||
1071 | struct drm_sysfs_class; | 1069 | struct drm_sysfs_class; |
1072 | extern struct class *drm_sysfs_create(struct module *owner, char *name); | 1070 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1073 | extern void drm_sysfs_destroy(void); | 1071 | extern void drm_sysfs_destroy(void); |
1074 | extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); | 1072 | extern int drm_sysfs_device_add(struct drm_minor *minor); |
1075 | extern void drm_sysfs_device_remove(struct drm_device *dev); | 1073 | extern void drm_sysfs_device_remove(struct drm_minor *minor); |
1076 | 1074 | ||
1077 | /* | 1075 | /* |
1078 | * Basic memory manager support (drm_mm.c) | 1076 | * Basic memory manager support (drm_mm.c) |
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 9468c7889ff1..aefa5ac4c0b1 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c | |||
@@ -122,7 +122,7 @@ EXPORT_SYMBOL(drm_agp_acquire); | |||
122 | int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, | 122 | int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, |
123 | struct drm_file *file_priv) | 123 | struct drm_file *file_priv) |
124 | { | 124 | { |
125 | return drm_agp_acquire((struct drm_device *) file_priv->head->dev); | 125 | return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); |
126 | } | 126 | } |
127 | 127 | ||
128 | /** | 128 | /** |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 0e7af53c87de..fc54140551a7 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -313,35 +313,36 @@ static void drm_cleanup(struct drm_device * dev) | |||
313 | drm_ht_remove(&dev->map_hash); | 313 | drm_ht_remove(&dev->map_hash); |
314 | drm_ctxbitmap_cleanup(dev); | 314 | drm_ctxbitmap_cleanup(dev); |
315 | 315 | ||
316 | drm_put_head(&dev->primary); | 316 | drm_put_minor(&dev->primary); |
317 | if (drm_put_dev(dev)) | 317 | if (drm_put_dev(dev)) |
318 | DRM_ERROR("Cannot unload module\n"); | 318 | DRM_ERROR("Cannot unload module\n"); |
319 | } | 319 | } |
320 | 320 | ||
321 | void drm_exit(struct drm_driver *driver) | 321 | int drm_minors_cleanup(int id, void *ptr, void *data) |
322 | { | 322 | { |
323 | int i; | 323 | struct drm_minor *minor = ptr; |
324 | struct drm_device *dev = NULL; | 324 | struct drm_device *dev; |
325 | struct drm_head *head; | 325 | struct drm_driver *driver = data; |
326 | |||
327 | dev = minor->dev; | ||
328 | if (minor->dev->driver != driver) | ||
329 | return 0; | ||
330 | |||
331 | if (minor->type != DRM_MINOR_LEGACY) | ||
332 | return 0; | ||
326 | 333 | ||
334 | if (dev) | ||
335 | pci_dev_put(dev->pdev); | ||
336 | drm_cleanup(dev); | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | void drm_exit(struct drm_driver *driver) | ||
341 | { | ||
327 | DRM_DEBUG("\n"); | 342 | DRM_DEBUG("\n"); |
328 | 343 | ||
329 | for (i = 0; i < drm_cards_limit; i++) { | 344 | idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); |
330 | head = drm_heads[i]; | 345 | |
331 | if (!head) | ||
332 | continue; | ||
333 | if (!head->dev) | ||
334 | continue; | ||
335 | if (head->dev->driver != driver) | ||
336 | continue; | ||
337 | dev = head->dev; | ||
338 | if (dev) { | ||
339 | /* release the pci driver */ | ||
340 | if (dev->pdev) | ||
341 | pci_dev_put(dev->pdev); | ||
342 | drm_cleanup(dev); | ||
343 | } | ||
344 | } | ||
345 | DRM_INFO("Module unloaded\n"); | 346 | DRM_INFO("Module unloaded\n"); |
346 | } | 347 | } |
347 | 348 | ||
@@ -357,13 +358,7 @@ static int __init drm_core_init(void) | |||
357 | { | 358 | { |
358 | int ret = -ENOMEM; | 359 | int ret = -ENOMEM; |
359 | 360 | ||
360 | drm_cards_limit = | 361 | idr_init(&drm_minors_idr); |
361 | (drm_cards_limit < | ||
362 | DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); | ||
363 | drm_heads = | ||
364 | drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); | ||
365 | if (!drm_heads) | ||
366 | goto err_p1; | ||
367 | 362 | ||
368 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | 363 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) |
369 | goto err_p1; | 364 | goto err_p1; |
@@ -391,7 +386,8 @@ err_p3: | |||
391 | drm_sysfs_destroy(); | 386 | drm_sysfs_destroy(); |
392 | err_p2: | 387 | err_p2: |
393 | unregister_chrdev(DRM_MAJOR, "drm"); | 388 | unregister_chrdev(DRM_MAJOR, "drm"); |
394 | drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); | 389 | |
390 | idr_destroy(&drm_minors_idr); | ||
395 | err_p1: | 391 | err_p1: |
396 | return ret; | 392 | return ret; |
397 | } | 393 | } |
@@ -403,7 +399,7 @@ static void __exit drm_core_exit(void) | |||
403 | 399 | ||
404 | unregister_chrdev(DRM_MAJOR, "drm"); | 400 | unregister_chrdev(DRM_MAJOR, "drm"); |
405 | 401 | ||
406 | drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); | 402 | idr_destroy(&drm_minors_idr); |
407 | } | 403 | } |
408 | 404 | ||
409 | module_init(drm_core_init); | 405 | module_init(drm_core_init); |
@@ -452,7 +448,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
452 | unsigned int cmd, unsigned long arg) | 448 | unsigned int cmd, unsigned long arg) |
453 | { | 449 | { |
454 | struct drm_file *file_priv = filp->private_data; | 450 | struct drm_file *file_priv = filp->private_data; |
455 | struct drm_device *dev = file_priv->head->dev; | 451 | struct drm_device *dev = file_priv->minor->dev; |
456 | struct drm_ioctl_desc *ioctl; | 452 | struct drm_ioctl_desc *ioctl; |
457 | drm_ioctl_t *func; | 453 | drm_ioctl_t *func; |
458 | unsigned int nr = DRM_IOCTL_NR(cmd); | 454 | unsigned int nr = DRM_IOCTL_NR(cmd); |
@@ -465,7 +461,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
465 | 461 | ||
466 | DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", | 462 | DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", |
467 | task_pid_nr(current), cmd, nr, | 463 | task_pid_nr(current), cmd, nr, |
468 | (long)old_encode_dev(file_priv->head->device), | 464 | (long)old_encode_dev(file_priv->minor->device), |
469 | file_priv->authenticated); | 465 | file_priv->authenticated); |
470 | 466 | ||
471 | if ((nr >= DRM_CORE_IOCTL_COUNT) && | 467 | if ((nr >= DRM_CORE_IOCTL_COUNT) && |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index f09d4b5002b0..df7bf48be692 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -129,16 +129,15 @@ static int drm_setup(struct drm_device * dev) | |||
129 | int drm_open(struct inode *inode, struct file *filp) | 129 | int drm_open(struct inode *inode, struct file *filp) |
130 | { | 130 | { |
131 | struct drm_device *dev = NULL; | 131 | struct drm_device *dev = NULL; |
132 | int minor = iminor(inode); | 132 | int minor_id = iminor(inode); |
133 | struct drm_minor *minor; | ||
133 | int retcode = 0; | 134 | int retcode = 0; |
134 | 135 | ||
135 | if (!((minor >= 0) && (minor < drm_cards_limit))) | 136 | minor = idr_find(&drm_minors_idr, minor_id); |
137 | if (!minor) | ||
136 | return -ENODEV; | 138 | return -ENODEV; |
137 | 139 | ||
138 | if (!drm_heads[minor]) | 140 | if (!(dev = minor->dev)) |
139 | return -ENODEV; | ||
140 | |||
141 | if (!(dev = drm_heads[minor]->dev)) | ||
142 | return -ENODEV; | 141 | return -ENODEV; |
143 | 142 | ||
144 | retcode = drm_open_helper(inode, filp, dev); | 143 | retcode = drm_open_helper(inode, filp, dev); |
@@ -168,19 +167,18 @@ EXPORT_SYMBOL(drm_open); | |||
168 | int drm_stub_open(struct inode *inode, struct file *filp) | 167 | int drm_stub_open(struct inode *inode, struct file *filp) |
169 | { | 168 | { |
170 | struct drm_device *dev = NULL; | 169 | struct drm_device *dev = NULL; |
171 | int minor = iminor(inode); | 170 | struct drm_minor *minor; |
171 | int minor_id = iminor(inode); | ||
172 | int err = -ENODEV; | 172 | int err = -ENODEV; |
173 | const struct file_operations *old_fops; | 173 | const struct file_operations *old_fops; |
174 | 174 | ||
175 | DRM_DEBUG("\n"); | 175 | DRM_DEBUG("\n"); |
176 | 176 | ||
177 | if (!((minor >= 0) && (minor < drm_cards_limit))) | 177 | minor = idr_find(&drm_minors_idr, minor_id); |
178 | return -ENODEV; | 178 | if (!minor) |
179 | |||
180 | if (!drm_heads[minor]) | ||
181 | return -ENODEV; | 179 | return -ENODEV; |
182 | 180 | ||
183 | if (!(dev = drm_heads[minor]->dev)) | 181 | if (!(dev = minor->dev)) |
184 | return -ENODEV; | 182 | return -ENODEV; |
185 | 183 | ||
186 | old_fops = filp->f_op; | 184 | old_fops = filp->f_op; |
@@ -225,7 +223,7 @@ static int drm_cpu_valid(void) | |||
225 | static int drm_open_helper(struct inode *inode, struct file *filp, | 223 | static int drm_open_helper(struct inode *inode, struct file *filp, |
226 | struct drm_device * dev) | 224 | struct drm_device * dev) |
227 | { | 225 | { |
228 | int minor = iminor(inode); | 226 | int minor_id = iminor(inode); |
229 | struct drm_file *priv; | 227 | struct drm_file *priv; |
230 | int ret; | 228 | int ret; |
231 | 229 | ||
@@ -234,7 +232,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
234 | if (!drm_cpu_valid()) | 232 | if (!drm_cpu_valid()) |
235 | return -EINVAL; | 233 | return -EINVAL; |
236 | 234 | ||
237 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor); | 235 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); |
238 | 236 | ||
239 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | 237 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); |
240 | if (!priv) | 238 | if (!priv) |
@@ -245,8 +243,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
245 | priv->filp = filp; | 243 | priv->filp = filp; |
246 | priv->uid = current->euid; | 244 | priv->uid = current->euid; |
247 | priv->pid = task_pid_nr(current); | 245 | priv->pid = task_pid_nr(current); |
248 | priv->minor = minor; | 246 | priv->minor = idr_find(&drm_minors_idr, minor_id); |
249 | priv->head = drm_heads[minor]; | ||
250 | priv->ioctl_count = 0; | 247 | priv->ioctl_count = 0; |
251 | /* for compatibility root is always authenticated */ | 248 | /* for compatibility root is always authenticated */ |
252 | priv->authenticated = capable(CAP_SYS_ADMIN); | 249 | priv->authenticated = capable(CAP_SYS_ADMIN); |
@@ -297,11 +294,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
297 | int drm_fasync(int fd, struct file *filp, int on) | 294 | int drm_fasync(int fd, struct file *filp, int on) |
298 | { | 295 | { |
299 | struct drm_file *priv = filp->private_data; | 296 | struct drm_file *priv = filp->private_data; |
300 | struct drm_device *dev = priv->head->dev; | 297 | struct drm_device *dev = priv->minor->dev; |
301 | int retcode; | 298 | int retcode; |
302 | 299 | ||
303 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, | 300 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, |
304 | (long)old_encode_dev(priv->head->device)); | 301 | (long)old_encode_dev(priv->minor->device)); |
305 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); | 302 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); |
306 | if (retcode < 0) | 303 | if (retcode < 0) |
307 | return retcode; | 304 | return retcode; |
@@ -324,7 +321,7 @@ EXPORT_SYMBOL(drm_fasync); | |||
324 | int drm_release(struct inode *inode, struct file *filp) | 321 | int drm_release(struct inode *inode, struct file *filp) |
325 | { | 322 | { |
326 | struct drm_file *file_priv = filp->private_data; | 323 | struct drm_file *file_priv = filp->private_data; |
327 | struct drm_device *dev = file_priv->head->dev; | 324 | struct drm_device *dev = file_priv->minor->dev; |
328 | int retcode = 0; | 325 | int retcode = 0; |
329 | unsigned long irqflags; | 326 | unsigned long irqflags; |
330 | 327 | ||
@@ -341,7 +338,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
341 | 338 | ||
342 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", | 339 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", |
343 | task_pid_nr(current), | 340 | task_pid_nr(current), |
344 | (long)old_encode_dev(file_priv->head->device), | 341 | (long)old_encode_dev(file_priv->minor->device), |
345 | dev->open_count); | 342 | dev->open_count); |
346 | 343 | ||
347 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { | 344 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { |
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index d9b560fe9bbe..93b1e0475c93 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
@@ -87,34 +87,35 @@ static struct drm_proc_list { | |||
87 | * "/proc/dri/%minor%/", and each entry in proc_list as | 87 | * "/proc/dri/%minor%/", and each entry in proc_list as |
88 | * "/proc/dri/%minor%/%name%". | 88 | * "/proc/dri/%minor%/%name%". |
89 | */ | 89 | */ |
90 | int drm_proc_init(struct drm_device * dev, int minor, | 90 | int drm_proc_init(struct drm_minor *minor, int minor_id, |
91 | struct proc_dir_entry *root, struct proc_dir_entry **dev_root) | 91 | struct proc_dir_entry *root) |
92 | { | 92 | { |
93 | struct proc_dir_entry *ent; | 93 | struct proc_dir_entry *ent; |
94 | int i, j; | 94 | int i, j; |
95 | char name[64]; | 95 | char name[64]; |
96 | 96 | ||
97 | sprintf(name, "%d", minor); | 97 | sprintf(name, "%d", minor_id); |
98 | *dev_root = proc_mkdir(name, root); | 98 | minor->dev_root = proc_mkdir(name, root); |
99 | if (!*dev_root) { | 99 | if (!minor->dev_root) { |
100 | DRM_ERROR("Cannot create /proc/dri/%s\n", name); | 100 | DRM_ERROR("Cannot create /proc/dri/%s\n", name); |
101 | return -1; | 101 | return -1; |
102 | } | 102 | } |
103 | 103 | ||
104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { | 104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { |
105 | ent = create_proc_entry(drm_proc_list[i].name, | 105 | ent = create_proc_entry(drm_proc_list[i].name, |
106 | S_IFREG | S_IRUGO, *dev_root); | 106 | S_IFREG | S_IRUGO, minor->dev_root); |
107 | if (!ent) { | 107 | if (!ent) { |
108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", | 108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
109 | name, drm_proc_list[i].name); | 109 | name, drm_proc_list[i].name); |
110 | for (j = 0; j < i; j++) | 110 | for (j = 0; j < i; j++) |
111 | remove_proc_entry(drm_proc_list[i].name, | 111 | remove_proc_entry(drm_proc_list[i].name, |
112 | *dev_root); | 112 | minor->dev_root); |
113 | remove_proc_entry(name, root); | 113 | remove_proc_entry(name, root); |
114 | minor->dev_root = NULL; | ||
114 | return -1; | 115 | return -1; |
115 | } | 116 | } |
116 | ent->read_proc = drm_proc_list[i].f; | 117 | ent->read_proc = drm_proc_list[i].f; |
117 | ent->data = dev; | 118 | ent->data = minor; |
118 | } | 119 | } |
119 | 120 | ||
120 | return 0; | 121 | return 0; |
@@ -130,18 +131,17 @@ int drm_proc_init(struct drm_device * dev, int minor, | |||
130 | * | 131 | * |
131 | * Remove all proc entries created by proc_init(). | 132 | * Remove all proc entries created by proc_init(). |
132 | */ | 133 | */ |
133 | int drm_proc_cleanup(int minor, struct proc_dir_entry *root, | 134 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) |
134 | struct proc_dir_entry *dev_root) | ||
135 | { | 135 | { |
136 | int i; | 136 | int i; |
137 | char name[64]; | 137 | char name[64]; |
138 | 138 | ||
139 | if (!root || !dev_root) | 139 | if (!root || !minor->dev_root) |
140 | return 0; | 140 | return 0; |
141 | 141 | ||
142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) | 142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) |
143 | remove_proc_entry(drm_proc_list[i].name, dev_root); | 143 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); |
144 | sprintf(name, "%d", minor); | 144 | sprintf(name, "%d", minor->index); |
145 | remove_proc_entry(name, root); | 145 | remove_proc_entry(name, root); |
146 | 146 | ||
147 | return 0; | 147 | return 0; |
@@ -163,7 +163,8 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, | |||
163 | static int drm_name_info(char *buf, char **start, off_t offset, int request, | 163 | static int drm_name_info(char *buf, char **start, off_t offset, int request, |
164 | int *eof, void *data) | 164 | int *eof, void *data) |
165 | { | 165 | { |
166 | struct drm_device *dev = (struct drm_device *) data; | 166 | struct drm_minor *minor = (struct drm_minor *) data; |
167 | struct drm_device *dev = minor->dev; | ||
167 | int len = 0; | 168 | int len = 0; |
168 | 169 | ||
169 | if (offset > DRM_PROC_LIMIT) { | 170 | if (offset > DRM_PROC_LIMIT) { |
@@ -205,7 +206,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, | |||
205 | static int drm__vm_info(char *buf, char **start, off_t offset, int request, | 206 | static int drm__vm_info(char *buf, char **start, off_t offset, int request, |
206 | int *eof, void *data) | 207 | int *eof, void *data) |
207 | { | 208 | { |
208 | struct drm_device *dev = (struct drm_device *) data; | 209 | struct drm_minor *minor = (struct drm_minor *) data; |
210 | struct drm_device *dev = minor->dev; | ||
209 | int len = 0; | 211 | int len = 0; |
210 | struct drm_map *map; | 212 | struct drm_map *map; |
211 | struct drm_map_list *r_list; | 213 | struct drm_map_list *r_list; |
@@ -261,7 +263,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, | |||
261 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, | 263 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, |
262 | int *eof, void *data) | 264 | int *eof, void *data) |
263 | { | 265 | { |
264 | struct drm_device *dev = (struct drm_device *) data; | 266 | struct drm_minor *minor = (struct drm_minor *) data; |
267 | struct drm_device *dev = minor->dev; | ||
265 | int ret; | 268 | int ret; |
266 | 269 | ||
267 | mutex_lock(&dev->struct_mutex); | 270 | mutex_lock(&dev->struct_mutex); |
@@ -284,7 +287,8 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, | |||
284 | static int drm__queues_info(char *buf, char **start, off_t offset, | 287 | static int drm__queues_info(char *buf, char **start, off_t offset, |
285 | int request, int *eof, void *data) | 288 | int request, int *eof, void *data) |
286 | { | 289 | { |
287 | struct drm_device *dev = (struct drm_device *) data; | 290 | struct drm_minor *minor = (struct drm_minor *) data; |
291 | struct drm_device *dev = minor->dev; | ||
288 | int len = 0; | 292 | int len = 0; |
289 | int i; | 293 | int i; |
290 | struct drm_queue *q; | 294 | struct drm_queue *q; |
@@ -334,7 +338,8 @@ static int drm__queues_info(char *buf, char **start, off_t offset, | |||
334 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, | 338 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, |
335 | int *eof, void *data) | 339 | int *eof, void *data) |
336 | { | 340 | { |
337 | struct drm_device *dev = (struct drm_device *) data; | 341 | struct drm_minor *minor = (struct drm_minor *) data; |
342 | struct drm_device *dev = minor->dev; | ||
338 | int ret; | 343 | int ret; |
339 | 344 | ||
340 | mutex_lock(&dev->struct_mutex); | 345 | mutex_lock(&dev->struct_mutex); |
@@ -357,7 +362,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, | |||
357 | static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | 362 | static int drm__bufs_info(char *buf, char **start, off_t offset, int request, |
358 | int *eof, void *data) | 363 | int *eof, void *data) |
359 | { | 364 | { |
360 | struct drm_device *dev = (struct drm_device *) data; | 365 | struct drm_minor *minor = (struct drm_minor *) data; |
366 | struct drm_device *dev = minor->dev; | ||
361 | int len = 0; | 367 | int len = 0; |
362 | struct drm_device_dma *dma = dev->dma; | 368 | struct drm_device_dma *dma = dev->dma; |
363 | int i; | 369 | int i; |
@@ -406,7 +412,8 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | |||
406 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | 412 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, |
407 | int *eof, void *data) | 413 | int *eof, void *data) |
408 | { | 414 | { |
409 | struct drm_device *dev = (struct drm_device *) data; | 415 | struct drm_minor *minor = (struct drm_minor *) data; |
416 | struct drm_device *dev = minor->dev; | ||
410 | int ret; | 417 | int ret; |
411 | 418 | ||
412 | mutex_lock(&dev->struct_mutex); | 419 | mutex_lock(&dev->struct_mutex); |
@@ -429,7 +436,8 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | |||
429 | static int drm__clients_info(char *buf, char **start, off_t offset, | 436 | static int drm__clients_info(char *buf, char **start, off_t offset, |
430 | int request, int *eof, void *data) | 437 | int request, int *eof, void *data) |
431 | { | 438 | { |
432 | struct drm_device *dev = (struct drm_device *) data; | 439 | struct drm_minor *minor = (struct drm_minor *) data; |
440 | struct drm_device *dev = minor->dev; | ||
433 | int len = 0; | 441 | int len = 0; |
434 | struct drm_file *priv; | 442 | struct drm_file *priv; |
435 | 443 | ||
@@ -445,7 +453,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, | |||
445 | list_for_each_entry(priv, &dev->filelist, lhead) { | 453 | list_for_each_entry(priv, &dev->filelist, lhead) { |
446 | DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", | 454 | DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", |
447 | priv->authenticated ? 'y' : 'n', | 455 | priv->authenticated ? 'y' : 'n', |
448 | priv->minor, | 456 | priv->minor->index, |
449 | priv->pid, | 457 | priv->pid, |
450 | priv->uid, priv->magic, priv->ioctl_count); | 458 | priv->uid, priv->magic, priv->ioctl_count); |
451 | } | 459 | } |
@@ -462,7 +470,8 @@ static int drm__clients_info(char *buf, char **start, off_t offset, | |||
462 | static int drm_clients_info(char *buf, char **start, off_t offset, | 470 | static int drm_clients_info(char *buf, char **start, off_t offset, |
463 | int request, int *eof, void *data) | 471 | int request, int *eof, void *data) |
464 | { | 472 | { |
465 | struct drm_device *dev = (struct drm_device *) data; | 473 | struct drm_minor *minor = (struct drm_minor *) data; |
474 | struct drm_device *dev = minor->dev; | ||
466 | int ret; | 475 | int ret; |
467 | 476 | ||
468 | mutex_lock(&dev->struct_mutex); | 477 | mutex_lock(&dev->struct_mutex); |
@@ -476,7 +485,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset, | |||
476 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, | 485 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, |
477 | int *eof, void *data) | 486 | int *eof, void *data) |
478 | { | 487 | { |
479 | struct drm_device *dev = (struct drm_device *) data; | 488 | struct drm_minor *minor = (struct drm_minor *) data; |
489 | struct drm_device *dev = minor->dev; | ||
480 | int len = 0; | 490 | int len = 0; |
481 | struct drm_vma_entry *pt; | 491 | struct drm_vma_entry *pt; |
482 | struct vm_area_struct *vma; | 492 | struct vm_area_struct *vma; |
@@ -535,7 +545,8 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, | |||
535 | static int drm_vma_info(char *buf, char **start, off_t offset, int request, | 545 | static int drm_vma_info(char *buf, char **start, off_t offset, int request, |
536 | int *eof, void *data) | 546 | int *eof, void *data) |
537 | { | 547 | { |
538 | struct drm_device *dev = (struct drm_device *) data; | 548 | struct drm_minor *minor = (struct drm_minor *) data; |
549 | struct drm_device *dev = minor->dev; | ||
539 | int ret; | 550 | int ret; |
540 | 551 | ||
541 | mutex_lock(&dev->struct_mutex); | 552 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index d93a217f856a..c2f584f3b46c 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -36,23 +36,49 @@ | |||
36 | #include "drmP.h" | 36 | #include "drmP.h" |
37 | #include "drm_core.h" | 37 | #include "drm_core.h" |
38 | 38 | ||
39 | unsigned int drm_cards_limit = 16; /* Enough for one machine */ | ||
40 | unsigned int drm_debug = 0; /* 1 to enable debug output */ | 39 | unsigned int drm_debug = 0; /* 1 to enable debug output */ |
41 | EXPORT_SYMBOL(drm_debug); | 40 | EXPORT_SYMBOL(drm_debug); |
42 | 41 | ||
43 | MODULE_AUTHOR(CORE_AUTHOR); | 42 | MODULE_AUTHOR(CORE_AUTHOR); |
44 | MODULE_DESCRIPTION(CORE_DESC); | 43 | MODULE_DESCRIPTION(CORE_DESC); |
45 | MODULE_LICENSE("GPL and additional rights"); | 44 | MODULE_LICENSE("GPL and additional rights"); |
46 | MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); | ||
47 | MODULE_PARM_DESC(debug, "Enable debug output"); | 45 | MODULE_PARM_DESC(debug, "Enable debug output"); |
48 | 46 | ||
49 | module_param_named(cards_limit, drm_cards_limit, int, 0444); | ||
50 | module_param_named(debug, drm_debug, int, 0600); | 47 | module_param_named(debug, drm_debug, int, 0600); |
51 | 48 | ||
52 | struct drm_head **drm_heads; | 49 | struct idr drm_minors_idr; |
50 | |||
53 | struct class *drm_class; | 51 | struct class *drm_class; |
54 | struct proc_dir_entry *drm_proc_root; | 52 | struct proc_dir_entry *drm_proc_root; |
55 | 53 | ||
54 | static int drm_minor_get_id(struct drm_device *dev, int type) | ||
55 | { | ||
56 | int new_id; | ||
57 | int ret; | ||
58 | int base = 0, limit = 63; | ||
59 | |||
60 | again: | ||
61 | if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { | ||
62 | DRM_ERROR("Out of memory expanding drawable idr\n"); | ||
63 | return -ENOMEM; | ||
64 | } | ||
65 | mutex_lock(&dev->struct_mutex); | ||
66 | ret = idr_get_new_above(&drm_minors_idr, NULL, | ||
67 | base, &new_id); | ||
68 | mutex_unlock(&dev->struct_mutex); | ||
69 | if (ret == -EAGAIN) { | ||
70 | goto again; | ||
71 | } else if (ret) { | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | if (new_id >= limit) { | ||
76 | idr_remove(&drm_minors_idr, new_id); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | return new_id; | ||
80 | } | ||
81 | |||
56 | static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | 82 | static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, |
57 | const struct pci_device_id *ent, | 83 | const struct pci_device_id *ent, |
58 | struct drm_driver *driver) | 84 | struct drm_driver *driver) |
@@ -145,48 +171,60 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
145 | * create the proc init entry via proc_init(). This routines assigns | 171 | * create the proc init entry via proc_init(). This routines assigns |
146 | * minor numbers to secondary heads of multi-headed cards | 172 | * minor numbers to secondary heads of multi-headed cards |
147 | */ | 173 | */ |
148 | static int drm_get_head(struct drm_device * dev, struct drm_head * head) | 174 | static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) |
149 | { | 175 | { |
150 | struct drm_head **heads = drm_heads; | 176 | struct drm_minor *new_minor; |
151 | int ret; | 177 | int ret; |
152 | int minor; | 178 | int minor_id; |
153 | 179 | ||
154 | DRM_DEBUG("\n"); | 180 | DRM_DEBUG("\n"); |
155 | 181 | ||
156 | for (minor = 0; minor < drm_cards_limit; minor++, heads++) { | 182 | minor_id = drm_minor_get_id(dev, type); |
157 | if (!*heads) { | 183 | if (minor_id < 0) |
158 | 184 | return minor_id; | |
159 | *head = (struct drm_head) { | 185 | |
160 | .dev = dev,.device = | 186 | new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); |
161 | MKDEV(DRM_MAJOR, minor),.minor = minor,}; | 187 | if (!new_minor) { |
162 | 188 | ret = -ENOMEM; | |
163 | if ((ret = | 189 | goto err_idr; |
164 | drm_proc_init(dev, minor, drm_proc_root, | 190 | } |
165 | &head->dev_root))) { | 191 | |
166 | printk(KERN_ERR | 192 | new_minor->type = type; |
167 | "DRM: Failed to initialize /proc/dri.\n"); | 193 | new_minor->device = MKDEV(DRM_MAJOR, minor_id); |
168 | goto err_g1; | 194 | new_minor->dev = dev; |
169 | } | 195 | new_minor->index = minor_id; |
170 | 196 | ||
171 | ret = drm_sysfs_device_add(dev, head); | 197 | idr_replace(&drm_minors_idr, new_minor, minor_id); |
172 | if (ret) { | 198 | |
173 | printk(KERN_ERR | 199 | if (type == DRM_MINOR_LEGACY) { |
174 | "DRM: Error sysfs_device_add.\n"); | 200 | ret = drm_proc_init(new_minor, minor_id, drm_proc_root); |
175 | goto err_g2; | 201 | if (ret) { |
176 | } | 202 | DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); |
177 | *heads = head; | 203 | goto err_mem; |
178 | |||
179 | DRM_DEBUG("new minor assigned %d\n", minor); | ||
180 | return 0; | ||
181 | } | 204 | } |
205 | } else | ||
206 | new_minor->dev_root = NULL; | ||
207 | |||
208 | ret = drm_sysfs_device_add(new_minor); | ||
209 | if (ret) { | ||
210 | printk(KERN_ERR | ||
211 | "DRM: Error sysfs_device_add.\n"); | ||
212 | goto err_g2; | ||
182 | } | 213 | } |
183 | DRM_ERROR("out of minors\n"); | 214 | *minor = new_minor; |
184 | return -ENOMEM; | 215 | |
185 | err_g2: | 216 | DRM_DEBUG("new minor assigned %d\n", minor_id); |
186 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); | 217 | return 0; |
187 | err_g1: | 218 | |
188 | *head = (struct drm_head) { | 219 | |
189 | .dev = NULL}; | 220 | err_g2: |
221 | if (new_minor->type == DRM_MINOR_LEGACY) | ||
222 | drm_proc_cleanup(new_minor, drm_proc_root); | ||
223 | err_mem: | ||
224 | kfree(new_minor); | ||
225 | err_idr: | ||
226 | idr_remove(&drm_minors_idr, minor_id); | ||
227 | *minor = NULL; | ||
190 | return ret; | 228 | return ret; |
191 | } | 229 | } |
192 | 230 | ||
@@ -222,12 +260,12 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
222 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | 260 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
223 | goto err_g2; | 261 | goto err_g2; |
224 | } | 262 | } |
225 | if ((ret = drm_get_head(dev, &dev->primary))) | 263 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) |
226 | goto err_g2; | 264 | goto err_g2; |
227 | 265 | ||
228 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 266 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
229 | driver->name, driver->major, driver->minor, driver->patchlevel, | 267 | driver->name, driver->major, driver->minor, driver->patchlevel, |
230 | driver->date, dev->primary.minor); | 268 | driver->date, dev->primary->index); |
231 | 269 | ||
232 | return 0; | 270 | return 0; |
233 | 271 | ||
@@ -276,18 +314,18 @@ int drm_put_dev(struct drm_device * dev) | |||
276 | * last minor released. | 314 | * last minor released. |
277 | * | 315 | * |
278 | */ | 316 | */ |
279 | int drm_put_head(struct drm_head * head) | 317 | int drm_put_minor(struct drm_minor **minor_p) |
280 | { | 318 | { |
281 | int minor = head->minor; | 319 | struct drm_minor *minor = *minor_p; |
282 | 320 | DRM_DEBUG("release secondary minor %d\n", minor->index); | |
283 | DRM_DEBUG("release secondary minor %d\n", minor); | ||
284 | |||
285 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); | ||
286 | drm_sysfs_device_remove(head->dev); | ||
287 | 321 | ||
288 | *head = (struct drm_head) {.dev = NULL}; | 322 | if (minor->type == DRM_MINOR_LEGACY) |
323 | drm_proc_cleanup(minor, drm_proc_root); | ||
324 | drm_sysfs_device_remove(minor); | ||
289 | 325 | ||
290 | drm_heads[minor] = NULL; | 326 | idr_remove(&drm_minors_idr, minor->index); |
291 | 327 | ||
328 | kfree(minor); | ||
329 | *minor_p = NULL; | ||
292 | return 0; | 330 | return 0; |
293 | } | 331 | } |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 05ed5043254f..7a1d9a782ddb 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "drm_core.h" | 19 | #include "drm_core.h" |
20 | #include "drmP.h" | 20 | #include "drmP.h" |
21 | 21 | ||
22 | #define to_drm_device(d) container_of(d, struct drm_device, dev) | 22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * drm_sysfs_suspend - DRM class suspend hook | 25 | * drm_sysfs_suspend - DRM class suspend hook |
@@ -31,7 +31,8 @@ | |||
31 | */ | 31 | */ |
32 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | 32 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) |
33 | { | 33 | { |
34 | struct drm_device *drm_dev = to_drm_device(dev); | 34 | struct drm_minor *drm_minor = to_drm_minor(dev); |
35 | struct drm_device *drm_dev = drm_minor->dev; | ||
35 | 36 | ||
36 | printk(KERN_ERR "%s\n", __FUNCTION__); | 37 | printk(KERN_ERR "%s\n", __FUNCTION__); |
37 | 38 | ||
@@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
50 | */ | 51 | */ |
51 | static int drm_sysfs_resume(struct device *dev) | 52 | static int drm_sysfs_resume(struct device *dev) |
52 | { | 53 | { |
53 | struct drm_device *drm_dev = to_drm_device(dev); | 54 | struct drm_minor *drm_minor = to_drm_minor(dev); |
55 | struct drm_device *drm_dev = drm_minor->dev; | ||
54 | 56 | ||
55 | if (drm_dev->driver->resume) | 57 | if (drm_dev->driver->resume) |
56 | return drm_dev->driver->resume(drm_dev); | 58 | return drm_dev->driver->resume(drm_dev); |
@@ -120,10 +122,11 @@ void drm_sysfs_destroy(void) | |||
120 | static ssize_t show_dri(struct device *device, struct device_attribute *attr, | 122 | static ssize_t show_dri(struct device *device, struct device_attribute *attr, |
121 | char *buf) | 123 | char *buf) |
122 | { | 124 | { |
123 | struct drm_device *dev = to_drm_device(device); | 125 | struct drm_minor *drm_minor = to_drm_minor(device); |
124 | if (dev->driver->dri_library_name) | 126 | struct drm_device *drm_dev = drm_minor->dev; |
125 | return dev->driver->dri_library_name(dev, buf); | 127 | if (drm_dev->driver->dri_library_name) |
126 | return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); | 128 | return drm_dev->driver->dri_library_name(drm_dev, buf); |
129 | return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); | ||
127 | } | 130 | } |
128 | 131 | ||
129 | static struct device_attribute device_attrs[] = { | 132 | static struct device_attribute device_attrs[] = { |
@@ -152,25 +155,28 @@ static void drm_sysfs_device_release(struct device *dev) | |||
152 | * as the parent for the Linux device, and make sure it has a file containing | 155 | * as the parent for the Linux device, and make sure it has a file containing |
153 | * the driver we're using (for userspace compatibility). | 156 | * the driver we're using (for userspace compatibility). |
154 | */ | 157 | */ |
155 | int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) | 158 | int drm_sysfs_device_add(struct drm_minor *minor) |
156 | { | 159 | { |
157 | int err; | 160 | int err; |
158 | int i, j; | 161 | int i, j; |
162 | char *minor_str; | ||
159 | 163 | ||
160 | dev->dev.parent = &dev->pdev->dev; | 164 | minor->kdev.parent = &minor->dev->pdev->dev; |
161 | dev->dev.class = drm_class; | 165 | minor->kdev.class = drm_class; |
162 | dev->dev.release = drm_sysfs_device_release; | 166 | minor->kdev.release = drm_sysfs_device_release; |
163 | dev->dev.devt = head->device; | 167 | minor->kdev.devt = minor->device; |
164 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); | 168 | minor_str = "card%d"; |
165 | 169 | ||
166 | err = device_register(&dev->dev); | 170 | snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index); |
171 | |||
172 | err = device_register(&minor->kdev); | ||
167 | if (err) { | 173 | if (err) { |
168 | DRM_ERROR("device add failed: %d\n", err); | 174 | DRM_ERROR("device add failed: %d\n", err); |
169 | goto err_out; | 175 | goto err_out; |
170 | } | 176 | } |
171 | 177 | ||
172 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { | 178 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { |
173 | err = device_create_file(&dev->dev, &device_attrs[i]); | 179 | err = device_create_file(&minor->kdev, &device_attrs[i]); |
174 | if (err) | 180 | if (err) |
175 | goto err_out_files; | 181 | goto err_out_files; |
176 | } | 182 | } |
@@ -180,8 +186,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) | |||
180 | err_out_files: | 186 | err_out_files: |
181 | if (i > 0) | 187 | if (i > 0) |
182 | for (j = 0; j < i; j++) | 188 | for (j = 0; j < i; j++) |
183 | device_remove_file(&dev->dev, &device_attrs[i]); | 189 | device_remove_file(&minor->kdev, &device_attrs[i]); |
184 | device_unregister(&dev->dev); | 190 | device_unregister(&minor->kdev); |
185 | err_out: | 191 | err_out: |
186 | 192 | ||
187 | return err; | 193 | return err; |
@@ -194,11 +200,11 @@ err_out: | |||
194 | * This call unregisters and cleans up a class device that was created with a | 200 | * This call unregisters and cleans up a class device that was created with a |
195 | * call to drm_sysfs_device_add() | 201 | * call to drm_sysfs_device_add() |
196 | */ | 202 | */ |
197 | void drm_sysfs_device_remove(struct drm_device *dev) | 203 | void drm_sysfs_device_remove(struct drm_minor *minor) |
198 | { | 204 | { |
199 | int i; | 205 | int i; |
200 | 206 | ||
201 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) | 207 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) |
202 | device_remove_file(&dev->dev, &device_attrs[i]); | 208 | device_remove_file(&minor->kdev, &device_attrs[i]); |
203 | device_unregister(&dev->dev); | 209 | device_unregister(&minor->kdev); |
204 | } | 210 | } |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index b20c1e950d3e..c234c6f24a8d 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -90,7 +90,7 @@ static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
90 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 90 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
91 | { | 91 | { |
92 | struct drm_file *priv = vma->vm_file->private_data; | 92 | struct drm_file *priv = vma->vm_file->private_data; |
93 | struct drm_device *dev = priv->head->dev; | 93 | struct drm_device *dev = priv->minor->dev; |
94 | struct drm_map *map = NULL; | 94 | struct drm_map *map = NULL; |
95 | struct drm_map_list *r_list; | 95 | struct drm_map_list *r_list; |
96 | struct drm_hash_item *hash; | 96 | struct drm_hash_item *hash; |
@@ -207,7 +207,7 @@ static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
207 | static void drm_vm_shm_close(struct vm_area_struct *vma) | 207 | static void drm_vm_shm_close(struct vm_area_struct *vma) |
208 | { | 208 | { |
209 | struct drm_file *priv = vma->vm_file->private_data; | 209 | struct drm_file *priv = vma->vm_file->private_data; |
210 | struct drm_device *dev = priv->head->dev; | 210 | struct drm_device *dev = priv->minor->dev; |
211 | struct drm_vma_entry *pt, *temp; | 211 | struct drm_vma_entry *pt, *temp; |
212 | struct drm_map *map; | 212 | struct drm_map *map; |
213 | struct drm_map_list *r_list; | 213 | struct drm_map_list *r_list; |
@@ -286,7 +286,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
286 | static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 286 | static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
287 | { | 287 | { |
288 | struct drm_file *priv = vma->vm_file->private_data; | 288 | struct drm_file *priv = vma->vm_file->private_data; |
289 | struct drm_device *dev = priv->head->dev; | 289 | struct drm_device *dev = priv->minor->dev; |
290 | struct drm_device_dma *dma = dev->dma; | 290 | struct drm_device_dma *dma = dev->dma; |
291 | unsigned long offset; | 291 | unsigned long offset; |
292 | unsigned long page_nr; | 292 | unsigned long page_nr; |
@@ -321,7 +321,7 @@ static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
321 | { | 321 | { |
322 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; | 322 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; |
323 | struct drm_file *priv = vma->vm_file->private_data; | 323 | struct drm_file *priv = vma->vm_file->private_data; |
324 | struct drm_device *dev = priv->head->dev; | 324 | struct drm_device *dev = priv->minor->dev; |
325 | struct drm_sg_mem *entry = dev->sg; | 325 | struct drm_sg_mem *entry = dev->sg; |
326 | unsigned long offset; | 326 | unsigned long offset; |
327 | unsigned long map_offset; | 327 | unsigned long map_offset; |
@@ -402,7 +402,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { | |||
402 | static void drm_vm_open_locked(struct vm_area_struct *vma) | 402 | static void drm_vm_open_locked(struct vm_area_struct *vma) |
403 | { | 403 | { |
404 | struct drm_file *priv = vma->vm_file->private_data; | 404 | struct drm_file *priv = vma->vm_file->private_data; |
405 | struct drm_device *dev = priv->head->dev; | 405 | struct drm_device *dev = priv->minor->dev; |
406 | struct drm_vma_entry *vma_entry; | 406 | struct drm_vma_entry *vma_entry; |
407 | 407 | ||
408 | DRM_DEBUG("0x%08lx,0x%08lx\n", | 408 | DRM_DEBUG("0x%08lx,0x%08lx\n", |
@@ -420,7 +420,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma) | |||
420 | static void drm_vm_open(struct vm_area_struct *vma) | 420 | static void drm_vm_open(struct vm_area_struct *vma) |
421 | { | 421 | { |
422 | struct drm_file *priv = vma->vm_file->private_data; | 422 | struct drm_file *priv = vma->vm_file->private_data; |
423 | struct drm_device *dev = priv->head->dev; | 423 | struct drm_device *dev = priv->minor->dev; |
424 | 424 | ||
425 | mutex_lock(&dev->struct_mutex); | 425 | mutex_lock(&dev->struct_mutex); |
426 | drm_vm_open_locked(vma); | 426 | drm_vm_open_locked(vma); |
@@ -438,7 +438,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
438 | static void drm_vm_close(struct vm_area_struct *vma) | 438 | static void drm_vm_close(struct vm_area_struct *vma) |
439 | { | 439 | { |
440 | struct drm_file *priv = vma->vm_file->private_data; | 440 | struct drm_file *priv = vma->vm_file->private_data; |
441 | struct drm_device *dev = priv->head->dev; | 441 | struct drm_device *dev = priv->minor->dev; |
442 | struct drm_vma_entry *pt, *temp; | 442 | struct drm_vma_entry *pt, *temp; |
443 | 443 | ||
444 | DRM_DEBUG("0x%08lx,0x%08lx\n", | 444 | DRM_DEBUG("0x%08lx,0x%08lx\n", |
@@ -473,7 +473,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
473 | struct drm_device_dma *dma; | 473 | struct drm_device_dma *dma; |
474 | unsigned long length = vma->vm_end - vma->vm_start; | 474 | unsigned long length = vma->vm_end - vma->vm_start; |
475 | 475 | ||
476 | dev = priv->head->dev; | 476 | dev = priv->minor->dev; |
477 | dma = dev->dma; | 477 | dma = dev->dma; |
478 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", | 478 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", |
479 | vma->vm_start, vma->vm_end, vma->vm_pgoff); | 479 | vma->vm_start, vma->vm_end, vma->vm_pgoff); |
@@ -543,7 +543,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); | |||
543 | static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | 543 | static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) |
544 | { | 544 | { |
545 | struct drm_file *priv = filp->private_data; | 545 | struct drm_file *priv = filp->private_data; |
546 | struct drm_device *dev = priv->head->dev; | 546 | struct drm_device *dev = priv->minor->dev; |
547 | struct drm_map *map = NULL; | 547 | struct drm_map *map = NULL; |
548 | unsigned long offset = 0; | 548 | unsigned long offset = 0; |
549 | struct drm_hash_item *hash; | 549 | struct drm_hash_item *hash; |
@@ -661,7 +661,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
661 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) | 661 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) |
662 | { | 662 | { |
663 | struct drm_file *priv = filp->private_data; | 663 | struct drm_file *priv = filp->private_data; |
664 | struct drm_device *dev = priv->head->dev; | 664 | struct drm_device *dev = priv->minor->dev; |
665 | int ret; | 665 | int ret; |
666 | 666 | ||
667 | mutex_lock(&dev->struct_mutex); | 667 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index 8d7ea81c4b66..e5de8ea41544 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c | |||
@@ -94,7 +94,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
94 | drm_i810_buf_priv_t *buf_priv; | 94 | drm_i810_buf_priv_t *buf_priv; |
95 | 95 | ||
96 | lock_kernel(); | 96 | lock_kernel(); |
97 | dev = priv->head->dev; | 97 | dev = priv->minor->dev; |
98 | dev_priv = dev->dev_private; | 98 | dev_priv = dev->dev_private; |
99 | buf = dev_priv->mmap_buffer; | 99 | buf = dev_priv->mmap_buffer; |
100 | buf_priv = buf->dev_private; | 100 | buf_priv = buf->dev_private; |
@@ -122,7 +122,7 @@ static const struct file_operations i810_buffer_fops = { | |||
122 | 122 | ||
123 | static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 123 | static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) |
124 | { | 124 | { |
125 | struct drm_device *dev = file_priv->head->dev; | 125 | struct drm_device *dev = file_priv->minor->dev; |
126 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 126 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
127 | drm_i810_private_t *dev_priv = dev->dev_private; | 127 | drm_i810_private_t *dev_priv = dev->dev_private; |
128 | const struct file_operations *old_fops; | 128 | const struct file_operations *old_fops; |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 9df08105f4f3..60c9376be486 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -96,7 +96,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
96 | drm_i830_buf_priv_t *buf_priv; | 96 | drm_i830_buf_priv_t *buf_priv; |
97 | 97 | ||
98 | lock_kernel(); | 98 | lock_kernel(); |
99 | dev = priv->head->dev; | 99 | dev = priv->minor->dev; |
100 | dev_priv = dev->dev_private; | 100 | dev_priv = dev->dev_private; |
101 | buf = dev_priv->mmap_buffer; | 101 | buf = dev_priv->mmap_buffer; |
102 | buf_priv = buf->dev_private; | 102 | buf_priv = buf->dev_private; |
@@ -124,7 +124,7 @@ static const struct file_operations i830_buffer_fops = { | |||
124 | 124 | ||
125 | static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 125 | static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) |
126 | { | 126 | { |
127 | struct drm_device *dev = file_priv->head->dev; | 127 | struct drm_device *dev = file_priv->minor->dev; |
128 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 128 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
129 | drm_i830_private_t *dev_priv = dev->dev_private; | 129 | drm_i830_private_t *dev_priv = dev->dev_private; |
130 | const struct file_operations *old_fops; | 130 | const struct file_operations *old_fops; |