diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-12 16:53:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-12 16:53:40 -0500 |
commit | 37ef4399a6bb265d3035e6d6e45f7677b132a3ba (patch) | |
tree | 31adbac36ea310a44562a335f501d69d5ce2c78c /drivers | |
parent | bf785ee0aeea7a3e717cb1e11df4135b6cbde7da (diff) | |
parent | 9c7d462eda13ca211b7b4a62f191f4cfda135e2d (diff) |
Merge branch 'drm-forlinus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
Diffstat (limited to 'drivers')
73 files changed, 2794 insertions, 1812 deletions
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile index e41060c76226..9d180c42816c 100644 --- a/drivers/char/drm/Makefile +++ b/drivers/char/drm/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
4 | 4 | ||
5 | drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ | 5 | drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ |
6 | drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \ | 6 | drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ |
7 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ | 7 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ |
8 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ | 8 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ |
9 | drm_sysfs.o | 9 | drm_sysfs.o |
@@ -18,7 +18,7 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o | |||
18 | ffb-objs := ffb_drv.o ffb_context.o | 18 | ffb-objs := ffb_drv.o ffb_context.o |
19 | sis-objs := sis_drv.o sis_ds.o sis_mm.o | 19 | sis-objs := sis_drv.o sis_ds.o sis_mm.o |
20 | savage-objs := savage_drv.o savage_bci.o savage_state.o | 20 | savage-objs := savage_drv.o savage_bci.o savage_state.o |
21 | via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o | 21 | via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o |
22 | 22 | ||
23 | ifeq ($(CONFIG_COMPAT),y) | 23 | ifeq ($(CONFIG_COMPAT),y) |
24 | drm-objs += drm_ioc32.o | 24 | drm-objs += drm_ioc32.o |
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index efff0eec618c..5485382cadec 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -52,7 +52,7 @@ | |||
52 | # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ | 52 | # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ |
53 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ | 53 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ |
54 | 54 | ||
55 | static unsigned long drm_ati_alloc_pcigart_table(void) | 55 | static void *drm_ati_alloc_pcigart_table(void) |
56 | { | 56 | { |
57 | unsigned long address; | 57 | unsigned long address; |
58 | struct page *page; | 58 | struct page *page; |
@@ -72,27 +72,26 @@ static unsigned long drm_ati_alloc_pcigart_table(void) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); | 74 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); |
75 | return address; | 75 | return (void *)address; |
76 | } | 76 | } |
77 | 77 | ||
78 | static void drm_ati_free_pcigart_table(unsigned long address) | 78 | static void drm_ati_free_pcigart_table(void *address) |
79 | { | 79 | { |
80 | struct page *page; | 80 | struct page *page; |
81 | int i; | 81 | int i; |
82 | DRM_DEBUG("%s\n", __FUNCTION__); | 82 | DRM_DEBUG("%s\n", __FUNCTION__); |
83 | 83 | ||
84 | page = virt_to_page(address); | 84 | page = virt_to_page((unsigned long)address); |
85 | 85 | ||
86 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { | 86 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { |
87 | __put_page(page); | 87 | __put_page(page); |
88 | ClearPageReserved(page); | 88 | ClearPageReserved(page); |
89 | } | 89 | } |
90 | 90 | ||
91 | free_pages(address, ATI_PCIGART_TABLE_ORDER); | 91 | free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); |
92 | } | 92 | } |
93 | 93 | ||
94 | int drm_ati_pcigart_cleanup(drm_device_t * dev, | 94 | int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
95 | drm_ati_pcigart_info * gart_info) | ||
96 | { | 95 | { |
97 | drm_sg_mem_t *entry = dev->sg; | 96 | drm_sg_mem_t *entry = dev->sg; |
98 | unsigned long pages; | 97 | unsigned long pages; |
@@ -136,10 +135,10 @@ int drm_ati_pcigart_cleanup(drm_device_t * dev, | |||
136 | 135 | ||
137 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); | 136 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); |
138 | 137 | ||
139 | int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) | 138 | int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
140 | { | 139 | { |
141 | drm_sg_mem_t *entry = dev->sg; | 140 | drm_sg_mem_t *entry = dev->sg; |
142 | unsigned long address = 0; | 141 | void *address = NULL; |
143 | unsigned long pages; | 142 | unsigned long pages; |
144 | u32 *pci_gart, page_base, bus_address = 0; | 143 | u32 *pci_gart, page_base, bus_address = 0; |
145 | int i, j, ret = 0; | 144 | int i, j, ret = 0; |
@@ -163,7 +162,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) | |||
163 | goto done; | 162 | goto done; |
164 | } | 163 | } |
165 | 164 | ||
166 | bus_address = pci_map_single(dev->pdev, (void *)address, | 165 | bus_address = pci_map_single(dev->pdev, address, |
167 | ATI_PCIGART_TABLE_PAGES * | 166 | ATI_PCIGART_TABLE_PAGES * |
168 | PAGE_SIZE, PCI_DMA_TODEVICE); | 167 | PAGE_SIZE, PCI_DMA_TODEVICE); |
169 | if (bus_address == 0) { | 168 | if (bus_address == 0) { |
@@ -176,7 +175,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) | |||
176 | address = gart_info->addr; | 175 | address = gart_info->addr; |
177 | bus_address = gart_info->bus_addr; | 176 | bus_address = gart_info->bus_addr; |
178 | DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", | 177 | DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", |
179 | bus_address, address); | 178 | bus_address, (unsigned long)address); |
180 | } | 179 | } |
181 | 180 | ||
182 | pci_gart = (u32 *) address; | 181 | pci_gart = (u32 *) address; |
@@ -195,7 +194,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) | |||
195 | if (entry->busaddr[i] == 0) { | 194 | if (entry->busaddr[i] == 0) { |
196 | DRM_ERROR("unable to map PCIGART pages!\n"); | 195 | DRM_ERROR("unable to map PCIGART pages!\n"); |
197 | drm_ati_pcigart_cleanup(dev, gart_info); | 196 | drm_ati_pcigart_cleanup(dev, gart_info); |
198 | address = 0; | 197 | address = NULL; |
199 | bus_address = 0; | 198 | bus_address = 0; |
200 | goto done; | 199 | goto done; |
201 | } | 200 | } |
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 64d6237fdd0b..9da0ddb892b5 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
@@ -90,8 +90,8 @@ | |||
90 | #define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ | 90 | #define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ |
91 | #define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ | 91 | #define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ |
92 | 92 | ||
93 | #define _DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */ | 93 | #define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ |
94 | #define _DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */ | 94 | #define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ |
95 | #define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) | 95 | #define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) |
96 | #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) | 96 | #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) |
97 | #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) | 97 | #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 3dc3c9d79ae4..54b561e69486 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -144,20 +144,6 @@ | |||
144 | /** \name Backward compatibility section */ | 144 | /** \name Backward compatibility section */ |
145 | /*@{*/ | 145 | /*@{*/ |
146 | 146 | ||
147 | #ifndef MODULE_LICENSE | ||
148 | #define MODULE_LICENSE(x) | ||
149 | #endif | ||
150 | |||
151 | #ifndef preempt_disable | ||
152 | #define preempt_disable() | ||
153 | #define preempt_enable() | ||
154 | #endif | ||
155 | |||
156 | #ifndef pte_offset_map | ||
157 | #define pte_offset_map pte_offset | ||
158 | #define pte_unmap(pte) | ||
159 | #endif | ||
160 | |||
161 | #define DRM_RPR_ARG(vma) vma, | 147 | #define DRM_RPR_ARG(vma) vma, |
162 | 148 | ||
163 | #define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) | 149 | #define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) |
@@ -286,10 +272,13 @@ typedef int drm_ioctl_t(struct inode *inode, struct file *filp, | |||
286 | typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, | 272 | typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, |
287 | unsigned long arg); | 273 | unsigned long arg); |
288 | 274 | ||
275 | #define DRM_AUTH 0x1 | ||
276 | #define DRM_MASTER 0x2 | ||
277 | #define DRM_ROOT_ONLY 0x4 | ||
278 | |||
289 | typedef struct drm_ioctl_desc { | 279 | typedef struct drm_ioctl_desc { |
290 | drm_ioctl_t *func; | 280 | drm_ioctl_t *func; |
291 | int auth_needed; | 281 | int flags; |
292 | int root_only; | ||
293 | } drm_ioctl_desc_t; | 282 | } drm_ioctl_desc_t; |
294 | 283 | ||
295 | typedef struct drm_devstate { | 284 | typedef struct drm_devstate { |
@@ -384,6 +373,7 @@ typedef struct drm_buf_entry { | |||
384 | /** File private data */ | 373 | /** File private data */ |
385 | typedef struct drm_file { | 374 | typedef struct drm_file { |
386 | int authenticated; | 375 | int authenticated; |
376 | int master; | ||
387 | int minor; | 377 | int minor; |
388 | pid_t pid; | 378 | pid_t pid; |
389 | uid_t uid; | 379 | uid_t uid; |
@@ -532,8 +522,9 @@ typedef struct drm_vbl_sig { | |||
532 | typedef struct ati_pcigart_info { | 522 | typedef struct ati_pcigart_info { |
533 | int gart_table_location; | 523 | int gart_table_location; |
534 | int is_pcie; | 524 | int is_pcie; |
535 | unsigned long addr; | 525 | void *addr; |
536 | dma_addr_t bus_addr; | 526 | dma_addr_t bus_addr; |
527 | drm_local_map_t mapping; | ||
537 | } drm_ati_pcigart_info; | 528 | } drm_ati_pcigart_info; |
538 | 529 | ||
539 | /** | 530 | /** |
@@ -544,16 +535,14 @@ typedef struct ati_pcigart_info { | |||
544 | struct drm_device; | 535 | struct drm_device; |
545 | 536 | ||
546 | struct drm_driver { | 537 | struct drm_driver { |
547 | int (*preinit) (struct drm_device *, unsigned long flags); | 538 | int (*load) (struct drm_device *, unsigned long flags); |
548 | void (*prerelease) (struct drm_device *, struct file * filp); | 539 | int (*firstopen) (struct drm_device *); |
549 | void (*pretakedown) (struct drm_device *); | 540 | int (*open) (struct drm_device *, drm_file_t *); |
550 | int (*postcleanup) (struct drm_device *); | 541 | void (*preclose) (struct drm_device *, struct file * filp); |
551 | int (*presetup) (struct drm_device *); | 542 | void (*postclose) (struct drm_device *, drm_file_t *); |
552 | int (*postsetup) (struct drm_device *); | 543 | void (*lastclose) (struct drm_device *); |
544 | int (*unload) (struct drm_device *); | ||
553 | int (*dma_ioctl) (DRM_IOCTL_ARGS); | 545 | int (*dma_ioctl) (DRM_IOCTL_ARGS); |
554 | int (*open_helper) (struct drm_device *, drm_file_t *); | ||
555 | void (*free_filp_priv) (struct drm_device *, drm_file_t *); | ||
556 | void (*release) (struct drm_device *, struct file * filp); | ||
557 | void (*dma_ready) (struct drm_device *); | 546 | void (*dma_ready) (struct drm_device *); |
558 | int (*dma_quiescent) (struct drm_device *); | 547 | int (*dma_quiescent) (struct drm_device *); |
559 | int (*context_ctor) (struct drm_device * dev, int context); | 548 | int (*context_ctor) (struct drm_device * dev, int context); |
@@ -561,8 +550,9 @@ struct drm_driver { | |||
561 | int (*kernel_context_switch) (struct drm_device * dev, int old, | 550 | int (*kernel_context_switch) (struct drm_device * dev, int old, |
562 | int new); | 551 | int new); |
563 | void (*kernel_context_switch_unlock) (struct drm_device * dev, | 552 | void (*kernel_context_switch_unlock) (struct drm_device * dev, |
564 | drm_lock_t * lock); | 553 | drm_lock_t *lock); |
565 | int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); | 554 | int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); |
555 | int (*dri_library_name) (struct drm_device *dev, char *buf); | ||
566 | 556 | ||
567 | /** | 557 | /** |
568 | * Called by \c drm_device_is_agp. Typically used to determine if a | 558 | * Called by \c drm_device_is_agp. Typically used to determine if a |
@@ -579,16 +569,24 @@ struct drm_driver { | |||
579 | 569 | ||
580 | /* these have to be filled in */ | 570 | /* these have to be filled in */ |
581 | 571 | ||
582 | int (*postinit) (struct drm_device *, unsigned long flags); | 572 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
583 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); | ||
584 | void (*irq_preinstall) (struct drm_device * dev); | 573 | void (*irq_preinstall) (struct drm_device * dev); |
585 | void (*irq_postinstall) (struct drm_device * dev); | 574 | void (*irq_postinstall) (struct drm_device * dev); |
586 | void (*irq_uninstall) (struct drm_device * dev); | 575 | void (*irq_uninstall) (struct drm_device * dev); |
587 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); | 576 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); |
577 | void (*reclaim_buffers_locked) (struct drm_device *dev, | ||
578 | struct file *filp); | ||
588 | unsigned long (*get_map_ofs) (drm_map_t * map); | 579 | unsigned long (*get_map_ofs) (drm_map_t * map); |
589 | unsigned long (*get_reg_ofs) (struct drm_device * dev); | 580 | unsigned long (*get_reg_ofs) (struct drm_device * dev); |
590 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); | 581 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); |
591 | int (*version) (drm_version_t * version); | 582 | |
583 | int major; | ||
584 | int minor; | ||
585 | int patchlevel; | ||
586 | char *name; | ||
587 | char *desc; | ||
588 | char *date; | ||
589 | |||
592 | u32 driver_features; | 590 | u32 driver_features; |
593 | int dev_priv_size; | 591 | int dev_priv_size; |
594 | drm_ioctl_desc_t *ioctls; | 592 | drm_ioctl_desc_t *ioctls; |
@@ -752,19 +750,43 @@ static inline int drm_core_has_MTRR(struct drm_device *dev) | |||
752 | { | 750 | { |
753 | return drm_core_check_feature(dev, DRIVER_USE_MTRR); | 751 | return drm_core_check_feature(dev, DRIVER_USE_MTRR); |
754 | } | 752 | } |
753 | |||
754 | #define DRM_MTRR_WC MTRR_TYPE_WRCOMB | ||
755 | |||
756 | static inline int drm_mtrr_add(unsigned long offset, unsigned long size, | ||
757 | unsigned int flags) | ||
758 | { | ||
759 | return mtrr_add(offset, size, flags, 1); | ||
760 | } | ||
761 | |||
762 | static inline int drm_mtrr_del(int handle, unsigned long offset, | ||
763 | unsigned long size, unsigned int flags) | ||
764 | { | ||
765 | return mtrr_del(handle, offset, size); | ||
766 | } | ||
767 | |||
755 | #else | 768 | #else |
756 | #define drm_core_has_MTRR(dev) (0) | 769 | #define drm_core_has_MTRR(dev) (0) |
770 | |||
771 | #define DRM_MTRR_WC 0 | ||
772 | |||
773 | static inline int drm_mtrr_add(unsigned long offset, unsigned long size, | ||
774 | unsigned int flags) | ||
775 | { | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static inline int drm_mtrr_del(int handle, unsigned long offset, | ||
780 | unsigned long size, unsigned int flags) | ||
781 | { | ||
782 | return 0; | ||
783 | } | ||
757 | #endif | 784 | #endif |
758 | 785 | ||
759 | /******************************************************************/ | 786 | /******************************************************************/ |
760 | /** \name Internal function definitions */ | 787 | /** \name Internal function definitions */ |
761 | /*@{*/ | 788 | /*@{*/ |
762 | 789 | ||
763 | /* Misc. support (drm_init.h) */ | ||
764 | extern int drm_flags; | ||
765 | extern void drm_parse_options(char *s); | ||
766 | extern int drm_cpu_valid(void); | ||
767 | |||
768 | /* Driver support (drm_drv.h) */ | 790 | /* Driver support (drm_drv.h) */ |
769 | extern int drm_init(struct drm_driver *driver); | 791 | extern int drm_init(struct drm_driver *driver); |
770 | extern void drm_exit(struct drm_driver *driver); | 792 | extern void drm_exit(struct drm_driver *driver); |
@@ -772,12 +794,11 @@ extern int drm_ioctl(struct inode *inode, struct file *filp, | |||
772 | unsigned int cmd, unsigned long arg); | 794 | unsigned int cmd, unsigned long arg); |
773 | extern long drm_compat_ioctl(struct file *filp, | 795 | extern long drm_compat_ioctl(struct file *filp, |
774 | unsigned int cmd, unsigned long arg); | 796 | unsigned int cmd, unsigned long arg); |
775 | extern int drm_takedown(drm_device_t * dev); | 797 | extern int drm_lastclose(drm_device_t *dev); |
776 | 798 | ||
777 | /* Device support (drm_fops.h) */ | 799 | /* Device support (drm_fops.h) */ |
778 | extern int drm_open(struct inode *inode, struct file *filp); | 800 | extern int drm_open(struct inode *inode, struct file *filp); |
779 | extern int drm_stub_open(struct inode *inode, struct file *filp); | 801 | extern int drm_stub_open(struct inode *inode, struct file *filp); |
780 | extern int drm_flush(struct file *filp); | ||
781 | extern int drm_fasync(int fd, struct file *filp, int on); | 802 | extern int drm_fasync(int fd, struct file *filp, int on); |
782 | extern int drm_release(struct inode *inode, struct file *filp); | 803 | extern int drm_release(struct inode *inode, struct file *filp); |
783 | 804 | ||
@@ -819,6 +840,8 @@ extern int drm_getstats(struct inode *inode, struct file *filp, | |||
819 | unsigned int cmd, unsigned long arg); | 840 | unsigned int cmd, unsigned long arg); |
820 | extern int drm_setversion(struct inode *inode, struct file *filp, | 841 | extern int drm_setversion(struct inode *inode, struct file *filp, |
821 | unsigned int cmd, unsigned long arg); | 842 | unsigned int cmd, unsigned long arg); |
843 | extern int drm_noop(struct inode *inode, struct file *filp, | ||
844 | unsigned int cmd, unsigned long arg); | ||
822 | 845 | ||
823 | /* Context IOCTL support (drm_context.h) */ | 846 | /* Context IOCTL support (drm_context.h) */ |
824 | extern int drm_resctx(struct inode *inode, struct file *filp, | 847 | extern int drm_resctx(struct inode *inode, struct file *filp, |
@@ -857,10 +880,6 @@ extern int drm_getmagic(struct inode *inode, struct file *filp, | |||
857 | extern int drm_authmagic(struct inode *inode, struct file *filp, | 880 | extern int drm_authmagic(struct inode *inode, struct file *filp, |
858 | unsigned int cmd, unsigned long arg); | 881 | unsigned int cmd, unsigned long arg); |
859 | 882 | ||
860 | /* Placeholder for ioctls past */ | ||
861 | extern int drm_noop(struct inode *inode, struct file *filp, | ||
862 | unsigned int cmd, unsigned long arg); | ||
863 | |||
864 | /* Locking IOCTL support (drm_lock.h) */ | 883 | /* Locking IOCTL support (drm_lock.h) */ |
865 | extern int drm_lock(struct inode *inode, struct file *filp, | 884 | extern int drm_lock(struct inode *inode, struct file *filp, |
866 | unsigned int cmd, unsigned long arg); | 885 | unsigned int cmd, unsigned long arg); |
@@ -873,6 +892,7 @@ extern int drm_lock_free(drm_device_t * dev, | |||
873 | /* Buffer management support (drm_bufs.h) */ | 892 | /* Buffer management support (drm_bufs.h) */ |
874 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); | 893 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); |
875 | extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); | 894 | extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); |
895 | extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request); | ||
876 | extern int drm_addmap(drm_device_t * dev, unsigned int offset, | 896 | extern int drm_addmap(drm_device_t * dev, unsigned int offset, |
877 | unsigned int size, drm_map_type_t type, | 897 | unsigned int size, drm_map_type_t type, |
878 | drm_map_flags_t flags, drm_local_map_t ** map_ptr); | 898 | drm_map_flags_t flags, drm_local_map_t ** map_ptr); |
@@ -908,8 +928,8 @@ extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp); | |||
908 | /* IRQ support (drm_irq.h) */ | 928 | /* IRQ support (drm_irq.h) */ |
909 | extern int drm_control(struct inode *inode, struct file *filp, | 929 | extern int drm_control(struct inode *inode, struct file *filp, |
910 | unsigned int cmd, unsigned long arg); | 930 | unsigned int cmd, unsigned long arg); |
911 | extern int drm_irq_uninstall(drm_device_t * dev); | ||
912 | extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); | 931 | extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); |
932 | extern int drm_irq_uninstall(drm_device_t * dev); | ||
913 | extern void drm_driver_irq_preinstall(drm_device_t * dev); | 933 | extern void drm_driver_irq_preinstall(drm_device_t * dev); |
914 | extern void drm_driver_irq_postinstall(drm_device_t * dev); | 934 | extern void drm_driver_irq_postinstall(drm_device_t * dev); |
915 | extern void drm_driver_irq_uninstall(drm_device_t * dev); | 935 | extern void drm_driver_irq_uninstall(drm_device_t * dev); |
@@ -933,13 +953,17 @@ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, | |||
933 | extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); | 953 | extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); |
934 | extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, | 954 | extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, |
935 | unsigned int cmd, unsigned long arg); | 955 | unsigned int cmd, unsigned long arg); |
936 | extern int drm_agp_alloc(struct inode *inode, struct file *filp, | 956 | extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request); |
957 | extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, | ||
937 | unsigned int cmd, unsigned long arg); | 958 | unsigned int cmd, unsigned long arg); |
938 | extern int drm_agp_free(struct inode *inode, struct file *filp, | 959 | extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request); |
960 | extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp, | ||
939 | unsigned int cmd, unsigned long arg); | 961 | unsigned int cmd, unsigned long arg); |
940 | extern int drm_agp_unbind(struct inode *inode, struct file *filp, | 962 | extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request); |
963 | extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, | ||
941 | unsigned int cmd, unsigned long arg); | 964 | unsigned int cmd, unsigned long arg); |
942 | extern int drm_agp_bind(struct inode *inode, struct file *filp, | 965 | extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request); |
966 | extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, | ||
943 | unsigned int cmd, unsigned long arg); | 967 | unsigned int cmd, unsigned long arg); |
944 | extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, | 968 | extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, |
945 | size_t pages, u32 type); | 969 | size_t pages, u32 type); |
@@ -991,10 +1015,8 @@ extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, | |||
991 | char *name); | 1015 | char *name); |
992 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); | 1016 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); |
993 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | 1017 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, |
994 | dev_t dev, | 1018 | drm_head_t *head); |
995 | struct device *device, | 1019 | extern void drm_sysfs_device_remove(struct class_device *class_dev); |
996 | const char *fmt, ...); | ||
997 | extern void drm_sysfs_device_remove(dev_t dev); | ||
998 | 1020 | ||
999 | /* Inline replacements for DRM_IOREMAP macros */ | 1021 | /* Inline replacements for DRM_IOREMAP macros */ |
1000 | static __inline__ void drm_core_ioremap(struct drm_map *map, | 1022 | static __inline__ void drm_core_ioremap(struct drm_map *map, |
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 2b6453a9ffce..fabc930c67a2 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * \file drm_agpsupport.h | 2 | * \file drm_agpsupport.c |
3 | * DRM support for AGP/GART backend | 3 | * DRM support for AGP/GART backend |
4 | * | 4 | * |
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | 5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> |
@@ -91,7 +91,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp, | |||
91 | /** | 91 | /** |
92 | * Acquire the AGP device. | 92 | * Acquire the AGP device. |
93 | * | 93 | * |
94 | * \param dev DRM device that is to acquire AGP | 94 | * \param dev DRM device that is to acquire AGP. |
95 | * \return zero on success or a negative number on failure. | 95 | * \return zero on success or a negative number on failure. |
96 | * | 96 | * |
97 | * Verifies the AGP device hasn't been acquired before and calls | 97 | * Verifies the AGP device hasn't been acquired before and calls |
@@ -134,7 +134,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, | |||
134 | /** | 134 | /** |
135 | * Release the AGP device. | 135 | * Release the AGP device. |
136 | * | 136 | * |
137 | * \param dev DRM device that is to release AGP | 137 | * \param dev DRM device that is to release AGP. |
138 | * \return zero on success or a negative number on failure. | 138 | * \return zero on success or a negative number on failure. |
139 | * | 139 | * |
140 | * Verifies the AGP device has been acquired and calls \c agp_backend_release. | 140 | * Verifies the AGP device has been acquired and calls \c agp_backend_release. |
@@ -147,7 +147,6 @@ int drm_agp_release(drm_device_t * dev) | |||
147 | dev->agp->acquired = 0; | 147 | dev->agp->acquired = 0; |
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | |||
151 | EXPORT_SYMBOL(drm_agp_release); | 150 | EXPORT_SYMBOL(drm_agp_release); |
152 | 151 | ||
153 | int drm_agp_release_ioctl(struct inode *inode, struct file *filp, | 152 | int drm_agp_release_ioctl(struct inode *inode, struct file *filp, |
@@ -208,30 +207,22 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, | |||
208 | * Verifies the AGP device is present and has been acquired, allocates the | 207 | * Verifies the AGP device is present and has been acquired, allocates the |
209 | * memory via alloc_agp() and creates a drm_agp_mem entry for it. | 208 | * memory via alloc_agp() and creates a drm_agp_mem entry for it. |
210 | */ | 209 | */ |
211 | int drm_agp_alloc(struct inode *inode, struct file *filp, | 210 | int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) |
212 | unsigned int cmd, unsigned long arg) | ||
213 | { | 211 | { |
214 | drm_file_t *priv = filp->private_data; | ||
215 | drm_device_t *dev = priv->head->dev; | ||
216 | drm_agp_buffer_t request; | ||
217 | drm_agp_mem_t *entry; | 212 | drm_agp_mem_t *entry; |
218 | DRM_AGP_MEM *memory; | 213 | DRM_AGP_MEM *memory; |
219 | unsigned long pages; | 214 | unsigned long pages; |
220 | u32 type; | 215 | u32 type; |
221 | drm_agp_buffer_t __user *argp = (void __user *)arg; | ||
222 | 216 | ||
223 | if (!dev->agp || !dev->agp->acquired) | 217 | if (!dev->agp || !dev->agp->acquired) |
224 | return -EINVAL; | 218 | return -EINVAL; |
225 | if (copy_from_user(&request, argp, sizeof(request))) | ||
226 | return -EFAULT; | ||
227 | if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) | 219 | if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) |
228 | return -ENOMEM; | 220 | return -ENOMEM; |
229 | 221 | ||
230 | memset(entry, 0, sizeof(*entry)); | 222 | memset(entry, 0, sizeof(*entry)); |
231 | 223 | ||
232 | pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; | 224 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
233 | type = (u32) request.type; | 225 | type = (u32) request->type; |
234 | |||
235 | if (!(memory = drm_alloc_agp(dev, pages, type))) { | 226 | if (!(memory = drm_alloc_agp(dev, pages, type))) { |
236 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 227 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
237 | return -ENOMEM; | 228 | return -ENOMEM; |
@@ -247,16 +238,39 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, | |||
247 | dev->agp->memory->prev = entry; | 238 | dev->agp->memory->prev = entry; |
248 | dev->agp->memory = entry; | 239 | dev->agp->memory = entry; |
249 | 240 | ||
250 | request.handle = entry->handle; | 241 | request->handle = entry->handle; |
251 | request.physical = memory->physical; | 242 | request->physical = memory->physical; |
243 | |||
244 | return 0; | ||
245 | } | ||
246 | EXPORT_SYMBOL(drm_agp_alloc); | ||
247 | |||
248 | int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, | ||
249 | unsigned int cmd, unsigned long arg) | ||
250 | { | ||
251 | drm_file_t *priv = filp->private_data; | ||
252 | drm_device_t *dev = priv->head->dev; | ||
253 | drm_agp_buffer_t request; | ||
254 | drm_agp_buffer_t __user *argp = (void __user *)arg; | ||
255 | int err; | ||
256 | |||
257 | if (copy_from_user(&request, argp, sizeof(request))) | ||
258 | return -EFAULT; | ||
259 | |||
260 | err = drm_agp_alloc(dev, &request); | ||
261 | if (err) | ||
262 | return err; | ||
252 | 263 | ||
253 | if (copy_to_user(argp, &request, sizeof(request))) { | 264 | if (copy_to_user(argp, &request, sizeof(request))) { |
265 | drm_agp_mem_t *entry = dev->agp->memory; | ||
266 | |||
254 | dev->agp->memory = entry->next; | 267 | dev->agp->memory = entry->next; |
255 | dev->agp->memory->prev = NULL; | 268 | dev->agp->memory->prev = NULL; |
256 | drm_free_agp(memory, pages); | 269 | drm_free_agp(entry->memory, entry->pages); |
257 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 270 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
258 | return -EFAULT; | 271 | return -EFAULT; |
259 | } | 272 | } |
273 | |||
260 | return 0; | 274 | return 0; |
261 | } | 275 | } |
262 | 276 | ||
@@ -293,21 +307,14 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev, | |||
293 | * Verifies the AGP device is present and acquired, looks-up the AGP memory | 307 | * Verifies the AGP device is present and acquired, looks-up the AGP memory |
294 | * entry and passes it to the unbind_agp() function. | 308 | * entry and passes it to the unbind_agp() function. |
295 | */ | 309 | */ |
296 | int drm_agp_unbind(struct inode *inode, struct file *filp, | 310 | int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) |
297 | unsigned int cmd, unsigned long arg) | ||
298 | { | 311 | { |
299 | drm_file_t *priv = filp->private_data; | ||
300 | drm_device_t *dev = priv->head->dev; | ||
301 | drm_agp_binding_t request; | ||
302 | drm_agp_mem_t *entry; | 312 | drm_agp_mem_t *entry; |
303 | int ret; | 313 | int ret; |
304 | 314 | ||
305 | if (!dev->agp || !dev->agp->acquired) | 315 | if (!dev->agp || !dev->agp->acquired) |
306 | return -EINVAL; | 316 | return -EINVAL; |
307 | if (copy_from_user | 317 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
308 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
309 | return -EFAULT; | ||
310 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
311 | return -EINVAL; | 318 | return -EINVAL; |
312 | if (!entry->bound) | 319 | if (!entry->bound) |
313 | return -EINVAL; | 320 | return -EINVAL; |
@@ -316,6 +323,21 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, | |||
316 | entry->bound = 0; | 323 | entry->bound = 0; |
317 | return ret; | 324 | return ret; |
318 | } | 325 | } |
326 | EXPORT_SYMBOL(drm_agp_unbind); | ||
327 | |||
328 | int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, | ||
329 | unsigned int cmd, unsigned long arg) | ||
330 | { | ||
331 | drm_file_t *priv = filp->private_data; | ||
332 | drm_device_t *dev = priv->head->dev; | ||
333 | drm_agp_binding_t request; | ||
334 | |||
335 | if (copy_from_user | ||
336 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
337 | return -EFAULT; | ||
338 | |||
339 | return drm_agp_unbind(dev, &request); | ||
340 | } | ||
319 | 341 | ||
320 | /** | 342 | /** |
321 | * Bind AGP memory into the GATT (ioctl) | 343 | * Bind AGP memory into the GATT (ioctl) |
@@ -330,26 +352,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, | |||
330 | * is currently bound into the GATT. Looks-up the AGP memory entry and passes | 352 | * is currently bound into the GATT. Looks-up the AGP memory entry and passes |
331 | * it to bind_agp() function. | 353 | * it to bind_agp() function. |
332 | */ | 354 | */ |
333 | int drm_agp_bind(struct inode *inode, struct file *filp, | 355 | int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) |
334 | unsigned int cmd, unsigned long arg) | ||
335 | { | 356 | { |
336 | drm_file_t *priv = filp->private_data; | ||
337 | drm_device_t *dev = priv->head->dev; | ||
338 | drm_agp_binding_t request; | ||
339 | drm_agp_mem_t *entry; | 357 | drm_agp_mem_t *entry; |
340 | int retcode; | 358 | int retcode; |
341 | int page; | 359 | int page; |
342 | 360 | ||
343 | if (!dev->agp || !dev->agp->acquired) | 361 | if (!dev->agp || !dev->agp->acquired) |
344 | return -EINVAL; | 362 | return -EINVAL; |
345 | if (copy_from_user | 363 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
346 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
347 | return -EFAULT; | ||
348 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
349 | return -EINVAL; | 364 | return -EINVAL; |
350 | if (entry->bound) | 365 | if (entry->bound) |
351 | return -EINVAL; | 366 | return -EINVAL; |
352 | page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; | 367 | page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; |
353 | if ((retcode = drm_bind_agp(entry->memory, page))) | 368 | if ((retcode = drm_bind_agp(entry->memory, page))) |
354 | return retcode; | 369 | return retcode; |
355 | entry->bound = dev->agp->base + (page << PAGE_SHIFT); | 370 | entry->bound = dev->agp->base + (page << PAGE_SHIFT); |
@@ -357,6 +372,21 @@ int drm_agp_bind(struct inode *inode, struct file *filp, | |||
357 | dev->agp->base, entry->bound); | 372 | dev->agp->base, entry->bound); |
358 | return 0; | 373 | return 0; |
359 | } | 374 | } |
375 | EXPORT_SYMBOL(drm_agp_bind); | ||
376 | |||
377 | int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, | ||
378 | unsigned int cmd, unsigned long arg) | ||
379 | { | ||
380 | drm_file_t *priv = filp->private_data; | ||
381 | drm_device_t *dev = priv->head->dev; | ||
382 | drm_agp_binding_t request; | ||
383 | |||
384 | if (copy_from_user | ||
385 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
386 | return -EFAULT; | ||
387 | |||
388 | return drm_agp_bind(dev, &request); | ||
389 | } | ||
360 | 390 | ||
361 | /** | 391 | /** |
362 | * Free AGP memory (ioctl). | 392 | * Free AGP memory (ioctl). |
@@ -372,20 +402,13 @@ int drm_agp_bind(struct inode *inode, struct file *filp, | |||
372 | * unbind_agp(). Frees it via free_agp() as well as the entry itself | 402 | * unbind_agp(). Frees it via free_agp() as well as the entry itself |
373 | * and unlinks from the doubly linked list it's inserted in. | 403 | * and unlinks from the doubly linked list it's inserted in. |
374 | */ | 404 | */ |
375 | int drm_agp_free(struct inode *inode, struct file *filp, | 405 | int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) |
376 | unsigned int cmd, unsigned long arg) | ||
377 | { | 406 | { |
378 | drm_file_t *priv = filp->private_data; | ||
379 | drm_device_t *dev = priv->head->dev; | ||
380 | drm_agp_buffer_t request; | ||
381 | drm_agp_mem_t *entry; | 407 | drm_agp_mem_t *entry; |
382 | 408 | ||
383 | if (!dev->agp || !dev->agp->acquired) | 409 | if (!dev->agp || !dev->agp->acquired) |
384 | return -EINVAL; | 410 | return -EINVAL; |
385 | if (copy_from_user | 411 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
386 | (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) | ||
387 | return -EFAULT; | ||
388 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
389 | return -EINVAL; | 412 | return -EINVAL; |
390 | if (entry->bound) | 413 | if (entry->bound) |
391 | drm_unbind_agp(entry->memory); | 414 | drm_unbind_agp(entry->memory); |
@@ -402,12 +425,30 @@ int drm_agp_free(struct inode *inode, struct file *filp, | |||
402 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 425 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
403 | return 0; | 426 | return 0; |
404 | } | 427 | } |
428 | EXPORT_SYMBOL(drm_agp_free); | ||
429 | |||
430 | int drm_agp_free_ioctl(struct inode *inode, struct file *filp, | ||
431 | unsigned int cmd, unsigned long arg) | ||
432 | { | ||
433 | drm_file_t *priv = filp->private_data; | ||
434 | drm_device_t *dev = priv->head->dev; | ||
435 | drm_agp_buffer_t request; | ||
436 | |||
437 | if (copy_from_user | ||
438 | (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) | ||
439 | return -EFAULT; | ||
440 | |||
441 | return drm_agp_free(dev, &request); | ||
442 | } | ||
405 | 443 | ||
406 | /** | 444 | /** |
407 | * Initialize the AGP resources. | 445 | * Initialize the AGP resources. |
408 | * | 446 | * |
409 | * \return pointer to a drm_agp_head structure. | 447 | * \return pointer to a drm_agp_head structure. |
410 | * | 448 | * |
449 | * Gets the drm_agp_t structure which is made available by the agpgart module | ||
450 | * via the inter_module_* functions. Creates and initializes a drm_agp_head | ||
451 | * structure. | ||
411 | */ | 452 | */ |
412 | drm_agp_head_t *drm_agp_init(drm_device_t * dev) | 453 | drm_agp_head_t *drm_agp_init(drm_device_t * dev) |
413 | { | 454 | { |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 319bdea8de8a..1db12dcb6802 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -36,22 +36,21 @@ | |||
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include "drmP.h" | 37 | #include "drmP.h" |
38 | 38 | ||
39 | unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource) | 39 | unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) |
40 | { | 40 | { |
41 | return pci_resource_start(dev->pdev, resource); | 41 | return pci_resource_start(dev->pdev, resource); |
42 | } | 42 | } |
43 | |||
44 | EXPORT_SYMBOL(drm_get_resource_start); | 43 | EXPORT_SYMBOL(drm_get_resource_start); |
45 | 44 | ||
46 | unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource) | 45 | unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) |
47 | { | 46 | { |
48 | return pci_resource_len(dev->pdev, resource); | 47 | return pci_resource_len(dev->pdev, resource); |
49 | } | 48 | } |
50 | 49 | ||
51 | EXPORT_SYMBOL(drm_get_resource_len); | 50 | EXPORT_SYMBOL(drm_get_resource_len); |
52 | 51 | ||
53 | static drm_map_list_t *drm_find_matching_map(drm_device_t * dev, | 52 | static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, |
54 | drm_local_map_t * map) | 53 | drm_local_map_t *map) |
55 | { | 54 | { |
56 | struct list_head *list; | 55 | struct list_head *list; |
57 | 56 | ||
@@ -74,7 +73,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t * dev, | |||
74 | 73 | ||
75 | #ifdef _LP64 | 74 | #ifdef _LP64 |
76 | static __inline__ unsigned int HandleID(unsigned long lhandle, | 75 | static __inline__ unsigned int HandleID(unsigned long lhandle, |
77 | drm_device_t * dev) | 76 | drm_device_t *dev) |
78 | { | 77 | { |
79 | static unsigned int map32_handle = START_RANGE; | 78 | static unsigned int map32_handle = START_RANGE; |
80 | unsigned int hash; | 79 | unsigned int hash; |
@@ -155,7 +154,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
155 | case _DRM_REGISTERS: | 154 | case _DRM_REGISTERS: |
156 | case _DRM_FRAME_BUFFER: | 155 | case _DRM_FRAME_BUFFER: |
157 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) | 156 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) |
158 | if (map->offset + map->size < map->offset || | 157 | if (map->offset + (map->size-1) < map->offset || |
159 | map->offset < virt_to_phys(high_memory)) { | 158 | map->offset < virt_to_phys(high_memory)) { |
160 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 159 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
161 | return -EINVAL; | 160 | return -EINVAL; |
@@ -301,6 +300,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, | |||
301 | return -EFAULT; | 300 | return -EFAULT; |
302 | } | 301 | } |
303 | 302 | ||
303 | if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP)) | ||
304 | return -EPERM; | ||
305 | |||
304 | err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, | 306 | err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, |
305 | &maplist); | 307 | &maplist); |
306 | 308 | ||
@@ -332,7 +334,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, | |||
332 | * | 334 | * |
333 | * \sa drm_addmap | 335 | * \sa drm_addmap |
334 | */ | 336 | */ |
335 | int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map) | 337 | int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) |
336 | { | 338 | { |
337 | struct list_head *list; | 339 | struct list_head *list; |
338 | drm_map_list_t *r_list = NULL; | 340 | drm_map_list_t *r_list = NULL; |
@@ -384,10 +386,9 @@ int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map) | |||
384 | 386 | ||
385 | return 0; | 387 | return 0; |
386 | } | 388 | } |
387 | |||
388 | EXPORT_SYMBOL(drm_rmmap_locked); | 389 | EXPORT_SYMBOL(drm_rmmap_locked); |
389 | 390 | ||
390 | int drm_rmmap(drm_device_t * dev, drm_local_map_t * map) | 391 | int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) |
391 | { | 392 | { |
392 | int ret; | 393 | int ret; |
393 | 394 | ||
@@ -397,7 +398,6 @@ int drm_rmmap(drm_device_t * dev, drm_local_map_t * map) | |||
397 | 398 | ||
398 | return ret; | 399 | return ret; |
399 | } | 400 | } |
400 | |||
401 | EXPORT_SYMBOL(drm_rmmap); | 401 | EXPORT_SYMBOL(drm_rmmap); |
402 | 402 | ||
403 | /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on | 403 | /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on |
@@ -548,7 +548,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
548 | DRM_DEBUG("count: %d\n", count); | 548 | DRM_DEBUG("count: %d\n", count); |
549 | DRM_DEBUG("order: %d\n", order); | 549 | DRM_DEBUG("order: %d\n", order); |
550 | DRM_DEBUG("size: %d\n", size); | 550 | DRM_DEBUG("size: %d\n", size); |
551 | DRM_DEBUG("agp_offset: %lu\n", agp_offset); | 551 | DRM_DEBUG("agp_offset: %lx\n", agp_offset); |
552 | DRM_DEBUG("alignment: %d\n", alignment); | 552 | DRM_DEBUG("alignment: %d\n", alignment); |
553 | DRM_DEBUG("page_order: %d\n", page_order); | 553 | DRM_DEBUG("page_order: %d\n", page_order); |
554 | DRM_DEBUG("total: %d\n", total); | 554 | DRM_DEBUG("total: %d\n", total); |
@@ -649,6 +649,8 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
649 | } | 649 | } |
650 | 650 | ||
651 | dma->buf_count += entry->buf_count; | 651 | dma->buf_count += entry->buf_count; |
652 | dma->seg_count += entry->seg_count; | ||
653 | dma->page_count += byte_count >> PAGE_SHIFT; | ||
652 | dma->byte_count += byte_count; | 654 | dma->byte_count += byte_count; |
653 | 655 | ||
654 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 656 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
@@ -664,7 +666,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
664 | atomic_dec(&dev->buf_alloc); | 666 | atomic_dec(&dev->buf_alloc); |
665 | return 0; | 667 | return 0; |
666 | } | 668 | } |
667 | |||
668 | EXPORT_SYMBOL(drm_addbufs_agp); | 669 | EXPORT_SYMBOL(drm_addbufs_agp); |
669 | #endif /* __OS_HAS_AGP */ | 670 | #endif /* __OS_HAS_AGP */ |
670 | 671 | ||
@@ -689,9 +690,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
689 | 690 | ||
690 | if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) | 691 | if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) |
691 | return -EINVAL; | 692 | return -EINVAL; |
693 | |||
692 | if (!dma) | 694 | if (!dma) |
693 | return -EINVAL; | 695 | return -EINVAL; |
694 | 696 | ||
697 | if (!capable(CAP_SYS_ADMIN)) | ||
698 | return -EPERM; | ||
699 | |||
695 | count = request->count; | 700 | count = request->count; |
696 | order = drm_order(request->size); | 701 | order = drm_order(request->size); |
697 | size = 1 << order; | 702 | size = 1 << order; |
@@ -882,7 +887,6 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
882 | return 0; | 887 | return 0; |
883 | 888 | ||
884 | } | 889 | } |
885 | |||
886 | EXPORT_SYMBOL(drm_addbufs_pci); | 890 | EXPORT_SYMBOL(drm_addbufs_pci); |
887 | 891 | ||
888 | static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | 892 | static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) |
@@ -908,6 +912,9 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
908 | if (!dma) | 912 | if (!dma) |
909 | return -EINVAL; | 913 | return -EINVAL; |
910 | 914 | ||
915 | if (!capable(CAP_SYS_ADMIN)) | ||
916 | return -EPERM; | ||
917 | |||
911 | count = request->count; | 918 | count = request->count; |
912 | order = drm_order(request->size); | 919 | order = drm_order(request->size); |
913 | size = 1 << order; | 920 | size = 1 << order; |
@@ -1026,6 +1033,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
1026 | } | 1033 | } |
1027 | 1034 | ||
1028 | dma->buf_count += entry->buf_count; | 1035 | dma->buf_count += entry->buf_count; |
1036 | dma->seg_count += entry->seg_count; | ||
1037 | dma->page_count += byte_count >> PAGE_SHIFT; | ||
1029 | dma->byte_count += byte_count; | 1038 | dma->byte_count += byte_count; |
1030 | 1039 | ||
1031 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 1040 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
@@ -1042,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
1042 | return 0; | 1051 | return 0; |
1043 | } | 1052 | } |
1044 | 1053 | ||
1045 | static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | 1054 | int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) |
1046 | { | 1055 | { |
1047 | drm_device_dma_t *dma = dev->dma; | 1056 | drm_device_dma_t *dma = dev->dma; |
1048 | drm_buf_entry_t *entry; | 1057 | drm_buf_entry_t *entry; |
@@ -1065,6 +1074,9 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
1065 | if (!dma) | 1074 | if (!dma) |
1066 | return -EINVAL; | 1075 | return -EINVAL; |
1067 | 1076 | ||
1077 | if (!capable(CAP_SYS_ADMIN)) | ||
1078 | return -EPERM; | ||
1079 | |||
1068 | count = request->count; | 1080 | count = request->count; |
1069 | order = drm_order(request->size); | 1081 | order = drm_order(request->size); |
1070 | size = 1 << order; | 1082 | size = 1 << order; |
@@ -1181,6 +1193,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
1181 | } | 1193 | } |
1182 | 1194 | ||
1183 | dma->buf_count += entry->buf_count; | 1195 | dma->buf_count += entry->buf_count; |
1196 | dma->seg_count += entry->seg_count; | ||
1197 | dma->page_count += byte_count >> PAGE_SHIFT; | ||
1184 | dma->byte_count += byte_count; | 1198 | dma->byte_count += byte_count; |
1185 | 1199 | ||
1186 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 1200 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
@@ -1196,6 +1210,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
1196 | atomic_dec(&dev->buf_alloc); | 1210 | atomic_dec(&dev->buf_alloc); |
1197 | return 0; | 1211 | return 0; |
1198 | } | 1212 | } |
1213 | EXPORT_SYMBOL(drm_addbufs_fb); | ||
1214 | |||
1199 | 1215 | ||
1200 | /** | 1216 | /** |
1201 | * Add buffers for DMA transfers (ioctl). | 1217 | * Add buffers for DMA transfers (ioctl). |
@@ -1577,5 +1593,6 @@ int drm_order(unsigned long size) | |||
1577 | 1593 | ||
1578 | return order; | 1594 | return order; |
1579 | } | 1595 | } |
1580 | |||
1581 | EXPORT_SYMBOL(drm_order); | 1596 | EXPORT_SYMBOL(drm_order); |
1597 | |||
1598 | |||
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c index bd958d69a2ac..f84254526949 100644 --- a/drivers/char/drm/drm_context.c +++ b/drivers/char/drm/drm_context.c | |||
@@ -433,7 +433,7 @@ int drm_addctx(struct inode *inode, struct file *filp, | |||
433 | if (ctx.handle != DRM_KERNEL_CONTEXT) { | 433 | if (ctx.handle != DRM_KERNEL_CONTEXT) { |
434 | if (dev->driver->context_ctor) | 434 | if (dev->driver->context_ctor) |
435 | if (!dev->driver->context_ctor(dev, ctx.handle)) { | 435 | if (!dev->driver->context_ctor(dev, ctx.handle)) { |
436 | DRM_DEBUG( "Running out of ctxs or memory.\n"); | 436 | DRM_DEBUG("Running out of ctxs or memory.\n"); |
437 | return -ENOMEM; | 437 | return -ENOMEM; |
438 | } | 438 | } |
439 | } | 439 | } |
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h index cc97bb906dda..f4f9db6c7ed4 100644 --- a/drivers/char/drm/drm_core.h +++ b/drivers/char/drm/drm_core.h | |||
@@ -24,11 +24,11 @@ | |||
24 | 24 | ||
25 | #define CORE_NAME "drm" | 25 | #define CORE_NAME "drm" |
26 | #define CORE_DESC "DRM shared core routines" | 26 | #define CORE_DESC "DRM shared core routines" |
27 | #define CORE_DATE "20040925" | 27 | #define CORE_DATE "20051102" |
28 | 28 | ||
29 | #define DRM_IF_MAJOR 1 | 29 | #define DRM_IF_MAJOR 1 |
30 | #define DRM_IF_MINOR 2 | 30 | #define DRM_IF_MINOR 2 |
31 | 31 | ||
32 | #define CORE_MAJOR 1 | 32 | #define CORE_MAJOR 1 |
33 | #define CORE_MINOR 0 | 33 | #define CORE_MINOR 0 |
34 | #define CORE_PATCHLEVEL 0 | 34 | #define CORE_PATCHLEVEL 1 |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 4dff7554eb08..c4fa5a29582b 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -56,66 +56,66 @@ static int drm_version(struct inode *inode, struct file *filp, | |||
56 | 56 | ||
57 | /** Ioctl table */ | 57 | /** Ioctl table */ |
58 | static drm_ioctl_desc_t drm_ioctls[] = { | 58 | static drm_ioctl_desc_t drm_ioctls[] = { |
59 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0}, | 59 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0}, |
60 | [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0}, | 60 | [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0}, |
61 | [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0}, | 61 | [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0}, |
62 | [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1}, | 62 | [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY}, |
63 | [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0}, | 63 | [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0}, |
64 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0}, | 64 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0}, |
65 | [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0}, | 65 | [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0}, |
66 | [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1}, | 66 | [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY}, |
67 | 67 | [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
68 | [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1}, | 68 | [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
69 | [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1}, | 69 | [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
70 | [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1}, | 70 | [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
71 | [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1}, | 71 | |
72 | 72 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
73 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1}, | 73 | [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH}, |
74 | [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0}, | 74 | |
75 | 75 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
76 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1}, | 76 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, |
77 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0}, | 77 | |
78 | 78 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
79 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1}, | 79 | [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
80 | [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1}, | 80 | [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
81 | [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1}, | 81 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, |
82 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0}, | 82 | [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
83 | [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1}, | 83 | [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
84 | [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1}, | 84 | [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH}, |
85 | [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0}, | 85 | |
86 | 86 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
87 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1}, | 87 | [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
88 | [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1}, | 88 | |
89 | 89 | [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH}, | |
90 | [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0}, | 90 | [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH}, |
91 | [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0}, | 91 | |
92 | 92 | [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH}, | |
93 | [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0}, | 93 | |
94 | 94 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | |
95 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1}, | 95 | [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
96 | [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1}, | 96 | [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH}, |
97 | [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0}, | 97 | [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH}, |
98 | [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0}, | 98 | [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH}, |
99 | [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0}, | ||
100 | /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ | 99 | /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ |
100 | [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH}, | ||
101 | 101 | ||
102 | [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1}, | 102 | [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
103 | 103 | ||
104 | #if __OS_HAS_AGP | 104 | #if __OS_HAS_AGP |
105 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1}, | 105 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, | 106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, | 107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, | 108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH}, |
109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, | 109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, | 110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, | 111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
112 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, | 112 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, | 115 | [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
116 | [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1}, | 116 | [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
117 | 117 | ||
118 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0}, | 118 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, |
119 | }; | 119 | }; |
120 | 120 | ||
121 | #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) | 121 | #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) |
@@ -129,7 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
129 | * | 129 | * |
130 | * \sa drm_device | 130 | * \sa drm_device |
131 | */ | 131 | */ |
132 | int drm_takedown(drm_device_t * dev) | 132 | int drm_lastclose(drm_device_t * dev) |
133 | { | 133 | { |
134 | drm_magic_entry_t *pt, *next; | 134 | drm_magic_entry_t *pt, *next; |
135 | drm_map_list_t *r_list; | 135 | drm_map_list_t *r_list; |
@@ -138,9 +138,9 @@ int drm_takedown(drm_device_t * dev) | |||
138 | 138 | ||
139 | DRM_DEBUG("\n"); | 139 | DRM_DEBUG("\n"); |
140 | 140 | ||
141 | if (dev->driver->pretakedown) | 141 | if (dev->driver->lastclose) |
142 | dev->driver->pretakedown(dev); | 142 | dev->driver->lastclose(dev); |
143 | DRM_DEBUG("driver pretakedown completed\n"); | 143 | DRM_DEBUG("driver lastclose completed\n"); |
144 | 144 | ||
145 | if (dev->unique) { | 145 | if (dev->unique) { |
146 | drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); | 146 | drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); |
@@ -233,7 +233,7 @@ int drm_takedown(drm_device_t * dev) | |||
233 | } | 233 | } |
234 | up(&dev->struct_sem); | 234 | up(&dev->struct_sem); |
235 | 235 | ||
236 | DRM_DEBUG("takedown completed\n"); | 236 | DRM_DEBUG("lastclose completed\n"); |
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
@@ -281,7 +281,7 @@ EXPORT_SYMBOL(drm_init); | |||
281 | /** | 281 | /** |
282 | * Called via cleanup_module() at module unload time. | 282 | * Called via cleanup_module() at module unload time. |
283 | * | 283 | * |
284 | * Cleans up all DRM device, calling takedown(). | 284 | * Cleans up all DRM device, calling drm_lastclose(). |
285 | * | 285 | * |
286 | * \sa drm_init | 286 | * \sa drm_init |
287 | */ | 287 | */ |
@@ -294,7 +294,7 @@ static void drm_cleanup(drm_device_t * dev) | |||
294 | return; | 294 | return; |
295 | } | 295 | } |
296 | 296 | ||
297 | drm_takedown(dev); | 297 | drm_lastclose(dev); |
298 | 298 | ||
299 | if (dev->maplist) { | 299 | if (dev->maplist) { |
300 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); | 300 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); |
@@ -317,8 +317,8 @@ static void drm_cleanup(drm_device_t * dev) | |||
317 | dev->agp = NULL; | 317 | dev->agp = NULL; |
318 | } | 318 | } |
319 | 319 | ||
320 | if (dev->driver->postcleanup) | 320 | if (dev->driver->unload) |
321 | dev->driver->postcleanup(dev); | 321 | dev->driver->unload(dev); |
322 | 322 | ||
323 | drm_put_head(&dev->primary); | 323 | drm_put_head(&dev->primary); |
324 | if (drm_put_dev(dev)) | 324 | if (drm_put_dev(dev)) |
@@ -342,12 +342,12 @@ void drm_exit(struct drm_driver *driver) | |||
342 | if (head->dev->driver != driver) | 342 | if (head->dev->driver != driver) |
343 | continue; | 343 | continue; |
344 | dev = head->dev; | 344 | dev = head->dev; |
345 | } | 345 | if (dev) { |
346 | if (dev) { | 346 | /* release the pci driver */ |
347 | /* release the pci driver */ | 347 | if (dev->pdev) |
348 | if (dev->pdev) | 348 | pci_dev_put(dev->pdev); |
349 | pci_dev_put(dev->pdev); | 349 | drm_cleanup(dev); |
350 | drm_cleanup(dev); | 350 | } |
351 | } | 351 | } |
352 | DRM_INFO("Module unloaded\n"); | 352 | DRM_INFO("Module unloaded\n"); |
353 | } | 353 | } |
@@ -432,14 +432,17 @@ static int drm_version(struct inode *inode, struct file *filp, | |||
432 | drm_device_t *dev = priv->head->dev; | 432 | drm_device_t *dev = priv->head->dev; |
433 | drm_version_t __user *argp = (void __user *)arg; | 433 | drm_version_t __user *argp = (void __user *)arg; |
434 | drm_version_t version; | 434 | drm_version_t version; |
435 | int ret; | 435 | int len; |
436 | 436 | ||
437 | if (copy_from_user(&version, argp, sizeof(version))) | 437 | if (copy_from_user(&version, argp, sizeof(version))) |
438 | return -EFAULT; | 438 | return -EFAULT; |
439 | 439 | ||
440 | /* version is a required function to return the personality module version */ | 440 | version.version_major = dev->driver->major; |
441 | if ((ret = dev->driver->version(&version))) | 441 | version.version_minor = dev->driver->minor; |
442 | return ret; | 442 | version.version_patchlevel = dev->driver->patchlevel; |
443 | DRM_COPY(version.name, dev->driver->name); | ||
444 | DRM_COPY(version.date, dev->driver->date); | ||
445 | DRM_COPY(version.desc, dev->driver->desc); | ||
443 | 446 | ||
444 | if (copy_to_user(argp, &version, sizeof(version))) | 447 | if (copy_to_user(argp, &version, sizeof(version))) |
445 | return -EFAULT; | 448 | return -EFAULT; |
@@ -493,8 +496,9 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
493 | if (!func) { | 496 | if (!func) { |
494 | DRM_DEBUG("no function\n"); | 497 | DRM_DEBUG("no function\n"); |
495 | retcode = -EINVAL; | 498 | retcode = -EINVAL; |
496 | } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) || | 499 | } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || |
497 | (ioctl->auth_needed && !priv->authenticated)) { | 500 | ((ioctl->flags & DRM_AUTH) && !priv->authenticated) || |
501 | ((ioctl->flags & DRM_MASTER) && !priv->master)) { | ||
498 | retcode = -EACCES; | 502 | retcode = -EACCES; |
499 | } else { | 503 | } else { |
500 | retcode = func(inode, filp, cmd, arg); | 504 | retcode = func(inode, filp, cmd, arg); |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index bf0a740122bf..403f44a1bf01 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -35,6 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "drmP.h" | 37 | #include "drmP.h" |
38 | #include "drm_sarea.h" | ||
38 | #include <linux/poll.h> | 39 | #include <linux/poll.h> |
39 | 40 | ||
40 | static int drm_open_helper(struct inode *inode, struct file *filp, | 41 | static int drm_open_helper(struct inode *inode, struct file *filp, |
@@ -42,15 +43,21 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
42 | 43 | ||
43 | static int drm_setup(drm_device_t * dev) | 44 | static int drm_setup(drm_device_t * dev) |
44 | { | 45 | { |
46 | drm_local_map_t *map; | ||
45 | int i; | 47 | int i; |
46 | int ret; | 48 | int ret; |
47 | 49 | ||
48 | if (dev->driver->presetup) { | 50 | if (dev->driver->firstopen) { |
49 | ret = dev->driver->presetup(dev); | 51 | ret = dev->driver->firstopen(dev); |
50 | if (ret != 0) | 52 | if (ret != 0) |
51 | return ret; | 53 | return ret; |
52 | } | 54 | } |
53 | 55 | ||
56 | /* prebuild the SAREA */ | ||
57 | i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); | ||
58 | if (i != 0) | ||
59 | return i; | ||
60 | |||
54 | atomic_set(&dev->ioctl_count, 0); | 61 | atomic_set(&dev->ioctl_count, 0); |
55 | atomic_set(&dev->vma_count, 0); | 62 | atomic_set(&dev->vma_count, 0); |
56 | dev->buf_use = 0; | 63 | dev->buf_use = 0; |
@@ -109,8 +116,6 @@ static int drm_setup(drm_device_t * dev) | |||
109 | * drm_select_queue fails between the time the interrupt is | 116 | * drm_select_queue fails between the time the interrupt is |
110 | * initialized and the time the queues are initialized. | 117 | * initialized and the time the queues are initialized. |
111 | */ | 118 | */ |
112 | if (dev->driver->postsetup) | ||
113 | dev->driver->postsetup(dev); | ||
114 | 119 | ||
115 | return 0; | 120 | return 0; |
116 | } | 121 | } |
@@ -154,10 +159,168 @@ int drm_open(struct inode *inode, struct file *filp) | |||
154 | 159 | ||
155 | return retcode; | 160 | return retcode; |
156 | } | 161 | } |
157 | |||
158 | EXPORT_SYMBOL(drm_open); | 162 | EXPORT_SYMBOL(drm_open); |
159 | 163 | ||
160 | /** | 164 | /** |
165 | * File \c open operation. | ||
166 | * | ||
167 | * \param inode device inode. | ||
168 | * \param filp file pointer. | ||
169 | * | ||
170 | * Puts the dev->fops corresponding to the device minor number into | ||
171 | * \p filp, call the \c open method, and restore the file operations. | ||
172 | */ | ||
173 | int drm_stub_open(struct inode *inode, struct file *filp) | ||
174 | { | ||
175 | drm_device_t *dev = NULL; | ||
176 | int minor = iminor(inode); | ||
177 | int err = -ENODEV; | ||
178 | struct file_operations *old_fops; | ||
179 | |||
180 | DRM_DEBUG("\n"); | ||
181 | |||
182 | if (!((minor >= 0) && (minor < drm_cards_limit))) | ||
183 | return -ENODEV; | ||
184 | |||
185 | if (!drm_heads[minor]) | ||
186 | return -ENODEV; | ||
187 | |||
188 | if (!(dev = drm_heads[minor]->dev)) | ||
189 | return -ENODEV; | ||
190 | |||
191 | old_fops = filp->f_op; | ||
192 | filp->f_op = fops_get(&dev->driver->fops); | ||
193 | if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { | ||
194 | fops_put(filp->f_op); | ||
195 | filp->f_op = fops_get(old_fops); | ||
196 | } | ||
197 | fops_put(old_fops); | ||
198 | |||
199 | return err; | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * Check whether DRI will run on this CPU. | ||
204 | * | ||
205 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. | ||
206 | */ | ||
207 | static int drm_cpu_valid(void) | ||
208 | { | ||
209 | #if defined(__i386__) | ||
210 | if (boot_cpu_data.x86 == 3) | ||
211 | return 0; /* No cmpxchg on a 386 */ | ||
212 | #endif | ||
213 | #if defined(__sparc__) && !defined(__sparc_v9__) | ||
214 | return 0; /* No cmpxchg before v9 sparc. */ | ||
215 | #endif | ||
216 | return 1; | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * Called whenever a process opens /dev/drm. | ||
221 | * | ||
222 | * \param inode device inode. | ||
223 | * \param filp file pointer. | ||
224 | * \param dev device. | ||
225 | * \return zero on success or a negative number on failure. | ||
226 | * | ||
227 | * Creates and initializes a drm_file structure for the file private data in \p | ||
228 | * filp and add it into the double linked list in \p dev. | ||
229 | */ | ||
230 | static int drm_open_helper(struct inode *inode, struct file *filp, | ||
231 | drm_device_t * dev) | ||
232 | { | ||
233 | int minor = iminor(inode); | ||
234 | drm_file_t *priv; | ||
235 | int ret; | ||
236 | |||
237 | if (filp->f_flags & O_EXCL) | ||
238 | return -EBUSY; /* No exclusive opens */ | ||
239 | if (!drm_cpu_valid()) | ||
240 | return -EINVAL; | ||
241 | |||
242 | DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); | ||
243 | |||
244 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | ||
245 | if (!priv) | ||
246 | return -ENOMEM; | ||
247 | |||
248 | memset(priv, 0, sizeof(*priv)); | ||
249 | filp->private_data = priv; | ||
250 | priv->uid = current->euid; | ||
251 | priv->pid = current->pid; | ||
252 | priv->minor = minor; | ||
253 | priv->head = drm_heads[minor]; | ||
254 | priv->ioctl_count = 0; | ||
255 | /* for compatibility root is always authenticated */ | ||
256 | priv->authenticated = capable(CAP_SYS_ADMIN); | ||
257 | priv->lock_count = 0; | ||
258 | |||
259 | if (dev->driver->open) { | ||
260 | ret = dev->driver->open(dev, priv); | ||
261 | if (ret < 0) | ||
262 | goto out_free; | ||
263 | } | ||
264 | |||
265 | down(&dev->struct_sem); | ||
266 | if (!dev->file_last) { | ||
267 | priv->next = NULL; | ||
268 | priv->prev = NULL; | ||
269 | dev->file_first = priv; | ||
270 | dev->file_last = priv; | ||
271 | /* first opener automatically becomes master */ | ||
272 | priv->master = 1; | ||
273 | } else { | ||
274 | priv->next = NULL; | ||
275 | priv->prev = dev->file_last; | ||
276 | dev->file_last->next = priv; | ||
277 | dev->file_last = priv; | ||
278 | } | ||
279 | up(&dev->struct_sem); | ||
280 | |||
281 | #ifdef __alpha__ | ||
282 | /* | ||
283 | * Default the hose | ||
284 | */ | ||
285 | if (!dev->hose) { | ||
286 | struct pci_dev *pci_dev; | ||
287 | pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); | ||
288 | if (pci_dev) { | ||
289 | dev->hose = pci_dev->sysdata; | ||
290 | pci_dev_put(pci_dev); | ||
291 | } | ||
292 | if (!dev->hose) { | ||
293 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); | ||
294 | if (b) | ||
295 | dev->hose = b->sysdata; | ||
296 | } | ||
297 | } | ||
298 | #endif | ||
299 | |||
300 | return 0; | ||
301 | out_free: | ||
302 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); | ||
303 | filp->private_data = NULL; | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | /** No-op. */ | ||
308 | int drm_fasync(int fd, struct file *filp, int on) | ||
309 | { | ||
310 | drm_file_t *priv = filp->private_data; | ||
311 | drm_device_t *dev = priv->head->dev; | ||
312 | int retcode; | ||
313 | |||
314 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, | ||
315 | (long)old_encode_dev(priv->head->device)); | ||
316 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); | ||
317 | if (retcode < 0) | ||
318 | return retcode; | ||
319 | return 0; | ||
320 | } | ||
321 | EXPORT_SYMBOL(drm_fasync); | ||
322 | |||
323 | /** | ||
161 | * Release file. | 324 | * Release file. |
162 | * | 325 | * |
163 | * \param inode device inode | 326 | * \param inode device inode |
@@ -167,7 +330,7 @@ EXPORT_SYMBOL(drm_open); | |||
167 | * If the hardware lock is held then free it, and take it again for the kernel | 330 | * If the hardware lock is held then free it, and take it again for the kernel |
168 | * context since it's necessary to reclaim buffers. Unlink the file private | 331 | * context since it's necessary to reclaim buffers. Unlink the file private |
169 | * data from its list and free it. Decreases the open count and if it reaches | 332 | * data from its list and free it. Decreases the open count and if it reaches |
170 | * zero calls takedown(). | 333 | * zero calls drm_lastclose(). |
171 | */ | 334 | */ |
172 | int drm_release(struct inode *inode, struct file *filp) | 335 | int drm_release(struct inode *inode, struct file *filp) |
173 | { | 336 | { |
@@ -180,8 +343,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
180 | 343 | ||
181 | DRM_DEBUG("open_count = %d\n", dev->open_count); | 344 | DRM_DEBUG("open_count = %d\n", dev->open_count); |
182 | 345 | ||
183 | if (dev->driver->prerelease) | 346 | if (dev->driver->preclose) |
184 | dev->driver->prerelease(dev, filp); | 347 | dev->driver->preclose(dev, filp); |
185 | 348 | ||
186 | /* ======================================================== | 349 | /* ======================================================== |
187 | * Begin inline drm_release | 350 | * Begin inline drm_release |
@@ -197,8 +360,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
197 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | 360 | DRM_DEBUG("File %p released, freeing lock for context %d\n", |
198 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | 361 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); |
199 | 362 | ||
200 | if (dev->driver->release) | 363 | if (dev->driver->reclaim_buffers_locked) |
201 | dev->driver->release(dev, filp); | 364 | dev->driver->reclaim_buffers_locked(dev, filp); |
202 | 365 | ||
203 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 366 | drm_lock_free(dev, &dev->lock.hw_lock->lock, |
204 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | 367 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); |
@@ -207,7 +370,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
207 | hardware at this point, possibly | 370 | hardware at this point, possibly |
208 | processed via a callback to the X | 371 | processed via a callback to the X |
209 | server. */ | 372 | server. */ |
210 | } else if (dev->driver->release && priv->lock_count | 373 | } else if (dev->driver->reclaim_buffers_locked && priv->lock_count |
211 | && dev->lock.hw_lock) { | 374 | && dev->lock.hw_lock) { |
212 | /* The lock is required to reclaim buffers */ | 375 | /* The lock is required to reclaim buffers */ |
213 | DECLARE_WAITQUEUE(entry, current); | 376 | DECLARE_WAITQUEUE(entry, current); |
@@ -237,15 +400,14 @@ int drm_release(struct inode *inode, struct file *filp) | |||
237 | __set_current_state(TASK_RUNNING); | 400 | __set_current_state(TASK_RUNNING); |
238 | remove_wait_queue(&dev->lock.lock_queue, &entry); | 401 | remove_wait_queue(&dev->lock.lock_queue, &entry); |
239 | if (!retcode) { | 402 | if (!retcode) { |
240 | if (dev->driver->release) | 403 | dev->driver->reclaim_buffers_locked(dev, filp); |
241 | dev->driver->release(dev, filp); | ||
242 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 404 | drm_lock_free(dev, &dev->lock.hw_lock->lock, |
243 | DRM_KERNEL_CONTEXT); | 405 | DRM_KERNEL_CONTEXT); |
244 | } | 406 | } |
245 | } | 407 | } |
246 | 408 | ||
247 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) | 409 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && |
248 | && !dev->driver->release) { | 410 | !dev->driver->reclaim_buffers_locked) { |
249 | dev->driver->reclaim_buffers(dev, filp); | 411 | dev->driver->reclaim_buffers(dev, filp); |
250 | } | 412 | } |
251 | 413 | ||
@@ -292,9 +454,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
292 | } | 454 | } |
293 | up(&dev->struct_sem); | 455 | up(&dev->struct_sem); |
294 | 456 | ||
295 | if (dev->driver->free_filp_priv) | 457 | if (dev->driver->postclose) |
296 | dev->driver->free_filp_priv(dev, priv); | 458 | dev->driver->postclose(dev, priv); |
297 | |||
298 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); | 459 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); |
299 | 460 | ||
300 | /* ======================================================== | 461 | /* ======================================================== |
@@ -313,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
313 | } | 474 | } |
314 | spin_unlock(&dev->count_lock); | 475 | spin_unlock(&dev->count_lock); |
315 | unlock_kernel(); | 476 | unlock_kernel(); |
316 | return drm_takedown(dev); | 477 | return drm_lastclose(dev); |
317 | } | 478 | } |
318 | spin_unlock(&dev->count_lock); | 479 | spin_unlock(&dev->count_lock); |
319 | 480 | ||
@@ -321,129 +482,11 @@ int drm_release(struct inode *inode, struct file *filp) | |||
321 | 482 | ||
322 | return retcode; | 483 | return retcode; |
323 | } | 484 | } |
324 | |||
325 | EXPORT_SYMBOL(drm_release); | 485 | EXPORT_SYMBOL(drm_release); |
326 | 486 | ||
327 | /** | ||
328 | * Called whenever a process opens /dev/drm. | ||
329 | * | ||
330 | * \param inode device inode. | ||
331 | * \param filp file pointer. | ||
332 | * \param dev device. | ||
333 | * \return zero on success or a negative number on failure. | ||
334 | * | ||
335 | * Creates and initializes a drm_file structure for the file private data in \p | ||
336 | * filp and add it into the double linked list in \p dev. | ||
337 | */ | ||
338 | static int drm_open_helper(struct inode *inode, struct file *filp, | ||
339 | drm_device_t * dev) | ||
340 | { | ||
341 | int minor = iminor(inode); | ||
342 | drm_file_t *priv; | ||
343 | int ret; | ||
344 | |||
345 | if (filp->f_flags & O_EXCL) | ||
346 | return -EBUSY; /* No exclusive opens */ | ||
347 | if (!drm_cpu_valid()) | ||
348 | return -EINVAL; | ||
349 | |||
350 | DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); | ||
351 | |||
352 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | ||
353 | if (!priv) | ||
354 | return -ENOMEM; | ||
355 | |||
356 | memset(priv, 0, sizeof(*priv)); | ||
357 | filp->private_data = priv; | ||
358 | priv->uid = current->euid; | ||
359 | priv->pid = current->pid; | ||
360 | priv->minor = minor; | ||
361 | priv->head = drm_heads[minor]; | ||
362 | priv->ioctl_count = 0; | ||
363 | priv->authenticated = capable(CAP_SYS_ADMIN); | ||
364 | priv->lock_count = 0; | ||
365 | |||
366 | if (dev->driver->open_helper) { | ||
367 | ret = dev->driver->open_helper(dev, priv); | ||
368 | if (ret < 0) | ||
369 | goto out_free; | ||
370 | } | ||
371 | |||
372 | down(&dev->struct_sem); | ||
373 | if (!dev->file_last) { | ||
374 | priv->next = NULL; | ||
375 | priv->prev = NULL; | ||
376 | dev->file_first = priv; | ||
377 | dev->file_last = priv; | ||
378 | } else { | ||
379 | priv->next = NULL; | ||
380 | priv->prev = dev->file_last; | ||
381 | dev->file_last->next = priv; | ||
382 | dev->file_last = priv; | ||
383 | } | ||
384 | up(&dev->struct_sem); | ||
385 | |||
386 | #ifdef __alpha__ | ||
387 | /* | ||
388 | * Default the hose | ||
389 | */ | ||
390 | if (!dev->hose) { | ||
391 | struct pci_dev *pci_dev; | ||
392 | pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); | ||
393 | if (pci_dev) { | ||
394 | dev->hose = pci_dev->sysdata; | ||
395 | pci_dev_put(pci_dev); | ||
396 | } | ||
397 | if (!dev->hose) { | ||
398 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); | ||
399 | if (b) | ||
400 | dev->hose = b->sysdata; | ||
401 | } | ||
402 | } | ||
403 | #endif | ||
404 | |||
405 | return 0; | ||
406 | out_free: | ||
407 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); | ||
408 | filp->private_data = NULL; | ||
409 | return ret; | ||
410 | } | ||
411 | |||
412 | /** No-op. */ | ||
413 | int drm_flush(struct file *filp) | ||
414 | { | ||
415 | drm_file_t *priv = filp->private_data; | ||
416 | drm_device_t *dev = priv->head->dev; | ||
417 | |||
418 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", | ||
419 | current->pid, (long)old_encode_dev(priv->head->device), | ||
420 | dev->open_count); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | EXPORT_SYMBOL(drm_flush); | ||
425 | |||
426 | /** No-op. */ | ||
427 | int drm_fasync(int fd, struct file *filp, int on) | ||
428 | { | ||
429 | drm_file_t *priv = filp->private_data; | ||
430 | drm_device_t *dev = priv->head->dev; | ||
431 | int retcode; | ||
432 | |||
433 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, | ||
434 | (long)old_encode_dev(priv->head->device)); | ||
435 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); | ||
436 | if (retcode < 0) | ||
437 | return retcode; | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | EXPORT_SYMBOL(drm_fasync); | ||
442 | |||
443 | /** No-op. */ | 487 | /** No-op. */ |
444 | unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) | 488 | unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) |
445 | { | 489 | { |
446 | return 0; | 490 | return 0; |
447 | } | 491 | } |
448 | |||
449 | EXPORT_SYMBOL(drm_poll); | 492 | EXPORT_SYMBOL(drm_poll); |
diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c deleted file mode 100644 index 754b934715c4..000000000000 --- a/drivers/char/drm/drm_init.c +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /** | ||
2 | * \file drm_init.c | ||
3 | * Setup/Cleanup for DRM | ||
4 | * | ||
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
6 | * \author Gareth Hughes <gareth@valinux.com> | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com | ||
11 | * | ||
12 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | ||
13 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
14 | * All Rights Reserved. | ||
15 | * | ||
16 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
17 | * copy of this software and associated documentation files (the "Software"), | ||
18 | * to deal in the Software without restriction, including without limitation | ||
19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
20 | * and/or sell copies of the Software, and to permit persons to whom the | ||
21 | * Software is furnished to do so, subject to the following conditions: | ||
22 | * | ||
23 | * The above copyright notice and this permission notice (including the next | ||
24 | * paragraph) shall be included in all copies or substantial portions of the | ||
25 | * Software. | ||
26 | * | ||
27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
28 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
29 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
30 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
31 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
32 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
33 | * OTHER DEALINGS IN THE SOFTWARE. | ||
34 | */ | ||
35 | |||
36 | #include "drmP.h" | ||
37 | |||
38 | /** | ||
39 | * Check whether DRI will run on this CPU. | ||
40 | * | ||
41 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. | ||
42 | */ | ||
43 | int drm_cpu_valid(void) | ||
44 | { | ||
45 | #if defined(__i386__) | ||
46 | if (boot_cpu_data.x86 == 3) | ||
47 | return 0; /* No cmpxchg on a 386 */ | ||
48 | #endif | ||
49 | #if defined(__sparc__) && !defined(__sparc_v9__) | ||
50 | return 0; /* No cmpxchg before v9 sparc. */ | ||
51 | #endif | ||
52 | return 1; | ||
53 | } | ||
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c index 9b0feba6b063..bcd4e604d3ec 100644 --- a/drivers/char/drm/drm_ioctl.c +++ b/drivers/char/drm/drm_ioctl.c | |||
@@ -137,17 +137,22 @@ int drm_setunique(struct inode *inode, struct file *filp, | |||
137 | 137 | ||
138 | static int drm_set_busid(drm_device_t * dev) | 138 | static int drm_set_busid(drm_device_t * dev) |
139 | { | 139 | { |
140 | int len; | ||
141 | |||
140 | if (dev->unique != NULL) | 142 | if (dev->unique != NULL) |
141 | return EBUSY; | 143 | return EBUSY; |
142 | 144 | ||
143 | dev->unique_len = 20; | 145 | dev->unique_len = 40; |
144 | dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); | 146 | dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); |
145 | if (dev->unique == NULL) | 147 | if (dev->unique == NULL) |
146 | return ENOMEM; | 148 | return ENOMEM; |
147 | 149 | ||
148 | snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", | 150 | len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", |
149 | dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); | 151 | dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); |
150 | 152 | ||
153 | if (len > dev->unique_len) | ||
154 | DRM_ERROR("Unique buffer overflowed\n"); | ||
155 | |||
151 | dev->devname = | 156 | dev->devname = |
152 | drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + | 157 | drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + |
153 | 2, DRM_MEM_DRIVER); | 158 | 2, DRM_MEM_DRIVER); |
@@ -239,7 +244,7 @@ int drm_getclient(struct inode *inode, struct file *filp, | |||
239 | { | 244 | { |
240 | drm_file_t *priv = filp->private_data; | 245 | drm_file_t *priv = filp->private_data; |
241 | drm_device_t *dev = priv->head->dev; | 246 | drm_device_t *dev = priv->head->dev; |
242 | drm_client_t __user *argp = (void __user *)arg; | 247 | drm_client_t __user *argp = (drm_client_t __user *)arg; |
243 | drm_client_t client; | 248 | drm_client_t client; |
244 | drm_file_t *pt; | 249 | drm_file_t *pt; |
245 | int idx; | 250 | int idx; |
@@ -262,7 +267,7 @@ int drm_getclient(struct inode *inode, struct file *filp, | |||
262 | client.iocs = pt->ioctl_count; | 267 | client.iocs = pt->ioctl_count; |
263 | up(&dev->struct_sem); | 268 | up(&dev->struct_sem); |
264 | 269 | ||
265 | if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client))) | 270 | if (copy_to_user(argp, &client, sizeof(client))) |
266 | return -EFAULT; | 271 | return -EFAULT; |
267 | return 0; | 272 | return 0; |
268 | } | 273 | } |
@@ -325,17 +330,13 @@ int drm_setversion(DRM_IOCTL_ARGS) | |||
325 | drm_set_version_t retv; | 330 | drm_set_version_t retv; |
326 | int if_version; | 331 | int if_version; |
327 | drm_set_version_t __user *argp = (void __user *)data; | 332 | drm_set_version_t __user *argp = (void __user *)data; |
328 | drm_version_t version; | ||
329 | 333 | ||
330 | DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); | 334 | DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); |
331 | 335 | ||
332 | memset(&version, 0, sizeof(version)); | ||
333 | |||
334 | dev->driver->version(&version); | ||
335 | retv.drm_di_major = DRM_IF_MAJOR; | 336 | retv.drm_di_major = DRM_IF_MAJOR; |
336 | retv.drm_di_minor = DRM_IF_MINOR; | 337 | retv.drm_di_minor = DRM_IF_MINOR; |
337 | retv.drm_dd_major = version.version_major; | 338 | retv.drm_dd_major = dev->driver->major; |
338 | retv.drm_dd_minor = version.version_minor; | 339 | retv.drm_dd_minor = dev->driver->minor; |
339 | 340 | ||
340 | DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); | 341 | DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); |
341 | 342 | ||
@@ -343,7 +344,7 @@ int drm_setversion(DRM_IOCTL_ARGS) | |||
343 | if (sv.drm_di_major != DRM_IF_MAJOR || | 344 | if (sv.drm_di_major != DRM_IF_MAJOR || |
344 | sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) | 345 | sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) |
345 | return EINVAL; | 346 | return EINVAL; |
346 | if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor); | 347 | if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor); |
347 | dev->if_version = DRM_MAX(if_version, dev->if_version); | 348 | dev->if_version = DRM_MAX(if_version, dev->if_version); |
348 | if (sv.drm_di_minor >= 1) { | 349 | if (sv.drm_di_minor >= 1) { |
349 | /* | 350 | /* |
@@ -354,9 +355,9 @@ int drm_setversion(DRM_IOCTL_ARGS) | |||
354 | } | 355 | } |
355 | 356 | ||
356 | if (sv.drm_dd_major != -1) { | 357 | if (sv.drm_dd_major != -1) { |
357 | if (sv.drm_dd_major != version.version_major || | 358 | if (sv.drm_dd_major != dev->driver->major || |
358 | sv.drm_dd_minor < 0 | 359 | sv.drm_dd_minor < 0 |
359 | || sv.drm_dd_minor > version.version_minor) | 360 | || sv.drm_dd_minor > dev->driver->minor) |
360 | return EINVAL; | 361 | return EINVAL; |
361 | 362 | ||
362 | if (dev->driver->set_version) | 363 | if (dev->driver->set_version) |
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index b48a595d54ec..f9e45303498d 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c | |||
@@ -130,7 +130,6 @@ int drm_lock(struct inode *inode, struct file *filp, | |||
130 | /* dev->driver->kernel_context_switch isn't used by any of the x86 | 130 | /* dev->driver->kernel_context_switch isn't used by any of the x86 |
131 | * drivers but is used by the Sparc driver. | 131 | * drivers but is used by the Sparc driver. |
132 | */ | 132 | */ |
133 | |||
134 | if (dev->driver->kernel_context_switch && | 133 | if (dev->driver->kernel_context_switch && |
135 | dev->last_context != lock.context) { | 134 | dev->last_context != lock.context) { |
136 | dev->driver->kernel_context_switch(dev, dev->last_context, | 135 | dev->driver->kernel_context_switch(dev, dev->last_context, |
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c index abef2acf99f5..8074771e348f 100644 --- a/drivers/char/drm/drm_memory.c +++ b/drivers/char/drm/drm_memory.c | |||
@@ -145,30 +145,22 @@ DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) | |||
145 | return drm_agp_allocate_memory(dev->agp->bridge, pages, type); | 145 | return drm_agp_allocate_memory(dev->agp->bridge, pages, type); |
146 | } | 146 | } |
147 | 147 | ||
148 | EXPORT_SYMBOL(drm_alloc_agp); | ||
149 | |||
150 | /** Wrapper around agp_free_memory() */ | 148 | /** Wrapper around agp_free_memory() */ |
151 | int drm_free_agp(DRM_AGP_MEM * handle, int pages) | 149 | int drm_free_agp(DRM_AGP_MEM * handle, int pages) |
152 | { | 150 | { |
153 | return drm_agp_free_memory(handle) ? 0 : -EINVAL; | 151 | return drm_agp_free_memory(handle) ? 0 : -EINVAL; |
154 | } | 152 | } |
155 | 153 | ||
156 | EXPORT_SYMBOL(drm_free_agp); | ||
157 | |||
158 | /** Wrapper around agp_bind_memory() */ | 154 | /** Wrapper around agp_bind_memory() */ |
159 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) | 155 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) |
160 | { | 156 | { |
161 | return drm_agp_bind_memory(handle, start); | 157 | return drm_agp_bind_memory(handle, start); |
162 | } | 158 | } |
163 | 159 | ||
164 | EXPORT_SYMBOL(drm_bind_agp); | ||
165 | |||
166 | /** Wrapper around agp_unbind_memory() */ | 160 | /** Wrapper around agp_unbind_memory() */ |
167 | int drm_unbind_agp(DRM_AGP_MEM * handle) | 161 | int drm_unbind_agp(DRM_AGP_MEM * handle) |
168 | { | 162 | { |
169 | return drm_agp_unbind_memory(handle); | 163 | return drm_agp_unbind_memory(handle); |
170 | } | 164 | } |
171 | |||
172 | EXPORT_SYMBOL(drm_unbind_agp); | ||
173 | #endif /* agp */ | 165 | #endif /* agp */ |
174 | #endif /* debug_memory */ | 166 | #endif /* debug_memory */ |
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index b370aca718d2..e84605fc54af 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * \file drm_memory.h | 2 | * \file drm_memory_debug.h |
3 | * Memory management wrappers for DRM. | 3 | * Memory management wrappers for DRM. |
4 | * | 4 | * |
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | 5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> |
@@ -43,42 +43,41 @@ typedef struct drm_mem_stats { | |||
43 | unsigned long bytes_freed; | 43 | unsigned long bytes_freed; |
44 | } drm_mem_stats_t; | 44 | } drm_mem_stats_t; |
45 | 45 | ||
46 | static DEFINE_SPINLOCK(DRM(mem_lock)); | 46 | static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; |
47 | static unsigned long DRM(ram_available) = 0; /* In pages */ | 47 | static unsigned long drm_ram_available = 0; /* In pages */ |
48 | static unsigned long DRM(ram_used) = 0; | 48 | static unsigned long drm_ram_used = 0; |
49 | static drm_mem_stats_t DRM(mem_stats)[] = | 49 | static drm_mem_stats_t drm_mem_stats[] = |
50 | { | 50 | { |
51 | [DRM_MEM_DMA] = { | 51 | [DRM_MEM_DMA] = {"dmabufs"}, |
52 | "dmabufs"},[DRM_MEM_SAREA] = { | 52 | [DRM_MEM_SAREA] = {"sareas"}, |
53 | "sareas"},[DRM_MEM_DRIVER] = { | 53 | [DRM_MEM_DRIVER] = {"driver"}, |
54 | "driver"},[DRM_MEM_MAGIC] = { | 54 | [DRM_MEM_MAGIC] = {"magic"}, |
55 | "magic"},[DRM_MEM_IOCTLS] = { | 55 | [DRM_MEM_IOCTLS] = {"ioctltab"}, |
56 | "ioctltab"},[DRM_MEM_MAPS] = { | 56 | [DRM_MEM_MAPS] = {"maplist"}, |
57 | "maplist"},[DRM_MEM_VMAS] = { | 57 | [DRM_MEM_VMAS] = {"vmalist"}, |
58 | "vmalist"},[DRM_MEM_BUFS] = { | 58 | [DRM_MEM_BUFS] = {"buflist"}, |
59 | "buflist"},[DRM_MEM_SEGS] = { | 59 | [DRM_MEM_SEGS] = {"seglist"}, |
60 | "seglist"},[DRM_MEM_PAGES] = { | 60 | [DRM_MEM_PAGES] = {"pagelist"}, |
61 | "pagelist"},[DRM_MEM_FILES] = { | 61 | [DRM_MEM_FILES] = {"files"}, |
62 | "files"},[DRM_MEM_QUEUES] = { | 62 | [DRM_MEM_QUEUES] = {"queues"}, |
63 | "queues"},[DRM_MEM_CMDS] = { | 63 | [DRM_MEM_CMDS] = {"commands"}, |
64 | "commands"},[DRM_MEM_MAPPINGS] = { | 64 | [DRM_MEM_MAPPINGS] = {"mappings"}, |
65 | "mappings"},[DRM_MEM_BUFLISTS] = { | 65 | [DRM_MEM_BUFLISTS] = {"buflists"}, |
66 | "buflists"},[DRM_MEM_AGPLISTS] = { | 66 | [DRM_MEM_AGPLISTS] = {"agplist"}, |
67 | "agplist"},[DRM_MEM_SGLISTS] = { | 67 | [DRM_MEM_SGLISTS] = {"sglist"}, |
68 | "sglist"},[DRM_MEM_TOTALAGP] = { | 68 | [DRM_MEM_TOTALAGP] = {"totalagp"}, |
69 | "totalagp"},[DRM_MEM_BOUNDAGP] = { | 69 | [DRM_MEM_BOUNDAGP] = {"boundagp"}, |
70 | "boundagp"},[DRM_MEM_CTXBITMAP] = { | 70 | [DRM_MEM_CTXBITMAP] = {"ctxbitmap"}, |
71 | "ctxbitmap"},[DRM_MEM_CTXLIST] = { | 71 | [DRM_MEM_CTXLIST] = {"ctxlist"}, |
72 | "ctxlist"},[DRM_MEM_STUB] = { | 72 | [DRM_MEM_STUB] = {"stub"}, |
73 | "stub"}, { | 73 | {NULL, 0,} /* Last entry must be null */ |
74 | NULL, 0,} /* Last entry must be null */ | ||
75 | }; | 74 | }; |
76 | 75 | ||
77 | void DRM(mem_init) (void) { | 76 | void drm_mem_init (void) { |
78 | drm_mem_stats_t *mem; | 77 | drm_mem_stats_t *mem; |
79 | struct sysinfo si; | 78 | struct sysinfo si; |
80 | 79 | ||
81 | for (mem = DRM(mem_stats); mem->name; ++mem) { | 80 | for (mem = drm_mem_stats; mem->name; ++mem) { |
82 | mem->succeed_count = 0; | 81 | mem->succeed_count = 0; |
83 | mem->free_count = 0; | 82 | mem->free_count = 0; |
84 | mem->fail_count = 0; | 83 | mem->fail_count = 0; |
@@ -87,13 +86,13 @@ void DRM(mem_init) (void) { | |||
87 | } | 86 | } |
88 | 87 | ||
89 | si_meminfo(&si); | 88 | si_meminfo(&si); |
90 | DRM(ram_available) = si.totalram; | 89 | drm_ram_available = si.totalram; |
91 | DRM(ram_used) = 0; | 90 | drm_ram_used = 0; |
92 | } | 91 | } |
93 | 92 | ||
94 | /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ | 93 | /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ |
95 | 94 | ||
96 | static int DRM(_mem_info) (char *buf, char **start, off_t offset, | 95 | static int drm__mem_info (char *buf, char **start, off_t offset, |
97 | int request, int *eof, void *data) { | 96 | int request, int *eof, void *data) { |
98 | drm_mem_stats_t *pt; | 97 | drm_mem_stats_t *pt; |
99 | int len = 0; | 98 | int len = 0; |
@@ -112,11 +111,11 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset, | |||
112 | " | allocs bytes\n\n"); | 111 | " | allocs bytes\n\n"); |
113 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", | 112 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", |
114 | "system", 0, 0, 0, | 113 | "system", 0, 0, 0, |
115 | DRM(ram_available) << (PAGE_SHIFT - 10)); | 114 | drm_ram_available << (PAGE_SHIFT - 10)); |
116 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", | 115 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", |
117 | "locked", 0, 0, 0, DRM(ram_used) >> 10); | 116 | "locked", 0, 0, 0, drm_ram_used >> 10); |
118 | DRM_PROC_PRINT("\n"); | 117 | DRM_PROC_PRINT("\n"); |
119 | for (pt = DRM(mem_stats); pt->name; pt++) { | 118 | for (pt = drm_mem_stats; pt->name; pt++) { |
120 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", | 119 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", |
121 | pt->name, | 120 | pt->name, |
122 | pt->succeed_count, | 121 | pt->succeed_count, |
@@ -135,17 +134,17 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset, | |||
135 | return len - offset; | 134 | return len - offset; |
136 | } | 135 | } |
137 | 136 | ||
138 | int DRM(mem_info) (char *buf, char **start, off_t offset, | 137 | int drm_mem_info (char *buf, char **start, off_t offset, |
139 | int len, int *eof, void *data) { | 138 | int len, int *eof, void *data) { |
140 | int ret; | 139 | int ret; |
141 | 140 | ||
142 | spin_lock(&DRM(mem_lock)); | 141 | spin_lock(&drm_mem_lock); |
143 | ret = DRM(_mem_info) (buf, start, offset, len, eof, data); | 142 | ret = drm__mem_info (buf, start, offset, len, eof, data); |
144 | spin_unlock(&DRM(mem_lock)); | 143 | spin_unlock(&drm_mem_lock); |
145 | return ret; | 144 | return ret; |
146 | } | 145 | } |
147 | 146 | ||
148 | void *DRM(alloc) (size_t size, int area) { | 147 | void *drm_alloc (size_t size, int area) { |
149 | void *pt; | 148 | void *pt; |
150 | 149 | ||
151 | if (!size) { | 150 | if (!size) { |
@@ -154,41 +153,41 @@ void *DRM(alloc) (size_t size, int area) { | |||
154 | } | 153 | } |
155 | 154 | ||
156 | if (!(pt = kmalloc(size, GFP_KERNEL))) { | 155 | if (!(pt = kmalloc(size, GFP_KERNEL))) { |
157 | spin_lock(&DRM(mem_lock)); | 156 | spin_lock(&drm_mem_lock); |
158 | ++DRM(mem_stats)[area].fail_count; | 157 | ++drm_mem_stats[area].fail_count; |
159 | spin_unlock(&DRM(mem_lock)); | 158 | spin_unlock(&drm_mem_lock); |
160 | return NULL; | 159 | return NULL; |
161 | } | 160 | } |
162 | spin_lock(&DRM(mem_lock)); | 161 | spin_lock(&drm_mem_lock); |
163 | ++DRM(mem_stats)[area].succeed_count; | 162 | ++drm_mem_stats[area].succeed_count; |
164 | DRM(mem_stats)[area].bytes_allocated += size; | 163 | drm_mem_stats[area].bytes_allocated += size; |
165 | spin_unlock(&DRM(mem_lock)); | 164 | spin_unlock(&drm_mem_lock); |
166 | return pt; | 165 | return pt; |
167 | } | 166 | } |
168 | 167 | ||
169 | void *DRM(calloc) (size_t nmemb, size_t size, int area) { | 168 | void *drm_calloc (size_t nmemb, size_t size, int area) { |
170 | void *addr; | 169 | void *addr; |
171 | 170 | ||
172 | addr = DRM(alloc) (nmemb * size, area); | 171 | addr = drm_alloc (nmemb * size, area); |
173 | if (addr != NULL) | 172 | if (addr != NULL) |
174 | memset((void *)addr, 0, size * nmemb); | 173 | memset((void *)addr, 0, size * nmemb); |
175 | 174 | ||
176 | return addr; | 175 | return addr; |
177 | } | 176 | } |
178 | 177 | ||
179 | void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) { | 178 | void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) { |
180 | void *pt; | 179 | void *pt; |
181 | 180 | ||
182 | if (!(pt = DRM(alloc) (size, area))) | 181 | if (!(pt = drm_alloc (size, area))) |
183 | return NULL; | 182 | return NULL; |
184 | if (oldpt && oldsize) { | 183 | if (oldpt && oldsize) { |
185 | memcpy(pt, oldpt, oldsize); | 184 | memcpy(pt, oldpt, oldsize); |
186 | DRM(free) (oldpt, oldsize, area); | 185 | drm_free (oldpt, oldsize, area); |
187 | } | 186 | } |
188 | return pt; | 187 | return pt; |
189 | } | 188 | } |
190 | 189 | ||
191 | void DRM(free) (void *pt, size_t size, int area) { | 190 | void drm_free (void *pt, size_t size, int area) { |
192 | int alloc_count; | 191 | int alloc_count; |
193 | int free_count; | 192 | int free_count; |
194 | 193 | ||
@@ -196,43 +195,43 @@ void DRM(free) (void *pt, size_t size, int area) { | |||
196 | DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); | 195 | DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); |
197 | else | 196 | else |
198 | kfree(pt); | 197 | kfree(pt); |
199 | spin_lock(&DRM(mem_lock)); | 198 | spin_lock(&drm_mem_lock); |
200 | DRM(mem_stats)[area].bytes_freed += size; | 199 | drm_mem_stats[area].bytes_freed += size; |
201 | free_count = ++DRM(mem_stats)[area].free_count; | 200 | free_count = ++drm_mem_stats[area].free_count; |
202 | alloc_count = DRM(mem_stats)[area].succeed_count; | 201 | alloc_count = drm_mem_stats[area].succeed_count; |
203 | spin_unlock(&DRM(mem_lock)); | 202 | spin_unlock(&drm_mem_lock); |
204 | if (free_count > alloc_count) { | 203 | if (free_count > alloc_count) { |
205 | DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", | 204 | DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", |
206 | free_count, alloc_count); | 205 | free_count, alloc_count); |
207 | } | 206 | } |
208 | } | 207 | } |
209 | 208 | ||
210 | unsigned long DRM(alloc_pages) (int order, int area) { | 209 | unsigned long drm_alloc_pages (int order, int area) { |
211 | unsigned long address; | 210 | unsigned long address; |
212 | unsigned long bytes = PAGE_SIZE << order; | 211 | unsigned long bytes = PAGE_SIZE << order; |
213 | unsigned long addr; | 212 | unsigned long addr; |
214 | unsigned int sz; | 213 | unsigned int sz; |
215 | 214 | ||
216 | spin_lock(&DRM(mem_lock)); | 215 | spin_lock(&drm_mem_lock); |
217 | if ((DRM(ram_used) >> PAGE_SHIFT) | 216 | if ((drm_ram_used >> PAGE_SHIFT) |
218 | > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) { | 217 | > (DRM_RAM_PERCENT * drm_ram_available) / 100) { |
219 | spin_unlock(&DRM(mem_lock)); | 218 | spin_unlock(&drm_mem_lock); |
220 | return 0; | 219 | return 0; |
221 | } | 220 | } |
222 | spin_unlock(&DRM(mem_lock)); | 221 | spin_unlock(&drm_mem_lock); |
223 | 222 | ||
224 | address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); | 223 | address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); |
225 | if (!address) { | 224 | if (!address) { |
226 | spin_lock(&DRM(mem_lock)); | 225 | spin_lock(&drm_mem_lock); |
227 | ++DRM(mem_stats)[area].fail_count; | 226 | ++drm_mem_stats[area].fail_count; |
228 | spin_unlock(&DRM(mem_lock)); | 227 | spin_unlock(&drm_mem_lock); |
229 | return 0; | 228 | return 0; |
230 | } | 229 | } |
231 | spin_lock(&DRM(mem_lock)); | 230 | spin_lock(&drm_mem_lock); |
232 | ++DRM(mem_stats)[area].succeed_count; | 231 | ++drm_mem_stats[area].succeed_count; |
233 | DRM(mem_stats)[area].bytes_allocated += bytes; | 232 | drm_mem_stats[area].bytes_allocated += bytes; |
234 | DRM(ram_used) += bytes; | 233 | drm_ram_used += bytes; |
235 | spin_unlock(&DRM(mem_lock)); | 234 | spin_unlock(&drm_mem_lock); |
236 | 235 | ||
237 | /* Zero outside the lock */ | 236 | /* Zero outside the lock */ |
238 | memset((void *)address, 0, bytes); | 237 | memset((void *)address, 0, bytes); |
@@ -246,7 +245,7 @@ unsigned long DRM(alloc_pages) (int order, int area) { | |||
246 | return address; | 245 | return address; |
247 | } | 246 | } |
248 | 247 | ||
249 | void DRM(free_pages) (unsigned long address, int order, int area) { | 248 | void drm_free_pages (unsigned long address, int order, int area) { |
250 | unsigned long bytes = PAGE_SIZE << order; | 249 | unsigned long bytes = PAGE_SIZE << order; |
251 | int alloc_count; | 250 | int alloc_count; |
252 | int free_count; | 251 | int free_count; |
@@ -264,12 +263,12 @@ void DRM(free_pages) (unsigned long address, int order, int area) { | |||
264 | free_pages(address, order); | 263 | free_pages(address, order); |
265 | } | 264 | } |
266 | 265 | ||
267 | spin_lock(&DRM(mem_lock)); | 266 | spin_lock(&drm_mem_lock); |
268 | free_count = ++DRM(mem_stats)[area].free_count; | 267 | free_count = ++drm_mem_stats[area].free_count; |
269 | alloc_count = DRM(mem_stats)[area].succeed_count; | 268 | alloc_count = drm_mem_stats[area].succeed_count; |
270 | DRM(mem_stats)[area].bytes_freed += bytes; | 269 | drm_mem_stats[area].bytes_freed += bytes; |
271 | DRM(ram_used) -= bytes; | 270 | drm_ram_used -= bytes; |
272 | spin_unlock(&DRM(mem_lock)); | 271 | spin_unlock(&drm_mem_lock); |
273 | if (free_count > alloc_count) { | 272 | if (free_count > alloc_count) { |
274 | DRM_MEM_ERROR(area, | 273 | DRM_MEM_ERROR(area, |
275 | "Excess frees: %d frees, %d allocs\n", | 274 | "Excess frees: %d frees, %d allocs\n", |
@@ -277,7 +276,7 @@ void DRM(free_pages) (unsigned long address, int order, int area) { | |||
277 | } | 276 | } |
278 | } | 277 | } |
279 | 278 | ||
280 | void *DRM(ioremap) (unsigned long offset, unsigned long size, | 279 | void *drm_ioremap (unsigned long offset, unsigned long size, |
281 | drm_device_t * dev) { | 280 | drm_device_t * dev) { |
282 | void *pt; | 281 | void *pt; |
283 | 282 | ||
@@ -288,19 +287,19 @@ void *DRM(ioremap) (unsigned long offset, unsigned long size, | |||
288 | } | 287 | } |
289 | 288 | ||
290 | if (!(pt = drm_ioremap(offset, size, dev))) { | 289 | if (!(pt = drm_ioremap(offset, size, dev))) { |
291 | spin_lock(&DRM(mem_lock)); | 290 | spin_lock(&drm_mem_lock); |
292 | ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; | 291 | ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; |
293 | spin_unlock(&DRM(mem_lock)); | 292 | spin_unlock(&drm_mem_lock); |
294 | return NULL; | 293 | return NULL; |
295 | } | 294 | } |
296 | spin_lock(&DRM(mem_lock)); | 295 | spin_lock(&drm_mem_lock); |
297 | ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; | 296 | ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; |
298 | DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; | 297 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; |
299 | spin_unlock(&DRM(mem_lock)); | 298 | spin_unlock(&drm_mem_lock); |
300 | return pt; | 299 | return pt; |
301 | } | 300 | } |
302 | 301 | ||
303 | void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size, | 302 | void *drm_ioremap_nocache (unsigned long offset, unsigned long size, |
304 | drm_device_t * dev) { | 303 | drm_device_t * dev) { |
305 | void *pt; | 304 | void *pt; |
306 | 305 | ||
@@ -311,19 +310,19 @@ void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size, | |||
311 | } | 310 | } |
312 | 311 | ||
313 | if (!(pt = drm_ioremap_nocache(offset, size, dev))) { | 312 | if (!(pt = drm_ioremap_nocache(offset, size, dev))) { |
314 | spin_lock(&DRM(mem_lock)); | 313 | spin_lock(&drm_mem_lock); |
315 | ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; | 314 | ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; |
316 | spin_unlock(&DRM(mem_lock)); | 315 | spin_unlock(&drm_mem_lock); |
317 | return NULL; | 316 | return NULL; |
318 | } | 317 | } |
319 | spin_lock(&DRM(mem_lock)); | 318 | spin_lock(&drm_mem_lock); |
320 | ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; | 319 | ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; |
321 | DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; | 320 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; |
322 | spin_unlock(&DRM(mem_lock)); | 321 | spin_unlock(&drm_mem_lock); |
323 | return pt; | 322 | return pt; |
324 | } | 323 | } |
325 | 324 | ||
326 | void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { | 325 | void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { |
327 | int alloc_count; | 326 | int alloc_count; |
328 | int free_count; | 327 | int free_count; |
329 | 328 | ||
@@ -333,11 +332,11 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { | |||
333 | else | 332 | else |
334 | drm_ioremapfree(pt, size, dev); | 333 | drm_ioremapfree(pt, size, dev); |
335 | 334 | ||
336 | spin_lock(&DRM(mem_lock)); | 335 | spin_lock(&drm_mem_lock); |
337 | DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; | 336 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size; |
338 | free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; | 337 | free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count; |
339 | alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; | 338 | alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; |
340 | spin_unlock(&DRM(mem_lock)); | 339 | spin_unlock(&drm_mem_lock); |
341 | if (free_count > alloc_count) { | 340 | if (free_count > alloc_count) { |
342 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, | 341 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, |
343 | "Excess frees: %d frees, %d allocs\n", | 342 | "Excess frees: %d frees, %d allocs\n", |
@@ -347,7 +346,7 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { | |||
347 | 346 | ||
348 | #if __OS_HAS_AGP | 347 | #if __OS_HAS_AGP |
349 | 348 | ||
350 | DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) { | 349 | DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { |
351 | DRM_AGP_MEM *handle; | 350 | DRM_AGP_MEM *handle; |
352 | 351 | ||
353 | if (!pages) { | 352 | if (!pages) { |
@@ -355,21 +354,21 @@ DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) { | |||
355 | return NULL; | 354 | return NULL; |
356 | } | 355 | } |
357 | 356 | ||
358 | if ((handle = DRM(agp_allocate_memory) (pages, type))) { | 357 | if ((handle = drm_agp_allocate_memory (pages, type))) { |
359 | spin_lock(&DRM(mem_lock)); | 358 | spin_lock(&drm_mem_lock); |
360 | ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; | 359 | ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; |
361 | DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated | 360 | drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated |
362 | += pages << PAGE_SHIFT; | 361 | += pages << PAGE_SHIFT; |
363 | spin_unlock(&DRM(mem_lock)); | 362 | spin_unlock(&drm_mem_lock); |
364 | return handle; | 363 | return handle; |
365 | } | 364 | } |
366 | spin_lock(&DRM(mem_lock)); | 365 | spin_lock(&drm_mem_lock); |
367 | ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count; | 366 | ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; |
368 | spin_unlock(&DRM(mem_lock)); | 367 | spin_unlock(&drm_mem_lock); |
369 | return NULL; | 368 | return NULL; |
370 | } | 369 | } |
371 | 370 | ||
372 | int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { | 371 | int drm_free_agp (DRM_AGP_MEM * handle, int pages) { |
373 | int alloc_count; | 372 | int alloc_count; |
374 | int free_count; | 373 | int free_count; |
375 | int retval = -EINVAL; | 374 | int retval = -EINVAL; |
@@ -380,13 +379,13 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { | |||
380 | return retval; | 379 | return retval; |
381 | } | 380 | } |
382 | 381 | ||
383 | if (DRM(agp_free_memory) (handle)) { | 382 | if (drm_agp_free_memory (handle)) { |
384 | spin_lock(&DRM(mem_lock)); | 383 | spin_lock(&drm_mem_lock); |
385 | free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; | 384 | free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; |
386 | alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; | 385 | alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; |
387 | DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed | 386 | drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed |
388 | += pages << PAGE_SHIFT; | 387 | += pages << PAGE_SHIFT; |
389 | spin_unlock(&DRM(mem_lock)); | 388 | spin_unlock(&drm_mem_lock); |
390 | if (free_count > alloc_count) { | 389 | if (free_count > alloc_count) { |
391 | DRM_MEM_ERROR(DRM_MEM_TOTALAGP, | 390 | DRM_MEM_ERROR(DRM_MEM_TOTALAGP, |
392 | "Excess frees: %d frees, %d allocs\n", | 391 | "Excess frees: %d frees, %d allocs\n", |
@@ -397,7 +396,7 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { | |||
397 | return retval; | 396 | return retval; |
398 | } | 397 | } |
399 | 398 | ||
400 | int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) { | 399 | int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) { |
401 | int retcode = -EINVAL; | 400 | int retcode = -EINVAL; |
402 | 401 | ||
403 | if (!handle) { | 402 | if (!handle) { |
@@ -406,21 +405,21 @@ int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) { | |||
406 | return retcode; | 405 | return retcode; |
407 | } | 406 | } |
408 | 407 | ||
409 | if (!(retcode = DRM(agp_bind_memory) (handle, start))) { | 408 | if (!(retcode = drm_agp_bind_memory (handle, start))) { |
410 | spin_lock(&DRM(mem_lock)); | 409 | spin_lock(&drm_mem_lock); |
411 | ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; | 410 | ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; |
412 | DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated | 411 | drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated |
413 | += handle->page_count << PAGE_SHIFT; | 412 | += handle->page_count << PAGE_SHIFT; |
414 | spin_unlock(&DRM(mem_lock)); | 413 | spin_unlock(&drm_mem_lock); |
415 | return retcode; | 414 | return retcode; |
416 | } | 415 | } |
417 | spin_lock(&DRM(mem_lock)); | 416 | spin_lock(&drm_mem_lock); |
418 | ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count; | 417 | ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; |
419 | spin_unlock(&DRM(mem_lock)); | 418 | spin_unlock(&drm_mem_lock); |
420 | return retcode; | 419 | return retcode; |
421 | } | 420 | } |
422 | 421 | ||
423 | int DRM(unbind_agp) (DRM_AGP_MEM * handle) { | 422 | int drm_unbind_agp (DRM_AGP_MEM * handle) { |
424 | int alloc_count; | 423 | int alloc_count; |
425 | int free_count; | 424 | int free_count; |
426 | int retcode = -EINVAL; | 425 | int retcode = -EINVAL; |
@@ -431,14 +430,14 @@ int DRM(unbind_agp) (DRM_AGP_MEM * handle) { | |||
431 | return retcode; | 430 | return retcode; |
432 | } | 431 | } |
433 | 432 | ||
434 | if ((retcode = DRM(agp_unbind_memory) (handle))) | 433 | if ((retcode = drm_agp_unbind_memory (handle))) |
435 | return retcode; | 434 | return retcode; |
436 | spin_lock(&DRM(mem_lock)); | 435 | spin_lock(&drm_mem_lock); |
437 | free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; | 436 | free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; |
438 | alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; | 437 | alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; |
439 | DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed | 438 | drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed |
440 | += handle->page_count << PAGE_SHIFT; | 439 | += handle->page_count << PAGE_SHIFT; |
441 | spin_unlock(&DRM(mem_lock)); | 440 | spin_unlock(&drm_mem_lock); |
442 | if (free_count > alloc_count) { | 441 | if (free_count > alloc_count) { |
443 | DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, | 442 | DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, |
444 | "Excess frees: %d frees, %d allocs\n", | 443 | "Excess frees: %d frees, %d allocs\n", |
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h index d51aeb4966f4..695115d70382 100644 --- a/drivers/char/drm/drm_os_linux.h +++ b/drivers/char/drm/drm_os_linux.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define DRM_ERR(d) -(d) | 13 | #define DRM_ERR(d) -(d) |
14 | /** Current process ID */ | 14 | /** Current process ID */ |
15 | #define DRM_CURRENTPID current->pid | 15 | #define DRM_CURRENTPID current->pid |
16 | #define DRM_SUSER(p) capable(CAP_SYS_ADMIN) | ||
16 | #define DRM_UDELAY(d) udelay(d) | 17 | #define DRM_UDELAY(d) udelay(d) |
17 | /** Read a byte from a MMIO region */ | 18 | /** Read a byte from a MMIO region */ |
18 | #define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset)) | 19 | #define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset)) |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index d66dc55e29a0..5b1d3a04458d 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -46,6 +46,7 @@ | |||
46 | {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 46 | {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
47 | {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 47 | {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
48 | {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 48 | {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
49 | {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | ||
49 | {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 50 | {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
50 | {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 51 | {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
51 | {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 52 | {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
@@ -69,6 +70,7 @@ | |||
69 | {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 70 | {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
70 | {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 71 | {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
71 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 72 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
73 | {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
72 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ | 74 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ |
73 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ | 75 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ |
74 | {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ | 76 | {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ |
@@ -82,10 +84,13 @@ | |||
82 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 84 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
83 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 85 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
84 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 86 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
87 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | ||
85 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 88 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
86 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 89 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
87 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 90 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
88 | {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 91 | {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
92 | {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
93 | {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ | ||
89 | {0, 0, 0} | 94 | {0, 0, 0} |
90 | 95 | ||
91 | #define r128_PCI_IDS \ | 96 | #define r128_PCI_IDS \ |
@@ -176,7 +181,7 @@ | |||
176 | 181 | ||
177 | #define viadrv_PCI_IDS \ | 182 | #define viadrv_PCI_IDS \ |
178 | {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 183 | {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
179 | {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 184 | {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ |
180 | {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 185 | {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
181 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 186 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
182 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 187 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
@@ -196,6 +201,10 @@ | |||
196 | {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 201 | {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
197 | {0, 0, 0} | 202 | {0, 0, 0} |
198 | 203 | ||
204 | #define gamma_PCI_IDS \ | ||
205 | {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
206 | {0, 0, 0} | ||
207 | |||
199 | #define savage_PCI_IDS \ | 208 | #define savage_PCI_IDS \ |
200 | {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ | 209 | {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ |
201 | {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ | 210 | {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ |
@@ -234,3 +243,4 @@ | |||
234 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 243 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
235 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 244 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
236 | {0, 0, 0} | 245 | {0, 0, 0} |
246 | |||
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index 3f452f763f0f..6f943e3309ef 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
@@ -61,16 +61,14 @@ static struct drm_proc_list { | |||
61 | const char *name; /**< file name */ | 61 | const char *name; /**< file name */ |
62 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ | 62 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ |
63 | } drm_proc_list[] = { | 63 | } drm_proc_list[] = { |
64 | { | 64 | {"name", drm_name_info}, |
65 | "name", drm_name_info}, { | 65 | {"mem", drm_mem_info}, |
66 | "mem", drm_mem_info}, { | 66 | {"vm", drm_vm_info}, |
67 | "vm", drm_vm_info}, { | 67 | {"clients", drm_clients_info}, |
68 | "clients", drm_clients_info}, { | 68 | {"queues", drm_queues_info}, |
69 | "queues", drm_queues_info}, { | 69 | {"bufs", drm_bufs_info}, |
70 | "bufs", drm_bufs_info}, | ||
71 | #if DRM_DEBUG_CODE | 70 | #if DRM_DEBUG_CODE |
72 | { | 71 | {"vma", drm_vma_info}, |
73 | "vma", drm_vma_info}, | ||
74 | #endif | 72 | #endif |
75 | }; | 73 | }; |
76 | 74 | ||
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 60b6f8e8bf69..42d766359caa 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -93,8 +93,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | |||
93 | 93 | ||
94 | dev->driver = driver; | 94 | dev->driver = driver; |
95 | 95 | ||
96 | if (dev->driver->preinit) | 96 | if (dev->driver->load) |
97 | if ((retcode = dev->driver->preinit(dev, ent->driver_data))) | 97 | if ((retcode = dev->driver->load(dev, ent->driver_data))) |
98 | goto error_out_unreg; | 98 | goto error_out_unreg; |
99 | 99 | ||
100 | if (drm_core_has_AGP(dev)) { | 100 | if (drm_core_has_AGP(dev)) { |
@@ -124,47 +124,10 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | |||
124 | return 0; | 124 | return 0; |
125 | 125 | ||
126 | error_out_unreg: | 126 | error_out_unreg: |
127 | drm_takedown(dev); | 127 | drm_lastclose(dev); |
128 | return retcode; | 128 | return retcode; |
129 | } | 129 | } |
130 | 130 | ||
131 | /** | ||
132 | * File \c open operation. | ||
133 | * | ||
134 | * \param inode device inode. | ||
135 | * \param filp file pointer. | ||
136 | * | ||
137 | * Puts the dev->fops corresponding to the device minor number into | ||
138 | * \p filp, call the \c open method, and restore the file operations. | ||
139 | */ | ||
140 | int drm_stub_open(struct inode *inode, struct file *filp) | ||
141 | { | ||
142 | drm_device_t *dev = NULL; | ||
143 | int minor = iminor(inode); | ||
144 | int err = -ENODEV; | ||
145 | struct file_operations *old_fops; | ||
146 | |||
147 | DRM_DEBUG("\n"); | ||
148 | |||
149 | if (!((minor >= 0) && (minor < drm_cards_limit))) | ||
150 | return -ENODEV; | ||
151 | |||
152 | if (!drm_heads[minor]) | ||
153 | return -ENODEV; | ||
154 | |||
155 | if (!(dev = drm_heads[minor]->dev)) | ||
156 | return -ENODEV; | ||
157 | |||
158 | old_fops = filp->f_op; | ||
159 | filp->f_op = fops_get(&dev->driver->fops); | ||
160 | if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { | ||
161 | fops_put(filp->f_op); | ||
162 | filp->f_op = fops_get(old_fops); | ||
163 | } | ||
164 | fops_put(old_fops); | ||
165 | |||
166 | return err; | ||
167 | } | ||
168 | 131 | ||
169 | /** | 132 | /** |
170 | * Get a secondary minor number. | 133 | * Get a secondary minor number. |
@@ -200,11 +163,7 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head) | |||
200 | goto err_g1; | 163 | goto err_g1; |
201 | } | 164 | } |
202 | 165 | ||
203 | head->dev_class = drm_sysfs_device_add(drm_class, | 166 | head->dev_class = drm_sysfs_device_add(drm_class, head); |
204 | MKDEV(DRM_MAJOR, | ||
205 | minor), | ||
206 | &dev->pdev->dev, | ||
207 | "card%d", minor); | ||
208 | if (IS_ERR(head->dev_class)) { | 167 | if (IS_ERR(head->dev_class)) { |
209 | printk(KERN_ERR | 168 | printk(KERN_ERR |
210 | "DRM: Error sysfs_device_add.\n"); | 169 | "DRM: Error sysfs_device_add.\n"); |
@@ -258,11 +217,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
258 | } | 217 | } |
259 | if ((ret = drm_get_head(dev, &dev->primary))) | 218 | if ((ret = drm_get_head(dev, &dev->primary))) |
260 | goto err_g1; | 219 | goto err_g1; |
261 | 220 | ||
262 | /* postinit is a required function to display the signon banner */ | 221 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
263 | /* drivers add secondary heads here if needed */ | 222 | driver->name, driver->major, driver->minor, driver->patchlevel, |
264 | if ((ret = dev->driver->postinit(dev, ent->driver_data))) | 223 | driver->date, dev->primary.minor); |
265 | goto err_g1; | ||
266 | 224 | ||
267 | return 0; | 225 | return 0; |
268 | 226 | ||
@@ -318,10 +276,9 @@ int drm_put_head(drm_head_t * head) | |||
318 | DRM_DEBUG("release secondary minor %d\n", minor); | 276 | DRM_DEBUG("release secondary minor %d\n", minor); |
319 | 277 | ||
320 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); | 278 | drm_proc_cleanup(minor, drm_proc_root, head->dev_root); |
321 | drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); | 279 | drm_sysfs_device_remove(head->dev_class); |
322 | 280 | ||
323 | *head = (drm_head_t) { | 281 | *head = (drm_head_t) {.dev = NULL}; |
324 | .dev = NULL}; | ||
325 | 282 | ||
326 | drm_heads[minor] = NULL; | 283 | drm_heads[minor] = NULL; |
327 | 284 | ||
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 6d3449761914..68e43ddc16ae 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/kdev_t.h> | 16 | #include <linux/kdev_t.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/string.h> | ||
20 | 18 | ||
21 | #include "drm_core.h" | 19 | #include "drm_core.h" |
22 | #include "drmP.h" | 20 | #include "drmP.h" |
@@ -28,15 +26,11 @@ struct drm_sysfs_class { | |||
28 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) | 26 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) |
29 | 27 | ||
30 | struct simple_dev { | 28 | struct simple_dev { |
31 | struct list_head node; | ||
32 | dev_t dev; | 29 | dev_t dev; |
33 | struct class_device class_dev; | 30 | struct class_device class_dev; |
34 | }; | 31 | }; |
35 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) | 32 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) |
36 | 33 | ||
37 | static LIST_HEAD(simple_dev_list); | ||
38 | static DEFINE_SPINLOCK(simple_dev_list_lock); | ||
39 | |||
40 | static void release_simple_dev(struct class_device *class_dev) | 34 | static void release_simple_dev(struct class_device *class_dev) |
41 | { | 35 | { |
42 | struct simple_dev *s_dev = to_simple_dev(class_dev); | 36 | struct simple_dev *s_dev = to_simple_dev(class_dev); |
@@ -124,6 +118,18 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs) | |||
124 | class_unregister(&cs->class); | 118 | class_unregister(&cs->class); |
125 | } | 119 | } |
126 | 120 | ||
121 | static ssize_t show_dri(struct class_device *class_device, char *buf) | ||
122 | { | ||
123 | drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev; | ||
124 | if (dev->driver->dri_library_name) | ||
125 | return dev->driver->dri_library_name(dev, buf); | ||
126 | return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); | ||
127 | } | ||
128 | |||
129 | static struct class_device_attribute class_device_attrs[] = { | ||
130 | __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), | ||
131 | }; | ||
132 | |||
127 | /** | 133 | /** |
128 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 134 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver |
129 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. | 135 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. |
@@ -138,13 +144,11 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs) | |||
138 | * Note: the struct drm_sysfs_class passed to this function must have previously been | 144 | * Note: the struct drm_sysfs_class passed to this function must have previously been |
139 | * created with a call to drm_sysfs_create(). | 145 | * created with a call to drm_sysfs_create(). |
140 | */ | 146 | */ |
141 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, | 147 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, |
142 | struct device *device, | 148 | drm_head_t *head) |
143 | const char *fmt, ...) | ||
144 | { | 149 | { |
145 | va_list args; | ||
146 | struct simple_dev *s_dev = NULL; | 150 | struct simple_dev *s_dev = NULL; |
147 | int retval; | 151 | int i, retval; |
148 | 152 | ||
149 | if ((cs == NULL) || (IS_ERR(cs))) { | 153 | if ((cs == NULL) || (IS_ERR(cs))) { |
150 | retval = -ENODEV; | 154 | retval = -ENODEV; |
@@ -158,26 +162,23 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, | |||
158 | } | 162 | } |
159 | memset(s_dev, 0x00, sizeof(*s_dev)); | 163 | memset(s_dev, 0x00, sizeof(*s_dev)); |
160 | 164 | ||
161 | s_dev->dev = dev; | 165 | s_dev->dev = MKDEV(DRM_MAJOR, head->minor); |
162 | s_dev->class_dev.dev = device; | 166 | s_dev->class_dev.dev = &(head->dev->pdev)->dev; |
163 | s_dev->class_dev.class = &cs->class; | 167 | s_dev->class_dev.class = &cs->class; |
164 | 168 | ||
165 | va_start(args, fmt); | 169 | snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); |
166 | vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args); | ||
167 | va_end(args); | ||
168 | retval = class_device_register(&s_dev->class_dev); | 170 | retval = class_device_register(&s_dev->class_dev); |
169 | if (retval) | 171 | if (retval) |
170 | goto error; | 172 | goto error; |
171 | 173 | ||
172 | class_device_create_file(&s_dev->class_dev, &cs->attr); | 174 | class_device_create_file(&s_dev->class_dev, &cs->attr); |
175 | class_set_devdata(&s_dev->class_dev, head); | ||
173 | 176 | ||
174 | spin_lock(&simple_dev_list_lock); | 177 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
175 | list_add(&s_dev->node, &simple_dev_list); | 178 | class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); |
176 | spin_unlock(&simple_dev_list_lock); | ||
177 | |||
178 | return &s_dev->class_dev; | 179 | return &s_dev->class_dev; |
179 | 180 | ||
180 | error: | 181 | error: |
181 | kfree(s_dev); | 182 | kfree(s_dev); |
182 | return ERR_PTR(retval); | 183 | return ERR_PTR(retval); |
183 | } | 184 | } |
@@ -189,23 +190,12 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, | |||
189 | * This call unregisters and cleans up a class device that was created with a | 190 | * This call unregisters and cleans up a class device that was created with a |
190 | * call to drm_sysfs_device_add() | 191 | * call to drm_sysfs_device_add() |
191 | */ | 192 | */ |
192 | void drm_sysfs_device_remove(dev_t dev) | 193 | void drm_sysfs_device_remove(struct class_device *class_dev) |
193 | { | 194 | { |
194 | struct simple_dev *s_dev = NULL; | 195 | struct simple_dev *s_dev = to_simple_dev(class_dev); |
195 | int found = 0; | 196 | int i; |
196 | 197 | ||
197 | spin_lock(&simple_dev_list_lock); | 198 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
198 | list_for_each_entry(s_dev, &simple_dev_list, node) { | 199 | class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); |
199 | if (s_dev->dev == dev) { | 200 | class_device_unregister(&s_dev->class_dev); |
200 | found = 1; | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | if (found) { | ||
205 | list_del(&s_dev->node); | ||
206 | spin_unlock(&simple_dev_list_lock); | ||
207 | class_device_unregister(&s_dev->class_dev); | ||
208 | } else { | ||
209 | spin_unlock(&simple_dev_list_lock); | ||
210 | } | ||
211 | } | 201 | } |
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index dba502373da1..cc1b89086876 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c | |||
@@ -114,7 +114,6 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
114 | 114 | ||
115 | static struct file_operations i810_buffer_fops = { | 115 | static struct file_operations i810_buffer_fops = { |
116 | .open = drm_open, | 116 | .open = drm_open, |
117 | .flush = drm_flush, | ||
118 | .release = drm_release, | 117 | .release = drm_release, |
119 | .ioctl = drm_ioctl, | 118 | .ioctl = drm_ioctl, |
120 | .mmap = i810_mmap_buffers, | 119 | .mmap = i810_mmap_buffers, |
@@ -1319,12 +1318,24 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp, | |||
1319 | return 0; | 1318 | return 0; |
1320 | } | 1319 | } |
1321 | 1320 | ||
1322 | void i810_driver_pretakedown(drm_device_t * dev) | 1321 | int i810_driver_load(drm_device_t *dev, unsigned long flags) |
1322 | { | ||
1323 | /* i810 has 4 more counters */ | ||
1324 | dev->counters += 4; | ||
1325 | dev->types[6] = _DRM_STAT_IRQ; | ||
1326 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
1327 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
1328 | dev->types[9] = _DRM_STAT_DMA; | ||
1329 | |||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1333 | void i810_driver_lastclose(drm_device_t * dev) | ||
1323 | { | 1334 | { |
1324 | i810_dma_cleanup(dev); | 1335 | i810_dma_cleanup(dev); |
1325 | } | 1336 | } |
1326 | 1337 | ||
1327 | void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp) | 1338 | void i810_driver_preclose(drm_device_t * dev, DRMFILE filp) |
1328 | { | 1339 | { |
1329 | if (dev->dev_private) { | 1340 | if (dev->dev_private) { |
1330 | drm_i810_private_t *dev_priv = dev->dev_private; | 1341 | drm_i810_private_t *dev_priv = dev->dev_private; |
@@ -1334,7 +1345,7 @@ void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp) | |||
1334 | } | 1345 | } |
1335 | } | 1346 | } |
1336 | 1347 | ||
1337 | void i810_driver_release(drm_device_t * dev, struct file *filp) | 1348 | void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp) |
1338 | { | 1349 | { |
1339 | i810_reclaim_buffers(dev, filp); | 1350 | i810_reclaim_buffers(dev, filp); |
1340 | } | 1351 | } |
@@ -1346,21 +1357,21 @@ int i810_driver_dma_quiescent(drm_device_t * dev) | |||
1346 | } | 1357 | } |
1347 | 1358 | ||
1348 | drm_ioctl_desc_t i810_ioctls[] = { | 1359 | drm_ioctl_desc_t i810_ioctls[] = { |
1349 | [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1}, | 1360 | [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1350 | [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0}, | 1361 | [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, DRM_AUTH}, |
1351 | [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0}, | 1362 | [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, DRM_AUTH}, |
1352 | [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0}, | 1363 | [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, DRM_AUTH}, |
1353 | [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0}, | 1364 | [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, DRM_AUTH}, |
1354 | [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0}, | 1365 | [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, DRM_AUTH}, |
1355 | [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0}, | 1366 | [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, DRM_AUTH}, |
1356 | [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0}, | 1367 | [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, DRM_AUTH}, |
1357 | [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0}, | 1368 | [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, DRM_AUTH}, |
1358 | [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0}, | 1369 | [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, DRM_AUTH}, |
1359 | [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0}, | 1370 | [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, DRM_AUTH}, |
1360 | [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0}, | 1371 | [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, DRM_AUTH}, |
1361 | [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1}, | 1372 | [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1362 | [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0}, | 1373 | [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, DRM_AUTH}, |
1363 | [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0} | 1374 | [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, DRM_AUTH} |
1364 | }; | 1375 | }; |
1365 | 1376 | ||
1366 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1377 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c index 070cef6c2b46..dfe6ad2b6a6e 100644 --- a/drivers/char/drm/i810_drv.c +++ b/drivers/char/drm/i810_drv.c | |||
@@ -38,38 +38,6 @@ | |||
38 | 38 | ||
39 | #include "drm_pciids.h" | 39 | #include "drm_pciids.h" |
40 | 40 | ||
41 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
42 | { | ||
43 | /* i810 has 4 more counters */ | ||
44 | dev->counters += 4; | ||
45 | dev->types[6] = _DRM_STAT_IRQ; | ||
46 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
47 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
48 | dev->types[9] = _DRM_STAT_DMA; | ||
49 | |||
50 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
51 | DRIVER_NAME, | ||
52 | DRIVER_MAJOR, | ||
53 | DRIVER_MINOR, | ||
54 | DRIVER_PATCHLEVEL, | ||
55 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
56 | ); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int version(drm_version_t * version) | ||
61 | { | ||
62 | int len; | ||
63 | |||
64 | version->version_major = DRIVER_MAJOR; | ||
65 | version->version_minor = DRIVER_MINOR; | ||
66 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
67 | DRM_COPY(version->name, DRIVER_NAME); | ||
68 | DRM_COPY(version->date, DRIVER_DATE); | ||
69 | DRM_COPY(version->desc, DRIVER_DESC); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static struct pci_device_id pciidlist[] = { | 41 | static struct pci_device_id pciidlist[] = { |
74 | i810_PCI_IDS | 42 | i810_PCI_IDS |
75 | }; | 43 | }; |
@@ -79,16 +47,14 @@ static struct drm_driver driver = { | |||
79 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | | 47 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | |
80 | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, | 48 | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, |
81 | .dev_priv_size = sizeof(drm_i810_buf_priv_t), | 49 | .dev_priv_size = sizeof(drm_i810_buf_priv_t), |
82 | .pretakedown = i810_driver_pretakedown, | 50 | .load = i810_driver_load, |
83 | .prerelease = i810_driver_prerelease, | 51 | .lastclose = i810_driver_lastclose, |
52 | .preclose = i810_driver_preclose, | ||
84 | .device_is_agp = i810_driver_device_is_agp, | 53 | .device_is_agp = i810_driver_device_is_agp, |
85 | .release = i810_driver_release, | 54 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, |
86 | .dma_quiescent = i810_driver_dma_quiescent, | 55 | .dma_quiescent = i810_driver_dma_quiescent, |
87 | .reclaim_buffers = i810_reclaim_buffers, | ||
88 | .get_map_ofs = drm_core_get_map_ofs, | 56 | .get_map_ofs = drm_core_get_map_ofs, |
89 | .get_reg_ofs = drm_core_get_reg_ofs, | 57 | .get_reg_ofs = drm_core_get_reg_ofs, |
90 | .postinit = postinit, | ||
91 | .version = version, | ||
92 | .ioctls = i810_ioctls, | 58 | .ioctls = i810_ioctls, |
93 | .fops = { | 59 | .fops = { |
94 | .owner = THIS_MODULE, | 60 | .owner = THIS_MODULE, |
@@ -98,13 +64,19 @@ static struct drm_driver driver = { | |||
98 | .mmap = drm_mmap, | 64 | .mmap = drm_mmap, |
99 | .poll = drm_poll, | 65 | .poll = drm_poll, |
100 | .fasync = drm_fasync, | 66 | .fasync = drm_fasync, |
101 | } | 67 | }, |
102 | , | 68 | |
103 | .pci_driver = { | 69 | .pci_driver = { |
104 | .name = DRIVER_NAME, | 70 | .name = DRIVER_NAME, |
105 | .id_table = pciidlist, | 71 | .id_table = pciidlist, |
106 | } | 72 | }, |
107 | , | 73 | |
74 | .name = DRIVER_NAME, | ||
75 | .desc = DRIVER_DESC, | ||
76 | .date = DRIVER_DATE, | ||
77 | .major = DRIVER_MAJOR, | ||
78 | .minor = DRIVER_MINOR, | ||
79 | .patchlevel = DRIVER_PATCHLEVEL, | ||
108 | }; | 80 | }; |
109 | 81 | ||
110 | static int __init i810_init(void) | 82 | static int __init i810_init(void) |
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h index c78f36aaa2f0..a18b80d91920 100644 --- a/drivers/char/drm/i810_drv.h +++ b/drivers/char/drm/i810_drv.h | |||
@@ -116,9 +116,13 @@ typedef struct drm_i810_private { | |||
116 | extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); | 116 | extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); |
117 | 117 | ||
118 | extern int i810_driver_dma_quiescent(drm_device_t * dev); | 118 | extern int i810_driver_dma_quiescent(drm_device_t * dev); |
119 | extern void i810_driver_release(drm_device_t * dev, struct file *filp); | 119 | extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, |
120 | extern void i810_driver_pretakedown(drm_device_t * dev); | 120 | struct file *filp); |
121 | extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp); | 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); |
122 | extern void i810_driver_lastclose(drm_device_t * dev); | ||
123 | extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp); | ||
124 | extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, | ||
125 | struct file *filp); | ||
122 | extern int i810_driver_device_is_agp(drm_device_t * dev); | 126 | extern int i810_driver_device_is_agp(drm_device_t * dev); |
123 | 127 | ||
124 | extern drm_ioctl_desc_t i810_ioctls[]; | 128 | extern drm_ioctl_desc_t i810_ioctls[]; |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index dc94f1914425..4fea32aed6d2 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -116,7 +116,6 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
116 | 116 | ||
117 | static struct file_operations i830_buffer_fops = { | 117 | static struct file_operations i830_buffer_fops = { |
118 | .open = drm_open, | 118 | .open = drm_open, |
119 | .flush = drm_flush, | ||
120 | .release = drm_release, | 119 | .release = drm_release, |
121 | .ioctl = drm_ioctl, | 120 | .ioctl = drm_ioctl, |
122 | .mmap = i830_mmap_buffers, | 121 | .mmap = i830_mmap_buffers, |
@@ -1517,12 +1516,24 @@ static int i830_setparam(struct inode *inode, struct file *filp, | |||
1517 | return 0; | 1516 | return 0; |
1518 | } | 1517 | } |
1519 | 1518 | ||
1520 | void i830_driver_pretakedown(drm_device_t * dev) | 1519 | int i830_driver_load(drm_device_t *dev, unsigned long flags) |
1520 | { | ||
1521 | /* i830 has 4 more counters */ | ||
1522 | dev->counters += 4; | ||
1523 | dev->types[6] = _DRM_STAT_IRQ; | ||
1524 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
1525 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
1526 | dev->types[9] = _DRM_STAT_DMA; | ||
1527 | |||
1528 | return 0; | ||
1529 | } | ||
1530 | |||
1531 | void i830_driver_lastclose(drm_device_t * dev) | ||
1521 | { | 1532 | { |
1522 | i830_dma_cleanup(dev); | 1533 | i830_dma_cleanup(dev); |
1523 | } | 1534 | } |
1524 | 1535 | ||
1525 | void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp) | 1536 | void i830_driver_preclose(drm_device_t * dev, DRMFILE filp) |
1526 | { | 1537 | { |
1527 | if (dev->dev_private) { | 1538 | if (dev->dev_private) { |
1528 | drm_i830_private_t *dev_priv = dev->dev_private; | 1539 | drm_i830_private_t *dev_priv = dev->dev_private; |
@@ -1532,7 +1543,7 @@ void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp) | |||
1532 | } | 1543 | } |
1533 | } | 1544 | } |
1534 | 1545 | ||
1535 | void i830_driver_release(drm_device_t * dev, struct file *filp) | 1546 | void i830_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp) |
1536 | { | 1547 | { |
1537 | i830_reclaim_buffers(dev, filp); | 1548 | i830_reclaim_buffers(dev, filp); |
1538 | } | 1549 | } |
@@ -1544,20 +1555,20 @@ int i830_driver_dma_quiescent(drm_device_t * dev) | |||
1544 | } | 1555 | } |
1545 | 1556 | ||
1546 | drm_ioctl_desc_t i830_ioctls[] = { | 1557 | drm_ioctl_desc_t i830_ioctls[] = { |
1547 | [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1}, | 1558 | [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1548 | [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0}, | 1559 | [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, DRM_AUTH}, |
1549 | [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0}, | 1560 | [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, DRM_AUTH}, |
1550 | [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0}, | 1561 | [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, DRM_AUTH}, |
1551 | [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0}, | 1562 | [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, DRM_AUTH}, |
1552 | [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0}, | 1563 | [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, DRM_AUTH}, |
1553 | [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0}, | 1564 | [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, DRM_AUTH}, |
1554 | [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0}, | 1565 | [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, DRM_AUTH}, |
1555 | [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0}, | 1566 | [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, DRM_AUTH}, |
1556 | [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0}, | 1567 | [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, DRM_AUTH}, |
1557 | [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0}, | 1568 | [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, DRM_AUTH}, |
1558 | [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0}, | 1569 | [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, DRM_AUTH}, |
1559 | [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0}, | 1570 | [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, DRM_AUTH}, |
1560 | [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0} | 1571 | [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, DRM_AUTH} |
1561 | }; | 1572 | }; |
1562 | 1573 | ||
1563 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1574 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c index acd821e8fe4d..722658188f5f 100644 --- a/drivers/char/drm/i830_drv.c +++ b/drivers/char/drm/i830_drv.c | |||
@@ -40,37 +40,6 @@ | |||
40 | 40 | ||
41 | #include "drm_pciids.h" | 41 | #include "drm_pciids.h" |
42 | 42 | ||
43 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
44 | { | ||
45 | dev->counters += 4; | ||
46 | dev->types[6] = _DRM_STAT_IRQ; | ||
47 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
48 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
49 | dev->types[9] = _DRM_STAT_DMA; | ||
50 | |||
51 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
52 | DRIVER_NAME, | ||
53 | DRIVER_MAJOR, | ||
54 | DRIVER_MINOR, | ||
55 | DRIVER_PATCHLEVEL, | ||
56 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
57 | ); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int version(drm_version_t * version) | ||
62 | { | ||
63 | int len; | ||
64 | |||
65 | version->version_major = DRIVER_MAJOR; | ||
66 | version->version_minor = DRIVER_MINOR; | ||
67 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
68 | DRM_COPY(version->name, DRIVER_NAME); | ||
69 | DRM_COPY(version->date, DRIVER_DATE); | ||
70 | DRM_COPY(version->desc, DRIVER_DESC); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static struct pci_device_id pciidlist[] = { | 43 | static struct pci_device_id pciidlist[] = { |
75 | i830_PCI_IDS | 44 | i830_PCI_IDS |
76 | }; | 45 | }; |
@@ -83,12 +52,12 @@ static struct drm_driver driver = { | |||
83 | .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, | 52 | .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, |
84 | #endif | 53 | #endif |
85 | .dev_priv_size = sizeof(drm_i830_buf_priv_t), | 54 | .dev_priv_size = sizeof(drm_i830_buf_priv_t), |
86 | .pretakedown = i830_driver_pretakedown, | 55 | .load = i830_driver_load, |
87 | .prerelease = i830_driver_prerelease, | 56 | .lastclose = i830_driver_lastclose, |
57 | .preclose = i830_driver_preclose, | ||
88 | .device_is_agp = i830_driver_device_is_agp, | 58 | .device_is_agp = i830_driver_device_is_agp, |
89 | .release = i830_driver_release, | 59 | .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked, |
90 | .dma_quiescent = i830_driver_dma_quiescent, | 60 | .dma_quiescent = i830_driver_dma_quiescent, |
91 | .reclaim_buffers = i830_reclaim_buffers, | ||
92 | .get_map_ofs = drm_core_get_map_ofs, | 61 | .get_map_ofs = drm_core_get_map_ofs, |
93 | .get_reg_ofs = drm_core_get_reg_ofs, | 62 | .get_reg_ofs = drm_core_get_reg_ofs, |
94 | #if USE_IRQS | 63 | #if USE_IRQS |
@@ -97,8 +66,6 @@ static struct drm_driver driver = { | |||
97 | .irq_uninstall = i830_driver_irq_uninstall, | 66 | .irq_uninstall = i830_driver_irq_uninstall, |
98 | .irq_handler = i830_driver_irq_handler, | 67 | .irq_handler = i830_driver_irq_handler, |
99 | #endif | 68 | #endif |
100 | .postinit = postinit, | ||
101 | .version = version, | ||
102 | .ioctls = i830_ioctls, | 69 | .ioctls = i830_ioctls, |
103 | .fops = { | 70 | .fops = { |
104 | .owner = THIS_MODULE, | 71 | .owner = THIS_MODULE, |
@@ -108,13 +75,19 @@ static struct drm_driver driver = { | |||
108 | .mmap = drm_mmap, | 75 | .mmap = drm_mmap, |
109 | .poll = drm_poll, | 76 | .poll = drm_poll, |
110 | .fasync = drm_fasync, | 77 | .fasync = drm_fasync, |
111 | } | 78 | }, |
112 | , | 79 | |
113 | .pci_driver = { | 80 | .pci_driver = { |
114 | .name = DRIVER_NAME, | 81 | .name = DRIVER_NAME, |
115 | .id_table = pciidlist, | 82 | .id_table = pciidlist, |
116 | } | 83 | }, |
117 | 84 | ||
85 | .name = DRIVER_NAME, | ||
86 | .desc = DRIVER_DESC, | ||
87 | .date = DRIVER_DATE, | ||
88 | .major = DRIVER_MAJOR, | ||
89 | .minor = DRIVER_MINOR, | ||
90 | .patchlevel = DRIVER_PATCHLEVEL, | ||
118 | }; | 91 | }; |
119 | 92 | ||
120 | static int __init i830_init(void) | 93 | static int __init i830_init(void) |
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index bc4bd49fb0cc..bf9075b576bd 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h | |||
@@ -136,10 +136,12 @@ extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); | |||
136 | extern void i830_driver_irq_preinstall(drm_device_t * dev); | 136 | extern void i830_driver_irq_preinstall(drm_device_t * dev); |
137 | extern void i830_driver_irq_postinstall(drm_device_t * dev); | 137 | extern void i830_driver_irq_postinstall(drm_device_t * dev); |
138 | extern void i830_driver_irq_uninstall(drm_device_t * dev); | 138 | extern void i830_driver_irq_uninstall(drm_device_t * dev); |
139 | extern void i830_driver_pretakedown(drm_device_t * dev); | 139 | extern int i830_driver_load(struct drm_device *, unsigned long flags); |
140 | extern void i830_driver_release(drm_device_t * dev, struct file *filp); | 140 | extern void i830_driver_preclose(drm_device_t * dev, DRMFILE filp); |
141 | extern void i830_driver_lastclose(drm_device_t * dev); | ||
142 | extern void i830_driver_reclaim_buffers_locked(drm_device_t * dev, | ||
143 | struct file *filp); | ||
141 | extern int i830_driver_dma_quiescent(drm_device_t * dev); | 144 | extern int i830_driver_dma_quiescent(drm_device_t * dev); |
142 | extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp); | ||
143 | extern int i830_driver_device_is_agp(drm_device_t * dev); | 145 | extern int i830_driver_device_is_agp(drm_device_t * dev); |
144 | 146 | ||
145 | #define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) | 147 | #define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index f3aa0c370127..9140703da1ba 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- | 1 | /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- |
2 | */ | 2 | */ |
3 | /************************************************************************** | 3 | /* |
4 | * | ||
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 4 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. | 5 | * All Rights Reserved. |
7 | * | 6 | * |
@@ -25,7 +24,7 @@ | |||
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * | 26 | * |
28 | **************************************************************************/ | 27 | */ |
29 | 28 | ||
30 | #include "drmP.h" | 29 | #include "drmP.h" |
31 | #include "drm.h" | 30 | #include "drm.h" |
@@ -196,7 +195,7 @@ static int i915_initialize(drm_device_t * dev, | |||
196 | return 0; | 195 | return 0; |
197 | } | 196 | } |
198 | 197 | ||
199 | static int i915_resume(drm_device_t * dev) | 198 | static int i915_dma_resume(drm_device_t * dev) |
200 | { | 199 | { |
201 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 200 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
202 | 201 | ||
@@ -253,7 +252,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) | |||
253 | retcode = i915_dma_cleanup(dev); | 252 | retcode = i915_dma_cleanup(dev); |
254 | break; | 253 | break; |
255 | case I915_RESUME_DMA: | 254 | case I915_RESUME_DMA: |
256 | retcode = i915_resume(dev); | 255 | retcode = i915_dma_resume(dev); |
257 | break; | 256 | break; |
258 | default: | 257 | default: |
259 | retcode = -EINVAL; | 258 | retcode = -EINVAL; |
@@ -654,6 +653,9 @@ static int i915_getparam(DRM_IOCTL_ARGS) | |||
654 | case I915_PARAM_ALLOW_BATCHBUFFER: | 653 | case I915_PARAM_ALLOW_BATCHBUFFER: |
655 | value = dev_priv->allow_batchbuffer ? 1 : 0; | 654 | value = dev_priv->allow_batchbuffer ? 1 : 0; |
656 | break; | 655 | break; |
656 | case I915_PARAM_LAST_DISPATCH: | ||
657 | value = READ_BREADCRUMB(dev_priv); | ||
658 | break; | ||
657 | default: | 659 | default: |
658 | DRM_ERROR("Unkown parameter %d\n", param.param); | 660 | DRM_ERROR("Unkown parameter %d\n", param.param); |
659 | return DRM_ERR(EINVAL); | 661 | return DRM_ERR(EINVAL); |
@@ -699,7 +701,19 @@ static int i915_setparam(DRM_IOCTL_ARGS) | |||
699 | return 0; | 701 | return 0; |
700 | } | 702 | } |
701 | 703 | ||
702 | void i915_driver_pretakedown(drm_device_t * dev) | 704 | int i915_driver_load(drm_device_t *dev, unsigned long flags) |
705 | { | ||
706 | /* i915 has 4 more counters */ | ||
707 | dev->counters += 4; | ||
708 | dev->types[6] = _DRM_STAT_IRQ; | ||
709 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
710 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
711 | dev->types[9] = _DRM_STAT_DMA; | ||
712 | |||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | void i915_driver_lastclose(drm_device_t * dev) | ||
703 | { | 717 | { |
704 | if (dev->dev_private) { | 718 | if (dev->dev_private) { |
705 | drm_i915_private_t *dev_priv = dev->dev_private; | 719 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -708,7 +722,7 @@ void i915_driver_pretakedown(drm_device_t * dev) | |||
708 | i915_dma_cleanup(dev); | 722 | i915_dma_cleanup(dev); |
709 | } | 723 | } |
710 | 724 | ||
711 | void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) | 725 | void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) |
712 | { | 726 | { |
713 | if (dev->dev_private) { | 727 | if (dev->dev_private) { |
714 | drm_i915_private_t *dev_priv = dev->dev_private; | 728 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -717,18 +731,18 @@ void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) | |||
717 | } | 731 | } |
718 | 732 | ||
719 | drm_ioctl_desc_t i915_ioctls[] = { | 733 | drm_ioctl_desc_t i915_ioctls[] = { |
720 | [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1}, | 734 | [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
721 | [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0}, | 735 | [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, |
722 | [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0}, | 736 | [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, |
723 | [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0}, | 737 | [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH}, |
724 | [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0}, | 738 | [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH}, |
725 | [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0}, | 739 | [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH}, |
726 | [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0}, | 740 | [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH}, |
727 | [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1}, | 741 | [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
728 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0}, | 742 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, |
729 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0}, | 743 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, |
730 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1}, | 744 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
731 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0} | 745 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} |
732 | }; | 746 | }; |
733 | 747 | ||
734 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 748 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 23e027d29080..77412ddac007 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
@@ -1,5 +1,4 @@ | |||
1 | /************************************************************************** | 1 | /* |
2 | * | ||
3 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 2 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
4 | * All Rights Reserved. | 3 | * All Rights Reserved. |
5 | * | 4 | * |
@@ -23,7 +22,7 @@ | |||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | * | 24 | * |
26 | **************************************************************************/ | 25 | */ |
27 | 26 | ||
28 | #ifndef _I915_DRM_H_ | 27 | #ifndef _I915_DRM_H_ |
29 | #define _I915_DRM_H_ | 28 | #define _I915_DRM_H_ |
@@ -152,6 +151,7 @@ typedef struct drm_i915_irq_wait { | |||
152 | */ | 151 | */ |
153 | #define I915_PARAM_IRQ_ACTIVE 1 | 152 | #define I915_PARAM_IRQ_ACTIVE 1 |
154 | #define I915_PARAM_ALLOW_BATCHBUFFER 2 | 153 | #define I915_PARAM_ALLOW_BATCHBUFFER 2 |
154 | #define I915_PARAM_LAST_DISPATCH 3 | ||
155 | 155 | ||
156 | typedef struct drm_i915_getparam { | 156 | typedef struct drm_i915_getparam { |
157 | int param; | 157 | int param; |
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 0508240f4e3b..8e2e6095c4b3 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- | 1 | /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- |
2 | */ | 2 | */ |
3 | /************************************************************************** | 3 | /* |
4 | * | 4 | * |
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. | 6 | * All Rights Reserved. |
@@ -25,7 +25,7 @@ | |||
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * | 27 | * |
28 | **************************************************************************/ | 28 | */ |
29 | 29 | ||
30 | #include "drmP.h" | 30 | #include "drmP.h" |
31 | #include "drm.h" | 31 | #include "drm.h" |
@@ -34,48 +34,22 @@ | |||
34 | 34 | ||
35 | #include "drm_pciids.h" | 35 | #include "drm_pciids.h" |
36 | 36 | ||
37 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
38 | { | ||
39 | dev->counters += 4; | ||
40 | dev->types[6] = _DRM_STAT_IRQ; | ||
41 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
42 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
43 | dev->types[9] = _DRM_STAT_DMA; | ||
44 | |||
45 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
46 | DRIVER_NAME, | ||
47 | DRIVER_MAJOR, | ||
48 | DRIVER_MINOR, | ||
49 | DRIVER_PATCHLEVEL, | ||
50 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
51 | ); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int version(drm_version_t * version) | ||
56 | { | ||
57 | int len; | ||
58 | |||
59 | version->version_major = DRIVER_MAJOR; | ||
60 | version->version_minor = DRIVER_MINOR; | ||
61 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
62 | DRM_COPY(version->name, DRIVER_NAME); | ||
63 | DRM_COPY(version->date, DRIVER_DATE); | ||
64 | DRM_COPY(version->desc, DRIVER_DESC); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static struct pci_device_id pciidlist[] = { | 37 | static struct pci_device_id pciidlist[] = { |
69 | i915_PCI_IDS | 38 | i915_PCI_IDS |
70 | }; | 39 | }; |
71 | 40 | ||
72 | static struct drm_driver driver = { | 41 | static struct drm_driver driver = { |
42 | /* don't use mtrr's here, the Xserver or user space app should | ||
43 | * deal with them for intel hardware. | ||
44 | */ | ||
73 | .driver_features = | 45 | .driver_features = |
74 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | | 46 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ |
75 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 47 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, |
76 | .pretakedown = i915_driver_pretakedown, | 48 | .load = i915_driver_load, |
77 | .prerelease = i915_driver_prerelease, | 49 | .lastclose = i915_driver_lastclose, |
50 | .preclose = i915_driver_preclose, | ||
78 | .device_is_agp = i915_driver_device_is_agp, | 51 | .device_is_agp = i915_driver_device_is_agp, |
52 | .vblank_wait = i915_driver_vblank_wait, | ||
79 | .irq_preinstall = i915_driver_irq_preinstall, | 53 | .irq_preinstall = i915_driver_irq_preinstall, |
80 | .irq_postinstall = i915_driver_irq_postinstall, | 54 | .irq_postinstall = i915_driver_irq_postinstall, |
81 | .irq_uninstall = i915_driver_irq_uninstall, | 55 | .irq_uninstall = i915_driver_irq_uninstall, |
@@ -83,8 +57,6 @@ static struct drm_driver driver = { | |||
83 | .reclaim_buffers = drm_core_reclaim_buffers, | 57 | .reclaim_buffers = drm_core_reclaim_buffers, |
84 | .get_map_ofs = drm_core_get_map_ofs, | 58 | .get_map_ofs = drm_core_get_map_ofs, |
85 | .get_reg_ofs = drm_core_get_reg_ofs, | 59 | .get_reg_ofs = drm_core_get_reg_ofs, |
86 | .postinit = postinit, | ||
87 | .version = version, | ||
88 | .ioctls = i915_ioctls, | 60 | .ioctls = i915_ioctls, |
89 | .fops = { | 61 | .fops = { |
90 | .owner = THIS_MODULE, | 62 | .owner = THIS_MODULE, |
@@ -97,11 +69,19 @@ static struct drm_driver driver = { | |||
97 | #ifdef CONFIG_COMPAT | 69 | #ifdef CONFIG_COMPAT |
98 | .compat_ioctl = i915_compat_ioctl, | 70 | .compat_ioctl = i915_compat_ioctl, |
99 | #endif | 71 | #endif |
100 | }, | 72 | }, |
73 | |||
101 | .pci_driver = { | 74 | .pci_driver = { |
102 | .name = DRIVER_NAME, | 75 | .name = DRIVER_NAME, |
103 | .id_table = pciidlist, | 76 | .id_table = pciidlist, |
104 | } | 77 | }, |
78 | |||
79 | .name = DRIVER_NAME, | ||
80 | .desc = DRIVER_DESC, | ||
81 | .date = DRIVER_DATE, | ||
82 | .major = DRIVER_MAJOR, | ||
83 | .minor = DRIVER_MINOR, | ||
84 | .patchlevel = DRIVER_PATCHLEVEL, | ||
105 | }; | 85 | }; |
106 | 86 | ||
107 | static int __init i915_init(void) | 87 | static int __init i915_init(void) |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 17e457c73dc7..c6c71b45f101 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- | 1 | /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- |
2 | */ | 2 | */ |
3 | /************************************************************************** | 3 | /* |
4 | * | 4 | * |
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. | 6 | * All Rights Reserved. |
@@ -25,7 +25,7 @@ | |||
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * | 27 | * |
28 | **************************************************************************/ | 28 | */ |
29 | 29 | ||
30 | #ifndef _I915_DRV_H_ | 30 | #ifndef _I915_DRV_H_ |
31 | #define _I915_DRV_H_ | 31 | #define _I915_DRV_H_ |
@@ -37,21 +37,18 @@ | |||
37 | 37 | ||
38 | #define DRIVER_NAME "i915" | 38 | #define DRIVER_NAME "i915" |
39 | #define DRIVER_DESC "Intel Graphics" | 39 | #define DRIVER_DESC "Intel Graphics" |
40 | #define DRIVER_DATE "20040405" | 40 | #define DRIVER_DATE "20051209" |
41 | 41 | ||
42 | /* Interface history: | 42 | /* Interface history: |
43 | * | 43 | * |
44 | * 1.1: Original. | 44 | * 1.1: Original. |
45 | * 1.2: Add Power Management | ||
46 | * 1.3: Add vblank support | ||
45 | */ | 47 | */ |
46 | #define DRIVER_MAJOR 1 | 48 | #define DRIVER_MAJOR 1 |
47 | #define DRIVER_MINOR 1 | 49 | #define DRIVER_MINOR 3 |
48 | #define DRIVER_PATCHLEVEL 0 | 50 | #define DRIVER_PATCHLEVEL 0 |
49 | 51 | ||
50 | /* We use our own dma mechanisms, not the drm template code. However, | ||
51 | * the shared IRQ code is useful to us: | ||
52 | */ | ||
53 | #define __HAVE_PM 1 | ||
54 | |||
55 | typedef struct _drm_i915_ring_buffer { | 52 | typedef struct _drm_i915_ring_buffer { |
56 | int tail_mask; | 53 | int tail_mask; |
57 | unsigned long Start; | 54 | unsigned long Start; |
@@ -97,6 +94,7 @@ typedef struct drm_i915_private { | |||
97 | int tex_lru_log_granularity; | 94 | int tex_lru_log_granularity; |
98 | int allow_batchbuffer; | 95 | int allow_batchbuffer; |
99 | struct mem_block *agp_heap; | 96 | struct mem_block *agp_heap; |
97 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | ||
100 | } drm_i915_private_t; | 98 | } drm_i915_private_t; |
101 | 99 | ||
102 | extern drm_ioctl_desc_t i915_ioctls[]; | 100 | extern drm_ioctl_desc_t i915_ioctls[]; |
@@ -104,14 +102,18 @@ extern int i915_max_ioctl; | |||
104 | 102 | ||
105 | /* i915_dma.c */ | 103 | /* i915_dma.c */ |
106 | extern void i915_kernel_lost_context(drm_device_t * dev); | 104 | extern void i915_kernel_lost_context(drm_device_t * dev); |
107 | extern void i915_driver_pretakedown(drm_device_t * dev); | 105 | extern int i915_driver_load(struct drm_device *, unsigned long flags); |
108 | extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp); | 106 | extern void i915_driver_lastclose(drm_device_t * dev); |
107 | extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); | ||
109 | extern int i915_driver_device_is_agp(drm_device_t * dev); | 108 | extern int i915_driver_device_is_agp(drm_device_t * dev); |
109 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | ||
110 | unsigned long arg); | ||
110 | 111 | ||
111 | /* i915_irq.c */ | 112 | /* i915_irq.c */ |
112 | extern int i915_irq_emit(DRM_IOCTL_ARGS); | 113 | extern int i915_irq_emit(DRM_IOCTL_ARGS); |
113 | extern int i915_irq_wait(DRM_IOCTL_ARGS); | 114 | extern int i915_irq_wait(DRM_IOCTL_ARGS); |
114 | 115 | ||
116 | extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); | ||
115 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 117 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
116 | extern void i915_driver_irq_preinstall(drm_device_t * dev); | 118 | extern void i915_driver_irq_preinstall(drm_device_t * dev); |
117 | extern void i915_driver_irq_postinstall(drm_device_t * dev); | 119 | extern void i915_driver_irq_postinstall(drm_device_t * dev); |
@@ -125,13 +127,10 @@ extern void i915_mem_takedown(struct mem_block **heap); | |||
125 | extern void i915_mem_release(drm_device_t * dev, | 127 | extern void i915_mem_release(drm_device_t * dev, |
126 | DRMFILE filp, struct mem_block *heap); | 128 | DRMFILE filp, struct mem_block *heap); |
127 | 129 | ||
128 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 130 | #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) |
129 | unsigned long arg); | 131 | #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) |
130 | 132 | #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) | |
131 | #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) | 133 | #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) |
132 | #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) | ||
133 | #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) | ||
134 | #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) | ||
135 | 134 | ||
136 | #define I915_VERBOSE 0 | 135 | #define I915_VERBOSE 0 |
137 | 136 | ||
@@ -195,6 +194,13 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); | |||
195 | #define PPCR 0x61204 | 194 | #define PPCR 0x61204 |
196 | #define PPCR_ON (1<<0) | 195 | #define PPCR_ON (1<<0) |
197 | 196 | ||
197 | #define DVOB 0x61140 | ||
198 | #define DVOB_ON (1<<31) | ||
199 | #define DVOC 0x61160 | ||
200 | #define DVOC_ON (1<<31) | ||
201 | #define LVDS 0x61180 | ||
202 | #define LVDS_ON (1<<31) | ||
203 | |||
198 | #define ADPA 0x61100 | 204 | #define ADPA 0x61100 |
199 | #define ADPA_DPMS_MASK (~(3<<10)) | 205 | #define ADPA_DPMS_MASK (~(3<<10)) |
200 | #define ADPA_DPMS_ON (0<<10) | 206 | #define ADPA_DPMS_ON (0<<10) |
@@ -258,4 +264,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); | |||
258 | 264 | ||
259 | #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) | 265 | #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) |
260 | 266 | ||
267 | #define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5]) | ||
268 | |||
261 | #endif | 269 | #endif |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 4fa448ee846b..a1381c61aa63 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- | 1 | /* i915_irq.c -- IRQ support for the I915 -*- linux-c -*- |
2 | */ | 2 | */ |
3 | /************************************************************************** | 3 | /* |
4 | * | ||
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 4 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. | 5 | * All Rights Reserved. |
7 | * | 6 | * |
@@ -25,16 +24,18 @@ | |||
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * | 26 | * |
28 | **************************************************************************/ | 27 | */ |
29 | 28 | ||
30 | #include "drmP.h" | 29 | #include "drmP.h" |
31 | #include "drm.h" | 30 | #include "drm.h" |
32 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
33 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
34 | 33 | ||
35 | #define USER_INT_FLAG 0x2 | 34 | #define USER_INT_FLAG (1<<1) |
35 | #define VSYNC_PIPEB_FLAG (1<<5) | ||
36 | #define VSYNC_PIPEA_FLAG (1<<7) | ||
37 | |||
36 | #define MAX_NOPID ((u32)~0) | 38 | #define MAX_NOPID ((u32)~0) |
37 | #define READ_BREADCRUMB(dev_priv) (((u32*)(dev_priv->hw_status_page))[5]) | ||
38 | 39 | ||
39 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 40 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
40 | { | 41 | { |
@@ -43,7 +44,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
43 | u16 temp; | 44 | u16 temp; |
44 | 45 | ||
45 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 46 | temp = I915_READ16(I915REG_INT_IDENTITY_R); |
46 | temp &= USER_INT_FLAG; | 47 | temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG); |
47 | 48 | ||
48 | DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); | 49 | DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); |
49 | 50 | ||
@@ -51,7 +52,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
51 | return IRQ_NONE; | 52 | return IRQ_NONE; |
52 | 53 | ||
53 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 54 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); |
54 | DRM_WAKEUP(&dev_priv->irq_queue); | 55 | |
56 | if (temp & USER_INT_FLAG) | ||
57 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
58 | |||
59 | if (temp & VSYNC_PIPEA_FLAG) { | ||
60 | atomic_inc(&dev->vbl_received); | ||
61 | DRM_WAKEUP(&dev->vbl_queue); | ||
62 | drm_vbl_send_signals(dev); | ||
63 | } | ||
55 | 64 | ||
56 | return IRQ_HANDLED; | 65 | return IRQ_HANDLED; |
57 | } | 66 | } |
@@ -102,6 +111,27 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) | |||
102 | return ret; | 111 | return ret; |
103 | } | 112 | } |
104 | 113 | ||
114 | int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) | ||
115 | { | ||
116 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
117 | unsigned int cur_vblank; | ||
118 | int ret = 0; | ||
119 | |||
120 | if (!dev_priv) { | ||
121 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
122 | return DRM_ERR(EINVAL); | ||
123 | } | ||
124 | |||
125 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
126 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
127 | - *sequence) <= (1<<23))); | ||
128 | |||
129 | *sequence = cur_vblank; | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | |||
105 | /* Needs the lock as it touches the ring. | 135 | /* Needs the lock as it touches the ring. |
106 | */ | 136 | */ |
107 | int i915_irq_emit(DRM_IOCTL_ARGS) | 137 | int i915_irq_emit(DRM_IOCTL_ARGS) |
@@ -165,7 +195,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev) | |||
165 | { | 195 | { |
166 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 196 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
167 | 197 | ||
168 | I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG); | 198 | I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG); |
169 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 199 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
170 | } | 200 | } |
171 | 201 | ||
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c index 13176d136a99..ba87ff17ff64 100644 --- a/drivers/char/drm/i915_mem.c +++ b/drivers/char/drm/i915_mem.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- | 1 | /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- |
2 | */ | 2 | */ |
3 | /************************************************************************** | 3 | /* |
4 | * | ||
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | 4 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. | 5 | * All Rights Reserved. |
7 | * | 6 | * |
@@ -25,7 +24,7 @@ | |||
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | 24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * | 26 | * |
28 | **************************************************************************/ | 27 | */ |
29 | 28 | ||
30 | #include "drmP.h" | 29 | #include "drmP.h" |
31 | #include "drm.h" | 30 | #include "drm.h" |
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c index 70dc7f64b7b9..c2a4bac14521 100644 --- a/drivers/char/drm/mga_dma.c +++ b/drivers/char/drm/mga_dma.c | |||
@@ -44,7 +44,9 @@ | |||
44 | #define MGA_DEFAULT_USEC_TIMEOUT 10000 | 44 | #define MGA_DEFAULT_USEC_TIMEOUT 10000 |
45 | #define MGA_FREELIST_DEBUG 0 | 45 | #define MGA_FREELIST_DEBUG 0 |
46 | 46 | ||
47 | static int mga_do_cleanup_dma(drm_device_t * dev); | 47 | #define MINIMAL_CLEANUP 0 |
48 | #define FULL_CLEANUP 1 | ||
49 | static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup); | ||
48 | 50 | ||
49 | /* ================================================================ | 51 | /* ================================================================ |
50 | * Engine control | 52 | * Engine control |
@@ -391,7 +393,7 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf) | |||
391 | * DMA initialization, cleanup | 393 | * DMA initialization, cleanup |
392 | */ | 394 | */ |
393 | 395 | ||
394 | int mga_driver_preinit(drm_device_t * dev, unsigned long flags) | 396 | int mga_driver_load(drm_device_t * dev, unsigned long flags) |
395 | { | 397 | { |
396 | drm_mga_private_t *dev_priv; | 398 | drm_mga_private_t *dev_priv; |
397 | 399 | ||
@@ -405,6 +407,14 @@ int mga_driver_preinit(drm_device_t * dev, unsigned long flags) | |||
405 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; | 407 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; |
406 | dev_priv->chipset = flags; | 408 | dev_priv->chipset = flags; |
407 | 409 | ||
410 | dev_priv->mmio_base = drm_get_resource_start(dev, 1); | ||
411 | dev_priv->mmio_size = drm_get_resource_len(dev, 1); | ||
412 | |||
413 | dev->counters += 3; | ||
414 | dev->types[6] = _DRM_STAT_IRQ; | ||
415 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
416 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
417 | |||
408 | return 0; | 418 | return 0; |
409 | } | 419 | } |
410 | 420 | ||
@@ -438,17 +448,19 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
438 | drm_buf_desc_t req; | 448 | drm_buf_desc_t req; |
439 | drm_agp_mode_t mode; | 449 | drm_agp_mode_t mode; |
440 | drm_agp_info_t info; | 450 | drm_agp_info_t info; |
451 | drm_agp_buffer_t agp_req; | ||
452 | drm_agp_binding_t bind_req; | ||
441 | 453 | ||
442 | /* Acquire AGP. */ | 454 | /* Acquire AGP. */ |
443 | err = drm_agp_acquire(dev); | 455 | err = drm_agp_acquire(dev); |
444 | if (err) { | 456 | if (err) { |
445 | DRM_ERROR("Unable to acquire AGP\n"); | 457 | DRM_ERROR("Unable to acquire AGP: %d\n", err); |
446 | return err; | 458 | return err; |
447 | } | 459 | } |
448 | 460 | ||
449 | err = drm_agp_info(dev, &info); | 461 | err = drm_agp_info(dev, &info); |
450 | if (err) { | 462 | if (err) { |
451 | DRM_ERROR("Unable to get AGP info\n"); | 463 | DRM_ERROR("Unable to get AGP info: %d\n", err); |
452 | return err; | 464 | return err; |
453 | } | 465 | } |
454 | 466 | ||
@@ -472,18 +484,24 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
472 | } | 484 | } |
473 | 485 | ||
474 | /* Allocate and bind AGP memory. */ | 486 | /* Allocate and bind AGP memory. */ |
475 | dev_priv->agp_pages = agp_size / PAGE_SIZE; | 487 | agp_req.size = agp_size; |
476 | dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0); | 488 | agp_req.type = 0; |
477 | if (dev_priv->agp_mem == NULL) { | 489 | err = drm_agp_alloc(dev, &agp_req); |
478 | dev_priv->agp_pages = 0; | 490 | if (err) { |
491 | dev_priv->agp_size = 0; | ||
479 | DRM_ERROR("Unable to allocate %uMB AGP memory\n", | 492 | DRM_ERROR("Unable to allocate %uMB AGP memory\n", |
480 | dma_bs->agp_size); | 493 | dma_bs->agp_size); |
481 | return DRM_ERR(ENOMEM); | 494 | return err; |
482 | } | 495 | } |
496 | |||
497 | dev_priv->agp_size = agp_size; | ||
498 | dev_priv->agp_handle = agp_req.handle; | ||
483 | 499 | ||
484 | err = drm_bind_agp(dev_priv->agp_mem, 0); | 500 | bind_req.handle = agp_req.handle; |
501 | bind_req.offset = 0; | ||
502 | err = drm_agp_bind(dev, &bind_req); | ||
485 | if (err) { | 503 | if (err) { |
486 | DRM_ERROR("Unable to bind AGP memory\n"); | 504 | DRM_ERROR("Unable to bind AGP memory: %d\n", err); |
487 | return err; | 505 | return err; |
488 | } | 506 | } |
489 | 507 | ||
@@ -497,7 +515,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
497 | err = drm_addmap(dev, offset, warp_size, | 515 | err = drm_addmap(dev, offset, warp_size, |
498 | _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); | 516 | _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); |
499 | if (err) { | 517 | if (err) { |
500 | DRM_ERROR("Unable to map WARP microcode\n"); | 518 | DRM_ERROR("Unable to map WARP microcode: %d\n", err); |
501 | return err; | 519 | return err; |
502 | } | 520 | } |
503 | 521 | ||
@@ -505,7 +523,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
505 | err = drm_addmap(dev, offset, dma_bs->primary_size, | 523 | err = drm_addmap(dev, offset, dma_bs->primary_size, |
506 | _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); | 524 | _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); |
507 | if (err) { | 525 | if (err) { |
508 | DRM_ERROR("Unable to map primary DMA region\n"); | 526 | DRM_ERROR("Unable to map primary DMA region: %d\n", err); |
509 | return err; | 527 | return err; |
510 | } | 528 | } |
511 | 529 | ||
@@ -513,7 +531,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
513 | err = drm_addmap(dev, offset, secondary_size, | 531 | err = drm_addmap(dev, offset, secondary_size, |
514 | _DRM_AGP, 0, &dev->agp_buffer_map); | 532 | _DRM_AGP, 0, &dev->agp_buffer_map); |
515 | if (err) { | 533 | if (err) { |
516 | DRM_ERROR("Unable to map secondary DMA region\n"); | 534 | DRM_ERROR("Unable to map secondary DMA region: %d\n", err); |
517 | return err; | 535 | return err; |
518 | } | 536 | } |
519 | 537 | ||
@@ -525,15 +543,29 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, | |||
525 | 543 | ||
526 | err = drm_addbufs_agp(dev, &req); | 544 | err = drm_addbufs_agp(dev, &req); |
527 | if (err) { | 545 | if (err) { |
528 | DRM_ERROR("Unable to add secondary DMA buffers\n"); | 546 | DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); |
529 | return err; | 547 | return err; |
530 | } | 548 | } |
531 | 549 | ||
550 | { | ||
551 | drm_map_list_t *_entry; | ||
552 | unsigned long agp_token = 0; | ||
553 | |||
554 | list_for_each_entry(_entry, &dev->maplist->head, head) { | ||
555 | if (_entry->map == dev->agp_buffer_map) | ||
556 | agp_token = _entry->user_token; | ||
557 | } | ||
558 | if (!agp_token) | ||
559 | return -EFAULT; | ||
560 | |||
561 | dev->agp_buffer_token = agp_token; | ||
562 | } | ||
563 | |||
532 | offset += secondary_size; | 564 | offset += secondary_size; |
533 | err = drm_addmap(dev, offset, agp_size - offset, | 565 | err = drm_addmap(dev, offset, agp_size - offset, |
534 | _DRM_AGP, 0, &dev_priv->agp_textures); | 566 | _DRM_AGP, 0, &dev_priv->agp_textures); |
535 | if (err) { | 567 | if (err) { |
536 | DRM_ERROR("Unable to map AGP texture region\n"); | 568 | DRM_ERROR("Unable to map AGP texture region %d\n", err); |
537 | return err; | 569 | return err; |
538 | } | 570 | } |
539 | 571 | ||
@@ -603,7 +635,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, | |||
603 | err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, | 635 | err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, |
604 | _DRM_READ_ONLY, &dev_priv->warp); | 636 | _DRM_READ_ONLY, &dev_priv->warp); |
605 | if (err != 0) { | 637 | if (err != 0) { |
606 | DRM_ERROR("Unable to create mapping for WARP microcode\n"); | 638 | DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", |
639 | err); | ||
607 | return err; | 640 | return err; |
608 | } | 641 | } |
609 | 642 | ||
@@ -622,7 +655,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, | |||
622 | } | 655 | } |
623 | 656 | ||
624 | if (err != 0) { | 657 | if (err != 0) { |
625 | DRM_ERROR("Unable to allocate primary DMA region\n"); | 658 | DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); |
626 | return DRM_ERR(ENOMEM); | 659 | return DRM_ERR(ENOMEM); |
627 | } | 660 | } |
628 | 661 | ||
@@ -646,7 +679,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, | |||
646 | } | 679 | } |
647 | 680 | ||
648 | if (bin_count == 0) { | 681 | if (bin_count == 0) { |
649 | DRM_ERROR("Unable to add secondary DMA buffers\n"); | 682 | DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); |
650 | return err; | 683 | return err; |
651 | } | 684 | } |
652 | 685 | ||
@@ -682,7 +715,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, | |||
682 | err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, | 715 | err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, |
683 | _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); | 716 | _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); |
684 | if (err) { | 717 | if (err) { |
685 | DRM_ERROR("Unable to map MMIO region\n"); | 718 | DRM_ERROR("Unable to map MMIO region: %d\n", err); |
686 | return err; | 719 | return err; |
687 | } | 720 | } |
688 | 721 | ||
@@ -690,7 +723,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, | |||
690 | _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, | 723 | _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, |
691 | &dev_priv->status); | 724 | &dev_priv->status); |
692 | if (err) { | 725 | if (err) { |
693 | DRM_ERROR("Unable to map status region\n"); | 726 | DRM_ERROR("Unable to map status region: %d\n", err); |
694 | return err; | 727 | return err; |
695 | } | 728 | } |
696 | 729 | ||
@@ -708,7 +741,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, | |||
708 | */ | 741 | */ |
709 | 742 | ||
710 | if (err) { | 743 | if (err) { |
711 | mga_do_cleanup_dma(dev); | 744 | mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); |
712 | } | 745 | } |
713 | 746 | ||
714 | /* Not only do we want to try and initialized PCI cards for PCI DMA, | 747 | /* Not only do we want to try and initialized PCI cards for PCI DMA, |
@@ -731,35 +764,32 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS) | |||
731 | DRM_DEVICE; | 764 | DRM_DEVICE; |
732 | drm_mga_dma_bootstrap_t bootstrap; | 765 | drm_mga_dma_bootstrap_t bootstrap; |
733 | int err; | 766 | int err; |
767 | static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; | ||
768 | const drm_mga_private_t *const dev_priv = | ||
769 | (drm_mga_private_t *) dev->dev_private; | ||
734 | 770 | ||
735 | DRM_COPY_FROM_USER_IOCTL(bootstrap, | 771 | DRM_COPY_FROM_USER_IOCTL(bootstrap, |
736 | (drm_mga_dma_bootstrap_t __user *) data, | 772 | (drm_mga_dma_bootstrap_t __user *) data, |
737 | sizeof(bootstrap)); | 773 | sizeof(bootstrap)); |
738 | 774 | ||
739 | err = mga_do_dma_bootstrap(dev, &bootstrap); | 775 | err = mga_do_dma_bootstrap(dev, &bootstrap); |
740 | if (!err) { | 776 | if (err) { |
741 | static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; | 777 | mga_do_cleanup_dma(dev, FULL_CLEANUP); |
742 | const drm_mga_private_t *const dev_priv = | 778 | return err; |
743 | (drm_mga_private_t *) dev->dev_private; | 779 | } |
744 | |||
745 | if (dev_priv->agp_textures != NULL) { | ||
746 | bootstrap.texture_handle = | ||
747 | dev_priv->agp_textures->offset; | ||
748 | bootstrap.texture_size = dev_priv->agp_textures->size; | ||
749 | } else { | ||
750 | bootstrap.texture_handle = 0; | ||
751 | bootstrap.texture_size = 0; | ||
752 | } | ||
753 | 780 | ||
754 | bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; | 781 | if (dev_priv->agp_textures != NULL) { |
755 | if (DRM_COPY_TO_USER((void __user *)data, &bootstrap, | 782 | bootstrap.texture_handle = dev_priv->agp_textures->offset; |
756 | sizeof(bootstrap))) { | 783 | bootstrap.texture_size = dev_priv->agp_textures->size; |
757 | err = DRM_ERR(EFAULT); | ||
758 | } | ||
759 | } else { | 784 | } else { |
760 | mga_do_cleanup_dma(dev); | 785 | bootstrap.texture_handle = 0; |
786 | bootstrap.texture_size = 0; | ||
761 | } | 787 | } |
762 | 788 | ||
789 | bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; | ||
790 | DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data, | ||
791 | bootstrap, sizeof(bootstrap)); | ||
792 | |||
763 | return err; | 793 | return err; |
764 | } | 794 | } |
765 | 795 | ||
@@ -853,13 +883,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) | |||
853 | 883 | ||
854 | ret = mga_warp_install_microcode(dev_priv); | 884 | ret = mga_warp_install_microcode(dev_priv); |
855 | if (ret < 0) { | 885 | if (ret < 0) { |
856 | DRM_ERROR("failed to install WARP ucode!\n"); | 886 | DRM_ERROR("failed to install WARP ucode!: %d\n", ret); |
857 | return ret; | 887 | return ret; |
858 | } | 888 | } |
859 | 889 | ||
860 | ret = mga_warp_init(dev_priv); | 890 | ret = mga_warp_init(dev_priv); |
861 | if (ret < 0) { | 891 | if (ret < 0) { |
862 | DRM_ERROR("failed to init WARP engine!\n"); | 892 | DRM_ERROR("failed to init WARP engine!: %d\n", ret); |
863 | return ret; | 893 | return ret; |
864 | } | 894 | } |
865 | 895 | ||
@@ -904,7 +934,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) | |||
904 | return 0; | 934 | return 0; |
905 | } | 935 | } |
906 | 936 | ||
907 | static int mga_do_cleanup_dma(drm_device_t * dev) | 937 | static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup) |
908 | { | 938 | { |
909 | int err = 0; | 939 | int err = 0; |
910 | DRM_DEBUG("\n"); | 940 | DRM_DEBUG("\n"); |
@@ -932,31 +962,39 @@ static int mga_do_cleanup_dma(drm_device_t * dev) | |||
932 | 962 | ||
933 | if (dev_priv->used_new_dma_init) { | 963 | if (dev_priv->used_new_dma_init) { |
934 | #if __OS_HAS_AGP | 964 | #if __OS_HAS_AGP |
935 | if (dev_priv->agp_mem != NULL) { | 965 | if (dev_priv->agp_handle != 0) { |
936 | dev_priv->agp_textures = NULL; | 966 | drm_agp_binding_t unbind_req; |
937 | drm_unbind_agp(dev_priv->agp_mem); | 967 | drm_agp_buffer_t free_req; |
968 | |||
969 | unbind_req.handle = dev_priv->agp_handle; | ||
970 | drm_agp_unbind(dev, &unbind_req); | ||
938 | 971 | ||
939 | drm_free_agp(dev_priv->agp_mem, | 972 | free_req.handle = dev_priv->agp_handle; |
940 | dev_priv->agp_pages); | 973 | drm_agp_free(dev, &free_req); |
941 | dev_priv->agp_pages = 0; | 974 | |
942 | dev_priv->agp_mem = NULL; | 975 | dev_priv->agp_textures = NULL; |
976 | dev_priv->agp_size = 0; | ||
977 | dev_priv->agp_handle = 0; | ||
943 | } | 978 | } |
944 | 979 | ||
945 | if ((dev->agp != NULL) && dev->agp->acquired) { | 980 | if ((dev->agp != NULL) && dev->agp->acquired) { |
946 | err = drm_agp_release(dev); | 981 | err = drm_agp_release(dev); |
947 | } | 982 | } |
948 | #endif | 983 | #endif |
949 | dev_priv->used_new_dma_init = 0; | ||
950 | } | 984 | } |
951 | 985 | ||
952 | dev_priv->warp = NULL; | 986 | dev_priv->warp = NULL; |
953 | dev_priv->primary = NULL; | 987 | dev_priv->primary = NULL; |
954 | dev_priv->mmio = NULL; | ||
955 | dev_priv->status = NULL; | ||
956 | dev_priv->sarea = NULL; | 988 | dev_priv->sarea = NULL; |
957 | dev_priv->sarea_priv = NULL; | 989 | dev_priv->sarea_priv = NULL; |
958 | dev->agp_buffer_map = NULL; | 990 | dev->agp_buffer_map = NULL; |
959 | 991 | ||
992 | if (full_cleanup) { | ||
993 | dev_priv->mmio = NULL; | ||
994 | dev_priv->status = NULL; | ||
995 | dev_priv->used_new_dma_init = 0; | ||
996 | } | ||
997 | |||
960 | memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); | 998 | memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); |
961 | dev_priv->warp_pipe = 0; | 999 | dev_priv->warp_pipe = 0; |
962 | memset(dev_priv->warp_pipe_phys, 0, | 1000 | memset(dev_priv->warp_pipe_phys, 0, |
@@ -967,7 +1005,7 @@ static int mga_do_cleanup_dma(drm_device_t * dev) | |||
967 | } | 1005 | } |
968 | } | 1006 | } |
969 | 1007 | ||
970 | return err; | 1008 | return 0; |
971 | } | 1009 | } |
972 | 1010 | ||
973 | int mga_dma_init(DRM_IOCTL_ARGS) | 1011 | int mga_dma_init(DRM_IOCTL_ARGS) |
@@ -985,11 +1023,11 @@ int mga_dma_init(DRM_IOCTL_ARGS) | |||
985 | case MGA_INIT_DMA: | 1023 | case MGA_INIT_DMA: |
986 | err = mga_do_init_dma(dev, &init); | 1024 | err = mga_do_init_dma(dev, &init); |
987 | if (err) { | 1025 | if (err) { |
988 | (void)mga_do_cleanup_dma(dev); | 1026 | (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); |
989 | } | 1027 | } |
990 | return err; | 1028 | return err; |
991 | case MGA_CLEANUP_DMA: | 1029 | case MGA_CLEANUP_DMA: |
992 | return mga_do_cleanup_dma(dev); | 1030 | return mga_do_cleanup_dma(dev, FULL_CLEANUP); |
993 | } | 1031 | } |
994 | 1032 | ||
995 | return DRM_ERR(EINVAL); | 1033 | return DRM_ERR(EINVAL); |
@@ -1118,7 +1156,7 @@ int mga_dma_buffers(DRM_IOCTL_ARGS) | |||
1118 | /** | 1156 | /** |
1119 | * Called just before the module is unloaded. | 1157 | * Called just before the module is unloaded. |
1120 | */ | 1158 | */ |
1121 | int mga_driver_postcleanup(drm_device_t * dev) | 1159 | int mga_driver_unload(drm_device_t * dev) |
1122 | { | 1160 | { |
1123 | drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); | 1161 | drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); |
1124 | dev->dev_private = NULL; | 1162 | dev->dev_private = NULL; |
@@ -1129,9 +1167,9 @@ int mga_driver_postcleanup(drm_device_t * dev) | |||
1129 | /** | 1167 | /** |
1130 | * Called when the last opener of the device is closed. | 1168 | * Called when the last opener of the device is closed. |
1131 | */ | 1169 | */ |
1132 | void mga_driver_pretakedown(drm_device_t * dev) | 1170 | void mga_driver_lastclose(drm_device_t * dev) |
1133 | { | 1171 | { |
1134 | mga_do_cleanup_dma(dev); | 1172 | mga_do_cleanup_dma(dev, FULL_CLEANUP); |
1135 | } | 1173 | } |
1136 | 1174 | ||
1137 | int mga_driver_dma_quiescent(drm_device_t * dev) | 1175 | int mga_driver_dma_quiescent(drm_device_t * dev) |
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 1713451a5cc6..9f7ed0e0351b 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c | |||
@@ -38,41 +38,6 @@ | |||
38 | #include "drm_pciids.h" | 38 | #include "drm_pciids.h" |
39 | 39 | ||
40 | static int mga_driver_device_is_agp(drm_device_t * dev); | 40 | static int mga_driver_device_is_agp(drm_device_t * dev); |
41 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
42 | { | ||
43 | drm_mga_private_t *const dev_priv = | ||
44 | (drm_mga_private_t *) dev->dev_private; | ||
45 | |||
46 | dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); | ||
47 | dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); | ||
48 | |||
49 | dev->counters += 3; | ||
50 | dev->types[6] = _DRM_STAT_IRQ; | ||
51 | dev->types[7] = _DRM_STAT_PRIMARY; | ||
52 | dev->types[8] = _DRM_STAT_SECONDARY; | ||
53 | |||
54 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
55 | DRIVER_NAME, | ||
56 | DRIVER_MAJOR, | ||
57 | DRIVER_MINOR, | ||
58 | DRIVER_PATCHLEVEL, | ||
59 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
60 | ); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int version(drm_version_t * version) | ||
65 | { | ||
66 | int len; | ||
67 | |||
68 | version->version_major = DRIVER_MAJOR; | ||
69 | version->version_minor = DRIVER_MINOR; | ||
70 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
71 | DRM_COPY(version->name, DRIVER_NAME); | ||
72 | DRM_COPY(version->date, DRIVER_DATE); | ||
73 | DRM_COPY(version->desc, DRIVER_DESC); | ||
74 | return 0; | ||
75 | } | ||
76 | 41 | ||
77 | static struct pci_device_id pciidlist[] = { | 42 | static struct pci_device_id pciidlist[] = { |
78 | mga_PCI_IDS | 43 | mga_PCI_IDS |
@@ -80,12 +45,12 @@ static struct pci_device_id pciidlist[] = { | |||
80 | 45 | ||
81 | static struct drm_driver driver = { | 46 | static struct drm_driver driver = { |
82 | .driver_features = | 47 | .driver_features = |
83 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | | 48 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | |
84 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 49 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
85 | DRIVER_IRQ_VBL, | 50 | DRIVER_IRQ_VBL, |
86 | .preinit = mga_driver_preinit, | 51 | .load = mga_driver_load, |
87 | .postcleanup = mga_driver_postcleanup, | 52 | .unload = mga_driver_unload, |
88 | .pretakedown = mga_driver_pretakedown, | 53 | .lastclose = mga_driver_lastclose, |
89 | .dma_quiescent = mga_driver_dma_quiescent, | 54 | .dma_quiescent = mga_driver_dma_quiescent, |
90 | .device_is_agp = mga_driver_device_is_agp, | 55 | .device_is_agp = mga_driver_device_is_agp, |
91 | .vblank_wait = mga_driver_vblank_wait, | 56 | .vblank_wait = mga_driver_vblank_wait, |
@@ -96,8 +61,6 @@ static struct drm_driver driver = { | |||
96 | .reclaim_buffers = drm_core_reclaim_buffers, | 61 | .reclaim_buffers = drm_core_reclaim_buffers, |
97 | .get_map_ofs = drm_core_get_map_ofs, | 62 | .get_map_ofs = drm_core_get_map_ofs, |
98 | .get_reg_ofs = drm_core_get_reg_ofs, | 63 | .get_reg_ofs = drm_core_get_reg_ofs, |
99 | .postinit = postinit, | ||
100 | .version = version, | ||
101 | .ioctls = mga_ioctls, | 64 | .ioctls = mga_ioctls, |
102 | .dma_ioctl = mga_dma_buffers, | 65 | .dma_ioctl = mga_dma_buffers, |
103 | .fops = { | 66 | .fops = { |
@@ -113,9 +76,16 @@ static struct drm_driver driver = { | |||
113 | #endif | 76 | #endif |
114 | }, | 77 | }, |
115 | .pci_driver = { | 78 | .pci_driver = { |
116 | .name = DRIVER_NAME, | 79 | .name = DRIVER_NAME, |
117 | .id_table = pciidlist, | 80 | .id_table = pciidlist, |
118 | } | 81 | }, |
82 | |||
83 | .name = DRIVER_NAME, | ||
84 | .desc = DRIVER_DESC, | ||
85 | .date = DRIVER_DATE, | ||
86 | .major = DRIVER_MAJOR, | ||
87 | .minor = DRIVER_MINOR, | ||
88 | .patchlevel = DRIVER_PATCHLEVEL, | ||
119 | }; | 89 | }; |
120 | 90 | ||
121 | static int __init mga_init(void) | 91 | static int __init mga_init(void) |
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index 461728e6a58a..6b0c53193506 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h | |||
@@ -38,11 +38,11 @@ | |||
38 | 38 | ||
39 | #define DRIVER_NAME "mga" | 39 | #define DRIVER_NAME "mga" |
40 | #define DRIVER_DESC "Matrox G200/G400" | 40 | #define DRIVER_DESC "Matrox G200/G400" |
41 | #define DRIVER_DATE "20050607" | 41 | #define DRIVER_DATE "20051102" |
42 | 42 | ||
43 | #define DRIVER_MAJOR 3 | 43 | #define DRIVER_MAJOR 3 |
44 | #define DRIVER_MINOR 2 | 44 | #define DRIVER_MINOR 2 |
45 | #define DRIVER_PATCHLEVEL 0 | 45 | #define DRIVER_PATCHLEVEL 1 |
46 | 46 | ||
47 | typedef struct drm_mga_primary_buffer { | 47 | typedef struct drm_mga_primary_buffer { |
48 | u8 *start; | 48 | u8 *start; |
@@ -144,22 +144,22 @@ typedef struct drm_mga_private { | |||
144 | drm_local_map_t *primary; | 144 | drm_local_map_t *primary; |
145 | drm_local_map_t *agp_textures; | 145 | drm_local_map_t *agp_textures; |
146 | 146 | ||
147 | DRM_AGP_MEM *agp_mem; | 147 | unsigned long agp_handle; |
148 | unsigned int agp_pages; | 148 | unsigned int agp_size; |
149 | } drm_mga_private_t; | 149 | } drm_mga_private_t; |
150 | 150 | ||
151 | extern drm_ioctl_desc_t mga_ioctls[]; | 151 | extern drm_ioctl_desc_t mga_ioctls[]; |
152 | extern int mga_max_ioctl; | 152 | extern int mga_max_ioctl; |
153 | 153 | ||
154 | /* mga_dma.c */ | 154 | /* mga_dma.c */ |
155 | extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags); | ||
156 | extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); | 155 | extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); |
157 | extern int mga_dma_init(DRM_IOCTL_ARGS); | 156 | extern int mga_dma_init(DRM_IOCTL_ARGS); |
158 | extern int mga_dma_flush(DRM_IOCTL_ARGS); | 157 | extern int mga_dma_flush(DRM_IOCTL_ARGS); |
159 | extern int mga_dma_reset(DRM_IOCTL_ARGS); | 158 | extern int mga_dma_reset(DRM_IOCTL_ARGS); |
160 | extern int mga_dma_buffers(DRM_IOCTL_ARGS); | 159 | extern int mga_dma_buffers(DRM_IOCTL_ARGS); |
161 | extern int mga_driver_postcleanup(drm_device_t * dev); | 160 | extern int mga_driver_load(drm_device_t *dev, unsigned long flags); |
162 | extern void mga_driver_pretakedown(drm_device_t * dev); | 161 | extern int mga_driver_unload(drm_device_t * dev); |
162 | extern void mga_driver_lastclose(drm_device_t * dev); | ||
163 | extern int mga_driver_dma_quiescent(drm_device_t * dev); | 163 | extern int mga_driver_dma_quiescent(drm_device_t * dev); |
164 | 164 | ||
165 | extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); | 165 | extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); |
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c index 47f54b5ae956..2837e669183a 100644 --- a/drivers/char/drm/mga_state.c +++ b/drivers/char/drm/mga_state.c | |||
@@ -1127,19 +1127,19 @@ static int mga_wait_fence(DRM_IOCTL_ARGS) | |||
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | drm_ioctl_desc_t mga_ioctls[] = { | 1129 | drm_ioctl_desc_t mga_ioctls[] = { |
1130 | [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, | 1130 | [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1131 | [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, | 1131 | [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH}, |
1132 | [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, | 1132 | [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH}, |
1133 | [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, | 1133 | [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH}, |
1134 | [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, | 1134 | [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH}, |
1135 | [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, | 1135 | [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH}, |
1136 | [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, | 1136 | [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH}, |
1137 | [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, | 1137 | [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH}, |
1138 | [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, | 1138 | [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH}, |
1139 | [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, | 1139 | [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH}, |
1140 | [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, | 1140 | [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH}, |
1141 | [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, | 1141 | [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH}, |
1142 | [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, | 1142 | [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1143 | }; | 1143 | }; |
1144 | 1144 | ||
1145 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1145 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index 7452753d4d01..db5a60450e68 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- | 1 | /* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- |
2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com | 2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com |
3 | * | 3 | */ |
4 | /* | ||
4 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. | 5 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. |
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 6 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
6 | * All Rights Reserved. | 7 | * All Rights Reserved. |
@@ -559,7 +560,8 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) | |||
559 | if (dev_priv->is_pci) { | 560 | if (dev_priv->is_pci) { |
560 | #endif | 561 | #endif |
561 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | 562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
562 | dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; | 563 | dev_priv->gart_info.addr = NULL; |
564 | dev_priv->gart_info.bus_addr = 0; | ||
563 | dev_priv->gart_info.is_pcie = 0; | 565 | dev_priv->gart_info.is_pcie = 0; |
564 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | 566 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { |
565 | DRM_ERROR("failed to init PCI GART!\n"); | 567 | DRM_ERROR("failed to init PCI GART!\n"); |
@@ -601,15 +603,16 @@ int r128_do_cleanup_cce(drm_device_t * dev) | |||
601 | drm_core_ioremapfree(dev_priv->cce_ring, dev); | 603 | drm_core_ioremapfree(dev_priv->cce_ring, dev); |
602 | if (dev_priv->ring_rptr != NULL) | 604 | if (dev_priv->ring_rptr != NULL) |
603 | drm_core_ioremapfree(dev_priv->ring_rptr, dev); | 605 | drm_core_ioremapfree(dev_priv->ring_rptr, dev); |
604 | if (dev->agp_buffer_map != NULL) | 606 | if (dev->agp_buffer_map != NULL) { |
605 | drm_core_ioremapfree(dev->agp_buffer_map, dev); | 607 | drm_core_ioremapfree(dev->agp_buffer_map, dev); |
608 | dev->agp_buffer_map = NULL; | ||
609 | } | ||
606 | } else | 610 | } else |
607 | #endif | 611 | #endif |
608 | { | 612 | { |
609 | if (dev_priv->gart_info.bus_addr) | 613 | if (dev_priv->gart_info.bus_addr) |
610 | if (!drm_ati_pcigart_cleanup(dev, | 614 | if (!drm_ati_pcigart_cleanup(dev, |
611 | &dev_priv-> | 615 | &dev_priv->gart_info)) |
612 | gart_info)) | ||
613 | DRM_ERROR | 616 | DRM_ERROR |
614 | ("failed to cleanup PCI GART!\n"); | 617 | ("failed to cleanup PCI GART!\n"); |
615 | } | 618 | } |
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h index 5ddc03202411..5d835b006f55 100644 --- a/drivers/char/drm/r128_drm.h +++ b/drivers/char/drm/r128_drm.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- | 1 | /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- |
2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com | 2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com |
3 | * | 3 | */ |
4 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. | 4 | /* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. |
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 1661e7351402..e20450ae220e 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c | |||
@@ -37,31 +37,6 @@ | |||
37 | 37 | ||
38 | #include "drm_pciids.h" | 38 | #include "drm_pciids.h" |
39 | 39 | ||
40 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
41 | { | ||
42 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
43 | DRIVER_NAME, | ||
44 | DRIVER_MAJOR, | ||
45 | DRIVER_MINOR, | ||
46 | DRIVER_PATCHLEVEL, | ||
47 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
48 | ); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int version(drm_version_t * version) | ||
53 | { | ||
54 | int len; | ||
55 | |||
56 | version->version_major = DRIVER_MAJOR; | ||
57 | version->version_minor = DRIVER_MINOR; | ||
58 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
59 | DRM_COPY(version->name, DRIVER_NAME); | ||
60 | DRM_COPY(version->date, DRIVER_DATE); | ||
61 | DRM_COPY(version->desc, DRIVER_DESC); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static struct pci_device_id pciidlist[] = { | 40 | static struct pci_device_id pciidlist[] = { |
66 | r128_PCI_IDS | 41 | r128_PCI_IDS |
67 | }; | 42 | }; |
@@ -72,8 +47,8 @@ static struct drm_driver driver = { | |||
72 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 47 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
73 | DRIVER_IRQ_VBL, | 48 | DRIVER_IRQ_VBL, |
74 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 49 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
75 | .prerelease = r128_driver_prerelease, | 50 | .preclose = r128_driver_preclose, |
76 | .pretakedown = r128_driver_pretakedown, | 51 | .lastclose = r128_driver_lastclose, |
77 | .vblank_wait = r128_driver_vblank_wait, | 52 | .vblank_wait = r128_driver_vblank_wait, |
78 | .irq_preinstall = r128_driver_irq_preinstall, | 53 | .irq_preinstall = r128_driver_irq_preinstall, |
79 | .irq_postinstall = r128_driver_irq_postinstall, | 54 | .irq_postinstall = r128_driver_irq_postinstall, |
@@ -82,8 +57,6 @@ static struct drm_driver driver = { | |||
82 | .reclaim_buffers = drm_core_reclaim_buffers, | 57 | .reclaim_buffers = drm_core_reclaim_buffers, |
83 | .get_map_ofs = drm_core_get_map_ofs, | 58 | .get_map_ofs = drm_core_get_map_ofs, |
84 | .get_reg_ofs = drm_core_get_reg_ofs, | 59 | .get_reg_ofs = drm_core_get_reg_ofs, |
85 | .postinit = postinit, | ||
86 | .version = version, | ||
87 | .ioctls = r128_ioctls, | 60 | .ioctls = r128_ioctls, |
88 | .dma_ioctl = r128_cce_buffers, | 61 | .dma_ioctl = r128_cce_buffers, |
89 | .fops = { | 62 | .fops = { |
@@ -97,12 +70,19 @@ static struct drm_driver driver = { | |||
97 | #ifdef CONFIG_COMPAT | 70 | #ifdef CONFIG_COMPAT |
98 | .compat_ioctl = r128_compat_ioctl, | 71 | .compat_ioctl = r128_compat_ioctl, |
99 | #endif | 72 | #endif |
100 | } | 73 | }, |
101 | , | 74 | |
102 | .pci_driver = { | 75 | .pci_driver = { |
103 | .name = DRIVER_NAME, | 76 | .name = DRIVER_NAME, |
104 | .id_table = pciidlist, | 77 | .id_table = pciidlist, |
105 | } | 78 | }, |
79 | |||
80 | .name = DRIVER_NAME, | ||
81 | .desc = DRIVER_DESC, | ||
82 | .date = DRIVER_DATE, | ||
83 | .major = DRIVER_MAJOR, | ||
84 | .minor = DRIVER_MINOR, | ||
85 | .patchlevel = DRIVER_PATCHLEVEL, | ||
106 | }; | 86 | }; |
107 | 87 | ||
108 | static int __init r128_init(void) | 88 | static int __init r128_init(void) |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 5c79e40eb88f..94abffb2cca5 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- | 1 | /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- |
2 | * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com | 2 | * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com |
3 | * | 3 | */ |
4 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | 4 | /* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. |
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -154,8 +154,8 @@ extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | |||
154 | extern void r128_driver_irq_preinstall(drm_device_t * dev); | 154 | extern void r128_driver_irq_preinstall(drm_device_t * dev); |
155 | extern void r128_driver_irq_postinstall(drm_device_t * dev); | 155 | extern void r128_driver_irq_postinstall(drm_device_t * dev); |
156 | extern void r128_driver_irq_uninstall(drm_device_t * dev); | 156 | extern void r128_driver_irq_uninstall(drm_device_t * dev); |
157 | extern void r128_driver_pretakedown(drm_device_t * dev); | 157 | extern void r128_driver_lastclose(drm_device_t * dev); |
158 | extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp); | 158 | extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp); |
159 | 159 | ||
160 | extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, | 160 | extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, |
161 | unsigned long arg); | 161 | unsigned long arg); |
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c index 27eb0e31bd3b..87f8ca2b0685 100644 --- a/drivers/char/drm/r128_irq.c +++ b/drivers/char/drm/r128_irq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- | 1 | /* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. | 3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. |
4 | * | 4 | * |
5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the | 5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the |
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c index 14479cc08a57..caeecc2c36da 100644 --- a/drivers/char/drm/r128_state.c +++ b/drivers/char/drm/r128_state.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* r128_state.c -- State support for r128 -*- linux-c -*- | 1 | /* r128_state.c -- State support for r128 -*- linux-c -*- |
2 | * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com | 2 | * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com |
3 | * | 3 | */ |
4 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 4 | /* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. |
6 | * | 6 | * |
7 | * Permission is hereby granted, free of charge, to any person obtaining a | 7 | * Permission is hereby granted, free of charge, to any person obtaining a |
@@ -1674,7 +1674,7 @@ static int r128_getparam(DRM_IOCTL_ARGS) | |||
1674 | return 0; | 1674 | return 0; |
1675 | } | 1675 | } |
1676 | 1676 | ||
1677 | void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) | 1677 | void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) |
1678 | { | 1678 | { |
1679 | if (dev->dev_private) { | 1679 | if (dev->dev_private) { |
1680 | drm_r128_private_t *dev_priv = dev->dev_private; | 1680 | drm_r128_private_t *dev_priv = dev->dev_private; |
@@ -1684,29 +1684,29 @@ void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) | |||
1684 | } | 1684 | } |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | void r128_driver_pretakedown(drm_device_t * dev) | 1687 | void r128_driver_lastclose(drm_device_t * dev) |
1688 | { | 1688 | { |
1689 | r128_do_cleanup_cce(dev); | 1689 | r128_do_cleanup_cce(dev); |
1690 | } | 1690 | } |
1691 | 1691 | ||
1692 | drm_ioctl_desc_t r128_ioctls[] = { | 1692 | drm_ioctl_desc_t r128_ioctls[] = { |
1693 | [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1}, | 1693 | [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1694 | [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1}, | 1694 | [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1695 | [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1}, | 1695 | [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1696 | [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1}, | 1696 | [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1697 | [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0}, | 1697 | [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH}, |
1698 | [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0}, | 1698 | [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH}, |
1699 | [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0}, | 1699 | [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH}, |
1700 | [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0}, | 1700 | [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH}, |
1701 | [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0}, | 1701 | [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH}, |
1702 | [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0}, | 1702 | [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH}, |
1703 | [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0}, | 1703 | [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH}, |
1704 | [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0}, | 1704 | [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH}, |
1705 | [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0}, | 1705 | [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH}, |
1706 | [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0}, | 1706 | [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH}, |
1707 | [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0}, | 1707 | [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH}, |
1708 | [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1}, | 1708 | [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1709 | [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0}, | 1709 | [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH}, |
1710 | }; | 1710 | }; |
1711 | 1711 | ||
1712 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); | 1712 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 3a1ac5f78b43..291dbf4c8186 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -52,8 +52,8 @@ static const int r300_cliprect_cntl[4] = { | |||
52 | * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command | 52 | * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command |
53 | * buffer, starting with index n. | 53 | * buffer, starting with index n. |
54 | */ | 54 | */ |
55 | static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, | 55 | static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, |
56 | drm_radeon_kcmd_buffer_t * cmdbuf, int n) | 56 | drm_radeon_kcmd_buffer_t *cmdbuf, int n) |
57 | { | 57 | { |
58 | drm_clip_rect_t box; | 58 | drm_clip_rect_t box; |
59 | int nr; | 59 | int nr; |
@@ -216,6 +216,7 @@ void r300_init_reg_flags(void) | |||
216 | ADD_RANGE(R300_TX_UNK1_0, 16); | 216 | ADD_RANGE(R300_TX_UNK1_0, 16); |
217 | ADD_RANGE(R300_TX_SIZE_0, 16); | 217 | ADD_RANGE(R300_TX_SIZE_0, 16); |
218 | ADD_RANGE(R300_TX_FORMAT_0, 16); | 218 | ADD_RANGE(R300_TX_FORMAT_0, 16); |
219 | ADD_RANGE(R300_TX_PITCH_0, 16); | ||
219 | /* Texture offset is dangerous and needs more checking */ | 220 | /* Texture offset is dangerous and needs more checking */ |
220 | ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); | 221 | ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); |
221 | ADD_RANGE(R300_TX_UNK4_0, 16); | 222 | ADD_RANGE(R300_TX_UNK4_0, 16); |
@@ -242,7 +243,7 @@ static __inline__ int r300_check_range(unsigned reg, int count) | |||
242 | 243 | ||
243 | /* we expect offsets passed to the framebuffer to be either within video memory or | 244 | /* we expect offsets passed to the framebuffer to be either within video memory or |
244 | within AGP space */ | 245 | within AGP space */ |
245 | static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv, | 246 | static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, |
246 | u32 offset) | 247 | u32 offset) |
247 | { | 248 | { |
248 | /* we realy want to check against end of video aperture | 249 | /* we realy want to check against end of video aperture |
@@ -317,8 +318,8 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * | |||
317 | * | 318 | * |
318 | * Note that checks are performed on contents and addresses of the registers | 319 | * Note that checks are performed on contents and addresses of the registers |
319 | */ | 320 | */ |
320 | static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, | 321 | static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, |
321 | drm_radeon_kcmd_buffer_t * cmdbuf, | 322 | drm_radeon_kcmd_buffer_t *cmdbuf, |
322 | drm_r300_cmd_header_t header) | 323 | drm_r300_cmd_header_t header) |
323 | { | 324 | { |
324 | int reg; | 325 | int reg; |
@@ -363,8 +364,8 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, | |||
363 | * the graphics card. | 364 | * the graphics card. |
364 | * Called by r300_do_cp_cmdbuf. | 365 | * Called by r300_do_cp_cmdbuf. |
365 | */ | 366 | */ |
366 | static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, | 367 | static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, |
367 | drm_radeon_kcmd_buffer_t * cmdbuf, | 368 | drm_radeon_kcmd_buffer_t *cmdbuf, |
368 | drm_r300_cmd_header_t header) | 369 | drm_r300_cmd_header_t header) |
369 | { | 370 | { |
370 | int sz; | 371 | int sz; |
@@ -400,8 +401,8 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, | |||
400 | * Emit a clear packet from userspace. | 401 | * Emit a clear packet from userspace. |
401 | * Called by r300_emit_packet3. | 402 | * Called by r300_emit_packet3. |
402 | */ | 403 | */ |
403 | static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, | 404 | static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, |
404 | drm_radeon_kcmd_buffer_t * cmdbuf) | 405 | drm_radeon_kcmd_buffer_t *cmdbuf) |
405 | { | 406 | { |
406 | RING_LOCALS; | 407 | RING_LOCALS; |
407 | 408 | ||
@@ -421,8 +422,8 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, | |||
421 | return 0; | 422 | return 0; |
422 | } | 423 | } |
423 | 424 | ||
424 | static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, | 425 | static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, |
425 | drm_radeon_kcmd_buffer_t * cmdbuf, | 426 | drm_radeon_kcmd_buffer_t *cmdbuf, |
426 | u32 header) | 427 | u32 header) |
427 | { | 428 | { |
428 | int count, i, k; | 429 | int count, i, k; |
@@ -489,8 +490,8 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, | |||
489 | return 0; | 490 | return 0; |
490 | } | 491 | } |
491 | 492 | ||
492 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, | 493 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, |
493 | drm_radeon_kcmd_buffer_t * cmdbuf) | 494 | drm_radeon_kcmd_buffer_t *cmdbuf) |
494 | { | 495 | { |
495 | u32 header; | 496 | u32 header; |
496 | int count; | 497 | int count; |
@@ -554,8 +555,8 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, | |||
554 | * Emit a rendering packet3 from userspace. | 555 | * Emit a rendering packet3 from userspace. |
555 | * Called by r300_do_cp_cmdbuf. | 556 | * Called by r300_do_cp_cmdbuf. |
556 | */ | 557 | */ |
557 | static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, | 558 | static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, |
558 | drm_radeon_kcmd_buffer_t * cmdbuf, | 559 | drm_radeon_kcmd_buffer_t *cmdbuf, |
559 | drm_r300_cmd_header_t header) | 560 | drm_r300_cmd_header_t header) |
560 | { | 561 | { |
561 | int n; | 562 | int n; |
@@ -623,7 +624,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, | |||
623 | /** | 624 | /** |
624 | * Emit the sequence to pacify R300. | 625 | * Emit the sequence to pacify R300. |
625 | */ | 626 | */ |
626 | static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv) | 627 | static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) |
627 | { | 628 | { |
628 | RING_LOCALS; | 629 | RING_LOCALS; |
629 | 630 | ||
@@ -657,9 +658,10 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) | |||
657 | * commands on the DMA ring buffer. | 658 | * commands on the DMA ring buffer. |
658 | * Called by the ioctl handler function radeon_cp_cmdbuf. | 659 | * Called by the ioctl handler function radeon_cp_cmdbuf. |
659 | */ | 660 | */ |
660 | int r300_do_cp_cmdbuf(drm_device_t * dev, | 661 | int r300_do_cp_cmdbuf(drm_device_t *dev, |
661 | DRMFILE filp, | 662 | DRMFILE filp, |
662 | drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf) | 663 | drm_file_t *filp_priv, |
664 | drm_radeon_kcmd_buffer_t *cmdbuf) | ||
663 | { | 665 | { |
664 | drm_radeon_private_t *dev_priv = dev->dev_private; | 666 | drm_radeon_private_t *dev_priv = dev->dev_private; |
665 | drm_device_dma_t *dma = dev->dma; | 667 | drm_device_dma_t *dma = dev->dma; |
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h index e5b73c002394..a0ed20e25221 100644 --- a/drivers/char/drm/r300_reg.h +++ b/drivers/char/drm/r300_reg.h | |||
@@ -797,6 +797,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
797 | 797 | ||
798 | # define R300_TX_FORMAT_YUV_MODE 0x00800000 | 798 | # define R300_TX_FORMAT_YUV_MODE 0x00800000 |
799 | 799 | ||
800 | #define R300_TX_PITCH_0 0x4500 | ||
800 | #define R300_TX_OFFSET_0 0x4540 | 801 | #define R300_TX_OFFSET_0 0x4540 |
801 | /* BEGIN: Guess from R200 */ | 802 | /* BEGIN: Guess from R200 */ |
802 | # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) | 803 | # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 342302d46743..915665c7fe7c 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* radeon_cp.c -- CP support for Radeon -*- linux-c -*- | 1 | /* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. | 3 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. |
4 | * Copyright 2000 VA Linux Systems, Inc., Fremont, California. | 4 | * Copyright 2000 VA Linux Systems, Inc., Fremont, California. |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. |
@@ -824,7 +824,7 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr) | |||
824 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); | 824 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); |
825 | } | 825 | } |
826 | 826 | ||
827 | static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr) | 827 | static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) |
828 | { | 828 | { |
829 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); | 829 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); |
830 | return RADEON_READ(RADEON_PCIE_DATA); | 830 | return RADEON_READ(RADEON_PCIE_DATA); |
@@ -1125,7 +1125,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1125 | | (dev_priv->fb_location >> 16)); | 1125 | | (dev_priv->fb_location >> 16)); |
1126 | 1126 | ||
1127 | #if __OS_HAS_AGP | 1127 | #if __OS_HAS_AGP |
1128 | if (!dev_priv->is_pci) { | 1128 | if (dev_priv->flags & CHIP_IS_AGP) { |
1129 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | 1129 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, |
1130 | (((dev_priv->gart_vm_start - 1 + | 1130 | (((dev_priv->gart_vm_start - 1 + |
1131 | dev_priv->gart_size) & 0xffff0000) | | 1131 | dev_priv->gart_size) & 0xffff0000) | |
@@ -1152,7 +1152,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1152 | dev_priv->ring.tail = cur_read_ptr; | 1152 | dev_priv->ring.tail = cur_read_ptr; |
1153 | 1153 | ||
1154 | #if __OS_HAS_AGP | 1154 | #if __OS_HAS_AGP |
1155 | if (!dev_priv->is_pci) { | 1155 | if (dev_priv->flags & CHIP_IS_AGP) { |
1156 | /* set RADEON_AGP_BASE here instead of relying on X from user space */ | 1156 | /* set RADEON_AGP_BASE here instead of relying on X from user space */ |
1157 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); | 1157 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); |
1158 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, | 1158 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, |
@@ -1278,13 +1278,15 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | |||
1278 | /* Enable or disable PCI GART on the chip */ | 1278 | /* Enable or disable PCI GART on the chip */ |
1279 | static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | 1279 | static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) |
1280 | { | 1280 | { |
1281 | u32 tmp = RADEON_READ(RADEON_AIC_CNTL); | 1281 | u32 tmp; |
1282 | 1282 | ||
1283 | if (dev_priv->flags & CHIP_IS_PCIE) { | 1283 | if (dev_priv->flags & CHIP_IS_PCIE) { |
1284 | radeon_set_pciegart(dev_priv, on); | 1284 | radeon_set_pciegart(dev_priv, on); |
1285 | return; | 1285 | return; |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | tmp = RADEON_READ(RADEON_AIC_CNTL); | ||
1289 | |||
1288 | if (on) { | 1290 | if (on) { |
1289 | RADEON_WRITE(RADEON_AIC_CNTL, | 1291 | RADEON_WRITE(RADEON_AIC_CNTL, |
1290 | tmp | RADEON_PCIGART_TRANSLATE_EN); | 1292 | tmp | RADEON_PCIGART_TRANSLATE_EN); |
@@ -1312,13 +1314,17 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
1312 | static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | 1314 | static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) |
1313 | { | 1315 | { |
1314 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1316 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1317 | |||
1315 | DRM_DEBUG("\n"); | 1318 | DRM_DEBUG("\n"); |
1316 | 1319 | ||
1317 | dev_priv->is_pci = init->is_pci; | 1320 | if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) |
1321 | { | ||
1322 | DRM_DEBUG("Forcing AGP card to PCI mode\n"); | ||
1323 | dev_priv->flags &= ~CHIP_IS_AGP; | ||
1324 | } | ||
1318 | 1325 | ||
1319 | if (dev_priv->is_pci && !dev->sg) { | 1326 | if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { |
1320 | DRM_ERROR("PCI GART memory not allocated!\n"); | 1327 | DRM_ERROR("PCI GART memory not allocated!\n"); |
1321 | dev->dev_private = (void *)dev_priv; | ||
1322 | radeon_do_cleanup_cp(dev); | 1328 | radeon_do_cleanup_cp(dev); |
1323 | return DRM_ERR(EINVAL); | 1329 | return DRM_ERR(EINVAL); |
1324 | } | 1330 | } |
@@ -1327,12 +1333,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1327 | if (dev_priv->usec_timeout < 1 || | 1333 | if (dev_priv->usec_timeout < 1 || |
1328 | dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { | 1334 | dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { |
1329 | DRM_DEBUG("TIMEOUT problem!\n"); | 1335 | DRM_DEBUG("TIMEOUT problem!\n"); |
1330 | dev->dev_private = (void *)dev_priv; | ||
1331 | radeon_do_cleanup_cp(dev); | 1336 | radeon_do_cleanup_cp(dev); |
1332 | return DRM_ERR(EINVAL); | 1337 | return DRM_ERR(EINVAL); |
1333 | } | 1338 | } |
1334 | 1339 | ||
1335 | switch (init->func) { | 1340 | switch(init->func) { |
1336 | case RADEON_INIT_R200_CP: | 1341 | case RADEON_INIT_R200_CP: |
1337 | dev_priv->microcode_version = UCODE_R200; | 1342 | dev_priv->microcode_version = UCODE_R200; |
1338 | break; | 1343 | break; |
@@ -1353,7 +1358,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1353 | if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && | 1358 | if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && |
1354 | (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { | 1359 | (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { |
1355 | DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); | 1360 | DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); |
1356 | dev->dev_private = (void *)dev_priv; | ||
1357 | radeon_do_cleanup_cp(dev); | 1361 | radeon_do_cleanup_cp(dev); |
1358 | return DRM_ERR(EINVAL); | 1362 | return DRM_ERR(EINVAL); |
1359 | } | 1363 | } |
@@ -1416,8 +1420,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1416 | 1420 | ||
1417 | DRM_GETSAREA(); | 1421 | DRM_GETSAREA(); |
1418 | 1422 | ||
1419 | dev_priv->fb_offset = init->fb_offset; | ||
1420 | dev_priv->mmio_offset = init->mmio_offset; | ||
1421 | dev_priv->ring_offset = init->ring_offset; | 1423 | dev_priv->ring_offset = init->ring_offset; |
1422 | dev_priv->ring_rptr_offset = init->ring_rptr_offset; | 1424 | dev_priv->ring_rptr_offset = init->ring_rptr_offset; |
1423 | dev_priv->buffers_offset = init->buffers_offset; | 1425 | dev_priv->buffers_offset = init->buffers_offset; |
@@ -1425,29 +1427,19 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1425 | 1427 | ||
1426 | if (!dev_priv->sarea) { | 1428 | if (!dev_priv->sarea) { |
1427 | DRM_ERROR("could not find sarea!\n"); | 1429 | DRM_ERROR("could not find sarea!\n"); |
1428 | dev->dev_private = (void *)dev_priv; | ||
1429 | radeon_do_cleanup_cp(dev); | 1430 | radeon_do_cleanup_cp(dev); |
1430 | return DRM_ERR(EINVAL); | 1431 | return DRM_ERR(EINVAL); |
1431 | } | 1432 | } |
1432 | 1433 | ||
1433 | dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); | ||
1434 | if (!dev_priv->mmio) { | ||
1435 | DRM_ERROR("could not find mmio region!\n"); | ||
1436 | dev->dev_private = (void *)dev_priv; | ||
1437 | radeon_do_cleanup_cp(dev); | ||
1438 | return DRM_ERR(EINVAL); | ||
1439 | } | ||
1440 | dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); | 1434 | dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); |
1441 | if (!dev_priv->cp_ring) { | 1435 | if (!dev_priv->cp_ring) { |
1442 | DRM_ERROR("could not find cp ring region!\n"); | 1436 | DRM_ERROR("could not find cp ring region!\n"); |
1443 | dev->dev_private = (void *)dev_priv; | ||
1444 | radeon_do_cleanup_cp(dev); | 1437 | radeon_do_cleanup_cp(dev); |
1445 | return DRM_ERR(EINVAL); | 1438 | return DRM_ERR(EINVAL); |
1446 | } | 1439 | } |
1447 | dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); | 1440 | dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); |
1448 | if (!dev_priv->ring_rptr) { | 1441 | if (!dev_priv->ring_rptr) { |
1449 | DRM_ERROR("could not find ring read pointer!\n"); | 1442 | DRM_ERROR("could not find ring read pointer!\n"); |
1450 | dev->dev_private = (void *)dev_priv; | ||
1451 | radeon_do_cleanup_cp(dev); | 1443 | radeon_do_cleanup_cp(dev); |
1452 | return DRM_ERR(EINVAL); | 1444 | return DRM_ERR(EINVAL); |
1453 | } | 1445 | } |
@@ -1455,7 +1447,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1455 | dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); | 1447 | dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); |
1456 | if (!dev->agp_buffer_map) { | 1448 | if (!dev->agp_buffer_map) { |
1457 | DRM_ERROR("could not find dma buffer region!\n"); | 1449 | DRM_ERROR("could not find dma buffer region!\n"); |
1458 | dev->dev_private = (void *)dev_priv; | ||
1459 | radeon_do_cleanup_cp(dev); | 1450 | radeon_do_cleanup_cp(dev); |
1460 | return DRM_ERR(EINVAL); | 1451 | return DRM_ERR(EINVAL); |
1461 | } | 1452 | } |
@@ -1465,7 +1456,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1465 | drm_core_findmap(dev, init->gart_textures_offset); | 1456 | drm_core_findmap(dev, init->gart_textures_offset); |
1466 | if (!dev_priv->gart_textures) { | 1457 | if (!dev_priv->gart_textures) { |
1467 | DRM_ERROR("could not find GART texture region!\n"); | 1458 | DRM_ERROR("could not find GART texture region!\n"); |
1468 | dev->dev_private = (void *)dev_priv; | ||
1469 | radeon_do_cleanup_cp(dev); | 1459 | radeon_do_cleanup_cp(dev); |
1470 | return DRM_ERR(EINVAL); | 1460 | return DRM_ERR(EINVAL); |
1471 | } | 1461 | } |
@@ -1476,7 +1466,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1476 | init->sarea_priv_offset); | 1466 | init->sarea_priv_offset); |
1477 | 1467 | ||
1478 | #if __OS_HAS_AGP | 1468 | #if __OS_HAS_AGP |
1479 | if (!dev_priv->is_pci) { | 1469 | if (dev_priv->flags & CHIP_IS_AGP) { |
1480 | drm_core_ioremap(dev_priv->cp_ring, dev); | 1470 | drm_core_ioremap(dev_priv->cp_ring, dev); |
1481 | drm_core_ioremap(dev_priv->ring_rptr, dev); | 1471 | drm_core_ioremap(dev_priv->ring_rptr, dev); |
1482 | drm_core_ioremap(dev->agp_buffer_map, dev); | 1472 | drm_core_ioremap(dev->agp_buffer_map, dev); |
@@ -1484,7 +1474,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1484 | !dev_priv->ring_rptr->handle || | 1474 | !dev_priv->ring_rptr->handle || |
1485 | !dev->agp_buffer_map->handle) { | 1475 | !dev->agp_buffer_map->handle) { |
1486 | DRM_ERROR("could not find ioremap agp regions!\n"); | 1476 | DRM_ERROR("could not find ioremap agp regions!\n"); |
1487 | dev->dev_private = (void *)dev_priv; | ||
1488 | radeon_do_cleanup_cp(dev); | 1477 | radeon_do_cleanup_cp(dev); |
1489 | return DRM_ERR(EINVAL); | 1478 | return DRM_ERR(EINVAL); |
1490 | } | 1479 | } |
@@ -1525,7 +1514,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1525 | + RADEON_READ(RADEON_CONFIG_APER_SIZE); | 1514 | + RADEON_READ(RADEON_CONFIG_APER_SIZE); |
1526 | 1515 | ||
1527 | #if __OS_HAS_AGP | 1516 | #if __OS_HAS_AGP |
1528 | if (!dev_priv->is_pci) | 1517 | if (dev_priv->flags & CHIP_IS_AGP) |
1529 | dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset | 1518 | dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset |
1530 | - dev->agp->base | 1519 | - dev->agp->base |
1531 | + dev_priv->gart_vm_start); | 1520 | + dev_priv->gart_vm_start); |
@@ -1551,7 +1540,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1551 | dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; | 1540 | dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; |
1552 | 1541 | ||
1553 | #if __OS_HAS_AGP | 1542 | #if __OS_HAS_AGP |
1554 | if (!dev_priv->is_pci) { | 1543 | if (dev_priv->flags & CHIP_IS_AGP) { |
1555 | /* Turn off PCI GART */ | 1544 | /* Turn off PCI GART */ |
1556 | radeon_set_pcigart(dev_priv, 0); | 1545 | radeon_set_pcigart(dev_priv, 0); |
1557 | } else | 1546 | } else |
@@ -1561,25 +1550,28 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1561 | if (dev_priv->pcigart_offset) { | 1550 | if (dev_priv->pcigart_offset) { |
1562 | dev_priv->gart_info.bus_addr = | 1551 | dev_priv->gart_info.bus_addr = |
1563 | dev_priv->pcigart_offset + dev_priv->fb_location; | 1552 | dev_priv->pcigart_offset + dev_priv->fb_location; |
1553 | dev_priv->gart_info.mapping.offset = | ||
1554 | dev_priv->gart_info.bus_addr; | ||
1555 | dev_priv->gart_info.mapping.size = | ||
1556 | RADEON_PCIGART_TABLE_SIZE; | ||
1557 | |||
1558 | drm_core_ioremap(&dev_priv->gart_info.mapping, dev); | ||
1564 | dev_priv->gart_info.addr = | 1559 | dev_priv->gart_info.addr = |
1565 | (unsigned long)drm_ioremap(dev_priv->gart_info. | 1560 | dev_priv->gart_info.mapping.handle; |
1566 | bus_addr, | ||
1567 | RADEON_PCIGART_TABLE_SIZE, | ||
1568 | dev); | ||
1569 | 1561 | ||
1570 | dev_priv->gart_info.is_pcie = | 1562 | dev_priv->gart_info.is_pcie = |
1571 | !!(dev_priv->flags & CHIP_IS_PCIE); | 1563 | !!(dev_priv->flags & CHIP_IS_PCIE); |
1572 | dev_priv->gart_info.gart_table_location = | 1564 | dev_priv->gart_info.gart_table_location = |
1573 | DRM_ATI_GART_FB; | 1565 | DRM_ATI_GART_FB; |
1574 | 1566 | ||
1575 | DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", | 1567 | DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", |
1576 | dev_priv->gart_info.addr, | 1568 | dev_priv->gart_info.addr, |
1577 | dev_priv->pcigart_offset); | 1569 | dev_priv->pcigart_offset); |
1578 | } else { | 1570 | } else { |
1579 | dev_priv->gart_info.gart_table_location = | 1571 | dev_priv->gart_info.gart_table_location = |
1580 | DRM_ATI_GART_MAIN; | 1572 | DRM_ATI_GART_MAIN; |
1581 | dev_priv->gart_info.addr = | 1573 | dev_priv->gart_info.addr = NULL; |
1582 | dev_priv->gart_info.bus_addr = 0; | 1574 | dev_priv->gart_info.bus_addr = 0; |
1583 | if (dev_priv->flags & CHIP_IS_PCIE) { | 1575 | if (dev_priv->flags & CHIP_IS_PCIE) { |
1584 | DRM_ERROR | 1576 | DRM_ERROR |
1585 | ("Cannot use PCI Express without GART in FB memory\n"); | 1577 | ("Cannot use PCI Express without GART in FB memory\n"); |
@@ -1590,7 +1582,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1590 | 1582 | ||
1591 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | 1583 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { |
1592 | DRM_ERROR("failed to init PCI GART!\n"); | 1584 | DRM_ERROR("failed to init PCI GART!\n"); |
1593 | dev->dev_private = (void *)dev_priv; | ||
1594 | radeon_do_cleanup_cp(dev); | 1585 | radeon_do_cleanup_cp(dev); |
1595 | return DRM_ERR(ENOMEM); | 1586 | return DRM_ERR(ENOMEM); |
1596 | } | 1587 | } |
@@ -1604,8 +1595,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1604 | 1595 | ||
1605 | dev_priv->last_buf = 0; | 1596 | dev_priv->last_buf = 0; |
1606 | 1597 | ||
1607 | dev->dev_private = (void *)dev_priv; | ||
1608 | |||
1609 | radeon_do_engine_reset(dev); | 1598 | radeon_do_engine_reset(dev); |
1610 | 1599 | ||
1611 | return 0; | 1600 | return 0; |
@@ -1624,11 +1613,15 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) | |||
1624 | drm_irq_uninstall(dev); | 1613 | drm_irq_uninstall(dev); |
1625 | 1614 | ||
1626 | #if __OS_HAS_AGP | 1615 | #if __OS_HAS_AGP |
1627 | if (!dev_priv->is_pci) { | 1616 | if (dev_priv->flags & CHIP_IS_AGP) { |
1628 | if (dev_priv->cp_ring != NULL) | 1617 | if (dev_priv->cp_ring != NULL) { |
1629 | drm_core_ioremapfree(dev_priv->cp_ring, dev); | 1618 | drm_core_ioremapfree(dev_priv->cp_ring, dev); |
1630 | if (dev_priv->ring_rptr != NULL) | 1619 | dev_priv->cp_ring = NULL; |
1620 | } | ||
1621 | if (dev_priv->ring_rptr != NULL) { | ||
1631 | drm_core_ioremapfree(dev_priv->ring_rptr, dev); | 1622 | drm_core_ioremapfree(dev_priv->ring_rptr, dev); |
1623 | dev_priv->ring_rptr = NULL; | ||
1624 | } | ||
1632 | if (dev->agp_buffer_map != NULL) { | 1625 | if (dev->agp_buffer_map != NULL) { |
1633 | drm_core_ioremapfree(dev->agp_buffer_map, dev); | 1626 | drm_core_ioremapfree(dev->agp_buffer_map, dev); |
1634 | dev->agp_buffer_map = NULL; | 1627 | dev->agp_buffer_map = NULL; |
@@ -1636,17 +1629,20 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) | |||
1636 | } else | 1629 | } else |
1637 | #endif | 1630 | #endif |
1638 | { | 1631 | { |
1639 | if (dev_priv->gart_info.bus_addr) | 1632 | |
1633 | if (dev_priv->gart_info.bus_addr) { | ||
1634 | /* Turn off PCI GART */ | ||
1635 | radeon_set_pcigart(dev_priv, 0); | ||
1640 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) | 1636 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) |
1641 | DRM_ERROR("failed to cleanup PCI GART!\n"); | 1637 | DRM_ERROR("failed to cleanup PCI GART!\n"); |
1638 | } | ||
1642 | 1639 | ||
1643 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { | 1640 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) |
1644 | drm_ioremapfree((void *)dev_priv->gart_info.addr, | 1641 | { |
1645 | RADEON_PCIGART_TABLE_SIZE, dev); | 1642 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); |
1646 | dev_priv->gart_info.addr = 0; | 1643 | dev_priv->gart_info.addr = 0; |
1647 | } | 1644 | } |
1648 | } | 1645 | } |
1649 | |||
1650 | /* only clear to the start of flags */ | 1646 | /* only clear to the start of flags */ |
1651 | memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); | 1647 | memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); |
1652 | 1648 | ||
@@ -1672,7 +1668,7 @@ static int radeon_do_resume_cp(drm_device_t * dev) | |||
1672 | DRM_DEBUG("Starting radeon_do_resume_cp()\n"); | 1668 | DRM_DEBUG("Starting radeon_do_resume_cp()\n"); |
1673 | 1669 | ||
1674 | #if __OS_HAS_AGP | 1670 | #if __OS_HAS_AGP |
1675 | if (!dev_priv->is_pci) { | 1671 | if (dev_priv->flags & CHIP_IS_AGP) { |
1676 | /* Turn off PCI GART */ | 1672 | /* Turn off PCI GART */ |
1677 | radeon_set_pcigart(dev_priv, 0); | 1673 | radeon_set_pcigart(dev_priv, 0); |
1678 | } else | 1674 | } else |
@@ -2103,7 +2099,7 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS) | |||
2103 | return ret; | 2099 | return ret; |
2104 | } | 2100 | } |
2105 | 2101 | ||
2106 | int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) | 2102 | int radeon_driver_load(struct drm_device *dev, unsigned long flags) |
2107 | { | 2103 | { |
2108 | drm_radeon_private_t *dev_priv; | 2104 | drm_radeon_private_t *dev_priv; |
2109 | int ret = 0; | 2105 | int ret = 0; |
@@ -2136,11 +2132,14 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) | |||
2136 | dev_priv->flags |= CHIP_IS_PCIE; | 2132 | dev_priv->flags |= CHIP_IS_PCIE; |
2137 | 2133 | ||
2138 | DRM_DEBUG("%s card detected\n", | 2134 | DRM_DEBUG("%s card detected\n", |
2139 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); | 2135 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); |
2140 | return ret; | 2136 | return ret; |
2141 | } | 2137 | } |
2142 | 2138 | ||
2143 | int radeon_presetup(struct drm_device *dev) | 2139 | /* Create mappings for registers and framebuffer so userland doesn't necessarily |
2140 | * have to find them. | ||
2141 | */ | ||
2142 | int radeon_driver_firstopen(struct drm_device *dev) | ||
2144 | { | 2143 | { |
2145 | int ret; | 2144 | int ret; |
2146 | drm_local_map_t *map; | 2145 | drm_local_map_t *map; |
@@ -2161,12 +2160,11 @@ int radeon_presetup(struct drm_device *dev) | |||
2161 | return 0; | 2160 | return 0; |
2162 | } | 2161 | } |
2163 | 2162 | ||
2164 | int radeon_driver_postcleanup(struct drm_device *dev) | 2163 | int radeon_driver_unload(struct drm_device *dev) |
2165 | { | 2164 | { |
2166 | drm_radeon_private_t *dev_priv = dev->dev_private; | 2165 | drm_radeon_private_t *dev_priv = dev->dev_private; |
2167 | 2166 | ||
2168 | DRM_DEBUG("\n"); | 2167 | DRM_DEBUG("\n"); |
2169 | |||
2170 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 2168 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); |
2171 | 2169 | ||
2172 | dev->dev_private = NULL; | 2170 | dev->dev_private = NULL; |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 1cd81a671a36..9c177a6b2a4c 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
@@ -624,6 +624,11 @@ typedef struct drm_radeon_indirect { | |||
624 | int discard; | 624 | int discard; |
625 | } drm_radeon_indirect_t; | 625 | } drm_radeon_indirect_t; |
626 | 626 | ||
627 | /* enum for card type parameters */ | ||
628 | #define RADEON_CARD_PCI 0 | ||
629 | #define RADEON_CARD_AGP 1 | ||
630 | #define RADEON_CARD_PCIE 2 | ||
631 | |||
627 | /* 1.3: An ioctl to get parameters that aren't available to the 3d | 632 | /* 1.3: An ioctl to get parameters that aren't available to the 3d |
628 | * client any other way. | 633 | * client any other way. |
629 | */ | 634 | */ |
@@ -640,6 +645,7 @@ typedef struct drm_radeon_indirect { | |||
640 | #define RADEON_PARAM_SAREA_HANDLE 9 | 645 | #define RADEON_PARAM_SAREA_HANDLE 9 |
641 | #define RADEON_PARAM_GART_TEX_HANDLE 10 | 646 | #define RADEON_PARAM_GART_TEX_HANDLE 10 |
642 | #define RADEON_PARAM_SCRATCH_OFFSET 11 | 647 | #define RADEON_PARAM_SCRATCH_OFFSET 11 |
648 | #define RADEON_PARAM_CARD_TYPE 12 | ||
643 | 649 | ||
644 | typedef struct drm_radeon_getparam { | 650 | typedef struct drm_radeon_getparam { |
645 | int param; | 651 | int param; |
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index ee49670d8162..b04ed1b562b9 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c | |||
@@ -42,29 +42,15 @@ int radeon_no_wb; | |||
42 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); | 42 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); |
43 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 43 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
44 | 44 | ||
45 | static int postinit(struct drm_device *dev, unsigned long flags) | 45 | static int dri_library_name(struct drm_device *dev, char *buf) |
46 | { | 46 | { |
47 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | 47 | drm_radeon_private_t *dev_priv = dev->dev_private; |
48 | DRIVER_NAME, | 48 | int family = dev_priv->flags & CHIP_FAMILY_MASK; |
49 | DRIVER_MAJOR, | ||
50 | DRIVER_MINOR, | ||
51 | DRIVER_PATCHLEVEL, | ||
52 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
53 | ); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int version(drm_version_t * version) | ||
58 | { | ||
59 | int len; | ||
60 | 49 | ||
61 | version->version_major = DRIVER_MAJOR; | 50 | return snprintf(buf, PAGE_SIZE, "%s\n", |
62 | version->version_minor = DRIVER_MINOR; | 51 | (family < CHIP_R200) ? "radeon" : |
63 | version->version_patchlevel = DRIVER_PATCHLEVEL; | 52 | ((family < CHIP_R300) ? "r200" : |
64 | DRM_COPY(version->name, DRIVER_NAME); | 53 | "r300")); |
65 | DRM_COPY(version->date, DRIVER_DATE); | ||
66 | DRM_COPY(version->desc, DRIVER_DESC); | ||
67 | return 0; | ||
68 | } | 54 | } |
69 | 55 | ||
70 | static struct pci_device_id pciidlist[] = { | 56 | static struct pci_device_id pciidlist[] = { |
@@ -77,23 +63,22 @@ static struct drm_driver driver = { | |||
77 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | | 63 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | |
78 | DRIVER_IRQ_VBL, | 64 | DRIVER_IRQ_VBL, |
79 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 65 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
80 | .preinit = radeon_driver_preinit, | 66 | .load = radeon_driver_load, |
81 | .presetup = radeon_presetup, | 67 | .firstopen = radeon_driver_firstopen, |
82 | .postcleanup = radeon_driver_postcleanup, | 68 | .open = radeon_driver_open, |
83 | .prerelease = radeon_driver_prerelease, | 69 | .preclose = radeon_driver_preclose, |
84 | .pretakedown = radeon_driver_pretakedown, | 70 | .postclose = radeon_driver_postclose, |
85 | .open_helper = radeon_driver_open_helper, | 71 | .lastclose = radeon_driver_lastclose, |
72 | .unload = radeon_driver_unload, | ||
86 | .vblank_wait = radeon_driver_vblank_wait, | 73 | .vblank_wait = radeon_driver_vblank_wait, |
74 | .dri_library_name = dri_library_name, | ||
87 | .irq_preinstall = radeon_driver_irq_preinstall, | 75 | .irq_preinstall = radeon_driver_irq_preinstall, |
88 | .irq_postinstall = radeon_driver_irq_postinstall, | 76 | .irq_postinstall = radeon_driver_irq_postinstall, |
89 | .irq_uninstall = radeon_driver_irq_uninstall, | 77 | .irq_uninstall = radeon_driver_irq_uninstall, |
90 | .irq_handler = radeon_driver_irq_handler, | 78 | .irq_handler = radeon_driver_irq_handler, |
91 | .free_filp_priv = radeon_driver_free_filp_priv, | ||
92 | .reclaim_buffers = drm_core_reclaim_buffers, | 79 | .reclaim_buffers = drm_core_reclaim_buffers, |
93 | .get_map_ofs = drm_core_get_map_ofs, | 80 | .get_map_ofs = drm_core_get_map_ofs, |
94 | .get_reg_ofs = drm_core_get_reg_ofs, | 81 | .get_reg_ofs = drm_core_get_reg_ofs, |
95 | .postinit = postinit, | ||
96 | .version = version, | ||
97 | .ioctls = radeon_ioctls, | 82 | .ioctls = radeon_ioctls, |
98 | .dma_ioctl = radeon_cp_buffers, | 83 | .dma_ioctl = radeon_cp_buffers, |
99 | .fops = { | 84 | .fops = { |
@@ -107,12 +92,19 @@ static struct drm_driver driver = { | |||
107 | #ifdef CONFIG_COMPAT | 92 | #ifdef CONFIG_COMPAT |
108 | .compat_ioctl = radeon_compat_ioctl, | 93 | .compat_ioctl = radeon_compat_ioctl, |
109 | #endif | 94 | #endif |
110 | } | 95 | }, |
111 | , | 96 | |
112 | .pci_driver = { | 97 | .pci_driver = { |
113 | .name = DRIVER_NAME, | 98 | .name = DRIVER_NAME, |
114 | .id_table = pciidlist, | 99 | .id_table = pciidlist, |
115 | } | 100 | }, |
101 | |||
102 | .name = DRIVER_NAME, | ||
103 | .desc = DRIVER_DESC, | ||
104 | .date = DRIVER_DATE, | ||
105 | .major = DRIVER_MAJOR, | ||
106 | .minor = DRIVER_MINOR, | ||
107 | .patchlevel = DRIVER_PATCHLEVEL, | ||
116 | }; | 108 | }; |
117 | 109 | ||
118 | static int __init radeon_init(void) | 110 | static int __init radeon_init(void) |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index d92ccee3e54c..498b19b1d641 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define DRIVER_NAME "radeon" | 39 | #define DRIVER_NAME "radeon" |
40 | #define DRIVER_DESC "ATI Radeon" | 40 | #define DRIVER_DESC "ATI Radeon" |
41 | #define DRIVER_DATE "20050911" | 41 | #define DRIVER_DATE "20051229" |
42 | 42 | ||
43 | /* Interface history: | 43 | /* Interface history: |
44 | * | 44 | * |
@@ -73,7 +73,7 @@ | |||
73 | * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color | 73 | * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color |
74 | * and GL_EXT_blend_[func|equation]_separate on r200 | 74 | * and GL_EXT_blend_[func|equation]_separate on r200 |
75 | * 1.12- Add R300 CP microcode support - this just loads the CP on r300 | 75 | * 1.12- Add R300 CP microcode support - this just loads the CP on r300 |
76 | * (No 3D support yet - just microcode loading) | 76 | * (No 3D support yet - just microcode loading). |
77 | * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters | 77 | * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters |
78 | * - Add hyperz support, add hyperz flags to clear ioctl. | 78 | * - Add hyperz support, add hyperz flags to clear ioctl. |
79 | * 1.14- Add support for color tiling | 79 | * 1.14- Add support for color tiling |
@@ -88,14 +88,13 @@ | |||
88 | * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR | 88 | * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR |
89 | * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) | 89 | * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) |
90 | * 1.19- Add support for gart table in FB memory and PCIE r300 | 90 | * 1.19- Add support for gart table in FB memory and PCIE r300 |
91 | * 1.20- Add support for r300 texrect | ||
92 | * 1.21- Add support for card type getparam | ||
91 | */ | 93 | */ |
92 | #define DRIVER_MAJOR 1 | 94 | #define DRIVER_MAJOR 1 |
93 | #define DRIVER_MINOR 19 | 95 | #define DRIVER_MINOR 21 |
94 | #define DRIVER_PATCHLEVEL 0 | 96 | #define DRIVER_PATCHLEVEL 0 |
95 | 97 | ||
96 | #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) | ||
97 | #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) | ||
98 | |||
99 | /* | 98 | /* |
100 | * Radeon chip families | 99 | * Radeon chip families |
101 | */ | 100 | */ |
@@ -103,8 +102,8 @@ enum radeon_family { | |||
103 | CHIP_R100, | 102 | CHIP_R100, |
104 | CHIP_RS100, | 103 | CHIP_RS100, |
105 | CHIP_RV100, | 104 | CHIP_RV100, |
106 | CHIP_R200, | ||
107 | CHIP_RV200, | 105 | CHIP_RV200, |
106 | CHIP_R200, | ||
108 | CHIP_RS200, | 107 | CHIP_RS200, |
109 | CHIP_R250, | 108 | CHIP_R250, |
110 | CHIP_RS250, | 109 | CHIP_RS250, |
@@ -138,6 +137,9 @@ enum radeon_chip_flags { | |||
138 | CHIP_IS_PCIE = 0x00200000UL, | 137 | CHIP_IS_PCIE = 0x00200000UL, |
139 | }; | 138 | }; |
140 | 139 | ||
140 | #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) | ||
141 | #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) | ||
142 | |||
141 | typedef struct drm_radeon_freelist { | 143 | typedef struct drm_radeon_freelist { |
142 | unsigned int age; | 144 | unsigned int age; |
143 | drm_buf_t *buf; | 145 | drm_buf_t *buf; |
@@ -245,8 +247,6 @@ typedef struct drm_radeon_private { | |||
245 | 247 | ||
246 | drm_radeon_depth_clear_t depth_clear; | 248 | drm_radeon_depth_clear_t depth_clear; |
247 | 249 | ||
248 | unsigned long fb_offset; | ||
249 | unsigned long mmio_offset; | ||
250 | unsigned long ring_offset; | 250 | unsigned long ring_offset; |
251 | unsigned long ring_rptr_offset; | 251 | unsigned long ring_rptr_offset; |
252 | unsigned long buffers_offset; | 252 | unsigned long buffers_offset; |
@@ -273,7 +273,6 @@ typedef struct drm_radeon_private { | |||
273 | 273 | ||
274 | /* starting from here on, data is preserved accross an open */ | 274 | /* starting from here on, data is preserved accross an open */ |
275 | uint32_t flags; /* see radeon_chip_flags */ | 275 | uint32_t flags; /* see radeon_chip_flags */ |
276 | int is_pci; | ||
277 | } drm_radeon_private_t; | 276 | } drm_radeon_private_t; |
278 | 277 | ||
279 | typedef struct drm_radeon_buf_priv { | 278 | typedef struct drm_radeon_buf_priv { |
@@ -330,17 +329,14 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); | |||
330 | extern void radeon_driver_irq_preinstall(drm_device_t * dev); | 329 | extern void radeon_driver_irq_preinstall(drm_device_t * dev); |
331 | extern void radeon_driver_irq_postinstall(drm_device_t * dev); | 330 | extern void radeon_driver_irq_postinstall(drm_device_t * dev); |
332 | extern void radeon_driver_irq_uninstall(drm_device_t * dev); | 331 | extern void radeon_driver_irq_uninstall(drm_device_t * dev); |
333 | extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp); | ||
334 | extern void radeon_driver_pretakedown(drm_device_t * dev); | ||
335 | extern int radeon_driver_open_helper(drm_device_t * dev, | ||
336 | drm_file_t * filp_priv); | ||
337 | extern void radeon_driver_free_filp_priv(drm_device_t * dev, | ||
338 | drm_file_t * filp_priv); | ||
339 | |||
340 | extern int radeon_preinit(struct drm_device *dev, unsigned long flags); | ||
341 | extern int radeon_postinit(struct drm_device *dev, unsigned long flags); | ||
342 | extern int radeon_postcleanup(struct drm_device *dev); | ||
343 | 332 | ||
333 | extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); | ||
334 | extern int radeon_driver_unload(struct drm_device *dev); | ||
335 | extern int radeon_driver_firstopen(struct drm_device *dev); | ||
336 | extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp); | ||
337 | extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp); | ||
338 | extern void radeon_driver_lastclose(drm_device_t * dev); | ||
339 | extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv); | ||
344 | extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, | 340 | extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, |
345 | unsigned long arg); | 341 | unsigned long arg); |
346 | 342 | ||
@@ -364,6 +360,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
364 | */ | 360 | */ |
365 | 361 | ||
366 | #define RADEON_AGP_COMMAND 0x0f60 | 362 | #define RADEON_AGP_COMMAND 0x0f60 |
363 | #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ | ||
364 | # define RADEON_AGP_ENABLE (1<<8) | ||
367 | #define RADEON_AUX_SCISSOR_CNTL 0x26f0 | 365 | #define RADEON_AUX_SCISSOR_CNTL 0x26f0 |
368 | # define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) | 366 | # define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) |
369 | # define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) | 367 | # define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) |
@@ -651,6 +649,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
651 | 649 | ||
652 | #define RADEON_WAIT_UNTIL 0x1720 | 650 | #define RADEON_WAIT_UNTIL 0x1720 |
653 | # define RADEON_WAIT_CRTC_PFLIP (1 << 0) | 651 | # define RADEON_WAIT_CRTC_PFLIP (1 << 0) |
652 | # define RADEON_WAIT_2D_IDLE (1 << 14) | ||
653 | # define RADEON_WAIT_3D_IDLE (1 << 15) | ||
654 | # define RADEON_WAIT_2D_IDLECLEAN (1 << 16) | 654 | # define RADEON_WAIT_2D_IDLECLEAN (1 << 16) |
655 | # define RADEON_WAIT_3D_IDLECLEAN (1 << 17) | 655 | # define RADEON_WAIT_3D_IDLECLEAN (1 << 17) |
656 | # define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) | 656 | # define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) |
@@ -1105,7 +1105,6 @@ do { \ | |||
1105 | write = 0; \ | 1105 | write = 0; \ |
1106 | _tab += _i; \ | 1106 | _tab += _i; \ |
1107 | } \ | 1107 | } \ |
1108 | \ | ||
1109 | while (_size > 0) { \ | 1108 | while (_size > 0) { \ |
1110 | *(ring + write) = *_tab++; \ | 1109 | *(ring + write) = *_tab++; \ |
1111 | write++; \ | 1110 | write++; \ |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 231ac1438c69..7bc27516d425 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* radeon_state.c -- State support for Radeon -*- linux-c -*- | 1 | /* radeon_state.c -- State support for Radeon -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright 2000 VA Linux Systems, Inc., Fremont, California. | 3 | * Copyright 2000 VA Linux Systems, Inc., Fremont, California. |
4 | * All Rights Reserved. | 4 | * All Rights Reserved. |
5 | * | 5 | * |
@@ -72,10 +72,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | |||
72 | 72 | ||
73 | case RADEON_EMIT_PP_MISC: | 73 | case RADEON_EMIT_PP_MISC: |
74 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, | 74 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, |
75 | &data[(RADEON_RB3D_DEPTHOFFSET | 75 | &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) { |
76 | - | ||
77 | RADEON_PP_MISC) / | ||
78 | 4])) { | ||
79 | DRM_ERROR("Invalid depth buffer offset\n"); | 76 | DRM_ERROR("Invalid depth buffer offset\n"); |
80 | return DRM_ERR(EINVAL); | 77 | return DRM_ERR(EINVAL); |
81 | } | 78 | } |
@@ -83,10 +80,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | |||
83 | 80 | ||
84 | case RADEON_EMIT_PP_CNTL: | 81 | case RADEON_EMIT_PP_CNTL: |
85 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, | 82 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, |
86 | &data[(RADEON_RB3D_COLOROFFSET | 83 | &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) { |
87 | - | ||
88 | RADEON_PP_CNTL) / | ||
89 | 4])) { | ||
90 | DRM_ERROR("Invalid colour buffer offset\n"); | 84 | DRM_ERROR("Invalid colour buffer offset\n"); |
91 | return DRM_ERR(EINVAL); | 85 | return DRM_ERR(EINVAL); |
92 | } | 86 | } |
@@ -109,10 +103,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | |||
109 | case RADEON_EMIT_PP_TXFILTER_1: | 103 | case RADEON_EMIT_PP_TXFILTER_1: |
110 | case RADEON_EMIT_PP_TXFILTER_2: | 104 | case RADEON_EMIT_PP_TXFILTER_2: |
111 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, | 105 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, |
112 | &data[(RADEON_PP_TXOFFSET_0 | 106 | &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) { |
113 | - | ||
114 | RADEON_PP_TXFILTER_0) / | ||
115 | 4])) { | ||
116 | DRM_ERROR("Invalid R100 texture offset\n"); | 107 | DRM_ERROR("Invalid R100 texture offset\n"); |
117 | return DRM_ERR(EINVAL); | 108 | return DRM_ERR(EINVAL); |
118 | } | 109 | } |
@@ -126,8 +117,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | |||
126 | case R200_EMIT_PP_CUBIC_OFFSETS_5:{ | 117 | case R200_EMIT_PP_CUBIC_OFFSETS_5:{ |
127 | int i; | 118 | int i; |
128 | for (i = 0; i < 5; i++) { | 119 | for (i = 0; i < 5; i++) { |
129 | if (radeon_check_and_fixup_offset | 120 | if (radeon_check_and_fixup_offset(dev_priv, |
130 | (dev_priv, filp_priv, &data[i])) { | 121 | filp_priv, |
122 | &data[i])) { | ||
131 | DRM_ERROR | 123 | DRM_ERROR |
132 | ("Invalid R200 cubic texture offset\n"); | 124 | ("Invalid R200 cubic texture offset\n"); |
133 | return DRM_ERR(EINVAL); | 125 | return DRM_ERR(EINVAL); |
@@ -239,8 +231,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | |||
239 | 231 | ||
240 | static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | 232 | static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * |
241 | dev_priv, | 233 | dev_priv, |
242 | drm_file_t * filp_priv, | 234 | drm_file_t *filp_priv, |
243 | drm_radeon_kcmd_buffer_t *cmdbuf, | 235 | drm_radeon_kcmd_buffer_t * |
236 | cmdbuf, | ||
244 | unsigned int *cmdsz) | 237 | unsigned int *cmdsz) |
245 | { | 238 | { |
246 | u32 *cmd = (u32 *) cmdbuf->buf; | 239 | u32 *cmd = (u32 *) cmdbuf->buf; |
@@ -555,7 +548,8 @@ static struct { | |||
555 | {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, | 548 | {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, |
556 | {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, | 549 | {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, |
557 | {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, | 550 | {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, |
558 | {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, | 551 | {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, |
552 | "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, | ||
559 | {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, | 553 | {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, |
560 | {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, | 554 | {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, |
561 | {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, | 555 | {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, |
@@ -569,7 +563,7 @@ static struct { | |||
569 | {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, | 563 | {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, |
570 | "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, | 564 | "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, |
571 | {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ | 565 | {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ |
572 | {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ | 566 | {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ |
573 | {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, | 567 | {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, |
574 | {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, | 568 | {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, |
575 | {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, | 569 | {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, |
@@ -592,7 +586,7 @@ static struct { | |||
592 | {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, | 586 | {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, |
593 | {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, | 587 | {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, |
594 | {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, | 588 | {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, |
595 | {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ | 589 | {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ |
596 | {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, | 590 | {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, |
597 | {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, | 591 | {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, |
598 | {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, | 592 | {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, |
@@ -985,8 +979,8 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, | |||
985 | * rendering a quad into just those buffers. Thus, we have to | 979 | * rendering a quad into just those buffers. Thus, we have to |
986 | * make sure the 3D engine is configured correctly. | 980 | * make sure the 3D engine is configured correctly. |
987 | */ | 981 | */ |
988 | if ((dev_priv->microcode_version == UCODE_R200) && | 982 | else if ((dev_priv->microcode_version == UCODE_R200) && |
989 | (flags & (RADEON_DEPTH | RADEON_STENCIL))) { | 983 | (flags & (RADEON_DEPTH | RADEON_STENCIL))) { |
990 | 984 | ||
991 | int tempPP_CNTL; | 985 | int tempPP_CNTL; |
992 | int tempRE_CNTL; | 986 | int tempRE_CNTL; |
@@ -1637,6 +1631,14 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, | |||
1637 | (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); | 1631 | (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); |
1638 | dwords = size / 4; | 1632 | dwords = size / 4; |
1639 | 1633 | ||
1634 | #define RADEON_COPY_MT(_buf, _data, _width) \ | ||
1635 | do { \ | ||
1636 | if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ | ||
1637 | DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ | ||
1638 | return DRM_ERR(EFAULT); \ | ||
1639 | } \ | ||
1640 | } while(0) | ||
1641 | |||
1640 | if (microtile) { | 1642 | if (microtile) { |
1641 | /* texture micro tiling in use, minimum texture width is thus 16 bytes. | 1643 | /* texture micro tiling in use, minimum texture width is thus 16 bytes. |
1642 | however, we cannot use blitter directly for texture width < 64 bytes, | 1644 | however, we cannot use blitter directly for texture width < 64 bytes, |
@@ -1648,46 +1650,19 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, | |||
1648 | from user space. */ | 1650 | from user space. */ |
1649 | if (tex->height == 1) { | 1651 | if (tex->height == 1) { |
1650 | if (tex_width >= 64 || tex_width <= 16) { | 1652 | if (tex_width >= 64 || tex_width <= 16) { |
1651 | if (DRM_COPY_FROM_USER(buffer, data, | 1653 | RADEON_COPY_MT(buffer, data, |
1652 | tex_width * | 1654 | (int)(tex_width * sizeof(u32))); |
1653 | sizeof(u32))) { | ||
1654 | DRM_ERROR | ||
1655 | ("EFAULT on pad, %d bytes\n", | ||
1656 | tex_width); | ||
1657 | return DRM_ERR(EFAULT); | ||
1658 | } | ||
1659 | } else if (tex_width == 32) { | 1655 | } else if (tex_width == 32) { |
1660 | if (DRM_COPY_FROM_USER | 1656 | RADEON_COPY_MT(buffer, data, 16); |
1661 | (buffer, data, 16)) { | 1657 | RADEON_COPY_MT(buffer + 8, |
1662 | DRM_ERROR | 1658 | data + 16, 16); |
1663 | ("EFAULT on pad, %d bytes\n", | ||
1664 | tex_width); | ||
1665 | return DRM_ERR(EFAULT); | ||
1666 | } | ||
1667 | if (DRM_COPY_FROM_USER | ||
1668 | (buffer + 8, data + 16, 16)) { | ||
1669 | DRM_ERROR | ||
1670 | ("EFAULT on pad, %d bytes\n", | ||
1671 | tex_width); | ||
1672 | return DRM_ERR(EFAULT); | ||
1673 | } | ||
1674 | } | 1659 | } |
1675 | } else if (tex_width >= 64 || tex_width == 16) { | 1660 | } else if (tex_width >= 64 || tex_width == 16) { |
1676 | if (DRM_COPY_FROM_USER(buffer, data, | 1661 | RADEON_COPY_MT(buffer, data, |
1677 | dwords * sizeof(u32))) { | 1662 | (int)(dwords * sizeof(u32))); |
1678 | DRM_ERROR("EFAULT on data, %d dwords\n", | ||
1679 | dwords); | ||
1680 | return DRM_ERR(EFAULT); | ||
1681 | } | ||
1682 | } else if (tex_width < 16) { | 1663 | } else if (tex_width < 16) { |
1683 | for (i = 0; i < tex->height; i++) { | 1664 | for (i = 0; i < tex->height; i++) { |
1684 | if (DRM_COPY_FROM_USER | 1665 | RADEON_COPY_MT(buffer, data, tex_width); |
1685 | (buffer, data, tex_width)) { | ||
1686 | DRM_ERROR | ||
1687 | ("EFAULT on pad, %d bytes\n", | ||
1688 | tex_width); | ||
1689 | return DRM_ERR(EFAULT); | ||
1690 | } | ||
1691 | buffer += 4; | 1666 | buffer += 4; |
1692 | data += tex_width; | 1667 | data += tex_width; |
1693 | } | 1668 | } |
@@ -1695,37 +1670,13 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, | |||
1695 | /* TODO: make sure this works when not fitting in one buffer | 1670 | /* TODO: make sure this works when not fitting in one buffer |
1696 | (i.e. 32bytes x 2048...) */ | 1671 | (i.e. 32bytes x 2048...) */ |
1697 | for (i = 0; i < tex->height; i += 2) { | 1672 | for (i = 0; i < tex->height; i += 2) { |
1698 | if (DRM_COPY_FROM_USER | 1673 | RADEON_COPY_MT(buffer, data, 16); |
1699 | (buffer, data, 16)) { | ||
1700 | DRM_ERROR | ||
1701 | ("EFAULT on pad, %d bytes\n", | ||
1702 | tex_width); | ||
1703 | return DRM_ERR(EFAULT); | ||
1704 | } | ||
1705 | data += 16; | 1674 | data += 16; |
1706 | if (DRM_COPY_FROM_USER | 1675 | RADEON_COPY_MT(buffer + 8, data, 16); |
1707 | (buffer + 8, data, 16)) { | ||
1708 | DRM_ERROR | ||
1709 | ("EFAULT on pad, %d bytes\n", | ||
1710 | tex_width); | ||
1711 | return DRM_ERR(EFAULT); | ||
1712 | } | ||
1713 | data += 16; | 1676 | data += 16; |
1714 | if (DRM_COPY_FROM_USER | 1677 | RADEON_COPY_MT(buffer + 4, data, 16); |
1715 | (buffer + 4, data, 16)) { | ||
1716 | DRM_ERROR | ||
1717 | ("EFAULT on pad, %d bytes\n", | ||
1718 | tex_width); | ||
1719 | return DRM_ERR(EFAULT); | ||
1720 | } | ||
1721 | data += 16; | 1678 | data += 16; |
1722 | if (DRM_COPY_FROM_USER | 1679 | RADEON_COPY_MT(buffer + 12, data, 16); |
1723 | (buffer + 12, data, 16)) { | ||
1724 | DRM_ERROR | ||
1725 | ("EFAULT on pad, %d bytes\n", | ||
1726 | tex_width); | ||
1727 | return DRM_ERR(EFAULT); | ||
1728 | } | ||
1729 | data += 16; | 1680 | data += 16; |
1730 | buffer += 16; | 1681 | buffer += 16; |
1731 | } | 1682 | } |
@@ -1735,31 +1686,22 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, | |||
1735 | /* Texture image width is larger than the minimum, so we | 1686 | /* Texture image width is larger than the minimum, so we |
1736 | * can upload it directly. | 1687 | * can upload it directly. |
1737 | */ | 1688 | */ |
1738 | if (DRM_COPY_FROM_USER(buffer, data, | 1689 | RADEON_COPY_MT(buffer, data, |
1739 | dwords * sizeof(u32))) { | 1690 | (int)(dwords * sizeof(u32))); |
1740 | DRM_ERROR("EFAULT on data, %d dwords\n", | ||
1741 | dwords); | ||
1742 | return DRM_ERR(EFAULT); | ||
1743 | } | ||
1744 | } else { | 1691 | } else { |
1745 | /* Texture image width is less than the minimum, so we | 1692 | /* Texture image width is less than the minimum, so we |
1746 | * need to pad out each image scanline to the minimum | 1693 | * need to pad out each image scanline to the minimum |
1747 | * width. | 1694 | * width. |
1748 | */ | 1695 | */ |
1749 | for (i = 0; i < tex->height; i++) { | 1696 | for (i = 0; i < tex->height; i++) { |
1750 | if (DRM_COPY_FROM_USER | 1697 | RADEON_COPY_MT(buffer, data, tex_width); |
1751 | (buffer, data, tex_width)) { | ||
1752 | DRM_ERROR | ||
1753 | ("EFAULT on pad, %d bytes\n", | ||
1754 | tex_width); | ||
1755 | return DRM_ERR(EFAULT); | ||
1756 | } | ||
1757 | buffer += 8; | 1698 | buffer += 8; |
1758 | data += tex_width; | 1699 | data += tex_width; |
1759 | } | 1700 | } |
1760 | } | 1701 | } |
1761 | } | 1702 | } |
1762 | 1703 | ||
1704 | #undef RADEON_COPY_MT | ||
1763 | buf->filp = filp; | 1705 | buf->filp = filp; |
1764 | buf->used = size; | 1706 | buf->used = size; |
1765 | offset = dev_priv->gart_buffers_offset + buf->offset; | 1707 | offset = dev_priv->gart_buffers_offset + buf->offset; |
@@ -1821,7 +1763,7 @@ static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple) | |||
1821 | } | 1763 | } |
1822 | 1764 | ||
1823 | static void radeon_apply_surface_regs(int surf_index, | 1765 | static void radeon_apply_surface_regs(int surf_index, |
1824 | drm_radeon_private_t * dev_priv) | 1766 | drm_radeon_private_t *dev_priv) |
1825 | { | 1767 | { |
1826 | if (!dev_priv->mmio) | 1768 | if (!dev_priv->mmio) |
1827 | return; | 1769 | return; |
@@ -1847,8 +1789,8 @@ static void radeon_apply_surface_regs(int surf_index, | |||
1847 | * freed, we suddenly need two surfaces to store A and C, which might | 1789 | * freed, we suddenly need two surfaces to store A and C, which might |
1848 | * not always be available. | 1790 | * not always be available. |
1849 | */ | 1791 | */ |
1850 | static int alloc_surface(drm_radeon_surface_alloc_t * new, | 1792 | static int alloc_surface(drm_radeon_surface_alloc_t *new, |
1851 | drm_radeon_private_t * dev_priv, DRMFILE filp) | 1793 | drm_radeon_private_t *dev_priv, DRMFILE filp) |
1852 | { | 1794 | { |
1853 | struct radeon_virt_surface *s; | 1795 | struct radeon_virt_surface *s; |
1854 | int i; | 1796 | int i; |
@@ -2158,6 +2100,11 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) | |||
2158 | 2100 | ||
2159 | LOCK_TEST_WITH_RETURN(dev, filp); | 2101 | LOCK_TEST_WITH_RETURN(dev, filp); |
2160 | 2102 | ||
2103 | if (!dev_priv) { | ||
2104 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2105 | return DRM_ERR(EINVAL); | ||
2106 | } | ||
2107 | |||
2161 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2108 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2162 | 2109 | ||
2163 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, | 2110 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, |
@@ -2596,9 +2543,9 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, | |||
2596 | return 0; | 2543 | return 0; |
2597 | } | 2544 | } |
2598 | 2545 | ||
2599 | static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, | 2546 | static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, |
2600 | drm_radeon_cmd_header_t header, | 2547 | drm_radeon_cmd_header_t header, |
2601 | drm_radeon_kcmd_buffer_t * cmdbuf) | 2548 | drm_radeon_kcmd_buffer_t *cmdbuf) |
2602 | { | 2549 | { |
2603 | int sz = header.scalars.count; | 2550 | int sz = header.scalars.count; |
2604 | int start = header.scalars.offset; | 2551 | int start = header.scalars.offset; |
@@ -2618,9 +2565,9 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, | |||
2618 | 2565 | ||
2619 | /* God this is ugly | 2566 | /* God this is ugly |
2620 | */ | 2567 | */ |
2621 | static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, | 2568 | static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, |
2622 | drm_radeon_cmd_header_t header, | 2569 | drm_radeon_cmd_header_t header, |
2623 | drm_radeon_kcmd_buffer_t * cmdbuf) | 2570 | drm_radeon_kcmd_buffer_t *cmdbuf) |
2624 | { | 2571 | { |
2625 | int sz = header.scalars.count; | 2572 | int sz = header.scalars.count; |
2626 | int start = ((unsigned int)header.scalars.offset) + 0x100; | 2573 | int start = ((unsigned int)header.scalars.offset) + 0x100; |
@@ -2638,9 +2585,9 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, | |||
2638 | return 0; | 2585 | return 0; |
2639 | } | 2586 | } |
2640 | 2587 | ||
2641 | static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, | 2588 | static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, |
2642 | drm_radeon_cmd_header_t header, | 2589 | drm_radeon_cmd_header_t header, |
2643 | drm_radeon_kcmd_buffer_t * cmdbuf) | 2590 | drm_radeon_kcmd_buffer_t *cmdbuf) |
2644 | { | 2591 | { |
2645 | int sz = header.vectors.count; | 2592 | int sz = header.vectors.count; |
2646 | int start = header.vectors.offset; | 2593 | int start = header.vectors.offset; |
@@ -2685,8 +2632,8 @@ static int radeon_emit_packet3(drm_device_t * dev, | |||
2685 | return 0; | 2632 | return 0; |
2686 | } | 2633 | } |
2687 | 2634 | ||
2688 | static int radeon_emit_packet3_cliprect(drm_device_t * dev, | 2635 | static int radeon_emit_packet3_cliprect(drm_device_t *dev, |
2689 | drm_file_t * filp_priv, | 2636 | drm_file_t *filp_priv, |
2690 | drm_radeon_kcmd_buffer_t *cmdbuf, | 2637 | drm_radeon_kcmd_buffer_t *cmdbuf, |
2691 | int orig_nbox) | 2638 | int orig_nbox) |
2692 | { | 2639 | { |
@@ -2818,7 +2765,8 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) | |||
2818 | kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); | 2765 | kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); |
2819 | if (kbuf == NULL) | 2766 | if (kbuf == NULL) |
2820 | return DRM_ERR(ENOMEM); | 2767 | return DRM_ERR(ENOMEM); |
2821 | if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) { | 2768 | if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, |
2769 | cmdbuf.bufsz)) { | ||
2822 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | 2770 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); |
2823 | return DRM_ERR(EFAULT); | 2771 | return DRM_ERR(EFAULT); |
2824 | } | 2772 | } |
@@ -2981,7 +2929,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) | |||
2981 | value = dev_priv->gart_vm_start; | 2929 | value = dev_priv->gart_vm_start; |
2982 | break; | 2930 | break; |
2983 | case RADEON_PARAM_REGISTER_HANDLE: | 2931 | case RADEON_PARAM_REGISTER_HANDLE: |
2984 | value = dev_priv->mmio_offset; | 2932 | value = dev_priv->mmio->offset; |
2985 | break; | 2933 | break; |
2986 | case RADEON_PARAM_STATUS_HANDLE: | 2934 | case RADEON_PARAM_STATUS_HANDLE: |
2987 | value = dev_priv->ring_rptr_offset; | 2935 | value = dev_priv->ring_rptr_offset; |
@@ -3004,6 +2952,15 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) | |||
3004 | case RADEON_PARAM_GART_TEX_HANDLE: | 2952 | case RADEON_PARAM_GART_TEX_HANDLE: |
3005 | value = dev_priv->gart_textures_offset; | 2953 | value = dev_priv->gart_textures_offset; |
3006 | break; | 2954 | break; |
2955 | |||
2956 | case RADEON_PARAM_CARD_TYPE: | ||
2957 | if (dev_priv->flags & CHIP_IS_PCIE) | ||
2958 | value = RADEON_CARD_PCIE; | ||
2959 | else if (dev_priv->flags & CHIP_IS_AGP) | ||
2960 | value = RADEON_CARD_AGP; | ||
2961 | else | ||
2962 | value = RADEON_CARD_PCI; | ||
2963 | break; | ||
3007 | default: | 2964 | default: |
3008 | return DRM_ERR(EINVAL); | 2965 | return DRM_ERR(EINVAL); |
3009 | } | 2966 | } |
@@ -3066,10 +3023,11 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
3066 | /* When a client dies: | 3023 | /* When a client dies: |
3067 | * - Check for and clean up flipped page state | 3024 | * - Check for and clean up flipped page state |
3068 | * - Free any alloced GART memory. | 3025 | * - Free any alloced GART memory. |
3026 | * - Free any alloced radeon surfaces. | ||
3069 | * | 3027 | * |
3070 | * DRM infrastructure takes care of reclaiming dma buffers. | 3028 | * DRM infrastructure takes care of reclaiming dma buffers. |
3071 | */ | 3029 | */ |
3072 | void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) | 3030 | void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) |
3073 | { | 3031 | { |
3074 | if (dev->dev_private) { | 3032 | if (dev->dev_private) { |
3075 | drm_radeon_private_t *dev_priv = dev->dev_private; | 3033 | drm_radeon_private_t *dev_priv = dev->dev_private; |
@@ -3082,16 +3040,17 @@ void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) | |||
3082 | } | 3040 | } |
3083 | } | 3041 | } |
3084 | 3042 | ||
3085 | void radeon_driver_pretakedown(drm_device_t * dev) | 3043 | void radeon_driver_lastclose(drm_device_t * dev) |
3086 | { | 3044 | { |
3087 | radeon_do_release(dev); | 3045 | radeon_do_release(dev); |
3088 | } | 3046 | } |
3089 | 3047 | ||
3090 | int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) | 3048 | int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) |
3091 | { | 3049 | { |
3092 | drm_radeon_private_t *dev_priv = dev->dev_private; | 3050 | drm_radeon_private_t *dev_priv = dev->dev_private; |
3093 | struct drm_radeon_driver_file_fields *radeon_priv; | 3051 | struct drm_radeon_driver_file_fields *radeon_priv; |
3094 | 3052 | ||
3053 | DRM_DEBUG("\n"); | ||
3095 | radeon_priv = | 3054 | radeon_priv = |
3096 | (struct drm_radeon_driver_file_fields *) | 3055 | (struct drm_radeon_driver_file_fields *) |
3097 | drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); | 3056 | drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); |
@@ -3100,6 +3059,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) | |||
3100 | return -ENOMEM; | 3059 | return -ENOMEM; |
3101 | 3060 | ||
3102 | filp_priv->driver_priv = radeon_priv; | 3061 | filp_priv->driver_priv = radeon_priv; |
3062 | |||
3103 | if (dev_priv) | 3063 | if (dev_priv) |
3104 | radeon_priv->radeon_fb_delta = dev_priv->fb_location; | 3064 | radeon_priv->radeon_fb_delta = dev_priv->fb_location; |
3105 | else | 3065 | else |
@@ -3107,7 +3067,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) | |||
3107 | return 0; | 3067 | return 0; |
3108 | } | 3068 | } |
3109 | 3069 | ||
3110 | void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) | 3070 | void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv) |
3111 | { | 3071 | { |
3112 | struct drm_radeon_driver_file_fields *radeon_priv = | 3072 | struct drm_radeon_driver_file_fields *radeon_priv = |
3113 | filp_priv->driver_priv; | 3073 | filp_priv->driver_priv; |
@@ -3116,33 +3076,33 @@ void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) | |||
3116 | } | 3076 | } |
3117 | 3077 | ||
3118 | drm_ioctl_desc_t radeon_ioctls[] = { | 3078 | drm_ioctl_desc_t radeon_ioctls[] = { |
3119 | [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1}, | 3079 | [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3120 | [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1}, | 3080 | [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3121 | [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1}, | 3081 | [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3122 | [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1}, | 3082 | [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3123 | [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0}, | 3083 | [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH}, |
3124 | [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0}, | 3084 | [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH}, |
3125 | [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0}, | 3085 | [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH}, |
3126 | [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0}, | 3086 | [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH}, |
3127 | [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0}, | 3087 | [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH}, |
3128 | [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0}, | 3088 | [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH}, |
3129 | [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0}, | 3089 | [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH}, |
3130 | [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0}, | 3090 | [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH}, |
3131 | [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0}, | 3091 | [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH}, |
3132 | [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0}, | 3092 | [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH}, |
3133 | [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1}, | 3093 | [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3134 | [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0}, | 3094 | [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH}, |
3135 | [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0}, | 3095 | [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH}, |
3136 | [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0}, | 3096 | [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH}, |
3137 | [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0}, | 3097 | [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH}, |
3138 | [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0}, | 3098 | [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH}, |
3139 | [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0}, | 3099 | [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH}, |
3140 | [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1}, | 3100 | [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
3141 | [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0}, | 3101 | [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH}, |
3142 | [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0}, | 3102 | [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH}, |
3143 | [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0}, | 3103 | [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH}, |
3144 | [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0}, | 3104 | [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH}, |
3145 | [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0} | 3105 | [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH} |
3146 | }; | 3106 | }; |
3147 | 3107 | ||
3148 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3108 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 6d10515795cc..0d426deeefec 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c | |||
@@ -533,16 +533,32 @@ static void savage_fake_dma_flush(drm_savage_private_t * dev_priv) | |||
533 | dev_priv->first_dma_page = dev_priv->current_dma_page = 0; | 533 | dev_priv->first_dma_page = dev_priv->current_dma_page = 0; |
534 | } | 534 | } |
535 | 535 | ||
536 | int savage_driver_load(drm_device_t *dev, unsigned long chipset) | ||
537 | { | ||
538 | drm_savage_private_t *dev_priv; | ||
539 | |||
540 | dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); | ||
541 | if (dev_priv == NULL) | ||
542 | return DRM_ERR(ENOMEM); | ||
543 | |||
544 | memset(dev_priv, 0, sizeof(drm_savage_private_t)); | ||
545 | dev->dev_private = (void *)dev_priv; | ||
546 | |||
547 | dev_priv->chipset = (enum savage_family)chipset; | ||
548 | |||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | |||
536 | /* | 553 | /* |
537 | * Initalize mappings. On Savage4 and SavageIX the alignment | 554 | * Initalize mappings. On Savage4 and SavageIX the alignment |
538 | * and size of the aperture is not suitable for automatic MTRR setup | 555 | * and size of the aperture is not suitable for automatic MTRR setup |
539 | * in drm_addmap. Therefore we do it manually before the maps are | 556 | * in drm_addmap. Therefore we add them manually before the maps are |
540 | * initialized. We also need to take care of deleting the MTRRs in | 557 | * initialized, and tear them down on last close. |
541 | * postcleanup. | ||
542 | */ | 558 | */ |
543 | int savage_preinit(drm_device_t * dev, unsigned long chipset) | 559 | int savage_driver_firstopen(drm_device_t *dev) |
544 | { | 560 | { |
545 | drm_savage_private_t *dev_priv; | 561 | drm_savage_private_t *dev_priv = dev->dev_private; |
546 | unsigned long mmio_base, fb_base, fb_size, aperture_base; | 562 | unsigned long mmio_base, fb_base, fb_size, aperture_base; |
547 | /* fb_rsrc and aper_rsrc aren't really used currently, but still exist | 563 | /* fb_rsrc and aper_rsrc aren't really used currently, but still exist |
548 | * in case we decide we need information on the BAR for BSD in the | 564 | * in case we decide we need information on the BAR for BSD in the |
@@ -551,14 +567,6 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset) | |||
551 | unsigned int fb_rsrc, aper_rsrc; | 567 | unsigned int fb_rsrc, aper_rsrc; |
552 | int ret = 0; | 568 | int ret = 0; |
553 | 569 | ||
554 | dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); | ||
555 | if (dev_priv == NULL) | ||
556 | return DRM_ERR(ENOMEM); | ||
557 | |||
558 | memset(dev_priv, 0, sizeof(drm_savage_private_t)); | ||
559 | dev->dev_private = (void *)dev_priv; | ||
560 | dev_priv->chipset = (enum savage_family)chipset; | ||
561 | |||
562 | dev_priv->mtrr[0].handle = -1; | 570 | dev_priv->mtrr[0].handle = -1; |
563 | dev_priv->mtrr[1].handle = -1; | 571 | dev_priv->mtrr[1].handle = -1; |
564 | dev_priv->mtrr[2].handle = -1; | 572 | dev_priv->mtrr[2].handle = -1; |
@@ -576,26 +584,24 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset) | |||
576 | dev_priv->mtrr[0].base = fb_base; | 584 | dev_priv->mtrr[0].base = fb_base; |
577 | dev_priv->mtrr[0].size = 0x01000000; | 585 | dev_priv->mtrr[0].size = 0x01000000; |
578 | dev_priv->mtrr[0].handle = | 586 | dev_priv->mtrr[0].handle = |
579 | mtrr_add(dev_priv->mtrr[0].base, | 587 | drm_mtrr_add(dev_priv->mtrr[0].base, |
580 | dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, | 588 | dev_priv->mtrr[0].size, DRM_MTRR_WC); |
581 | 1); | ||
582 | dev_priv->mtrr[1].base = fb_base + 0x02000000; | 589 | dev_priv->mtrr[1].base = fb_base + 0x02000000; |
583 | dev_priv->mtrr[1].size = 0x02000000; | 590 | dev_priv->mtrr[1].size = 0x02000000; |
584 | dev_priv->mtrr[1].handle = | 591 | dev_priv->mtrr[1].handle = |
585 | mtrr_add(dev_priv->mtrr[1].base, | 592 | drm_mtrr_add(dev_priv->mtrr[1].base, |
586 | dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB, | 593 | dev_priv->mtrr[1].size, DRM_MTRR_WC); |
587 | 1); | ||
588 | dev_priv->mtrr[2].base = fb_base + 0x04000000; | 594 | dev_priv->mtrr[2].base = fb_base + 0x04000000; |
589 | dev_priv->mtrr[2].size = 0x04000000; | 595 | dev_priv->mtrr[2].size = 0x04000000; |
590 | dev_priv->mtrr[2].handle = | 596 | dev_priv->mtrr[2].handle = |
591 | mtrr_add(dev_priv->mtrr[2].base, | 597 | drm_mtrr_add(dev_priv->mtrr[2].base, |
592 | dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB, | 598 | dev_priv->mtrr[2].size, DRM_MTRR_WC); |
593 | 1); | ||
594 | } else { | 599 | } else { |
595 | DRM_ERROR("strange pci_resource_len %08lx\n", | 600 | DRM_ERROR("strange pci_resource_len %08lx\n", |
596 | drm_get_resource_len(dev, 0)); | 601 | drm_get_resource_len(dev, 0)); |
597 | } | 602 | } |
598 | } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) { | 603 | } else if (dev_priv->chipset != S3_SUPERSAVAGE && |
604 | dev_priv->chipset != S3_SAVAGE2000) { | ||
599 | mmio_base = drm_get_resource_start(dev, 0); | 605 | mmio_base = drm_get_resource_start(dev, 0); |
600 | fb_rsrc = 1; | 606 | fb_rsrc = 1; |
601 | fb_base = drm_get_resource_start(dev, 1); | 607 | fb_base = drm_get_resource_start(dev, 1); |
@@ -609,9 +615,8 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset) | |||
609 | dev_priv->mtrr[0].base = fb_base; | 615 | dev_priv->mtrr[0].base = fb_base; |
610 | dev_priv->mtrr[0].size = 0x08000000; | 616 | dev_priv->mtrr[0].size = 0x08000000; |
611 | dev_priv->mtrr[0].handle = | 617 | dev_priv->mtrr[0].handle = |
612 | mtrr_add(dev_priv->mtrr[0].base, | 618 | drm_mtrr_add(dev_priv->mtrr[0].base, |
613 | dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, | 619 | dev_priv->mtrr[0].size, DRM_MTRR_WC); |
614 | 1); | ||
615 | } else { | 620 | } else { |
616 | DRM_ERROR("strange pci_resource_len %08lx\n", | 621 | DRM_ERROR("strange pci_resource_len %08lx\n", |
617 | drm_get_resource_len(dev, 1)); | 622 | drm_get_resource_len(dev, 1)); |
@@ -648,16 +653,21 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset) | |||
648 | /* | 653 | /* |
649 | * Delete MTRRs and free device-private data. | 654 | * Delete MTRRs and free device-private data. |
650 | */ | 655 | */ |
651 | int savage_postcleanup(drm_device_t * dev) | 656 | void savage_driver_lastclose(drm_device_t *dev) |
652 | { | 657 | { |
653 | drm_savage_private_t *dev_priv = dev->dev_private; | 658 | drm_savage_private_t *dev_priv = dev->dev_private; |
654 | int i; | 659 | int i; |
655 | 660 | ||
656 | for (i = 0; i < 3; ++i) | 661 | for (i = 0; i < 3; ++i) |
657 | if (dev_priv->mtrr[i].handle >= 0) | 662 | if (dev_priv->mtrr[i].handle >= 0) |
658 | mtrr_del(dev_priv->mtrr[i].handle, | 663 | drm_mtrr_del(dev_priv->mtrr[i].handle, |
659 | dev_priv->mtrr[i].base, | 664 | dev_priv->mtrr[i].base, |
660 | dev_priv->mtrr[i].size); | 665 | dev_priv->mtrr[i].size, DRM_MTRR_WC); |
666 | } | ||
667 | |||
668 | int savage_driver_unload(drm_device_t *dev) | ||
669 | { | ||
670 | drm_savage_private_t *dev_priv = dev->dev_private; | ||
661 | 671 | ||
662 | drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); | 672 | drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); |
663 | 673 | ||
@@ -994,8 +1004,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) | |||
994 | * DMA buffer management | 1004 | * DMA buffer management |
995 | */ | 1005 | */ |
996 | 1006 | ||
997 | static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev, | 1007 | static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d) |
998 | drm_dma_t * d) | ||
999 | { | 1008 | { |
1000 | drm_buf_t *buf; | 1009 | drm_buf_t *buf; |
1001 | int i; | 1010 | int i; |
@@ -1057,7 +1066,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS) | |||
1057 | return ret; | 1066 | return ret; |
1058 | } | 1067 | } |
1059 | 1068 | ||
1060 | void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) | 1069 | void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) |
1061 | { | 1070 | { |
1062 | drm_device_dma_t *dma = dev->dma; | 1071 | drm_device_dma_t *dma = dev->dma; |
1063 | drm_savage_private_t *dev_priv = dev->dev_private; | 1072 | drm_savage_private_t *dev_priv = dev->dev_private; |
@@ -1090,10 +1099,10 @@ void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) | |||
1090 | } | 1099 | } |
1091 | 1100 | ||
1092 | drm_ioctl_desc_t savage_ioctls[] = { | 1101 | drm_ioctl_desc_t savage_ioctls[] = { |
1093 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1}, | 1102 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
1094 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0}, | 1103 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH}, |
1095 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0}, | 1104 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH}, |
1096 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0}, | 1105 | [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH}, |
1097 | }; | 1106 | }; |
1098 | 1107 | ||
1099 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); | 1108 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); |
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c index 22d799cde41c..aa6c0d1a82f8 100644 --- a/drivers/char/drm/savage_drv.c +++ b/drivers/char/drm/savage_drv.c | |||
@@ -30,31 +30,6 @@ | |||
30 | 30 | ||
31 | #include "drm_pciids.h" | 31 | #include "drm_pciids.h" |
32 | 32 | ||
33 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
34 | { | ||
35 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
36 | DRIVER_NAME, | ||
37 | DRIVER_MAJOR, | ||
38 | DRIVER_MINOR, | ||
39 | DRIVER_PATCHLEVEL, | ||
40 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
41 | ); | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static int version(drm_version_t * version) | ||
46 | { | ||
47 | int len; | ||
48 | |||
49 | version->version_major = DRIVER_MAJOR; | ||
50 | version->version_minor = DRIVER_MINOR; | ||
51 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
52 | DRM_COPY(version->name, DRIVER_NAME); | ||
53 | DRM_COPY(version->date, DRIVER_DATE); | ||
54 | DRM_COPY(version->desc, DRIVER_DESC); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static struct pci_device_id pciidlist[] = { | 33 | static struct pci_device_id pciidlist[] = { |
59 | savage_PCI_IDS | 34 | savage_PCI_IDS |
60 | }; | 35 | }; |
@@ -63,13 +38,13 @@ static struct drm_driver driver = { | |||
63 | .driver_features = | 38 | .driver_features = |
64 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, | 39 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, |
65 | .dev_priv_size = sizeof(drm_savage_buf_priv_t), | 40 | .dev_priv_size = sizeof(drm_savage_buf_priv_t), |
66 | .preinit = savage_preinit, | 41 | .load = savage_driver_load, |
67 | .postinit = postinit, | 42 | .firstopen = savage_driver_firstopen, |
68 | .postcleanup = savage_postcleanup, | 43 | .lastclose = savage_driver_lastclose, |
44 | .unload = savage_driver_unload, | ||
69 | .reclaim_buffers = savage_reclaim_buffers, | 45 | .reclaim_buffers = savage_reclaim_buffers, |
70 | .get_map_ofs = drm_core_get_map_ofs, | 46 | .get_map_ofs = drm_core_get_map_ofs, |
71 | .get_reg_ofs = drm_core_get_reg_ofs, | 47 | .get_reg_ofs = drm_core_get_reg_ofs, |
72 | .version = version, | ||
73 | .ioctls = savage_ioctls, | 48 | .ioctls = savage_ioctls, |
74 | .dma_ioctl = savage_bci_buffers, | 49 | .dma_ioctl = savage_bci_buffers, |
75 | .fops = { | 50 | .fops = { |
@@ -80,12 +55,19 @@ static struct drm_driver driver = { | |||
80 | .mmap = drm_mmap, | 55 | .mmap = drm_mmap, |
81 | .poll = drm_poll, | 56 | .poll = drm_poll, |
82 | .fasync = drm_fasync, | 57 | .fasync = drm_fasync, |
83 | } | 58 | }, |
84 | , | 59 | |
85 | .pci_driver = { | 60 | .pci_driver = { |
86 | .name = DRIVER_NAME, | 61 | .name = DRIVER_NAME, |
87 | .id_table = pciidlist, | 62 | .id_table = pciidlist, |
88 | } | 63 | }, |
64 | |||
65 | .name = DRIVER_NAME, | ||
66 | .desc = DRIVER_DESC, | ||
67 | .date = DRIVER_DATE, | ||
68 | .major = DRIVER_MAJOR, | ||
69 | .minor = DRIVER_MINOR, | ||
70 | .patchlevel = DRIVER_PATCHLEVEL, | ||
89 | }; | 71 | }; |
90 | 72 | ||
91 | static int __init savage_init(void) | 73 | static int __init savage_init(void) |
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h index a4b0fa998a95..dd46cb85439c 100644 --- a/drivers/char/drm/savage_drv.h +++ b/drivers/char/drm/savage_drv.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* savage_drv.h -- Private header for the savage driver | 1 | /* savage_drv.h -- Private header for the savage driver */ |
2 | * | 2 | /* |
3 | * Copyright 2004 Felix Kuehling | 3 | * Copyright 2004 Felix Kuehling |
4 | * All Rights Reserved. | 4 | * All Rights Reserved. |
5 | * | 5 | * |
@@ -192,7 +192,7 @@ typedef struct drm_savage_private { | |||
192 | /* Err, there is a macro wait_event in include/linux/wait.h. | 192 | /* Err, there is a macro wait_event in include/linux/wait.h. |
193 | * Avoid unwanted macro expansion. */ | 193 | * Avoid unwanted macro expansion. */ |
194 | void (*emit_clip_rect) (struct drm_savage_private * dev_priv, | 194 | void (*emit_clip_rect) (struct drm_savage_private * dev_priv, |
195 | drm_clip_rect_t * pbox); | 195 | const drm_clip_rect_t * pbox); |
196 | void (*dma_flush) (struct drm_savage_private * dev_priv); | 196 | void (*dma_flush) (struct drm_savage_private * dev_priv); |
197 | } drm_savage_private_t; | 197 | } drm_savage_private_t; |
198 | 198 | ||
@@ -208,16 +208,18 @@ extern void savage_dma_reset(drm_savage_private_t * dev_priv); | |||
208 | extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); | 208 | extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); |
209 | extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, | 209 | extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, |
210 | unsigned int n); | 210 | unsigned int n); |
211 | extern int savage_preinit(drm_device_t * dev, unsigned long chipset); | 211 | extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); |
212 | extern int savage_postcleanup(drm_device_t * dev); | 212 | extern int savage_driver_firstopen(drm_device_t *dev); |
213 | extern void savage_driver_lastclose(drm_device_t *dev); | ||
214 | extern int savage_driver_unload(drm_device_t *dev); | ||
213 | extern int savage_do_cleanup_bci(drm_device_t * dev); | 215 | extern int savage_do_cleanup_bci(drm_device_t * dev); |
214 | extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); | 216 | extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); |
215 | 217 | ||
216 | /* state functions */ | 218 | /* state functions */ |
217 | extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, | 219 | extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, |
218 | drm_clip_rect_t * pbox); | 220 | const drm_clip_rect_t * pbox); |
219 | extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, | 221 | extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, |
220 | drm_clip_rect_t * pbox); | 222 | const drm_clip_rect_t * pbox); |
221 | 223 | ||
222 | #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ | 224 | #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ |
223 | #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ | 225 | #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ |
@@ -500,15 +502,6 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, | |||
500 | 502 | ||
501 | #define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) | 503 | #define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) |
502 | 504 | ||
503 | #define BCI_COPY_FROM_USER(src,n) do { \ | ||
504 | unsigned int i; \ | ||
505 | for (i = 0; i < n; ++i) { \ | ||
506 | uint32_t val; \ | ||
507 | DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \ | ||
508 | BCI_WRITE(val); \ | ||
509 | } \ | ||
510 | } while(0) | ||
511 | |||
512 | /* | 505 | /* |
513 | * command DMA support | 506 | * command DMA support |
514 | */ | 507 | */ |
@@ -534,8 +527,8 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, | |||
534 | 527 | ||
535 | #define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) | 528 | #define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) |
536 | 529 | ||
537 | #define DMA_COPY_FROM_USER(src,n) do { \ | 530 | #define DMA_COPY(src, n) do { \ |
538 | DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \ | 531 | memcpy(dma_ptr, (src), (n)*4); \ |
539 | dma_ptr += n; \ | 532 | dma_ptr += n; \ |
540 | } while(0) | 533 | } while(0) |
541 | 534 | ||
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c index e87a5d59b99c..ef2581d16146 100644 --- a/drivers/char/drm/savage_state.c +++ b/drivers/char/drm/savage_state.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "savage_drv.h" | 27 | #include "savage_drv.h" |
28 | 28 | ||
29 | void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, | 29 | void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, |
30 | drm_clip_rect_t * pbox) | 30 | const drm_clip_rect_t * pbox) |
31 | { | 31 | { |
32 | uint32_t scstart = dev_priv->state.s3d.new_scstart; | 32 | uint32_t scstart = dev_priv->state.s3d.new_scstart; |
33 | uint32_t scend = dev_priv->state.s3d.new_scend; | 33 | uint32_t scend = dev_priv->state.s3d.new_scend; |
@@ -53,7 +53,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, | |||
53 | } | 53 | } |
54 | 54 | ||
55 | void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, | 55 | void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, |
56 | drm_clip_rect_t * pbox) | 56 | const drm_clip_rect_t * pbox) |
57 | { | 57 | { |
58 | uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; | 58 | uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; |
59 | uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; | 59 | uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; |
@@ -115,18 +115,19 @@ static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit, | |||
115 | 115 | ||
116 | #define SAVE_STATE(reg,where) \ | 116 | #define SAVE_STATE(reg,where) \ |
117 | if(start <= reg && start+count > reg) \ | 117 | if(start <= reg && start+count > reg) \ |
118 | DRM_GET_USER_UNCHECKED(dev_priv->state.where, ®s[reg-start]) | 118 | dev_priv->state.where = regs[reg - start] |
119 | #define SAVE_STATE_MASK(reg,where,mask) do { \ | 119 | #define SAVE_STATE_MASK(reg,where,mask) do { \ |
120 | if(start <= reg && start+count > reg) { \ | 120 | if(start <= reg && start+count > reg) { \ |
121 | uint32_t tmp; \ | 121 | uint32_t tmp; \ |
122 | DRM_GET_USER_UNCHECKED(tmp, ®s[reg-start]); \ | 122 | tmp = regs[reg - start]; \ |
123 | dev_priv->state.where = (tmp & (mask)) | \ | 123 | dev_priv->state.where = (tmp & (mask)) | \ |
124 | (dev_priv->state.where & ~(mask)); \ | 124 | (dev_priv->state.where & ~(mask)); \ |
125 | } \ | 125 | } \ |
126 | } while (0) | 126 | } while (0) |
127 | |||
127 | static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, | 128 | static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, |
128 | unsigned int start, unsigned int count, | 129 | unsigned int start, unsigned int count, |
129 | const uint32_t __user * regs) | 130 | const uint32_t *regs) |
130 | { | 131 | { |
131 | if (start < SAVAGE_TEXPALADDR_S3D || | 132 | if (start < SAVAGE_TEXPALADDR_S3D || |
132 | start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { | 133 | start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { |
@@ -148,8 +149,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, | |||
148 | SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); | 149 | SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); |
149 | if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) | 150 | if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) |
150 | return savage_verify_texaddr(dev_priv, 0, | 151 | return savage_verify_texaddr(dev_priv, 0, |
151 | dev_priv->state.s3d. | 152 | dev_priv->state.s3d.texaddr); |
152 | texaddr); | ||
153 | } | 153 | } |
154 | 154 | ||
155 | return 0; | 155 | return 0; |
@@ -157,7 +157,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, | |||
157 | 157 | ||
158 | static int savage_verify_state_s4(drm_savage_private_t * dev_priv, | 158 | static int savage_verify_state_s4(drm_savage_private_t * dev_priv, |
159 | unsigned int start, unsigned int count, | 159 | unsigned int start, unsigned int count, |
160 | const uint32_t __user * regs) | 160 | const uint32_t *regs) |
161 | { | 161 | { |
162 | int ret = 0; | 162 | int ret = 0; |
163 | 163 | ||
@@ -174,19 +174,18 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv, | |||
174 | ~SAVAGE_SCISSOR_MASK_S4); | 174 | ~SAVAGE_SCISSOR_MASK_S4); |
175 | 175 | ||
176 | /* if any texture regs were changed ... */ | 176 | /* if any texture regs were changed ... */ |
177 | if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) { | 177 | if (start <= SAVAGE_TEXDESCR_S4 && |
178 | start + count > SAVAGE_TEXPALADDR_S4) { | ||
178 | /* ... check texture state */ | 179 | /* ... check texture state */ |
179 | SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); | 180 | SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); |
180 | SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); | 181 | SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); |
181 | SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); | 182 | SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); |
182 | if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) | 183 | if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) |
183 | ret |= | 184 | ret |= savage_verify_texaddr(dev_priv, 0, |
184 | savage_verify_texaddr(dev_priv, 0, | 185 | dev_priv->state.s4.texaddr0); |
185 | dev_priv->state.s4.texaddr0); | ||
186 | if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) | 186 | if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) |
187 | ret |= | 187 | ret |= savage_verify_texaddr(dev_priv, 1, |
188 | savage_verify_texaddr(dev_priv, 1, | 188 | dev_priv->state.s4.texaddr1); |
189 | dev_priv->state.s4.texaddr1); | ||
190 | } | 189 | } |
191 | 190 | ||
192 | return ret; | 191 | return ret; |
@@ -197,7 +196,7 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv, | |||
197 | 196 | ||
198 | static int savage_dispatch_state(drm_savage_private_t * dev_priv, | 197 | static int savage_dispatch_state(drm_savage_private_t * dev_priv, |
199 | const drm_savage_cmd_header_t * cmd_header, | 198 | const drm_savage_cmd_header_t * cmd_header, |
200 | const uint32_t __user * regs) | 199 | const uint32_t *regs) |
201 | { | 200 | { |
202 | unsigned int count = cmd_header->state.count; | 201 | unsigned int count = cmd_header->state.count; |
203 | unsigned int start = cmd_header->state.start; | 202 | unsigned int start = cmd_header->state.start; |
@@ -209,9 +208,6 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, | |||
209 | if (!count) | 208 | if (!count) |
210 | return 0; | 209 | return 0; |
211 | 210 | ||
212 | if (DRM_VERIFYAREA_READ(regs, count * 4)) | ||
213 | return DRM_ERR(EFAULT); | ||
214 | |||
215 | if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { | 211 | if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { |
216 | ret = savage_verify_state_s3d(dev_priv, start, count, regs); | 212 | ret = savage_verify_state_s3d(dev_priv, start, count, regs); |
217 | if (ret != 0) | 213 | if (ret != 0) |
@@ -236,8 +232,8 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, | |||
236 | /* scissor regs are emitted in savage_dispatch_draw */ | 232 | /* scissor regs are emitted in savage_dispatch_draw */ |
237 | if (start < SAVAGE_DRAWCTRL0_S4) { | 233 | if (start < SAVAGE_DRAWCTRL0_S4) { |
238 | if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) | 234 | if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) |
239 | count2 = | 235 | count2 = count - |
240 | count - (SAVAGE_DRAWCTRL1_S4 + 1 - start); | 236 | (SAVAGE_DRAWCTRL1_S4 + 1 - start); |
241 | if (start + count > SAVAGE_DRAWCTRL0_S4) | 237 | if (start + count > SAVAGE_DRAWCTRL0_S4) |
242 | count = SAVAGE_DRAWCTRL0_S4 - start; | 238 | count = SAVAGE_DRAWCTRL0_S4 - start; |
243 | } else if (start <= SAVAGE_DRAWCTRL1_S4) { | 239 | } else if (start <= SAVAGE_DRAWCTRL1_S4) { |
@@ -263,7 +259,7 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, | |||
263 | while (count > 0) { | 259 | while (count > 0) { |
264 | unsigned int n = count < 255 ? count : 255; | 260 | unsigned int n = count < 255 ? count : 255; |
265 | DMA_SET_REGISTERS(start, n); | 261 | DMA_SET_REGISTERS(start, n); |
266 | DMA_COPY_FROM_USER(regs, n); | 262 | DMA_COPY(regs, n); |
267 | count -= n; | 263 | count -= n; |
268 | start += n; | 264 | start += n; |
269 | regs += n; | 265 | regs += n; |
@@ -421,8 +417,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv, | |||
421 | 417 | ||
422 | static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, | 418 | static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, |
423 | const drm_savage_cmd_header_t * cmd_header, | 419 | const drm_savage_cmd_header_t * cmd_header, |
424 | const uint32_t __user * vtxbuf, | 420 | const uint32_t *vtxbuf, unsigned int vb_size, |
425 | unsigned int vb_size, unsigned int vb_stride) | 421 | unsigned int vb_stride) |
426 | { | 422 | { |
427 | unsigned char reorder = 0; | 423 | unsigned char reorder = 0; |
428 | unsigned int prim = cmd_header->prim.prim; | 424 | unsigned int prim = cmd_header->prim.prim; |
@@ -507,8 +503,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, | |||
507 | 503 | ||
508 | for (i = start; i < start + count; ++i) { | 504 | for (i = start; i < start + count; ++i) { |
509 | unsigned int j = i + reorder[i % 3]; | 505 | unsigned int j = i + reorder[i % 3]; |
510 | DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], | 506 | DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); |
511 | vtx_size); | ||
512 | } | 507 | } |
513 | 508 | ||
514 | DMA_COMMIT(); | 509 | DMA_COMMIT(); |
@@ -517,13 +512,12 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, | |||
517 | DMA_DRAW_PRIMITIVE(count, prim, skip); | 512 | DMA_DRAW_PRIMITIVE(count, prim, skip); |
518 | 513 | ||
519 | if (vb_stride == vtx_size) { | 514 | if (vb_stride == vtx_size) { |
520 | DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start], | 515 | DMA_COPY(&vtxbuf[vb_stride * start], |
521 | vtx_size * count); | 516 | vtx_size * count); |
522 | } else { | 517 | } else { |
523 | for (i = start; i < start + count; ++i) { | 518 | for (i = start; i < start + count; ++i) { |
524 | DMA_COPY_FROM_USER(&vtxbuf | 519 | DMA_COPY(&vtxbuf [vb_stride * i], |
525 | [vb_stride * i], | 520 | vtx_size); |
526 | vtx_size); | ||
527 | } | 521 | } |
528 | } | 522 | } |
529 | 523 | ||
@@ -541,7 +535,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, | |||
541 | 535 | ||
542 | static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, | 536 | static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, |
543 | const drm_savage_cmd_header_t * cmd_header, | 537 | const drm_savage_cmd_header_t * cmd_header, |
544 | const uint16_t __user * usr_idx, | 538 | const uint16_t *idx, |
545 | const drm_buf_t * dmabuf) | 539 | const drm_buf_t * dmabuf) |
546 | { | 540 | { |
547 | unsigned char reorder = 0; | 541 | unsigned char reorder = 0; |
@@ -628,11 +622,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, | |||
628 | while (n != 0) { | 622 | while (n != 0) { |
629 | /* Can emit up to 255 indices (85 triangles) at once. */ | 623 | /* Can emit up to 255 indices (85 triangles) at once. */ |
630 | unsigned int count = n > 255 ? 255 : n; | 624 | unsigned int count = n > 255 ? 255 : n; |
631 | /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ | ||
632 | uint16_t idx[255]; | ||
633 | 625 | ||
634 | /* Copy and check indices */ | 626 | /* check indices */ |
635 | DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); | ||
636 | for (i = 0; i < count; ++i) { | 627 | for (i = 0; i < count; ++i) { |
637 | if (idx[i] > dmabuf->total / 32) { | 628 | if (idx[i] > dmabuf->total / 32) { |
638 | DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", | 629 | DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", |
@@ -652,8 +643,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, | |||
652 | 643 | ||
653 | for (i = 1; i + 1 < count; i += 2) | 644 | for (i = 1; i + 1 < count; i += 2) |
654 | BCI_WRITE(idx[i + reorder[i % 3]] | | 645 | BCI_WRITE(idx[i + reorder[i % 3]] | |
655 | (idx[i + 1 + reorder[(i + 1) % 3]] << | 646 | (idx[i + 1 + |
656 | 16)); | 647 | reorder[(i + 1) % 3]] << 16)); |
657 | if (i < count) | 648 | if (i < count) |
658 | BCI_WRITE(idx[i + reorder[i % 3]]); | 649 | BCI_WRITE(idx[i + reorder[i % 3]]); |
659 | } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { | 650 | } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { |
@@ -674,7 +665,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, | |||
674 | BCI_WRITE(idx[i]); | 665 | BCI_WRITE(idx[i]); |
675 | } | 666 | } |
676 | 667 | ||
677 | usr_idx += count; | 668 | idx += count; |
678 | n -= count; | 669 | n -= count; |
679 | 670 | ||
680 | prim |= BCI_CMD_DRAW_CONT; | 671 | prim |= BCI_CMD_DRAW_CONT; |
@@ -685,8 +676,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, | |||
685 | 676 | ||
686 | static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, | 677 | static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, |
687 | const drm_savage_cmd_header_t * cmd_header, | 678 | const drm_savage_cmd_header_t * cmd_header, |
688 | const uint16_t __user * usr_idx, | 679 | const uint16_t *idx, |
689 | const uint32_t __user * vtxbuf, | 680 | const uint32_t *vtxbuf, |
690 | unsigned int vb_size, unsigned int vb_stride) | 681 | unsigned int vb_size, unsigned int vb_stride) |
691 | { | 682 | { |
692 | unsigned char reorder = 0; | 683 | unsigned char reorder = 0; |
@@ -751,11 +742,8 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, | |||
751 | while (n != 0) { | 742 | while (n != 0) { |
752 | /* Can emit up to 255 vertices (85 triangles) at once. */ | 743 | /* Can emit up to 255 vertices (85 triangles) at once. */ |
753 | unsigned int count = n > 255 ? 255 : n; | 744 | unsigned int count = n > 255 ? 255 : n; |
754 | /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ | 745 | |
755 | uint16_t idx[255]; | 746 | /* Check indices */ |
756 | |||
757 | /* Copy and check indices */ | ||
758 | DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); | ||
759 | for (i = 0; i < count; ++i) { | 747 | for (i = 0; i < count; ++i) { |
760 | if (idx[i] > vb_size / (vb_stride * 4)) { | 748 | if (idx[i] > vb_size / (vb_stride * 4)) { |
761 | DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", | 749 | DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", |
@@ -775,8 +763,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, | |||
775 | 763 | ||
776 | for (i = 0; i < count; ++i) { | 764 | for (i = 0; i < count; ++i) { |
777 | unsigned int j = idx[i + reorder[i % 3]]; | 765 | unsigned int j = idx[i + reorder[i % 3]]; |
778 | DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], | 766 | DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); |
779 | vtx_size); | ||
780 | } | 767 | } |
781 | 768 | ||
782 | DMA_COMMIT(); | 769 | DMA_COMMIT(); |
@@ -786,14 +773,13 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, | |||
786 | 773 | ||
787 | for (i = 0; i < count; ++i) { | 774 | for (i = 0; i < count; ++i) { |
788 | unsigned int j = idx[i]; | 775 | unsigned int j = idx[i]; |
789 | DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], | 776 | DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); |
790 | vtx_size); | ||
791 | } | 777 | } |
792 | 778 | ||
793 | DMA_COMMIT(); | 779 | DMA_COMMIT(); |
794 | } | 780 | } |
795 | 781 | ||
796 | usr_idx += count; | 782 | idx += count; |
797 | n -= count; | 783 | n -= count; |
798 | 784 | ||
799 | prim |= BCI_CMD_DRAW_CONT; | 785 | prim |= BCI_CMD_DRAW_CONT; |
@@ -804,11 +790,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, | |||
804 | 790 | ||
805 | static int savage_dispatch_clear(drm_savage_private_t * dev_priv, | 791 | static int savage_dispatch_clear(drm_savage_private_t * dev_priv, |
806 | const drm_savage_cmd_header_t * cmd_header, | 792 | const drm_savage_cmd_header_t * cmd_header, |
807 | const drm_savage_cmd_header_t __user * data, | 793 | const drm_savage_cmd_header_t *data, |
808 | unsigned int nbox, | 794 | unsigned int nbox, |
809 | const drm_clip_rect_t __user * usr_boxes) | 795 | const drm_clip_rect_t *boxes) |
810 | { | 796 | { |
811 | unsigned int flags = cmd_header->clear0.flags, mask, value; | 797 | unsigned int flags = cmd_header->clear0.flags; |
812 | unsigned int clear_cmd; | 798 | unsigned int clear_cmd; |
813 | unsigned int i, nbufs; | 799 | unsigned int i, nbufs; |
814 | DMA_LOCALS; | 800 | DMA_LOCALS; |
@@ -816,9 +802,6 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, | |||
816 | if (nbox == 0) | 802 | if (nbox == 0) |
817 | return 0; | 803 | return 0; |
818 | 804 | ||
819 | DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask); | ||
820 | DRM_GET_USER_UNCHECKED(value, &data->clear1.value); | ||
821 | |||
822 | clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | | 805 | clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | |
823 | BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; | 806 | BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; |
824 | BCI_CMD_SET_ROP(clear_cmd, 0xCC); | 807 | BCI_CMD_SET_ROP(clear_cmd, 0xCC); |
@@ -828,21 +811,19 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, | |||
828 | if (nbufs == 0) | 811 | if (nbufs == 0) |
829 | return 0; | 812 | return 0; |
830 | 813 | ||
831 | if (mask != 0xffffffff) { | 814 | if (data->clear1.mask != 0xffffffff) { |
832 | /* set mask */ | 815 | /* set mask */ |
833 | BEGIN_DMA(2); | 816 | BEGIN_DMA(2); |
834 | DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); | 817 | DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); |
835 | DMA_WRITE(mask); | 818 | DMA_WRITE(data->clear1.mask); |
836 | DMA_COMMIT(); | 819 | DMA_COMMIT(); |
837 | } | 820 | } |
838 | for (i = 0; i < nbox; ++i) { | 821 | for (i = 0; i < nbox; ++i) { |
839 | drm_clip_rect_t box; | ||
840 | unsigned int x, y, w, h; | 822 | unsigned int x, y, w, h; |
841 | unsigned int buf; | 823 | unsigned int buf; |
842 | DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); | 824 | x = boxes[i].x1, y = boxes[i].y1; |
843 | x = box.x1, y = box.y1; | 825 | w = boxes[i].x2 - boxes[i].x1; |
844 | w = box.x2 - box.x1; | 826 | h = boxes[i].y2 - boxes[i].y1; |
845 | h = box.y2 - box.y1; | ||
846 | BEGIN_DMA(nbufs * 6); | 827 | BEGIN_DMA(nbufs * 6); |
847 | for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { | 828 | for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { |
848 | if (!(flags & buf)) | 829 | if (!(flags & buf)) |
@@ -862,13 +843,13 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, | |||
862 | DMA_WRITE(dev_priv->depth_bd); | 843 | DMA_WRITE(dev_priv->depth_bd); |
863 | break; | 844 | break; |
864 | } | 845 | } |
865 | DMA_WRITE(value); | 846 | DMA_WRITE(data->clear1.value); |
866 | DMA_WRITE(BCI_X_Y(x, y)); | 847 | DMA_WRITE(BCI_X_Y(x, y)); |
867 | DMA_WRITE(BCI_W_H(w, h)); | 848 | DMA_WRITE(BCI_W_H(w, h)); |
868 | } | 849 | } |
869 | DMA_COMMIT(); | 850 | DMA_COMMIT(); |
870 | } | 851 | } |
871 | if (mask != 0xffffffff) { | 852 | if (data->clear1.mask != 0xffffffff) { |
872 | /* reset mask */ | 853 | /* reset mask */ |
873 | BEGIN_DMA(2); | 854 | BEGIN_DMA(2); |
874 | DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); | 855 | DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); |
@@ -880,8 +861,7 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, | |||
880 | } | 861 | } |
881 | 862 | ||
882 | static int savage_dispatch_swap(drm_savage_private_t * dev_priv, | 863 | static int savage_dispatch_swap(drm_savage_private_t * dev_priv, |
883 | unsigned int nbox, | 864 | unsigned int nbox, const drm_clip_rect_t *boxes) |
884 | const drm_clip_rect_t __user * usr_boxes) | ||
885 | { | 865 | { |
886 | unsigned int swap_cmd; | 866 | unsigned int swap_cmd; |
887 | unsigned int i; | 867 | unsigned int i; |
@@ -895,16 +875,14 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv, | |||
895 | BCI_CMD_SET_ROP(swap_cmd, 0xCC); | 875 | BCI_CMD_SET_ROP(swap_cmd, 0xCC); |
896 | 876 | ||
897 | for (i = 0; i < nbox; ++i) { | 877 | for (i = 0; i < nbox; ++i) { |
898 | drm_clip_rect_t box; | ||
899 | DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); | ||
900 | |||
901 | BEGIN_DMA(6); | 878 | BEGIN_DMA(6); |
902 | DMA_WRITE(swap_cmd); | 879 | DMA_WRITE(swap_cmd); |
903 | DMA_WRITE(dev_priv->back_offset); | 880 | DMA_WRITE(dev_priv->back_offset); |
904 | DMA_WRITE(dev_priv->back_bd); | 881 | DMA_WRITE(dev_priv->back_bd); |
905 | DMA_WRITE(BCI_X_Y(box.x1, box.y1)); | 882 | DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); |
906 | DMA_WRITE(BCI_X_Y(box.x1, box.y1)); | 883 | DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); |
907 | DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1)); | 884 | DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1, |
885 | boxes[i].y2 - boxes[i].y1)); | ||
908 | DMA_COMMIT(); | 886 | DMA_COMMIT(); |
909 | } | 887 | } |
910 | 888 | ||
@@ -912,68 +890,52 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv, | |||
912 | } | 890 | } |
913 | 891 | ||
914 | static int savage_dispatch_draw(drm_savage_private_t * dev_priv, | 892 | static int savage_dispatch_draw(drm_savage_private_t * dev_priv, |
915 | const drm_savage_cmd_header_t __user * start, | 893 | const drm_savage_cmd_header_t *start, |
916 | const drm_savage_cmd_header_t __user * end, | 894 | const drm_savage_cmd_header_t *end, |
917 | const drm_buf_t * dmabuf, | 895 | const drm_buf_t * dmabuf, |
918 | const unsigned int __user * usr_vtxbuf, | 896 | const unsigned int *vtxbuf, |
919 | unsigned int vb_size, unsigned int vb_stride, | 897 | unsigned int vb_size, unsigned int vb_stride, |
920 | unsigned int nbox, | 898 | unsigned int nbox, |
921 | const drm_clip_rect_t __user * usr_boxes) | 899 | const drm_clip_rect_t *boxes) |
922 | { | 900 | { |
923 | unsigned int i, j; | 901 | unsigned int i, j; |
924 | int ret; | 902 | int ret; |
925 | 903 | ||
926 | for (i = 0; i < nbox; ++i) { | 904 | for (i = 0; i < nbox; ++i) { |
927 | drm_clip_rect_t box; | 905 | const drm_savage_cmd_header_t *cmdbuf; |
928 | const drm_savage_cmd_header_t __user *usr_cmdbuf; | 906 | dev_priv->emit_clip_rect(dev_priv, &boxes[i]); |
929 | DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); | ||
930 | dev_priv->emit_clip_rect(dev_priv, &box); | ||
931 | 907 | ||
932 | usr_cmdbuf = start; | 908 | cmdbuf = start; |
933 | while (usr_cmdbuf < end) { | 909 | while (cmdbuf < end) { |
934 | drm_savage_cmd_header_t cmd_header; | 910 | drm_savage_cmd_header_t cmd_header; |
935 | DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, | 911 | cmd_header = *cmdbuf; |
936 | sizeof(cmd_header)); | 912 | cmdbuf++; |
937 | usr_cmdbuf++; | ||
938 | switch (cmd_header.cmd.cmd) { | 913 | switch (cmd_header.cmd.cmd) { |
939 | case SAVAGE_CMD_DMA_PRIM: | 914 | case SAVAGE_CMD_DMA_PRIM: |
940 | ret = | 915 | ret = savage_dispatch_dma_prim( |
941 | savage_dispatch_dma_prim(dev_priv, | 916 | dev_priv, &cmd_header, dmabuf); |
942 | &cmd_header, | ||
943 | dmabuf); | ||
944 | break; | 917 | break; |
945 | case SAVAGE_CMD_VB_PRIM: | 918 | case SAVAGE_CMD_VB_PRIM: |
946 | ret = | 919 | ret = savage_dispatch_vb_prim( |
947 | savage_dispatch_vb_prim(dev_priv, | 920 | dev_priv, &cmd_header, |
948 | &cmd_header, | 921 | vtxbuf, vb_size, vb_stride); |
949 | (const uint32_t | ||
950 | __user *) | ||
951 | usr_vtxbuf, vb_size, | ||
952 | vb_stride); | ||
953 | break; | 922 | break; |
954 | case SAVAGE_CMD_DMA_IDX: | 923 | case SAVAGE_CMD_DMA_IDX: |
955 | j = (cmd_header.idx.count + 3) / 4; | 924 | j = (cmd_header.idx.count + 3) / 4; |
956 | /* j was check in savage_bci_cmdbuf */ | 925 | /* j was check in savage_bci_cmdbuf */ |
957 | ret = | 926 | ret = savage_dispatch_dma_idx(dev_priv, |
958 | savage_dispatch_dma_idx(dev_priv, | 927 | &cmd_header, (const uint16_t *)cmdbuf, |
959 | &cmd_header, | 928 | dmabuf); |
960 | (const uint16_t | 929 | cmdbuf += j; |
961 | __user *) | ||
962 | usr_cmdbuf, dmabuf); | ||
963 | usr_cmdbuf += j; | ||
964 | break; | 930 | break; |
965 | case SAVAGE_CMD_VB_IDX: | 931 | case SAVAGE_CMD_VB_IDX: |
966 | j = (cmd_header.idx.count + 3) / 4; | 932 | j = (cmd_header.idx.count + 3) / 4; |
967 | /* j was check in savage_bci_cmdbuf */ | 933 | /* j was check in savage_bci_cmdbuf */ |
968 | ret = | 934 | ret = savage_dispatch_vb_idx(dev_priv, |
969 | savage_dispatch_vb_idx(dev_priv, | 935 | &cmd_header, (const uint16_t *)cmdbuf, |
970 | &cmd_header, | 936 | (const uint32_t *)vtxbuf, vb_size, |
971 | (const uint16_t | 937 | vb_stride); |
972 | __user *)usr_cmdbuf, | 938 | cmdbuf += j; |
973 | (const uint32_t | ||
974 | __user *)usr_vtxbuf, | ||
975 | vb_size, vb_stride); | ||
976 | usr_cmdbuf += j; | ||
977 | break; | 939 | break; |
978 | default: | 940 | default: |
979 | /* What's the best return code? EFAULT? */ | 941 | /* What's the best return code? EFAULT? */ |
@@ -998,10 +960,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
998 | drm_device_dma_t *dma = dev->dma; | 960 | drm_device_dma_t *dma = dev->dma; |
999 | drm_buf_t *dmabuf; | 961 | drm_buf_t *dmabuf; |
1000 | drm_savage_cmdbuf_t cmdbuf; | 962 | drm_savage_cmdbuf_t cmdbuf; |
1001 | drm_savage_cmd_header_t __user *usr_cmdbuf; | 963 | drm_savage_cmd_header_t *kcmd_addr = NULL; |
1002 | drm_savage_cmd_header_t __user *first_draw_cmd; | 964 | drm_savage_cmd_header_t *first_draw_cmd; |
1003 | unsigned int __user *usr_vtxbuf; | 965 | unsigned int *kvb_addr = NULL; |
1004 | drm_clip_rect_t __user *usr_boxes; | 966 | drm_clip_rect_t *kbox_addr = NULL; |
1005 | unsigned int i, j; | 967 | unsigned int i, j; |
1006 | int ret = 0; | 968 | int ret = 0; |
1007 | 969 | ||
@@ -1024,15 +986,53 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1024 | dmabuf = NULL; | 986 | dmabuf = NULL; |
1025 | } | 987 | } |
1026 | 988 | ||
1027 | usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr; | 989 | /* Copy the user buffers into kernel temporary areas. This hasn't been |
1028 | usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr; | 990 | * a performance loss compared to VERIFYAREA_READ/ |
1029 | usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr; | 991 | * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct |
1030 | if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) || | 992 | * for locking on FreeBSD. |
1031 | (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size)) | 993 | */ |
1032 | || (cmdbuf.nbox | 994 | if (cmdbuf.size) { |
1033 | && DRM_VERIFYAREA_READ(usr_boxes, | 995 | kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); |
1034 | cmdbuf.nbox * sizeof(drm_clip_rect_t)))) | 996 | if (kcmd_addr == NULL) |
1035 | return DRM_ERR(EFAULT); | 997 | return ENOMEM; |
998 | |||
999 | if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, | ||
1000 | cmdbuf.size * 8)) | ||
1001 | { | ||
1002 | drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); | ||
1003 | return DRM_ERR(EFAULT); | ||
1004 | } | ||
1005 | cmdbuf.cmd_addr = kcmd_addr; | ||
1006 | } | ||
1007 | if (cmdbuf.vb_size) { | ||
1008 | kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER); | ||
1009 | if (kvb_addr == NULL) { | ||
1010 | ret = DRM_ERR(ENOMEM); | ||
1011 | goto done; | ||
1012 | } | ||
1013 | |||
1014 | if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr, | ||
1015 | cmdbuf.vb_size)) { | ||
1016 | ret = DRM_ERR(EFAULT); | ||
1017 | goto done; | ||
1018 | } | ||
1019 | cmdbuf.vb_addr = kvb_addr; | ||
1020 | } | ||
1021 | if (cmdbuf.nbox) { | ||
1022 | kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t), | ||
1023 | DRM_MEM_DRIVER); | ||
1024 | if (kbox_addr == NULL) { | ||
1025 | ret = DRM_ERR(ENOMEM); | ||
1026 | goto done; | ||
1027 | } | ||
1028 | |||
1029 | if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr, | ||
1030 | cmdbuf.nbox * sizeof(drm_clip_rect_t))) { | ||
1031 | ret = DRM_ERR(EFAULT); | ||
1032 | goto done; | ||
1033 | } | ||
1034 | cmdbuf.box_addr = kbox_addr; | ||
1035 | } | ||
1036 | 1036 | ||
1037 | /* Make sure writes to DMA buffers are finished before sending | 1037 | /* Make sure writes to DMA buffers are finished before sending |
1038 | * DMA commands to the graphics hardware. */ | 1038 | * DMA commands to the graphics hardware. */ |
@@ -1046,9 +1046,8 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1046 | first_draw_cmd = NULL; | 1046 | first_draw_cmd = NULL; |
1047 | while (i < cmdbuf.size) { | 1047 | while (i < cmdbuf.size) { |
1048 | drm_savage_cmd_header_t cmd_header; | 1048 | drm_savage_cmd_header_t cmd_header; |
1049 | DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, | 1049 | cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr; |
1050 | sizeof(cmd_header)); | 1050 | cmdbuf.cmd_addr++; |
1051 | usr_cmdbuf++; | ||
1052 | i++; | 1051 | i++; |
1053 | 1052 | ||
1054 | /* Group drawing commands with same state to minimize | 1053 | /* Group drawing commands with same state to minimize |
@@ -1068,21 +1067,18 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1068 | case SAVAGE_CMD_DMA_PRIM: | 1067 | case SAVAGE_CMD_DMA_PRIM: |
1069 | case SAVAGE_CMD_VB_PRIM: | 1068 | case SAVAGE_CMD_VB_PRIM: |
1070 | if (!first_draw_cmd) | 1069 | if (!first_draw_cmd) |
1071 | first_draw_cmd = usr_cmdbuf - 1; | 1070 | first_draw_cmd = cmdbuf.cmd_addr - 1; |
1072 | usr_cmdbuf += j; | 1071 | cmdbuf.cmd_addr += j; |
1073 | i += j; | 1072 | i += j; |
1074 | break; | 1073 | break; |
1075 | default: | 1074 | default: |
1076 | if (first_draw_cmd) { | 1075 | if (first_draw_cmd) { |
1077 | ret = | 1076 | ret = savage_dispatch_draw( |
1078 | savage_dispatch_draw(dev_priv, | 1077 | dev_priv, first_draw_cmd, |
1079 | first_draw_cmd, | 1078 | cmdbuf.cmd_addr - 1, |
1080 | usr_cmdbuf - 1, dmabuf, | 1079 | dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size, |
1081 | usr_vtxbuf, | 1080 | cmdbuf.vb_stride, |
1082 | cmdbuf.vb_size, | 1081 | cmdbuf.nbox, cmdbuf.box_addr); |
1083 | cmdbuf.vb_stride, | ||
1084 | cmdbuf.nbox, | ||
1085 | usr_boxes); | ||
1086 | if (ret != 0) | 1082 | if (ret != 0) |
1087 | return ret; | 1083 | return ret; |
1088 | first_draw_cmd = NULL; | 1084 | first_draw_cmd = NULL; |
@@ -1098,12 +1094,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1098 | DRM_ERROR("command SAVAGE_CMD_STATE extends " | 1094 | DRM_ERROR("command SAVAGE_CMD_STATE extends " |
1099 | "beyond end of command buffer\n"); | 1095 | "beyond end of command buffer\n"); |
1100 | DMA_FLUSH(); | 1096 | DMA_FLUSH(); |
1101 | return DRM_ERR(EINVAL); | 1097 | ret = DRM_ERR(EINVAL); |
1098 | goto done; | ||
1102 | } | 1099 | } |
1103 | ret = savage_dispatch_state(dev_priv, &cmd_header, | 1100 | ret = savage_dispatch_state(dev_priv, &cmd_header, |
1104 | (uint32_t __user *) | 1101 | (const uint32_t *)cmdbuf.cmd_addr); |
1105 | usr_cmdbuf); | 1102 | cmdbuf.cmd_addr += j; |
1106 | usr_cmdbuf += j; | ||
1107 | i += j; | 1103 | i += j; |
1108 | break; | 1104 | break; |
1109 | case SAVAGE_CMD_CLEAR: | 1105 | case SAVAGE_CMD_CLEAR: |
@@ -1111,39 +1107,40 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1111 | DRM_ERROR("command SAVAGE_CMD_CLEAR extends " | 1107 | DRM_ERROR("command SAVAGE_CMD_CLEAR extends " |
1112 | "beyond end of command buffer\n"); | 1108 | "beyond end of command buffer\n"); |
1113 | DMA_FLUSH(); | 1109 | DMA_FLUSH(); |
1114 | return DRM_ERR(EINVAL); | 1110 | ret = DRM_ERR(EINVAL); |
1111 | goto done; | ||
1115 | } | 1112 | } |
1116 | ret = savage_dispatch_clear(dev_priv, &cmd_header, | 1113 | ret = savage_dispatch_clear(dev_priv, &cmd_header, |
1117 | usr_cmdbuf, | 1114 | cmdbuf.cmd_addr, |
1118 | cmdbuf.nbox, usr_boxes); | 1115 | cmdbuf.nbox, cmdbuf.box_addr); |
1119 | usr_cmdbuf++; | 1116 | cmdbuf.cmd_addr++; |
1120 | i++; | 1117 | i++; |
1121 | break; | 1118 | break; |
1122 | case SAVAGE_CMD_SWAP: | 1119 | case SAVAGE_CMD_SWAP: |
1123 | ret = savage_dispatch_swap(dev_priv, | 1120 | ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox, |
1124 | cmdbuf.nbox, usr_boxes); | 1121 | cmdbuf.box_addr); |
1125 | break; | 1122 | break; |
1126 | default: | 1123 | default: |
1127 | DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); | 1124 | DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); |
1128 | DMA_FLUSH(); | 1125 | DMA_FLUSH(); |
1129 | return DRM_ERR(EINVAL); | 1126 | ret = DRM_ERR(EINVAL); |
1127 | goto done; | ||
1130 | } | 1128 | } |
1131 | 1129 | ||
1132 | if (ret != 0) { | 1130 | if (ret != 0) { |
1133 | DMA_FLUSH(); | 1131 | DMA_FLUSH(); |
1134 | return ret; | 1132 | goto done; |
1135 | } | 1133 | } |
1136 | } | 1134 | } |
1137 | 1135 | ||
1138 | if (first_draw_cmd) { | 1136 | if (first_draw_cmd) { |
1139 | ret = | 1137 | ret = savage_dispatch_draw ( |
1140 | savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf, | 1138 | dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf, |
1141 | dmabuf, usr_vtxbuf, cmdbuf.vb_size, | 1139 | cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride, |
1142 | cmdbuf.vb_stride, cmdbuf.nbox, | 1140 | cmdbuf.nbox, cmdbuf.box_addr); |
1143 | usr_boxes); | ||
1144 | if (ret != 0) { | 1141 | if (ret != 0) { |
1145 | DMA_FLUSH(); | 1142 | DMA_FLUSH(); |
1146 | return ret; | 1143 | goto done; |
1147 | } | 1144 | } |
1148 | } | 1145 | } |
1149 | 1146 | ||
@@ -1157,5 +1154,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
1157 | savage_freelist_put(dev, dmabuf); | 1154 | savage_freelist_put(dev, dmabuf); |
1158 | } | 1155 | } |
1159 | 1156 | ||
1160 | return 0; | 1157 | done: |
1158 | /* If we didn't need to allocate them, these'll be NULL */ | ||
1159 | drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); | ||
1160 | drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER); | ||
1161 | drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t), | ||
1162 | DRM_MEM_DRIVER); | ||
1163 | |||
1164 | return ret; | ||
1161 | } | 1165 | } |
diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h index 8f273da76ddb..30f7b3827466 100644 --- a/drivers/char/drm/sis_drm.h +++ b/drivers/char/drm/sis_drm.h | |||
@@ -1,3 +1,28 @@ | |||
1 | /* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ | ||
2 | /* | ||
3 | * Copyright 2005 Eric Anholt | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the next | ||
14 | * paragraph) shall be included in all copies or substantial portions of the | ||
15 | * Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
23 | * SOFTWARE. | ||
24 | * | ||
25 | */ | ||
1 | 26 | ||
2 | #ifndef __SIS_DRM_H__ | 27 | #ifndef __SIS_DRM_H__ |
3 | #define __SIS_DRM_H__ | 28 | #define __SIS_DRM_H__ |
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c index 3cef10643a8f..6f6d7d613ede 100644 --- a/drivers/char/drm/sis_drv.c +++ b/drivers/char/drm/sis_drv.c | |||
@@ -32,31 +32,6 @@ | |||
32 | 32 | ||
33 | #include "drm_pciids.h" | 33 | #include "drm_pciids.h" |
34 | 34 | ||
35 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
36 | { | ||
37 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
38 | DRIVER_NAME, | ||
39 | DRIVER_MAJOR, | ||
40 | DRIVER_MINOR, | ||
41 | DRIVER_PATCHLEVEL, | ||
42 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
43 | ); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int version(drm_version_t * version) | ||
48 | { | ||
49 | int len; | ||
50 | |||
51 | version->version_major = DRIVER_MAJOR; | ||
52 | version->version_minor = DRIVER_MINOR; | ||
53 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
54 | DRM_COPY(version->name, DRIVER_NAME); | ||
55 | DRM_COPY(version->date, DRIVER_DATE); | ||
56 | DRM_COPY(version->desc, DRIVER_DESC); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static struct pci_device_id pciidlist[] = { | 35 | static struct pci_device_id pciidlist[] = { |
61 | sisdrv_PCI_IDS | 36 | sisdrv_PCI_IDS |
62 | }; | 37 | }; |
@@ -68,8 +43,6 @@ static struct drm_driver driver = { | |||
68 | .reclaim_buffers = drm_core_reclaim_buffers, | 43 | .reclaim_buffers = drm_core_reclaim_buffers, |
69 | .get_map_ofs = drm_core_get_map_ofs, | 44 | .get_map_ofs = drm_core_get_map_ofs, |
70 | .get_reg_ofs = drm_core_get_reg_ofs, | 45 | .get_reg_ofs = drm_core_get_reg_ofs, |
71 | .postinit = postinit, | ||
72 | .version = version, | ||
73 | .ioctls = sis_ioctls, | 46 | .ioctls = sis_ioctls, |
74 | .fops = { | 47 | .fops = { |
75 | .owner = THIS_MODULE, | 48 | .owner = THIS_MODULE, |
@@ -79,11 +52,18 @@ static struct drm_driver driver = { | |||
79 | .mmap = drm_mmap, | 52 | .mmap = drm_mmap, |
80 | .poll = drm_poll, | 53 | .poll = drm_poll, |
81 | .fasync = drm_fasync, | 54 | .fasync = drm_fasync, |
82 | }, | 55 | }, |
83 | .pci_driver = { | 56 | .pci_driver = { |
84 | .name = DRIVER_NAME, | 57 | .name = DRIVER_NAME, |
85 | .id_table = pciidlist, | 58 | .id_table = pciidlist, |
86 | } | 59 | }, |
60 | |||
61 | .name = DRIVER_NAME, | ||
62 | .desc = DRIVER_DESC, | ||
63 | .date = DRIVER_DATE, | ||
64 | .major = DRIVER_MAJOR, | ||
65 | .minor = DRIVER_MINOR, | ||
66 | .patchlevel = DRIVER_PATCHLEVEL, | ||
87 | }; | 67 | }; |
88 | 68 | ||
89 | static int __init sis_init(void) | 69 | static int __init sis_init(void) |
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h index b1fddad83a93..e218e5269503 100644 --- a/drivers/char/drm/sis_drv.h +++ b/drivers/char/drm/sis_drv.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* sis_drv.h -- Private header for sis driver -*- linux-c -*- | 1 | /* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | 3 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. |
4 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 4 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
5 | * All rights reserved. | 5 | * All rights reserved. |
diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h index da850b4f5440..94f2b4728b63 100644 --- a/drivers/char/drm/sis_ds.h +++ b/drivers/char/drm/sis_ds.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- | 1 | /* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- |
2 | * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw | 2 | * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw |
3 | * | 3 | */ |
4 | /* | ||
4 | * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. | 5 | * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | 7 | * |
@@ -35,7 +36,7 @@ | |||
35 | 36 | ||
36 | #define SET_SIZE 5000 | 37 | #define SET_SIZE 5000 |
37 | 38 | ||
38 | typedef unsigned int ITEM_TYPE; | 39 | typedef unsigned long ITEM_TYPE; |
39 | 40 | ||
40 | typedef struct { | 41 | typedef struct { |
41 | ITEM_TYPE val; | 42 | ITEM_TYPE val; |
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c index a8529728fa63..6774d2fe3452 100644 --- a/drivers/char/drm/sis_mm.c +++ b/drivers/char/drm/sis_mm.c | |||
@@ -86,7 +86,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) | |||
86 | { | 86 | { |
87 | drm_sis_mem_t fb; | 87 | drm_sis_mem_t fb; |
88 | struct sis_memreq req; | 88 | struct sis_memreq req; |
89 | drm_sis_mem_t __user *argp = (void __user *)data; | 89 | drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; |
90 | int retval = 0; | 90 | int retval = 0; |
91 | 91 | ||
92 | DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); | 92 | DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); |
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) | |||
110 | 110 | ||
111 | DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); | 111 | DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); |
112 | 112 | ||
113 | DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); | 113 | DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); |
114 | 114 | ||
115 | return retval; | 115 | return retval; |
116 | } | 116 | } |
@@ -127,9 +127,9 @@ static int sis_fb_free(DRM_IOCTL_ARGS) | |||
127 | 127 | ||
128 | if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) | 128 | if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) |
129 | retval = DRM_ERR(EINVAL); | 129 | retval = DRM_ERR(EINVAL); |
130 | sis_free((u32) fb.free); | 130 | sis_free(fb.free); |
131 | 131 | ||
132 | DRM_DEBUG("free fb, offset = %lu\n", fb.free); | 132 | DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free); |
133 | 133 | ||
134 | return retval; | 134 | return retval; |
135 | } | 135 | } |
@@ -176,7 +176,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) | |||
176 | { | 176 | { |
177 | DRM_DEVICE; | 177 | DRM_DEVICE; |
178 | drm_sis_private_t *dev_priv = dev->dev_private; | 178 | drm_sis_private_t *dev_priv = dev->dev_private; |
179 | drm_sis_mem_t __user *argp = (void __user *)data; | 179 | drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; |
180 | drm_sis_mem_t fb; | 180 | drm_sis_mem_t fb; |
181 | PMemBlock block; | 181 | PMemBlock block; |
182 | int retval = 0; | 182 | int retval = 0; |
@@ -267,7 +267,7 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS) | |||
267 | { | 267 | { |
268 | DRM_DEVICE; | 268 | DRM_DEVICE; |
269 | drm_sis_private_t *dev_priv = dev->dev_private; | 269 | drm_sis_private_t *dev_priv = dev->dev_private; |
270 | drm_sis_mem_t __user *argp = (void __user *)data; | 270 | drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; |
271 | drm_sis_mem_t agp; | 271 | drm_sis_mem_t agp; |
272 | PMemBlock block; | 272 | PMemBlock block; |
273 | int retval = 0; | 273 | int retval = 0; |
@@ -367,7 +367,7 @@ int sis_final_context(struct drm_device *dev, int context) | |||
367 | 367 | ||
368 | if (i < MAX_CONTEXT) { | 368 | if (i < MAX_CONTEXT) { |
369 | set_t *set; | 369 | set_t *set; |
370 | unsigned int item; | 370 | ITEM_TYPE item; |
371 | int retval; | 371 | int retval; |
372 | 372 | ||
373 | DRM_DEBUG("find socket %d, context = %d\n", i, context); | 373 | DRM_DEBUG("find socket %d, context = %d\n", i, context); |
@@ -376,7 +376,7 @@ int sis_final_context(struct drm_device *dev, int context) | |||
376 | set = global_ppriv[i].sets[0]; | 376 | set = global_ppriv[i].sets[0]; |
377 | retval = setFirst(set, &item); | 377 | retval = setFirst(set, &item); |
378 | while (retval) { | 378 | while (retval) { |
379 | DRM_DEBUG("free video memory 0x%x\n", item); | 379 | DRM_DEBUG("free video memory 0x%lx\n", item); |
380 | #if defined(__linux__) && defined(CONFIG_FB_SIS) | 380 | #if defined(__linux__) && defined(CONFIG_FB_SIS) |
381 | sis_free(item); | 381 | sis_free(item); |
382 | #else | 382 | #else |
@@ -390,7 +390,7 @@ int sis_final_context(struct drm_device *dev, int context) | |||
390 | set = global_ppriv[i].sets[1]; | 390 | set = global_ppriv[i].sets[1]; |
391 | retval = setFirst(set, &item); | 391 | retval = setFirst(set, &item); |
392 | while (retval) { | 392 | while (retval) { |
393 | DRM_DEBUG("free agp memory 0x%x\n", item); | 393 | DRM_DEBUG("free agp memory 0x%lx\n", item); |
394 | mmFreeMem((PMemBlock) item); | 394 | mmFreeMem((PMemBlock) item); |
395 | retval = setNext(set, &item); | 395 | retval = setNext(set, &item); |
396 | } | 396 | } |
@@ -403,12 +403,12 @@ int sis_final_context(struct drm_device *dev, int context) | |||
403 | } | 403 | } |
404 | 404 | ||
405 | drm_ioctl_desc_t sis_ioctls[] = { | 405 | drm_ioctl_desc_t sis_ioctls[] = { |
406 | [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0}, | 406 | [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH}, |
407 | [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0}, | 407 | [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH}, |
408 | [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1}, | 408 | [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
409 | [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0}, | 409 | [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH}, |
410 | [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0}, | 410 | [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH}, |
411 | [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1} | 411 | [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY} |
412 | }; | 412 | }; |
413 | 413 | ||
414 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); | 414 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); |
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c index c275cbb6e9ce..baa4416032a8 100644 --- a/drivers/char/drm/tdfx_drv.c +++ b/drivers/char/drm/tdfx_drv.c | |||
@@ -36,31 +36,6 @@ | |||
36 | 36 | ||
37 | #include "drm_pciids.h" | 37 | #include "drm_pciids.h" |
38 | 38 | ||
39 | static int postinit(struct drm_device *dev, unsigned long flags) | ||
40 | { | ||
41 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | ||
42 | DRIVER_NAME, | ||
43 | DRIVER_MAJOR, | ||
44 | DRIVER_MINOR, | ||
45 | DRIVER_PATCHLEVEL, | ||
46 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
47 | ); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static int version(drm_version_t * version) | ||
52 | { | ||
53 | int len; | ||
54 | |||
55 | version->version_major = DRIVER_MAJOR; | ||
56 | version->version_minor = DRIVER_MINOR; | ||
57 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
58 | DRM_COPY(version->name, DRIVER_NAME); | ||
59 | DRM_COPY(version->date, DRIVER_DATE); | ||
60 | DRM_COPY(version->desc, DRIVER_DESC); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static struct pci_device_id pciidlist[] = { | 39 | static struct pci_device_id pciidlist[] = { |
65 | tdfx_PCI_IDS | 40 | tdfx_PCI_IDS |
66 | }; | 41 | }; |
@@ -70,8 +45,6 @@ static struct drm_driver driver = { | |||
70 | .reclaim_buffers = drm_core_reclaim_buffers, | 45 | .reclaim_buffers = drm_core_reclaim_buffers, |
71 | .get_map_ofs = drm_core_get_map_ofs, | 46 | .get_map_ofs = drm_core_get_map_ofs, |
72 | .get_reg_ofs = drm_core_get_reg_ofs, | 47 | .get_reg_ofs = drm_core_get_reg_ofs, |
73 | .postinit = postinit, | ||
74 | .version = version, | ||
75 | .fops = { | 48 | .fops = { |
76 | .owner = THIS_MODULE, | 49 | .owner = THIS_MODULE, |
77 | .open = drm_open, | 50 | .open = drm_open, |
@@ -80,11 +53,18 @@ static struct drm_driver driver = { | |||
80 | .mmap = drm_mmap, | 53 | .mmap = drm_mmap, |
81 | .poll = drm_poll, | 54 | .poll = drm_poll, |
82 | .fasync = drm_fasync, | 55 | .fasync = drm_fasync, |
83 | }, | 56 | }, |
84 | .pci_driver = { | 57 | .pci_driver = { |
85 | .name = DRIVER_NAME, | 58 | .name = DRIVER_NAME, |
86 | .id_table = pciidlist, | 59 | .id_table = pciidlist, |
87 | } | 60 | }, |
61 | |||
62 | .name = DRIVER_NAME, | ||
63 | .desc = DRIVER_DESC, | ||
64 | .date = DRIVER_DATE, | ||
65 | .major = DRIVER_MAJOR, | ||
66 | .minor = DRIVER_MINOR, | ||
67 | .patchlevel = DRIVER_PATCHLEVEL, | ||
88 | }; | 68 | }; |
89 | 69 | ||
90 | static int __init tdfx_init(void) | 70 | static int __init tdfx_init(void) |
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h index a582a3db4c75..84204ec1b046 100644 --- a/drivers/char/drm/tdfx_drv.h +++ b/drivers/char/drm/tdfx_drv.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* tdfx.h -- 3dfx DRM template customization -*- linux-c -*- | 1 | /* tdfx.h -- 3dfx DRM template customization -*- linux-c -*- |
2 | * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com | 2 | * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com |
3 | * | 3 | */ |
4 | /* | ||
4 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
5 | * All Rights Reserved. | 6 | * All Rights Reserved. |
6 | * | 7 | * |
@@ -30,10 +31,6 @@ | |||
30 | #ifndef __TDFX_H__ | 31 | #ifndef __TDFX_H__ |
31 | #define __TDFX_H__ | 32 | #define __TDFX_H__ |
32 | 33 | ||
33 | /* This remains constant for all DRM template files. | ||
34 | */ | ||
35 | #define DRM(x) tdfx_##x | ||
36 | |||
37 | /* General customization: | 34 | /* General customization: |
38 | */ | 35 | */ |
39 | 36 | ||
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index d4b1766608b0..593c0b8f650a 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c | |||
@@ -213,7 +213,9 @@ static int via_initialize(drm_device_t * dev, | |||
213 | dev_priv->dma_wrap = init->size; | 213 | dev_priv->dma_wrap = init->size; |
214 | dev_priv->dma_offset = init->offset; | 214 | dev_priv->dma_offset = init->offset; |
215 | dev_priv->last_pause_ptr = NULL; | 215 | dev_priv->last_pause_ptr = NULL; |
216 | dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr; | 216 | dev_priv->hw_addr_ptr = |
217 | (volatile uint32_t *)((char *)dev_priv->mmio->handle + | ||
218 | init->reg_pause_addr); | ||
217 | 219 | ||
218 | via_cmdbuf_start(dev_priv); | 220 | via_cmdbuf_start(dev_priv); |
219 | 221 | ||
@@ -232,13 +234,13 @@ int via_dma_init(DRM_IOCTL_ARGS) | |||
232 | 234 | ||
233 | switch (init.func) { | 235 | switch (init.func) { |
234 | case VIA_INIT_DMA: | 236 | case VIA_INIT_DMA: |
235 | if (!capable(CAP_SYS_ADMIN)) | 237 | if (!DRM_SUSER(DRM_CURPROC)) |
236 | retcode = DRM_ERR(EPERM); | 238 | retcode = DRM_ERR(EPERM); |
237 | else | 239 | else |
238 | retcode = via_initialize(dev, dev_priv, &init); | 240 | retcode = via_initialize(dev, dev_priv, &init); |
239 | break; | 241 | break; |
240 | case VIA_CLEANUP_DMA: | 242 | case VIA_CLEANUP_DMA: |
241 | if (!capable(CAP_SYS_ADMIN)) | 243 | if (!DRM_SUSER(DRM_CURPROC)) |
242 | retcode = DRM_ERR(EPERM); | 244 | retcode = DRM_ERR(EPERM); |
243 | else | 245 | else |
244 | retcode = via_dma_cleanup(dev); | 246 | retcode = via_dma_cleanup(dev); |
@@ -349,9 +351,6 @@ int via_cmdbuffer(DRM_IOCTL_ARGS) | |||
349 | return 0; | 351 | return 0; |
350 | } | 352 | } |
351 | 353 | ||
352 | extern int | ||
353 | via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, | ||
354 | unsigned int size); | ||
355 | static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, | 354 | static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, |
356 | drm_via_cmdbuffer_t * cmd) | 355 | drm_via_cmdbuffer_t * cmd) |
357 | { | 356 | { |
@@ -450,9 +449,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
450 | if ((count <= 8) && (count >= 0)) { | 449 | if ((count <= 8) && (count >= 0)) { |
451 | uint32_t rgtr, ptr; | 450 | uint32_t rgtr, ptr; |
452 | rgtr = *(dev_priv->hw_addr_ptr); | 451 | rgtr = *(dev_priv->hw_addr_ptr); |
453 | ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + | 452 | ptr = ((volatile char *)dev_priv->last_pause_ptr - |
454 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - | 453 | dev_priv->dma_ptr) + dev_priv->dma_offset + |
455 | CMDBUF_ALIGNMENT_SIZE; | 454 | (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE; |
456 | if (rgtr <= ptr) { | 455 | if (rgtr <= ptr) { |
457 | DRM_ERROR | 456 | DRM_ERROR |
458 | ("Command regulator\npaused at count %d, address %x, " | 457 | ("Command regulator\npaused at count %d, address %x, " |
@@ -472,7 +471,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
472 | && count--) ; | 471 | && count--) ; |
473 | 472 | ||
474 | rgtr = *(dev_priv->hw_addr_ptr); | 473 | rgtr = *(dev_priv->hw_addr_ptr); |
475 | ptr = ((char *)paused_at - dev_priv->dma_ptr) + | 474 | ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + |
476 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; | 475 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; |
477 | 476 | ||
478 | ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? | 477 | ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? |
@@ -724,3 +723,22 @@ int via_cmdbuf_size(DRM_IOCTL_ARGS) | |||
724 | sizeof(d_siz)); | 723 | sizeof(d_siz)); |
725 | return ret; | 724 | return ret; |
726 | } | 725 | } |
726 | |||
727 | drm_ioctl_desc_t via_ioctls[] = { | ||
728 | [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, DRM_AUTH}, | ||
729 | [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, DRM_AUTH}, | ||
730 | [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, DRM_AUTH|DRM_MASTER}, | ||
731 | [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, DRM_AUTH|DRM_MASTER}, | ||
732 | [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, DRM_AUTH|DRM_MASTER}, | ||
733 | [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, DRM_AUTH}, | ||
734 | [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, DRM_AUTH}, | ||
735 | [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, DRM_AUTH}, | ||
736 | [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, DRM_AUTH}, | ||
737 | [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, DRM_AUTH}, | ||
738 | [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, DRM_AUTH}, | ||
739 | [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, DRM_AUTH}, | ||
740 | [DRM_IOCTL_NR(DRM_VIA_DMA_BLIT)] = {via_dma_blit, DRM_AUTH}, | ||
741 | [DRM_IOCTL_NR(DRM_VIA_BLIT_SYNC)] = {via_dma_blit_sync, DRM_AUTH} | ||
742 | }; | ||
743 | |||
744 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); | ||
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c new file mode 100644 index 000000000000..9d5e027dae0e --- /dev/null +++ b/drivers/char/drm/via_dmablit.c | |||
@@ -0,0 +1,805 @@ | |||
1 | /* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro | ||
2 | * | ||
3 | * Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the | ||
13 | * next paragraph) shall be included in all copies or substantial portions | ||
14 | * of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
20 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
21 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
22 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: | ||
25 | * Thomas Hellstrom. | ||
26 | * Partially based on code obtained from Digeo Inc. | ||
27 | */ | ||
28 | |||
29 | |||
30 | /* | ||
31 | * Unmaps the DMA mappings. | ||
32 | * FIXME: Is this a NoOp on x86? Also | ||
33 | * FIXME: What happens if this one is called and a pending blit has previously done | ||
34 | * the same DMA mappings? | ||
35 | */ | ||
36 | |||
37 | #include "drmP.h" | ||
38 | #include "via_drm.h" | ||
39 | #include "via_drv.h" | ||
40 | #include "via_dmablit.h" | ||
41 | |||
42 | #include <linux/pagemap.h> | ||
43 | |||
44 | #define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK) | ||
45 | #define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK) | ||
46 | #define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT) | ||
47 | |||
48 | typedef struct _drm_via_descriptor { | ||
49 | uint32_t mem_addr; | ||
50 | uint32_t dev_addr; | ||
51 | uint32_t size; | ||
52 | uint32_t next; | ||
53 | } drm_via_descriptor_t; | ||
54 | |||
55 | |||
56 | /* | ||
57 | * Unmap a DMA mapping. | ||
58 | */ | ||
59 | |||
60 | |||
61 | |||
62 | static void | ||
63 | via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | ||
64 | { | ||
65 | int num_desc = vsg->num_desc; | ||
66 | unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page; | ||
67 | unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page; | ||
68 | drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] + | ||
69 | descriptor_this_page; | ||
70 | dma_addr_t next = vsg->chain_start; | ||
71 | |||
72 | while(num_desc--) { | ||
73 | if (descriptor_this_page-- == 0) { | ||
74 | cur_descriptor_page--; | ||
75 | descriptor_this_page = vsg->descriptors_per_page - 1; | ||
76 | desc_ptr = vsg->desc_pages[cur_descriptor_page] + | ||
77 | descriptor_this_page; | ||
78 | } | ||
79 | dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE); | ||
80 | dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction); | ||
81 | next = (dma_addr_t) desc_ptr->next; | ||
82 | desc_ptr--; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * If mode = 0, count how many descriptors are needed. | ||
88 | * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors. | ||
89 | * Descriptors are run in reverse order by the hardware because we are not allowed to update the | ||
90 | * 'next' field without syncing calls when the descriptor is already mapped. | ||
91 | */ | ||
92 | |||
93 | static void | ||
94 | via_map_blit_for_device(struct pci_dev *pdev, | ||
95 | const drm_via_dmablit_t *xfer, | ||
96 | drm_via_sg_info_t *vsg, | ||
97 | int mode) | ||
98 | { | ||
99 | unsigned cur_descriptor_page = 0; | ||
100 | unsigned num_descriptors_this_page = 0; | ||
101 | unsigned char *mem_addr = xfer->mem_addr; | ||
102 | unsigned char *cur_mem; | ||
103 | unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr); | ||
104 | uint32_t fb_addr = xfer->fb_addr; | ||
105 | uint32_t cur_fb; | ||
106 | unsigned long line_len; | ||
107 | unsigned remaining_len; | ||
108 | int num_desc = 0; | ||
109 | int cur_line; | ||
110 | dma_addr_t next = 0 | VIA_DMA_DPR_EC; | ||
111 | drm_via_descriptor_t *desc_ptr = 0; | ||
112 | |||
113 | if (mode == 1) | ||
114 | desc_ptr = vsg->desc_pages[cur_descriptor_page]; | ||
115 | |||
116 | for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) { | ||
117 | |||
118 | line_len = xfer->line_length; | ||
119 | cur_fb = fb_addr; | ||
120 | cur_mem = mem_addr; | ||
121 | |||
122 | while (line_len > 0) { | ||
123 | |||
124 | remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len); | ||
125 | line_len -= remaining_len; | ||
126 | |||
127 | if (mode == 1) { | ||
128 | desc_ptr->mem_addr = | ||
129 | dma_map_page(&pdev->dev, | ||
130 | vsg->pages[VIA_PFN(cur_mem) - | ||
131 | VIA_PFN(first_addr)], | ||
132 | VIA_PGOFF(cur_mem), remaining_len, | ||
133 | vsg->direction); | ||
134 | desc_ptr->dev_addr = cur_fb; | ||
135 | |||
136 | desc_ptr->size = remaining_len; | ||
137 | desc_ptr->next = (uint32_t) next; | ||
138 | next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr), | ||
139 | DMA_TO_DEVICE); | ||
140 | desc_ptr++; | ||
141 | if (++num_descriptors_this_page >= vsg->descriptors_per_page) { | ||
142 | num_descriptors_this_page = 0; | ||
143 | desc_ptr = vsg->desc_pages[++cur_descriptor_page]; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | num_desc++; | ||
148 | cur_mem += remaining_len; | ||
149 | cur_fb += remaining_len; | ||
150 | } | ||
151 | |||
152 | mem_addr += xfer->mem_stride; | ||
153 | fb_addr += xfer->fb_stride; | ||
154 | } | ||
155 | |||
156 | if (mode == 1) { | ||
157 | vsg->chain_start = next; | ||
158 | vsg->state = dr_via_device_mapped; | ||
159 | } | ||
160 | vsg->num_desc = num_desc; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Function that frees up all resources for a blit. It is usable even if the | ||
165 | * blit info has only be partially built as long as the status enum is consistent | ||
166 | * with the actual status of the used resources. | ||
167 | */ | ||
168 | |||
169 | |||
170 | void | ||
171 | via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | ||
172 | { | ||
173 | struct page *page; | ||
174 | int i; | ||
175 | |||
176 | switch(vsg->state) { | ||
177 | case dr_via_device_mapped: | ||
178 | via_unmap_blit_from_device(pdev, vsg); | ||
179 | case dr_via_desc_pages_alloc: | ||
180 | for (i=0; i<vsg->num_desc_pages; ++i) { | ||
181 | if (vsg->desc_pages[i] != NULL) | ||
182 | free_page((unsigned long)vsg->desc_pages[i]); | ||
183 | } | ||
184 | kfree(vsg->desc_pages); | ||
185 | case dr_via_pages_locked: | ||
186 | for (i=0; i<vsg->num_pages; ++i) { | ||
187 | if ( NULL != (page = vsg->pages[i])) { | ||
188 | if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) | ||
189 | SetPageDirty(page); | ||
190 | page_cache_release(page); | ||
191 | } | ||
192 | } | ||
193 | case dr_via_pages_alloc: | ||
194 | vfree(vsg->pages); | ||
195 | default: | ||
196 | vsg->state = dr_via_sg_init; | ||
197 | } | ||
198 | if (vsg->bounce_buffer) { | ||
199 | vfree(vsg->bounce_buffer); | ||
200 | vsg->bounce_buffer = NULL; | ||
201 | } | ||
202 | vsg->free_on_sequence = 0; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Fire a blit engine. | ||
207 | */ | ||
208 | |||
209 | static void | ||
210 | via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine) | ||
211 | { | ||
212 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
213 | |||
214 | VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0); | ||
215 | VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0); | ||
216 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD | | ||
217 | VIA_DMA_CSR_DE); | ||
218 | VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); | ||
219 | VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); | ||
220 | VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); | ||
221 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will | ||
226 | * occur here if the calling user does not have access to the submitted address. | ||
227 | */ | ||
228 | |||
229 | static int | ||
230 | via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) | ||
231 | { | ||
232 | int ret; | ||
233 | unsigned long first_pfn = VIA_PFN(xfer->mem_addr); | ||
234 | vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) - | ||
235 | first_pfn + 1; | ||
236 | |||
237 | if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) | ||
238 | return DRM_ERR(ENOMEM); | ||
239 | memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); | ||
240 | down_read(¤t->mm->mmap_sem); | ||
241 | ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr, | ||
242 | vsg->num_pages, vsg->direction, 0, vsg->pages, NULL); | ||
243 | |||
244 | up_read(¤t->mm->mmap_sem); | ||
245 | if (ret != vsg->num_pages) { | ||
246 | if (ret < 0) | ||
247 | return ret; | ||
248 | vsg->state = dr_via_pages_locked; | ||
249 | return DRM_ERR(EINVAL); | ||
250 | } | ||
251 | vsg->state = dr_via_pages_locked; | ||
252 | DRM_DEBUG("DMA pages locked\n"); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the | ||
258 | * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be | ||
259 | * quite large for some blits, and pages don't need to be contingous. | ||
260 | */ | ||
261 | |||
262 | static int | ||
263 | via_alloc_desc_pages(drm_via_sg_info_t *vsg) | ||
264 | { | ||
265 | int i; | ||
266 | |||
267 | vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t); | ||
268 | vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / | ||
269 | vsg->descriptors_per_page; | ||
270 | |||
271 | if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL))) | ||
272 | return DRM_ERR(ENOMEM); | ||
273 | |||
274 | memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages); | ||
275 | vsg->state = dr_via_desc_pages_alloc; | ||
276 | for (i=0; i<vsg->num_desc_pages; ++i) { | ||
277 | if (NULL == (vsg->desc_pages[i] = | ||
278 | (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) | ||
279 | return DRM_ERR(ENOMEM); | ||
280 | } | ||
281 | DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages, | ||
282 | vsg->num_desc); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void | ||
287 | via_abort_dmablit(drm_device_t *dev, int engine) | ||
288 | { | ||
289 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
290 | |||
291 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA); | ||
292 | } | ||
293 | |||
294 | static void | ||
295 | via_dmablit_engine_off(drm_device_t *dev, int engine) | ||
296 | { | ||
297 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
298 | |||
299 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD); | ||
300 | } | ||
301 | |||
302 | |||
303 | |||
304 | /* | ||
305 | * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here. | ||
306 | * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue | ||
307 | * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while | ||
308 | * the workqueue task takes care of processing associated with the old blit. | ||
309 | */ | ||
310 | |||
311 | void | ||
312 | via_dmablit_handler(drm_device_t *dev, int engine, int from_irq) | ||
313 | { | ||
314 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
315 | drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; | ||
316 | int cur; | ||
317 | int done_transfer; | ||
318 | unsigned long irqsave=0; | ||
319 | uint32_t status = 0; | ||
320 | |||
321 | DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", | ||
322 | engine, from_irq, (unsigned long) blitq); | ||
323 | |||
324 | if (from_irq) { | ||
325 | spin_lock(&blitq->blit_lock); | ||
326 | } else { | ||
327 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
328 | } | ||
329 | |||
330 | done_transfer = blitq->is_active && | ||
331 | (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); | ||
332 | done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE)); | ||
333 | |||
334 | cur = blitq->cur; | ||
335 | if (done_transfer) { | ||
336 | |||
337 | blitq->blits[cur]->aborted = blitq->aborting; | ||
338 | blitq->done_blit_handle++; | ||
339 | DRM_WAKEUP(blitq->blit_queue + cur); | ||
340 | |||
341 | cur++; | ||
342 | if (cur >= VIA_NUM_BLIT_SLOTS) | ||
343 | cur = 0; | ||
344 | blitq->cur = cur; | ||
345 | |||
346 | /* | ||
347 | * Clear transfer done flag. | ||
348 | */ | ||
349 | |||
350 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD); | ||
351 | |||
352 | blitq->is_active = 0; | ||
353 | blitq->aborting = 0; | ||
354 | schedule_work(&blitq->wq); | ||
355 | |||
356 | } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) { | ||
357 | |||
358 | /* | ||
359 | * Abort transfer after one second. | ||
360 | */ | ||
361 | |||
362 | via_abort_dmablit(dev, engine); | ||
363 | blitq->aborting = 1; | ||
364 | blitq->end = jiffies + DRM_HZ; | ||
365 | } | ||
366 | |||
367 | if (!blitq->is_active) { | ||
368 | if (blitq->num_outstanding) { | ||
369 | via_fire_dmablit(dev, blitq->blits[cur], engine); | ||
370 | blitq->is_active = 1; | ||
371 | blitq->cur = cur; | ||
372 | blitq->num_outstanding--; | ||
373 | blitq->end = jiffies + DRM_HZ; | ||
374 | if (!timer_pending(&blitq->poll_timer)) { | ||
375 | blitq->poll_timer.expires = jiffies+1; | ||
376 | add_timer(&blitq->poll_timer); | ||
377 | } | ||
378 | } else { | ||
379 | if (timer_pending(&blitq->poll_timer)) { | ||
380 | del_timer(&blitq->poll_timer); | ||
381 | } | ||
382 | via_dmablit_engine_off(dev, engine); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | if (from_irq) { | ||
387 | spin_unlock(&blitq->blit_lock); | ||
388 | } else { | ||
389 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | |||
394 | |||
395 | /* | ||
396 | * Check whether this blit is still active, performing necessary locking. | ||
397 | */ | ||
398 | |||
399 | static int | ||
400 | via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue) | ||
401 | { | ||
402 | unsigned long irqsave; | ||
403 | uint32_t slot; | ||
404 | int active; | ||
405 | |||
406 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
407 | |||
408 | /* | ||
409 | * Allow for handle wraparounds. | ||
410 | */ | ||
411 | |||
412 | active = ((blitq->done_blit_handle - handle) > (1 << 23)) && | ||
413 | ((blitq->cur_blit_handle - handle) <= (1 << 23)); | ||
414 | |||
415 | if (queue && active) { | ||
416 | slot = handle - blitq->done_blit_handle + blitq->cur -1; | ||
417 | if (slot >= VIA_NUM_BLIT_SLOTS) { | ||
418 | slot -= VIA_NUM_BLIT_SLOTS; | ||
419 | } | ||
420 | *queue = blitq->blit_queue + slot; | ||
421 | } | ||
422 | |||
423 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
424 | |||
425 | return active; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * Sync. Wait for at least three seconds for the blit to be performed. | ||
430 | */ | ||
431 | |||
432 | static int | ||
433 | via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine) | ||
434 | { | ||
435 | |||
436 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
437 | drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; | ||
438 | wait_queue_head_t *queue; | ||
439 | int ret = 0; | ||
440 | |||
441 | if (via_dmablit_active(blitq, engine, handle, &queue)) { | ||
442 | DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ, | ||
443 | !via_dmablit_active(blitq, engine, handle, NULL)); | ||
444 | } | ||
445 | DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n", | ||
446 | handle, engine, ret); | ||
447 | |||
448 | return ret; | ||
449 | } | ||
450 | |||
451 | |||
452 | /* | ||
453 | * A timer that regularly polls the blit engine in cases where we don't have interrupts: | ||
454 | * a) Broken hardware (typically those that don't have any video capture facility). | ||
455 | * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted. | ||
456 | * The timer and hardware IRQ's can and do work in parallel. If the hardware has | ||
457 | * irqs, it will shorten the latency somewhat. | ||
458 | */ | ||
459 | |||
460 | |||
461 | |||
462 | static void | ||
463 | via_dmablit_timer(unsigned long data) | ||
464 | { | ||
465 | drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; | ||
466 | drm_device_t *dev = blitq->dev; | ||
467 | int engine = (int) | ||
468 | (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues); | ||
469 | |||
470 | DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine, | ||
471 | (unsigned long) jiffies); | ||
472 | |||
473 | via_dmablit_handler(dev, engine, 0); | ||
474 | |||
475 | if (!timer_pending(&blitq->poll_timer)) { | ||
476 | blitq->poll_timer.expires = jiffies+1; | ||
477 | add_timer(&blitq->poll_timer); | ||
478 | } | ||
479 | via_dmablit_handler(dev, engine, 0); | ||
480 | |||
481 | } | ||
482 | |||
483 | |||
484 | |||
485 | |||
486 | /* | ||
487 | * Workqueue task that frees data and mappings associated with a blit. | ||
488 | * Also wakes up waiting processes. Each of these tasks handles one | ||
489 | * blit engine only and may not be called on each interrupt. | ||
490 | */ | ||
491 | |||
492 | |||
493 | static void | ||
494 | via_dmablit_workqueue(void *data) | ||
495 | { | ||
496 | drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; | ||
497 | drm_device_t *dev = blitq->dev; | ||
498 | unsigned long irqsave; | ||
499 | drm_via_sg_info_t *cur_sg; | ||
500 | int cur_released; | ||
501 | |||
502 | |||
503 | DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long) | ||
504 | (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); | ||
505 | |||
506 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
507 | |||
508 | while(blitq->serviced != blitq->cur) { | ||
509 | |||
510 | cur_released = blitq->serviced++; | ||
511 | |||
512 | DRM_DEBUG("Releasing blit slot %d\n", cur_released); | ||
513 | |||
514 | if (blitq->serviced >= VIA_NUM_BLIT_SLOTS) | ||
515 | blitq->serviced = 0; | ||
516 | |||
517 | cur_sg = blitq->blits[cur_released]; | ||
518 | blitq->num_free++; | ||
519 | |||
520 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
521 | |||
522 | DRM_WAKEUP(&blitq->busy_queue); | ||
523 | |||
524 | via_free_sg_info(dev->pdev, cur_sg); | ||
525 | kfree(cur_sg); | ||
526 | |||
527 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
528 | } | ||
529 | |||
530 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
531 | } | ||
532 | |||
533 | |||
534 | /* | ||
535 | * Init all blit engines. Currently we use two, but some hardware have 4. | ||
536 | */ | ||
537 | |||
538 | |||
539 | void | ||
540 | via_init_dmablit(drm_device_t *dev) | ||
541 | { | ||
542 | int i,j; | ||
543 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
544 | drm_via_blitq_t *blitq; | ||
545 | |||
546 | pci_set_master(dev->pdev); | ||
547 | |||
548 | for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) { | ||
549 | blitq = dev_priv->blit_queues + i; | ||
550 | blitq->dev = dev; | ||
551 | blitq->cur_blit_handle = 0; | ||
552 | blitq->done_blit_handle = 0; | ||
553 | blitq->head = 0; | ||
554 | blitq->cur = 0; | ||
555 | blitq->serviced = 0; | ||
556 | blitq->num_free = VIA_NUM_BLIT_SLOTS; | ||
557 | blitq->num_outstanding = 0; | ||
558 | blitq->is_active = 0; | ||
559 | blitq->aborting = 0; | ||
560 | blitq->blit_lock = SPIN_LOCK_UNLOCKED; | ||
561 | for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) { | ||
562 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); | ||
563 | } | ||
564 | DRM_INIT_WAITQUEUE(&blitq->busy_queue); | ||
565 | INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq); | ||
566 | init_timer(&blitq->poll_timer); | ||
567 | blitq->poll_timer.function = &via_dmablit_timer; | ||
568 | blitq->poll_timer.data = (unsigned long) blitq; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * Build all info and do all mappings required for a blit. | ||
574 | */ | ||
575 | |||
576 | |||
577 | static int | ||
578 | via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) | ||
579 | { | ||
580 | int draw = xfer->to_fb; | ||
581 | int ret = 0; | ||
582 | |||
583 | vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
584 | vsg->bounce_buffer = 0; | ||
585 | |||
586 | vsg->state = dr_via_sg_init; | ||
587 | |||
588 | if (xfer->num_lines <= 0 || xfer->line_length <= 0) { | ||
589 | DRM_ERROR("Zero size bitblt.\n"); | ||
590 | return DRM_ERR(EINVAL); | ||
591 | } | ||
592 | |||
593 | /* | ||
594 | * Below check is a driver limitation, not a hardware one. We | ||
595 | * don't want to lock unused pages, and don't want to incoporate the | ||
596 | * extra logic of avoiding them. Make sure there are no. | ||
597 | * (Not a big limitation anyway.) | ||
598 | */ | ||
599 | |||
600 | if (((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) || | ||
601 | (xfer->mem_stride > 2048*4)) { | ||
602 | DRM_ERROR("Too large system memory stride. Stride: %d, " | ||
603 | "Length: %d\n", xfer->mem_stride, xfer->line_length); | ||
604 | return DRM_ERR(EINVAL); | ||
605 | } | ||
606 | |||
607 | if (xfer->num_lines > 2048) { | ||
608 | DRM_ERROR("Too many PCI DMA bitblt lines.\n"); | ||
609 | return DRM_ERR(EINVAL); | ||
610 | } | ||
611 | |||
612 | /* | ||
613 | * we allow a negative fb stride to allow flipping of images in | ||
614 | * transfer. | ||
615 | */ | ||
616 | |||
617 | if (xfer->mem_stride < xfer->line_length || | ||
618 | abs(xfer->fb_stride) < xfer->line_length) { | ||
619 | DRM_ERROR("Invalid frame-buffer / memory stride.\n"); | ||
620 | return DRM_ERR(EINVAL); | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * A hardware bug seems to be worked around if system memory addresses start on | ||
625 | * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted | ||
626 | * about this. Meanwhile, impose the following restrictions: | ||
627 | */ | ||
628 | |||
629 | #ifdef VIA_BUGFREE | ||
630 | if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) || | ||
631 | ((xfer->mem_stride & 3) != (xfer->fb_stride & 3))) { | ||
632 | DRM_ERROR("Invalid DRM bitblt alignment.\n"); | ||
633 | return DRM_ERR(EINVAL); | ||
634 | } | ||
635 | #else | ||
636 | if ((((unsigned long)xfer->mem_addr & 15) || | ||
637 | ((unsigned long)xfer->fb_addr & 3)) || (xfer->mem_stride & 15) || | ||
638 | (xfer->fb_stride & 3)) { | ||
639 | DRM_ERROR("Invalid DRM bitblt alignment.\n"); | ||
640 | return DRM_ERR(EINVAL); | ||
641 | } | ||
642 | #endif | ||
643 | |||
644 | if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) { | ||
645 | DRM_ERROR("Could not lock DMA pages.\n"); | ||
646 | via_free_sg_info(dev->pdev, vsg); | ||
647 | return ret; | ||
648 | } | ||
649 | |||
650 | via_map_blit_for_device(dev->pdev, xfer, vsg, 0); | ||
651 | if (0 != (ret = via_alloc_desc_pages(vsg))) { | ||
652 | DRM_ERROR("Could not allocate DMA descriptor pages.\n"); | ||
653 | via_free_sg_info(dev->pdev, vsg); | ||
654 | return ret; | ||
655 | } | ||
656 | via_map_blit_for_device(dev->pdev, xfer, vsg, 1); | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | |||
662 | /* | ||
663 | * Reserve one free slot in the blit queue. Will wait for one second for one | ||
664 | * to become available. Otherwise -EBUSY is returned. | ||
665 | */ | ||
666 | |||
667 | static int | ||
668 | via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) | ||
669 | { | ||
670 | int ret=0; | ||
671 | unsigned long irqsave; | ||
672 | |||
673 | DRM_DEBUG("Num free is %d\n", blitq->num_free); | ||
674 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
675 | while(blitq->num_free == 0) { | ||
676 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
677 | |||
678 | DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); | ||
679 | if (ret) { | ||
680 | return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret; | ||
681 | } | ||
682 | |||
683 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
684 | } | ||
685 | |||
686 | blitq->num_free--; | ||
687 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
688 | |||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | /* | ||
693 | * Hand back a free slot if we changed our mind. | ||
694 | */ | ||
695 | |||
696 | static void | ||
697 | via_dmablit_release_slot(drm_via_blitq_t *blitq) | ||
698 | { | ||
699 | unsigned long irqsave; | ||
700 | |||
701 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
702 | blitq->num_free++; | ||
703 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
704 | DRM_WAKEUP( &blitq->busy_queue ); | ||
705 | } | ||
706 | |||
707 | /* | ||
708 | * Grab a free slot. Build blit info and queue a blit. | ||
709 | */ | ||
710 | |||
711 | |||
712 | static int | ||
713 | via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer) | ||
714 | { | ||
715 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | ||
716 | drm_via_sg_info_t *vsg; | ||
717 | drm_via_blitq_t *blitq; | ||
718 | int ret; | ||
719 | int engine; | ||
720 | unsigned long irqsave; | ||
721 | |||
722 | if (dev_priv == NULL) { | ||
723 | DRM_ERROR("Called without initialization.\n"); | ||
724 | return DRM_ERR(EINVAL); | ||
725 | } | ||
726 | |||
727 | engine = (xfer->to_fb) ? 0 : 1; | ||
728 | blitq = dev_priv->blit_queues + engine; | ||
729 | if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) { | ||
730 | return ret; | ||
731 | } | ||
732 | if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { | ||
733 | via_dmablit_release_slot(blitq); | ||
734 | return DRM_ERR(ENOMEM); | ||
735 | } | ||
736 | if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) { | ||
737 | via_dmablit_release_slot(blitq); | ||
738 | kfree(vsg); | ||
739 | return ret; | ||
740 | } | ||
741 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | ||
742 | |||
743 | blitq->blits[blitq->head++] = vsg; | ||
744 | if (blitq->head >= VIA_NUM_BLIT_SLOTS) | ||
745 | blitq->head = 0; | ||
746 | blitq->num_outstanding++; | ||
747 | xfer->sync.sync_handle = ++blitq->cur_blit_handle; | ||
748 | |||
749 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | ||
750 | xfer->sync.engine = engine; | ||
751 | |||
752 | via_dmablit_handler(dev, engine, 0); | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * Sync on a previously submitted blit. Note that the X server use signals extensively, and | ||
759 | * that there is a very big proability that this IOCTL will be interrupted by a signal. In that | ||
760 | * case it returns with -EAGAIN for the signal to be delivered. | ||
761 | * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock(). | ||
762 | */ | ||
763 | |||
764 | int | ||
765 | via_dma_blit_sync( DRM_IOCTL_ARGS ) | ||
766 | { | ||
767 | drm_via_blitsync_t sync; | ||
768 | int err; | ||
769 | DRM_DEVICE; | ||
770 | |||
771 | DRM_COPY_FROM_USER_IOCTL(sync, (drm_via_blitsync_t *)data, sizeof(sync)); | ||
772 | |||
773 | if (sync.engine >= VIA_NUM_BLIT_ENGINES) | ||
774 | return DRM_ERR(EINVAL); | ||
775 | |||
776 | err = via_dmablit_sync(dev, sync.sync_handle, sync.engine); | ||
777 | |||
778 | if (DRM_ERR(EINTR) == err) | ||
779 | err = DRM_ERR(EAGAIN); | ||
780 | |||
781 | return err; | ||
782 | } | ||
783 | |||
784 | |||
785 | /* | ||
786 | * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal | ||
787 | * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should | ||
788 | * be reissued. See the above IOCTL code. | ||
789 | */ | ||
790 | |||
791 | int | ||
792 | via_dma_blit( DRM_IOCTL_ARGS ) | ||
793 | { | ||
794 | drm_via_dmablit_t xfer; | ||
795 | int err; | ||
796 | DRM_DEVICE; | ||
797 | |||
798 | DRM_COPY_FROM_USER_IOCTL(xfer, (drm_via_dmablit_t __user *)data, sizeof(xfer)); | ||
799 | |||
800 | err = via_dmablit(dev, &xfer); | ||
801 | |||
802 | DRM_COPY_TO_USER_IOCTL((void __user *)data, xfer, sizeof(xfer)); | ||
803 | |||
804 | return err; | ||
805 | } | ||
diff --git a/drivers/char/drm/via_dmablit.h b/drivers/char/drm/via_dmablit.h new file mode 100644 index 000000000000..f4036cd5d0e0 --- /dev/null +++ b/drivers/char/drm/via_dmablit.h | |||
@@ -0,0 +1,140 @@ | |||
1 | /* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro | ||
2 | * | ||
3 | * Copyright 2005 Thomas Hellstrom. | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the | ||
14 | * next paragraph) shall be included in all copies or substantial portions | ||
15 | * of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
20 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
21 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
22 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellstrom. | ||
27 | * Register info from Digeo Inc. | ||
28 | */ | ||
29 | |||
30 | #ifndef _VIA_DMABLIT_H | ||
31 | #define _VIA_DMABLIT_H | ||
32 | |||
33 | #include <linux/dma-mapping.h> | ||
34 | |||
35 | #define VIA_NUM_BLIT_ENGINES 2 | ||
36 | #define VIA_NUM_BLIT_SLOTS 8 | ||
37 | |||
38 | struct _drm_via_descriptor; | ||
39 | |||
40 | typedef struct _drm_via_sg_info { | ||
41 | struct page **pages; | ||
42 | unsigned long num_pages; | ||
43 | struct _drm_via_descriptor **desc_pages; | ||
44 | int num_desc_pages; | ||
45 | int num_desc; | ||
46 | enum dma_data_direction direction; | ||
47 | unsigned char *bounce_buffer; | ||
48 | dma_addr_t chain_start; | ||
49 | uint32_t free_on_sequence; | ||
50 | unsigned int descriptors_per_page; | ||
51 | int aborted; | ||
52 | enum { | ||
53 | dr_via_device_mapped, | ||
54 | dr_via_desc_pages_alloc, | ||
55 | dr_via_pages_locked, | ||
56 | dr_via_pages_alloc, | ||
57 | dr_via_sg_init | ||
58 | } state; | ||
59 | } drm_via_sg_info_t; | ||
60 | |||
61 | typedef struct _drm_via_blitq { | ||
62 | drm_device_t *dev; | ||
63 | uint32_t cur_blit_handle; | ||
64 | uint32_t done_blit_handle; | ||
65 | unsigned serviced; | ||
66 | unsigned head; | ||
67 | unsigned cur; | ||
68 | unsigned num_free; | ||
69 | unsigned num_outstanding; | ||
70 | unsigned long end; | ||
71 | int aborting; | ||
72 | int is_active; | ||
73 | drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; | ||
74 | spinlock_t blit_lock; | ||
75 | wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS]; | ||
76 | wait_queue_head_t busy_queue; | ||
77 | struct work_struct wq; | ||
78 | struct timer_list poll_timer; | ||
79 | } drm_via_blitq_t; | ||
80 | |||
81 | |||
82 | /* | ||
83 | * PCI DMA Registers | ||
84 | * Channels 2 & 3 don't seem to be implemented in hardware. | ||
85 | */ | ||
86 | |||
87 | #define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */ | ||
88 | #define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */ | ||
89 | #define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */ | ||
90 | #define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */ | ||
91 | |||
92 | #define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */ | ||
93 | #define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */ | ||
94 | #define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */ | ||
95 | #define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */ | ||
96 | |||
97 | #define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */ | ||
98 | #define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */ | ||
99 | #define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */ | ||
100 | #define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */ | ||
101 | |||
102 | #define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */ | ||
103 | #define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */ | ||
104 | #define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */ | ||
105 | #define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */ | ||
106 | |||
107 | #define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */ | ||
108 | #define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */ | ||
109 | #define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */ | ||
110 | #define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */ | ||
111 | |||
112 | #define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */ | ||
113 | #define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */ | ||
114 | #define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */ | ||
115 | #define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */ | ||
116 | |||
117 | #define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */ | ||
118 | |||
119 | /* Define for DMA engine */ | ||
120 | /* DPR */ | ||
121 | #define VIA_DMA_DPR_EC (1<<1) /* end of chain */ | ||
122 | #define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */ | ||
123 | #define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */ | ||
124 | |||
125 | /* MR */ | ||
126 | #define VIA_DMA_MR_CM (1<<0) /* chaining mode */ | ||
127 | #define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */ | ||
128 | #define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */ | ||
129 | |||
130 | /* CSR */ | ||
131 | #define VIA_DMA_CSR_DE (1<<0) /* DMA enable */ | ||
132 | #define VIA_DMA_CSR_TS (1<<1) /* transfer start */ | ||
133 | #define VIA_DMA_CSR_TA (1<<2) /* transfer abort */ | ||
134 | #define VIA_DMA_CSR_TD (1<<3) /* transfer done */ | ||
135 | #define VIA_DMA_CSR_DD (1<<4) /* descriptor done */ | ||
136 | #define VIA_DMA_DPR_EC (1<<1) /* end of chain */ | ||
137 | |||
138 | |||
139 | |||
140 | #endif | ||
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h index ebde9206115e..47f0b5b26379 100644 --- a/drivers/char/drm/via_drm.h +++ b/drivers/char/drm/via_drm.h | |||
@@ -75,6 +75,8 @@ | |||
75 | #define DRM_VIA_CMDBUF_SIZE 0x0b | 75 | #define DRM_VIA_CMDBUF_SIZE 0x0b |
76 | #define NOT_USED | 76 | #define NOT_USED |
77 | #define DRM_VIA_WAIT_IRQ 0x0d | 77 | #define DRM_VIA_WAIT_IRQ 0x0d |
78 | #define DRM_VIA_DMA_BLIT 0x0e | ||
79 | #define DRM_VIA_BLIT_SYNC 0x0f | ||
78 | 80 | ||
79 | #define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) | 81 | #define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) |
80 | #define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) | 82 | #define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) |
@@ -89,6 +91,8 @@ | |||
89 | #define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ | 91 | #define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ |
90 | drm_via_cmdbuf_size_t) | 92 | drm_via_cmdbuf_size_t) |
91 | #define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) | 93 | #define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) |
94 | #define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t) | ||
95 | #define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t) | ||
92 | 96 | ||
93 | /* Indices into buf.Setup where various bits of state are mirrored per | 97 | /* Indices into buf.Setup where various bits of state are mirrored per |
94 | * context and per buffer. These can be fired at the card as a unit, | 98 | * context and per buffer. These can be fired at the card as a unit, |
@@ -103,8 +107,12 @@ | |||
103 | #define VIA_BACK 0x2 | 107 | #define VIA_BACK 0x2 |
104 | #define VIA_DEPTH 0x4 | 108 | #define VIA_DEPTH 0x4 |
105 | #define VIA_STENCIL 0x8 | 109 | #define VIA_STENCIL 0x8 |
106 | #define VIDEO 0 | 110 | #define VIA_MEM_VIDEO 0 /* matches drm constant */ |
107 | #define AGP 1 | 111 | #define VIA_MEM_AGP 1 /* matches drm constant */ |
112 | #define VIA_MEM_SYSTEM 2 | ||
113 | #define VIA_MEM_MIXED 3 | ||
114 | #define VIA_MEM_UNKNOWN 4 | ||
115 | |||
108 | typedef struct { | 116 | typedef struct { |
109 | uint32_t offset; | 117 | uint32_t offset; |
110 | uint32_t size; | 118 | uint32_t size; |
@@ -192,6 +200,9 @@ typedef struct _drm_via_sarea { | |||
192 | unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS]; | 200 | unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS]; |
193 | unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */ | 201 | unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */ |
194 | 202 | ||
203 | /* Used by the 3d driver only at this point, for pageflipping: | ||
204 | */ | ||
205 | unsigned int pfCurrentOffset; | ||
195 | } drm_via_sarea_t; | 206 | } drm_via_sarea_t; |
196 | 207 | ||
197 | typedef struct _drm_via_cmdbuf_size { | 208 | typedef struct _drm_via_cmdbuf_size { |
@@ -212,6 +223,16 @@ typedef enum { | |||
212 | 223 | ||
213 | #define VIA_IRQ_FLAGS_MASK 0xF0000000 | 224 | #define VIA_IRQ_FLAGS_MASK 0xF0000000 |
214 | 225 | ||
226 | enum drm_via_irqs { | ||
227 | drm_via_irq_hqv0 = 0, | ||
228 | drm_via_irq_hqv1, | ||
229 | drm_via_irq_dma0_dd, | ||
230 | drm_via_irq_dma0_td, | ||
231 | drm_via_irq_dma1_dd, | ||
232 | drm_via_irq_dma1_td, | ||
233 | drm_via_irq_num | ||
234 | }; | ||
235 | |||
215 | struct drm_via_wait_irq_request { | 236 | struct drm_via_wait_irq_request { |
216 | unsigned irq; | 237 | unsigned irq; |
217 | via_irq_seq_type_t type; | 238 | via_irq_seq_type_t type; |
@@ -224,20 +245,25 @@ typedef union drm_via_irqwait { | |||
224 | struct drm_wait_vblank_reply reply; | 245 | struct drm_wait_vblank_reply reply; |
225 | } drm_via_irqwait_t; | 246 | } drm_via_irqwait_t; |
226 | 247 | ||
227 | #ifdef __KERNEL__ | 248 | typedef struct drm_via_blitsync { |
228 | 249 | uint32_t sync_handle; | |
229 | int via_fb_init(DRM_IOCTL_ARGS); | 250 | unsigned engine; |
230 | int via_mem_alloc(DRM_IOCTL_ARGS); | 251 | } drm_via_blitsync_t; |
231 | int via_mem_free(DRM_IOCTL_ARGS); | 252 | |
232 | int via_agp_init(DRM_IOCTL_ARGS); | 253 | typedef struct drm_via_dmablit { |
233 | int via_map_init(DRM_IOCTL_ARGS); | 254 | uint32_t num_lines; |
234 | int via_decoder_futex(DRM_IOCTL_ARGS); | 255 | uint32_t line_length; |
235 | int via_dma_init(DRM_IOCTL_ARGS); | 256 | |
236 | int via_cmdbuffer(DRM_IOCTL_ARGS); | 257 | uint32_t fb_addr; |
237 | int via_flush_ioctl(DRM_IOCTL_ARGS); | 258 | uint32_t fb_stride; |
238 | int via_pci_cmdbuffer(DRM_IOCTL_ARGS); | 259 | |
239 | int via_cmdbuf_size(DRM_IOCTL_ARGS); | 260 | unsigned char *mem_addr; |
240 | int via_wait_irq(DRM_IOCTL_ARGS); | 261 | uint32_t mem_stride; |
262 | |||
263 | int bounce_buffer; | ||
264 | int to_fb; | ||
265 | |||
266 | drm_via_blitsync_t sync; | ||
267 | } drm_via_dmablit_t; | ||
241 | 268 | ||
242 | #endif | ||
243 | #endif /* _VIA_DRM_H_ */ | 269 | #endif /* _VIA_DRM_H_ */ |
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index 016665e0c69f..3f012255d315 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c | |||
@@ -29,54 +29,21 @@ | |||
29 | 29 | ||
30 | #include "drm_pciids.h" | 30 | #include "drm_pciids.h" |
31 | 31 | ||
32 | static int postinit(struct drm_device *dev, unsigned long flags) | 32 | static int dri_library_name(struct drm_device *dev, char *buf) |
33 | { | 33 | { |
34 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", | 34 | return snprintf(buf, PAGE_SIZE, "unichrome"); |
35 | DRIVER_NAME, | ||
36 | DRIVER_MAJOR, | ||
37 | DRIVER_MINOR, | ||
38 | DRIVER_PATCHLEVEL, | ||
39 | DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) | ||
40 | ); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int version(drm_version_t * version) | ||
45 | { | ||
46 | int len; | ||
47 | |||
48 | version->version_major = DRIVER_MAJOR; | ||
49 | version->version_minor = DRIVER_MINOR; | ||
50 | version->version_patchlevel = DRIVER_PATCHLEVEL; | ||
51 | DRM_COPY(version->name, DRIVER_NAME); | ||
52 | DRM_COPY(version->date, DRIVER_DATE); | ||
53 | DRM_COPY(version->desc, DRIVER_DESC); | ||
54 | return 0; | ||
55 | } | 35 | } |
56 | 36 | ||
57 | static struct pci_device_id pciidlist[] = { | 37 | static struct pci_device_id pciidlist[] = { |
58 | viadrv_PCI_IDS | 38 | viadrv_PCI_IDS |
59 | }; | 39 | }; |
60 | 40 | ||
61 | static drm_ioctl_desc_t ioctls[] = { | ||
62 | [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0}, | ||
63 | [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0}, | ||
64 | [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0}, | ||
65 | [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0}, | ||
66 | [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0}, | ||
67 | [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0}, | ||
68 | [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0}, | ||
69 | [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0}, | ||
70 | [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0}, | ||
71 | [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0}, | ||
72 | [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0}, | ||
73 | [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0} | ||
74 | }; | ||
75 | |||
76 | static struct drm_driver driver = { | 41 | static struct drm_driver driver = { |
77 | .driver_features = | 42 | .driver_features = |
78 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | | 43 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | |
79 | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, | 44 | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, |
45 | .load = via_driver_load, | ||
46 | .unload = via_driver_unload, | ||
80 | .context_ctor = via_init_context, | 47 | .context_ctor = via_init_context, |
81 | .context_dtor = via_final_context, | 48 | .context_dtor = via_final_context, |
82 | .vblank_wait = via_driver_vblank_wait, | 49 | .vblank_wait = via_driver_vblank_wait, |
@@ -85,13 +52,11 @@ static struct drm_driver driver = { | |||
85 | .irq_uninstall = via_driver_irq_uninstall, | 52 | .irq_uninstall = via_driver_irq_uninstall, |
86 | .irq_handler = via_driver_irq_handler, | 53 | .irq_handler = via_driver_irq_handler, |
87 | .dma_quiescent = via_driver_dma_quiescent, | 54 | .dma_quiescent = via_driver_dma_quiescent, |
55 | .dri_library_name = dri_library_name, | ||
88 | .reclaim_buffers = drm_core_reclaim_buffers, | 56 | .reclaim_buffers = drm_core_reclaim_buffers, |
89 | .get_map_ofs = drm_core_get_map_ofs, | 57 | .get_map_ofs = drm_core_get_map_ofs, |
90 | .get_reg_ofs = drm_core_get_reg_ofs, | 58 | .get_reg_ofs = drm_core_get_reg_ofs, |
91 | .postinit = postinit, | 59 | .ioctls = via_ioctls, |
92 | .version = version, | ||
93 | .ioctls = ioctls, | ||
94 | .num_ioctls = DRM_ARRAY_SIZE(ioctls), | ||
95 | .fops = { | 60 | .fops = { |
96 | .owner = THIS_MODULE, | 61 | .owner = THIS_MODULE, |
97 | .open = drm_open, | 62 | .open = drm_open, |
@@ -100,15 +65,23 @@ static struct drm_driver driver = { | |||
100 | .mmap = drm_mmap, | 65 | .mmap = drm_mmap, |
101 | .poll = drm_poll, | 66 | .poll = drm_poll, |
102 | .fasync = drm_fasync, | 67 | .fasync = drm_fasync, |
103 | }, | 68 | }, |
104 | .pci_driver = { | 69 | .pci_driver = { |
105 | .name = DRIVER_NAME, | 70 | .name = DRIVER_NAME, |
106 | .id_table = pciidlist, | 71 | .id_table = pciidlist, |
107 | } | 72 | }, |
73 | |||
74 | .name = DRIVER_NAME, | ||
75 | .desc = DRIVER_DESC, | ||
76 | .date = DRIVER_DATE, | ||
77 | .major = DRIVER_MAJOR, | ||
78 | .minor = DRIVER_MINOR, | ||
79 | .patchlevel = DRIVER_PATCHLEVEL, | ||
108 | }; | 80 | }; |
109 | 81 | ||
110 | static int __init via_init(void) | 82 | static int __init via_init(void) |
111 | { | 83 | { |
84 | driver.num_ioctls = via_max_ioctl; | ||
112 | via_init_command_verifier(); | 85 | via_init_command_verifier(); |
113 | return drm_init(&driver); | 86 | return drm_init(&driver); |
114 | } | 87 | } |
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index 7d5daf43797e..aad4f99f5405 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
@@ -24,24 +24,26 @@ | |||
24 | #ifndef _VIA_DRV_H_ | 24 | #ifndef _VIA_DRV_H_ |
25 | #define _VIA_DRV_H_ | 25 | #define _VIA_DRV_H_ |
26 | 26 | ||
27 | #define DRIVER_AUTHOR "VIA" | 27 | #define DRIVER_AUTHOR "Various" |
28 | 28 | ||
29 | #define DRIVER_NAME "via" | 29 | #define DRIVER_NAME "via" |
30 | #define DRIVER_DESC "VIA Unichrome / Pro" | 30 | #define DRIVER_DESC "VIA Unichrome / Pro" |
31 | #define DRIVER_DATE "20050523" | 31 | #define DRIVER_DATE "20051116" |
32 | 32 | ||
33 | #define DRIVER_MAJOR 2 | 33 | #define DRIVER_MAJOR 2 |
34 | #define DRIVER_MINOR 6 | 34 | #define DRIVER_MINOR 7 |
35 | #define DRIVER_PATCHLEVEL 3 | 35 | #define DRIVER_PATCHLEVEL 4 |
36 | 36 | ||
37 | #include "via_verifier.h" | 37 | #include "via_verifier.h" |
38 | 38 | ||
39 | #include "via_dmablit.h" | ||
40 | |||
39 | #define VIA_PCI_BUF_SIZE 60000 | 41 | #define VIA_PCI_BUF_SIZE 60000 |
40 | #define VIA_FIRE_BUF_SIZE 1024 | 42 | #define VIA_FIRE_BUF_SIZE 1024 |
41 | #define VIA_NUM_IRQS 2 | 43 | #define VIA_NUM_IRQS 4 |
42 | 44 | ||
43 | typedef struct drm_via_ring_buffer { | 45 | typedef struct drm_via_ring_buffer { |
44 | drm_map_t map; | 46 | drm_local_map_t map; |
45 | char *virtual_start; | 47 | char *virtual_start; |
46 | } drm_via_ring_buffer_t; | 48 | } drm_via_ring_buffer_t; |
47 | 49 | ||
@@ -56,9 +58,9 @@ typedef struct drm_via_irq { | |||
56 | 58 | ||
57 | typedef struct drm_via_private { | 59 | typedef struct drm_via_private { |
58 | drm_via_sarea_t *sarea_priv; | 60 | drm_via_sarea_t *sarea_priv; |
59 | drm_map_t *sarea; | 61 | drm_local_map_t *sarea; |
60 | drm_map_t *fb; | 62 | drm_local_map_t *fb; |
61 | drm_map_t *mmio; | 63 | drm_local_map_t *mmio; |
62 | unsigned long agpAddr; | 64 | unsigned long agpAddr; |
63 | wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS]; | 65 | wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS]; |
64 | char *dma_ptr; | 66 | char *dma_ptr; |
@@ -82,8 +84,15 @@ typedef struct drm_via_private { | |||
82 | maskarray_t *irq_masks; | 84 | maskarray_t *irq_masks; |
83 | uint32_t irq_enable_mask; | 85 | uint32_t irq_enable_mask; |
84 | uint32_t irq_pending_mask; | 86 | uint32_t irq_pending_mask; |
87 | int *irq_map; | ||
88 | drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; | ||
85 | } drm_via_private_t; | 89 | } drm_via_private_t; |
86 | 90 | ||
91 | enum via_family { | ||
92 | VIA_OTHER = 0, | ||
93 | VIA_PRO_GROUP_A, | ||
94 | }; | ||
95 | |||
87 | /* VIA MMIO register access */ | 96 | /* VIA MMIO register access */ |
88 | #define VIA_BASE ((dev_priv->mmio)) | 97 | #define VIA_BASE ((dev_priv->mmio)) |
89 | 98 | ||
@@ -92,12 +101,31 @@ typedef struct drm_via_private { | |||
92 | #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) | 101 | #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) |
93 | #define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) | 102 | #define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) |
94 | 103 | ||
104 | extern drm_ioctl_desc_t via_ioctls[]; | ||
105 | extern int via_max_ioctl; | ||
106 | |||
107 | extern int via_fb_init(DRM_IOCTL_ARGS); | ||
108 | extern int via_mem_alloc(DRM_IOCTL_ARGS); | ||
109 | extern int via_mem_free(DRM_IOCTL_ARGS); | ||
110 | extern int via_agp_init(DRM_IOCTL_ARGS); | ||
111 | extern int via_map_init(DRM_IOCTL_ARGS); | ||
112 | extern int via_decoder_futex(DRM_IOCTL_ARGS); | ||
113 | extern int via_dma_init(DRM_IOCTL_ARGS); | ||
114 | extern int via_cmdbuffer(DRM_IOCTL_ARGS); | ||
115 | extern int via_flush_ioctl(DRM_IOCTL_ARGS); | ||
116 | extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS); | ||
117 | extern int via_cmdbuf_size(DRM_IOCTL_ARGS); | ||
118 | extern int via_wait_irq(DRM_IOCTL_ARGS); | ||
119 | extern int via_dma_blit_sync( DRM_IOCTL_ARGS ); | ||
120 | extern int via_dma_blit( DRM_IOCTL_ARGS ); | ||
121 | |||
122 | extern int via_driver_load(drm_device_t *dev, unsigned long chipset); | ||
123 | extern int via_driver_unload(drm_device_t *dev); | ||
124 | |||
95 | extern int via_init_context(drm_device_t * dev, int context); | 125 | extern int via_init_context(drm_device_t * dev, int context); |
96 | extern int via_final_context(drm_device_t * dev, int context); | 126 | extern int via_final_context(drm_device_t * dev, int context); |
97 | 127 | ||
98 | extern int via_do_cleanup_map(drm_device_t * dev); | 128 | extern int via_do_cleanup_map(drm_device_t * dev); |
99 | extern int via_map_init(struct inode *inode, struct file *filp, | ||
100 | unsigned int cmd, unsigned long arg); | ||
101 | extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); | 129 | extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); |
102 | 130 | ||
103 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); | 131 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); |
@@ -111,8 +139,10 @@ extern int via_driver_dma_quiescent(drm_device_t * dev); | |||
111 | extern void via_init_futex(drm_via_private_t * dev_priv); | 139 | extern void via_init_futex(drm_via_private_t * dev_priv); |
112 | extern void via_cleanup_futex(drm_via_private_t * dev_priv); | 140 | extern void via_cleanup_futex(drm_via_private_t * dev_priv); |
113 | extern void via_release_futex(drm_via_private_t * dev_priv, int context); | 141 | extern void via_release_futex(drm_via_private_t * dev_priv, int context); |
142 | extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, | ||
143 | int force_sequence, unsigned int *sequence); | ||
114 | 144 | ||
115 | extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, | 145 | extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq); |
116 | unsigned int size); | 146 | extern void via_init_dmablit(drm_device_t *dev); |
117 | 147 | ||
118 | #endif | 148 | #endif |
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c index 5c71e089246c..9429736b3b96 100644 --- a/drivers/char/drm/via_ds.c +++ b/drivers/char/drm/via_ds.c | |||
@@ -22,14 +22,7 @@ | |||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | * DEALINGS IN THE SOFTWARE. | 23 | * DEALINGS IN THE SOFTWARE. |
24 | */ | 24 | */ |
25 | #include <linux/module.h> | 25 | #include "drmP.h" |
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/poll.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <asm/io.h> | ||
33 | 26 | ||
34 | #include "via_ds.h" | 27 | #include "via_ds.h" |
35 | extern unsigned int VIA_DEBUG; | 28 | extern unsigned int VIA_DEBUG; |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index d023add1929b..56d7e3daea12 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -50,6 +50,15 @@ | |||
50 | #define VIA_IRQ_HQV1_ENABLE (1 << 25) | 50 | #define VIA_IRQ_HQV1_ENABLE (1 << 25) |
51 | #define VIA_IRQ_HQV0_PENDING (1 << 9) | 51 | #define VIA_IRQ_HQV0_PENDING (1 << 9) |
52 | #define VIA_IRQ_HQV1_PENDING (1 << 10) | 52 | #define VIA_IRQ_HQV1_PENDING (1 << 10) |
53 | #define VIA_IRQ_DMA0_DD_ENABLE (1 << 20) | ||
54 | #define VIA_IRQ_DMA0_TD_ENABLE (1 << 21) | ||
55 | #define VIA_IRQ_DMA1_DD_ENABLE (1 << 22) | ||
56 | #define VIA_IRQ_DMA1_TD_ENABLE (1 << 23) | ||
57 | #define VIA_IRQ_DMA0_DD_PENDING (1 << 4) | ||
58 | #define VIA_IRQ_DMA0_TD_PENDING (1 << 5) | ||
59 | #define VIA_IRQ_DMA1_DD_PENDING (1 << 6) | ||
60 | #define VIA_IRQ_DMA1_TD_PENDING (1 << 7) | ||
61 | |||
53 | 62 | ||
54 | /* | 63 | /* |
55 | * Device-specific IRQs go here. This type might need to be extended with | 64 | * Device-specific IRQs go here. This type might need to be extended with |
@@ -61,13 +70,24 @@ static maskarray_t via_pro_group_a_irqs[] = { | |||
61 | {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, | 70 | {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, |
62 | 0x00000000}, | 71 | 0x00000000}, |
63 | {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, | 72 | {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, |
64 | 0x00000000} | 73 | 0x00000000}, |
74 | {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, | ||
75 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, | ||
76 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, | ||
77 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, | ||
65 | }; | 78 | }; |
66 | static int via_num_pro_group_a = | 79 | static int via_num_pro_group_a = |
67 | sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); | 80 | sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); |
81 | static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; | ||
68 | 82 | ||
69 | static maskarray_t via_unichrome_irqs[] = { }; | 83 | static maskarray_t via_unichrome_irqs[] = { |
84 | {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, | ||
85 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, | ||
86 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, | ||
87 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} | ||
88 | }; | ||
70 | static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); | 89 | static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); |
90 | static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; | ||
71 | 91 | ||
72 | static unsigned time_diff(struct timeval *now, struct timeval *then) | 92 | static unsigned time_diff(struct timeval *now, struct timeval *then) |
73 | { | 93 | { |
@@ -113,6 +133,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
113 | atomic_inc(&cur_irq->irq_received); | 133 | atomic_inc(&cur_irq->irq_received); |
114 | DRM_WAKEUP(&cur_irq->irq_queue); | 134 | DRM_WAKEUP(&cur_irq->irq_queue); |
115 | handled = 1; | 135 | handled = 1; |
136 | if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { | ||
137 | via_dmablit_handler(dev, 0, 1); | ||
138 | } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { | ||
139 | via_dmablit_handler(dev, 1, 1); | ||
140 | } | ||
116 | } | 141 | } |
117 | cur_irq++; | 142 | cur_irq++; |
118 | } | 143 | } |
@@ -165,7 +190,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) | |||
165 | return ret; | 190 | return ret; |
166 | } | 191 | } |
167 | 192 | ||
168 | static int | 193 | int |
169 | via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | 194 | via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, |
170 | unsigned int *sequence) | 195 | unsigned int *sequence) |
171 | { | 196 | { |
@@ -174,6 +199,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | |||
174 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; | 199 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; |
175 | int ret = 0; | 200 | int ret = 0; |
176 | maskarray_t *masks = dev_priv->irq_masks; | 201 | maskarray_t *masks = dev_priv->irq_masks; |
202 | int real_irq; | ||
177 | 203 | ||
178 | DRM_DEBUG("%s\n", __FUNCTION__); | 204 | DRM_DEBUG("%s\n", __FUNCTION__); |
179 | 205 | ||
@@ -182,15 +208,23 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | |||
182 | return DRM_ERR(EINVAL); | 208 | return DRM_ERR(EINVAL); |
183 | } | 209 | } |
184 | 210 | ||
185 | if (irq >= dev_priv->num_irqs) { | 211 | if (irq >= drm_via_irq_num) { |
186 | DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, | 212 | DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, |
187 | irq); | 213 | irq); |
188 | return DRM_ERR(EINVAL); | 214 | return DRM_ERR(EINVAL); |
189 | } | 215 | } |
190 | 216 | ||
191 | cur_irq += irq; | 217 | real_irq = dev_priv->irq_map[irq]; |
218 | |||
219 | if (real_irq < 0) { | ||
220 | DRM_ERROR("%s Video IRQ %d not available on this hardware.\n", | ||
221 | __FUNCTION__, irq); | ||
222 | return DRM_ERR(EINVAL); | ||
223 | } | ||
224 | |||
225 | cur_irq += real_irq; | ||
192 | 226 | ||
193 | if (masks[irq][2] && !force_sequence) { | 227 | if (masks[real_irq][2] && !force_sequence) { |
194 | DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, | 228 | DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, |
195 | ((VIA_READ(masks[irq][2]) & masks[irq][3]) == | 229 | ((VIA_READ(masks[irq][2]) & masks[irq][3]) == |
196 | masks[irq][4])); | 230 | masks[irq][4])); |
@@ -226,6 +260,8 @@ void via_driver_irq_preinstall(drm_device_t * dev) | |||
226 | via_pro_group_a_irqs : via_unichrome_irqs; | 260 | via_pro_group_a_irqs : via_unichrome_irqs; |
227 | dev_priv->num_irqs = (dev_priv->pro_group_a) ? | 261 | dev_priv->num_irqs = (dev_priv->pro_group_a) ? |
228 | via_num_pro_group_a : via_num_unichrome; | 262 | via_num_pro_group_a : via_num_unichrome; |
263 | dev_priv->irq_map = (dev_priv->pro_group_a) ? | ||
264 | via_irqmap_pro_group_a : via_irqmap_unichrome; | ||
229 | 265 | ||
230 | for (i = 0; i < dev_priv->num_irqs; ++i) { | 266 | for (i = 0; i < dev_priv->num_irqs; ++i) { |
231 | atomic_set(&cur_irq->irq_received, 0); | 267 | atomic_set(&cur_irq->irq_received, 0); |
@@ -241,7 +277,7 @@ void via_driver_irq_preinstall(drm_device_t * dev) | |||
241 | 277 | ||
242 | dev_priv->last_vblank_valid = 0; | 278 | dev_priv->last_vblank_valid = 0; |
243 | 279 | ||
244 | // Clear VSync interrupt regs | 280 | /* Clear VSync interrupt regs */ |
245 | status = VIA_READ(VIA_REG_INTERRUPT); | 281 | status = VIA_READ(VIA_REG_INTERRUPT); |
246 | VIA_WRITE(VIA_REG_INTERRUPT, status & | 282 | VIA_WRITE(VIA_REG_INTERRUPT, status & |
247 | ~(dev_priv->irq_enable_mask)); | 283 | ~(dev_priv->irq_enable_mask)); |
@@ -291,8 +327,7 @@ void via_driver_irq_uninstall(drm_device_t * dev) | |||
291 | 327 | ||
292 | int via_wait_irq(DRM_IOCTL_ARGS) | 328 | int via_wait_irq(DRM_IOCTL_ARGS) |
293 | { | 329 | { |
294 | drm_file_t *priv = filp->private_data; | 330 | DRM_DEVICE; |
295 | drm_device_t *dev = priv->head->dev; | ||
296 | drm_via_irqwait_t __user *argp = (void __user *)data; | 331 | drm_via_irqwait_t __user *argp = (void __user *)data; |
297 | drm_via_irqwait_t irqwait; | 332 | drm_via_irqwait_t irqwait; |
298 | struct timeval now; | 333 | struct timeval now; |
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c index 6bd6ac52ad1b..c6a08e96285b 100644 --- a/drivers/char/drm/via_map.c +++ b/drivers/char/drm/via_map.c | |||
@@ -27,16 +27,10 @@ | |||
27 | 27 | ||
28 | static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) | 28 | static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) |
29 | { | 29 | { |
30 | drm_via_private_t *dev_priv; | 30 | drm_via_private_t *dev_priv = dev->dev_private; |
31 | 31 | ||
32 | DRM_DEBUG("%s\n", __FUNCTION__); | 32 | DRM_DEBUG("%s\n", __FUNCTION__); |
33 | 33 | ||
34 | dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER); | ||
35 | if (dev_priv == NULL) | ||
36 | return -ENOMEM; | ||
37 | |||
38 | memset(dev_priv, 0, sizeof(drm_via_private_t)); | ||
39 | |||
40 | DRM_GETSAREA(); | 34 | DRM_GETSAREA(); |
41 | if (!dev_priv->sarea) { | 35 | if (!dev_priv->sarea) { |
42 | DRM_ERROR("could not find sarea!\n"); | 36 | DRM_ERROR("could not find sarea!\n"); |
@@ -67,7 +61,8 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) | |||
67 | dev_priv->agpAddr = init->agpAddr; | 61 | dev_priv->agpAddr = init->agpAddr; |
68 | 62 | ||
69 | via_init_futex(dev_priv); | 63 | via_init_futex(dev_priv); |
70 | dev_priv->pro_group_a = (dev->pdev->device == 0x3118); | 64 | |
65 | via_init_dmablit(dev); | ||
71 | 66 | ||
72 | dev->dev_private = (void *)dev_priv; | 67 | dev->dev_private = (void *)dev_priv; |
73 | return 0; | 68 | return 0; |
@@ -75,15 +70,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) | |||
75 | 70 | ||
76 | int via_do_cleanup_map(drm_device_t * dev) | 71 | int via_do_cleanup_map(drm_device_t * dev) |
77 | { | 72 | { |
78 | if (dev->dev_private) { | 73 | via_dma_cleanup(dev); |
79 | |||
80 | drm_via_private_t *dev_priv = dev->dev_private; | ||
81 | |||
82 | via_dma_cleanup(dev); | ||
83 | |||
84 | drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | ||
85 | dev->dev_private = NULL; | ||
86 | } | ||
87 | 74 | ||
88 | return 0; | 75 | return 0; |
89 | } | 76 | } |
@@ -107,3 +94,29 @@ int via_map_init(DRM_IOCTL_ARGS) | |||
107 | 94 | ||
108 | return -EINVAL; | 95 | return -EINVAL; |
109 | } | 96 | } |
97 | |||
98 | int via_driver_load(drm_device_t *dev, unsigned long chipset) | ||
99 | { | ||
100 | drm_via_private_t *dev_priv; | ||
101 | |||
102 | dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | ||
103 | if (dev_priv == NULL) | ||
104 | return DRM_ERR(ENOMEM); | ||
105 | |||
106 | dev->dev_private = (void *)dev_priv; | ||
107 | |||
108 | if (chipset == VIA_PRO_GROUP_A) | ||
109 | dev_priv->pro_group_a = 1; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int via_driver_unload(drm_device_t *dev) | ||
115 | { | ||
116 | drm_via_private_t *dev_priv = dev->dev_private; | ||
117 | |||
118 | drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c index 3baddacdff26..33e0cb12e4c3 100644 --- a/drivers/char/drm/via_mm.c +++ b/drivers/char/drm/via_mm.c | |||
@@ -42,7 +42,7 @@ static int via_agp_free(drm_via_mem_t * mem); | |||
42 | static int via_fb_alloc(drm_via_mem_t * mem); | 42 | static int via_fb_alloc(drm_via_mem_t * mem); |
43 | static int via_fb_free(drm_via_mem_t * mem); | 43 | static int via_fb_free(drm_via_mem_t * mem); |
44 | 44 | ||
45 | static int add_alloc_set(int context, int type, unsigned int val) | 45 | static int add_alloc_set(int context, int type, unsigned long val) |
46 | { | 46 | { |
47 | int i, retval = 0; | 47 | int i, retval = 0; |
48 | 48 | ||
@@ -56,7 +56,7 @@ static int add_alloc_set(int context, int type, unsigned int val) | |||
56 | return retval; | 56 | return retval; |
57 | } | 57 | } |
58 | 58 | ||
59 | static int del_alloc_set(int context, int type, unsigned int val) | 59 | static int del_alloc_set(int context, int type, unsigned long val) |
60 | { | 60 | { |
61 | int i, retval = 0; | 61 | int i, retval = 0; |
62 | 62 | ||
@@ -199,13 +199,13 @@ int via_mem_alloc(DRM_IOCTL_ARGS) | |||
199 | sizeof(mem)); | 199 | sizeof(mem)); |
200 | 200 | ||
201 | switch (mem.type) { | 201 | switch (mem.type) { |
202 | case VIDEO: | 202 | case VIA_MEM_VIDEO: |
203 | if (via_fb_alloc(&mem) < 0) | 203 | if (via_fb_alloc(&mem) < 0) |
204 | return -EFAULT; | 204 | return -EFAULT; |
205 | DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, | 205 | DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, |
206 | sizeof(mem)); | 206 | sizeof(mem)); |
207 | return 0; | 207 | return 0; |
208 | case AGP: | 208 | case VIA_MEM_AGP: |
209 | if (via_agp_alloc(&mem) < 0) | 209 | if (via_agp_alloc(&mem) < 0) |
210 | return -EFAULT; | 210 | return -EFAULT; |
211 | DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, | 211 | DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, |
@@ -232,7 +232,7 @@ static int via_fb_alloc(drm_via_mem_t * mem) | |||
232 | if (block) { | 232 | if (block) { |
233 | fb.offset = block->ofs; | 233 | fb.offset = block->ofs; |
234 | fb.free = (unsigned long)block; | 234 | fb.free = (unsigned long)block; |
235 | if (!add_alloc_set(fb.context, VIDEO, fb.free)) { | 235 | if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) { |
236 | DRM_DEBUG("adding to allocation set fails\n"); | 236 | DRM_DEBUG("adding to allocation set fails\n"); |
237 | via_mmFreeMem((PMemBlock) fb.free); | 237 | via_mmFreeMem((PMemBlock) fb.free); |
238 | retval = -1; | 238 | retval = -1; |
@@ -269,7 +269,7 @@ static int via_agp_alloc(drm_via_mem_t * mem) | |||
269 | if (block) { | 269 | if (block) { |
270 | agp.offset = block->ofs; | 270 | agp.offset = block->ofs; |
271 | agp.free = (unsigned long)block; | 271 | agp.free = (unsigned long)block; |
272 | if (!add_alloc_set(agp.context, AGP, agp.free)) { | 272 | if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) { |
273 | DRM_DEBUG("adding to allocation set fails\n"); | 273 | DRM_DEBUG("adding to allocation set fails\n"); |
274 | via_mmFreeMem((PMemBlock) agp.free); | 274 | via_mmFreeMem((PMemBlock) agp.free); |
275 | retval = -1; | 275 | retval = -1; |
@@ -297,11 +297,11 @@ int via_mem_free(DRM_IOCTL_ARGS) | |||
297 | 297 | ||
298 | switch (mem.type) { | 298 | switch (mem.type) { |
299 | 299 | ||
300 | case VIDEO: | 300 | case VIA_MEM_VIDEO: |
301 | if (via_fb_free(&mem) == 0) | 301 | if (via_fb_free(&mem) == 0) |
302 | return 0; | 302 | return 0; |
303 | break; | 303 | break; |
304 | case AGP: | 304 | case VIA_MEM_AGP: |
305 | if (via_agp_free(&mem) == 0) | 305 | if (via_agp_free(&mem) == 0) |
306 | return 0; | 306 | return 0; |
307 | break; | 307 | break; |
@@ -329,7 +329,7 @@ static int via_fb_free(drm_via_mem_t * mem) | |||
329 | 329 | ||
330 | via_mmFreeMem((PMemBlock) fb.free); | 330 | via_mmFreeMem((PMemBlock) fb.free); |
331 | 331 | ||
332 | if (!del_alloc_set(fb.context, VIDEO, fb.free)) { | 332 | if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) { |
333 | retval = -1; | 333 | retval = -1; |
334 | } | 334 | } |
335 | 335 | ||
@@ -352,7 +352,7 @@ static int via_agp_free(drm_via_mem_t * mem) | |||
352 | 352 | ||
353 | via_mmFreeMem((PMemBlock) agp.free); | 353 | via_mmFreeMem((PMemBlock) agp.free); |
354 | 354 | ||
355 | if (!del_alloc_set(agp.context, AGP, agp.free)) { | 355 | if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) { |
356 | retval = -1; | 356 | retval = -1; |
357 | } | 357 | } |
358 | 358 | ||
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c index 4ac495f297f7..70c897c88766 100644 --- a/drivers/char/drm/via_verifier.c +++ b/drivers/char/drm/via_verifier.c | |||
@@ -237,7 +237,7 @@ static hazard_t table3[256]; | |||
237 | static __inline__ int | 237 | static __inline__ int |
238 | eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) | 238 | eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) |
239 | { | 239 | { |
240 | if ((*buf - buf_end) >= num_words) { | 240 | if ((buf_end - *buf) >= num_words) { |
241 | *buf += num_words; | 241 | *buf += num_words; |
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
@@ -249,14 +249,14 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) | |||
249 | * Partially stolen from drm_memory.h | 249 | * Partially stolen from drm_memory.h |
250 | */ | 250 | */ |
251 | 251 | ||
252 | static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq, | 252 | static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, |
253 | unsigned long offset, | 253 | unsigned long offset, |
254 | unsigned long size, | 254 | unsigned long size, |
255 | drm_device_t * dev) | 255 | drm_device_t * dev) |
256 | { | 256 | { |
257 | struct list_head *list; | 257 | struct list_head *list; |
258 | drm_map_list_t *r_list; | 258 | drm_map_list_t *r_list; |
259 | drm_map_t *map = seq->map_cache; | 259 | drm_local_map_t *map = seq->map_cache; |
260 | 260 | ||
261 | if (map && map->offset <= offset | 261 | if (map && map->offset <= offset |
262 | && (offset + size) <= (map->offset + map->size)) { | 262 | && (offset + size) <= (map->offset + map->size)) { |
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h index eb4eda344345..256590fcc22a 100644 --- a/drivers/char/drm/via_verifier.h +++ b/drivers/char/drm/via_verifier.h | |||
@@ -47,7 +47,7 @@ typedef struct { | |||
47 | int agp_texture; | 47 | int agp_texture; |
48 | int multitex; | 48 | int multitex; |
49 | drm_device_t *dev; | 49 | drm_device_t *dev; |
50 | drm_map_t *map_cache; | 50 | drm_local_map_t *map_cache; |
51 | uint32_t vertex_count; | 51 | uint32_t vertex_count; |
52 | int agp; | 52 | int agp; |
53 | const uint32_t *buf_start; | 53 | const uint32_t *buf_start; |
@@ -55,5 +55,7 @@ typedef struct { | |||
55 | 55 | ||
56 | extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, | 56 | extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, |
57 | drm_device_t * dev, int agp); | 57 | drm_device_t * dev, int agp); |
58 | extern int via_parse_command_stream(drm_device_t *dev, const uint32_t *buf, | ||
59 | unsigned int size); | ||
58 | 60 | ||
59 | #endif | 61 | #endif |
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c index 7fab9fbdf424..300ac61b09ed 100644 --- a/drivers/char/drm/via_video.c +++ b/drivers/char/drm/via_video.c | |||
@@ -50,8 +50,11 @@ void via_release_futex(drm_via_private_t * dev_priv, int context) | |||
50 | unsigned int i; | 50 | unsigned int i; |
51 | volatile int *lock; | 51 | volatile int *lock; |
52 | 52 | ||
53 | if (!dev_priv->sarea_priv) | ||
54 | return; | ||
55 | |||
53 | for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) { | 56 | for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) { |
54 | lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); | 57 | lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); |
55 | if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { | 58 | if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { |
56 | if (_DRM_LOCK_IS_HELD(*lock) | 59 | if (_DRM_LOCK_IS_HELD(*lock) |
57 | && (*lock & _DRM_LOCK_CONT)) { | 60 | && (*lock & _DRM_LOCK_CONT)) { |
@@ -79,7 +82,7 @@ int via_decoder_futex(DRM_IOCTL_ARGS) | |||
79 | if (fx.lock > VIA_NR_XVMC_LOCKS) | 82 | if (fx.lock > VIA_NR_XVMC_LOCKS) |
80 | return -EFAULT; | 83 | return -EFAULT; |
81 | 84 | ||
82 | lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock); | 85 | lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock); |
83 | 86 | ||
84 | switch (fx.func) { | 87 | switch (fx.func) { |
85 | case VIA_FUTEX_WAIT: | 88 | case VIA_FUTEX_WAIT: |