diff options
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 126 |
1 files changed, 44 insertions, 82 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 7c20dc344b99..eb3cf550626d 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -362,25 +362,19 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry) | |||
362 | 362 | ||
363 | #if __OS_HAS_AGP | 363 | #if __OS_HAS_AGP |
364 | /** | 364 | /** |
365 | * Add AGP buffers for DMA transfers (ioctl). | 365 | * Add AGP buffers for DMA transfers. |
366 | * | 366 | * |
367 | * \param inode device inode. | 367 | * \param dev drm_device_t to which the buffers are to be added. |
368 | * \param filp file pointer. | 368 | * \param request pointer to a drm_buf_desc_t describing the request. |
369 | * \param cmd command. | ||
370 | * \param arg pointer to a drm_buf_desc_t request. | ||
371 | * \return zero on success or a negative number on failure. | 369 | * \return zero on success or a negative number on failure. |
372 | * | 370 | * |
373 | * After some sanity checks creates a drm_buf structure for each buffer and | 371 | * After some sanity checks creates a drm_buf structure for each buffer and |
374 | * reallocates the buffer list of the same size order to accommodate the new | 372 | * reallocates the buffer list of the same size order to accommodate the new |
375 | * buffers. | 373 | * buffers. |
376 | */ | 374 | */ |
377 | static int drm_addbufs_agp( struct inode *inode, struct file *filp, | 375 | static int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) |
378 | unsigned int cmd, unsigned long arg ) | ||
379 | { | 376 | { |
380 | drm_file_t *priv = filp->private_data; | ||
381 | drm_device_t *dev = priv->head->dev; | ||
382 | drm_device_dma_t *dma = dev->dma; | 377 | drm_device_dma_t *dma = dev->dma; |
383 | drm_buf_desc_t request; | ||
384 | drm_buf_entry_t *entry; | 378 | drm_buf_entry_t *entry; |
385 | drm_buf_t *buf; | 379 | drm_buf_t *buf; |
386 | unsigned long offset; | 380 | unsigned long offset; |
@@ -394,25 +388,20 @@ static int drm_addbufs_agp( struct inode *inode, struct file *filp, | |||
394 | int byte_count; | 388 | int byte_count; |
395 | int i; | 389 | int i; |
396 | drm_buf_t **temp_buflist; | 390 | drm_buf_t **temp_buflist; |
397 | drm_buf_desc_t __user *argp = (void __user *)arg; | ||
398 | 391 | ||
399 | if ( !dma ) return -EINVAL; | 392 | if ( !dma ) return -EINVAL; |
400 | 393 | ||
401 | if ( copy_from_user( &request, argp, | 394 | count = request->count; |
402 | sizeof(request) ) ) | 395 | order = drm_order(request->size); |
403 | return -EFAULT; | ||
404 | |||
405 | count = request.count; | ||
406 | order = drm_order( request.size ); | ||
407 | size = 1 << order; | 396 | size = 1 << order; |
408 | 397 | ||
409 | alignment = (request.flags & _DRM_PAGE_ALIGN) | 398 | alignment = (request->flags & _DRM_PAGE_ALIGN) |
410 | ? PAGE_ALIGN(size) : size; | 399 | ? PAGE_ALIGN(size) : size; |
411 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; | 400 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; |
412 | total = PAGE_SIZE << page_order; | 401 | total = PAGE_SIZE << page_order; |
413 | 402 | ||
414 | byte_count = 0; | 403 | byte_count = 0; |
415 | agp_offset = dev->agp->base + request.agp_start; | 404 | agp_offset = dev->agp->base + request->agp_start; |
416 | 405 | ||
417 | DRM_DEBUG( "count: %d\n", count ); | 406 | DRM_DEBUG( "count: %d\n", count ); |
418 | DRM_DEBUG( "order: %d\n", order ); | 407 | DRM_DEBUG( "order: %d\n", order ); |
@@ -526,11 +515,8 @@ static int drm_addbufs_agp( struct inode *inode, struct file *filp, | |||
526 | 515 | ||
527 | up( &dev->struct_sem ); | 516 | up( &dev->struct_sem ); |
528 | 517 | ||
529 | request.count = entry->buf_count; | 518 | request->count = entry->buf_count; |
530 | request.size = size; | 519 | request->size = size; |
531 | |||
532 | if ( copy_to_user( argp, &request, sizeof(request) ) ) | ||
533 | return -EFAULT; | ||
534 | 520 | ||
535 | dma->flags = _DRM_DMA_USE_AGP; | 521 | dma->flags = _DRM_DMA_USE_AGP; |
536 | 522 | ||
@@ -539,13 +525,9 @@ static int drm_addbufs_agp( struct inode *inode, struct file *filp, | |||
539 | } | 525 | } |
540 | #endif /* __OS_HAS_AGP */ | 526 | #endif /* __OS_HAS_AGP */ |
541 | 527 | ||
542 | static int drm_addbufs_pci( struct inode *inode, struct file *filp, | 528 | static int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) |
543 | unsigned int cmd, unsigned long arg ) | ||
544 | { | 529 | { |
545 | drm_file_t *priv = filp->private_data; | ||
546 | drm_device_t *dev = priv->head->dev; | ||
547 | drm_device_dma_t *dma = dev->dma; | 530 | drm_device_dma_t *dma = dev->dma; |
548 | drm_buf_desc_t request; | ||
549 | int count; | 531 | int count; |
550 | int order; | 532 | int order; |
551 | int size; | 533 | int size; |
@@ -561,26 +543,22 @@ static int drm_addbufs_pci( struct inode *inode, struct file *filp, | |||
561 | int page_count; | 543 | int page_count; |
562 | unsigned long *temp_pagelist; | 544 | unsigned long *temp_pagelist; |
563 | drm_buf_t **temp_buflist; | 545 | drm_buf_t **temp_buflist; |
564 | drm_buf_desc_t __user *argp = (void __user *)arg; | ||
565 | 546 | ||
566 | if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL; | 547 | if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL; |
567 | if ( !dma ) return -EINVAL; | 548 | if ( !dma ) return -EINVAL; |
568 | 549 | ||
569 | if ( copy_from_user( &request, argp, sizeof(request) ) ) | 550 | count = request->count; |
570 | return -EFAULT; | 551 | order = drm_order(request->size); |
571 | |||
572 | count = request.count; | ||
573 | order = drm_order( request.size ); | ||
574 | size = 1 << order; | 552 | size = 1 << order; |
575 | 553 | ||
576 | DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n", | 554 | DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n", |
577 | request.count, request.size, size, | 555 | request->count, request->size, size, |
578 | order, dev->queue_count ); | 556 | order, dev->queue_count ); |
579 | 557 | ||
580 | if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; | 558 | if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; |
581 | if ( dev->queue_count ) return -EBUSY; /* Not while in use */ | 559 | if ( dev->queue_count ) return -EBUSY; /* Not while in use */ |
582 | 560 | ||
583 | alignment = (request.flags & _DRM_PAGE_ALIGN) | 561 | alignment = (request->flags & _DRM_PAGE_ALIGN) |
584 | ? PAGE_ALIGN(size) : size; | 562 | ? PAGE_ALIGN(size) : size; |
585 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; | 563 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; |
586 | total = PAGE_SIZE << page_order; | 564 | total = PAGE_SIZE << page_order; |
@@ -758,25 +736,17 @@ static int drm_addbufs_pci( struct inode *inode, struct file *filp, | |||
758 | 736 | ||
759 | up( &dev->struct_sem ); | 737 | up( &dev->struct_sem ); |
760 | 738 | ||
761 | request.count = entry->buf_count; | 739 | request->count = entry->buf_count; |
762 | request.size = size; | 740 | request->size = size; |
763 | |||
764 | if ( copy_to_user( argp, &request, sizeof(request) ) ) | ||
765 | return -EFAULT; | ||
766 | 741 | ||
767 | atomic_dec( &dev->buf_alloc ); | 742 | atomic_dec( &dev->buf_alloc ); |
768 | return 0; | 743 | return 0; |
769 | 744 | ||
770 | } | 745 | } |
771 | 746 | ||
772 | static int drm_addbufs_sg( struct inode *inode, struct file *filp, | 747 | static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) |
773 | unsigned int cmd, unsigned long arg ) | ||
774 | { | 748 | { |
775 | drm_file_t *priv = filp->private_data; | ||
776 | drm_device_t *dev = priv->head->dev; | ||
777 | drm_device_dma_t *dma = dev->dma; | 749 | drm_device_dma_t *dma = dev->dma; |
778 | drm_buf_desc_t __user *argp = (void __user *)arg; | ||
779 | drm_buf_desc_t request; | ||
780 | drm_buf_entry_t *entry; | 750 | drm_buf_entry_t *entry; |
781 | drm_buf_t *buf; | 751 | drm_buf_t *buf; |
782 | unsigned long offset; | 752 | unsigned long offset; |
@@ -795,20 +765,17 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp, | |||
795 | 765 | ||
796 | if ( !dma ) return -EINVAL; | 766 | if ( !dma ) return -EINVAL; |
797 | 767 | ||
798 | if ( copy_from_user( &request, argp, sizeof(request) ) ) | 768 | count = request->count; |
799 | return -EFAULT; | 769 | order = drm_order(request->size); |
800 | |||
801 | count = request.count; | ||
802 | order = drm_order( request.size ); | ||
803 | size = 1 << order; | 770 | size = 1 << order; |
804 | 771 | ||
805 | alignment = (request.flags & _DRM_PAGE_ALIGN) | 772 | alignment = (request->flags & _DRM_PAGE_ALIGN) |
806 | ? PAGE_ALIGN(size) : size; | 773 | ? PAGE_ALIGN(size) : size; |
807 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; | 774 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; |
808 | total = PAGE_SIZE << page_order; | 775 | total = PAGE_SIZE << page_order; |
809 | 776 | ||
810 | byte_count = 0; | 777 | byte_count = 0; |
811 | agp_offset = request.agp_start; | 778 | agp_offset = request->agp_start; |
812 | 779 | ||
813 | DRM_DEBUG( "count: %d\n", count ); | 780 | DRM_DEBUG( "count: %d\n", count ); |
814 | DRM_DEBUG( "order: %d\n", order ); | 781 | DRM_DEBUG( "order: %d\n", order ); |
@@ -923,11 +890,8 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp, | |||
923 | 890 | ||
924 | up( &dev->struct_sem ); | 891 | up( &dev->struct_sem ); |
925 | 892 | ||
926 | request.count = entry->buf_count; | 893 | request->count = entry->buf_count; |
927 | request.size = size; | 894 | request->size = size; |
928 | |||
929 | if ( copy_to_user( argp, &request, sizeof(request) ) ) | ||
930 | return -EFAULT; | ||
931 | 895 | ||
932 | dma->flags = _DRM_DMA_USE_SG; | 896 | dma->flags = _DRM_DMA_USE_SG; |
933 | 897 | ||
@@ -935,13 +899,9 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp, | |||
935 | return 0; | 899 | return 0; |
936 | } | 900 | } |
937 | 901 | ||
938 | int drm_addbufs_fb(struct inode *inode, struct file *filp, | 902 | int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request) |
939 | unsigned int cmd, unsigned long arg) | ||
940 | { | 903 | { |
941 | drm_file_t *priv = filp->private_data; | ||
942 | drm_device_t *dev = priv->head->dev; | ||
943 | drm_device_dma_t *dma = dev->dma; | 904 | drm_device_dma_t *dma = dev->dma; |
944 | drm_buf_desc_t request; | ||
945 | drm_buf_entry_t *entry; | 905 | drm_buf_entry_t *entry; |
946 | drm_buf_t *buf; | 906 | drm_buf_t *buf; |
947 | unsigned long offset; | 907 | unsigned long offset; |
@@ -955,7 +915,6 @@ int drm_addbufs_fb(struct inode *inode, struct file *filp, | |||
955 | int byte_count; | 915 | int byte_count; |
956 | int i; | 916 | int i; |
957 | drm_buf_t **temp_buflist; | 917 | drm_buf_t **temp_buflist; |
958 | drm_buf_desc_t __user *argp = (void __user *)arg; | ||
959 | 918 | ||
960 | if (!drm_core_check_feature(dev, DRIVER_FB_DMA)) | 919 | if (!drm_core_check_feature(dev, DRIVER_FB_DMA)) |
961 | return -EINVAL; | 920 | return -EINVAL; |
@@ -963,20 +922,17 @@ int drm_addbufs_fb(struct inode *inode, struct file *filp, | |||
963 | if (!dma) | 922 | if (!dma) |
964 | return -EINVAL; | 923 | return -EINVAL; |
965 | 924 | ||
966 | if (copy_from_user(&request, argp, sizeof(request))) | 925 | count = request->count; |
967 | return -EFAULT; | 926 | order = drm_order(request->size); |
968 | |||
969 | count = request.count; | ||
970 | order = drm_order(request.size); | ||
971 | size = 1 << order; | 927 | size = 1 << order; |
972 | 928 | ||
973 | alignment = (request.flags & _DRM_PAGE_ALIGN) | 929 | alignment = (request->flags & _DRM_PAGE_ALIGN) |
974 | ? PAGE_ALIGN(size) : size; | 930 | ? PAGE_ALIGN(size) : size; |
975 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; | 931 | page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; |
976 | total = PAGE_SIZE << page_order; | 932 | total = PAGE_SIZE << page_order; |
977 | 933 | ||
978 | byte_count = 0; | 934 | byte_count = 0; |
979 | agp_offset = request.agp_start; | 935 | agp_offset = request->agp_start; |
980 | 936 | ||
981 | DRM_DEBUG("count: %d\n", count); | 937 | DRM_DEBUG("count: %d\n", count); |
982 | DRM_DEBUG("order: %d\n", order); | 938 | DRM_DEBUG("order: %d\n", order); |
@@ -1089,11 +1045,8 @@ int drm_addbufs_fb(struct inode *inode, struct file *filp, | |||
1089 | 1045 | ||
1090 | up(&dev->struct_sem); | 1046 | up(&dev->struct_sem); |
1091 | 1047 | ||
1092 | request.count = entry->buf_count; | 1048 | request->count = entry->buf_count; |
1093 | request.size = size; | 1049 | request->size = size; |
1094 | |||
1095 | if (copy_to_user(argp, &request, sizeof(request))) | ||
1096 | return -EFAULT; | ||
1097 | 1050 | ||
1098 | dma->flags = _DRM_DMA_USE_FB; | 1051 | dma->flags = _DRM_DMA_USE_FB; |
1099 | 1052 | ||
@@ -1121,6 +1074,7 @@ int drm_addbufs( struct inode *inode, struct file *filp, | |||
1121 | drm_buf_desc_t request; | 1074 | drm_buf_desc_t request; |
1122 | drm_file_t *priv = filp->private_data; | 1075 | drm_file_t *priv = filp->private_data; |
1123 | drm_device_t *dev = priv->head->dev; | 1076 | drm_device_t *dev = priv->head->dev; |
1077 | int ret; | ||
1124 | 1078 | ||
1125 | if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) | 1079 | if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) |
1126 | return -EINVAL; | 1080 | return -EINVAL; |
@@ -1131,15 +1085,23 @@ int drm_addbufs( struct inode *inode, struct file *filp, | |||
1131 | 1085 | ||
1132 | #if __OS_HAS_AGP | 1086 | #if __OS_HAS_AGP |
1133 | if ( request.flags & _DRM_AGP_BUFFER ) | 1087 | if ( request.flags & _DRM_AGP_BUFFER ) |
1134 | return drm_addbufs_agp( inode, filp, cmd, arg ); | 1088 | ret=drm_addbufs_agp(dev, &request); |
1135 | else | 1089 | else |
1136 | #endif | 1090 | #endif |
1137 | if ( request.flags & _DRM_SG_BUFFER ) | 1091 | if ( request.flags & _DRM_SG_BUFFER ) |
1138 | return drm_addbufs_sg( inode, filp, cmd, arg ); | 1092 | ret=drm_addbufs_sg(dev, &request); |
1139 | else if ( request.flags & _DRM_FB_BUFFER) | 1093 | else if ( request.flags & _DRM_FB_BUFFER) |
1140 | return drm_addbufs_fb( inode, filp, cmd, arg ); | 1094 | ret=drm_addbufs_fb(dev, &request); |
1141 | else | 1095 | else |
1142 | return drm_addbufs_pci( inode, filp, cmd, arg ); | 1096 | ret=drm_addbufs_pci(dev, &request); |
1097 | |||
1098 | if (ret==0) { | ||
1099 | if (copy_to_user((void __user *)arg, &request, | ||
1100 | sizeof(request))) { | ||
1101 | ret = -EFAULT; | ||
1102 | } | ||
1103 | } | ||
1104 | return ret; | ||
1143 | } | 1105 | } |
1144 | 1106 | ||
1145 | 1107 | ||