You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(135) |
Nov
(123) |
Dec
(83) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(244) |
Feb
(72) |
Mar
(221) |
Apr
(91) |
May
(104) |
Jun
(93) |
Jul
(78) |
Aug
(1) |
Sep
(1) |
Oct
(29) |
Nov
(98) |
Dec
(20) |
2003 |
Jan
|
Feb
(21) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(18) |
Sep
(18) |
Oct
(23) |
Nov
(12) |
Dec
(6) |
2004 |
Jan
(2) |
Feb
(32) |
Mar
|
Apr
(12) |
May
(11) |
Jun
(11) |
Jul
|
Aug
(9) |
Sep
|
Oct
(15) |
Nov
|
Dec
|
2005 |
Jan
|
Feb
(2) |
Mar
(11) |
Apr
(6) |
May
(1) |
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2006 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2007 |
Jan
|
Feb
(2) |
Mar
|
Apr
(25) |
May
(2) |
Jun
|
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(13) |
Oct
|
Nov
(2) |
Dec
(2) |
2011 |
Jan
|
Feb
|
Mar
(10) |
Apr
(10) |
May
(1) |
Jun
(6) |
Jul
|
Aug
(2) |
Sep
(5) |
Oct
|
Nov
|
Dec
|
From: James S. <jsi...@us...> - 2001-10-08 04:36:36
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv26231 Modified Files: Config.in Log Message: If marked experimental it should be only configurable when experimental code is set. Index: Config.in =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/Config.in,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- Config.in 2001/10/08 02:23:57 1.50 +++ Config.in 2001/10/08 04:36:34 1.51 @@ -168,7 +168,7 @@ bool ' 3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX bool ' 3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1 fi - tristate ' SIS acceleration (EXPERIMENTAL)' CONFIG_FB_SIS + tristate ' SIS acceleration (EXPERIMENTAL)' CONFIG_FB_SIS $CONFIG_EXPERIMENTAL if [ "$CONFIG_FB_SIS" != "n" ]; then bool ' SIS 630/540/730 support' CONFIG_FB_SIS_300 bool ' SIS 315H/315 support' CONFIG_FB_SIS_315 |
From: James S. <jsi...@us...> - 2001-10-08 04:33:48
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/serial In directory usw-pr-cvs1:/tmp/cvs-serv25653 Modified Files: serial_21285.c serial_8250.c serial_8250.h serial_8250_pci.c serial_8250_pnp.c serial_amba.c serial_clps711x.c serial_core.c serial_sa1100.c Log Message: More syncing to Russel King's serial work. I really need to get to reworking it so the serial layer behaves more like the parallel port layer. Index: serial_21285.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_21285.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- serial_21285.c 2001/07/29 18:24:12 1.3 +++ serial_21285.c 2001/10/08 04:33:45 1.4 @@ -563,3 +563,8 @@ } #endif /* CONFIG_SERIAL_21285_CONSOLE */ + +EXPORT_NO_SYMBOLS; + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver"); Index: serial_8250.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- serial_8250.c 2001/08/23 02:46:17 1.7 +++ serial_8250.c 2001/10/08 04:33:45 1.8 @@ -76,8 +76,9 @@ static struct tty_driver normal, callout; static struct tty_struct *serial8250_table[UART_NR]; static struct termios *serial8250_termios[UART_NR], *serial8250_termios_locked[UART_NR]; -#ifdef SUPPORT_SYSRQ +#ifdef CONFIG_SERIAL_8250_CONSOLE static struct console serial8250_console; +static unsigned int lsr_break_flag; #endif static struct uart_info *IRQ_ports[NR_IRQS]; @@ -692,7 +693,7 @@ * may get masked by ignore_status_mask * or read_status_mask. */ - uart_handle_break(info, &sercons); + uart_handle_break(info, &serial8250_console); } else if (*status & UART_LSR_PE) port->icount.parity++; else if (*status & UART_LSR_FE) @@ -706,7 +707,7 @@ *status &= port->read_status_mask; #ifdef CONFIG_SERIAL_8250_CONSOLE - if (port->line == sercons.index) { + if (port->line == serial8250_console.index) { /* Recover the break flag from console xmit */ *status |= lsr_break_flag; lsr_break_flag = 0; @@ -1651,6 +1652,8 @@ } #endif +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + /* * Wait for transmitter & holding register to empty */ @@ -1880,3 +1883,7 @@ EXPORT_SYMBOL(register_serial); EXPORT_SYMBOL(unregister_serial); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); + Index: serial_8250.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 Index: serial_8250_pci.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pci.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- serial_8250_pci.c 2001/09/02 23:41:27 1.7 +++ serial_8250_pci.c 2001/10/08 04:33:45 1.8 @@ -1071,3 +1071,9 @@ module_init(serial8250_pci_init); module_exit(serial8250_pci_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); +MODULE_GENERIC_TABLE(pci, serial_pci_tbl); Index: serial_8250_pnp.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pnp.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- serial_8250_pnp.c 2001/07/29 18:24:12 1.3 +++ serial_8250_pnp.c 2001/10/08 04:33:45 1.4 @@ -544,3 +544,10 @@ module_init(serial8250_pnp_init); module_exit(serial8250_pnp_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250/16x50 PNPBIOS serial probe module"); +MODULE_GENERIC_TABLE(pnp, pnp_dev_table); + Index: serial_amba.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_amba.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- serial_amba.c 2001/08/23 02:46:18 1.6 +++ serial_amba.c 2001/10/08 04:33:45 1.7 @@ -487,7 +487,7 @@ /* first, disable everything */ save_flags(flags); cli(); - old_cr = UART_GET_CR(port) &= ~AMBA_UARTCR_MSIE; + old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE; if ((port->flags & ASYNC_HARDPPS_CD) || (cflag & CRTSCTS) || !(cflag & CLOCAL)) @@ -496,6 +496,7 @@ UART_PUT_CR(port, 0); /* Set baud rate */ + quot -= 1; UART_PUT_LCRM(port, ((quot & 0xf00) >> 8)); UART_PUT_LCRL(port, (quot & 0xff)); @@ -725,6 +726,7 @@ } static struct console amba_console = { + name: "ttyAM", write: ambauart_console_write, #ifdef used_and_not_const_char_pointer read: ambauart_console_read, @@ -780,3 +782,9 @@ module_init(ambauart_init); module_exit(ambauart_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd"); +MODULE_DESCRIPTION("ARM AMBA serial port driver"); +MODULE_LICENSE("GPL"); Index: serial_clps711x.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_clps711x.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- serial_clps711x.c 2001/08/18 22:23:04 1.6 +++ serial_clps711x.c 2001/10/08 04:33:45 1.7 @@ -676,3 +676,9 @@ module_init(clps711xuart_init); module_exit(clps711xuart_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Deep Blue Solutions Ltd"); +MODULE_DESCRIPTION("CLPS-711x generic serial driver"); +MODULE_LICENSE("GPL"); Index: serial_core.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_core.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- serial_core.c 2001/08/18 22:23:04 1.12 +++ serial_core.c 2001/10/08 04:33:45 1.13 @@ -273,7 +273,7 @@ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) quot = info->state->custom_divisor; else - quot = (info->port->uartclk / (16 * baud)) - 1; + quot = info->port->uartclk / (16 * baud); return quot; } @@ -1689,11 +1689,43 @@ } co->cflag = cflag; - quot = (port->uartclk / (16 * baud)) - 1; + quot = (port->uartclk / (16 * baud)); port->ops->change_speed(port, cflag, 0, quot); return 0; } + +extern void ambauart_console_init(void); +extern void anakin_console_init(void); +extern void clps711xuart_console_init(void); +extern void rs285_console_init(void); +extern void sa1100_rs_console_init(void); +extern void serial8250_console_init(void); + +/* + * Central "initialise all serial consoles" container. Needs to be killed. + */ +void __init uart_console_init(void) +{ +#ifdef CONFIG_SERIAL_AMBA_CONSOLE + ambauart_console_init(); +#endif +#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE + anakin_console_init(); +#endif +#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE + clps711xuart_console_init(); +#endif +#ifdef CONFIG_SERIAL_21285_CONSOLE + rs285_console_init(); +#endif +#ifdef CONFIG_SERIAL_SA1100_CONSOLE + sa1100_rs_console_init(); +#endif +#ifdef CONFIG_SERIAL_8250_CONSOLE + serial8250_console_init(); +#endif +} #endif /* CONFIG_SERIAL_CORE_CONSOLE */ #ifdef CONFIG_PM @@ -2147,3 +2179,6 @@ module_init(uart_init); module_exit(uart_exit); + +MODULE_DESCRIPTION("Serial driver core"); +MODULE_LICENSE("GPL"); Index: serial_sa1100.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_sa1100.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- serial_sa1100.c 2001/08/23 02:46:18 1.11 +++ serial_sa1100.c 2001/10/08 04:33:45 1.12 @@ -434,6 +434,7 @@ UART_PUT_UTCR0(port, utcr0); /* set the baud rate */ + quot -= 1; UART_PUT_UTCR1(port, ((quot & 0xf00) >> 8)); UART_PUT_UTCR2(port, (quot & 0xff)); @@ -792,4 +793,10 @@ module_init(sa1100_serial_init); module_exit(sa1100_serial_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Deep Blue Solutions Ltd"); +MODULE_DESCRIPTION("SA1100 generic serial port driver"); +MODULE_LICENSE("GPL"); |
From: James S. <jsi...@us...> - 2001-10-08 04:30:41
|
Update of /cvsroot/linuxconsole/ruby/linux/kernel In directory usw-pr-cvs1:/tmp/cvs-serv25361 Modified Files: printk.c Log Message: After looking at Andrew Morton's patch and my work I merged them more together. The design I have is far more fine grain locking. I also did alot of proper inlining of code to minimize the diff. I replaced the console_sem with a console_lock again. But this time I don't do IRQ blocking with it (only spin_lock and spin_unlock) and I have the proper locking down for the console driver list now. Index: printk.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/kernel/printk.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- printk.c 2001/08/05 22:58:18 1.16 +++ printk.c 2001/10/08 04:30:38 1.17 @@ -13,7 +13,7 @@ * Fixed SMP synchronization, 08/08/99, Manfred Spraul * man...@co... * Rewrote bits to get rid of console_lock - * 01Mar01 Andrew Morton <an...@uo...> + * 01Mar01 Andrew Morton <an...@uo...> */ #include <linux/mm.h> @@ -27,7 +27,7 @@ #include <asm/uaccess.h> -#define LOG_BUF_LEN (16384) /* This must be a power of two */ +#define LOG_BUF_LEN (16384) /* This must be a power of two */ #define LOG_BUF_MASK (LOG_BUF_LEN-1) /* printk's without a loglevel use this.. */ @@ -44,14 +44,13 @@ int default_message_loglevel = DEFAULT_MESSAGE_LOGLEVEL; int minimum_console_loglevel = MINIMUM_CONSOLE_LOGLEVEL; int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; + int oops_in_progress; /* - * console_sem protects the console_drivers list, and also - * provides serialisation for access to the entire console - * driver system. + * console_lock protects the console_drivers list */ -static DECLARE_MUTEX(console_sem); +static spinlock_t console_lock = SPIN_LOCK_UNLOCKED; struct console *console_drivers; /* @@ -68,14 +67,10 @@ * The indices into log_buf are not constrained to LOG_BUF_LEN - they * must be masked before subscripting */ -static unsigned long log_start; /* Index into log_buf: next char to be read - syslog() */ -static unsigned long con_start; /* Index into log_buf: next char to be sent - to consoles */ -static unsigned long log_end; /* Index into log_buf: most recently written - char + 1 */ -static unsigned long logged_chars; /* Number of chars produced since last - read+clear operation */ +static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ +static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ +static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ +static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; static int preferred_console = -1; @@ -147,7 +142,7 @@ * 6 -- Disable printk's to console * 7 -- Enable printk's to console * 8 -- Set level of messages printed to console - * 9 -- Return the number of unread characters in the log buffer + * 9 -- Return number of unread characters in the log buffer */ int do_syslog(int type, char * buf, int len) { @@ -171,7 +166,7 @@ error = verify_area(VERIFY_WRITE,buf,len); if (error) goto out; - error = wait_event_interruptible(log_wait,(log_start-log_end)); + error = wait_event_interruptible(log_wait, (log_start - log_end)); if (error) goto out; i = 0; @@ -267,7 +262,7 @@ spin_lock_irq(&logbuf_lock); error = log_end - log_start; spin_unlock_irq(&logbuf_lock); - break; + break; default: error = -EINVAL; break; @@ -302,18 +297,17 @@ /* * Write out chars from start to end - 1 inclusive */ -static void _call_console_drivers(struct console *con, unsigned long start, - unsigned long end, int msg_log_level) +static void _call_console_drivers(struct console *con, unsigned long start, unsigned long end, int msg_log_level) { - if (msg_log_level<console_loglevel && con && start != end){ + if (msg_log_level < console_loglevel && con && start != end) { if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { - /* wrapped write */ - __call_console_drivers(con, start & LOG_BUF_MASK, LOG_BUF_LEN); - __call_console_drivers(con, 0, end & LOG_BUF_MASK); - } else { - __call_console_drivers(con, start, end); - } - } + /* wrapped write */ + __call_console_drivers(con, start & LOG_BUF_MASK, LOG_BUF_LEN); + __call_console_drivers(con, 0, end & LOG_BUF_MASK); + } else { + __call_console_drivers(con, start, end); + } + } } /* @@ -321,50 +315,47 @@ * log_buf[start] to log_buf[end - 1]. * The console_sem must be held. */ -static void call_console_drivers(struct console *con, unsigned long start, - unsigned long end) +static void call_console_drivers(struct console *con, unsigned long start, unsigned long end) { unsigned long cur_index, start_print; - static int msg_level = -1; + static int msg_level = -1; - if (((long)(start - end)) > 0) - BUG(); + if (((long)(start - end)) > 0) + BUG(); cur_index = start; - start_print = start; - while (cur_index != end) { - if (msg_level < 0 && - ((end - cur_index) >= 3) && - LOG_BUF(cur_index + 0) == '<' && - LOG_BUF(cur_index + 1) >= '0' && - LOG_BUF(cur_index + 1) <= '7' && - LOG_BUF(cur_index + 2) == '>') { - msg_level = LOG_BUF(cur_index + 1) - '0'; - cur_index += 3; - start_print = cur_index; - } - while (cur_index != end) { - char c = LOG_BUF(cur_index); - cur_index++; + start_print = start; + while (cur_index != end) { + if ( msg_level < 0 && + ((end - cur_index) > 2) && + LOG_BUF(cur_index + 0) == '<' && + LOG_BUF(cur_index + 1) >= '0' && + LOG_BUF(cur_index + 1) <= '7' && + LOG_BUF(cur_index + 2) == '>') + { + msg_level = LOG_BUF(cur_index + 1) - '0'; + cur_index += 3; + start_print = cur_index; + } + while (cur_index != end) { + char c = LOG_BUF(cur_index); + cur_index++; - if (c == '\n') { + if (c == '\n') { if (msg_level < 0) { - /* - * printk() has already given us - * loglevel tages in the buffer. - * This code is here in case the - * log buffer has wrapped right - * around and scribbled on those - * tags. - */ - msg_level = default_message_loglevel; - } - _call_console_drivers(con, start_print, - cur_index, msg_level); - msg_level = -1; - start_print = cur_index; - break; - } + /* + * printk() has already given us loglevel tags in + * the buffer. This code is here in case the + * log buffer has wrapped right round and scribbled + * on those tags + */ + msg_level = default_message_loglevel; + } + _call_console_drivers(con, start_print, cur_index, msg_level); + msg_level = -1; + start_print = cur_index; + break; + } } } _call_console_drivers(con, start_print, end, msg_level); @@ -373,100 +364,116 @@ static void emit_log_char(char c) { LOG_BUF(log_end) = c; - log_end++; - if (log_end - log_start > LOG_BUF_LEN) - log_start = log_end - LOG_BUF_LEN; + log_end++; + if (log_end - log_start > LOG_BUF_LEN) + log_start = log_end - LOG_BUF_LEN; if (log_end - con_start > LOG_BUF_LEN) - con_start = log_end - LOG_BUF_LEN; - if (logged_chars < LOG_BUF_LEN) - logged_chars++; + con_start = log_end - LOG_BUF_LEN; + if (logged_chars < LOG_BUF_LEN) + logged_chars++; } +/* + * This is printk. It can be called from any context. We want it to work. + * + * We try to grab the console_sem. If we succeed, it's easy - we log the output and + * call the console drivers. If we fail to get the semaphore we place the output + * into the log buffer and return. The current holder of the console_sem will + * notice the new output in release_console_sem() and will send it to the + * consoles before releasing the semaphore. + * + * One effect of this deferred printing is that code which calls printk() and + * then changes console_loglevel may break. This is because console_loglevel + * is inspected when the actual printing occurs. + */ asmlinkage int printk(const char *fmt, ...) { static struct { - char buf[1024]; - unsigned long semi_random; + char buf[1024]; + unsigned long semi_random; } printk_buf; - static int log_level_unknown = 1; - struct tty_driver *driver; - unsigned long sr_copy; - unsigned long flags; - struct console *con; - int printed_len; - va_list args; + static int log_level_unknown = 1; + struct tty_driver *driver; + unsigned long sr_copy; + unsigned long flags; + struct console *con; + int printed_len; + va_list args; char *p; if (oops_in_progress) { /* If a crash is occurring, make sure we can't deadlock */ spin_lock_init(&logbuf_lock); - /* And make sure that we print immediately */ + spin_lock_init(&console_lock); } /* This stops the holder of console_sem just where we want him */ spin_lock_irqsave(&logbuf_lock, flags); + /* Emit the output into the temporary buffer */ printk_buf.semi_random += jiffies; sr_copy = printk_buf.semi_random; va_start(args, fmt); - printed_len = vsprintf(printk_buf.buf, fmt, args); + printed_len = vsnprintf(printk_buf.buf, sizeof(printk_buf.buf), fmt, args); va_end(args); - - if (sr_copy != printk_buf.semi_random) + + if (sr_copy != printk_buf.semi_random) panic("buffer overrun in printk()"); - /* - * Copy the output into log_buf. If the caller didn't provide - * appropriate log level tags, we insert them here - */ + /* + * Copy the output into log_buf. If the caller didn't provide + * appropriate log level tags, we insert them here + */ for (p = printk_buf.buf; *p; p++) { - if (log_level_unknown) { - if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { + if (log_level_unknown) { + if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { emit_log_char('<'); - emit_log_char(default_message_loglevel + '0'); - emit_log_char('>'); - } - log_level_unknown = 0; - } - emit_log_char(*p); - if (*p == '\n') + emit_log_char(default_message_loglevel + '0'); + emit_log_char('>'); + } + log_level_unknown = 0; + } + emit_log_char(*p); + if (*p == '\n') log_level_unknown = 1; } spin_unlock_irqrestore(&logbuf_lock, flags); - for (con = console_drivers; con; con = con->next) { - if ((con->flags & CON_ENABLED) && con->write) { + spin_lock(&console_lock); + for (con = console_drivers; con; con = con->next) { + /* + * We own the drivers list. We can drop the lock and + * let release_console_sem() print the text + */ + if ((con->flags & CON_ENABLED) && con->write) { driver = get_tty_driver(con->device(con)); - if (driver && !down_trylock(&driver->tty_lock)) + if (driver && !down_trylock(&driver->tty_lock)) { + driver->may_schedule = 0; release_console_sem(con->device(con)); + } } } + spin_unlock(&console_lock); return printed_len; } EXPORT_SYMBOL(printk); -void console_print(const char *s) -{ - printk(KERN_EMERG "%s", s); -} -EXPORT_SYMBOL(console_print); - /** * acquire_console_sem - lock the console system for exclusive use. * * Acquires a semaphore which guarantees that the caller has - * exclusive access to the console display being drawn to. + * exclusive access to a console system. * * Can sleep, returns nothing. */ void acquire_console_sem(kdev_t device) { struct tty_driver *driver = get_tty_driver(device); - + if (in_interrupt()) - BUG(); - down(&driver->tty_lock); - //console_may_schedule = 1; + BUG(); + down(&driver->tty_lock); + driver->may_schedule = 1; } EXPORT_SYMBOL(acquire_console_sem); @@ -488,42 +495,67 @@ { struct tty_driver *driver = get_tty_driver(device); unsigned long _con_start, _log_end; - unsigned long must_wake_klogd = 0; + unsigned long must_wake_klogd = 0; unsigned long flags; struct console *con; if (driver->flags & TTY_DRIVER_CONSOLE) { - /* Look for new messages */ + spin_lock(&console_lock); + /* Look for new messages */ for (con = console_drivers; con; con = con->next) { if (con->device(con) == device) break; - } - + } + spin_unlock(&console_lock); + for ( ; ; ) { - spin_lock_irqsave(&logbuf_lock, flags); - must_wake_klogd |= log_start - log_end; - if (con_start == log_end) - break; /* Nothing to print */ - _con_start = con_start; - _log_end = log_end; - con_start = log_end; /* Flush */ - spin_unlock_irqrestore(&logbuf_lock, flags); - call_console_drivers(con, _con_start, _log_end); + spin_lock_irqsave(&logbuf_lock, flags); + must_wake_klogd |= log_start - log_end; + if (con_start == log_end) + break; /* Nothing to print */ + _con_start = con_start; + _log_end = log_end; + con_start = log_end; /* Flush */ + spin_unlock_irqrestore(&logbuf_lock, flags); + call_console_drivers(con, _con_start, _log_end); } - spin_unlock_irqrestore(&logbuf_lock, flags); - if (must_wake_klogd && !oops_in_progress) - wake_up_interruptible(&log_wait); + spin_unlock_irqrestore(&logbuf_lock, flags); + if (must_wake_klogd && !oops_in_progress) + wake_up_interruptible(&log_wait); } - up(&driver->tty_lock); + driver->may_schedule = 0; + up(&driver->tty_lock); } +/** console_conditional_schedule - yield the CPU if required + * + * If the console code is currently allowed to sleep, and + * if this CPU should yield the CPU to another task, do + * so here. + * + * Must be called within acquire_console_sem(). + */ +void console_conditional_schedule(struct tty_driver *driver) +{ + if (driver->may_schedule && current->need_resched) { + set_current_state(TASK_RUNNING); + schedule(); + } +} + +void console_print(const char *s) +{ + printk(KERN_EMERG "%s", s); +} +EXPORT_SYMBOL(console_print); + /* * The console driver calls this routine during kernel initialization * to register the console printing procedure with printk() and to * print any messages that were printed by the kernel before the * console driver was initialized. */ -void register_console(struct console *console) +void register_console(struct console * console) { struct tty_driver *driver; unsigned long flags; @@ -573,25 +605,26 @@ * Put this console in the list - keep the * preferred driver at the head of the list. */ - down(&console_sem); + spin_lock(&console_lock); if ((console->flags & CON_CONSDEV) || console_drivers == NULL) { console->next = console_drivers; console_drivers = console; } else { console->next = console_drivers->next; console_drivers->next = console; - } - driver = get_tty_driver(console->device(console)); - if (driver) { - init_MUTEX(&driver->tty_lock); - driver->flags |= TTY_DRIVER_CONSOLE; } - up(&console_sem); - if (console->flags & CON_PRINTBUFFER) { + spin_unlock(&console_lock); + + driver = get_tty_driver(console->device(console)); + if (driver) { + init_MUTEX(&driver->tty_lock); + driver->flags |= TTY_DRIVER_CONSOLE; + } + + if (console->flags & CON_PRINTBUFFER) { /* - * release_cosole_sem() will print out the buffered - * messages for us. - */ + * release_console_sem() will print out the buffered messages for us. + */ spin_lock_irqsave(&logbuf_lock, flags); con_start = log_start; spin_unlock_irqrestore(&logbuf_lock, flags); @@ -600,15 +633,16 @@ } EXPORT_SYMBOL(register_console); -int unregister_console(struct console *console) +int unregister_console(struct console * console) { struct tty_driver *driver = get_tty_driver(console->device(console)); struct console *a,*b; int res = 1; - down(&console_sem); if (driver) release_console_sem(console->device(console)); + + spin_lock(&console_lock); if (console_drivers == console) { console_drivers=console->next; res = 0; @@ -629,14 +663,16 @@ */ if (console_drivers == NULL) preferred_console = -1; - up(&console_sem); + + spin_unlock(&console_lock); return res; } EXPORT_SYMBOL(unregister_console); -/* - * Write a message to a certain tty, not just the console. This is used for - * messages that need to be redirected to a specific tty. +/** + * tty_write_message - write a message to a certain tty, not just the console. + * + * This is used for messages that need to be redirected to a specific tty. * We don't put it into the syslog queue right now maybe in the future if * really needed. */ |
From: James S. <jsi...@us...> - 2001-10-08 04:27:17
|
Update of /cvsroot/linuxconsole/ruby/linux/include/linux In directory usw-pr-cvs1:/tmp/cvs-serv24972 Modified Files: tty_driver.h Log Message: Added may_schedule field. From Andrew Morton's console sem patch. I feel it is much better to allow any TTY device the ability to conditional schedule. Especially some serial devices can be just as slow as VESA fb. Index: tty_driver.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/include/linux/tty_driver.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- tty_driver.h 2001/06/02 16:40:03 1.2 +++ tty_driver.h 2001/10/08 04:27:13 1.3 @@ -129,6 +129,7 @@ short subtype; /* subtype of tty driver */ struct termios init_termios; /* Initial termios */ int flags; /* tty driver flags */ + int may_schedule; /* when we can schedule */ int *refcount; /* for loadable tty drivers */ struct semaphore tty_lock;/* access control for printk and tty layer */ struct proc_dir_entry *proc_entry; /* /proc fs entry */ |
From: James S. <jsi...@us...> - 2001-10-08 02:27:12
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv5943 Modified Files: vesafb.c Log Message: Removed a compile warning. Index: vesafb.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/vesafb.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- vesafb.c 2001/05/06 00:05:28 1.16 +++ vesafb.c 2001/10/08 02:27:09 1.17 @@ -203,7 +203,7 @@ if (!options || !*options) return 0; - while (this_opt = strsep(&options, ",")) { + while ((this_opt = strsep(&options, ","))) { if (!*this_opt) continue; if (! strcmp(this_opt, "inverse")) |
From: James S. <jsi...@us...> - 2001-10-08 02:26:22
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video/tdfx In directory usw-pr-cvs1:/tmp/cvs-serv5728 Modified Files: 3dfxfb.c Log Message: Synced up to the standard tree by adding in the pci_register code. Index: 3dfxfb.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/tdfx/3dfxfb.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- 3dfxfb.c 2001/06/07 06:18:11 1.12 +++ 3dfxfb.c 2001/10/08 02:26:20 1.13 @@ -18,6 +18,11 @@ * Voodoo3 support was contributed Harold Oga. Lots of additions * (proper acceleration, 24 bpp, hardware cursor) and bug fixes by Attila * Kesmarki. Thanks guys! + * + * Voodoo1 and Voodoo2 support aren't relevant to this driver as they + * behave very differently from the Voodoo3/4/5. For anyone wanting to + * use frame buffer on the Voodoo1/2, see the sstfb driver (which is + * located at http://www.sourceforge.net/projects/sstfb). * * While I _am_ grateful to 3Dfx for releasing the specs for Banshee, * I do wish the next version is a bit more complete. Without the XF86 @@ -32,9 +37,6 @@ * TODO: * - support for 16/32 bpp needs fixing (funky bootup penguin) * - multihead support (basically need to support an array of fb_infos) - * - banshee and voodoo3 now supported -- any others? afaik, the original - * voodoo was a 3d-only card, so we won't consider that. what about - * voodoo2? * - support other architectures (PPC, Alpha); does the fact that the VGA * core can be accessed only thru I/O (not memory mapped) complicate * things? @@ -105,6 +107,34 @@ }; /* + * PCI driver prototypes + */ +static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id); +static void tdfxfb_remove(struct pci_dev *pdev); + +static struct pci_device_id tdfxfb_id_table[] __devinitdata = { + { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE, + PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, + 0xff0000, 0 }, + { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3, + PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, + 0xff0000, 0 }, + { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5, + PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, + 0xff0000, 0 }, + { 0, } +}; + +static struct pci_driver tdfxfb_driver = { + name: "tdfxfb", + id_table: tdfxfb_id_table, + probe: tdfxfb_probe, + remove: tdfxfb_remove, +}; + +MODULE_DEVICE_TABLE(pci, tdfxfb_id_table); + +/* * Frame buffer device API */ int tdfxfb_init(void); @@ -124,8 +154,6 @@ unsigned int width, unsigned int height, int dx, int dy); static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image); -static int tdfxfb_ioctl(struct inode* inode, struct file *file, u_int cmd, - u_long arg, struct fb_info *info); static struct fb_ops tdfxfb_ops = { owner: THIS_MODULE, @@ -138,7 +166,6 @@ fb_fillrect: tdfxfb_fillrect, fb_copyarea: tdfxfb_copyarea, fb_imageblit: tdfxfb_imageblit, - fb_ioctl: tdfxfb_ioctl, }; /* @@ -161,7 +188,7 @@ static int nowrap = 1; // not implemented (yet) static int inverse = 0; static int nohwcursor = 0; -static const char *mode_option __initdata = NULL; +static char *mode_option __initdata = NULL; /* ------------------------------------------------------------------------- * Hardware-specific funcions @@ -1077,21 +1104,6 @@ banshee_wait_idle(); } -static int tdfxfb_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg, struct fb_info *info) -{ -/* These IOCTLs ar just for testing only... - switch (cmd) { - case 0x4680: - nowrap=nopan=0; - return 0; - case 0x4681: - nowrap=nopan=1; - return 0; - }*/ - return -EINVAL; -} - static void tdfxfb_hwcursor_init(struct fb_info *info) { unsigned int start; @@ -1103,15 +1115,18 @@ info->cursor.image); } -int __init tdfxfb_init(void) +/** + * tdfxfb_probe - Device Initializiation + * + * @pdev: PCI Device to initialize + * @id: PCI Device ID + * + * Initializes and allocates resources for PCI device @pdev. + * + */ +static int __devinit tdfxfb_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { - struct pci_dev *pdev = NULL; - - while ((pdev = pci_find_device(PCI_VENDOR_ID_3DFX, PCI_ANY_ID, pdev))) { - if(((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && - ((pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE) || - (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO3) || - (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO5))) { /* Configure the default fb_fix_screeninfo first */ memset(&fb_info, 0, sizeof(fb_info)); fb_info.par = &default_par; @@ -1189,27 +1204,36 @@ printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), fb_info.fix.id); - } - } - return 0; + return 0; } /** - * tdfxfb_exit - Driver cleanup + * tdfxfb_remove - Device removal * - * Releases all resources allocated during the - * course of the driver's lifetime. + * @pdev: PCI Device to cleanup * - * FIXME - do results of fb_alloc_cmap need disposal? + * Releases all resources allocated during the course of the driver's + * lifetime for the PCI device @pdev. + * */ -static void __exit tdfxfb_exit (void) +static void __devexit tdfxfb_remove(struct pci_dev *pdev) { struct tdfx_par *par = (struct tdfx_par *) fb_info.par; unregister_framebuffer(&fb_info); - del_timer_sync(&par->hwcursor.timer); + //del_timer_sync(&par->hwcursor.timer); iounmap(par->regbase_virt); iounmap(fb_info.screen_base); +} + +int __init tdfxfb_init(void) +{ + return pci_module_init(&tdfxfb_driver); +} + +static void __exit tdfxfb_exit(void) +{ + pci_unregister_driver(&tdfxfb_driver); } MODULE_AUTHOR("Hannu Mallat <hm...@cc...>"); |
From: James S. <jsi...@us...> - 2001-10-08 02:25:19
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv5592 Modified Files: fbmem.c Log Message: Made the penguin logo come back. It works even for stand alone fbdev systems. Hey this way you know if it worked. Index: fbmem.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/fbmem.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- fbmem.c 2001/10/06 16:11:13 1.50 +++ fbmem.c 2001/10/08 02:25:16 1.51 @@ -775,7 +775,7 @@ } #endif -static void __init fbcon_show_logo(struct fb_info *info) +static void fbcon_show_logo(struct fb_info *info) { u16 palette_red[16], palette_green[16], palette_blue[16]; int depth = info->var.bits_per_pixel; @@ -885,7 +885,7 @@ printk("%s: MTRR turned on\n", fb_info->fix.id); } #endif - + fbcon_show_logo(fb_info); return 0; } |
From: James S. <jsi...@us...> - 2001-10-08 02:24:01
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv5311 Modified Files: Config.in Log Message: Oops. Small config error with SiS. Index: Config.in =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/Config.in,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- Config.in 2001/10/06 16:11:13 1.49 +++ Config.in 2001/10/08 02:23:57 1.50 @@ -168,6 +168,7 @@ bool ' 3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX bool ' 3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1 fi + tristate ' SIS acceleration (EXPERIMENTAL)' CONFIG_FB_SIS if [ "$CONFIG_FB_SIS" != "n" ]; then bool ' SIS 630/540/730 support' CONFIG_FB_SIS_300 bool ' SIS 315H/315 support' CONFIG_FB_SIS_315 |
From: johann d. <jd...@us...> - 2001-10-07 19:29:11
|
Update of /cvsroot/linuxconsole/ruby/utils In directory usw-pr-cvs1:/tmp/cvs-serv30954 Modified Files: Tag: iforce-split Makefile ffcfstress.c ffmvforce.c fftest.c Log Message: Reflected the change of the ff_effect structure (the "direction" member was moved out of the union, as every effect type used it). Index: Makefile =================================================================== RCS file: /cvsroot/linuxconsole/ruby/utils/Makefile,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -u -d -r1.10 -r1.10.2.1 --- Makefile 2001/10/03 08:35:19 1.10 +++ Makefile 2001/10/07 19:29:08 1.10.2.1 @@ -41,7 +41,7 @@ $(RM) *.o *.swp $(PROGRAMS) *.orig *.rej map *~ ffcfstress: ffcfstress.c - $(CC) -O2 -mcpu=pentiumpro -fno-implement-inlines -funsigned-char \ + $(CC) -O2 -fno-implement-inlines -funsigned-char \ -lm ffcfstress.c -o ffcfstress ffmvforce.o: ffmvforce.c Index: ffcfstress.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/utils/ffcfstress.c,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -d -r1.1 -r1.1.2.1 --- ffcfstress.c 2001/10/02 17:47:28 1.1 +++ ffcfstress.c 2001/10/07 19:29:08 1.1.2.1 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/input.h> +#include "../linux/include/linux/input.h" #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> @@ -186,7 +186,7 @@ effect.replay.length=0xffff; effect.replay.delay=0; effect.u.constant.level=0; - effect.u.constant.direction=0xC000; + effect.direction=0xC000; effect.u.constant.shape.attack_length=0; effect.u.constant.shape.attack_level=0; effect.u.constant.shape.fade_length=0; @@ -231,7 +231,7 @@ if (force>1.0) force=1.0; if (force<-1.0) force=1.0; effect.u.constant.level=(short)(force*32767.0); /* only to be safe */ - effect.u.constant.direction=0xC000; + effect.direction=0xC000; effect.u.constant.shape.attack_level=(short)(force*32767.0); /* this one counts! */ effect.u.constant.shape.fade_level=(short)(force*32767.0); /* only to be safe */ Index: ffmvforce.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/utils/ffmvforce.c,v retrieving revision 1.8 retrieving revision 1.8.2.1 diff -u -d -r1.8 -r1.8.2.1 --- ffmvforce.c 2001/10/02 18:27:59 1.8 +++ ffmvforce.c 2001/10/07 19:29:08 1.8.2.1 @@ -77,8 +77,8 @@ printf("mouse: %d %d n: %4.2f %4.2f angle: %4.2f\n", x, y, nx, ny, angle); effect.type = FF_CONSTANT; effect.u.constant.level = 0x7fff * max(fabs(nx), fabs(ny)); - effect.u.constant.direction = 0x8000 * (angle + M_PI)/M_PI; -printf("level: %04x direction: %04x\n", (unsigned int)effect.u.constant.level, (unsigned int)effect.u.constant.direction); + effect.direction = 0x8000 * (angle + M_PI)/M_PI; +printf("level: %04x direction: %04x\n", (unsigned int)effect.u.constant.level, (unsigned int)effect.direction); effect.u.constant.shape.attack_length = 0; effect.u.constant.shape.attack_level = 0; effect.u.constant.shape.fade_length = 0; Index: fftest.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/utils/fftest.c,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -u -d -r1.11 -r1.11.2.1 --- fftest.c 2001/10/02 18:27:59 1.11 +++ fftest.c 2001/10/07 19:29:08 1.11.2.1 @@ -105,7 +105,7 @@ effects[1].type = FF_CONSTANT; effects[1].id = -1; effects[1].u.constant.level = 0x2000; /* Strength : 25 % */ - effects[1].u.constant.direction = 0x6000; /* 135 degrees */ + effects[1].direction = 0x6000; /* 135 degrees */ effects[1].u.constant.shape.attack_length = 0x100; effects[1].u.constant.shape.attack_level = 0; effects[1].u.constant.shape.fade_length = 0x100; @@ -128,7 +128,7 @@ effects[0].u.periodic.magnitude = 0x4000; /* 0.5 * Maximum magnitude */ effects[0].u.periodic.offset = 0; effects[0].u.periodic.phase = 0; - effects[0].u.periodic.direction = 0x4000; /* Along X axis */ + effects[0].direction = 0x4000; /* Along X axis */ effects[0].u.periodic.shape.attack_length = 0x100; effects[0].u.periodic.shape.attack_level = 0; effects[0].u.periodic.shape.fade_length = 0x100; |
From: johann d. <jd...@us...> - 2001-10-07 19:25:45
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input In directory usw-pr-cvs1:/tmp/cvs-serv30438 Modified Files: Tag: iforce-split iforce-ff.c Log Message: iforce_upload_* now return the correct value. Index: iforce-ff.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/Attic/iforce-ff.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- iforce-ff.c 2001/10/07 17:06:49 1.1.2.1 +++ iforce-ff.c 2001/10/07 19:25:43 1.1.2.2 @@ -41,6 +41,8 @@ { unsigned char data[3]; + printk(KERN_DEBUG "iforce: in make_magnitude_modifier\n"); + if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 2, @@ -350,25 +352,27 @@ struct iforce_core_effect* core_effect = iforce->core_effects + core_id; struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk); struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk); - int err = 1; + int param1_err = 1; + int param2_err = 1; + int core_err = 0; if (!is_update || need_period_modifier(iforce, effect)) { - err = make_period_modifier(iforce, mod1_chunk, + param1_err = make_period_modifier(iforce, mod1_chunk, is_update, effect->u.periodic.magnitude, effect->u.periodic.offset, effect->u.periodic.period, effect->u.periodic.phase); - if (err) return err; + if (param1_err) return param1_err; set_bit(FF_MOD1_IS_USED, core_effect->flags); } if (!is_update || need_shape_modifier(iforce, effect)) { - err = make_shape_modifier(iforce, mod2_chunk, + param2_err = make_shape_modifier(iforce, mod2_chunk, is_update, effect->u.periodic.shape.attack_length, effect->u.periodic.shape.attack_level, effect->u.periodic.shape.fade_length, effect->u.periodic.shape.fade_level); - if (err) return err; + if (param2_err) return param2_err; set_bit(FF_MOD2_IS_USED, core_effect->flags); } @@ -382,7 +386,7 @@ } if (!is_update || need_core(iforce, effect)) { - err = make_core(iforce, effect->id, + core_err = make_core(iforce, effect->id, mod1_chunk->start, mod2_chunk->start, wave_code, @@ -397,7 +401,13 @@ printk(KERN_DEBUG "iforce.c: no effect packet was needed\n"); } - return err; + /* If one of the parameter creation failed, we already returned an + * error code. + * If the core creation failed, we return its error code. + * Else: if one parameter at least was created, we return 0 + * else we return 1; + */ + return core_err < 0 ? core_err : (param1_err && param2_err); } /* @@ -413,31 +423,33 @@ struct iforce_core_effect* core_effect = iforce->core_effects + core_id; struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk); struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk); - int ret = 1; + int param1_err = 1; + int param2_err = 1; + int core_err = 0; printk(KERN_DEBUG "iforce.c: make constant effect\n"); if (!is_update || need_magnitude_modifier(iforce, effect)) { - ret = make_magnitude_modifier(iforce, mod1_chunk, + param1_err = make_magnitude_modifier(iforce, mod1_chunk, is_update, effect->u.constant.level); - if (ret) return ret; + if (param1_err) return param1_err; set_bit(FF_MOD1_IS_USED, core_effect->flags); } if (!is_update || need_shape_modifier(iforce, effect)) { - ret = make_shape_modifier(iforce, mod2_chunk, + param2_err = make_shape_modifier(iforce, mod2_chunk, is_update, effect->u.constant.shape.attack_length, effect->u.constant.shape.attack_level, effect->u.constant.shape.fade_length, effect->u.constant.shape.fade_level); - if (ret) return ret; + if (param2_err) return param2_err; set_bit(FF_MOD2_IS_USED, core_effect->flags); } if (!is_update || need_core(iforce, effect)) { - ret = make_core(iforce, effect->id, + core_err = make_core(iforce, effect->id, mod1_chunk->start, mod2_chunk->start, 0x00, @@ -452,7 +464,13 @@ printk(KERN_DEBUG "iforce.c: no effect packet was needed\n"); } - return ret; + /* If one of the parameter creation failed, we already returned an + * error code. + * If the core creation failed, we return its error code. + * Else: if one parameter at least was created, we return 0 + * else we return 1; + */ + return core_err < 0 ? core_err : (param1_err && param2_err); } /* @@ -465,7 +483,8 @@ struct resource* mod_chunk = &(core_effect->mod1_chunk); u8 type, axes; u16 mod1, mod2, direction; - int err = 1; + int param_err = 1; + int core_err = 0; printk(KERN_DEBUG "iforce.c: make interactive effect\n"); @@ -476,7 +495,7 @@ } if (!is_update || need_interactive_modifier(iforce, effect)) { - err = make_interactive_modifier(iforce, mod_chunk, + param_err = make_interactive_modifier(iforce, mod_chunk, is_update, effect->u.interactive.right_saturation, effect->u.interactive.left_saturation, @@ -484,7 +503,7 @@ effect->u.interactive.left_coeff, effect->u.interactive.deadband, effect->u.interactive.center); - if (err) return err; + if (param_err) return param_err; set_bit(FF_MOD1_IS_USED, core_effect->flags); } @@ -526,7 +545,7 @@ } if (!is_update || need_core(iforce, effect)) { - err = make_core(iforce, effect->id, + core_err = make_core(iforce, effect->id, mod1, mod2, type, axes, effect->replay.length, effect->replay.delay, @@ -534,5 +553,11 @@ direction); } - return err; + /* If the parameter creation failed, we already returned an + * error code. + * If the core creation failed, we return its error code. + * Else: if a parameter was created, we return 0 + * else we return 1; + */ + return core_err < 0 ? core_err : param_err; } |
From: johann d. <jd...@us...> - 2001-10-07 19:25:05
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input In directory usw-pr-cvs1:/tmp/cvs-serv30231 Modified Files: Tag: iforce-split iforce-packets.c Log Message: Restart an effect that stopped early. This happens when we send core effect parameters for updated effects. Index: iforce-packets.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/Attic/iforce-packets.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- iforce-packets.c 2001/10/07 17:06:49 1.1.2.1 +++ iforce-packets.c 2001/10/07 19:25:03 1.1.2.2 @@ -209,6 +209,7 @@ } else { printk(KERN_WARNING "iforce.c: effect %d stopped, while it should not\nStarting again\n", i); + input_report_ff(dev, i, 1); } } if (LO(cmd) > 3) { |
From: James S. <jsi...@us...> - 2001-10-07 17:16:08
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv8534 Modified Files: vgacon.c Log Message: Added sched.h to vgacon to deal with issues compiling on some machines. Index: vgacon.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/video/vgacon.c,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- vgacon.c 2001/10/04 02:45:52 1.55 +++ vgacon.c 2001/10/07 17:16:06 1.56 @@ -37,6 +37,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> +#include <linux/sched.h> #include <linux/tty.h> #include <linux/string.h> #include <linux/kd.h> |
From: johann d. <jd...@us...> - 2001-10-07 17:06:52
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input In directory usw-pr-cvs1:/tmp/cvs-serv6680 Modified Files: Tag: iforce-split Makefile Added Files: Tag: iforce-split iforce-ff.c iforce-main.c iforce-packets.c iforce-serio.c iforce-usb.c iforce.h Removed Files: Tag: iforce-split iforce.c Log Message: Split iforce.c into several smaller files. --- NEW FILE: iforce-ff.c --- /* * $Id: iforce-ff.c,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include "iforce.h" /* * Set the magnitude of a constant force effect * Return error code * * Note: caller must ensure exclusive access to device */ static int make_magnitude_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __s16 level) { unsigned char data[3]; if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 2, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = HIFIX80(level); iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data); iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data); return 0; } /* * Upload the component of an effect dealing with the period, phase and magnitude */ static int make_period_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __s16 magnitude, __s16 offset, u16 period, u16 phase) { unsigned char data[7]; period = TIME_SCALE(period); if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = HIFIX80(magnitude); data[3] = HIFIX80(offset); data[4] = HI(phase); data[5] = LO(period); data[6] = HI(period); iforce_send_packet(iforce, FF_CMD_PERIOD, data); return 0; } /* * Uploads the part of an effect setting the shape of the force */ static int make_shape_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, u16 attack_duration, __s16 initial_level, u16 fade_duration, __s16 final_level) { unsigned char data[8]; attack_duration = TIME_SCALE(attack_duration); fade_duration = TIME_SCALE(fade_duration); if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = LO(attack_duration); data[3] = HI(attack_duration); data[4] = HIFIX80(initial_level); data[5] = LO(fade_duration); data[6] = HI(fade_duration); data[7] = HIFIX80(final_level); iforce_send_packet(iforce, FF_CMD_SHAPE, data); return 0; } /* * Component of spring, friction, inertia... effects */ static int make_interactive_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __s16 rsat, __s16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center) { unsigned char data[10]; if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 8, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = HIFIX80(rk); data[3] = HIFIX80(lk); data[4] = LO(center); data[5] = HI(center); data[6] = LO(db); data[7] = HI(db); data[8] = HIFIX80(rsat); data[9] = HIFIX80(lsat); iforce_send_packet(iforce, FF_CMD_INTERACT, data); return 0; } static unsigned char find_button(struct iforce *iforce, signed short button) { int i; for (i = 1; iforce->type->btn[i] >= 0; i++) if (iforce->type->btn[i] == button) return i + 1; return 0; } /* * Analyse the changes in an effect, and tell if we need to send an interactive * parameter packet */ static int need_interactive_modifier(struct iforce* iforce, struct ff_effect* new) { int id = new->id; struct ff_effect* old = &iforce->core_effects[id].effect; if (new->type != FF_SPRING && new->type != FF_FRICTION) { printk(KERN_WARNING "iforce.c: bad effect type in need_interactive_modifier\n"); return FALSE; } return (old->u.interactive.right_saturation != new->u.interactive.right_saturation || old->u.interactive.left_saturation != new->u.interactive.left_saturation || old->u.interactive.right_coeff != new->u.interactive.right_coeff || old->u.interactive.left_coeff != new->u.interactive.left_coeff || old->u.interactive.deadband != new->u.interactive.deadband || old->u.interactive.center != new->u.interactive.center); } /* * Analyse the changes in an effect, and tell if we need to send a magnitude * parameter packet */ static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect) { int id = effect->id; struct ff_effect* old = &iforce->core_effects[id].effect; if (effect->type != FF_CONSTANT) { printk(KERN_WARNING "iforce.c: bad effect type in need_shape_modifier\n"); return FALSE; } return (old->u.constant.level != effect->u.constant.level); } /* * Analyse the changes in an effect, and tell if we need to send a shape * parameter packet */ static int need_shape_modifier(struct iforce* iforce, struct ff_effect* effect) { int id = effect->id; struct ff_effect* old = &iforce->core_effects[id].effect; switch (effect->type) { case FF_CONSTANT: if (old->u.constant.shape.attack_length != effect->u.constant.shape.attack_length || old->u.constant.shape.attack_level != effect->u.constant.shape.attack_level || old->u.constant.shape.fade_length != effect->u.constant.shape.fade_length || old->u.constant.shape.fade_level != effect->u.constant.shape.fade_level) return TRUE; break; case FF_PERIODIC: if (old->u.periodic.shape.attack_length != effect->u.periodic.shape.attack_length || old->u.periodic.shape.attack_level != effect->u.periodic.shape.attack_level || old->u.periodic.shape.fade_length != effect->u.periodic.shape.fade_length || old->u.periodic.shape.fade_level != effect->u.periodic.shape.fade_level) return TRUE; break; default: printk(KERN_WARNING "iforce.c: bad effect type in need_shape_modifier\n"); } return FALSE; } /* * Analyse the changes in an effect, and tell if we need to send a periodic * parameter effect */ static int need_period_modifier(struct iforce* iforce, struct ff_effect* new) { int id = new->id; struct ff_effect* old = &iforce->core_effects[id].effect; if (new->type != FF_PERIODIC) { printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n"); return FALSE; } return (old->u.periodic.period != new->u.periodic.period || old->u.periodic.magnitude != new->u.periodic.magnitude || old->u.periodic.offset != new->u.periodic.offset || old->u.periodic.phase != new->u.periodic.phase); } /* * Analyse the changes in an effect, and tell if we need to send an effect * packet */ static int need_core(struct iforce* iforce, struct ff_effect* new) { int id = new->id; struct ff_effect* old = &iforce->core_effects[id].effect; if (old->direction != new->direction || old->trigger.button != new->trigger.button || old->trigger.interval != new->trigger.interval || old->replay.length != new->replay.length || old->replay.delay != new->replay.delay) return TRUE; return FALSE; } /* * Send the part common to all effects to the device */ static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2, u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button, u16 interval, u16 direction) { unsigned char data[14]; duration = TIME_SCALE(duration); delay = TIME_SCALE(delay); interval = TIME_SCALE(interval); data[0] = LO(id); data[1] = effect_type; data[2] = LO(axes) | find_button(iforce, button); data[3] = LO(duration); data[4] = HI(duration); data[5] = HI(direction); data[6] = LO(interval); data[7] = HI(interval); data[8] = LO(mod_id1); data[9] = HI(mod_id1); data[10] = LO(mod_id2); data[11] = HI(mod_id2); data[12] = LO(delay); data[13] = HI(delay); iforce_send_packet(iforce, FF_CMD_EFFECT, data); return 0; } /* * Upload a periodic effect to the device * See also iforce_upload_constant. */ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update) { u8 wave_code; int core_id = effect->id; struct iforce_core_effect* core_effect = iforce->core_effects + core_id; struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk); struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk); int err = 1; if (!is_update || need_period_modifier(iforce, effect)) { err = make_period_modifier(iforce, mod1_chunk, is_update, effect->u.periodic.magnitude, effect->u.periodic.offset, effect->u.periodic.period, effect->u.periodic.phase); if (err) return err; set_bit(FF_MOD1_IS_USED, core_effect->flags); } if (!is_update || need_shape_modifier(iforce, effect)) { err = make_shape_modifier(iforce, mod2_chunk, is_update, effect->u.periodic.shape.attack_length, effect->u.periodic.shape.attack_level, effect->u.periodic.shape.fade_length, effect->u.periodic.shape.fade_level); if (err) return err; set_bit(FF_MOD2_IS_USED, core_effect->flags); } switch (effect->u.periodic.waveform) { case FF_SQUARE: wave_code = 0x20; break; case FF_TRIANGLE: wave_code = 0x21; break; case FF_SINE: wave_code = 0x22; break; case FF_SAW_UP: wave_code = 0x23; break; case FF_SAW_DOWN: wave_code = 0x24; break; default: wave_code = 0x20; break; } if (!is_update || need_core(iforce, effect)) { err = make_core(iforce, effect->id, mod1_chunk->start, mod2_chunk->start, wave_code, 0x20, effect->replay.length, effect->replay.delay, effect->trigger.button, effect->trigger.interval, effect->direction); } else { printk(KERN_DEBUG "iforce.c: no effect packet was needed\n"); } return err; } /* * Upload a constant force effect * Return value: * <0 Error code * 0 Ok, effect created or updated * 1 effect did not change since last upload, and no packet was therefore sent */ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update) { int core_id = effect->id; struct iforce_core_effect* core_effect = iforce->core_effects + core_id; struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk); struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk); int ret = 1; printk(KERN_DEBUG "iforce.c: make constant effect\n"); if (!is_update || need_magnitude_modifier(iforce, effect)) { ret = make_magnitude_modifier(iforce, mod1_chunk, is_update, effect->u.constant.level); if (ret) return ret; set_bit(FF_MOD1_IS_USED, core_effect->flags); } if (!is_update || need_shape_modifier(iforce, effect)) { ret = make_shape_modifier(iforce, mod2_chunk, is_update, effect->u.constant.shape.attack_length, effect->u.constant.shape.attack_level, effect->u.constant.shape.fade_length, effect->u.constant.shape.fade_level); if (ret) return ret; set_bit(FF_MOD2_IS_USED, core_effect->flags); } if (!is_update || need_core(iforce, effect)) { ret = make_core(iforce, effect->id, mod1_chunk->start, mod2_chunk->start, 0x00, 0x20, effect->replay.length, effect->replay.delay, effect->trigger.button, effect->trigger.interval, effect->direction); } else { printk(KERN_DEBUG "iforce.c: no effect packet was needed\n"); } return ret; } /* * Upload an interactive effect. Those are for example friction, inertia, springs... */ int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* effect, int is_update) { int core_id = effect->id; struct iforce_core_effect* core_effect = iforce->core_effects + core_id; struct resource* mod_chunk = &(core_effect->mod1_chunk); u8 type, axes; u16 mod1, mod2, direction; int err = 1; printk(KERN_DEBUG "iforce.c: make interactive effect\n"); switch (effect->type) { case FF_SPRING: type = 0x40; break; case FF_FRICTION: type = 0x41; break; default: return -1; } if (!is_update || need_interactive_modifier(iforce, effect)) { err = make_interactive_modifier(iforce, mod_chunk, is_update, effect->u.interactive.right_saturation, effect->u.interactive.left_saturation, effect->u.interactive.right_coeff, effect->u.interactive.left_coeff, effect->u.interactive.deadband, effect->u.interactive.center); if (err) return err; set_bit(FF_MOD1_IS_USED, core_effect->flags); } switch ((test_bit(ABS_X, &effect->u.interactive.axis) || test_bit(ABS_WHEEL, &effect->u.interactive.axis)) | (!!test_bit(ABS_Y, &effect->u.interactive.axis) << 1)) { case 0: /* Only one axis, choose orientation */ mod1 = mod_chunk->start; mod2 = 0xffff; direction = effect->direction; axes = 0x20; break; case 1: /* Only X axis */ mod1 = mod_chunk->start; mod2 = 0xffff; direction = 0x5a00; axes = 0x40; break; case 2: /* Only Y axis */ mod1 = 0xffff; mod2 = mod_chunk->start; direction = 0xb400; axes = 0x80; break; case 3: /* Both X and Y axes */ /* TODO: same setting for both axes is not mandatory */ mod1 = mod_chunk->start; mod2 = mod_chunk->start; direction = 0x6000; axes = 0xc0; break; default: return -1; } if (!is_update || need_core(iforce, effect)) { err = make_core(iforce, effect->id, mod1, mod2, type, axes, effect->replay.length, effect->replay.delay, effect->trigger.button, effect->trigger.interval, direction); } return err; } --- NEW FILE: iforce-main.c --- /* * $Id: iforce-main.c,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include "iforce.h" #include "usbpath.h" MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>, Johann Deneux <de...@if...>"); MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); MODULE_LICENSE("GPL"); static signed short btn_joystick[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, BTN_DEAD, -1 }; static signed short btn_wheel[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 }; static signed short btn_avb_tw[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 }; static signed short abs_joystick[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; static signed short abs_joystick2[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 }; static signed short abs_wheel[] = { ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, -1 }; static signed short ff_iforce[] = { FF_PERIODIC, FF_CONSTANT, FF_SPRING, FF_FRICTION, FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP, FF_SAW_DOWN, FF_GAIN, FF_AUTOCENTER, -1 }; static struct iforce_device iforce_device[] = { { 0x044f, 0xa01c, "Thrustmaster Motor Sport GT", btn_wheel, abs_wheel, ff_iforce }, { 0x046d, 0xc281, "Logitech WingMan Force", btn_joystick, abs_joystick, ff_iforce }, { 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce }, { 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_joystick, abs_joystick2, ff_iforce }, { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_wheel, abs_wheel, ff_iforce }, { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } }; static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct iforce* iforce = (struct iforce*)(dev->private); unsigned char data[3]; printk(KERN_DEBUG "iforce.c: input_event(type = %d, code = %d, value = %d)\n", type, code, value); if (type != EV_FF) return -1; switch (code) { case FF_GAIN: data[0] = value >> 9; iforce_send_packet(iforce, FF_CMD_GAIN, data); return 0; case FF_AUTOCENTER: data[0] = 0x03; data[1] = value >> 9; iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data); data[0] = 0x04; data[1] = 0x01; iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data); return 0; default: /* Play or stop an effect */ if (!CHECK_OWNERSHIP(code, iforce)) { return -1; } if (value > 0) { set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags); } else { clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags); } data[0] = LO(code); data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0; data[2] = LO(value); iforce_send_packet(iforce, FF_CMD_PLAY, data); return 0; } return -1; } /* * Function called when an ioctl is performed on the event dev entry. * It uploads an effect to the device */ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) { struct iforce* iforce = (struct iforce*)(dev->private); int id; int ret; int is_update; printk(KERN_DEBUG "iforce.c: upload effect\n"); /* * If we want to create a new effect, get a free id */ if (effect->id == -1) { for (id=0; id < FF_EFFECTS_MAX; ++id) if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break; if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max) return -ENOMEM; effect->id = id; iforce->core_effects[id].owner = current->pid; iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED); /* Only IS_USED bit must be set */ is_update = FALSE; } else { /* We want to update an effect */ if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES; /* Parameter type cannot be updated */ if (effect->type != iforce->core_effects[effect->id].effect.type) return -EINVAL; /* Check the effect is not already being updated */ if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) { printk(KERN_DEBUG "iforce.c: update too frequent refused\n"); return -EAGAIN; } is_update = TRUE; } /* * Upload the effect */ switch (effect->type) { case FF_PERIODIC: ret = iforce_upload_periodic(iforce, effect, is_update); break; case FF_CONSTANT: ret = iforce_upload_constant(iforce, effect, is_update); break; case FF_SPRING: case FF_FRICTION: ret = iforce_upload_interactive(iforce, effect, is_update); break; default: return -EINVAL; } if (ret == 0) { /* A packet was sent, forbid new updates until we are notified * that the packet was updated */ set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags); } iforce->core_effects[effect->id].effect = *effect; return ret; } /* * Erases an effect: it frees the effect id and mark as unused the memory * allocated for the parameters */ static int iforce_erase_effect(struct input_dev *dev, int effect_id) { struct iforce* iforce = (struct iforce*)(dev->private); int err = 0; struct iforce_core_effect* core_effect; /* Check who is trying to erase this effect */ if (iforce->core_effects[effect_id].owner != current->pid) { printk(KERN_WARNING "iforce.c: %d tried to erase an effect belonging to %d\n", current->pid, iforce->core_effects[effect_id].owner); return -EACCES; } printk(KERN_DEBUG "iforce.c: erase effect %d\n", effect_id); if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX) return -EINVAL; core_effect = iforce->core_effects + effect_id; if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk)); if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk)); /*TODO: remember to change that if more FF_MOD* bits are added */ core_effect->flags[0] = 0; return err; } static int iforce_open(struct input_dev *dev) { struct iforce *iforce = dev->private; switch (iforce->bus) { #ifdef IFORCE_USB case IFORCE_USB: if (iforce->open++) break; iforce->irq.dev = iforce->usbdev; if (usb_submit_urb(&iforce->irq)) return -EIO; break; #endif } /* Reset device */ iforce_send_packet(iforce, FF_CMD_ENABLE, "\004"); return 0; } static int iforce_flush(struct input_dev *dev, struct file *file) { struct iforce *iforce = dev->private; int i; /* Erase all effects this process owns */ for (i=0; i<dev->ff_effects_max; ++i) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && current->pid == iforce->core_effects[i].owner) { /* Stop effect */ iforce_input_event(dev, EV_FF, i, 0); /* Free ressources assigned to effect */ if (iforce_erase_effect(dev, i)) { printk(KERN_WARNING "iforce_flush: (%s) erase effect %d failed\n", dev->phys, i); } } } return 0; } static void iforce_close(struct input_dev *dev) { struct iforce *iforce = dev->private; printk(KERN_DEBUG "iforce.c: in iforce_close\n"); /* Disable force feedback playback */ iforce_send_packet(iforce, FF_CMD_ENABLE, "\001"); switch (iforce->bus) { #ifdef IFORCE_USB case IFORCE_USB: if (!--iforce->open) usb_unlink_urb(&iforce->irq); break; #endif } } int iforce_init_device(struct iforce *iforce) { unsigned char c[] = "CEOV"; char path[64]; int i; init_waitqueue_head(&iforce->wait); spin_lock_init(&iforce->xmit_lock); init_MUTEX(&iforce->mem_mutex); iforce->xmit.buf = iforce->xmit_data; iforce->dev.ff_effects_max = 10; switch (iforce->bus) { #ifdef IFORCE_232 case IFORCE_232: strcpy(path, iforce->serio->phys); break; #endif #ifdef IFORCE_USB case IFORCE_USB: usb_make_path(iforce->usbdev, path, 64); break; #endif } sprintf(iforce->phys, "%s/input0", path); /* * Input device fields. */ iforce->dev.idbus = BUS_USB; iforce->dev.private = iforce; iforce->dev.name = iforce->name; iforce->dev.name = iforce->phys; iforce->dev.open = iforce_open; iforce->dev.close = iforce_close; iforce->dev.flush = iforce_flush; iforce->dev.event = iforce_input_event; iforce->dev.upload_effect = iforce_upload_effect; iforce->dev.erase_effect = iforce_erase_effect; /* * On-device memory allocation. */ iforce->device_memory.name = "I-Force device effect memory"; iforce->device_memory.start = 0; iforce->device_memory.end = 200; iforce->device_memory.flags = IORESOURCE_MEM; iforce->device_memory.parent = NULL; iforce->device_memory.child = NULL; iforce->device_memory.sibling = NULL; /* * Wait until device ready - until it sends its first response. */ for (i = 0; i < 20; i++) if (!iforce_get_id_packet(iforce, "O")) break; if (i == 20) { /* 5 seconds */ printk(KERN_ERR "iforce.c: Timeout waiting for response from device.\n"); iforce_close(&iforce->dev); return -1; } /* * Get device info. */ if (!iforce_get_id_packet(iforce, "M")) iforce->dev.idvendor = (iforce->edata[2] << 8) | iforce->edata[1]; if (!iforce_get_id_packet(iforce, "P")) iforce->dev.idproduct = (iforce->edata[2] << 8) | iforce->edata[1]; if (!iforce_get_id_packet(iforce, "B")) iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; if (!iforce_get_id_packet(iforce, "N")) iforce->dev.ff_effects_max = iforce->edata[1]; /* Check if the device can store more effects than the driver can really handle */ if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) { printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.c\n", iforce->dev.ff_effects_max, FF_EFFECTS_MAX); iforce->dev.ff_effects_max = FF_EFFECTS_MAX; } /* * Display additional info. */ for (i = 0; c[i]; i++) if (!iforce_get_id_packet(iforce, c + i)) iforce_dump_packet("info", iforce->ecmd, iforce->edata); /* * Disable spring, enable force feedback. * FIXME: We should use iforce_set_autocenter() et al here. */ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000"); /* * Find appropriate device entry */ for (i = 0; iforce_device[i].idvendor; i++) if (iforce_device[i].idvendor == iforce->dev.idvendor && iforce_device[i].idproduct == iforce->dev.idproduct) break; iforce->type = iforce_device + i; sprintf(iforce->name, iforce->type->name, iforce->dev.idproduct, iforce->dev.idvendor); /* * Set input device bitfields and ranges. */ iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS); for (i = 0; iforce->type->btn[i] >= 0; i++) { signed short t = iforce->type->btn[i]; set_bit(t, iforce->dev.keybit); if (t != BTN_DEAD) set_bit(FF_BTN(t), iforce->dev.ffbit); } for (i = 0; iforce->type->abs[i] >= 0; i++) { signed short t = iforce->type->abs[i]; set_bit(t, iforce->dev.absbit); switch (t) { case ABS_X: case ABS_Y: case ABS_WHEEL: iforce->dev.absmax[t] = 1920; iforce->dev.absmin[t] = -1920; iforce->dev.absflat[t] = 128; iforce->dev.absfuzz[t] = 16; set_bit(FF_ABS(t), iforce->dev.ffbit); break; case ABS_THROTTLE: case ABS_GAS: case ABS_BRAKE: iforce->dev.absmax[t] = 255; iforce->dev.absmin[t] = 0; break; case ABS_RUDDER: iforce->dev.absmax[t] = 127; iforce->dev.absmin[t] = -128; break; case ABS_HAT0X: case ABS_HAT0Y: iforce->dev.absmax[t] = 1; iforce->dev.absmin[t] = -1; break; } } for (i = 0; iforce->type->ff[i] >= 0; i++) set_bit(iforce->type->ff[i], iforce->dev.ffbit); /* * Register input device. */ input_register_device(&iforce->dev); printk(KERN_INFO "input: %s [%d effects, %ld bytes memory] on %s\n", iforce->dev.name, iforce->dev.ff_effects_max, iforce->device_memory.end, path); return 0; } static int __init iforce_init(void) { #ifdef IFORCE_USB usb_register(&iforce_usb_driver); #endif #ifdef IFORCE_232 serio_register_device(&iforce_serio_dev); #endif return 0; } static void __exit iforce_exit(void) { #ifdef IFORCE_USB usb_deregister(&iforce_usb_driver); #endif #ifdef IFORCE_232 serio_unregister_device(&iforce_serio_dev); #endif } module_init(iforce_init); module_exit(iforce_exit); --- NEW FILE: iforce-packets.c --- /* * $Id: iforce-packets.c,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include "iforce.h" static struct { __s32 x; __s32 y; } iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) { int i; printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd); for (i = 0; i < LO(cmd); i++) printk("%02x ", data[i]); printk(")\n"); } /* * Send a packet of bytes to the device */ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) { /* Copy data to buffer */ int n = LO(cmd); int c; int empty; int head, tail; unsigned long flags; /* * Update head and tail of xmit buffer */ spin_lock_irqsave(&iforce->xmit_lock, flags); head = iforce->xmit.head; tail = iforce->xmit.tail; if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { printk(KERN_WARNING "iforce.c: not enough space in xmit buffer to send new packet\n"); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return -1; } empty = head == tail; XMIT_INC(iforce->xmit.head, n+2); /* * Store packet in xmit buffer */ iforce->xmit.buf[head] = HI(cmd); XMIT_INC(head, 1); iforce->xmit.buf[head] = LO(cmd); XMIT_INC(head, 1); c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE); if (n < c) c=n; memcpy(&iforce->xmit.buf[head], data, c); if (n != c) { memcpy(&iforce->xmit.buf[0], data + c, n - c); } XMIT_INC(head, n); spin_unlock_irqrestore(&iforce->xmit_lock, flags); /* * If necessary, start the transmission */ switch (iforce->bus) { #ifdef IFORCE_232 case IFORCE_232: if (empty) iforce_serial_xmit(iforce); break; #endif #ifdef IFORCE_USB case IFORCE_USB: if (empty & !iforce->out.status) { iforce_usb_xmit(iforce); } break; #endif } return 0; } /* Mark an effect that was being updated as ready. That means it can be updated * again */ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) { int i; for (i=0; i<iforce->dev.ff_effects_max; ++i) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && (iforce->core_effects[i].mod1_chunk.start == addr || iforce->core_effects[i].mod2_chunk.start == addr)) { clear_bit(FF_CORE_UPDATE, iforce->core_effects[i].flags); printk(KERN_DEBUG "iforce.c: marked effect %d as ready\n", i); return 0; } } printk(KERN_DEBUG "iforce.c: unused effect %04x updated !!!\n", addr); return -1; } void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) { struct input_dev *dev = &iforce->dev; int i; static int being_used = 0; if (being_used) printk(KERN_WARNING "iforce.c: re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef IFORCE_232 if (HI(iforce->expect_packet) == HI(cmd)) { iforce->expect_packet = 0; iforce->ecmd = cmd; memcpy(iforce->edata, data, IFORCE_MAX_LENGTH); if (waitqueue_active(&iforce->wait)) wake_up(&iforce->wait); } #endif if (!iforce->type) { being_used--; return; } switch (HI(cmd)) { case 0x01: /* joystick position data */ case 0x03: /* wheel position data */ if (HI(cmd) == 1) { input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2])); input_report_abs(dev, ABS_THROTTLE, 255 - data[4]); if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit)) input_report_abs(dev, ABS_RUDDER, (__s8)data[7]); } else { input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_GAS, 255 - data[2]); input_report_abs(dev, ABS_BRAKE, 255 - data[3]); } input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x); input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y); for (i = 0; iforce->type->btn[i] >= 0; i++) input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7))); break; case 0x02: /* status report */ input_report_key(dev, BTN_DEAD, data[0] & 0x02); /* Check if an effect was just started or stopped */ i = data[1] & 0x7f; if (data[1] & 0x80) { if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report play event */ input_report_ff_status(dev, i, FF_STATUS_PLAYING); printk(KERN_DEBUG "iforce.c: effect %d started to play\n", i); } } else { if (!test_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[i].flags)) { if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report stop event */ input_report_ff_status(dev, i, FF_STATUS_STOPPED); printk(KERN_DEBUG "iforce.c: effect %d stopped to play\n", i); } } else { printk(KERN_WARNING "iforce.c: effect %d stopped, while it should not\nStarting again\n", i); } } if (LO(cmd) > 3) { int j; for (j=3; j<LO(cmd); j+=2) { if (mark_core_as_ready(iforce, data[j] | (data[j+1]<<8))) iforce_dump_packet("ff status", cmd, data); } } break; } being_used--; } int iforce_get_id_packet(struct iforce *iforce, char *packet) { DECLARE_WAITQUEUE(wait, current); int timeout = HZ; /* 1 second */ switch (iforce->bus) { #ifdef IFORCE_USB case IFORCE_USB: iforce->dr.request = packet[0]; iforce->ctrl.dev = iforce->usbdev; set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&iforce->wait, &wait); if (usb_submit_urb(&iforce->ctrl)) { set_current_state(TASK_RUNNING); remove_wait_queue(&iforce->wait, &wait); return -1; } while (timeout && iforce->ctrl.status == -EINPROGRESS) timeout = schedule_timeout(timeout); set_current_state(TASK_RUNNING); remove_wait_queue(&iforce->wait, &wait); if (!timeout) { usb_unlink_urb(&iforce->ctrl); return -1; } break; #endif #ifdef IFORCE_232 case IFORCE_232: iforce->expect_packet = FF_CMD_QUERY; iforce_send_packet(iforce, FF_CMD_QUERY, packet); set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&iforce->wait, &wait); while (timeout && iforce->expect_packet) timeout = schedule_timeout(timeout); set_current_state(TASK_RUNNING); remove_wait_queue(&iforce->wait, &wait); if (!timeout) { iforce->expect_packet = 0; return -1; } break; #endif } return -(iforce->edata[0] != packet[0]); } --- NEW FILE: iforce-serio.c --- /* * $Id: iforce-serio.c,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include "iforce.h" void iforce_serial_xmit(struct iforce *iforce) { unsigned char cs; int i; unsigned long flags; if (test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) { set_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags); return; } spin_lock_irqsave(&iforce->xmit_lock, flags); again: if (iforce->xmit.head == iforce->xmit.tail) { clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return; } cs = 0x2b; serio_write(iforce->serio, 0x2b); serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]); cs ^= iforce->xmit.buf[iforce->xmit.tail]; XMIT_INC(iforce->xmit.tail, 1); for (i=iforce->xmit.buf[iforce->xmit.tail]; i >= 0; --i) { serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]); cs ^= iforce->xmit.buf[iforce->xmit.tail]; XMIT_INC(iforce->xmit.tail, 1); } serio_write(iforce->serio, cs); if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags)) goto again; clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); spin_unlock_irqrestore(&iforce->xmit_lock, flags); } static void iforce_serio_write_wakeup(struct serio *serio) { iforce_serial_xmit((struct iforce *)serio->private); } static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags) { struct iforce* iforce = serio->private; if (!iforce->pkt) { if (data != 0x2b) { return; } iforce->pkt = 1; return; } if (!iforce->id) { if (data > 3 && data != 0xff) { iforce->pkt = 0; return; } iforce->id = data; return; } if (!iforce->len) { if (data > IFORCE_MAX_LENGTH) { iforce->pkt = 0; iforce->id = 0; return; } iforce->len = data; return; } if (iforce->idx < iforce->len) { iforce->csum += iforce->data[iforce->idx++] = data; return; } if (iforce->idx == iforce->len) { iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data); iforce->pkt = 0; iforce->id = 0; iforce->len = 0; iforce->idx = 0; iforce->csum = 0; } } static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev) { struct iforce *iforce; if (serio->type != (SERIO_RS232 | SERIO_IFORCE)) return; if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return; memset(iforce, 0, sizeof(struct iforce)); iforce->bus = IFORCE_232; iforce->serio = serio; serio->private = iforce; if (serio_open(serio, dev)) { kfree(iforce); return; } if (iforce_init_device(iforce)) { serio_close(serio); kfree(iforce); return; } } static void iforce_serio_disconnect(struct serio *serio) { struct iforce* iforce = serio->private; input_unregister_device(&iforce->dev); serio_close(serio); kfree(iforce); } struct serio_dev iforce_serio_dev = { write_wakeup: iforce_serio_write_wakeup, interrupt: iforce_serio_irq, connect: iforce_serio_connect, disconnect: iforce_serio_disconnect, }; --- NEW FILE: iforce-usb.c --- /* * $Id: iforce-usb.c,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include "iforce.h" void iforce_usb_xmit(struct iforce *iforce) { int n, c; unsigned long flags; spin_lock_irqsave(&iforce->xmit_lock, flags); if (iforce->xmit.head == iforce->xmit.tail) { spin_unlock_irqrestore(&iforce->xmit_lock, flags); return; } ((char *)iforce->out.transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail]; XMIT_INC(iforce->xmit.tail, 1); n = iforce->xmit.buf[iforce->xmit.tail]; XMIT_INC(iforce->xmit.tail, 1); iforce->out.transfer_buffer_length = n + 2; iforce->out.dev = iforce->usbdev; /* Copy rest of data then */ c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE); if (n < c) c=n; memcpy(iforce->out.transfer_buffer + 1, &iforce->xmit.buf[iforce->xmit.tail], c); if (n != c) { memcpy(iforce->out.transfer_buffer + 1 + c, &iforce->xmit.buf[0], n-c); } XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(&iforce->out)) ) { printk(KERN_WARNING "iforce.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n); } spin_unlock_irqrestore(&iforce->xmit_lock, flags); } static void iforce_usb_irq(struct urb *urb) { struct iforce *iforce = urb->context; if (urb->status) return; iforce_process_packet(iforce, (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1); } static void iforce_usb_out(struct urb *urb) { struct iforce *iforce = urb->context; if (urb->status) return; iforce_usb_xmit(iforce); if (waitqueue_active(&iforce->wait)) wake_up(&iforce->wait); } static void iforce_usb_ctrl(struct urb *urb) { struct iforce *iforce = urb->context; if (urb->status) return; iforce->ecmd = 0xff00 | urb->actual_length; if (waitqueue_active(&iforce->wait)) wake_up(&iforce->wait); } static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct usb_endpoint_descriptor *epirq, *epout; struct iforce *iforce; epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1; if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) return NULL; memset(iforce, 0, sizeof(struct iforce)); iforce->bus = IFORCE_USB; iforce->usbdev = dev; iforce->dr.requesttype = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE; iforce->dr.index = 0; iforce->dr.length = 16; FILL_INT_URB(&iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress), iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval); FILL_BULK_URB(&iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress), iforce + 1, 32, iforce_usb_out, iforce); FILL_CONTROL_URB(&iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0), (void*) &iforce->dr, iforce->edata, 16, iforce_usb_ctrl, iforce); if (iforce_init_device(iforce)) { kfree(iforce); return NULL; } return iforce; } static void iforce_usb_disconnect(struct usb_device *dev, void *ptr) { struct iforce *iforce = ptr; usb_unlink_urb(&iforce->irq); input_unregister_device(&iforce->dev); kfree(iforce); } static struct usb_device_id iforce_usb_ids [] = { { USB_DEVICE(0x044f, 0xa01c) }, /* Thrustmaster Motor Sport GT */ { USB_DEVICE(0x046d, 0xc281) }, /* Logitech WingMan Force */ { USB_DEVICE(0x046d, 0xc291) }, /* Logitech WingMan Formula Force */ { USB_DEVICE(0x05ef, 0x020a) }, /* AVB Top Shot Pegasus */ { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */ { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */ { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, iforce_usb_ids); struct usb_driver iforce_usb_driver = { name: "iforce", probe: iforce_usb_probe, disconnect: iforce_usb_disconnect, id_table: iforce_usb_ids, }; --- NEW FILE: iforce.h --- /* * $Id: iforce.h,v 1.1.2.1 2001/10/07 17:06:49 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik <vo...@uc...> * Copyright (c) 2001 Johann Deneux <de...@if...> * * USB/RS232 I-Force joysticks and wheels. */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vo...@uc...>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/usb.h> #include <linux/serio.h> #include <linux/config.h> #include <linux/circ_buf.h> #include <asm/semaphore.h> /* FF: This module provides arbitrary resource management routines. * I use it to manage the device's memory. * Despite the name of this module, I am *not* going to access the ioports. */ #include <linux/ioport.h> #define IFORCE_MAX_LENGTH 16 #if defined(CONFIG_INPUT_IFORCE_232) || defined(CONFIG_INPUT_IFORCE_232_MODULE) #define IFORCE_232 1 #endif #if defined(CONFIG_INPUT_IFORCE_USB) || defined(CONFIG_INPUT_IFORCE_USB_MODULE) #define IFORCE_USB 2 #endif #define FALSE 0 #define TRUE 1 #define FF_EFFECTS_MAX 32 /* Each force feedback effect is made of one core effect, which can be * associated to at most to effect modifiers */ #define FF_MOD1_IS_USED 0 #define FF_MOD2_IS_USED 1 #define FF_CORE_IS_USED 2 #define FF_CORE_IS_PLAYED 3 /* Effect is actually being played */ #define FF_CORE_SHOULD_PLAY 4 /* User wants the effect to be played */ #define FF_CORE_UPDATE 5 /* Effect is being updated */ #define FF_MODCORE_MAX 5 #define CHECK_OWNERSHIP(i, iforce) \ ((i) < FF_EFFECTS_MAX && i >= 0 && \ test_bit(FF_CORE_IS_USED, (iforce)->core_effects[(i)].flags) && \ (current->pid == 0 || \ (iforce)->core_effects[(i)].owner == current->pid)) struct iforce_core_effect { /* Information about where modifiers are stored in the device's memory */ struct resource mod1_chunk; struct resource mod2_chunk; unsigned long flags[NBITS(FF_MODCORE_MAX)]; pid_t owner; /* Used to keep track of parameters of an effect. They are needed * to know what parts of an effect changed in an update operation. * We try to send only parameter packets if possible, as sending * effect parameter requires the effect to be stoped and restarted */ struct ff_effect effect; }; #define FF_CMD_EFFECT 0x010e #define FF_CMD_SHAPE 0x0208 #define FF_CMD_MAGNITUDE 0x0303 #define FF_CMD_PERIOD 0x0407 #define FF_CMD_INTERACT 0x050a #define FF_CMD_AUTOCENTER 0x4002 #define FF_CMD_PLAY 0x4103 #define FF_CMD_ENABLE 0x4201 #define FF_CMD_GAIN 0x4301 #define FF_CMD_QUERY 0xff01 /* Buffer for async write */ #define XMIT_SIZE 256 #define XMIT_INC(var, n) (var)+=n; (var)&= XMIT_SIZE -1 /* iforce::xmit_flags */ #define IFORCE_XMIT_RUNNING 0 #define IFORCE_XMIT_AGAIN 1 struct iforce_device { u16 idvendor; u16 idproduct; char *name; signed short *btn; signed short *abs; signed short *ff; }; struct iforce { struct input_dev dev; /* Input device interface */ struct iforce_device *type; char name[64]; char phys[64]; int open; int bus; unsigned char data[IFORCE_MAX_LENGTH]; unsigned char edata[IFORCE_MAX_LENGTH]; u16 ecmd; u16 expect_packet; #ifdef IFORCE_232 struct serio *serio; /* RS232 transfer */ int idx, pkt, len, id; unsigned char csum; #endif #ifdef IFORCE_USB struct usb_device *usbdev; /* USB transfer */ struct urb irq, out, ctrl; devrequest dr; #endif spinlock_t xmit_lock; /* Buffer used for asynchronous sending of bytes to the device */ struct circ_buf xmit; unsigned char xmit_data[XMIT_SIZE]; long xmit_flags[1]; /* Force Feedback */ wait_queue_head_t wait; struct resource device_memory; struct iforce_core_effect core_effects[FF_EFFECTS_MAX]; struct semaphore mem_mutex; }; /* Get hi and low bytes of a 16-bits int */ #define HI(a) ((unsigned char)((a) >> 8)) #define LO(a) ((unsigned char)((a) & 0xff)) /* For many parameters, it seems that 0x80 is a special value that should * be avoided. Instead, we replace this value by 0x7f */ #define HIFIX80(a) ((unsigned char)(((a)<0? (a)+255 : (a))>>8)) /* Encode a time value */ #define TIME_SCALE(a) ((a) == 0xffff ? 0xffff : (a) * 1000 / 256) /* Public functions */ /* iforce-serio.c */ void iforce_serial_xmit(struct iforce *iforce); /* iforce-usb.c */ void iforce_usb_xmit(struct iforce *iforce); /* iforce-main.c */ int iforce_init_device(struct iforce *iforce); /* iforce-packets.c */ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data); int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data); void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ; int iforce_get_id_packet(struct iforce *iforce, char *packet); /* iforce-ff.c */ int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update); int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update); int iforce_upload_interactive(struct iforce*, struct ff_effect*, int is_update); /* Public variables */ struct serio_dev iforce_serio_dev; struct usb_driver iforce_usb_driver; Index: Makefile =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/Makefile,v retrieving revision 1.42 retrieving revision 1.42.2.1 diff -u -d -r1.42 -r1.42.2.1 --- Makefile 2001/08/27 11:48:38 1.42 +++ Makefile 2001/10/07 17:06:49 1.42.2.1 @@ -28,6 +28,14 @@ hid-objs += hiddev.o endif +iforce-objs := iforce-packets.o iforce-ff.o iforce-main.o +ifeq ($(CONFIG_IFORCE_SERIAL),y) + iforce-objs += iforce-serio.o +endif +ifeq ($(CONFIG_IFORCE_USB),y) + iforce-objs += iforce-usb.o +endif + # Object file lists. obj-y := @@ -147,3 +155,6 @@ hid.o: $(hid-objs) $(LD) -r -o $@ $(hid-objs) + +iforce.o: $(iforce-objs) + $(LD) -r -o $@ $(iforce-objs) --- iforce.c DELETED --- |
From: Paul M. <le...@us...> - 2001-10-06 21:06:35
|
Update of /cvsroot/linuxconsole/ruby/linux/fs/gfxfs In directory usw-pr-cvs1:/tmp/cvs-serv16175 Modified Files: dir.c Log Message: Add support for the dcache provided readdir. Index: dir.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/fs/gfxfs/dir.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- dir.c 2001/10/06 21:00:43 1.1 +++ dir.c 2001/10/06 21:06:32 1.2 @@ -9,10 +9,12 @@ * */ #include <linux/gfxfs_fs.h> +#include <linux/dcache.h> /* FIXME: Keep things happy for now, add our own later */ struct file_operations gfxfs_dir_ops = { read: generic_read_dir, + readdir: dcache_readdir, }; /* Ditto */ |
From: Paul M. <le...@us...> - 2001-10-06 21:01:17
|
Update of /cvsroot/linuxconsole/ruby/linux/include/linux In directory usw-pr-cvs1:/tmp/cvs-serv15040 Modified Files: gfxfs_fs.h Log Message: header updates too. Index: gfxfs_fs.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/include/linux/gfxfs_fs.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- gfxfs_fs.h 2001/10/06 19:35:58 1.1 +++ gfxfs_fs.h 2001/10/06 21:01:15 1.2 @@ -5,14 +5,24 @@ * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * + * Released under the terms of the GNU GPL v2.0. + * */ #ifndef __GFXFS_FS_H #define __GFXFS_FS_H #include <linux/fs.h> +#include <linux/config.h> #define GFXFS_SUPER_MAGIC 0x8048494 /* "gfxfs" */ +#ifdef CONFIG_GFXFS_FS_DEBUG + #define gfxfs_debug(x...) printk(KERN_DEBUG "gfxfs: " \ + __FUNCTION__ "(): " ##x) +#else + #define gfxfs_debug(x...) do { } while (0) +#endif /* CONFIG_GFXFS_FS_DEBUG */ + /* * struct gfxfs_dentry - gfxfs dentry * @@ -32,6 +42,17 @@ struct dentry *f_dentry; struct file_operations *f_ops; }; + +/* fs/gfxfs/inode.c */ +extern void gfxfs_read_inode(struct inode *inode); +extern struct inode *gfxfs_get_inode(struct super_block *sb, int mode, int dev); + +/* fs/gfxfs/file.c */ +extern struct file_operations gfxfs_file_ops; + +/* fs/gfxfs/dir.c */ +extern struct file_operations gfxfs_dir_ops; +extern struct inode_operations gfxfs_dir_inode_ops; #endif /* __GFXFS_FS_H */ |
From: Paul M. <le...@us...> - 2001-10-06 21:00:46
|
Update of /cvsroot/linuxconsole/ruby/linux/fs In directory usw-pr-cvs1:/tmp/cvs-serv14922 Modified Files: Config.in Log Message: GfxFS updates. Index: Config.in =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/fs/Config.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Config.in 2001/10/06 17:47:04 1.1 +++ Config.in 2001/10/06 21:00:43 1.2 @@ -46,6 +46,7 @@ tristate 'OS/2 HPFS file system support' CONFIG_HPFS_FS dep_tristate 'Graphics file system support (EXPERIMENTAL)' CONFIG_GFXFS_FS $CONFIG_EXPERIMENTAL +dep_bool ' Debug gfxfs' CONFIG_GFXFS_FS_DEBUG $CONFIG_GFXFS_FS bool '/proc file system support' CONFIG_PROC_FS |
From: Paul M. <le...@us...> - 2001-10-06 21:00:46
|
Update of /cvsroot/linuxconsole/ruby/linux/fs/gfxfs In directory usw-pr-cvs1:/tmp/cvs-serv14922/gfxfs Added Files: Makefile dir.c file.c inode.c super.c Log Message: GfxFS updates. --- NEW FILE: Makefile --- # # Makefile for the Linux graphics filesystem routines. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (not a .c file). # # Note 2! The CFLAGS definitions are now in the main makefile. O_TARGET := gfxfs.o obj-y := super.o inode.o file.o dir.o obj-m := $(O_TARGET) include $(TOPDIR)/Rules.make --- NEW FILE: dir.c --- /* * fs/gfxfs/dir.c * * gfxfs directory operations * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * * Released under the terms of the GNU GPL v2.0. * */ #include <linux/gfxfs_fs.h> /* FIXME: Keep things happy for now, add our own later */ struct file_operations gfxfs_dir_ops = { read: generic_read_dir, }; /* Ditto */ struct inode_operations gfxfs_dir_inode_ops = { /* Empty for now */ }; --- NEW FILE: file.c --- /* * fs/gfxfs/file.c * * gfxfs file operations * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * * Released under the terms of the GNU GPL v2.0. * */ #include <linux/gfxfs_fs.h> /* * FIXME: Use generic routines for now, add our own later. */ struct file_operations gfxfs_file_ops = { mmap: generic_file_mmap, llseek: generic_file_llseek, }; --- NEW FILE: inode.c --- /* * fs/gfxfs/inode.c * * gfxfs inode operations * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * * Released under the terms of the GNU GPL v2.0. * */ #include <linux/locks.h> #include <linux/gfxfs_fs.h> #include <asm/uaccess.h> void gfxfs_read_inode(struct inode *inode) { inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; } struct inode *gfxfs_get_inode(struct super_block *sb, int mode, int dev) { struct inode *inode = new_inode(sb); if (!inode) { printk(KERN_WARNING "gfxfs: Unable to get new inode\n"); return NULL; } inode->i_mode = mode; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; gfxfs_read_inode(inode); switch (mode & S_IFMT) { case S_IFREG: inode->i_fop = &gfxfs_file_ops; break; case S_IFDIR: inode->i_op = &gfxfs_dir_inode_ops; inode->i_fop = &gfxfs_dir_ops; break; default: init_special_inode(inode, mode, dev); break; } return inode; } --- NEW FILE: super.c --- /* * fs/gfxfs/super.c * * gfxfs superblock operations * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * * Released under the terms of the GNU GPL v2.0. * */ #include <linux/module.h> #include <linux/init.h> #include <linux/gfxfs_fs.h> #include <linux/pagemap.h> #include <linux/dcache.h> static struct vfsmount *gfxfs_mnt; static int gfxfs_statfs(struct super_block *sb, struct statfs *buf) { buf->f_type = GFXFS_SUPER_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; buf->f_namelen = NAME_MAX; return 0; } static struct super_operations gfxfs_super_ops = { statfs: gfxfs_statfs, }; static struct super_block *gfxfs_read_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = GFXFS_SUPER_MAGIC; sb->s_op = &gfxfs_super_ops; root_inode = gfxfs_get_inode(sb, S_IFDIR | 0755, 0); if (!root_inode) { printk(KERN_WARNING "gfxfs: Unable to get root inode\n"); return NULL; } sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) { printk(KERN_WARNING "gfxfs: Unable to get root dentry\n"); iput(root_inode); return NULL; } return sb; } static DECLARE_FSTYPE(gfxfs_fs_type, "gfxfs", gfxfs_read_super, FS_SINGLE); static int __init init_gfxfs_fs(void) { int ret = register_filesystem(&gfxfs_fs_type); if (!ret) { gfxfs_mnt = kern_mount(&gfxfs_fs_type); ret = PTR_ERR(gfxfs_mnt); if (!IS_ERR(gfxfs_mnt)) { ret = 0; } } return ret; } static void __exit exit_gfxfs_fs(void) { kern_umount(gfxfs_mnt); unregister_filesystem(&gfxfs_fs_type); } EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Paul Mundt <pm...@mv...>"); MODULE_DESCRIPTION("graphics file system"); MODULE_LICENSE("GPL"); module_init(init_gfxfs_fs); module_exit(exit_gfxfs_fs); |
From: Paul M. <le...@us...> - 2001-10-06 19:36:00
|
Update of /cvsroot/linuxconsole/ruby/linux/include/linux In directory usw-pr-cvs1:/tmp/cvs-serv31635 Added Files: gfxfs_fs.h Log Message: Added preliminary header. --- NEW FILE: gfxfs_fs.h --- /* * include/linux/gfxfs_fs.h * * Primary GfxFS header. * * Copyright (C) 2001 Paul Mundt <pm...@mv...> * */ #ifndef __GFXFS_FS_H #define __GFXFS_FS_H #include <linux/fs.h> #define GFXFS_SUPER_MAGIC 0x8048494 /* "gfxfs" */ /* * struct gfxfs_dentry - gfxfs dentry * * @f_dentry: Pointer to underlying dentry. * @f_ops: File operations associated with given dentry. * * Each gfxfs dentry has the ability for callbacks to be * registered with it upon allocation. In the event a * callback is registered, it gets executed in place of * the generic dcache routines. For all other operations, * we rely on generic routines provided by the dcache. * * Notably, the registered file operations callbacks * only apply to regular (S_IFREG) files. */ struct gfxfs_dentry { struct dentry *f_dentry; struct file_operations *f_ops; }; #endif /* __GFXFS_FS_H */ |
From: Paul M. <le...@us...> - 2001-10-06 17:47:07
|
Update of /cvsroot/linuxconsole/ruby/linux/fs In directory usw-pr-cvs1:/tmp/cvs-serv11819 Added Files: Config.in Makefile Log Message: Added GfxFS rules. --- NEW FILE: Config.in --- # # File system configuration # mainmenu_option next_comment comment 'File systems' bool 'Quota support' CONFIG_QUOTA tristate 'Kernel automounter support' CONFIG_AUTOFS_FS tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS dep_tristate 'Reiserfs support' CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'Amiga FFS file system support (EXPERIMENTAL)' CONFIG_AFFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL # msdos file systems tristate 'DOS FAT fs support' CONFIG_FAT_FS dep_tristate ' MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS dep_tristate ' UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS dep_tristate ' VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS dep_tristate 'EFS file system support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'Journalling Flash File System (JFFS) support (EXPERIMENTAL)' CONFIG_JFFS_FS $CONFIG_EXPERIMENTAL $CONFIG_MTD if [ "$CONFIG_JFFS_FS" = "y" -o "$CONFIG_JFFS_FS" = "m" ] ; then int 'JFFS debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_JFFS_FS_VERBOSE 0 fi tristate 'Compressed ROM file system support' CONFIG_CRAMFS bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS tristate 'Simple RAM-based file system support' CONFIG_RAMFS tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS tristate 'Minix fs support' CONFIG_MINIX_FS tristate 'FreeVxFS file system support (VERITAS VxFS(TM) compatible)' CONFIG_VXFS_FS tristate 'NTFS file system support (read only)' CONFIG_NTFS_FS dep_mbool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW $CONFIG_NTFS_FS $CONFIG_EXPERIMENTAL tristate 'OS/2 HPFS file system support' CONFIG_HPFS_FS dep_tristate 'Graphics file system support (EXPERIMENTAL)' CONFIG_GFXFS_FS $CONFIG_EXPERIMENTAL bool '/proc file system support' CONFIG_PROC_FS dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL dep_bool ' Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS dep_bool ' Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS # It compiles as a module for testing only. It should not be used # as a module in general. If we make this "tristate", a bunch of people # who don't know what they are doing turn it on and complain when it # breaks. dep_bool '/dev/pts file system for Unix98 PTYs' CONFIG_DEVPTS_FS $CONFIG_UNIX98_PTYS dep_tristate 'QNX4 file system support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL dep_mbool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW $CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL tristate 'ROM file system support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS tristate 'UDF file system support (read only)' CONFIG_UDF_FS dep_mbool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW $CONFIG_UDF_FS $CONFIG_EXPERIMENTAL tristate 'UFS file system support (read only)' CONFIG_UFS_FS dep_mbool ' UFS file system write support (DANGEROUS)' CONFIG_UFS_FS_WRITE $CONFIG_UFS_FS $CONFIG_EXPERIMENTAL if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network File Systems' dep_tristate 'Coda file system support (advanced network fs)' CONFIG_CODA_FS $CONFIG_INET dep_tristate 'NFS file system support' CONFIG_NFS_FS $CONFIG_INET dep_mbool ' Provide NFSv3 client support' CONFIG_NFS_V3 $CONFIG_NFS_FS dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET dep_mbool ' Provide NFSv3 server support' CONFIG_NFSD_V3 $CONFIG_NFSD if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then define_tristate CONFIG_SUNRPC y define_tristate CONFIG_LOCKD y else if [ "$CONFIG_NFS_FS" = "m" -o "$CONFIG_NFSD" = "m" ]; then define_tristate CONFIG_SUNRPC m define_tristate CONFIG_LOCKD m else define_tristate CONFIG_SUNRPC n define_tristate CONFIG_LOCKD n fi fi if [ "$CONFIG_NFSD_V3" = "y" -o "$CONFIG_NFS_V3" = "y" ]; then define_bool CONFIG_LOCKD_V4 y fi dep_tristate 'SMB file system support (to mount Windows shares etc.)' CONFIG_SMB_FS $CONFIG_INET if [ "$CONFIG_SMB_FS" != "n" ]; then bool ' Use a default NLS' CONFIG_SMB_NLS_DEFAULT if [ "$CONFIG_SMB_NLS_DEFAULT" = "y" ]; then string ' Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "cp437" fi fi if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then tristate 'NCP file system support (to mount NetWare volumes)' CONFIG_NCP_FS source fs/ncpfs/Config.in else # for fs/nls/Config.in define_bool CONFIG_NCPFS_NLS n fi endmenu else # for fs/nls/Config.in define_bool CONFIG_NCPFS_NLS n define_bool CONFIG_SMB_FS n fi mainmenu_option next_comment comment 'Partition Types' source fs/partitions/Config.in endmenu source fs/nls/Config.in endmenu --- NEW FILE: Makefile --- # # Makefile for the Linux filesystems. # # 14 Sep 2000, Christoph Hellwig <hc...@ca...> # Rewritten to use lists instead of if-statements. # O_TARGET := fs.o export-objs := filesystems.o open.o dcache.o mod-subdirs := nls obj-y := open.o read_write.o devices.o file_table.o buffer.o \ super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \ fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \ dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \ filesystems.o ifeq ($(CONFIG_QUOTA),y) obj-y += dquot.o else obj-y += noquot.o endif subdir-$(CONFIG_PROC_FS) += proc subdir-y += partitions # Do not add any filesystems before this line subdir-$(CONFIG_EXT2_FS) += ext2 subdir-$(CONFIG_CRAMFS) += cramfs subdir-$(CONFIG_RAMFS) += ramfs subdir-$(CONFIG_CODA_FS) += coda subdir-$(CONFIG_MINIX_FS) += minix subdir-$(CONFIG_FAT_FS) += fat subdir-$(CONFIG_UMSDOS_FS) += umsdos subdir-$(CONFIG_MSDOS_FS) += msdos subdir-$(CONFIG_VFAT_FS) += vfat subdir-$(CONFIG_BFS_FS) += bfs subdir-$(CONFIG_ISO9660_FS) += isofs subdir-$(CONFIG_DEVFS_FS) += devfs subdir-$(CONFIG_HFS_FS) += hfs subdir-$(CONFIG_VXFS_FS) += freevxfs subdir-$(CONFIG_NFS_FS) += nfs subdir-$(CONFIG_NFSD) += nfsd subdir-$(CONFIG_LOCKD) += lockd subdir-$(CONFIG_NLS) += nls subdir-$(CONFIG_SYSV_FS) += sysv subdir-$(CONFIG_SMB_FS) += smbfs subdir-$(CONFIG_NCP_FS) += ncpfs subdir-$(CONFIG_HPFS_FS) += hpfs subdir-$(CONFIG_NTFS_FS) += ntfs subdir-$(CONFIG_UFS_FS) += ufs subdir-$(CONFIG_EFS_FS) += efs subdir-$(CONFIG_JFFS_FS) += jffs subdir-$(CONFIG_AFFS_FS) += affs subdir-$(CONFIG_ROMFS_FS) += romfs subdir-$(CONFIG_QNX4FS_FS) += qnx4 subdir-$(CONFIG_UDF_FS) += udf subdir-$(CONFIG_AUTOFS_FS) += autofs subdir-$(CONFIG_AUTOFS4_FS) += autofs4 subdir-$(CONFIG_ADFS_FS) += adfs subdir-$(CONFIG_REISERFS_FS) += reiserfs subdir-$(CONFIG_DEVPTS_FS) += devpts subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs subdir-$(CONFIG_GFXFS_FS) += gfxfs obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o # binfmt_script is always there obj-y += binfmt_script.o obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o # persistent filesystems obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) include $(TOPDIR)/Rules.make |
From: Paul M. <le...@us...> - 2001-10-06 17:46:44
|
Update of /cvsroot/linuxconsole/ruby/linux/fs/gfxfs In directory usw-pr-cvs1:/tmp/cvs-serv11793/gfxfs Log Message: Directory /cvsroot/linuxconsole/ruby/linux/fs/gfxfs added to the repository |
From: James S. <jsi...@us...> - 2001-10-06 16:31:00
|
Update of /cvsroot/linuxconsole/ruby In directory usw-pr-cvs1:/tmp/cvs-serv29635 Removed Files: AGAINST-2.4.9 Log Message: --- AGAINST-2.4.9 DELETED --- |
From: James S. <jsi...@us...> - 2001-10-06 16:30:22
|
Update of /cvsroot/linuxconsole/ruby In directory usw-pr-cvs1:/tmp/cvs-serv29561 Added Files: AGAINST-2.4.10 Log Message: --- NEW FILE: AGAINST-2.4.10 --- |
From: James S. <jsi...@us...> - 2001-10-06 16:27:55
|
Update of /cvsroot/linuxconsole/ruby/linux/arch/i386/kernel In directory usw-pr-cvs1:/tmp/cvs-serv29140 Added Files: dmi_scan.c Log Message: Hm. On DELL PS/2 and PM suspend don't get along. For now I just ignore the problem but we will have to think about handling PM on a input level. --- NEW FILE: dmi_scan.c --- #include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> #include <linux/apm_bios.h> #include <linux/slab.h> #include <asm/io.h> #include <linux/pm.h> #include <linux/keyboard.h> struct dmi_header { u8 type; u8 length; u16 handle; }; #define dmi_printk(x) //#define dmi_printk(x) printk x static char * __init dmi_string(struct dmi_header *dm, u8 s) { u8 *bp=(u8 *)dm; bp+=dm->length; if(!s) return ""; s--; while(s>0) { bp+=strlen(bp); bp++; s--; } return bp; } /* * We have to be cautious here. We have seen BIOSes with DMI pointers * pointing to completely the wrong place for example */ static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *)) { u8 *buf; struct dmi_header *dm; u8 *data; int i=1; buf = ioremap(base, len); if(buf==NULL) return -1; data = buf; /* * Stop when we see al the items the table claimed to have * OR we run off the end of the table (also happens) */ while(i<num && (data - buf) < len) { dm=(struct dmi_header *)data; /* * Avoid misparsing crud if the length of the last * record is crap */ if((data-buf+dm->length) >= len) break; decode(dm); data+=dm->length; /* * Don't go off the end of the data if there is * stuff looking like string fill past the end */ while((data-buf) < len && (*data || data[1])) data++; data+=2; i++; } iounmap(buf); return 0; } int __init dmi_iterate(void (*decode)(struct dmi_header *)) { unsigned char buf[20]; long fp=0xE0000L; fp -= 16; #ifdef CONFIG_SIMNOW /* * Skip on x86/64 with simnow. Will eventually go away * If you see this ifdef in 2.6pre mail me ! */ return; #endif while( fp < 0xFFFFF) { fp+=16; isa_memcpy_fromio(buf, fp, 20); if(memcmp(buf, "_DMI_", 5)==0) { u16 num=buf[13]<<8|buf[12]; u16 len=buf[7]<<8|buf[6]; u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; dmi_printk((KERN_INFO "DMI %d.%d present.\n", buf[14]>>4, buf[14]&0x0F)); dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", buf[13]<<8|buf[12], buf[7]<<8|buf[6])); dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8])); if(dmi_table(base,len, num, decode)==0) return 0; } } return -1; } enum { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_BIOS_DATE, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_STRING_MAX }; static char *dmi_ident[DMI_STRING_MAX]; /* * Save a DMI string */ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) { char *d = (char*)dm; char *p = dmi_string(dm, d[string]); if(p==NULL || *p == 0) return; if (dmi_ident[slot]) return; dmi_ident[slot] = kmalloc(strlen(p)+1, GFP_KERNEL); if(dmi_ident[slot]) strcpy(dmi_ident[slot], p); else printk(KERN_ERR "dmi_save_ident: out of memory.\n"); } /* * DMI callbacks for problem boards */ struct dmi_strmatch { u8 slot; char *substr; }; #define NONE 255 struct dmi_blacklist { int (*callback)(struct dmi_blacklist *); char *ident; struct dmi_strmatch matches[4]; }; #define NO_MATCH { NONE, NULL} #define MATCH(a,b) { a, b } /* * We have problems with IDE DMA on some platforms. In paticular the * KT7 series. On these it seems the newer BIOS has fixed them. The * rule needs to be improved to match specific BIOS revisions with * corruption problems */ static __init int disable_ide_dma(struct dmi_blacklist *d) { #ifdef CONFIG_BLK_DEV_IDE extern int noautodma; if(noautodma == 0) { noautodma = 1; printk(KERN_INFO "%s series board detected. Disabling IDE DMA.\n", d->ident); } #endif return 0; } /* * Reboot options and system auto-detection code provided by * Dell Computer Corporation so their systems "just work". :-) */ /* * Some machines require the "reboot=b" commandline option, this quirk makes that automatic. */ static __init int set_bios_reboot(struct dmi_blacklist *d) { extern int reboot_thru_bios; if (reboot_thru_bios == 0) { reboot_thru_bios = 1; printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); } return 0; } /* * Some machines require the "reboot=s" commandline option, this quirk makes that automatic. */ static __init int set_smp_reboot(struct dmi_blacklist *d) { #ifdef CONFIG_SMP extern int reboot_smp; if (reboot_smp == 0) { reboot_smp = 1; printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident); } #endif return 0; } /* * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic. */ static __init int set_smp_bios_reboot(struct dmi_blacklist *d) { set_smp_reboot(d); set_bios_reboot(d); return 0; } /* * Some bioses have a broken protected mode poweroff and need to use realmode */ static __init int set_realmode_power_off(struct dmi_blacklist *d) { if (apm_info.realmode_power_off == 0) { apm_info.realmode_power_off = 1; printk(KERN_INFO "%s bios detected. Using realmode poweroff only.\n", d->ident); } return 0; } /* * Some laptops require interrupts to be enabled during APM calls */ static __init int set_apm_ints(struct dmi_blacklist *d) { if (apm_info.allow_ints == 0) { apm_info.allow_ints = 1; printk(KERN_INFO "%s machine detected. Enabling interrupts during APM calls.\n", d->ident); } return 0; } /* * Some APM bioses corrupt memory or just plain do not work */ static __init int apm_is_horked(struct dmi_blacklist *d) { if (apm_info.disabled == 0) { apm_info.disabled = 1; printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident); } return 0; } /* * Check for clue free BIOS implementations who use * the following QA technique * * [ Write BIOS Code ]<------ * | ^ * < Does it Compile >----N-- * |Y ^ * < Does it Boot Win98 >-N-- * |Y * [Ship It] * * Phoenix A04 08/24/2000 is known bad (Dell Inspiron 5000e) * Phoenix A07 09/29/2000 is known good (Dell Inspiron 5000) */ static __init int broken_apm_power(struct dmi_blacklist *d) { apm_info.get_power_status_broken = 1; printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n"); return 0; } #if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE) /* * Check for a Sony Vaio system in order to enable the use of * the sonypi driver (we don't want this driver to be used on * other systems, even if they have the good PCI IDs). * * This one isn't a bug detect for those who asked, we simply want to * activate Sony specific goodies like the camera and jogdial.. */ int is_sony_vaio_laptop; static __init int sony_vaio_laptop(struct dmi_blacklist *d) { if (is_sony_vaio_laptop == 0) { is_sony_vaio_laptop = 1; printk(KERN_INFO "%s laptop detected.\n", d->ident); } return 0; } #endif /* * This bios swaps the APM minute reporting bytes over (Many sony laptops * have this problem). */ static __init int swab_apm_power_in_minutes(struct dmi_blacklist *d) { apm_info.get_power_status_swabinminutes = 1; printk(KERN_WARNING "BIOS strings suggest APM reports battery life in minutes and wrong byte order.\n"); return 0; } /* * The Intel 440GX hall of shame. * * On many (all we have checked) of these boxes the $PIRQ table is wrong. * The MP1.4 table is right however and so SMP kernels tend to work. */ static __init int broken_pirq(struct dmi_blacklist *d) { printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n"); printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n"); printk(KERN_INFO " *** If you see IRQ problems, in paticular SCSI resets and hangs at boot\n"); printk(KERN_INFO " *** contact your vendor and ask about updates.\n"); printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n"); return 0; } /* * Process the DMI blacklists */ /* * This will be expanded over time to force things like the APM * interrupt mask settings according to the laptop */ static __initdata struct dmi_blacklist dmi_blacklist[]={ #if 0 { disable_ide_dma, "KT7", { /* Overbroad right now - kill DMA on problem KT7 boards */ MATCH(DMI_PRODUCT_NAME, "KT7-RAID"), NO_MATCH, NO_MATCH, NO_MATCH } }, #endif { broken_apm_power, "Dell Inspiron 5000e", { /* Handle problems with APM on Inspiron 5000e */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "A04"), MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH } }, { set_realmode_power_off, "Award Software v4.60 PGMA", { /* broken PM poweroff bios */ MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."), MATCH(DMI_BIOS_VERSION, "4.60 PGMA"), MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH } }, { set_smp_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */ MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"), NO_MATCH, NO_MATCH } }, { set_bios_reboot, "Dell PowerEdge 300", { /* Handle problems with rebooting on Dell 1300's */ MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), NO_MATCH, NO_MATCH } }, { set_apm_ints, "IBM", { /* Allow interrupts during suspend on IBM laptops */ MATCH(DMI_SYS_VENDOR, "IBM"), NO_MATCH, NO_MATCH, NO_MATCH } }, { set_apm_ints, "Dell Inspiron", { /* Allow interrupts during suspend on Dell Inspiron laptops*/ MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), NO_MATCH, NO_MATCH } }, { set_apm_ints, "Compaq 12XL125", { /* Allow interrupts during suspend on Compaq Laptops*/ MATCH(DMI_SYS_VENDOR, "Compaq"), MATCH(DMI_PRODUCT_NAME, "Compaq PC"), MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION,"4.06") } }, { set_apm_ints, "ASUSTeK", { /* Allow interrupts during APM or the clock goes slow */ MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), NO_MATCH, NO_MATCH } }, { apm_is_horked, "Trigem Delhi3", { /* APM crashes */ MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"), MATCH(DMI_PRODUCT_NAME, "Delhi3"), NO_MATCH, NO_MATCH, } }, { apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */ MATCH(DMI_SYS_VENDOR, "SHARP"), MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"), MATCH(DMI_BIOS_VENDOR,"SystemSoft"), MATCH(DMI_BIOS_VERSION,"Version R2.08") } }, #if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE) { sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */ MATCH(DMI_SYS_VENDOR, "Sony Corporation"), MATCH(DMI_PRODUCT_NAME, "PCG-"), NO_MATCH, NO_MATCH, } }, #endif { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0206H"), MATCH(DMI_BIOS_DATE, "08/23/99"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505VX */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "W2K06H0"), MATCH(DMI_BIOS_DATE, "02/03/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-XG29 */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0117A0"), MATCH(DMI_BIOS_DATE, "04/25/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0121Z1"), MATCH(DMI_BIOS_DATE, "05/11/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0203D0"), MATCH(DMI_BIOS_DATE, "05/12/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0203Z3"), MATCH(DMI_BIOS_DATE, "08/25/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-F104K */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0204K2"), MATCH(DMI_BIOS_DATE, "08/28/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0208P1"), MATCH(DMI_BIOS_DATE, "11/09/00"), NO_MATCH } }, { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VE */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0204P1"), MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH } }, /* Problem Intel 440GX bioses */ { broken_pirq, "SABR1 Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), MATCH(DMI_BIOS_VERSION,"SABR1"), NO_MATCH, NO_MATCH } }, { broken_pirq, "l44GX Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"), NO_MATCH, NO_MATCH } }, { broken_pirq, "l44GX Bios", { /* Bad $PIR */ MATCH(DMI_BIOS_VENDOR, "Intel Corporation"), MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0125.P13"), NO_MATCH, NO_MATCH } }, /* Intel in disgiuse - In this case they can't hide and they don't run too well either... */ { broken_pirq, "Dell PowerEdge 8450", { /* Bad $PIR */ MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"), NO_MATCH, NO_MATCH, NO_MATCH } }, { NULL, } }; /* * Walk the blacklist table running matching functions until someone * returns 1 or we hit the end. */ static __init void dmi_check_blacklist(void) { struct dmi_blacklist *d; int i; d=&dmi_blacklist[0]; while(d->callback) { for(i=0;i<4;i++) { int s = d->matches[i].slot; if(s==NONE) continue; if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) continue; /* No match */ goto fail; } if(d->callback(d)) return; fail: d++; } } /* * Process a DMI table entry. Right now all we care about are the BIOS * and machine entries. For 2.5 we should pull the smbus controller info * out of here. */ static void __init dmi_decode(struct dmi_header *dm) { u8 *data = (u8 *)dm; char *p; switch(dm->type) { case 0: p=dmi_string(dm,data[4]); if(*p) { dmi_printk(("BIOS Vendor: %s\n", p)); dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_BIOS_VERSION, 5); dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8]))); dmi_save_ident(dm, DMI_BIOS_DATE, 8); } break; case 1: p=dmi_string(dm,data[4]); if(*p) { dmi_printk(("System Vendor: %s.\n",p)); dmi_save_ident(dm, DMI_SYS_VENDOR, 4); dmi_printk(("Product Name: %s.\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); dmi_printk(("Version %s.\n", dmi_string(dm, data[6]))); dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); dmi_printk(("Serial Number %s.\n", dmi_string(dm, data[7]))); } break; case 2: p=dmi_string(dm,data[4]); if(*p) { dmi_printk(("Board Vendor: %s.\n",p)); dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); dmi_printk(("Board Name: %s.\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_BOARD_NAME, 5); dmi_printk(("Board Version: %s.\n", dmi_string(dm, data[6]))); dmi_save_ident(dm, DMI_BOARD_VERSION, 6); } break; case 3: p=dmi_string(dm,data[8]); if(*p && *p!=' ') dmi_printk(("Asset Tag: %s.\n", p)); break; } } static int __init dmi_scan_machine(void) { int err = dmi_iterate(dmi_decode); if(err == 0) dmi_check_blacklist(); return err; } module_init(dmi_scan_machine); |
From: James S. <jsi...@us...> - 2001-10-06 16:25:03
|
Update of /cvsroot/linuxconsole/ruby/linux/fs/proc In directory usw-pr-cvs1:/tmp/cvs-serv28674 Removed Files: kmsg.c Log Message: Changes in standard tree. --- kmsg.c DELETED --- |
From: James S. <jsi...@us...> - 2001-10-06 16:21:25
|
Update of /cvsroot/linuxconsole/ruby/linux/arch/sparc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28089 Removed Files: debuglocks.c Log Message: Changes in standard tree. --- debuglocks.c DELETED --- |