Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 31095 Details for
Bug 45100
xbox-sources (new packages)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
xbox-sources-2.6.6-CVS10May2004.patch
xbox-sources-2.6.6-CVS10May2004.patch (text/plain), 450.99 KB, created by
Chris Bainbridge (RETIRED)
on 2004-05-10 04:45:44 UTC
(
hide
)
Description:
xbox-sources-2.6.6-CVS10May2004.patch
Filename:
MIME Type:
Creator:
Chris Bainbridge (RETIRED)
Created:
2004-05-10 04:45:44 UTC
Size:
450.99 KB
patch
obsolete
>diff -urN linux-2.6.6.orig/Makefile linux-2.6.6/Makefile >--- linux-2.6.6.orig/Makefile 2004-05-10 03:32:53.000000000 +0100 >+++ linux-2.6.6/Makefile 2004-05-10 12:30:51.916578648 +0100 >@@ -1,7 +1,7 @@ > VERSION = 2 > PATCHLEVEL = 6 > SUBLEVEL = 6 >-EXTRAVERSION = >+EXTRAVERSION = -xbox > NAME=Zonked Quokka > > # *DOCUMENTATION* >diff -urN linux-2.6.6.orig/arch/i386/Kconfig linux-2.6.6/arch/i386/Kconfig >--- linux-2.6.6.orig/arch/i386/Kconfig 2004-05-10 03:32:01.000000000 +0100 >+++ linux-2.6.6/arch/i386/Kconfig 2004-05-10 12:30:22.795005800 +0100 >@@ -52,6 +52,22 @@ > > If unsure, choose "PC-compatible" instead. > >+config X86_XBOX >+ bool "Microsoft Xbox" >+ help >+ This option is needed to make Linux boot on XBox Gaming Systems. >+ >+ The XBox can be considered as a standard PC with a Coppermine-based Celeron 733 MHz, >+ IDE harddrive, DVD, Ethernet, USB and graphics. >+ >+ To boot the kernel you need "_romwell", either used as a replacement BIOS (cromwell) >+ or as a bootloader. >+ >+ For more information see http://xbox-linux.sourceforge.net/ >+ >+ If you do not specifically need a kernel for XBOX machine, >+ say N here otherwise the kernel you build will not be bootable. >+ > config X86_VOYAGER > bool "Voyager (NCR)" > help >@@ -521,6 +537,10 @@ > If you have a system with several CPUs, you do not need to say Y > here: the IO-APIC will be used automatically. > >+config XBOX_EJECT >+ bool "XBOX eject fix" >+ depends on X86_XBOX >+ > config X86_LOCAL_APIC > bool > depends on !SMP && X86_UP_APIC >@@ -1127,7 +1147,7 @@ > > config MCA > bool "MCA support" >- depends on !(X86_VISWS || X86_VOYAGER) >+ depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX) > help > MicroChannel Architecture is found in some IBM PS/2 machines and > laptops. It is a bus system similar to PCI or ISA. See >@@ -1314,7 +1334,7 @@ > > config X86_BIOS_REBOOT > bool >- depends on !(X86_VISWS || X86_VOYAGER) >+ depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX) > default y > > config X86_TRAMPOLINE >diff -urN linux-2.6.6.orig/arch/i386/Makefile linux-2.6.6/arch/i386/Makefile >--- linux-2.6.6.orig/arch/i386/Makefile 2004-05-10 03:32:27.000000000 +0100 >+++ linux-2.6.6/arch/i386/Makefile 2004-05-10 12:30:22.814002912 +0100 >@@ -65,6 +65,10 @@ > # Default subarch .c files > mcore-y := mach-default > >+# Xbox subarch support >+mflags-$(CONFIG_X86_XBOX) := -Iinclude/asm-i386/mach-xbox >+mcore-$(CONFIG_X86_XBOX) := mach-xbox >+ > # Voyager subarch support > mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-i386/mach-voyager > mcore-$(CONFIG_X86_VOYAGER) := mach-voyager >diff -urN linux-2.6.6.orig/arch/i386/boot/compressed/Makefile linux-2.6.6/arch/i386/boot/compressed/Makefile >--- linux-2.6.6.orig/arch/i386/boot/compressed/Makefile 2004-05-10 03:32:54.000000000 +0100 >+++ linux-2.6.6/arch/i386/boot/compressed/Makefile 2004-05-10 12:30:22.841998656 +0100 >@@ -5,6 +5,17 @@ > # > > targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o >+ >+# >+# There is some strange interaction when paging is off, that makes >+# newer v1.1+ Xboxen (manufactured August 2002 or later) crash while >+# decrompressing the kernel. Compiling the decrompressor without any >+# optimization reliably works around this problem. >+# >+ifeq ($(CONFIG_X86_XBOX),y) >+CFLAGS_misc.o := -O0 >+endif >+ > EXTRA_AFLAGS := -traditional > > LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 >diff -urN linux-2.6.6.orig/arch/i386/kernel/Makefile linux-2.6.6/arch/i386/kernel/Makefile >--- linux-2.6.6.orig/arch/i386/kernel/Makefile 2004-05-10 03:32:02.000000000 +0100 >+++ linux-2.6.6/arch/i386/kernel/Makefile 2004-05-10 12:30:22.864995160 +0100 >@@ -25,6 +25,7 @@ > obj-$(CONFIG_X86_IO_APIC) += io_apic.o > obj-$(CONFIG_X86_NUMAQ) += numaq.o > obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o >+obj-$(CONFIG_XBOX_EJECT) += xboxejectfix.o > obj-$(CONFIG_MODULES) += module.o > obj-y += sysenter.o vsyscall.o > obj-$(CONFIG_ACPI_SRAT) += srat.o >diff -urN linux-2.6.6.orig/arch/i386/kernel/xboxejectfix.c linux-2.6.6/arch/i386/kernel/xboxejectfix.c >--- linux-2.6.6.orig/arch/i386/kernel/xboxejectfix.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/arch/i386/kernel/xboxejectfix.c 2004-05-10 12:30:22.867994704 +0100 >@@ -0,0 +1,147 @@ >+/** >+ * Driver that handles the EXTSMI# interrupt on the xbox. >+ * Makes it possible to use the eject-button without the xbox rebooting... >+ * >+ * smbus-command sequence to prevent reboot from cromwell. >+ * >+ * Changelog: >+ * 2003-01-14 Anders Gustafsson <andersg@0x63.nu> >+ * initial version >+ * 2003-02-08 Milosch Meriac <xboxlinux@meriac.de> >+ * rewrote debug macros because of compiler errors >+ * 2003-08-06 Michael Steil <mist@c64.org> >+ * removed Linux I2C dependency, now compiles >+ * without I2C in the kernel >+ * >+ * Todo: add errorhandling! >+ * >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/init.h> >+#include <asm/io.h> >+#include <linux/xbox.h> >+#include <linux/interrupt.h> >+ >+#define IRQ 12 >+#define DRIVER_NAME "xboxejectfix" >+ >+/* just some crap */ >+static char dev[]=DRIVER_NAME; >+ >+/* External variable from ide-cd.c that specifies whether we simulate drive >+ locking in software */ >+extern volatile int Xbox_simulate_drive_locked; >+ >+#define BASE 0x8000 >+ >+/* Power Management 1 Enable Register */ >+#define PM02 (BASE+0x02) >+ >+/* Power Management 1 Control Register */ >+#define PM04 (BASE+0x04) >+ >+/* ACPI GP Status Register */ >+#define PM20 (BASE+0x20) >+ >+/* ACPI GP Enable Register */ >+#define PM22 (BASE+0x22) >+# define EXTSMI_EN_MASK 0x0002 >+ >+/* Global SMI Enable Register */ >+#define PM2A (BASE+0x2A) >+ >+ >+static DECLARE_MUTEX(extsmi_sem); >+static DECLARE_COMPLETION(extsmi_exited); >+static int extsmi_pid=0; >+ >+static irqreturn_t extsmi_interupt(int unused, void *dev_id, struct pt_regs *regs) { >+ int reason; >+ >+ reason=inw(0x8020); >+ outw(reason,0x8020); /* ack IS THIS NEEDED? */ >+ if(reason&0x2){ >+ /* wake up thread */ >+ up(&extsmi_sem); >+ } >+ return 0; >+} >+ >+/** >+ * Process an event. This is run in process-context. >+ */ >+static void extsmi_process(void){ >+ int reason; >+ reason=Xbox_SMC_read(SMC_CMD_INTERRUPT_REASON); >+ >+ if(reason&TRAYBUTTON_MASK){ /* Tray button! Respond to prevent reboot! */ >+ Xbox_SMC_write(SMC_CMD_INTERRUPT_RESPOND, SMC_SUBCMD_RESPOND_CONTINUE); >+ Xbox_SMC_write(0x00, 0x0c); >+ /* eject unless lock simulation is being used */ >+ if (!Xbox_simulate_drive_locked) >+ Xbox_tray_eject(); >+ } >+} >+ >+static int extsmi_thread(void *data){ >+ daemonize("extsmi"); >+ reparent_to_init(); >+ strcpy(current->comm, "xbox_extsmi"); >+ >+ do { >+ extsmi_process(); >+ down_interruptible(&extsmi_sem); >+ } while (!signal_pending(current)); >+ >+ complete_and_exit(&extsmi_exited, 0); >+} >+ >+static int extsmi_init(void){ >+ int pid; >+ >+ if (!machine_is_xbox) { >+ printk("This machine is no Xbox.\n"); >+ return -1; >+ } >+ printk("Enabling Xbox eject problem workaround.\n"); >+ >+ pid = kernel_thread(extsmi_thread, NULL, >+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND); >+ if (pid < 0) { >+ return pid; >+ } >+ >+ extsmi_pid = pid; >+ >+ /* this shuts a lot of interrupts off! */ >+ outw(inw(0x80e2)&0xf8c7,0x80e2); >+ outw(0,0x80ac); >+ outb(0,0x8025); >+ outw(EXTSMI_EN_MASK,PM22); /* enable the EXTSMI# interupt! */ >+ outw(0,PM02); >+ outb(1,PM04); /* enable sci interrupts! */ >+ Xbox_SMC_write(SMC_CMD_RESET_ON_EJECT, SMC_SUBCMD_RESET_ON_EJECT_DISABLE); >+ >+ /* FIXME! retval! */ >+ request_irq(IRQ,extsmi_interupt,SA_INTERRUPT|SA_SHIRQ,"xboxejectfix",dev); >+ return 0; >+} >+ >+static void extsmi_exit(void){ >+ int res; >+ if (!machine_is_xbox) return; /* can this happen??? */ >+ free_irq(IRQ,dev); >+ >+ /* Kill the thread */ >+ res = kill_proc(extsmi_pid, SIGTERM, 1); >+ wait_for_completion(&extsmi_exited); >+ return; >+} >+ >+module_init(extsmi_init); >+module_exit(extsmi_exit); >+ >+MODULE_AUTHOR("Anders Gustafsson <andersg@0x63.nu>"); >+MODULE_LICENSE("GPL"); >diff -urN linux-2.6.6.orig/arch/i386/mach-xbox/Makefile linux-2.6.6/arch/i386/mach-xbox/Makefile >--- linux-2.6.6.orig/arch/i386/mach-xbox/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/arch/i386/mach-xbox/Makefile 2004-05-10 12:30:22.869994400 +0100 >@@ -0,0 +1,5 @@ >+# >+# Makefile for the linux kernel. >+# >+ >+obj-y := setup.o reboot.o >diff -urN linux-2.6.6.orig/arch/i386/mach-xbox/reboot.c linux-2.6.6/arch/i386/mach-xbox/reboot.c >--- linux-2.6.6.orig/arch/i386/mach-xbox/reboot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/arch/i386/mach-xbox/reboot.c 2004-05-10 12:30:22.871994096 +0100 >@@ -0,0 +1,51 @@ >+/* >+ * arch/i386/mach-xbox/reboot.c >+ * Olivier Fauchon <olivier.fauchon@free.fr> >+ * Anders Gustafsson <andersg@0x63.nu> >+ * >+ */ >+ >+#include <asm/io.h> >+ >+/* we don't use any of those, but dmi_scan.c needs 'em */ >+void (*pm_power_off)(void); >+int reboot_thru_bios; >+ >+#define XBOX_SMB_IO_BASE 0xC000 >+#define XBOX_SMB_HOST_ADDRESS (0x4 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_HOST_COMMAND (0x8 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_HOST_DATA (0x6 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_GLOBAL_ENABLE (0x2 + XBOX_SMB_IO_BASE) >+ >+#define XBOX_PIC_ADDRESS 0x10 >+ >+#define SMC_CMD_POWER 0x02 >+#define SMC_SUBCMD_POWER_RESET 0x01 >+#define SMC_SUBCMD_POWER_CYCLE 0x40 >+#define SMC_SUBCMD_POWER_OFF 0x80 >+ >+ >+static void xbox_pic_cmd(u8 command) >+{ >+ outw_p(((XBOX_PIC_ADDRESS) << 1), XBOX_SMB_HOST_ADDRESS); >+ outb_p(SMC_CMD_POWER, XBOX_SMB_HOST_COMMAND); >+ outw_p(command, XBOX_SMB_HOST_DATA); >+ outw_p(inw(XBOX_SMB_IO_BASE), XBOX_SMB_IO_BASE); >+ outb_p(0x0a, XBOX_SMB_GLOBAL_ENABLE); >+} >+ >+void machine_restart(char * __unused) >+{ >+ printk(KERN_INFO "Sending POWER_CYCLE to XBOX-PIC.\n"); >+ xbox_pic_cmd(SMC_SUBCMD_POWER_CYCLE); >+} >+ >+void machine_power_off(void) >+{ >+ printk(KERN_INFO "Sending POWER_OFF to XBOX-PIC.\n"); >+ xbox_pic_cmd(SMC_SUBCMD_POWER_OFF); >+} >+ >+void machine_halt(void) >+{ >+} >diff -urN linux-2.6.6.orig/arch/i386/mach-xbox/setup.c linux-2.6.6/arch/i386/mach-xbox/setup.c >--- linux-2.6.6.orig/arch/i386/mach-xbox/setup.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/arch/i386/mach-xbox/setup.c 2004-05-10 12:30:22.873993792 +0100 >@@ -0,0 +1,84 @@ >+/* >+ * Machine specific setup for xbox >+ */ >+ >+#include <linux/config.h> >+#include <linux/smp.h> >+#include <linux/init.h> >+#include <linux/irq.h> >+#include <linux/interrupt.h> >+#include <asm/arch_hooks.h> >+ >+/** >+ * pre_intr_init_hook - initialisation prior to setting up interrupt vectors >+ * >+ * Description: >+ * Perform any necessary interrupt initialisation prior to setting up >+ * the "ordinary" interrupt call gates. For legacy reasons, the ISA >+ * interrupts should be initialised here if the machine emulates a PC >+ * in any way. >+ **/ >+void __init pre_intr_init_hook(void) >+{ >+ init_ISA_irqs(); >+} >+ >+/* >+ * IRQ2 is cascade interrupt to second interrupt controller >+ */ >+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; >+ >+/** >+ * intr_init_hook - post gate setup interrupt initialisation >+ * >+ * Description: >+ * Fill in any interrupts that may have been left out by the general >+ * init_IRQ() routine. interrupts having to do with the machine rather >+ * than the devices on the I/O bus (like APIC interrupts in intel MP >+ * systems) are started here. >+ **/ >+void __init intr_init_hook(void) >+{ >+#ifdef CONFIG_X86_LOCAL_APIC >+ apic_intr_init(); >+#endif >+ >+ setup_irq(2, &irq2); >+} >+ >+/** >+ * pre_setup_arch_hook - hook called prior to any setup_arch() execution >+ * >+ * Description: >+ * generally used to activate any machine specific identification >+ * routines that may be needed before setup_arch() runs. On VISWS >+ * this is used to get the board revision and type. >+ **/ >+void __init pre_setup_arch_hook(void) >+{ >+} >+ >+/** >+ * trap_init_hook - initialise system specific traps >+ * >+ * Description: >+ * Called as the final act of trap_init(). Used in VISWS to initialise >+ * the various board specific APIC traps. >+ **/ >+void __init trap_init_hook(void) >+{ >+} >+ >+static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL }; >+ >+/** >+ * time_init_hook - do any specific initialisations for the system timer. >+ * >+ * Description: >+ * Must plug the system timer interrupt source at HZ into the IRQ listed >+ * in irq_vectors.h:TIMER_IRQ >+ **/ >+void __init time_init_hook(void) >+{ >+ setup_irq(0, &irq0); >+} >diff -urN linux-2.6.6.orig/arch/i386/pci/direct.c linux-2.6.6/arch/i386/pci/direct.c >--- linux-2.6.6.orig/arch/i386/pci/direct.c 2004-05-10 03:32:26.000000000 +0100 >+++ linux-2.6.6/arch/i386/pci/direct.c 2004-05-10 12:30:22.890991208 +0100 >@@ -4,6 +4,7 @@ > > #include <linux/pci.h> > #include <linux/init.h> >+#include "mach_pci_blacklist.h" > #include "pci.h" > > /* >@@ -20,6 +21,9 @@ > if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) > return -EINVAL; > >+ if (mach_pci_is_blacklisted(bus, PCI_SLOT(devfn), PCI_FUNC(devfn))) >+ return -EINVAL; >+ > spin_lock_irqsave(&pci_config_lock, flags); > > outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); >diff -urN linux-2.6.6.orig/drivers/i2c/busses/Kconfig linux-2.6.6/drivers/i2c/busses/Kconfig >--- linux-2.6.6.orig/drivers/i2c/busses/Kconfig 2004-05-10 03:33:13.000000000 +0100 >+++ linux-2.6.6/drivers/i2c/busses/Kconfig 2004-05-10 12:30:22.908988472 +0100 >@@ -49,6 +49,10 @@ > This driver can also be built as a module. If so, the module > will be called i2c-amd756. > >+config I2C_XBOX >+ tristate "XBOX I2C" >+ depends on I2C && EXPERIMENTAL >+ > config I2C_AMD8111 > tristate "AMD 8111" > depends on I2C && EXPERIMENTAL >diff -urN linux-2.6.6.orig/drivers/i2c/busses/Makefile linux-2.6.6/drivers/i2c/busses/Makefile >--- linux-2.6.6.orig/drivers/i2c/busses/Makefile 2004-05-10 03:32:00.000000000 +0100 >+++ linux-2.6.6/drivers/i2c/busses/Makefile 2004-05-10 12:30:22.915987408 +0100 >@@ -6,6 +6,7 @@ > obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o > obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o > obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o >+obj-$(CONFIG_I2C_XBOX) += i2c-xbox.o > obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o > obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o > obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o >diff -urN linux-2.6.6.orig/drivers/i2c/busses/i2c-xbox.c linux-2.6.6/drivers/i2c/busses/i2c-xbox.c >--- linux-2.6.6.orig/drivers/i2c/busses/i2c-xbox.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/i2c/busses/i2c-xbox.c 2004-05-10 12:30:22.919986800 +0100 >@@ -0,0 +1,417 @@ >+/* >+ i2c-xbox.c - Part of lm_sensors, Linux kernel modules for hardware >+ monitoring >+ >+ Copyright (c) 1999-2002 Edgar Hucek <hostmaster@ed-soft.at> >+ >+ Shamelessly ripped from i2c-xbox.c: >+ >+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. >+*/ >+ >+/* >+ Supports XBOX, Note: we assume there can only be one device, with one SMBus interface. >+*/ >+ >+#include <linux/version.h> >+#include <linux/module.h> >+#include <linux/pci.h> >+#include <asm/io.h> >+#include <linux/kernel.h> >+#include <linux/stddef.h> >+#include <linux/sched.h> >+#include <linux/ioport.h> >+#include <linux/i2c.h> >+#include <linux/init.h> >+ >+#include <linux/sched.h> >+#include <linux/errno.h> /* error codes */ >+#include <linux/interrupt.h> /* intr_count */ >+#include <linux/xbox.h> >+#include <linux/delay.h> >+ >+ >+#define GS_ABRT_STS (1 << 0) >+#define GS_COL_STS (1 << 1) >+#define GS_PRERR_STS (1 << 2) >+#define GS_HST_STS (1 << 3) >+#define GS_IRQ_ON (1 << 4) >+#define GS_HCYC_STS (1 << 4) >+#define GS_TO_STS (1 << 5) >+#define GS_SMB_STS (1 << 11) >+ >+#define SMB_GCTL_HOST_START (1 << 3) >+#define SMB_GCTL_HOST_INTERRUPT (1 << 4) >+#define SMB_GCTL_ABORT (1 << 5) >+#define SMB_GCTL_SNOOP (1 << 8) >+#define SMB_GCTL_SLAVE_INTERRUPT (1 << 9) >+#define SMB_GCTL_ALERT_INTERRUPT (1 << 10) >+ >+#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \ >+ GS_HCYC_STS | GS_TO_STS) >+ >+#define GE_CYC_TYPE_MASK (7) >+#define GE_HOST_STC (1 << 3) >+#define GE_ABORT (1 << 5) >+ >+#define I2C_HW_SMBUS_XBOX 0x05 >+#define SMBGCFG 0x041 /* mh */ >+#define SMBBA 0x058 /* mh */ >+ >+struct sd { >+ const unsigned short vendor; >+ const unsigned short device; >+ const unsigned short function; >+ const char* name; >+ int amdsetup:1; >+}; >+ >+static struct sd supported[] = { >+ {PCI_VENDOR_ID_NVIDIA, 0x01b4, 1, "nVidia XBOX nForce", 0}, >+ {0, 0, 0} >+}; >+ >+/* XBOX SMBus address offsets */ >+#define SMB_ADDR_OFFSET 0x04 >+#define SMB_IOSIZE 8 >+#define SMB_GLOBAL_STATUS (0x0 + xbox_smba) >+#define SMB_GLOBAL_ENABLE (0x2 + xbox_smba) >+#define SMB_HOST_ADDRESS (0x4 + xbox_smba) >+#define SMB_HOST_DATA (0x6 + xbox_smba) >+#define SMB_HOST_COMMAND (0x8 + xbox_smba) >+ >+ >+ >+ >+ >+/* Other settings */ >+#define MAX_TIMEOUT 500 >+ >+/* XBOX constants */ >+#define XBOX_QUICK 0x00 >+#define XBOX_BYTE 0x01 >+#define XBOX_BYTE_DATA 0x02 >+#define XBOX_WORD_DATA 0x03 >+#define XBOX_PROCESS_CALL 0x04 >+#define XBOX_BLOCK_DATA 0x05 >+ >+/* insmod parameters */ >+ >+#ifdef MODULE >+static >+#else >+extern >+#endif >+int __init i2c_xbox_init(void); >+static int __init xbox_cleanup(void); >+static int xbox_setup(void); >+static s32 xbox_access(struct i2c_adapter *adap, u16 addr, >+ unsigned short flags, char read_write, >+ u8 command, int size, union i2c_smbus_data *data); >+static void xbox_do_pause(unsigned int amount); >+static void xbox_abort(void); >+static int xbox_transaction(void); >+static u32 xbox_func(struct i2c_adapter *adapter); >+ >+static struct i2c_algorithm smbus_algorithm = { >+ /* name */ "Non-I2C SMBus adapter", >+ /* id */ I2C_ALGO_SMBUS, >+ /* master_xfer */ NULL, >+ /* smbus_access */ xbox_access, >+ /* slave;_send */ NULL, >+ /* slave_rcv */ NULL, >+ /* algo_control */ NULL, >+ /* functionality */ xbox_func, >+}; >+ >+static struct i2c_adapter xbox_adapter = { >+ .owner = THIS_MODULE, >+ .class = I2C_ADAP_CLASS_SMBUS, >+ .algo = &smbus_algorithm, >+ .name = "unset", >+}; >+ >+static int __initdata xbox_initialized; >+static unsigned short xbox_smba = 0; >+spinlock_t xbox_driver_lock = SPIN_LOCK_UNLOCKED; >+struct driver_data; >+static struct pci_dev *XBOX_dev; >+ >+/* Detect whether a XBOX can be found, and initialize it, where necessary. >+ Note the differences between kernels with the old PCI BIOS interface and >+ newer kernels with the real PCI interface. In compat.h some things are >+ defined to make the transition easier. */ >+int xbox_setup(void) >+{ >+ unsigned char temp; >+ struct sd *currdev; >+ u16 cmd; >+ >+ XBOX_dev = NULL; >+ >+ /* Look for a supported chip */ >+ for(currdev = supported; currdev->vendor; ) { >+ XBOX_dev = pci_find_device(currdev->vendor, >+ currdev->device, XBOX_dev); >+ if (XBOX_dev != NULL) { >+ pci_read_config_byte(XBOX_dev, SMBGCFG, &temp); >+ pci_read_config_word(XBOX_dev, 0x14, &xbox_smba); >+ >+ xbox_smba &= 0xfffc; >+ if (PCI_FUNC(XBOX_dev->devfn) == currdev->function) >+ { >+ pci_read_config_word(XBOX_dev,PCI_STATUS,&cmd); >+ break; >+ } >+ } else { >+ currdev++; >+ } >+ } >+ >+ if (XBOX_dev == NULL) { >+ printk >+ ("i2c-xbox.o: Error: No XBOX or compatible device detected!\n"); >+ return(-ENODEV); >+ } >+ printk(KERN_INFO "i2c-xbox.o: Found %s SMBus controller.\n", currdev->name); >+ >+ /* Everything is happy, let's grab the memory and set things up. */ >+ if(!request_region(xbox_smba, SMB_IOSIZE, "xbox-smbus")) { >+ printk >+ ("i2c-xbox.o: SMB region 0x%x already in use!\n", >+ xbox_smba); >+ return(-ENODEV); >+ } >+ >+ return 0; >+} >+ >+/* >+ SMBUS event = I/O 28-29 bit 11 >+ see E0 for the status bits and enabled in E2 >+ >+*/ >+ >+/* Internally used pause function */ >+void xbox_do_pause(unsigned int amount) >+{ >+ current->state = TASK_INTERRUPTIBLE; >+ schedule_timeout(amount); >+} >+ >+void xbox_abort(void) >+{ >+ printk("i2c-xbox.o: Sending abort.\n"); >+ outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); >+ xbox_do_pause(100); >+ outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); >+} >+ >+int xbox_transaction(void) >+{ >+ int temp; >+ int result = 0; >+ int timeout = 0; >+ >+ /* Make sure the SMBus host is ready to start transmitting */ >+ if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) { >+ do { >+ udelay(100); >+ temp = inw_p(SMB_GLOBAL_STATUS); >+ } while ((temp & (GS_HST_STS | GS_SMB_STS)) && >+ (timeout++ < MAX_TIMEOUT)); >+ /* If the SMBus is still busy, we give up */ >+ if (timeout >= MAX_TIMEOUT) { >+ printk("i2c-xbox.o: Busy wait timeout! (%04x)\n", temp); >+ xbox_abort(); >+ return(-1); >+ } >+ timeout = 0; >+ } >+ >+ /* start the transaction by setting the start bit */ >+ outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC , SMB_GLOBAL_ENABLE); >+ >+ /* We will always wait for a fraction of a second! */ >+ temp = inw_p(SMB_GLOBAL_STATUS); >+ while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT)) { >+ udelay(100); >+ temp = inw_p(SMB_GLOBAL_STATUS); >+ } >+ >+ /* If the SMBus is still busy, we give up */ >+ if (timeout >= MAX_TIMEOUT) { >+ printk("i2c-xbox.o: Completion timeout!\n"); >+ xbox_abort (); >+ return(-1); >+ } >+ >+ if (temp & GS_PRERR_STS) { >+ result = -1; >+ } >+ >+ if (temp & GS_COL_STS) { >+ result = -1; >+ printk("i2c-xbox.o: SMBus collision!\n"); >+ } >+ >+ if (temp & GS_TO_STS) { >+ result = -1; >+ } >+ outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); >+ >+ return result; >+} >+ >+/* Return -1 on error. */ >+s32 xbox_access(struct i2c_adapter * adap, u16 addr, >+ unsigned short flags, char read_write, >+ u8 command, int size, union i2c_smbus_data * data) >+{ >+ /** TODO: Should I supporte the 10-bit transfers? */ >+ switch (size) { >+ case I2C_SMBUS_PROC_CALL: >+ printk >+ ("i2c-xbox.o: I2C_SMBUS_PROC_CALL not supported!\n"); >+ /* TODO: Well... It is supported, I'm just not sure what to do here... */ >+ return -1; >+ case I2C_SMBUS_QUICK: >+ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), >+ SMB_HOST_ADDRESS); >+ size = XBOX_QUICK; >+ break; >+ case I2C_SMBUS_BYTE: >+ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), >+ SMB_HOST_ADDRESS); >+ /* TODO: Why only during write? */ >+ if (read_write == I2C_SMBUS_WRITE) >+ outb_p(command, SMB_HOST_COMMAND); >+ size = XBOX_BYTE; >+ break; >+ case I2C_SMBUS_BYTE_DATA: >+ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), >+ SMB_HOST_ADDRESS); >+ outb_p(command, SMB_HOST_COMMAND); >+ if (read_write == I2C_SMBUS_WRITE) >+ outw_p(data->byte, SMB_HOST_DATA); >+ size = XBOX_BYTE_DATA; >+ break; >+ case I2C_SMBUS_WORD_DATA: >+ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), >+ SMB_HOST_ADDRESS); >+ outb_p(command, SMB_HOST_COMMAND); >+ if (read_write == I2C_SMBUS_WRITE) >+ outw_p(data->word, SMB_HOST_DATA); /* TODO: endian???? */ >+ size = XBOX_WORD_DATA; >+ break; >+ } >+ >+ /* How about enabling interrupts... */ >+ outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); >+ >+ if (xbox_transaction()) /* Error in transaction */ >+ return -1; >+ >+ if ((read_write == I2C_SMBUS_WRITE) || (size == XBOX_QUICK)) >+ return 0; >+ >+ >+ switch (size) { >+ case XBOX_BYTE: >+ data->byte = inw_p(SMB_HOST_DATA); >+ break; >+ case XBOX_BYTE_DATA: >+ data->byte = inw_p(SMB_HOST_DATA); >+ break; >+ case XBOX_WORD_DATA: >+ data->word = inw_p(SMB_HOST_DATA); /* TODO: endian???? */ >+ break; >+ } >+ >+ return 0; >+} >+ >+u32 xbox_func(struct i2c_adapter *adapter) >+{ >+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | >+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | >+ I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL; >+} >+ >+int __init i2c_xbox_init(void) >+{ >+ int res; >+ printk("i2c-xbox.o version 0.0.1\n"); >+ xbox_initialized = 0; >+ if ((res = xbox_setup())) { >+ printk >+ ("i2c-xbox.o: XBOX or compatible device not detected, module not inserted.\n"); >+ xbox_cleanup(); >+ return res; >+ } >+ xbox_initialized++; >+ sprintf(xbox_adapter.name, "SMBus adapter at %04x",xbox_smba); >+ if ((res = i2c_add_adapter(&xbox_adapter))) { >+ printk >+ ("i2c-xbox.o: Adapter registration failed, module not inserted.\n"); >+ xbox_cleanup(); >+ return res; >+ } >+ xbox_initialized++; >+ printk("i2c-xbox.o: SMBus bus detected and initialized\n"); >+ return 0; >+} >+ >+int __init xbox_cleanup(void) >+{ >+ int res; >+ if (xbox_initialized >= 2) { >+ if ((res = i2c_del_adapter(&xbox_adapter))) { >+ printk >+ ("i2c-xbox.o: i2c_del_adapter failed, module not removed\n"); >+ return res; >+ } else >+ xbox_initialized--; >+ } >+ if (xbox_initialized >= 1) { >+ release_region(xbox_smba, SMB_IOSIZE); >+ xbox_initialized--; >+ } >+ free_irq(XBOX_dev->irq, XBOX_dev); >+ return 0; >+} >+ >+EXPORT_SYMBOL(i2c_xbox_init); >+ >+#ifdef MODULE >+ >+MODULE_AUTHOR("Edgar Hucek <hostmaster@ed-soft.at>"); >+MODULE_DESCRIPTION("XBOX nForce SMBus driver"); >+ >+#ifdef MODULE_LICENSE >+MODULE_LICENSE("GPL"); >+#endif >+ >+int init_module(void) >+{ >+ return i2c_xbox_init(); >+} >+ >+void cleanup_module(void) >+{ >+ xbox_cleanup(); >+} >+ >+#endif /* MODULE */ >diff -urN linux-2.6.6.orig/drivers/ide/ide-cd.c linux-2.6.6/drivers/ide/ide-cd.c >--- linux-2.6.6.orig/drivers/ide/ide-cd.c 2004-05-10 03:32:29.000000000 +0100 >+++ linux-2.6.6/drivers/ide/ide-cd.c 2004-05-10 12:30:22.952981784 +0100 >@@ -324,6 +324,14 @@ > > #include "ide-cd.h" > >+#ifdef CONFIG_X86_XBOX >+#include <linux/xbox.h> >+/* Global flag indicating whether to simulate Xbox drive locking in >+ * software. There should only be one Xbox drive in a system! This >+ * variable is externally referenced by arch/i386/kernel/xboxejectfix.c. */ >+volatile int Xbox_simulate_drive_locked = 0; >+#endif /* CONFIG_X86_XBOX */ >+ > /**************************************************************************** > * Generic packet command support and error handling routines. > */ >@@ -2121,6 +2129,16 @@ > if (sense == NULL) > sense = &my_sense; > >+#ifdef CONFIG_X86_XBOX >+ /* If we're on an Xbox and this is an Xbox drive, simulate the lock >+ request in software. (See arch/i386/kernel/xboxejectfix.c) */ >+ if (CDROM_CONFIG_FLAGS(drive)->xbox_drive && machine_is_xbox) { >+ CDROM_STATE_FLAGS(drive)->door_locked = lockflag; >+ Xbox_simulate_drive_locked = lockflag; >+ return 0; >+ } >+#endif /* CONFIG_X86_XBOX */ >+ > /* If the drive cannot lock the door, just pretend. */ > if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) { > stat = 0; >@@ -2169,6 +2187,23 @@ > if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag) > return 0; > >+#ifdef CONFIG_X86_XBOX >+ /* Older Xbox DVD drives don't understand the ATAPI command, but the SMC >+ can do the eject. Note that some Xbox drives support the eject >+ command, namely the Samsung, so for that drive we do a regular eject >+ sequence. */ >+ if (machine_is_xbox && CDROM_CONFIG_FLAGS(drive)->xbox_drive && >+ CDROM_CONFIG_FLAGS(drive)->xbox_eject) { >+ if (ejectflag) { >+ Xbox_tray_load(); >+ } else { >+ Xbox_simulate_drive_locked = 0; >+ Xbox_tray_eject(); >+ } >+ return 0; >+ } >+#endif >+ > cdrom_prepare_request(&req); > > /* only tell drive to close tray if open, if it can do that */ >@@ -3258,6 +3293,67 @@ > /* uses CD in slot 0 when value is set to 3 */ > cdi->sanyo_slot = 3; > } >+#ifdef CONFIG_X86_XBOX >+ /* THOMSON DVD drives in the Xbox report incorrect capabilities >+ and do not understand the ATAPI eject command, but the SMC >+ can do the eject. */ >+ else if ((strcmp(drive->id->model, "THOMSON-DVD") == 0)) { >+ CDROM_CONFIG_FLAGS(drive)->audio_play = 1; >+ CDROM_CONFIG_FLAGS(drive)->dvd = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1; >+ } >+ /* PHILIPS drives in Xboxen manufactured pre September 2003, >+ report correct capabilities, but do not understand the ATAPI >+ eject command, hence require the SMC to do so. */ >+ else if ((strcmp(drive->id->model, "PHILIPS XBOX DVD DRIVE") == 0)) { >+ CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1; >+ } >+ /* PHILIPS drives in Xboxen manufactured post September 2003, >+ report incorrect capabilities, but understand the ATAPI >+ eject command. */ >+ else if ((strcmp(drive->id->model, "PHILIPS J5 3235C") == 0)) { >+ CDROM_CONFIG_FLAGS(drive)->audio_play = 1; >+ CDROM_CONFIG_FLAGS(drive)->dvd = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0; >+ } >+ /* SAMSUNG drives in the Xbox report correct capabilities >+ and understand the ATAPI eject command. */ >+ else if (strcmp(drive->id->model, "SAMSUNG DVD-ROM SDG-605B") == 0) { >+ CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1; >+ CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0; >+ } >+#endif >+ >+ /* Is an Xbox drive detected? */ >+#ifdef CONFIG_X86_XBOX >+ if (CDROM_CONFIG_FLAGS(drive)->xbox_drive) { >+#endif >+ /* If an Xbox drive is present in a regular PC, we can't eject. >+ Act like the drive cannot eject, unless the ATAPI eject command >+ is supported by the drive. If the drive doesn't support ATAPI >+ ejecting, act like door locking is impossible as well. */ >+#ifdef CONFIG_X86_XBOX >+ if (!machine_is_xbox) { >+#endif /* CONFIG_X86_XBOX */ >+ CDROM_CONFIG_FLAGS(drive)->no_doorlock = CDROM_CONFIG_FLAGS >+ (drive)->xbox_eject; >+ CDROM_CONFIG_FLAGS(drive)->no_eject = CDROM_CONFIG_FLAGS(drive) >+ ->xbox_eject; >+#ifdef CONFIG_X86_XBOX >+ } else { >+ /* An Xbox drive in an Xbox. We can support ejecting through >+ the SMC and support drive locking in software by ignoring >+ the eject interrupt (see arch/i386/kernel/xboxejectfix.c). */ >+ CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0; >+ CDROM_CONFIG_FLAGS(drive)->no_eject = 0; >+ Xbox_simulate_drive_locked = 0; >+ } >+#endif >+ } >+ > #endif /* not STANDARD_ATAPI */ > > info->toc = NULL; >diff -urN linux-2.6.6.orig/drivers/ide/ide-cd.h linux-2.6.6/drivers/ide/ide-cd.h >--- linux-2.6.6.orig/drivers/ide/ide-cd.h 2004-05-10 03:33:21.000000000 +0100 >+++ linux-2.6.6/drivers/ide/ide-cd.h 2004-05-10 12:30:22.962980264 +0100 >@@ -93,6 +93,10 @@ > __u8 close_tray : 1; /* can close the tray */ > __u8 writing : 1; /* pseudo write in progress */ > __u8 mo_drive : 1; /* drive is an MO device */ >+#ifdef CONFIG_X86_XBOX >+ __u8 xbox_drive : 1; /* drive is an Xbox drive */ >+ __u8 xbox_eject : 1; /* use Xbox SMC eject mechanism */ >+#endif > __u8 reserved : 2; > byte max_speed; /* Max speed of the drive */ > }; >diff -urN linux-2.6.6.orig/drivers/pci/pci.ids linux-2.6.6/drivers/pci/pci.ids >--- linux-2.6.6.orig/drivers/pci/pci.ids 2004-05-10 03:32:37.000000000 +0100 >+++ linux-2.6.6/drivers/pci/pci.ids 2004-05-10 12:30:23.026970536 +0100 >@@ -2856,6 +2856,7 @@ > 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x] > 0288 NV28GL [Quadro4 980 XGL] > 0289 NV28GL [Quadro4 780 XGL] >+ 02a0 NV16 [GeForce3 MX - nForce GPU] > 0300 NV30 [GeForce FX] > 0301 NV30 [GeForce FX 5800 Ultra] > 0302 NV30 [GeForce FX 5800] >diff -urN linux-2.6.6.orig/drivers/usb/input/Kconfig linux-2.6.6/drivers/usb/input/Kconfig >--- linux-2.6.6.orig/drivers/usb/input/Kconfig 2004-05-10 03:33:08.000000000 +0100 >+++ linux-2.6.6/drivers/usb/input/Kconfig 2004-05-10 12:30:23.059965520 +0100 >@@ -192,19 +192,29 @@ > module will be called mtouchusb. > > config USB_XPAD >- tristate "X-Box gamepad support" >+ tristate "X-Box controller (gamepad) support" > depends on USB && INPUT > ---help--- >- Say Y here if you want to use the X-Box pad with your computer. >+ Say Y here if you want to use Xbox controllers with your computer. > Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV) > and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. > >- For information about how to connect the X-Box pad to USB, see >+ For information about how to connect an Xbox controller to USB, see > <file:Documentation/input/xpad.txt>. > > To compile this driver as a module, choose M here: the > module will be called xpad. > >+config USB_XPAD_MOUSE >+ bool "Mouse emulation for Xbox controller" >+ depends on USB_XPAD >+ ---help--- >+ Say Y here if you want to enable mouse emulation for your Xbox >+ controller. >+ Make sure to say Y to "Mouse support" (CONFIG_INPUT_MOUSEDEV) >+ and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. >+ >+ > config USB_ATI_REMOTE > tristate "ATI USB RF remote control" > depends on USB && INPUT >diff -urN linux-2.6.6.orig/drivers/usb/input/Makefile linux-2.6.6/drivers/usb/input/Makefile >--- linux-2.6.6.orig/drivers/usb/input/Makefile 2004-05-10 03:32:52.000000000 +0100 >+++ linux-2.6.6/drivers/usb/input/Makefile 2004-05-10 12:32:01.583987592 +0100 >@@ -4,6 +4,7 @@ > > # Multipart objects. > usbhid-objs := hid-core.o >+xpad-objs := xpad-core.o > > # Optional parts of multipart objects. > >@@ -26,6 +27,10 @@ > usbhid-objs += hid-ff.o > endif > >+ifeq ($(CONFIG_USB_XPAD_MOUSE),y) >+ xpad-objs += xpad-mouse.o >+endif >+ > obj-$(CONFIG_USB_AIPTEK) += aiptek.o > obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o > obj-$(CONFIG_USB_HID) += usbhid.o >diff -urN linux-2.6.6.orig/drivers/usb/input/xpad-core.c linux-2.6.6/drivers/usb/input/xpad-core.c >--- linux-2.6.6.orig/drivers/usb/input/xpad-core.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/usb/input/xpad-core.c 2004-05-10 12:30:23.070963848 +0100 >@@ -0,0 +1,579 @@ >+/* >+ * Xbox input device driver for Linux - v0.1.4 >+ * >+ * Copyright (c) 2002 - 2004 Marko Friedemann <mfr@bmx-chemnitz.de> >+ * >+ * Contributors: >+ * Vojtech Pavlik <vojtech@suse.sz>, >+ * Oliver Schwartz <Oliver.Schwartz@gmx.de>, >+ * Steven Toth <steve@toth.demon.co.uk>, >+ * Franz Lehner <franz@caos.at>, >+ * Ivan Hawkes <blackhawk@ivanhawkes.com> >+ * >+ * >+ * 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 >+ * >+ * >+ * This driver is based on: >+ * - information from http://euc.jp/periphs/xbox-controller.en.html >+ * - the iForce driver drivers/char/joystick/iforce.c >+ * - the skeleton-driver drivers/usb/usb-skeleton.c >+ * >+ * Thanks to: >+ * - ITO Takayuki for providing essential xpad information on his website >+ * - Vojtech Pavlik - iforce driver / input subsystem >+ * - Greg Kroah-Hartman - usb-skeleton driver >+ * >+ * TODO: >+ * - fine tune axes >+ * - fine tune mouse behaviour (should not do linear acceleration) >+ * - NEW: get rumble working correctly, fix all the bugs and support multiple >+ * simultaneous effects >+ * - NEW: split funtionality mouse/joustick into two source files >+ * - NEW: implement /proc interface (toggle mouse/rumble enable/disable, etc.) >+ * - NEW: implement user space daemon application that handles that interface >+ * >+ * History: moved to end of file >+ */ >+ >+#include <linux/config.h> >+#include <linux/kernel.h> >+#include <linux/init.h> >+#include <linux/slab.h> >+#include <linux/module.h> >+#include <linux/smp_lock.h> >+#include <linux/usb.h> >+#include <linux/version.h> >+#include <linux/timer.h> >+#include <asm/uaccess.h> >+ >+#include "xpad.h" >+ >+static struct xpad_device xpad_device[] = { >+ /* please keep those ordered wrt. vendor/product ids >+ vendor, product, isMat, name */ >+ { 0x044f, 0x0f07, 0, "Thrustmaster, Inc. Controller" }, >+ { 0x045e, 0x0202, 0, "Microsoft Xbox Controller" }, >+ { 0x045e, 0x0285, 0, "Microsoft Xbox Controller S" }, >+ { 0x045e, 0x0289, 0, "Microsoft Xbox Controller S" }, /* microsoft is stupid */ >+ { 0x046d, 0xca88, 0, "Logitech Compact Controller for Xbox" }, >+ { 0x05fd, 0x1007, 0, "???Mad Catz Controller???" }, /* CHECKME: this seems strange */ >+ { 0x05fd, 0x107a, 0, "InterAct PowerPad Pro" }, >+ { 0x0738, 0x4516, 0, "Mad Catz Control Pad" }, >+ { 0x0738, 0x4522, 0, "Mad Catz LumiCON" }, >+ { 0x0738, 0x4526, 0, "Mad Catz Control Pad Pro" }, >+ { 0x0738, 0x4536, 0, "Mad Catz MicroCON" }, >+ { 0x0738, 0x4540, 1, "Mad Catz Beat Pad" }, >+ { 0x0738, 0x4556, 0, "Mad Catz Lynx Wireless Controller" }, >+ { 0x0738, 0x6040, 1, "Mad Catz Beat Pad Pro" }, >+ { 0x0c12, 0x9902, 0, "HAMA VibraX - *FAULTY HARDWARE*" }, /* these are broken */ >+ { 0x0e4c, 0x2390, 0, "Radica Games Jtech Controller"}, >+ { 0x0e6f, 0x0003, 0, "Logic3 Freebird wireless Controller" }, >+ { 0x0f30, 0x0202, 0, "Joytech Advanced Controller" }, >+ { 0x12ab, 0x8809, 1, "Xbox DDR dancepad" }, >+ { 0xffff, 0xffff, 0, "Chinese-made Xbox Controller" }, /* WTF are device IDs for? */ >+ { 0x0000, 0x0000, 0, "nothing detected - FAIL" } >+}; >+ >+static signed short xpad_btn[] = { >+ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* analogue buttons */ >+ BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ >+ BTN_0, BTN_1, BTN_2, BTN_3, /* d-pad as buttons */ >+ -1 /* terminating entry */ >+}; >+ >+static signed short xpad_mat_btn[] = { >+ BTN_A, BTN_B, BTN_X, BTN_Y, /* A, B, X, Y */ >+ BTN_START, BTN_BACK, /* start/back */ >+ BTN_0, BTN_1, BTN_2, BTN_3, /* directions, LEFT/RIGHT is mouse >+ * so we cannot use those! */ >+ -1 /* terminating entry */ >+}; >+ >+static signed short xpad_abs[] = { >+ ABS_X, ABS_Y, /* left stick */ >+ ABS_RX, ABS_RY, /* right stick */ >+ ABS_Z, ABS_RZ, /* triggers left/right */ >+ ABS_HAT0X, ABS_HAT0Y, /* digital pad */ >+ ABS_HAT1X, ABS_HAT1Y, /* analogue buttons A + B */ >+ ABS_HAT2X, ABS_HAT2Y, /* analogue buttons C + X */ >+ ABS_HAT3X, ABS_HAT3Y, /* analogue buttons Y + Z */ >+ -1 /* terminating entry */ >+}; >+ >+static struct usb_device_id xpad_table [] = { >+ { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not approved class */ >+ { USB_INTERFACE_INFO( 3 , 0 , 0) }, /* for Joytech Advanced Controller */ >+ { } >+}; >+ >+MODULE_DEVICE_TABLE(usb, xpad_table); >+ >+/** >+ * xpad_process_packet >+ * >+ * Completes a request by converting the data into events >+ * for the input subsystem. >+ * >+ * The report descriptor was taken from ITO Takayukis website: >+ * http://euc.jp/periphs/xbox-controller.en.html >+ */ >+static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) >+{ >+ struct input_dev *dev = &xpad->dev; >+ >+ input_regs(dev, regs); >+ >+ /* digital pad (button mode) bits (3 2 1 0) (right left down up) */ >+ input_report_key(dev, BTN_0, (data[2] & 0x01)); >+ input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3); >+ input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1); >+ input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2); >+ >+ /* start and back buttons */ >+ input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); >+ input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); >+ >+ /* buttons A, B, X, Y digital mode */ >+ input_report_key(dev, BTN_A, data[4]); >+ input_report_key(dev, BTN_B, data[5]); >+ input_report_key(dev, BTN_X, data[6]); >+ input_report_key(dev, BTN_Y, data[7]); >+ >+ if (xpad->isMat) >+ return; >+ >+ /* left stick */ >+ input_report_abs(dev, ABS_X, ((__s16) (((__s16)data[13] << 8) | data[12]))); >+ input_report_abs(dev, ABS_Y, ((__s16) (((__s16)data[15] << 8) | data[14]))); >+ >+ /* right stick */ >+ input_report_abs(dev, ABS_RX, ((__s16) (((__s16)data[17] << 8) | data[16]))); >+ input_report_abs(dev, ABS_RY, ((__s16) (((__s16)data[19] << 8) | data[18]))); >+ >+ /* triggers left/right */ >+ input_report_abs(dev, ABS_Z, data[10]); >+ input_report_abs(dev, ABS_RZ, data[11]); >+ >+ /* digital pad (analogue mode): bits (3 2 1 0) (right left down up) */ >+ input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); >+ input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x01) - !!(data[2] & 0x02)); >+ >+ /* stick press left/right */ >+ input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); >+ input_report_key(dev, BTN_THUMBR, data[2] >> 7); >+ >+ /* button A, B, X, Y analogue mode */ >+ input_report_abs(dev, ABS_HAT1X, data[4]); >+ input_report_abs(dev, ABS_HAT1Y, data[5]); >+ input_report_abs(dev, ABS_HAT2Y, data[6]); >+ input_report_abs(dev, ABS_HAT3X, data[7]); >+ >+ /* button C (black) digital/analogue mode */ >+ input_report_key(dev, BTN_C, data[8]); >+ input_report_abs(dev, ABS_HAT2X, data[8]); >+ >+ /* button Z (white) digital/analogue mode */ >+ input_report_key(dev, BTN_Z, data[9]); >+ input_report_abs(dev, ABS_HAT3Y, data[9]); >+ >+ input_sync(dev); >+ >+ /* process input data for mouse event generation */ >+ xpad_mouse_process_packet(xpad, cmd, data); >+} >+ >+/** >+ * xpad_irq_in >+ * >+ * Completion handler for interrupt in transfers (user input). >+ * Just calls xpad_process_packet which does then emit input events. >+ */ >+static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) >+{ >+ struct usb_xpad *xpad = urb->context; >+ int retval; >+ >+ switch (urb->status) { >+ case 0: >+ /* success */ >+ break; >+ case -ECONNRESET: >+ case -ENOENT: >+ case -ESHUTDOWN: >+ /* this urb is terminated, clean up */ >+ dbg("%s - urb shutting down with status: %d", >+ __FUNCTION__, urb->status); >+ return; >+ default: >+ dbg("%s - nonzero urb status received: %d", >+ __FUNCTION__, urb->status); >+ goto exit; >+ } >+ >+ xpad_process_packet(xpad, 0, xpad->idata, regs); >+ >+exit: >+ retval = usb_submit_urb(urb, GFP_ATOMIC); >+ if (retval) >+ err("%s - usb_submit_urb failed with result %d", >+ __FUNCTION__, retval); >+} >+ >+/* xpad_init_urb >+ * >+ * initialize the input urb >+ * this is to be called when joystick or mouse device are opened >+ */ >+int xpad_start_urb(struct usb_xpad *xpad) >+{ >+ int status; >+ >+ // check if joystick or mouse device are opened >+ if (xpad->open_count + xpad->mouse_open_count > 0) >+ return 0; >+ >+ xpad->irq_in->dev = xpad->udev; >+ if ((status = usb_submit_urb(xpad->irq_in, GFP_KERNEL))) { >+ err("open input urb failed: %d", status); >+ return -EIO; >+ } >+ >+ return 0; >+} >+ >+/** >+ * xpad_open >+ * >+ * Called when a an application opens the device. >+ */ >+static int xpad_open(struct input_dev *dev) >+{ >+ struct usb_xpad *xpad = dev->private; >+ int status; >+ >+ if (xpad->open_count) >+ return 0; >+ >+ info("opening device"); >+ >+ if ((status = xpad_start_urb(xpad))) >+ return status; >+ >+ ++xpad->open_count; >+ >+ xpad_rumble_open(xpad); >+ >+ return 0; >+} >+ >+void xpad_stop_urb(struct usb_xpad *xpad) >+{ >+ if (xpad->open_count + xpad->mouse_open_count > 0) >+ return; >+ >+ usb_unlink_urb(xpad->irq_in); >+} >+ >+/** >+ * xpad_close >+ * >+ * Called when an application closes the device. >+ */ >+static void xpad_close(struct input_dev *dev) >+{ >+ struct usb_xpad *xpad = dev->private; >+ >+ if (--xpad->open_count) >+ return; >+ >+ info("closing device"); >+ >+ xpad_stop_urb(xpad); >+ xpad_rumble_close(xpad); >+} >+ >+/** xpad_init_input_device >+ * >+ * setup the input device for the kernel >+ */ >+static void xpad_init_input_device(struct usb_interface *intf, struct xpad_device device) >+{ >+ struct usb_xpad *xpad = usb_get_intfdata(intf); >+ struct usb_device *udev = interface_to_usbdev(intf); >+ char path[64]; >+ int i; >+ >+ xpad->dev.id.bustype = BUS_USB; >+ xpad->dev.id.vendor = udev->descriptor.idVendor; >+ xpad->dev.id.product = udev->descriptor.idProduct; >+ xpad->dev.id.version = udev->descriptor.bcdDevice; >+ xpad->dev.dev = &intf->dev; >+ xpad->dev.private = xpad; >+ xpad->dev.name = device.name; >+ xpad->dev.phys = xpad->phys; >+ xpad->dev.open = xpad_open; >+ xpad->dev.close = xpad_close; >+ >+ usb_make_path(udev, path, 64); >+ snprintf(xpad->phys, 64, "%s/input0", path); >+ >+ /* this was meant to allow a user space tool on-the-fly configuration >+ of driver options (mouse on, rumble on, etc) >+ yet, Vojtech said this is better done using sysfs (linux 2.6) >+ plus, it needs a patch to the input subsystem */ >+// xpad->dev.ioctl = xpad_ioctl; >+ >+ if (xpad->isMat) { >+ xpad->dev.evbit[0] = BIT(EV_KEY); >+ for (i = 0; xpad_mat_btn[i] >= 0; ++i) >+ set_bit(xpad_mat_btn[i], xpad->dev.keybit); >+ } else { >+ xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); >+ >+ for (i = 0; xpad_btn[i] >= 0; ++i) >+ set_bit(xpad_btn[i], xpad->dev.keybit); >+ >+ for (i = 0; xpad_abs[i] >= 0; ++i) { >+ >+ signed short t = xpad_abs[i]; >+ >+ set_bit(t, xpad->dev.absbit); >+ >+ switch (t) { >+ case ABS_X: >+ case ABS_Y: >+ case ABS_RX: >+ case ABS_RY: /* the two sticks */ >+ xpad->dev.absmax[t] = 32767; >+ xpad->dev.absmin[t] = -32768; >+ xpad->dev.absflat[t] = 128; >+ xpad->dev.absfuzz[t] = 16; >+ break; >+ case ABS_Z: /* left trigger */ >+ case ABS_RZ: /* right trigger */ >+ case ABS_HAT1X: /* analogue button A */ >+ case ABS_HAT1Y: /* analogue button B */ >+ case ABS_HAT2X: /* analogue button C */ >+ case ABS_HAT2Y: /* analogue button X */ >+ case ABS_HAT3X: /* analogue button Y */ >+ case ABS_HAT3Y: /* analogue button Z */ >+ xpad->dev.absmax[t] = 255; >+ xpad->dev.absmin[t] = 0; >+ break; >+ case ABS_HAT0X: >+ case ABS_HAT0Y: /* the d-pad */ >+ xpad->dev.absmax[t] = 1; >+ xpad->dev.absmin[t] = -1; >+ break; >+ } >+ } >+ >+ if (xpad_rumble_probe(udev, xpad, ifnum) != 0) >+ err("could not init rumble"); >+ } >+ >+ input_register_device(&xpad->dev); >+ printk(KERN_INFO "input: %s on %s\n", xpad->dev.name, path); >+} >+ >+/** >+ * xpad_probe >+ * >+ * Called upon device detection to find a suitable driver. >+ * Must return NULL when no xpad is found, else setup everything. >+ */ >+static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) >+{ >+ struct usb_device *udev = interface_to_usbdev(intf); >+ struct usb_xpad *xpad = NULL; >+ struct usb_endpoint_descriptor *ep_irq_in; >+ int i; >+ int probedDevNum = -1; /* this takes the index into the known devices >+ array for the recognized device */ >+ >+ // try to detect the device we are called for >+ for (i = 0; xpad_device[i].idVendor; ++i) { >+ if ((udev->descriptor.idVendor == xpad_device[i].idVendor) && >+ (udev->descriptor.idProduct == xpad_device[i].idProduct)) { >+ probedDevNum = i; >+ break; >+ } >+ } >+ >+ // sanity check, did we recognize this device? if not, fail >+ if ((probedDevNum == -1) || (!xpad_device[probedDevNum].idVendor && >+ !xpad_device[probedDevNum].idProduct)) >+ return -ENODEV; >+ >+ if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { >+ err("cannot allocate memory for new pad"); >+ return -ENOMEM; >+ } >+ memset(xpad, 0, sizeof(struct usb_xpad)); >+ >+ xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, >+ SLAB_ATOMIC, &xpad->idata_dma); >+ if (!xpad->idata) { >+ kfree(xpad); >+ return -ENOMEM; >+ } >+ >+ /* setup input interrupt pipe (button and axis state) */ >+ xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); >+ if (!xpad->irq_in) { >+ err("cannot allocate memory for new pad irq urb"); >+ usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); >+ kfree(xpad); >+ return -ENOMEM; >+ } >+ >+ ep_irq_in = &intf->altsetting[0].endpoint[0].desc; >+ >+ xpad->udev = udev; >+ xpad->isMat = xpad_device[probedDevNum].isMat; >+ >+ /* init input URB for USB INT transfer from device */ >+ usb_fill_int_urb(xpad->irq_in, udev, >+ usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), >+ xpad->idata, XPAD_PKT_LEN, >+ xpad_irq_in, xpad, ep_irq_in->bInterval); >+ xpad->irq_in->transfer_dma = xpad->idata_dma; >+ xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; >+ >+ // we set this here so we can extract it in the two functions below >+ usb_set_intfdata(intf, xpad); >+ >+ xpad_init_input_device(intf, xpad_device[probedDevNum]); >+ xpad_mouse_init_input_device(intf, xpad_device[probedDevNum]); >+ >+ return 0; >+} >+ >+/** >+ * xpad_disconnect >+ * >+ * Called upon device disconnect to dispose of the structures and >+ * close the USB connections. >+ */ >+static void xpad_disconnect(struct usb_interface *intf) >+{ >+ struct usb_xpad *xpad = usb_get_intfdata(intf); >+ >+ usb_set_intfdata(intf, NULL); >+ if (xpad) { >+ info( "disconnecting device" ); >+ usb_unlink_urb(xpad->irq_in); >+ xpad_rumble_close(xpad); >+ input_unregister_device(&xpad->dev); >+ >+ usb_free_urb(xpad->irq_in); >+ xpad_mouse_cleanup(xpad); >+ >+ usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, >+ xpad->idata, xpad->idata_dma); >+ >+ xpad_rumble_disconnect(xpad); >+ >+ kfree(xpad); >+ } >+} >+ >+/******************* Linux driver framework specific stuff ************/ >+ >+static struct usb_driver xpad_driver = { >+ .owner = THIS_MODULE, >+ .name = "xpad", >+ .probe = xpad_probe, >+ .disconnect = xpad_disconnect, >+ .id_table = xpad_table, >+}; >+ >+/** >+ * driver init entry point >+ */ >+static int __init usb_xpad_init(void) >+{ >+ int result = usb_register(&xpad_driver); >+ if (result == 0) >+ info(DRIVER_DESC " " DRIVER_VERSION); >+ return result; >+} >+ >+/** >+ * driver exit entry point >+ */ >+static void __exit usb_xpad_exit(void) >+{ >+ usb_deregister(&xpad_driver); >+} >+ >+module_init(usb_xpad_init); >+module_exit(usb_xpad_exit); >+ >+MODULE_AUTHOR(DRIVER_AUTHOR); >+MODULE_DESCRIPTION(DRIVER_DESC); >+MODULE_LICENSE("GPL"); >+ >+/* >+ * driver history >+ * ---------------- >+ * >+ * 2003-05-15 - 0.1.2 : ioctls, dynamic mouse/rumble activation, /proc fs >+ * - added some /proc files for informational purposes (readonly right now) >+ * - added init parameters for mouse/rumble activation upon detection >+ * - added dynamic changes to mouse events / rumble effect generation via >+ * ioctls - NOTE: this requires a currently unofficial joydev patch! >+ * >+ * 2003-04-29 - 0.1.1 : minor cleanups, some comments >+ * - fixed incorrect handling of unknown devices (please try ir dongle now) >+ * - fixed input URB length (the 256 bytes from 0.1.0 broke everything for the >+ * MS controller as well as my Interact device, set back to 32 (please >+ * REPORT problems BEFORE any further changes here, since those can be fatal) >+ * - fixed rumbling for MS controllers (need 6 bytes output report) >+ * - dropped kernel-2.5 ifdefs, much more readable now >+ * - preparation for major rework under way, stay tuned >+ * >+ * 2003-03-25 - 0.1.0 : (Franz) Some Debuggin >+ * - Better Handling >+ * - X/Y support, Speed differenting >+ * - Landing Zone, Dead Zone, Offset kompensation, Zero-adjustment, .... aso. >+ * - Removed Wheel handling in Mouse Emulation .. sensless.. >+ * >+ * 2003-01-23 - 0.1.0-pre : added mouse emulation and rumble support >+ * - can provide mouse emulation (compile time switch) >+ * this code has been taken from Oliver Schwartz' xpad-mouse driver >+ * - basic rumble support (compile time switch) EXPERIMENTAL! >+ * >+ * 2002-08-05 - 0.0.6 : added analog button support >+ * >+ * 2002-07-17 - 0.0.5 : (Vojtech Pavlik) rework >+ * - simplified d-pad handling >+ * >+ * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3 >+ * - verified the lack of HID and report descriptors >+ * - verified that ALL buttons WORK >+ * - fixed d-pad to axes mapping >+ * >+ * 2002-07-14 - 0.0.3 : (Vojtech Pavlik) rework >+ * - indentation fixes >+ * - usb + input init sequence fixes >+ * >+ * 2002-07-02 - 0.0.2 : basic working version >+ * - all axes and 9 of the 10 buttons work (german InterAct device) >+ * - the black button does not work >+ * >+ * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller" >+ */ >diff -urN linux-2.6.6.orig/drivers/usb/input/xpad-mouse.c linux-2.6.6/drivers/usb/input/xpad-mouse.c >--- linux-2.6.6.orig/drivers/usb/input/xpad-mouse.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/usb/input/xpad-mouse.c 2004-05-10 12:30:23.073963392 +0100 >@@ -0,0 +1,270 @@ >+/* >+ * Xbox input device driver for Linux - v0.1.4 >+ * >+ * mouse emulation stuff, merged from Olivers xpad-mouse >+ * >+ * Copyright (c) 2003, 2004 Marko Friedemann <mfr@bmx-chemnitz.de> >+ * portions Copyright (c) 2002 Oliver Schwartz <Oliver.Schwartz@gmx.de>, >+ * 2003 Franz Lehner <franz@chaos.at> >+ * >+ * Released under GPL. See xpad-core.c for details >+ */ >+ >+#include <linux/config.h> >+#include <linux/kernel.h> >+#include <linux/init.h> >+#include <linux/slab.h> >+#include <linux/module.h> >+#include <linux/smp_lock.h> >+#include <linux/proc_fs.h> >+#include <linux/usb.h> >+#include <linux/version.h> >+#include <linux/timer.h> >+#include <asm/uaccess.h> >+ >+#define __USB_XPAD_MOUSE >+#include "xpad.h" >+#undef __USB_XPAD_MOUSE >+ >+#define XPAD_WHEELBRAKE 20 >+#define JOY_DeadZone_fast 6000 >+#define JOY_DeadZone_slow 200 >+#define XPAD_OFFSET_COUNTER 5 >+ >+ >+static int mouse_on_load = 1; >+MODULE_PARM( mouse_on_load, "i" ); >+MODULE_PARM_DESC( mouse_on_load, "set to 0 to deactivate mouse support on insmod (default 1)" ); >+ >+ >+/** >+ * xpad_removedeadzone >+ * >+ * Franz? Please clarify and correct. >+ * >+ * Removes the deadzone for mouse operation. >+ * Allows for better handling near the stick's center. >+ */ >+static int xpad_mouse_removedeadzone(signed int position, int speed, int deadzone) >+{ >+ if (position>31000) position=31000; >+ if (position<-31000) position=-31000; >+ >+ if ((position>0)&(position<deadzone)) return 0; >+ if ((position<0)&(position>(-deadzone))) return 0; >+ >+ if (position>deadzone) position -= deadzone; >+ if (position<(-(deadzone))) position+= deadzone; >+ position = (int)(position / speed); >+ >+ return position; >+} >+ >+void xpad_mouse_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) >+{ >+ struct input_dev *dev_mouse = &xpad->dev_mouse; >+ >+ int signledirection, xyspeed; >+ //int joy_y2; >+ unsigned char MouseLeft,MouseRight, MouseMiddle; >+ signed int left_joy_x, left_joy_y, right_joy_x, right_joy_y; >+ >+ if (!xpad->mouse_open_count || !xpad->mouse_enabled) >+ return; >+ >+ left_joy_x = ((__s16) (((__s16)data[13] << 8) | data[12])); >+ left_joy_y = ((__s16) (((__s16)data[15] << 8) | data[14])); >+ >+ right_joy_x = ((__s16) (((__s16)data[17] << 8) | data[16])); >+ right_joy_y = ((__s16) (((__s16)data[19] << 8) | data[18])); >+ >+ // Creates Offset when first starting >+ /* CHECKME: who coded this? Franz? Please clarify: >+ 1) is this necessary for joystick operation? >+ 2) offset_counter was only defined when MOUSE >+ support was configured (has been FIXED, see above) */ >+ if (xpad->offsetset_compensation>0) { >+ >+ if (xpad->offsetset_compensation == XPAD_OFFSET_COUNTER) { >+ xpad->left_offset_x = left_joy_x; >+ xpad->left_offset_y = left_joy_y; >+ xpad->right_offset_x = right_joy_x; >+ xpad->right_offset_y = right_joy_y; >+ } else { >+ xpad->left_offset_x += left_joy_x; >+ xpad->left_offset_y += left_joy_y; >+ xpad->right_offset_x += right_joy_x; >+ xpad->right_offset_y += right_joy_y; >+ } >+ >+ if (xpad->offsetset_compensation == 1) { >+ xpad->left_offset_x = xpad->left_offset_x / XPAD_OFFSET_COUNTER; >+ xpad->left_offset_y = xpad->left_offset_y / XPAD_OFFSET_COUNTER; >+ xpad->right_offset_x = xpad->right_offset_x / XPAD_OFFSET_COUNTER; >+ xpad->right_offset_y = xpad->right_offset_y / XPAD_OFFSET_COUNTER; >+ } >+ >+ xpad->offsetset_compensation--; >+ } >+ >+ left_joy_x -= xpad->left_offset_x; >+ left_joy_y -= xpad->left_offset_y; >+ >+ right_joy_x -= xpad->right_offset_x; >+ right_joy_y -= xpad->right_offset_y; >+ >+ if (data[11]<0x10) { >+ // Normal Speed Mode >+ xpad->rel_x = (xpad_mouse_removedeadzone(left_joy_x,0x1500,JOY_DeadZone_fast)); >+ xpad->rel_y = -(xpad_mouse_removedeadzone(left_joy_y,0x1500,JOY_DeadZone_fast)); >+ xyspeed = 2; >+ //printk("%d:",xpad->rel_y); >+ } else { >+ // Ultra Slow Mode >+ xpad->rel_x = (xpad_mouse_removedeadzone(left_joy_x,0x3500,JOY_DeadZone_slow)); >+ xpad->rel_y = -(xpad_mouse_removedeadzone(left_joy_y,0x3500,JOY_DeadZone_slow)); >+ xyspeed = 1; >+ } >+ >+ // X-Y Steering >+ signledirection=1; >+ if (signledirection&((data[2] & 0x04)!=0)) { signledirection=0; xpad->rel_x -=xyspeed; } >+ if (signledirection&((data[2] & 0x08)!=0)) { signledirection=0; xpad->rel_x +=xyspeed; } >+ if (signledirection&((data[2] & 0x02)!=0)) { signledirection=0; xpad->rel_y +=xyspeed; } >+ if (signledirection&((data[2] & 0x01)!=0)) { signledirection=0; xpad->rel_y -=xyspeed; } >+ >+ /* wheel handling */ >+ //joy_y2 = xpad_mouse_removedeadzone(joy_y2); >+ //xpad->rel_wheel = (joy_y2>0)?1:(joy_y2<0)?-1:0; >+ xpad->rel_wheel=0; >+ >+ if (data[10]==0xFF) MouseLeft=1; else MouseLeft =0; >+ if ((MouseLeft==0)&(data[7]!=0)) MouseLeft =1; >+ if ((MouseLeft==0)&(data[4]!=0)) MouseLeft = 1; >+ if ((MouseLeft==0)&((data[2] >> 7)!=0)) MouseLeft = 1; >+ if ((MouseLeft==0)&(((data[2] & 0x40) >> 6)!=0)) MouseLeft = 1; >+ >+ if (data[5]!=0) MouseRight=1; else MouseRight=0; >+ if (data[6]!=0) MouseMiddle =1; else MouseMiddle=0; >+ >+ // Generating Mouse Emulation Events (Button Events) >+ input_report_key(dev_mouse, BTN_LEFT, MouseLeft); >+ input_report_key(dev_mouse, BTN_RIGHT, MouseRight); >+ input_report_key(dev_mouse, BTN_MIDDLE, MouseMiddle); >+ >+ input_sync(dev_mouse); >+} >+ >+/** >+ * xpad_timer >+ * >+ * Reports the mouse events in the interval given in xpad_open. >+ * >+ * Taken from Oliver Schwartz' xpad-mouse driver to avoid strange mouse >+ * behaviour encountered when the input events where send directly >+ * in xpad_process_packet. >+ */ >+static void xpad_timer(unsigned long data) >+{ >+ struct usb_xpad *xpad = (struct usb_xpad *)data; >+ >+ if (xpad->mouse_enabled) { >+ input_report_rel(&xpad->dev_mouse, REL_X, xpad->rel_x); >+ input_report_rel(&xpad->dev_mouse, REL_Y, xpad->rel_y); >+ >+ input_sync(&xpad->dev_mouse); >+ >+ /*if (xpad->rel_wheeltimer == 0) { >+ input_report_rel(&xpad->dev_mouse, REL_WHEEL, xpad->rel_wheel); >+ xpad->rel_wheeltimer = XPAD_WHEELBRAKE; >+ } else >+ xpad->rel_wheeltimer--;*/ >+ } >+ >+ // reschedule the timer so that it fires continually >+ add_timer(&xpad->timer); >+} >+ >+static int xpad_mouse_open(struct input_dev *dev) >+{ >+ struct usb_xpad *xpad = dev->private; >+ int status; >+ >+ if (xpad->mouse_open_count) >+ return 0; >+ >+ if ((status = xpad_start_urb(xpad))) >+ return status; >+ >+ ++xpad->mouse_open_count; >+ >+ info("opening mouse device"); >+ >+ // set up timer for mouse event generation >+ init_timer(&xpad->timer); >+ xpad->timer.expires = 1*HZ/5; /* every 200 ms */ >+ xpad->timer.data = (unsigned long)xpad; >+ xpad->timer.function = xpad_timer; >+ // now start the timer >+ add_timer(&xpad->timer); >+ >+ return 0; >+} >+ >+static void xpad_mouse_close(struct input_dev *dev) >+{ >+ struct usb_xpad *xpad = dev->private; >+ >+ if (--xpad->mouse_open_count) >+ return; >+ >+ xpad_stop_urb(xpad); >+ >+ info("closing mouse device"); >+ del_timer(&xpad->timer); >+} >+ >+int xpad_mouse_init_input_device(struct usb_interface *intf, struct xpad_device device) >+{ >+ struct usb_xpad *xpad = usb_get_intfdata(intf); >+ struct usb_device *udev = interface_to_usbdev(intf); >+ >+ /* the mouse device struct for the kernel (mouse emulation) */ >+ xpad->dev_mouse.id.bustype = BUS_USB; >+ xpad->dev_mouse.id.vendor = udev->descriptor.idVendor; >+ xpad->dev_mouse.id.product = udev->descriptor.idProduct; >+ xpad->dev_mouse.id.version = udev->descriptor.bcdDevice; >+ xpad->dev_mouse.dev = &intf->dev; >+ xpad->dev_mouse.private = xpad; >+ xpad->dev_mouse.name = device.name; >+ xpad->dev_mouse.phys = xpad->phys; >+ xpad->dev_mouse.open = xpad_mouse_open; >+ xpad->dev_mouse.close = xpad_mouse_close; >+ xpad->offsetset_compensation = XPAD_OFFSET_COUNTER; // Find new offset point >+ xpad->mouse_enabled = mouse_on_load; >+ >+ /* mouse setup */ >+ xpad->dev_mouse.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); >+ >+ set_bit(REL_X, xpad->dev_mouse.relbit); >+ set_bit(REL_Y, xpad->dev_mouse.relbit); >+ set_bit(REL_WHEEL, xpad->dev_mouse.relbit); >+ >+ set_bit(BTN_LEFT, xpad->dev_mouse.keybit); >+ set_bit(BTN_RIGHT, xpad->dev_mouse.keybit); >+ set_bit(BTN_MIDDLE, xpad->dev_mouse.keybit); >+ set_bit(BTN_SIDE, xpad->dev_mouse.keybit); >+ set_bit(BTN_EXTRA, xpad->dev_mouse.keybit); >+ >+ input_register_device(&xpad->dev_mouse); >+ printk(KERN_INFO "input: mouse emulation %s@ %s\n", >+ (mouse_on_load ? "" : "(disabled) "), xpad->dev_mouse.name); >+} >+ >+void xpad_mouse_cleanup(struct usb_xpad *xpad) >+{ >+ // the timer exists only when the mouse device is used >+ if (xpad->mouse_open_count) >+ del_timer(&xpad->timer); >+ input_unregister_device(&xpad->dev_mouse); >+} >diff -urN linux-2.6.6.orig/drivers/usb/input/xpad.h linux-2.6.6/drivers/usb/input/xpad.h >--- linux-2.6.6.orig/drivers/usb/input/xpad.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/usb/input/xpad.h 2004-05-10 12:30:23.092960504 +0100 >@@ -0,0 +1,167 @@ >+/* >+ * Xbox Controller driver for Linux - v0.1.4 >+ * >+ * header file containing ioctl definitions >+ * >+ * Copyright (c) 2003 Marko Friedemann <mfr@bmx-chemnitz.de> >+ * >+ * >+ * 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 >+ */ >+ >+#ifndef __XPAD_h >+#define __XPAD_h >+ >+ >+/*********** ioctl stuff, can be used outside of the driver ***********/ >+#define USB_XPAD_IOC_MAGIC 'x' >+ >+#define USB_XPAD_IOCRESET _IO( USB_XPAD_IOC_MAGIC, 0 ) >+#define USB_XPAD_IOCSMOUSE _IOW( USB_XPAD_IOC_MAGIC, 1, int ) >+#define USB_XPAD_IOCGMOUSE _IOR( USB_XPAD_IOC_MAGIC, 2, int ) >+#define USB_XPAD_IOCSRUMBLE _IOW( USB_XPAD_IOC_MAGIC, 3, int ) >+#define USB_XPAD_IOCGRUMBLE _IOR( USB_XPAD_IOC_MAGIC, 4, int ) >+ >+#define USB_XPAD_IOCSIR _IOW( USB_XPAD_IOC_MAGIC, 5, int ) >+#define USB_XPAD_IOCGIR _IOR( USB_XPAD_IOC_MAGIC, 6, int ) >+ >+#define USB_XPAD_IOC_MAXNR 6 >+ >+ >+/************************* driver internals ***************************/ >+#ifdef __KERNEL__ >+ >+#include <linux/input.h> >+#include <linux/circ_buf.h> >+ >+/****************** driver description and version ********************/ >+#define DRIVER_VERSION "v0.1.4" >+#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>,\ >+ Oliver Schwartz <Oliver.Schwartz@gmx.de>, Georg Lukas <georg@op-co.de>" >+ >+#ifdef CONFIG_USB_XPAD_MOUSE >+#define DRIVER_DESC "driver for Xbox controllers with mouse emulation" >+#else >+#define DRIVER_DESC "driver for Xbox controllers" >+#endif >+ >+/****************************** constants *****************************/ >+#define XPAD_MAX_DEVICES 4 >+#define XPAD_PKT_LEN 32 /* input packet size */ >+#define XPAD_PKT_LEN_FF 6 /* output packet size - rumble */ >+ >+#define XPAD_TX_BUFSIZE XPAD_PKT_LEN_FF * 8 /* max. 8 requests */ >+ >+/************************* the device struct **************************/ >+struct usb_xpad { >+ struct input_dev dev; /* input device interface */ >+ struct usb_device *udev; /* usb device */ >+ >+ struct urb *irq_in; /* urb for int. in report */ >+ unsigned char *idata; /* input data */ >+ dma_addr_t idata_dma; >+ >+ char phys[65]; /* physical input dev path */ >+ >+ int open_count; /* reference count */ >+ >+ unsigned char offsetset_compensation; >+ int left_offset_x; >+ int left_offset_y; >+ int right_offset_x; >+ int right_offset_y; >+ >+ int isMat; /* is this a dancepad/mat? */ >+ >+#ifdef CONFIG_USB_XPAD_RUMBLE >+ int rumble_enabled; /* ioctl can toggle rumble */ >+ >+ int ep_out_adr; /* number of out endpoint */ >+ unsigned char tx_data[XPAD_PKT_LEN_FF]; /* output data (rumble) */ >+ int strong_rumble, play_strong; /* strong rumbling */ >+ int weak_rumble, play_weak; /* weak rumbling */ >+ struct timer_list rumble_timer; /* timed urb out retry */ >+ wait_queue_head_t wait; /* wait for URBs on queue */ >+ >+ spinlock_t tx_lock; >+ struct circ_buf tx; >+ unsigned char tx_buf[XPAD_TX_BUFSIZE]; >+ long tx_flags[1]; /* transmit flags */ >+#endif >+ >+#ifdef CONFIG_USB_XPAD_MOUSE >+ struct input_dev dev_mouse; /* mouse device interface */ >+ int mouse_open_count; /* reference count */ >+ int mouse_enabled; /* ioctl can toggle rumble */ >+ >+ int rel_x; >+ int rel_y; >+ int rel_wheel; >+ int rel_wheeltimer; >+ struct timer_list timer; /* timed mouse input events */ >+#endif >+}; >+ >+/* for the list of know devices */ >+struct xpad_device { >+ u16 idVendor; >+ u16 idProduct; >+ u8 isMat; >+ char *name; >+}; >+ >+#ifdef __USB_XPAD_MOUSE >+ extern int xpad_start_urb(struct usb_xpad *xpad); >+ extern void xpad_stop_urb(struct usb_xpad *xpad); >+#endif >+ >+/************************ mouse function stubs ************************/ >+#ifndef CONFIG_USB_XPAD_MOUSE >+ #define mouse_open_count open_count >+ #define xpad_mouse_process_packet(xpad, cmd, data) {} >+ #define xpad_mouse_init_input_device(intf, device) {} >+ #define xpad_mouse_cleanup(xpad) {} >+#else /* CONFIG_USB_XPAD_MOUSE */ >+ #ifndef __USB_XPAD_MOUSE >+ extern void xpad_mouse_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data); >+ extern void xpad_mouse_init_input_device(struct usb_interface *intf, struct xpad_device device); >+ extern void xpad_mouse_cleanup(struct usb_xpad *xpad); >+ #endif /* __USB_XPAD_MOUSE */ >+#endif /* CONFIG_USB_XPAD_MOUSE */ >+ >+/************************ rumble function stubs ***********************/ >+#ifndef CONFIG_USB_XPAD_RUMBLE >+ #define xpad_rumble_ioctl(dev, cmd, arg) -ENOTTY >+ #define xpad_rumble_open(xpad) {} >+ #define xpad_rumble_probe(udev, xpad, ifnum) 0 >+ #define xpad_rumble_close(xpad) {} >+ #define xpad_rumble_disconnect(xpad) {} >+#else /* CONFIG_USB_XPAD_RUMBLE */ >+ >+ #define XPAD_TX_RUNNING 0 >+ #define XPAD_TX_INC(var, n) (var) += n; (var) %= XPAD_TX_BUFSIZE >+ >+ #ifndef __USB_XPAD_RUMBLE >+ extern int xpad_rumble_ioctl(struct input_dev *dev, unsigned int cmd, unsigned long arg); >+ extern void xpad_rumble_open(struct usb_xpad *xpad); >+ extern int xpad_rumble_probe(struct usb_device *udev, struct usb_xpad *xpad, unsigned int ifnum); >+ extern void xpad_rumble_close(struct usb_xpad *xpad); >+ extern void xpad_rumble_disconnect(struct usb_xpad *xpad); >+ #endif /* __USB_XPAD_RUMBLE */ >+#endif /* CONFIG_USB_XPAD_RUMBLE */ >+ >+#endif /* __KERNEL__ */ >+ >+#endif /* __XPAD_h */ >diff -urN linux-2.6.6.orig/drivers/video/Kconfig linux-2.6.6/drivers/video/Kconfig >--- linux-2.6.6.orig/drivers/video/Kconfig 2004-05-10 03:31:59.000000000 +0100 >+++ linux-2.6.6/drivers/video/Kconfig 2004-05-10 12:30:23.136953816 +0100 >@@ -405,6 +405,16 @@ > To compile this driver as a module, choose M here: the > module will be called rivafb. > >+config FB_XBOX >+ tristate "nVidia Xbox support" >+ depends on FB && PCI && I2C_XBOX && EXPERIMENTAL >+ help >+ This driver supports the graphics chip of the Microsoft Xbox. >+ Say Y if you have an Xbox, N otherwise >+ >+ To compile this driver as a module, choose M here: the >+ module will be called xboxfb. >+ > config FB_I810 > tristate "Intel 810/815 support (EXPERIMENTAL)" > depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI >diff -urN linux-2.6.6.orig/drivers/video/Makefile linux-2.6.6/drivers/video/Makefile >--- linux-2.6.6.orig/drivers/video/Makefile 2004-05-10 03:32:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/Makefile 2004-05-10 12:30:23.143952752 +0100 >@@ -56,6 +56,7 @@ > > obj-$(CONFIG_FB_MATROX) += matrox/ cfbfillrect.o cfbcopyarea.o cfbimgblt.o > obj-$(CONFIG_FB_RIVA) += riva/ cfbimgblt.o vgastate.o >+obj-$(CONFIG_FB_XBOX) += xbox/ cfbimgblt.o vgastate.o > obj-$(CONFIG_FB_SIS) += sis/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o > obj-$(CONFIG_FB_ATY) += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o > obj-$(CONFIG_FB_ATY128) += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o >diff -urN linux-2.6.6.orig/drivers/video/fbmem.c linux-2.6.6/drivers/video/fbmem.c >--- linux-2.6.6.orig/drivers/video/fbmem.c 2004-05-10 03:31:55.000000000 +0100 >+++ linux-2.6.6/drivers/video/fbmem.c 2004-05-10 12:30:23.151951536 +0100 >@@ -123,6 +123,8 @@ > extern int sgivwfb_setup(char*); > extern int rivafb_init(void); > extern int rivafb_setup(char*); >+extern int xboxfb_init(void); >+extern int xboxfb_setup(char*); > extern int tdfxfb_init(void); > extern int tdfxfb_setup(char*); > extern int tridentfb_init(void); >@@ -218,6 +220,9 @@ > #ifdef CONFIG_FB_RIVA > { "rivafb", rivafb_init, rivafb_setup }, > #endif >+#ifdef CONFIG_FB_XBOX >+ { "xboxfb", xboxfb_init, xboxfb_setup }, >+#endif > #ifdef CONFIG_FB_3DFX > { "tdfxfb", tdfxfb_init, tdfxfb_setup }, > #endif >diff -urN linux-2.6.6.orig/drivers/video/xbox/Makefile linux-2.6.6/drivers/video/xbox/Makefile >--- linux-2.6.6.orig/drivers/video/xbox/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/Makefile 2004-05-10 12:30:23.154951080 +0100 >@@ -0,0 +1,7 @@ >+# >+# Makefile for the Xbox framebuffer driver >+# >+ >+obj-$(CONFIG_FB_XBOX) += xboxfb.o >+ >+xboxfb-objs := fbdev.o riva_hw.o nv_driver.o encoder-i2c.o encoder.o focus.o conexant.o xlb.o >diff -urN linux-2.6.6.orig/drivers/video/xbox/conexant.c linux-2.6.6/drivers/video/xbox/conexant.c >--- linux-2.6.6.orig/drivers/video/xbox/conexant.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/conexant.c 2004-05-10 12:30:23.160950168 +0100 >@@ -0,0 +1,639 @@ >+/* >+ * linux/drivers/video/riva/conexant.c - Xbox driver for conexant chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#include "conexant.h" >+#include "focus.h" >+ >+#define ADR(x) (x / 2 - 0x17) >+ >+typedef struct { >+ long v_activeo; >+ long v_linesi; >+ long h_clki; >+ long h_clko; >+ long h_blanki; >+ long h_blanko; >+ long v_blanki; >+ long v_blanko; >+ long vscale; >+ double clk_ratio; >+} xbox_tv_mode_parameter; >+ >+ >+ // and here is all the video timing for every standard >+ >+static const conexant_video_parameter vidstda[] = { >+ { 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 }, >+ { 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 288, 312.5, 0.0000092 }, >+ { 3582056.25, 0.0000056, 0.00000811, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 }, >+ { 3575611.88, 0.0000058, 0.00000832, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 4433619.49, 0.0000053, 0.00000755, 0.0000047, 0.000063555, 0.0000105, 0.000036407, 0.0000015, 243, 262.5, 0.0000092 } >+}; >+ >+static const unsigned char default_mode[] = { >+ 0x00, >+ 0x00, 0x28, 0x80, 0xE4, 0x00, 0x00, 0x80, 0x80, >+ 0x80, 0x13, 0xDA, 0x4B, 0x28, 0xA3, 0x9F, 0x25, >+ 0xA3, 0x9F, 0x25, 0x00, 0x00, 0x00, 0x00, 0x44, >+ 0xC7, 0x00, 0x00, 0x41, 0x35, 0x03, 0x46, 0x00, >+ 0x02, 0x00, 0x01, 0x60, 0x88, 0x8a, 0xa6, 0x68, >+ 0xc1, 0x2e, 0xf2, 0x27, 0x00, 0xb0, 0x0a, 0x0b, >+ 0x71, 0x5a, 0xe0, 0x36, 0x00, 0x50, 0x72, 0x1c, >+ 0x0d, 0x24, 0xf0, 0x58, 0x81, 0x49, 0x8c, 0x0c, >+ 0x8c, 0x79, 0x26, 0x52, 0x00, 0x24, 0x00, 0x00, >+ 0x00, 0x00, 0x01, 0x9C, 0x9B, 0xC0, 0xC0, 0x19, >+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x57, 0x20, >+ 0x40, 0x6E, 0x7E, 0xF4, 0x51, 0x0F, 0xF1, 0x05, >+ 0xD3, 0x78, 0xA2, 0x25, 0x54, 0xA5, 0x00, 0x00 >+}; >+ >+static const double pll_base = 13.5e6; >+ >+static void conexant_calc_blankings( >+ xbox_video_mode * mode, >+ xbox_tv_mode_parameter * param >+); >+ >+static int conexant_calc_mode_params( >+ xbox_video_mode * mode, >+ xbox_tv_mode_parameter * param >+); >+ >+static double fabs(double d) { >+ if (d > 0) return d; >+ else return -d; >+} >+ >+int conexant_calc_vga_mode( >+ xbox_av_type av_type, >+ unsigned char pll_int, >+ unsigned char * regs >+){ >+ memset(regs, 0, NUM_CONEXANT_REGS); >+ // Protect against overclocking >+ if (pll_int > 36) { >+ pll_int = 36; // 36 / 6 * 13.5 MHz = 81 MHz, just above the limit. >+ } >+ if (pll_int == 0) { >+ pll_int = 1; // 0 will cause a burnout ... >+ } >+ if (av_type == AV_VGA) { >+ // use internal sync signals >+ regs[ADR(0x2e)] = 0xbd; // HDTV_EN = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, GY_SYNC_DIS=1, HD_SYNC_EDGE = 1, RASTER_SEL = 01 >+ } >+ else { >+ // use sync on green >+ regs[ADR(0x2e)] = 0xad; // HDTV_EN = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01 >+ } >+ regs[ADR(0x32)] = 0x48; // DRVS = 2, IN_MODE[3] = 1; >+ regs[ADR(0x3c)] = 0x80; // MCOMPY >+ regs[ADR(0x3e)] = 0x80; // MCOMPU >+ regs[ADR(0x40)] = 0x80; // MCOMPV >+ regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed >+ regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1 >+ regs[ADR(0x9c)] = 0x00; // PLL_FRACT >+ regs[ADR(0x9e)] = 0x00; // PLL_FRACT >+ regs[ADR(0xa0)] = pll_int; // PLL_INT >+ regs[ADR(0xba)] = 0x28; // SLAVER = 1, DACDISD = 1 >+ regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11 >+ regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV) >+ >+ return 1; >+} >+ >+int conexant_calc_hdtv_mode( >+ xbox_hdtv_mode hdtv_mode, >+ unsigned char pll_int, >+ unsigned char * regs >+){ >+ memset(regs, 0, NUM_CONEXANT_REGS); >+ // Protect against overclocking >+ if (pll_int > 36) { >+ pll_int = 36; // 36 / 6 * 13.5 MHz = 81 MHz, just above the limit. >+ } >+ if (pll_int == 0) { >+ pll_int = 1; // 0 will cause a burnout ... >+ } >+ switch (hdtv_mode) { >+ case HDTV_480p: >+ // use sync on green >+ regs[ADR(0x2e)] = 0xed; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01 >+ regs[ADR(0x32)] = 0x48; // DRVS = 2, IN_MODE[3] = 1; >+ regs[ADR(0x3e)] = 0x45; // MCOMPU >+ regs[ADR(0x40)] = 0x51; // MCOMPV >+ break; >+ case HDTV_720p: >+ // use sync on green >+ regs[ADR(0x2e)] = 0xea; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01 >+ regs[ADR(0x32)] = 0x49; // DRVS = 2, IN_MODE[3] = 1, CSC_SEL=1; >+ regs[ADR(0x3e)] = 0x45; // MCOMPU >+ regs[ADR(0x40)] = 0x51; // MCOMPV >+ break; >+ case HDTV_1080i: >+ // use sync on green >+ regs[ADR(0x2e)] = 0xeb; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01 >+ regs[ADR(0x32)] = 0x49; // DRVS = 2, IN_MODE[3] = 1, CSC_SEL=1; >+ regs[ADR(0x3e)] = 0x48; // MCOMPU >+ regs[ADR(0x40)] = 0x5b; // MCOMPV >+ break; >+ } >+ regs[ADR(0x3c)] = 0x80; // MCOMPY >+ regs[ADR(0xa0)] = pll_int; // PLL_INT >+ regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed >+ regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1 >+ regs[ADR(0x9c)] = 0x00; // PLL_FRACT >+ regs[ADR(0x9e)] = 0x00; // PLL_FRACT >+ regs[ADR(0xba)] = 0x28; // SLAVER = 1, DACDISD = 1 >+ regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11 >+ regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV) >+ >+ return 1; >+} >+ >+int conexant_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out) >+{ >+ unsigned char b; >+ unsigned int m = 0; >+ double dPllOutputFrequency; >+ xbox_tv_mode_parameter param; >+ char* regs = riva_out->encoder_mode; >+ >+ if (conexant_calc_mode_params(mode, ¶m)) >+ { >+ // copy default mode settings >+ memcpy(regs,default_mode,sizeof(default_mode)); >+ >+ regs[ADR(0x32)] = 0x28; // DRVS = 1, IN_MODE[3] = 1; >+ >+ // H_CLKI >+ b=regs[ADR(0x8e)]&(~0x07); >+ regs[ADR(0x8e)] = ((param.h_clki>>8)&0x07)|b; >+ regs[ADR(0x8a)] = ((param.h_clki)&0xff); >+ // H_CLKO >+ b=regs[ADR(0x86)]&(~0x0f); >+ regs[ADR(0x86)] = ((param.h_clko>>8)&0x0f)|b; >+ regs[ADR(0x76)] = ((param.h_clko)&0xff); >+ // V_LINESI >+ b=regs[ADR(0x38)]&(~0x02); >+ regs[ADR(0x38)] = ((param.v_linesi>>9)&0x02)|b; >+ b=regs[ADR(0x96)]&(~0x03); >+ regs[ADR(0x96)] = ((param.v_linesi>>8)&0x03)|b; >+ regs[ADR(0x90)] = ((param.v_linesi)&0xff); >+ // V_ACTIVEO >+ /* TODO: Absolutely not sure about other modes than plain NTSC / PAL */ >+ switch(mode->tv_encoding) { >+ case TV_ENC_NTSC: >+ case TV_ENC_NTSC60: >+ case TV_ENC_PALM: >+ case TV_ENC_PAL60: >+ m=param.v_activeo + 1; >+ break; >+ case TV_ENC_PALBDGHI: >+ m=param.v_activeo + 2; >+ break; >+ default: >+ m=param.v_activeo + 2; >+ break; >+ } >+ b=regs[ADR(0x86)]&(~0x80); >+ regs[ADR(0x86)] = ((m>>1)&0x80)|b; >+ regs[ADR(0x84)] = ((m)&0xff); >+ // H_ACTIVE >+ b=regs[ADR(0x86)]&(~0x70); >+ regs[ADR(0x86)] = (((mode->xres + 5)>>4)&0x70)|b; >+ regs[ADR(0x78)] = ((mode->xres + 5)&0xff); >+ // V_ACTIVEI >+ b=regs[ADR(0x96)]&(~0x0c); >+ regs[ADR(0x96)] = ((mode->yres>>6)&0x0c)|b; >+ regs[ADR(0x94)] = ((mode->yres)&0xff); >+ // H_BLANKI >+ b=regs[ADR(0x38)]&(~0x01); >+ regs[ADR(0x38)] = ((param.h_blanki>>9)&0x01)|b; >+ b=regs[ADR(0x8e)]&(~0x08); >+ regs[ADR(0x8e)] = ((param.h_blanki>>5)&0x08)|b; >+ regs[ADR(0x8c)] = ((param.h_blanki)&0xff); >+ // H_BLANKO >+ b=regs[ADR(0x9a)]&(~0xc0); >+ regs[ADR(0x9a)] = ((param.h_blanko>>2)&0xc0)|b; >+ regs[ADR(0x80)] = ((param.h_blanko)&0xff); >+ >+ // V_SCALE >+ b=regs[ADR(0x9a)]&(~0x3f); >+ regs[ADR(0x9a)] = ((param.vscale>>8)&0x3f)|b; >+ regs[ADR(0x98)] = ((param.vscale)&0xff); >+ // V_BLANKO >+ regs[ADR(0x82)] = ((param.v_blanko)&0xff); >+ // V_BLANKI >+ regs[ADR(0x92)] = ((param.v_blanki)&0xff); >+ { >+ unsigned int dwPllRatio, dwFract, dwInt; >+ // adjust PLL >+ dwPllRatio = (int)(6.0 * ((double)param.h_clko / vidstda[mode->tv_encoding].m_dSecHsyncPeriod) * >+ param.clk_ratio * 0x10000 / pll_base + 0.5); >+ dwInt = dwPllRatio / 0x10000; >+ dwFract = dwPllRatio - (dwInt * 0x10000); >+ b=regs[ADR(0xa0)]&(~0x3f); >+ regs[ADR(0xa0)] = ((dwInt)&0x3f)|b; >+ regs[ADR(0x9e)] = ((dwFract>>8)&0xff); >+ regs[ADR(0x9c)] = ((dwFract)&0xff); >+ // recalc value >+ dPllOutputFrequency = ((double)dwInt + ((double)dwFract)/65536.0)/(6 * param.clk_ratio / pll_base); >+ // enable 3:2 clocking mode >+ b=regs[ADR(0x38)]&(~0x20); >+ if (param.clk_ratio > 1.1) { >+ b |= 0x20; >+ } >+ regs[ADR(0x38)] = b; >+ >+ // update burst start position >+ m=(vidstda[mode->tv_encoding].m_dSecBurstStart) * dPllOutputFrequency + 0.5; >+ b=regs[ADR(0x38)]&(~0x04); >+ regs[ADR(0x38)] = ((m>>6)&0x04)|b; >+ regs[ADR(0x7c)] = (m&0xff); >+ // update burst end position (note +128 is in hardware) >+ m=(vidstda[mode->tv_encoding].m_dSecBurstEnd) * dPllOutputFrequency + 0.5; >+ if(m<128) m=128; >+ b=regs[ADR(0x38)]&(~0x08); >+ regs[ADR(0x38)] = (((m-128)>>5)&0x08)|b; >+ regs[ADR(0x7e)] = ((m-128)&0xff); >+ // update HSYNC width >+ m=(vidstda[mode->tv_encoding].m_dSecHsyncWidth) * dPllOutputFrequency + 0.5; >+ regs[ADR(0x7a)] = ((m)&0xff); >+ } >+ // adjust Subcarrier generation increment >+ { >+ unsigned int dwSubcarrierIncrement = (unsigned int) ( >+ (65536.0 * 65536.0) * ( >+ vidstda[mode->tv_encoding].m_dHzBurstFrequency >+ * vidstda[mode->tv_encoding].m_dSecHsyncPeriod >+ / (double)param.h_clko >+ ) + 0.5 >+ ); >+ regs[ADR(0xae)] = (dwSubcarrierIncrement&0xff); >+ regs[ADR(0xb0)] = ((dwSubcarrierIncrement>>8)&0xff); >+ regs[ADR(0xb2)] = ((dwSubcarrierIncrement>>16)&0xff); >+ regs[ADR(0xb4)] = ((dwSubcarrierIncrement>>24)&0xff); >+ } >+ // adjust WSS increment >+ { >+ unsigned int dwWssIncrement = 0; >+ >+ switch(mode->tv_encoding) { >+ case TV_ENC_NTSC: >+ case TV_ENC_NTSC60: >+ dwWssIncrement=(unsigned int) ((1048576.0 / ( 0.000002234 * dPllOutputFrequency))+0.5); >+ break; >+ case TV_ENC_PALBDGHI: >+ case TV_ENC_PALN: >+ case TV_ENC_PALNC: >+ case TV_ENC_PALM: >+ case TV_ENC_PAL60: >+ dwWssIncrement=(unsigned int) ((1048576.0 / ( 0.0000002 * dPllOutputFrequency))+0.5); >+ break; >+ default: >+ break; >+ } >+ >+ regs[ADR(0x66)] = (dwWssIncrement&0xff); >+ regs[ADR(0x68)] = ((dwWssIncrement>>8)&0xff); >+ regs[ADR(0x6a)] = ((dwWssIncrement>>16)&0xf); >+ } >+ // set mode register >+ b=regs[ADR(0xa2)]&(0x41); >+ switch(mode->tv_encoding) { >+ case TV_ENC_NTSC: >+ b |= 0x0a; // SETUP + VSYNC_DUR >+ break; >+ case TV_ENC_NTSC60: >+ b |= 0x08; // VSYNC_DUR >+ break; >+ case TV_ENC_PALBDGHI: >+ case TV_ENC_PALNC: >+ b |= 0x24; // PAL_MD + 625LINE >+ break; >+ case TV_ENC_PALN: >+ b |= 0x2e; // PAL_MD + SETUP + 625LINE + VSYNC_DUR >+ break; >+ case TV_ENC_PALM: >+ b |= 0x2a; // PAL_MD + SETUP + VSYNC_DUR >+ break; >+ case TV_ENC_PAL60: >+ b |= 0x28; // PAL_MD + VSYNC_DUR >+ break; >+ default: >+ break; >+ } >+ regs[ADR(0xa2)] = b; >+ regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed >+ switch(mode->av_type) { >+ case AV_COMPOSITE: >+ case AV_SVIDEO: >+ regs[ADR(0x2e)] |= 0x40; // RGB2YPRPB = 1 >+ regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1 >+ regs[ADR(0x5a)] = 0x00; // Y_OFF (Brightness) >+ regs[ADR(0xa4)] = 0xe5; // SYNC_AMP >+ regs[ADR(0xa6)] = 0x74; // BST_AMP >+ regs[ADR(0xba)] = 0x24; // SLAVER = 1, DACDISC = 1 >+ regs[ADR(0xce)] = 0x19; // OUT_MUXA = 01, OUT_MUXB = 10, OUT_MUXC = 10, OUT_MUXD = 00 >+ regs[ADR(0xd6)] = 0x00; // OUT_MODE = 00 (CVBS) >+ break; >+ case AV_SCART_RGB: >+ regs[ADR(0x6c)] = 0x4e; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 1, EN_REG_RD = 1 >+ regs[ADR(0x5a)] = 0xff; // Y_OFF (Brightness) >+ regs[ADR(0xa4)] = 0xe7; // SYNC_AMP >+ regs[ADR(0xa6)] = 0x77; // BST_AMP >+ regs[ADR(0xba)] = 0x20; // SLAVER = 1, enable all DACs >+ regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11 >+ regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV) >+ break; >+ default: >+ break; >+ } >+ riva_out->ext.vend = mode->yres; >+ riva_out->ext.vtotal = param.v_linesi - 1; >+ riva_out->ext.vcrtc = mode->yres; >+ riva_out->ext.vsyncstart = param.v_linesi - param.v_blanki; >+ riva_out->ext.vsyncend = riva_out->ext.vsyncstart + 3; >+ riva_out->ext.vvalidstart = 0; >+ riva_out->ext.vvalidend = mode->yres; >+ riva_out->ext.hend = mode->xres + 7; >+ riva_out->ext.htotal = param.h_clki - 1; >+ riva_out->ext.hcrtc = mode->xres - 1; >+ riva_out->ext.hsyncstart = param.h_clki - param.h_blanki - 7; >+ riva_out->ext.hsyncend = riva_out->ext.hsyncstart + 32; >+ riva_out->ext.hvalidstart = 0; >+ riva_out->ext.hvalidend = mode->xres - 1; >+ riva_out->ext.crtchdispend = mode->xres + 8; >+ riva_out->ext.crtcvstart = mode->yres + 34; >+ riva_out->ext.crtcvtotal = param.v_linesi + 32; >+ return 1; >+ } >+ else >+ { >+ return 0; >+ } >+} >+ >+static int conexant_calc_mode_params( >+ xbox_video_mode * mode, >+ xbox_tv_mode_parameter * param >+){ >+ const double dMinHBT = 2.5e-6; // 2.5uSec time for horizontal syncing >+ const double invalidMetric = 1000; >+ >+ /* algorithm shamelessly ripped from nvtv/calc_bt.c */ >+ double dTempVOC = 0; >+ double dTempHOC = 0; >+ double dBestMetric = invalidMetric; >+ double dTempVSR = 0; >+ double dBestVSR = 0; >+ double dTempCLKRATIO = 1; >+ double dBestCLKRATIO = 1; >+ unsigned int minTLI = 0; >+ unsigned int maxTLI = 0; >+ unsigned int tempTLI = 0; >+ unsigned int bestTLI = 0; >+ unsigned int minHCLKO = 0; >+ unsigned int maxHCLKO = 0; >+ unsigned int minHCLKI = 0; >+ unsigned int tempHCLKI = 0; >+ unsigned int bestHCLKI = 0; >+ int actCLKRATIO; >+ unsigned int dTempHCLKO = 0; >+ double dTempVACTIVEO = 0; >+ double dDelta = 0; >+ double dMetric = 0; >+ double alo = vidstda[mode->tv_encoding].m_dwALO; >+ double tlo = vidstda[mode->tv_encoding].m_TotalLinesOut; >+ double tto = vidstda[mode->tv_encoding].m_dSecHsyncPeriod; >+ double ato = tto - (vidstda[mode->tv_encoding].m_dSecBlankBeginToHsync + vidstda[mode->tv_encoding].m_dSecActiveBegin); >+ >+ /* Range to search */ >+ double dMinHOC = mode->hoc - 0.02; >+ double dMaxHOC = mode->hoc + 0.02; >+ double dMinVOC = mode->voc - 0.02; >+ double dMaxVOC = mode->voc + 0.02; >+ >+ if (dMinHOC < 0) dMinHOC = 0; >+ if (dMinVOC < 0) dMinVOC = 0; >+ >+ minTLI= (unsigned int)(mode->yres / ((1 - dMinVOC) * alo) * tlo); >+ maxTLI = min((unsigned int)(mode->yres / ((1 - dMaxVOC) * alo) * tlo), (unsigned int)1023); >+ minHCLKO = (unsigned int) ((mode->xres * 2) / >+ ((1 - dMinHOC) * (ato / tto))); >+ maxHCLKO = (unsigned int) ((mode->xres * 2) / >+ ((1 - dMaxHOC) * (ato / tto))); >+ for (actCLKRATIO = 0; actCLKRATIO <= 1; actCLKRATIO++) >+ { >+ dTempCLKRATIO = 1.0; >+ if (actCLKRATIO) dTempCLKRATIO = 3.0/2.0; >+ for(tempTLI = minTLI; tempTLI <= maxTLI; tempTLI++) >+ { >+ dTempVSR = (double)tempTLI / tlo; >+ dTempVACTIVEO = (int)((((double)mode->yres * tlo) + >+ (tempTLI - 1)) / tempTLI); >+ dTempVOC = 1 - dTempVACTIVEO / alo; >+ >+ for(dTempHCLKO = minHCLKO; dTempHCLKO <= maxHCLKO; dTempHCLKO++) >+ { >+ tempHCLKI = (unsigned int)((dTempHCLKO * dTempCLKRATIO) * (tlo / tempTLI) + 0.5); >+ minHCLKI = ((dMinHBT / tto) * tempHCLKI) + mode->xres; >+ // check if solution is valid >+ if ((fabs((double)(tempTLI * tempHCLKI) - (tlo * dTempHCLKO * dTempCLKRATIO)) < 1e-3) && >+ (tempHCLKI >= minHCLKI) && (tempHCLKI < 2048)) >+ { >+ dTempHOC = 1 - (((double)mode->xres / ((double)dTempHCLKO / 2)) / >+ (ato / tto)); >+ dDelta = fabs(dTempHOC - mode->hoc) + fabs(dTempVOC - mode->voc); >+ dMetric = ((dTempHOC - mode->hoc) * (dTempHOC - mode->hoc)) + >+ ((dTempVOC - mode->voc) * (dTempVOC - mode->voc)) + >+ (2 * dDelta * dDelta); >+ if(dMetric < dBestMetric) >+ { >+ dBestVSR = dTempVSR; >+ dBestMetric = dMetric; >+ bestTLI = tempTLI; >+ bestHCLKI = tempHCLKI; >+ dBestCLKRATIO = dTempCLKRATIO; >+ } >+ } /* valid solution */ >+ } /* dTempHCLKO loop */ >+ } /* tempTLI loop */ >+ } /* CLKRATIO loop */ >+ >+ if(dBestMetric != invalidMetric) >+ { >+ param->v_linesi = bestTLI; >+ param->h_clki = bestHCLKI; >+ param->clk_ratio = dBestCLKRATIO; >+ param->v_activeo = (unsigned int)( >+ ( >+ (mode->yres * vidstda[mode->tv_encoding].m_TotalLinesOut) >+ + param->v_linesi - 1 >+ ) / param->v_linesi >+ ); >+ param->h_clko = (unsigned int)( >+ ( >+ (param->v_linesi * param->h_clki) / >+ (vidstda[mode->tv_encoding].m_TotalLinesOut * param->clk_ratio) >+ ) >+ + 0.5 >+ ); >+ conexant_calc_blankings(mode, param); >+ return 1; >+ } >+ else >+ { >+ return 0; >+ } >+} >+ >+static void conexant_calc_blankings( >+ xbox_video_mode * mode, >+ xbox_tv_mode_parameter * param >+){ >+ double dTotalHBlankI; >+ double dFrontPorchIn; >+ double dFrontPorchOut; >+ double dMinFrontPorchIn; >+ double dBackPorchIn; >+ double dBackPorchOut; >+ double dTotalHBlankO; >+ double dHeadRoom; >+ double dMaxHsyncDrift; >+ double dFifoMargin; >+ double vsrq; >+ double dMaxHR; >+ double tlo = vidstda[mode->tv_encoding].m_TotalLinesOut; >+ const int MFP = 14; // Minimum front porch >+ const int MBP = 4; // Minimum back porch >+ const int FIFO_SIZE = 1024; >+ double vsr = (double)param->v_linesi / vidstda[mode->tv_encoding].m_TotalLinesOut; >+ >+ // H_BLANKO >+ param->h_blanko = 2 * (int)( >+ vidstda[mode->tv_encoding].m_dSecImageCentre / (2 * vidstda[mode->tv_encoding].m_dSecHsyncPeriod) * >+ param->h_clko >+ + 0.5 >+ ) - mode->xres + 15; >+ >+ // V_BLANKO >+ switch (mode->tv_encoding) { >+ case TV_ENC_NTSC: >+ case TV_ENC_NTSC60: >+ case TV_ENC_PAL60: >+ case TV_ENC_PALM: >+ param->v_blanko = (int)( 140 - ( param->v_activeo / 2.0 ) + 0.5 ); >+ break; >+ default: >+ param->v_blanko = (int)( 167 - ( param->v_activeo / 2.0 ) + 0.5 ); >+ break; >+ } >+ >+ // V_BLANKI >+ vsrq = ( (int)( vsr * 4096.0 + .5 ) ) / 4096.0; >+ param->vscale = (int)( ( vsr - 1 ) * 4096 + 0.5 ); >+ if( vsrq < vsr ) >+ { >+ // These calculations are in units of dHCLKO >+ dMaxHsyncDrift = ( vsrq - vsr ) * tlo / vsr * param->h_clko; >+ dMinFrontPorchIn = MFP / ( (double)param->h_clki * vsr ) * param->h_clko; >+ dFrontPorchOut = param->h_clko - param->h_blanko - mode->xres * 2; >+ dFifoMargin = ( FIFO_SIZE - mode->xres ) * 2; >+ >+ // Check for fifo overflow >+ if( dFrontPorchOut + dFifoMargin < -dMaxHsyncDrift + dMinFrontPorchIn ) >+ { >+ dTotalHBlankO = param->h_clko - mode->xres * 2; >+ dTotalHBlankI = ( (double)param->h_clki - (double)mode->xres ) / param->h_clki / vsr * param->h_clko; >+ >+ // Try forcing the Hsync drift the opposite direction >+ dMaxHsyncDrift = ( vsrq + 1.0 / 4096 - vsr ) * tlo / vsr * param->h_clko; >+ >+ // Check that fifo overflow and underflow can be avoided >+ if( dTotalHBlankO + dFifoMargin >= dTotalHBlankI + dMaxHsyncDrift ) >+ { >+ vsrq = vsrq + 1.0 / 4096; >+ param->vscale = (int)( ( vsrq - 1 ) * 4096 ); >+ } >+ >+ // NOTE: If fifo overflow and underflow can't be avoided, >+ // alternative overscan compensation ratios should >+ // be selected and all calculations repeated. If >+ // that is not feasible, the calculations for >+ // H_BLANKI below will delay the overflow or under- >+ // flow as much as possible, to minimize the visible >+ // artifacts. >+ } >+ } >+ >+ param->v_blanki = (int)( ( param->v_blanko - 1 ) * vsrq ); >+ >+ // H_BLANKI >+ >+ // These calculations are in units of dHCLKI >+ dTotalHBlankI = param->h_clki - mode->xres; >+ dFrontPorchIn = max( (double)MFP, min( dTotalHBlankI / 8.0, dTotalHBlankI - (double)MBP ) ); >+ dBackPorchIn = dTotalHBlankI - dFrontPorchIn; >+ dMaxHsyncDrift = ( vsrq - vsr ) * tlo * param->h_clki; >+ dTotalHBlankO = ( param->h_clko - mode->xres * 2.0 ) / param->h_clko * vsr * param->h_clki; >+ dBackPorchOut = ((double)param->h_blanko) / (double)param->h_clko * vsr * param->h_clki; >+ dFrontPorchOut = dTotalHBlankO - dBackPorchOut; >+ dFifoMargin = ( FIFO_SIZE - mode->xres ) * 2.0 / param->h_clko * vsr * param->h_clki; >+ // This may be excessive, but is adjusted by the code. >+ dHeadRoom = 32.0; >+ >+ // Check that fifo overflow and underflow can be avoided >+ if( ( dTotalHBlankO + dFifoMargin ) >= ( dTotalHBlankI + fabs( dMaxHsyncDrift ) ) ) >+ { >+ dMaxHR = ( dTotalHBlankO + dFifoMargin ) - ( dTotalHBlankI - fabs( dMaxHsyncDrift ) ); >+ if( dMaxHR < ( dHeadRoom * 2.0 ) ) >+ { >+ dHeadRoom = (int)( dMaxHR / 2.0); >+ } >+ >+ // Check for overflow >+ if( ( ( dFrontPorchOut + dFifoMargin ) - dHeadRoom ) < ( dFrontPorchIn - min( dMaxHsyncDrift, 0.0 ) ) ) >+ { >+ dFrontPorchIn = max( (double)MFP, ( dFrontPorchOut + dFifoMargin + min( dMaxHsyncDrift, 0.0 ) - dHeadRoom ) ); >+ dBackPorchIn = dTotalHBlankI - dFrontPorchIn; >+ } >+ >+ // Check for underflow >+ if( dBackPorchOut - dHeadRoom < dBackPorchIn + max( dMaxHsyncDrift, 0.0 ) ) >+ { >+ dBackPorchIn = max( (double)MBP, ( dBackPorchOut - max( dMaxHsyncDrift, 0.0 ) - dHeadRoom ) ); >+ dFrontPorchIn = dTotalHBlankI - dBackPorchIn; >+ } >+ } >+ else if( dMaxHsyncDrift < 0 ) >+ { >+ // Delay the overflow as long as possible >+ dBackPorchIn = min( ( dBackPorchOut - 1 ), ( dTotalHBlankI - MFP ) ); >+ dFrontPorchIn = dTotalHBlankI - dBackPorchIn; >+ } >+ else >+ { >+ // Delay the underflow as long as possible >+ dFrontPorchIn = min( ( dFrontPorchOut + dFifoMargin - 1 ), ( dTotalHBlankI - MBP ) ); >+ dBackPorchIn = dTotalHBlankI - dFrontPorchIn; >+ } >+ >+ param->h_blanki = (int)( dBackPorchIn ); >+ >+} >diff -urN linux-2.6.6.orig/drivers/video/xbox/conexant.h linux-2.6.6/drivers/video/xbox/conexant.h >--- linux-2.6.6.orig/drivers/video/xbox/conexant.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/conexant.h 2004-05-10 12:30:23.162949864 +0100 >@@ -0,0 +1,28 @@ >+/* >+ * linux/drivers/video/riva/conexant.h - Xbox driver for conexant chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#ifndef conexant_h >+#define conexant_h >+ >+#include <linux/xboxfbctl.h> >+#include "xboxfb.h" >+#include "encoder.h" >+ >+int conexant_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out); >+int conexant_calc_vga_mode(xbox_av_type av_type, unsigned char pll_int, unsigned char * mode_out); >+int conexant_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out); >+ >+#endif >diff -urN linux-2.6.6.orig/drivers/video/xbox/encoder-i2c.c linux-2.6.6/drivers/video/xbox/encoder-i2c.c >--- linux-2.6.6.orig/drivers/video/xbox/encoder-i2c.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/encoder-i2c.c 2004-05-10 12:30:23.164949560 +0100 >@@ -0,0 +1,203 @@ >+/* >+ * linux/drivers/video/riva/encoder-i2c.c - Xbox I2C driver for encoder chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * Most of the code was stolen from extsmi.c >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/i2c.h> >+#include <linux/init.h> >+#include <linux/delay.h> >+ >+#define CONEXANT_ADDRESS 0x45 >+#define FOCUS_ADDRESS 0x6a >+#define XLB_ADDRESS 0x70 >+#define EEPROM_ADDRESS 0x54 >+#define PIC_ADDRESS 0x10 >+ >+#define DRIVER_NAME "xbox-tv-i2c" >+ >+extern int __init i2c_xbox_init(void); >+ >+static int tv_attach_adapter(struct i2c_adapter *adap); >+ >+static struct i2c_driver tv_driver = { >+ .name = "i2c xbox conexant driver", >+ .id = I2C_DRIVERID_I2CDEV, >+ .flags = I2C_DF_NOTIFY, >+ .attach_adapter = tv_attach_adapter, >+}; >+ >+static struct i2c_client pic_client = { >+ .name = "I2C xbox pic client", >+ .id = 2, >+ .flags = 0, >+ .addr = PIC_ADDRESS, >+ .adapter = NULL, >+ .driver = &tv_driver, >+}; >+ >+static struct i2c_client conexant_client = { >+ .name = "I2C xbox conexant client", >+ .id = 1, >+ .flags = 0, >+ .addr = CONEXANT_ADDRESS, >+ .adapter = NULL, >+ .driver = &tv_driver, >+}; >+ >+static struct i2c_client focus_client = { >+ .name = "I2C xbox focus client", >+ .id = 1, >+ .flags = 0, >+ .addr = FOCUS_ADDRESS, >+ .adapter = NULL, >+ .driver = &tv_driver, >+}; >+ >+static struct i2c_client xlb_client = { >+ .name = "I2C xbox XLB client", >+ .id = 1, >+ .flags = 0, >+ .addr = XLB_ADDRESS, >+ .adapter = NULL, >+ .driver = &tv_driver, >+}; >+ >+static struct i2c_client eeprom_client = { >+ .name = "I2C xbox eeprom client", >+ .id = 3, >+ .flags = 0, >+ .addr = EEPROM_ADDRESS, >+ .adapter = NULL, >+ .driver = &tv_driver, >+}; >+ >+static int tv_attach_adapter(struct i2c_adapter *adap) >+{ >+ int i; >+ >+ if ((i = i2c_adapter_id(adap)) < 0) { >+ printk("i2c-dev.o: Unknown adapter ?!?\n"); >+ return -ENODEV; >+ } >+ >+ printk(KERN_INFO DRIVER_NAME ": Using '%s'!\n",adap->name); >+ conexant_client.adapter = adap; >+ focus_client.adapter = adap; >+ xlb_client.adapter = adap; >+ pic_client.adapter = adap; >+ eeprom_client.adapter = adap; >+ i2c_attach_client(&conexant_client); >+ i2c_attach_client(&focus_client); >+ i2c_attach_client(&xlb_client); >+ i2c_attach_client(&pic_client); >+ i2c_attach_client(&eeprom_client); >+ >+ return 0; >+} >+ >+int tv_i2c_init(void) { >+ int res; >+ i2c_xbox_init(); >+ if ((res = i2c_add_driver(&tv_driver))) { >+ printk(KERN_ERR DRIVER_NAME ": XBox tv driver registration failed.\n"); >+ return res; >+ } >+ return 0; >+} >+ >+int conexant_i2c_read_reg(unsigned char adr) { >+ if (!conexant_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_read_byte_data(&conexant_client, adr); >+} >+ >+int conexant_i2c_write_reg(unsigned char adr, unsigned char value) { >+ if (!conexant_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_write_byte_data(&conexant_client, adr, value); >+} >+ >+int focus_i2c_read_reg(unsigned char adr) { >+ if (!focus_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_read_byte_data(&focus_client, adr); >+} >+ >+int focus_i2c_write_reg(unsigned char adr, unsigned char value) { >+ if (!focus_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_write_byte_data(&focus_client, adr, value); >+} >+ >+int xlb_i2c_read_reg(unsigned char adr) { >+ if (!xlb_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No XLB client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_read_byte_data(&xlb_client, adr); >+} >+ >+int xlb_i2c_write_reg(unsigned char adr, unsigned char value) { >+ if (!xlb_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No XLB client attached.\n"); >+ return -1; >+ } >+ udelay(500); >+ return i2c_smbus_write_byte_data(&xlb_client, adr, value); >+} >+ >+unsigned char pic_i2c_read_reg(unsigned char adr) { >+ if (!pic_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No pic client attached.\n"); >+ return 0; >+ } >+ udelay(500); >+ return (unsigned char)i2c_smbus_read_byte_data(&pic_client, adr); >+} >+ >+unsigned char eeprom_i2c_read(unsigned char adr) { >+ if (!eeprom_client.adapter) { >+ printk(KERN_ERR DRIVER_NAME " : No eeprom client attached.\n"); >+ return 0; >+ } >+ udelay(500); >+ return (unsigned char)i2c_smbus_read_byte_data(&eeprom_client, adr); >+} >+ >+void tv_i2c_exit(void){ >+ int res; >+ >+ if ((res = i2c_del_driver(&tv_driver))) { >+ printk(KERN_ERR DRIVER_NAME ": XBox tv Driver deregistration failed, " >+ "module not removed.\n"); >+ } >+ return; >+} >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/encoder-i2c.h linux-2.6.6/drivers/video/xbox/encoder-i2c.h >--- linux-2.6.6.orig/drivers/video/xbox/encoder-i2c.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/encoder-i2c.h 2004-05-10 12:30:23.166949256 +0100 >@@ -0,0 +1,31 @@ >+/* >+ * linux/drivers/video/riva/encoder-i2c.h - Xbox I2C driver for encoder chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#ifndef encoder_i2c_h >+#define encoder_i2c_h >+ >+int tv_i2c_init(void); >+void tv_i2c_exit(void); >+int conexant_i2c_read_reg(unsigned char adr); >+int conexant_i2c_write_reg(unsigned char adr, unsigned char value); >+int focus_i2c_read_reg(unsigned char adr); >+int focus_i2c_write_reg(unsigned char adr, unsigned char value); >+int xlb_i2c_read_reg(unsigned char adr); >+int xlb_i2c_write_reg(unsigned char adr, unsigned char value); >+unsigned char pic_i2c_read_reg(unsigned char adr); >+unsigned char eeprom_i2c_read(unsigned char adr); >+ >+#endif >diff -urN linux-2.6.6.orig/drivers/video/xbox/encoder.c linux-2.6.6/drivers/video/xbox/encoder.c >--- linux-2.6.6.orig/drivers/video/xbox/encoder.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/encoder.c 2004-05-10 12:30:23.169948800 +0100 >@@ -0,0 +1,174 @@ >+/* >+ * linux/drivers/video/riva/encoder.c - Xbox driver for encoder chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#include "encoder-i2c.h" >+#include "encoder.h" >+#include "focus.h" >+#include <asm/io.h> >+ >+#define ADR(x) (x / 2 - 0x17) >+ >+static const conexant_video_parameter vidstda[] = { >+ { 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 }, >+ { 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 288, 312.5, 0.0000092 }, >+ { 3582056.25, 0.0000056, 0.00000811, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 }, >+ { 3575611.88, 0.0000058, 0.00000832, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 }, >+ { 4433619.49, 0.0000053, 0.00000755, 0.0000047, 0.000063555, 0.0000105, 0.000036407, 0.0000015, 243, 262.5, 0.0000092 } >+}; >+ >+ >+static const double pll_base = 13.5e6; >+ >+xbox_encoder_type tv_get_video_encoder(void) { >+ unsigned char b = 0; >+ >+ b = conexant_i2c_read_reg(0x00); >+ if(b != 255) { >+ return ENCODER_CONEXANT; >+ } >+ b = focus_i2c_read_reg(0x00); >+ if(b != 255) { >+ return ENCODER_FOCUS; >+ } >+ b = xlb_i2c_read_reg(0x00); >+ if(b != 255) { >+ return ENCODER_XLB; >+ } >+ return 0; >+} >+ >+int tv_init(void) { >+ return tv_i2c_init(); >+} >+ >+void tv_exit(void) { >+ tv_i2c_exit(); >+} >+ >+void tv_load_mode(unsigned char * mode) { >+ int n, n1; >+ unsigned char b; >+ >+ switch (tv_get_video_encoder()) { >+ case ENCODER_CONEXANT: >+ conexant_i2c_write_reg(0xc4, 0x00); // EN_OUT = 1 >+ >+ // Conexant init (starts at register 0x2e) >+ n1=0; >+ for(n=0x2e;n<0x100;n+=2) { >+ switch(n) { >+ case 0x6c: // reset >+ conexant_i2c_write_reg(n, mode[n1] & 0x7f); >+ break; >+ case 0xc4: // EN_OUT >+ conexant_i2c_write_reg(n, mode[n1] & 0xfe); >+ break; >+ case 0xb8: // autoconfig >+ break; >+ >+ default: >+ conexant_i2c_write_reg(n, mode[n1]); >+ break; >+ } >+ n1++; >+ } >+ // Timing Reset >+ b=conexant_i2c_read_reg(0x6c) & (0x7f); >+ conexant_i2c_write_reg(0x6c, 0x80|b); >+ b=conexant_i2c_read_reg(0xc4) & (0xfe); >+ conexant_i2c_write_reg(0xc4, 0x01|b); // EN_OUT = 1 >+ >+ /* >+ conexant_i2c_write_reg(0xA8, (0xD9/1.3)); >+ conexant_i2c_write_reg(0xAA, (0x9A/1.3)); >+ conexant_i2c_write_reg(0xAC, (0xA4/1.3)); >+ */ >+ >+ conexant_i2c_write_reg(0xA8, 0x81); >+ conexant_i2c_write_reg(0xAA, 0x49); >+ conexant_i2c_write_reg(0xAC, 0x8C); >+ break; >+ case ENCODER_FOCUS: >+ //Set the command register soft reset >+ focus_i2c_write_reg(0x0c,0x03); >+ focus_i2c_write_reg(0x0d,0x21); >+ >+ for (n = 0; n<0xc4; n++) { >+ focus_i2c_write_reg(n,mode[n]); >+ } >+ //Clear soft reset flag >+ b = focus_i2c_read_reg(0x0c); >+ b &= ~0x01; >+ focus_i2c_write_reg(0x0c,b); >+ b = focus_i2c_read_reg(0x0d); >+ focus_i2c_write_reg(0x0d,b); >+ break; >+ case ENCODER_XLB: >+ //Nothing yet >+ break; >+ } >+} >+ >+void tv_save_mode(unsigned char * mode) { >+ int n, n1; >+ switch (tv_get_video_encoder()) { >+ case ENCODER_CONEXANT: >+ // Conexant init (starts at register 0x2e) >+ n1=0; >+ for(n=0x2e;n<0x100;n+=2) { >+ mode[n1] = conexant_i2c_read_reg(n); >+ n1++; >+ } >+ break; >+ case ENCODER_FOCUS: >+ for (n=0;n<0xc4;n++) { >+ mode[n] = focus_i2c_read_reg(n); >+ } >+ break; >+ case ENCODER_XLB: >+ break; >+ } >+} >+ >+xbox_tv_encoding get_tv_encoding(void) { >+ unsigned char eeprom_value; >+ xbox_tv_encoding enc = TV_ENC_PALBDGHI; >+ eeprom_value = eeprom_i2c_read(0x5a); >+ if (eeprom_value == 0x40) { >+ enc = TV_ENC_NTSC; >+ } >+ else { >+ enc = TV_ENC_PALBDGHI; >+ } >+ return enc; >+} >+ >+xbox_av_type detect_av_type(void) { >+ xbox_av_type avType; >+ switch (pic_i2c_read_reg(0x04)) { >+ case 0: avType = AV_SCART_RGB; break; >+ case 1: avType = AV_HDTV; break; >+ case 2: avType = AV_VGA_SOG; break; >+ case 4: avType = AV_SVIDEO; break; >+ case 6: avType = AV_COMPOSITE; break; >+ case 7: avType = AV_VGA; break; >+ default: avType = AV_COMPOSITE; break; >+ } >+ return avType; >+} >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/encoder.h linux-2.6.6/drivers/video/xbox/encoder.h >--- linux-2.6.6.orig/drivers/video/xbox/encoder.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/encoder.h 2004-05-10 12:30:23.171948496 +0100 >@@ -0,0 +1,64 @@ >+/* >+ * linux/drivers/video/riva/encoder.h - Xbox driver for encoder chip >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+ >+#ifndef encoder_h >+#define encoder_h >+ >+#include <linux/xboxfbctl.h> >+ >+typedef struct { >+ double m_dHzBurstFrequency; >+ double m_dSecBurstStart; >+ double m_dSecBurstEnd; >+ double m_dSecHsyncWidth; >+ double m_dSecHsyncPeriod; >+ double m_dSecActiveBegin; >+ double m_dSecImageCentre; >+ double m_dSecBlankBeginToHsync; >+ unsigned int m_dwALO; >+ double m_TotalLinesOut; >+ double m_dSecHsyncToBlankEnd; >+} conexant_video_parameter; >+ >+typedef struct _xbox_video_mode { >+ int xres; >+ int yres; >+ int bpp; >+ double hoc; >+ double voc; >+ xbox_av_type av_type; >+ xbox_tv_encoding tv_encoding; >+} xbox_video_mode; >+ >+typedef enum enumHdtvModes { >+ HDTV_480p, >+ HDTV_720p, >+ HDTV_1080i >+} xbox_hdtv_mode; >+ >+static const conexant_video_parameter vidstda[]; >+ >+int tv_init(void); >+void tv_exit(void); >+xbox_encoder_type tv_get_video_encoder(void); >+ >+void tv_save_mode(unsigned char * mode_out); >+void tv_load_mode(unsigned char * mode); >+xbox_tv_encoding get_tv_encoding(void); >+xbox_av_type detect_av_type(void); >+ >+#endif >diff -urN linux-2.6.6.orig/drivers/video/xbox/fbdev.c linux-2.6.6/drivers/video/xbox/fbdev.c >--- linux-2.6.6.orig/drivers/video/xbox/fbdev.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/fbdev.c 2004-05-10 12:30:23.191945456 +0100 >@@ -0,0 +1,2254 @@ >+/* >+ * linux/drivers/video/riva/fbdev.c - nVidia Xbox fb driver >+ * >+ * Maintained by Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Based on the nVidia RIVA 128/TNT/TNT2 fb driver, maintained by >+ * Ani Joshi <ajoshi@shell.unixbox.com> >+ * >+ * Copyright 1999-2000 Jeff Garzik >+ * >+ * Contributors: >+ * >+ * Ani Joshi: Lots of debugging and cleanup work, really helped >+ * get the driver going >+ * >+ * Ferenc Bakonyi: Bug fixes, cleanup, modularization >+ * >+ * Jindrich Makovicka: Accel code help, hw cursor, mtrr >+ * >+ * Paul Richards: Bug fixes, updates >+ * >+ * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven >+ * Includes riva_hw.c from nVidia, see copyright below. >+ * KGI code provided the basis for state storage, init, and mode switching. >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * restoring text mode fails >+ * doublescan modes are broken >+ */ >+ >+#include <linux/config.h> >+#include <linux/module.h> >+#include <linux/kernel.h> >+#include <linux/errno.h> >+#include <linux/string.h> >+#include <linux/mm.h> >+#include <linux/tty.h> >+#include <linux/slab.h> >+#include <linux/delay.h> >+#include <linux/fb.h> >+#include <linux/init.h> >+#include <linux/pci.h> >+#ifdef CONFIG_MTRR >+#include <asm/mtrr.h> >+#endif >+#ifdef CONFIG_PPC_OF >+#include <asm/prom.h> >+#include <asm/pci-bridge.h> >+#endif >+ >+#include "xboxfb.h" >+#include "nvreg.h" >+#include <linux/sys.h> >+#include <asm/uaccess.h> >+#include <linux/xboxfbctl.h> >+#include "encoder-i2c.h" >+#include "conexant.h" >+#include "focus.h" >+#include "xlb.h" >+ >+#ifndef CONFIG_PCI /* sanity check */ >+#error This driver requires PCI support. >+#endif >+ >+/* version number of this driver */ >+#define RIVAFB_VERSION "0.9.5b" >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * various helpful macros and constants >+ * >+ * ------------------------------------------------------------------------- */ >+ >+#undef RIVAFBDEBUG >+#ifdef RIVAFBDEBUG >+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) >+#else >+#define DPRINTK(fmt, args...) >+#endif >+ >+#ifndef RIVA_NDEBUG >+#define assert(expr) \ >+ if(!(expr)) { \ >+ printk( "Assertion failed! %s,%s,%s,line=%d\n",\ >+ #expr,__FILE__,__FUNCTION__,__LINE__); \ >+ BUG(); \ >+ } >+#else >+#define assert(expr) >+#endif >+ >+#define PFX "xboxfb: " >+ >+/* macro that allows you to set overflow bits */ >+#define SetBitField(value,from,to) SetBF(to,GetBF(value,from)) >+#define SetBit(n) (1<<(n)) >+#define Set8Bits(value) ((value)&0xff) >+ >+/* HW cursor parameters */ >+#define MAX_CURS 32 >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * prototypes >+ * >+ * ------------------------------------------------------------------------- */ >+ >+static int xboxfb_blank(int blank, struct fb_info *info); >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * card identification >+ * >+ * ------------------------------------------------------------------------- */ >+ >+enum riva_chips { >+ CH_GEFORCE3_XBOX >+}; >+ >+/* directly indexed by riva_chips enum, above */ >+static struct riva_chip_info { >+ const char *name; >+ unsigned arch_rev; >+} riva_chip_info[] __initdata = { >+ { "GeForce3", NV_ARCH_20} >+}; >+ >+static struct pci_device_id xboxfb_pci_tbl[] = { >+ { PCI_VENDOR_ID_NVIDIA, 0x2a0, >+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_XBOX }, >+ { 0, } /* terminate list */ >+}; >+MODULE_DEVICE_TABLE(pci, xboxfb_pci_tbl); >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * global variables >+ * >+ * ------------------------------------------------------------------------- */ >+ >+/* command line data, set in xboxfb_setup() */ >+static u32 pseudo_palette[17]; >+static int flatpanel __initdata = -1; /* Autodetect later */ >+static int forceCRTC __initdata = -1; >+#ifdef CONFIG_MTRR >+static int nomtrr __initdata = 0; >+#endif >+ >+#ifndef MODULE >+static char *mode_option __initdata = NULL; >+#endif >+ >+static xbox_tv_encoding tv_encoding __initdata = TV_ENC_INVALID; >+static xbox_av_type av_type __initdata = AV_INVALID; >+static int hoc __initdata = -1; >+static int voc __initdata = -1; >+ >+static struct fb_fix_screeninfo xboxfb_fix = { >+ .id = "Xbox", >+ .type = FB_TYPE_PACKED_PIXELS, >+ .xpanstep = 1, >+ .ypanstep = 1, >+}; >+ >+static struct fb_var_screeninfo xboxfb_default_var = { >+ .xres = 640, >+ .yres = 480, >+ .xres_virtual = 640, >+ .yres_virtual = 480, >+ .bits_per_pixel = 8, >+ .red = {0, 8, 0}, >+ .green = {0, 8, 0}, >+ .blue = {0, 8, 0}, >+ .transp = {0, 0, 0}, >+ .activate = FB_ACTIVATE_NOW, >+ .height = -1, >+ .width = -1, >+ .accel_flags = FB_ACCELF_TEXT, >+ .pixclock = 39721, >+ .left_margin = 40, >+ .right_margin = 24, >+ .upper_margin = 32, >+ .lower_margin = 11, >+ .hsync_len = 96, >+ .vsync_len = 2, >+ .vmode = FB_VMODE_NONINTERLACED >+}; >+ >+static struct fb_var_screeninfo xboxfb_mode_480p = { >+ .xres = 720, >+ .yres = 480, >+ .xres_virtual = 720, >+ .yres_virtual = 480, >+ .bits_per_pixel = 32, >+ .red = {0, 8, 16}, >+ .green = {0, 8, 8}, >+ .blue = {0, 8, 0}, >+ .transp = {0, 0, 0}, >+ .activate = FB_ACTIVATE_NOW, >+ .height = -1, >+ .width = -1, >+ .accel_flags = FB_ACCELF_TEXT, >+ .pixclock = 37000, >+ .left_margin = 56, >+ .right_margin = 18, >+ .upper_margin = 29, >+ .lower_margin = 9, >+ .hsync_len = 64, >+ .vsync_len = 7, >+ .vmode = FB_VMODE_NONINTERLACED >+}; >+ >+static struct fb_var_screeninfo xboxfb_mode_720p = { >+ .xres = 1280, >+ .yres = 720, >+ .xres_virtual = 1280, >+ .yres_virtual = 720, >+ .bits_per_pixel = 8, >+ .red = {0, 8, 0}, >+ .green = {0, 8, 0}, >+ .blue = {0, 8, 0}, >+ .transp = {0, 0, 0}, >+ .activate = FB_ACTIVATE_NOW, >+ .height = -1, >+ .width = -1, >+ .accel_flags = FB_ACCELF_TEXT, >+ .pixclock = 13468, >+ .left_margin = 220, >+ .right_margin = 70, >+ .upper_margin = 22, >+ .lower_margin = 3, >+ .hsync_len = 80, >+ .vsync_len = 5, >+ .vmode = FB_VMODE_NONINTERLACED >+}; >+ >+static const char* tvEncodingNames[] = { >+ "NTSC", >+ "NTSC-60", >+ "PAL-BDGHI", >+ "PAL-N", >+ "PAL-NC", >+ "PAL-M", >+ "PAL-60" >+}; >+ >+static const char* avTypeNames[] = { >+ "SCART (RGB)", >+ "S-Video", >+ "VGA (Sync on green)", >+ "HDTV (Component video)", >+ "Composite", >+ "VGA (internal syncs)" >+}; >+ >+/* from GGI */ >+static const struct riva_regs reg_template = { >+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */ >+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, >+ 0x41, 0x01, 0x0F, 0x00, 0x00}, >+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT */ >+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */ >+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ >+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */ >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, /* 0x40 */ >+ }, >+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */ >+ 0xFF}, >+ {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */ >+ 0xEB /* MISC */ >+}; >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * MMIO access macros >+ * >+ * ------------------------------------------------------------------------- */ >+ >+static inline void CRTCout(struct riva_par *par, unsigned char index, >+ unsigned char val) >+{ >+ VGA_WR08(par->riva.PCIO, 0x3d4, index); >+ VGA_WR08(par->riva.PCIO, 0x3d5, val); >+} >+ >+static inline unsigned char CRTCin(struct riva_par *par, >+ unsigned char index) >+{ >+ VGA_WR08(par->riva.PCIO, 0x3d4, index); >+ return (VGA_RD08(par->riva.PCIO, 0x3d5)); >+} >+ >+static inline void GRAout(struct riva_par *par, unsigned char index, >+ unsigned char val) >+{ >+ VGA_WR08(par->riva.PVIO, 0x3ce, index); >+ VGA_WR08(par->riva.PVIO, 0x3cf, val); >+} >+ >+static inline unsigned char GRAin(struct riva_par *par, >+ unsigned char index) >+{ >+ VGA_WR08(par->riva.PVIO, 0x3ce, index); >+ return (VGA_RD08(par->riva.PVIO, 0x3cf)); >+} >+ >+static inline void SEQout(struct riva_par *par, unsigned char index, >+ unsigned char val) >+{ >+ VGA_WR08(par->riva.PVIO, 0x3c4, index); >+ VGA_WR08(par->riva.PVIO, 0x3c5, val); >+} >+ >+static inline unsigned char SEQin(struct riva_par *par, >+ unsigned char index) >+{ >+ VGA_WR08(par->riva.PVIO, 0x3c4, index); >+ return (VGA_RD08(par->riva.PVIO, 0x3c5)); >+} >+ >+static inline void ATTRout(struct riva_par *par, unsigned char index, >+ unsigned char val) >+{ >+ VGA_WR08(par->riva.PCIO, 0x3c0, index); >+ VGA_WR08(par->riva.PCIO, 0x3c0, val); >+} >+ >+static inline unsigned char ATTRin(struct riva_par *par, >+ unsigned char index) >+{ >+ VGA_WR08(par->riva.PCIO, 0x3c0, index); >+ return (VGA_RD08(par->riva.PCIO, 0x3c1)); >+} >+ >+static inline void MISCout(struct riva_par *par, unsigned char val) >+{ >+ VGA_WR08(par->riva.PVIO, 0x3c2, val); >+} >+ >+static inline unsigned char MISCin(struct riva_par *par) >+{ >+ return (VGA_RD08(par->riva.PVIO, 0x3cc)); >+} >+ >+static u8 byte_rev[256] = { >+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, >+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, >+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, >+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, >+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, >+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, >+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, >+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, >+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, >+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, >+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, >+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, >+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, >+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, >+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, >+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, >+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, >+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, >+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, >+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, >+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, >+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, >+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, >+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, >+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, >+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, >+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, >+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, >+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, >+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, >+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, >+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, >+}; >+ >+static inline void reverse_order(u32 *l) >+{ >+ u8 *a = (u8 *)l; >+ *a = byte_rev[*a], a++; >+ *a = byte_rev[*a], a++; >+ *a = byte_rev[*a], a++; >+ *a = byte_rev[*a]; >+} >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * cursor stuff >+ * >+ * ------------------------------------------------------------------------- */ >+ >+/** >+ * xboxfb_load_cursor_image - load cursor image to hardware >+ * @data: address to monochrome bitmap (1 = foreground color, 0 = background) >+ * @par: pointer to private data >+ * @w: width of cursor image in pixels >+ * @h: height of cursor image in scanlines >+ * @bg: background color (ARGB1555) - alpha bit determines opacity >+ * @fg: foreground color (ARGB1555) >+ * >+ * DESCRIPTiON: >+ * Loads cursor image based on a monochrome source and mask bitmap. The >+ * image bits determines the color of the pixel, 0 for background, 1 for >+ * foreground. Only the affected region (as determined by @w and @h >+ * parameters) will be updated. >+ * >+ * CALLED FROM: >+ * xboxfb_cursor() >+ */ >+static void xboxfb_load_cursor_image(struct riva_par *par, u8 *data, >+ u8* mask, u16 bg, u16 fg, u32 w, u32 h) >+{ >+ int i, j, k = 0; >+ u32 b, m, tmp; >+ >+ for (i = 0; i < h; i++) { >+ b = *((u32 *)data); >+ data = (u8 *)((u32 *)data + 1); >+ m = *((u32 *)mask); >+ mask = (u8 *)((u32 *)mask + 1); >+ reverse_order(&b); >+ >+ for (j = 0; j < w/2; j++) { >+ tmp = 0; >+#if defined (__BIG_ENDIAN) >+ tmp = (b & (1 << 31)) ? fg << 16 : bg << 16; >+ if (m & (1 << 31)) { >+ tmp |= 1 << 31; >+ } >+ b <<= 1; >+ m <<= 1; >+ >+ tmp |= (b & (1 << 31)) ? fg : bg; >+ if (m & (1 << 31)) { >+ tmp |= 1 << 15; >+ } >+ b <<= 1; >+ m <<= 1; >+#else >+ tmp = (b & 1) ? fg : bg; >+ if (m & 1) { >+ tmp |= 1 << 15; >+ } >+ b >>= 1; >+ m >>= 1; >+ >+ tmp |= (b & 1) ? fg << 16 : bg << 16; >+ if (m & 1) { >+ tmp |= 1 << 31; >+ } >+ b >>= 1; >+ m >>= 1; >+#endif >+ writel(tmp, par->riva.CURSOR + k++); >+ } >+ k += (MAX_CURS - w)/2; >+ } >+} >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * general utility functions >+ * >+ * ------------------------------------------------------------------------- */ >+ >+/** >+ * riva_wclut - set CLUT entry >+ * @chip: pointer to RIVA_HW_INST object >+ * @regnum: register number >+ * @red: red component >+ * @green: green component >+ * @blue: blue component >+ * >+ * DESCRIPTION: >+ * Sets color register @regnum. >+ * >+ * CALLED FROM: >+ * xboxfb_setcolreg() >+ */ >+static void riva_wclut(RIVA_HW_INST *chip, >+ unsigned char regnum, unsigned char red, >+ unsigned char green, unsigned char blue) >+{ >+ VGA_WR08(chip->PDIO, 0x3c8, regnum); >+ VGA_WR08(chip->PDIO, 0x3c9, red); >+ VGA_WR08(chip->PDIO, 0x3c9, green); >+ VGA_WR08(chip->PDIO, 0x3c9, blue); >+} >+ >+/** >+ * riva_rclut - read fromCLUT register >+ * @chip: pointer to RIVA_HW_INST object >+ * @regnum: register number >+ * @red: red component >+ * @green: green component >+ * @blue: blue component >+ * >+ * DESCRIPTION: >+ * Reads red, green, and blue from color register @regnum. >+ * >+ * CALLED FROM: >+ * xboxfb_setcolreg() >+ */ >+static void riva_rclut(RIVA_HW_INST *chip, >+ unsigned char regnum, unsigned char *red, >+ unsigned char *green, unsigned char *blue) >+{ >+ >+ VGA_WR08(chip->PDIO, 0x3c8, regnum); >+ *red = VGA_RD08(chip->PDIO, 0x3c9); >+ *green = VGA_RD08(chip->PDIO, 0x3c9); >+ *blue = VGA_RD08(chip->PDIO, 0x3c9); >+} >+ >+/** >+ * riva_save_state - saves current chip state >+ * @par: pointer to riva_par object containing info for current riva board >+ * @regs: pointer to riva_regs object >+ * >+ * DESCRIPTION: >+ * Saves current chip state to @regs. >+ * >+ * CALLED FROM: >+ * xboxfb_probe() >+ */ >+/* from GGI */ >+static void riva_save_state(struct riva_par *par, struct riva_regs *regs) >+{ >+ int i; >+ >+ par->riva.LockUnlock(&par->riva, 0); >+ >+ par->riva.UnloadStateExt(&par->riva, ®s->ext); >+ >+ regs->misc_output = MISCin(par); >+ >+ for (i = 0; i < NUM_CRT_REGS; i++) >+ regs->crtc[i] = CRTCin(par, i); >+ >+ for (i = 0; i < NUM_ATC_REGS; i++) >+ regs->attr[i] = ATTRin(par, i); >+ >+ for (i = 0; i < NUM_GRC_REGS; i++) >+ regs->gra[i] = GRAin(par, i); >+ >+ for (i = 0; i < NUM_SEQ_REGS; i++) >+ regs->seq[i] = SEQin(par, i); >+} >+ >+/** >+ * riva_load_state - loads current chip state >+ * @par: pointer to riva_par object containing info for current riva board >+ * @regs: pointer to riva_regs object >+ * >+ * DESCRIPTION: >+ * Loads chip state from @regs. >+ * >+ * CALLED FROM: >+ * riva_load_video_mode() >+ * xboxfb_probe() >+ * xboxfb_remove() >+ */ >+/* from GGI */ >+static void riva_load_state(struct riva_par *par, struct riva_regs *regs) >+{ >+ RIVA_HW_STATE *state = ®s->ext; >+ int i; >+ >+ CRTCout(par, 0x11, 0x00); >+ >+ par->riva.LockUnlock(&par->riva, 0); >+ >+ par->riva.LoadStateExt(&par->riva, state); >+ >+ par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start; >+ >+ par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PRAMDAC[0x00000848/4] = 0x10100111; >+ par->riva.PRAMDAC[0x00000880/4] = 0; >+ par->riva.PRAMDAC[0x000008a0/4] = 0; >+ par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ /* Switch GPU to RGB output */ >+ par->riva.PRAMDAC[0x00000630/4] = 0; >+ /* These fix the maroon borders seen when booting from Xromwell or >+ * xbeboot >+ */ >+ par->riva.PRAMDAC[0x0000084c/4] = 0; >+ par->riva.PRAMDAC[0x000008c4/4] = 0; >+ >+ /* for YCrCb: >+ par->riva.PRAMDAC[0x00000630/4] = 2; >+ par->riva.PRAMDAC[0x0000084c/4] =0x00801080; >+ par->riva.PRAMDAC[0x000008c4/4] =0x40801080; >+ */ >+ MISCout(par, regs->misc_output); >+ >+ for (i = 0; i < NUM_CRT_REGS; i++) { >+ switch (i) { >+ case 0x0c: >+ case 0x0d: >+ case 0x19: >+ case 0x20 ... 0x40: >+ break; >+ default: >+ CRTCout(par, i, regs->crtc[i]); >+ } >+ } >+ >+ for (i = 0; i < NUM_ATC_REGS; i++) >+ ATTRout(par, i, regs->attr[i]); >+ >+ for (i = 0; i < NUM_GRC_REGS; i++) >+ GRAout(par, i, regs->gra[i]); >+ >+ for (i = 0; i < NUM_SEQ_REGS; i++) >+ SEQout(par, i, regs->seq[i]); >+ tv_save_mode(regs->encoder_mode); >+} >+ >+static inline unsigned long xbox_memory_size(void) { >+ /* make a guess on the xbox memory size. There are just >+ two possibilities */ >+ if ((num_physpages << PAGE_SHIFT) > 64*1024*1024) { >+ return 128*1024*1024; >+ } else { >+ return 64*1024*1024; >+ } >+} >+ >+static inline unsigned long available_framebuffer_memory(void) { >+ return xbox_memory_size() - (num_physpages << PAGE_SHIFT); >+} >+ >+/** >+ * riva_load_video_mode - calculate timings >+ * @info: pointer to fb_info object containing info for current riva board >+ * >+ * DESCRIPTION: >+ * Calculate some timings and then send em off to riva_load_state(). >+ * >+ * CALLED FROM: >+ * xboxfb_set_par() >+ */ >+static void riva_load_video_mode(struct fb_info *info) >+{ >+ int bpp, width, height, hDisplaySize, hStart, hTotal, vStart, vTotal; >+ int crtc_hDisplay, crtc_hStart, crtc_hEnd, crtc_hTotal; >+ int crtc_vDisplay, crtc_vStart, crtc_vEnd, crtc_vTotal, dotClock; >+ int crtc_hBlankStart, crtc_hBlankEnd, crtc_vBlankStart, crtc_vBlankEnd; >+ struct riva_par *par = (struct riva_par *) info->par; >+ struct riva_regs newmode; >+ int encoder_ok = 0; >+ >+ /* time to calculate */ >+ xboxfb_blank(1, info); >+ >+ bpp = info->var.bits_per_pixel; >+ if (bpp == 16 && info->var.green.length == 5) >+ bpp = 15; >+ width = info->var.xres_virtual; >+ height = info->var.yres_virtual; >+ hDisplaySize = info->var.xres; >+ hStart = hDisplaySize + info->var.right_margin; >+ hTotal = hDisplaySize + info->var.right_margin + >+ info->var.hsync_len + info->var.left_margin; >+ vStart = info->var.yres + info->var.lower_margin; >+ vTotal = info->var.yres + info->var.lower_margin + >+ info->var.vsync_len + info->var.upper_margin; >+ >+ crtc_hDisplay = (hDisplaySize / 8) - 1; >+ crtc_hStart = (hTotal - 32) / 8; >+ /* crtc_hStart = hStart / 8 - 1; */ >+ crtc_hEnd = crtc_hStart + 1; >+ /* crtc_hEnd = (hStart + info->var.hsync_len) / 8 - 1; */ >+ crtc_hTotal = hTotal / 8 - 5; >+ crtc_hBlankStart = crtc_hDisplay; >+ crtc_hBlankEnd = crtc_hTotal + 4; >+ >+ crtc_vDisplay = info->var.yres - 1; >+ /* crtc_vStart = vStart - 1; */ >+ crtc_vStart = vStart - 1; >+ /* crtc_vEnd = vStart + info->var.vsync_len - 1; */ >+ crtc_vEnd = crtc_vStart + 2; >+ crtc_vTotal = vTotal + 2; >+ crtc_vDisplay = info->var.yres - 1; >+ crtc_vBlankStart = crtc_vDisplay; >+ crtc_vBlankEnd = crtc_vTotal + 1; >+ >+ dotClock = 1000000000 / info->var.pixclock; >+ >+ memcpy(&newmode, ®_template, sizeof(struct riva_regs)); >+ >+ if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) >+ vTotal |= 1; >+ >+ if (par->FlatPanel) { >+ crtc_vStart = crtc_vTotal - 3; >+ crtc_vEnd = crtc_vTotal - 2; >+ crtc_vBlankStart = crtc_vStart; >+ crtc_hStart = crtc_hTotal - 3; >+ crtc_hEnd = crtc_hTotal - 2; >+ crtc_hBlankEnd = crtc_hTotal + 4; >+ } >+ >+ newmode.ext.bpp = bpp; >+ newmode.ext.fb_start = par->riva_fb_start; >+ >+ if((par->av_type == AV_VGA) || (par->av_type == AV_VGA_SOG) || (par->av_type == AV_HDTV)) { >+ unsigned char pll_int = (unsigned char)((double)dotClock * 6.0 / 13.5e3 + 0.5); >+ if (par->av_type == AV_HDTV) { >+ xbox_hdtv_mode hdtv_mode = HDTV_480p; >+ if (info->var.yres > 800) { >+ hdtv_mode = HDTV_1080i; >+ crtc_vStart = vStart + 31; >+ crtc_vEnd = crtc_vStart + 2; >+ } >+ else if (info->var.yres > 600) { >+ hdtv_mode = HDTV_720p; >+ } >+ switch (par->video_encoder) { >+ case ENCODER_CONEXANT: >+ encoder_ok = conexant_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode); >+ break; >+ case ENCODER_FOCUS: >+ encoder_ok = focus_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode); >+ break; >+ case ENCODER_XLB: >+ encoder_ok = xlb_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode); >+ break; >+ default: >+ printk("Error - unknown encoder type detected\n"); >+ } >+ } >+ else { >+ switch (par->video_encoder) { >+ case ENCODER_CONEXANT: >+ encoder_ok = conexant_calc_vga_mode(par->av_type, pll_int, newmode.encoder_mode); >+ break; >+ case ENCODER_FOCUS: >+ //No vga functions as yet - so set up for 480p otherwise we dont boot at all. >+ encoder_ok = focus_calc_hdtv_mode(HDTV_480p, pll_int, newmode.encoder_mode); >+ break; >+ case ENCODER_XLB: >+ //No vga functions as yet - so set up for 480p otherwise we dont boot at all. >+ encoder_ok = xlb_calc_hdtv_mode(HDTV_480p, pll_int, newmode.encoder_mode); >+ break; >+ default: >+ printk("Error - unknown encoder type detected\n"); >+ } >+ } >+ newmode.ext.vend = info->var.yres - 1; >+ newmode.ext.vtotal = vTotal; >+ newmode.ext.vcrtc = info->var.yres - 1; >+ newmode.ext.vsyncstart = vStart; >+ newmode.ext.vsyncend = vStart + 3; >+ newmode.ext.vvalidstart = 0; >+ newmode.ext.vvalidend = info->var.yres - 1; >+ newmode.ext.hend = info->var.xres - 1; >+ newmode.ext.htotal = hTotal; >+ newmode.ext.hcrtc = info->var.xres - 1; >+ newmode.ext.hsyncstart = hStart; >+ newmode.ext.hsyncend = hStart + 32; >+ newmode.ext.hvalidstart = 0; >+ newmode.ext.hvalidend = info->var.xres - 1; >+ } >+ >+ /* Normal composite */ >+ else { >+ xbox_video_mode encoder_mode; >+ encoder_mode.xres = info->var.xres; >+ encoder_mode.yres = info->var.yres; >+ encoder_mode.tv_encoding = par->tv_encoding; >+ encoder_mode.bpp = bpp; >+ encoder_mode.hoc = par->hoc; >+ encoder_mode.voc = par->voc; >+ encoder_mode.av_type = par->av_type; >+ >+ switch (par->video_encoder) { >+ case ENCODER_CONEXANT: >+ encoder_ok = conexant_calc_mode(&encoder_mode, &newmode); >+ break; >+ case ENCODER_FOCUS: >+ encoder_ok = focus_calc_mode(&encoder_mode, &newmode); >+ break; >+ case ENCODER_XLB: >+ encoder_ok = xlb_calc_mode(&encoder_mode, &newmode); >+ break; >+ default: >+ printk("Error - unknown encoder type detected\n"); >+ } >+ >+ crtc_hDisplay = (newmode.ext.crtchdispend / 8) - 1; >+ crtc_hStart = (newmode.ext.htotal - 32) / 8; >+ crtc_hEnd = crtc_hStart + 1; >+ crtc_hTotal = (newmode.ext.htotal) / 8 - 5; >+ crtc_hBlankStart = crtc_hDisplay; >+ crtc_hBlankEnd = (newmode.ext.htotal) / 8 - 1; >+ >+ crtc_vDisplay = info->var.yres - 1; >+ crtc_vStart = newmode.ext.crtcvstart; >+ crtc_vEnd = newmode.ext.crtcvstart + 3; >+ crtc_vTotal = newmode.ext.crtcvtotal; >+ crtc_vBlankStart = crtc_vDisplay; >+ crtc_vBlankEnd = crtc_vTotal + 1; >+ } >+ >+ if (encoder_ok) { >+ newmode.crtc[0x0] = Set8Bits (crtc_hTotal); >+ newmode.crtc[0x1] = Set8Bits (crtc_hDisplay); >+ newmode.crtc[0x2] = Set8Bits (crtc_hBlankStart); >+ newmode.crtc[0x3] = SetBitField (crtc_hBlankEnd, 4: 0, 4:0) | SetBit (7); >+ newmode.crtc[0x4] = Set8Bits (crtc_hStart); >+ newmode.crtc[0x5] = SetBitField (crtc_hBlankEnd, 5: 5, 7:7) >+ | SetBitField (crtc_hEnd, 4: 0, 4:0); >+ newmode.crtc[0x6] = SetBitField (crtc_vTotal, 7: 0, 7:0); >+ newmode.crtc[0x7] = SetBitField (crtc_vTotal, 8: 8, 0:0) >+ | SetBitField (crtc_vDisplay, 8: 8, 1:1) >+ | SetBitField (crtc_vStart, 8: 8, 2:2) >+ | SetBitField (crtc_vBlankStart, 8: 8, 3:3) >+ | SetBit (4) >+ | SetBitField (crtc_vTotal, 9: 9, 5:5) >+ | SetBitField (crtc_vDisplay, 9: 9, 6:6) >+ | SetBitField (crtc_vStart, 9: 9, 7:7); >+ newmode.crtc[0x9] = SetBitField (crtc_vBlankStart, 9: 9, 5:5) >+ | SetBit (6); >+ newmode.crtc[0x10] = Set8Bits (crtc_vStart); >+ newmode.crtc[0x11] = SetBitField (crtc_vEnd, 3: 0, 3:0) >+ | SetBit (5); >+ newmode.crtc[0x12] = Set8Bits (crtc_vDisplay); >+ newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8); >+ newmode.crtc[0x15] = Set8Bits (crtc_vBlankStart); >+ newmode.crtc[0x16] = Set8Bits (crtc_vBlankEnd); >+ >+ newmode.ext.screen = SetBitField(crtc_hBlankEnd,6:6,4:4) >+ | SetBitField(crtc_vBlankStart,10:10,3:3) >+ | SetBitField(crtc_vStart,10:10,2:2) >+ | SetBitField(crtc_vDisplay,10:10,1:1) >+ | SetBitField(crtc_vTotal,10:10,0:0); >+ newmode.ext.horiz = SetBitField(crtc_hTotal,8:8,0:0) >+ | SetBitField(crtc_hDisplay,8:8,1:1) >+ | SetBitField(crtc_hBlankStart,8:8,2:2) >+ | SetBitField(crtc_hStart,8:8,3:3); >+ newmode.ext.extra = SetBitField(crtc_vTotal,11:11,0:0) >+ | SetBitField(crtc_vDisplay,11:11,2:2) >+ | SetBitField(crtc_vStart,11:11,4:4) >+ | SetBitField(crtc_vBlankStart,11:11,6:6); >+ >+ if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { >+ int tmp = (crtc_hTotal >> 1) & ~1; >+ newmode.ext.interlace = Set8Bits(tmp); >+ newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4); >+ } else >+ newmode.ext.interlace = 0xff; /* interlace off */ >+ >+ if (par->riva.Architecture >= NV_ARCH_10) >+ /* use 2 KByte at top of framebuffer */ >+ par->riva.CURSOR = (U032 *)(info->screen_base + info->fix.smem_len - 2 * 1024); >+ >+ if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) >+ newmode.misc_output &= ~0x40; >+ else >+ newmode.misc_output |= 0x40; >+ if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) >+ newmode.misc_output &= ~0x80; >+ else >+ newmode.misc_output |= 0x80; >+ >+ par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width, >+ hDisplaySize, height, dotClock); >+ >+ newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff; >+ if (par->FlatPanel == 1) { >+ newmode.ext.pixel |= (1 << 7); >+ newmode.ext.scale |= (1 << 8); >+ } >+ if (par->SecondCRTC) { >+ newmode.ext.head = par->riva.PCRTC0[0x00000860/4] & ~0x00001000; >+ newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000; >+ newmode.ext.crtcOwner = 3; >+ newmode.ext.pllsel |= 0x20000800; >+ newmode.ext.vpll2 = newmode.ext.vpll; >+ } else if (par->riva.twoHeads) { >+ newmode.ext.head = par->riva.PCRTC0[0x00000860/4] | 0x00001000; >+ newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] & ~0x00001000; >+ newmode.ext.crtcOwner = 0; >+ newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4]; >+ } >+ if (par->FlatPanel == 1) { >+ newmode.ext.pixel |= (1 << 7); >+ newmode.ext.scale |= (1 << 8); >+ } >+ newmode.ext.cursorConfig = 0x02000100; >+ par->current_state = newmode; >+ riva_load_state(par, &par->current_state); >+ tv_load_mode(newmode.encoder_mode); >+ par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */ >+ } >+ else { >+ printk("Error: Unable to set encoder resolution %dx%d\n",info->var.xres, info->var.yres); >+ } >+ >+ xboxfb_blank(0, info); >+} >+ >+/** >+ * xboxfb_do_maximize - >+ * @info: pointer to fb_info object containing info for current riva board >+ * @var: >+ * @nom: >+ * @den: >+ * >+ * DESCRIPTION: >+ * . >+ * >+ * RETURNS: >+ * -EINVAL on failure, 0 on success >+ * >+ * >+ * CALLED FROM: >+ * xboxfb_check_var() >+ */ >+static int xboxfb_do_maximize(struct fb_info *info, >+ struct fb_var_screeninfo *var, >+ int nom, int den) >+{ >+ static struct { >+ int xres, yres; >+ } modes[] = { >+ {1600, 1280}, >+ {1280, 1024}, >+ {1024, 768}, >+ {800, 600}, >+ {640, 480}, >+ {-1, -1} >+ }; >+ int i; >+ >+ /* use highest possible virtual resolution */ >+ if (var->xres_virtual == -1 && var->yres_virtual == -1) { >+ printk(KERN_WARNING PFX >+ "using maximum available virtual resolution\n"); >+ for (i = 0; modes[i].xres != -1; i++) { >+ if (modes[i].xres * nom / den * modes[i].yres < >+ info->fix.smem_len / 2) >+ break; >+ } >+ if (modes[i].xres == -1) { >+ printk(KERN_ERR PFX >+ "could not find a virtual resolution that fits into video memory!!\n"); >+ DPRINTK("EXIT - EINVAL error\n"); >+ return -EINVAL; >+ } >+ var->xres_virtual = modes[i].xres; >+ var->yres_virtual = modes[i].yres; >+ >+ printk(KERN_INFO PFX >+ "virtual resolution set to maximum of %dx%d\n", >+ var->xres_virtual, var->yres_virtual); >+ } else if (var->xres_virtual == -1) { >+ var->xres_virtual = (info->fix.smem_len * den / >+ (nom * var->yres_virtual * 2)) & ~15; >+ printk(KERN_WARNING PFX >+ "setting virtual X resolution to %d\n", var->xres_virtual); >+ } else if (var->yres_virtual == -1) { >+ var->xres_virtual = (var->xres_virtual + 15) & ~15; >+ var->yres_virtual = info->fix.smem_len * den / >+ (nom * var->xres_virtual * 2); >+ printk(KERN_WARNING PFX >+ "setting virtual Y resolution to %d\n", var->yres_virtual); >+ } else { >+ var->xres_virtual = (var->xres_virtual + 15) & ~15; >+ if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) { >+ printk(KERN_ERR PFX >+ "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n", >+ var->xres, var->yres, var->bits_per_pixel); >+ DPRINTK("EXIT - EINVAL error\n"); >+ return -EINVAL; >+ } >+ } >+ >+ if (var->xres_virtual * nom / den >= 8192) { >+ printk(KERN_WARNING PFX >+ "virtual X resolution (%d) is too high, lowering to %d\n", >+ var->xres_virtual, 8192 * den / nom - 16); >+ var->xres_virtual = 8192 * den / nom - 16; >+ } >+ >+ if (var->xres_virtual < var->xres) { >+ printk(KERN_ERR PFX >+ "virtual X resolution (%d) is smaller than real\n", var->xres_virtual); >+ return -EINVAL; >+ } >+ >+ if (var->yres_virtual < var->yres) { >+ printk(KERN_ERR PFX >+ "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual); >+ return -EINVAL; >+ } >+ return 0; >+} >+ >+/* acceleration routines */ >+inline void wait_for_idle(struct riva_par *par) >+{ >+ while (par->riva.Busy(&par->riva)); >+} >+ >+/* set copy ROP, no mask */ >+static void riva_setup_ROP(struct riva_par *par) >+{ >+ RIVA_FIFO_FREE(par->riva, Patt, 5); >+ par->riva.Patt->Shape = 0; >+ par->riva.Patt->Color0 = 0xffffffff; >+ par->riva.Patt->Color1 = 0xffffffff; >+ par->riva.Patt->Monochrome[0] = 0xffffffff; >+ par->riva.Patt->Monochrome[1] = 0xffffffff; >+ >+ RIVA_FIFO_FREE(par->riva, Rop, 1); >+ par->riva.Rop->Rop3 = 0xCC; >+} >+ >+void riva_setup_accel(struct riva_par *par) >+{ >+ RIVA_FIFO_FREE(par->riva, Clip, 2); >+ par->riva.Clip->TopLeft = 0x0; >+ par->riva.Clip->WidthHeight = 0x80008000; >+ riva_setup_ROP(par); >+ wait_for_idle(par); >+} >+ >+/** >+ * riva_get_cmap_len - query current color map length >+ * @var: standard kernel fb changeable data >+ * >+ * DESCRIPTION: >+ * Get current color map length. >+ * >+ * RETURNS: >+ * Length of color map >+ * >+ * CALLED FROM: >+ * xboxfb_setcolreg() >+ */ >+static int riva_get_cmap_len(const struct fb_var_screeninfo *var) >+{ >+ int rc = 256; /* reasonable default */ >+ >+ switch (var->green.length) { >+ case 8: >+ rc = 256; /* 256 entries (2^8), 8 bpp and RGB8888 */ >+ break; >+ case 5: >+ rc = 32; /* 32 entries (2^5), 16 bpp, RGB555 */ >+ break; >+ case 6: >+ rc = 64; /* 64 entries (2^6), 16 bpp, RGB565 */ >+ break; >+ default: >+ /* should not occur */ >+ break; >+ } >+ return rc; >+} >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * framebuffer operations >+ * >+ * ------------------------------------------------------------------------- */ >+ >+static int xboxfb_open(struct fb_info *info, int user) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ int cnt = atomic_read(&par->ref_count); >+ >+ if (!cnt) { >+ memset(&par->state, 0, sizeof(struct vgastate)); >+ par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; >+ /* save the DAC for Riva128 */ >+ if (par->riva.Architecture == NV_ARCH_03) >+ par->state.flags |= VGA_SAVE_CMAP; >+ save_vga(&par->state); >+ >+ RivaGetConfig(&par->riva, par->Chipset); >+ par->riva.CURSOR = (U032*)(info->screen_base + info->fix.smem_len); >+ par->riva.PCRTC[0x00000800/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start; >+ par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start; >+ >+ par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1; >+ >+ /* vgaHWunlock() + riva unlock (0x7F) */ >+ CRTCout(par, 0x11, 0xFF); >+ par->riva.LockUnlock(&par->riva, 0); >+ >+ riva_save_state(par, &par->initial_state); >+ } >+ atomic_inc(&par->ref_count); >+ return 0; >+} >+ >+static int xboxfb_release(struct fb_info *info, int user) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ int cnt = atomic_read(&par->ref_count); >+ >+ if (!cnt) >+ return -EINVAL; >+ if (cnt == 1) { >+ par->riva.LockUnlock(&par->riva, 0); >+ par->riva.LoadStateExt(&par->riva, &par->initial_state.ext); >+ riva_load_state(par, &par->initial_state); >+ restore_vga(&par->state); >+ par->riva.LockUnlock(&par->riva, 1); >+ } >+ atomic_dec(&par->ref_count); >+ return 0; >+} >+ >+static int xboxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) >+{ >+ int nom, den; /* translating from pixels->bytes */ >+ >+ switch (var->bits_per_pixel) { >+ case 1 ... 8: >+ var->red.offset = var->green.offset = var->blue.offset = 0; >+ var->red.length = var->green.length = var->blue.length = 8; >+ var->bits_per_pixel = 8; >+ nom = den = 1; >+ break; >+ case 9 ... 15: >+ var->green.length = 5; >+ /* fall through */ >+ case 16: >+ var->bits_per_pixel = 16; >+ if (var->green.length == 5) { >+ /* 0rrrrrgg gggbbbbb */ >+ var->red.offset = 10; >+ var->green.offset = 5; >+ var->blue.offset = 0; >+ var->red.length = 5; >+ var->green.length = 5; >+ var->blue.length = 5; >+ } else { >+ /* rrrrrggg gggbbbbb */ >+ var->red.offset = 11; >+ var->green.offset = 5; >+ var->blue.offset = 0; >+ var->red.length = 5; >+ var->green.length = 6; >+ var->blue.length = 5; >+ } >+ nom = 2; >+ den = 1; >+ break; >+ case 17 ... 32: >+ var->red.length = var->green.length = var->blue.length = 8; >+ var->bits_per_pixel = 32; >+ var->red.offset = 16; >+ var->green.offset = 8; >+ var->blue.offset = 0; >+ nom = 4; >+ den = 1; >+ break; >+ default: >+ printk(KERN_ERR PFX >+ "mode %dx%dx%d rejected...color depth not supported.\n", >+ var->xres, var->yres, var->bits_per_pixel); >+ DPRINTK("EXIT, returning -EINVAL\n"); >+ return -EINVAL; >+ } >+ >+ if (xboxfb_do_maximize(info, var, nom, den) < 0) >+ return -EINVAL; >+ >+ if (var->xoffset < 0) >+ var->xoffset = 0; >+ if (var->yoffset < 0) >+ var->yoffset = 0; >+ >+ /* truncate xoffset and yoffset to maximum if too high */ >+ if (var->xoffset > var->xres_virtual - var->xres) >+ var->xoffset = var->xres_virtual - var->xres - 1; >+ >+ if (var->yoffset > var->yres_virtual - var->yres) >+ var->yoffset = var->yres_virtual - var->yres - 1; >+ >+ var->red.msb_right = >+ var->green.msb_right = >+ var->blue.msb_right = >+ var->transp.offset = var->transp.length = var->transp.msb_right = 0; >+ return 0; >+} >+ >+static int xboxfb_set_par(struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ riva_load_video_mode(info); >+ riva_setup_accel(par); >+ >+ info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3)); >+ info->fix.visual = (info->var.bits_per_pixel == 8) ? >+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; >+ return 0; >+} >+ >+/** >+ * xboxfb_pan_display >+ * @var: standard kernel fb changeable data >+ * @con: TODO >+ * @info: pointer to fb_info object containing info for current riva board >+ * >+ * DESCRIPTION: >+ * Pan (or wrap, depending on the `vmode' field) the display using the >+ * `xoffset' and `yoffset' fields of the `var' structure. >+ * If the values don't fit, return -EINVAL. >+ * >+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag >+ */ >+static int xboxfb_pan_display(struct fb_var_screeninfo *var, >+ struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *)info->par; >+ unsigned int base; >+ >+ if (var->xoffset > (var->xres_virtual - var->xres)) >+ return -EINVAL; >+ if (var->yoffset > (var->yres_virtual - var->yres)) >+ return -EINVAL; >+ >+ if (var->vmode & FB_VMODE_YWRAP) { >+ if (var->yoffset < 0 >+ || var->yoffset >= info->var.yres_virtual >+ || var->xoffset) return -EINVAL; >+ } else { >+ if (var->xoffset + info->var.xres > info->var.xres_virtual || >+ var->yoffset + info->var.yres > info->var.yres_virtual) >+ return -EINVAL; >+ } >+ >+ base = var->yoffset * info->fix.line_length + var->xoffset; >+ base += par->riva_fb_start; >+ >+ par->riva.SetStartAddress(&par->riva, base); >+ >+ info->var.xoffset = var->xoffset; >+ info->var.yoffset = var->yoffset; >+ >+ if (var->vmode & FB_VMODE_YWRAP) >+ info->var.vmode |= FB_VMODE_YWRAP; >+ else >+ info->var.vmode &= ~FB_VMODE_YWRAP; >+ return 0; >+} >+ >+static int xboxfb_blank(int blank, struct fb_info *info) >+{ >+ struct riva_par *par= (struct riva_par *)info->par; >+ unsigned char tmp, vesa; >+ >+ tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */ >+ vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */ >+ >+ if (blank) { >+ tmp |= 0x20; >+ switch (blank - 1) { >+ case VESA_NO_BLANKING: >+ break; >+ case VESA_VSYNC_SUSPEND: >+ vesa |= 0x80; >+ break; >+ case VESA_HSYNC_SUSPEND: >+ vesa |= 0x40; >+ break; >+ case VESA_POWERDOWN: >+ vesa |= 0xc0; >+ break; >+ } >+ } >+ SEQout(par, 0x01, tmp); >+ CRTCout(par, 0x1a, vesa); >+ return 0; >+} >+ >+/** >+ * xboxfb_setcolreg >+ * @regno: register index >+ * @red: red component >+ * @green: green component >+ * @blue: blue component >+ * @transp: transparency >+ * @info: pointer to fb_info object containing info for current riva board >+ * >+ * DESCRIPTION: >+ * Set a single color register. The values supplied have a 16 bit >+ * magnitude. >+ * >+ * RETURNS: >+ * Return != 0 for invalid regno. >+ * >+ * CALLED FROM: >+ * fbcmap.c:fb_set_cmap() >+ */ >+static int xboxfb_setcolreg(unsigned regno, unsigned red, unsigned green, >+ unsigned blue, unsigned transp, >+ struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *)info->par; >+ RIVA_HW_INST *chip = &par->riva; >+ int i; >+ >+ if (regno >= riva_get_cmap_len(&info->var)) >+ return -EINVAL; >+ >+ if (info->var.grayscale) { >+ /* gray = 0.30*R + 0.59*G + 0.11*B */ >+ red = green = blue = >+ (red * 77 + green * 151 + blue * 28) >> 8; >+ } >+ >+ switch (info->var.bits_per_pixel) { >+ case 8: >+ /* "transparent" stuff is completely ignored. */ >+ riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8); >+ break; >+ case 16: >+ if (info->var.green.length == 5) { >+ if (regno < 16) { >+ /* 0rrrrrgg gggbbbbb */ >+ ((u32 *)info->pseudo_palette)[regno] = >+ ((red & 0xf800) >> 1) | >+ ((green & 0xf800) >> 6) | >+ ((blue & 0xf800) >> 11); >+ } >+ for (i = 0; i < 8; i++) >+ riva_wclut(chip, regno*8+i, red >> 8, >+ green >> 8, blue >> 8); >+ } else { >+ u8 r, g, b; >+ >+ if (regno < 16) { >+ /* rrrrrggg gggbbbbb */ >+ ((u32 *)info->pseudo_palette)[regno] = >+ ((red & 0xf800) >> 0) | >+ ((green & 0xf800) >> 5) | >+ ((blue & 0xf800) >> 11); >+ } >+ if (regno < 32) { >+ for (i = 0; i < 8; i++) { >+ riva_wclut(chip, regno*8+i, red >> 8, >+ green >> 8, blue >> 8); >+ } >+ } >+ for (i = 0; i < 4; i++) { >+ riva_rclut(chip, regno*2+i, &r, &g, &b); >+ riva_wclut(chip, regno*4+i, r, green >> 8, b); >+ } >+ } >+ break; >+ case 32: >+ if (regno < 16) { >+ ((u32 *)info->pseudo_palette)[regno] = >+ ((red & 0xff00) << 8) | >+ ((green & 0xff00)) | ((blue & 0xff00) >> 8); >+ >+ } >+ riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8); >+ break; >+ default: >+ /* do nothing */ >+ break; >+ } >+ return 0; >+} >+ >+/** >+ * xboxfb_fillrect - hardware accelerated color fill function >+ * @info: pointer to fb_info structure >+ * @rect: pointer to fb_fillrect structure >+ * >+ * DESCRIPTION: >+ * This function fills up a region of framebuffer memory with a solid >+ * color with a choice of two different ROP's, copy or invert. >+ * >+ * CALLED FROM: >+ * framebuffer hook >+ */ >+static void xboxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ u_int color, rop = 0; >+ >+ if (info->var.bits_per_pixel == 8) >+ color = rect->color; >+ else >+ color = ((u32 *)info->pseudo_palette)[rect->color]; >+ >+ switch (rect->rop) { >+ case ROP_XOR: >+ rop = 0x66; >+ break; >+ case ROP_COPY: >+ default: >+ rop = 0xCC; >+ break; >+ } >+ >+ RIVA_FIFO_FREE(par->riva, Rop, 1); >+ par->riva.Rop->Rop3 = rop; >+ >+ RIVA_FIFO_FREE(par->riva, Bitmap, 1); >+ par->riva.Bitmap->Color1A = color; >+ >+ RIVA_FIFO_FREE(par->riva, Bitmap, 2); >+ par->riva.Bitmap->UnclippedRectangle[0].TopLeft = >+ (rect->dx << 16) | rect->dy; >+ par->riva.Bitmap->UnclippedRectangle[0].WidthHeight = >+ (rect->width << 16) | rect->height; >+ RIVA_FIFO_FREE(par->riva, Rop, 1); >+ par->riva.Rop->Rop3 = 0xCC; /* back to COPY */ >+} >+ >+/** >+ * xboxfb_copyarea - hardware accelerated blit function >+ * @info: pointer to fb_info structure >+ * @region: pointer to fb_copyarea structure >+ * >+ * DESCRIPTION: >+ * This copies an area of pixels from one location to another >+ * >+ * CALLED FROM: >+ * framebuffer hook >+ */ >+static void xboxfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ RIVA_FIFO_FREE(par->riva, Blt, 3); >+ par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx; >+ par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx; >+ par->riva.Blt->WidthHeight = (region->height << 16) | region->width; >+ wait_for_idle(par); >+} >+ >+static inline void convert_bgcolor_16(u32 *col) >+{ >+ *col = ((*col & 0x00007C00) << 9) >+ | ((*col & 0x000003E0) << 6) >+ | ((*col & 0x0000001F) << 3) >+ | 0xFF000000; >+} >+ >+/** >+ * xboxfb_imageblit: hardware accelerated color expand function >+ * @info: pointer to fb_info structure >+ * @image: pointer to fb_image structure >+ * >+ * DESCRIPTION: >+ * If the source is a monochrome bitmap, the function fills up a a region >+ * of framebuffer memory with pixels whose color is determined by the bit >+ * setting of the bitmap, 1 - foreground, 0 - background. >+ * >+ * If the source is not a monochrome bitmap, color expansion is not done. >+ * In this case, it is channeled to a software function. >+ * >+ * CALLED FROM: >+ * framebuffer hook >+ */ >+static void xboxfb_imageblit(struct fb_info *info, >+ const struct fb_image *image) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ u32 fgx = 0, bgx = 0, width, tmp; >+ u8 *cdat = (u8 *) image->data; >+ volatile u32 *d; >+ int i, size; >+ >+ if (image->depth != 1) { >+ cfb_imageblit(info, image); >+ return; >+ } >+ >+ switch (info->var.bits_per_pixel) { >+ case 8: >+ fgx = image->fg_color; >+ bgx = image->bg_color; >+ break; >+ case 16: >+ fgx = ((u32 *)info->pseudo_palette)[image->fg_color]; >+ bgx = ((u32 *)info->pseudo_palette)[image->bg_color]; >+ if (info->var.green.length == 6) >+ convert_bgcolor_16(&bgx); >+ break; >+ case 32: >+ fgx = ((u32 *)info->pseudo_palette)[image->fg_color]; >+ bgx = ((u32 *)info->pseudo_palette)[image->bg_color]; >+ break; >+ } >+ >+ RIVA_FIFO_FREE(par->riva, Bitmap, 7); >+ par->riva.Bitmap->ClipE.TopLeft = >+ (image->dy << 16) | (image->dx & 0xFFFF); >+ par->riva.Bitmap->ClipE.BottomRight = >+ (((image->dy + image->height) << 16) | >+ ((image->dx + image->width) & 0xffff)); >+ par->riva.Bitmap->Color0E = bgx; >+ par->riva.Bitmap->Color1E = fgx; >+ par->riva.Bitmap->WidthHeightInE = >+ (image->height << 16) | ((image->width + 31) & ~31); >+ par->riva.Bitmap->WidthHeightOutE = >+ (image->height << 16) | ((image->width + 31) & ~31); >+ par->riva.Bitmap->PointE = >+ (image->dy << 16) | (image->dx & 0xFFFF); >+ >+ d = &par->riva.Bitmap->MonochromeData01E; >+ >+ width = (image->width + 31)/32; >+ size = width * image->height; >+ while (size >= 16) { >+ RIVA_FIFO_FREE(par->riva, Bitmap, 16); >+ for (i = 0; i < 16; i++) { >+ tmp = *((u32 *)cdat); >+ cdat = (u8 *)((u32 *)cdat + 1); >+ reverse_order(&tmp); >+ d[i] = tmp; >+ } >+ size -= 16; >+ } >+ if (size) { >+ RIVA_FIFO_FREE(par->riva, Bitmap, size); >+ for (i = 0; i < size; i++) { >+ tmp = *((u32 *) cdat); >+ cdat = (u8 *)((u32 *)cdat + 1); >+ reverse_order(&tmp); >+ d[i] = tmp; >+ } >+ } >+} >+ >+/** >+ * xboxfb_cursor - hardware cursor function >+ * @info: pointer to info structure >+ * @cursor: pointer to fbcursor structure >+ * >+ * DESCRIPTION: >+ * A cursor function that supports displaying a cursor image via hardware. >+ * Within the kernel, copy and invert rops are supported. If exported >+ * to user space, only the copy rop will be supported. >+ * >+ * CALLED FROM >+ * framebuffer hook >+ */ >+static int xboxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ u8 mask[MAX_CURS * MAX_CURS/8]; >+ u16 fg, bg; >+ >+ par->riva.ShowHideCursor(&par->riva, 0); >+ >+ if (cursor->set & FB_CUR_SETPOS) { >+ u32 xx, yy, temp; >+ >+ info->cursor.image.dx = cursor->image.dx; >+ info->cursor.image.dy = cursor->image.dy; >+ yy = cursor->image.dy - info->var.yoffset; >+ xx = cursor->image.dx - info->var.xoffset; >+ temp = xx & 0xFFFF; >+ temp |= yy << 16; >+ >+ par->riva.PRAMDAC[0x0000300/4] = temp; >+ } >+ >+ if (cursor->set & FB_CUR_SETSIZE) { >+ info->cursor.image.height = cursor->image.height; >+ info->cursor.image.width = cursor->image.width; >+ memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2); >+ } >+ >+ if (cursor->set & FB_CUR_SETCMAP) { >+ info->cursor.image.bg_color = cursor->image.bg_color; >+ info->cursor.image.fg_color = cursor->image.fg_color; >+ } >+ >+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) { >+ u32 bg_idx = info->cursor.image.bg_color; >+ u32 fg_idx = info->cursor.image.fg_color; >+ u32 s_pitch = (info->cursor.image.width+7) >> 3; >+ u32 d_pitch = MAX_CURS/8; >+ u8 *msk = (u8 *) info->cursor.mask; >+ >+ fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height); >+ bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) | >+ ((info->cmap.green[bg_idx] & 0xf8) << 2) | >+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3); >+ >+ fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) | >+ ((info->cmap.green[fg_idx] & 0xf8) << 2) | >+ ((info->cmap.blue[fg_idx] & 0xf8) >> 3); >+ >+ par->riva.LockUnlock(&par->riva, 0); >+ >+ xboxfb_load_cursor_image(par, mask, mask, bg, fg, >+ info->cursor.image.width, >+ info->cursor.image.height); >+ } >+ if (info->cursor.enable) >+ par->riva.ShowHideCursor(&par->riva, 1); >+ return 0; >+} >+ >+static int xboxfb_sync(struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *)info->par; >+ >+ wait_for_idle(par); >+ return 0; >+} >+ >+static int xboxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, >+ unsigned long arg, struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ xbox_overscan overscan; >+ xboxfb_config config; >+ xbox_tv_encoding encoding; >+ int ret = 0; >+ >+ switch (cmd) { >+ case FBIO_XBOX_SET_OVERSCAN: >+ if(!copy_from_user(&overscan, (xbox_overscan*)arg, sizeof(overscan))) { >+ par->hoc = overscan.hoc; >+ par->voc = overscan.voc; >+ riva_load_video_mode (info); >+ if (info->var.accel_flags & FB_ACCELF_TEXT) { >+ riva_setup_accel(par); >+ } >+ >+ } >+ else { >+ ret = -EFAULT; >+ } >+ break; >+ case FBIO_XBOX_GET_OVERSCAN: >+ overscan.hoc = par->hoc; >+ overscan.voc = par->voc; >+ if (copy_to_user((xbox_overscan*)arg, &overscan, sizeof(overscan))) { >+ ret = -EFAULT; >+ } >+ break; >+ case FBIO_XBOX_GET_CONFIG: >+ config.av_type = par->av_type; >+ config.encoder_type = par->video_encoder; >+ if (copy_to_user((xboxfb_config*)arg, &config, sizeof(config))) { >+ ret = -EFAULT; >+ } >+ break; >+ case FBIO_XBOX_GET_TV_ENCODING: >+ encoding = par->tv_encoding; >+ if (copy_to_user((xbox_tv_encoding*)arg, &encoding, sizeof(encoding))) { >+ ret = -EFAULT; >+ } >+ break; >+ case FBIO_XBOX_SET_TV_ENCODING: >+ if(!copy_from_user(&encoding, (xbox_tv_encoding*)arg, sizeof(encoding))) { >+ par->tv_encoding = encoding; >+ riva_load_video_mode (info); >+ if (info->var.accel_flags & FB_ACCELF_TEXT) { >+ riva_setup_accel(par); >+ } >+ } >+ else { >+ ret = -EFAULT; >+ } >+ break; >+ default: >+ ret = -EINVAL; >+ } >+ return ret; >+} >+ >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * initialization helper functions >+ * >+ * ------------------------------------------------------------------------- */ >+ >+/* kernel interface */ >+static struct fb_ops riva_fb_ops = { >+ .owner = THIS_MODULE, >+ .fb_open = xboxfb_open, >+ .fb_release = xboxfb_release, >+ .fb_check_var = xboxfb_check_var, >+ .fb_set_par = xboxfb_set_par, >+ .fb_setcolreg = xboxfb_setcolreg, >+ .fb_pan_display = xboxfb_pan_display, >+ .fb_blank = xboxfb_blank, >+ .fb_fillrect = xboxfb_fillrect, >+ .fb_copyarea = xboxfb_copyarea, >+ .fb_imageblit = xboxfb_imageblit, >+ .fb_cursor = xboxfb_cursor, >+ .fb_sync = xboxfb_sync, >+ .fb_ioctl = xboxfb_ioctl, >+}; >+ >+static int __devinit riva_set_fbinfo(struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ unsigned int cmap_len; >+ >+ info->flags = FBINFO_FLAG_DEFAULT; >+ info->var = xboxfb_default_var; >+ info->fix = xboxfb_fix; >+ info->fbops = &riva_fb_ops; >+ info->pseudo_palette = pseudo_palette; >+ >+#ifndef MODULE >+ if (mode_option) >+ { >+ if (!strncmp(mode_option, "480p", 4)) { >+ info->var = xboxfb_mode_480p; >+ } >+ else if (!strncmp(mode_option, "720p", 4)) { >+ info->var = xboxfb_mode_720p; >+ } >+ else { >+ fb_find_mode(&info->var, info, mode_option, >+ NULL, 0, NULL, 8); >+ } >+ } >+#endif >+ if (par->use_default_var) >+ /* We will use the modified default var */ >+ info->var = xboxfb_default_var; >+ >+ cmap_len = riva_get_cmap_len(&info->var); >+ fb_alloc_cmap(&info->cmap, cmap_len, 0); >+ >+ info->pixmap.size = 64 * 1024; >+ info->pixmap.buf_align = 4; >+ info->pixmap.scan_align = 4; >+ info->pixmap.flags = FB_PIXMAP_SYSTEM; >+ return 0; >+} >+ >+#ifdef CONFIG_PPC_OF >+static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ struct device_node *dp; >+ unsigned char *pedid = NULL; >+ >+ dp = pci_device_to_OF_node(pd); >+ pedid = (unsigned char *)get_property(dp, "EDID,B", 0); >+ >+ if (pedid) { >+ par->EDID = pedid; >+ return 1; >+ } else >+ return 0; >+} >+#endif /* CONFIG_PPC_OF */ >+ >+static int riva_dfp_parse_EDID(struct riva_par *par) >+{ >+ unsigned char *block = par->EDID; >+ >+ if (!block) >+ return 0; >+ >+ /* jump to detailed timing block section */ >+ block += 54; >+ >+ par->clock = (block[0] + (block[1] << 8)); >+ par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4)); >+ par->hblank = (block[3] + ((block[4] & 0x0f) << 8)); >+ par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4)); >+ par->vblank = (block[6] + ((block[7] & 0x0f) << 8)); >+ par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2)); >+ par->hSync_width = (block[9] + ((block[11] & 0x30) << 4)); >+ par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2)); >+ par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4)); >+ par->interlaced = ((block[17] & 0x80) >> 7); >+ par->synct = ((block[17] & 0x18) >> 3); >+ par->misc = ((block[17] & 0x06) >> 1); >+ par->hAct_high = par->vAct_high = 0; >+ if (par->synct == 3) { >+ if (par->misc & 2) >+ par->hAct_high = 1; >+ if (par->misc & 1) >+ par->vAct_high = 1; >+ } >+ >+ printk(KERN_INFO PFX >+ "detected DFP panel size from EDID: %dx%d\n", >+ par->panel_xres, par->panel_yres); >+ par->got_dfpinfo = 1; >+ return 1; >+} >+ >+static void riva_update_default_var(struct fb_info *info) >+{ >+ struct fb_var_screeninfo *var = &xboxfb_default_var; >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ var->xres = par->panel_xres; >+ var->yres = par->panel_yres; >+ var->xres_virtual = par->panel_xres; >+ var->yres_virtual = par->panel_yres; >+ var->xoffset = var->yoffset = 0; >+ var->bits_per_pixel = 8; >+ var->pixclock = 100000000 / par->clock; >+ var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width); >+ var->right_margin = par->hOver_plus; >+ var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width); >+ var->lower_margin = par->vOver_plus; >+ var->hsync_len = par->hSync_width; >+ var->vsync_len = par->vSync_width; >+ var->sync = 0; >+ >+ if (par->synct == 3) { >+ if (par->hAct_high) >+ var->sync |= FB_SYNC_HOR_HIGH_ACT; >+ if (par->vAct_high) >+ var->sync |= FB_SYNC_VERT_HIGH_ACT; >+ } >+ >+ var->vmode = 0; >+ if (par->interlaced) >+ var->vmode |= FB_VMODE_INTERLACED; >+ >+ var->accel_flags |= FB_ACCELF_TEXT; >+ >+ par->use_default_var = 1; >+} >+ >+ >+static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev) >+{ >+#ifdef CONFIG_PPC_OF >+ if (!riva_get_EDID_OF(info, pdev)) >+ printk("xboxfb: could not retrieve EDID from OF\n"); >+#else >+ /* XXX use other methods later */ >+#endif >+} >+ >+ >+static void riva_get_dfpinfo(struct fb_info *info) >+{ >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ if (riva_dfp_parse_EDID(par)) >+ riva_update_default_var(info); >+ >+ /* if user specified flatpanel, we respect that */ >+ if (par->got_dfpinfo == 1) >+ par->FlatPanel = 1; >+} >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * PCI bus >+ * >+ * ------------------------------------------------------------------------- */ >+ >+static int __devinit xboxfb_probe(struct pci_dev *pd, >+ const struct pci_device_id *ent) >+{ >+ struct riva_chip_info *rci = &riva_chip_info[ent->driver_data]; >+ struct riva_par *default_par; >+ struct fb_info *info; >+ unsigned long fb_start; >+ unsigned long fb_size; >+ >+ assert(pd != NULL); >+ assert(rci != NULL); >+ >+ info = kmalloc(sizeof(struct fb_info), GFP_KERNEL); >+ if (!info) >+ goto err_out; >+ >+ default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL); >+ if (!default_par) >+ goto err_out_kfree; >+ >+ memset(info, 0, sizeof(struct fb_info)); >+ memset(default_par, 0, sizeof(struct riva_par)); >+ >+ info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL); >+ if (info->pixmap.addr == NULL) >+ goto err_out_kfree1; >+ memset(info->pixmap.addr, 0, 64 * 1024); >+ >+ strcat(xboxfb_fix.id, rci->name); >+ default_par->riva.Architecture = rci->arch_rev; >+ >+ default_par->Chipset = (pd->vendor << 16) | pd->device; >+ printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset); >+ >+ default_par->FlatPanel = flatpanel; >+ if (flatpanel == 1) >+ printk(KERN_INFO PFX "flatpanel support enabled\n"); >+ default_par->forceCRTC = forceCRTC; >+ >+ xboxfb_fix.mmio_len = pci_resource_len(pd, 0); >+ >+ { >+ /* enable IO and mem if not already done */ >+ unsigned short cmd; >+ >+ pci_read_config_word(pd, PCI_COMMAND, &cmd); >+ cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); >+ pci_write_config_word(pd, PCI_COMMAND, cmd); >+ } >+ >+ xboxfb_fix.mmio_start = pci_resource_start(pd, 0); >+ xboxfb_fix.smem_start = pci_resource_start(pd, 1); >+ >+ if (xbox_memory_size() == 64*1024*1024) printk(KERN_INFO PFX "Detected 64MB of system RAM\n"); >+ else printk(KERN_INFO PFX "Detected 128MB of system RAM\n"); >+ >+ fb_size = available_framebuffer_memory(); >+ fb_start = xbox_memory_size() - fb_size; >+ printk(KERN_INFO PFX "Using %dM framebuffer memory\n", (int)(fb_size/(1024*1024))); >+ default_par->riva_fb_start = fb_start; >+ xboxfb_fix.smem_start += fb_start; >+ xboxfb_fix.smem_len = fb_size; >+ tv_init(); >+ if (tv_encoding == TV_ENC_INVALID) { >+ tv_encoding = get_tv_encoding(); >+ printk(KERN_INFO PFX "Setting TV mode from EEPROM (%s)\n", tvEncodingNames[tv_encoding]); >+ } >+ default_par->tv_encoding = tv_encoding; >+ default_par->video_encoder = tv_get_video_encoder(); >+ switch(default_par->video_encoder) { >+ case ENCODER_CONEXANT: >+ printk(KERN_INFO PFX "detected conexant encoder\n"); >+ break; >+ case ENCODER_FOCUS: >+ printk(KERN_INFO PFX "detected focus encoder\n"); >+ break; >+ case ENCODER_XLB: >+ printk(KERN_INFO PFX "detected Xcalibur encoder\n"); >+ break; >+ default: >+ printk(KERN_INFO PFX "detected unknown encoder\n"); >+ } >+ >+ >+ if (av_type == AV_INVALID) { >+ av_type = detect_av_type(); >+ printk(KERN_INFO PFX "Setting cable type from AVIP ID: %s\n", avTypeNames[av_type]); >+ } >+ default_par->av_type = av_type; >+ if ((hoc < 0) || (hoc > 20)) { >+ hoc = 10; >+ } >+ default_par->hoc = hoc / 100.0; >+ if ((voc < 0) || (voc > 20)) { >+ voc = 10; >+ } >+ default_par->voc = voc / 100.0; >+ >+ if (!request_mem_region(xboxfb_fix.mmio_start, >+ xboxfb_fix.mmio_len, "xboxfb")) { >+ printk(KERN_ERR PFX "cannot reserve MMIO region\n"); >+ goto err_out_kfree2; >+ } >+ >+ default_par->ctrl_base = ioremap(xboxfb_fix.mmio_start, >+ xboxfb_fix.mmio_len); >+ if (!default_par->ctrl_base) { >+ printk(KERN_ERR PFX "cannot ioremap MMIO base\n"); >+ goto err_out_free_base0; >+ } >+ >+ info->par = default_par; >+ >+ riva_get_EDID(info, pd); >+ >+ riva_get_dfpinfo(info); >+ >+ switch (default_par->riva.Architecture) { >+ case NV_ARCH_03: >+ /* Riva128's PRAMIN is in the "framebuffer" space >+ * Since these cards were never made with more than 8 megabytes >+ * we can safely allocate this separately. >+ */ >+ if (!request_mem_region(xboxfb_fix.smem_start + 0x00C00000, >+ 0x00008000, "xboxfb")) { >+ printk(KERN_ERR PFX "cannot reserve PRAMIN region\n"); >+ goto err_out_iounmap_ctrl; >+ } >+ default_par->riva.PRAMIN = ioremap(xboxfb_fix.smem_start + 0x00C00000, 0x00008000); >+ if (!default_par->riva.PRAMIN) { >+ printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n"); >+ goto err_out_free_nv3_pramin; >+ } >+ xboxfb_fix.accel = FB_ACCEL_NV3; >+ break; >+ case NV_ARCH_04: >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000); >+ default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000); >+ xboxfb_fix.accel = FB_ACCEL_NV4; >+ break; >+ } >+ >+ riva_common_setup(default_par); >+ >+ if (default_par->riva.Architecture == NV_ARCH_03) { >+ default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH; >+ } >+ >+ /* xboxfb_fix.smem_len = riva_get_memlen(default_par) * 1024; */ >+ default_par->dclk_max = riva_get_maxdclk(default_par) * 1000; >+ >+ if (!request_mem_region(xboxfb_fix.smem_start, xboxfb_fix.smem_len, "xboxfb")) { >+ printk(KERN_ERR PFX "cannot reserve FB region\n"); >+ goto err_out_iounmap_nv3_pramin; >+ } >+ >+ info->screen_base = ioremap(xboxfb_fix.smem_start, fb_size); >+ if (!info->screen_base) { >+ printk(KERN_ERR PFX "cannot ioremap FB base\n"); >+ goto err_out_free_base1; >+ } >+ >+#ifdef CONFIG_MTRR >+ if (!nomtrr) { >+ default_par->mtrr.vram = mtrr_add(xboxfb_fix.smem_start, fb_size, >+ MTRR_TYPE_WRCOMB, 1); >+ if (default_par->mtrr.vram < 0) { >+ printk(KERN_ERR PFX "unable to setup MTRR\n"); >+ } else { >+ default_par->mtrr.vram_valid = 1; >+ /* let there be speed */ >+ printk(KERN_INFO PFX "RIVA MTRR set to ON\n"); >+ } >+ } >+#endif /* CONFIG_MTRR */ >+ >+ if (riva_set_fbinfo(info) < 0) { >+ printk(KERN_ERR PFX "error setting initial video mode\n"); >+ goto err_out_iounmap_fb; >+ } >+ >+ if (register_framebuffer(info) < 0) { >+ printk(KERN_ERR PFX >+ "error registering riva framebuffer\n"); >+ goto err_out_iounmap_fb; >+ } >+ >+ pci_set_drvdata(pd, info); >+ >+ printk(KERN_INFO PFX >+ "PCI nVidia NV%x framebuffer ver %s (%s, %ldMB @ 0x%lX)\n", >+ default_par->riva.Architecture, >+ RIVAFB_VERSION, >+ info->fix.id, >+ fb_size / (1024 * 1024), >+ info->fix.smem_start); >+ return 0; >+ >+err_out_iounmap_fb: >+ iounmap(info->screen_base); >+err_out_free_base1: >+ release_mem_region(xboxfb_fix.smem_start, fb_size); >+err_out_iounmap_nv3_pramin: >+ if (default_par->riva.Architecture == NV_ARCH_03) >+ iounmap((caddr_t)default_par->riva.PRAMIN); >+err_out_free_nv3_pramin: >+ if (default_par->riva.Architecture == NV_ARCH_03) >+ release_mem_region(xboxfb_fix.smem_start + 0x00C00000, 0x00008000); >+err_out_iounmap_ctrl: >+ iounmap(default_par->ctrl_base); >+err_out_free_base0: >+ release_mem_region(xboxfb_fix.mmio_start, xboxfb_fix.mmio_len); >+err_out_kfree2: >+ kfree(info->pixmap.addr); >+err_out_kfree1: >+ kfree(default_par); >+err_out_kfree: >+ kfree(info); >+err_out: >+ return -ENODEV; >+} >+ >+static void __exit xboxfb_remove(struct pci_dev *pd) >+{ >+ struct fb_info *info = pci_get_drvdata(pd); >+ struct riva_par *par = (struct riva_par *) info->par; >+ >+ if (!info) >+ return; >+ >+ unregister_framebuffer(info); >+#ifdef CONFIG_MTRR >+ if (par->mtrr.vram_valid) >+ mtrr_del(par->mtrr.vram, info->fix.smem_start, info->fix.smem_len); >+#endif /* CONFIG_MTRR */ >+ >+ iounmap(par->ctrl_base); >+ iounmap(info->screen_base); >+ >+ release_mem_region(info->fix.mmio_start, >+ info->fix.mmio_len); >+ release_mem_region(info->fix.smem_start, info->fix.smem_len); >+ >+ if (par->riva.Architecture == NV_ARCH_03) { >+ iounmap((caddr_t)par->riva.PRAMIN); >+ release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000); >+ } >+ kfree(info->pixmap.addr); >+ kfree(par); >+ kfree(info); >+ pci_set_drvdata(pd, NULL); >+} >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * initialization >+ * >+ * ------------------------------------------------------------------------- */ >+ >+#ifndef MODULE >+int __init xboxfb_setup(char *options) >+{ >+ char *this_opt; >+ >+ if (!options || !*options) >+ return 0; >+ >+ while ((this_opt = strsep(&options, ",")) != NULL) { >+ if (!strncmp(this_opt, "forceCRTC", 9)) { >+ char *p; >+ >+ p = this_opt + 9; >+ if (!*p || !*(++p)) continue; >+ forceCRTC = *p - '0'; >+ if (forceCRTC < 0 || forceCRTC > 1) >+ forceCRTC = -1; >+ } else if (!strncmp(this_opt, "flatpanel", 9)) { >+ flatpanel = 1; >+#ifdef CONFIG_MTRR >+ } else if (!strncmp(this_opt, "nomtrr", 6)) { >+ nomtrr = 1; >+#endif >+ } else if (!strncmp(this_opt, "tv=", 3)) { >+ if(!strncmp(this_opt + 3, "PAL", 3)) { >+ tv_encoding = TV_ENC_PALBDGHI; >+ } >+ else if(!strncmp(this_opt + 3, "NTSC", 4)) { >+ tv_encoding = TV_ENC_NTSC; >+ } >+ else if(!strncmp(this_opt + 3, "VGA", 3)) { >+ av_type = AV_VGA_SOG; >+ } >+ } else if (!strncmp(this_opt, "hoc=", 4)) { >+ sscanf(this_opt+4, "%d", &hoc); >+ } else if (!strncmp(this_opt, "voc=", 4)) { >+ sscanf(this_opt+4, "%d", &voc); >+ } else >+ mode_option = this_opt; >+ } >+ return 0; >+} >+#endif /* !MODULE */ >+ >+static struct pci_driver xboxfb_driver = { >+ .name = "xboxfb", >+ .id_table = xboxfb_pci_tbl, >+ .probe = xboxfb_probe, >+ .remove = __exit_p(xboxfb_remove), >+}; >+ >+ >+ >+/* ------------------------------------------------------------------------- * >+ * >+ * modularization >+ * >+ * ------------------------------------------------------------------------- */ >+ >+int __init xboxfb_init(void) >+{ >+ if (pci_register_driver(&xboxfb_driver) > 0) >+ return 0; >+ pci_unregister_driver(&xboxfb_driver); >+ return -ENODEV; >+} >+ >+ >+#ifdef MODULE >+static void __exit xboxfb_exit(void) >+{ >+ pci_unregister_driver(&xboxfb_driver); >+} >+ >+module_init(xboxfb_init); >+module_exit(xboxfb_exit); >+ >+MODULE_PARM(flatpanel, "i"); >+MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)"); >+MODULE_PARM(forceCRTC, "i"); >+MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)"); >+ >+#ifdef CONFIG_MTRR >+MODULE_PARM(nomtrr, "i"); >+MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)"); >+#endif >+ >+MODULE_PARM(tv, "s"); >+MODULE_PARM_DESC(tv, "Specifies the TV encoding (\"PAL\", \"NTSC\" or \"VGA\")."); >+MODULE_PARM(hoc, "i"); >+MODULE_PARM_DESC(hoc, "Horizontal overscan compensation ratio, in % (0-20)"); >+MODULE_PARM(voc, "i"); >+MODULE_PARM_DESC(voc, "Vertical overscan compensation ratio, in % (0-20)"); >+ >+#endif /* MODULE */ >+ >+MODULE_AUTHOR("Oliver Schwartz"); >+MODULE_DESCRIPTION("Framebuffer driver for Xbox"); >+MODULE_LICENSE("GPL"); >diff -urN linux-2.6.6.orig/drivers/video/xbox/focus.c linux-2.6.6/drivers/video/xbox/focus.c >--- linux-2.6.6.orig/drivers/video/xbox/focus.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/focus.c 2004-05-10 12:30:23.195944848 +0100 >@@ -0,0 +1,328 @@ >+/* >+ * linux/drivers/video/riva/focus.c - Xbox driver for Focus encoder >+ * >+ * Maintainer: David Pye (dmp) <dmp@davidmpye.dyndns.org> >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * VGA SoG/internal sync not yet implemented >+*/ >+#include "focus.h" >+#include "encoder.h" >+ >+ >+static const unsigned char focus_defaults[0xc4] = { >+ /*0x00*/ 0x00,0x00,0x00,0x00,0x80,0x02,0xaa,0x0a, >+ /*0x08*/ 0x00,0x10,0x00,0x00,0x03,0x21,0x15,0x04, >+ /*0x10*/ 0x00,0xe9,0x07,0x00,0x80,0xf5,0x20,0x00, >+ /*0x18*/ 0xef,0x21,0x1f,0x00,0x03,0x03,0x00,0x00, >+ /*0x20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, >+ /*0x28*/ 0x0c,0x01,0x00,0x00,0x00,0x00,0x08,0x11, >+ /*0x30*/ 0x00,0x0f,0x05,0xfe,0x0b,0x80,0x00,0x00, >+ /*0x38*/ 0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00, >+ /*0x40*/ 0x2a,0x09,0x8a,0xcb,0x00,0x00,0x8d,0x00, >+ /*0x48*/ 0x7c,0x3c,0x9a,0x2f,0x21,0x01,0x3f,0x00, >+ /*0x50*/ 0x3e,0x03,0x17,0x21,0x1b,0x1b,0x24,0x9c, >+ /*0x58*/ 0x01,0x3e,0x0f,0x0f,0x60,0x05,0xc8,0x00, >+ /*0x60*/ 0x9d,0x04,0x9d,0x01,0x02,0x00,0x0a,0x05, >+ /*0x68*/ 0x00,0x1a,0xff,0x03,0x1e,0x0f,0x78,0x00, >+ /*0x70*/ 0x00,0xb1,0x04,0x15,0x49,0x10,0x00,0xa3, >+ /*0x78*/ 0xc8,0x15,0x05,0x15,0x3e,0x03,0x00,0x20, >+ /*0x80*/ 0x57,0x2f,0x07,0x00,0x00,0x08,0x00,0x00, >+ /*0x88*/ 0x08,0x16,0x16,0x9c,0x03,0x00,0x00,0x00, >+ /*0x90*/ 0x00,0x00,0xc4,0x48,0x00,0x00,0x00,0x00, >+ /*0x98*/ 0x00,0x00,0x00,0x80,0x00,0x00,0xe4,0x00, >+ /*0xa0*/ 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00, >+ /*0xa8*/ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, >+ /*0xb0*/ 0x00,0x00,0xd7,0x05,0x00,0x00,0xf0,0x00, >+ /*0xb8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, >+ /*0xc0*/ 0x00,0x00,0xee,0x00 >+}; >+ >+int focus_calc_hdtv_mode( >+ xbox_hdtv_mode hdtv_mode, >+ unsigned char pll_int, >+ unsigned char * regs >+ ){ >+ unsigned char b; >+ int m=0; >+ int tv_vtotal, tv_htotal, tv_vactive, tv_hactive, vga_htotal, vga_vtotal; >+ int pll_n, pll_m, pll_p, ncon, ncod; >+ >+ memcpy(regs,focus_defaults,sizeof(focus_defaults)); >+ /* Uncomment for HDTV 480p colour bars */ >+ //regs[0x0d]|=0x02; >+ >+ /* Turn on bridge bypass */ >+ regs[0x0a] |= 0x10; >+ /* Turn on the HDTV clock, and turn off the SDTV one */ >+ regs[0xa1] = 0x04; >+ >+ /* HDTV Hor start */ >+ regs[0xb8] = 0xbe; >+ >+ /*Set up video mode to HDTV, progressive, >+ * and disable YUV matrix bypass */ >+ regs[0x92] = 0x1a; >+ regs[0x93] &= ~0x40; >+ >+ switch (hdtv_mode) { >+ case HDTV_480p: >+ /* PLL settings */ >+ regs[0x10] = 0x00; >+ regs[0x11] = 0x00; >+ regs[0x12] = 0x00; >+ regs[0x13] = 0x00; >+ regs[0x14] = 0x00; >+ regs[0x15] = 0x00; >+ regs[0x16] = 0x00; >+ regs[0x17] = 0x00; >+ regs[0x18] = 0xD7; >+ regs[0x19] = 0x03; >+ regs[0x1A] = 0x7C; >+ regs[0x1B] = 0x00; >+ regs[0x1C] = 0x07; >+ regs[0x1D] = 0x07; >+ /* Porches/HSync width/Luma offset */ >+ regs[0x94] = 0x3F; >+ regs[0x95] = 0x2D; >+ regs[0x96] = 0x3B; >+ regs[0x97] = 0x00; >+ regs[0x98] = 0x1B; >+ regs[0x99] = 0x03; >+ /* Colour scaling */ >+ regs[0xA2] = 0x4D; >+ regs[0xA4] = 0x96; >+ regs[0xA6] = 0x1D; >+ regs[0xA8] = 0x58; >+ regs[0xAA] = 0x8A; >+ regs[0xAC] = 0x4A; >+ break; >+ case HDTV_720p: >+ /* PLL settings */ >+ regs[0x10] = 0x00; >+ regs[0x11] = 0x00; >+ regs[0x12] = 0x00; >+ regs[0x13] = 0x00; >+ regs[0x14] = 0x00; >+ regs[0x15] = 0x00; >+ regs[0x16] = 0x00; >+ regs[0x17] = 0x00; >+ regs[0x18] = 0x3B; >+ regs[0x19] = 0x04; >+ regs[0x1A] = 0xC7; >+ regs[0x1B] = 0x00; >+ regs[0x1C] = 0x01; >+ regs[0x1D] = 0x01; >+ /* Porches/HSync width/Luma offset */ >+ regs[0x94] = 0x28; >+ regs[0x95] = 0x46; >+ regs[0x96] = 0xDC; >+ regs[0x97] = 0x00; >+ regs[0x98] = 0x2C; >+ regs[0x99] = 0x06; >+ /* Colour scaling */ >+ regs[0xA2] = 0x36; >+ regs[0xA4] = 0xB7; >+ regs[0xA6] = 0x13; >+ regs[0xA8] = 0x58; >+ regs[0xAA] = 0x8A; >+ regs[0xAC] = 0x4A; >+ /* HSync timing invert - needed to centre picture */ >+ regs[0x93] |= 0x01; >+ >+ break; >+ case HDTV_1080i: >+ /* PLL settings */ >+ regs[0x10] = 0x00; >+ regs[0x11] = 0x00; >+ regs[0x12] = 0x00; >+ regs[0x13] = 0x00; >+ regs[0x14] = 0x00; >+ regs[0x15] = 0x00; >+ regs[0x16] = 0x00; >+ regs[0x17] = 0x00; >+ regs[0x18] = 0x3B; >+ regs[0x19] = 0x04; >+ regs[0x1A] = 0xC7; >+ regs[0x1B] = 0x00; >+ regs[0x1C] = 0x01; >+ regs[0x1D] = 0x01; >+ /* Porches/HSync width/Luma offset */ >+ regs[0x94] = 0x2C; >+ regs[0x95] = 0x2C; >+ regs[0x96] = 0x58; >+ regs[0x97] = 0x00; >+ regs[0x98] = 0x6C; >+ regs[0x99] = 0x08; >+ /* Colour scaling */ >+ regs[0xA2] = 0x36; >+ regs[0xA4] = 0xB7; >+ regs[0xA6] = 0x13; >+ regs[0xA8] = 0x58; >+ regs[0xAA] = 0x8A; >+ regs[0xAC] = 0x4A; >+ /* Set mode to interlaced */ >+ regs[0x92] |= 0x80; >+ break; >+ } >+ return 1; >+} >+ >+int focus_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out) >+{ >+ unsigned char b; >+ char* regs = riva_out->encoder_mode; >+ int m = 0; >+ int tv_htotal, tv_vtotal, tv_vactive, tv_hactive; >+ int vga_htotal, vga_vtotal; >+ long ncon, ncod; >+ int pll_m, pll_n, pll_p, vsc, hsc; >+ >+ memcpy(regs,focus_defaults,sizeof(focus_defaults)); >+ >+ /* Uncomment for SDTV colour bars */ >+ //regs[0x45]=0x02; >+ >+ switch(mode->tv_encoding) { >+ case TV_ENC_NTSC: >+ tv_vtotal=525; >+ tv_vactive=480; >+ tv_hactive = 710; >+ tv_htotal = 858; >+ regs[0x0d] &= ~0x01; >+ regs[0x40] = 0x21; >+ regs[0x41] = 0xF0; >+ regs[0x42] = 0x7C; >+ regs[0x43] = 0x1F; >+ regs[0x49] = 0x44; >+ regs[0x4a] = 0x76; >+ regs[0x4b] = 0x3B; >+ regs[0x4c] = 0x00; >+ regs[0x60] = 0x89; >+ regs[0x62] = 0x89; >+ regs[0x69] = 0x16; >+ regs[0x6C] = 0x20; >+ regs[0x74] = 0x04; >+ regs[0x75] = 0x10; >+ regs[0x80] = 0x67; >+ regs[0x81] = 0x21; >+ regs[0x82] = 0x0C; >+ regs[0x83] = 0x18; >+ regs[0x86] = 0x18; >+ regs[0x89] = 0x13; >+ regs[0x8A] = 0x13; >+ break; >+ case TV_ENC_PALBDGHI: >+ tv_vtotal = 625; >+ tv_vactive = 576; >+ tv_hactive = 702; >+ tv_htotal = 864; >+ break; >+ default: >+ /* Default to PAL */ >+ tv_vtotal = 625; >+ tv_vactive = 576; >+ tv_hactive = 702; >+ tv_htotal = 864; >+ break; >+ } >+ >+ /* Video control - set to RGB input*/ >+ b = (regs[0x92] &= ~0x04); >+ regs[0x92] = (b|= 0x01); >+ regs[0x93] &= ~0x40; >+ /* Colour scaling */ >+ regs[0xA2] = 0x4D; >+ regs[0xA4] = 0x96; >+ regs[0xA6] = 0x1D; >+ regs[0xA8] = 0xA0; >+ regs[0xAA] = 0xDB; >+ regs[0xAC] = 0x7E; >+ >+ tv_vactive = tv_vactive * (1.0f-mode->voc); >+ vga_vtotal = mode->yres * ((float)tv_vtotal/tv_vactive); >+ vga_htotal = mode->xres * 1.25f; >+ tv_hactive = tv_hactive * (1.0f-mode->hoc); >+ /*These should be calculated or at least deduced. >+ *However they are good enough for 640x480 -> 800x600 now*/ >+ pll_n = 32; >+ pll_m = 512; >+ pll_p = 4; >+ >+ ncon = vga_htotal * vga_vtotal; >+ ncod = tv_htotal * tv_vtotal * pll_p; >+ >+ regs[0x04] = (mode->xres+64)&0xFF; >+ regs[0x05] = ((mode->xres+64)>>8)&0xFF; >+ >+ if (tv_vtotal>vga_vtotal) { >+ /* Upscaling */ >+ vsc = ((((float)tv_vtotal/(float)vga_vtotal)-1)*65536); >+ /* For upscaling, adjust FIFO_LAT (FIFO latency) */ >+ regs[0x38] = 0x82; >+ } >+ else { >+ /* Downscaling */ >+ vsc = ((((float)tv_vtotal/(float)vga_vtotal))*65536); >+ } >+ regs[0x06] = (vsc)&0xFF; >+ regs[0x07] = (vsc>>8)&0xFF; >+ >+ hsc = 128*((float)tv_hactive/(float)mode->xres-1); >+ if (tv_hactive > mode->xres) { >+ /* Upscaling */ >+ regs[0x08] = 0; >+ regs[0x09] = hsc&0xFF; >+ } >+ else { /* Downscaling */ >+ hsc = 256 + hsc; >+ regs[0x08] = hsc&0xFF; >+ regs[0x09] = 0; >+ } >+ >+ >+ regs[0x10] = (ncon)&0xFF; >+ regs[0x11] = (ncon>>8)&0xFF ; >+ regs[0x12] = (ncon>>16)&0xFF ; >+ regs[0x13] = (ncon>>24)&0xFF ; >+ regs[0x14] = (ncod)&0xFF ; >+ regs[0x15] = (ncod>>8)&0xFF ; >+ regs[0x16] = (ncod>>16)&0xFF ; >+ regs[0x17] = (ncod>>24)&0xFF ; >+ regs[0x18] = (pll_m-17)&0xFF; >+ regs[0x19] = ((pll_m-17)>>8)&0xFF; >+ regs[0x1A] = (pll_n-1)&0xFF ; >+ regs[0x1B] = ((pll_n-1)>>8)&0xFF ; >+ regs[0x1C] = (pll_p-1)&0xFF; >+ regs[0x1D] = (pll_p-1)&0xFF; >+ >+ /* Guesswork */ >+ riva_out->ext.vsyncstart = vga_vtotal * 0.95; >+ riva_out->ext.hsyncstart = vga_htotal * 0.95; >+ >+ riva_out->ext.width = mode->xres; >+ riva_out->ext.height = mode->yres; >+ riva_out->ext.htotal = vga_htotal - 1; >+ riva_out->ext.vend = mode->yres - 1; >+ riva_out->ext.vtotal = vga_vtotal- 1; >+ riva_out->ext.vcrtc = mode->yres - 1; >+ riva_out->ext.vsyncend = riva_out->ext.vsyncstart + 3; >+ riva_out->ext.vvalidstart = 0; >+ riva_out->ext.vvalidend = mode->yres - 1; >+ riva_out->ext.hend = mode->xres + 7 ; >+ riva_out->ext.hcrtc = mode->xres - 1; >+ riva_out->ext.hsyncend = riva_out->ext.hsyncstart + 32; >+ riva_out->ext.hvalidstart = 0; >+ riva_out->ext.hvalidend = mode->xres - 1; >+ riva_out->ext.crtchdispend = mode->xres; >+ riva_out->ext.crtcvstart = mode->yres + 32; >+ //increased from 32 >+ riva_out->ext.crtcvtotal = mode->yres + 64; >+ >+ return 1; >+} >diff -urN linux-2.6.6.orig/drivers/video/xbox/focus.h linux-2.6.6/drivers/video/xbox/focus.h >--- linux-2.6.6.orig/drivers/video/xbox/focus.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/focus.h 2004-05-10 12:30:23.197944544 +0100 >@@ -0,0 +1,24 @@ >+/* >+ * linux/drivers/video/riva/focus.c - Xbox driver for Focus encoder >+ * >+ * Maintainer: David Pye (dmp) <dmp@davidmpye.dyndns.org> >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+ >+#ifndef focus_h_ >+#define focus_h_ >+ >+#include "encoder.h" >+#include "xboxfb.h" >+ >+int focus_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out ); >+int focus_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out); >+#endif >diff -urN linux-2.6.6.orig/drivers/video/xbox/nv_driver.c linux-2.6.6/drivers/video/xbox/nv_driver.c >--- linux-2.6.6.orig/drivers/video/xbox/nv_driver.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/nv_driver.c 2004-05-10 12:30:23.201943936 +0100 >@@ -0,0 +1,364 @@ >+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */ >+/* >+ * Copyright 1996-1997 David J. McKay >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining a >+ * copy of this software and associated documentation files (the "Software"), >+ * to deal in the Software without restriction, including without limitation >+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, >+ * and/or sell copies of the Software, and to permit persons to whom the >+ * Software is furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be included in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, >+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF >+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE >+ * SOFTWARE. >+ */ >+ >+/* >+ * GPL licensing note -- nVidia is allowing a liberal interpretation of >+ * the documentation restriction above, to merely say that this nVidia's >+ * copyright and disclaimer should be included with all code derived >+ * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 >+ */ >+ >+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen >+ <jpaana@s2.org> */ >+ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0 >+5 20:47:06 mvojkovi Exp $ */ >+ >+#include <linux/delay.h> >+#include <linux/pci.h> >+#include <linux/pci_ids.h> >+#include "nv_type.h" >+#include "xboxfb.h" >+#include "nvreg.h" >+ >+ >+#ifndef CONFIG_PCI /* sanity check */ >+#error This driver requires PCI support. >+#endif >+ >+#define PFX "rivafb: " >+ >+static inline unsigned char MISCin(struct riva_par *par) >+{ >+ return (VGA_RD08(par->riva.PVIO, 0x3cc)); >+} >+ >+static Bool >+riva_is_connected(struct riva_par *par, Bool second) >+{ >+ volatile U032 *PRAMDAC = par->riva.PRAMDAC0; >+ U032 reg52C, reg608; >+ Bool present; >+ >+ if(second) PRAMDAC += 0x800; >+ >+ reg52C = PRAMDAC[0x052C/4]; >+ reg608 = PRAMDAC[0x0608/4]; >+ >+ PRAMDAC[0x0608/4] = reg608 & ~0x00010000; >+ >+ PRAMDAC[0x052C/4] = reg52C & 0x0000FEEE; >+ mdelay(1); >+ PRAMDAC[0x052C/4] |= 1; >+ >+ par->riva.PRAMDAC0[0x0610/4] = 0x94050140; >+ par->riva.PRAMDAC0[0x0608/4] |= 0x00001000; >+ >+ mdelay(1); >+ >+ present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE; >+ >+ par->riva.PRAMDAC0[0x0608/4] &= 0x0000EFFF; >+ >+ PRAMDAC[0x052C/4] = reg52C; >+ PRAMDAC[0x0608/4] = reg608; >+ >+ return present; >+} >+ >+static void >+riva_override_CRTC(struct riva_par *par) >+{ >+ printk(KERN_INFO PFX >+ "Detected CRTC controller %i being used\n", >+ par->SecondCRTC ? 1 : 0); >+ >+ if(par->forceCRTC != -1) { >+ printk(KERN_INFO PFX >+ "Forcing usage of CRTC %i\n", par->forceCRTC); >+ par->SecondCRTC = par->forceCRTC; >+ } >+} >+ >+static void >+riva_is_second(struct riva_par *par) >+{ >+ if (par->FlatPanel == 1) { >+ switch(par->Chipset) { >+ case NV_CHIP_GEFORCE4_440_GO: >+ case NV_CHIP_GEFORCE4_440_GO_M64: >+ case NV_CHIP_GEFORCE4_420_GO: >+ case NV_CHIP_GEFORCE4_420_GO_M32: >+ case NV_CHIP_QUADRO4_500_GOGL: >+ par->SecondCRTC = TRUE; >+ break; >+ default: >+ par->SecondCRTC = FALSE; >+ break; >+ } >+ } else { >+ if(riva_is_connected(par, 0)) { >+ if(par->riva.PRAMDAC0[0x0000052C/4] & 0x100) >+ par->SecondCRTC = TRUE; >+ else >+ par->SecondCRTC = FALSE; >+ } else >+ if (riva_is_connected(par, 1)) { >+ if(par->riva.PRAMDAC0[0x0000252C/4] & 0x100) >+ par->SecondCRTC = TRUE; >+ else >+ par->SecondCRTC = FALSE; >+ } else /* default */ >+ par->SecondCRTC = FALSE; >+ } >+ riva_override_CRTC(par); >+} >+ >+unsigned long riva_get_memlen(struct riva_par *par) >+{ >+ RIVA_HW_INST *chip = &par->riva; >+ unsigned long memlen = 0; >+ unsigned int chipset = par->Chipset; >+ struct pci_dev* dev; >+ int amt; >+ >+ switch (chip->Architecture) { >+ case NV_ARCH_03: >+ if (chip->PFB[0x00000000/4] & 0x00000020) { >+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20) >+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) { >+ /* >+ * SDRAM 128 ZX. >+ */ >+ switch (chip->PFB[0x00000000/4] & 0x03) { >+ case 2: >+ memlen = 1024 * 4; >+ break; >+ case 1: >+ memlen = 1024 * 2; >+ break; >+ default: >+ memlen = 1024 * 8; >+ break; >+ } >+ } else { >+ memlen = 1024 * 8; >+ } >+ } else { >+ /* >+ * SGRAM 128. >+ */ >+ switch (chip->PFB[0x00000000/4] & 0x00000003) { >+ case 0: >+ memlen = 1024 * 8; >+ break; >+ case 2: >+ memlen = 1024 * 4; >+ break; >+ default: >+ memlen = 1024 * 2; >+ break; >+ } >+ } >+ break; >+ case NV_ARCH_04: >+ if (chip->PFB[0x00000000/4] & 0x00000100) { >+ memlen = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * >+ 1024 * 2 + 1024 * 2; >+ } else { >+ switch (chip->PFB[0x00000000/4] & 0x00000003) { >+ case 0: >+ memlen = 1024 * 32; >+ break; >+ case 1: >+ memlen = 1024 * 4; >+ break; >+ case 2: >+ memlen = 1024 * 8; >+ break; >+ case 3: >+ default: >+ memlen = 1024 * 16; >+ break; >+ } >+ } >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ if(chipset == NV_CHIP_IGEFORCE2) { >+ >+ dev = pci_find_slot(0, 1); >+ pci_read_config_dword(dev, 0x7C, &amt); >+ memlen = (((amt >> 6) & 31) + 1) * 1024; >+ } else if (chipset == NV_CHIP_0x01F0) { >+ dev = pci_find_slot(0, 1); >+ pci_read_config_dword(dev, 0x84, &amt); >+ memlen = (((amt >> 4) & 127) + 1) * 1024; >+ } else { >+ switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF){ >+ case 0x02: >+ memlen = 1024 * 2; >+ break; >+ case 0x04: >+ memlen = 1024 * 4; >+ break; >+ case 0x08: >+ memlen = 1024 * 8; >+ break; >+ case 0x10: >+ memlen = 1024 * 16; >+ break; >+ case 0x20: >+ memlen = 1024 * 32; >+ break; >+ case 0x40: >+ memlen = 1024 * 64; >+ break; >+ case 0x80: >+ memlen = 1024 * 128; >+ break; >+ default: >+ memlen = 1024 * 16; >+ break; >+ } >+ } >+ break; >+ } >+ return memlen; >+} >+ >+unsigned long riva_get_maxdclk(struct riva_par *par) >+{ >+ RIVA_HW_INST *chip = &par->riva; >+ unsigned long dclk = 0; >+ >+ switch (chip->Architecture) { >+ case NV_ARCH_03: >+ if (chip->PFB[0x00000000/4] & 0x00000020) { >+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20) >+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) { >+ /* >+ * SDRAM 128 ZX. >+ */ >+ dclk = 800000; >+ } else { >+ dclk = 1000000; >+ } >+ } else { >+ /* >+ * SGRAM 128. >+ */ >+ dclk = 1000000; >+ } >+ break; >+ case NV_ARCH_04: >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) { >+ case 3: >+ dclk = 800000; >+ break; >+ default: >+ dclk = 1000000; >+ break; >+ } >+ break; >+ } >+ return dclk; >+} >+ >+void >+riva_common_setup(struct riva_par *par) >+{ >+ par->riva.EnableIRQ = 0; >+ par->riva.PRAMDAC0 = (unsigned *)(par->ctrl_base + 0x00680000); >+ par->riva.PFB = (unsigned *)(par->ctrl_base + 0x00100000); >+ par->riva.PFIFO = (unsigned *)(par->ctrl_base + 0x00002000); >+ par->riva.PGRAPH = (unsigned *)(par->ctrl_base + 0x00400000); >+ par->riva.PEXTDEV = (unsigned *)(par->ctrl_base + 0x00101000); >+ par->riva.PTIMER = (unsigned *)(par->ctrl_base + 0x00009000); >+ par->riva.PMC = (unsigned *)(par->ctrl_base + 0x00000000); >+ par->riva.FIFO = (unsigned *)(par->ctrl_base + 0x00800000); >+ par->riva.PCIO0 = (U008 *)(par->ctrl_base + 0x00601000); >+ par->riva.PDIO0 = (U008 *)(par->ctrl_base + 0x00681000); >+ par->riva.PVIO = (U008 *)(par->ctrl_base + 0x000C0000); >+ >+ par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0; >+ >+ if (par->FlatPanel == -1) { >+ switch (par->Chipset) { >+ case NV_CHIP_GEFORCE4_440_GO: >+ case NV_CHIP_GEFORCE4_440_GO_M64: >+ case NV_CHIP_GEFORCE4_420_GO: >+ case NV_CHIP_GEFORCE4_420_GO_M32: >+ case NV_CHIP_QUADRO4_500_GOGL: >+ case NV_CHIP_GEFORCE2_GO: >+ printk(KERN_INFO PFX >+ "On a laptop. Assuming Digital Flat Panel\n"); >+ par->FlatPanel = 1; >+ break; >+ default: >+ break; >+ } >+ } >+ >+ switch (par->Chipset & 0x0ff0) { >+ case 0x0110: >+ if (par->Chipset == NV_CHIP_GEFORCE2_GO) >+ par->SecondCRTC = TRUE; >+#if defined(__powerpc__) >+ if (par->FlatPanel == 1) >+ par->SecondCRTC = TRUE; >+#endif >+ riva_override_CRTC(par); >+ break; >+ case 0x0170: >+ case 0x0180: >+ case 0x01F0: >+ case 0x0250: >+ case 0x0280: >+ riva_is_second(par); >+ break; >+ default: >+ break; >+ } >+ >+ if (par->SecondCRTC) { >+ par->riva.PCIO = par->riva.PCIO0 + 0x2000; >+ par->riva.PCRTC = par->riva.PCRTC0 + 0x800; >+ par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800; >+ par->riva.PDIO = par->riva.PDIO0 + 0x2000; >+ } else { >+ par->riva.PCIO = par->riva.PCIO0; >+ par->riva.PCRTC = par->riva.PCRTC0; >+ par->riva.PRAMDAC = par->riva.PRAMDAC0; >+ par->riva.PDIO = par->riva.PDIO0; >+ } >+ >+ if (par->FlatPanel == -1) { >+ /* Fix me, need x86 DDC code */ >+ par->FlatPanel = 0; >+ } >+ par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE; >+} >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/nv_type.h linux-2.6.6/drivers/video/xbox/nv_type.h >--- linux-2.6.6.orig/drivers/video/xbox/nv_type.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/nv_type.h 2004-05-10 12:30:23.204943480 +0100 >@@ -0,0 +1,58 @@ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.35 2002/08/05 20:47:06 mvojkovi Exp $ */ >+ >+#ifndef __NV_STRUCT_H__ >+#define __NV_STRUCT_H__ >+ >+#define NV_CHIP_RIVA_128 ((PCI_VENDOR_ID_NVIDIA_SGS << 16)| PCI_DEVICE_ID_NVIDIA_RIVA128) >+#define NV_CHIP_TNT ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_TNT) >+#define NV_CHIP_TNT2 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_TNT2) >+#define NV_CHIP_UTNT2 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_UTNT2) >+#define NV_CHIP_VTNT2 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_VTNT2) >+#define NV_CHIP_UVTNT2 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_UVTNT2) >+#define NV_CHIP_ITNT2 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_ITNT2) >+#define NV_CHIP_GEFORCE_256 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_GEFORCE_256) >+#define NV_CHIP_GEFORCE_DDR ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR) >+#define NV_CHIP_QUADRO ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_QUADRO) >+#define NV_CHIP_GEFORCE2_MX ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX) >+#define NV_CHIP_GEFORCE2_MX_100 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX_100) >+#define NV_CHIP_QUADRO2_MXR ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR) >+#define NV_CHIP_GEFORCE2_GO ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO) >+#define NV_CHIP_GEFORCE2_GTS ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS) >+#define NV_CHIP_GEFORCE2_TI ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_TI) >+#define NV_CHIP_GEFORCE2_ULTRA ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA) >+#define NV_CHIP_QUADRO2_PRO ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO) >+#define NV_CHIP_GEFORCE4_MX_460 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460) >+#define NV_CHIP_GEFORCE4_MX_440 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440) >+#define NV_CHIP_GEFORCE4_MX_420 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420) >+#define NV_CHIP_GEFORCE4_440_GO ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO) >+#define NV_CHIP_GEFORCE4_420_GO ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO) >+#define NV_CHIP_GEFORCE4_420_GO_M32 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32) >+#define NV_CHIP_QUADRO4_500XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL) >+#define NV_CHIP_GEFORCE4_440_GO_M64 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64) >+#define NV_CHIP_QUADRO4_200 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_200) >+#define NV_CHIP_QUADRO4_550XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL) >+#define NV_CHIP_QUADRO4_500_GOGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL) >+#define NV_CHIP_0x0180 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0180) >+#define NV_CHIP_0x0181 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0181) >+#define NV_CHIP_0x0182 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0182) >+#define NV_CHIP_0x0188 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0188) >+#define NV_CHIP_0x018A ((PCI_VENDOR_ID_NVIDIA << 16) | 0x018A) >+#define NV_CHIP_0x018B ((PCI_VENDOR_ID_NVIDIA << 16) | 0x018B) >+#define NV_CHIP_IGEFORCE2 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_IGEFORCE2) >+#define NV_CHIP_0x01F0 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x01F0) >+#define NV_CHIP_GEFORCE3 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3) >+#define NV_CHIP_GEFORCE3_TI_200 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3_TI_200) >+#define NV_CHIP_GEFORCE3_TI_500 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3_TI_500) >+#define NV_CHIP_QUADRO_DCC ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO_DCC) >+#define NV_CHIP_GEFORCE4_TI_4600 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600) >+#define NV_CHIP_GEFORCE4_TI_4400 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400) >+#define NV_CHIP_GEFORCE4_TI_4200 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200) >+#define NV_CHIP_QUADRO4_900XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL) >+#define NV_CHIP_QUADRO4_750XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL) >+#define NV_CHIP_QUADRO4_700XGL ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL) >+#define NV_CHIP_0x0280 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0280) >+#define NV_CHIP_0x0281 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0281) >+#define NV_CHIP_0x0288 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0288) >+#define NV_CHIP_0x0289 ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0289) >+ >+#endif /* __NV_STRUCT_H__ */ >diff -urN linux-2.6.6.orig/drivers/video/xbox/nvreg.h linux-2.6.6/drivers/video/xbox/nvreg.h >--- linux-2.6.6.orig/drivers/video/xbox/nvreg.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/nvreg.h 2004-05-10 12:30:23.228939832 +0100 >@@ -0,0 +1,188 @@ >+/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */ >+/* >+ * Copyright 1996-1997 David J. McKay >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining a >+ * copy of this software and associated documentation files (the "Software"), >+ * to deal in the Software without restriction, including without limitation >+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, >+ * and/or sell copies of the Software, and to permit persons to whom the >+ * Software is furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be included in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, >+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF >+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE >+ * SOFTWARE. >+ */ >+ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/nvreg.h,v 3.2.2.1 1998/01/18 10:35:36 hohndel Exp $ */ >+ >+#ifndef __NVREG_H_ >+#define __NVREG_H_ >+ >+/* Little macro to construct bitmask for contiguous ranges of bits */ >+#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b)) >+#define MASKEXPAND(mask) BITMASK(1?mask,0?mask) >+ >+/* Macro to set specific bitfields (mask has to be a macro x:y) ! */ >+#define SetBF(mask,value) ((value) << (0?mask)) >+#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) ) >+ >+#define MaskAndSetBF(var,mask,value) (var)=(((var)&(~MASKEXPAND(mask)) \ >+ | SetBF(mask,value))) >+ >+#define DEVICE_BASE(device) (0?NV##_##device) >+#define DEVICE_SIZE(device) ((1?NV##_##device) - DEVICE_BASE(device)+1) >+ >+/* This is where we will have to have conditional compilation */ >+#define DEVICE_ACCESS(device,reg) \ >+ nvCONTROL[(NV_##device##_##reg)/4] >+ >+#define DEVICE_WRITE(device,reg,value) DEVICE_ACCESS(device,reg)=(value) >+#define DEVICE_READ(device,reg) DEVICE_ACCESS(device,reg) >+#define DEVICE_PRINT(device,reg) \ >+ ErrorF("NV_"#device"_"#reg"=#%08lx\n",DEVICE_ACCESS(device,reg)) >+#define DEVICE_DEF(device,mask,value) \ >+ SetBF(NV_##device##_##mask,NV_##device##_##mask##_##value) >+#define DEVICE_VALUE(device,mask,value) SetBF(NV_##device##_##mask,value) >+#define DEVICE_MASK(device,mask) MASKEXPAND(NV_##device##_##mask) >+ >+#define PDAC_Write(reg,value) DEVICE_WRITE(PDAC,reg,value) >+#define PDAC_Read(reg) DEVICE_READ(PDAC,reg) >+#define PDAC_Print(reg) DEVICE_PRINT(PDAC,reg) >+#define PDAC_Def(mask,value) DEVICE_DEF(PDAC,mask,value) >+#define PDAC_Val(mask,value) DEVICE_VALUE(PDAC,mask,value) >+#define PDAC_Mask(mask) DEVICE_MASK(PDAC,mask) >+ >+#define PFB_Write(reg,value) DEVICE_WRITE(PFB,reg,value) >+#define PFB_Read(reg) DEVICE_READ(PFB,reg) >+#define PFB_Print(reg) DEVICE_PRINT(PFB,reg) >+#define PFB_Def(mask,value) DEVICE_DEF(PFB,mask,value) >+#define PFB_Val(mask,value) DEVICE_VALUE(PFB,mask,value) >+#define PFB_Mask(mask) DEVICE_MASK(PFB,mask) >+ >+#define PRM_Write(reg,value) DEVICE_WRITE(PRM,reg,value) >+#define PRM_Read(reg) DEVICE_READ(PRM,reg) >+#define PRM_Print(reg) DEVICE_PRINT(PRM,reg) >+#define PRM_Def(mask,value) DEVICE_DEF(PRM,mask,value) >+#define PRM_Val(mask,value) DEVICE_VALUE(PRM,mask,value) >+#define PRM_Mask(mask) DEVICE_MASK(PRM,mask) >+ >+#define PGRAPH_Write(reg,value) DEVICE_WRITE(PGRAPH,reg,value) >+#define PGRAPH_Read(reg) DEVICE_READ(PGRAPH,reg) >+#define PGRAPH_Print(reg) DEVICE_PRINT(PGRAPH,reg) >+#define PGRAPH_Def(mask,value) DEVICE_DEF(PGRAPH,mask,value) >+#define PGRAPH_Val(mask,value) DEVICE_VALUE(PGRAPH,mask,value) >+#define PGRAPH_Mask(mask) DEVICE_MASK(PGRAPH,mask) >+ >+#define PDMA_Write(reg,value) DEVICE_WRITE(PDMA,reg,value) >+#define PDMA_Read(reg) DEVICE_READ(PDMA,reg) >+#define PDMA_Print(reg) DEVICE_PRINT(PDMA,reg) >+#define PDMA_Def(mask,value) DEVICE_DEF(PDMA,mask,value) >+#define PDMA_Val(mask,value) DEVICE_VALUE(PDMA,mask,value) >+#define PDMA_Mask(mask) DEVICE_MASK(PDMA,mask) >+ >+#define PTIMER_Write(reg,value) DEVICE_WRITE(PTIMER,reg,value) >+#define PTIMER_Read(reg) DEVICE_READ(PTIMER,reg) >+#define PTIMER_Print(reg) DEVICE_PRINT(PTIMER,reg) >+#define PTIMER_Def(mask,value) DEVICE_DEF(PTIMER,mask,value) >+#define PTIMER_Val(mask,value) DEVICE_VALUE(PTIEMR,mask,value) >+#define PTIMER_Mask(mask) DEVICE_MASK(PTIMER,mask) >+ >+#define PEXTDEV_Write(reg,value) DEVICE_WRITE(PEXTDEV,reg,value) >+#define PEXTDEV_Read(reg) DEVICE_READ(PEXTDEV,reg) >+#define PEXTDEV_Print(reg) DEVICE_PRINT(PEXTDEV,reg) >+#define PEXTDEV_Def(mask,value) DEVICE_DEF(PEXTDEV,mask,value) >+#define PEXTDEV_Val(mask,value) DEVICE_VALUE(PEXTDEV,mask,value) >+#define PEXTDEV_Mask(mask) DEVICE_MASK(PEXTDEV,mask) >+ >+#define PFIFO_Write(reg,value) DEVICE_WRITE(PFIFO,reg,value) >+#define PFIFO_Read(reg) DEVICE_READ(PFIFO,reg) >+#define PFIFO_Print(reg) DEVICE_PRINT(PFIFO,reg) >+#define PFIFO_Def(mask,value) DEVICE_DEF(PFIFO,mask,value) >+#define PFIFO_Val(mask,value) DEVICE_VALUE(PFIFO,mask,value) >+#define PFIFO_Mask(mask) DEVICE_MASK(PFIFO,mask) >+ >+#define PRAM_Write(reg,value) DEVICE_WRITE(PRAM,reg,value) >+#define PRAM_Read(reg) DEVICE_READ(PRAM,reg) >+#define PRAM_Print(reg) DEVICE_PRINT(PRAM,reg) >+#define PRAM_Def(mask,value) DEVICE_DEF(PRAM,mask,value) >+#define PRAM_Val(mask,value) DEVICE_VALUE(PRAM,mask,value) >+#define PRAM_Mask(mask) DEVICE_MASK(PRAM,mask) >+ >+#define PRAMFC_Write(reg,value) DEVICE_WRITE(PRAMFC,reg,value) >+#define PRAMFC_Read(reg) DEVICE_READ(PRAMFC,reg) >+#define PRAMFC_Print(reg) DEVICE_PRINT(PRAMFC,reg) >+#define PRAMFC_Def(mask,value) DEVICE_DEF(PRAMFC,mask,value) >+#define PRAMFC_Val(mask,value) DEVICE_VALUE(PRAMFC,mask,value) >+#define PRAMFC_Mask(mask) DEVICE_MASK(PRAMFC,mask) >+ >+#define PMC_Write(reg,value) DEVICE_WRITE(PMC,reg,value) >+#define PMC_Read(reg) DEVICE_READ(PMC,reg) >+#define PMC_Print(reg) DEVICE_PRINT(PMC,reg) >+#define PMC_Def(mask,value) DEVICE_DEF(PMC,mask,value) >+#define PMC_Val(mask,value) DEVICE_VALUE(PMC,mask,value) >+#define PMC_Mask(mask) DEVICE_MASK(PMC,mask) >+ >+#define PMC_Write(reg,value) DEVICE_WRITE(PMC,reg,value) >+#define PMC_Read(reg) DEVICE_READ(PMC,reg) >+#define PMC_Print(reg) DEVICE_PRINT(PMC,reg) >+#define PMC_Def(mask,value) DEVICE_DEF(PMC,mask,value) >+#define PMC_Val(mask,value) DEVICE_VALUE(PMC,mask,value) >+#define PMC_Mask(mask) DEVICE_MASK(PMC,mask) >+ >+ >+#define PBUS_Write(reg,value) DEVICE_WRITE(PBUS,reg,value) >+#define PBUS_Read(reg) DEVICE_READ(PBUS,reg) >+#define PBUS_Print(reg) DEVICE_PRINT(PBUS,reg) >+#define PBUS_Def(mask,value) DEVICE_DEF(PBUS,mask,value) >+#define PBUS_Val(mask,value) DEVICE_VALUE(PBUS,mask,value) >+#define PBUS_Mask(mask) DEVICE_MASK(PBUS,mask) >+ >+ >+#define PRAMDAC_Write(reg,value) DEVICE_WRITE(PRAMDAC,reg,value) >+#define PRAMDAC_Read(reg) DEVICE_READ(PRAMDAC,reg) >+#define PRAMDAC_Print(reg) DEVICE_PRINT(PRAMDAC,reg) >+#define PRAMDAC_Def(mask,value) DEVICE_DEF(PRAMDAC,mask,value) >+#define PRAMDAC_Val(mask,value) DEVICE_VALUE(PRAMDAC,mask,value) >+#define PRAMDAC_Mask(mask) DEVICE_MASK(PRAMDAC,mask) >+ >+ >+#define PDAC_ReadExt(reg) \ >+ ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\ >+ (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\ >+ (PDAC_Read(INDEX_DATA))) >+ >+#define PDAC_WriteExt(reg,value)\ >+ ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\ >+ (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\ >+ (PDAC_Write(INDEX_DATA,(value)))) >+ >+#define CRTC_Write(index,value) outb((index), 0x3d4); outb(value, 0x3d5) >+#define CRTC_Read(index) (outb(index, 0x3d4),inb(0x3d5)) >+ >+#define PCRTC_Write(index,value) CRTC_Write(NV_PCRTC_##index,value) >+#define PCRTC_Read(index) CRTC_Read(NV_PCRTC_##index) >+ >+#define PCRTC_Def(mask,value) DEVICE_DEF(PCRTC,mask,value) >+#define PCRTC_Val(mask,value) DEVICE_VALUE(PCRTC,mask,value) >+#define PCRTC_Mask(mask) DEVICE_MASK(PCRTC,mask) >+ >+#define SR_Write(index,value) outb(0x3c4,(index));outb(0x3c5,value) >+#define SR_Read(index) (outb(0x3c4,index),inb(0x3c5)) >+ >+extern volatile unsigned *nvCONTROL; >+ >+typedef enum {NV1,NV3,NV4,NumNVChips} NVChipType; >+ >+NVChipType GetChipType(void); >+ >+#endif >+ >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/riva_hw.c linux-2.6.6/drivers/video/xbox/riva_hw.c >--- linux-2.6.6.orig/drivers/video/xbox/riva_hw.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/riva_hw.c 2004-05-10 12:30:23.252936184 +0100 >@@ -0,0 +1,2253 @@ >+ /***************************************************************************\ >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NOTICE TO USER: The source code is copyrighted under U.S. and *| >+|* international laws. Users and possessors of this source code are *| >+|* hereby granted a nonexclusive, royalty-free copyright license to *| >+|* use this code in individual and commercial software. *| >+|* *| >+|* Any use of this source code must include, in the user documenta- *| >+|* tion and internal comments to the code, notices to the end user *| >+|* as follows: *| >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| >+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| >+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| >+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| >+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| >+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| >+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| >+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| >+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| >+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| >+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| >+|* *| >+|* U.S. Government End Users. This source code is a "commercial *| >+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| >+|* consisting of "commercial computer software" and "commercial *| >+|* computer software documentation," as such terms are used in *| >+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| >+|* ment only as a commercial end item. Consistent with 48 C.F.R. *| >+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| >+|* all U.S. Government End Users acquire the source code with only *| >+|* those rights set forth herein. *| >+|* *| >+ \***************************************************************************/ >+ >+/* >+ * GPL licensing note -- nVidia is allowing a liberal interpretation of >+ * the documentation restriction above, to merely say that this nVidia's >+ * copyright and disclaimer should be included with all code derived >+ * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 >+ */ >+ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.33 2002/08/05 20:47:06 mvojkovi Exp $ */ >+ >+#include <linux/pci.h> >+#include <linux/pci_ids.h> >+#include "riva_hw.h" >+#include "riva_tbl.h" >+#include "nv_type.h" >+ >+/* >+ * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT >+ * operate identically (except TNT has more memory and better 3D quality. >+ */ >+static int nv3Busy >+( >+ RIVA_HW_INST *chip >+) >+{ >+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01)); >+} >+static int nv4Busy >+( >+ RIVA_HW_INST *chip >+) >+{ >+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01)); >+} >+static int nv10Busy >+( >+ RIVA_HW_INST *chip >+) >+{ >+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01)); >+} >+ >+static void vgaLockUnlock >+( >+ RIVA_HW_INST *chip, >+ int Lock >+) >+{ >+ U008 cr11; >+ VGA_WR08(chip->PCIO, 0x3D4, 0x11); >+ cr11 = VGA_RD08(chip->PCIO, 0x3D5); >+ if(Lock) cr11 |= 0x80; >+ else cr11 &= ~0x80; >+ VGA_WR08(chip->PCIO, 0x3D5, cr11); >+} >+static void nv3LockUnlock >+( >+ RIVA_HW_INST *chip, >+ int Lock >+) >+{ >+ VGA_WR08(chip->PVIO, 0x3C4, 0x06); >+ VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57); >+ vgaLockUnlock(chip, Lock); >+} >+static void nv4LockUnlock >+( >+ RIVA_HW_INST *chip, >+ int Lock >+) >+{ >+ VGA_WR08(chip->PCIO, 0x3D4, 0x1F); >+ VGA_WR08(chip->PCIO, 0x3D5, Lock ? 0x99 : 0x57); >+ vgaLockUnlock(chip, Lock); >+} >+ >+static int ShowHideCursor >+( >+ RIVA_HW_INST *chip, >+ int ShowHide >+) >+{ >+ int cursor; >+ cursor = chip->CurrentState->cursor1; >+ chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) | >+ (ShowHide & 0x01); >+ VGA_WR08(chip->PCIO, 0x3D4, 0x31); >+ VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1); >+ return (cursor & 0x01); >+} >+ >+static int nv10ShowHideCursor >+( >+ RIVA_HW_INST *chip, >+ int ShowHide >+) >+{ >+ unsigned int cursor; >+ cursor = chip->CurrentState->cursorConfig; >+ chip->CurrentState->cursorConfig = (chip->PCRTC[0x00000810/4] & 0xFFFFFFFE) | >+ (ShowHide & 0x01); >+ chip->PCRTC[0x00000810/4] = chip->CurrentState->cursorConfig; >+ return (cursor & 0x01); >+} >+ >+/****************************************************************************\ >+* * >+* The video arbitration routines calculate some "magic" numbers. Fixes * >+* the snow seen when accessing the framebuffer without it. * >+* It just works (I hope). * >+* * >+\****************************************************************************/ >+ >+#define DEFAULT_GR_LWM 100 >+#define DEFAULT_VID_LWM 100 >+#define DEFAULT_GR_BURST_SIZE 256 >+#define DEFAULT_VID_BURST_SIZE 128 >+#define VIDEO 0 >+#define GRAPHICS 1 >+#define MPORT 2 >+#define ENGINE 3 >+#define GFIFO_SIZE 320 >+#define GFIFO_SIZE_128 256 >+#define MFIFO_SIZE 120 >+#define VFIFO_SIZE 256 >+#define ABS(a) (a>0?a:-a) >+typedef struct { >+ int gdrain_rate; >+ int vdrain_rate; >+ int mdrain_rate; >+ int gburst_size; >+ int vburst_size; >+ char vid_en; >+ char gr_en; >+ int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm; >+ int by_gfacc; >+ char vid_only_once; >+ char gr_only_once; >+ char first_vacc; >+ char first_gacc; >+ char first_macc; >+ int vocc; >+ int gocc; >+ int mocc; >+ char cur; >+ char engine_en; >+ char converged; >+ int priority; >+} nv3_arb_info; >+typedef struct { >+ int graphics_lwm; >+ int video_lwm; >+ int graphics_burst_size; >+ int video_burst_size; >+ int graphics_hi_priority; >+ int media_hi_priority; >+ int rtl_values; >+ int valid; >+} nv3_fifo_info; >+typedef struct { >+ char pix_bpp; >+ char enable_video; >+ char gr_during_vid; >+ char enable_mp; >+ int memory_width; >+ int video_scale; >+ int pclk_khz; >+ int mclk_khz; >+ int mem_page_miss; >+ int mem_latency; >+ char mem_aligned; >+} nv3_sim_state; >+typedef struct { >+ int graphics_lwm; >+ int video_lwm; >+ int graphics_burst_size; >+ int video_burst_size; >+ int valid; >+} nv4_fifo_info; >+typedef struct { >+ int pclk_khz; >+ int mclk_khz; >+ int nvclk_khz; >+ char mem_page_miss; >+ char mem_latency; >+ int memory_width; >+ char enable_video; >+ char gr_during_vid; >+ char pix_bpp; >+ char mem_aligned; >+ char enable_mp; >+} nv4_sim_state; >+typedef struct { >+ int graphics_lwm; >+ int video_lwm; >+ int graphics_burst_size; >+ int video_burst_size; >+ int valid; >+} nv10_fifo_info; >+typedef struct { >+ int pclk_khz; >+ int mclk_khz; >+ int nvclk_khz; >+ char mem_page_miss; >+ char mem_latency; >+ int memory_type; >+ int memory_width; >+ char enable_video; >+ char gr_during_vid; >+ char pix_bpp; >+ char mem_aligned; >+ char enable_mp; >+} nv10_sim_state; >+static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo) >+{ >+ int iter = 0; >+ int tmp; >+ int vfsize, mfsize, gfsize; >+ int mburst_size = 32; >+ int mmisses, gmisses, vmisses; >+ int misses; >+ int vlwm, glwm, mlwm; >+ int last, next, cur; >+ int max_gfsize ; >+ long ns; >+ >+ vlwm = 0; >+ glwm = 0; >+ mlwm = 0; >+ vfsize = 0; >+ gfsize = 0; >+ cur = ainfo->cur; >+ mmisses = 2; >+ gmisses = 2; >+ vmisses = 2; >+ if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128; >+ else max_gfsize = GFIFO_SIZE; >+ max_gfsize = GFIFO_SIZE; >+ while (1) >+ { >+ if (ainfo->vid_en) >+ { >+ if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc; >+ if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ; >+ ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz; >+ vfsize = ns * ainfo->vdrain_rate / 1000000; >+ vfsize = ainfo->wcvlwm - ainfo->vburst_size + vfsize; >+ } >+ if (state->enable_mp) >+ { >+ if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc; >+ } >+ if (ainfo->gr_en) >+ { >+ if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ; >+ if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc; >+ ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz; >+ gfsize = (ns * (long) ainfo->gdrain_rate)/1000000; >+ gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize; >+ } >+ mfsize = 0; >+ if (!state->gr_during_vid && ainfo->vid_en) >+ if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once) >+ next = VIDEO; >+ else if (ainfo->mocc < 0) >+ next = MPORT; >+ else if (ainfo->gocc< ainfo->by_gfacc) >+ next = GRAPHICS; >+ else return (0); >+ else switch (ainfo->priority) >+ { >+ case VIDEO: >+ if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) >+ next = VIDEO; >+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) >+ next = GRAPHICS; >+ else if (ainfo->mocc<0) >+ next = MPORT; >+ else return (0); >+ break; >+ case GRAPHICS: >+ if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) >+ next = GRAPHICS; >+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) >+ next = VIDEO; >+ else if (ainfo->mocc<0) >+ next = MPORT; >+ else return (0); >+ break; >+ default: >+ if (ainfo->mocc<0) >+ next = MPORT; >+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) >+ next = GRAPHICS; >+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) >+ next = VIDEO; >+ else return (0); >+ break; >+ } >+ last = cur; >+ cur = next; >+ iter++; >+ switch (cur) >+ { >+ case VIDEO: >+ if (last==cur) misses = 0; >+ else if (ainfo->first_vacc) misses = vmisses; >+ else misses = 1; >+ ainfo->first_vacc = 0; >+ if (last!=cur) >+ { >+ ns = 1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; >+ vlwm = ns * ainfo->vdrain_rate/ 1000000; >+ vlwm = ainfo->vocc - vlwm; >+ } >+ ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz; >+ ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000; >+ ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000; >+ ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000; >+ break; >+ case GRAPHICS: >+ if (last==cur) misses = 0; >+ else if (ainfo->first_gacc) misses = gmisses; >+ else misses = 1; >+ ainfo->first_gacc = 0; >+ if (last!=cur) >+ { >+ ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ; >+ glwm = ns * ainfo->gdrain_rate/1000000; >+ glwm = ainfo->gocc - glwm; >+ } >+ ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz; >+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000; >+ ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000; >+ ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000; >+ break; >+ default: >+ if (last==cur) misses = 0; >+ else if (ainfo->first_macc) misses = mmisses; >+ else misses = 1; >+ ainfo->first_macc = 0; >+ ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz; >+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000; >+ ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000; >+ ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000; >+ break; >+ } >+ if (iter>100) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz; >+ tmp = ns * ainfo->gdrain_rate/1000000; >+ if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz; >+ tmp = ns * ainfo->vdrain_rate/1000000; >+ if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf) - tmp> VFIFO_SIZE) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(ainfo->gocc) > max_gfsize) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(ainfo->vocc) > VFIFO_SIZE) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(ainfo->mocc) > MFIFO_SIZE) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(vfsize) > VFIFO_SIZE) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(gfsize) > max_gfsize) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ if (ABS(mfsize) > MFIFO_SIZE) >+ { >+ ainfo->converged = 0; >+ return (1); >+ } >+ } >+} >+static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_info *ainfo) >+{ >+ long ens, vns, mns, gns; >+ int mmisses, gmisses, vmisses, eburst_size, mburst_size; >+ int refresh_cycle; >+ >+ refresh_cycle = 0; >+ refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5; >+ mmisses = 2; >+ if (state->mem_aligned) gmisses = 2; >+ else gmisses = 3; >+ vmisses = 2; >+ eburst_size = state->memory_width * 1; >+ mburst_size = 32; >+ gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; >+ ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000; >+ ainfo->wcmocc = 0; >+ ainfo->wcgocc = 0; >+ ainfo->wcvocc = 0; >+ ainfo->wcvlwm = 0; >+ ainfo->wcglwm = 0; >+ ainfo->engine_en = 1; >+ ainfo->converged = 1; >+ if (ainfo->engine_en) >+ { >+ ens = 1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz; >+ ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0; >+ ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0; >+ ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0; >+ ainfo->cur = ENGINE; >+ ainfo->first_vacc = 1; >+ ainfo->first_gacc = 1; >+ ainfo->first_macc = 1; >+ nv3_iterate(res_info, state,ainfo); >+ } >+ if (state->enable_mp) >+ { >+ mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz; >+ ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000; >+ ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000; >+ ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000; >+ ainfo->cur = MPORT; >+ ainfo->first_vacc = 1; >+ ainfo->first_gacc = 1; >+ ainfo->first_macc = 0; >+ nv3_iterate(res_info, state,ainfo); >+ } >+ if (ainfo->gr_en) >+ { >+ ainfo->first_vacc = 1; >+ ainfo->first_gacc = 0; >+ ainfo->first_macc = 1; >+ gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz; >+ ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000; >+ ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0; >+ ainfo->mocc = state->enable_mp ? 0-gns*ainfo->mdrain_rate/1000000: 0; >+ ainfo->cur = GRAPHICS; >+ nv3_iterate(res_info, state,ainfo); >+ } >+ if (ainfo->vid_en) >+ { >+ ainfo->first_vacc = 0; >+ ainfo->first_gacc = 1; >+ ainfo->first_macc = 1; >+ vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz; >+ ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000; >+ ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0; >+ ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ; >+ ainfo->cur = VIDEO; >+ nv3_iterate(res_info, state, ainfo); >+ } >+ if (ainfo->converged) >+ { >+ res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16; >+ res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32; >+ res_info->graphics_burst_size = ainfo->gburst_size; >+ res_info->video_burst_size = ainfo->vburst_size; >+ res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS); >+ res_info->media_hi_priority = (ainfo->priority == MPORT); >+ if (res_info->video_lwm > 160) >+ { >+ res_info->graphics_lwm = 256; >+ res_info->video_lwm = 128; >+ res_info->graphics_burst_size = 64; >+ res_info->video_burst_size = 64; >+ res_info->graphics_hi_priority = 0; >+ res_info->media_hi_priority = 0; >+ ainfo->converged = 0; >+ return (0); >+ } >+ if (res_info->video_lwm > 128) >+ { >+ res_info->video_lwm = 128; >+ } >+ return (1); >+ } >+ else >+ { >+ res_info->graphics_lwm = 256; >+ res_info->video_lwm = 128; >+ res_info->graphics_burst_size = 64; >+ res_info->video_burst_size = 64; >+ res_info->graphics_hi_priority = 0; >+ res_info->media_hi_priority = 0; >+ return (0); >+ } >+} >+static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo) >+{ >+ int done, g,v, p; >+ >+ done = 0; >+ for (p=0; p < 2; p++) >+ { >+ for (g=128 ; g > 32; g= g>> 1) >+ { >+ for (v=128; v >=32; v = v>> 1) >+ { >+ ainfo->priority = p; >+ ainfo->gburst_size = g; >+ ainfo->vburst_size = v; >+ done = nv3_arb(res_info, state,ainfo); >+ if (done && (g==128)) >+ if ((res_info->graphics_lwm + g) > 256) >+ done = 0; >+ if (done) >+ goto Done; >+ } >+ } >+ } >+ >+ Done: >+ return done; >+} >+static void nv3CalcArbitration >+( >+ nv3_fifo_info * res_info, >+ nv3_sim_state * state >+) >+{ >+ nv3_fifo_info save_info; >+ nv3_arb_info ainfo; >+ char res_gr, res_vid; >+ >+ ainfo.gr_en = 1; >+ ainfo.vid_en = state->enable_video; >+ ainfo.vid_only_once = 0; >+ ainfo.gr_only_once = 0; >+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8); >+ ainfo.vdrain_rate = (int) state->pclk_khz * 2; >+ if (state->video_scale != 0) >+ ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale; >+ ainfo.mdrain_rate = 33000; >+ res_info->rtl_values = 0; >+ if (!state->gr_during_vid && state->enable_video) >+ { >+ ainfo.gr_only_once = 1; >+ ainfo.gr_en = 1; >+ ainfo.gdrain_rate = 0; >+ res_vid = nv3_get_param(res_info, state, &ainfo); >+ res_vid = ainfo.converged; >+ save_info.video_lwm = res_info->video_lwm; >+ save_info.video_burst_size = res_info->video_burst_size; >+ ainfo.vid_en = 1; >+ ainfo.vid_only_once = 1; >+ ainfo.gr_en = 1; >+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8); >+ ainfo.vdrain_rate = 0; >+ res_gr = nv3_get_param(res_info, state, &ainfo); >+ res_gr = ainfo.converged; >+ res_info->video_lwm = save_info.video_lwm; >+ res_info->video_burst_size = save_info.video_burst_size; >+ res_info->valid = res_gr & res_vid; >+ } >+ else >+ { >+ if (!ainfo.gr_en) ainfo.gdrain_rate = 0; >+ if (!ainfo.vid_en) ainfo.vdrain_rate = 0; >+ res_gr = nv3_get_param(res_info, state, &ainfo); >+ res_info->valid = ainfo.converged; >+ } >+} >+static void nv3UpdateArbitrationSettings >+( >+ unsigned VClk, >+ unsigned pixelDepth, >+ unsigned *burst, >+ unsigned *lwm, >+ RIVA_HW_INST *chip >+) >+{ >+ nv3_fifo_info fifo_data; >+ nv3_sim_state sim_data; >+ unsigned int M, N, P, pll, MClk; >+ >+ pll = chip->PRAMDAC0[0x00000504/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ MClk = (N * chip->CrystalFreqKHz / M) >> P; >+ sim_data.pix_bpp = (char)pixelDepth; >+ sim_data.enable_video = 0; >+ sim_data.enable_mp = 0; >+ sim_data.video_scale = 1; >+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; >+ sim_data.memory_width = 128; >+ >+ sim_data.mem_latency = 9; >+ sim_data.mem_aligned = 1; >+ sim_data.mem_page_miss = 11; >+ sim_data.gr_during_vid = 0; >+ sim_data.pclk_khz = VClk; >+ sim_data.mclk_khz = MClk; >+ nv3CalcArbitration(&fifo_data, &sim_data); >+ if (fifo_data.valid) >+ { >+ int b = fifo_data.graphics_burst_size >> 4; >+ *burst = 0; >+ while (b >>= 1) (*burst)++; >+ *lwm = fifo_data.graphics_lwm >> 3; >+ } >+ else >+ { >+ *lwm = 0x24; >+ *burst = 0x2; >+ } >+} >+static void nv4CalcArbitration >+( >+ nv4_fifo_info *fifo, >+ nv4_sim_state *arb >+) >+{ >+ int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align; >+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs; >+ int found, mclk_extra, mclk_loop, cbs, m1, p1; >+ int mclk_freq, pclk_freq, nvclk_freq, mp_enable; >+ int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate; >+ int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm; >+ int craw, vraw; >+ >+ fifo->valid = 1; >+ pclk_freq = arb->pclk_khz; >+ mclk_freq = arb->mclk_khz; >+ nvclk_freq = arb->nvclk_khz; >+ pagemiss = arb->mem_page_miss; >+ cas = arb->mem_latency; >+ width = arb->memory_width >> 6; >+ video_enable = arb->enable_video; >+ color_key_enable = arb->gr_during_vid; >+ bpp = arb->pix_bpp; >+ align = arb->mem_aligned; >+ mp_enable = arb->enable_mp; >+ clwm = 0; >+ vlwm = 0; >+ cbs = 128; >+ pclks = 2; >+ nvclks = 2; >+ nvclks += 2; >+ nvclks += 1; >+ mclks = 5; >+ mclks += 3; >+ mclks += 1; >+ mclks += cas; >+ mclks += 1; >+ mclks += 1; >+ mclks += 1; >+ mclks += 1; >+ mclk_extra = 3; >+ nvclks += 2; >+ nvclks += 1; >+ nvclks += 1; >+ nvclks += 1; >+ if (mp_enable) >+ mclks+=4; >+ nvclks += 0; >+ pclks += 0; >+ found = 0; >+ vbs = 0; >+ while (found != 1) >+ { >+ fifo->valid = 1; >+ found = 1; >+ mclk_loop = mclks+mclk_extra; >+ us_m = mclk_loop *1000*1000 / mclk_freq; >+ us_n = nvclks*1000*1000 / nvclk_freq; >+ us_p = nvclks*1000*1000 / pclk_freq; >+ if (video_enable) >+ { >+ video_drain_rate = pclk_freq * 2; >+ crtc_drain_rate = pclk_freq * bpp/8; >+ vpagemiss = 2; >+ vpagemiss += 1; >+ crtpagemiss = 2; >+ vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq; >+ if (nvclk_freq * 2 > mclk_freq * width) >+ video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ; >+ else >+ video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq; >+ us_video = vpm_us + us_m + us_n + us_p + video_fill_us; >+ vlwm = us_video * video_drain_rate/(1000*1000); >+ vlwm++; >+ vbs = 128; >+ if (vlwm > 128) vbs = 64; >+ if (vlwm > (256-64)) vbs = 32; >+ if (nvclk_freq * 2 > mclk_freq * width) >+ video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ; >+ else >+ video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq; >+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq; >+ us_crt = >+ us_video >+ +video_fill_us >+ +cpm_us >+ +us_m + us_n +us_p >+ ; >+ clwm = us_crt * crtc_drain_rate/(1000*1000); >+ clwm++; >+ } >+ else >+ { >+ crtc_drain_rate = pclk_freq * bpp/8; >+ crtpagemiss = 2; >+ crtpagemiss += 1; >+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq; >+ us_crt = cpm_us + us_m + us_n + us_p ; >+ clwm = us_crt * crtc_drain_rate/(1000*1000); >+ clwm++; >+ } >+ m1 = clwm + cbs - 512; >+ p1 = m1 * pclk_freq / mclk_freq; >+ p1 = p1 * bpp / 8; >+ if ((p1 < m1) && (m1 > 0)) >+ { >+ fifo->valid = 0; >+ found = 0; >+ if (mclk_extra ==0) found = 1; >+ mclk_extra--; >+ } >+ else if (video_enable) >+ { >+ if ((clwm > 511) || (vlwm > 255)) >+ { >+ fifo->valid = 0; >+ found = 0; >+ if (mclk_extra ==0) found = 1; >+ mclk_extra--; >+ } >+ } >+ else >+ { >+ if (clwm > 519) >+ { >+ fifo->valid = 0; >+ found = 0; >+ if (mclk_extra ==0) found = 1; >+ mclk_extra--; >+ } >+ } >+ craw = clwm; >+ vraw = vlwm; >+ if (clwm < 384) clwm = 384; >+ if (vlwm < 128) vlwm = 128; >+ data = (int)(clwm); >+ fifo->graphics_lwm = data; >+ fifo->graphics_burst_size = 128; >+ data = (int)((vlwm+15)); >+ fifo->video_lwm = data; >+ fifo->video_burst_size = vbs; >+ } >+} >+static void nv4UpdateArbitrationSettings >+( >+ unsigned VClk, >+ unsigned pixelDepth, >+ unsigned *burst, >+ unsigned *lwm, >+ RIVA_HW_INST *chip >+) >+{ >+ nv4_fifo_info fifo_data; >+ nv4_sim_state sim_data; >+ unsigned int M, N, P, pll, MClk, NVClk, cfg1; >+ >+ pll = chip->PRAMDAC0[0x00000504/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ MClk = (N * chip->CrystalFreqKHz / M) >> P; >+ pll = chip->PRAMDAC0[0x00000500/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ NVClk = (N * chip->CrystalFreqKHz / M) >> P; >+ cfg1 = chip->PFB[0x00000204/4]; >+ sim_data.pix_bpp = (char)pixelDepth; >+ sim_data.enable_video = 0; >+ sim_data.enable_mp = 0; >+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; >+ sim_data.mem_latency = (char)cfg1 & 0x0F; >+ sim_data.mem_aligned = 1; >+ sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01)); >+ sim_data.gr_during_vid = 0; >+ sim_data.pclk_khz = VClk; >+ sim_data.mclk_khz = MClk; >+ sim_data.nvclk_khz = NVClk; >+ nv4CalcArbitration(&fifo_data, &sim_data); >+ if (fifo_data.valid) >+ { >+ int b = fifo_data.graphics_burst_size >> 4; >+ *burst = 0; >+ while (b >>= 1) (*burst)++; >+ *lwm = fifo_data.graphics_lwm >> 3; >+ } >+} >+static void nv10CalcArbitration >+( >+ nv10_fifo_info *fifo, >+ nv10_sim_state *arb >+) >+{ >+ int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align; >+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs; >+ int nvclk_fill, us_extra; >+ int found, mclk_extra, mclk_loop, cbs, m1; >+ int mclk_freq, pclk_freq, nvclk_freq, mp_enable; >+ int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate; >+ int vus_m, vus_n, vus_p; >+ int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm; >+ int clwm_rnd_down; >+ int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2; >+ int pclks_2_top_fifo, min_mclk_extra; >+ int us_min_mclk_extra; >+ >+ fifo->valid = 1; >+ pclk_freq = arb->pclk_khz; /* freq in KHz */ >+ mclk_freq = arb->mclk_khz; >+ nvclk_freq = arb->nvclk_khz; >+ pagemiss = arb->mem_page_miss; >+ cas = arb->mem_latency; >+ width = arb->memory_width/64; >+ video_enable = arb->enable_video; >+ color_key_enable = arb->gr_during_vid; >+ bpp = arb->pix_bpp; >+ align = arb->mem_aligned; >+ mp_enable = arb->enable_mp; >+ clwm = 0; >+ vlwm = 1024; >+ >+ cbs = 512; >+ vbs = 512; >+ >+ pclks = 4; /* lwm detect. */ >+ >+ nvclks = 3; /* lwm -> sync. */ >+ nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */ >+ >+ mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */ >+ >+ mclks += 1; /* arb_hp_req */ >+ mclks += 5; /* ap_hp_req tiling pipeline */ >+ >+ mclks += 2; /* tc_req latency fifo */ >+ mclks += 2; /* fb_cas_n_ memory request to fbio block */ >+ mclks += 7; /* sm_d_rdv data returned from fbio block */ >+ >+ /* fb.rd.d.Put_gc need to accumulate 256 bits for read */ >+ if (arb->memory_type == 0) >+ if (arb->memory_width == 64) /* 64 bit bus */ >+ mclks += 4; >+ else >+ mclks += 2; >+ else >+ if (arb->memory_width == 64) /* 64 bit bus */ >+ mclks += 2; >+ else >+ mclks += 1; >+ >+ if ((!video_enable) && (arb->memory_width == 128)) >+ { >+ mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */ >+ min_mclk_extra = 17; >+ } >+ else >+ { >+ mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */ >+ /* mclk_extra = 4; */ /* Margin of error */ >+ min_mclk_extra = 18; >+ } >+ >+ nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */ >+ nvclks += 1; /* fbi_d_rdv_n */ >+ nvclks += 1; /* Fbi_d_rdata */ >+ nvclks += 1; /* crtfifo load */ >+ >+ if(mp_enable) >+ mclks+=4; /* Mp can get in with a burst of 8. */ >+ /* Extra clocks determined by heuristics */ >+ >+ nvclks += 0; >+ pclks += 0; >+ found = 0; >+ while(found != 1) { >+ fifo->valid = 1; >+ found = 1; >+ mclk_loop = mclks+mclk_extra; >+ us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */ >+ us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */ >+ us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq; >+ us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */ >+ us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */ >+ us_pipe = us_m + us_n + us_p; >+ us_pipe_min = us_m_min + us_n + us_p; >+ us_extra = 0; >+ >+ vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */ >+ vus_n = (4)*1000*1000 / nvclk_freq;/* nvclk latency in us */ >+ vus_p = 0*1000*1000 / pclk_freq;/* pclk latency in us */ >+ vus_pipe = vus_m + vus_n + vus_p; >+ >+ if(video_enable) { >+ video_drain_rate = pclk_freq * 4; /* MB/s */ >+ crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */ >+ >+ vpagemiss = 1; /* self generating page miss */ >+ vpagemiss += 1; /* One higher priority before */ >+ >+ crtpagemiss = 2; /* self generating page miss */ >+ if(mp_enable) >+ crtpagemiss += 1; /* if MA0 conflict */ >+ >+ vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq; >+ >+ us_video = vpm_us + vus_m; /* Video has separate read return path */ >+ >+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq; >+ us_crt = >+ us_video /* Wait for video */ >+ +cpm_us /* CRT Page miss */ >+ +us_m + us_n +us_p /* other latency */ >+ ; >+ >+ clwm = us_crt * crtc_drain_rate/(1000*1000); >+ clwm++; /* fixed point <= float_point - 1. Fixes that */ >+ } else { >+ crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */ >+ >+ crtpagemiss = 1; /* self generating page miss */ >+ crtpagemiss += 1; /* MA0 page miss */ >+ if(mp_enable) >+ crtpagemiss += 1; /* if MA0 conflict */ >+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq; >+ us_crt = cpm_us + us_m + us_n + us_p ; >+ clwm = us_crt * crtc_drain_rate/(1000*1000); >+ clwm++; /* fixed point <= float_point - 1. Fixes that */ >+ >+ /* >+ // >+ // Another concern, only for high pclks so don't do this >+ // with video: >+ // What happens if the latency to fetch the cbs is so large that >+ // fifo empties. In that case we need to have an alternate clwm value >+ // based off the total burst fetch >+ // >+ us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ; >+ us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq; >+ clwm_mt = us_crt * crtc_drain_rate/(1000*1000); >+ clwm_mt ++; >+ if(clwm_mt > clwm) >+ clwm = clwm_mt; >+ */ >+ /* Finally, a heuristic check when width == 64 bits */ >+ if(width == 1){ >+ nvclk_fill = nvclk_freq * 8; >+ if(crtc_drain_rate * 100 >= nvclk_fill * 102) >+ clwm = 0xfff; /*Large number to fail */ >+ >+ else if(crtc_drain_rate * 100 >= nvclk_fill * 98) { >+ clwm = 1024; >+ cbs = 512; >+ us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ; >+ } >+ } >+ } >+ >+ >+ /* >+ Overfill check: >+ >+ */ >+ >+ clwm_rnd_down = ((int)clwm/8)*8; >+ if (clwm_rnd_down < clwm) >+ clwm += 8; >+ >+ m1 = clwm + cbs - 1024; /* Amount of overfill */ >+ m2us = us_pipe_min + us_min_mclk_extra; >+ pclks_2_top_fifo = (1024-clwm)/(8*width); >+ >+ /* pclk cycles to drain */ >+ p1clk = m2us * pclk_freq/(1000*1000); >+ p2 = p1clk * bpp / 8; /* bytes drained. */ >+ >+ if((p2 < m1) && (m1 > 0)) { >+ fifo->valid = 0; >+ found = 0; >+ if(min_mclk_extra == 0) { >+ if(cbs <= 32) { >+ found = 1; /* Can't adjust anymore! */ >+ } else { >+ cbs = cbs/2; /* reduce the burst size */ >+ } >+ } else { >+ min_mclk_extra--; >+ } >+ } else { >+ if (clwm > 1023){ /* Have some margin */ >+ fifo->valid = 0; >+ found = 0; >+ if(min_mclk_extra == 0) >+ found = 1; /* Can't adjust anymore! */ >+ else >+ min_mclk_extra--; >+ } >+ } >+ craw = clwm; >+ >+ if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8; >+ data = (int)(clwm); >+ /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */ >+ fifo->graphics_lwm = data; fifo->graphics_burst_size = cbs; >+ >+ /* printf("VID LWM: %f bytes, prog: 0x%x, bs: %d\n, ", vlwm, data, vbs ); */ >+ fifo->video_lwm = 1024; fifo->video_burst_size = 512; >+ } >+} >+static void nv10UpdateArbitrationSettings >+( >+ unsigned VClk, >+ unsigned pixelDepth, >+ unsigned *burst, >+ unsigned *lwm, >+ RIVA_HW_INST *chip >+) >+{ >+ nv10_fifo_info fifo_data; >+ nv10_sim_state sim_data; >+ unsigned int M, N, P, pll, MClk, NVClk, cfg1; >+ >+ pll = chip->PRAMDAC0[0x00000504/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ MClk = (N * chip->CrystalFreqKHz / M) >> P; >+ pll = chip->PRAMDAC0[0x00000500/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ NVClk = (N * chip->CrystalFreqKHz / M) >> P; >+ cfg1 = chip->PFB[0x00000204/4]; >+ sim_data.pix_bpp = (char)pixelDepth; >+ sim_data.enable_video = 0; >+ sim_data.enable_mp = 0; >+ sim_data.memory_type = (chip->PFB[0x00000200/4] & 0x01) ? 1 : 0; >+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; >+ sim_data.mem_latency = (char)cfg1 & 0x0F; >+ sim_data.mem_aligned = 1; >+ sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01)); >+ sim_data.gr_during_vid = 0; >+ sim_data.pclk_khz = VClk; >+ sim_data.mclk_khz = MClk; >+ sim_data.nvclk_khz = NVClk; >+ nv10CalcArbitration(&fifo_data, &sim_data); >+ if (fifo_data.valid) >+ { >+ int b = fifo_data.graphics_burst_size >> 4; >+ *burst = 0; >+ while (b >>= 1) (*burst)++; >+ *lwm = fifo_data.graphics_lwm >> 3; >+ } >+} >+ >+static void nForceUpdateArbitrationSettings >+( >+ unsigned VClk, >+ unsigned pixelDepth, >+ unsigned *burst, >+ unsigned *lwm, >+ RIVA_HW_INST *chip >+) >+{ >+ nv10_fifo_info fifo_data; >+ nv10_sim_state sim_data; >+ unsigned int M, N, P, pll, MClk, NVClk; >+ unsigned int uMClkPostDiv; >+ struct pci_dev *dev; >+ >+ dev = pci_find_slot(0, 3); >+ pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); >+ uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; >+ >+ if(!uMClkPostDiv) uMClkPostDiv = 4; >+ MClk = 400000 / uMClkPostDiv; >+ >+ pll = chip->PRAMDAC0[0x00000500/4]; >+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; >+ NVClk = (N * chip->CrystalFreqKHz / M) >> P; >+ sim_data.pix_bpp = (char)pixelDepth; >+ sim_data.enable_video = 0; >+ sim_data.enable_mp = 0; >+ >+ dev = pci_find_slot(0, 1); >+ pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); >+ sim_data.memory_type = (sim_data.memory_type >> 12) & 1; >+ >+ sim_data.memory_width = 64; >+ sim_data.mem_latency = 3; >+ sim_data.mem_aligned = 1; >+ sim_data.mem_page_miss = 10; >+ sim_data.gr_during_vid = 0; >+ sim_data.pclk_khz = VClk; >+ sim_data.mclk_khz = MClk; >+ sim_data.nvclk_khz = NVClk; >+ nv10CalcArbitration(&fifo_data, &sim_data); >+ if (fifo_data.valid) >+ { >+ int b = fifo_data.graphics_burst_size >> 4; >+ *burst = 0; >+ while (b >>= 1) (*burst)++; >+ *lwm = fifo_data.graphics_lwm >> 3; >+ } >+} >+ >+/****************************************************************************\ >+* * >+* RIVA Mode State Routines * >+* * >+\****************************************************************************/ >+ >+/* >+ * Calculate the Video Clock parameters for the PLL. >+ */ >+static int CalcVClock >+( >+ int clockIn, >+ int *clockOut, >+ int *mOut, >+ int *nOut, >+ int *pOut, >+ RIVA_HW_INST *chip >+) >+{ >+ unsigned lowM, highM, highP; >+ unsigned DeltaNew, DeltaOld; >+ unsigned VClk, Freq; >+ unsigned M, N, P; >+ >+ DeltaOld = 0xFFFFFFFF; >+ >+ VClk = (unsigned)clockIn; >+ >+ if (chip->CrystalFreqKHz == 13500) >+ { >+ lowM = 7; >+ highM = 13 - (chip->Architecture == NV_ARCH_03); >+ } >+ else >+ { >+ lowM = 8; >+ highM = 14 - (chip->Architecture == NV_ARCH_03); >+ } >+ >+ highP = 4 - (chip->Architecture == NV_ARCH_03); >+ for (P = 0; P <= highP; P ++) >+ { >+ Freq = VClk << P; >+ if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz)) >+ { >+ for (M = lowM; M <= highM; M++) >+ { >+ N = (VClk << P) * M / chip->CrystalFreqKHz; >+ if(N <= 255) { >+ Freq = (chip->CrystalFreqKHz * N / M) >> P; >+ if (Freq > VClk) >+ DeltaNew = Freq - VClk; >+ else >+ DeltaNew = VClk - Freq; >+ if (DeltaNew < DeltaOld) >+ { >+ *mOut = M; >+ *nOut = N; >+ *pOut = P; >+ *clockOut = Freq; >+ DeltaOld = DeltaNew; >+ } >+ } >+ } >+ } >+ } >+ return (DeltaOld != 0xFFFFFFFF); >+} >+/* >+ * Calculate extended mode parameters (SVGA) and save in a >+ * mode state structure. >+ */ >+static void CalcStateExt >+( >+ RIVA_HW_INST *chip, >+ RIVA_HW_STATE *state, >+ int bpp, >+ int width, >+ int hDisplaySize, >+ int height, >+ int dotClock >+) >+{ >+ int pixelDepth, VClk, m, n, p; >+ /* >+ * Save mode parameters. >+ */ >+ state->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */ >+ state->width = width; >+ state->height = height; >+ /* >+ * Extended RIVA registers. >+ */ >+ pixelDepth = (bpp + 1)/8; >+ CalcVClock(dotClock, &VClk, &m, &n, &p, chip); >+ >+ switch (chip->Architecture) >+ { >+ case NV_ARCH_03: >+ nv3UpdateArbitrationSettings(VClk, >+ pixelDepth * 8, >+ &(state->arbitration0), >+ &(state->arbitration1), >+ chip); >+ state->cursor0 = 0x00; >+ state->cursor1 = 0x78; >+ state->cursor2 = 0x00000000; >+ state->pllsel = 0x10010100; >+ state->config = ((width + 31)/32) >+ | (((pixelDepth > 2) ? 3 : pixelDepth) << 8) >+ | 0x1000; >+ state->general = 0x00100100; >+ state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02; >+ break; >+ case NV_ARCH_04: >+ nv4UpdateArbitrationSettings(VClk, >+ pixelDepth * 8, >+ &(state->arbitration0), >+ &(state->arbitration1), >+ chip); >+ state->cursor0 = 0x00; >+ state->cursor1 = 0xFC; >+ state->cursor2 = 0x00000000; >+ state->pllsel = 0x10000700; >+ state->config = 0x00001114; >+ state->general = bpp == 16 ? 0x00101100 : 0x00100100; >+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00; >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ if((chip->Chipset == NV_CHIP_IGEFORCE2) || >+ (chip->Chipset == NV_CHIP_0x01F0)) >+ { >+ nForceUpdateArbitrationSettings(VClk, >+ pixelDepth * 8, >+ &(state->arbitration0), >+ &(state->arbitration1), >+ chip); >+ } else { >+ nv10UpdateArbitrationSettings(VClk, >+ pixelDepth * 8, >+ &(state->arbitration0), >+ &(state->arbitration1), >+ chip); >+ } >+ state->cursor0 = chip->CursorStart; >+ state->pllsel = 0x10000700; >+ state->config = chip->PFB[0x00000200/4]; >+ state->general = bpp == 16 ? 0x00101100 : 0x00100100; >+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00; >+ break; >+ } >+ >+ /* Paul Richards: below if block borks things in kernel for some reason */ >+ /* if((bpp != 8) && (chip->Architecture != NV_ARCH_03)) >+ state->general |= 0x00000030; */ >+ >+ state->vpll = (p << 16) | (n << 8) | m; >+ state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3; >+ state->pixel = pixelDepth > 2 ? 3 : pixelDepth; >+ state->pixel |= 0x80; >+ state->offset0 = >+ state->offset1 = >+ state->offset2 = >+ state->offset3 = 0; >+ state->pitch0 = >+ state->pitch1 = >+ state->pitch2 = >+ state->pitch3 = pixelDepth * width; >+} >+/* >+ * Load fixed function state and pre-calculated/stored state. >+ */ >+#define LOAD_FIXED_STATE(tbl,dev) \ >+ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \ >+ chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1] >+#define LOAD_FIXED_STATE_8BPP(tbl,dev) \ >+ for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \ >+ chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1] >+#define LOAD_FIXED_STATE_15BPP(tbl,dev) \ >+ for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \ >+ chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1] >+#define LOAD_FIXED_STATE_16BPP(tbl,dev) \ >+ for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \ >+ chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1] >+#define LOAD_FIXED_STATE_32BPP(tbl,dev) \ >+ for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \ >+ chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1] >+static void UpdateFifoState >+( >+ RIVA_HW_INST *chip >+) >+{ >+ int i; >+ >+ switch (chip->Architecture) >+ { >+ case NV_ARCH_04: >+ LOAD_FIXED_STATE(nv4,FIFO); >+ chip->Tri03 = 0L; >+ chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ /* >+ * Initialize state for the RivaTriangle3D05 routines. >+ */ >+ LOAD_FIXED_STATE(nv10tri05,PGRAPH); >+ LOAD_FIXED_STATE(nv10,FIFO); >+ chip->Tri03 = 0L; >+ chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ } >+} >+static void LoadStateExt >+( >+ RIVA_HW_INST *chip, >+ RIVA_HW_STATE *state >+) >+{ >+ int i; >+ >+ /* >+ * Load HW fixed function state. >+ */ >+ LOAD_FIXED_STATE(Riva,PMC); >+ LOAD_FIXED_STATE(Riva,PTIMER); >+ switch (chip->Architecture) >+ { >+ case NV_ARCH_03: >+ /* >+ * Make sure frame buffer config gets set before loading PRAMIN. >+ */ >+ chip->PFB[0x00000200/4] = state->config; >+ LOAD_FIXED_STATE(nv3,PFIFO); >+ LOAD_FIXED_STATE(nv3,PRAMIN); >+ LOAD_FIXED_STATE(nv3,PGRAPH); >+ switch (state->bpp) >+ { >+ case 15: >+ case 16: >+ LOAD_FIXED_STATE_15BPP(nv3,PRAMIN); >+ LOAD_FIXED_STATE_15BPP(nv3,PGRAPH); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case 24: >+ case 32: >+ LOAD_FIXED_STATE_32BPP(nv3,PRAMIN); >+ LOAD_FIXED_STATE_32BPP(nv3,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ case 8: >+ default: >+ LOAD_FIXED_STATE_8BPP(nv3,PRAMIN); >+ LOAD_FIXED_STATE_8BPP(nv3,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ } >+ for (i = 0x00000; i < 0x00800; i++) >+ chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03; >+ chip->PGRAPH[0x00000630/4] = state->offset0; >+ chip->PGRAPH[0x00000634/4] = state->offset1; >+ chip->PGRAPH[0x00000638/4] = state->offset2; >+ chip->PGRAPH[0x0000063C/4] = state->offset3; >+ chip->PGRAPH[0x00000650/4] = state->pitch0; >+ chip->PGRAPH[0x00000654/4] = state->pitch1; >+ chip->PGRAPH[0x00000658/4] = state->pitch2; >+ chip->PGRAPH[0x0000065C/4] = state->pitch3; >+ break; >+ case NV_ARCH_04: >+ /* >+ * Make sure frame buffer config gets set before loading PRAMIN. >+ */ >+ chip->PFB[0x00000200/4] = state->config; >+ LOAD_FIXED_STATE(nv4,PFIFO); >+ LOAD_FIXED_STATE(nv4,PRAMIN); >+ LOAD_FIXED_STATE(nv4,PGRAPH); >+ switch (state->bpp) >+ { >+ case 15: >+ LOAD_FIXED_STATE_15BPP(nv4,PRAMIN); >+ LOAD_FIXED_STATE_15BPP(nv4,PGRAPH); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case 16: >+ LOAD_FIXED_STATE_16BPP(nv4,PRAMIN); >+ LOAD_FIXED_STATE_16BPP(nv4,PGRAPH); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case 24: >+ case 32: >+ LOAD_FIXED_STATE_32BPP(nv4,PRAMIN); >+ LOAD_FIXED_STATE_32BPP(nv4,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ case 8: >+ default: >+ LOAD_FIXED_STATE_8BPP(nv4,PRAMIN); >+ LOAD_FIXED_STATE_8BPP(nv4,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ } >+ chip->PGRAPH[0x00000640/4] = state->offset0; >+ chip->PGRAPH[0x00000644/4] = state->offset1; >+ chip->PGRAPH[0x00000648/4] = state->offset2; >+ chip->PGRAPH[0x0000064C/4] = state->offset3; >+ chip->PGRAPH[0x00000670/4] = state->pitch0; >+ chip->PGRAPH[0x00000674/4] = state->pitch1; >+ chip->PGRAPH[0x00000678/4] = state->pitch2; >+ chip->PGRAPH[0x0000067C/4] = state->pitch3; >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ if(chip->twoHeads) { >+ VGA_WR08(chip->PCIO, 0x03D4, 0x44); >+ VGA_WR08(chip->PCIO, 0x03D5, state->crtcOwner); >+ chip->LockUnlock(chip, 0); >+ } >+ >+ LOAD_FIXED_STATE(nv10,PFIFO); >+ LOAD_FIXED_STATE(nv10,PRAMIN); >+ LOAD_FIXED_STATE(nv10,PGRAPH); >+ switch (state->bpp) >+ { >+ case 15: >+ LOAD_FIXED_STATE_15BPP(nv10,PRAMIN); >+ LOAD_FIXED_STATE_15BPP(nv10,PGRAPH); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case 16: >+ LOAD_FIXED_STATE_16BPP(nv10,PRAMIN); >+ LOAD_FIXED_STATE_16BPP(nv10,PGRAPH); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ break; >+ case 24: >+ case 32: >+ LOAD_FIXED_STATE_32BPP(nv10,PRAMIN); >+ LOAD_FIXED_STATE_32BPP(nv10,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ case 8: >+ default: >+ LOAD_FIXED_STATE_8BPP(nv10,PRAMIN); >+ LOAD_FIXED_STATE_8BPP(nv10,PGRAPH); >+ chip->Tri03 = 0L; >+ break; >+ } >+ >+ if(chip->Architecture == NV_ARCH_10) { >+ chip->PGRAPH[0x00000640/4] = state->offset0; >+ chip->PGRAPH[0x00000644/4] = state->offset1; >+ chip->PGRAPH[0x00000648/4] = state->offset2; >+ chip->PGRAPH[0x0000064C/4] = state->offset3; >+ chip->PGRAPH[0x00000670/4] = state->pitch0; >+ chip->PGRAPH[0x00000674/4] = state->pitch1; >+ chip->PGRAPH[0x00000678/4] = state->pitch2; >+ chip->PGRAPH[0x0000067C/4] = state->pitch3; >+ chip->PGRAPH[0x00000680/4] = state->pitch3; >+ } else { >+ chip->PGRAPH[0x00000820/4] = state->offset0; >+ chip->PGRAPH[0x00000824/4] = state->offset1; >+ chip->PGRAPH[0x00000828/4] = state->offset2; >+ chip->PGRAPH[0x0000082C/4] = state->offset3; >+ chip->PGRAPH[0x00000850/4] = state->pitch0; >+ chip->PGRAPH[0x00000854/4] = state->pitch1; >+ chip->PGRAPH[0x00000858/4] = state->pitch2; >+ chip->PGRAPH[0x0000085C/4] = state->pitch3; >+ chip->PGRAPH[0x00000860/4] = state->pitch3; >+ chip->PGRAPH[0x00000864/4] = state->pitch3; >+ chip->PGRAPH[0x000009A4/4] = chip->PFB[0x00000200/4]; >+ chip->PGRAPH[0x000009A8/4] = chip->PFB[0x00000204/4]; >+ } >+ if(chip->twoHeads) { >+ chip->PCRTC0[0x00000860/4] = state->head; >+ chip->PCRTC0[0x00002860/4] = state->head2; >+ } >+ chip->PRAMDAC[0x00000404/4] |= (1 << 25); >+ >+ chip->PMC[0x00008704/4] = 1; >+ chip->PMC[0x00008140/4] = 0; >+ chip->PMC[0x00008920/4] = 0; >+ chip->PMC[0x00008924/4] = 0; >+ chip->PMC[0x00008908/4] = 0x01ffffff; >+ chip->PMC[0x0000890C/4] = 0x01ffffff; >+ chip->PMC[0x00001588/4] = 0; >+ >+ chip->PFB[0x00000240/4] = 0; >+ chip->PFB[0x00000244/4] = 0; >+ chip->PFB[0x00000248/4] = 0; >+ chip->PFB[0x0000024C/4] = 0; >+ chip->PFB[0x00000250/4] = 0; >+ chip->PFB[0x00000254/4] = 0; >+ chip->PFB[0x00000258/4] = 0; >+ chip->PFB[0x0000025C/4] = 0; >+ >+ chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4]; >+ chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4]; >+ chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4]; >+ chip->PGRAPH[0x00000B0C/4] = chip->PFB[0x0000024C/4]; >+ chip->PGRAPH[0x00000B10/4] = chip->PFB[0x00000250/4]; >+ chip->PGRAPH[0x00000B14/4] = chip->PFB[0x00000254/4]; >+ chip->PGRAPH[0x00000B18/4] = chip->PFB[0x00000258/4]; >+ chip->PGRAPH[0x00000B1C/4] = chip->PFB[0x0000025C/4]; >+ chip->PGRAPH[0x00000B20/4] = chip->PFB[0x00000260/4]; >+ chip->PGRAPH[0x00000B24/4] = chip->PFB[0x00000264/4]; >+ chip->PGRAPH[0x00000B28/4] = chip->PFB[0x00000268/4]; >+ chip->PGRAPH[0x00000B2C/4] = chip->PFB[0x0000026C/4]; >+ chip->PGRAPH[0x00000B30/4] = chip->PFB[0x00000270/4]; >+ chip->PGRAPH[0x00000B34/4] = chip->PFB[0x00000274/4]; >+ chip->PGRAPH[0x00000B38/4] = chip->PFB[0x00000278/4]; >+ chip->PGRAPH[0x00000B3C/4] = chip->PFB[0x0000027C/4]; >+ chip->PGRAPH[0x00000B40/4] = chip->PFB[0x00000280/4]; >+ chip->PGRAPH[0x00000B44/4] = chip->PFB[0x00000284/4]; >+ chip->PGRAPH[0x00000B48/4] = chip->PFB[0x00000288/4]; >+ chip->PGRAPH[0x00000B4C/4] = chip->PFB[0x0000028C/4]; >+ chip->PGRAPH[0x00000B50/4] = chip->PFB[0x00000290/4]; >+ chip->PGRAPH[0x00000B54/4] = chip->PFB[0x00000294/4]; >+ chip->PGRAPH[0x00000B58/4] = chip->PFB[0x00000298/4]; >+ chip->PGRAPH[0x00000B5C/4] = chip->PFB[0x0000029C/4]; >+ chip->PGRAPH[0x00000B60/4] = chip->PFB[0x000002A0/4]; >+ chip->PGRAPH[0x00000B64/4] = chip->PFB[0x000002A4/4]; >+ chip->PGRAPH[0x00000B68/4] = chip->PFB[0x000002A8/4]; >+ chip->PGRAPH[0x00000B6C/4] = chip->PFB[0x000002AC/4]; >+ chip->PGRAPH[0x00000B70/4] = chip->PFB[0x000002B0/4]; >+ chip->PGRAPH[0x00000B74/4] = chip->PFB[0x000002B4/4]; >+ chip->PGRAPH[0x00000B78/4] = chip->PFB[0x000002B8/4]; >+ chip->PGRAPH[0x00000B7C/4] = chip->PFB[0x000002BC/4]; >+ chip->PGRAPH[0x00000F40/4] = 0x10000000; >+ chip->PGRAPH[0x00000F44/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00000040; >+ chip->PGRAPH[0x00000F54/4] = 0x00000008; >+ chip->PGRAPH[0x00000F50/4] = 0x00000200; >+ for (i = 0; i < (3*16); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00000040; >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00000800; >+ for (i = 0; i < (16*16); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F40/4] = 0x30000000; >+ chip->PGRAPH[0x00000F44/4] = 0x00000004; >+ chip->PGRAPH[0x00000F50/4] = 0x00006400; >+ for (i = 0; i < (59*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00006800; >+ for (i = 0; i < (47*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00006C00; >+ for (i = 0; i < (3*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00007000; >+ for (i = 0; i < (19*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00007400; >+ for (i = 0; i < (12*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00007800; >+ for (i = 0; i < (12*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00004400; >+ for (i = 0; i < (8*4); i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00000000; >+ for (i = 0; i < 16; i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ chip->PGRAPH[0x00000F50/4] = 0x00000040; >+ for (i = 0; i < 4; i++) >+ chip->PGRAPH[0x00000F54/4] = 0x00000000; >+ >+ chip->PCRTC[0x0000080c/4] = state->cursor0; >+ chip->PCRTC[0x00000810/4] = state->cursorConfig; >+ >+ if(chip->flatPanel) { >+ if((chip->Chipset & 0x0ff0) == 0x0110) { >+ chip->PRAMDAC[0x0528/4] = state->dither; >+ } else >+ if((chip->Chipset & 0x0ff0) >= 0x0170) { >+ chip->PRAMDAC[0x083C/4] = state->dither; >+ } >+ >+ VGA_WR08(chip->PCIO, 0x03D4, 0x53); >+ VGA_WR08(chip->PCIO, 0x03D5, 0); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x54); >+ VGA_WR08(chip->PCIO, 0x03D5, 0); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x21); >+ VGA_WR08(chip->PCIO, 0x03D5, 0xfa); >+ } >+ >+ VGA_WR08(chip->PCIO, 0x03D4, 0x41); >+ VGA_WR08(chip->PCIO, 0x03D5, state->extra); >+ } >+ LOAD_FIXED_STATE(Riva,FIFO); >+ UpdateFifoState(chip); >+ /* >+ * Load HW mode state. >+ */ >+ VGA_WR08(chip->PCIO, 0x03D4, 0x19); >+ VGA_WR08(chip->PCIO, 0x03D5, state->repaint0); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x1A); >+ VGA_WR08(chip->PCIO, 0x03D5, state->repaint1); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x25); >+ VGA_WR08(chip->PCIO, 0x03D5, state->screen); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x28); >+ VGA_WR08(chip->PCIO, 0x03D5, state->pixel); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x2D); >+ VGA_WR08(chip->PCIO, 0x03D5, state->horiz); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x1B); >+ VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x20); >+ VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x30); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x39); >+ VGA_WR08(chip->PCIO, 0x03D5, state->interlace); >+ >+ if(!chip->flatPanel) { >+ chip->PRAMDAC0[0x00000508/4] = state->vpll; >+ chip->PRAMDAC0[0x0000050C/4] = state->pllsel; >+ if(chip->twoHeads) >+ chip->PRAMDAC0[0x00000520/4] = state->vpll2; >+ } else { >+ chip->PRAMDAC[0x00000848/4] = state->scale; >+ } >+ chip->PRAMDAC[0x00000600/4] = state->general; >+ chip->PCRTC[0x00000800/4] = state->fb_start; >+ chip->PRAMDAC[0x00000800/4] = state->vend; >+ chip->PRAMDAC[0x00000804/4] = state->vtotal; >+ chip->PRAMDAC[0x00000808/4] = state->vcrtc; >+ chip->PRAMDAC[0x0000080c/4] = state->vsyncstart; >+ chip->PRAMDAC[0x00000810/4] = state->vsyncend; >+ chip->PRAMDAC[0x00000814/4] = state->vvalidstart; >+ chip->PRAMDAC[0x00000818/4] = state->vvalidend; >+ chip->PRAMDAC[0x00000820/4] = state->hend; >+ chip->PRAMDAC[0x00000824/4] = state->htotal; >+ chip->PRAMDAC[0x00000828/4] = state->hcrtc; >+ chip->PRAMDAC[0x0000082c/4] = state->hsyncstart; >+ chip->PRAMDAC[0x00000830/4] = state->hsyncend; >+ chip->PRAMDAC[0x00000834/4] = state->hvalidstart; >+ chip->PRAMDAC[0x00000838/4] = state->hvalidend; >+ chip->PRAMDAC[0x00000840/4] = state->checksum ; >+ >+ /* >+ * Turn off VBlank enable and reset. >+ */ >+ chip->PCRTC[0x00000140/4] = 0; >+ chip->PCRTC[0x00000100/4] = chip->VBlankBit; >+ /* >+ * Set interrupt enable. >+ */ >+ chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01; >+ /* >+ * Set current state pointer. >+ */ >+ chip->CurrentState = state; >+ /* >+ * Reset FIFO free and empty counts. >+ */ >+ chip->FifoFreeCount = 0; >+ /* Free count from first subchannel */ >+ chip->FifoEmptyCount = chip->Rop->FifoFree; >+} >+static void UnloadStateExt >+( >+ RIVA_HW_INST *chip, >+ RIVA_HW_STATE *state >+) >+{ >+ /* >+ * Save current HW state. >+ */ >+ VGA_WR08(chip->PCIO, 0x03D4, 0x19); >+ state->repaint0 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x1A); >+ state->repaint1 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x25); >+ state->screen = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x28); >+ state->pixel = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x2D); >+ state->horiz = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x1B); >+ state->arbitration0 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x20); >+ state->arbitration1 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x39); >+ state->interlace = VGA_RD08(chip->PCIO, 0x03D5); >+ state->vpll = chip->PRAMDAC0[0x00000508/4]; >+ state->vpll2 = chip->PRAMDAC0[0x00000520/4]; >+ state->pllsel = chip->PRAMDAC0[0x0000050C/4]; >+ state->general = chip->PRAMDAC[0x00000600/4]; >+ state->scale = chip->PRAMDAC[0x00000848/4]; >+ state->config = chip->PFB[0x00000200/4]; >+ switch (chip->Architecture) >+ { >+ case NV_ARCH_03: >+ state->offset0 = chip->PGRAPH[0x00000630/4]; >+ state->offset1 = chip->PGRAPH[0x00000634/4]; >+ state->offset2 = chip->PGRAPH[0x00000638/4]; >+ state->offset3 = chip->PGRAPH[0x0000063C/4]; >+ state->pitch0 = chip->PGRAPH[0x00000650/4]; >+ state->pitch1 = chip->PGRAPH[0x00000654/4]; >+ state->pitch2 = chip->PGRAPH[0x00000658/4]; >+ state->pitch3 = chip->PGRAPH[0x0000065C/4]; >+ VGA_WR08(chip->PCIO, 0x03D4, 0x30); >+ state->cursor0 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x31); >+ state->cursor1 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x2F); >+ state->cursor2 = VGA_RD08(chip->PCIO, 0x03D5); >+ break; >+ case NV_ARCH_04: >+ state->offset0 = chip->PGRAPH[0x00000640/4]; >+ state->offset1 = chip->PGRAPH[0x00000644/4]; >+ state->offset2 = chip->PGRAPH[0x00000648/4]; >+ state->offset3 = chip->PGRAPH[0x0000064C/4]; >+ state->pitch0 = chip->PGRAPH[0x00000670/4]; >+ state->pitch1 = chip->PGRAPH[0x00000674/4]; >+ state->pitch2 = chip->PGRAPH[0x00000678/4]; >+ state->pitch3 = chip->PGRAPH[0x0000067C/4]; >+ VGA_WR08(chip->PCIO, 0x03D4, 0x30); >+ state->cursor0 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x31); >+ state->cursor1 = VGA_RD08(chip->PCIO, 0x03D5); >+ VGA_WR08(chip->PCIO, 0x03D4, 0x2F); >+ state->cursor2 = VGA_RD08(chip->PCIO, 0x03D5); >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ state->offset0 = chip->PGRAPH[0x00000640/4]; >+ state->offset1 = chip->PGRAPH[0x00000644/4]; >+ state->offset2 = chip->PGRAPH[0x00000648/4]; >+ state->offset3 = chip->PGRAPH[0x0000064C/4]; >+ state->pitch0 = chip->PGRAPH[0x00000670/4]; >+ state->pitch1 = chip->PGRAPH[0x00000674/4]; >+ state->pitch2 = chip->PGRAPH[0x00000678/4]; >+ state->pitch3 = chip->PGRAPH[0x0000067C/4]; >+ if(chip->twoHeads) { >+ state->head = chip->PCRTC0[0x00000860/4]; >+ state->head2 = chip->PCRTC0[0x00002860/4]; >+ VGA_WR08(chip->PCIO, 0x03D4, 0x44); >+ state->crtcOwner = VGA_RD08(chip->PCIO, 0x03D5); >+ } >+ VGA_WR08(chip->PCIO, 0x03D4, 0x41); >+ state->extra = VGA_RD08(chip->PCIO, 0x03D5); >+ state->cursorConfig = chip->PCRTC[0x00000810/4]; >+ >+ if((chip->Chipset & 0x0ff0) == 0x0110) { >+ state->dither = chip->PRAMDAC[0x0528/4]; >+ } else >+ if((chip->Chipset & 0x0ff0) >= 0x0170) { >+ state->dither = chip->PRAMDAC[0x083C/4]; >+ } >+ state->fb_start = chip->PCRTC[0x00000800/4]; >+ state->cursor0 = chip->PCRTC[0x0000080c/4]; >+ state->vend = chip->PRAMDAC[0x00000800/4]; >+ state->vtotal = chip->PRAMDAC[0x00000804/4]; >+ state->vcrtc = chip->PRAMDAC[0x00000808/4]; >+ state->vsyncstart = chip->PRAMDAC[0x0000080c/4]; >+ state->vsyncend = chip->PRAMDAC[0x00000810/4]; >+ state->vvalidstart = chip->PRAMDAC[0x00000814/4]; >+ state->vvalidend = chip->PRAMDAC[0x00000818/4]; >+ state->hend = chip->PRAMDAC[0x00000820/4]; >+ state->htotal = chip->PRAMDAC[0x00000824/4]; >+ state->hcrtc = chip->PRAMDAC[0x00000828/4]; >+ state->hsyncstart = chip->PRAMDAC[0x0000082c/4]; >+ state->hsyncend = chip->PRAMDAC[0x00000830/4]; >+ state->hvalidstart = chip->PRAMDAC[0x00000834/4]; >+ state->hvalidend = chip->PRAMDAC[0x00000838/4]; >+ state->checksum = chip->PRAMDAC[0x00000840/4]; >+ break; >+ } >+} >+static void SetStartAddress >+( >+ RIVA_HW_INST *chip, >+ unsigned start >+) >+{ >+ chip->PCRTC[0x800/4] = start; >+} >+ >+static void SetStartAddress3 >+( >+ RIVA_HW_INST *chip, >+ unsigned start >+) >+{ >+ int offset = start >> 2; >+ int pan = (start & 3) << 1; >+ unsigned char tmp; >+ >+ /* >+ * Unlock extended registers. >+ */ >+ chip->LockUnlock(chip, 0); >+ /* >+ * Set start address. >+ */ >+ VGA_WR08(chip->PCIO, 0x3D4, 0x0D); VGA_WR08(chip->PCIO, 0x3D5, offset); >+ offset >>= 8; >+ VGA_WR08(chip->PCIO, 0x3D4, 0x0C); VGA_WR08(chip->PCIO, 0x3D5, offset); >+ offset >>= 8; >+ VGA_WR08(chip->PCIO, 0x3D4, 0x19); tmp = VGA_RD08(chip->PCIO, 0x3D5); >+ VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F)); >+ VGA_WR08(chip->PCIO, 0x3D4, 0x2D); tmp = VGA_RD08(chip->PCIO, 0x3D5); >+ VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60)); >+ /* >+ * 4 pixel pan register. >+ */ >+ offset = VGA_RD08(chip->PCIO, chip->IO + 0x0A); >+ VGA_WR08(chip->PCIO, 0x3C0, 0x13); >+ VGA_WR08(chip->PCIO, 0x3C0, pan); >+} >+static void nv3SetSurfaces2D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); >+ >+ RIVA_FIFO_FREE(*chip,Tri03,5); >+ chip->FIFO[0x00003800] = 0x80000003; >+ Surface->Offset = surf0; >+ chip->FIFO[0x00003800] = 0x80000004; >+ Surface->Offset = surf1; >+ chip->FIFO[0x00003800] = 0x80000013; >+} >+static void nv4SetSurfaces2D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); >+ >+ chip->FIFO[0x00003800] = 0x80000003; >+ Surface->Offset = surf0; >+ chip->FIFO[0x00003800] = 0x80000004; >+ Surface->Offset = surf1; >+ chip->FIFO[0x00003800] = 0x80000014; >+} >+static void nv10SetSurfaces2D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); >+ >+ chip->FIFO[0x00003800] = 0x80000003; >+ Surface->Offset = surf0; >+ chip->FIFO[0x00003800] = 0x80000004; >+ Surface->Offset = surf1; >+ chip->FIFO[0x00003800] = 0x80000014; >+} >+static void nv3SetSurfaces3D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); >+ >+ RIVA_FIFO_FREE(*chip,Tri03,5); >+ chip->FIFO[0x00003800] = 0x80000005; >+ Surface->Offset = surf0; >+ chip->FIFO[0x00003800] = 0x80000006; >+ Surface->Offset = surf1; >+ chip->FIFO[0x00003800] = 0x80000013; >+} >+static void nv4SetSurfaces3D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); >+ >+ chip->FIFO[0x00003800] = 0x80000005; >+ Surface->Offset = surf0; >+ chip->FIFO[0x00003800] = 0x80000006; >+ Surface->Offset = surf1; >+ chip->FIFO[0x00003800] = 0x80000014; >+} >+static void nv10SetSurfaces3D >+( >+ RIVA_HW_INST *chip, >+ unsigned surf0, >+ unsigned surf1 >+) >+{ >+ RivaSurface3D *Surfaces3D = (RivaSurface3D *)&(chip->FIFO[0x0000E000/4]); >+ >+ RIVA_FIFO_FREE(*chip,Tri03,4); >+ chip->FIFO[0x00003800] = 0x80000007; >+ Surfaces3D->RenderBufferOffset = surf0; >+ Surfaces3D->ZBufferOffset = surf1; >+ chip->FIFO[0x00003800] = 0x80000014; >+} >+ >+/****************************************************************************\ >+* * >+* Probe RIVA Chip Configuration * >+* * >+\****************************************************************************/ >+ >+static void nv3GetConfig >+( >+ RIVA_HW_INST *chip >+) >+{ >+ /* >+ * Fill in chip configuration. >+ */ >+ if (chip->PFB[0x00000000/4] & 0x00000020) >+ { >+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20) >+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) >+ { >+ /* >+ * SDRAM 128 ZX. >+ */ >+ chip->RamBandwidthKBytesPerSec = 800000; >+ switch (chip->PFB[0x00000000/4] & 0x03) >+ { >+ case 2: >+ chip->RamAmountKBytes = 1024 * 4; >+ break; >+ case 1: >+ chip->RamAmountKBytes = 1024 * 2; >+ break; >+ default: >+ chip->RamAmountKBytes = 1024 * 8; >+ break; >+ } >+ } >+ else >+ { >+ chip->RamBandwidthKBytesPerSec = 1000000; >+ chip->RamAmountKBytes = 1024 * 8; >+ } >+ } >+ else >+ { >+ /* >+ * SGRAM 128. >+ */ >+ chip->RamBandwidthKBytesPerSec = 1000000; >+ switch (chip->PFB[0x00000000/4] & 0x00000003) >+ { >+ case 0: >+ chip->RamAmountKBytes = 1024 * 8; >+ break; >+ case 2: >+ chip->RamAmountKBytes = 1024 * 4; >+ break; >+ default: >+ chip->RamAmountKBytes = 1024 * 2; >+ break; >+ } >+ } >+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500; >+ chip->CURSOR = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]); >+ chip->VBlankBit = 0x00000100; >+ chip->MaxVClockFreqKHz = 256000; >+ /* >+ * Set chip functions. >+ */ >+ chip->Busy = nv3Busy; >+ chip->ShowHideCursor = ShowHideCursor; >+ chip->CalcStateExt = CalcStateExt; >+ chip->LoadStateExt = LoadStateExt; >+ chip->UnloadStateExt = UnloadStateExt; >+ chip->SetStartAddress = SetStartAddress3; >+ chip->SetSurfaces2D = nv3SetSurfaces2D; >+ chip->SetSurfaces3D = nv3SetSurfaces3D; >+ chip->LockUnlock = nv3LockUnlock; >+} >+static void nv4GetConfig >+( >+ RIVA_HW_INST *chip >+) >+{ >+ /* >+ * Fill in chip configuration. >+ */ >+ if (chip->PFB[0x00000000/4] & 0x00000100) >+ { >+ chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2 >+ + 1024 * 2; >+ } >+ else >+ { >+ switch (chip->PFB[0x00000000/4] & 0x00000003) >+ { >+ case 0: >+ chip->RamAmountKBytes = 1024 * 32; >+ break; >+ case 1: >+ chip->RamAmountKBytes = 1024 * 4; >+ break; >+ case 2: >+ chip->RamAmountKBytes = 1024 * 8; >+ break; >+ case 3: >+ default: >+ chip->RamAmountKBytes = 1024 * 16; >+ break; >+ } >+ } >+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) >+ { >+ case 3: >+ chip->RamBandwidthKBytesPerSec = 800000; >+ break; >+ default: >+ chip->RamBandwidthKBytesPerSec = 1000000; >+ break; >+ } >+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500; >+ chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]); >+ chip->VBlankBit = 0x00000001; >+ chip->MaxVClockFreqKHz = 350000; >+ /* >+ * Set chip functions. >+ */ >+ chip->Busy = nv4Busy; >+ chip->ShowHideCursor = ShowHideCursor; >+ chip->CalcStateExt = CalcStateExt; >+ chip->LoadStateExt = LoadStateExt; >+ chip->UnloadStateExt = UnloadStateExt; >+ chip->SetStartAddress = SetStartAddress; >+ chip->SetSurfaces2D = nv4SetSurfaces2D; >+ chip->SetSurfaces3D = nv4SetSurfaces3D; >+ chip->LockUnlock = nv4LockUnlock; >+} >+static void nv10GetConfig >+( >+ RIVA_HW_INST *chip, >+ unsigned int chipset >+) >+{ >+ struct pci_dev* dev; >+ int amt; >+ >+#ifdef __BIG_ENDIAN >+ /* turn on big endian register access */ >+ chip->PMC[0x00000004/4] = 0x01000001; >+#endif >+ >+ /* >+ * Fill in chip configuration. >+ */ >+ if(chipset == NV_CHIP_IGEFORCE2) { >+ dev = pci_find_slot(0, 1); >+ pci_read_config_dword(dev, 0x7C, &amt); >+ chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; >+ } else if(chipset == NV_CHIP_0x01F0) { >+ dev = pci_find_slot(0, 1); >+ pci_read_config_dword(dev, 0x84, &amt); >+ chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; >+ } else { >+ switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF) >+ { >+ case 0x02: >+ chip->RamAmountKBytes = 1024 * 2; >+ break; >+ case 0x04: >+ chip->RamAmountKBytes = 1024 * 4; >+ break; >+ case 0x08: >+ chip->RamAmountKBytes = 1024 * 8; >+ break; >+ case 0x10: >+ chip->RamAmountKBytes = 1024 * 16; >+ break; >+ case 0x20: >+ chip->RamAmountKBytes = 1024 * 32; >+ break; >+ case 0x40: >+ chip->RamAmountKBytes = 1024 * 64; >+ break; >+ case 0x80: >+ chip->RamAmountKBytes = 1024 * 128; >+ break; >+ default: >+ chip->RamAmountKBytes = 1024 * 16; >+ break; >+ } >+ } >+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) >+ { >+ case 3: >+ chip->RamBandwidthKBytesPerSec = 800000; >+ break; >+ default: >+ chip->RamBandwidthKBytesPerSec = 1000000; >+ break; >+ } >+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 : >+ 13500; >+ >+ switch (chipset & 0x0ff0) { >+ case 0x0170: >+ case 0x0180: >+ case 0x01F0: >+ case 0x0250: >+ case 0x0280: >+ if(chip->PEXTDEV[0x0000/4] & (1 << 22)) >+ chip->CrystalFreqKHz = 27000; >+ break; >+ default: >+ break; >+ } >+ >+ chip->CursorStart = (chip->RamAmountKBytes - 2) * 1024; >+ chip->CURSOR = NULL; /* can't set this here */ >+ chip->VBlankBit = 0x00000001; >+ chip->MaxVClockFreqKHz = 350000; >+ /* >+ * Set chip functions. >+ */ >+ chip->Busy = nv10Busy; >+ chip->ShowHideCursor = nv10ShowHideCursor; >+ chip->CalcStateExt = CalcStateExt; >+ chip->LoadStateExt = LoadStateExt; >+ chip->UnloadStateExt = UnloadStateExt; >+ chip->SetStartAddress = SetStartAddress; >+ chip->SetSurfaces2D = nv10SetSurfaces2D; >+ chip->SetSurfaces3D = nv10SetSurfaces3D; >+ chip->LockUnlock = nv4LockUnlock; >+ >+ switch(chipset & 0x0ff0) { >+ case 0x0110: >+ case 0x0170: >+ case 0x0180: >+ case 0x01F0: >+ case 0x0250: >+ case 0x0280: >+ chip->twoHeads = TRUE; >+ break; >+ default: >+ chip->twoHeads = FALSE; >+ break; >+ } >+} >+int RivaGetConfig >+( >+ RIVA_HW_INST *chip, >+ unsigned int chipset >+) >+{ >+ /* >+ * Save this so future SW know whats it's dealing with. >+ */ >+ chip->Version = RIVA_SW_VERSION; >+ /* >+ * Chip specific configuration. >+ */ >+ switch (chip->Architecture) >+ { >+ case NV_ARCH_03: >+ nv3GetConfig(chip); >+ break; >+ case NV_ARCH_04: >+ nv4GetConfig(chip); >+ break; >+ case NV_ARCH_10: >+ case NV_ARCH_20: >+ nv10GetConfig(chip, chipset); >+ break; >+ default: >+ return (-1); >+ } >+ chip->Chipset = chipset; >+ /* >+ * Fill in FIFO pointers. >+ */ >+ chip->Rop = (RivaRop *)&(chip->FIFO[0x00000000/4]); >+ chip->Clip = (RivaClip *)&(chip->FIFO[0x00002000/4]); >+ chip->Patt = (RivaPattern *)&(chip->FIFO[0x00004000/4]); >+ chip->Pixmap = (RivaPixmap *)&(chip->FIFO[0x00006000/4]); >+ chip->Blt = (RivaScreenBlt *)&(chip->FIFO[0x00008000/4]); >+ chip->Bitmap = (RivaBitmap *)&(chip->FIFO[0x0000A000/4]); >+ chip->Line = (RivaLine *)&(chip->FIFO[0x0000C000/4]); >+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); >+ return (0); >+} >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/riva_hw.h linux-2.6.6/drivers/video/xbox/riva_hw.h >--- linux-2.6.6.orig/drivers/video/xbox/riva_hw.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/riva_hw.h 2004-05-10 12:30:23.257935424 +0100 >@@ -0,0 +1,566 @@ >+/***************************************************************************\ >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NOTICE TO USER: The source code is copyrighted under U.S. and *| >+|* international laws. Users and possessors of this source code are *| >+|* hereby granted a nonexclusive, royalty-free copyright license to *| >+|* use this code in individual and commercial software. *| >+|* *| >+|* Any use of this source code must include, in the user documenta- *| >+|* tion and internal comments to the code, notices to the end user *| >+|* as follows: *| >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| >+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| >+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| >+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| >+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| >+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| >+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| >+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| >+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| >+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| >+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| >+|* *| >+|* U.S. Government End Users. This source code is a "commercial *| >+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| >+|* consisting of "commercial computer software" and "commercial *| >+|* computer software documentation," as such terms are used in *| >+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| >+|* ment only as a commercial end item. Consistent with 48 C.F.R. *| >+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| >+|* all U.S. Government End Users acquire the source code with only *| >+|* those rights set forth herein. *| >+|* *| >+\***************************************************************************/ >+ >+/* >+ * GPL licensing note -- nVidia is allowing a liberal interpretation of >+ * the documentation restriction above, to merely say that this nVidia's >+ * copyright and disclaimer should be included with all code derived >+ * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 >+ */ >+ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.21 2002/10/14 18:22:46 mvojkovi Exp $ */ >+#ifndef __RIVA_HW_H__ >+#define __RIVA_HW_H__ >+#define RIVA_SW_VERSION 0x00010003 >+ >+#ifndef Bool >+typedef int Bool; >+#endif >+ >+#ifndef TRUE >+#define TRUE 1 >+#endif >+#ifndef FALSE >+#define FALSE 0 >+#endif >+#ifndef NULL >+#define NULL 0 >+#endif >+ >+/* >+ * Typedefs to force certain sized values. >+ */ >+typedef unsigned char U008; >+typedef unsigned short U016; >+typedef unsigned int U032; >+ >+/* >+ * HW access macros. >+ */ >+#if defined(__powerpc__) >+#include <asm/io.h> >+#define NV_WR08(p,i,d) out_8(p+i, d) >+#define NV_RD08(p,i) in_8(p+i) >+#else >+#define NV_WR08(p,i,d) (((U008 *)(p))[i]=(d)) >+#define NV_RD08(p,i) (((U008 *)(p))[i]) >+#endif >+#define NV_WR16(p,i,d) (((U016 *)(p))[(i)/2]=(d)) >+#define NV_RD16(p,i) (((U016 *)(p))[(i)/2]) >+#define NV_WR32(p,i,d) (((U032 *)(p))[(i)/4]=(d)) >+#define NV_RD32(p,i) (((U032 *)(p))[(i)/4]) >+#define VGA_WR08(p,i,d) NV_WR08(p,i,d) >+#define VGA_RD08(p,i) NV_RD08(p,i) >+ >+/* >+ * Define supported architectures. >+ */ >+#define NV_ARCH_03 0x03 >+#define NV_ARCH_04 0x04 >+#define NV_ARCH_10 0x10 >+#define NV_ARCH_20 0x20 >+ >+/***************************************************************************\ >+* * >+* FIFO registers. * >+* * >+\***************************************************************************/ >+ >+/* >+ * Raster OPeration. Windows style ROP3. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BB]; >+ U032 Rop3; >+} RivaRop; >+/* >+ * 8X8 Monochrome pattern. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BD]; >+ U032 Shape; >+ U032 reserved03[0x001]; >+ U032 Color0; >+ U032 Color1; >+ U032 Monochrome[2]; >+} RivaPattern; >+/* >+ * Scissor clip rectangle. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BB]; >+ U032 TopLeft; >+ U032 WidthHeight; >+} RivaClip; >+/* >+ * 2D filled rectangle. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop[1]; >+#endif >+ U032 reserved01[0x0BC]; >+ U032 Color; >+ U032 reserved03[0x03E]; >+ U032 TopLeft; >+ U032 WidthHeight; >+} RivaRectangle; >+/* >+ * 2D screen-screen BLT. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BB]; >+ U032 TopLeftSrc; >+ U032 TopLeftDst; >+ U032 WidthHeight; >+} RivaScreenBlt; >+/* >+ * 2D pixel BLT. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop[1]; >+#endif >+ U032 reserved01[0x0BC]; >+ U032 TopLeft; >+ U032 WidthHeight; >+ U032 WidthHeightIn; >+ U032 reserved02[0x03C]; >+ U032 Pixels; >+} RivaPixmap; >+/* >+ * Filled rectangle combined with monochrome expand. Useful for glyphs. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BB]; >+ U032 reserved03[(0x040)-1]; >+ U032 Color1A; >+ struct >+ { >+ U032 TopLeft; >+ U032 WidthHeight; >+ } UnclippedRectangle[64]; >+ U032 reserved04[(0x080)-3]; >+ struct >+ { >+ U032 TopLeft; >+ U032 BottomRight; >+ } ClipB; >+ U032 Color1B; >+ struct >+ { >+ U032 TopLeft; >+ U032 BottomRight; >+ } ClippedRectangle[64]; >+ U032 reserved05[(0x080)-5]; >+ struct >+ { >+ U032 TopLeft; >+ U032 BottomRight; >+ } ClipC; >+ U032 Color1C; >+ U032 WidthHeightC; >+ U032 PointC; >+ U032 MonochromeData1C; >+ U032 reserved06[(0x080)+121]; >+ struct >+ { >+ U032 TopLeft; >+ U032 BottomRight; >+ } ClipD; >+ U032 Color1D; >+ U032 WidthHeightInD; >+ U032 WidthHeightOutD; >+ U032 PointD; >+ U032 MonochromeData1D; >+ U032 reserved07[(0x080)+120]; >+ struct >+ { >+ U032 TopLeft; >+ U032 BottomRight; >+ } ClipE; >+ U032 Color0E; >+ U032 Color1E; >+ U032 WidthHeightInE; >+ U032 WidthHeightOutE; >+ U032 PointE; >+ U032 MonochromeData01E; >+} RivaBitmap; >+/* >+ * 3D textured, Z buffered triangle. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BC]; >+ U032 TextureOffset; >+ U032 TextureFormat; >+ U032 TextureFilter; >+ U032 FogColor; >+/* This is a problem on LynxOS */ >+#ifdef Control >+#undef Control >+#endif >+ U032 Control; >+ U032 AlphaTest; >+ U032 reserved02[0x339]; >+ U032 FogAndIndex; >+ U032 Color; >+ float ScreenX; >+ float ScreenY; >+ float ScreenZ; >+ float EyeM; >+ float TextureS; >+ float TextureT; >+} RivaTexturedTriangle03; >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BB]; >+ U032 ColorKey; >+ U032 TextureOffset; >+ U032 TextureFormat; >+ U032 TextureFilter; >+ U032 Blend; >+/* This is a problem on LynxOS */ >+#ifdef Control >+#undef Control >+#endif >+ U032 Control; >+ U032 FogColor; >+ U032 reserved02[0x39]; >+ struct >+ { >+ float ScreenX; >+ float ScreenY; >+ float ScreenZ; >+ float EyeM; >+ U032 Color; >+ U032 Specular; >+ float TextureS; >+ float TextureT; >+ } Vertex[16]; >+ U032 DrawTriangle3D; >+} RivaTexturedTriangle05; >+/* >+ * 2D line. >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop[1]; >+#endif >+ U032 reserved01[0x0BC]; >+ U032 Color; /* source color 0304-0307*/ >+ U032 Reserved02[0x03e]; >+ struct { /* start aliased methods in array 0400- */ >+ U032 point0; /* y_x S16_S16 in pixels 0- 3*/ >+ U032 point1; /* y_x S16_S16 in pixels 4- 7*/ >+ } Lin[16]; /* end of aliased methods in array -047f*/ >+ struct { /* start aliased methods in array 0480- */ >+ U032 point0X; /* in pixels, 0 at left 0- 3*/ >+ U032 point0Y; /* in pixels, 0 at top 4- 7*/ >+ U032 point1X; /* in pixels, 0 at left 8- b*/ >+ U032 point1Y; /* in pixels, 0 at top c- f*/ >+ } Lin32[8]; /* end of aliased methods in array -04ff*/ >+ U032 PolyLin[32]; /* y_x S16_S16 in pixels 0500-057f*/ >+ struct { /* start aliased methods in array 0580- */ >+ U032 x; /* in pixels, 0 at left 0- 3*/ >+ U032 y; /* in pixels, 0 at top 4- 7*/ >+ } PolyLin32[16]; /* end of aliased methods in array -05ff*/ >+ struct { /* start aliased methods in array 0600- */ >+ U032 color; /* source color 0- 3*/ >+ U032 point; /* y_x S16_S16 in pixels 4- 7*/ >+ } ColorPolyLin[16]; /* end of aliased methods in array -067f*/ >+} RivaLine; >+/* >+ * 2D/3D surfaces >+ */ >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BE]; >+ U032 Offset; >+} RivaSurface; >+typedef volatile struct >+{ >+ U032 reserved00[4]; >+#ifdef __BIG_ENDIAN >+ U032 FifoFree; >+#else >+ U016 FifoFree; >+ U016 Nop; >+#endif >+ U032 reserved01[0x0BD]; >+ U032 Pitch; >+ U032 RenderBufferOffset; >+ U032 ZBufferOffset; >+} RivaSurface3D; >+ >+/***************************************************************************\ >+* * >+* Virtualized RIVA H/W interface. * >+* * >+\***************************************************************************/ >+ >+#define FP_ENABLE 1 >+#define FP_DITHER 2 >+ >+struct _riva_hw_inst; >+struct _riva_hw_state; >+/* >+ * Virtialized chip interface. Makes RIVA 128 and TNT look alike. >+ */ >+typedef struct _riva_hw_inst >+{ >+ /* >+ * Chip specific settings. >+ */ >+ U032 Architecture; >+ U032 Version; >+ U032 Chipset; >+ U032 CrystalFreqKHz; >+ U032 RamAmountKBytes; >+ U032 MaxVClockFreqKHz; >+ U032 RamBandwidthKBytesPerSec; >+ U032 EnableIRQ; >+ U032 IO; >+ U032 VBlankBit; >+ U032 FifoFreeCount; >+ U032 FifoEmptyCount; >+ U032 CursorStart; >+ U032 flatPanel; >+ Bool twoHeads; >+ /* >+ * Non-FIFO registers. >+ */ >+ volatile U032 *PCRTC0; >+ volatile U032 *PCRTC; >+ volatile U032 *PRAMDAC0; >+ volatile U032 *PFB; >+ volatile U032 *PFIFO; >+ volatile U032 *PGRAPH; >+ volatile U032 *PEXTDEV; >+ volatile U032 *PTIMER; >+ volatile U032 *PMC; >+ volatile U032 *PRAMIN; >+ volatile U032 *FIFO; >+ volatile U032 *CURSOR; >+ volatile U008 *PCIO0; >+ volatile U008 *PCIO; >+ volatile U008 *PVIO; >+ volatile U008 *PDIO0; >+ volatile U008 *PDIO; >+ volatile U032 *PRAMDAC; >+ /* >+ * Common chip functions. >+ */ >+ int (*Busy)(struct _riva_hw_inst *); >+ void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int); >+ void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *); >+ void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *); >+ void (*SetStartAddress)(struct _riva_hw_inst *,U032); >+ void (*SetSurfaces2D)(struct _riva_hw_inst *,U032,U032); >+ void (*SetSurfaces3D)(struct _riva_hw_inst *,U032,U032); >+ int (*ShowHideCursor)(struct _riva_hw_inst *,int); >+ void (*LockUnlock)(struct _riva_hw_inst *, int); >+ /* >+ * Current extended mode settings. >+ */ >+ struct _riva_hw_state *CurrentState; >+ /* >+ * FIFO registers. >+ */ >+ RivaRop *Rop; >+ RivaPattern *Patt; >+ RivaClip *Clip; >+ RivaPixmap *Pixmap; >+ RivaScreenBlt *Blt; >+ RivaBitmap *Bitmap; >+ RivaLine *Line; >+ RivaTexturedTriangle03 *Tri03; >+ RivaTexturedTriangle05 *Tri05; >+} RIVA_HW_INST; >+/* >+ * Extended mode state information. >+ */ >+typedef struct _riva_hw_state >+{ >+ U032 bpp; >+ U032 width; >+ U032 height; >+ U032 interlace; >+ U032 repaint0; >+ U032 repaint1; >+ U032 screen; >+ U032 scale; >+ U032 dither; >+ U032 extra; >+ U032 pixel; >+ U032 horiz; >+ U032 arbitration0; >+ U032 arbitration1; >+ U032 vpll; >+ U032 vpll2; >+ U032 pllsel; >+ U032 general; >+ U032 crtcOwner; >+ U032 head; >+ U032 head2; >+ U032 config; >+ U032 cursorConfig; >+ U032 cursor0; >+ U032 cursor1; >+ U032 cursor2; >+ U032 offset0; >+ U032 offset1; >+ U032 offset2; >+ U032 offset3; >+ U032 pitch0; >+ U032 pitch1; >+ U032 pitch2; >+ U032 pitch3; >+ U032 fb_start; >+ U032 vend; >+ U032 vtotal; >+ U032 vcrtc; >+ U032 vsyncstart; >+ U032 vsyncend; >+ U032 vvalidstart; >+ U032 vvalidend; >+ U032 hend; >+ U032 htotal; >+ U032 hcrtc; >+ U032 hsyncstart; >+ U032 hsyncend; >+ U032 hvalidstart; >+ U032 hvalidend; >+ U032 crtchdispend; >+ U032 crtcvstart; >+ U032 crtcvtotal; >+ U032 checksum; >+} RIVA_HW_STATE; >+/* >+ * External routines. >+ */ >+int RivaGetConfig(RIVA_HW_INST *, unsigned int); >+/* >+ * FIFO Free Count. Should attempt to yield processor if RIVA is busy. >+ */ >+ >+#define RIVA_FIFO_FREE(hwinst,hwptr,cnt) \ >+{ \ >+ while ((hwinst).FifoFreeCount < (cnt)) \ >+ (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \ >+ (hwinst).FifoFreeCount -= (cnt); \ >+} >+#endif /* __RIVA_HW_H__ */ >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/riva_tbl.h linux-2.6.6/drivers/video/xbox/riva_tbl.h >--- linux-2.6.6.orig/drivers/video/xbox/riva_tbl.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/riva_tbl.h 2004-05-10 12:30:23.268933752 +0100 >@@ -0,0 +1,1008 @@ >+ /***************************************************************************\ >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NOTICE TO USER: The source code is copyrighted under U.S. and *| >+|* international laws. Users and possessors of this source code are *| >+|* hereby granted a nonexclusive, royalty-free copyright license to *| >+|* use this code in individual and commercial software. *| >+|* *| >+|* Any use of this source code must include, in the user documenta- *| >+|* tion and internal comments to the code, notices to the end user *| >+|* as follows: *| >+|* *| >+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| >+|* *| >+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| >+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| >+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| >+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| >+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| >+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| >+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| >+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| >+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| >+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| >+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| >+|* *| >+|* U.S. Government End Users. This source code is a "commercial *| >+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| >+|* consisting of "commercial computer software" and "commercial *| >+|* computer software documentation," as such terms are used in *| >+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| >+|* ment only as a commercial end item. Consistent with 48 C.F.R. *| >+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| >+|* all U.S. Government End Users acquire the source code with only *| >+|* those rights set forth herein. *| >+|* *| >+ \***************************************************************************/ >+ >+/* >+ * GPL licensing note -- nVidia is allowing a liberal interpretation of >+ * the documentation restriction above, to merely say that this nVidia's >+ * copyright and disclaimer should be included with all code derived >+ * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 >+ */ >+ >+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h,v 1.9 2002/01/30 01:35:03 mvojkovi Exp $ */ >+ >+ >+/* >+ * RIVA Fixed Functionality Init Tables. >+ */ >+static unsigned RivaTablePMC[][2] = >+{ >+ {0x00000050, 0x00000000}, >+ {0x00000080, 0xFFFF00FF}, >+ {0x00000080, 0xFFFFFFFF} >+}; >+static unsigned RivaTablePTIMER[][2] = >+{ >+ {0x00000080, 0x00000008}, >+ {0x00000084, 0x00000003}, >+ {0x00000050, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF} >+}; >+static unsigned RivaTableFIFO[][2] = >+{ >+ {0x00000000, 0x80000000}, >+ {0x00000800, 0x80000001}, >+ {0x00001000, 0x80000002}, >+ {0x00001800, 0x80000010}, >+ {0x00002000, 0x80000011}, >+ {0x00002800, 0x80000012}, >+ {0x00003000, 0x80000016}, >+ {0x00003800, 0x80000013} >+}; >+static unsigned nv3TablePFIFO[][2] = >+{ >+ {0x00000140, 0x00000000}, >+ {0x00000480, 0x00000000}, >+ {0x00000490, 0x00000000}, >+ {0x00000494, 0x00000000}, >+ {0x00000481, 0x00000000}, >+ {0x00000084, 0x00000000}, >+ {0x00000086, 0x00002000}, >+ {0x00000085, 0x00002200}, >+ {0x00000484, 0x00000000}, >+ {0x0000049C, 0x00000000}, >+ {0x00000104, 0x00000000}, >+ {0x00000108, 0x00000000}, >+ {0x00000100, 0x00000000}, >+ {0x000004A0, 0x00000000}, >+ {0x000004A4, 0x00000000}, >+ {0x000004A8, 0x00000000}, >+ {0x000004AC, 0x00000000}, >+ {0x000004B0, 0x00000000}, >+ {0x000004B4, 0x00000000}, >+ {0x000004B8, 0x00000000}, >+ {0x000004BC, 0x00000000}, >+ {0x00000050, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x00000480, 0x00000001}, >+ {0x00000490, 0x00000001}, >+ {0x00000140, 0x00000001} >+}; >+static unsigned nv3TablePGRAPH[][2] = >+{ >+ {0x00000020, 0x1230001F}, >+ {0x00000021, 0x10113000}, >+ {0x00000022, 0x1131F101}, >+ {0x00000023, 0x0100F531}, >+ {0x00000060, 0x00000000}, >+ {0x00000065, 0x00000000}, >+ {0x00000068, 0x00000000}, >+ {0x00000069, 0x00000000}, >+ {0x0000006A, 0x00000000}, >+ {0x0000006B, 0x00000000}, >+ {0x0000006C, 0x00000000}, >+ {0x0000006D, 0x00000000}, >+ {0x0000006E, 0x00000000}, >+ {0x0000006F, 0x00000000}, >+ {0x000001A8, 0x00000000}, >+ {0x00000440, 0xFFFFFFFF}, >+ {0x00000480, 0x00000001}, >+ {0x000001A0, 0x00000000}, >+ {0x000001A2, 0x00000000}, >+ {0x0000018A, 0xFFFFFFFF}, >+ {0x00000190, 0x00000000}, >+ {0x00000142, 0x00000000}, >+ {0x00000154, 0x00000000}, >+ {0x00000155, 0xFFFFFFFF}, >+ {0x00000156, 0x00000000}, >+ {0x00000157, 0xFFFFFFFF}, >+ {0x00000064, 0x10010002}, >+ {0x00000050, 0x00000000}, >+ {0x00000051, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x00000041, 0xFFFFFFFF}, >+ {0x00000440, 0xFFFFFFFF}, >+ {0x000001A9, 0x00000001} >+}; >+static unsigned nv3TablePGRAPH_8BPP[][2] = >+{ >+ {0x000001AA, 0x00001111} >+}; >+static unsigned nv3TablePGRAPH_15BPP[][2] = >+{ >+ {0x000001AA, 0x00002222} >+}; >+static unsigned nv3TablePGRAPH_32BPP[][2] = >+{ >+ {0x000001AA, 0x00003333} >+}; >+static unsigned nv3TablePRAMIN[][2] = >+{ >+ {0x00000500, 0x00010000}, >+ {0x00000501, 0x007FFFFF}, >+ {0x00000200, 0x80000000}, >+ {0x00000201, 0x00C20341}, >+ {0x00000204, 0x80000001}, >+ {0x00000205, 0x00C50342}, >+ {0x00000208, 0x80000002}, >+ {0x00000209, 0x00C60343}, >+ {0x0000020C, 0x80000003}, >+ {0x0000020D, 0x00DC0348}, >+ {0x00000210, 0x80000004}, >+ {0x00000211, 0x00DC0349}, >+ {0x00000214, 0x80000005}, >+ {0x00000215, 0x00DC034A}, >+ {0x00000218, 0x80000006}, >+ {0x00000219, 0x00DC034B}, >+ {0x00000240, 0x80000010}, >+ {0x00000241, 0x00D10344}, >+ {0x00000244, 0x80000011}, >+ {0x00000245, 0x00D00345}, >+ {0x00000248, 0x80000012}, >+ {0x00000249, 0x00CC0346}, >+ {0x0000024C, 0x80000013}, >+ {0x0000024D, 0x00D70347}, >+ {0x00000258, 0x80000016}, >+ {0x00000259, 0x00CA034C}, >+ {0x00000D05, 0x00000000}, >+ {0x00000D06, 0x00000000}, >+ {0x00000D07, 0x00000000}, >+ {0x00000D09, 0x00000000}, >+ {0x00000D0A, 0x00000000}, >+ {0x00000D0B, 0x00000000}, >+ {0x00000D0D, 0x00000000}, >+ {0x00000D0E, 0x00000000}, >+ {0x00000D0F, 0x00000000}, >+ {0x00000D11, 0x00000000}, >+ {0x00000D12, 0x00000000}, >+ {0x00000D13, 0x00000000}, >+ {0x00000D15, 0x00000000}, >+ {0x00000D16, 0x00000000}, >+ {0x00000D17, 0x00000000}, >+ {0x00000D19, 0x00000000}, >+ {0x00000D1A, 0x00000000}, >+ {0x00000D1B, 0x00000000}, >+ {0x00000D1D, 0x00000140}, >+ {0x00000D1E, 0x00000000}, >+ {0x00000D1F, 0x00000000}, >+ {0x00000D20, 0x10100200}, >+ {0x00000D21, 0x00000000}, >+ {0x00000D22, 0x00000000}, >+ {0x00000D23, 0x00000000}, >+ {0x00000D24, 0x10210200}, >+ {0x00000D25, 0x00000000}, >+ {0x00000D26, 0x00000000}, >+ {0x00000D27, 0x00000000}, >+ {0x00000D28, 0x10420200}, >+ {0x00000D29, 0x00000000}, >+ {0x00000D2A, 0x00000000}, >+ {0x00000D2B, 0x00000000}, >+ {0x00000D2C, 0x10830200}, >+ {0x00000D2D, 0x00000000}, >+ {0x00000D2E, 0x00000000}, >+ {0x00000D2F, 0x00000000}, >+ {0x00000D31, 0x00000000}, >+ {0x00000D32, 0x00000000}, >+ {0x00000D33, 0x00000000} >+}; >+static unsigned nv3TablePRAMIN_8BPP[][2] = >+{ >+ /* 0xXXXXX3XX For MSB mono format */ >+ /* 0xXXXXX2XX For LSB mono format */ >+ {0x00000D04, 0x10110203}, >+ {0x00000D08, 0x10110203}, >+ {0x00000D0C, 0x1011020B}, >+ {0x00000D10, 0x10118203}, >+ {0x00000D14, 0x10110203}, >+ {0x00000D18, 0x10110203}, >+ {0x00000D1C, 0x10419208}, >+ {0x00000D30, 0x10118203} >+}; >+static unsigned nv3TablePRAMIN_15BPP[][2] = >+{ >+ /* 0xXXXXX2XX For MSB mono format */ >+ /* 0xXXXXX3XX For LSB mono format */ >+ {0x00000D04, 0x10110200}, >+ {0x00000D08, 0x10110200}, >+ {0x00000D0C, 0x10110208}, >+ {0x00000D10, 0x10118200}, >+ {0x00000D14, 0x10110200}, >+ {0x00000D18, 0x10110200}, >+ {0x00000D1C, 0x10419208}, >+ {0x00000D30, 0x10118200} >+}; >+static unsigned nv3TablePRAMIN_32BPP[][2] = >+{ >+ /* 0xXXXXX3XX For MSB mono format */ >+ /* 0xXXXXX2XX For LSB mono format */ >+ {0x00000D04, 0x10110201}, >+ {0x00000D08, 0x10110201}, >+ {0x00000D0C, 0x10110209}, >+ {0x00000D10, 0x10118201}, >+ {0x00000D14, 0x10110201}, >+ {0x00000D18, 0x10110201}, >+ {0x00000D1C, 0x10419208}, >+ {0x00000D30, 0x10118201} >+}; >+static unsigned nv4TableFIFO[][2] = >+{ >+ {0x00003800, 0x80000014} >+}; >+static unsigned nv4TablePFIFO[][2] = >+{ >+ {0x00000140, 0x00000000}, >+ {0x00000480, 0x00000000}, >+ {0x00000494, 0x00000000}, >+ {0x00000481, 0x00000000}, >+ {0x0000048B, 0x00000000}, >+ {0x00000400, 0x00000000}, >+ {0x00000414, 0x00000000}, >+ {0x00000084, 0x03000100}, >+ {0x00000085, 0x00000110}, >+ {0x00000086, 0x00000112}, >+ {0x00000143, 0x0000FFFF}, >+ {0x00000496, 0x0000FFFF}, >+ {0x00000050, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x00000415, 0x00000001}, >+ {0x00000480, 0x00000001}, >+ {0x00000494, 0x00000001}, >+ {0x00000495, 0x00000001}, >+ {0x00000140, 0x00000001} >+}; >+static unsigned nv4TablePGRAPH[][2] = >+{ >+ {0x00000020, 0x1231C001}, >+ {0x00000021, 0x72111101}, >+ {0x00000022, 0x11D5F071}, >+ {0x00000023, 0x10D4FF31}, >+ {0x00000060, 0x00000000}, >+ {0x00000068, 0x00000000}, >+ {0x00000070, 0x00000000}, >+ {0x00000078, 0x00000000}, >+ {0x00000061, 0x00000000}, >+ {0x00000069, 0x00000000}, >+ {0x00000071, 0x00000000}, >+ {0x00000079, 0x00000000}, >+ {0x00000062, 0x00000000}, >+ {0x0000006A, 0x00000000}, >+ {0x00000072, 0x00000000}, >+ {0x0000007A, 0x00000000}, >+ {0x00000063, 0x00000000}, >+ {0x0000006B, 0x00000000}, >+ {0x00000073, 0x00000000}, >+ {0x0000007B, 0x00000000}, >+ {0x00000064, 0x00000000}, >+ {0x0000006C, 0x00000000}, >+ {0x00000074, 0x00000000}, >+ {0x0000007C, 0x00000000}, >+ {0x00000065, 0x00000000}, >+ {0x0000006D, 0x00000000}, >+ {0x00000075, 0x00000000}, >+ {0x0000007D, 0x00000000}, >+ {0x00000066, 0x00000000}, >+ {0x0000006E, 0x00000000}, >+ {0x00000076, 0x00000000}, >+ {0x0000007E, 0x00000000}, >+ {0x00000067, 0x00000000}, >+ {0x0000006F, 0x00000000}, >+ {0x00000077, 0x00000000}, >+ {0x0000007F, 0x00000000}, >+ {0x00000058, 0x00000000}, >+ {0x00000059, 0x00000000}, >+ {0x0000005A, 0x00000000}, >+ {0x0000005B, 0x00000000}, >+ {0x00000196, 0x00000000}, >+ {0x000001A1, 0x01FFFFFF}, >+ {0x00000197, 0x00000000}, >+ {0x000001A2, 0x01FFFFFF}, >+ {0x00000198, 0x00000000}, >+ {0x000001A3, 0x01FFFFFF}, >+ {0x00000199, 0x00000000}, >+ {0x000001A4, 0x01FFFFFF}, >+ {0x00000050, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x0000005C, 0x10010100}, >+ {0x000001C4, 0xFFFFFFFF}, >+ {0x000001C8, 0x00000001}, >+ {0x00000204, 0x00000000}, >+ {0x000001C3, 0x00000001} >+}; >+static unsigned nv4TablePGRAPH_8BPP[][2] = >+{ >+ {0x000001C9, 0x00111111}, >+ {0x00000186, 0x00001010}, >+ {0x0000020C, 0x03020202} >+}; >+static unsigned nv4TablePGRAPH_15BPP[][2] = >+{ >+ {0x000001C9, 0x00226222}, >+ {0x00000186, 0x00002071}, >+ {0x0000020C, 0x09080808} >+}; >+static unsigned nv4TablePGRAPH_16BPP[][2] = >+{ >+ {0x000001C9, 0x00556555}, >+ {0x00000186, 0x000050C2}, >+ {0x0000020C, 0x0C0B0B0B} >+}; >+static unsigned nv4TablePGRAPH_32BPP[][2] = >+{ >+ {0x000001C9, 0x0077D777}, >+ {0x00000186, 0x000070E5}, >+ {0x0000020C, 0x0E0D0D0D} >+}; >+static unsigned nv4TablePRAMIN[][2] = >+{ >+ {0x00000000, 0x80000010}, >+ {0x00000001, 0x80011145}, >+ {0x00000002, 0x80000011}, >+ {0x00000003, 0x80011146}, >+ {0x00000004, 0x80000012}, >+ {0x00000005, 0x80011147}, >+ {0x00000006, 0x80000013}, >+ {0x00000007, 0x80011148}, >+ {0x00000008, 0x80000014}, >+ {0x00000009, 0x80011149}, >+ {0x0000000A, 0x80000015}, >+ {0x0000000B, 0x8001114A}, >+ {0x0000000C, 0x80000016}, >+ {0x0000000D, 0x8001114F}, >+ {0x00000020, 0x80000000}, >+ {0x00000021, 0x80011142}, >+ {0x00000022, 0x80000001}, >+ {0x00000023, 0x80011143}, >+ {0x00000024, 0x80000002}, >+ {0x00000025, 0x80011144}, >+ {0x00000026, 0x80000003}, >+ {0x00000027, 0x8001114B}, >+ {0x00000028, 0x80000004}, >+ {0x00000029, 0x8001114C}, >+ {0x0000002A, 0x80000005}, >+ {0x0000002B, 0x8001114D}, >+ {0x0000002C, 0x80000006}, >+ {0x0000002D, 0x8001114E}, >+ {0x00000500, 0x00003000}, >+ {0x00000501, 0x01FFFFFF}, >+ {0x00000502, 0x00000002}, >+ {0x00000503, 0x00000002}, >+ {0x00000508, 0x01008043}, >+ {0x0000050A, 0x00000000}, >+ {0x0000050B, 0x00000000}, >+ {0x0000050C, 0x01008019}, >+ {0x0000050E, 0x00000000}, >+ {0x0000050F, 0x00000000}, >+#if 1 >+ {0x00000510, 0x01008018}, >+#else >+ {0x00000510, 0x01008044}, >+#endif >+ {0x00000512, 0x00000000}, >+ {0x00000513, 0x00000000}, >+ {0x00000514, 0x01008021}, >+ {0x00000516, 0x00000000}, >+ {0x00000517, 0x00000000}, >+ {0x00000518, 0x0100805F}, >+ {0x0000051A, 0x00000000}, >+ {0x0000051B, 0x00000000}, >+#if 1 >+ {0x0000051C, 0x0100804B}, >+#else >+ {0x0000051C, 0x0100804A}, >+#endif >+ {0x0000051E, 0x00000000}, >+ {0x0000051F, 0x00000000}, >+ {0x00000520, 0x0100A048}, >+ {0x00000521, 0x00000D01}, >+ {0x00000522, 0x11401140}, >+ {0x00000523, 0x00000000}, >+ {0x00000524, 0x0300A054}, >+ {0x00000525, 0x00000D01}, >+ {0x00000526, 0x11401140}, >+ {0x00000527, 0x00000000}, >+ {0x00000528, 0x0300A055}, >+ {0x00000529, 0x00000D01}, >+ {0x0000052A, 0x11401140}, >+ {0x0000052B, 0x00000000}, >+ {0x0000052C, 0x00000058}, >+ {0x0000052E, 0x11401140}, >+ {0x0000052F, 0x00000000}, >+ {0x00000530, 0x00000059}, >+ {0x00000532, 0x11401140}, >+ {0x00000533, 0x00000000}, >+ {0x00000534, 0x0000005A}, >+ {0x00000536, 0x11401140}, >+ {0x00000537, 0x00000000}, >+ {0x00000538, 0x0000005B}, >+ {0x0000053A, 0x11401140}, >+ {0x0000053B, 0x00000000}, >+ {0x0000053C, 0x0300A01C}, >+ {0x0000053E, 0x11401140}, >+ {0x0000053F, 0x00000000} >+}; >+static unsigned nv4TablePRAMIN_8BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000302}, >+ {0x0000050D, 0x00000302}, >+ {0x00000511, 0x00000202}, >+ {0x00000515, 0x00000302}, >+ {0x00000519, 0x00000302}, >+ {0x0000051D, 0x00000302}, >+ {0x0000052D, 0x00000302}, >+ {0x0000052E, 0x00000302}, >+ {0x00000535, 0x00000000}, >+ {0x00000539, 0x00000000}, >+ {0x0000053D, 0x00000302} >+}; >+static unsigned nv4TablePRAMIN_15BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000902}, >+ {0x0000050D, 0x00000902}, >+ {0x00000511, 0x00000802}, >+ {0x00000515, 0x00000902}, >+ {0x00000519, 0x00000902}, >+ {0x0000051D, 0x00000902}, >+ {0x0000052D, 0x00000902}, >+ {0x0000052E, 0x00000902}, >+ {0x00000535, 0x00000702}, >+ {0x00000539, 0x00000702}, >+ {0x0000053D, 0x00000902} >+}; >+static unsigned nv4TablePRAMIN_16BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000C02}, >+ {0x0000050D, 0x00000C02}, >+ {0x00000511, 0x00000B02}, >+ {0x00000515, 0x00000C02}, >+ {0x00000519, 0x00000C02}, >+ {0x0000051D, 0x00000C02}, >+ {0x0000052D, 0x00000C02}, >+ {0x0000052E, 0x00000C02}, >+ {0x00000535, 0x00000702}, >+ {0x00000539, 0x00000702}, >+ {0x0000053D, 0x00000C02} >+}; >+static unsigned nv4TablePRAMIN_32BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000E02}, >+ {0x0000050D, 0x00000E02}, >+ {0x00000511, 0x00000D02}, >+ {0x00000515, 0x00000E02}, >+ {0x00000519, 0x00000E02}, >+ {0x0000051D, 0x00000E02}, >+ {0x0000052D, 0x00000E02}, >+ {0x0000052E, 0x00000E02}, >+ {0x00000535, 0x00000E02}, >+ {0x00000539, 0x00000E02}, >+ {0x0000053D, 0x00000E02} >+}; >+static unsigned nv10TableFIFO[][2] = >+{ >+ {0x00003800, 0x80000014} >+}; >+static unsigned nv10TablePFIFO[][2] = >+{ >+ {0x00000140, 0x00000000}, >+ {0x00000480, 0x00000000}, >+ {0x00000494, 0x00000000}, >+ {0x00000481, 0x00000000}, >+ {0x0000048B, 0x00000000}, >+ {0x00000400, 0x00000000}, >+ {0x00000414, 0x00000000}, >+ {0x00000084, 0x03000100}, >+ {0x00000085, 0x00000110}, >+ {0x00000086, 0x00000112}, >+ {0x00000143, 0x0000FFFF}, >+ {0x00000496, 0x0000FFFF}, >+ {0x00000050, 0x00000000}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x00000415, 0x00000001}, >+ {0x00000480, 0x00000001}, >+ {0x00000494, 0x00000001}, >+ {0x00000495, 0x00000001}, >+ {0x00000140, 0x00000001} >+}; >+static unsigned nv10TablePGRAPH[][2] = >+{ >+ {0x00000020, 0x0003FFFF}, >+ {0x00000021, 0x00118701}, >+ {0x00000022, 0x24F82AD9}, >+ {0x00000023, 0x55DE0030}, >+ {0x00000020, 0x00000000}, >+ {0x00000024, 0x00000000}, >+ {0x00000058, 0x00000000}, >+ {0x00000060, 0x00000000}, >+ {0x00000068, 0x00000000}, >+ {0x00000070, 0x00000000}, >+ {0x00000078, 0x00000000}, >+ {0x00000059, 0x00000000}, >+ {0x00000061, 0x00000000}, >+ {0x00000069, 0x00000000}, >+ {0x00000071, 0x00000000}, >+ {0x00000079, 0x00000000}, >+ {0x0000005A, 0x00000000}, >+ {0x00000062, 0x00000000}, >+ {0x0000006A, 0x00000000}, >+ {0x00000072, 0x00000000}, >+ {0x0000007A, 0x00000000}, >+ {0x0000005B, 0x00000000}, >+ {0x00000063, 0x00000000}, >+ {0x0000006B, 0x00000000}, >+ {0x00000073, 0x00000000}, >+ {0x0000007B, 0x00000000}, >+ {0x0000005C, 0x00000000}, >+ {0x00000064, 0x00000000}, >+ {0x0000006C, 0x00000000}, >+ {0x00000074, 0x00000000}, >+ {0x0000007C, 0x00000000}, >+ {0x0000005D, 0x00000000}, >+ {0x00000065, 0x00000000}, >+ {0x0000006D, 0x00000000}, >+ {0x00000075, 0x00000000}, >+ {0x0000007D, 0x00000000}, >+ {0x0000005E, 0x00000000}, >+ {0x00000066, 0x00000000}, >+ {0x0000006E, 0x00000000}, >+ {0x00000076, 0x00000000}, >+ {0x0000007E, 0x00000000}, >+ {0x0000005F, 0x00000000}, >+ {0x00000067, 0x00000000}, >+ {0x0000006F, 0x00000000}, >+ {0x00000077, 0x00000000}, >+ {0x0000007F, 0x00000000}, >+ {0x00000053, 0x00000000}, >+ {0x00000054, 0x00000000}, >+ {0x00000055, 0x00000000}, >+ {0x00000056, 0x00000000}, >+ {0x00000057, 0x00000000}, >+ {0x00000196, 0x00000000}, >+ {0x000001A1, 0x01FFFFFF}, >+ {0x00000197, 0x00000000}, >+ {0x000001A2, 0x01FFFFFF}, >+ {0x00000198, 0x00000000}, >+ {0x000001A3, 0x01FFFFFF}, >+ {0x00000199, 0x00000000}, >+ {0x000001A4, 0x01FFFFFF}, >+ {0x0000019A, 0x00000000}, >+ {0x000001A5, 0x01FFFFFF}, >+ {0x0000019B, 0x00000000}, >+ {0x000001A6, 0x01FFFFFF}, >+ {0x00000050, 0x01111111}, >+ {0x00000040, 0xFFFFFFFF}, >+ {0x00000051, 0x10010100}, >+ {0x000001C5, 0xFFFFFFFF}, >+ {0x000001C8, 0x00000001}, >+ {0x00000204, 0x00000000}, >+ {0x000001C4, 0x00000001} >+}; >+static unsigned nv10TablePGRAPH_8BPP[][2] = >+{ >+ {0x000001C9, 0x00111111}, >+ {0x00000186, 0x00001010}, >+ {0x0000020C, 0x03020202} >+}; >+static unsigned nv10TablePGRAPH_15BPP[][2] = >+{ >+ {0x000001C9, 0x00226222}, >+ {0x00000186, 0x00002071}, >+ {0x0000020C, 0x09080808} >+}; >+static unsigned nv10TablePGRAPH_16BPP[][2] = >+{ >+ {0x000001C9, 0x00556555}, >+ {0x00000186, 0x000050C2}, >+ {0x0000020C, 0x000B0B0C} >+}; >+static unsigned nv10TablePGRAPH_32BPP[][2] = >+{ >+ {0x000001C9, 0x0077D777}, >+ {0x00000186, 0x000070E5}, >+ {0x0000020C, 0x0E0D0D0D} >+}; >+static unsigned nv10tri05TablePGRAPH[][2] = >+{ >+ {(0x00000E00/4), 0x00000000}, >+ {(0x00000E04/4), 0x00000000}, >+ {(0x00000E08/4), 0x00000000}, >+ {(0x00000E0C/4), 0x00000000}, >+ {(0x00000E10/4), 0x00001000}, >+ {(0x00000E14/4), 0x00001000}, >+ {(0x00000E18/4), 0x4003ff80}, >+ {(0x00000E1C/4), 0x00000000}, >+ {(0x00000E20/4), 0x00000000}, >+ {(0x00000E24/4), 0x00000000}, >+ {(0x00000E28/4), 0x00000000}, >+ {(0x00000E2C/4), 0x00000000}, >+ {(0x00000E30/4), 0x00080008}, >+ {(0x00000E34/4), 0x00080008}, >+ {(0x00000E38/4), 0x00000000}, >+ {(0x00000E3C/4), 0x00000000}, >+ {(0x00000E40/4), 0x00000000}, >+ {(0x00000E44/4), 0x00000000}, >+ {(0x00000E48/4), 0x00000000}, >+ {(0x00000E4C/4), 0x00000000}, >+ {(0x00000E50/4), 0x00000000}, >+ {(0x00000E54/4), 0x00000000}, >+ {(0x00000E58/4), 0x00000000}, >+ {(0x00000E5C/4), 0x00000000}, >+ {(0x00000E60/4), 0x00000000}, >+ {(0x00000E64/4), 0x10000000}, >+ {(0x00000E68/4), 0x00000000}, >+ {(0x00000E6C/4), 0x00000000}, >+ {(0x00000E70/4), 0x00000000}, >+ {(0x00000E74/4), 0x00000000}, >+ {(0x00000E78/4), 0x00000000}, >+ {(0x00000E7C/4), 0x00000000}, >+ {(0x00000E80/4), 0x00000000}, >+ {(0x00000E84/4), 0x00000000}, >+ {(0x00000E88/4), 0x08000000}, >+ {(0x00000E8C/4), 0x00000000}, >+ {(0x00000E90/4), 0x00000000}, >+ {(0x00000E94/4), 0x00000000}, >+ {(0x00000E98/4), 0x00000000}, >+ {(0x00000E9C/4), 0x4B7FFFFF}, >+ {(0x00000EA0/4), 0x00000000}, >+ {(0x00000EA4/4), 0x00000000}, >+ {(0x00000EA8/4), 0x00000000}, >+ {(0x00000F00/4), 0x07FF0800}, >+ {(0x00000F04/4), 0x07FF0800}, >+ {(0x00000F08/4), 0x07FF0800}, >+ {(0x00000F0C/4), 0x07FF0800}, >+ {(0x00000F10/4), 0x07FF0800}, >+ {(0x00000F14/4), 0x07FF0800}, >+ {(0x00000F18/4), 0x07FF0800}, >+ {(0x00000F1C/4), 0x07FF0800}, >+ {(0x00000F20/4), 0x07FF0800}, >+ {(0x00000F24/4), 0x07FF0800}, >+ {(0x00000F28/4), 0x07FF0800}, >+ {(0x00000F2C/4), 0x07FF0800}, >+ {(0x00000F30/4), 0x07FF0800}, >+ {(0x00000F34/4), 0x07FF0800}, >+ {(0x00000F38/4), 0x07FF0800}, >+ {(0x00000F3C/4), 0x07FF0800}, >+ {(0x00000F40/4), 0x10000000}, >+ {(0x00000F44/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006740}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F50/4), 0x00006750}, >+ {(0x00000F54/4), 0x40000000}, >+ {(0x00000F54/4), 0x40000000}, >+ {(0x00000F54/4), 0x40000000}, >+ {(0x00000F54/4), 0x40000000}, >+ {(0x00000F50/4), 0x00006760}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006770}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006780}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x000067A0}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F50/4), 0x00006AB0}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F50/4), 0x00006AC0}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006C10}, >+ {(0x00000F54/4), 0xBF800000}, >+ {(0x00000F50/4), 0x00007030}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007040}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007050}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007060}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007070}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007080}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00007090}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x000070A0}, >+ {(0x00000F54/4), 0x7149F2CA}, >+ {(0x00000F50/4), 0x00006A80}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F50/4), 0x00006AA0}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00000040}, >+ {(0x00000F54/4), 0x00000005}, >+ {(0x00000F50/4), 0x00006400}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x4B7FFFFF}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006410}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006420}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x00006430}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x000064C0}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F54/4), 0x477FFFFF}, >+ {(0x00000F54/4), 0x3F800000}, >+ {(0x00000F50/4), 0x000064D0}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0xC5000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x000064E0}, >+ {(0x00000F54/4), 0xC4FFF000}, >+ {(0x00000F54/4), 0xC4FFF000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F50/4), 0x000064F0}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F54/4), 0x00000000}, >+ {(0x00000F40/4), 0x30000000}, >+ {(0x00000F44/4), 0x00000004}, >+ {(0x00000F48/4), 0x10000000}, >+ {(0x00000F4C/4), 0x00000000} >+}; >+static unsigned nv10TablePRAMIN[][2] = >+{ >+ {0x00000000, 0x80000010}, >+ {0x00000001, 0x80011145}, >+ {0x00000002, 0x80000011}, >+ {0x00000003, 0x80011146}, >+ {0x00000004, 0x80000012}, >+ {0x00000005, 0x80011147}, >+ {0x00000006, 0x80000013}, >+ {0x00000007, 0x80011148}, >+ {0x00000008, 0x80000014}, >+ {0x00000009, 0x80011149}, >+ {0x0000000A, 0x80000015}, >+ {0x0000000B, 0x8001114A}, >+ {0x0000000C, 0x80000016}, >+ {0x0000000D, 0x80011150}, >+ {0x00000020, 0x80000000}, >+ {0x00000021, 0x80011142}, >+ {0x00000022, 0x80000001}, >+ {0x00000023, 0x80011143}, >+ {0x00000024, 0x80000002}, >+ {0x00000025, 0x80011144}, >+ {0x00000026, 0x80000003}, >+ {0x00000027, 0x8001114B}, >+ {0x00000028, 0x80000004}, >+ {0x00000029, 0x8001114C}, >+ {0x0000002A, 0x80000005}, >+ {0x0000002B, 0x8001114D}, >+ {0x0000002C, 0x80000006}, >+ {0x0000002D, 0x8001114E}, >+ {0x0000002E, 0x80000007}, >+ {0x0000002F, 0x8001114F}, >+ {0x00000500, 0x00003000}, >+ {0x00000501, 0x01FFFFFF}, >+ {0x00000502, 0x00000002}, >+ {0x00000503, 0x00000002}, >+#ifdef __BIG_ENDIAN >+ {0x00000508, 0x01088043}, >+#else >+ {0x00000508, 0x01008043}, >+#endif >+ {0x0000050A, 0x00000000}, >+ {0x0000050B, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x0000050C, 0x01088019}, >+#else >+ {0x0000050C, 0x01008019}, >+#endif >+ {0x0000050E, 0x00000000}, >+ {0x0000050F, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x00000510, 0x01088018}, >+#else >+ {0x00000510, 0x01008018}, >+#endif >+ {0x00000512, 0x00000000}, >+ {0x00000513, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x00000514, 0x01088021}, >+#else >+ {0x00000514, 0x01008021}, >+#endif >+ {0x00000516, 0x00000000}, >+ {0x00000517, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x00000518, 0x0108805F}, >+#else >+ {0x00000518, 0x0100805F}, >+#endif >+ {0x0000051A, 0x00000000}, >+ {0x0000051B, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x0000051C, 0x0108804B}, >+#else >+ {0x0000051C, 0x0100804B}, >+#endif >+ {0x0000051E, 0x00000000}, >+ {0x0000051F, 0x00000000}, >+ {0x00000520, 0x0100A048}, >+ {0x00000521, 0x00000D01}, >+ {0x00000522, 0x11401140}, >+ {0x00000523, 0x00000000}, >+ {0x00000524, 0x0300A094}, >+ {0x00000525, 0x00000D01}, >+ {0x00000526, 0x11401140}, >+ {0x00000527, 0x00000000}, >+ {0x00000528, 0x0300A095}, >+ {0x00000529, 0x00000D01}, >+ {0x0000052A, 0x11401140}, >+ {0x0000052B, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x0000052C, 0x00080058}, >+#else >+ {0x0000052C, 0x00000058}, >+#endif >+ {0x0000052E, 0x11401140}, >+ {0x0000052F, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x00000530, 0x00080059}, >+#else >+ {0x00000530, 0x00000059}, >+#endif >+ {0x00000532, 0x11401140}, >+ {0x00000533, 0x00000000}, >+ {0x00000534, 0x0000005A}, >+ {0x00000536, 0x11401140}, >+ {0x00000537, 0x00000000}, >+ {0x00000538, 0x0000005B}, >+ {0x0000053A, 0x11401140}, >+ {0x0000053B, 0x00000000}, >+ {0x0000053C, 0x00000093}, >+ {0x0000053E, 0x11401140}, >+ {0x0000053F, 0x00000000}, >+#ifdef __BIG_ENDIAN >+ {0x00000540, 0x0308A01C}, >+#else >+ {0x00000540, 0x0300A01C}, >+#endif >+ {0x00000542, 0x11401140}, >+ {0x00000543, 0x00000000} >+}; >+static unsigned nv10TablePRAMIN_8BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000302}, >+ {0x0000050D, 0x00000302}, >+ {0x00000511, 0x00000202}, >+ {0x00000515, 0x00000302}, >+ {0x00000519, 0x00000302}, >+ {0x0000051D, 0x00000302}, >+ {0x0000052D, 0x00000302}, >+ {0x0000052E, 0x00000302}, >+ {0x00000535, 0x00000000}, >+ {0x00000539, 0x00000000}, >+ {0x0000053D, 0x00000000}, >+ {0x00000541, 0x00000302} >+}; >+static unsigned nv10TablePRAMIN_15BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000902}, >+ {0x0000050D, 0x00000902}, >+ {0x00000511, 0x00000802}, >+ {0x00000515, 0x00000902}, >+ {0x00000519, 0x00000902}, >+ {0x0000051D, 0x00000902}, >+ {0x0000052D, 0x00000902}, >+ {0x0000052E, 0x00000902}, >+ {0x00000535, 0x00000902}, >+ {0x00000539, 0x00000902}, >+ {0x0000053D, 0x00000902}, >+ {0x00000541, 0x00000902} >+}; >+static unsigned nv10TablePRAMIN_16BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000C02}, >+ {0x0000050D, 0x00000C02}, >+ {0x00000511, 0x00000B02}, >+ {0x00000515, 0x00000C02}, >+ {0x00000519, 0x00000C02}, >+ {0x0000051D, 0x00000C02}, >+ {0x0000052D, 0x00000C02}, >+ {0x0000052E, 0x00000C02}, >+ {0x00000535, 0x00000C02}, >+ {0x00000539, 0x00000C02}, >+ {0x0000053D, 0x00000C02}, >+ {0x00000541, 0x00000C02} >+}; >+static unsigned nv10TablePRAMIN_32BPP[][2] = >+{ >+ /* 0xXXXXXX01 For MSB mono format */ >+ /* 0xXXXXXX02 For LSB mono format */ >+ {0x00000509, 0x00000E02}, >+ {0x0000050D, 0x00000E02}, >+ {0x00000511, 0x00000D02}, >+ {0x00000515, 0x00000E02}, >+ {0x00000519, 0x00000E02}, >+ {0x0000051D, 0x00000E02}, >+ {0x0000052D, 0x00000E02}, >+ {0x0000052E, 0x00000E02}, >+ {0x00000535, 0x00000E02}, >+ {0x00000539, 0x00000E02}, >+ {0x0000053D, 0x00000E02}, >+ {0x00000541, 0x00000E02} >+}; >+ >diff -urN linux-2.6.6.orig/drivers/video/xbox/xboxfb.h linux-2.6.6/drivers/video/xbox/xboxfb.h >--- linux-2.6.6.orig/drivers/video/xbox/xboxfb.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/xboxfb.h 2004-05-10 12:30:23.292930104 +0100 >@@ -0,0 +1,73 @@ >+#ifndef __XBOXFB_H >+#define __XBOXFB_H >+ >+#include <linux/config.h> >+#include <linux/fb.h> >+#include <video/vga.h> >+#include "riva_hw.h" >+#include <linux/xboxfbctl.h> >+ >+/* GGI compatibility macros */ >+#define NUM_SEQ_REGS 0x05 >+#define NUM_CRT_REGS 0x41 >+#define NUM_GRC_REGS 0x09 >+#define NUM_ATC_REGS 0x15 >+ >+#define NUM_CONEXANT_REGS 0x69 >+#define NUM_FOCUS_REGS 0xff >+#define MAX_ENCODER_REGS 0xff >+ >+/* holds the state of the VGA core and extended Riva hw state from riva_hw.c. >+ * From KGI originally. */ >+struct riva_regs { >+ u8 attr[NUM_ATC_REGS]; >+ u8 crtc[NUM_CRT_REGS]; >+ u8 gra[NUM_GRC_REGS]; >+ u8 seq[NUM_SEQ_REGS]; >+ u8 misc_output; >+ RIVA_HW_STATE ext; >+ u8 encoder_mode[MAX_ENCODER_REGS]; >+}; >+ >+struct riva_par { >+ RIVA_HW_INST riva; /* interface to riva_hw.c */ >+ >+ caddr_t ctrl_base; /* virtual control register base addr */ >+ unsigned dclk_max; /* max DCLK */ >+ >+ struct riva_regs initial_state; /* initial startup video mode */ >+ struct riva_regs current_state; >+ struct vgastate state; >+ atomic_t ref_count; >+ u32 cursor_data[32 * 32/4]; >+ int cursor_reset; >+ unsigned char *EDID; >+ >+ int panel_xres, panel_yres; >+ int hOver_plus, hSync_width, hblank; >+ int vOver_plus, vSync_width, vblank; >+ int hAct_high, vAct_high, interlaced; >+ int synct, misc, clock; >+ >+ int use_default_var; >+ int got_dfpinfo; >+ unsigned int Chipset; >+ int forceCRTC; >+ Bool SecondCRTC; >+ int FlatPanel; >+#ifdef CONFIG_MTRR >+ struct { int vram; int vram_valid; } mtrr; >+#endif >+ unsigned riva_fb_start; /* start address of fb in riva address space */ >+ xbox_tv_encoding tv_encoding; >+ xbox_av_type av_type; >+ xbox_encoder_type video_encoder; >+ double hoc; >+ double voc; >+}; >+ >+void riva_common_setup(struct riva_par *); >+unsigned long riva_get_memlen(struct riva_par *); >+unsigned long riva_get_maxdclk(struct riva_par *); >+ >+#endif /* __XBOXFB_H */ >diff -urN linux-2.6.6.orig/drivers/video/xbox/xlb.c linux-2.6.6/drivers/video/xbox/xlb.c >--- linux-2.6.6.orig/drivers/video/xbox/xlb.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/xlb.c 2004-05-10 12:30:23.294929800 +0100 >@@ -0,0 +1,30 @@ >+/* >+ * linux/drivers/video/riva/xlb.c - Xbox driver for Xcalibur encoder >+ * >+ * Maintainer: David Pye (dmp) <dmp@davidmpye.dyndns.org> >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * It doesnt work! >+*/ >+#include "xlb.h" >+#include "encoder.h" >+ >+ >+int xlb_calc_hdtv_mode( >+ xbox_hdtv_mode hdtv_mode, >+ unsigned char pll_int, >+ unsigned char * regs >+ ){ >+ >+ return 1; >+} >+ >+int xlb_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out) >+{ >+ return 1; >+} >diff -urN linux-2.6.6.orig/drivers/video/xbox/xlb.h linux-2.6.6/drivers/video/xbox/xlb.h >--- linux-2.6.6.orig/drivers/video/xbox/xlb.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/drivers/video/xbox/xlb.h 2004-05-10 12:30:23.296929496 +0100 >@@ -0,0 +1,24 @@ >+/* >+ * linux/drivers/video/riva/xlb.c - Xbox driver for Xcalibur encoder >+ * >+ * Maintainer: David Pye (dmp) <dmp@davidmpye.dyndns.org> >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+ >+#ifndef xlb_h_ >+#define xlb_h_ >+ >+#include "encoder.h" >+#include "xboxfb.h" >+ >+int xlb_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out ); >+int xlb_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out); >+#endif >diff -urN linux-2.6.6.orig/fs/Kconfig linux-2.6.6/fs/Kconfig >--- linux-2.6.6.orig/fs/Kconfig 2004-05-10 03:32:38.000000000 +0100 >+++ linux-2.6.6/fs/Kconfig 2004-05-10 12:30:23.304928280 +0100 >@@ -667,6 +667,26 @@ > (the one containing the directory /) cannot be a module, so saying M > could be dangerous. If unsure, say N. > >+config FATX_FS >+ tristate "FATX filesystem support (EXPERIMENTAL)" >+ depends on EXPERIMENTAL && !LBD >+ help >+ This adds support for the FATX filesystem as found in Microsoft's Xbox. >+ >+ The FATX filesystem is a derivative of the FAT filesystem minus some >+ legacy fields and redundant information. For lengthier discussions on >+ the filesystem, see: >+ >+ http://xbox-linux.sourceforge.net/docs/fatxfat.html >+ http://xbox-linux.sourceforge.net/docs/hdpartfs.html >+ http://xbox-linux.sourceforge.net/docs/hackingfatx.html >+ >+ If you are running Linux on the Xbox, choose Y unless you know >+ what you're doing. Otherwise, choose N. >+ >+ To compile this filesystem support as a module, choose M here: the >+ module will be called fatx. >+ > config NTFS_FS > tristate "NTFS file system support" > select NLS >diff -urN linux-2.6.6.orig/fs/Makefile linux-2.6.6/fs/Makefile >--- linux-2.6.6.orig/fs/Makefile 2004-05-10 03:32:38.000000000 +0100 >+++ linux-2.6.6/fs/Makefile 2004-05-10 12:30:23.307927824 +0100 >@@ -59,6 +59,7 @@ > obj-$(CONFIG_UMSDOS_FS) += umsdos/ > obj-$(CONFIG_MSDOS_FS) += msdos/ > obj-$(CONFIG_VFAT_FS) += vfat/ >+obj-$(CONFIG_FATX_FS) += fatx/ > obj-$(CONFIG_BFS_FS) += bfs/ > obj-$(CONFIG_ISO9660_FS) += isofs/ > obj-$(CONFIG_DEVFS_FS) += devfs/ >diff -urN linux-2.6.6.orig/fs/fatx/Makefile linux-2.6.6/fs/fatx/Makefile >--- linux-2.6.6.orig/fs/fatx/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/Makefile 2004-05-10 12:30:23.309927520 +0100 >@@ -0,0 +1,7 @@ >+# >+# Makefile for the Linux fatx filesystem routines. >+# >+ >+obj-$(CONFIG_FATX_FS) += fatx.o >+ >+fatx-objs := namei.o cache.o dir.o file.o inode.o misc.o fatxfs_syms.o >diff -urN linux-2.6.6.orig/fs/fatx/cache.c linux-2.6.6/fs/fatx/cache.c >--- linux-2.6.6.orig/fs/fatx/cache.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/cache.c 2004-05-10 12:30:23.312927064 +0100 >@@ -0,0 +1,319 @@ >+/* >+ * linux/fs/fatx/cache.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/fatx_fs.h> >+#include <linux/kernel.h> >+#include <linux/errno.h> >+#include <linux/string.h> >+#include <linux/stat.h> >+#include <linux/buffer_head.h> >+ >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+static struct fatx_cache *fatx_cache,cache[FATX_CACHE]; >+static spinlock_t fatx_cache_lock = SPIN_LOCK_UNLOCKED; >+ >+int fatx_access(struct super_block *sb,int nr,int new_value) >+{ >+ struct buffer_head *bh, *bh2, *c_bh, *c_bh2; >+ unsigned char *p_first, *p_last; >+ int copy, first = 0, last = 0, next, b; >+ >+ next = 0; >+ >+ if ((unsigned) (nr-2) >= FATX_SB(sb)->clusters) >+ return 0; >+ if (FATX_SB(sb)->fat_bits == 32) { >+ first = last = nr*4; >+ } else if (FATX_SB(sb)->fat_bits == 16) { >+ first = last = nr*2; >+ } >+ >+ b = FATX_SB(sb)->fat_start + (first >> sb->s_blocksize_bits); >+ if (!(bh = sb_bread(sb, b))) { >+ PRINTK("FATX: bread in fatx_access failed\n"); >+ return 0; >+ } >+ if ((first >> sb->s_blocksize_bits) == (last >> sb->s_blocksize_bits)) { >+ bh2 = bh; >+ } else { >+ if (!(bh2 = sb_bread(sb, b+1))) { >+ if(bh) brelse(bh); >+ PRINTK("FATX: 2nd bread in fatx_access failed\n"); >+ return 0; >+ } >+ } >+ if (FATX_SB(sb)->fat_bits == 32) { >+ p_first = p_last = NULL; /* GCC needs that stuff */ >+ next = CF_LE_L(((__u32 *) bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]); >+ next &= 0xffffffff; >+ if (next >= EOC_FAT32) next = -1; >+ } else if (FATX_SB(sb)->fat_bits == 16) { >+ p_first = p_last = NULL; /* GCC needs that stuff */ >+ next = CF_LE_W(((__u16 *) bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]); >+ if (next >= EOC_FAT16) next = -1; >+ } >+ PRINTK("FATX: fatx_access: 0x%x, nr=0x%x, first=0x%x, next=0x%x\n", b, nr, first, next); >+ if (new_value != -1) { >+ if (FATX_SB(sb)->fat_bits == 32) { >+ ((__u32 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2] >+ = CT_LE_L(new_value); >+ } else if (FATX_SB(sb)->fat_bits == 16) { >+ ((__u16 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1] >+ = CT_LE_W(new_value); >+ } >+ mark_buffer_dirty(bh); >+ for (copy = 1; copy < FATX_SB(sb)->fats; copy++) { >+ b = FATX_SB(sb)->fat_start + (first >> sb->s_blocksize_bits) >+ + FATX_SB(sb)->fat_length * copy; >+ if (!(c_bh = sb_bread(sb, b))) >+ break; >+ if (bh != bh2) { >+ if (!(c_bh2 = sb_bread(sb, b+1))) { >+ if(c_bh) brelse(c_bh); >+ break; >+ } >+ memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize); >+ mark_buffer_dirty(c_bh2); >+ if(c_bh2) brelse(c_bh2); >+ } >+ memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize); >+ mark_buffer_dirty(c_bh); >+ if(c_bh) brelse(c_bh); >+ } >+ } >+ if(bh) brelse(bh); >+ if (bh != bh2) >+ if(bh2) brelse(bh2); >+ return next; >+} >+ >+void fatx_cache_init(void) >+{ >+ static int initialized = 0; >+ int count; >+ >+ spin_lock(&fatx_cache_lock); >+ if (initialized) { >+ spin_unlock(&fatx_cache_lock); >+ return; >+ } >+ fatx_cache = &cache[0]; >+ for (count = 0; count < FATX_CACHE; count++) { >+ cache[count].device = 0; >+ cache[count].next = count == FATX_CACHE-1 ? NULL : >+ &cache[count+1]; >+ } >+ initialized = 1; >+ spin_unlock(&fatx_cache_lock); >+} >+ >+ >+void fatx_cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu) >+{ >+ struct fatx_cache *walk; >+ int first = FATX_I(inode)->i_start; >+ >+ if (!first) >+ return; >+ spin_lock(&fatx_cache_lock); >+ for (walk = fatx_cache; walk; walk = walk->next) >+ if (inode->i_rdev == walk->device >+ && walk->start_cluster == first >+ && walk->file_cluster <= cluster >+ && walk->file_cluster > *f_clu) { >+ *d_clu = walk->disk_cluster; >+#ifdef DEBUG >+printk("cache hit: %d (%d)\n",walk->file_cluster,*d_clu); >+#endif >+ if ((*f_clu = walk->file_cluster) == cluster) { >+ spin_unlock(&fatx_cache_lock); >+ return; >+ } >+ } >+ spin_unlock(&fatx_cache_lock); >+#ifdef DEBUG >+printk("cache miss\n"); >+#endif >+} >+ >+ >+#ifdef DEBUG >+static void list_cache(void) >+{ >+ struct fatx_cache *walk; >+ >+ for (walk = fatx_cache; walk; walk = walk->next) { >+ if (walk->device) >+ printk("<%s,%d>(%d,%d) ", kdevname(walk->device), >+ walk->start_cluster, walk->file_cluster, >+ walk->disk_cluster); >+ else printk("-- "); >+ } >+ printk("\n"); >+} >+#endif >+ >+ >+void fatx_cache_add(struct inode *inode,int f_clu,int d_clu) >+{ >+ struct fatx_cache *walk,*last; >+ int first = FATX_I(inode)->i_start; >+ >+ last = NULL; >+ spin_lock(&fatx_cache_lock); >+ for (walk = fatx_cache; walk->next; walk = (last = walk)->next) >+ if (walk->device == inode->i_rdev >+ && walk->start_cluster == first >+ && walk->file_cluster == f_clu) { >+ if (walk->disk_cluster != d_clu) { >+ printk("FAT cache corruption inode=%ld\n", >+ inode->i_ino); >+ spin_unlock(&fatx_cache_lock); >+ fatx_cache_inval_inode(inode); >+ return; >+ } >+ /* update LRU */ >+ if (last == NULL) { >+ spin_unlock(&fatx_cache_lock); >+ return; >+ } >+ last->next = walk->next; >+ walk->next = fatx_cache; >+ fatx_cache = walk; >+#ifdef DEBUG >+list_cache(); >+#endif >+ spin_unlock(&fatx_cache_lock); >+ return; >+ } >+ walk->device = inode->i_rdev; >+ walk->start_cluster = first; >+ walk->file_cluster = f_clu; >+ walk->disk_cluster = d_clu; >+ last->next = NULL; >+ walk->next = fatx_cache; >+ fatx_cache = walk; >+ spin_unlock(&fatx_cache_lock); >+#ifdef DEBUG >+list_cache(); >+#endif >+} >+ >+ >+/* Cache invalidation occurs rarely, thus the LRU chain is not updated. It >+ fixes itself after a while. */ >+ >+void fatx_cache_inval_inode(struct inode *inode) >+{ >+ struct fatx_cache *walk; >+ int first = FATX_I(inode)->i_start; >+ >+ spin_lock(&fatx_cache_lock); >+ for (walk = fatx_cache; walk; walk = walk->next) >+ if (walk->device == inode->i_rdev >+ && walk->start_cluster == first) >+ walk->device = 0; >+ spin_unlock(&fatx_cache_lock); >+} >+ >+ >+void fatx_cache_inval_dev(dev_t device) >+{ >+ struct fatx_cache *walk; >+ >+ spin_lock(&fatx_cache_lock); >+ for (walk = fatx_cache; walk; walk = walk->next) >+ if (walk->device == device) >+ walk->device = 0; >+ spin_unlock(&fatx_cache_lock); >+} >+ >+ >+int fatx_get_cluster(struct inode *inode,int cluster) >+{ >+ int nr,count; >+ >+ if (!(nr = FATX_I(inode)->i_start)) return 0; >+ if (!cluster) return nr; >+ count = 0; >+ for (fatx_cache_lookup(inode,cluster,&count,&nr); count < cluster; >+ count++) { >+ if ((nr = fatx_access(inode->i_sb,nr,-1)) == -1) return 0; >+ if (!nr) return 0; >+ } >+ fatx_cache_add(inode,cluster,nr); >+ return nr; >+} >+ >+unsigned long fatx_bmap(struct inode *inode,unsigned long sector) >+{ >+ struct super_block *sb = inode->i_sb; >+ struct fatx_sb_info *sbi = FATX_SB(sb); >+ unsigned long cluster, offset, last_block; >+ >+ if ((inode->i_ino == FATX_ROOT_INO || (S_ISDIR(inode->i_mode) && >+ !FATX_I(inode)->i_start))) { >+ if (sector >= sbi->dir_entries >> sbi->dir_per_block_bits) >+ return 0; >+ return sector + sbi->dir_start; >+ } >+ >+ last_block = (FATX_I(inode)->mmu_private + (sb->s_blocksize - 1)) >+ >> sb->s_blocksize_bits; >+ if (sector >= last_block) >+ return 0; >+ >+ cluster = sector / sbi->cluster_size; >+ offset = sector % sbi->cluster_size; >+ if (!(cluster = fatx_get_cluster(inode, cluster))) >+ return 0; >+ >+ return (cluster - 2) * sbi->cluster_size + sbi->data_start + offset; >+} >+ >+ >+/* Free all clusters after the skip'th cluster. Doesn't use the cache, >+ because this way we get an additional sanity check. */ >+ >+int fatx_free(struct inode *inode,int skip) >+{ >+ int nr,last; >+ >+ if (!(nr = FATX_I(inode)->i_start)) return 0; >+ last = 0; >+ while (skip--) { >+ last = nr; >+ if ((nr = fatx_access(inode->i_sb,nr,-1)) == -1) return 0; >+ if (!nr) { >+ printk("fatx_free: skipped EOF\n"); >+ return -EIO; >+ } >+ } >+ if (last) { >+ fatx_access(inode->i_sb,last,EOF_FAT(inode->i_sb)); >+ fatx_cache_inval_inode(inode); >+ } else { >+ fatx_cache_inval_inode(inode); >+ FATX_I(inode)->i_start = 0; >+ FATX_I(inode)->i_logstart = 0; >+ mark_inode_dirty(inode); >+ } >+ lock_fatx(inode->i_sb); >+ while (nr != -1) { >+ if (!(nr = fatx_access(inode->i_sb,nr,0))) { >+ fatx_fs_panic(inode->i_sb,"fatx_free: deleting beyond EOF"); >+ break; >+ } >+ if (FATX_SB(inode->i_sb)->free_clusters != -1) { >+ FATX_SB(inode->i_sb)->free_clusters++; >+ } >+ inode->i_blocks -= (1 << FATX_SB(inode->i_sb)->cluster_bits) / 512; >+ } >+ unlock_fatx(inode->i_sb); >+ return 0; >+} >diff -urN linux-2.6.6.orig/fs/fatx/dir.c linux-2.6.6/fs/fatx/dir.c >--- linux-2.6.6.orig/fs/fatx/dir.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/dir.c 2004-05-10 12:30:23.316926456 +0100 >@@ -0,0 +1,436 @@ >+/* >+ * linux/fs/fatx/dir.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/fs.h> >+#include <linux/fatx_fs.h> >+#include <linux/nls.h> >+#include <linux/kernel.h> >+#include <linux/errno.h> >+#include <linux/stat.h> >+#include <linux/string.h> >+#include <linux/ioctl.h> >+#include <linux/dirent.h> >+#include <linux/mm.h> >+#include <linux/ctype.h> >+ >+#include <asm/uaccess.h> >+ >+#define DEBUG >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+static inline void fatx_printname(const char *name, int length) >+{ >+ int i; >+ for(i=0;i<length;i++) { >+ PRINTK("%c",name[i]); >+ } >+} >+ >+/* >+ * Now an ugly part: this set of directory scan routines works on clusters >+ * rather than on inodes and sectors. They are necessary to locate the '..' >+ * directory "inode". raw_scan_sector operates in four modes: >+ * >+ * name number ino action >+ * -------- -------- -------- ------------------------------------------------- >+ * non-NULL - X Find an entry with that name >+ * NULL non-NULL non-NULL Find an entry whose data starts at *number >+ * NULL non-NULL NULL Count subdirectories in *number. (*) >+ * NULL NULL non-NULL Find an empty entry >+ * >+ * (*) The return code should be ignored. It DOES NOT indicate success or >+ * failure. *number has to be initialized to zero. >+ * >+ * - = not used, X = a value is returned unless NULL >+ * >+ * If res_bh is non-NULL, the buffer is not deallocated but returned to the >+ * caller on success. res_de is set accordingly. >+ * >+ * If cont is non-zero, raw_found continues with the entry after the one >+ * res_bh/res_de point to. >+ */ >+static int fatx_raw_scan_sector(struct super_block *sb, int sector, >+ const char *name, int name_length, int *number, >+ loff_t *i_pos, struct buffer_head **res_bh, >+ struct fatx_dir_entry **res_de ) >+{ >+ struct buffer_head *bh; >+ struct fatx_dir_entry *data; >+ int entry,start,done = 0; >+ >+ PRINTK("FATX: fatx_raw_scan_sector: sector=%08lX\n",(long)sector); >+ >+ if (!(bh = sb_bread(sb,sector))) { >+ printk("FATX: fatx_raw_scan_sector: sb_bread failed\n"); >+ return -EIO; >+ } >+ data = (struct fatx_dir_entry *) bh->b_data; >+ for (entry = 0; entry < FATX_SB(sb)->dir_per_block; entry++) { >+ if (FATX_END_OF_DIR(&data[entry])) { >+ //no more entries to look through... >+ if(bh) brelse(bh); >+ PRINTK("FATX: fatx_raw_scan_sector: END OF DIR\n"); >+ return -ENOENT; >+ } else if (name) { //search for name >+ done = (data[entry].name_length == name_length) && >+ !strncmp(data[entry].name,name,name_length); >+ } else if (!i_pos) { /* count subdirectories */ >+ done = 0; >+ if (!FATX_IS_FREE(&data[entry]) && (data[entry].attr & ATTR_DIR)) >+ (*number)++; >+ } else if (number) { /* search for start cluster */ >+ done = !FATX_IS_FREE(&data[entry]) && >+ (CF_LE_L(data[entry].start) == *number); >+ } else { /* search for free entry */ >+ done = FATX_IS_FREE(&data[entry]); >+ } >+ if (done) { >+ if (i_pos) >+ *i_pos = sector * FATX_SB(sb)->dir_per_block + entry; >+ start = CF_LE_L(data[entry].start); >+ if (!res_bh) { >+ if(bh) brelse(bh); >+ } else { >+ *res_bh = bh; >+ *res_de = &data[entry]; >+ } >+ PRINTK("FATX: fatx_raw_scan_sector: found: start=%08lX\n",(long)start); >+ return start; >+ } >+ } >+ if(bh) brelse(bh); >+ PRINTK("FATX: fatx_raw_scan_sector: entry not in sector %08lX\n",(long)sector); >+ return -EAGAIN; >+} >+ >+/* >+ * raw_scan_root performs raw_scan_sector on the root directory until the >+ * requested entry is found or the end of the directory is reached. >+ */ >+static int fatx_raw_scan_root(struct super_block *sb, const char *name, >+ int name_length, int *number, loff_t *i_pos, >+ struct buffer_head **res_bh, struct fatx_dir_entry **res_de ) >+{ >+ int count,cluster; >+ >+ for (count = 0; count < FATX_SB(sb)->cluster_size; count++) { >+ if ((cluster = fatx_raw_scan_sector(sb,FATX_SB(sb)->dir_start + count, >+ name,name_length,number,i_pos,res_bh,res_de)) >= 0) >+ return cluster; >+ if (cluster == -ENOENT) { >+ //end of dir...act like all sectors scanned and !found >+ PRINTK("FATX: fatx_raw_scan_root cluster %d\n",cluster); >+ return cluster; >+ } >+ } >+ >+ PRINTK("FATX: fatx_raw_scan_root leave\n"); >+ >+ return -ENOENT; >+} >+ >+/* >+ * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the >+ * requested entry is found or the end of the directory is reached. >+ */ >+static int fatx_raw_scan_nonroot(struct super_block *sb, int start, >+ const char *name, int name_length, int *number, >+ loff_t *i_pos, struct buffer_head **res_bh, >+ struct fatx_dir_entry **res_de ) >+{ >+ int count,cluster; >+ >+ PRINTK("FATX: fatx_raw_scan_nonroot: entered (start=%08lX)\n",(long)start); >+ >+ do { >+ for (count = 0; count < FATX_SB(sb)->cluster_size; count++) { >+ if ((cluster = fatx_raw_scan_sector(sb,FATX_SB(sb)->data_start + >+ (FATX_SB(sb)->cluster_size * (start - 2) ) + count, >+ name,name_length,number,i_pos,res_bh,res_de)) >= 0) >+ return cluster; >+ if (cluster == -ENOENT) { >+ //EOD: act like all sectors scanned and !found >+ return cluster; >+ } >+ } >+ if (!(start = fatx_access(sb,start,-1))) { >+ printk("FATX: fatx_raw_scan_nonroot: start sector %lX not in use\n",(long)start); >+ fatx_fs_panic(sb,"FATX error"); >+ break; >+ } >+ } >+ while (start != -1); >+ return -ENOENT; >+} >+ >+/* >+ * Scans a directory for a given file (name points to its formatted name) or >+ * for an empty directory slot (name is NULL). Returns an error code or zero. >+ */ >+int fatx_scan(struct inode *dir, const char *name, int name_length, >+ struct buffer_head **res_bh, struct fatx_dir_entry **res_de, >+ loff_t *i_pos ) >+{ >+ int res; >+ >+ if (FATX_I(dir)->i_start) >+ res = fatx_raw_scan_nonroot(dir->i_sb,FATX_I(dir)->i_start,name,name_length,NULL,i_pos,res_bh,res_de); >+ else >+ res = fatx_raw_scan_root(dir->i_sb,name,name_length,NULL,i_pos,res_bh,res_de); >+ >+ return res<0 ? res : 0; >+} >+ >+/* >+ * See if directory is empty >+ */ >+int fatx_dir_empty(struct inode *dir) >+{ >+ loff_t pos; >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ loff_t i_pos; >+ int result = 0; >+ >+ pos = 0; >+ bh = NULL; >+ while (fatx_get_entry(dir,&pos,&bh,&de,&i_pos) > -1) { >+ if (FATX_END_OF_DIR(de)) { >+ break; >+ } >+ if (!FATX_IS_FREE(de)) { >+ result = -ENOTEMPTY; >+ break; >+ } >+ } >+ if (bh) >+ brelse(bh); >+ >+ return result; >+} >+ >+/* >+ * fatx_subdirs counts the number of sub-directories of dir. It can be run >+ * on directories being created. >+ */ >+int fatx_subdirs(struct inode *dir) >+{ >+ int count; >+ >+ count = 0; >+ if (dir->i_ino == FATX_ROOT_INO) { >+ fatx_raw_scan_root(dir->i_sb,NULL,0,&count,NULL,NULL,NULL); >+ } else { >+ if ((dir->i_ino != FATX_ROOT_INO) && !FATX_I(dir)->i_start) { >+ return 0; /* in mkdir */ >+ } else { >+ fatx_raw_scan_nonroot(dir->i_sb,FATX_I(dir)->i_start, >+ NULL,0,&count,NULL,NULL,NULL); >+ } >+ } >+ return count; >+} >+ >+int fatx_do_add_entry( >+ struct inode *dir, >+ struct buffer_head **bh, >+ struct fatx_dir_entry **de, >+ loff_t *i_pos) >+{ >+ loff_t offset, curr; >+ struct buffer_head *new_bh; >+ >+ offset = curr = 0; >+ *bh = NULL; >+ while (fatx_get_entry(dir,&curr,bh,de,i_pos) > -1) { >+ if (FATX_IS_FREE(*de)) { >+ PRINTK("FATX: fatx_do_add_entry: found free entry\n"); >+ return offset; >+ } >+ if (FATX_END_OF_DIR(*de)) { >+ struct buffer_head *eod_bh = NULL; >+ struct fatx_dir_entry *eod_de = NULL; >+ loff_t eod_i_pos; >+ >+ PRINTK("FATX: fatx_do_add_entry: found EOD at %lX\n",(long)(*de)); >+ //make sure the next one isn't first in new cluster >+ if (fatx_get_entry(dir,&curr,&eod_bh,&eod_de,&eod_i_pos) > -1) { >+ //EOD in same cluster...find proper de and mark new EOD >+ eod_de->name_length = 0xFF; >+ mark_buffer_dirty(eod_bh); >+ PRINTK("FATX: fatx_do_add_entry: marked new EOD at %lX\n",(long)eod_de); >+ if(eod_bh) brelse(eod_bh); >+ } else { >+ //we will take the easy out...do nothing... >+ //assume fat table used to indicate EOD >+ //if this is wrong, need to fatx_extend_dir >+ //making first entry in next cluster EOD >+ printk("FATX: fatx_do_add_entry: EOD marked by FAT\n"); >+ printk("FATX: ...:offset=%08lX, curr=%08lX\n", >+ (unsigned long)offset,(unsigned long)curr); >+ } >+ PRINTK("FATX: fatx_do_add_entry: using entry at %lX\n",(long)(*de)); >+ return offset; >+ } >+ offset = curr; >+ } >+ PRINTK("FATX: fatx_do_add_entry: need to extend dir\n"); >+ if (dir->i_ino == FATX_ROOT_INO) { >+ printk("FATX: fatx_do_add_entry: but it's root dir...can't extend\n"); >+ return -ENOSPC; >+ } >+ new_bh = fatx_extend_dir(dir); >+ if (!new_bh) { >+ PRINTK("FATX: fatx_do_add_entry: fatx_extend_dir failed...no space?\n"); >+ return -ENOSPC; >+ } >+ if(new_bh) brelse(new_bh); >+ fatx_get_entry(dir,&curr,bh,de,i_pos); >+ (*de)[1].name_length = 0xFF; >+ PRINTK("FATX: fatx_do_add_entry: using entry at %ld\n",(long)offset); >+ return offset; >+} >+ >+int fatx_new_dir(struct inode *dir, struct inode *parent) >+{ >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ >+ if ((bh = fatx_extend_dir(dir)) == NULL) { >+ printk("FATX: fatx_new_dir: failed to get new cluster...no space?\n"); >+ return -ENOSPC; >+ } >+ /* zeroed out, so... */ >+ de = (struct fatx_dir_entry*)&bh->b_data[0]; >+ de[0].attr = de[1].attr = ATTR_DIR; >+ de[0].name_length = 0xFF; //end of dir marker >+ de[0].start = CT_LE_W(FATX_I(dir)->i_logstart); >+ de[1].start = CT_LE_W(FATX_I(parent)->i_logstart); >+ mark_buffer_dirty(bh); >+ if(bh) brelse(bh); >+ dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; >+ mark_inode_dirty(dir); >+ >+ return 0; >+} >+ >+// sure to hope this is correct... >+int fatx_readdir(struct file *filp, void *dirent, filldir_t filldir) >+{ >+ struct inode *inode = filp->f_dentry->d_inode; >+ struct inode *tmpi; >+ struct super_block *sb = inode->i_sb; >+ struct fatx_dir_entry *de; >+ struct buffer_head *bh; >+ loff_t i_pos; >+ int inum; >+ loff_t cpos = 0; //file position (dir position) >+ int offset = 0; //cpos offset for root dir handling >+ int entry = 0; //next filldir entry location >+ >+ PRINTK("FATX: fatx_readdir entered\n"); >+ >+ cpos = filp->f_pos; >+ >+ if (cpos == 0) { >+ if (filldir(dirent,".",1,entry++,inode->i_ino,DT_DIR)<0) { >+ printk("\nFATX: fatx_readdir exiting in root defaults\n"); >+ return 0; >+ } >+ cpos += 1 << FATX_DIR_BITS; >+ } >+ >+ if (cpos == 1 << FATX_DIR_BITS) { >+ if (filldir(dirent,"..",2,entry++, >+ filp->f_dentry->d_parent->d_inode->i_ino,DT_DIR)<0) { >+ printk("\nFATX: fatx_readdir exiting in root defaults\n"); >+ filp->f_pos = 1 << FATX_DIR_BITS; >+ return 0; >+ } >+ cpos += 1 << FATX_DIR_BITS; >+ } >+ >+ offset = 2 << FATX_DIR_BITS; >+ cpos -= offset; >+ >+ bh = NULL; >+ >+ while(fatx_get_entry(inode,&cpos,&bh,&de,&i_pos) != -1) { >+ if (FATX_END_OF_DIR(de)) { >+ PRINTK("FATX: entry %ld marked as END OF DIR\n",(long)(cpos >> FATX_DIR_BITS)); >+ cpos -= 1 << FATX_DIR_BITS; // make sure it comes back to here if re-entered >+ break; //done...end of dir. >+ } >+ >+ if (FATX_IS_FREE(de)) { >+ PRINTK("FATX: entry %ld marked as FREE\n",(long)(cpos >> FATX_DIR_BITS)); >+ continue; >+ } >+ >+ tmpi = fatx_iget(sb, i_pos); >+ if (tmpi) { >+ inum = tmpi->i_ino; >+ iput(tmpi); >+ } else { >+ inum = iunique(sb, FATX_ROOT_INO); >+ } >+ >+ if (filldir(dirent,de->name,de->name_length,entry++,inum, >+ (de->attr & ATTR_DIR) ? DT_DIR : DT_REG ) < 0 ) { >+ break; >+ } >+ PRINTK("\nFATX: fatx_readdir: dir entry %3d: ",(int)entry); >+ fatx_printname(de->name,de->name_length); >+ PRINTK("\n"); >+ } >+ >+ filp->f_pos = cpos + offset; >+ if (bh) >+ brelse(bh); >+ >+ PRINTK("\nFATX: fatx_readdir leaving\n"); >+ >+ return 0; >+} >+ >+struct file_operations fatx_dir_operations = { >+ .read = generic_read_dir, >+ .readdir = fatx_readdir, >+ .ioctl = NULL, >+ .fsync = file_fsync, >+}; >+ >+/* This assumes that size of cluster is above the 32*slots */ >+ >+int fatx_add_entries(struct inode *dir,int slots, struct buffer_head **bh, >+ struct fatx_dir_entry **de, loff_t *i_pos) >+{ >+ loff_t offset, curr; >+ int row; >+ struct buffer_head *new_bh; >+ >+ offset = curr = 0; >+ *bh = NULL; >+ row = 0; >+ while (fatx_get_entry(dir,&curr,bh,de,i_pos) > -1) { >+ if (IS_FREE((*de)->name)) { >+ if (++row == slots) >+ return offset; >+ } else { >+ row = 0; >+ offset = curr; >+ } >+ } >+ if (dir->i_ino == FATX_ROOT_INO) >+ return -ENOSPC; >+ new_bh = fatx_extend_dir(dir); >+ if (!new_bh) >+ return -ENOSPC; >+ if(new_bh) brelse(new_bh); >+ do fatx_get_entry(dir,&curr,bh,de,i_pos); while (++row<slots); >+ return offset; >+} >diff -urN linux-2.6.6.orig/fs/fatx/fatxfs_syms.c linux-2.6.6/fs/fatx/fatxfs_syms.c >--- linux-2.6.6.orig/fs/fatx/fatxfs_syms.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/fatxfs_syms.c 2004-05-10 12:30:23.318926152 +0100 >@@ -0,0 +1,77 @@ >+/* >+ * linux/fs/fatx/fatxfs_syms.c >+ * >+ * Exported kernel symbols for the FATX filesystem. >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/module.h> >+#include <linux/mm.h> >+#include <linux/fatx_fs.h> >+#include <linux/init.h> >+ >+unsigned int fatx_debug = 0; >+ >+MODULE_PARM(fatx_debug,"i"); >+MODULE_PARM_DESC(fatx_debug,"turn on fatx debugging output"); >+ >+EXPORT_SYMBOL(fatx_lookup); >+EXPORT_SYMBOL(fatx_create); >+EXPORT_SYMBOL(fatx_rmdir); >+EXPORT_SYMBOL(fatx_mkdir); >+EXPORT_SYMBOL(fatx_rename); >+EXPORT_SYMBOL(fatx_unlink); >+ >+EXPORT_SYMBOL(fatx_new_dir); >+EXPORT_SYMBOL(fatx_get_block); >+EXPORT_SYMBOL(fatx_clear_inode); >+EXPORT_SYMBOL(fatx_date_unix2dos); >+EXPORT_SYMBOL(fatx_delete_inode); >+EXPORT_SYMBOL(fatx_get_entry); >+EXPORT_SYMBOL(fatx_notify_change); >+EXPORT_SYMBOL(fatx_put_super); >+EXPORT_SYMBOL(fatx_attach); >+EXPORT_SYMBOL(fatx_detach); >+EXPORT_SYMBOL(fatx_build_inode); >+EXPORT_SYMBOL(fatx_fill_super); >+EXPORT_SYMBOL(fatx_readdir); >+EXPORT_SYMBOL(fatx_scan); >+EXPORT_SYMBOL(fatx_statfs); >+EXPORT_SYMBOL(fatx_write_inode); >+EXPORT_SYMBOL(fatx_get_cluster); >+EXPORT_SYMBOL(fatx_add_entries); >+EXPORT_SYMBOL(fatx_dir_empty); >+EXPORT_SYMBOL(fatx_truncate); >+ >+static struct super_block *fatx_get_sb(struct file_system_type *fs_type, >+ int flags, const char *dev_name, void *data) >+{ >+ return get_sb_bdev(fs_type, flags, dev_name, data, fatx_fill_super); >+} >+ >+static struct file_system_type fatx_fs_type = { >+ .owner = THIS_MODULE, >+ .name = "fatx", >+ .get_sb = fatx_get_sb, >+ .kill_sb = kill_block_super, >+ .fs_flags = FS_REQUIRES_DEV, >+}; >+ >+static int __init init_fatx_fs(void) >+{ >+ printk("FATX driver Version 0.1.0\n"); >+ fatx_hash_init(); >+ return register_filesystem(&fatx_fs_type); >+} >+ >+static void __exit exit_fatx_fs(void) >+{ >+ unregister_filesystem(&fatx_fs_type); >+} >+ >+module_init(init_fatx_fs) >+module_exit(exit_fatx_fs) >+MODULE_LICENSE("GPL"); >+ >diff -urN linux-2.6.6.orig/fs/fatx/file.c linux-2.6.6/fs/fatx/file.c >--- linux-2.6.6.orig/fs/fatx/file.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/file.c 2004-05-10 12:30:23.320925848 +0100 >@@ -0,0 +1,103 @@ >+/* >+ * linux/fs/fatx/file.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/sched.h> >+#include <linux/fs.h> >+#include <linux/fatx_fs.h> >+#include <linux/errno.h> >+#include <linux/fcntl.h> >+#include <linux/stat.h> >+#include <linux/string.h> >+#include <linux/pagemap.h> >+ >+#include <asm/uaccess.h> >+#include <asm/system.h> >+ >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+struct file_operations fatx_file_operations = { >+ .llseek = generic_file_llseek, >+ .read = generic_file_read, >+ .write = fatx_file_write, >+ .mmap = generic_file_mmap, >+ .fsync = file_fsync, >+ .readv = generic_file_readv, >+ .writev = generic_file_writev, >+ .sendfile = generic_file_sendfile, >+}; >+ >+struct inode_operations fatx_file_inode_operations = { >+ .truncate = fatx_truncate, >+ .setattr = fatx_notify_change, >+}; >+ >+int fatx_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) >+{ >+ struct super_block *sb = inode->i_sb; >+ unsigned long phys; >+ >+ phys = fatx_bmap(inode, iblock); >+ if (phys) { >+ map_bh(bh_result, sb, phys); >+ return 0; >+ } >+ if (!create) >+ return 0; >+ if (iblock << sb->s_blocksize_bits != FATX_I(inode)->mmu_private) { >+ BUG(); >+ return -EIO; >+ } >+ if (!(iblock % FATX_SB(inode->i_sb)->cluster_size)) { >+ if (fatx_add_cluster(inode) < 0) >+ return -ENOSPC; >+ } >+ FATX_I(inode)->mmu_private += sb->s_blocksize; >+ phys = fatx_bmap(inode, iblock); >+ if (!phys) >+ BUG(); >+ set_buffer_new(bh_result); >+ map_bh(bh_result, sb, phys); >+ return 0; >+} >+ >+ssize_t fatx_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) >+{ >+ struct inode *inode = filp->f_dentry->d_inode; >+ int retval; >+ >+ retval = generic_file_write(filp, buf, count, ppos); >+ if (retval > 0) { >+ inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME; >+ FATX_I(inode)->i_attrs |= ATTR_ARCH; >+ mark_inode_dirty(inode); >+ } >+ return retval; >+} >+ >+void fatx_truncate(struct inode *inode) >+{ >+ struct fatx_sb_info *sbi = FATX_SB(inode->i_sb); >+ int cluster; >+ >+ /* Why no return value? Surely the disk could fail... */ >+ if (IS_RDONLY (inode)) >+ return /* -EPERM */; >+ if (IS_IMMUTABLE(inode)) >+ return /* -EPERM */; >+ cluster = 1 << sbi->cluster_bits; >+ /* >+ * This protects against truncating a file bigger than it was then >+ * trying to write into the hole. >+ */ >+ if (FATX_I(inode)->mmu_private > inode->i_size) >+ FATX_I(inode)->mmu_private = inode->i_size; >+ >+ fatx_free(inode, (inode->i_size + (cluster - 1)) >> sbi->cluster_bits); >+ FATX_I(inode)->i_attrs |= ATTR_ARCH; >+ inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME; >+ mark_inode_dirty(inode); >+} >diff -urN linux-2.6.6.orig/fs/fatx/inode.c linux-2.6.6/fs/fatx/inode.c >--- linux-2.6.6.orig/fs/fatx/inode.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/inode.c 2004-05-10 12:30:23.325925088 +0100 >@@ -0,0 +1,671 @@ >+/* >+ * linux/fs/fatx/inode.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/module.h> >+#include <linux/time.h> >+#include <linux/slab.h> >+#include <linux/smp_lock.h> >+#include <linux/seq_file.h> >+ >+#include <linux/fatx_fs.h> >+#include <linux/fatx_fs_sb.h> >+ >+#include <linux/pagemap.h> >+#include <linux/buffer_head.h> >+#include <linux/mount.h> >+#include <linux/vfs.h> >+#include <linux/parser.h> >+#include <asm/unaligned.h> >+ >+ >+#ifndef CONFIG_NLS_DEFAULT >+#define CONFIG_NLS_DEFAULT "iso8859-15" >+#endif >+ >+#define FAT_HASH_BITS 8 >+#define FAT_HASH_SIZE (1UL << FAT_HASH_BITS) >+#define FAT_HASH_MASK (FAT_HASH_SIZE-1) >+ >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+static int fatx_writepage(struct page *page, struct writeback_control *wbc) >+{ >+ return block_write_full_page(page,fatx_get_block, wbc); >+} >+ >+static int fatx_readpage(struct file *file, struct page *page) >+{ >+ return block_read_full_page(page,fatx_get_block); >+} >+ >+static int fatx_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) >+{ >+ return cont_prepare_write(page,from,to,fatx_get_block, >+ &FATX_I(page->mapping->host)->mmu_private); >+} >+ >+static sector_t _fatx_bmap(struct address_space *mapping, sector_t block) >+{ >+ return generic_block_bmap(mapping,block,fatx_get_block); >+} >+ >+static int fatx_commit_write(struct file *file, struct page *page, unsigned from, unsigned to) >+{ >+ kunmap(page); >+ return generic_commit_write(file, page, from, to); >+} >+ >+struct address_space_operations fatx_aops = { >+ .readpage = fatx_readpage, >+ .writepage = fatx_writepage, >+ .sync_page = block_sync_page, >+ .prepare_write = fatx_prepare_write, >+ .commit_write = fatx_commit_write, >+ .bmap = _fatx_bmap >+}; >+ >+void fatx_put_super(struct super_block *sb) >+{ >+ fatx_cache_inval_dev(sb->s_dev); >+ set_blocksize(sb->s_bdev,BLOCK_SIZE); >+ if (FATX_SB(sb)->nls_io) { >+ unload_nls(FATX_SB(sb)->nls_io); >+ FATX_SB(sb)->nls_io = NULL; >+ } >+} >+ >+static struct list_head fatx_inode_hashtable[FAT_HASH_SIZE]; >+spinlock_t fatx_inode_lock = SPIN_LOCK_UNLOCKED; >+ >+void fatx_hash_init(void) >+{ >+ int i; >+ for(i = 0; i < FAT_HASH_SIZE; i++) { >+ INIT_LIST_HEAD(&fatx_inode_hashtable[i]); >+ } >+} >+ >+static inline unsigned long fatx_hash(struct super_block *sb, int i_pos) >+{ >+ unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb; >+ tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2); >+ return tmp & FAT_HASH_MASK; >+} >+ >+void fatx_attach(struct inode *inode, loff_t i_pos) >+{ >+ spin_lock(&fatx_inode_lock); >+ FATX_I(inode)->i_pos = i_pos; >+ list_add(&FATX_I(inode)->i_fat_hash, >+ fatx_inode_hashtable + fatx_hash(inode->i_sb, i_pos)); >+ spin_unlock(&fatx_inode_lock); >+} >+ >+void fatx_detach(struct inode *inode) >+{ >+ spin_lock(&fatx_inode_lock); >+ FATX_I(inode)->i_pos = 0; >+ list_del(&FATX_I(inode)->i_fat_hash); >+ INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash); >+ spin_unlock(&fatx_inode_lock); >+} >+ >+struct inode *fatx_iget(struct super_block *sb, loff_t i_pos) >+{ >+ struct list_head *p = fatx_inode_hashtable + fatx_hash(sb, i_pos); >+ struct list_head *walk; >+ struct fatx_inode_info *i; >+ struct inode *inode = NULL; >+ >+ spin_lock(&fatx_inode_lock); >+ list_for_each(walk, p) { >+ i = list_entry(walk, struct fatx_inode_info, i_fat_hash); >+ if (i->i_fat_inode->i_sb != sb) >+ continue; >+ if (i->i_pos != i_pos) >+ continue; >+ inode = igrab(i->i_fat_inode); >+ if (inode) >+ break; >+ } >+ spin_unlock(&fatx_inode_lock); >+ return inode; >+} >+ >+/* doesn't deal with root inode */ >+static void fatx_fill_inode(struct inode *inode, struct fatx_dir_entry *de) >+{ >+ struct super_block *sb = inode->i_sb; >+ struct fatx_sb_info *sbi = FATX_SB(sb); >+ int nr; >+ >+ INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash); >+ FATX_I(inode)->i_pos = 0; >+ FATX_I(inode)->i_fat_inode = inode; >+ inode->i_uid = sbi->options.fs_uid; >+ inode->i_gid = sbi->options.fs_gid; >+ inode->i_version++; >+ inode->i_generation = get_seconds(); >+ >+ if ((de->attr & ATTR_DIR) && !FATX_IS_FREE(de)) { >+ inode->i_generation &= ~1; >+ inode->i_mode = FATX_MKMODE(de->attr,S_IRWXUGO & >+ ~sbi->options.fs_umask) | S_IFDIR; >+ inode->i_op = sbi->dir_ops; >+ inode->i_fop = &fatx_dir_operations; >+ >+ FATX_I(inode)->i_start = CF_LE_L(de->start); >+ FATX_I(inode)->i_logstart = FATX_I(inode)->i_start; >+ inode->i_nlink = fatx_subdirs(inode) + 2; >+ /* includes .., compensating for "self" */ >+#ifdef DEBUG >+ if (!inode->i_nlink) { >+ printk("directory %d: i_nlink == 0\n",inode->i_ino); >+ inode->i_nlink = 1; >+ } >+#endif >+ if ((nr = FATX_I(inode)->i_start) != 0) >+ while (nr != -1) { >+ inode->i_size += 1 << sbi->cluster_bits; >+ if (!(nr = fatx_access(sb, nr, -1))) { >+ printk("Directory %ld: bad FAT\n", >+ inode->i_ino); >+ break; >+ } >+ } >+ FATX_I(inode)->mmu_private = inode->i_size; >+ } else { /* not a directory */ >+ inode->i_generation |= 1; >+ inode->i_mode = FATX_MKMODE(de->attr,S_IRWXUGO & ~sbi->options.fs_umask) | S_IFREG; >+ FATX_I(inode)->i_start = CF_LE_L(de->start); >+ FATX_I(inode)->i_logstart = FATX_I(inode)->i_start; >+ inode->i_size = CF_LE_L(de->size); >+ inode->i_op = &fatx_file_inode_operations; >+ inode->i_fop = &fatx_file_operations; >+ inode->i_mapping->a_ops = &fatx_aops; >+ FATX_I(inode)->mmu_private = inode->i_size; >+ } >+ FATX_I(inode)->i_attrs = de->attr & ATTR_UNUSED; >+ /* this is as close to the truth as we can get ... */ >+ inode->i_blksize = 1 << sbi->cluster_bits; >+ inode->i_blocks = ((inode->i_size + inode->i_blksize - 1) >+ & ~(inode->i_blksize - 1)) >> 9; >+ inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = >+ fatx_date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date)); >+ inode->i_ctime.tv_nsec = fatx_date_dos2unix(CF_LE_W(de->ctime),CF_LE_W(de->cdate)); >+} >+ >+struct inode *fatx_build_inode( struct super_block *sb, struct fatx_dir_entry *de, loff_t i_pos, int *res ) >+{ >+ struct inode *inode; >+ *res = 0; >+ inode = fatx_iget(sb, i_pos); >+ if (inode) >+ goto out; >+ inode = new_inode(sb); >+ *res = -ENOMEM; >+ if (!inode) >+ goto out; >+ *res = 0; >+ inode->i_ino = iunique(sb, FATX_ROOT_INO); >+ inode->i_version = 1; >+ fatx_fill_inode(inode, de); >+ fatx_attach(inode, i_pos); >+ insert_inode_hash(inode); >+out: >+ return inode; >+} >+ >+/* >+ * parse super block values out of FATX "boot block" >+ * unlike the other FAT variants, much of the data is calculated from the >+ * the partition information. >+ */ >+int fatx_parse_boot_block ( struct super_block *sb, struct buffer_head *bh ) >+{ >+ struct fatx_boot_sector *b = (struct fatx_boot_sector *)bh->b_data; >+ struct fatx_sb_info *sbi = FATX_SB(sb); >+ int logical_sector_size, hard_blksize; >+ unsigned int total_sectors; >+ unsigned long cl_count; >+ unsigned long fat_length; >+ >+ PRINTK("FATX: entered fatx_parse_boot_block\n"); >+ >+ if (b->magic != FATX_BOOTBLOCK_MAGIC) { >+ printk("FATX: boot block signature not found. Not FATX?\n"); >+ return -1; >+ } >+ >+ PRINTK("FATX: fatx_magic: %08lX\n",(unsigned long)b->magic); >+ >+ logical_sector_size = 512; >+ >+ sbi->cluster_size = CLUSTER_SIZE; >+ >+ PRINTK("FATX: cluster_size: %d\n",(int)sbi->cluster_size); >+ >+ //sb->s_block_size enters as hardware block (sector) size >+ hard_blksize = sb->s_blocksize; >+ sb->s_blocksize = logical_sector_size; >+ sb->s_blocksize_bits = ffs(logical_sector_size) - 1; >+ >+ //figure total sector count >+ //total_sectors = fatx_get_total_size(sb); >+ total_sectors = sb->s_bdev->bd_inode->i_size >> 9; >+ >+ PRINTK("FATX: total_sectors for given device: %ld\n",(unsigned long)total_sectors); >+ >+ sbi->cluster_bits = 14; >+ sbi->fats = 1; >+ >+ //hmm...fat should start right after boot block sectors (first 8) >+ sbi->fat_start = 8; //this might be: + CF_LE_W(b->fatx_unknown) >+ sbi->root_cluster = 0; >+ sbi->dir_per_block = logical_sector_size/sizeof(struct fatx_dir_entry); >+ sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; >+ sbi->dir_entries = 256; >+ >+ //check cluster count >+ >+ cl_count = total_sectors / sbi->cluster_size; >+ >+ if( cl_count >= 0xfff4 ) { >+ //FATX-32 >+ sb->s_maxbytes = FATX32_MAX_NON_LFS; >+ sbi->fat_bits = 32; >+ } else { >+ //FATX-16 >+ sb->s_maxbytes = FATX16_MAX_NON_LFS; >+ sbi->fat_bits = 16; >+ } >+ >+ fat_length = cl_count * (sbi->fat_bits>>3); >+ if(fat_length % 4096) { >+ fat_length = ((fat_length / 4096) + 1) * 4096; >+ } >+ sbi->fat_length = fat_length / logical_sector_size; >+ >+ sbi->dir_start = sbi->fat_start + sbi->fat_length; >+ sbi->data_start = sbi->dir_start + CLUSTER_SIZE; >+ sbi->clusters = ((total_sectors-sbi->data_start) / sbi->cluster_size); >+ sbi->free_clusters = -1; /* Don't know yet */ >+ >+ PRINTK("FATX: logical_sector_size: %d\n",(int)logical_sector_size); >+ PRINTK("FATX: fat_length: %d\n",(int)sbi->fat_length); >+ PRINTK("FATX: spc_bits: %d\n",sbi->fat_bits>>3); >+ PRINTK("FATX: fat_start: %d\n",(int)sbi->fat_start); >+ PRINTK("FATX: dir_start: %d\n",(int)sbi->dir_start); >+ PRINTK("FATX: data_start: %d\n",(int)sbi->data_start); >+ PRINTK("FATX: clusters: %ld\n",(unsigned long)sbi->clusters); >+ PRINTK("FATX: fat_bits: %d\n",(int)sbi->fat_bits); >+ PRINTK("FATX: fat_length: %d\n",(int)sbi->fat_length); >+ PRINTK("FATX: root_dir_sectors: %d\n",(int)CLUSTER_SIZE); >+ PRINTK("FATX: dir_per_block: %d\n",(int)sbi->dir_per_block); >+ PRINTK("FATX: dir_per_block_bits: %d\n",(int)sbi->dir_per_block_bits); >+ PRINTK("FATX: dir_entries : %d\n",(int)sbi->dir_entries); >+ PRINTK("FATX: cluster_bits: %d\n",(int)sbi->cluster_bits); >+ >+ PRINTK("FATX: leaving fatx_parse_boot_block\n"); >+ >+ return 0; >+} >+ >+static void fatx_read_root(struct inode *inode) >+{ >+ struct super_block *sb = inode->i_sb; >+ struct fatx_sb_info *sbi = FATX_SB(sb); >+ >+ INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash); >+ FATX_I(inode)->i_pos = 0; >+ FATX_I(inode)->i_fat_inode = inode; >+ inode->i_uid = sbi->options.fs_uid; >+ inode->i_gid = sbi->options.fs_gid; >+ inode->i_version = 1; >+ inode->i_generation = 0; >+ inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR; >+ inode->i_op = sbi->dir_ops; >+ inode->i_fop = &fatx_dir_operations; >+ >+ FATX_I(inode)->i_start = FATX_ROOT_INO; >+ inode->i_size = sbi->dir_entries * sizeof(struct fatx_dir_entry); >+ >+ inode->i_blksize = 1 << sbi->cluster_bits; >+ inode->i_blocks = ((inode->i_size + inode->i_blksize - 1) >+ & ~(inode->i_blksize - 1)) >> 9; >+ FATX_I(inode)->i_logstart = 0; >+ FATX_I(inode)->mmu_private = inode->i_size; >+ >+ FATX_I(inode)->i_attrs = 0; >+ inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0; >+ inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0; >+ FATX_I(inode)->i_ctime_ms = 0; >+ inode->i_nlink = fatx_subdirs(inode) + 2; >+} >+ >+/* The public inode operations for the fatx fs */ >+struct inode_operations fatx_dir_inode_operations = { >+ .create = fatx_create, >+ .lookup = fatx_lookup, >+ .unlink = fatx_unlink, >+ .mkdir = fatx_mkdir, >+ .rmdir = fatx_rmdir, >+ .rename = fatx_rename, >+ .setattr = fatx_notify_change, >+}; >+ >+void fatx_write_inode(struct inode *inode, int wait) >+{ >+ struct super_block *sb = inode->i_sb; >+ struct buffer_head *bh; >+ struct fatx_dir_entry *raw_entry; >+ unsigned int i_pos; >+ >+ PRINTK("FATX: fatx_write_inode: entered\n"); >+ >+retry: >+ i_pos = FATX_I(inode)->i_pos; >+ if (inode->i_ino == FATX_ROOT_INO || !i_pos) { >+ return; >+ } >+ lock_kernel(); >+ if (!(bh = sb_bread(sb, i_pos >> FATX_SB(sb)->dir_per_block_bits))) { >+ PRINTK("dev = %s, ino = %d\n", sb->s_id, i_pos); >+ fatx_fs_panic(sb, "fatx_write_inode: unable to read i-node block"); >+ unlock_kernel(); >+ return; >+ } >+ spin_lock(&fatx_inode_lock); >+ if (i_pos != FATX_I(inode)->i_pos) { >+ spin_unlock(&fatx_inode_lock); >+ if(bh) brelse(bh); >+ unlock_kernel(); >+ goto retry; >+ } >+ >+ raw_entry = &((struct fatx_dir_entry *) (bh->b_data)) >+ [i_pos & (FATX_SB(sb)->dir_per_block - 1)]; >+ if (S_ISDIR(inode->i_mode)) { >+ raw_entry->attr = ATTR_DIR; >+ raw_entry->size = 0; >+ } >+ else { >+ raw_entry->attr = ATTR_NONE; >+ raw_entry->size = CT_LE_L(inode->i_size); >+ } >+ raw_entry->attr |= FATX_MKATTR(inode->i_mode) | >+ FATX_I(inode)->i_attrs; >+ raw_entry->start = CT_LE_L(FATX_I(inode)->i_logstart); >+ >+ PRINTK("FATX: fatx_write_inode: start == %08lX (LE=%08lX)\n", >+ (long)FATX_I(inode)->i_logstart, >+ (long)CT_LE_L(FATX_I(inode)->i_logstart)); >+ >+ fatx_date_unix2dos(inode->i_mtime.tv_sec,&raw_entry->time,&raw_entry->date); >+ raw_entry->time = CT_LE_W(raw_entry->time); >+ raw_entry->date = CT_LE_W(raw_entry->date); >+ >+ fatx_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate); >+ raw_entry->ctime = CT_LE_W(raw_entry->ctime); >+ raw_entry->cdate = CT_LE_W(raw_entry->cdate); >+ raw_entry->atime = CT_LE_W(raw_entry->ctime); >+ raw_entry->adate = CT_LE_W(raw_entry->cdate); >+ >+ spin_unlock(&fatx_inode_lock); >+ mark_buffer_dirty(bh); >+ if(bh) brelse(bh); >+ unlock_kernel(); >+ >+ PRINTK("FATX: fatx_write_inode: leaving\n"); >+} >+ >+int fatx_statfs(struct super_block *sb,struct kstatfs *buf) >+{ >+ int free,nr; >+ >+ lock_fatx(sb); >+ if (FATX_SB(sb)->free_clusters != -1) >+ free = FATX_SB(sb)->free_clusters; >+ else { >+ free = 0; >+ for (nr = 2; nr < FATX_SB(sb)->clusters+2; nr++) >+ if (!fatx_access(sb,nr,-1)) free++; >+ FATX_SB(sb)->free_clusters = free; >+ } >+ unlock_fatx(sb); >+ buf->f_type = sb->s_magic; >+ buf->f_bsize = 1 << FATX_SB(sb)->cluster_bits; >+ buf->f_blocks = FATX_SB(sb)->clusters; >+ buf->f_bfree = free; >+ buf->f_bavail = free; >+ buf->f_namelen = FATX_MAX_NAME_LENGTH; >+ return 0; >+} >+ >+ >+void fatx_delete_inode(struct inode *inode) >+{ >+ if (!is_bad_inode(inode)) { >+ lock_kernel(); >+ inode->i_size = 0; >+ fatx_truncate(inode); >+ unlock_kernel(); >+ } >+ clear_inode(inode); >+} >+ >+void fatx_clear_inode(struct inode *inode) >+{ >+ if (is_bad_inode(inode)) >+ return; >+ lock_kernel(); >+ spin_lock(&fatx_inode_lock); >+ fatx_cache_inval_inode(inode); >+ list_del(&FATX_I(inode)->i_fat_hash); >+ spin_unlock(&fatx_inode_lock); >+ unlock_kernel(); >+} >+ >+static struct super_operations fatx_sops = { >+ .write_inode = fatx_write_inode, >+ .delete_inode = fatx_delete_inode, >+ .put_super = fatx_put_super, >+ .statfs = fatx_statfs, >+ .clear_inode = fatx_clear_inode, >+ .read_inode = make_bad_inode, >+}; >+ >+enum { >+ Opt_uid, Opt_gid, Opt_umask, Opt_quiet, Opt_err, >+}; >+ >+static match_table_t fat_tokens = { >+ {Opt_uid, "uid=%u"}, >+ {Opt_gid, "gid=%u"}, >+ {Opt_umask, "umask=%o"}, >+ {Opt_quiet, "quiet"}, >+ {Opt_err, NULL} >+}; >+ >+static int parse_options(char *options,struct fatx_mount_options *opts) >+{ >+ char *p; >+ substring_t args[MAX_OPT_ARGS]; >+ int option; >+ >+ opts->fs_uid = current->uid; >+ opts->fs_gid = current->gid; >+ opts->fs_umask = current->fs->umask; >+ >+ while ((p = strsep(&options, ",")) != NULL) { >+ int token; >+ if (!*p) >+ continue; >+ token = match_token(p, fat_tokens, args); >+ switch(token) { >+ case Opt_quiet: >+ opts->quiet = 1; >+ break; >+ case Opt_uid: >+ if (match_int(&args[0], &option)) >+ return 0; >+ opts->fs_uid = option; >+ break; >+ case Opt_gid: >+ if (match_int(&args[0], &option)) >+ return 0; >+ opts->fs_gid = option; >+ break; >+ case Opt_umask: >+ if (match_octal(&args[0], &option)) >+ return 0; >+ opts->fs_umask = option; >+ break; >+ default: >+ printk(KERN_ERR "FATX: Unrecognized mount option \"%s\" " >+ "or missing value\n", p); >+ return 0; >+ } >+ } >+ return 1; >+} >+ >+int fatx_fill_super(struct super_block *sb,void *data, int silent) >+{ >+ struct inode *root_inode; >+ struct buffer_head *bh; >+ struct fatx_sb_info *sbi; >+ int hard_blksize; >+ int error; >+ >+ PRINTK("FATX: entering fatx_fill_super\n"); >+ >+ sbi = kmalloc(sizeof(struct fatx_sb_info), GFP_KERNEL); >+ if (!sbi) >+ return -ENOMEM; >+ sb->s_fs_info = sbi; >+ memset(sbi, 0, sizeof(struct fatx_sb_info)); >+ sbi->private_data = NULL; >+ >+ sbi->dir_ops = &fatx_dir_inode_operations; >+ >+ sb->s_op = &fatx_sops; >+ >+ hard_blksize = 512; >+ >+ //store fat value parsed into fatx_bits...possibly overridden later >+ sbi->fat_bits = 0; >+ >+ error = -EINVAL; >+ if (!parse_options((char *) data, &(sbi->options))) >+ goto out_fail; >+ >+ fatx_cache_init(); >+ >+ error = -EIO; >+ >+ sb_min_blocksize(sb, 512); >+// sb_set_blocksize(sb, hard_blksize); >+ bh = sb_bread(sb, 0); >+ if (bh == NULL) { >+ PRINTK("FATX: unable to read boot sector\n"); >+ goto out_fail; >+ } >+ >+ // insert call(s) to superblock parsing >+ error = fatx_parse_boot_block(sb,bh); >+ brelse(bh); >+ >+ if (error) >+ goto out_invalid; >+ >+ sb_set_blocksize(sb, sb->s_blocksize); >+ >+ sb->s_magic = FATX_BOOTBLOCK_MAGIC; >+ /* set up enough so that it can read an inode */ >+ init_MUTEX(&sbi->fatx_lock); >+ sbi->prev_free = 0; >+ >+ >+ sbi->nls_io = NULL; >+ if (! sbi->nls_io) >+ sbi->nls_io = load_nls_default(); >+ >+ root_inode = new_inode(sb); >+ if (!root_inode) >+ goto out_unload_nls; >+ root_inode->i_ino = FATX_ROOT_INO; >+ fatx_read_root(root_inode); >+ insert_inode_hash(root_inode); >+ sb->s_root = d_alloc_root(root_inode); >+ if (!sb->s_root) >+ goto out_no_root; >+ >+ PRINTK("FATX: leave fatx_fill_super\n"); >+ >+ return 0; >+ >+out_no_root: >+ PRINTK("FATX: get root inode failed\n"); >+ iput(root_inode); >+out_unload_nls: >+ unload_nls(sbi->nls_io); >+ goto out_fail; >+out_invalid: >+ error = -EINVAL; >+ if (!silent) { >+ PRINTK("VFS: Can't find a valid FAT filesystem on dev %s.\n", >+ sb->s_id); >+ } >+out_fail: >+ if(sbi->private_data) >+ kfree(sbi->private_data); >+ sbi->private_data = NULL; >+ kfree(sbi); >+ return error; >+} >+ >+int fatx_notify_change(struct dentry * dentry, struct iattr * attr) >+{ >+ struct super_block *sb = dentry->d_sb; >+ struct inode *inode = dentry->d_inode; >+ int error; >+ >+ /* FAT cannot truncate to a longer file */ >+ if (attr->ia_valid & ATTR_SIZE) { >+ if (attr->ia_size > inode->i_size) >+ return -EPERM; >+ } >+ >+ error = inode_change_ok(inode, attr); >+ if (error) >+ return FATX_SB(sb)->options.quiet ? 0 : error; >+ >+ if (((attr->ia_valid & ATTR_UID) && >+ (attr->ia_uid != FATX_SB(sb)->options.fs_uid)) || >+ ((attr->ia_valid & ATTR_GID) && >+ (attr->ia_gid != FATX_SB(sb)->options.fs_gid)) || >+ ((attr->ia_valid & ATTR_MODE) && >+ (attr->ia_mode & ~FATX_VALID_MODE))) >+ error = -EPERM; >+ >+ if (error) >+ return FATX_SB(sb)->options.quiet ? 0 : error; >+ >+ error = inode_setattr(inode, attr); >+ if (error) >+ return error; >+ >+ if (S_ISDIR(inode->i_mode)) >+ inode->i_mode |= S_IXUGO; >+ >+ inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU >+ & ~FATX_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) & >+ ~FATX_SB(sb)->options.fs_umask; >+ return 0; >+} >+ >diff -urN linux-2.6.6.orig/fs/fatx/misc.c linux-2.6.6/fs/fatx/misc.c >--- linux-2.6.6.orig/fs/fatx/misc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/misc.c 2004-05-10 12:30:23.328924632 +0100 >@@ -0,0 +1,272 @@ >+/* >+ * linux/fs/fatx/misc.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#include <linux/fatx_fs.h> >+#include <linux/sched.h> >+#include <linux/kernel.h> >+#include <linux/errno.h> >+#include <linux/string.h> >+#include <linux/stat.h> >+#include <linux/time.h> >+#include <linux/types.h> >+ >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+/* >+ * fatx_fs_panic reports a severe file system problem and sets the file system >+ * read-only. The file system can be made writable again by remounting it. >+ */ >+ >+void fatx_fs_panic(struct super_block *s,const char *msg) >+{ >+ int not_ro; >+ >+ not_ro = !(s->s_flags & MS_RDONLY); >+ if (not_ro) s->s_flags |= MS_RDONLY; >+ printk("Filesystem panic (dev %s).\n %s\n", s->s_id, msg); >+ if (not_ro) >+ printk(" File system has been set read-only\n"); >+} >+ >+static int day_n[] = { 0, 31, 59, 90,120,151,181,212,243,273,304,334,0,0,0,0 }; >+ /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ >+ >+extern struct timezone sys_tz; >+ >+int fatx_date_dos2unix(unsigned short time,unsigned short date) >+{ >+ int month,year,secs,days; >+ >+ /* first subtract and mask after that... Otherwise, if >+ date == 0, bad things happen */ >+ month= ((date >> 5) - 1) & 15; >+ year = date >> 9; >+ days = (date & 31)-1+day_n[month]+(year/4)+(year+30)*365; >+ //skipped and current leap years >+ days += ((year & 3) == 0 && month < 2 ? 0 : 1) + 7; >+ >+ secs = (time & 31)*2; //seconds into curr minute >+ secs += 60*((time >> 5) & 63); //minutes into curr hour >+ secs += 3600*(time >> 11); //hours into curr day >+ secs += 86400*days; //days (from 1.1.70) >+ >+ secs += sys_tz.tz_minuteswest*60; >+ return secs; >+} >+ >+ >+/* >+ * fat_add_cluster tries to allocate a new cluster and adds it to the >+ * file represented by inode. >+ */ >+int fatx_add_cluster(struct inode *inode) >+{ >+ struct super_block *sb = inode->i_sb; >+ int count, nr, limit, last, curr, file_cluster; >+ int cluster_size = FATX_SB(sb)->cluster_size; >+ int res = -ENOSPC; >+ >+ lock_fatx(sb); >+ >+ if (FATX_SB(sb)->free_clusters == 0) { >+ unlock_fatx(sb); >+ return res; >+ } >+ limit = FATX_SB(sb)->clusters; >+ nr = limit; /* to keep GCC happy */ >+ for (count = 0; count < limit; count++) { >+ nr = ((count + FATX_SB(sb)->prev_free) % limit) + 2; >+ if (fatx_access(sb, nr, -1) == 0) >+ break; >+ } >+ if (count >= limit) { >+ FATX_SB(sb)->free_clusters = 0; >+ unlock_fatx(sb); >+ return res; >+ } >+ >+ FATX_SB(sb)->prev_free = (count + FATX_SB(sb)->prev_free + 1) % limit; >+ fatx_access(sb, nr, EOF_FAT(sb)); >+ if (FATX_SB(sb)->free_clusters != -1) >+ FATX_SB(sb)->free_clusters--; >+ >+ unlock_fatx(sb); >+ >+ /* We must locate the last cluster of the file to add this >+ new one (nr) to the end of the link list (the FAT). >+ >+ Here file_cluster will be the number of the last cluster of the >+ file (before we add nr). >+ >+ last is the corresponding cluster number on the disk. We will >+ use last to plug the nr cluster. We will use file_cluster to >+ update the cache. >+ */ >+ last = file_cluster = 0; >+ if ((curr = FATX_I(inode)->i_start) != 0) { >+ fatx_cache_lookup(inode, INT_MAX, &last, &curr); >+ file_cluster = last; >+ while (curr && curr != -1){ >+ file_cluster++; >+ if (!(curr = fatx_access(sb, last = curr,-1))) { >+ fatx_fs_panic(sb, "File without EOF"); >+ return res; >+ } >+ } >+ } >+ if (last) { >+ fatx_access(sb, last, nr); >+ fatx_cache_add(inode, file_cluster, nr); >+ } else { >+ FATX_I(inode)->i_start = nr; >+ FATX_I(inode)->i_logstart = nr; >+ mark_inode_dirty(inode); >+ } >+ if (file_cluster >+ != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) { >+ printk ("file_cluster badly computed!!! %d <> %ld\n", >+ file_cluster, >+ inode->i_blocks / cluster_size / (sb->s_blocksize / 512)); >+ fatx_cache_inval_inode(inode); >+ } >+ inode->i_blocks += (1 << FATX_SB(sb)->cluster_bits) / 512; >+ return nr; >+} >+ >+/* Convert linear UNIX date to a MS-DOS time/date pair. */ >+ >+void fatx_date_unix2dos(int unix_date,unsigned short *time, >+ unsigned short *date) >+{ >+ int day,year,nl_day,month; >+ >+ unix_date -= sys_tz.tz_minuteswest*60; >+ >+ /* bound low end at Jan 1 GMT 00:00:00 2000. */ >+ if (unix_date < ((30 * 365) + 7) * 24 * 60 * 60) { >+ unix_date = ((30 * 365) + 7) * 24 * 60 * 60; >+ } >+ >+ *time = (unix_date % 60)/2 + //seconds >+ (((unix_date/60) % 60) << 5) + //minutes >+ (((unix_date/3600) % 24) << 11); //hours >+ >+ day = unix_date/86400-(30 * 365 + 7); //days (from 1.1.2000) >+ year = day/365; >+ if ((year+3)/4+365*year > day) year--; >+ day -= (year+3)/4+365*year; >+ if (day == 59 && !(year & 3)) { >+ nl_day = day; >+ month = 2; >+ } >+ else { >+ nl_day = (year & 3) || day <= 59 ? day : day-1; >+ for (month = 0; month < 12; month++) >+ if (day_n[month] > nl_day) break; >+ } >+ *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); >+} >+ >+struct buffer_head *fatx_extend_dir(struct inode *inode) >+{ >+ struct super_block *sb = inode->i_sb; >+ int nr, sector, last_sector; >+ struct buffer_head *bh, *res = NULL; >+ int cluster_size = FATX_SB(sb)->cluster_size; >+ >+ if (inode->i_ino == FATX_ROOT_INO) >+ return res; >+ >+ nr = fatx_add_cluster(inode); >+ if (nr < 0) >+ return res; >+ >+ sector = FATX_SB(sb)->data_start + (nr - 2) * cluster_size; >+ last_sector = sector + cluster_size; >+ for ( ; sector < last_sector; sector++) { >+#ifdef DEBUG >+ printk("zeroing sector %d\n", sector); >+#endif >+ if (!(bh = sb_getblk(sb, sector))) >+ printk("getblk failed\n"); >+ else { >+ memset(bh->b_data, 0xFF, sb->s_blocksize); >+ set_buffer_uptodate(bh); >+ mark_buffer_dirty(bh); >+ if (!res) >+ res = bh; >+ else >+ if(bh) brelse(bh); >+ } >+ } >+ if (inode->i_size & (sb->s_blocksize - 1)) { >+ fatx_fs_panic(sb, "Odd directory size"); >+ inode->i_size = (inode->i_size + sb->s_blocksize) >+ & ~(sb->s_blocksize - 1); >+ } >+ inode->i_size += 1 << FATX_SB(sb)->cluster_bits; >+ FATX_I(inode)->mmu_private += 1 << FATX_SB(sb)->cluster_bits; >+ mark_inode_dirty(inode); >+ >+ return res; >+} >+ >+/* Returns the inode number of the directory entry at offset pos. If bh is >+ non-NULL, it is brelse'd before. Pos is incremented. The buffer header is >+ returned in bh. >+ AV. Most often we do it item-by-item. Makes sense to optimize. >+ AV. OK, there we go: if both bh and de are non-NULL we assume that we just >+ AV. want the next entry (took one explicit de=NULL in vfat/namei.c). >+ AV. It's done in fatx_get_entry() (inlined), here the slow case lives. >+ AV. Additionally, when we return -1 (i.e. reached the end of directory) >+ AV. we make bh NULL. >+ */ >+ >+int fatx_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh, >+ struct fatx_dir_entry **de, loff_t *i_pos) >+{ >+ struct super_block *sb = dir->i_sb; >+ struct fatx_sb_info *sbi = FATX_SB(sb); >+ int sector, offset; >+ >+ while (1) { >+ offset = *pos; >+ PRINTK("get_entry offset %d\n",offset); >+ if (*bh) >+ if(*bh) brelse(*bh); >+ *bh = NULL; >+ if ((sector = fatx_bmap(dir,offset >> sb->s_blocksize_bits)) == -1) >+ return -1; >+ PRINTK("FATX: get_entry sector %d %p\n",sector,*bh); >+ PRINTK("FATX: get_entry sector apres brelse\n"); >+ if (!sector) >+ return -1; /* beyond EOF */ >+ *pos += sizeof(struct fatx_dir_entry); >+ if (!(*bh = sb_bread(sb, sector))) { >+ printk("Directory sread (sector 0x%x) failed\n",sector); >+ continue; >+ } >+ PRINTK("FATX: get_entry apres sread\n"); >+ >+ offset &= sb->s_blocksize - 1; >+ *de = (struct fatx_dir_entry *) ((*bh)->b_data + offset); >+ *i_pos = (sector << sbi->dir_per_block_bits) + (offset >> FATX_DIR_BITS); >+ >+ return 0; >+ } >+} >+ >+void lock_fatx(struct super_block *sb) >+{ >+ down(&(FATX_SB(sb)->fatx_lock)); >+} >+ >+void unlock_fatx(struct super_block *sb) >+{ >+ up(&(FATX_SB(sb)->fatx_lock)); >+} >+ >diff -urN linux-2.6.6.orig/fs/fatx/namei.c linux-2.6.6/fs/fatx/namei.c >--- linux-2.6.6.orig/fs/fatx/namei.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/fatx/namei.c 2004-05-10 12:30:23.332924024 +0100 >@@ -0,0 +1,419 @@ >+/* >+ * linux/fs/fatx/namei.c >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+#define __NO_VERSION__ >+#include <linux/module.h> >+ >+#include <linux/sched.h> >+#include <linux/fatx_fs.h> >+#include <linux/errno.h> >+#include <linux/string.h> >+ >+#include <asm/uaccess.h> >+ >+#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0) >+ >+/* Characters that are undesirable in an MS-DOS file name */ >+ >+static char bad_chars[] = "*?<>|\";"; >+ >+/* >+ * Formats a FATX file name. Rejects invalid names. >+ */ >+ >+static int fatx_format_name( const char *name,int len,char *out_name ) >+{ >+ int i; >+ char trash[FATX_MAX_NAME_LENGTH]; >+ >+ if (len > FATX_MAX_NAME_LENGTH) return -EINVAL; >+ >+ if (out_name == NULL) out_name = trash; >+ >+ memset(out_name,0xFF,FATX_MAX_NAME_LENGTH); >+ >+ //check for bad characters in name >+ for(i=0; i<len; i++) { >+ if (strchr(bad_chars,name[i])) return -EINVAL; >+ out_name[i] = name[i]; >+ } >+ >+ return 0; >+} >+ >+/* >+ * Locates a directory entry. Uses unformatted name. >+ */ >+ >+static int fatx_find( struct inode *dir, const char *name, int len, struct buffer_head **bh, >+ struct fatx_dir_entry **de, loff_t *i_pos) >+{ >+ //verify its a valid name >+ if (fatx_format_name(name,len,NULL) < 0) return -ENOENT; >+ >+ PRINTK("FATX: fatx_find\n"); >+ >+ //find the name in the directory >+ return fatx_scan(dir,name,len,bh,de,i_pos); >+ >+} >+ >+/* >+ * Get inode using directory and name >+ */ >+ >+struct dentry *fatx_lookup(struct inode *dir,struct dentry *dentry,struct nameidata *nd) >+{ >+ struct super_block *sb = dir->i_sb; >+ struct inode *inode = NULL; >+ struct fatx_dir_entry *de; >+ struct buffer_head *bh = NULL; >+ loff_t i_pos; >+ int res; >+ >+ PRINTK("FATX: fatx_lookup\n"); >+ >+ res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, >+ &de, &i_pos); >+ >+ if (res == -ENOENT) >+ goto add; >+ if (res < 0) >+ goto out; >+ inode = fatx_build_inode(sb, de, i_pos, &res); >+ if (res) >+ goto out; >+add: >+ d_add(dentry, inode); >+ res = 0; >+out: >+ if (bh) >+ brelse(bh); >+ return ERR_PTR(res); >+} >+ >+/* >+ * Creates a directory entry (name is already formatted). >+ */ >+ >+static int fatx_add_entry( >+ struct inode *dir, >+ const char *name, >+ int len, >+ struct buffer_head **bh, >+ struct fatx_dir_entry **de, >+ loff_t *i_pos, >+ int is_dir ) >+{ >+ int res; >+ >+ if ((res = fatx_do_add_entry(dir, bh, de, i_pos))<0) >+ return res; >+ dir->i_ctime = dir->i_mtime = CURRENT_TIME; >+ mark_inode_dirty(dir); >+ memset((*de)->name,0xFF,FATX_MAX_NAME_LENGTH); >+ memcpy((*de)->name,name,len); >+ (*de)->name_length = len; >+ (*de)->attr = is_dir ? ATTR_DIR : ATTR_ARCH; >+ (*de)->start = 0; >+ fatx_date_unix2dos(dir->i_mtime.tv_sec,&(*de)->time,&(*de)->date); >+ (*de)->size = 0; >+ mark_buffer_dirty(*bh); >+ return 0; >+} >+ >+/* >+ * Create a file >+ */ >+ >+int fatx_create(struct inode *dir,struct dentry *dentry,int mode, struct nameidata *nd) >+{ >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ struct inode *inode; >+ loff_t i_pos; >+ int res; >+ const char *name = dentry->d_name.name; >+ int name_length = dentry->d_name.len; >+ char szFormatName[FATX_MAX_NAME_LENGTH]; >+ >+ res = fatx_format_name(name,name_length,szFormatName); >+ if (res < 0) >+ return res; >+ >+ if (fatx_scan(dir,name,name_length,&bh,&de,&i_pos) >= 0) { >+ if(bh) brelse(bh); >+ return -EINVAL; >+ } >+ inode = NULL; >+ res = fatx_add_entry(dir, szFormatName, name_length, &bh, &de, &i_pos, 0); >+ if (res) >+ return res; >+ inode = fatx_build_inode(dir->i_sb, de, i_pos, &res); >+ if(bh) brelse(bh); >+ if (!inode) >+ return res; >+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; >+ mark_inode_dirty(inode); >+ d_instantiate(dentry, inode); >+ return 0; >+} >+ >+/* >+ * Remove a directory >+ */ >+ >+int fatx_rmdir(struct inode *dir, struct dentry *dentry) >+{ >+ struct inode *inode = dentry->d_inode; >+ loff_t i_pos; >+ int res; >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ >+ bh = NULL; >+ res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len, >+ &bh, &de, &i_pos); >+ if (res < 0) >+ goto rmdir_done; >+ /* >+ * Check whether the directory is not in use, then check >+ * whether it is empty. >+ */ >+ res = fatx_dir_empty(inode); >+ if (res) >+ goto rmdir_done; >+ >+ de->name_length = DELETED_FLAG; >+ mark_buffer_dirty(bh); >+ fatx_detach(inode); >+ inode->i_nlink = 0; >+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; >+ dir->i_nlink--; >+ mark_inode_dirty(inode); >+ mark_inode_dirty(dir); >+ res = 0; >+ >+rmdir_done: >+ if(bh) brelse(bh); >+ return res; >+} >+ >+/* >+ * Make a directory >+ */ >+ >+int fatx_mkdir(struct inode *dir,struct dentry *dentry,int mode) >+{ >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ struct inode *inode; >+ int res; >+ const char *name = dentry->d_name.name; >+ int name_length = dentry->d_name.len; >+ loff_t i_pos; >+ char szFormatName[FATX_MAX_NAME_LENGTH]; >+ >+ res = fatx_format_name(name,name_length,szFormatName); >+ if (res < 0) >+ return res; >+ if (fatx_scan(dir,name,name_length,&bh,&de,&i_pos) >= 0) >+ goto out_exist; >+ >+ res = fatx_add_entry(dir, szFormatName, name_length, &bh, &de, &i_pos, 1); >+ if (res) >+ goto out_unlock; >+ inode = fatx_build_inode(dir->i_sb, de, i_pos, &res); >+ if (!inode) { >+ if(bh) brelse(bh); >+ goto out_unlock; >+ } >+ res = 0; >+ >+ dir->i_nlink++; >+ inode->i_nlink = 2; /* no need to mark them dirty */ >+ >+ res = fatx_new_dir(inode, dir); >+ if (res) >+ goto mkdir_error; >+ >+ if(bh) brelse(bh); >+ d_instantiate(dentry, inode); >+ res = 0; >+ >+out_unlock: >+ return res; >+ >+mkdir_error: >+ printk(KERN_WARNING "fatx_mkdir: error=%d, attempting cleanup\n", res); >+ inode->i_nlink = 0; >+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; >+ dir->i_nlink--; >+ mark_inode_dirty(inode); >+ mark_inode_dirty(dir); >+ de->name_length = DELETED_FLAG; >+ mark_buffer_dirty(bh); >+ if(bh) brelse(bh); >+ fatx_detach(inode); >+ iput(inode); >+ goto out_unlock; >+ >+out_exist: >+ if(bh) brelse(bh); >+ res = -EINVAL; >+ goto out_unlock; >+} >+ >+/* >+ * Unlink a file >+ */ >+ >+int fatx_unlink( struct inode *dir, struct dentry *dentry) >+{ >+ struct inode *inode = dentry->d_inode; >+ loff_t i_pos; >+ int res; >+ struct buffer_head *bh; >+ struct fatx_dir_entry *de; >+ >+ bh = NULL; >+ res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len, >+ &bh, &de, &i_pos); >+ if (res < 0) >+ goto unlink_done; >+ >+ de->name_length = DELETED_FLAG; >+ mark_buffer_dirty(bh); >+ fatx_detach(inode); >+ if(bh) brelse(bh); >+ inode->i_nlink = 0; >+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; >+ mark_inode_dirty(inode); >+ mark_inode_dirty(dir); >+ res = 0; >+unlink_done: >+ return res; >+} >+ >+static int do_fatx_rename(struct inode *old_dir, struct dentry *old_dentry, >+ struct inode *new_dir, struct dentry *new_dentry, >+ struct buffer_head *old_bh, struct fatx_dir_entry *old_de, >+ int old_ino ) >+{ >+ struct buffer_head *new_bh=NULL,*dotdot_bh=NULL; >+ struct fatx_dir_entry *new_de,*dotdot_de; >+ struct inode *old_inode,*new_inode; >+ loff_t new_ino; >+ int error; >+ int is_dir; >+ const char *new_name = new_dentry->d_name.name; >+ int new_name_len = new_dentry->d_name.len; >+ >+ PRINTK("FATX: do_fatx_rename: entered\n"); >+ >+ old_inode = old_dentry->d_inode; >+ new_inode = new_dentry->d_inode; >+ is_dir = S_ISDIR(old_inode->i_mode); >+ >+ error = fatx_scan(new_dir,new_name,new_name_len,&new_bh,&new_de,&new_ino); >+ if (error>=0 &&!new_inode) >+ goto degenerate_case; >+ if (!new_bh) { >+ error = fatx_add_entry( new_dir, new_name, new_name_len, &new_bh, >+ &new_de, &new_ino, is_dir ); >+ if (error) >+ goto out; >+ } >+ new_dir->i_version++; >+ >+ /* There we go */ >+ >+ if (new_inode) >+ fatx_detach(new_inode); >+ old_de->name_length = DELETED_FLAG; >+ mark_buffer_dirty(old_bh); >+ fatx_detach(old_inode); >+ fatx_attach(old_inode, new_ino); >+ FATX_I(old_inode)->i_attrs &= ~ATTR_HIDDEN; >+ mark_inode_dirty(old_inode); >+ old_dir->i_version++; >+ old_dir->i_ctime = old_dir->i_mtime = old_dir->i_atime = CURRENT_TIME; >+ mark_inode_dirty(old_dir); >+ if (new_inode) { >+ new_inode->i_nlink--; >+ new_inode->i_ctime = new_inode->i_atime = CURRENT_TIME; >+ mark_inode_dirty(new_inode); >+ } >+ if (dotdot_bh) { >+ dotdot_de->start = CT_LE_L(FATX_I(new_dir)->i_logstart); >+ >+ PRINTK("FATX: do_fatx_rename: start = %08lX (LE=%08lX)\n", >+ (long)FATX_I(new_dir)->i_logstart, >+ (long)dotdot_de->start); >+ >+ mark_buffer_dirty(dotdot_bh); >+ old_dir->i_nlink--; >+ mark_inode_dirty(old_dir); >+ if (new_inode) { >+ new_inode->i_nlink--; >+ mark_inode_dirty(new_inode); >+ } else { >+ new_dir->i_nlink++; >+ mark_inode_dirty(new_dir); >+ } >+ } >+ error = 0; >+out: >+ if(new_bh) brelse(new_bh); >+ if(dotdot_bh) brelse(dotdot_bh); >+ PRINTK("FATX: do_fatx_rename: leaving (normal)\n"); >+ return error; >+ >+degenerate_case: >+ error = -EINVAL; >+ if (new_de!=old_de) >+ goto out; >+ FATX_I(old_inode)->i_attrs &= ~ATTR_HIDDEN; >+ mark_inode_dirty(old_inode); >+ old_dir->i_version++; >+ old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; >+ mark_inode_dirty(old_dir); >+ PRINTK("FATX: do_fatx_rename: leaving (degenerate)\n"); >+ return 0; >+} >+ >+/* >+ * Rename, a wrapper for rename_same_dir & rename_diff_dir >+ */ >+ >+int fatx_rename(struct inode *old_dir,struct dentry *old_dentry, >+ struct inode *new_dir,struct dentry *new_dentry) >+{ >+ struct buffer_head *old_bh; >+ struct fatx_dir_entry *old_de; >+ loff_t old_ino; >+ int error; >+ >+ error = fatx_format_name(old_dentry->d_name.name,old_dentry->d_name.len,NULL); >+ if (error < 0) >+ goto rename_done; >+ error = fatx_format_name(new_dentry->d_name.name,new_dentry->d_name.len,NULL); >+ if (error < 0) >+ goto rename_done; >+ >+ error = fatx_scan(old_dir, old_dentry->d_name.name, old_dentry->d_name.len, >+ &old_bh, &old_de, &old_ino ); >+ if (error < 0) >+ goto rename_done; >+ >+ error = do_fatx_rename( old_dir, old_dentry, new_dir, new_dentry, >+ old_bh, old_de, (ino_t)old_ino ); >+ if(old_bh) brelse(old_bh); >+ >+rename_done: >+ return error; >+} >diff -urN linux-2.6.6.orig/fs/partitions/Kconfig linux-2.6.6/fs/partitions/Kconfig >--- linux-2.6.6.orig/fs/partitions/Kconfig 2004-05-10 03:33:19.000000000 +0100 >+++ linux-2.6.6/fs/partitions/Kconfig 2004-05-10 12:30:23.340922808 +0100 >@@ -233,4 +233,12 @@ > were partitioned using EFI GPT. Presently only useful on the > IA-64 platform. > >+config XBOX_PARTITION >+ bool "Xbox Partition support (EXPERIMENTAL)" >+ depends on PARTITION_ADVANCED && EXPERIMENTAL && BROKEN >+ help >+ Say Y here if you are running Linux on the Xbox, or would >+ like to access a hard disk partitioned for the Xbox under >+ a PC running Linux. Otherwise, say N. >+ > # define_bool CONFIG_ACORN_PARTITION_CUMANA y >diff -urN linux-2.6.6.orig/fs/partitions/Makefile linux-2.6.6/fs/partitions/Makefile >--- linux-2.6.6.orig/fs/partitions/Makefile 2004-05-10 03:32:28.000000000 +0100 >+++ linux-2.6.6/fs/partitions/Makefile 2004-05-10 12:30:23.342922504 +0100 >@@ -18,3 +18,4 @@ > obj-$(CONFIG_IBM_PARTITION) += ibm.o > obj-$(CONFIG_EFI_PARTITION) += efi.o > obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o >+obj-$(CONFIG_XBOX_PARTITION) += xbox.o >diff -urN linux-2.6.6.orig/fs/partitions/check.c linux-2.6.6/fs/partitions/check.c >--- linux-2.6.6.orig/fs/partitions/check.c 2004-05-10 03:33:19.000000000 +0100 >+++ linux-2.6.6/fs/partitions/check.c 2004-05-10 12:30:23.345922048 +0100 >@@ -36,6 +36,9 @@ > #include "ibm.h" > #include "ultrix.h" > #include "efi.h" >+#ifdef CONFIG_XBOX_PARTITION >+#include "xbox.h" >+#endif > > #ifdef CONFIG_BLK_DEV_MD > extern void md_autodetect_dev(dev_t dev); >@@ -190,6 +193,14 @@ > memset(&state->parts, 0, sizeof(state->parts)); > res = check_part[i++](state, bdev); > } >+#ifdef CONFIG_XBOX_PARTITION >+ { >+ int xbox; >+ >+ xbox = xbox_partition(state, bdev); >+ if(!res) res = xbox; >+ } >+#endif > if (res > 0) > return state; > if (!res) >diff -urN linux-2.6.6.orig/fs/partitions/xbox.c linux-2.6.6/fs/partitions/xbox.c >--- linux-2.6.6.orig/fs/partitions/xbox.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/partitions/xbox.c 2004-05-10 12:30:23.347921744 +0100 >@@ -0,0 +1,113 @@ >+/* >+ * fs/partitions/xbox.c >+ * >+ * //TODO: find and insert GPL notice >+ * >+ * June 2002 by SpeedBump: initial implementation >+ */ >+ >+#include <linux/errno.h> >+#include <linux/genhd.h> >+#include <linux/kernel.h> >+ >+#include "check.h" >+#include "xbox.h" >+ >+ >+/* >+ * The native Xbox kernel makes use of an implicit partitioning >+ * scheme. Partition locations and sizes on-disk are hard-coded. >+ */ >+#define XBOX_CONFIG_START 0x00000000L >+#define XBOX_CACHE1_START 0x00000400L >+#define XBOX_CACHE2_START 0x00177400L >+#define XBOX_CACHE3_START 0x002EE400L >+#define XBOX_SYSTEM_START 0x00465400L >+#define XBOX_DATA_START 0x0055F400L >+#define XBOX_EXTEND_START 0x00EE8AB0L >+ >+#define XBOX_CONFIG_SIZE (XBOX_CACHE1_START - XBOX_CONFIG_START) >+#define XBOX_CACHE1_SIZE (XBOX_CACHE2_START - XBOX_CACHE1_START) >+#define XBOX_CACHE2_SIZE (XBOX_CACHE3_START - XBOX_CACHE2_START) >+#define XBOX_CACHE3_SIZE (XBOX_SYSTEM_START - XBOX_CACHE3_START) >+#define XBOX_SYSTEM_SIZE (XBOX_DATA_START - XBOX_SYSTEM_START) >+#define XBOX_DATA_SIZE (XBOX_EXTEND_START - XBOX_DATA_START) >+ >+#define XBOX_MAGIC_SECT 3L >+ >+ >+static int xbox_check_magic(struct block_device *bdev, sector_t at_sect, >+ char *magic) >+{ >+ Sector sect; >+ char *data; >+ int ret; >+ >+ data = read_dev_sector(bdev, at_sect, §); >+ if (!data) >+ return -1; >+ >+ /* Ick! */ >+ ret = (*(u32*)data == *(u32*)magic) ? 1 : 0; >+ put_dev_sector(sect); >+ >+ return ret; >+} >+ >+static inline int xbox_drive_detect(struct block_device *bdev) >+{ >+ /** >+ * "BRFR" is apparently the magic number in the config area >+ * the others are just paranoid checks to assure the expected >+ * "FATX" tags for the other xbox partitions >+ * >+ * the odds against a non-xbox drive having random data to match is >+ * astronomical...but it's possible I guess...you should only include >+ * this check if you actually *have* an xbox drive...since it has to >+ * be detected first >+ * >+ * @see check.c >+ */ >+ return (xbox_check_magic(bdev, XBOX_MAGIC_SECT, "BRFR") && >+ xbox_check_magic(bdev, XBOX_SYSTEM_START, "FATX") && >+ xbox_check_magic(bdev, XBOX_DATA_START, "FATX")) ? >+ 0 : -ENODEV; >+} >+ >+int xbox_partition(struct parsed_partitions *state, struct block_device *bdev) >+{ >+ int slot, err; >+ sector_t last, size; >+ >+ err = xbox_drive_detect(bdev); >+ if (err) >+ return err; >+ >+ slot = 50; >+ printk(" [xbox]"); >+ >+ put_partition(state, slot++, XBOX_DATA_START, XBOX_DATA_SIZE); >+ put_partition(state, slot++, XBOX_SYSTEM_START, XBOX_SYSTEM_SIZE); >+ put_partition(state, slot++, XBOX_CACHE1_START, XBOX_CACHE1_SIZE); >+ put_partition(state, slot++, XBOX_CACHE2_START, XBOX_CACHE2_SIZE); >+ put_partition(state, slot++, XBOX_CACHE3_START, XBOX_CACHE3_SIZE); >+ >+ /* >+ * Xbox HDDs come in two sizes - 8GB and 10GB. The native Xbox kernel >+ * will only acknowledge the first 8GB, regardless of actual disk >+ * size. For disks larger than 8GB, anything above that limit is made >+ * available as a seperate partition. >+ */ >+ last = bdev->bd_disk->capacity; >+ if (last == XBOX_EXTEND_START) >+ goto out; >+ >+ printk(" <"); >+ size = last - XBOX_EXTEND_START; >+ put_partition(state, slot++, XBOX_EXTEND_START, size); >+ printk(" >"); >+ >+out: >+ printk("\n"); >+ return 1; >+} >diff -urN linux-2.6.6.orig/fs/partitions/xbox.h linux-2.6.6/fs/partitions/xbox.h >--- linux-2.6.6.orig/fs/partitions/xbox.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/fs/partitions/xbox.h 2004-05-10 12:30:23.349921440 +0100 >@@ -0,0 +1,6 @@ >+/* >+ * fs/partitions/xbox.h >+ */ >+ >+int xbox_partition(struct parsed_partitions *state, >+ struct block_device *bdev); >diff -urN linux-2.6.6.orig/include/asm-i386/mach-default/mach_pci_blacklist.h linux-2.6.6/include/asm-i386/mach-default/mach_pci_blacklist.h >--- linux-2.6.6.orig/include/asm-i386/mach-default/mach_pci_blacklist.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/asm-i386/mach-default/mach_pci_blacklist.h 2004-05-10 12:30:23.351921136 +0100 >@@ -0,0 +1,6 @@ >+#ifndef __ASM_MACH_PCI_BLACKLIST_H >+#define __ASM_MACH_PCI_BLACKLIST_H >+ >+#define mach_pci_is_blacklisted(bus,dev,fn) 0 >+ >+#endif >diff -urN linux-2.6.6.orig/include/asm-i386/mach-xbox/mach_pci_blacklist.h linux-2.6.6/include/asm-i386/mach-xbox/mach_pci_blacklist.h >--- linux-2.6.6.orig/include/asm-i386/mach-xbox/mach_pci_blacklist.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/asm-i386/mach-xbox/mach_pci_blacklist.h 2004-05-10 12:30:23.352920984 +0100 >@@ -0,0 +1,14 @@ >+#ifndef __ASM_MACH_PCI_BLACKLIST_H >+#define __ASM_MACH_PCI_BLACKLIST_H >+ >+#include <linux/xbox.h> >+ >+static inline int mach_pci_is_blacklisted(int bus, int dev, int fn) >+{ >+ if(machine_is_xbox) { >+ return (bus > 1) || ((bus != 0) && ((dev != 0) || (fn != 0))) || >+ (!bus && !dev && ((fn == 1) || (fn == 2))); >+ } >+} >+ >+#endif >diff -urN linux-2.6.6.orig/include/asm-i386/mach-xbox/setup_arch_pre.h linux-2.6.6/include/asm-i386/mach-xbox/setup_arch_pre.h >--- linux-2.6.6.orig/include/asm-i386/mach-xbox/setup_arch_pre.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/asm-i386/mach-xbox/setup_arch_pre.h 2004-05-10 12:30:23.354920680 +0100 >@@ -0,0 +1,26 @@ >+#ifndef _SETUP_PRE_XBOX_ >+#define _SETUP_PRE_XBOX_ >+ >+/* Hook to call BIOS initialisation function */ >+ >+/* no action for generic */ >+ >+#define ARCH_SETUP arch_setup_xbox(); >+ >+#include <linux/timex.h> >+#include <asm/io.h> >+ >+//int CLOCK_TICK_RATE; >+int machine_is_xbox = 0; >+ >+static inline void arch_setup_xbox(void) { >+ outl(0x80000000, 0xcf8); >+ if (inl(0xcfc)==0x02a510de) { /* Xbox PCI 0:0:0 ID 0x10de/0x02a5 */ >+ machine_is_xbox = 1; >+// CLOCK_TICK_RATE = 1125000; >+ } else { >+// CLOCK_TICK_RATE = 1193180; >+ } >+} >+ >+#endif >diff -urN linux-2.6.6.orig/include/asm-i386/timex.h linux-2.6.6/include/asm-i386/timex.h >--- linux-2.6.6.orig/include/asm-i386/timex.h 2004-05-10 03:32:27.000000000 +0100 >+++ linux-2.6.6/include/asm-i386/timex.h 2004-05-10 12:30:23.356920376 +0100 >@@ -11,12 +11,12 @@ > > #ifdef CONFIG_X86_PC9800 > extern int CLOCK_TICK_RATE; >+#elif defined(CONFIG_MELAN) >+# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ >+#elif defined(CONFIG_X86_XBOX) >+# define CLOCK_TICK_RATE 1125000 > #else >-#ifdef CONFIG_X86_ELAN >-# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ >-#else >-# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ >-#endif >+# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ > #endif > > #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ >diff -urN linux-2.6.6.orig/include/linux/fatx_fs.h linux-2.6.6/include/linux/fatx_fs.h >--- linux-2.6.6.orig/include/linux/fatx_fs.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/linux/fatx_fs.h 2004-05-10 12:30:23.360919768 +0100 >@@ -0,0 +1,253 @@ >+#ifndef _LINUX_FATX_FS_H >+#define _LINUX_FATX_FS_H >+ >+/* >+ * The FATX filesystem constants/structures >+ * >+ */ >+ >+#include <linux/fs.h> >+#include <linux/buffer_head.h> >+#include <asm/byteorder.h> >+ >+#define FATX_ROOT_INO 1 /* == MINIX_ROOT_INO */ >+ >+#define FATX_CACHE 8 /* FAT cache size */ >+ >+#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ >+ >+#define FATX_ENT_FREE (0) >+#define FATX32_MAX_NON_LFS ((1UL<<32) - 1) >+#define FATX16_MAX_NON_LFS ((1UL<<30) - 1) >+ >+#define CLUSTER_SIZE 32 >+#define ATTR_RO 1 /* read-only */ >+#define ATTR_HIDDEN 2 /* hidden */ >+#define ATTR_SYS 4 /* system */ >+#define ATTR_DIR 16 /* directory */ >+#define ATTR_ARCH 0 /* archived */ >+#define ATTR_UNUSED (ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) >+ >+#define ATTR_NONE 0 /* no attribute bits */ >+ >+#define FATX_BOOTBLOCK_MAGIC cpu_to_le32(0x58544146) >+#define FATX_MAX_NAME_LENGTH 42 >+#define FATX_DIR_BITS 6 >+ >+#define DELETED_FLAG 0xe5 /* marks file as deleted when in name_length */ >+ >+//FF == end of directory info, E5 == deleted entry >+#define FATX_IS_FREE(de) ((de)->name_length==DELETED_FLAG) >+#define FATX_END_OF_DIR(de) ((de)->name_length==0xFF) >+ >+#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG) >+ >+#define CF_LE_W(v) le16_to_cpu(v) >+#define CF_LE_L(v) le32_to_cpu(v) >+#define CT_LE_W(v) cpu_to_le16(v) >+#define CT_LE_L(v) cpu_to_le32(v) >+ >+/* bad cluster mark */ >+#define BAD_FAT16 0xFFF7 >+#define BAD_FAT32 0x0FFFFFF7 >+#define BAD_FAT(s) (FATX_SB(s)->fat_bits == 32 ? BAD_FAT32 : BAD_FAT16) >+ >+#define EOC_FAT16 0xFFF8 // end of chain marker >+#define EOC_FAT32 0xFFFFFFF8 // end of chain marker >+#define EOF_FAT16 0xFFF8 // end of file marker >+#define EOF_FAT32 0xFFFFFFF8 // end of file marker >+#define EOF_FAT(s) (FATX_SB(s)->fat_bits == 32 ? EOF_FAT32 : EOF_FAT16) >+ >+#define FATX_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO) >+ >+/* Convert attribute bits and a mask to the UNIX mode. */ >+#define FATX_MKMODE(a,m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO)) >+ >+/* Convert the UNIX mode to FATX attribute bits. */ >+#define FATX_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO) >+ >+struct fatx_boot_sector { >+ __u32 magic; /* "FATX" */ >+ __u32 volume_id; /* Volume ID */ >+ __u32 cluster_size; /* sectors/cluster */ >+ __u16 fats; /* number of FATs */ >+ __u32 unknown; >+}; >+ >+struct fatx_dir_entry { >+ __u8 name_length; /* length of filename (bytes) */ >+ __u8 attr; /* attribute bits */ >+ __s8 name[42]; /* filename */ >+ __u32 start; /* first cluster */ >+ __u32 size; /* file size (in bytes) */ >+ __u16 time,date; /* time, date */ >+ __u16 ctime,cdate; /* Creation time */ >+ __u16 atime,adate; /* Last access time */ >+}; >+ >+struct fatx_boot_fsinfo { >+ __u32 signature1; /* 0x41615252L */ >+ __u32 reserved1[120]; /* Nothing as far as I can tell */ >+ __u32 signature2; /* 0x61417272L */ >+ __u32 free_clusters; /* Free cluster count. -1 if unknown */ >+ __u32 next_cluster; /* Most recently allocated cluster. >+ * Unused under Linux. */ >+ __u32 reserved2[4]; >+}; >+ >+struct fatx_cache { >+ dev_t device; /* device number. 0 means unused. */ >+ int start_cluster; /* first cluster of the chain. */ >+ int file_cluster; /* cluster number in the file. */ >+ int disk_cluster; /* cluster number on disk. */ >+ struct fatx_cache *next; /* next cache entry */ >+}; >+ >+#ifdef __KERNEL__ >+ >+#include <linux/buffer_head.h> >+#include <linux/string.h> >+#include <linux/nls.h> >+#include <linux/fatx_fs_i.h> >+#include <linux/fatx_fs_sb.h> >+#include <asm/statfs.h> >+ >+static inline struct fatx_sb_info *FATX_SB(struct super_block *sb) >+{ >+ return sb->s_fs_info; >+} >+ >+static inline struct fatx_inode_info *FATX_I(struct inode *inode) >+{ >+ return container_of(inode, struct fatx_inode_info, vfs_inode); >+} >+ >+/* fatx/cache.c */ >+extern int fatx_access(struct super_block *sb, int nr, int new_value); >+extern unsigned long fatx_bmap(struct inode *inode,unsigned long sector); >+extern void fatx_cache_init(void); >+extern void fatx_cache_lookup(struct inode *inode, int cluster, int *f_clu, >+ int *d_clu); >+extern void fatx_cache_add(struct inode *inode, int f_clu, int d_clu); >+extern void fatx_cache_inval_inode(struct inode *inode); >+extern void fatx_cache_inval_dev(dev_t device); >+extern int fatx_get_cluster(struct inode *inode,int cluster); >+extern int fatx_free(struct inode *inode, int skip); >+extern void fatx_clusters_flush(struct super_block *sb); >+ >+/* fatx/dir.c */ >+extern struct file_operations fat_dir_operations; >+extern int fatx_readdir(struct file *filp, void *dirent, filldir_t filldir); >+extern int fatx_dir_empty(struct inode *dir); >+extern int fatx_add_entries(struct inode *dir, int slots, struct buffer_head **bh, >+ struct fatx_dir_entry **de, loff_t *i_pos); >+extern int fatx_new_dir(struct inode *dir, struct inode *parent); >+ >+/* fat/file.c */ >+extern struct file_operations fatx_file_operations; >+extern struct inode_operations fatx_file_inode_operations; >+extern ssize_t fatx_file_read(struct file *filp, char *buf, size_t count, >+ loff_t *ppos); >+extern int fatx_get_block(struct inode *inode, sector_t iblock, >+ struct buffer_head *bh_result, int create); >+extern ssize_t fatx_file_write(struct file *filp, const char __user *buf, size_t count, >+ loff_t *ppos); >+extern void fatx_truncate(struct inode *inode); >+ >+/* fat/inode.c */ >+extern void fatx_hash_init(void); >+extern void fatx_attach(struct inode *inode, loff_t i_pos); >+extern void fatx_detach(struct inode *inode); >+extern struct inode *fatx_iget(struct super_block *sb, loff_t i_pos); >+extern struct inode *fatx_build_inode( >+ struct super_block *sb, >+ struct fatx_dir_entry *de, >+ loff_t i_pos, >+ int *res); >+extern int fatx_fill_super(struct super_block *sb,void *data, int silent); >+ >+extern void fatx_delete_inode(struct inode *inode); >+extern void fatx_clear_inode(struct inode *inode); >+extern void fatx_put_super(struct super_block *sb); >+ >+typedef int (*fatx_boot_block_parse_func)( >+ struct super_block *sb, >+ struct buffer_head *bh ); >+typedef void (*fatx_read_root_func)(struct inode *inode); >+ >+extern int fatx_statfs(struct super_block *sb, struct kstatfs *buf); >+extern void fatx_write_inode(struct inode *inode, int wait); >+extern int fatx_notify_change(struct dentry * dentry, struct iattr * attr); >+ >+extern struct address_space_operations fatx_aops; >+extern spinlock_t fatx_inode_lock; >+ >+ >+/* fatx/namei.c - these are for the xbox's FATX */ >+struct dentry *fatx_lookup(struct inode *dir,struct dentry *dentry, struct nameidata *nd); >+extern int fatx_create(struct inode *dir, struct dentry *dentry, int mode, >+ struct nameidata *nd); >+extern int fatx_rmdir(struct inode *dir, struct dentry *dentry); >+extern int fatx_unlink(struct inode *dir, struct dentry *dentry); >+extern int fatx_mkdir(struct inode *dir, struct dentry *dentry, int mode); >+extern int fatx_rename(struct inode *old_dir, struct dentry *old_dentry, >+ struct inode *new_dir, struct dentry *new_dentry); >+ >+/* fatx/fatxfs_syms.c */ >+extern unsigned int fatx_debug; >+ >+extern struct file_system_type fatx_fs_type; >+ >+extern int fatx_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh, >+ struct fatx_dir_entry **de,loff_t *i_pos ); >+ >+extern int fatx_scan(struct inode *dir, const char *name, int name_length, >+ struct buffer_head **res_bh,struct fatx_dir_entry **res_de, >+ loff_t *i_pos); >+ >+/* miscelaneous support code for fatx fs */ >+extern int fatx_date_dos2unix( unsigned short, unsigned short ); >+extern void fatx_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date); >+ >+static inline unsigned char fatx_tolower(struct nls_table *t, unsigned char c) >+{ >+ unsigned char nc = t->charset2lower[c]; >+ >+ return nc ? nc : c; >+} >+ >+static inline unsigned char fatx_toupper(struct nls_table *t, unsigned char c) >+{ >+ unsigned char nc = t->charset2upper[c]; >+ >+ return nc ? nc : c; >+} >+ >+static inline int fatx_strnicmp(struct nls_table *t, const unsigned char *s1, >+ const unsigned char *s2, int len ) >+{ >+ while(len--) { >+ if (fatx_tolower(t, *s1++) != fatx_tolower(t, *s2++)) >+ return 1; >+ } >+ return 0; >+} >+ >+/* directory code for fatx fs */ >+extern int fatx_do_add_entry(struct inode *dir, struct buffer_head **bh, >+ struct fatx_dir_entry **de, loff_t *i_pos); >+ >+extern int fatx_dir_empty(struct inode *dir); >+extern int fatx_subdirs(struct inode *dir); >+ >+extern struct file_operations fatx_dir_operations; >+#endif /* __KERNEL__ */ >+ >+extern int fatx_access(struct super_block *sb, int nr, int new_value); >+extern void fatx_fs_panic(struct super_block *s,const char *msg); >+extern struct buffer_head *fatx_extend_dir(struct inode *inode); >+extern int fatx_add_cluster(struct inode *inode); >+extern void lock_fatx(struct super_block *sb); >+extern void unlock_fatx(struct super_block *sb); >+ >+#endif /* _LINUX_FATX_FS_H */ >diff -urN linux-2.6.6.orig/include/linux/fatx_fs_i.h linux-2.6.6/include/linux/fatx_fs_i.h >--- linux-2.6.6.orig/include/linux/fatx_fs_i.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/linux/fatx_fs_i.h 2004-05-10 12:30:23.362919464 +0100 >@@ -0,0 +1,26 @@ >+#ifndef _FATX_FS_I >+#define _FATX_FS_I >+ >+#include <linux/fs.h> >+ >+/* >+ * FATX file system inode data in memory >+ */ >+ >+struct fatx_inode_info { >+ /* cache of lastest accessed cluster */ >+ int file_cluster; /* cluster number in the file. */ >+ int disk_cluster; /* cluster number on disk. */ >+ >+ loff_t mmu_private; >+ int i_start; /* first cluster or 0 */ >+ int i_logstart; /* logical first cluster */ >+ int i_attrs; /* unused attribute bits */ >+ int i_ctime_ms; /* unused change time in milliseconds */ >+ loff_t i_pos; /* on-disk position of directory entry or 0 */ >+ struct inode *i_fat_inode; /* struct inode of this one */ >+ struct list_head i_fat_hash; /* hash by i_location */ >+ struct inode vfs_inode; >+}; >+ >+#endif >diff -urN linux-2.6.6.orig/include/linux/fatx_fs_sb.h linux-2.6.6/include/linux/fatx_fs_sb.h >--- linux-2.6.6.orig/include/linux/fatx_fs_sb.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/linux/fatx_fs_sb.h 2004-05-10 12:30:23.364919160 +0100 >@@ -0,0 +1,51 @@ >+#ifndef _FATX_FS_SB >+#define _FATX_FS_SB >+ >+/* >+ * FATX file system in-core superblock data >+ * >+ * Written 2003 by Edgar Hucek and Lehner Franz >+ * >+ */ >+ >+struct fatx_mount_options { >+ uid_t fs_uid; >+ gid_t fs_gid; >+ unsigned short fs_umask; >+ unsigned short codepage; /* Codepage for shortname conversions */ >+ unsigned short shortname; /* flags for shortname display/create rule */ >+ unsigned char name_check; /* r = relaxed, n = normal, s = strict */ >+ unsigned char conversion; /* b = binary, t = text, a = auto */ >+ unsigned quiet:1; /* set = fake successful chmods and chowns */ >+}; >+ >+#define FATX_CACHE_NR 8 /* number of FAT cache */ >+ >+struct fatx_sb_info { >+ unsigned short sec_per_clus; /* sectors/cluster */ >+ unsigned short cluster_bits; /* log2(cluster_size) */ >+ unsigned int cluster_size; /* cluster size */ >+ unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ >+ unsigned short fat_start; >+ unsigned long fat_length; /* FAT start & length (sec.) */ >+ unsigned long dir_start; >+ unsigned short dir_entries; /* root dir start & entries */ >+ unsigned long data_start; /* first data sector */ >+ unsigned long clusters; /* number of clusters */ >+ unsigned long root_cluster; /* first cluster of the root directory */ >+ unsigned long fsinfo_sector; /* FAT32 fsinfo offset from start of disk */ >+ struct semaphore fatx_lock; >+ int prev_free; /* previously returned free cluster number */ >+ int free_clusters; /* -1 if undefined */ >+ struct fatx_mount_options options; >+ struct nls_table *nls_disk; /* Codepage used on disk */ >+ struct nls_table *nls_io; /* Charset used for input and display */ >+ void *dir_ops; /* Opaque; default directory operations */ >+ void *private_data; >+ int dir_per_block; /* dir entries per block */ >+ int dir_per_block_bits; /* log2(dir_per_block) */ >+ >+ spinlock_t cache_lock; >+}; >+ >+#endif >diff -urN linux-2.6.6.orig/include/linux/pci_ids.h linux-2.6.6/include/linux/pci_ids.h >--- linux-2.6.6.orig/include/linux/pci_ids.h 2004-05-10 03:32:28.000000000 +0100 >+++ linux-2.6.6/include/linux/pci_ids.h 2004-05-10 12:30:23.373917792 +0100 >@@ -1100,6 +1100,7 @@ > #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 > #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 > #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B >+#define PCI_DEVICE_ID_NVIDIA_IGEFORCE3 0x02a0 > > #define PCI_VENDOR_ID_IMS 0x10e0 > #define PCI_DEVICE_ID_IMS_8849 0x8849 >diff -urN linux-2.6.6.orig/include/linux/xbox.h linux-2.6.6/include/linux/xbox.h >--- linux-2.6.6.orig/include/linux/xbox.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/linux/xbox.h 2004-05-10 12:30:23.377917184 +0100 >@@ -0,0 +1,135 @@ >+#ifndef _XBOX_H_ >+#define _XBOX_H_ >+ >+#define XBOX_SMB_IO_BASE 0xC000 >+#define XBOX_SMB_HOST_ADDRESS (0x4 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_HOST_COMMAND (0x8 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_HOST_DATA (0x6 + XBOX_SMB_IO_BASE) >+#define XBOX_SMB_GLOBAL_ENABLE (0x2 + XBOX_SMB_IO_BASE) >+#define XBOX_GE_CYC_TYPE_MASK (7) >+#define XBOX_BYTE_DATA 0x02 >+ >+#define XBOX_SMC_ADDRESS 0x10 >+#define XBOX_TV_ADDRESS 0x45 >+ >+#define SMC_CMD_POWER 0x02 >+#define SMC_CMD_TRAY_STATE 0x03 >+#define SMC_CMD_AV_PACK 0x04 >+#define SMC_CMD_LED_MODE 0x07 >+#define SMC_CMD_LED_REGISTER 0x08 >+#define SMC_CMD_EJECT 0x0C >+#define SMC_CMD_INTERRUPT_RESPOND 0x0D >+#define SMC_CMD_INTERRUPT_REASON 0x11 >+#define SMC_CMD_RESET_ON_EJECT 0x19 >+#define SMC_CMD_SCRATCH_REGISTER 0x1B >+// I think commands 20 and 21 are used for bootup authentication, but >+// I don't know those commands. The CROM people know. >+// >+#define SMC_SUBCMD_POWER_RESET 0x01 >+#define SMC_SUBCMD_POWER_CYCLE 0x40 >+#define SMC_SUBCMD_POWER_OFF 0x80 >+// >+#define SMC_SUBCMD_RESPOND_CONTINUE 0x04 >+// >+// These are from recent posts to this list (except MISSING) >+#define SMC_VALUE_AV_SCART 0x00 >+#define SMC_VALUE_AV_HDTV 0x01 >+#define SMC_VALUE_AV_VGA 0x02 >+#define SMC_VALUE_AV_RFU 0x03 >+#define SMC_VALUE_AV_SVIDEO 0x04 >+#define SMC_VALUE_AV_STANDARD 0x06 >+#define SMC_VALUE_AV_UNDEFINED 0x05 >+#define SMC_VALUE_AV_MISSING 0x07 >+// >+#define SMC_SUBCMD_LED_MODE_DEFAULT 0x00 >+#define SMC_SUBCMD_LED_MODE_CUSTOM 0x01 >+ >+#define SMC_SUBCMD_EJECT_EJECT 0x00 >+#define SMC_SUBCMD_EJECT_LOAD 0x01 >+ >+// Bits 01...40 all have meaning but I don't know them all. >+#define SMC_VALUE_INTERRUPT_POWER_BUTTON 0x01 >+#define SMC_VALUE_INTERRUPT_AV_REMOVED 0x10 >+#define SMC_VALUE_INTERRUPT_EJECT_BUTTON 0x20 >+ >+#define SMC_SUBCMD_RESET_ON_EJECT_ENABLE 0x00 >+#define SMC_SUBCMD_RESET_ON_EJECT_DISABLE 0x01 >+ >+// These are defined by the *kernel*, not the SMC. >+#define SMC_SCRATCH_EJECT_AFTER_BOOT 0x01 >+#define SMC_SCRATCH_DISPLAY_ERROR 0x02 >+#define SMC_SCRATCH_NO_ANIMATION 0x04 >+#define SMC_SCRATCH_RUN_DASHBOARD 0x08 >+ >+/* interrupt causes */ >+#define POWERDOWN_MASK (1<<0) >+#define TRAYCLOSED_MASK (1<<1) >+#define TRAYOPENING_MASK (1<<2) >+#define AVPLUGGED_MASK (1<<3) >+#define AVUNPLUGGED_MASK (1<<4) >+#define TRAYBUTTON_MASK (1<<5) >+#define TRAYCLOSING_MASK (1<<6) >+#define UNKNOWN_MASK (1<<7) >+ >+extern int machine_is_xbox; >+ >+#define XBOX_I2C_IO_BASE 0xc000 >+static inline void Xbox_SMC_write(u8 d1,u8 d2) { >+ int c=4; >+ u8 b=0; >+ u32 dwSpinsToLive = 0x8000000; >+ >+ /* >+ while(inw(XBOX_I2C_IO_BASE+0)&0x0800); >+ */ >+ while(c--) { >+ outb(XBOX_SMC_ADDRESS<<1, XBOX_SMB_HOST_ADDRESS); >+ outb((u8)d1, XBOX_SMB_HOST_COMMAND); >+ outb((u8)d2, XBOX_SMB_HOST_DATA); >+ outw(0xffff, XBOX_I2C_IO_BASE+0); >+ outb(0x0a, XBOX_SMB_GLOBAL_ENABLE); >+ { >+ while((b !=0x10) && ((b&0x26)==0) && (dwSpinsToLive--)) { >+ b=inb(XBOX_I2C_IO_BASE); >+ } >+ if(b&0x2) continue; >+ if(b&0x24) continue; >+ if(!(b&0x10)) continue; >+ break; >+ } >+ } >+} >+ >+static inline int Xbox_SMC_read(u8 d) { >+ int c=4; >+ u8 b=0; >+ u32 dwSpinsToLive = 0x8000000; >+ >+ /* >+ while(inw(XBOX_I2C_IO_BASE+0)&0x0800); >+ */ >+ while(c--) { >+ outb((XBOX_SMC_ADDRESS<<1)|1, XBOX_SMB_HOST_ADDRESS); >+ outb(d, XBOX_SMB_HOST_COMMAND); >+ outw(0xffff, XBOX_I2C_IO_BASE+0); >+ outb(0x0a, XBOX_SMB_GLOBAL_ENABLE); >+ { >+ while((b !=0x10) && ((b&0x26)==0) && (dwSpinsToLive--)) { >+ b=inb(XBOX_I2C_IO_BASE); >+ } >+ if(b&0x2) continue; >+ if(b&0x24) continue; >+ if(!(b&0x10)) continue; >+ break; >+ } >+ } >+ return (int)inb(XBOX_SMB_HOST_DATA); >+} >+ >+#define Xbox_tray_load() Xbox_SMC_write(SMC_CMD_EJECT, SMC_SUBCMD_EJECT_LOAD); >+#define Xbox_tray_eject() Xbox_SMC_write(SMC_CMD_EJECT, SMC_SUBCMD_EJECT_EJECT); >+ >+#define Xbox_power_off() Xbox_SMC_write(SMC_CMD_POWER, SMC_SUBCMD_POWER_OFF); >+#define Xbox_reset() Xbox_SMC_write(SMC_CMD_POWER, SMC_SUBCMD_POWER_RESET); >+ >+#endif /* _XBOX_H_ */ >diff -urN linux-2.6.6.orig/include/linux/xboxfbctl.h linux-2.6.6/include/linux/xboxfbctl.h >--- linux-2.6.6.orig/include/linux/xboxfbctl.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/include/linux/xboxfbctl.h 2004-05-10 12:30:23.379916880 +0100 >@@ -0,0 +1,67 @@ >+/* >+ * linux/include/video/xboxfbctl.h >+ * - Type definitions for ioctls of Xbox video driver >+ * >+ * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de> >+ * >+ * Contributors: >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ * >+ * Known bugs and issues: >+ * >+ * none >+ */ >+ >+#ifndef xbofbctl_h >+#define xbofbctl_h >+ >+typedef enum enumVideoStandards { >+ TV_ENC_INVALID=-1, >+ TV_ENC_NTSC=0, >+ TV_ENC_NTSC60, >+ TV_ENC_PALBDGHI, >+ TV_ENC_PALN, >+ TV_ENC_PALNC, >+ TV_ENC_PALM, >+ TV_ENC_PAL60 >+} xbox_tv_encoding; >+ >+typedef enum enumAvTypes { >+ AV_INVALID=-1, >+ AV_SCART_RGB, >+ AV_SVIDEO, >+ AV_VGA_SOG, >+ AV_HDTV, >+ AV_COMPOSITE, >+ AV_VGA >+} xbox_av_type; >+ >+typedef enum enumEncoderType { >+ ENCODER_CONEXANT, >+ ENCODER_FOCUS, >+ ENCODER_XLB >+} xbox_encoder_type; >+ >+typedef struct _xboxOverscan { >+ double hoc; >+ double voc; >+} xbox_overscan; >+ >+typedef struct _xboxFbConfig { >+ xbox_av_type av_type; >+ xbox_encoder_type encoder_type; >+} xboxfb_config; >+ >+#define FBIO_XBOX_GET_OVERSCAN _IOR('x', 1, xbox_overscan) >+/* in param: double hoc (0.0-0.2), double voc (0.0 - 0.2) */ >+#define FBIO_XBOX_SET_OVERSCAN _IOW('x', 2, xbox_overscan) >+ >+#define FBIO_XBOX_GET_TV_ENCODING _IOR('x', 3, xbox_tv_encoding) >+#define FBIO_XBOX_SET_TV_ENCODING _IOW('x', 4, xbox_tv_encoding) >+ >+#define FBIO_XBOX_GET_CONFIG _IOR('x', 5, xboxfb_config) >+ >+#endif >diff -urN linux-2.6.6.orig/kernel.config linux-2.6.6/kernel.config >--- linux-2.6.6.orig/kernel.config 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.6.6/kernel.config 2004-05-10 12:30:23.392914904 +0100 >@@ -0,0 +1,1250 @@ >+# >+# Automatically generated make config: don't edit >+# >+CONFIG_X86=y >+CONFIG_MMU=y >+CONFIG_UID16=y >+CONFIG_GENERIC_ISA_DMA=y >+ >+# >+# Code maturity level options >+# >+CONFIG_EXPERIMENTAL=y >+# CONFIG_CLEAN_COMPILE is not set >+# CONFIG_STANDALONE is not set >+CONFIG_BROKEN=y >+CONFIG_BROKEN_ON_SMP=y >+ >+# >+# General setup >+# >+CONFIG_SWAP=y >+CONFIG_SYSVIPC=y >+CONFIG_BSD_PROCESS_ACCT=y >+CONFIG_SYSCTL=y >+CONFIG_LOG_BUF_SHIFT=14 >+# CONFIG_HOTPLUG is not set >+CONFIG_IKCONFIG=y >+CONFIG_IKCONFIG_PROC=y >+CONFIG_EMBEDDED=y >+# CONFIG_KALLSYMS is not set >+CONFIG_FUTEX=y >+CONFIG_EPOLL=y >+# CONFIG_IOSCHED_NOOP is not set >+# CONFIG_IOSCHED_AS is not set >+CONFIG_IOSCHED_DEADLINE=y >+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set >+ >+# >+# Loadable module support >+# >+CONFIG_MODULES=y >+CONFIG_MODULE_UNLOAD=y >+CONFIG_MODULE_FORCE_UNLOAD=y >+CONFIG_OBSOLETE_MODPARM=y >+# CONFIG_MODVERSIONS is not set >+CONFIG_KMOD=y >+ >+# >+# Processor type and features >+# >+# CONFIG_X86_PC is not set >+# CONFIG_X86_ELAN is not set >+CONFIG_X86_XBOX=y >+# CONFIG_X86_VOYAGER is not set >+# CONFIG_X86_NUMAQ is not set >+# CONFIG_X86_SUMMIT is not set >+# CONFIG_X86_BIGSMP is not set >+# CONFIG_X86_VISWS is not set >+# CONFIG_X86_GENERICARCH is not set >+# CONFIG_X86_ES7000 is not set >+# CONFIG_M386 is not set >+# CONFIG_M486 is not set >+# CONFIG_M586 is not set >+# CONFIG_M586TSC is not set >+# CONFIG_M586MMX is not set >+# CONFIG_M686 is not set >+# CONFIG_MPENTIUMII is not set >+CONFIG_MPENTIUMIII=y >+# CONFIG_MPENTIUMM is not set >+# CONFIG_MPENTIUM4 is not set >+# CONFIG_MK6 is not set >+# CONFIG_MK7 is not set >+# CONFIG_MK8 is not set >+# CONFIG_MELAN is not set >+# CONFIG_MCRUSOE is not set >+# CONFIG_MWINCHIPC6 is not set >+# CONFIG_MWINCHIP2 is not set >+# CONFIG_MWINCHIP3D is not set >+# CONFIG_MCYRIXIII is not set >+# CONFIG_MVIAC3_2 is not set >+CONFIG_X86_GENERIC=y >+CONFIG_X86_CMPXCHG=y >+CONFIG_X86_XADD=y >+CONFIG_X86_L1_CACHE_SHIFT=7 >+CONFIG_RWSEM_XCHGADD_ALGORITHM=y >+CONFIG_X86_WP_WORKS_OK=y >+CONFIG_X86_INVLPG=y >+CONFIG_X86_BSWAP=y >+CONFIG_X86_POPAD_OK=y >+CONFIG_X86_GOOD_APIC=y >+CONFIG_X86_INTEL_USERCOPY=y >+CONFIG_X86_USE_PPRO_CHECKSUM=y >+CONFIG_HPET_TIMER=y >+# CONFIG_HPET_EMULATE_RTC is not set >+# CONFIG_PREEMPT is not set >+# CONFIG_X86_UP_APIC is not set >+CONFIG_XBOX_EJECT=y >+CONFIG_X86_TSC=y >+# CONFIG_X86_MCE is not set >+# CONFIG_TOSHIBA is not set >+# CONFIG_I8K is not set >+# CONFIG_MICROCODE is not set >+# CONFIG_X86_MSR is not set >+# CONFIG_X86_CPUID is not set >+# CONFIG_EDD is not set >+CONFIG_NOHIGHMEM=y >+# CONFIG_HIGHMEM4G is not set >+# CONFIG_HIGHMEM64G is not set >+# CONFIG_MATH_EMULATION is not set >+CONFIG_MTRR=y >+# CONFIG_REGPARM is not set >+ >+# >+# Power management options (ACPI, APM) >+# >+# CONFIG_PM is not set >+ >+# >+# ACPI (Advanced Configuration and Power Interface) Support >+# >+# CONFIG_ACPI is not set >+ >+# >+# CPU Frequency scaling >+# >+# CONFIG_CPU_FREQ is not set >+ >+# >+# Bus options (PCI, PCMCIA, EISA, MCA, ISA) >+# >+CONFIG_PCI=y >+# CONFIG_PCI_GOBIOS is not set >+# CONFIG_PCI_GOMMCONFIG is not set >+CONFIG_PCI_GODIRECT=y >+# CONFIG_PCI_GOANY is not set >+CONFIG_PCI_DIRECT=y >+# CONFIG_PCI_LEGACY_PROC is not set >+# CONFIG_PCI_NAMES is not set >+# CONFIG_ISA is not set >+# CONFIG_SCx200 is not set >+ >+# >+# Executable file formats >+# >+CONFIG_BINFMT_ELF=y >+CONFIG_BINFMT_AOUT=m >+CONFIG_BINFMT_MISC=m >+ >+# >+# Device Drivers >+# >+ >+# >+# Generic Driver Options >+# >+ >+# >+# Memory Technology Devices (MTD) >+# >+# CONFIG_MTD is not set >+ >+# >+# Parallel port support >+# >+# CONFIG_PARPORT is not set >+ >+# >+# Plug and Play support >+# >+ >+# >+# Block devices >+# >+# CONFIG_BLK_DEV_FD is not set >+# CONFIG_BLK_CPQ_DA is not set >+# CONFIG_BLK_CPQ_CISS_DA is not set >+# CONFIG_BLK_DEV_DAC960 is not set >+# CONFIG_BLK_DEV_UMEM is not set >+CONFIG_BLK_DEV_LOOP=m >+CONFIG_BLK_DEV_CRYPTOLOOP=m >+CONFIG_BLK_DEV_NBD=m >+CONFIG_BLK_DEV_RAM=y >+CONFIG_BLK_DEV_RAM_SIZE=4096 >+CONFIG_BLK_DEV_INITRD=y >+# CONFIG_LBD is not set >+ >+# >+# ATA/ATAPI/MFM/RLL support >+# >+CONFIG_IDE=y >+CONFIG_BLK_DEV_IDE=y >+ >+# >+# Please see Documentation/ide.txt for help/info on IDE drives >+# >+# CONFIG_BLK_DEV_HD_IDE is not set >+CONFIG_BLK_DEV_IDEDISK=y >+# CONFIG_IDEDISK_MULTI_MODE is not set >+# CONFIG_IDEDISK_STROKE is not set >+CONFIG_BLK_DEV_IDECD=y >+# CONFIG_BLK_DEV_IDETAPE is not set >+# CONFIG_BLK_DEV_IDEFLOPPY is not set >+# CONFIG_BLK_DEV_IDESCSI is not set >+# CONFIG_IDE_TASK_IOCTL is not set >+# CONFIG_IDE_TASKFILE_IO is not set >+ >+# >+# IDE chipset support/bugfixes >+# >+CONFIG_IDE_GENERIC=y >+# CONFIG_BLK_DEV_CMD640 is not set >+CONFIG_BLK_DEV_IDEPCI=y >+CONFIG_IDEPCI_SHARE_IRQ=y >+# CONFIG_BLK_DEV_OFFBOARD is not set >+CONFIG_BLK_DEV_GENERIC=y >+# CONFIG_BLK_DEV_OPTI621 is not set >+# CONFIG_BLK_DEV_RZ1000 is not set >+CONFIG_BLK_DEV_IDEDMA_PCI=y >+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set >+CONFIG_IDEDMA_PCI_AUTO=y >+# CONFIG_IDEDMA_ONLYDISK is not set >+CONFIG_BLK_DEV_ADMA=y >+# CONFIG_BLK_DEV_AEC62XX is not set >+# CONFIG_BLK_DEV_ALI15X3 is not set >+CONFIG_BLK_DEV_AMD74XX=y >+# CONFIG_BLK_DEV_CMD64X is not set >+# CONFIG_BLK_DEV_TRIFLEX is not set >+# CONFIG_BLK_DEV_CY82C693 is not set >+# CONFIG_BLK_DEV_CS5520 is not set >+# CONFIG_BLK_DEV_CS5530 is not set >+# CONFIG_BLK_DEV_HPT34X is not set >+# CONFIG_BLK_DEV_HPT366 is not set >+# CONFIG_BLK_DEV_SC1200 is not set >+# CONFIG_BLK_DEV_PIIX is not set >+# CONFIG_BLK_DEV_NS87415 is not set >+# CONFIG_BLK_DEV_PDC202XX_OLD is not set >+# CONFIG_BLK_DEV_PDC202XX_NEW is not set >+# CONFIG_BLK_DEV_SVWKS is not set >+# CONFIG_BLK_DEV_SIIMAGE is not set >+# CONFIG_BLK_DEV_SIS5513 is not set >+# CONFIG_BLK_DEV_SLC90E66 is not set >+# CONFIG_BLK_DEV_TRM290 is not set >+# CONFIG_BLK_DEV_VIA82CXXX is not set >+CONFIG_BLK_DEV_IDEDMA=y >+# CONFIG_IDEDMA_IVB is not set >+CONFIG_IDEDMA_AUTO=y >+# CONFIG_DMA_NONPCI is not set >+# CONFIG_BLK_DEV_HD is not set >+ >+# >+# SCSI device support >+# >+CONFIG_SCSI=m >+CONFIG_SCSI_PROC_FS=y >+ >+# >+# SCSI support type (disk, tape, CD-ROM) >+# >+CONFIG_BLK_DEV_SD=m >+CONFIG_CHR_DEV_ST=m >+CONFIG_CHR_DEV_OSST=m >+CONFIG_BLK_DEV_SR=m >+CONFIG_BLK_DEV_SR_VENDOR=y >+CONFIG_CHR_DEV_SG=m >+ >+# >+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs >+# >+CONFIG_SCSI_MULTI_LUN=y >+CONFIG_SCSI_REPORT_LUNS=y >+# CONFIG_SCSI_CONSTANTS is not set >+# CONFIG_SCSI_LOGGING is not set >+ >+# >+# SCSI low-level drivers >+# >+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set >+# CONFIG_SCSI_ACARD is not set >+# CONFIG_SCSI_AACRAID is not set >+# CONFIG_SCSI_AIC7XXX is not set >+# CONFIG_SCSI_AIC7XXX_OLD is not set >+# CONFIG_SCSI_AIC79XX is not set >+# CONFIG_SCSI_DPT_I2O is not set >+# CONFIG_SCSI_ADVANSYS is not set >+# CONFIG_SCSI_MEGARAID is not set >+# CONFIG_SCSI_SATA is not set >+# CONFIG_SCSI_BUSLOGIC is not set >+# CONFIG_SCSI_CPQFCTS is not set >+# CONFIG_SCSI_DMX3191D is not set >+# CONFIG_SCSI_EATA is not set >+# CONFIG_SCSI_EATA_PIO is not set >+# CONFIG_SCSI_FUTURE_DOMAIN is not set >+# CONFIG_SCSI_GDTH is not set >+# CONFIG_SCSI_IPS is not set >+# CONFIG_SCSI_INITIO is not set >+# CONFIG_SCSI_INIA100 is not set >+# CONFIG_SCSI_SYM53C8XX_2 is not set >+# CONFIG_SCSI_PCI2000 is not set >+# CONFIG_SCSI_PCI2220I is not set >+# CONFIG_SCSI_QLOGIC_ISP is not set >+# CONFIG_SCSI_QLOGIC_FC is not set >+# CONFIG_SCSI_QLOGIC_1280 is not set >+CONFIG_SCSI_QLA2XXX=m >+# CONFIG_SCSI_QLA21XX is not set >+# CONFIG_SCSI_QLA22XX is not set >+# CONFIG_SCSI_QLA2300 is not set >+# CONFIG_SCSI_QLA2322 is not set >+# CONFIG_SCSI_QLA6312 is not set >+# CONFIG_SCSI_QLA6322 is not set >+# CONFIG_SCSI_DC395x is not set >+# CONFIG_SCSI_DC390T is not set >+# CONFIG_SCSI_NSP32 is not set >+# CONFIG_SCSI_DEBUG is not set >+ >+# >+# Multi-device support (RAID and LVM) >+# >+CONFIG_MD=y >+# CONFIG_BLK_DEV_MD is not set >+CONFIG_BLK_DEV_DM=m >+# CONFIG_DM_CRYPT is not set >+ >+# >+# Fusion MPT device support >+# >+# CONFIG_FUSION is not set >+ >+# >+# IEEE 1394 (FireWire) support >+# >+# CONFIG_IEEE1394 is not set >+ >+# >+# I2O device support >+# >+# CONFIG_I2O is not set >+ >+# >+# Macintosh device drivers >+# >+ >+# >+# Networking support >+# >+CONFIG_NET=y >+ >+# >+# Networking options >+# >+CONFIG_PACKET=m >+CONFIG_PACKET_MMAP=y >+CONFIG_NETLINK_DEV=m >+CONFIG_UNIX=m >+# CONFIG_NET_KEY is not set >+CONFIG_INET=y >+CONFIG_IP_MULTICAST=y >+CONFIG_IP_ADVANCED_ROUTER=y >+CONFIG_IP_MULTIPLE_TABLES=y >+CONFIG_IP_ROUTE_NAT=y >+CONFIG_IP_ROUTE_MULTIPATH=y >+CONFIG_IP_ROUTE_TOS=y >+CONFIG_IP_ROUTE_VERBOSE=y >+# CONFIG_IP_PNP is not set >+# CONFIG_NET_IPIP is not set >+# CONFIG_NET_IPGRE is not set >+# CONFIG_IP_MROUTE is not set >+# CONFIG_ARPD is not set >+# CONFIG_INET_ECN is not set >+# CONFIG_SYN_COOKIES is not set >+# CONFIG_INET_AH is not set >+# CONFIG_INET_ESP is not set >+# CONFIG_INET_IPCOMP is not set >+CONFIG_IPV6=m >+CONFIG_IPV6_PRIVACY=y >+# CONFIG_INET6_AH is not set >+# CONFIG_INET6_ESP is not set >+# CONFIG_INET6_IPCOMP is not set >+# CONFIG_IPV6_TUNNEL is not set >+# CONFIG_DECNET is not set >+# CONFIG_BRIDGE is not set >+# CONFIG_NETFILTER is not set >+ >+# >+# SCTP Configuration (EXPERIMENTAL) >+# >+CONFIG_IPV6_SCTP__=m >+# CONFIG_IP_SCTP is not set >+# CONFIG_ATM is not set >+# CONFIG_VLAN_8021Q is not set >+# CONFIG_LLC2 is not set >+# CONFIG_IPX is not set >+# CONFIG_ATALK is not set >+# CONFIG_X25 is not set >+# CONFIG_LAPB is not set >+# CONFIG_NET_DIVERT is not set >+# CONFIG_ECONET is not set >+# CONFIG_WAN_ROUTER is not set >+# CONFIG_NET_FASTROUTE is not set >+# CONFIG_NET_HW_FLOWCONTROL is not set >+ >+# >+# QoS and/or fair queueing >+# >+# CONFIG_NET_SCHED is not set >+ >+# >+# Network testing >+# >+# CONFIG_NET_PKTGEN is not set >+CONFIG_NETDEVICES=y >+ >+# >+# ARCnet devices >+# >+# CONFIG_ARCNET is not set >+CONFIG_DUMMY=m >+# CONFIG_BONDING is not set >+# CONFIG_EQUALIZER is not set >+# CONFIG_TUN is not set >+CONFIG_ETHERTAP=m >+ >+# >+# Ethernet (10 or 100Mbit) >+# >+CONFIG_NET_ETHERNET=y >+CONFIG_MII=m >+# CONFIG_HAPPYMEAL is not set >+# CONFIG_SUNGEM is not set >+# CONFIG_NET_VENDOR_3COM is not set >+ >+# >+# Tulip family network device support >+# >+# CONFIG_NET_TULIP is not set >+# CONFIG_HP100 is not set >+CONFIG_NET_PCI=y >+CONFIG_PCNET32=m >+# CONFIG_AMD8111_ETH is not set >+# CONFIG_ADAPTEC_STARFIRE is not set >+# CONFIG_B44 is not set >+CONFIG_FORCEDETH=m >+# CONFIG_DGRS is not set >+# CONFIG_EEPRO100 is not set >+# CONFIG_E100 is not set >+# CONFIG_FEALNX is not set >+# CONFIG_NATSEMI is not set >+# CONFIG_NE2K_PCI is not set >+# CONFIG_8139CP is not set >+# CONFIG_8139TOO is not set >+# CONFIG_SIS900 is not set >+# CONFIG_EPIC100 is not set >+# CONFIG_SUNDANCE is not set >+# CONFIG_TLAN is not set >+# CONFIG_VIA_RHINE is not set >+ >+# >+# Ethernet (1000 Mbit) >+# >+# CONFIG_ACENIC is not set >+# CONFIG_DL2K is not set >+# CONFIG_E1000 is not set >+# CONFIG_NS83820 is not set >+# CONFIG_HAMACHI is not set >+# CONFIG_YELLOWFIN is not set >+# CONFIG_R8169 is not set >+# CONFIG_SIS190 is not set >+# CONFIG_SK98LIN is not set >+# CONFIG_TIGON3 is not set >+ >+# >+# Ethernet (10000 Mbit) >+# >+# CONFIG_IXGB is not set >+# CONFIG_FDDI is not set >+# CONFIG_HIPPI is not set >+# CONFIG_PPP is not set >+# CONFIG_SLIP is not set >+ >+# >+# Wireless LAN (non-hamradio) >+# >+# CONFIG_NET_RADIO is not set >+ >+# >+# Token Ring devices >+# >+# CONFIG_TR is not set >+# CONFIG_NET_FC is not set >+# CONFIG_RCPCI is not set >+# CONFIG_SHAPER is not set >+ >+# >+# Wan interfaces >+# >+# CONFIG_WAN is not set >+ >+# >+# Amateur Radio support >+# >+# CONFIG_HAMRADIO is not set >+ >+# >+# IrDA (infrared) support >+# >+# CONFIG_IRDA is not set >+ >+# >+# Bluetooth support >+# >+# CONFIG_BT is not set >+ >+# >+# ISDN subsystem >+# >+# CONFIG_ISDN is not set >+ >+# >+# Telephony Support >+# >+# CONFIG_PHONE is not set >+ >+# >+# Input device support >+# >+CONFIG_INPUT=y >+ >+# >+# Userland interfaces >+# >+CONFIG_INPUT_MOUSEDEV=y >+CONFIG_INPUT_MOUSEDEV_PSAUX=y >+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 >+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=576 >+CONFIG_INPUT_JOYDEV=m >+# CONFIG_INPUT_TSDEV is not set >+CONFIG_INPUT_EVDEV=m >+# CONFIG_INPUT_EVBUG is not set >+ >+# >+# Input I/O drivers >+# >+# CONFIG_GAMEPORT is not set >+CONFIG_SOUND_GAMEPORT=y >+CONFIG_SERIO=y >+CONFIG_SERIO_I8042=y >+CONFIG_SERIO_SERPORT=m >+# CONFIG_SERIO_CT82C710 is not set >+CONFIG_SERIO_PCIPS2=m >+ >+# >+# Input Device Drivers >+# >+CONFIG_INPUT_KEYBOARD=y >+CONFIG_KEYBOARD_ATKBD=y >+# CONFIG_KEYBOARD_SUNKBD is not set >+# CONFIG_KEYBOARD_XTKBD is not set >+# CONFIG_KEYBOARD_NEWTON is not set >+CONFIG_INPUT_MOUSE=y >+CONFIG_MOUSE_PS2=m >+CONFIG_MOUSE_SERIAL=m >+# CONFIG_INPUT_JOYSTICK is not set >+# CONFIG_INPUT_TOUCHSCREEN is not set >+CONFIG_INPUT_MISC=y >+CONFIG_INPUT_PCSPKR=m >+CONFIG_INPUT_UINPUT=m >+ >+# >+# Character devices >+# >+CONFIG_VT=y >+CONFIG_VT_CONSOLE=y >+CONFIG_HW_CONSOLE=y >+# CONFIG_SERIAL_NONSTANDARD is not set >+ >+# >+# Serial drivers >+# >+CONFIG_SERIAL_8250=m >+CONFIG_SERIAL_8250_NR_UARTS=4 >+# CONFIG_SERIAL_8250_EXTENDED is not set >+ >+# >+# Non-8250 serial port support >+# >+CONFIG_SERIAL_CORE=m >+CONFIG_UNIX98_PTYS=y >+CONFIG_LEGACY_PTYS=y >+CONFIG_LEGACY_PTY_COUNT=256 >+ >+# >+# Mice >+# >+CONFIG_BUSMOUSE=m >+# CONFIG_QIC02_TAPE is not set >+ >+# >+# IPMI >+# >+# CONFIG_IPMI_HANDLER is not set >+ >+# >+# Watchdog Cards >+# >+# CONFIG_WATCHDOG is not set >+# CONFIG_HW_RANDOM is not set >+# CONFIG_NVRAM is not set >+CONFIG_RTC=m >+CONFIG_GEN_RTC=m >+CONFIG_GEN_RTC_X=y >+# CONFIG_DTLK is not set >+# CONFIG_R3964 is not set >+# CONFIG_APPLICOM is not set >+# CONFIG_SONYPI is not set >+ >+# >+# Ftape, the floppy tape device driver >+# >+CONFIG_FTAPE=m >+CONFIG_ZFTAPE=m >+CONFIG_ZFT_DFLT_BLK_SZ=10240 >+ >+# >+# The compressor will be built as a module only! >+# >+CONFIG_ZFT_COMPRESSOR=m >+CONFIG_FT_NR_BUFFERS=3 >+CONFIG_FT_PROC_FS=y >+CONFIG_FT_NORMAL_DEBUG=y >+# CONFIG_FT_FULL_DEBUG is not set >+# CONFIG_FT_NO_TRACE is not set >+# CONFIG_FT_NO_TRACE_AT_ALL is not set >+ >+# >+# Hardware configuration >+# >+CONFIG_FT_STD_FDC=y >+# CONFIG_FT_MACH2 is not set >+# CONFIG_FT_PROBE_FC10 is not set >+# CONFIG_FT_ALT_FDC is not set >+CONFIG_FT_FDC_THR=8 >+CONFIG_FT_FDC_MAX_RATE=2000 >+CONFIG_FT_ALPHA_CLOCK=0 >+CONFIG_AGP=m >+# CONFIG_AGP_ALI is not set >+# CONFIG_AGP_ATI is not set >+# CONFIG_AGP_AMD is not set >+# CONFIG_AGP_AMD64 is not set >+# CONFIG_AGP_INTEL is not set >+CONFIG_AGP_NVIDIA=m >+# CONFIG_AGP_SIS is not set >+# CONFIG_AGP_SWORKS is not set >+# CONFIG_AGP_VIA is not set >+# CONFIG_AGP_EFFICEON is not set >+CONFIG_DRM=y >+# CONFIG_DRM_TDFX is not set >+# CONFIG_DRM_GAMMA is not set >+# CONFIG_DRM_R128 is not set >+# CONFIG_DRM_RADEON is not set >+# CONFIG_DRM_MGA is not set >+# CONFIG_DRM_SIS is not set >+# CONFIG_MWAVE is not set >+CONFIG_RAW_DRIVER=m >+CONFIG_MAX_RAW_DEVS=256 >+CONFIG_HANGCHECK_TIMER=m >+ >+# >+# I2C support >+# >+CONFIG_I2C=y >+CONFIG_I2C_CHARDEV=y >+ >+# >+# I2C Algorithms >+# >+CONFIG_I2C_ALGOBIT=m >+CONFIG_I2C_ALGOPCF=m >+ >+# >+# I2C Hardware Bus support >+# >+# CONFIG_I2C_ALI1535 is not set >+# CONFIG_I2C_ALI15X3 is not set >+CONFIG_I2C_AMD756=m >+CONFIG_I2C_XBOX=y >+# CONFIG_I2C_AMD8111 is not set >+# CONFIG_I2C_ELV is not set >+# CONFIG_I2C_I801 is not set >+# CONFIG_I2C_I810 is not set >+# CONFIG_I2C_ISA is not set >+CONFIG_I2C_NFORCE2=m >+# CONFIG_I2C_PARPORT_LIGHT is not set >+# CONFIG_I2C_PIIX4 is not set >+# CONFIG_I2C_PROSAVAGE is not set >+# CONFIG_I2C_SAVAGE4 is not set >+# CONFIG_SCx200_ACB is not set >+# CONFIG_I2C_SIS5595 is not set >+# CONFIG_I2C_SIS630 is not set >+# CONFIG_I2C_SIS96X is not set >+# CONFIG_I2C_VELLEMAN is not set >+# CONFIG_I2C_VIA is not set >+# CONFIG_I2C_VIAPRO is not set >+# CONFIG_I2C_VOODOO3 is not set >+ >+# >+# I2C Hardware Sensors Chip support >+# >+CONFIG_I2C_SENSOR=m >+CONFIG_SENSORS_ADM1021=m >+# CONFIG_SENSORS_ASB100 is not set >+# CONFIG_SENSORS_EEPROM is not set >+# CONFIG_SENSORS_FSCHER is not set >+# CONFIG_SENSORS_GL518SM is not set >+# CONFIG_SENSORS_IT87 is not set >+# CONFIG_SENSORS_LM75 is not set >+# CONFIG_SENSORS_LM78 is not set >+# CONFIG_SENSORS_LM83 is not set >+# CONFIG_SENSORS_LM85 is not set >+# CONFIG_SENSORS_LM90 is not set >+# CONFIG_SENSORS_VIA686A is not set >+# CONFIG_SENSORS_W83781D is not set >+# CONFIG_SENSORS_W83L785TS is not set >+# CONFIG_I2C_DEBUG_CORE is not set >+# CONFIG_I2C_DEBUG_BUS is not set >+# CONFIG_I2C_DEBUG_CHIP is not set >+ >+# >+# Misc devices >+# >+# CONFIG_IBM_ASM is not set >+ >+# >+# Multimedia devices >+# >+# CONFIG_VIDEO_DEV is not set >+ >+# >+# Digital Video Broadcasting Devices >+# >+# CONFIG_DVB is not set >+ >+# >+# Graphics support >+# >+CONFIG_FB=y >+# CONFIG_FB_CIRRUS is not set >+# CONFIG_FB_PM2 is not set >+# CONFIG_FB_CYBER2000 is not set >+# CONFIG_FB_IMSTT is not set >+# CONFIG_FB_VGA16 is not set >+# CONFIG_FB_VESA is not set >+CONFIG_VIDEO_SELECT=y >+# CONFIG_FB_HGA is not set >+# CONFIG_FB_RIVA is not set >+CONFIG_FB_XBOX=y >+# CONFIG_FB_MATROX is not set >+# CONFIG_FB_RADEON_OLD is not set >+# CONFIG_FB_RADEON is not set >+# CONFIG_FB_ATY128 is not set >+# CONFIG_FB_ATY is not set >+# CONFIG_FB_SIS is not set >+# CONFIG_FB_NEOMAGIC is not set >+# CONFIG_FB_KYRO is not set >+# CONFIG_FB_3DFX is not set >+# CONFIG_FB_VOODOO1 is not set >+# CONFIG_FB_TRIDENT is not set >+# CONFIG_FB_PM3 is not set >+# CONFIG_FB_VIRTUAL is not set >+ >+# >+# Console display driver support >+# >+CONFIG_VGA_CONSOLE=y >+# CONFIG_MDA_CONSOLE is not set >+CONFIG_DUMMY_CONSOLE=y >+CONFIG_FRAMEBUFFER_CONSOLE=y >+CONFIG_PCI_CONSOLE=y >+CONFIG_FONTS=y >+CONFIG_FONT_8x8=y >+CONFIG_FONT_8x16=y >+# CONFIG_FONT_6x11 is not set >+# CONFIG_FONT_PEARL_8x8 is not set >+# CONFIG_FONT_ACORN_8x8 is not set >+# CONFIG_FONT_MINI_4x6 is not set >+# CONFIG_FONT_SUN8x16 is not set >+# CONFIG_FONT_SUN12x22 is not set >+ >+# >+# Logo configuration >+# >+CONFIG_LOGO=y >+CONFIG_LOGO_LINUX_MONO=y >+CONFIG_LOGO_LINUX_VGA16=y >+CONFIG_LOGO_LINUX_CLUT224=y >+ >+# >+# Sound >+# >+CONFIG_SOUND=m >+ >+# >+# Advanced Linux Sound Architecture >+# >+CONFIG_SND=m >+CONFIG_SND_SEQUENCER=m >+CONFIG_SND_SEQ_DUMMY=m >+CONFIG_SND_OSSEMUL=y >+CONFIG_SND_MIXER_OSS=m >+CONFIG_SND_PCM_OSS=m >+CONFIG_SND_SEQUENCER_OSS=y >+CONFIG_SND_RTCTIMER=m >+# CONFIG_SND_VERBOSE_PRINTK is not set >+# CONFIG_SND_DEBUG is not set >+ >+# >+# Generic devices >+# >+CONFIG_SND_DUMMY=m >+CONFIG_SND_VIRMIDI=m >+CONFIG_SND_MTPAV=m >+CONFIG_SND_SERIAL_U16550=m >+CONFIG_SND_MPU401=m >+ >+# >+# PCI devices >+# >+# CONFIG_SND_ALI5451 is not set >+# CONFIG_SND_AZT3328 is not set >+# CONFIG_SND_BT87X is not set >+# CONFIG_SND_CS46XX is not set >+# CONFIG_SND_CS4281 is not set >+# CONFIG_SND_EMU10K1 is not set >+# CONFIG_SND_KORG1212 is not set >+# CONFIG_SND_NM256 is not set >+# CONFIG_SND_RME32 is not set >+# CONFIG_SND_RME96 is not set >+# CONFIG_SND_RME9652 is not set >+# CONFIG_SND_HDSP is not set >+# CONFIG_SND_TRIDENT is not set >+# CONFIG_SND_YMFPCI is not set >+# CONFIG_SND_ALS4000 is not set >+# CONFIG_SND_CMIPCI is not set >+# CONFIG_SND_ENS1370 is not set >+# CONFIG_SND_ENS1371 is not set >+# CONFIG_SND_ES1938 is not set >+# CONFIG_SND_ES1968 is not set >+# CONFIG_SND_MAESTRO3 is not set >+# CONFIG_SND_FM801 is not set >+# CONFIG_SND_ICE1712 is not set >+# CONFIG_SND_ICE1724 is not set >+CONFIG_SND_INTEL8X0=m >+# CONFIG_SND_SONICVIBES is not set >+# CONFIG_SND_VIA82XX is not set >+# CONFIG_SND_VX222 is not set >+ >+# >+# ALSA USB devices >+# >+CONFIG_SND_USB_AUDIO=m >+ >+# >+# Open Sound System >+# >+# CONFIG_SOUND_PRIME is not set >+ >+# >+# USB support >+# >+CONFIG_USB=m >+# CONFIG_USB_DEBUG is not set >+ >+# >+# Miscellaneous USB options >+# >+CONFIG_USB_DEVICEFS=y >+CONFIG_USB_BANDWIDTH=y >+CONFIG_USB_DYNAMIC_MINORS=y >+ >+# >+# USB Host Controller Drivers >+# >+CONFIG_USB_EHCI_HCD=m >+CONFIG_USB_OHCI_HCD=m >+CONFIG_USB_UHCI_HCD=m >+ >+# >+# USB Device Class drivers >+# >+CONFIG_USB_AUDIO=m >+CONFIG_USB_BLUETOOTH_TTY=m >+CONFIG_USB_MIDI=m >+CONFIG_USB_ACM=m >+CONFIG_USB_PRINTER=m >+CONFIG_USB_STORAGE=m >+# CONFIG_USB_STORAGE_DEBUG is not set >+CONFIG_USB_STORAGE_DATAFAB=y >+CONFIG_USB_STORAGE_FREECOM=y >+CONFIG_USB_STORAGE_ISD200=y >+CONFIG_USB_STORAGE_DPCM=y >+CONFIG_USB_STORAGE_HP8200e=y >+CONFIG_USB_STORAGE_SDDR09=y >+CONFIG_USB_STORAGE_SDDR55=y >+CONFIG_USB_STORAGE_JUMPSHOT=y >+ >+# >+# USB Human Interface Devices (HID) >+# >+CONFIG_USB_HID=m >+CONFIG_USB_HIDINPUT=y >+CONFIG_HID_FF=y >+CONFIG_HID_PID=y >+CONFIG_LOGITECH_FF=y >+CONFIG_THRUSTMASTER_FF=y >+CONFIG_USB_HIDDEV=y >+ >+# >+# USB HID Boot Protocol drivers >+# >+CONFIG_USB_KBD=m >+CONFIG_USB_MOUSE=m >+CONFIG_USB_AIPTEK=m >+CONFIG_USB_WACOM=m >+CONFIG_USB_KBTAB=m >+CONFIG_USB_POWERMATE=m >+CONFIG_USB_XPAD=m >+CONFIG_USB_XPAD_MOUSE=y >+ >+# >+# USB Imaging devices >+# >+CONFIG_USB_MDC800=m >+CONFIG_USB_MICROTEK=m >+CONFIG_USB_HPUSBSCSI=m >+ >+# >+# USB Multimedia devices >+# >+CONFIG_USB_DABUSB=m >+ >+# >+# Video4Linux support is needed for USB Multimedia device support >+# >+ >+# >+# USB Network adaptors >+# >+CONFIG_USB_CATC=m >+CONFIG_USB_KAWETH=m >+CONFIG_USB_PEGASUS=m >+CONFIG_USB_RTL8150=m >+CONFIG_USB_USBNET=m >+ >+# >+# USB Host-to-Host Cables >+# >+CONFIG_USB_AN2720=y >+CONFIG_USB_BELKIN=y >+CONFIG_USB_GENESYS=y >+CONFIG_USB_NET1080=y >+CONFIG_USB_PL2301=y >+ >+# >+# Intelligent USB Devices/Gadgets >+# >+CONFIG_USB_ARMLINUX=y >+CONFIG_USB_EPSON2888=y >+CONFIG_USB_ZAURUS=y >+CONFIG_USB_CDCETHER=y >+ >+# >+# USB Network Adapters >+# >+CONFIG_USB_AX8817X=y >+ >+# >+# USB port drivers >+# >+ >+# >+# USB Serial Converter support >+# >+CONFIG_USB_SERIAL=m >+CONFIG_USB_SERIAL_GENERIC=y >+CONFIG_USB_SERIAL_BELKIN=m >+CONFIG_USB_SERIAL_WHITEHEAT=m >+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m >+CONFIG_USB_SERIAL_EMPEG=m >+CONFIG_USB_SERIAL_FTDI_SIO=m >+CONFIG_USB_SERIAL_VISOR=m >+CONFIG_USB_SERIAL_IPAQ=m >+CONFIG_USB_SERIAL_IR=m >+CONFIG_USB_SERIAL_EDGEPORT=m >+CONFIG_USB_SERIAL_EDGEPORT_TI=m >+CONFIG_USB_SERIAL_KEYSPAN_PDA=m >+CONFIG_USB_SERIAL_KEYSPAN=m >+CONFIG_USB_SERIAL_KEYSPAN_MPR=y >+CONFIG_USB_SERIAL_KEYSPAN_USA28=y >+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y >+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y >+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y >+CONFIG_USB_SERIAL_KEYSPAN_USA19=y >+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y >+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y >+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y >+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y >+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y >+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y >+CONFIG_USB_SERIAL_KLSI=m >+CONFIG_USB_SERIAL_KOBIL_SCT=m >+CONFIG_USB_SERIAL_MCT_U232=m >+CONFIG_USB_SERIAL_PL2303=m >+# CONFIG_USB_SERIAL_SAFE is not set >+CONFIG_USB_SERIAL_CYBERJACK=m >+CONFIG_USB_SERIAL_XIRCOM=m >+CONFIG_USB_SERIAL_OMNINET=m >+CONFIG_USB_EZUSB=y >+ >+# >+# USB Miscellaneous drivers >+# >+CONFIG_USB_EMI62=m >+CONFIG_USB_EMI26=m >+CONFIG_USB_TIGL=m >+CONFIG_USB_AUERSWALD=m >+CONFIG_USB_RIO500=m >+CONFIG_USB_LEGOTOWER=m >+CONFIG_USB_BRLVGER=m >+CONFIG_USB_LCD=m >+CONFIG_USB_LED=m >+CONFIG_USB_TEST=m >+ >+# >+# USB Gadget Support >+# >+CONFIG_USB_GADGET=m >+CONFIG_USB_GADGET_NET2280=y >+CONFIG_USB_NET2280=m >+# CONFIG_USB_GADGET_PXA2XX is not set >+# CONFIG_USB_GADGET_GOKU is not set >+# CONFIG_USB_GADGET_SA1100 is not set >+CONFIG_USB_ZERO=m >+CONFIG_USB_ETH=m >+CONFIG_USB_GADGETFS=m >+CONFIG_USB_FILE_STORAGE=m >+# CONFIG_USB_FILE_STORAGE_TEST is not set >+CONFIG_USB_G_SERIAL=m >+ >+# >+# File systems >+# >+CONFIG_EXT2_FS=y >+CONFIG_EXT3_FS=m >+# CONFIG_JBD is not set >+CONFIG_REISERFS_FS=y >+# CONFIG_REISERFS_CHECK is not set >+CONFIG_REISERFS_PROC_INFO=y >+# CONFIG_JFS_FS is not set >+# CONFIG_XFS_FS is not set >+# CONFIG_MINIX_FS is not set >+# CONFIG_ROMFS_FS is not set >+# CONFIG_QUOTA is not set >+# CONFIG_AUTOFS_FS is not set >+# CONFIG_AUTOFS4_FS is not set >+ >+# >+# CD-ROM/DVD Filesystems >+# >+CONFIG_ISO9660_FS=y >+CONFIG_JOLIET=y >+CONFIG_ZISOFS=y >+CONFIG_ZISOFS_FS=y >+CONFIG_UDF_FS=y >+ >+# >+# DOS/FAT/NT Filesystems >+# >+CONFIG_FAT_FS=m >+CONFIG_MSDOS_FS=m >+CONFIG_VFAT_FS=m >+CONFIG_NTFS_FS=m >+# CONFIG_NTFS_DEBUG is not set >+CONFIG_NTFS_RW=y >+CONFIG_FATX_FS=m >+ >+# >+# Pseudo filesystems >+# >+CONFIG_PROC_FS=y >+CONFIG_PROC_KCORE=y >+CONFIG_DEVFS_FS=y >+CONFIG_DEVFS_MOUNT=y >+# CONFIG_DEVFS_DEBUG is not set >+# CONFIG_DEVPTS_FS_XATTR is not set >+CONFIG_TMPFS=y >+# CONFIG_HUGETLBFS is not set >+# CONFIG_HUGETLB_PAGE is not set >+CONFIG_RAMFS=y >+ >+# >+# Miscellaneous filesystems >+# >+# CONFIG_ADFS_FS is not set >+# CONFIG_AFFS_FS is not set >+# CONFIG_HFS_FS is not set >+# CONFIG_HFSPLUS_FS is not set >+# CONFIG_BEFS_FS is not set >+# CONFIG_BFS_FS is not set >+# CONFIG_EFS_FS is not set >+CONFIG_CRAMFS=y >+# CONFIG_VXFS_FS is not set >+# CONFIG_HPFS_FS is not set >+# CONFIG_QNX4FS_FS is not set >+# CONFIG_SYSV_FS is not set >+# CONFIG_UFS_FS is not set >+ >+# >+# Network File Systems >+# >+CONFIG_NFS_FS=m >+CONFIG_NFS_V3=y >+CONFIG_NFS_V4=y >+CONFIG_NFS_DIRECTIO=y >+CONFIG_NFSD=m >+CONFIG_NFSD_V3=y >+CONFIG_NFSD_V4=y >+CONFIG_NFSD_TCP=y >+CONFIG_LOCKD=m >+CONFIG_LOCKD_V4=y >+CONFIG_EXPORTFS=m >+CONFIG_SUNRPC=m >+# CONFIG_SUNRPC_GSS is not set >+CONFIG_SMB_FS=m >+CONFIG_SMB_NLS_DEFAULT=y >+CONFIG_SMB_NLS_REMOTE="cp850" >+CONFIG_CIFS=m >+# CONFIG_NCP_FS is not set >+# CONFIG_CODA_FS is not set >+# CONFIG_INTERMEZZO_FS is not set >+# CONFIG_AFS_FS is not set >+ >+# >+# Partition Types >+# >+CONFIG_PARTITION_ADVANCED=y >+# CONFIG_ACORN_PARTITION is not set >+# CONFIG_OSF_PARTITION is not set >+# CONFIG_AMIGA_PARTITION is not set >+# CONFIG_ATARI_PARTITION is not set >+# CONFIG_MAC_PARTITION is not set >+CONFIG_MSDOS_PARTITION=y >+# CONFIG_BSD_DISKLABEL is not set >+# CONFIG_MINIX_SUBPARTITION is not set >+# CONFIG_SOLARIS_X86_PARTITION is not set >+# CONFIG_UNIXWARE_DISKLABEL is not set >+# CONFIG_LDM_PARTITION is not set >+# CONFIG_NEC98_PARTITION is not set >+# CONFIG_SGI_PARTITION is not set >+# CONFIG_ULTRIX_PARTITION is not set >+# CONFIG_SUN_PARTITION is not set >+# CONFIG_EFI_PARTITION is not set >+CONFIG_XBOX_PARTITION=y >+ >+# >+# Native Language Support >+# >+CONFIG_NLS=y >+CONFIG_NLS_DEFAULT="iso8859-15" >+CONFIG_NLS_CODEPAGE_437=m >+CONFIG_NLS_CODEPAGE_737=m >+CONFIG_NLS_CODEPAGE_775=m >+CONFIG_NLS_CODEPAGE_850=m >+CONFIG_NLS_CODEPAGE_852=m >+CONFIG_NLS_CODEPAGE_855=m >+CONFIG_NLS_CODEPAGE_857=m >+CONFIG_NLS_CODEPAGE_860=m >+CONFIG_NLS_CODEPAGE_861=m >+CONFIG_NLS_CODEPAGE_862=m >+CONFIG_NLS_CODEPAGE_863=m >+CONFIG_NLS_CODEPAGE_864=m >+CONFIG_NLS_CODEPAGE_865=m >+CONFIG_NLS_CODEPAGE_866=m >+CONFIG_NLS_CODEPAGE_869=m >+CONFIG_NLS_CODEPAGE_936=m >+CONFIG_NLS_CODEPAGE_950=m >+CONFIG_NLS_CODEPAGE_932=m >+CONFIG_NLS_CODEPAGE_949=m >+CONFIG_NLS_CODEPAGE_874=m >+CONFIG_NLS_ISO8859_8=m >+CONFIG_NLS_CODEPAGE_1250=m >+CONFIG_NLS_CODEPAGE_1251=m >+CONFIG_NLS_ISO8859_1=m >+CONFIG_NLS_ISO8859_2=m >+CONFIG_NLS_ISO8859_3=m >+CONFIG_NLS_ISO8859_4=m >+CONFIG_NLS_ISO8859_5=m >+CONFIG_NLS_ISO8859_6=m >+CONFIG_NLS_ISO8859_7=m >+CONFIG_NLS_ISO8859_9=m >+CONFIG_NLS_ISO8859_13=m >+CONFIG_NLS_ISO8859_14=m >+CONFIG_NLS_ISO8859_15=m >+CONFIG_NLS_KOI8_R=m >+CONFIG_NLS_KOI8_U=m >+CONFIG_NLS_UTF8=m >+ >+# >+# Profiling support >+# >+# CONFIG_PROFILING is not set >+ >+# >+# Kernel hacking >+# >+# CONFIG_DEBUG_KERNEL is not set >+# CONFIG_EARLY_PRINTK is not set >+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set >+# CONFIG_FRAME_POINTER is not set >+ >+# >+# Security options >+# >+# CONFIG_SECURITY is not set >+ >+# >+# Cryptographic options >+# >+CONFIG_CRYPTO=y >+CONFIG_CRYPTO_HMAC=y >+CONFIG_CRYPTO_NULL=m >+CONFIG_CRYPTO_MD4=m >+CONFIG_CRYPTO_MD5=m >+CONFIG_CRYPTO_SHA1=m >+CONFIG_CRYPTO_SHA256=m >+CONFIG_CRYPTO_SHA512=m >+CONFIG_CRYPTO_DES=m >+CONFIG_CRYPTO_BLOWFISH=m >+CONFIG_CRYPTO_TWOFISH=m >+CONFIG_CRYPTO_SERPENT=m >+CONFIG_CRYPTO_AES=m >+CONFIG_CRYPTO_CAST5=m >+CONFIG_CRYPTO_CAST6=m >+# CONFIG_CRYPTO_ARC4 is not set >+CONFIG_CRYPTO_DEFLATE=m >+CONFIG_CRYPTO_TEST=m >+ >+# >+# Library routines >+# >+CONFIG_CRC32=m >+CONFIG_ZLIB_INFLATE=y >+CONFIG_ZLIB_DEFLATE=m >diff -urN linux-2.6.6.orig/sound/pci/ac97/ac97_codec.c linux-2.6.6/sound/pci/ac97/ac97_codec.c >--- linux-2.6.6.orig/sound/pci/ac97/ac97_codec.c 2004-05-10 03:32:28.000000000 +0100 >+++ linux-2.6.6/sound/pci/ac97/ac97_codec.c 2004-05-10 12:30:23.000000000 +0100 >@@ -1807,10 +1807,13 @@ > } > > if (!ac97_is_audio(ac97) && !ac97_is_modem(ac97)) { >+ /* PATCH FOR XBOX */ >+ /* > if (!(ac97->scaps & (AC97_SCAP_SKIP_AUDIO|AC97_SCAP_SKIP_MODEM))) > snd_printk(KERN_ERR "AC'97 %d access error (not audio or modem codec)\n", ac97->num); > snd_ac97_free(ac97); > return -EACCES; >+ */ > } > > if (bus->reset) // FIXME: always skipping? >diff -urN linux-2.6.6.orig/sound/usb/usbquirks.h linux-2.6.6/sound/usb/usbquirks.h >--- linux-2.6.6.orig/sound/usb/usbquirks.h 2004-05-10 03:32:28.000000000 +0100 >+++ linux-2.6.6/sound/usb/usbquirks.h 2004-05-10 12:30:23.000000000 +0100 >@@ -653,6 +653,80 @@ > .type = QUIRK_MIDI_STANDARD_INTERFACE > } > }, >+{ /* >+ * This quirk is for the Xbox Communicator >+ * please NOTE: >+ * >+ * THIS HAS _NOT_ BEEN TESTED THOROUGHLY! >+ * >+ * IT IS REALLY JUST SOME COPY&PASTE FROM ABOVE. >+ * You have been warned. >+ * >+ * In fact, I managed to kinda crash it and the Xbox hung while >+ * cleaning up alsa on shutdown. >+ * >+ * What worked was to cat <file> > /dev/dsp and get static >+ * on the headset. Getting Mplayer to output sound did not work >+ * for me (no music files and therefore no extensive tests, though). >+ * Also I had no luck with the mic, mixer said it "found no elements". >+ * >+ * If you wanna try, go ahead and report to xbox-linux.org (ML, IRC) >+ * >+ * Marko Friedemann <mfr@bmx-chemnitz.de> >+ */ >+ USB_DEVICE(0x045e, 0x0283), >+ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { >+ .vendor_name = "Microsoft", >+ .product_name = "Xbox Communicator", >+ .ifnum = QUIRK_ANY_INTERFACE, >+ .type = QUIRK_COMPOSITE, >+ .data = & (const snd_usb_audio_quirk_t[]) { >+ { >+ .ifnum = 0, >+ .type = QUIRK_AUDIO_FIXED_ENDPOINT, >+ .data = & (const struct audioformat) { >+ /* seems might as well be wrong */ >+ .format = SNDRV_PCM_FORMAT_S16_LE, >+ /* as might this */ >+ .channels = 1, >+ .iface = 0, >+ .altsetting = 0, >+ .altset_idx = 0, >+ .attributes = 0, >+ .endpoint = 0x04, >+ .ep_attr = 0x05, >+ /* and those */ >+ .rates = SNDRV_PCM_RATE_CONTINUOUS, >+ .rate_min = 44100, >+ .rate_max = 44100, >+ } >+ }, >+ { >+ .ifnum = 1, >+ .type = QUIRK_AUDIO_FIXED_ENDPOINT, >+ .data = & (const struct audioformat) { >+ /* seems might as well be wrong */ >+ .format = SNDRV_PCM_FORMAT_S16_LE, >+ /* as might this */ >+ .channels = 1, >+ .iface = 1, >+ .altsetting = 0, >+ .altset_idx = 0, >+ .attributes = 0, >+ .endpoint = 0x85, >+ .ep_attr = 0x05, >+ /* and those */ >+ .rates = SNDRV_PCM_RATE_CONTINUOUS, >+ .rate_min = 44100, >+ .rate_max = 44100, >+ } >+ }, >+ { >+ .ifnum = -1 >+ } >+ } >+ } >+}, > > /* Midiman/M-Audio devices */ > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45100
:
27590
|
27591
|
27592
|
31021
|
31022
|
31023
|
31024
|
31038
|
31039
|
31040
|
31094
| 31095 |
32231
|
32232
|
32233
|
33099
|
33100
|
33101
|
35462
|
35463
|
35466