]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/misc/sisusbvga/sisusb_con.c
Merge branches 'release', 'bugzilla-6217', 'bugzilla-6629', 'bugzilla-6933', 'bugzill...
[linux-2.6-omap-h63xx.git] / drivers / usb / misc / sisusbvga / sisusb_con.c
index be5c1a25ae21c1282b7a5d4637b8036b632e2192..b624320df903da090c8380f59d06593d8c648302 100644 (file)
  *
  */
 
-#include <linux/config.h>
+#include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/fs.h>
+#include <linux/usb.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/string.h>
 #include <linux/selection.h>
 #include <linux/spinlock.h>
 #include <linux/kref.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 
 #include "sisusb.h"
+#include "sisusb_init.h"
 
 #ifdef INCL_SISUSB_CON
-extern int sisusb_setreg(struct sisusb_usb_data *, int, u8);
-extern int sisusb_getreg(struct sisusb_usb_data *, int, u8 *);
-extern int sisusb_setidxreg(struct sisusb_usb_data *, int, u8, u8);
-extern int sisusb_getidxreg(struct sisusb_usb_data *, int, u8, u8 *);
-extern int sisusb_setidxregor(struct sisusb_usb_data *, int, u8, u8);
-extern int sisusb_setidxregand(struct sisusb_usb_data *, int, u8, u8);
-extern int sisusb_setidxregandor(struct sisusb_usb_data *, int, u8, u8, u8);
-
-extern int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
-extern int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
-extern int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
-extern int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
-extern int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
-                       u32 dest, int length, size_t *bytes_written);
-
-extern void sisusb_delete(struct kref *kref);
-extern int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
-
-extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
 
 #define sisusbcon_writew(val, addr)    (*(addr) = (val))
 #define sisusbcon_readw(addr)          (*(addr))
@@ -102,8 +83,6 @@ static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES];
 /* Forward declaration */
 static const struct consw sisusb_con;
 
-extern struct semaphore disconnect_sem;
-
 static inline void
 sisusbcon_memsetw(u16 *s, u16 c, unsigned int count)
 {
@@ -194,11 +173,11 @@ sisusb_get_sisusb_lock_and_check(unsigned short console)
        if (!(sisusb = sisusb_get_sisusb(console)))
                return NULL;
 
-       down(&sisusb->lock);
+       mutex_lock(&sisusb->lock);
 
        if (!sisusb_sisusb_valid(sisusb) ||
            !sisusb->havethisconsole[console]) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return NULL;
        }
 
@@ -236,18 +215,13 @@ sisusbcon_init(struct vc_data *c, int init)
         * are set up/restored.
         */
 
-       down(&disconnect_sem);
-
-       if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
-               up(&disconnect_sem);
+       if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
                return;
-       }
 
-       down(&sisusb->lock);
+       mutex_lock(&sisusb->lock);
 
        if (!sisusb_sisusb_valid(sisusb)) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -284,9 +258,7 @@ sisusbcon_init(struct vc_data *c, int init)
        if (!*c->vc_uni_pagedir_loc)
                con_set_default_unimap(c);
 
-       up(&sisusb->lock);
-
-       up(&disconnect_sem);
+       mutex_unlock(&sisusb->lock);
 
        if (init) {
                c->vc_cols = cols;
@@ -306,14 +278,10 @@ sisusbcon_deinit(struct vc_data *c)
         * and others, ie not under our control.
         */
 
-       down(&disconnect_sem);
-
-       if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
-               up(&disconnect_sem);
+       if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
                return;
-       }
 
-       down(&sisusb->lock);
+       mutex_lock(&sisusb->lock);
 
        /* Clear ourselves in mysisusbs */
        mysisusbs[c->vc_num] = NULL;
@@ -332,18 +300,16 @@ sisusbcon_deinit(struct vc_data *c)
                }
        }
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        /* decrement the usage count on our sisusb */
        kref_put(&sisusb->kref, sisusb_delete);
-
-       up(&disconnect_sem);
 }
 
 /* interface routine */
 static u8
 sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
