diff options
author | Dave Airlie <airlied@redhat.com> | 2008-11-27 23:22:24 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-12-29 02:47:22 -0500 |
commit | 7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch) | |
tree | 1b5debcc86ff20bd5e11b42ea5c52da42214e376 /include | |
parent | e7f7ab45ebcb54fd5f814ea15ea079e079662f67 (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 'include')
-rw-r--r-- | include/drm/drm.h | 3 | ||||
-rw-r--r-- | include/drm/drmP.h | 64 | ||||
-rw-r--r-- | include/drm/drm_sarea.h | 6 |
3 files changed, 54 insertions, 19 deletions
diff --git a/include/drm/drm.h b/include/drm/drm.h index f46ba4b57da4..3fb173c5af3e 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h | |||
@@ -634,6 +634,9 @@ struct drm_gem_open { | |||
634 | #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) | 634 | #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) |
635 | #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) | 635 | #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) |
636 | 636 | ||
637 | #define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) | ||
638 | #define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) | ||
639 | |||
637 | #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) | 640 | #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) |
638 | #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) | 641 | #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) |
639 | #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) | 642 | #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 08b8539e7b3c..4c6e8298b424 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -238,11 +238,11 @@ struct drm_device; | |||
238 | */ | 238 | */ |
239 | #define LOCK_TEST_WITH_RETURN( dev, file_priv ) \ | 239 | #define LOCK_TEST_WITH_RETURN( dev, file_priv ) \ |
240 | do { \ | 240 | do { \ |
241 | if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ | 241 | if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock) || \ |
242 | dev->lock.file_priv != file_priv ) { \ | 242 | file_priv->master->lock.file_priv != file_priv) { \ |
243 | DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ | 243 | DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ |
244 | __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ | 244 | __func__, _DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock),\ |
245 | dev->lock.file_priv, file_priv ); \ | 245 | file_priv->master->lock.file_priv, file_priv); \ |
246 | return -EINVAL; \ | 246 | return -EINVAL; \ |
247 | } \ | 247 | } \ |
248 | } while (0) | 248 | } while (0) |
@@ -379,21 +379,25 @@ struct drm_buf_entry { | |||
379 | /** File private data */ | 379 | /** File private data */ |
380 | struct drm_file { | 380 | struct drm_file { |
381 | int authenticated; | 381 | int authenticated; |
382 | int master; | ||
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_minor *minor; | 387 | struct drm_minor *minor; |
389 | int remove_auth_on_close; | ||
390 | unsigned long lock_count; | 388 | unsigned long lock_count; |
389 | |||
391 | /** Mapping of mm object handles to object pointers. */ | 390 | /** Mapping of mm object handles to object pointers. */ |
392 | struct idr object_idr; | 391 | struct idr object_idr; |
393 | /** Lock for synchronization of access to object_idr. */ | 392 | /** Lock for synchronization of access to object_idr. */ |
394 | spinlock_t table_lock; | 393 | spinlock_t table_lock; |
394 | |||
395 | struct file *filp; | 395 | struct file *filp; |
396 | void *driver_priv; | 396 | void *driver_priv; |
397 | |||
398 | int is_master; /* this file private is a master for a minor */ | ||
399 | struct drm_master *master; /* master this node is currently associated with | ||
400 | N.B. not always minor->master */ | ||
397 | }; | 401 | }; |
398 | 402 | ||
399 | /** Wait queue */ | 403 | /** Wait queue */ |
@@ -523,6 +527,7 @@ struct drm_map_list { | |||
523 | struct drm_hash_item hash; | 527 | struct drm_hash_item hash; |
524 | struct drm_map *map; /**< mapping */ | 528 | struct drm_map *map; /**< mapping */ |
525 | uint64_t user_token; | 529 | uint64_t user_token; |
530 | struct drm_master *master; | ||
526 | }; | 531 | }; |
527 | 532 | ||
528 | typedef struct drm_map drm_local_map_t; | 533 | typedef struct drm_map drm_local_map_t; |
@@ -612,6 +617,30 @@ struct drm_gem_object { | |||
612 | void *driver_private; | 617 | void *driver_private; |
613 | }; | 618 | }; |
614 | 619 | ||
620 | /* per-master structure */ | ||
621 | struct drm_master { | ||
622 | |||
623 | struct kref refcount; /* refcount for this master */ | ||
624 | |||
625 | struct list_head head; /**< each minor contains a list of masters */ | ||
626 | struct drm_minor *minor; /**< link back to minor we are a master for */ | ||
627 | |||
628 | char *unique; /**< Unique identifier: e.g., busid */ | ||
629 | int unique_len; /**< Length of unique field */ | ||
630 | |||
631 | int blocked; /**< Blocked due to VC switch? */ | ||
632 | |||
633 | /** \name Authentication */ | ||
634 | /*@{ */ | ||
635 | struct drm_open_hash magiclist; | ||
636 | struct list_head magicfree; | ||
637 | /*@} */ | ||
638 | |||
639 | struct drm_lock_data lock; /**< Information on hardware lock */ | ||
640 | |||
641 | void *driver_priv; /**< Private structure for driver to use */ | ||
642 | }; | ||
643 | |||
615 | /** | 644 | /** |
616 | * DRM driver structure. This structure represent the common code for | 645 | * DRM driver structure. This structure represent the common code for |
617 | * a family of cards. There will one drm_device for each card present | 646 | * a family of cards. There will one drm_device for each card present |
@@ -712,6 +741,10 @@ struct drm_driver { | |||
712 | void (*set_version) (struct drm_device *dev, | 741 | void (*set_version) (struct drm_device *dev, |
713 | struct drm_set_version *sv); | 742 | struct drm_set_version *sv); |
714 | 743 | ||
744 | /* Master routines */ | ||
745 | int (*master_create)(struct drm_device *dev, struct drm_master *master); | ||
746 | void (*master_destroy)(struct drm_device *dev, struct drm_master *master); | ||
747 | |||
715 | int (*proc_init)(struct drm_minor *minor); | 748 | int (*proc_init)(struct drm_minor *minor); |
716 | void (*proc_cleanup)(struct drm_minor *minor); | 749 | void (*proc_cleanup)(struct drm_minor *minor); |
717 | 750 | ||
@@ -754,6 +787,8 @@ struct drm_minor { | |||
754 | struct device kdev; /**< Linux device */ | 787 | struct device kdev; /**< Linux device */ |
755 | struct drm_device *dev; | 788 | struct drm_device *dev; |
756 | struct proc_dir_entry *dev_root; /**< proc directory entry */ | 789 | struct proc_dir_entry *dev_root; /**< proc directory entry */ |
790 | struct drm_master *master; /* currently active master for this node */ | ||
791 | struct list_head master_list; | ||
757 | }; | 792 | }; |
758 | 793 | ||
759 | /** | 794 | /** |
@@ -762,13 +797,9 @@ struct drm_minor { | |||
762 | */ | 797 | */ |
763 | struct drm_device { | 798 | struct drm_device { |
764 | struct list_head driver_item; /**< list of devices per driver */ | 799 | struct list_head driver_item; /**< list of devices per driver */ |
765 | char *unique; /**< Unique identifier: e.g., busid */ | ||
766 | int unique_len; /**< Length of unique field */ | ||
767 | char *devname; /**< For /proc/interrupts */ | 800 | char *devname; /**< For /proc/interrupts */ |
768 | int if_version; /**< Highest interface version set */ | 801 | int if_version; /**< Highest interface version set */ |
769 | 802 | ||
770 | int blocked; /**< Blocked due to VC switch? */ | ||
771 | |||
772 | /** \name Locks */ | 803 | /** \name Locks */ |
773 | /*@{ */ | 804 | /*@{ */ |
774 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ | 805 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ |
@@ -791,12 +822,7 @@ struct drm_device { | |||
791 | atomic_t counts[15]; | 822 | atomic_t counts[15]; |
792 | /*@} */ | 823 | /*@} */ |
793 | 824 | ||
794 | /** \name Authentication */ | ||
795 | /*@{ */ | ||
796 | struct list_head filelist; | 825 | struct list_head filelist; |
797 | struct drm_open_hash magiclist; /**< magic hash table */ | ||
798 | struct list_head magicfree; | ||
799 | /*@} */ | ||
800 | 826 | ||
801 | /** \name Memory management */ | 827 | /** \name Memory management */ |
802 | /*@{ */ | 828 | /*@{ */ |
@@ -813,7 +839,6 @@ struct drm_device { | |||
813 | struct idr ctx_idr; | 839 | struct idr ctx_idr; |
814 | 840 | ||
815 | struct list_head vmalist; /**< List of vmas (for debugging) */ | 841 | struct list_head vmalist; /**< List of vmas (for debugging) */ |
816 | struct drm_lock_data lock; /**< Information on hardware lock */ | ||
817 | /*@} */ | 842 | /*@} */ |
818 | 843 | ||
819 | /** \name DMA queues (contexts) */ | 844 | /** \name DMA queues (contexts) */ |
@@ -1192,6 +1217,13 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); | |||
1192 | extern void drm_agp_chipset_flush(struct drm_device *dev); | 1217 | extern void drm_agp_chipset_flush(struct drm_device *dev); |
1193 | 1218 | ||
1194 | /* Stub support (drm_stub.h) */ | 1219 | /* Stub support (drm_stub.h) */ |
1220 | extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, | ||
1221 | struct drm_file *file_priv); | ||
1222 | extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | ||
1223 | struct drm_file *file_priv); | ||
1224 | struct drm_master *drm_master_create(struct drm_minor *minor); | ||
1225 | extern struct drm_master *drm_master_get(struct drm_master *master); | ||
1226 | extern void drm_master_put(struct drm_master **master); | ||
1195 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | 1227 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, |
1196 | struct drm_driver *driver); | 1228 | struct drm_driver *driver); |
1197 | extern int drm_put_dev(struct drm_device *dev); | 1229 | extern int drm_put_dev(struct drm_device *dev); |
diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h index 480037331e4e..ee5389d22c64 100644 --- a/include/drm/drm_sarea.h +++ b/include/drm/drm_sarea.h | |||
@@ -36,12 +36,12 @@ | |||
36 | 36 | ||
37 | /* SAREA area needs to be at least a page */ | 37 | /* SAREA area needs to be at least a page */ |
38 | #if defined(__alpha__) | 38 | #if defined(__alpha__) |
39 | #define SAREA_MAX 0x2000 | 39 | #define SAREA_MAX 0x2000U |
40 | #elif defined(__ia64__) | 40 | #elif defined(__ia64__) |
41 | #define SAREA_MAX 0x10000 /* 64kB */ | 41 | #define SAREA_MAX 0x10000U /* 64kB */ |
42 | #else | 42 | #else |
43 | /* Intel 830M driver needs at least 8k SAREA */ | 43 | /* Intel 830M driver needs at least 8k SAREA */ |
44 | #define SAREA_MAX 0x2000 | 44 | #define SAREA_MAX 0x2000U |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | /** Maximum number of drawables in the SAREA */ | 47 | /** Maximum number of drawables in the SAREA */ |