diff options
author | Bruno Prémont <bonbons@linux-vserver.org> | 2009-01-04 16:11:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-04 16:33:20 -0500 |
commit | e687d691cb3790d25e31c74f5941fd7c565e9df5 (patch) | |
tree | d606511c734e99fb6e4786d20ab42a8cf1b2232f | |
parent | c644f0e4b56f9a2fc066cd0d75a18074d130e4a3 (diff) |
viafb: fix crashes due to 4k stack overflow
The function viafb_cursor() uses 2 stack-variables of CURSOR_SIZE bits;
CURSOR_SIZE is defined as (8 * 1024). Using up twice 1k on stack is too
much for 4k-stack (though it works with 8k-stacks). Make those two
variables kzalloc'ed to preserve stack space.
Also merge the whole lot of local struct's in viafb_ioctl into a union so
the stack usage gets minimized here as well. (struct's are only accessed
in their indicidual IOCTL case) This second part is only compile-tested as
I know of no userspace app using the IOCTLs.
Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
Cc: <JosephChan@via.com.tw>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/video/via/viafbdev.c | 248 |
1 files changed, 129 insertions, 119 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 73ac754ad801..e21fe5b6f9ff 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -546,23 +546,25 @@ static int viafb_blank(int blank_mode, struct fb_info *info) | |||
546 | 546 | ||
547 | static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | 547 | static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) |
548 | { | 548 | { |
549 | struct viafb_ioctl_mode viamode; | 549 | union { |
550 | struct viafb_ioctl_samm viasamm; | 550 | struct viafb_ioctl_mode viamode; |
551 | struct viafb_driver_version driver_version; | 551 | struct viafb_ioctl_samm viasamm; |
552 | struct fb_var_screeninfo sec_var; | 552 | struct viafb_driver_version driver_version; |
553 | struct _panel_size_pos_info panel_pos_size_para; | 553 | struct fb_var_screeninfo sec_var; |
554 | struct _panel_size_pos_info panel_pos_size_para; | ||
555 | struct viafb_ioctl_setting viafb_setting; | ||
556 | struct device_t active_dev; | ||
557 | } u; | ||
554 | u32 state_info = 0; | 558 | u32 state_info = 0; |
555 | u32 viainfo_size = sizeof(struct viafb_ioctl_info); | ||
556 | u32 *viafb_gamma_table; | 559 | u32 *viafb_gamma_table; |
557 | char driver_name[] = "viafb"; | 560 | char driver_name[] = "viafb"; |
558 | 561 | ||
559 | u32 __user *argp = (u32 __user *) arg; | 562 | u32 __user *argp = (u32 __user *) arg; |
560 | u32 gpu32; | 563 | u32 gpu32; |
561 | u32 video_dev_info = 0; | 564 | u32 video_dev_info = 0; |
562 | struct viafb_ioctl_setting viafb_setting = {}; | ||
563 | struct device_t active_dev = {}; | ||
564 | 565 | ||
565 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); | 566 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); |
567 | memset(&u, 0, sizeof(u)); | ||
566 | 568 | ||
567 | switch (cmd) { | 569 | switch (cmd) { |
568 | case VIAFB_GET_CHIP_INFO: | 570 | case VIAFB_GET_CHIP_INFO: |
@@ -571,7 +573,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
571 | return -EFAULT; | 573 | return -EFAULT; |
572 | break; | 574 | break; |
573 | case VIAFB_GET_INFO_SIZE: | 575 | case VIAFB_GET_INFO_SIZE: |
574 | return put_user(viainfo_size, argp); | 576 | return put_user((u32)sizeof(struct viafb_ioctl_info), argp); |
575 | case VIAFB_GET_INFO: | 577 | case VIAFB_GET_INFO: |
576 | return viafb_ioctl_get_viafb_info(arg); | 578 | return viafb_ioctl_get_viafb_info(arg); |
577 | case VIAFB_HOTPLUG: | 579 | case VIAFB_HOTPLUG: |
@@ -584,60 +586,60 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
584 | viafb_hotplug = (gpu32) ? 1 : 0; | 586 | viafb_hotplug = (gpu32) ? 1 : 0; |
585 | break; | 587 | break; |
586 | case VIAFB_GET_RESOLUTION: | 588 | case VIAFB_GET_RESOLUTION: |
587 | viamode.xres = (u32) viafb_hotplug_Xres; | 589 | u.viamode.xres = (u32) viafb_hotplug_Xres; |
588 | viamode.yres = (u32) viafb_hotplug_Yres; | 590 | u.viamode.yres = (u32) viafb_hotplug_Yres; |
589 | viamode.refresh = (u32) viafb_hotplug_refresh; | 591 | u.viamode.refresh = (u32) viafb_hotplug_refresh; |
590 | viamode.bpp = (u32) viafb_hotplug_bpp; | 592 | u.viamode.bpp = (u32) viafb_hotplug_bpp; |
591 | if (viafb_SAMM_ON == 1) { | 593 | if (viafb_SAMM_ON == 1) { |
592 | viamode.xres_sec = viafb_second_xres; | 594 | u.viamode.xres_sec = viafb_second_xres; |
593 | viamode.yres_sec = viafb_second_yres; | 595 | u.viamode.yres_sec = viafb_second_yres; |
594 | viamode.virtual_xres_sec = viafb_second_virtual_xres; | 596 | u.viamode.virtual_xres_sec = viafb_second_virtual_xres; |
595 | viamode.virtual_yres_sec = viafb_second_virtual_yres; | 597 | u.viamode.virtual_yres_sec = viafb_second_virtual_yres; |
596 | viamode.refresh_sec = viafb_refresh1; | 598 | u.viamode.refresh_sec = viafb_refresh1; |
597 | viamode.bpp_sec = viafb_bpp1; | 599 | u.viamode.bpp_sec = viafb_bpp1; |
598 | } else { | 600 | } else { |
599 | viamode.xres_sec = 0; | 601 | u.viamode.xres_sec = 0; |
600 | viamode.yres_sec = 0; | 602 | u.viamode.yres_sec = 0; |
601 | viamode.virtual_xres_sec = 0; | 603 | u.viamode.virtual_xres_sec = 0; |
602 | viamode.virtual_yres_sec = 0; | 604 | u.viamode.virtual_yres_sec = 0; |
603 | viamode.refresh_sec = 0; | 605 | u.viamode.refresh_sec = 0; |
604 | viamode.bpp_sec = 0; | 606 | u.viamode.bpp_sec = 0; |
605 | } | 607 | } |
606 | if (copy_to_user(argp, &viamode, sizeof(viamode))) | 608 | if (copy_to_user(argp, &u.viamode, sizeof(u.viamode))) |
607 | return -EFAULT; | 609 | return -EFAULT; |
608 | break; | 610 | break; |
609 | case VIAFB_GET_SAMM_INFO: | 611 | case VIAFB_GET_SAMM_INFO: |
610 | viasamm.samm_status = viafb_SAMM_ON; | 612 | u.viasamm.samm_status = viafb_SAMM_ON; |
611 | 613 | ||
612 | if (viafb_SAMM_ON == 1) { | 614 | if (viafb_SAMM_ON == 1) { |
613 | if (viafb_dual_fb) { | 615 | if (viafb_dual_fb) { |
614 | viasamm.size_prim = viaparinfo->fbmem_free; | 616 | u.viasamm.size_prim = viaparinfo->fbmem_free; |
615 | viasamm.size_sec = viaparinfo1->fbmem_free; | 617 | u.viasamm.size_sec = viaparinfo1->fbmem_free; |
616 | } else { | 618 | } else { |
617 | if (viafb_second_size) { | 619 | if (viafb_second_size) { |
618 | viasamm.size_prim = | 620 | u.viasamm.size_prim = |
619 | viaparinfo->fbmem_free - | 621 | viaparinfo->fbmem_free - |
620 | viafb_second_size * 1024 * 1024; | 622 | viafb_second_size * 1024 * 1024; |
621 | viasamm.size_sec = | 623 | u.viasamm.size_sec = |
622 | viafb_second_size * 1024 * 1024; | 624 | viafb_second_size * 1024 * 1024; |
623 | } else { | 625 | } else { |
624 | viasamm.size_prim = | 626 | u.viasamm.size_prim = |
625 | viaparinfo->fbmem_free >> 1; | 627 | viaparinfo->fbmem_free >> 1; |
626 | viasamm.size_sec = | 628 | u.viasamm.size_sec = |
627 | (viaparinfo->fbmem_free >> 1); | 629 | (viaparinfo->fbmem_free >> 1); |
628 | } | 630 | } |
629 | } | 631 | } |
630 | viasamm.mem_base = viaparinfo->fbmem; | 632 | u.viasamm.mem_base = viaparinfo->fbmem; |
631 | viasamm.offset_sec = viafb_second_offset; | 633 | u.viasamm.offset_sec = viafb_second_offset; |
632 | } else { | 634 | } else { |
633 | viasamm.size_prim = | 635 | u.viasamm.size_prim = |
634 | viaparinfo->memsize - viaparinfo->fbmem_used; | 636 | viaparinfo->memsize - viaparinfo->fbmem_used; |
635 | viasamm.size_sec = 0; | 637 | u.viasamm.size_sec = 0; |
636 | viasamm.mem_base = viaparinfo->fbmem; | 638 | u.viasamm.mem_base = viaparinfo->fbmem; |
637 | viasamm.offset_sec = 0; | 639 | u.viasamm.offset_sec = 0; |
638 | } | 640 | } |
639 | 641 | ||
640 | if (copy_to_user(argp, &viasamm, sizeof(viasamm))) | 642 | if (copy_to_user(argp, &u.viasamm, sizeof(u.viasamm))) |
641 | return -EFAULT; | 643 | return -EFAULT; |
642 | 644 | ||
643 | break; | 645 | break; |
@@ -662,74 +664,75 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
662 | viafb_lcd_disable(); | 664 | viafb_lcd_disable(); |
663 | break; | 665 | break; |
664 | case VIAFB_SET_DEVICE: | 666 | case VIAFB_SET_DEVICE: |
665 | if (copy_from_user(&active_dev, (void *)argp, | 667 | if (copy_from_user(&u.active_dev, (void *)argp, |
666 | sizeof(active_dev))) | 668 | sizeof(u.active_dev))) |
667 | return -EFAULT; | 669 | return -EFAULT; |
668 | viafb_set_device(active_dev); | 670 | viafb_set_device(u.active_dev); |
669 | viafb_set_par(info); | 671 | viafb_set_par(info); |
670 | break; | 672 | break; |
671 | case VIAFB_GET_DEVICE: | 673 | case VIAFB_GET_DEVICE: |
672 | active_dev.crt = viafb_CRT_ON; | 674 | u.active_dev.crt = viafb_CRT_ON; |
673 | active_dev.dvi = viafb_DVI_ON; | 675 | u.active_dev.dvi = viafb_DVI_ON; |
674 | active_dev.lcd = viafb_LCD_ON; | 676 | u.active_dev.lcd = viafb_LCD_ON; |
675 | active_dev.samm = viafb_SAMM_ON; | 677 | u.active_dev.samm = viafb_SAMM_ON; |
676 | active_dev.primary_dev = viafb_primary_dev; | 678 | u.active_dev.primary_dev = viafb_primary_dev; |
677 | 679 | ||
678 | active_dev.lcd_dsp_cent = viafb_lcd_dsp_method; | 680 | u.active_dev.lcd_dsp_cent = viafb_lcd_dsp_method; |
679 | active_dev.lcd_panel_id = viafb_lcd_panel_id; | 681 | u.active_dev.lcd_panel_id = viafb_lcd_panel_id; |
680 | active_dev.lcd_mode = viafb_lcd_mode; | 682 | u.active_dev.lcd_mode = viafb_lcd_mode; |
681 | 683 | ||
682 | active_dev.xres = viafb_hotplug_Xres; | 684 | u.active_dev.xres = viafb_hotplug_Xres; |
683 | active_dev.yres = viafb_hotplug_Yres; | 685 | u.active_dev.yres = viafb_hotplug_Yres; |
684 | 686 | ||
685 | active_dev.xres1 = viafb_second_xres; | 687 | u.active_dev.xres1 = viafb_second_xres; |
686 | active_dev.yres1 = viafb_second_yres; | 688 | u.active_dev.yres1 = viafb_second_yres; |
687 | 689 | ||
688 | active_dev.bpp = viafb_bpp; | 690 | u.active_dev.bpp = viafb_bpp; |
689 | active_dev.bpp1 = viafb_bpp1; | 691 | u.active_dev.bpp1 = viafb_bpp1; |
690 | active_dev.refresh = viafb_refresh; | 692 | u.active_dev.refresh = viafb_refresh; |
691 | active_dev.refresh1 = viafb_refresh1; | 693 | u.active_dev.refresh1 = viafb_refresh1; |
692 | 694 | ||
693 | active_dev.epia_dvi = viafb_platform_epia_dvi; | 695 | u.active_dev.epia_dvi = viafb_platform_epia_dvi; |
694 | active_dev.lcd_dual_edge = viafb_device_lcd_dualedge; | 696 | u.active_dev.lcd_dual_edge = viafb_device_lcd_dualedge; |
695 | active_dev.bus_width = viafb_bus_width; | 697 | u.active_dev.bus_width = viafb_bus_width; |
696 | 698 | ||
697 | if (copy_to_user(argp, &active_dev, sizeof(active_dev))) | 699 | if (copy_to_user(argp, &u.active_dev, sizeof(u.active_dev))) |
698 | return -EFAULT; | 700 | return -EFAULT; |
699 | break; | 701 | break; |
700 | 702 | ||
701 | case VIAFB_GET_DRIVER_VERSION: | 703 | case VIAFB_GET_DRIVER_VERSION: |
702 | driver_version.iMajorNum = VERSION_MAJOR; | 704 | u.driver_version.iMajorNum = VERSION_MAJOR; |
703 | driver_version.iKernelNum = VERSION_KERNEL; | 705 | u.driver_version.iKernelNum = VERSION_KERNEL; |
704 | driver_version.iOSNum = VERSION_OS; | 706 | u.driver_version.iOSNum = VERSION_OS; |
705 | driver_version.iMinorNum = VERSION_MINOR; | 707 | u.driver_version.iMinorNum = VERSION_MINOR; |
706 | 708 | ||
707 | if (copy_to_user(argp, &driver_version, | 709 | if (copy_to_user(argp, &u.driver_version, |
708 | sizeof(driver_version))) | 710 | sizeof(u.driver_version))) |
709 | return -EFAULT; | 711 | return -EFAULT; |
710 | 712 | ||
711 | break; | 713 | break; |
712 | 714 | ||
713 | case VIAFB_SET_DEVICE_INFO: | 715 | case VIAFB_SET_DEVICE_INFO: |
714 | if (copy_from_user(&viafb_setting, | 716 | if (copy_from_user(&u.viafb_setting, |
715 | argp, sizeof(viafb_setting))) | 717 | argp, sizeof(u.viafb_setting))) |
716 | return -EFAULT; | 718 | return -EFAULT; |
717 | if (apply_device_setting(viafb_setting, info) < 0) | 719 | if (apply_device_setting(u.viafb_setting, info) < 0) |
718 | return -EINVAL; | 720 | return -EINVAL; |
719 | 721 | ||
720 | break; | 722 | break; |
721 | 723 | ||
722 | case VIAFB_SET_SECOND_MODE: | 724 | case VIAFB_SET_SECOND_MODE: |
723 | if (copy_from_user(&sec_var, argp, sizeof(sec_var))) | 725 | if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var))) |
724 | return -EFAULT; | 726 | return -EFAULT; |
725 | apply_second_mode_setting(&sec_var); | 727 | apply_second_mode_setting(&u.sec_var); |
726 | break; | 728 | break; |
727 | 729 | ||
728 | case VIAFB_GET_DEVICE_INFO: | 730 | case VIAFB_GET_DEVICE_INFO: |
729 | 731 | ||
730 | retrieve_device_setting(&viafb_setting); | 732 | retrieve_device_setting(&u.viafb_setting); |
731 | 733 | ||
732 | if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting))) | 734 | if (copy_to_user(argp, &u.viafb_setting, |
735 | sizeof(u.viafb_setting))) | ||
733 | return -EFAULT; | 736 | return -EFAULT; |
734 | 737 | ||
735 | break; | 738 | break; |
@@ -806,51 +809,51 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
806 | break; | 809 | break; |
807 | 810 | ||
808 | case VIAFB_GET_PANEL_MAX_SIZE: | 811 | case VIAFB_GET_PANEL_MAX_SIZE: |
809 | if (copy_from_user | 812 | if (copy_from_user(&u.panel_pos_size_para, argp, |
810 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 813 | sizeof(u.panel_pos_size_para))) |
811 | return -EFAULT; | 814 | return -EFAULT; |
812 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | 815 | u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; |
813 | if (copy_to_user(argp, &panel_pos_size_para, | 816 | if (copy_to_user(argp, &u.panel_pos_size_para, |
814 | sizeof(panel_pos_size_para))) | 817 | sizeof(u.panel_pos_size_para))) |
815 | return -EFAULT; | 818 | return -EFAULT; |
816 | break; | 819 | break; |
817 | case VIAFB_GET_PANEL_MAX_POSITION: | 820 | case VIAFB_GET_PANEL_MAX_POSITION: |
818 | if (copy_from_user | 821 | if (copy_from_user(&u.panel_pos_size_para, argp, |
819 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 822 | sizeof(u.panel_pos_size_para))) |
820 | return -EFAULT; | 823 | return -EFAULT; |
821 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | 824 | u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; |
822 | if (copy_to_user(argp, &panel_pos_size_para, | 825 | if (copy_to_user(argp, &u.panel_pos_size_para, |
823 | sizeof(panel_pos_size_para))) | 826 | sizeof(u.panel_pos_size_para))) |
824 | return -EFAULT; | 827 | return -EFAULT; |
825 | break; | 828 | break; |
826 | 829 | ||
827 | case VIAFB_GET_PANEL_POSITION: | 830 | case VIAFB_GET_PANEL_POSITION: |
828 | if (copy_from_user | 831 | if (copy_from_user(&u.panel_pos_size_para, argp, |
829 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 832 | sizeof(u.panel_pos_size_para))) |
830 | return -EFAULT; | 833 | return -EFAULT; |
831 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | 834 | u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; |
832 | if (copy_to_user(argp, &panel_pos_size_para, | 835 | if (copy_to_user(argp, &u.panel_pos_size_para, |
833 | sizeof(panel_pos_size_para))) | 836 | sizeof(u.panel_pos_size_para))) |
834 | return -EFAULT; | 837 | return -EFAULT; |
835 | break; | 838 | break; |
836 | case VIAFB_GET_PANEL_SIZE: | 839 | case VIAFB_GET_PANEL_SIZE: |
837 | if (copy_from_user | 840 | if (copy_from_user(&u.panel_pos_size_para, argp, |
838 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 841 | sizeof(u.panel_pos_size_para))) |
839 | return -EFAULT; | 842 | return -EFAULT; |
840 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | 843 | u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; |
841 | if (copy_to_user(argp, &panel_pos_size_para, | 844 | if (copy_to_user(argp, &u.panel_pos_size_para, |
842 | sizeof(panel_pos_size_para))) | 845 | sizeof(u.panel_pos_size_para))) |
843 | return -EFAULT; | 846 | return -EFAULT; |
844 | break; | 847 | break; |
845 | 848 | ||
846 | case VIAFB_SET_PANEL_POSITION: | 849 | case VIAFB_SET_PANEL_POSITION: |
847 | if (copy_from_user | 850 | if (copy_from_user(&u.panel_pos_size_para, argp, |
848 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 851 | sizeof(u.panel_pos_size_para))) |
849 | return -EFAULT; | 852 | return -EFAULT; |
850 | break; | 853 | break; |
851 | case VIAFB_SET_PANEL_SIZE: | 854 | case VIAFB_SET_PANEL_SIZE: |
852 | if (copy_from_user | 855 | if (copy_from_user(&u.panel_pos_size_para, argp, |
853 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | 856 | sizeof(u.panel_pos_size_para))) |
854 | return -EFAULT; | 857 | return -EFAULT; |
855 | break; | 858 | break; |
856 | 859 | ||
@@ -1052,10 +1055,8 @@ static void viafb_imageblit(struct fb_info *info, | |||
1052 | 1055 | ||
1053 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1056 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1054 | { | 1057 | { |
1055 | u8 data[CURSOR_SIZE / 8]; | ||
1056 | u32 data_bak[CURSOR_SIZE / 32]; | ||
1057 | u32 temp, xx, yy, bg_col = 0, fg_col = 0; | 1058 | u32 temp, xx, yy, bg_col = 0, fg_col = 0; |
1058 | int size, i, j = 0; | 1059 | int i, j = 0; |
1059 | static int hw_cursor; | 1060 | static int hw_cursor; |
1060 | struct viafb_par *p_viafb_par; | 1061 | struct viafb_par *p_viafb_par; |
1061 | 1062 | ||
@@ -1178,22 +1179,29 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1178 | } | 1179 | } |
1179 | 1180 | ||
1180 | if (cursor->set & FB_CUR_SETSHAPE) { | 1181 | if (cursor->set & FB_CUR_SETSHAPE) { |
1181 | size = | 1182 | struct { |
1183 | u8 data[CURSOR_SIZE / 8]; | ||
1184 | u32 bak[CURSOR_SIZE / 32]; | ||
1185 | } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); | ||
1186 | int size = | ||
1182 | ((viacursor.image.width + 7) >> 3) * | 1187 | ((viacursor.image.width + 7) >> 3) * |
1183 | viacursor.image.height; | 1188 | viacursor.image.height; |
1184 | 1189 | ||
1190 | if (cr_data == NULL) | ||
1191 | goto out; | ||
1192 | |||
1185 | if (MAX_CURS == 32) { | 1193 | if (MAX_CURS == 32) { |
1186 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 1194 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { |
1187 | data_bak[i] = 0x0; | 1195 | cr_data->bak[i] = 0x0; |
1188 | data_bak[i + 1] = 0xFFFFFFFF; | 1196 | cr_data->bak[i + 1] = 0xFFFFFFFF; |
1189 | i += 1; | 1197 | i += 1; |
1190 | } | 1198 | } |
1191 | } else if (MAX_CURS == 64) { | 1199 | } else if (MAX_CURS == 64) { |
1192 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | 1200 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { |
1193 | data_bak[i] = 0x0; | 1201 | cr_data->bak[i] = 0x0; |
1194 | data_bak[i + 1] = 0x0; | 1202 | cr_data->bak[i + 1] = 0x0; |
1195 | data_bak[i + 2] = 0xFFFFFFFF; | 1203 | cr_data->bak[i + 2] = 0xFFFFFFFF; |
1196 | data_bak[i + 3] = 0xFFFFFFFF; | 1204 | cr_data->bak[i + 3] = 0xFFFFFFFF; |
1197 | i += 3; | 1205 | i += 3; |
1198 | } | 1206 | } |
1199 | } | 1207 | } |
@@ -1201,12 +1209,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1201 | switch (viacursor.rop) { | 1209 | switch (viacursor.rop) { |
1202 | case ROP_XOR: | 1210 | case ROP_XOR: |
1203 | for (i = 0; i < size; i++) | 1211 | for (i = 0; i < size; i++) |
1204 | data[i] = viacursor.mask[i]; | 1212 | cr_data->data[i] = viacursor.mask[i]; |
1205 | break; | 1213 | break; |
1206 | case ROP_COPY: | 1214 | case ROP_COPY: |
1207 | 1215 | ||
1208 | for (i = 0; i < size; i++) | 1216 | for (i = 0; i < size; i++) |
1209 | data[i] = viacursor.mask[i]; | 1217 | cr_data->data[i] = viacursor.mask[i]; |
1210 | break; | 1218 | break; |
1211 | default: | 1219 | default: |
1212 | break; | 1220 | break; |
@@ -1214,23 +1222,25 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1214 | 1222 | ||
1215 | if (MAX_CURS == 32) { | 1223 | if (MAX_CURS == 32) { |
1216 | for (i = 0; i < size; i++) { | 1224 | for (i = 0; i < size; i++) { |
1217 | data_bak[j] = (u32) data[i]; | 1225 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1218 | data_bak[j + 1] = ~data_bak[j]; | 1226 | cr_data->bak[j + 1] = ~cr_data->bak[j]; |
1219 | j += 2; | 1227 | j += 2; |
1220 | } | 1228 | } |
1221 | } else if (MAX_CURS == 64) { | 1229 | } else if (MAX_CURS == 64) { |
1222 | for (i = 0; i < size; i++) { | 1230 | for (i = 0; i < size; i++) { |
1223 | data_bak[j] = (u32) data[i]; | 1231 | cr_data->bak[j] = (u32) cr_data->data[i]; |
1224 | data_bak[j + 1] = 0x0; | 1232 | cr_data->bak[j + 1] = 0x0; |
1225 | data_bak[j + 2] = ~data_bak[j]; | 1233 | cr_data->bak[j + 2] = ~cr_data->bak[j]; |
1226 | data_bak[j + 3] = ~data_bak[j + 1]; | 1234 | cr_data->bak[j + 3] = ~cr_data->bak[j + 1]; |
1227 | j += 4; | 1235 | j += 4; |
1228 | } | 1236 | } |
1229 | } | 1237 | } |
1230 | 1238 | ||
1231 | memcpy(((struct viafb_par *)(info->par))->fbmem_virt + | 1239 | memcpy(((struct viafb_par *)(info->par))->fbmem_virt + |
1232 | ((struct viafb_par *)(info->par))->cursor_start, | 1240 | ((struct viafb_par *)(info->par))->cursor_start, |
1233 | data_bak, CURSOR_SIZE); | 1241 | cr_data->bak, CURSOR_SIZE); |
1242 | out: | ||
1243 | kfree(cr_data); | ||
1234 | } | 1244 | } |
1235 | 1245 | ||
1236 | if (viacursor.enable) | 1246 | if (viacursor.enable) |