-                           u8 blink, u8 underline, u8 reverse)
+                           u8 blink, u8 underline, u8 reverse, u8 unused)
 {
        u8 attr = color;
 
@@ -408,24 +374,16 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
                return;
 
        /* sisusb->lock is down */
-
-       /* Don't need to put the character into buffer ourselves,
-        * because the vt does this BEFORE calling us.
-        */
-#if 0
-       sisusbcon_writew(ch, SISUSB_VADDR(x, y));
-#endif
-
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
-                               (u32)SISUSB_HADDR(x, y), 2, &written);
+                               (long)SISUSB_HADDR(x, y), 2, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 /* Interface routine */
@@ -453,14 +411,14 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
                sisusbcon_writew(sisusbcon_readw(s++), dest++);
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
-                               (u32)SISUSB_HADDR(x, y), count * 2, &written);
+                               (long)SISUSB_HADDR(x, y), count * 2, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 /* Interface routine */
@@ -504,7 +462,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
        }
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -512,9 +470,9 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
 
 
        sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y),
-                               (u32)SISUSB_HADDR(x, y), length, &written);
+                               (long)SISUSB_HADDR(x, y), length, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 /* Interface routine */
@@ -525,10 +483,6 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx,
        struct sisusb_usb_data *sisusb;
        ssize_t written;
        int cols, length;
-#if 0
-       u16 *src, *dest;
-       int i;
-#endif
 
        if (width <= 0 || height <= 0)
                return;
@@ -540,43 +494,8 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx,
 
        cols = sisusb->sisusb_num_columns;
 
-       /* Don't need to move data outselves, because
-        * vt does this BEFORE calling us.
-        * This is only used by vt's insert/deletechar.
-        */
-#if 0
-       if (sx == 0 && dx == 0 && width >= c->vc_cols && width <= cols) {
-
-               sisusbcon_memmovew(SISUSB_VADDR(0, dy), SISUSB_VADDR(0, sy),
-                                       height * width * 2);
-
-       } else if (dy < sy || (dy == sy && dx < sx)) {
-
-               src  = SISUSB_VADDR(sx, sy);
-               dest = SISUSB_VADDR(dx, dy);
-
-               for (i = height; i > 0; i--) {
-                       sisusbcon_memmovew(dest, src, width * 2);
-                       src  += cols;
-                       dest += cols;
-               }
-
-       } else {
-
-               src  = SISUSB_VADDR(sx, sy + height - 1);
-               dest = SISUSB_VADDR(dx, dy + height - 1);
-
-               for (i = height; i > 0; i--) {
-                       sisusbcon_memmovew(dest, src, width * 2);
-                       src  -= cols;
-                       dest -= cols;
-               }
-
-       }
-#endif
-
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -584,9 +503,9 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx,
 
 
        sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy),
-                               (u32)SISUSB_HADDR(dx, dy), length, &written);
+                               (long)SISUSB_HADDR(dx, dy), length, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 /* interface routine */
@@ -609,7 +528,7 @@ sisusbcon_switch(struct vc_data *c)
 
        /* Don't write to screen if in gfx mode */
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -618,8 +537,8 @@ sisusbcon_switch(struct vc_data *c)
         * as origin.
         */
        if (c->vc_origin == (unsigned long)c->vc_screenbuf) {
-               up(&sisusb->lock);
-               printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n");
+               mutex_unlock(&sisusb->lock);
+               dev_dbg(&sisusb->sisusb_dev->dev, "ASSERT ORIGIN != SCREENBUF!\n");
                return 0;
        }
 
@@ -632,10 +551,10 @@ sisusbcon_switch(struct vc_data *c)
                                                                length);
 
        sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin,
-                               (u32)SISUSB_HADDR(0, 0),
+                               (long)SISUSB_HADDR(0, 0),
                                length, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 0;
 }
@@ -657,7 +576,7 @@ sisusbcon_save_screen(struct vc_data *c)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -669,7 +588,7 @@ sisusbcon_save_screen(struct vc_data *c)
        sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin,
                                                                length);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 /* interface routine */
@@ -690,7 +609,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return -EINVAL;
        }
 
@@ -705,7 +624,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
                        break;
        }
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 0;
 }
@@ -728,7 +647,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
                sisusb->is_gfx = blank ? 1 : 0;
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -777,7 +696,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
                        cr63  = 0x40;
                        break;
                default:
-                       up(&sisusb->lock);
+                       mutex_unlock(&sisusb->lock);
                        return -EINVAL;
                }
 
@@ -788,7 +707,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
 
        }
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return ret;
 }
@@ -809,7 +728,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -849,7 +768,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines)
 
        sisusbcon_set_start_address(sisusb, c);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 1;
 }
@@ -867,7 +786,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -879,7 +798,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
        if (mode == CM_ERASE) {
                sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20);
                sisusb->sisusb_cursor_size_to = -1;
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return;
        }
 
@@ -919,7 +838,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
                sisusb->sisusb_cursor_size_to   = to;
        }
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 }
 
 static int
