From 9f72c10255c1874b0fe7229f170f86ea3e1f6d91 Mon Sep 17 00:00:00 2001 From: gpoirier Date: Tue, 13 Jun 2006 07:57:06 +0000 Subject: Fixes suggested by Ivo, and failure under non-root operation improved. Original patch by Mark Sanderson < mmp AH kiora P ath P cx > (reworked a bit to try to meet out commit policy). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18693 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/vo_s3fb.c | 76 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'libvo') diff --git a/libvo/vo_s3fb.c b/libvo/vo_s3fb.c index 8f9c7ceef7..8a07ae0764 100644 --- a/libvo/vo_s3fb.c +++ b/libvo/vo_s3fb.c @@ -39,6 +39,12 @@ static vo_info_t info = LIBVO_EXTERN(s3fb) +typedef struct vga_type { + int cr38, cr39, cr53; + unsigned char *mmio; +} vga_t; + +static vga_t *v = NULL; static int fd = -1; static struct fb_fix_screeninfo fb_finfo; static struct fb_var_screeninfo fb_vinfo; @@ -80,12 +86,7 @@ static void clear_screen(); #define S3V_MMIO_REGSIZE 0x8000 /* 32KB */ #define S3_NEWMMIO_VGABASE (S3_NEWMMIO_REGBASE + 0x8000) -#define OUTREG(mmreg, value) *(unsigned int *)(&v.mmio[mmreg]) = value - -typedef struct vga_type { - int cr38, cr39, cr53; - unsigned char *mmio; -} vga_t; +#define OUTREG(mmreg, value) *(unsigned int *)(&v->mmio[mmreg]) = value int readcrtc(int reg) { outb(reg, 0x3d4); @@ -97,36 +98,52 @@ void writecrtc(int reg, int value) { outb(value, 0x3d5); } -int enable(vga_t *v) { +// enable S3 registers +int enable() { int fd; - // enable registers - if (iopl(3) != 0) - return 0; + if (v) + return 1; + errno = 0; + v = (vga_t *)malloc(sizeof(vga_t)); + if (v) { + if (ioperm(0x3d4, 2, 1) == 0) { + fd = open("/dev/mem", O_RDWR); + if (fd != -1) { + v->mmio = mmap(0, S3_NEWMMIO_REGSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, + S3_MEMBASE + S3_NEWMMIO_REGBASE); + close(fd); + if (v->mmio != MAP_FAILED) { v->cr38 = readcrtc(0x38); v->cr39 = readcrtc(0x39); v->cr53 = readcrtc(0x53); writecrtc(0x38, 0x48); writecrtc(0x39, 0xa5); writecrtc(0x53, 0x08); - fd = open("/dev/mem", O_RDWR); - v->mmio = mmap(0, S3_NEWMMIO_REGSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, - S3_MEMBASE + S3_NEWMMIO_REGBASE); - close(fd); return 1; } + } + iopl(0); + } + free(v); + v = NULL; + } +} -void disable(vga_t *v) { +void disable() { + if (v) { writecrtc(0x53, v->cr53); writecrtc(0x39, v->cr39); writecrtc(0x38, v->cr38); - iopl(0); + ioperm(0x3d4, 2, 0); munmap(v->mmio, S3_NEWMMIO_REGSIZE); + free(v); + v = NULL; + } } int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int crop, int xres, int yres, int line_length, int offset) { int tmp, pitch, start, src_wc, src_hc, bpp; - vga_t v; if (format == 0 || format == 7) bpp = 4; @@ -151,9 +168,6 @@ int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, in // start is the top left viewable scaler input pixel start = offset + crop * pitch + crop * bpp; - if (!enable(&v)) - return 0; - OUTREG(COL_CHROMA_KEY_CONTROL_REG, 0x47000000); OUTREG(CHROMA_KEY_UPPER_BOUND_REG, 0x0); OUTREG(BLEND_CONTROL_REG, 0x00000020); @@ -192,18 +206,12 @@ int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, in writecrtc(0x67, readcrtc(0x67) | 0x4); - disable(&v); - return offset; } void yuv_off() { - vga_t v; - - enable(&v); - writecrtc(0x67, readcrtc(0x67) & ~0xc); - memset(v.mmio + 0x8180, 0, 0x80); + memset(v->mmio + 0x8180, 0, 0x80); OUTREG(0x81b8, 0x900); OUTREG(0x81bc, 0x900); OUTREG(0x81c8, 0x900); @@ -213,7 +221,6 @@ void yuv_off() { OUTREG(0x81fc, 0x00010001); writecrtc(0x92, 0); writecrtc(0x93, 0); - disable(&v); } static int preinit(const char *arg) @@ -271,9 +278,17 @@ static int preinit(const char *arg) return -1; } - return 0; + if (!enable()) { + mp_msg(MSGT_VO, MSGL_FATAL, "s3fb: Couldn't map S3 registers: %s\n", strerror(errno)); + close(fd); + fd = -1; + return -1; } + return 0; // Success +} + +/* And close our mess */ static void uninit(void) { if (inpage0) { @@ -282,12 +297,13 @@ static void uninit(void) inpage0 = NULL; } - /* And close our mess */ if(smem) { munmap(smem, fb_finfo.smem_len); smem = NULL; } + disable(); + if(fd != -1) { close(fd); fd = -1; -- cgit v1.2.3