diff options
Diffstat (limited to 'drivers/usb/misc/sisusbvga/sisusb_con.c')
| -rw-r--r-- | drivers/usb/misc/sisusbvga/sisusb_con.c | 255 |
1 files changed, 83 insertions, 172 deletions
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index be5c1a25ae2..a638c4e9a94 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -47,49 +47,29 @@ * */ -#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/kd.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/vt_kern.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 +82,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 +172,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; } @@ -230,24 +208,19 @@ sisusbcon_init(struct vc_data *c, int init) struct sisusb_usb_data *sisusb; int cols, rows; - /* This is called by take_over_console(), + /* This is called by do_take_over_console(), * ie by us/under our control. It is * only called after text mode and fonts * 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 +257,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; @@ -302,18 +273,14 @@ sisusbcon_deinit(struct vc_data *c) struct sisusb_usb_data *sisusb; int i; - /* This is called by take_over_console() + /* This is called by do_take_over_console() * 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 +299,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 +373,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 +410,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 +461,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 +469,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 +482,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 +493,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 +502,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 +527,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 +536,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 +550,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 +575,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 +587,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 +608,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 +623,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table) break; } - up(&sisusb->lock); + mutex_unlock(&sisusb->lock); return 0; } @@ -728,7 +646,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 +695,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 +706,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) } - up(&sisusb->lock); + mutex_unlock(&sisusb->lock); return ret; } @@ -809,7 +727,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 +767,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 +785,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 +797,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 +837,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 +877,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 +912,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 +1002,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 +1024,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 +1034,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 +1052,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 +1086,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; } @@ -1268,9 +1187,9 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, * And so is the hi_font_mask. */ for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct vc_data *c = vc_cons[i].d; - if (c && c->vc_sw == &sisusb_con) - c->vc_hi_font_mask = ch512 ? 0x0800 : 0; + struct vc_data *d = vc_cons[i].d; + if (d && d->vc_sw == &sisusb_con) + d->vc_hi_font_mask = ch512 ? 0x0800 : 0; } sisusb->current_font_512 = ch512; @@ -1327,10 +1246,10 @@ 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; + int rows = c->vc_scan_lines / fh; /* Now adjust our consoles' size */ @@ -1351,7 +1270,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 +1336,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 +1405,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 +1429,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; + int i, ret; - down(&disconnect_sem); - - 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 +1445,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 +1461,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,20 +1482,17 @@ 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); - + console_lock(); + ret = do_take_over_console(&sisusb_con, first - 1, last - 1, 0); + console_unlock(); if (!ret) sisusb->haveconsole = 1; else { @@ -1628,11 +1536,14 @@ sisusb_console_exit(struct sisusb_usb_data *sisusb) if (sisusb->haveconsole) { for (i = 0; i < MAX_NR_CONSOLES; i++) - if (sisusb->havethisconsole[i]) - take_over_console(&sisusb_dummy_con, i, i, 0); + if (sisusb->havethisconsole[i]) { + console_lock(); + do_take_over_console(&sisusb_dummy_con, i, i, 0); + console_unlock(); /* At this point, con_deinit for all our - * consoles is executed by take_over_console(). + * consoles is executed by do_take_over_console(). */ + } sisusb->haveconsole = 0; } |