@@ -959,9 +878,9 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
        }
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t),
-                               (u32)SISUSB_HADDR(0, t), length, &written);
+                               (long)SISUSB_HADDR(0, t), length, &written);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 1;
 }
@@ -994,7 +913,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -1084,7 +1003,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
 
        c->vc_pos = c->vc_pos - oldorigin + c->vc_origin;
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 1;
 }
@@ -1106,7 +1025,7 @@ sisusbcon_set_origin(struct vc_data *c)
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -1116,14 +1035,15 @@ sisusbcon_set_origin(struct vc_data *c)
 
        sisusb->con_rolled_over = 0;
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 1;
 }
 
 /* Interface routine */
 static int
-sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
+sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows,
+                unsigned int user)
 {
        struct sisusb_usb_data *sisusb;
        int fh;
@@ -1133,7 +1053,7 @@ sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
 
        fh = sisusb->current_font_height;
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        /* We are quite unflexible as regards resizing. The vt code
         * handles sizes where the line length isn't equal the pitch
@@ -1167,7 +1087,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
 
        if ((slot != 0 && slot != 2) || !fh) {
                if (uplock)
-                       up(&sisusb->lock);
+                       mutex_unlock(&sisusb->lock);
                return -EINVAL;
        }
 
@@ -1327,7 +1247,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
        }
 
        if (uplock)
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
 
        if (dorecalc && c) {
                int i, rows = c->vc_scan_lines / fh;
@@ -1351,7 +1271,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
 
 font_op_error:
        if (uplock)
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
 
        return -EIO;
 }
@@ -1417,19 +1337,19 @@ sisusbcon_font_get(struct vc_data *c, struct console_font *font)
        font->charcount = 256;
 
        if (!font->data) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
        if (!sisusb->font_backup) {
-               up(&sisusb->lock);
+               mutex_unlock(&sisusb->lock);
                return -ENODEV;
        }
 
        /* Copy 256 chars only, like vgacon */
        memcpy(font->data, sisusb->font_backup, 256 * 32);
 
-       up(&sisusb->lock);
+       mutex_unlock(&sisusb->lock);
 
        return 0;
 }
@@ -1486,7 +1406,7 @@ static int sisusbdummycon_dummy(void)
 
 #define SISUSBCONDUMMY (void *)sisusbdummycon_dummy
 
-const struct consw sisusb_dummy_con = {
+static const struct consw sisusb_dummy_con = {
        .owner =                THIS_MODULE,
        .con_startup =          sisusbdummycon_startup,
        .con_init =             sisusbdummycon_init,
@@ -1510,16 +1430,13 @@ const struct consw sisusb_dummy_con = {
 int
 sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
 {
-       int i, ret, minor = sisusb->minor;
-
-       down(&disconnect_sem);
+       int i, ret;
 
-       down(&sisusb->lock);
+       mutex_lock(&sisusb->lock);
 
        /* Erm.. that should not happen */
        if (sisusb->haveconsole || !sisusb->SiS_Pr) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
+               mutex_unlock(&sisusb->lock);
                return 1;
        }
 
@@ -1529,15 +1446,13 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
        if (first > last ||
            first > MAX_NR_CONSOLES ||
            last > MAX_NR_CONSOLES) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
+               mutex_unlock(&sisusb->lock);
                return 1;
        }
 
        /* If gfxcore not initialized or no consoles given, quit graciously */
        if (!sisusb->gfxinit || first < 1 || last < 1) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
+               mutex_unlock(&sisusb->lock);
                return 0;
        }
 
@@ -1547,11 +1462,8 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
 
        /* Set up text mode (and upload  default font) */
        if (sisusb_reset_text_mode(sisusb, 1)) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
-               printk(KERN_ERR
-                       "sisusbvga[%d]: Failed to set up text mode\n",
-                       minor);
+               mutex_unlock(&sisusb->lock);
+               dev_err(&sisusb->sisusb_dev->dev, "Failed to set up text mode\n");
                return 1;
        }
 
@@ -1571,16 +1483,12 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
 
        /* Allocate screen buffer */
        if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
-               up(&sisusb->lock);
-               up(&disconnect_sem);
-               printk(KERN_ERR
-                       "sisusbvga[%d]: Failed to allocate screen buffer\n",
-                       minor);
+               mutex_unlock(&sisusb->lock);
+               dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate screen buffer\n");
                return 1;
        }
 
-       up(&sisusb->lock);
-       up(&disconnect_sem);
+       mutex_unlock(&sisusb->lock);
 
        /* Now grab the desired console(s) */
        ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);