diff options
189 files changed, 5104 insertions, 3578 deletions
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 39a9c8aee6ee..129bbbb7d246 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -299,6 +299,8 @@ KAO --> EHCI, OHCI, or UHCI. </para> !Edrivers/usb/core/hcd.c +!Edrivers/usb/core/hcd-pci.c +!Edrivers/usb/core/buffer.c </sect1> </chapter> diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 7b98848f723f..8772f5a9509a 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -283,10 +283,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL support' @@ -314,6 +310,8 @@ if [ "$CONFIG_PCI" = "y" ]; then fi if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/cris/config.in b/arch/cris/config.in index 749f99120660..fee3cbd8e93e 100644 --- a/arch/cris/config.in +++ b/arch/cris/config.in @@ -135,12 +135,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - mainmenu_option next_comment comment 'ATA/IDE/MFM/RLL support' @@ -168,6 +162,8 @@ source drivers/ieee1394/Config.in source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' @@ -187,6 +183,8 @@ source net/irda/Config.in source drivers/isdn/Config.in +source drivers/telephony/Config.in + mainmenu_option next_comment comment 'Old CD-ROM drivers (not SCSI, not IDE)' diff --git a/arch/i386/config.in b/arch/i386/config.in index 45a94723913a..ef14ef970d4d 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -332,12 +332,6 @@ endmenu source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - source drivers/message/fusion/Config.in source drivers/ieee1394/Config.in @@ -345,6 +339,8 @@ source drivers/ieee1394/Config.in source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' @@ -364,6 +360,8 @@ source net/irda/Config.in source drivers/isdn/Config.in +source drivers/telephony/Config.in + # # input before char - char/joystick depends on it. As does USB. # diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index b6475816bc4f..2b3f4d17b791 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -214,6 +214,7 @@ #include <linux/sched.h> #include <linux/pm.h> #include <linux/kernel.h> +#include <linux/smp.h> #include <linux/smp_lock.h> #include <asm/system.h> @@ -419,6 +420,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static struct apm_user * user_list; static spinlock_t user_list_lock = SPIN_LOCK_UNLOCKED; +static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; static char driver_version[] = "1.16"; /* no spaces */ @@ -568,7 +570,12 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi) { APM_DECL_SEGS - unsigned long flags; + unsigned long flags; + int cpu = smp_processor_id(); + struct desc_struct save_desc_40; + + save_desc_40 = cpu_gdt_table[cpu][0x40 / 8]; + cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc; local_save_flags(flags); APM_DO_CLI; @@ -591,6 +598,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, : "memory", "cc"); APM_DO_RESTORE_SEGS; local_irq_restore(flags); + cpu_gdt_table[cpu][0x40 / 8] = save_desc_40; return *eax & 0xff; } @@ -613,6 +621,11 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) u8 error; APM_DECL_SEGS unsigned long flags; + int cpu = smp_processor_id(); + struct desc_struct save_desc_40; + + save_desc_40 = cpu_gdt_table[cpu][0x40 / 8]; + cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc; local_save_flags(flags); APM_DO_CLI; @@ -639,6 +652,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) } APM_DO_RESTORE_SEGS; local_irq_restore(flags); + cpu_gdt_table[smp_processor_id()][0x40 / 8] = save_desc_40; return error; } @@ -931,9 +945,9 @@ static void handle_poweroff (int key, struct pt_regs *pt_regs, } static struct sysrq_key_op sysrq_poweroff_op = { - handler: handle_poweroff, - help_msg: "Off", - action_msg: "Power Off\n" + .handler = handle_poweroff, + .help_msg = "Off", + .action_msg = "Power Off\n" }; @@ -1826,12 +1840,12 @@ __setup("apm=", apm_setup); #endif static struct file_operations apm_bios_fops = { - owner: THIS_MODULE, - read: do_read, - poll: do_poll, - ioctl: do_ioctl, - open: do_open, - release: do_release, + .owner = THIS_MODULE, + .read = do_read, + .poll = do_poll, + .ioctl = do_ioctl, + .open = do_open, + .release = do_release, }; static struct miscdevice apm_device = { @@ -1927,13 +1941,13 @@ static int __init apm_init(void) * NOTE: on SMP we call into the APM BIOS only on CPU#0, so it's * enough to modify CPU#0's GDT. */ - for (i = 0; i < NR_CPUS; i++) { - set_base(cpu_gdt_table[i][APM_40 >> 3], - __va((unsigned long)0x40 << 4)); - _set_limit((char *)&cpu_gdt_table[i][APM_40 >> 3], 4095 - (0x40 << 4)); + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); + + apm_bios_entry.offset = apm_info.bios.offset; + apm_bios_entry.segment = APM_CS; - apm_bios_entry.offset = apm_info.bios.offset; - apm_bios_entry.segment = APM_CS; + for (i = 0; i < NR_CPUS; i++) { set_base(cpu_gdt_table[i][APM_CS >> 3], __va((unsigned long)apm_info.bios.cseg << 4)); set_base(cpu_gdt_table[i][APM_CS_16 >> 3], diff --git a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c index e57644c66229..a6e685b12f8b 100644 --- a/arch/i386/kernel/bluesmoke.c +++ b/arch/i386/kernel/bluesmoke.c @@ -307,7 +307,7 @@ static void do_mce_timer(void *data) } static struct tq_struct mce_task = { - routine: do_mce_timer + .routine = do_mce_timer }; static void mce_timerfunc (unsigned long data) diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 23b42fc63941..9c7f94037fda 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -189,8 +189,8 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) } static struct cpu_dev amd_cpu_dev __initdata = { - c_vendor: "AMD", - c_ident: { "AuthenticAMD" }, + .c_vendor = "AMD", + .c_ident = { "AuthenticAMD" }, c_models: { { X86_VENDOR_AMD, 4, { @@ -203,9 +203,9 @@ static struct cpu_dev amd_cpu_dev __initdata = { } }, }, - c_init: init_amd, - c_identify: amd_identify, - c_size_cache: amd_size_cache, + .c_init = init_amd, + .c_identify = amd_identify, + .c_size_cache = amd_size_cache, }; int __init amd_init_cpu(void) diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index e5bd1bebc4b0..a59806babec7 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c @@ -411,10 +411,10 @@ static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size } static struct cpu_dev centaur_cpu_dev __initdata = { - c_vendor: "Centaur", - c_ident: { "CentaurHauls" }, - c_init: init_centaur, - c_size_cache: centaur_size_cache, + .c_vendor = "Centaur", + .c_ident = { "CentaurHauls" }, + .c_init = init_centaur, + .c_size_cache = centaur_size_cache, }; int __init centaur_init_cpu(void) diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index cf90d41aba42..35b2fea4d03d 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -31,7 +31,7 @@ static void default_init(struct cpuinfo_x86 * c) } static struct cpu_dev default_cpu = { - c_init: default_init, + .c_init = default_init, }; static struct cpu_dev * this_cpu = &default_cpu; diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index d9d3771b428d..572889eed255 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -322,10 +322,10 @@ static void cyrix_identify(struct cpuinfo_x86 * c) } static struct cpu_dev cyrix_cpu_dev __initdata = { - c_vendor: "Cyrix", - c_ident: { "CyrixInstead" }, - c_init: init_cyrix, - c_identify: cyrix_identify, + .c_vendor = "Cyrix", + .c_ident = { "CyrixInstead" }, + .c_init = init_cyrix, + .c_identify = cyrix_identify, }; int __init cyrix_init_cpu(void) @@ -337,10 +337,10 @@ int __init cyrix_init_cpu(void) //early_arch_initcall(cyrix_init_cpu); static struct cpu_dev nsc_cpu_dev __initdata = { - c_vendor: "NSC", - c_ident: { "Geode by NSC" }, - c_init: init_cyrix, - c_identify: generic_identify, + .c_vendor = "NSC", + .c_ident = { "Geode by NSC" }, + .c_init = init_cyrix, + .c_identify = generic_identify, }; int __init nsc_init_cpu(void) diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 636e88762ef1..ff98d996d336 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -327,8 +327,8 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) } static struct cpu_dev intel_cpu_dev __initdata = { - c_vendor: "Intel", - c_ident: { "GenuineIntel" }, + .c_vendor = "Intel", + .c_ident = { "GenuineIntel" }, c_models: { { X86_VENDOR_INTEL, 4, { @@ -375,9 +375,9 @@ static struct cpu_dev intel_cpu_dev __initdata = { } }, }, - c_init: init_intel, - c_identify: generic_identify, - c_size_cache: intel_size_cache, + .c_init = init_intel, + .c_identify = generic_identify, + .c_size_cache = intel_size_cache, }; __init int intel_cpu_init(void) diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/i386/kernel/cpu/nexgen.c index 487e9e795d79..18da763a4fc9 100644 --- a/arch/i386/kernel/cpu/nexgen.c +++ b/arch/i386/kernel/cpu/nexgen.c @@ -42,13 +42,13 @@ static void nexgen_identify(struct cpuinfo_x86 * c) } static struct cpu_dev nexgen_cpu_dev __initdata = { - c_vendor: "Nexgen", - c_ident: { "NexGenDriven" }, + .c_vendor = "Nexgen", + .c_ident = { "NexGenDriven" }, c_models: { { X86_VENDOR_NEXGEN,5, { [1] "Nx586" } }, }, - c_init: init_nexgen, - c_identify: nexgen_identify, + .c_init = init_nexgen, + .c_identify = nexgen_identify, }; int __init nexgen_init_cpu(void) diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 570affdb1f0c..4788021a9a1b 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -119,8 +119,8 @@ static void c_stop(struct seq_file *m, void *v) { } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c index e56935319bba..19b420e2d5f1 100644 --- a/arch/i386/kernel/cpu/rise.c +++ b/arch/i386/kernel/cpu/rise.c @@ -29,8 +29,8 @@ static void __init init_rise(struct cpuinfo_x86 *c) } static struct cpu_dev rise_cpu_dev __initdata = { - c_vendor: "Rise", - c_ident: { "RiseRiseRise" }, + .c_vendor = "Rise", + .c_ident = { "RiseRiseRise" }, c_models: { { X86_VENDOR_RISE, 5, { @@ -41,7 +41,7 @@ static struct cpu_dev rise_cpu_dev __initdata = { } }, }, - c_init: init_rise, + .c_init = init_rise, }; int __init rise_init_cpu(void) diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index 3fe5124e438f..2314da6f8421 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c @@ -80,10 +80,10 @@ static void transmeta_identify(struct cpuinfo_x86 * c) } static struct cpu_dev transmeta_cpu_dev __initdata = { - c_vendor: "Transmeta", - c_ident: { "GenuineTMx86", "TransmetaCPU" }, - c_init: init_transmeta, - c_identify: transmeta_identify, + .c_vendor = "Transmeta", + .c_ident = { "GenuineTMx86", "TransmetaCPU" }, + .c_init = init_transmeta, + .c_identify = transmeta_identify, }; int __init transmeta_init_cpu(void) diff --git a/arch/i386/kernel/cpu/umc.c b/arch/i386/kernel/cpu/umc.c index a99545811457..ae8eed32e982 100644 --- a/arch/i386/kernel/cpu/umc.c +++ b/arch/i386/kernel/cpu/umc.c @@ -11,8 +11,8 @@ static void __init init_umc(struct cpuinfo_x86 * c) } static struct cpu_dev umc_cpu_dev __initdata = { - c_vendor: "UMC", - c_ident: { "UMC UMC UMC" }, + .c_vendor = "UMC", + .c_ident = { "UMC UMC UMC" }, c_models: { { X86_VENDOR_UMC, 4, { @@ -21,7 +21,7 @@ static struct cpu_dev umc_cpu_dev __initdata = { } }, }, - c_init: init_umc, + .c_init = init_umc, }; int __init umc_init_cpu(void) diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 546f83f03f0f..871c21a29b1e 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -146,10 +146,10 @@ static int cpuid_open(struct inode *inode, struct file *file) * File operations we support */ static struct file_operations cpuid_fops = { - owner: THIS_MODULE, - llseek: cpuid_seek, - read: cpuid_read, - open: cpuid_open, + .owner = THIS_MODULE, + .llseek = cpuid_seek, + .read = cpuid_read, + .open = cpuid_open, }; int __init cpuid_init(void) diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 6e875d22283f..4f7a5472eb1c 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -247,13 +247,13 @@ static int i8259A_resume(struct device *dev, u32 level) } static struct device_driver driver_i8259A = { - resume: i8259A_resume, + .resume = i8259A_resume, }; static struct device device_i8259A = { - name: "i8259A", - bus_id: "0020", - driver: &driver_i8259A, + .name = "i8259A", + .bus_id = "0020", + .driver = &driver_i8259A, }; static int __init init_8259A_devicefs(void) diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 0e2577f00d2c..ccdebea64733 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -109,17 +109,17 @@ static unsigned int mc_fsize; /* file size of /dev/cpu/microcode */ /* we share file_operations between misc and devfs mechanisms */ static struct file_operations microcode_fops = { - owner: THIS_MODULE, - read: microcode_read, - write: microcode_write, - ioctl: microcode_ioctl, - open: microcode_open, + .owner = THIS_MODULE, + .read = microcode_read, + .write = microcode_write, + .ioctl = microcode_ioctl, + .open = microcode_open, }; static struct miscdevice microcode_dev = { - minor: MICROCODE_MINOR, - name: "microcode", - fops: µcode_fops, + .minor = MICROCODE_MINOR, + .name = "microcode", + .fops = µcode_fops, }; static devfs_handle_t devfs_handle; diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index e125a183e33c..5ad97d4a10c3 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -246,11 +246,11 @@ static int msr_open(struct inode *inode, struct file *file) * File operations we support */ static struct file_operations msr_fops = { - owner: THIS_MODULE, - llseek: msr_seek, - read: msr_read, - write: msr_write, - open: msr_open, + .owner = THIS_MODULE, + .llseek = msr_seek, + .read = msr_read, + .write = msr_write, + .open = msr_open, }; int __init msr_init(void) diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c index c17e01b48bab..79e925e8c59a 100644 --- a/arch/i386/kernel/mtrr.c +++ b/arch/i386/kernel/mtrr.c @@ -1836,11 +1836,11 @@ static int mtrr_close (struct inode *ino, struct file *file) static struct file_operations mtrr_fops = { - owner: THIS_MODULE, - read: mtrr_read, - write: mtrr_write, - ioctl: mtrr_ioctl, - release: mtrr_close, + .owner = THIS_MODULE, + .read = mtrr_read, + .write = mtrr_write, + .ioctl = mtrr_ioctl, + .release = mtrr_close, }; # ifdef CONFIG_PROC_FS diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b5c74b80769d..49cb22992039 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -566,6 +566,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, struct_cpy(childregs, regs); childregs->eax = 0; childregs->esp = esp; + p->user_vm_lock = NULL; p->thread.esp = (unsigned long) childregs; p->thread.esp0 = (unsigned long) (childregs+1); @@ -587,6 +588,47 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, IO_BITMAP_BYTES); } + /* + * The common fastpath: + */ + if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_RELEASE_VM))) + return 0; + /* + * Set a new TLS for the child thread? + */ + if (clone_flags & CLONE_SETTLS) { + struct desc_struct *desc; + struct user_desc info; + int idx; + + if (copy_from_user(&info, (void *)childregs->esi, sizeof(info))) + return -EFAULT; + if (LDT_empty(&info)) + return -EINVAL; + + idx = info.entry_number; + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + + desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; + desc->a = LDT_entry_a(&info); + desc->b = LDT_entry_b(&info); + } + + /* + * Notify the child of the TID? + */ + if (clone_flags & CLONE_SETTID) + if (put_user(p->pid, (pid_t *)childregs->edx)) + return -EFAULT; + + /* + * Does the userspace VM want any unlock on mm_release()? + */ + if (clone_flags & CLONE_RELEASE_VM) { + childregs->esp -= sizeof(0UL); + p->user_vm_lock = (long *) esp; + } return 0; } diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 5a4f1a257d97..b8c97ff93fb2 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -968,16 +968,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus) { int apicid, cpu, bit; - if (clustered_apic_mode && (numnodes > 1)) { - printk("Remapping cross-quad port I/O for %d quads\n", - numnodes); - printk("xquad_portio vaddr 0x%08lx, len %08lx\n", - (u_long) xquad_portio, - (u_long) numnodes * XQUAD_PORTIO_LEN); - xquad_portio = ioremap (XQUAD_PORTIO_BASE, - numnodes * XQUAD_PORTIO_LEN); - } - #ifdef CONFIG_MTRR /* Must be done before other processors booted */ mtrr_init_boot_cpu (); @@ -1076,6 +1066,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus) if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid) BUG(); + if (clustered_apic_mode && (numnodes > 1)) { + printk("Remapping cross-quad port I/O for %d quads\n", + numnodes); + printk("xquad_portio vaddr 0x%08lx, len %08lx\n", + (u_long) xquad_portio, + (u_long) numnodes * XQUAD_PORTIO_LEN); + xquad_portio = ioremap (XQUAD_PORTIO_BASE, + numnodes * XQUAD_PORTIO_LEN); + } + /* * Scan the CPU present map and fire up the other CPUs via do_boot_cpu * diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index f56251513581..a32314075d1d 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -639,8 +639,8 @@ bad_ctc: } static struct device device_i8253 = { - name: "i8253", - bus_id: "0040", + .name = "i8253", + .bus_id = "0040", }; static int time_init_driverfs(void) diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 9f7b7dc037b0..22d82e3b3e9f 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -159,7 +159,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag area->phys_addr = phys_addr; addr = area->addr; if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) { - vfree(addr); + vunmap(addr); return NULL; } return (void *) (offset + (char *)addr); @@ -215,13 +215,13 @@ void iounmap(void *addr) struct vm_struct *p; if (addr <= high_memory) return; - p = remove_kernel_area((void *) (PAGE_MASK & (unsigned long) addr)); + p = remove_vm_area((void *) (PAGE_MASK & (unsigned long) addr)); if (!p) { printk("__iounmap: bad address %p\n", addr); return; } - vmfree_area_pages(VMALLOC_VMADDR(p->addr), p->size); + unmap_vm_area(p); if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { change_page_attr(virt_to_page(__va(p->phys_addr)), p->size >> PAGE_SHIFT, diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 7a624d2b4742..b7b69cda6dc1 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -118,10 +118,6 @@ fi # !HP_SIM endmenu -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then source drivers/mtd/Config.in source drivers/pnp/Config.in @@ -154,6 +150,10 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu +if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in +fi + if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 973bc2bcd2dc..f1c6f6bedbf0 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -375,8 +375,8 @@ static pmu_config_t pmu_conf; /* PMU configuration */ static pfm_session_t pfm_sessions; /* global sessions information */ static struct proc_dir_entry *perfmon_dir; /* for debug only */ static pfm_stats_t pfm_stats; -int __per_cpu_data pfm_syst_wide; -static int __per_cpu_data pfm_dcr_pp; +DEFINE_PER_CPU(int, pfm_syst_wide); +static DEFINE_PER_CPU(int, pfm_dcr_pp); /* sysctl() controls */ static pfm_sysctl_t pfm_sysctl; @@ -1764,7 +1764,7 @@ pfm_stop(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, ia64_srlz_i(); #ifdef CONFIG_SMP - this_cpu(pfm_dcr_pp) = 0; + __get_cpu_var(pfm_dcr_pp) = 0; #else pfm_tasklist_toggle_pp(0); #endif @@ -2172,7 +2172,7 @@ pfm_start(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, if (ctx->ctx_fl_system) { #ifdef CONFIG_SMP - this_cpu(pfm_dcr_pp) = 1; + __get_cpu_var(pfm_dcr_pp) = 1; #else pfm_tasklist_toggle_pp(1); #endif @@ -2227,8 +2227,8 @@ pfm_enable(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, ia64_srlz_i(); #ifdef CONFIG_SMP - this_cpu(pfm_syst_wide) = 1; - this_cpu(pfm_dcr_pp) = 0; + __get_cpu_var(pfm_syst_wide) = 1; + __get_cpu_var(pfm_dcr_pp) = 0; #endif } else { /* @@ -2980,9 +2980,9 @@ perfmon_proc_info(char *page) p += sprintf(p, "CPU%d syst_wide : %d\n" "CPU%d dcr_pp : %d\n", smp_processor_id(), - this_cpu(pfm_syst_wide), + __get_cpu_var(pfm_syst_wide), smp_processor_id(), - this_cpu(pfm_dcr_pp)); + __get_cpu_var(pfm_dcr_pp)); #endif LOCK_PFS(); @@ -3052,7 +3052,7 @@ pfm_syst_wide_update_task(struct task_struct *task, int mode) /* * propagate the value of the dcr_pp bit to the psr */ - ia64_psr(regs)->pp = mode ? this_cpu(pfm_dcr_pp) : 0; + ia64_psr(regs)->pp = mode ? __get_cpu_var(pfm_dcr_pp) : 0; } #endif @@ -3546,8 +3546,8 @@ pfm_flush_regs (struct task_struct *task) ia64_srlz_i(); #ifdef CONFIG_SMP - this_cpu(pfm_syst_wide) = 0; - this_cpu(pfm_dcr_pp) = 0; + __get_cpu_var(pfm_syst_wide) = 0; + __get_cpu_var(pfm_dcr_pp) = 0; #else pfm_tasklist_toggle_pp(0); #endif diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 8a426aaf5998..fc88ad9159b8 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -194,7 +194,7 @@ ia64_save_extra (struct task_struct *task) pfm_save_regs(task); # ifdef CONFIG_SMP - if (this_cpu(pfm_syst_wide)) + if (__get_cpu_var(pfm_syst_wide)) pfm_syst_wide_update_task(task, 0); # endif #endif @@ -216,7 +216,7 @@ ia64_load_extra (struct task_struct *task) pfm_load_regs(task); # ifdef CONFIG_SMP - if (this_cpu(pfm_syst_wide)) pfm_syst_wide_update_task(task, 1); + if (__get_cpu_var(pfm_syst_wide)) pfm_syst_wide_update_task(task, 1); # endif #endif diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index a68a8c393959..5dfa535fa18f 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -58,7 +58,7 @@ extern char _end; unsigned long __per_cpu_offset[NR_CPUS]; #endif -struct cpuinfo_ia64 cpu_info __per_cpu_data; +DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info); unsigned long ia64_phys_stacked_size_p8; unsigned long ia64_cycles_per_usec; diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 5dd0a97cd4ac..7bde7122fdc2 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -80,7 +80,7 @@ static volatile struct call_data_struct *call_data; #define IPI_CPU_STOP 1 /* This needs to be cacheline aligned because it is written to by *other* CPUs. */ -static __u64 ipi_operation __per_cpu_data ____cacheline_aligned; +static DECLARE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned; static void stop_this_cpu (void) @@ -99,7 +99,7 @@ void handle_IPI (int irq, void *dev_id, struct pt_regs *regs) { int this_cpu = smp_processor_id(); - unsigned long *pending_ipis = &this_cpu(ipi_operation); + unsigned long *pending_ipis = &__get_cpu_var(ipi_operation); unsigned long ops; /* Count this now; we may make a call that never returns. */ diff --git a/arch/m68k/config.in b/arch/m68k/config.in index d3ce9e6638e9..25189494353a 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -152,10 +152,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - if [ "$CONFIG_MAC" = "y" ]; then source drivers/input/Config.in fi @@ -271,6 +267,7 @@ fi endmenu if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in mainmenu_option next_comment comment 'Network device support' diff --git a/arch/mips/config.in b/arch/mips/config.in index 8579193f7f88..af96bff4a683 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -334,12 +334,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - if [ "$CONFIG_SGI_IP22" != "y" -a \ "$CONFIG_DECSTATION" != "y" ]; then @@ -372,6 +366,8 @@ if [ "$CONFIG_DECSTATION" != "y" -a \ fi if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' @@ -391,6 +387,8 @@ source net/irda/Config.in source drivers/isdn/Config.in +source drivers/telephony/Config.in + mainmenu_option next_comment comment 'Old CD-ROM drivers (not SCSI, not IDE)' diff --git a/arch/mips64/config.in b/arch/mips64/config.in index 877922fc21e5..3b6fd0c3f8ce 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -132,12 +132,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL support' @@ -163,6 +157,8 @@ endmenu #source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' @@ -182,6 +178,8 @@ source net/irda/Config.in source drivers/isdn/Config.in +source drivers/telephony/Config.in + mainmenu_option next_comment comment 'Old CD-ROM drivers (not SCSI, not IDE)' diff --git a/arch/parisc/config.in b/arch/parisc/config.in index 016628d2db6f..acead292ee4e 100644 --- a/arch/parisc/config.in +++ b/arch/parisc/config.in @@ -99,10 +99,6 @@ endmenu source drivers/block/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'SCSI support' @@ -149,6 +145,8 @@ fi endmenu if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 386bf135f1b5..0f3d42a9c3e8 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -419,10 +419,6 @@ source drivers/pnp/Config.in source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'ATA/IDE/MFM/RLL support' @@ -449,6 +445,8 @@ source drivers/ieee1394/Config.in source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/ppc64/config.in b/arch/ppc64/config.in index 20159b4a0cb0..8faa94ea5fb1 100644 --- a/arch/ppc64/config.in +++ b/arch/ppc64/config.in @@ -87,10 +87,6 @@ source drivers/pnp/Config.in source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL support' @@ -118,6 +114,8 @@ source drivers/ieee1394/Config.in source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/sh/config.in b/arch/sh/config.in index f956fae61abe..d4cebd924ae9 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -207,10 +207,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL support' @@ -236,6 +232,8 @@ endmenu source drivers/ieee1394/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/sparc/config.in b/arch/sparc/config.in index 2810a503a8e6..53eb949382ba 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -87,10 +87,6 @@ dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK endmenu -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - # Don't frighten a common SBus user if [ "$CONFIG_PCI" = "y" ]; then @@ -158,6 +154,8 @@ endmenu source drivers/fc4/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 7ff56c408258..ea3040b2acb0 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -95,10 +95,6 @@ dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK endmenu -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL device support' @@ -207,6 +203,8 @@ fi source drivers/ieee1394/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' diff --git a/arch/sparc64/mm/modutil.c b/arch/sparc64/mm/modutil.c index f723383ae0e7..fcda829f73b5 100644 --- a/arch/sparc64/mm/modutil.c +++ b/arch/sparc64/mm/modutil.c @@ -4,6 +4,8 @@ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Based upon code written by Linus Torvalds and others. */ + +#warning "major untested changes to this file --hch (2002/08/05)" #include <linux/slab.h> #include <linux/vmalloc.h> @@ -16,6 +18,7 @@ static struct vm_struct * modvmlist = NULL; void module_unmap (void * addr) { struct vm_struct **p, *tmp; + int i; if (!addr) return; @@ -23,21 +26,38 @@ void module_unmap (void * addr) printk("Trying to unmap module with bad address (%p)\n", addr); return; } + for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; - vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size); - kfree(tmp); - return; } } printk("Trying to unmap nonexistent module vm area (%p)\n", addr); + return; + +found: + + unmap_vm_area(tmp); + + for (i = 0; i < tmp->nr_pages; i++) { + if (unlikely(!tmp->pages[i])) + BUG(); + __free_page(tmp->pages[i]); + } + + kfree(tmp->pages); + kfree(tmp); } + void * module_map (unsigned long size) { - void * addr; struct vm_struct **p, *tmp, *area; + struct vm_struct *area; + struct page **pages; + void * addr; + unsigned int nr_pages, array_size, i; + size = PAGE_ALIGN(size); if (!size || size > MODULES_LEN) return NULL; @@ -55,11 +75,32 @@ void * module_map (unsigned long size) area->size = size + PAGE_SIZE; area->addr = addr; area->next = *p; + area->pages = NULL; + area->nr_pages = 0; + area->phys_addr = 0; *p = area; - if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) { - module_unmap(addr); + nr_pages = (size+PAGE_SIZE) >> PAGE_SHIFT; + array_size = (nr_pages * sizeof(struct page *)); + + area->nr_pages = nr_pages; + area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM)); + if (!area->pages) return NULL; + memset(area->pages, 0, array_size); + + for (i = 0; i < area->nr_pages; i++) { + area->pages[i] = alloc_page(gfp_mask); + if (unlikely(!area->pages[i])) + goto fail; } - return addr; + + if (map_vm_area(area, prot, &pages)) + goto fail; + return area->addr; + +fail: + vfree(area->addr); + return NULL; +} } diff --git a/arch/x86_64/config.in b/arch/x86_64/config.in index beb522968c8e..65e921b8e88d 100644 --- a/arch/x86_64/config.in +++ b/arch/x86_64/config.in @@ -119,12 +119,6 @@ source drivers/block/Config.in source drivers/md/Config.in -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - mainmenu_option next_comment comment 'ATA/ATAPI/MFM/RLL support' @@ -155,6 +149,8 @@ source drivers/ieee1394/Config.in #source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in + mainmenu_option next_comment comment 'Network device support' @@ -175,6 +171,8 @@ source net/irda/Config.in source drivers/isdn/Config.in +source drivers/telephony/Config.in + # no support for non IDE/SCSI cdroms as they were all ISA only # diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index df07b097193d..db3d25ebfd35 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -105,10 +105,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); static int revalidate_allvol(kdev_t dev); -static int revalidate_logvol(kdev_t dev, int maxusage); static int cciss_revalidate(kdev_t dev); static int deregister_disk(int ctlr, int logvol); -static int register_new_disk(kdev_t dev, int cltr); +static int register_new_disk(int cltr); static void cciss_getgeometry(int cntl_num); @@ -333,27 +332,6 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) } } -/* - * fills in the disk information. - */ -static void cciss_geninit( int ctlr) -{ - drive_info_struct *drv; - int i; - - /* Loop through each real device */ - hba[ctlr]->gendisk.nr_real = 0; - for(i=0; i< NWD; i++) - { - drv = &(hba[ctlr]->drv[i]); - if( !(drv->nr_blocks)) - continue; - hba[ctlr]->hd[i << NWD_SHIFT].nr_sects = drv->nr_blocks; - //hba[ctlr]->gendisk.nr_real++; - (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size; - } - hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun+1; -} /* * Open. Make sure the device is really there. */ @@ -599,7 +577,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case CCISS_REGNEWD: { - return(register_new_disk(inode->i_rdev, ctlr)); + return(register_new_disk(ctlr)); } case CCISS_PASSTHRU: { @@ -726,49 +704,11 @@ static int cciss_revalidate(kdev_t dev) { int ctlr = major(dev) - MAJOR_NR; int target = minor(dev) >> NWD_SHIFT; - struct gendisk *gdev = &(hba[ctlr]->gendisk); - gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks; + struct gendisk *disk = &hba[ctlr]->gendisk[target]; + disk->part[0].nr_sects = hba[ctlr]->drv[target].nr_blocks; return 0; } -/* Borrowed and adapted from sd.c */ -/* - * FIXME: we are missing the exclusion with ->open() here - it can happen - * just as we are rereading partition tables. - */ -static int revalidate_logvol(kdev_t dev, int maxusage) -{ - int ctlr, target; - struct gendisk *gdev; - unsigned long flags; - int res; - - target = minor(dev) >> NWD_SHIFT; - ctlr = major(dev) - MAJOR_NR; - gdev = &(hba[ctlr]->gendisk); - - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - if (hba[ctlr]->drv[target].usage_count > maxusage) { - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - printk(KERN_WARNING "cciss: Device busy for " - "revalidation (usage=%d)\n", - hba[ctlr]->drv[target].usage_count); - return -EBUSY; - } - hba[ctlr]->drv[target].usage_count++; - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - - res = wipe_partitions(dev); - if (res) - goto leave; - - /* setup partitions per disk */ - grok_partitions(dev, hba[ctlr]->drv[target].nr_blocks); -leave: - hba[ctlr]->drv[target].usage_count--; - return res; -} - /* * revalidate_allvol is for online array config utilities. After a * utility reconfigures the drives in the array, it can use this function @@ -799,6 +739,15 @@ static int revalidate_allvol(kdev_t dev) hba[ctlr]->usage_count++; spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + for(i=0; i< NWD; i++) { + struct gendisk *disk = &hba[ctlr]->gendisk[i]; + if (disk->major_name) { + wipe_partitions(mk_kdev(disk->major, disk->first_minor)); + del_gendisk(disk); + disk->major_name = NULL; + } + } + /* * Set the partition and block size structures for all volumes * on this controller to zero. We will reread all of this data @@ -806,8 +755,6 @@ static int revalidate_allvol(kdev_t dev) memset(hba[ctlr]->hd, 0, sizeof(struct hd_struct) * 256); memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct) * CISS_MAX_LUN); - hba[ctlr]->gendisk.nr_real = 0; - /* * Tell the array controller not to give us any interrupts while * we check the new geometry. Then turn interrupts back on when @@ -817,13 +764,20 @@ static int revalidate_allvol(kdev_t dev) cciss_getgeometry(ctlr); hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON); - cciss_geninit(ctlr); - for(i=0; i<NWD; i++) { - kdev_t kdev = mk_kdev(major(dev), i << NWD_SHIFT); - if (hba[ctlr]->gendisk.part[ i<<NWD_SHIFT ].nr_sects) - revalidate_logvol(kdev, 2); + /* Loop through each real device */ + for (i = 0; i < NWD; i++) { + struct gendisk *disk = &hba[ctlr]->gendisk[i]; + drive_info_struct *drv = &(hba[ctlr]->drv[i]); + if (!drv->nr_blocks) + continue; + (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size; + disk->major_name = hba[ctlr]->names + 12 * i; + add_gendisk(disk); + register_disk(disk, + mk_kdev(disk->major, disk->first_minor), + 1<<disk->minor_shift, disk->fops, + drv->nr_blocks); } - hba[ctlr]->usage_count--; return 0; } @@ -831,18 +785,15 @@ static int revalidate_allvol(kdev_t dev) static int deregister_disk(int ctlr, int logvol) { unsigned long flags; - struct gendisk *gdev = &(hba[ctlr]->gendisk); + struct gendisk *disk = &hba[ctlr]->gendisk[logvol]; ctlr_info_t *h = hba[ctlr]; - int start, max_p; - if (!capable(CAP_SYS_RAWIO)) return -EPERM; spin_lock_irqsave(CCISS_LOCK(ctlr), flags); /* make sure logical volume is NOT is use */ - if( h->drv[logvol].usage_count > 1) - { + if( h->drv[logvol].usage_count > 1) { spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); return -EBUSY; } @@ -850,25 +801,24 @@ static int deregister_disk(int ctlr, int logvol) spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); /* invalidate the devices and deregister the disk */ - max_p = 1 << gdev->minor_shift; - start = logvol << gdev->minor_shift; - wipe_partitions(mk_kdev(MAJOR_NR+ctlr, start)); + if (disk->major_name) { + wipe_partitions(mk_kdev(disk->major, disk->first_minor)); + del_gendisk(disk); + disk->major_name = NULL; + } /* check to see if it was the last disk */ - if (logvol == h->highest_lun) - { + if (logvol == h->highest_lun) { /* if so, find the new hightest lun */ int i, newhighest =-1; - for(i=0; i<h->highest_lun; i++) - { + for(i=0; i<h->highest_lun; i++) { /* if the disk has size > 0, it is available */ - if (h->gendisk.part[i << gdev->minor_shift].nr_sects) + if (h->drv[i].nr_blocks) newhighest = i; } h->highest_lun = newhighest; } --h->num_luns; - gdev->nr_real = h->highest_lun+1; /* zero out the disk size info */ h->drv[logvol].nr_blocks = 0; h->drv[logvol].block_size = 0; @@ -1065,11 +1015,11 @@ case CMD_HARDWARE_ERR: return(return_status); } -static int register_new_disk(kdev_t dev, int ctlr) +static int register_new_disk(int ctlr) { - struct gendisk *gdev = &(hba[ctlr]->gendisk); + struct gendisk *disk; ctlr_info_t *h = hba[ctlr]; - int start, max_p, i; + int i; int num_luns; int logvol; int new_lun_found = 0; @@ -1084,7 +1034,6 @@ static int register_new_disk(kdev_t dev, int ctlr) __u32 lunid = 0; unsigned int block_size; unsigned int total_size; - kdev_t kdev; if (!capable(CAP_SYS_RAWIO)) return -EPERM; @@ -1292,15 +1241,16 @@ static int register_new_disk(kdev_t dev, int ctlr) hba[ctlr]->drv[logvol].sectors, hba[ctlr]->drv[logvol].cylinders); hba[ctlr]->drv[logvol].usage_count = 0; - max_p = 1 << gdev->minor_shift; - start = logvol<< gdev->minor_shift; - kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift); - - wipe_partitions(kdev); ++hba[ctlr]->num_luns; - gdev->nr_real = hba[ctlr]->highest_lun + 1; /* setup partitions per disk */ - grok_partitions(kdev, hba[ctlr]->drv[logvol].nr_blocks); + disk = &hba[ctlr]->gendisk[logvol]; + disk->major_name = hba[ctlr]->names + 12 * logvol; + add_gendisk(disk); + register_disk(disk, + mk_kdev(disk->major, disk->first_minor), + 1<<disk->minor_shift, + disk->fops, + hba[ctlr]->drv[logvol].nr_blocks); kfree(ld_buff); kfree(size_buff); @@ -2488,22 +2438,28 @@ static int __init cciss_init_one(struct pci_dev *pdev, blk_queue_max_sectors(q, 512); - /* Fill in the gendisk data */ - hba[i]->gendisk.major = MAJOR_NR + i; - hba[i]->gendisk.major_name = "cciss"; - hba[i]->gendisk.minor_shift = NWD_SHIFT; - hba[i]->gendisk.part = hba[i]->hd; - hba[i]->gendisk.nr_real = hba[i]->highest_lun+1; - /* Get on the disk list */ - add_gendisk(&(hba[i]->gendisk)); + for(j=0; j<NWD; j++) { + drive_info_struct *drv = &(hba[i]->drv[j]); + struct gendisk *disk = hba[i]->gendisk + j; - cciss_geninit(i); - for(j=0; j<NWD; j++) - register_disk(&(hba[i]->gendisk), - mk_kdev(MAJOR_NR+i, j <<4), - MAX_PART, &cciss_fops, - hba[i]->drv[j].nr_blocks); + sprintf(hba[i]->names + 12 * j, "cciss/c%dd%d", i, j); + disk->major = MAJOR_NR + i; + disk->first_minor = j << NWD_SHIFT; + disk->major_name = NULL; + disk->minor_shift = NWD_SHIFT; + disk->part = hba[i]->hd + (j << NWD_SHIFT); + disk->nr_real = 1; + if( !(drv->nr_blocks)) + continue; + (BLK_DEFAULT_QUEUE(MAJOR_NR + i))->hardsect_size = drv->block_size; + disk->major_name = hba[i]->names + 12 * j; + add_gendisk(disk); + register_disk(disk, + mk_kdev(disk->major, disk->first_minor), + 1<<disk->minor_shift, disk->fops, + drv->nr_blocks); + } cciss_register_scsi(i, 1); /* hook ourself into SCSI subsystem */ @@ -2513,7 +2469,7 @@ static int __init cciss_init_one(struct pci_dev *pdev, static void __devexit cciss_remove_one (struct pci_dev *pdev) { ctlr_info_t *tmp_ptr; - int i; + int i, j; char flush_buf[4]; int return_code; @@ -2548,7 +2504,13 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) remove_proc_entry(hba[i]->devname, proc_cciss); /* remove it from the disk list */ - del_gendisk(&(hba[i]->gendisk)); + for (j = 0; j < NWD; j++) { + struct gendisk *disk = &hba[i]->gendisk[j]; + if (disk->major_name) { + del_gendisk(disk); + disk->major_name = NULL; + } + } pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 3179b51e56bf..7192717a23fe 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -81,7 +81,8 @@ struct ctlr_info int nr_frees; // Disk structures we need to pass back - struct gendisk gendisk; + struct gendisk gendisk[NWD]; + char names[12 * NWD]; // indexed by minor numbers struct hd_struct hd[256]; int sizes[256]; diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index b5e79170bb29..b9dfeb902e3c 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1483,6 +1483,7 @@ static int revalidate_allvol(kdev_t dev) if (!drv->nr_blks) continue; (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size; + disk->major_name = ida_names + (ctlr*NWD+i)*10; add_gendisk(disk); register_disk(disk, mk_kdev(disk->major,disk->first_minor), diff --git a/drivers/char/Config.help b/drivers/char/Config.help index a3b8d1254791..fad516fd9c3e 100644 --- a/drivers/char/Config.help +++ b/drivers/char/Config.help @@ -969,6 +969,31 @@ CONFIG_RTC The module is called rtc.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +Generic Real Time Clock Support +CONFIG_GEN_RTC + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock (or hardware clock) built + into your computer. + + It reports status information via the file /proc/driver/rtc and its + behaviour is set by various ioctls on /dev/rtc. If you enable the + "extended RTC operation" below it will also provide an emulation + for RTC_UIE which is required by some programs and may improve + precision in some cases. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called genrtc.o. If you want to compile it as a module, + say M here and read <file:Documentation/modules.txt>. To load the + module automaticaly add 'alias char-major-10-135 genrtc' to your + /etc/modules.conf + +Extended RTC operation +CONFIG_GEN_RTC_X + Provides an emulation for RTC_UIE which is required by some programs + and may improve precision of the generic RTC support in some cases. + CONFIG_H8 The Hitachi H8/337 is a microcontroller used to deal with the power and thermal environment. If you say Y here, you will be able to diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 7eb721082265..5a5c678f456e 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -151,6 +151,12 @@ if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then fi tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC +if [ "$CONFIG_RTC" != "y" ]; then + tristate 'Generic /dev/rtc emulation' CONFIG_GEN_RTC + if [ "$CONFIG_GEN_RTC" != "n" ]; then + bool ' Extended RTC operation' CONFIG_GEN_RTC_X + fi +fi if [ "$CONFIG_IA64" = "y" ]; then bool 'EFI Real Time Clock Services' CONFIG_EFI_RTC fi diff --git a/drivers/char/Makefile b/drivers/char/Makefile index e2891668329a..63417ee05fab 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -167,6 +167,7 @@ obj-$(CONFIG_APPLICOM) += applicom.o obj-$(CONFIG_SONYPI) += sonypi.o obj-$(CONFIG_ATARIMOUSE) += atarimouse.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o ifeq ($(CONFIG_PPC),) obj-$(CONFIG_NVRAM) += nvram.o diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c new file mode 100644 index 000000000000..0af50fd3829f --- /dev/null +++ b/drivers/char/genrtc.c @@ -0,0 +1,518 @@ +/* + * Real Time Clock interface for q40 and other m68k machines + * emulate some RTC irq capabilities in software + * + * Copyright (C) 1999 Richard Zidlicky + * + * based on Paul Gortmaker's rtc.c device and + * Sam Creasey Generic rtc driver + * + * This driver allows use of the real time clock (built into + * nearly all computers) from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the /proc/dev/rtc + * pseudo-file for status information. + * + * The ioctls can be used to set the interrupt behaviour where + * supported. + * + * The /dev/rtc interface will block on reads until an interrupt + * has been received. If a RTC interrupt has already happened, + * it will output an unsigned long and then block. The output value + * contains the interrupt status in the low byte and the number of + * interrupts since the last read in the remaining high bytes. The + * /dev/rtc interface can also be used with the select(2) call. + * + * 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. + * + + * 1.01 fix for 2.3.X rz@linux-m68k.org + * 1.02 merged with code from genrtc.c rz@linux-m68k.org + * 1.03 make it more portable zippel@linux-m68k.org + * 1.04 removed useless timer code rz@linux-m68k.org + * 1.05 portable RTC_UIE emulation rz@linux-m68k.org + * 1.06 set_rtc_time can return an error trini@kernel.crashing.org + */ + +#define RTC_VERSION "1.06" + +#include <linux/module.h> +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/miscdevice.h> +#include <linux/fcntl.h> + +#include <linux/rtc.h> +#include <linux/init.h> +#include <linux/poll.h> +#include <linux/proc_fs.h> +#include <linux/tqueue.h> + +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/rtc.h> + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); + +static int gen_rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +/* + * Bits in gen_rtc_status. + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ + +unsigned char gen_rtc_status; /* bitmapped status byte. */ +unsigned long gen_rtc_irq_data; /* our output to the world */ + +/* months start at 0 now */ +unsigned char days_in_mo[] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int irq_active; + +#ifdef CONFIG_GEN_RTC_X +struct tq_struct genrtc_task; +static struct timer_list timer_task; + +static unsigned int oldsecs; +static int lostint; +static int tt_exp; + +void gen_rtc_timer(unsigned long data); + +static volatile int stask_active; /* schedule_task */ +static volatile int ttask_active; /* timer_task */ +static int stop_rtc_timers; /* don't requeue tasks */ +static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED; + +/* + * Routine to poll RTC seconds field for change as often as posible, + * after first RTC_UIE use timer to reduce polling + */ +void genrtc_troutine(void *data) +{ + unsigned int tmp = get_rtc_ss(); + + if (stop_rtc_timers) { + stask_active = 0; + return; + } + + if (oldsecs != tmp){ + oldsecs = tmp; + + timer_task.function = gen_rtc_timer; + timer_task.expires = jiffies + HZ - (HZ/10); + tt_exp=timer_task.expires; + ttask_active=1; + stask_active=0; + add_timer(&timer_task); + + gen_rtc_interrupt(0); + } else if (schedule_task(&genrtc_task) == 0) + stask_active = 0; +} + +void gen_rtc_timer(unsigned long data) +{ + lostint = get_rtc_ss() - oldsecs ; + if (lostint<0) + lostint = 60 - lostint; + if (time_after(jiffies, tt_exp)) + printk(KERN_INFO "genrtc: timer task delayed by %ld jiffies\n", + jiffies-tt_exp); + ttask_active=0; + stask_active=1; + if ((schedule_task(&genrtc_task) == 0)) + stask_active = 0; +} + +/* + * call gen_rtc_interrupt function to signal an RTC_UIE, + * arg is unused. + * Could be invoked either from a real interrupt handler or + * from some routine that periodically (eg 100HZ) monitors + * whether RTC_SECS changed + */ +void gen_rtc_interrupt(unsigned long arg) +{ + /* We store the status in the low byte and the number of + * interrupts received since the last read in the remainder + * of rtc_irq_data. */ + + gen_rtc_irq_data += 0x100; + gen_rtc_irq_data &= ~0xff; + gen_rtc_irq_data |= RTC_UIE; + + if (lostint){ + printk("genrtc: system delaying clock ticks?\n"); + /* increment count so that userspace knows something is wrong */ + gen_rtc_irq_data += ((lostint-1)<<8); + lostint = 0; + } + + wake_up_interruptible(&gen_rtc_wait); +} + +/* + * Now all the various file operations that we export. + */ +static ssize_t gen_rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long data; + ssize_t retval; + + if (count != sizeof (unsigned int) && count != sizeof (unsigned long)) + return -EINVAL; + + if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data) + return -EAGAIN; + + add_wait_queue(&gen_rtc_wait, &wait); + retval = -ERESTARTSYS; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + data = xchg(&gen_rtc_irq_data, 0); + if (data) + break; + if (signal_pending(current)) + goto out; + schedule(); + } + + /* first test allows optimizer to nuke this case for 32-bit machines */ + if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { + unsigned int uidata = data; + retval = put_user(uidata, (unsigned long *)buf); + } + else { + retval = put_user(data, (unsigned long *)buf); + } + if (!retval) + retval = sizeof(unsigned long); + out: + current->state = TASK_RUNNING; + remove_wait_queue(&gen_rtc_wait, &wait); + + return retval; +} + +static unsigned int gen_rtc_poll(struct file *file, + struct poll_table_struct *wait) +{ + poll_wait(file, &gen_rtc_wait, wait); + if (gen_rtc_irq_data != 0) + return POLLIN | POLLRDNORM; + return 0; +} + +#endif + +/* + * Used to disable/enable interrupts, only RTC_UIE supported + * We also clear out any old irq data after an ioctl() that + * meddles with the interrupt enable/disable bits. + */ + +static inline void gen_clear_rtc_irq_bit(unsigned char bit) +{ +#ifdef CONFIG_GEN_RTC_X + stop_rtc_timers = 1; + if (ttask_active){ + del_timer_sync(&timer_task); + ttask_active = 0; + } + while (stask_active) + schedule(); + + spin_lock(&gen_rtc_lock); + irq_active = 0; + spin_unlock(&gen_rtc_lock); +#endif +} + +static inline int gen_set_rtc_irq_bit(unsigned char bit) +{ +#ifdef CONFIG_GEN_RTC_X + spin_lock(&gen_rtc_lock); + if ( !irq_active ) { + irq_active = 1; + stop_rtc_timers = 0; + lostint = 0; + genrtc_task.routine = genrtc_troutine; + oldsecs = get_rtc_ss(); + init_timer(&timer_task); + + stask_active = 1; + if (schedule_task(&genrtc_task) == 0){ + stask_active = 0; + } + } + spin_unlock(&gen_rtc_lock); + gen_rtc_irq_data = 0; + return 0; +#else + return -EINVAL; +#endif +} + +static int gen_rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct rtc_time wtime; + struct rtc_pll_info pll; + + switch (cmd) { + + case RTC_PLL_GET: + if (get_rtc_pll(&pll)) + return -EINVAL; + else + return copy_to_user((void *)arg, &pll, sizeof pll) ? -EFAULT : 0; + + case RTC_PLL_SET: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + if (copy_from_user(&pll, (struct rtc_pll_info*)arg, + sizeof(pll))) + return -EFAULT; + return set_rtc_pll(&pll); + + case RTC_UIE_OFF: /* disable ints from RTC updates. */ + gen_clear_rtc_irq_bit(RTC_UIE); + return 0; + + case RTC_UIE_ON: /* enable ints for RTC updates. */ + return gen_set_rtc_irq_bit(RTC_UIE); + + case RTC_RD_TIME: /* Read the time/date from RTC */ + /* this doesn't get week-day, who cares */ + memset(&wtime, 0, sizeof(wtime)); + get_rtc_time(&wtime); + + return copy_to_user((void *)arg, &wtime, sizeof(wtime)) ? -EFAULT : 0; + + case RTC_SET_TIME: /* Set the RTC */ + { + int year; + unsigned char leap_yr; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&wtime, (struct rtc_time *)arg, + sizeof(wtime))) + return -EFAULT; + + year = wtime.tm_year + 1900; + leap_yr = ((!(year % 4) && (year % 100)) || + !(year % 400)); + + if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) + return -EINVAL; + + if (wtime.tm_mday < 0 || wtime.tm_mday > + (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) + return -EINVAL; + + if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || + wtime.tm_min < 0 || wtime.tm_min >= 60 || + wtime.tm_sec < 0 || wtime.tm_sec >= 60) + return -EINVAL; + + return set_rtc_time(&wtime); + } + } + + return -EINVAL; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int gen_rtc_open(struct inode *inode, struct file *file) +{ + if (gen_rtc_status & RTC_IS_OPEN) + return -EBUSY; + + MOD_INC_USE_COUNT; + + gen_rtc_status |= RTC_IS_OPEN; + gen_rtc_irq_data = 0; + irq_active = 0; + + return 0; +} + +static int gen_rtc_release(struct inode *inode, struct file *file) +{ + /* + * Turn off all interrupts once the device is no longer + * in use and clear the data. + */ + + gen_clear_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); + + gen_rtc_status &= ~RTC_IS_OPEN; + MOD_DEC_USE_COUNT; + + return 0; +} + +static int gen_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + + +/* + * The various file operations we support. + */ + +static struct file_operations gen_rtc_fops = { + .owner = THIS_MODULE, +#ifdef CONFIG_GEN_RTC_X + .read = gen_rtc_read, + .poll = gen_rtc_poll, +#endif + .ioctl = gen_rtc_ioctl, + .open = gen_rtc_open, + .release = gen_rtc_release +}; + +static struct miscdevice rtc_gen_dev = +{ + RTC_MINOR, + "rtc", + &gen_rtc_fops +}; + +int __init rtc_generic_init(void) +{ + + printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); + + misc_register(&rtc_gen_dev); + create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL); + + return 0; +} + +static void __exit rtc_generic_exit(void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_gen_dev); +} + +module_init(rtc_generic_init); +module_exit(rtc_generic_exit); +EXPORT_NO_SYMBOLS; + + +/* + * Info exported via "/proc/rtc". + */ + +int gen_rtc_proc_output(char *buf) +{ + char *p; + struct rtc_time tm; + unsigned tmp; + struct rtc_pll_info pll; + + p = buf; + + get_rtc_time(&tm); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04u\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900); + + tm.tm_hour=0;tm.tm_min=0;tm.tm_sec=0; + + p += sprintf(p, "alarm\t\t: "); + if (tm.tm_hour <= 24) + p += sprintf(p, "%02d:", tm.tm_hour); + else + p += sprintf(p, "**:"); + + if (tm.tm_min <= 59) + p += sprintf(p, "%02d:", tm.tm_min); + else + p += sprintf(p, "**:"); + + if (tm.tm_sec <= 59) + p += sprintf(p, "%02d\n", tm.tm_sec); + else + p += sprintf(p, "**\n"); + + tmp= RTC_24H ; + p += sprintf(p, + "DST_enable\t: %s\n" + "BCD\t\t: %s\n" + "24hr\t\t: %s\n" + "square_wave\t: %s\n" + "alarm_IRQ\t: %s\n" + "update_IRQ\t: %s\n" + "periodic_IRQ\t: %s\n" + "periodic_freq\t: %ld\n" + "batt_status\t: %s\n", + (tmp & RTC_DST_EN) ? "yes" : "no", + (tmp & RTC_DM_BINARY) ? "no" : "yes", + (tmp & RTC_24H) ? "yes" : "no", + (tmp & RTC_SQWE) ? "yes" : "no", + (tmp & RTC_AIE) ? "yes" : "no", + irq_active ? "yes" : "no", + (tmp & RTC_PIE) ? "yes" : "no", + 0L /* freq */, + "okay" ); + if (!get_rtc_pll(&pll)) + p += sprintf(p, + "PLL adjustment\t: %d\n" + "PLL max +ve adjustment\t: %d\n" + "PLL max -ve adjustment\t: %d\n" + "PLL +ve adjustment factor\t: %d\n" + "PLL -ve adjustment factor\t: %d\n" + "PLL frequency\t: %ld\n", + pll.pll_value, + pll.pll_max, + pll.pll_min, + pll.pll_posmult, + pll.pll_negmult, + pll.pll_clock); + return p - buf; +} + +static int gen_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = gen_rtc_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + + +MODULE_AUTHOR("Richard Zidlicky"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 611aad3bbfc6..057ecc055616 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -210,6 +210,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) return 0; } +extern long vread(char *buf, char *addr, unsigned long count); +extern long vwrite(char *buf, char *addr, unsigned long count); + /* * This function reads the *virtual* memory as seen by the kernel. */ @@ -273,8 +276,6 @@ static ssize_t read_kmem(struct file *file, char *buf, return virtr + read; } -extern long vwrite(char *buf, char *addr, unsigned long count); - /* * This function writes to the *virtual* memory as seen by the kernel. */ diff --git a/drivers/i2c/Config.in b/drivers/i2c/Config.in index 3d1bbe455ecc..af9fd0f1f444 100644 --- a/drivers/i2c/Config.in +++ b/drivers/i2c/Config.in @@ -32,10 +32,10 @@ if [ "$CONFIG_I2C" != "n" ]; then dep_tristate ' Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX fi fi - if [ "$CONFIG_405" = "y" ]; then - dep_tristate 'PPC 405 I2C Algorithm' CONFIG_I2C_PPC405_ALGO $CONFIG_I2C - if [ "$CONFIG_I2C_PPC405_ALGO" != "n" ]; then - dep_tristate ' PPC 405 I2C Adapter' CONFIG_I2C_PPC405_ADAP $CONFIG_I2C_PPC405_ALGO + if [ "$CONFIG_IBM_OCP" = "y" ]; then + dep_tristate 'IBM on-chip I2C Algorithm' CONFIG_I2C_IBM_OCP_ALGO $CONFIG_I2C + if [ "$CONFIG_I2C_IBM_OCP_ALGO" != "n" ]; then + dep_tristate ' IBM on-chip I2C Adapter' CONFIG_I2C_IBM_OCP_ADAP $CONFIG_I2C_IBM_OCP_ALGO fi fi diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 10e68e096edc..f446ce18feec 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1107,7 +1107,6 @@ static void sym_eh_timeout(u_long p) { __sym_eh_done((Scsi_Cmnd *)p, 1); } static int sym_eh_handler(int op, char *opname, Scsi_Cmnd *cmd) { hcb_p np = SYM_SOFTC_PTR(cmd); - unsigned long flags; SYM_QUEHEAD *qp; int to_do = SYM_EH_DO_IGNORE; int sts = -1; @@ -1118,8 +1117,6 @@ static int sym_eh_handler(int op, char *opname, Scsi_Cmnd *cmd) printf_warning("%s: %s operation started.\n", devname, opname); - SYM_LOCK_HCB(np, flags); - #if 0 /* This one should be the result of some race, thus to ignore */ if (cmd->serial_number != cmd->serial_number_at_timeout) @@ -1198,8 +1195,6 @@ finish: if (to_do == SYM_EH_DO_COMPLETE) sym_xpt_done2(np, cmd, CAM_REQ_ABORTED); - SYM_UNLOCK_HCB(np, flags); - /* Wait for completion with locks released, as required by kernel */ if (to_do == SYM_EH_DO_WAIT) { init_timer(&ep->timer); diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 446a76045b82..87c3989fc246 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -2,10 +2,10 @@ # Makefile for USB Core files and filesystem # -export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o +export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \ - config.o file.o + config.o file.o buffer.o ifeq ($(CONFIG_PCI),y) usbcore-objs += hcd-pci.o diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c new file mode 100644 index 000000000000..097a5b51052d --- /dev/null +++ b/drivers/usb/core/buffer.c @@ -0,0 +1,186 @@ +/* + * DMA memory management for framework level HCD code (hc_driver) + * + * This implementation plugs in through generic "usb_bus" level methods, + * and works with real PCI, or when "pci device == null" makes sense. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/pci.h> + + +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif + +#include <linux/usb.h> +#include "hcd.h" + + +/* + * DMA-Consistent Buffers + */ + +/* FIXME tune these based on pool statistics ... */ +static const size_t pool_max [HCD_BUFFER_POOLS] = { + 32, + 128, + 512, + PAGE_SIZE / 2 + /* bigger --> allocate pages */ +}; + + +/* SETUP primitives */ + +/** + * hcd_buffer_create - initialize buffer pools + * @hcd: the bus whose buffer pools are to be initialized + * + * Call this as part of initializing a host controller that uses the pci dma + * memory allocators. It initializes some pools of dma-consistent memory that + * will be shared by all drivers using that controller, or returns a negative + * errno value on error. + * + * Call hcd_buffer_destroy() to clean up after using those pools. + */ +int hcd_buffer_create (struct usb_hcd *hcd) +{ + char name [16]; + int i, size; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { + if (!(size = pool_max [i])) + continue; + snprintf (name, sizeof name, "buffer-%d", size); + hcd->pool [i] = pci_pool_create (name, hcd->pdev, + size, size, 0, SLAB_KERNEL); + if (!hcd->pool [i]) { + hcd_buffer_destroy (hcd); + return -ENOMEM; + } + } + return 0; +} +EXPORT_SYMBOL (hcd_buffer_create); + + +/** + * hcd_buffer_destroy - deallocate buffer pools + * @hcd: the bus whose buffer pools are to be destroyed + * + * This frees the buffer pools created by hcd_buffer_create(). + */ +void hcd_buffer_destroy (struct usb_hcd *hcd) +{ + int i; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { + struct pci_pool *pool = hcd->pool [i]; + if (pool) { + pci_pool_destroy (pool); + hcd->pool [i] = 0; + } + } +} +EXPORT_SYMBOL (hcd_buffer_destroy); + + +/* sometimes alloc/free could use kmalloc with SLAB_DMA, for + * better sharing and to leverage mm/slab.c intelligence. + */ + +void *hcd_buffer_alloc ( + struct usb_bus *bus, + size_t size, + int mem_flags, + dma_addr_t *dma +) +{ + struct usb_hcd *hcd = bus->hcpriv; + int i; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { + if (size <= pool_max [i]) + return pci_pool_alloc (hcd->pool [i], mem_flags, dma); + } + return pci_alloc_consistent (hcd->pdev, size, dma); +} + +void hcd_buffer_free ( + struct usb_bus *bus, + size_t size, + void *addr, + dma_addr_t dma +) +{ + struct usb_hcd *hcd = bus->hcpriv; + int i; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { + if (size <= pool_max [i]) { + pci_pool_free (hcd->pool [i], addr, dma); + return; + } + } + pci_free_consistent (hcd->pdev, size, addr, dma); +} + + +/* + * DMA-Mappings for arbitrary memory buffers + */ + +int hcd_buffer_map ( + struct usb_bus *bus, + void *addr, + dma_addr_t *dma, + size_t size, + int direction +) { + struct usb_hcd *hcd = bus->hcpriv; + + // FIXME pci_map_single() has no standard failure mode! + *dma = pci_map_single (hcd->pdev, addr, size, + (direction == USB_DIR_IN) + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE); + return 0; +} + +void hcd_buffer_dmasync ( + struct usb_bus *bus, + dma_addr_t dma, + size_t size, + int direction +) { + struct usb_hcd *hcd = bus->hcpriv; + + pci_dma_sync_single (hcd->pdev, dma, size, + (direction == USB_DIR_IN) + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE); +} + +void hcd_buffer_unmap ( + struct usb_bus *bus, + dma_addr_t dma, + size_t size, + int direction +) { + struct usb_hcd *hcd = bus->hcpriv; + + pci_unmap_single (hcd->pdev, dma, size, + (direction == USB_DIR_IN) + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE); +} + + +// FIXME DMA-Mappings for struct scatterlist diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 446e7870c348..a1019b4b838b 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -130,10 +130,19 @@ clean_2: return retval; } } - pci_set_drvdata(dev, hcd); + pci_set_drvdata (dev, hcd); hcd->driver = driver; hcd->description = driver->description; hcd->pdev = dev; + hcd->self.bus_name = dev->slot_name; + hcd->product_desc = dev->name; + + if ((retval = hcd_buffer_create (hcd)) != 0) { +clean_3: + driver->hcd_free (hcd); + goto clean_2; + } + info ("%s @ %s, %s", hcd->description, dev->slot_name, dev->name); pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); @@ -154,8 +163,7 @@ clean_2: != 0) { err ("request interrupt %s failed", bufp); retval = -EBUSY; - driver->hcd_free (hcd); - goto clean_2; + goto clean_3; } hcd->irq = dev->irq; @@ -168,8 +176,6 @@ clean_2: usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = dev->slot_name; - hcd->product_desc = dev->name; INIT_LIST_HEAD (&hcd->dev_list); @@ -216,6 +222,7 @@ void usb_hcd_pci_remove (struct pci_dev *dev) usb_disconnect (&hub); hcd->driver->stop (hcd); + hcd_buffer_destroy (hcd); hcd->state = USB_STATE_HALT; free_irq (hcd->irq, hcd); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 05bb930ea5fd..d568135857e2 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -454,7 +454,6 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) /* rh_timer protected by hcd_data_lock */ if (timer_pending (&hcd->rh_timer) || urb->status != -EINPROGRESS - || !HCD_IS_RUNNING (hcd->state) || urb->transfer_buffer_length < len) { dbg ("not queuing status urb, stat %d", urb->status); return -EINVAL; @@ -508,8 +507,12 @@ static void rh_report_status (unsigned long ptr) BUG (); } spin_unlock_irqrestore (&hcd_data_lock, flags); - } else + } else { spin_unlock_irqrestore (&urb->lock, flags); + spin_lock_irqsave (&hcd_data_lock, flags); + rh_status_urb (hcd, urb); + spin_unlock_irqrestore (&hcd_data_lock, flags); + } } else { /* this urb's been unlinked */ urb->hcpriv = 0; @@ -1245,6 +1248,11 @@ struct usb_operations usb_hcd_operations = { .submit_urb = hcd_submit_urb, .unlink_urb = hcd_unlink_urb, .deallocate = hcd_free_dev, + .buffer_alloc = hcd_buffer_alloc, + .buffer_free = hcd_buffer_free, + .buffer_map = hcd_buffer_map, + .buffer_dmasync = hcd_buffer_dmasync, + .buffer_unmap = hcd_buffer_unmap, }; EXPORT_SYMBOL (usb_hcd_operations); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 111f6cbd886f..e33a8b409ee4 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -58,6 +58,9 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ atomic_t resume_count; /* multiple resumes issue */ #endif +#define HCD_BUFFER_POOLS 4 + struct pci_pool *pool [HCD_BUFFER_POOLS]; + int state; # define __ACTIVE 0x01 # define __SLEEPY 0x02 @@ -109,6 +112,25 @@ struct usb_operations { int (*get_frame_number) (struct usb_device *usb_dev); int (*submit_urb) (struct urb *urb, int mem_flags); int (*unlink_urb) (struct urb *urb); + + /* allocate dma-consistent buffer for URB_DMA_NOMAPPING */ + void *(*buffer_alloc)(struct usb_bus *bus, size_t size, + int mem_flags, + dma_addr_t *dma); + void (*buffer_free)(struct usb_bus *bus, size_t size, + void *addr, dma_addr_t dma); + + int (*buffer_map) (struct usb_bus *bus, + void *addr, dma_addr_t *dma, + size_t size, int direction); + void (*buffer_dmasync) (struct usb_bus *bus, + dma_addr_t dma, + size_t size, int direction); + void (*buffer_unmap) (struct usb_bus *bus, + dma_addr_t dma, + size_t size, int direction); + + // FIXME also: buffer_sg_map (), buffer_sg_unmap () }; /* each driver provides one of these, and hardware init support */ @@ -181,6 +203,25 @@ extern int usb_hcd_pci_resume (struct pci_dev *dev); #endif /* CONFIG_PCI */ +/* pci-ish (pdev null is ok) buffer alloc/mapping support */ +int hcd_buffer_create (struct usb_hcd *hcd); +void hcd_buffer_destroy (struct usb_hcd *hcd); + +void *hcd_buffer_alloc (struct usb_bus *bus, size_t size, + int mem_flags, dma_addr_t *dma); +void hcd_buffer_free (struct usb_bus *bus, size_t size, + void *addr, dma_addr_t dma); + +int hcd_buffer_map (struct usb_bus *bus, + void *addr, dma_addr_t *dma, + size_t size, int direction); +void hcd_buffer_dmasync (struct usb_bus *bus, + dma_addr_t dma, + size_t size, int direction); +void hcd_buffer_unmap (struct usb_bus *bus, + dma_addr_t dma, + size_t size, int direction); + /* generic bus glue, needed for host controllers that don't use PCI */ extern struct usb_operations usb_hcd_operations; extern void usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 17fe095d0d11..03fdc5368f7d 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -863,9 +863,11 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t return 0; udev = to_usb_device (dev); - len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE); + len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE); + if (len < 0) + return 0; buf[len] = '\n'; - buf[len+1] = 0x00; + buf[len+1] = 0; return len+1; } static DEVICE_ATTR(product,"product",S_IRUGO,show_product,NULL); @@ -881,9 +883,11 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off) return 0; udev = to_usb_device (dev); - len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE); + len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE); + if (len < 0) + return 0; buf[len] = '\n'; - buf[len+1] = 0x00; + buf[len+1] = 0; return len+1; } static DEVICE_ATTR(manufacturer,"manufacturer",S_IRUGO,show_manufacturer,NULL); @@ -899,9 +903,11 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off) return 0; udev = to_usb_device (dev); - len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE); + len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE); + if (len < 0) + return 0; buf[len] = '\n'; - buf[len+1] = 0x00; + buf[len+1] = 0; return len+1; } static DEVICE_ATTR(serial,"serial",S_IRUGO,show_serial,NULL); @@ -918,13 +924,13 @@ static void usb_find_drivers(struct usb_device *dev) unsigned claimed = 0; /* FIXME should get called for each new configuration not just the - * first one for a device. switching configs (or altesettings) should + * first one for a device. switching configs (or altsettings) should * undo driverfs and HCD state for the previous interfaces. */ for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { struct usb_interface *interface = &dev->actconfig->interface[ifnum]; struct usb_interface_descriptor *desc = interface->altsetting; - + /* register this interface with driverfs */ interface->dev.parent = &dev->dev; interface->dev.bus = &usb_bus_type; @@ -1455,6 +1461,152 @@ int usb_new_device(struct usb_device *dev) } +/** + * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP + * @dev: device the buffer will be used with + * @size: requested buffer size + * @mem_flags: affect whether allocation may block + * @dma: used to return DMA address of buffer + * + * Return value is either null (indicating no buffer could be allocated), or + * the cpu-space pointer to a buffer that may be used to perform DMA to the + * specified device. Such cpu-space buffers are returned along with the DMA + * address (through the pointer provided). + * + * These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to + * avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping + * hardware for long idle periods. The implementation varies between + * platforms, depending on details of how DMA will work to this device. + * + * When the buffer is no longer used, free it with usb_buffer_free(). + */ +void *usb_buffer_alloc ( + struct usb_device *dev, + size_t size, + int mem_flags, + dma_addr_t *dma +) +{ + if (!dev || !dev->bus || !dev->bus->op || !dev->bus->op->buffer_alloc) + return 0; + return dev->bus->op->buffer_alloc (dev->bus, size, mem_flags, dma); +} + +/** + * usb_buffer_free - free memory allocated with usb_buffer_alloc() + * @dev: device the buffer was used with + * @size: requested buffer size + * @addr: CPU address of buffer + * @dma: DMA address of buffer + * + * This reclaims an I/O buffer, letting it be reused. The memory must have + * been allocated using usb_buffer_alloc(), and the parameters must match + * those provided in that allocation request. + */ +void usb_buffer_free ( + struct usb_device *dev, + size_t size, + void *addr, + dma_addr_t dma +) +{ + if (!dev || !dev->bus || !dev->bus->op || !dev->bus->op->buffer_free) + return; + dev->bus->op->buffer_free (dev->bus, size, addr, dma); +} + +/** + * usb_buffer_map - create DMA mapping(s) for an urb + * @urb: urb whose transfer_buffer will be mapped + * + * Return value is either null (indicating no buffer could be mapped), or + * the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the + * operation succeeds. + * + * This call would normally be used for an urb which is reused, perhaps + * as the target of a large periodic transfer, with usb_buffer_dmasync() + * calls to synchronize memory and dma state. It may not be used for + * control requests. + * + * Reverse the effect of this call with usb_buffer_unmap(). + */ +struct urb *usb_buffer_map (struct urb *urb) +{ + struct usb_bus *bus; + struct usb_operations *op; + + if (!urb + || usb_pipecontrol (urb->pipe) + || !urb->dev + || !(bus = urb->dev->bus) + || !(op = bus->op) + || !op->buffer_map) + return 0; + + if (op->buffer_map (bus, + urb->transfer_buffer, + &urb->transfer_dma, + urb->transfer_buffer_length, + usb_pipein (urb->pipe) + ? USB_DIR_IN + : USB_DIR_OUT)) + return 0; + urb->transfer_flags |= URB_NO_DMA_MAP; + return urb; +} + +/** + * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) + * @urb: urb whose transfer_buffer will be synchronized + */ +void usb_buffer_dmasync (struct urb *urb) +{ + struct usb_bus *bus; + struct usb_operations *op; + + if (!urb + || !(urb->transfer_flags & URB_NO_DMA_MAP) + || !urb->dev + || !(bus = urb->dev->bus) + || !(op = bus->op) + || !op->buffer_dmasync) + return; + + op->buffer_dmasync (bus, + urb->transfer_dma, + urb->transfer_buffer_length, + usb_pipein (urb->pipe) + ? USB_DIR_IN + : USB_DIR_OUT); +} + +/** + * usb_buffer_unmap - free DMA mapping(s) for an urb + * @urb: urb whose transfer_buffer will be unmapped + * + * Reverses the effect of usb_buffer_map(). + */ +void usb_buffer_unmap (struct urb *urb) +{ + struct usb_bus *bus; + struct usb_operations *op; + + if (!urb + || !(urb->transfer_flags & URB_NO_DMA_MAP) + || !urb->dev + || !(bus = urb->dev->bus) + || !(op = bus->op) + || !op->buffer_unmap) + return; + + op->buffer_unmap (bus, + urb->transfer_dma, + urb->transfer_buffer_length, + usb_pipein (urb->pipe) + ? USB_DIR_IN + : USB_DIR_OUT); +} + #ifdef CONFIG_PROC_FS struct list_head *usb_driver_get_list(void) { @@ -1534,4 +1686,11 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(usb_get_current_frame_number); +EXPORT_SYMBOL (usb_buffer_alloc); +EXPORT_SYMBOL (usb_buffer_free); + +EXPORT_SYMBOL (usb_buffer_map); +EXPORT_SYMBOL (usb_buffer_dmasync); +EXPORT_SYMBOL (usb_buffer_unmap); + MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 8b1f0135aa99..83a9a9be9916 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001 by David Brownell + * Copyright (c) 2001-2002 by David Brownell * * 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 @@ -175,3 +175,215 @@ dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) {} (status & PORT_CONNECT) ? " CONNECT" : "" \ ) +#ifdef DEBUG + +#define speed_char(info1) ({ char tmp; \ + switch (info1 & (3 << 12)) { \ + case 0 << 12: tmp = 'f'; break; \ + case 1 << 12: tmp = 'l'; break; \ + case 2 << 12: tmp = 'h'; break; \ + default: tmp = '?'; break; \ + }; tmp; }) + +static ssize_t +show_async (struct device *dev, char *buf, size_t count, loff_t off) +{ + struct pci_dev *pdev; + struct ehci_hcd *ehci; + unsigned long flags; + unsigned temp, size; + char *next; + struct ehci_qh *qh; + + if (off != 0) + return 0; + + pdev = container_of (dev, struct pci_dev, dev); + ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); + next = buf; + size = count; + + /* dumps a snapshot of the async schedule. + * usually empty except for long-term bulk reads, or head. + * one QH per line, and TDs we know about + */ + spin_lock_irqsave (&ehci->lock, flags); + if (ehci->async) { + qh = ehci->async; + do { + u32 scratch; + struct list_head *entry; + struct ehci_qtd *td; + + scratch = cpu_to_le32p (&qh->hw_info1); + temp = snprintf (next, size, "qh %p dev%d %cs ep%d", + qh, scratch & 0x007f, + speed_char (scratch), + (scratch >> 8) & 0x000f); + size -= temp; + next += temp; + + list_for_each (entry, &qh->qtd_list) { + td = list_entry (entry, struct ehci_qtd, + qtd_list); + scratch = cpu_to_le32p (&td->hw_token); + temp = snprintf (next, size, + ", td %p len=%d %s", + td, scratch >> 16, + ({ char *tmp; + switch ((scratch>>8)&0x03) { + case 0: tmp = "out"; break; + case 1: tmp = "in"; break; + case 2: tmp = "setup"; break; + default: tmp = "?"; break; + } tmp;}) + ); + size -= temp; + next += temp; + } + + temp = snprintf (next, size, "\n"); + size -= temp; + next += temp; + + } while ((qh = qh->qh_next.qh) != ehci->async); + } + spin_unlock_irqrestore (&ehci->lock, flags); + + return count - size; +} +static DEVICE_ATTR (async, "sched-async", S_IRUSR, show_async, NULL); + +#define DBG_SCHED_LIMIT 64 + +static ssize_t +show_periodic (struct device *dev, char *buf, size_t count, loff_t off) +{ + struct pci_dev *pdev; + struct ehci_hcd *ehci; + unsigned long flags; + union ehci_shadow p, *seen; + unsigned temp, size, seen_count; + char *next; + unsigned i, tag; + + if (off != 0) + return 0; + if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) + return 0; + seen_count = 0; + + pdev = container_of (dev, struct pci_dev, dev); + ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); + next = buf; + size = count; + + temp = snprintf (next, size, "size = %d\n", ehci->periodic_size); + size -= temp; + next += temp; + + /* dump a snapshot of the periodic schedule. + * iso changes, interrupt usually doesn't. + */ + spin_lock_irqsave (&ehci->lock, flags); + for (i = 0; i < ehci->periodic_size; i++) { + p = ehci->pshadow [i]; + if (!p.ptr) + continue; + tag = Q_NEXT_TYPE (ehci->periodic [i]); + + temp = snprintf (next, size, "%4d: ", i); + size -= temp; + next += temp; + + do { + switch (tag) { + case Q_TYPE_QH: + temp = snprintf (next, size, " intr-%d %p", + p.qh->period, p.qh); + size -= temp; + next += temp; + for (temp = 0; temp < seen_count; temp++) { + if (seen [temp].ptr == p.ptr) + break; + } + /* show more info the first time around */ + if (temp == seen_count) { + u32 scratch = cpu_to_le32p ( + &p.qh->hw_info1); + + temp = snprintf (next, size, + " (%cs dev%d ep%d)", + speed_char (scratch), + scratch & 0x007f, + (scratch >> 8) & 0x000f); + + /* FIXME TDs too */ + + if (seen_count < DBG_SCHED_LIMIT) + seen [seen_count++].qh = p.qh; + } else + temp = 0; + tag = Q_NEXT_TYPE (p.qh->hw_next); + p = p.qh->qh_next; + break; + case Q_TYPE_FSTN: + temp = snprintf (next, size, + " fstn-%8x/%p", p.fstn->hw_prev, + p.fstn); + tag = Q_NEXT_TYPE (p.fstn->hw_next); + p = p.fstn->fstn_next; + break; + case Q_TYPE_ITD: + temp = snprintf (next, size, + " itd/%p", p.itd); + tag = Q_NEXT_TYPE (p.itd->hw_next); + p = p.itd->itd_next; + break; + case Q_TYPE_SITD: + temp = snprintf (next, size, + " sitd/%p", p.sitd); + tag = Q_NEXT_TYPE (p.sitd->hw_next); + p = p.sitd->sitd_next; + break; + } + size -= temp; + next += temp; + } while (p.ptr); + + temp = snprintf (next, size, "\n"); + size -= temp; + next += temp; + } + spin_unlock_irqrestore (&ehci->lock, flags); + kfree (seen); + + return count - size; +} +static DEVICE_ATTR (periodic, "sched-periodic", S_IRUSR, show_periodic, NULL); + +#undef DBG_SCHED_LIMIT + +static inline void create_debug_files (struct ehci_hcd *bus) +{ + device_create_file (&bus->hcd.pdev->dev, &dev_attr_async); + device_create_file (&bus->hcd.pdev->dev, &dev_attr_periodic); +} + +static inline void remove_debug_files (struct ehci_hcd *bus) +{ + device_remove_file (&bus->hcd.pdev->dev, &dev_attr_async); + device_remove_file (&bus->hcd.pdev->dev, &dev_attr_periodic); +} + +#else /* DEBUG */ + +static inline void create_debug_files (struct ehci_hcd *bus) +{ +} + +static inline void remove_debug_files (struct ehci_hcd *bus) +{ +} + +#endif /* DEBUG */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index dcb10d5dc2cd..6aaf8a72f382 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -65,6 +65,8 @@ * * HISTORY: * + * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared; + * only scheduling is different, no arbitrary limitations. * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support, * clean up HC run state handshaking. * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts @@ -85,7 +87,7 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2002-Jul-25" +#define DRIVER_VERSION "2002-Aug-06" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -93,6 +95,8 @@ // #define EHCI_VERBOSE_DEBUG // #define have_split_iso +#define INTR_AUTOMAGIC /* to be removed later in 2.5 */ + /* magic numbers that can affect system performance */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ #define EHCI_TUNE_RL_HS 0 /* nak throttle; see 4.9 */ @@ -376,6 +380,8 @@ done2: return -ENOMEM; } + create_debug_files (ehci); + /* * Start, enabling full USB 2.0 functionality ... usb 1.1 devices * are explicitly handed to companion controller(s), so no TT is @@ -429,6 +435,8 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_ready (ehci); ehci_reset (ehci); + remove_debug_files (ehci); + /* root hub is shut down separately (first, when possible) */ tasklet_disable (&ehci->tasklet); ehci_tasklet ((unsigned long) ehci); @@ -614,7 +622,8 @@ dead: * * hcd-specific init for hcpriv hasn't been done yet * - * NOTE: EHCI queues control and bulk requests transparently, like OHCI. + * NOTE: control, bulk, and interrupt share the same code to append TDs + * to a (possibly active) QH, and the same QH scanning code. */ static int ehci_urb_enqueue ( struct usb_hcd *hcd, @@ -626,10 +635,11 @@ static int ehci_urb_enqueue ( urb->transfer_flags &= ~EHCI_STATE_UNLINK; INIT_LIST_HEAD (&qtd_list); - switch (usb_pipetype (urb->pipe)) { - case PIPE_CONTROL: - case PIPE_BULK: + switch (usb_pipetype (urb->pipe)) { + // case PIPE_CONTROL: + // case PIPE_BULK: + default: if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) return -ENOMEM; return submit_async (ehci, urb, &qtd_list, mem_flags); @@ -649,9 +659,6 @@ static int ehci_urb_enqueue ( dbg ("no split iso support yet"); return -ENOSYS; #endif /* have_split_iso */ - - default: /* can't happen */ - return -ENOSYS; } } @@ -665,15 +672,16 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; unsigned long flags; - dbg ("%s urb_dequeue %p qh state %d", - hcd->self.bus_name, urb, qh->qh_state); + dbg ("%s urb_dequeue %p qh %p state %d", + hcd->self.bus_name, urb, qh, qh->qh_state); switch (usb_pipetype (urb->pipe)) { - case PIPE_CONTROL: - case PIPE_BULK: + // case PIPE_CONTROL: + // case PIPE_BULK: + default: spin_lock_irqsave (&ehci->lock, flags); if (ehci->reclaim) { -dbg ("dq: reclaim busy, %s", RUN_CONTEXT); + dbg ("dq: reclaim busy, %s", RUN_CONTEXT); if (in_interrupt ()) { spin_unlock_irqrestore (&ehci->lock, flags); return -EAGAIN; @@ -683,28 +691,43 @@ dbg ("dq: reclaim busy, %s", RUN_CONTEXT); && ehci->hcd.state != USB_STATE_HALT ) { spin_unlock_irqrestore (&ehci->lock, flags); -// yeech ... this could spin for up to two frames! -dbg ("wait for dequeue: state %d, reclaim %p, hcd state %d", - qh->qh_state, ehci->reclaim, ehci->hcd.state -); - udelay (100); + /* let pending unlinks complete */ + wait_ms (1); spin_lock_irqsave (&ehci->lock, flags); } } if (qh->qh_state == QH_STATE_LINKED) start_unlink_async (ehci, qh); spin_unlock_irqrestore (&ehci->lock, flags); - return 0; + break; case PIPE_INTERRUPT: - intr_deschedule (ehci, urb->start_frame, qh, - (urb->dev->speed == USB_SPEED_HIGH) - ? urb->interval - : (urb->interval << 3)); - if (ehci->hcd.state == USB_STATE_HALT) - urb->status = -ESHUTDOWN; - qh_completions (ehci, qh, 1); - return 0; + if (qh->qh_state == QH_STATE_LINKED) { + /* messy, can spin or block a microframe ... */ + intr_deschedule (ehci, qh, 1); + /* qh_state == IDLE */ + } + qh_completions (ehci, qh); + + /* reschedule QH iff another request is queued */ + if (!list_empty (&qh->qtd_list) + && HCD_IS_RUNNING (ehci->hcd.state)) { + int status; + + spin_lock_irqsave (&ehci->lock, flags); + status = qh_schedule (ehci, qh); + spin_unlock_irqrestore (&ehci->lock, flags); + + if (status != 0) { + // shouldn't happen often, but ... + // FIXME kill those tds' urbs + err ("can't reschedule qh %p, err %d", + qh, status); + } + return status; + } + + break; case PIPE_ISOCHRONOUS: // itd or sitd ... @@ -712,9 +735,9 @@ dbg ("wait for dequeue: state %d, reclaim %p, hcd state %d", // wait till next completion, do it then. // completion irqs can wait up to 1024 msec, urb->transfer_flags |= EHCI_STATE_UNLINK; - return 0; + break; } - return -EINVAL; + return 0; } /*-------------------------------------------------------------------------*/ @@ -728,6 +751,7 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev) int i; unsigned long flags; + /* ASSERT: no requests/urbs are still linked (so no TDs) */ /* ASSERT: nobody can be submitting urbs for this any more */ dbg ("%s: free_config devnum %d", hcd->self.bus_name, udev->devnum); @@ -736,34 +760,57 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev) for (i = 0; i < 32; i++) { if (dev->ep [i]) { struct ehci_qh *qh; + char *why; /* dev->ep never has ITDs or SITDs */ qh = (struct ehci_qh *) dev->ep [i]; - vdbg ("free_config, ep 0x%02x qh %p", i, qh); - if (!list_empty (&qh->qtd_list)) { - dbg ("ep 0x%02x qh %p not empty!", i, qh); + + /* detect/report non-recoverable errors */ + if (in_interrupt ()) + why = "disconnect() didn't"; + else if ((qh->hw_info2 & cpu_to_le32 (0xffff)) != 0 + && qh->qh_state != QH_STATE_IDLE) + why = "(active periodic)"; + else + why = 0; + if (why) { + err ("dev %s-%s ep %d-%s error: %s", + hcd->self.bus_name, udev->devpath, + i & 0xf, (i & 0x10) ? "IN" : "OUT", + why); BUG (); } - dev->ep [i] = 0; - /* wait_ms() won't spin here -- we're a thread */ + dev->ep [i] = 0; + if (qh->qh_state == QH_STATE_IDLE) + goto idle; + dbg ("free_config, async ep 0x%02x qh %p", i, qh); + + /* scan_async() empties the ring as it does its work, + * using IAA, but doesn't (yet?) turn it off. if it + * doesn't empty this qh, likely it's the last entry. + */ while (qh->qh_state == QH_STATE_LINKED && ehci->reclaim && ehci->hcd.state != USB_STATE_HALT ) { spin_unlock_irqrestore (&ehci->lock, flags); + /* wait_ms() won't spin, we're a thread; + * and we know IRQ+tasklet can progress + */ wait_ms (1); spin_lock_irqsave (&ehci->lock, flags); } - if (qh->qh_state == QH_STATE_LINKED) { + if (qh->qh_state == QH_STATE_LINKED) start_unlink_async (ehci, qh); - while (qh->qh_state != QH_STATE_IDLE) { - spin_unlock_irqrestore (&ehci->lock, - flags); - wait_ms (1); - spin_lock_irqsave (&ehci->lock, flags); - } + while (qh->qh_state != QH_STATE_IDLE + && ehci->hcd.state != USB_STATE_HALT) { + spin_unlock_irqrestore (&ehci->lock, + flags); + wait_ms (1); + spin_lock_irqsave (&ehci->lock, flags); } +idle: qh_put (ehci, qh); } } diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3057d75b0fed..e0426d675d60 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -47,9 +47,11 @@ static int qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) { int i, count; + u64 addr = buf; /* one buffer entry per 4K ... first might be short or unaligned */ - qtd->hw_buf [0] = cpu_to_le32 (buf); + qtd->hw_buf [0] = cpu_to_le32 ((u32)addr); + qtd->hw_buf_hi [0] = cpu_to_le32 ((u32)(addr >> 32)); count = 0x1000 - (buf & 0x0fff); /* rest of that page */ if (likely (len < count)) /* ... iff needed */ count = len; @@ -59,7 +61,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) /* per-qtd limit: from 16K to 20K (best alignment) */ for (i = 1; count < len && i < 5; i++) { - u64 addr = buf; + addr = buf; qtd->hw_buf [i] = cpu_to_le32 ((u32)addr); qtd->hw_buf_hi [i] = cpu_to_le32 ((u32)(addr >> 32)); buf += 0x1000; @@ -157,30 +159,6 @@ static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token) } } -static void ehci_urb_complete ( - struct ehci_hcd *ehci, - dma_addr_t addr, - struct urb *urb -) { - if (urb->transfer_buffer_length && usb_pipein (urb->pipe)) - pci_dma_sync_single (ehci->hcd.pdev, addr, - urb->transfer_buffer_length, - PCI_DMA_FROMDEVICE); - - /* cleanse status if we saw no error */ - if (likely (urb->status == -EINPROGRESS)) { - if (urb->actual_length != urb->transfer_buffer_length - && (urb->transfer_flags & URB_SHORT_NOT_OK)) - urb->status = -EREMOTEIO; - else - urb->status = 0; - } - - /* only report unlinks once */ - if (likely (urb->status != -ENOENT && urb->status != -ENOTCONN)) - urb->complete (urb); -} - /* urb->lock ignored from here on (hcd is done with urb) */ static void ehci_urb_done ( @@ -188,6 +166,11 @@ static void ehci_urb_done ( dma_addr_t addr, struct urb *urb ) { +#ifdef INTR_AUTOMAGIC + struct urb *resubmit = 0; + struct usb_device *dev = 0; +#endif + if (urb->transfer_buffer_length) pci_unmap_single (ehci->hcd.pdev, addr, @@ -196,7 +179,23 @@ static void ehci_urb_done ( ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); if (likely (urb->hcpriv != 0)) { - qh_put (ehci, (struct ehci_qh *) urb->hcpriv); + struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; + + /* S-mask in a QH means it's an interrupt urb */ + if ((qh->hw_info2 & cpu_to_le32 (0x00ff)) != 0) { + + /* ... update hc-wide periodic stats (for usbfs) */ + ehci->hcd.self.bandwidth_int_reqs--; + +#ifdef INTR_AUTOMAGIC + if (!((urb->status == -ENOENT) + || (urb->status == -ECONNRESET))) { + resubmit = usb_get_urb (urb); + dev = urb->dev; + } +#endif + } + qh_put (ehci, qh); urb->hcpriv = 0; } @@ -208,33 +207,46 @@ static void ehci_urb_done ( urb->status = 0; } - /* hand off urb ownership */ usb_hcd_giveback_urb (&ehci->hcd, urb); + +#ifdef INTR_AUTOMAGIC + if (resubmit && ((urb->status == -ENOENT) + || (urb->status == -ECONNRESET))) { + usb_put_urb (resubmit); + resubmit = 0; + } + // device drivers will soon be doing something like this + if (resubmit) { + int status; + + resubmit->dev = dev; + status = usb_submit_urb (resubmit, SLAB_KERNEL); + if (status != 0) + err ("can't resubmit interrupt urb %p: status %d", + resubmit, status); + usb_put_urb (resubmit); + } +#endif } /* * Process completed qtds for a qh, issuing completions if needed. - * When freeing: frees qtds, unmaps buf, returns URB to driver. - * When not freeing (queued periodic qh): retain qtds, mapping, and urb. + * Frees qtds, unmaps buf, returns URB to driver. * Races up to qh->hw_current; returns number of urb completions. */ -static int -qh_completions ( - struct ehci_hcd *ehci, - struct ehci_qh *qh, - int freeing -) { +static void +qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) +{ struct ehci_qtd *qtd, *last; struct list_head *next, *qtd_list = &qh->qtd_list; int unlink = 0, halted = 0; unsigned long flags; - int retval = 0; spin_lock_irqsave (&ehci->lock, flags); if (unlikely (list_empty (qtd_list))) { spin_unlock_irqrestore (&ehci->lock, flags); - return retval; + return; } /* scan QTDs till end of list, or we reach an active one */ @@ -251,14 +263,8 @@ qh_completions ( if (likely (last->urb != urb)) { /* complete() can reenter this HCD */ spin_unlock_irqrestore (&ehci->lock, flags); - if (likely (freeing != 0)) - ehci_urb_done (ehci, last->buf_dma, - last->urb); - else - ehci_urb_complete (ehci, last->buf_dma, - last->urb); + ehci_urb_done (ehci, last->buf_dma, last->urb); spin_lock_irqsave (&ehci->lock, flags); - retval++; } /* qh overlays can have HC's old cached copies of @@ -270,8 +276,7 @@ qh_completions ( qh->hw_qtd_next = last->hw_next; } - if (likely (freeing != 0)) - ehci_qtd_free (ehci, last); + ehci_qtd_free (ehci, last); last = 0; } next = qtd->qtd_list.next; @@ -288,7 +293,7 @@ qh_completions ( /* fault: unlink the rest, since this qtd saw an error? */ if (unlikely ((token & QTD_STS_HALT) != 0)) { - freeing = unlink = 1; + unlink = 1; /* status copied below */ /* QH halts only because of fault (above) or unlink (here). */ @@ -296,13 +301,14 @@ qh_completions ( /* unlinking everything because of HC shutdown? */ if (ehci->hcd.state == USB_STATE_HALT) { - freeing = unlink = 1; + unlink = 1; /* explicit unlink, maybe starting here? */ } else if (qh->qh_state == QH_STATE_IDLE && (urb->status == -ECONNRESET + || urb->status == -ESHUTDOWN || urb->status == -ENOENT)) { - freeing = unlink = 1; + unlink = 1; /* QH halted to unlink urbs _after_ this? */ } else if (!unlink && (token & QTD_STS_ACTIVE) != 0) { @@ -312,7 +318,7 @@ qh_completions ( /* unlink the rest? once we start unlinking, after * a fault or explicit unlink, we unlink all later - * urbs. usb spec requires that. + * urbs. usb spec requires that for faults... */ if (unlink && urb->status == -EINPROGRESS) urb->status = -ECONNRESET; @@ -330,31 +336,7 @@ qh_completions ( qtd_copy_status (urb, qtd->length, token); spin_unlock (&urb->lock); - /* - * NOTE: this won't work right with interrupt urbs that - * need multiple qtds ... only the first scan of qh->qtd_list - * starts at the right qtd, yet multiple scans could happen - * for transfers that are scheduled across multiple uframes. - * (Such schedules are not currently allowed!) - */ - if (likely (freeing != 0)) - list_del (&qtd->qtd_list); - else { - /* restore everything the HC could change - * from an interrupt QTD - */ - qtd->hw_token = (qtd->hw_token - & __constant_cpu_to_le32 (0x8300)) - | cpu_to_le32 (qtd->length << 16) - | __constant_cpu_to_le32 (QTD_STS_ACTIVE - | (EHCI_TUNE_CERR << 10)); - qtd->hw_buf [0] &= ~__constant_cpu_to_le32 (0x0fff); - - /* this offset, and the length above, - * are likely wrong on QTDs #2..N - */ - qtd->hw_buf [0] |= cpu_to_le32 (0x0fff & qtd->buf_dma); - } + list_del (&qtd->qtd_list); #if 0 if (urb->status == -EINPROGRESS) @@ -382,14 +364,9 @@ qh_completions ( /* last urb's completion might still need calling */ if (likely (last != 0)) { - if (likely (freeing != 0)) { - ehci_urb_done (ehci, last->buf_dma, last->urb); - ehci_qtd_free (ehci, last); - } else - ehci_urb_complete (ehci, last->buf_dma, last->urb); - retval++; + ehci_urb_done (ehci, last->buf_dma, last->urb); + ehci_qtd_free (ehci, last); } - return retval; } /*-------------------------------------------------------------------------*/ @@ -450,6 +427,7 @@ qh_urb_transaction ( struct ehci_qtd *qtd, *qtd_prev; dma_addr_t buf, map_buf; int len, maxpacket; + int is_input; u32 token; /* @@ -495,10 +473,11 @@ qh_urb_transaction ( * data transfer stage: buffer setup */ len = urb->transfer_buffer_length; + is_input = usb_pipein (urb->pipe); if (likely (len > 0)) { buf = map_buf = pci_map_single (ehci->hcd.pdev, urb->transfer_buffer, len, - usb_pipein (urb->pipe) + is_input ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); if (unlikely (!buf)) @@ -506,12 +485,11 @@ qh_urb_transaction ( } else buf = map_buf = 0; - if (!buf || usb_pipein (urb->pipe)) + if (!buf || is_input) token |= (1 /* "in" */ << 8); /* else it's already initted to "out" pid (0 << 8) */ - maxpacket = usb_maxpacket (urb->dev, urb->pipe, - usb_pipeout (urb->pipe)); + maxpacket = usb_maxpacket (urb->dev, urb->pipe, !is_input) & 0x03ff; /* * buffer gets wrapped in one or more qtds; @@ -607,6 +585,11 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh) // That'd mean updating how usbcore talks to HCDs. (2.5?) +// high bandwidth multiplier, as encoded in highspeed endpoint descriptors +#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) +// ... and packet size, for any kind of endpoint descriptor +#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x03ff) + /* * Each QH holds a qtd list; a QH is used for everything except iso. * @@ -624,6 +607,8 @@ ehci_qh_make ( ) { struct ehci_qh *qh = ehci_qh_alloc (ehci, flags); u32 info1 = 0, info2 = 0; + int is_input, type; + int maxp = 0; if (!qh) return qh; @@ -634,6 +619,53 @@ ehci_qh_make ( info1 |= usb_pipeendpoint (urb->pipe) << 8; info1 |= usb_pipedevice (urb->pipe) << 0; + is_input = usb_pipein (urb->pipe); + type = usb_pipetype (urb->pipe); + maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input); + + /* Compute interrupt scheduling parameters just once, and save. + * - allowing for high bandwidth, how many nsec/uframe are used? + * - split transactions need a second CSPLIT uframe; same question + * - splits also need a schedule gap (for full/low speed I/O) + * - qh has a polling interval + * + * For control/bulk requests, the HC or TT handles these. + */ + if (type == PIPE_INTERRUPT) { + qh->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, + hb_mult (maxp) * max_packet (maxp)); + qh->start = NO_FRAME; + + if (urb->dev->speed == USB_SPEED_HIGH) { + qh->c_usecs = 0; + qh->gap_uf = 0; + + /* FIXME handle HS periods of less than 1 frame. */ + qh->period = urb->interval >> 3; + if (qh->period < 1) { + dbg ("intr period %d uframes, NYET!", + urb->interval); + qh = 0; + goto done; + } + } else { + /* gap is f(FS/LS transfer times) */ + qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed, + is_input, 0, maxp) / (125 * 1000); + + /* FIXME this just approximates SPLIT/CSPLIT times */ + if (is_input) { // SPLIT, gap, CSPLIT+DATA + qh->c_usecs = qh->usecs + HS_USECS (0); + qh->usecs = HS_USECS (1); + } else { // SPLIT+DATA, gap, CSPLIT + qh->usecs += HS_USECS (1); + qh->c_usecs = HS_USECS (0); + } + + qh->period = urb->interval; + } + } + /* using TT? */ switch (urb->dev->speed) { case USB_SPEED_LOW: @@ -643,67 +675,63 @@ ehci_qh_make ( case USB_SPEED_FULL: /* EPS 0 means "full" */ info1 |= (EHCI_TUNE_RL_TT << 28); - if (usb_pipecontrol (urb->pipe)) { + if (type == PIPE_CONTROL) { info1 |= (1 << 27); /* for TT */ info1 |= 1 << 14; /* toggle from qtd */ } - info1 |= usb_maxpacket (urb->dev, urb->pipe, - usb_pipeout (urb->pipe)) << 16; + info1 |= maxp << 16; info2 |= (EHCI_TUNE_MULT_TT << 30); info2 |= urb->dev->ttport << 23; info2 |= urb->dev->tt->hub->devnum << 16; - /* NOTE: if (usb_pipeint (urb->pipe)) { scheduler sets c-mask } - * ... and a 0.96 scheduler might use FSTN nodes too - */ + /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */ + break; case USB_SPEED_HIGH: /* no TT involved */ info1 |= (2 << 12); /* EPS "high" */ info1 |= (EHCI_TUNE_RL_HS << 28); - if (usb_pipecontrol (urb->pipe)) { + if (type == PIPE_CONTROL) { info1 |= 64 << 16; /* usb2 fixed maxpacket */ info1 |= 1 << 14; /* toggle from qtd */ info2 |= (EHCI_TUNE_MULT_HS << 30); - } else if (usb_pipebulk (urb->pipe)) { + } else if (type == PIPE_BULK) { info1 |= 512 << 16; /* usb2 fixed maxpacket */ info2 |= (EHCI_TUNE_MULT_HS << 30); - } else { - u32 temp; - temp = usb_maxpacket (urb->dev, urb->pipe, - usb_pipeout (urb->pipe)); - info1 |= (temp & 0x3ff) << 16; /* maxpacket */ - /* HS intr can be "high bandwidth" */ - temp = 1 + ((temp >> 11) & 0x03); - info2 |= temp << 30; /* mult */ + } else { /* PIPE_INTERRUPT */ + info1 |= max_packet (maxp) << 16; + info2 |= hb_mult (maxp) << 30; } break; - default: #ifdef DEBUG + default: BUG (); #endif } - /* NOTE: if (usb_pipeint (urb->pipe)) { scheduler sets s-mask } */ + /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */ qh->qh_state = QH_STATE_IDLE; qh->hw_info1 = cpu_to_le32 (info1); qh->hw_info2 = cpu_to_le32 (info2); /* initialize sw and hw queues with these qtds */ - list_splice (qtd_list, &qh->qtd_list); - qh_update (qh, list_entry (qtd_list->next, struct ehci_qtd, qtd_list)); + if (!list_empty (qtd_list)) { + list_splice (qtd_list, &qh->qtd_list); + qh_update (qh, list_entry (qtd_list->next, struct ehci_qtd, qtd_list)); + } else { + qh->hw_qtd_next = qh->hw_alt_next = EHCI_LIST_END; + } /* initialize data toggle state */ - if (!usb_pipecontrol (urb->pipe)) - clear_toggle (urb->dev, - usb_pipeendpoint (urb->pipe), - usb_pipeout (urb->pipe), - qh); + clear_toggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, qh); +done: return qh; } +#undef hb_mult +#undef hb_packet /*-------------------------------------------------------------------------*/ @@ -745,50 +773,48 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) /*-------------------------------------------------------------------------*/ -static int -submit_async ( +/* + * For control/bulk/interrupt, return QH with these TDs appended. + * Allocates and initializes the QH if necessary. + * Returns null if it can't allocate a QH it needs to. + * If the QH has TDs (urbs) already, that's great. + */ +static struct ehci_qh *qh_append_tds ( struct ehci_hcd *ehci, struct urb *urb, struct list_head *qtd_list, - int mem_flags -) { - struct ehci_qtd *qtd; - struct hcd_dev *dev; - int epnum; - unsigned long flags; + int epnum, + void **ptr +) +{ struct ehci_qh *qh = 0; - qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); - dev = (struct hcd_dev *)urb->dev->hcpriv; - epnum = usb_pipeendpoint (urb->pipe); - if (usb_pipein (urb->pipe)) - epnum |= 0x10; - - vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]", - ehci->hcd.self.bus_name, urb, urb->transfer_buffer_length, - epnum & 0x0f, (epnum & 0x10) ? "in" : "out", - qtd, dev ? dev->ep [epnum] : (void *)~0); - - spin_lock_irqsave (&ehci->lock, flags); - - qh = (struct ehci_qh *) dev->ep [epnum]; + qh = (struct ehci_qh *) *ptr; if (likely (qh != 0)) { - u32 hw_next = QTD_NEXT (qtd->qtd_dma); + struct ehci_qtd *qtd; + + if (unlikely (list_empty (qtd_list))) + qtd = 0; + else + qtd = list_entry (qtd_list->next, struct ehci_qtd, + qtd_list); /* maybe patch the qh used for set_address */ if (unlikely (epnum == 0 && le32_to_cpu (qh->hw_info1 & 0x7f) == 0)) qh->hw_info1 |= cpu_to_le32 (usb_pipedevice(urb->pipe)); - /* is an URB is queued to this qh already? */ - if (unlikely (!list_empty (&qh->qtd_list))) { + /* append to tds already queued to this qh? */ + if (unlikely (!list_empty (&qh->qtd_list) && qtd)) { struct ehci_qtd *last_qtd; int short_rx = 0; + u32 hw_next; /* update the last qtd's "next" pointer */ // dbg_qh ("non-empty qh", ehci, qh); last_qtd = list_entry (qh->qtd_list.prev, struct ehci_qtd, qtd_list); + hw_next = QTD_NEXT (qtd->qtd_dma); last_qtd->hw_next = hw_next; /* previous urb allows short rx? maybe optimize. */ @@ -803,6 +829,7 @@ submit_async ( * Interrupt code must cope with case of HC having it * cached, and clobbering these updates. * ... complicates getting rid of extra interrupts! + * (Or: use dummy td, so cache always stays valid.) */ if (qh->hw_current == cpu_to_le32 (last_qtd->qtd_dma)) { wmb (); @@ -822,31 +849,61 @@ submit_async ( */ /* usb_clear_halt() means qh data toggle gets reset */ - if (usb_pipebulk (urb->pipe) - && unlikely (!usb_gettoggle (urb->dev, + if (unlikely (!usb_gettoggle (urb->dev, (epnum & 0x0f), !(epnum & 0x10)))) { clear_toggle (urb->dev, epnum & 0x0f, !(epnum & 0x10), qh); } - qh_update (qh, qtd); + if (qtd) + qh_update (qh, qtd); } list_splice (qtd_list, qh->qtd_list.prev); } else { /* can't sleep here, we have ehci->lock... */ qh = ehci_qh_make (ehci, urb, qtd_list, SLAB_ATOMIC); - if (likely (qh != 0)) { - // dbg_qh ("new qh", ehci, qh); - dev->ep [epnum] = qh; - } + // if (qh) dbg_qh ("new qh", ehci, qh); + *ptr = qh; } + if (qh) + urb->hcpriv = qh_get (qh); + return qh; +} + +/*-------------------------------------------------------------------------*/ + +static int +submit_async ( + struct ehci_hcd *ehci, + struct urb *urb, + struct list_head *qtd_list, + int mem_flags +) { + struct ehci_qtd *qtd; + struct hcd_dev *dev; + int epnum; + unsigned long flags; + struct ehci_qh *qh = 0; + + qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); + dev = (struct hcd_dev *)urb->dev->hcpriv; + epnum = usb_pipeendpoint (urb->pipe); + if (usb_pipein (urb->pipe)) + epnum |= 0x10; + + vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]", + ehci->hcd.self.bus_name, urb, urb->transfer_buffer_length, + epnum & 0x0f, (epnum & 0x10) ? "in" : "out", + qtd, dev ? dev->ep [epnum] : (void *)~0); + + spin_lock_irqsave (&ehci->lock, flags); + qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]); /* Control/bulk operations through TTs don't need scheduling, * the HC and TT handle it when the TT has a buffer ready. */ if (likely (qh != 0)) { - urb->hcpriv = qh_get (qh); if (likely (qh->qh_state == QH_STATE_IDLE)) qh_link_async (ehci, qh_get (qh)); } @@ -873,7 +930,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) ehci->reclaim = 0; ehci->reclaim_ready = 0; - qh_completions (ehci, qh, 1); + qh_completions (ehci, qh); // unlink any urb should now unlink all following urbs, so that // relinking only happens for urbs before the unlinked ones. @@ -973,13 +1030,15 @@ rescan: spin_unlock_irqrestore (&ehci->lock, flags); /* concurrent unlink could happen here */ - qh_completions (ehci, qh, 1); + qh_completions (ehci, qh); spin_lock_irqsave (&ehci->lock, flags); qh_put (ehci, qh); } - /* unlink idle entries (reduces PCI usage) */ + /* unlink idle entries, reducing HC PCI usage as + * well as HCD schedule-scanning costs + */ if (list_empty (&qh->qtd_list) && !ehci->reclaim) { if (qh->qh_next.qh != qh) { // dbg ("irq/empty"); @@ -987,6 +1046,7 @@ rescan: } else { // FIXME: arrange to stop // after it's been idle a while. + // stop/restart isn't free... } } qh = qh->qh_next.qh; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 5e08204d34d9..1cb1b8a701bd 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -220,31 +220,31 @@ static int disable_periodic (struct ehci_hcd *ehci) /*-------------------------------------------------------------------------*/ +// FIXME microframe periods not yet handled + static void intr_deschedule ( struct ehci_hcd *ehci, - unsigned frame, struct ehci_qh *qh, - unsigned period + int wait ) { unsigned long flags; int status; - - period >>= 3; // FIXME microframe periods not handled yet + unsigned frame = qh->start; spin_lock_irqsave (&ehci->lock, flags); do { periodic_unlink (ehci, frame, qh); qh_put (ehci, qh); - frame += period; + frame += qh->period; } while (frame < ehci->periodic_size); qh->qh_state = QH_STATE_UNLINK; qh->qh_next.ptr = 0; - ehci->periodic_urbs--; + ehci->periodic_sched--; /* maybe turn off periodic schedule */ - if (!ehci->periodic_urbs) + if (!ehci->periodic_sched) status = disable_periodic (ehci); else { status = 0; @@ -258,21 +258,35 @@ static void intr_deschedule ( * (yeech!) to be sure it's done. * No other threads may be mucking with this qh. */ - if (!status && ((ehci_get_frame (&ehci->hcd) - frame) % period) == 0) - udelay (125); + if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) { + if (wait) { + udelay (125); + qh->hw_next = EHCI_LIST_END; + } else { + /* we may not be IDLE yet, but if the qh is empty + * the race is very short. then if qh also isn't + * rescheduled soon, it won't matter. otherwise... + */ + vdbg ("intr_deschedule..."); + } + } else + qh->hw_next = EHCI_LIST_END; qh->qh_state = QH_STATE_IDLE; - qh->hw_next = EHCI_LIST_END; + + /* update per-qh bandwidth utilization (for usbfs) */ + ehci->hcd.self.bandwidth_allocated -= + (qh->usecs + qh->c_usecs) / qh->period; vdbg ("descheduled qh %p, per = %d frame = %d count = %d, urbs = %d", - qh, period, frame, - atomic_read (&qh->refcount), ehci->periodic_urbs); + qh, qh->period, frame, + atomic_read (&qh->refcount), ehci->periodic_sched); } static int check_period ( struct ehci_hcd *ehci, unsigned frame, - int uframe, + unsigned uframe, unsigned period, unsigned usecs ) { @@ -309,19 +323,142 @@ static int check_period ( return 1; } +static int check_intr_schedule ( + struct ehci_hcd *ehci, + unsigned frame, + unsigned uframe, + const struct ehci_qh *qh, + u32 *c_maskp +) +{ + int retval = -ENOSPC; + + if (!check_period (ehci, frame, uframe, qh->period, qh->usecs)) + goto done; + if (!qh->c_usecs) { + retval = 0; + *c_maskp = cpu_to_le32 (0); + goto done; + } + + /* This is a split transaction; check the bandwidth available for + * the completion too. Check both worst and best case gaps: worst + * case is SPLIT near uframe end, and CSPLIT near start ... best is + * vice versa. Difference can be almost two uframe times, but we + * reserve unnecessary bandwidth (waste it) this way. (Actually + * even better cases exist, like immediate device NAK.) + * + * FIXME don't even bother unless we know this TT is idle in that + * range of uframes ... for now, check_period() allows only one + * interrupt transfer per frame, so needn't check "TT busy" status + * when scheduling a split (QH, SITD, or FSTN). + * + * FIXME ehci 0.96 and above can use FSTNs + */ + if (!check_period (ehci, frame, uframe + qh->gap_uf + 1, + qh->period, qh->c_usecs)) + goto done; + if (!check_period (ehci, frame, uframe + qh->gap_uf, + qh->period, qh->c_usecs)) + goto done; + + *c_maskp = cpu_to_le32 (0x03 << (8 + uframe + qh->gap_uf)); + retval = 0; +done: + return retval; +} + +static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + int status; + unsigned uframe; + u32 c_mask; + unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */ + + qh->hw_next = EHCI_LIST_END; + frame = qh->start; + + /* reuse the previous schedule slots, if we can */ + if (frame < qh->period) { + uframe = ffs (le32_to_cpup (&qh->hw_info2) & 0x00ff); + status = check_intr_schedule (ehci, frame, --uframe, + qh, &c_mask); + } else { + uframe = 0; + c_mask = 0; + status = -ENOSPC; + } + + /* else scan the schedule to find a group of slots such that all + * uframes have enough periodic bandwidth available. + */ + if (status) { + frame = qh->period - 1; + do { + for (uframe = 0; uframe < 8; uframe++) { + status = check_intr_schedule (ehci, + frame, uframe, qh, + &c_mask); + if (status == 0) + break; + } + } while (status && --frame); + if (status) + goto done; + qh->start = frame; + + /* reset S-frame and (maybe) C-frame masks */ + qh->hw_info2 &= ~0xffff; + qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask; + } else + dbg ("reused previous qh %p schedule", qh); + + /* stuff into the periodic schedule */ + qh->qh_state = QH_STATE_LINKED; + dbg ("qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)", + qh, qh->usecs, qh->c_usecs, + qh->period, frame, uframe, qh->gap_uf); + do { + if (unlikely (ehci->pshadow [frame].ptr != 0)) { + +// FIXME -- just link toward the end, before any qh with a shorter period, +// AND accomodate it already having been linked here (after some other qh) +// AS WELL AS updating the schedule checking logic + + BUG (); + } else { + ehci->pshadow [frame].qh = qh_get (qh); + ehci->periodic [frame] = + QH_NEXT (qh->qh_dma); + } + wmb (); + frame += qh->period; + } while (frame < ehci->periodic_size); + + /* update per-qh bandwidth for usbfs */ + ehci->hcd.self.bandwidth_allocated += + (qh->usecs + qh->c_usecs) / qh->period; + + /* maybe enable periodic schedule processing */ + if (!ehci->periodic_sched++) + status = enable_periodic (ehci); +done: + return status; +} + static int intr_submit ( struct ehci_hcd *ehci, struct urb *urb, struct list_head *qtd_list, int mem_flags ) { - unsigned epnum, period; - unsigned short usecs, c_usecs, gap_uf; + unsigned epnum; unsigned long flags; struct ehci_qh *qh; struct hcd_dev *dev; int is_input; int status = 0; + struct list_head empty; /* get endpoint and transfer/schedule data */ epnum = usb_pipeendpoint (urb->pipe); @@ -329,198 +466,30 @@ static int intr_submit ( if (is_input) epnum |= 0x10; - /* - * HS interrupt transfers are simple -- only one microframe. FS/LS - * interrupt transfers involve a SPLIT in one microframe and CSPLIT - * sometime later. We need to know how much time each will be - * needed in each microframe and, for FS/LS, how many microframes - * separate the two in the best case. - */ - usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, - urb->transfer_buffer_length); - if (urb->dev->speed == USB_SPEED_HIGH) { - gap_uf = 0; - c_usecs = 0; - - /* FIXME handle HS periods of less than 1 frame. */ - period = urb->interval >> 3; - if (period < 1) { - dbg ("intr period %d uframes, NYET!", urb->interval); - status = -EINVAL; - goto done; - } - } else { - /* gap is a function of full/low speed transfer times */ - gap_uf = 1 + usb_calc_bus_time (urb->dev->speed, is_input, 0, - urb->transfer_buffer_length) / (125 * 1000); - - /* FIXME this just approximates SPLIT/CSPLIT times */ - if (is_input) { // SPLIT, gap, CSPLIT+DATA - c_usecs = usecs + HS_USECS (0); - usecs = HS_USECS (1); - } else { // SPLIT+DATA, gap, CSPLIT - usecs = usecs + HS_USECS (1); - c_usecs = HS_USECS (0); - } - - period = urb->interval; - } + spin_lock_irqsave (&ehci->lock, flags); + dev = (struct hcd_dev *)urb->dev->hcpriv; - /* - * NOTE: current completion/restart logic doesn't handle more than - * one qtd in a periodic qh ... 16-20 KB/urb is pretty big for this. - * such big requests need many periods to transfer. - * - * FIXME want to change hcd core submit model to expect queuing - * for all transfer types ... not just ISO and (with flag) BULK. - * that means: getting rid of this check; handling the "interrupt - * urb already queued" case below like bulk queuing is handled (no - * errors possible!); and completly getting rid of that annoying - * qh restart logic. simpler/smaller overall, and more flexible. - */ - if (unlikely (qtd_list->next != qtd_list->prev)) { - dbg ("only one intr qtd per urb allowed"); - status = -EINVAL; + /* get qh and force any scheduling errors */ + INIT_LIST_HEAD (&empty); + qh = qh_append_tds (ehci, urb, &empty, epnum, &dev->ep [epnum]); + if (qh == 0) { + status = -ENOMEM; goto done; } - - spin_lock_irqsave (&ehci->lock, flags); - - /* get the qh (must be empty and idle) */ - dev = (struct hcd_dev *)urb->dev->hcpriv; - qh = (struct ehci_qh *) dev->ep [epnum]; - if (qh) { - /* only allow one queued interrupt urb per EP */ - if (unlikely (qh->qh_state != QH_STATE_IDLE - || !list_empty (&qh->qtd_list))) { - dbg ("interrupt urb already queued"); - status = -EBUSY; - } else { - /* maybe reset hardware's data toggle in the qh */ - if (unlikely (!usb_gettoggle (urb->dev, epnum & 0x0f, - !(epnum & 0x10)))) { - qh->hw_token |= - __constant_cpu_to_le32 (QTD_TOGGLE); - usb_settoggle (urb->dev, epnum & 0x0f, - !(epnum & 0x10), 1); - } - /* trust the QH was set up as interrupt ... */ - list_splice (qtd_list, &qh->qtd_list); - qh_update (qh, list_entry (qtd_list->next, - struct ehci_qtd, qtd_list)); - qtd_list = &qh->qtd_list; - } - } else { - /* can't sleep here, we have ehci->lock... */ - qh = ehci_qh_make (ehci, urb, qtd_list, SLAB_ATOMIC); - if (likely (qh != 0)) { - // dbg ("new INTR qh %p", qh); - dev->ep [epnum] = qh; - qtd_list = &qh->qtd_list; - } else - status = -ENOMEM; + if (qh->qh_state == QH_STATE_IDLE) { + if ((status = qh_schedule (ehci, qh)) != 0) + goto done; } - /* Schedule this periodic QH. */ - if (likely (status == 0)) { - unsigned frame = period; - - qh->hw_next = EHCI_LIST_END; - qh->usecs = usecs; - qh->c_usecs = c_usecs; - - urb->hcpriv = qh_get (qh); - status = -ENOSPC; - - /* pick a set of schedule slots, link the QH into them */ - do { - int uframe; - u32 c_mask = 0; - - /* pick a set of slots such that all uframes have - * enough periodic bandwidth available. - */ - frame--; - for (uframe = 0; uframe < 8; uframe++) { - if (check_period (ehci, frame, uframe, - period, usecs) == 0) - continue; - - /* If this is a split transaction, check the - * bandwidth available for the completion - * too. check both best and worst case gaps: - * worst case is SPLIT near uframe end, and - * CSPLIT near start ... best is vice versa. - * Difference can be almost two uframe times. - * - * FIXME don't even bother unless we know - * this TT is idle in that uframe ... right - * now we know only one interrupt transfer - * will be scheduled per frame, so we don't - * need to update/check TT state when we - * schedule a split (QH, SITD, or FSTN). - * - * FIXME ehci 0.96 and above can use FSTNs - */ - if (!c_usecs) - break; - if (check_period (ehci, frame, - uframe + gap_uf, - period, c_usecs) == 0) - continue; - if (check_period (ehci, frame, - uframe + gap_uf + 1, - period, c_usecs) == 0) - continue; - - c_mask = 0x03 << (8 + uframe + gap_uf); - c_mask = cpu_to_le32 (c_mask); - break; - } - if (uframe == 8) - continue; - - /* QH will run once each period, starting there */ - urb->start_frame = frame; - status = 0; - - /* reset S-frame and (maybe) C-frame masks */ - qh->hw_info2 &= ~0xffff; - qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask; - // dbg_qh ("Schedule INTR qh", ehci, qh); - - /* stuff into the periodic schedule */ - qh->qh_state = QH_STATE_LINKED; - vdbg ("qh %p usecs %d period %d.0 starting %d.%d", - qh, qh->usecs, period, frame, uframe); - do { - if (unlikely (ehci->pshadow [frame].ptr != 0)) { -// FIXME -- just link toward the end, before any qh with a shorter period, -// AND handle it already being (implicitly) linked into this frame -// AS WELL AS updating the check_period() logic - BUG (); - } else { - ehci->pshadow [frame].qh = qh_get (qh); - ehci->periodic [frame] = - QH_NEXT (qh->qh_dma); - } - wmb (); - frame += period; - } while (frame < ehci->periodic_size); - - /* update bandwidth utilization records (for usbfs) */ - usb_claim_bandwidth (urb->dev, urb, - (usecs + c_usecs) / period, 0); + /* then queue the urb's tds to the qh */ + qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]); + BUG_ON (qh == 0); - /* maybe enable periodic schedule processing */ - if (!ehci->periodic_urbs++) - status = enable_periodic (ehci); - break; + /* ... update usbfs periodic stats */ + ehci->hcd.self.bandwidth_int_reqs++; - } while (frame); - } - spin_unlock_irqrestore (&ehci->lock, flags); done: + spin_unlock_irqrestore (&ehci->lock, flags); if (status) qtd_list_free (ehci, urb, qtd_list); @@ -534,10 +503,6 @@ intr_complete ( struct ehci_qh *qh, unsigned long flags /* caller owns ehci->lock ... */ ) { - struct ehci_qtd *qtd; - struct urb *urb; - int unlinking; - /* nothing to report? */ if (likely ((qh->hw_token & __constant_cpu_to_le32 (QTD_STS_ACTIVE)) != 0)) @@ -547,43 +512,14 @@ intr_complete ( return flags; } - qtd = list_entry (qh->qtd_list.next, struct ehci_qtd, qtd_list); - urb = qtd->urb; - unlinking = (urb->status == -ENOENT) || (urb->status == -ECONNRESET); - - /* call any completions, after patching for reactivation */ + /* handle any completions */ spin_unlock_irqrestore (&ehci->lock, flags); - /* NOTE: currently restricted to one qtd per qh! */ - if (qh_completions (ehci, qh, 0) == 0) - urb = 0; + qh_completions (ehci, qh); spin_lock_irqsave (&ehci->lock, flags); - /* never reactivate requests that were unlinked ... */ - if (likely (urb != 0)) { - if (unlinking - || urb->status == -ECONNRESET - || urb->status == -ENOENT - // || (urb->dev == null) - || ehci->hcd.state == USB_STATE_HALT) - urb = 0; - // FIXME look at all those unlink cases ... we always - // need exactly one completion that reports unlink. - // the one above might not have been it! - } + if (unlikely (list_empty (&qh->qtd_list))) + intr_deschedule (ehci, qh, 0); - /* normally reactivate */ - if (likely (urb != 0)) { - if (usb_pipeout (urb->pipe)) - pci_dma_sync_single (ehci->hcd.pdev, - qtd->buf_dma, - urb->transfer_buffer_length, - PCI_DMA_TODEVICE); - urb->status = -EINPROGRESS; - urb->actual_length = 0; - - /* patch qh and restart */ - qh_update (qh, qtd); - } return flags; } @@ -806,7 +742,7 @@ static int get_iso_range ( /* calculate the legal range [start,max) */ now = readl (&ehci->regs->frame_index) + 1; /* next uframe */ - if (!ehci->periodic_urbs) + if (!ehci->periodic_sched) now += 8; /* startup delay */ now %= mod; end = now + mod; @@ -926,7 +862,7 @@ itd_schedule (struct ehci_hcd *ehci, struct urb *urb) usb_claim_bandwidth (urb->dev, urb, usecs, 1); /* maybe enable periodic schedule processing */ - if (!ehci->periodic_urbs++) { + if (!ehci->periodic_sched++) { if ((status = enable_periodic (ehci)) != 0) { // FIXME deschedule right away err ("itd_schedule, enable = %d", status); @@ -1009,8 +945,8 @@ itd_complete ( spin_lock_irqsave (&ehci->lock, flags); /* defer stopping schedule; completion can submit */ - ehci->periodic_urbs--; - if (!ehci->periodic_urbs) + ehci->periodic_sched--; + if (!ehci->periodic_sched) (void) disable_periodic (ehci); return flags; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index c2cea19d2a56..7efa35064789 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -50,7 +50,7 @@ struct ehci_hcd { /* one per controller */ union ehci_shadow *pshadow; /* mirror hw periodic table */ int next_uframe; /* scan periodic, start here */ - unsigned periodic_urbs; /* how many urbs scheduled? */ + unsigned periodic_sched; /* periodic activity count */ /* deferred work from IRQ, etc */ struct tasklet_struct tasklet; @@ -72,7 +72,7 @@ struct ehci_hcd { /* one per controller */ }; /* unwrap an HCD pointer to get an EHCI_HCD pointer */ -#define hcd_to_ehci(hcd_ptr) list_entry(hcd_ptr, struct ehci_hcd, hcd) +#define hcd_to_ehci(hcd_ptr) container_of(hcd_ptr, struct ehci_hcd, hcd) /* NOTE: urb->transfer_flags expected to not use this bit !!! */ #define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */ @@ -287,12 +287,20 @@ struct ehci_qh { struct list_head qtd_list; /* sw qtd list */ atomic_t refcount; - unsigned short usecs; /* intr bandwidth */ - unsigned short c_usecs; /* ... split completion bw */ - short qh_state; + + u8 qh_state; #define QH_STATE_LINKED 1 /* HC sees this */ #define QH_STATE_UNLINK 2 /* HC may still see this */ #define QH_STATE_IDLE 3 /* HC doesn't see this */ + + /* periodic schedule info */ + u8 usecs; /* intr bandwidth */ + u8 gap_uf; /* uframes split/csplit gap */ + u8 c_usecs; /* ... split completion bw */ + unsigned short period; /* polling interval */ + unsigned short start; /* where polling starts */ +#define NO_FRAME ((unsigned short)~0) /* pick new start */ + } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 7518b8992b8f..eeb11c335f0d 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -938,7 +938,7 @@ rescan_this: /* ED's now officially unlinked, hc doesn't see */ ed->state = ED_IDLE; ed->hwINFO &= ~ED_SKIP; - ed->hwHeadP &= ~cpu_to_le32 (ED_H); + ed->hwHeadP &= ~ED_H; ed->hwNextED = 0; /* but if there's work queued, reschedule */ diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 0587dc76e342..5a2438e8953b 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * konicawc.c - konica webcam driver * * Author: Simon Evans <spse@secret.org.uk> @@ -8,7 +6,7 @@ * Copyright (C) 2002 Simon Evans * * Licence: GPL - * + * * Driver for USB webcams based on Konica chipset. This * chipset is used in Intel YC76 camera. * @@ -18,6 +16,7 @@ #include <linux/module.h> #include <linux/init.h> + #include "usbvideo.h" #define MAX_BRIGHTNESS 108 @@ -26,9 +25,11 @@ #define MAX_SHARPNESS 108 #define MAX_WHITEBAL 372 #define MAX_SPEED 6 + + #define MAX_CAMERAS 1 -#define DRIVER_VERSION "v1.1" +#define DRIVER_VERSION "v1.3" #define DRIVER_DESC "Konica Webcam driver" enum ctrl_req { @@ -41,18 +42,32 @@ enum ctrl_req { enum frame_sizes { - SIZE_160X136 = 0, - SIZE_176X144 = 1, - SIZE_320X240 = 2, + SIZE_160X120 = 0, + SIZE_160X136 = 1, + SIZE_176X144 = 2, + SIZE_320X240 = 3, + }; +#define MAX_FRAME_SIZE SIZE_320X240 static usbvideo_t *cams; +#ifdef CONFIG_USB_DEBUG +static int debug; +#define DEBUG(n, format, arg...) \ + if (n <= debug) { \ + printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ + } +#else +#define DEBUG(n, arg...) +static const int debug = 0; +#endif + + /* Some default values for inital camera settings, can be set by modprobe */ -static int debug; static enum frame_sizes size; static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */ static int brightness = MAX_BRIGHTNESS/2; @@ -61,31 +76,36 @@ static int saturation = MAX_SATURATION/2; static int sharpness = MAX_SHARPNESS/2; static int whitebal = 3*(MAX_WHITEBAL/4); -static int speed_to_interface[] = { 1, 0, 3, 2, 4, 5, 6 }; +static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; /* These FPS speeds are from the windows config box. They are * indexed on size (0-2) and speed (0-6). Divide by 3 to get the * real fps. */ -static int speed_to_fps[3][7] = { { 24, 40, 48, 60, 72, 80, 100 }, - { 18, 30, 36, 45, 54, 60, 75 }, - { 6, 10, 12, 15, 18, 20, 25 } }; - +static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, + { 24, 40, 48, 60, 72, 80, 100 }, + { 18, 30, 36, 45, 54, 60, 75 }, + { 6, 10, 12, 15, 18, 21, 25 } }; -static int camera_sizes[][2] = { { 160, 136 }, - { 176, 144 }, - { 320, 240 }, - { } /* List terminator */ +struct cam_size { + u16 width; + u16 height; + u8 cmd; }; +static struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, + { 160, 136, 0xa }, + { 176, 144, 0x4 }, + { 320, 240, 0x5 } }; + struct konicawc { u8 brightness; /* camera uses 0 - 9, x11 for real value */ u8 contrast; /* as above */ u8 saturation; /* as above */ u8 sharpness; /* as above */ u8 white_bal; /* 0 - 33, x11 for real value */ - u8 speed; /* Stored as 0 - 6, used as index in speed_to_* (above) */ + u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */ u8 size; /* Frame Size */ int height; int width; @@ -93,6 +113,10 @@ struct konicawc { u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC]; struct urb *last_data_urb; int lastframe; + int cur_frame_size; /* number of bytes in current frame size */ + int maxline; /* number of lines per frame */ + int yplanesz; /* Number of bytes in the Y plane */ + unsigned int buttonsts:1; }; @@ -110,42 +134,56 @@ static int konicawc_ctrl_msg(uvd_t *uvd, u8 dir, u8 request, u16 value, u16 inde } +static inline void konicawc_camera_on(uvd_t *uvd) +{ + DEBUG(0, "camera on"); + konicawc_set_misc(uvd, 0x2, 1, 0x0b); +} + + +static inline void konicawc_camera_off(uvd_t *uvd) +{ + DEBUG(0, "camera off"); + konicawc_set_misc(uvd, 0x2, 0, 0x0b); +} + + +static void konicawc_set_camera_size(uvd_t *uvd) +{ + struct konicawc *cam = (struct konicawc *)uvd->user_data; + + konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08); + cam->width = camera_sizes[cam->size].width; + cam->height = camera_sizes[cam->size].height; + cam->yplanesz = cam->height * cam->width; + cam->cur_frame_size = (cam->yplanesz * 3) / 2; + cam->maxline = cam->yplanesz / 256; + uvd->videosize = VIDEOSIZE(cam->width, cam->height); +} + + static int konicawc_setup_on_open(uvd_t *uvd) { struct konicawc *cam = (struct konicawc *)uvd->user_data; - konicawc_set_misc(uvd, 0x2, 0, 0x0b); - dbg("setting brightness to %d (%d)", cam->brightness, + DEBUG(1, "setting brightness to %d (%d)", cam->brightness, cam->brightness * 11); konicawc_set_value(uvd, cam->brightness, SetBrightness); - dbg("setting white balance to %d (%d)", cam->white_bal, + DEBUG(1, "setting white balance to %d (%d)", cam->white_bal, cam->white_bal * 11); konicawc_set_value(uvd, cam->white_bal, SetWhitebal); - dbg("setting contrast to %d (%d)", cam->contrast, + DEBUG(1, "setting contrast to %d (%d)", cam->contrast, cam->contrast * 11); konicawc_set_value(uvd, cam->contrast, SetContrast); - dbg("setting saturation to %d (%d)", cam->saturation, + DEBUG(1, "setting saturation to %d (%d)", cam->saturation, cam->saturation * 11); konicawc_set_value(uvd, cam->saturation, SetSaturation); - dbg("setting sharpness to %d (%d)", cam->sharpness, + DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness, cam->sharpness * 11); konicawc_set_value(uvd, cam->sharpness, SetSharpness); - dbg("setting size %d", cam->size); - switch(cam->size) { - case 0: - konicawc_set_misc(uvd, 0x2, 0xa, 0x08); - break; - - case 1: - konicawc_set_misc(uvd, 0x2, 4, 0x08); - break; - - case 2: - konicawc_set_misc(uvd, 0x2, 5, 0x08); - break; - } - konicawc_set_misc(uvd, 0x2, 1, 0x0b); - cam->lastframe = -1; + konicawc_set_camera_size(uvd); + cam->lastframe = -2; + cam->buttonsts = 0; return 0; } @@ -154,23 +192,25 @@ static void konicawc_adjust_picture(uvd_t *uvd) { struct konicawc *cam = (struct konicawc *)uvd->user_data; - dbg("new brightness: %d", uvd->vpic.brightness); + konicawc_camera_off(uvd); + DEBUG(1, "new brightness: %d", uvd->vpic.brightness); uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness; if(cam->brightness != uvd->vpic.brightness / 11) { cam->brightness = uvd->vpic.brightness / 11; - dbg("setting brightness to %d (%d)", cam->brightness, + DEBUG(1, "setting brightness to %d (%d)", cam->brightness, cam->brightness * 11); konicawc_set_value(uvd, cam->brightness, SetBrightness); } - dbg("new contrast: %d", uvd->vpic.contrast); + DEBUG(1, "new contrast: %d", uvd->vpic.contrast); uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast; if(cam->contrast != uvd->vpic.contrast / 11) { cam->contrast = uvd->vpic.contrast / 11; - dbg("setting contrast to %d (%d)", cam->contrast, + DEBUG(1, "setting contrast to %d (%d)", cam->contrast, cam->contrast * 11); konicawc_set_value(uvd, cam->contrast, SetContrast); } + konicawc_camera_on(uvd); } @@ -180,21 +220,20 @@ static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *st int i, totlen = 0; unsigned char *status = stsurb->transfer_buffer; int keep = 0, discard = 0, bad = 0; - static int buttonsts = 0; + struct konicawc *cam = (struct konicawc *)uvd->user_data; for (i = 0; i < dataurb->number_of_packets; i++) { - int button = buttonsts; + int button = cam->buttonsts; unsigned char sts; int n = dataurb->iso_frame_desc[i].actual_length; int st = dataurb->iso_frame_desc[i].status; - cdata = dataurb->transfer_buffer + + cdata = dataurb->transfer_buffer + dataurb->iso_frame_desc[i].offset; /* Detect and ignore errored packets */ if (st < 0) { - if (debug >= 1) - err("Data error: packet=%d. len=%d. status=%d.", - i, n, st); + DEBUG(1, "Data error: packet=%d. len=%d. status=%d.", + i, n, st); uvd->stats.iso_err_count++; continue; } @@ -210,8 +249,8 @@ static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *st /* sts: 0x80-0xff: frame start with frame number (ie 0-7f) * otherwise: - * bit 0 0:drop packet (padding data) - * 1 keep packet + * bit 0 0: keep packet + * 1: drop packet (padding data) * * bit 4 0 button not clicked * 1 button clicked @@ -225,10 +264,10 @@ static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *st /* work out the button status, but dont do anything with it for now */ - - if(button != buttonsts) { - dbg("button: %sclicked", button ? "" : "un"); - buttonsts = button; + + if(button != cam->buttonsts) { + DEBUG(2, "button: %sclicked", button ? "" : "un"); + cam->buttonsts = button; } if(sts == 0x01) { /* drop frame */ @@ -241,34 +280,52 @@ static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *st bad++; continue; } + if(!sts && cam->lastframe == -2) { + DEBUG(2, "dropping frame looking for image start"); + continue; + } keep++; - if(*(status+i) & 0x80) { /* frame start */ + if(sts & 0x80) { /* frame start */ unsigned char marker[] = { 0, 0xff, 0, 0x00 }; - if(debug > 1) - dbg("Adding Marker packet = %d, frame = %2.2x", - i, *(status+i)); - marker[3] = *(status+i) - 0x80; - RingQueue_Enqueue(&uvd->dp, marker, 4); + + if(cam->lastframe == -2) { + DEBUG(2, "found initial image"); + cam->lastframe = -1; + } + + marker[3] = sts & 0x7F; + RingQueue_Enqueue(&uvd->dp, marker, 4); totlen += 4; } + totlen += n; /* Little local accounting */ - if(debug > 5) - dbg("Adding packet %d, bytes = %d", i, n); RingQueue_Enqueue(&uvd->dp, cdata, n); - } - if(debug > 8) { - dbg("finished: keep = %d discard = %d bad = %d added %d bytes", + DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes", keep, discard, bad, totlen); - } return totlen; } +static void resubmit_urb(uvd_t *uvd, struct urb *urb) +{ + int i, ret; + for (i = 0; i < FRAMES_PER_DESC; i++) { + urb->iso_frame_desc[i].status = 0; + } + urb->dev = uvd->dev; + urb->status = 0; + ret = usb_submit_urb(urb, GFP_KERNEL); + DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length); + if(ret) + err("usb_submit_urb error (%d)", ret); + +} + + static void konicawc_isoc_irq(struct urb *urb) { - int i, ret, len = 0; uvd_t *uvd = urb->context; struct konicawc *cam = (struct konicawc *)uvd->user_data; @@ -277,42 +334,35 @@ static void konicawc_isoc_irq(struct urb *urb) return; if (!uvd->streaming) { - if (debug >= 1) - info("Not streaming, but interrupt!"); + DEBUG(1, "Not streaming, but interrupt!"); return; } - if (urb->actual_length > 32) { - cam->last_data_urb = urb; - goto urb_done_with; - } + DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length); uvd->stats.urb_count++; - if (urb->actual_length <= 0) - goto urb_done_with; + if (urb->transfer_buffer_length > 32) { + cam->last_data_urb = urb; + return; + } /* Copy the data received into ring queue */ if(cam->last_data_urb) { - len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); - for (i = 0; i < FRAMES_PER_DESC; i++) { - cam->last_data_urb->iso_frame_desc[i].status = 0; - } + int len = 0; + if(urb->start_frame != cam->last_data_urb->start_frame) + err("Lost sync on frames"); + else if (!urb->status && !cam->last_data_urb->status) + len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); + + resubmit_urb(uvd, urb); + resubmit_urb(uvd, cam->last_data_urb); cam->last_data_urb = NULL; + uvd->stats.urb_length = len; + uvd->stats.data_count += len; + if(len) + RingQueue_WakeUpInterruptible(&uvd->dp); + return; } - uvd->stats.urb_length = len; - uvd->stats.data_count += len; - if(len) - RingQueue_WakeUpInterruptible(&uvd->dp); - -urb_done_with: - for (i = 0; i < FRAMES_PER_DESC; i++) { - urb->iso_frame_desc[i].status = 0; - } - urb->dev = uvd->dev; - urb->status = 0; - ret = usb_submit_urb(urb, GFP_KERNEL); - if(ret) - err("usb_submit_urb error (%d)", ret); return; } @@ -322,13 +372,18 @@ static int konicawc_start_data(uvd_t *uvd) struct usb_device *dev = uvd->dev; int i, errFlag; struct konicawc *cam = (struct konicawc *)uvd->user_data; + int pktsz; + struct usb_interface_descriptor *interface; + interface = &dev->actconfig->interface[uvd->iface].altsetting[spd_to_iface[cam->speed]]; + pktsz = interface->endpoint[1].wMaxPacketSize; + DEBUG(1, "pktsz = %d", pktsz); if (!CAMERA_IS_OPERATIONAL(uvd)) { err("Camera is not operational"); return -EFAULT; } uvd->curframe = -1; - + konicawc_camera_on(uvd); /* Alternate interface 1 is is the biggest frame size */ i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); if (i < 0) { @@ -349,10 +404,10 @@ static int konicawc_start_data(uvd_t *uvd) urb->transfer_buffer = uvd->sbuf[i].data; urb->complete = konicawc_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; - urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC; - for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) { + urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; + for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = uvd->iso_packet_len; + urb->iso_frame_desc[j].length = pktsz; } urb = cam->sts_urb[i]; @@ -375,18 +430,17 @@ static int konicawc_start_data(uvd_t *uvd) /* Submit all URBs */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { - errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); - if (errFlag) - err ("usb_submit_isoc(%d) ret %d", i, errFlag); - errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL); if (errFlag) err("usb_submit_isoc(%d) ret %d", i, errFlag); + + errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); + if (errFlag) + err ("usb_submit_isoc(%d) ret %d", i, errFlag); } uvd->streaming = 1; - if (debug > 1) - dbg("streaming=1 video_endp=$%02x", uvd->video_endp); + DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp); return 0; } @@ -399,6 +453,8 @@ static void konicawc_stop_data(uvd_t *uvd) if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) return; + konicawc_camera_off(uvd); + uvd->streaming = 0; cam = (struct konicawc *)uvd->user_data; cam->last_data_urb = NULL; @@ -413,8 +469,6 @@ static void konicawc_stop_data(uvd_t *uvd) err("usb_unlink_urb() error %d.", j); } - uvd->streaming = 0; - if (!uvd->remove_pending) { /* Set packet size to 0 */ j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); @@ -428,42 +482,33 @@ static void konicawc_stop_data(uvd_t *uvd) static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame) { - int n; - int maxline, yplanesz; struct konicawc *cam = (struct konicawc *)uvd->user_data; - assert(uvd != NULL); + int maxline = cam->maxline; + int yplanesz = cam->yplanesz; + assert(frame != NULL); - maxline = (cam->height * cam->width * 3) / (2 * 384); - yplanesz = cam->height * cam->width; - if(debug > 5) - dbg("maxline = %d yplanesz = %d", maxline, yplanesz); - - if(debug > 3) - dbg("Frame state = %d", frame->scanstate); + DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz); + DEBUG(3, "Frame state = %d", frame->scanstate); if(frame->scanstate == ScanState_Scanning) { int drop = 0; int curframe; int fdrops = 0; - if(debug > 3) - dbg("Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp)); + DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp)); while(RingQueue_GetLength(&uvd->dp) >= 4) { if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) && (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) && (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) { curframe = RING_QUEUE_PEEK(&uvd->dp, 3); - if(cam->lastframe != -1) { - if(curframe < cam->lastframe) { - fdrops = (curframe + 0x80) - cam->lastframe; - } else { - fdrops = curframe - cam->lastframe; - } + if(cam->lastframe >= 0) { + fdrops = (0x80 + curframe - cam->lastframe) & 0x7F; fdrops--; - if(fdrops) + if(fdrops) { info("Dropped %d frames (%d -> %d)", fdrops, cam->lastframe, curframe); + } } cam->lastframe = curframe; frame->curline = 0; @@ -474,18 +519,20 @@ static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame) RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); drop++; } + if(drop) + DEBUG(2, "dropped %d bytes looking for new frame", drop); } if(frame->scanstate == ScanState_Scanning) return; - /* Try to move data from queue into frame buffer + /* Try to move data from queue into frame buffer * We get data in blocks of 384 bytes made up of: * 256 Y, 64 U, 64 V. * This needs to be written out as a Y plane, a U plane and a V plane. */ - while ( frame->curline < maxline && (n = RingQueue_GetLength(&uvd->dp)) >= 384) { + while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) { /* Y */ RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256); /* U */ @@ -497,8 +544,7 @@ static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame) } /* See if we filled the frame */ if (frame->curline == maxline) { - if(debug > 5) - dbg("got whole frame"); + DEBUG(5, "got whole frame"); frame->frameState = FrameState_Done_Hold; frame->curline = 0; @@ -510,10 +556,8 @@ static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame) static int konicawc_calculate_fps(uvd_t *uvd) { - struct konicawc *t = uvd->user_data; - dbg("fps = %d", speed_to_fps[t->size][t->speed]/3); - - return speed_to_fps[t->size][t->speed]/3; + struct konicawc *cam = uvd->user_data; + return spd_to_fps[cam->size][cam->speed]/3; } @@ -550,10 +594,10 @@ static void konicawc_configure_video(uvd_t *uvd) uvd->vcap.type = VID_TYPE_CAPTURE; uvd->vcap.channels = 1; uvd->vcap.audios = 0; - uvd->vcap.minwidth = camera_sizes[cam->size][0]; - uvd->vcap.minheight = camera_sizes[cam->size][1]; - uvd->vcap.maxwidth = camera_sizes[cam->size][0]; - uvd->vcap.maxheight = camera_sizes[cam->size][1]; + uvd->vcap.minwidth = camera_sizes[cam->size].width; + uvd->vcap.minheight = camera_sizes[cam->size].height; + uvd->vcap.maxwidth = camera_sizes[cam->size].width; + uvd->vcap.maxheight = camera_sizes[cam->size].height; memset(&uvd->vchan, 0, sizeof(uvd->vchan)); uvd->vchan.flags = 0 ; @@ -563,15 +607,14 @@ static void konicawc_configure_video(uvd_t *uvd) strcpy(uvd->vchan.name, "Camera"); /* Talk to device */ - dbg("device init"); + DEBUG(1, "device init"); if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) - dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]); + DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) - dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]); + DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); if(konicawc_set_misc(uvd, 0x2, 0, 0xd)) - dbg("2,0,d failed"); - dbg("setting initial values"); - + DEBUG(2, "2,0,d failed"); + DEBUG(1, "setting initial values"); } @@ -582,8 +625,7 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st int actInterface=-1, inactInterface=-1, maxPS=0; unsigned char video_ep = 0; - if (debug >= 1) - dbg("konicawc_probe(%p,%u.)", dev, ifnum); + DEBUG(1, "konicawc_probe(%p,%u.)", dev, ifnum); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) @@ -594,10 +636,8 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st /* Validate found interface: must have one ISO endpoint */ nas = dev->actconfig->interface[ifnum].num_altsetting; - if (debug > 0) - info("Number of alternate settings=%d.", nas); - if (nas < 8) { - err("Too few alternate settings for this camera!"); + if (nas != 8) { + err("Incorrect number of alternate settings (%d) for this camera!", nas); return NULL; } /* Validate all alternate settings */ @@ -612,7 +652,7 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st return NULL; } endpoint = &interface->endpoint[1]; - dbg("found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", + DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", endpoint->bEndpointAddress, endpoint->wMaxPacketSize); if (video_ep == 0) video_ep = endpoint->bEndpointAddress; @@ -636,22 +676,20 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st return NULL; } } else { - if (i == speed_to_interface[speed]) { + if (i == spd_to_iface[speed]) { /* This one is the requested one */ actInterface = i; - maxPS = endpoint->wMaxPacketSize; - if (debug > 0) { - info("Selecting requested active setting=%d. maxPS=%d.", - i, maxPS); - } } } + if(endpoint->wMaxPacketSize > maxPS) + maxPS = endpoint->wMaxPacketSize; } if(actInterface == -1) { err("Cant find required endpoint"); return NULL; } + DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS); /* Code below may sleep, need to lock module while we are here */ MOD_INC_USE_COUNT; @@ -670,26 +708,10 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st } } cam->speed = speed; - switch(size) { - case SIZE_160X136: - default: - cam->height = 136; - cam->width = 160; - cam->size = SIZE_160X136; - break; - - case SIZE_176X144: - cam->height = 144; - cam->width = 176; - cam->size = SIZE_176X144; - break; - - case SIZE_320X240: - cam->height = 240; - cam->width = 320; - cam->size = SIZE_320X240; - break; - } + RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240); + cam->width = camera_sizes[size].width; + cam->height = camera_sizes[size].height; + cam->size = size; uvd->flags = 0; uvd->debug = debug; @@ -773,9 +795,9 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_PARM(speed, "i"); -MODULE_PARM_DESC(speed, "FPS speed: 0 (slowest) - 6 (fastest)"); +MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)"); MODULE_PARM(size, "i"); -MODULE_PARM_DESC(size, "Frame Size 0: 160x136 1: 176x144 2: 320x240"); +MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240"); MODULE_PARM(brightness, "i"); MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108"); MODULE_PARM(contrast, "i"); @@ -786,7 +808,11 @@ MODULE_PARM(sharpness, "i"); MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108"); MODULE_PARM(whitebal, "i"); MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363"); + +#ifdef CONFIG_USB_DEBUG MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); +#endif + module_init(konicawc_init); module_exit(konicawc_cleanup); diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c index bd9b38810f3c..499908292ffa 100644 --- a/drivers/usb/misc/tiglusb.c +++ b/drivers/usb/misc/tiglusb.c @@ -41,10 +41,6 @@ #include <linux/ticable.h> #include "tiglusb.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -# define minor(x) MINOR(x) -#endif - /* * Version Information */ diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c index 236a0d80cf22..52c4f8283822 100644 --- a/drivers/usb/net/cdc-ether.c +++ b/drivers/usb/net/cdc-ether.c @@ -1,4 +1,4 @@ -// Portions of this file taken from +// Portions of this file taken from // Petko Manolov - Petkan (petkan@dce.bg) // from his driver pegasus.c @@ -1170,23 +1170,20 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, if (rc) { // Nope we couldn't find one we liked. // This device was not meant for us to control. - kfree( ether_dev ); - return NULL; + goto error_all; } - // Now that we FOUND a configuration. let's try to make the + // Now that we FOUND a configuration. let's try to make the // device go into it. if ( usb_set_configuration( usb, ether_dev->bConfigurationValue ) ) { err("usb_set_configuration() failed"); - kfree( ether_dev ); - return NULL; + goto error_all; } // Now set the communication interface up as required. if (usb_set_interface(usb, ether_dev->comm_bInterfaceNumber, ether_dev->comm_bAlternateSetting)) { err("usb_set_interface() failed"); - kfree( ether_dev ); - return NULL; + goto error_all; } // Only turn traffic on right now if we must... @@ -1194,23 +1191,21 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // We found an alternate setting for the data // interface that allows us to turn off traffic. // We should use it. - if (usb_set_interface( usb, - ether_dev->data_bInterfaceNumber, + if (usb_set_interface( usb, + ether_dev->data_bInterfaceNumber, ether_dev->data_bAlternateSetting_without_traffic)) { err("usb_set_interface() failed"); - kfree( ether_dev ); - return NULL; + goto error_all; } } else { // We didn't find an alternate setting for the data // interface that would let us turn off traffic. // Oh well, let's go ahead and do what we must... - if (usb_set_interface( usb, - ether_dev->data_bInterfaceNumber, + if (usb_set_interface( usb, + ether_dev->data_bInterfaceNumber, ether_dev->data_bAlternateSetting_with_traffic)) { err("usb_set_interface() failed"); - kfree( ether_dev ); - return NULL; + goto error_all; } } @@ -1220,8 +1215,7 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // Hmm... The kernel is not sharing today... // Fine, we didn't want it anyway... err( "Unable to initialize ethernet device" ); - kfree( ether_dev ); - return NULL; + goto error_all; } // Now that we have an ethernet device, let's set it up @@ -1241,7 +1235,7 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // We'll keep track of this information for later... ether_dev->usb = usb; ether_dev->net = net; - + // and don't forget the MAC address. set_ethernet_addr( ether_dev ); @@ -1249,12 +1243,12 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, log_device_info( ether_dev ); // I claim this interface to be a CDC Ethernet Networking device - usb_driver_claim_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]), + usb_driver_claim_interface( &CDCEther_driver, + &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]), ether_dev ); // I claim this interface to be a CDC Ethernet Networking device - usb_driver_claim_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]), + usb_driver_claim_interface( &CDCEther_driver, + &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]), ether_dev ); // Does this REALLY do anything??? @@ -1265,6 +1259,14 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // Okay, we are finally done... return NULL; + + // bailing out with our tail between our knees +error_all: + usb_free_urb(ether_dev->tx_urb); + usb_free_urb(ether_dev->rx_urb); + usb_free_urb(ether_dev->intr_urb); + kfree( ether_dev ); + return NULL; } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 21fb4e6c1835..b223f089723e 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -147,7 +147,8 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) srb->host_scribble = (unsigned char *)us; /* enqueue the command */ - BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE || us->srb != NULL); + BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE); + BUG_ON(us->srb != NULL); srb->scsi_done = done; us->srb = srb; diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 35aad61fb843..0418d92651aa 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -203,16 +203,9 @@ extern void fill_inquiry_response(struct us_data *us, /* The scsi_lock() and scsi_unlock() macros protect the sm_state and the * single queue element srb for write access */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,3) #define scsi_unlock(host) spin_unlock_irq(host->host_lock) #define scsi_lock(host) spin_lock_irq(host->host_lock) #define sg_address(psg) (page_address((psg)->page) + (psg)->offset) -#else -#define scsi_unlock(host) spin_unlock_irq(&io_request_lock) -#define scsi_lock(host) spin_lock_irq(&io_request_lock) - -#define sg_address(psg) ((psg)->address) -#endif #endif diff --git a/drivers/video/Config.in b/drivers/video/Config.in index 128d62f9af84..b90b2bff0615 100644 --- a/drivers/video/Config.in +++ b/drivers/video/Config.in @@ -265,7 +265,7 @@ if [ "$CONFIG_FB" = "y" ]; then "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then + "$CONFIG_FB_SA1100" = "y" ]; then define_tristate CONFIG_FBCON_CFB8 y else if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ @@ -292,7 +292,7 @@ if [ "$CONFIG_FB" = "y" ]; then "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ - "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then + "$CONFIG_FB_SA1100" = "y" ]; then define_tristate CONFIG_FBCON_CFB16 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ @@ -331,7 +331,7 @@ if [ "$CONFIG_FB" = "y" ]; then "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \ - "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_ATY" = "y" ]; then + "$CONFIG_FB_SIS" = "y" ]; then define_tristate CONFIG_FBCON_CFB32 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ @@ -352,7 +352,7 @@ if [ "$CONFIG_FB" = "y" ]; then "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \ "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \ - "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ + "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_OF" = "y" -o \ "$CONFIG_FB_SGIVW" = "y" ]; then define_tristate CONFIG_FBCON_ACCEL y diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 15c9f417e2d2..585d3e654a52 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -60,7 +60,7 @@ obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbim obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o -obj-$(CONFIG_FB_OF) += offb.o +obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblit.o cfbcopyarea.o obj-$(CONFIG_FB_IMSTT) += imsttfb.o obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o obj-$(CONFIG_FB_CLGEN) += clgenfb.o @@ -89,7 +89,7 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbi obj-$(CONFIG_FB_MATROX) += matrox/ obj-$(CONFIG_FB_RIVA) += riva/ obj-$(CONFIG_FB_SIS) += sis/ -obj-$(CONFIG_FB_ATY) += aty/ +obj-$(CONFIG_FB_ATY) += aty/ cfbimgblt.o obj-$(CONFIG_FB_SUN3) += sun3fb.o obj-$(CONFIG_FB_BWTWO) += bwtwofb.o diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c index 336f501f0317..0a7ea6ec1f79 100644 --- a/drivers/video/S3triofb.c +++ b/drivers/video/S3triofb.c @@ -124,15 +124,15 @@ static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info); static struct fb_ops s3trio_ops = { - owner: THIS_MODULE, - fb_get_fix: s3trio_get_fix, - fb_get_var: s3trio_get_var, - fb_set_var: s3trio_set_var, - fb_get_cmap: s3trio_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: s3trio_setcolreg, - fb_pan_display: s3trio_pan_display, - fb_blank: s3triofb_blank, + .owner = THIS_MODULE, + .fb_get_fix = s3trio_get_fix, + .fb_get_var = s3trio_get_var, + .fb_set_var = s3trio_set_var, + .fb_get_cmap = s3trio_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = s3trio_setcolreg, + .fb_pan_display =s3trio_pan_display, + .fb_blank = s3triofb_blank, }; /* @@ -776,14 +776,14 @@ static void fbcon_trio8_revc(struct display *p, int xx, int yy) } static struct display_switch fbcon_trio8 = { - setup: fbcon_cfb8_setup, - bmove: fbcon_trio8_bmove, - clear: fbcon_trio8_clear, - putc: fbcon_trio8_putc, - putcs: fbcon_trio8_putcs, - revc: fbcon_trio8_revc, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH(8) + .setup = fbcon_cfb8_setup, + .bmove = fbcon_trio8_bmove, + .clear = fbcon_trio8_clear, + .putc = fbcon_trio8_putc, + .putcs = fbcon_trio8_putcs, + .revc = fbcon_trio8_revc, + .clear_margins = fbcon_cfb8_clear_margins, + .fontwidthmask = FONTWIDTH(8) }; #endif diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 4947a37b5334..096014df8eaa 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -1176,16 +1176,16 @@ acornfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma } static struct fb_ops acornfb_ops = { - owner: THIS_MODULE, - fb_get_fix: acornfb_get_fix, - fb_get_var: acornfb_get_var, - fb_set_var: acornfb_set_var, - fb_get_cmap: acornfb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: acornfb_setcolreg, - fb_pan_display: acornfb_pan_display, - fb_blank: acornfb_blank, - fb_mmap: acornfb_mmap, + .owner = THIS_MODULE, + .fb_get_fix = acornfb_get_fix, + .fb_get_var = acornfb_get_var, + .fb_set_var = acornfb_set_var, + .fb_get_cmap = acornfb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = acornfb_setcolreg, + .fb_pan_display =acornfb_pan_display, + .fb_blank = acornfb_blank, + .fb_mmap = acornfb_mmap, }; static int @@ -1275,19 +1275,19 @@ static struct fb_videomode modedb[] __initdata = { static struct fb_videomode __initdata acornfb_default_mode = { - name: NULL, - refresh: 60, - xres: 640, - yres: 480, - pixclock: 39722, - left_margin: 56, - right_margin: 16, - upper_margin: 34, - lower_margin: 9, - hsync_len: 88, - vsync_len: 2, - sync: 0, - vmode: FB_VMODE_NONINTERLACED + .name = NULL, + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39722, + .left_margin = 56, + .right_margin = 16, + .upper_margin = 34, + .lower_margin = 9, + .hsync_len = 88, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED }; static void __init diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index 7bbd9b26cd86..357ce2571f66 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -1164,16 +1164,16 @@ static void ami_rebuild_copper(void); static struct fb_ops amifb_ops = { - owner: THIS_MODULE, - fb_get_fix: amifb_get_fix, - fb_get_var: amifb_get_var, - fb_set_var: amifb_set_var, - fb_get_cmap: amifb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: amifb_setcolreg, - fb_pan_display: amifb_pan_display, - fb_blank: amifb_blank, - fb_ioctl: amifb_ioctl, + .owner = THIS_MODULE, + .fb_get_fix = amifb_get_fix, + .fb_get_var = amifb_get_var, + .fb_set_var = amifb_set_var, + .fb_get_cmap = amifb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = amifb_setcolreg, + .fb_pan_display = amifb_pan_display, + .fb_blank = amifb_blank, + .fb_ioctl = amifb_ioctl, }; static void __init amifb_setup_mcap(char *spec) diff --git a/drivers/video/anakinfb.c b/drivers/video/anakinfb.c index 3206f467426a..340a90c23efe 100644 --- a/drivers/video/anakinfb.c +++ b/drivers/video/anakinfb.c @@ -27,28 +27,28 @@ static struct fb_info fb_info; static struct display display; static struct fb_var_screeninfo anakinfb_var = { - xres: 400, - yres: 234, - xres_virtual: 400, - yres_virtual: 234, - bits_per_pixel: 16, - red: { 11, 5, 0 }, - green: { 5, 6, 0 }, - blue: { 0, 5, 0 }, - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - vmode: FB_VMODE_NONINTERLACED, + .xres = 400, + .yres = 234, + .xres_virtual = 400, + .yres_virtual = 234, + .bits_per_pixel =16, + .red = { 11, 5, 0 }, + .green = { 5, 6, 0 }, + .blue = { 0, 5, 0 }, + .activate FB_ACTIVATE_NOW, + .height -1, + .width -1, + .vmode FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo anakinfb_fix = { - id: "AnakinFB", - smem_start: VGA_START, - smem_len: VGA_SIZE, - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_TRUECOLOR, - line_length: 400*2, - accel: FB_ACCEL_NONE, + .id = "AnakinFB", + .smem_start = VGA_START, + .smem_len = VGA_SIZE, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 400*2, + .accel = FB_ACCEL_NONE, }; static int @@ -64,16 +64,14 @@ anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, } static struct fb_ops anakinfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: anakinfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = anakinfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; int __init diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index fb3bc329b9e1..33ea709cefa1 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c @@ -2623,15 +2623,15 @@ atafb_blank(int blank, struct fb_info *info) } static struct fb_ops atafb_ops = { - owner: THIS_MODULE, - fb_get_fix: atafb_get_fix, - fb_get_var: atafb_get_var, - fb_set_var: atafb_set_var, - fb_get_cmap: atafb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_pan_display: atafb_pan_display, - fb_blank: atafb_blank, - fb_ioctl: atafb_ioctl, + .owner = THIS_MODULE, + .fb_get_fix = atafb_get_fix, + .fb_get_var = atafb_get_var, + .fb_set_var = atafb_set_var, + .fb_get_cmap = atafb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_pan_display =atafb_pan_display, + .fb_blank = atafb_blank, + .fb_ioctl = atafb_ioctl, }; static void diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile index e8ecd51e6cc5..26b1ebf749da 100644 --- a/drivers/video/aty/Makefile +++ b/drivers/video/aty/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_FB_ATY) += atyfb.o -atyfb-y := atyfb_base.o mach64_accel.o ../cfbimgblt.o +atyfb-y := atyfb_base.o mach64_accel.o atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o mach64_cursor.o atyfb-objs := $(atyfb-y) diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index b532ed334276..8342386c4a47 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h @@ -3,7 +3,7 @@ */ #include <linux/config.h> - +#include <video/fbcon.h> /* * Elements of the hardware specific atyfb_par structure @@ -12,9 +12,6 @@ struct crtc { u32 vxres; u32 vyres; - u32 xoffset; - u32 yoffset; - u32 bpp; u32 h_tot_disp; u32 h_sync_strt_wid; u32 v_tot_disp; @@ -94,7 +91,6 @@ struct atyfb_par { u8 ram_type; u8 mem_refresh_rate; u8 blitter_may_be_busy; - u32 accel_flags; #ifdef __sparc__ struct pci_mmap_map *mmap_map; int consolecnt; @@ -103,6 +99,7 @@ struct atyfb_par { int open; #endif #ifdef CONFIG_PMAC_PBOOK + struct fb_info *next; unsigned char *save_framebuffer; unsigned long save_pll[64]; #endif @@ -161,7 +158,7 @@ static inline void aty_st_le32(int regindex, u32 val, regindex -= 0x800; #ifdef CONFIG_ATARI - out_le32((volatile u32 *)(par->ati_regbase + regindex)); + out_le32((volatile u32 *)(par->ati_regbase + regindex), val); #else writel(val, par->ati_regbase + regindex); #endif @@ -280,13 +277,4 @@ static inline void wait_for_idle(struct atyfb_par *par) extern void aty_reset_engine(const struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); -extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); - - /* - * Text console acceleration - */ -extern const struct display_switch fbcon_aty8; -extern const struct display_switch fbcon_aty16; -extern const struct display_switch fbcon_aty24; -extern const struct display_switch fbcon_aty32; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index d1c0dc789247..d7e50db324ec 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -66,10 +66,7 @@ #include <asm/uaccess.h> #include <video/fbcon.h> -#include <video/fbcon-cfb8.h> -#include <video/fbcon-cfb16.h> -#include <video/fbcon-cfb24.h> -#include <video/fbcon-cfb32.h> +#include "../fbcon-accel.h" #include <video/mach64.h> #include "atyfb.h" @@ -134,11 +131,11 @@ struct pci_mmap_map { }; static struct fb_fix_screeninfo atyfb_fix __initdata = { - id: "ATY Mach64", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - xpanstep: 8, - ypanstep: 1, + .id = "ATY Mach64", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .xpanstep = 8, + .ypanstep = 1, }; /* @@ -147,12 +144,9 @@ static struct fb_fix_screeninfo atyfb_fix __initdata = { static int atyfb_open(struct fb_info *info, int user); static int atyfb_release(struct fb_info *info, int user); -static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info); -static int atyfb_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); -static int atyfb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); +static int atyfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info); +static int atyfb_set_par(struct fb_info *info); static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info); static int atyfb_pan_display(struct fb_var_screeninfo *var, int con, @@ -160,19 +154,15 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, int con, static int atyfb_blank(int blank, struct fb_info *info); static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, int con, struct fb_info *info); +extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); +extern void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area); +extern void atyfb_imageblit(struct fb_info *info, struct fb_image *image); #ifdef __sparc__ static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma); #endif static int atyfb_rasterimg(struct fb_info *info, int start); - - /* - * Interface to the low level console driver - */ - -static int atyfbcon_updatevar(int con, struct fb_info *info); - /* * Internal routines */ @@ -189,24 +179,13 @@ static int aty_var_to_crtc(const struct fb_info *info, struct crtc *crtc); static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var); - -static void atyfb_set_par(struct atyfb_par *par, - struct fb_info *info); -static int atyfb_decode_var(const struct fb_var_screeninfo *var, - struct atyfb_par *par, - const struct fb_info *info); static int atyfb_encode_var(struct fb_var_screeninfo *var, const struct atyfb_par *par, const struct fb_info *info); static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); -static int encode_fix(struct fb_fix_screeninfo *fix, - const struct atyfb_par *par, - const struct fb_info *info); -static void atyfb_set_dispsw(struct display *disp, - struct fb_info *info); #ifdef CONFIG_PPC -static int read_aty_sense(const struct fb_info *info); +static int read_aty_sense(const struct atyfb_par *par); #endif @@ -219,26 +198,34 @@ int atyfb_init(void); int atyfb_setup(char *); #endif +int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) +{ + *var = info->var; + return 0; +} + static struct fb_ops atyfb_ops = { - owner:THIS_MODULE, - fb_open:atyfb_open, - fb_release:atyfb_release, - fb_get_fix:atyfb_get_fix, - fb_get_var:atyfb_get_var, - fb_set_var:atyfb_set_var, - fb_get_cmap:gen_get_cmap, - fb_set_cmap:gen_set_cmap, - fb_setcolreg:atyfb_setcolreg, - fb_pan_display:atyfb_pan_display, - fb_blank:atyfb_blank, - fb_ioctl:atyfb_ioctl, + .owner = THIS_MODULE, + .fb_open = atyfb_open, + .fb_release = atyfb_release, + .fb_set_var = gen_set_var, + .fb_check_var = atyfb_check_var, + .fb_set_par = atyfb_set_par, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = atyfb_setcolreg, + .fb_pan_display = atyfb_pan_display, + .fb_blank = atyfb_blank, + .fb_ioctl = atyfb_ioctl, + .fb_fillrect = atyfb_fillrect, + .fb_copyarea = atyfb_copyarea, + .fb_imageblit = atyfb_imageblit, #ifdef __sparc__ - fb_mmap:atyfb_mmap, + .fb_mmap = atyfb_mmap, #endif - fb_rasterimg:atyfb_rasterimg, + .fb_rasterimg = atyfb_rasterimg, }; -static char atyfb_name[16] = "ATY Mach64"; static char fontname[40] __initdata = { 0 }; static char curblink __initdata = 1; static char noaccel __initdata = 0; @@ -462,63 +449,62 @@ static char *aty_ct_ram[8] __initdata = { * Apple monitor sense */ -static int __init read_aty_sense(const struct fb_info *info) +static int __init read_aty_sense(const struct atyfb_par *par) { int sense, i; - aty_st_le32(GP_IO, 0x31003100, info); /* drive outputs high */ + aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */ __delay(200); - aty_st_le32(GP_IO, 0, info); /* turn off outputs */ + aty_st_le32(GP_IO, 0, par); /* turn off outputs */ __delay(2000); - i = aty_ld_le32(GP_IO, info); /* get primary sense value */ + i = aty_ld_le32(GP_IO, par); /* get primary sense value */ sense = ((i & 0x3000) >> 3) | (i & 0x100); /* drive each sense line low in turn and collect the other 2 */ - aty_st_le32(GP_IO, 0x20000000, info); /* drive A low */ + aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */ __delay(2000); - i = aty_ld_le32(GP_IO, info); + i = aty_ld_le32(GP_IO, par); sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4); - aty_st_le32(GP_IO, 0x20002000, info); /* drive A high again */ + aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */ __delay(200); - aty_st_le32(GP_IO, 0x10000000, info); /* drive B low */ + aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */ __delay(2000); - i = aty_ld_le32(GP_IO, info); + i = aty_ld_le32(GP_IO, par); sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6); - aty_st_le32(GP_IO, 0x10001000, info); /* drive B high again */ + aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */ __delay(200); - aty_st_le32(GP_IO, 0x01000000, info); /* drive C low */ + aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */ __delay(2000); - sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12; - aty_st_le32(GP_IO, 0, info); /* turn off outputs */ - + sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12; + aty_st_le32(GP_IO, 0, par); /* turn off outputs */ return sense; } #endif /* defined(CONFIG_PPC) */ #if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT) -static void aty_st_lcd(int index, u32 val, const struct fb_info *info) +static void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) { unsigned long temp; /* write addr byte */ - temp = aty_ld_le32(LCD_INDEX, info); - aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info); + temp = aty_ld_le32(LCD_INDEX, par); + aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par); /* write the register value */ - aty_st_le32(LCD_DATA, val, info); + aty_st_le32(LCD_DATA, val, par); } -static u32 aty_ld_lcd(int index, const struct fb_info *info) +static u32 aty_ld_lcd(int index, const struct atyfb_par *par) { unsigned long temp; /* write addr byte */ - temp = aty_ld_le32(LCD_INDEX, info); - aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info); + temp = aty_ld_le32(LCD_INDEX, par); + aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par); /* read the register value */ - return aty_ld_le32(LCD_DATA, info); + return aty_ld_le32(LCD_DATA, par); } #endif /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */ @@ -646,9 +632,6 @@ static int aty_var_to_crtc(const struct fb_info *info, /* output */ crtc->vxres = vxres; crtc->vyres = vyres; - crtc->xoffset = xoffset; - crtc->yoffset = yoffset; - crtc->bpp = bpp; crtc->h_tot_disp = h_total | (h_disp << 16); crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) | ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) | @@ -792,8 +775,6 @@ static int aty_crtc_to_var(const struct crtc *crtc, var->xres_virtual = crtc->vxres; var->yres_virtual = crtc->vyres; var->bits_per_pixel = bpp; - var->xoffset = crtc->xoffset; - var->yoffset = crtc->yoffset; var->left_margin = left; var->right_margin = right; var->upper_margin = upper; @@ -808,14 +789,14 @@ static int aty_crtc_to_var(const struct crtc *crtc, /* ------------------------------------------------------------------------- */ -static void atyfb_set_par(struct atyfb_par *par, - struct fb_info *info) +static int atyfb_set_par(struct fb_info *info) { - u32 i; + struct atyfb_par *par = (struct atyfb_par *) info->par; int accelmode; u8 tmp; + u32 i; - accelmode = par->accel_flags; /* hack */ + accelmode = info->var.accel_flags; /* hack */ if (par->blitter_may_be_busy) wait_for_idle(par); @@ -825,13 +806,13 @@ static void atyfb_set_par(struct atyfb_par *par, /* better call aty_StrobeClock ?? */ aty_st_8(CLOCK_CNTL + par->clk_wr_offset, CLOCK_STROBE, par); - par->dac_ops->set_dac(info, &par->pll, par->crtc.bpp, accelmode); + par->dac_ops->set_dac(info, &par->pll, info->var.bits_per_pixel, accelmode); par->pll_ops->set_pll(info, &par->pll); if (!M64_HAS(INTEGRATED)) { /* Don't forget MEM_CNTL */ i = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff; - switch (par->crtc.bpp) { + switch (info->var.bits_per_pixel) { case 8: i |= 0x02000000; break; @@ -847,7 +828,7 @@ static void atyfb_set_par(struct atyfb_par *par, i = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff; if (!M64_HAS(MAGIC_POSTDIV)) i |= par->mem_refresh_rate << 20; - switch (par->crtc.bpp) { + switch (info->var.bits_per_pixel) { case 8: case 24: i |= 0x00000000; @@ -880,8 +861,11 @@ static void atyfb_set_par(struct atyfb_par *par, } aty_st_8(DAC_MASK, 0xff, par); + info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel/8; + info->fix.visual = info->var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; + /* Initialize the graphics engine */ - if (par->accel_flags & FB_ACCELF_TEXT) + if (info->var.accel_flags & FB_ACCELF_TEXT) aty_init_engine(par, info); #ifdef CONFIG_BOOTX_TEXT @@ -889,33 +873,29 @@ static void atyfb_set_par(struct atyfb_par *par, (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8, ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1, - par->crtc.bpp, - par->crtc.vxres * par->crtc.bpp / 8); + info->var.bits_per_pixel, + par->crtc.vxres * info->var.bits_per_pixel / 8); #endif /* CONFIG_BOOTX_TEXT */ + return 0; } -static int atyfb_decode_var(const struct fb_var_screeninfo *var, - struct atyfb_par *par, - const struct fb_info *info) +static int atyfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { + struct atyfb_par *par = (struct atyfb_par *) info->par; int err; if ((err = aty_var_to_crtc(info, var, &par->crtc)) || (err = - par->pll_ops->var_to_pll(info, var->pixclock, par->crtc.bpp, + par->pll_ops->var_to_pll(info, var->pixclock, var->bits_per_pixel, &par->pll))) return err; - if (var->accel_flags & FB_ACCELF_TEXT) - par->accel_flags = FB_ACCELF_TEXT; - else - par->accel_flags = 0; - #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */ if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info)) return -EINVAL; #endif - + atyfb_encode_var(var, par, info); return 0; } @@ -933,8 +913,6 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var, var->height = -1; var->width = -1; - var->accel_flags = par->accel_flags; - return 0; } @@ -943,10 +921,10 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var, static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) { - u32 xoffset = par->crtc.xoffset; - u32 yoffset = par->crtc.yoffset; + u32 xoffset = info->var.xoffset; + u32 yoffset = info->var.yoffset; u32 vxres = par->crtc.vxres; - u32 bpp = par->crtc.bpp; + u32 bpp = info->var.bits_per_pixel; par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); @@ -1024,7 +1002,7 @@ static int atyfb_release(struct fb_info *info, int user) var.yres_virtual = var.yres; } - atyfb_set_var(&var, -1, info); + gen_set_var(&var, -1, info); } } } else { @@ -1034,167 +1012,6 @@ static int atyfb_release(struct fb_info *info, int user) return (0); } - -static int encode_fix(struct fb_fix_screeninfo *fix, - const struct atyfb_par *par, - const struct fb_info *info) -{ - memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - - strcpy(fix->id, atyfb_name); - fix->smem_start = info->fix.smem_start; - fix->smem_len = info->fix.smem_len; - fix->mmio_start = info->fix.mmio_start; - fix->mmio_len = info->fix.mmio_len; - fix->accel = info->fix.accel; - fix->type = info->fix.type; - fix->type_aux = info->fix.type_aux; - fix->line_length = par->crtc.vxres * par->crtc.bpp / 8; - fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR - : FB_VISUAL_DIRECTCOLOR; - fix->ywrapstep = info->fix.ywrapstep; - fix->xpanstep = info->fix.xpanstep; - fix->ypanstep = info->fix.ypanstep; - return 0; -} - - /* - * Get the Fixed Part of the Display - */ - -static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info) -{ - struct atyfb_par *par = (struct atyfb_par *) info->par; - - atyfb_decode_var(&fb_display[con].var, par, info); - encode_fix(fix, par, info); - return 0; -} - - - /* - * Get the User Defined Part of the Display - */ - -static int atyfb_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - struct atyfb_par *par = (struct atyfb_par *) info->par; - - if (con == -1) - atyfb_encode_var(var, par, info); - else - *var = fb_display[con].var; - return 0; -} - - -static void atyfb_set_dispsw(struct display *disp, - struct fb_info *info) -{ - switch (info->var.bits_per_pixel) { - case 8: - disp->dispsw = &fbcon_aty8; - break; - case 16: - disp->dispsw = &fbcon_aty16; - disp->dispsw_data = info->pseudo_palette; - break; - case 24: - disp->dispsw = &fbcon_aty24; - disp->dispsw_data = info->pseudo_palette; - break; - case 32: - disp->dispsw = &fbcon_aty32; - disp->dispsw_data = info->pseudo_palette; - break; - default: - disp->dispsw = &fbcon_dummy; - } -#ifdef CONFIG_FB_ATY_CT -/* - if (info->cursor) { - &disp->dispsw.cursor = atyfb_cursor; - &disp->dispsw.set_font = atyfb_set_font; - } -*/ -#endif /* CONFIG_FB_ATY_CT */ -} - - - /* - * Set the User Defined Part of the Display - */ - -static int atyfb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - struct atyfb_par *par = (struct atyfb_par *) info->par; - struct display *display; - int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, - err; - int activate = var->activate; - - if (con >= 0) - display = &fb_display[con]; - else - display = info->disp; /* used during initialization */ - - if ((err = atyfb_decode_var(var, par, info))) - return err; - - atyfb_encode_var(var, par, info); - - if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - oldxres = display->var.xres; - oldyres = display->var.yres; - oldvxres = display->var.xres_virtual; - oldvyres = display->var.yres_virtual; - oldbpp = display->var.bits_per_pixel; - oldaccel = display->var.accel_flags; - display->var = *var; - accel = var->accel_flags & FB_ACCELF_TEXT; - if (oldxres != var->xres || oldyres != var->yres || - oldvxres != var->xres_virtual - || oldvyres != var->yres_virtual - || oldbpp != var->bits_per_pixel - || oldaccel != var->accel_flags) { - struct fb_fix_screeninfo fix; - - encode_fix(&fix, par, info); - display->visual = fix.visual; - display->type = fix.type; - display->type_aux = fix.type_aux; - display->ypanstep = fix.ypanstep; - display->ywrapstep = fix.ywrapstep; - display->line_length = fix.line_length; - display->can_soft_blank = 1; - display->inverse = 0; - if (accel) - display->scrollmode = - (par->bus_type == - PCI) ? SCROLL_YNOMOVE : 0; - else - display->scrollmode = SCROLL_YREDRAW; - if (info->changevar) - (*info->changevar) (con); - } - if (!info->display_fg || - info->display_fg->vc_num == con) { - atyfb_set_par(par, info); - atyfb_set_dispsw(display, info); - } - if (oldbpp != var->bits_per_pixel) { - if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) - return err; - do_install_cmap(con, info); - } - } - return 0; -} - - /* * Pan or Wrap the Display * @@ -1214,8 +1031,8 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, int con, if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres) return -EINVAL; - par->crtc.xoffset = xoffset; - par->crtc.yoffset = yoffset; + info->var.xoffset = xoffset; + info->var.yoffset = yoffset; set_off_pitch(par, info); return 0; } @@ -1250,12 +1067,6 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, #endif /* __sparc__ || DEBUG */ #ifdef __sparc__ struct fbtype fbtyp; - struct display *disp; - - if (con >= 0) - disp = &fb_display[con]; - else - disp = info2->disp; #endif switch (cmd) { @@ -1264,8 +1075,8 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, fbtyp.fb_type = FBTYPE_PCI_GENERIC; fbtyp.fb_width = par->crtc.vxres; fbtyp.fb_height = par->crtc.vyres; - fbtyp.fb_depth = par->crtc.bpp; - fbtyp.fb_cmsize = disp->cmap.len; + fbtyp.fb_depth = info->var.bits_per_pixel; + fbtyp.fb_cmsize = info->cmap.len; fbtyp.fb_size = info->fix.smem_len; if (copy_to_user ((struct fbtype *) arg, &fbtyp, sizeof(fbtyp))) @@ -1439,16 +1250,16 @@ static struct { u8 b[2][256]; } atyfb_save; -static void atyfb_save_palette(struct fb_info *info, int enter) +static void atyfb_save_palette(struct atyfb_par *par, int enter) { int i, tmp; for (i = 0; i < 256; i++) { - tmp = aty_ld_8(DAC_CNTL, info) & 0xfc; + tmp = aty_ld_8(DAC_CNTL, par) & 0xfc; if (M64_HAS(EXTRA_BRIGHT)) tmp |= 0x2; - aty_st_8(DAC_CNTL, tmp, info); - aty_st_8(DAC_MASK, 0xff, info); + aty_st_8(DAC_CNTL, tmp, par); + aty_st_8(DAC_MASK, 0xff, par); writeb(i, &par->aty_cmap_regs->rindex); atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut); @@ -1477,15 +1288,16 @@ static void atyfb_palette(int enter) d->fb_info->fbops == &atyfb_ops && d->fb_info->display_fg && d->fb_info->display_fg->vc_num == i) { - atyfb_save_palette(d->fb_info, enter); info = d->fb_info; par = (struct atyfb_par *) info->par; + + atyfb_save_palette(par, enter); if (enter) { - atyfb_save.yoffset = par->crtc.yoffset; - par->crtc.yoffset = 0; + atyfb_save.yoffset = info->var.yoffset; + info->var.yoffset = 0; set_off_pitch(par, info); } else { - par->crtc.yoffset = atyfb_save.yoffset; + info->var.yoffset = atyfb_save.yoffset; set_off_pitch(par, info); } break; @@ -1506,32 +1318,32 @@ static struct fb_info *first_display = NULL; * management registers. There's is some confusion about which * chipID is a Rage LT or LT pro :( */ -static int aty_power_mgmt_LT(int sleep, struct fb_info *info) +static int aty_power_mgmt_LT(int sleep, struct atyfb_par *par) { unsigned int pm; int timeout; - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); timeout = 200000; if (sleep) { /* Sleep */ pm &= ~PWR_MGT_ON; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); pm &= ~(PWR_BLON | AUTO_PWR_UP); pm |= SUSPEND_NOW; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); pm |= PWR_MGT_ON; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); do { - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); if ((--timeout) == 0) break; @@ -1540,18 +1352,18 @@ static int aty_power_mgmt_LT(int sleep, struct fb_info *info) } else { /* Wakeup */ pm &= ~PWR_MGT_ON; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); pm |= (PWR_BLON | AUTO_PWR_UP); pm &= ~SUSPEND_NOW; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); pm |= PWR_MGT_ON; - aty_st_le32(POWER_MANAGEMENT_LG, pm, info); + aty_st_le32(POWER_MANAGEMENT_LG, pm, par); do { - pm = aty_ld_le32(POWER_MANAGEMENT_LG, info); + pm = aty_ld_le32(POWER_MANAGEMENT_LG, par); udelay(10); if ((--timeout) == 0) break; @@ -1562,32 +1374,32 @@ static int aty_power_mgmt_LT(int sleep, struct fb_info *info) return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE; } -static int aty_power_mgmt_LTPro(int sleep, struct fb_info *info) +static int aty_power_mgmt_LTPro(int sleep, struct atyfb_par *par) { unsigned int pm; int timeout; - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG; - aty_st_lcd(POWER_MANAGEMENT, pm, info); - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); timeout = 200; if (sleep) { /* Sleep */ pm &= ~PWR_MGT_ON; - aty_st_lcd(POWER_MANAGEMENT, pm, info); - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); udelay(10); pm &= ~(PWR_BLON | AUTO_PWR_UP); pm |= SUSPEND_NOW; - aty_st_lcd(POWER_MANAGEMENT, pm, info); - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); udelay(10); pm |= PWR_MGT_ON; - aty_st_lcd(POWER_MANAGEMENT, pm, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); do { - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); mdelay(1); if ((--timeout) == 0) break; @@ -1596,18 +1408,18 @@ static int aty_power_mgmt_LTPro(int sleep, struct fb_info *info) } else { /* Wakeup */ pm &= ~PWR_MGT_ON; - aty_st_lcd(POWER_MANAGEMENT, pm, info); - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); udelay(10); pm &= ~SUSPEND_NOW; pm |= (PWR_BLON | AUTO_PWR_UP); - aty_st_lcd(POWER_MANAGEMENT, pm, info); - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); udelay(10); pm |= PWR_MGT_ON; - aty_st_lcd(POWER_MANAGEMENT, pm, info); + aty_st_lcd(POWER_MANAGEMENT, pm, par); do { - pm = aty_ld_lcd(POWER_MANAGEMENT, info); + pm = aty_ld_lcd(POWER_MANAGEMENT, par); mdelay(1); if ((--timeout) == 0) break; @@ -1617,10 +1429,10 @@ static int aty_power_mgmt_LTPro(int sleep, struct fb_info *info) return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE; } -static int aty_power_mgmt(int sleep, struct fb_info *info) +static int aty_power_mgmt(int sleep, struct atyfb_par *par) { - return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, info) - : aty_power_mgmt_LTPro(sleep, info); + return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, par) + : aty_power_mgmt_LTPro(sleep, par); } /* @@ -1635,12 +1447,11 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) result = PBOOK_SLEEP_OK; - for (info = first_display; info != NULL; info = info->next) { + for (info = first_display; info != NULL; info = par->next) { struct fb_fix_screeninfo fix; int nb; - atyfb_get_fix(&fix, fg_console, info); - nb = fb_display[fg_console].var.yres * fix.line_length; + nb = fb_display[fg_console].var.yres * info->fix.line_length; switch (when) { case PBOOK_SLEEP_REQUEST: @@ -1659,7 +1470,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) wait_for_idle(par); /* Stop accel engine (stop bus mastering) */ if (par->accel_flags & FB_ACCELF_TEXT) - aty_reset_engine(info); + aty_reset_engine(par); /* Backup fb content */ if (par->save_framebuffer) @@ -1670,11 +1481,11 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) atyfb_blank(VESA_POWERDOWN + 1, info); /* Set chip to "suspend" mode */ - result = aty_power_mgmt(1, info); + result = aty_power_mgmt(1, par); break; case PBOOK_WAKE: /* Wakeup chip */ - result = aty_power_mgmt(0, info); + result = aty_power_mgmt(0, par); /* Restore fb content */ if (par->save_framebuffer) { @@ -1684,7 +1495,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) par->save_framebuffer = 0; } /* Restore display */ - atyfb_set_par(par->par, info); + atyfb_set_par(info); atyfb_blank(0, info); break; } @@ -1711,7 +1522,8 @@ static int backlight_conv[] = { static int aty_set_backlight_enable(int on, int level, void *data) { struct fb_info *info = (struct fb_info *) data; - unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info); + struct atyfb_par *par = (struct atyfb_par *) info->par; + unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); reg |= (BLMOD_EN | BIASMOD_EN); if (on && level > BACKLIGHT_OFF) { @@ -1721,8 +1533,7 @@ static int aty_set_backlight_enable(int on, int level, void *data) reg &= ~BIAS_MOD_LEVEL_MASK; reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT); } - aty_st_lcd(LCD_MISC_CNTL, reg, info); - + aty_st_lcd(LCD_MISC_CNTL, reg, par); return 0; } @@ -1784,7 +1595,7 @@ static int __init aty_init(struct fb_info *info, const char *name) if (!M64_HAS(INTEGRATED)) { u32 stat0; u8 dac_type, dac_subtype, clk_type; - stat0 = aty_ld_le32(CONFIG_STAT0, info); + stat0 = aty_ld_le32(CONFIG_STAT0, par); par->bus_type = (stat0 >> 0) & 0x07; par->ram_type = (stat0 >> 3) & 0x07; ramname = aty_gx_ram[par->ram_type]; @@ -2034,7 +1845,7 @@ static int __init aty_init(struct fb_info *info, const char *name) disp = info->disp; - strcpy(info->modename, atyfb_name); + strcpy(info->modename, info->fix.id); info->node = NODEV; info->fbops = &atyfb_ops; info->disp = disp; @@ -2043,7 +1854,7 @@ static int __init aty_init(struct fb_info *info, const char *name) strcpy(info->fontname, fontname); info->changevar = NULL; info->switch_con = gen_switch; - info->updatevar = &atyfbcon_updatevar; + info->updatevar = gen_update_var; info->flags = FBINFO_FLAG_DEFAULT; #ifdef CONFIG_PMAC_BACKLIGHT @@ -2093,7 +1904,7 @@ static int __init aty_init(struct fb_info *info, const char *name) default_vmode = VMODE_800_600_60; else default_vmode = VMODE_640_480_67; - sense = read_aty_sense(info); + sense = read_aty_sense(par); printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n", sense, @@ -2145,12 +1956,12 @@ static int __init aty_init(struct fb_info *info, const char *name) var.yres_virtual = var.yres; } - if (atyfb_decode_var(&var, par, info)) { + if (atyfb_check_var(&var, info)) { printk("atyfb: can't set default video mode\n"); return 0; } #ifdef __sparc__ - atyfb_save_palette(info, 0); + atyfb_save_palette(par, 0); #endif #ifdef CONFIG_FB_ATY_CT @@ -2168,7 +1979,7 @@ static int __init aty_init(struct fb_info *info, const char *name) fb_alloc_cmap(&info->cmap, 256, 0); - atyfb_set_var(&var, -1, info); + gen_set_var(&var, -1, info); if (register_framebuffer(info) < 0) return 0; @@ -2176,16 +1987,17 @@ static int __init aty_init(struct fb_info *info, const char *name) fb_list = info; printk("fb%d: %s frame buffer device on %s\n", - GET_FB_IDX(info->node), atyfb_name, name); + GET_FB_IDX(info->node), info->fix.id, name); return 1; } int __init atyfb_init(void) { #if defined(CONFIG_PCI) + unsigned long addr, res_start, res_size; + struct atyfb_par *default_par; struct pci_dev *pdev = NULL; struct fb_info *info; - unsigned long addr, res_start, res_size; int i; #ifdef __sparc__ extern void (*prom_palette) (int); @@ -2201,7 +2013,6 @@ int __init atyfb_init(void) #else u16 tmp; #endif - struct atyfb_par *default_par; while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) { @@ -2239,6 +2050,7 @@ int __init atyfb_init(void) memset(default_par, 0, sizeof(struct atyfb_par)); info->disp = (struct display *) (info + 1); + info->fix = atyfb_fix; info->par = default_par; rp = &pdev->resource[0]; @@ -2258,14 +2070,13 @@ int __init atyfb_init(void) /* * Map memory-mapped registers. */ - par->ati_regbase = addr + 0x7ffc00UL; + default_par->ati_regbase = addr + 0x7ffc00UL; info->fix.mmio_start = addr + 0x7ffc00UL; /* * Map in big-endian aperture. */ - info->screen_base = - (unsigned long) addr + 0x800000UL; + info->screen_base = (char *) (addr + 0x800000UL); info->fix.smem_start = addr + 0x800000UL; /* @@ -2361,11 +2172,9 @@ int __init atyfb_init(void) /* * Fix PROMs idea of MEM_CNTL settings... */ - mem = aty_ld_le32(MEM_CNTL, info); - chip_id = - aty_ld_le32(CONFIG_CHIP_ID, info); - if (((chip_id & CFG_CHIP_TYPE) == - VT_CHIP_ID) + mem = aty_ld_le32(MEM_CNTL, default_par); + chip_id = aty_ld_le32(CONFIG_CHIP_ID, default_par); + if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { switch (mem & 0x0f) { case 3: @@ -2383,13 +2192,11 @@ int __init atyfb_init(void) default: break; } - if ((aty_ld_le32 - (CONFIG_STAT0, - info) & 7) >= SDRAM) + if ((aty_ld_le32(CONFIG_STAT0, default_par) & 7) >= SDRAM) mem &= ~(0x00700000); } mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ - aty_st_le32(MEM_CNTL, mem, info); + aty_st_le32(MEM_CNTL, mem, default_par); } /* @@ -2427,21 +2234,21 @@ int __init atyfb_init(void) crtc.vyres = prom_getintdefault(node, "height", 768); - crtc.bpp = + var->bits_per_pixel = prom_getintdefault(node, "depth", 8); - crtc.xoffset = crtc.yoffset = 0; + var->xoffset = var->yoffset = 0; crtc.h_tot_disp = - aty_ld_le32(CRTC_H_TOTAL_DISP, info); + aty_ld_le32(CRTC_H_TOTAL_DISP, default_par); crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, - info); + default_par); crtc.v_tot_disp = - aty_ld_le32(CRTC_V_TOTAL_DISP, info); + aty_ld_le32(CRTC_V_TOTAL_DISP, default_par); crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, - info); + default_par); crtc.gen_cntl = - aty_ld_le32(CRTC_GEN_CNTL, info); + aty_ld_le32(CRTC_GEN_CNTL, default_par); aty_crtc_to_var(&crtc, var); h_total = var->xres + var->right_margin + @@ -2452,10 +2259,10 @@ int __init atyfb_init(void) /* * Read the PLL to figure actual Refresh Rate. */ - clock_cntl = aty_ld_8(CLOCK_CNTL, info); + clock_cntl = aty_ld_8(CLOCK_CNTL, default_par); /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */ for (i = 0; i < 16; i++) - pll_regs[i] = aty_ld_pll(i, info); + pll_regs[i] = aty_ld_pll(i, default_par); /* * PLL Reference Divider M: @@ -2555,21 +2362,21 @@ int __init atyfb_init(void) /* * Add /dev/fb mmap values. */ - par->mmap_map[0].voff = 0x8000000000000000UL; - par->mmap_map[0].poff = - info->screen_base & PAGE_MASK; - par->mmap_map[0].size = + default_par->mmap_map[0].voff = 0x8000000000000000UL; + default_par->mmap_map[0].poff = + (unsigned long) info->screen_base & PAGE_MASK; + default_par->mmap_map[0].size = info->fix.smem_len; - par->mmap_map[0].prot_mask = _PAGE_CACHE; - par->mmap_map[0].prot_flag = _PAGE_E; - par->mmap_map[1].voff = - par->mmap_map[0].voff + + default_par->mmap_map[0].prot_mask = _PAGE_CACHE; + default_par->mmap_map[0].prot_flag = _PAGE_E; + default_par->mmap_map[1].voff = + default_par->mmap_map[0].voff + info->fix.smem_len; - par->mmap_map[1].poff = - par->ati_regbase & PAGE_MASK; - par->mmap_map[1].size = PAGE_SIZE; - par->mmap_map[1].prot_mask = _PAGE_CACHE; - par->mmap_map[1].prot_flag = _PAGE_E; + default_par->mmap_map[1].poff = + default_par->ati_regbase & PAGE_MASK; + default_par->mmap_map[1].size = PAGE_SIZE; + default_par->mmap_map[1].prot_mask = _PAGE_CACHE; + default_par->mmap_map[1].prot_flag = _PAGE_E; #endif /* __sparc__ */ #ifdef CONFIG_PMAC_PBOOK @@ -2577,15 +2384,16 @@ int __init atyfb_init(void) pmu_register_sleep_notifier (&aty_sleep_notifier); /* FIXME info->next = first_display; */ - first_display = info; + default_par->next = first_display; #endif } } #elif defined(CONFIG_ATARI) - u32 clock_r; - int m64_num; + struct atyfb_par *default_par; struct fb_info *info; + int m64_num; + u32 clock_r; for (m64_num = 0; m64_num < mach64_count; m64_num++) { if (!phys_vmembase[m64_num] || !phys_size[m64_num] || @@ -2602,6 +2410,7 @@ int __init atyfb_init(void) return -ENOMEM; } memset(info, 0, sizeof(struct fb_info)); + info->fix = atyfb_fix; /* * Map the video memory (physical address given) to somewhere in the @@ -2610,25 +2419,25 @@ int __init atyfb_init(void) info->screen_base = (unsigned long)ioremap(phys_vmembase[m64_num], phys_size[m64_num]); info->fix.smem_start = info->screen_base; /* Fake! */ - par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num], + default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num], 0x10000) + 0xFC00ul; info->fix.mmio_start = par->ati_regbase; /* Fake! */ - aty_st_le32(CLOCK_CNTL, 0x12345678, info); - clock_r = aty_ld_le32(CLOCK_CNTL, info); + aty_st_le32(CLOCK_CNTL, 0x12345678, default_par); + clock_r = aty_ld_le32(CLOCK_CNTL, default_par); switch (clock_r & 0x003F) { case 0x12: - par->clk_wr_offset = 3; /* */ + default_par->clk_wr_offset = 3; /* */ break; case 0x34: - par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */ + default_par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */ break; case 0x16: - par->clk_wr_offset = 1; /* */ + default_par->clk_wr_offset = 1; /* */ break; case 0x38: - par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */ + default_par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */ break; } @@ -2831,7 +2640,7 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt */ aty_st_8(DAC_CNTL, i, par); aty_st_8(DAC_MASK, 0xff, par); - scale = (M64_HAS(INTEGRATED) && par->crtc.bpp == 16) ? 3 : 0; + scale = (M64_HAS(INTEGRATED) && info->var.bits_per_pixel == 16) ? 3 : 0; #ifdef CONFIG_ATARI out_8(&par->aty_cmap_regs->windex, regno << scale); out_8(&par->aty_cmap_regs->lut, red); @@ -2844,7 +2653,7 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, writeb(blue, &par->aty_cmap_regs->lut); #endif if (regno < 16) - switch (par->crtc.bpp) { + switch (info->var.bits_per_pixel) { case 16: ((u16 *) (info->pseudo_palette))[regno] = (regno << 10) | (regno << 5) | regno; @@ -2862,52 +2671,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, return 0; } - /* - * Update the `var' structure (called by fbcon.c) - */ - -static int atyfbcon_updatevar(int con, struct fb_info *info) -{ - struct atyfb_par *par = (struct atyfb_par *) info->par; - struct display *p = &fb_display[con]; - struct vc_data *conp = p->conp; - u32 yres, yoffset, sy, height; - - yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1; - yoffset = fb_display[con].var.yoffset; - - sy = (conp->vc_rows + p->yscroll) * fontheight(p); - height = yres - conp->vc_rows * fontheight(p); - - if (height && (yoffset + yres > sy)) { - struct fb_fillrect area; - - area.dx = fb_display[con].var.xoffset; - area.dy = sy; - area.height = height; - area.width = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8; - area.color = attr_bgcol_ec(p, conp); - area.rop = ROP_COPY; - - if (sy + height > par->crtc.vyres) { - wait_for_fifo(1, par); - aty_st_le32(SC_BOTTOM, sy + height - 1, par); - } - atyfb_fillrect(info, &area); - } -#ifdef CONFIG_FB_ATY_CT - if (par->cursor && (yoffset + yres <= sy)) - atyfb_cursor(p, CM_ERASE, par->cursor->pos.x, - par->cursor->pos.y); -#endif /* CONFIG_FB_ATY_CT */ - - par->crtc.yoffset = yoffset; - set_off_pitch(par, info); - return 0; -} - - - #ifdef MODULE int __init init_module(void) { diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index d2ffd74c7307..0894d4d00aee 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c @@ -6,27 +6,10 @@ #include <linux/sched.h> #include <linux/delay.h> #include <linux/fb.h> - -#include <video/fbcon.h> -#include <video/fbcon-cfb8.h> -#include <video/fbcon-cfb16.h> -#include <video/fbcon-cfb24.h> -#include <video/fbcon-cfb32.h> - #include <video/mach64.h> #include "atyfb.h" /* - * Text console acceleration - */ - -static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, - int dx, int height, int width); -static void fbcon_aty_clear(struct vc_data *conp, struct display *p, - int sy, int sx, int height, int width); - - - /* * Generic Mach64 routines */ @@ -63,9 +46,9 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) u32 pitch_value; /* determine modal information from global mode structure */ - pitch_value = par->crtc.vxres; + pitch_value = info->var.xres_virtual; - if (par->crtc.bpp == 24) { + if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* horizontal coordinates and widths must be adjusted */ pitch_value = pitch_value * 3; @@ -187,7 +170,7 @@ static inline void draw_rect(s16 x, s16 y, u16 width, u16 height, par->blitter_may_be_busy = 1; } -static void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area) +void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area) { struct atyfb_par *par = (struct atyfb_par *) info->par; @@ -197,8 +180,8 @@ static void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area) if (!area->width || !area->height) return; - pitch_value = par->crtc.vxres; - if (par->crtc.bpp == 24) { + pitch_value = info->var.xres_virtual; + if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* horizontal coordinates and widths must be adjusted */ pitch_value *= 3; @@ -237,7 +220,7 @@ void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) rect->color |= (rect->color << 8); rect->color |= (rect->color << 16); - if (par->crtc.bpp == 24) { + if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* horizontal coordinates and widths must be adjusted */ rect->dx *= 3; @@ -255,111 +238,11 @@ void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) draw_rect(rect->dx, rect->dy, rect->width, rect->height, par); } - /* - * Text console acceleration - */ - -static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, - int dx, int height, int width) +void atyfb_imageblit(struct fb_info *info, struct fb_image *image) { - struct fb_info *info = p->fb_info; - struct fb_copyarea area; -#ifdef __sparc__ - struct atyfb_par *par = (struct atyfb_par *) (info->par); - - if (par->mmaped && (!info->display_fg - || info->display_fg->vc_num == - par->vtconsole)) - return; -#endif - - area.sx = sx * fontwidth(p); - area.sy = sy * fontheight(p); - area.dx = dx * fontwidth(p); - area.dy = dy * fontheight(p); - area.width = width * fontwidth(p); - area.height = height * fontheight(p); - - atyfb_copyarea(info, &area); -} - -static void fbcon_aty_clear(struct vc_data *conp, struct display *p, - int sy, int sx, int height, int width) -{ - struct fb_info *info = p->fb_info; - struct fb_fillrect region; -#ifdef __sparc__ - struct atyfb_par *par = (struct atyfb_par *) (info->par); - - if (par->mmaped && (!info->display_fg - || info->display_fg->vc_num == - par->vtconsole)) - return; -#endif - region.color = attr_bgcol_ec(p, conp); - region.color |= (region.color << 8); - region.color |= (region.color << 16); - - region.dx = sx * fontwidth(p); - region.dy = sy * fontheight(p); - region.width = width * fontwidth(p); - region.height = height * fontheight(p); - region.rop = ROP_COPY; - - atyfb_fillrect(info, ®ion); -} - -#ifdef __sparc__ -#define check_access \ - if (par->mmaped && (!info->display_fg \ - || info->display_fg->vc_num == par->vtconsole)) \ - return; -#else -#define check_access do { } while (0) -#endif - -#define DEF_FBCON_ATY_OP(name, call, args...) \ -static void name(struct vc_data *conp, struct display *p, args) \ -{ \ - struct fb_info *info = p->fb_info; \ - struct atyfb_par *par = (struct atyfb_par *) info->par; \ - check_access; \ - if (par->blitter_may_be_busy) \ - wait_for_idle(par); \ - call; \ + struct atyfb_par *par = (struct atyfb_par *) info->par; + + if (par->blitter_may_be_busy) + wait_for_idle(par); + cfb_imageblit(info, image); } - -#define DEF_FBCON_ATY(width) \ - DEF_FBCON_ATY_OP(fbcon_aty##width##_putc, \ - fbcon_cfb##width##_putc(conp, p, c, yy, xx), \ - int c, int yy, int xx) \ - DEF_FBCON_ATY_OP(fbcon_aty##width##_putcs, \ - fbcon_cfb##width##_putcs(conp, p, s, count, yy, xx), \ - const unsigned short *s, int count, int yy, int xx) \ - DEF_FBCON_ATY_OP(fbcon_aty##width##_clear_margins, \ - fbcon_cfb##width##_clear_margins(conp, p, bottom_only), \ - int bottom_only) \ - \ -const struct display_switch fbcon_aty##width = { \ - setup: fbcon_cfb##width##_setup, \ - bmove: fbcon_aty_bmove, \ - clear: fbcon_aty_clear, \ - putc: fbcon_aty##width##_putc, \ - putcs: fbcon_aty##width##_putcs, \ - revc: fbcon_cfb##width##_revc, \ - clear_margins: fbcon_aty##width##_clear_margins, \ - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) \ -}; - -#ifdef FBCON_HAS_CFB8 -DEF_FBCON_ATY(8) -#endif -#ifdef FBCON_HAS_CFB16 - DEF_FBCON_ATY(16) -#endif -#ifdef FBCON_HAS_CFB24 - DEF_FBCON_ATY(24) -#endif -#ifdef FBCON_HAS_CFB32 - DEF_FBCON_ATY(32) -#endif diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index df57da42d3f0..3d83d8e175d7 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c @@ -271,11 +271,11 @@ static int dummy(void) } const struct aty_dac_ops aty_dac_ct = { - set_dac:(void *) dummy, + .set_dac = (void *) dummy, }; const struct aty_pll_ops aty_pll_ct = { - var_to_pll:aty_var_to_pll_ct, - pll_to_var:aty_pll_ct_to_var, - set_pll:aty_set_pll_ct, + .var_to_pll = aty_var_to_pll_ct, + .pll_to_var = aty_pll_ct_to_var, + .set_pll = aty_set_pll_ct, }; diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c index 5ac49784efd6..75045ebe2f4e 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/aty/mach64_cursor.c @@ -129,7 +129,7 @@ static void aty_set_cursor(struct fb_info *info, int on) #endif if (on) { - x = c->pos.x - c->hot.x - par->crtc.xoffset; + x = c->pos.x - c->hot.x - info->var.xoffset; if (x < 0) { xoff = -x; x = 0; @@ -137,7 +137,7 @@ static void aty_set_cursor(struct fb_info *info, int on) xoff = 0; } - y = c->pos.y - c->hot.y - par->crtc.yoffset; + y = c->pos.y - c->hot.y - info->var.yoffset; if (y < 0) { yoff = -y; y = 0; diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c index 02639730591d..d11e58454b29 100644 --- a/drivers/video/aty/mach64_gx.c +++ b/drivers/video/aty/mach64_gx.c @@ -191,13 +191,13 @@ static void aty_set_pll_514(const struct fb_info *info, } const struct aty_dac_ops aty_dac_ibm514 = { - set_dac:aty_set_dac_514, + .set_dac = aty_set_dac_514, }; const struct aty_pll_ops aty_pll_ibm514 = { - var_to_pll:aty_var_to_pll_514, - pll_to_var:aty_pll_514_to_var, - set_pll:aty_set_pll_514, + .var_to_pll = aty_var_to_pll_514, + .pll_to_var = aty_pll_514_to_var, + .set_pll = aty_set_pll_514, }; @@ -280,7 +280,7 @@ static int aty_set_dac_ATI68860_B(const struct fb_info *info, } const struct aty_dac_ops aty_dac_ati68860b = { - set_dac:aty_set_dac_ATI68860_B, + .set_dac = aty_set_dac_ATI68860_B, }; @@ -333,7 +333,7 @@ static int aty_set_dac_ATT21C498(const struct fb_info *info, } const struct aty_dac_ops aty_dac_att21c498 = { - set_dac: aty_set_dac_ATT21C498, + .set_dac = aty_set_dac_ATT21C498, }; @@ -487,9 +487,9 @@ static void aty_set_pll18818(const struct fb_info *info, } const struct aty_pll_ops aty_pll_ati18818_1 = { - var_to_pll:aty_var_to_pll_18818, - pll_to_var:aty_pll_18818_to_var, - set_pll:aty_set_pll18818, + .var_to_pll = aty_var_to_pll_18818, + .pll_to_var = aty_pll_18818_to_var, + .set_pll = aty_set_pll18818, }; @@ -603,9 +603,9 @@ static void aty_set_pll_1703(const struct fb_info *info, } const struct aty_pll_ops aty_pll_stg1703 = { - var_to_pll:aty_var_to_pll_1703, - pll_to_var:aty_pll_1703_to_var, - set_pll:aty_set_pll_1703, + .var_to_pll = aty_var_to_pll_1703, + .pll_to_var = aty_pll_1703_to_var, + .set_pll = aty_set_pll_1703, }; @@ -727,9 +727,9 @@ static void aty_set_pll_8398(const struct fb_info *info, } const struct aty_pll_ops aty_pll_ch8398 = { - var_to_pll:aty_var_to_pll_8398, - pll_to_var:aty_pll_8398_to_var, - set_pll:aty_set_pll_8398, + .var_to_pll = aty_var_to_pll_8398, + .pll_to_var = aty_pll_8398_to_var, + .set_pll = aty_set_pll_8398, }; @@ -874,9 +874,9 @@ static void aty_set_pll_408(const struct fb_info *info, } const struct aty_pll_ops aty_pll_att20c408 = { - var_to_pll:aty_var_to_pll_408, - pll_to_var:aty_pll_408_to_var, - set_pll:aty_set_pll_408, + .var_to_pll = aty_var_to_pll_408, + .pll_to_var = aty_pll_408_to_var, + .set_pll = aty_set_pll_408, }; @@ -904,11 +904,11 @@ static int dummy(void) } const struct aty_dac_ops aty_dac_unsupported = { - set_dac:aty_set_dac_unsupported, + .set_dac = aty_set_dac_unsupported, }; const struct aty_pll_ops aty_pll_unsupported = { - var_to_pll:(void *) dummy, - pll_to_var:(void *) dummy, - set_pll:(void *) dummy, + .var_to_pll = (void *) dummy, + .pll_to_var = (void *) dummy, + .set_pll = (void *) dummy, }; diff --git a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c index 2859ef189175..ae43cc8ea62e 100644 --- a/drivers/video/aty128fb.c +++ b/drivers/video/aty128fb.c @@ -117,18 +117,18 @@ static struct fb_var_screeninfo default_var = { /* default modedb mode */ /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ static struct fb_videomode defaultmode __initdata = { - refresh: 60, - xres: 640, - yres: 480, - pixclock: 39722, - left_margin: 48, - right_margin: 16, - upper_margin: 33, - lower_margin: 10, - hsync_len: 96, - vsync_len: 2, - sync: 0, - vmode: FB_VMODE_NONINTERLACED + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39722, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED }; /* struct to hold chip description information */ @@ -415,16 +415,16 @@ static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p, #endif static struct fb_ops aty128fb_ops = { - owner: THIS_MODULE, - fb_get_fix: aty128fb_get_fix, - fb_get_var: aty128fb_get_var, - fb_set_var: aty128fb_set_var, - fb_get_cmap: aty128fb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: aty128fb_setcolreg, - fb_pan_display: aty128fb_pan_display, - fb_blank: aty128fb_blank, - fb_rasterimg: aty128fb_rasterimg, + .owner = THIS_MODULE, + .fb_get_fix = aty128fb_get_fix, + .fb_get_var = aty128fb_get_var, + .fb_set_var = aty128fb_set_var, + .fb_get_cmap = aty128fb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = aty128fb_setcolreg, + .fb_pan_display =aty128fb_pan_display, + .fb_blank = aty128fb_blank, + .fb_rasterimg = aty128fb_rasterimg, }; #ifdef CONFIG_PMAC_BACKLIGHT @@ -1749,7 +1749,7 @@ aty128_init(struct fb_info_aty128 *info, const char *name) board_list = aty128_board_list_add(board_list, info); size = (var.bits_per_pixel <= 8) ? 256 : 32; - fb_alloc_cmap(info->fb_info.cmap, size, 0); + fb_alloc_cmap(&info->fb_info.cmap, size, 0); if (register_framebuffer(&info->fb_info) < 0) return 0; diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index 5240cbd37ffa..a57643eb7b32 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c @@ -28,6 +28,14 @@ #include <asm/io.h> #include <video/fbcon.h> +#if BITS_PER_LONG == 32 +#define FB_READ fb_readl +#define FB_WRITE fb_writel +#else +#define FB_READ fb_readq +#define FB_WRITE fb_writeq +#endif + void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area) { int x2, y2, lineincr, shift, shift_right, shift_left, old_dx, old_dy; @@ -137,19 +145,19 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area) dst = (unsigned long *) dst1; src = (unsigned long *) src1; - last = (fb_readl(src) & start_mask); + last = (FB_READ(src) & start_mask); if (shift > 0) - fb_writel(fb_readl(dst) | (last >> shift_right), dst); + FB_WRITE(FB_READ(dst) | (last >> shift_right), dst); for (j = 0; j < n; j++) { dst++; - tmp = fb_readl(src); + tmp = FB_READ(src); src++; - fb_writel((last << shift_left) | (tmp >> shift_right), dst); + FB_WRITE((last << shift_left) | (tmp >> shift_right), dst); last = tmp; src++; } - fb_writel(fb_readl(dst) | (last << shift_left), dst); + FB_WRITE(FB_READ(dst) | (last << shift_left), dst); src1 += lineincr; dst1 += lineincr; } while (--height); @@ -161,19 +169,19 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area) dst = (unsigned long *) dst1; src = (unsigned long *) src1; - last = (fb_readl(src) & end_mask); + last = (FB_READ(src) & end_mask); if (shift < 0) - fb_writel(fb_readl(dst) | (last >> shift_right), dst); + FB_WRITE(FB_READ(dst) | (last >> shift_right), dst); for (j = 0; j < n; j++) { dst--; - tmp = fb_readl(src); + tmp = FB_READ(src); src--; - fb_writel((tmp << shift_left) | (last >> shift_right), dst); + FB_WRITE((tmp << shift_left) | (last >> shift_right), dst); last = tmp; src--; } - fb_writel(fb_readl(dst) | (last >> shift_right), dst); + FB_WRITE(FB_READ(dst) | (last >> shift_right), dst); src1 += lineincr; dst1 += lineincr; } while (--height); @@ -187,16 +195,16 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area) src = (unsigned long *) (src1 - start_index); if (start_mask) - fb_writel(fb_readl(src) | start_mask, dst); + FB_WRITE(FB_READ(src) | start_mask, dst); for (j = 0; j < n; j++) { - fb_writel(fb_readl(src), dst); + FB_WRITE(FB_READ(src), dst); dst++; src++; } if (end_mask) - fb_writel(fb_readl(src) | end_mask, dst); + FB_WRITE(FB_READ(src) | end_mask, dst); src1 += lineincr; dst1 += lineincr; } while (--height); @@ -207,9 +215,9 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area) src = (unsigned long *) src1; if (start_mask) - fb_writel(fb_readl(src) | start_mask, dst); + FB_WRITE(FB_READ(src) | start_mask, dst); for (j = 0; j < n; j++) { - fb_writel(fb_readl(src), dst); + FB_WRITE(FB_READ(src), dst); dst--; src--; } diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index 0fbc695a85d8..d052a89bd5eb 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c @@ -22,6 +22,14 @@ #include <asm/types.h> #include <video/fbcon.h> +#if BITS_PER_LONG == 32 +#define FB_READ fb_readl +#define FB_WRITE fb_writel +#else +#define FB_READ fb_readq +#define FB_WRITE fb_writeq +#endif + void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect) { unsigned long start_index, end_index, start_mask = 0, end_mask = 0; @@ -93,33 +101,19 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect) dst = (unsigned long *) (dst1 - start_index); if (start_mask) { -#if BITS_PER_LONG == 32 - fb_writel(fb_readl(dst) | - start_mask, dst); -#else - fb_writeq(fb_readq(dst) | + FB_WRITE(FB_READ(dst) | start_mask, dst); -#endif dst++; } for (i = 0; i < n; i++) { -#if BITS_PER_LONG == 32 - fb_writel(fg, dst); -#else - fb_writeq(fg, dst); -#endif + FB_WRITE(fg, dst); dst++; } if (end_mask) -#if BITS_PER_LONG == 32 - fb_writel(fb_readl(dst) | end_mask, - dst); -#else - fb_writeq(fb_readq(dst) | end_mask, + FB_WRITE(FB_READ(dst) | end_mask, dst); -#endif dst1 += linesize; } while (--height); break; @@ -128,33 +122,19 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect) dst = (unsigned long *) (dst1 - start_index); if (start_mask) { -#if BITS_PER_LONG == 32 - fb_writel(fb_readl(dst) ^ + FB_WRITE(FB_READ(dst) ^ start_mask, dst); -#else - fb_writeq(fb_readq(dst) ^ - start_mask, dst); -#endif dst++; } for (i = 0; i < n; i++) { -#if BITS_PER_LONG == 32 - fb_writel(fb_readl(dst) ^ fg, dst); -#else - fb_writeq(fb_readq(dst) ^ fg, dst); -#endif + FB_WRITE(FB_READ(dst) ^ fg, dst); dst++; } if (end_mask) { -#if BITS_PER_LONG == 32 - fb_writel(fb_readl(dst) ^ end_mask, + FB_WRITE(FB_READ(dst) ^ end_mask, dst); -#else - fb_writeq(fb_readq(dst) ^ end_mask, - dst); -#endif } dst1 += linesize; } while (--height); diff --git a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c index 084fa2ff5403..58d8070dbf87 100644 --- a/drivers/video/cgsixfb.c +++ b/drivers/video/cgsixfb.c @@ -521,13 +521,13 @@ static void cg6_restore_palette (struct fb_info_sbusfb *fb) } static struct display_switch cg6_dispsw __initdata = { - setup: cg6_setup, - bmove: fbcon_redraw_bmove, - clear: cg6_clear, - putc: cg6_putc, - putcs: cg6_putcs, - revc: cg6_revc, - fontwidthmask: FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ + .setup = cg6_setup, + .bmove = fbcon_redraw_bmove, + .clear = cg6_clear, + .putc = cg6_putc, + .putcs = cg6_putcs, + .revc = cg6_revc, + .fontwidthmask =FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ }; static void cg6_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue) diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index b5ce7c9688f3..4ad4e2e30ae5 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -126,14 +126,14 @@ static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int chipsfb_blank(int blank, struct fb_info *info); static struct fb_ops chipsfb_ops = { - owner: THIS_MODULE, - fb_get_fix: chips_get_fix, - fb_get_var: chips_get_var, - fb_set_var: chips_set_var, - fb_get_cmap: chips_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: chipsfb_setcolreg, - fb_blank: chipsfb_blank, + .owner = THIS_MODULE, + .fb_get_fix = chips_get_fix, + .fb_get_var = chips_get_var, + .fb_set_var = chips_set_var, + .fb_get_cmap = chips_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = chipsfb_setcolreg, + .fb_blank = chipsfb_blank, }; static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green, diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c index 40268f2ad262..492027ff4f1c 100644 --- a/drivers/video/clgenfb.c +++ b/drivers/video/clgenfb.c @@ -498,17 +498,17 @@ static int clgenfb_setcolreg (unsigned regno, unsigned red, unsigned green, /* function table of the above functions */ static struct fb_ops clgenfb_ops = { - owner: THIS_MODULE, - fb_open: clgenfb_open, - fb_release: clgenfb_release, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: clgenfb_setcolreg, - fb_pan_display: fbgen_pan_display, - fb_blank: fbgen_blank, + .owner = THIS_MODULE, + .fb_open = clgenfb_open, + .fb_release = clgenfb_release, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = clgenfb_setcolreg, + .fb_pan_display =fbgen_pan_display, + .fb_blank = fbgen_blank, }; /*--- Hardware Specific Routines -------------------------------------------*/ @@ -555,14 +555,14 @@ static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); static struct display_switch fbcon_clgen_8 = { - setup: fbcon_cfb8_setup, - bmove: fbcon_clgen8_bmove, - clear: fbcon_clgen8_clear, - putc: fbcon_cfb8_putc, - putcs: fbcon_cfb8_putcs, - revc: fbcon_cfb8_revc, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb8_setup, + .bmove = fbcon_clgen8_bmove, + .clear = fbcon_clgen8_clear, + .putc = fbcon_cfb8_putc, + .putcs = fbcon_cfb8_putcs, + .revc = fbcon_cfb8_revc, + .clear_margins =fbcon_cfb8_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif #ifdef FBCON_HAS_CFB16 @@ -571,14 +571,14 @@ static void fbcon_clgen16_bmove (struct display *p, int sy, int sx, static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); static struct display_switch fbcon_clgen_16 = { - setup: fbcon_cfb16_setup, - bmove: fbcon_clgen16_bmove, - clear: fbcon_clgen16_clear, - putc: fbcon_cfb16_putc, - putcs: fbcon_cfb16_putcs, - revc: fbcon_cfb16_revc, - clear_margins: fbcon_cfb16_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb16_setup, + .bmove = fbcon_clgen16_bmove, + .clear = fbcon_clgen16_clear, + .putc = fbcon_cfb16_putc, + .putcs = fbcon_cfb16_putcs, + .revc = fbcon_cfb16_revc, + .clear_margins =fbcon_cfb16_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif #ifdef FBCON_HAS_CFB32 @@ -587,14 +587,14 @@ static void fbcon_clgen32_bmove (struct display *p, int sy, int sx, static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); static struct display_switch fbcon_clgen_32 = { - setup: fbcon_cfb32_setup, - bmove: fbcon_clgen32_bmove, - clear: fbcon_clgen32_clear, - putc: fbcon_cfb32_putc, - putcs: fbcon_cfb32_putcs, - revc: fbcon_cfb32_revc, - clear_margins: fbcon_cfb32_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb32_setup, + .bmove = fbcon_clgen32_bmove, + .clear = fbcon_clgen32_clear, + .putc = fbcon_cfb32_putc, + .putcs = fbcon_cfb32_putcs, + .revc = fbcon_cfb32_revc, + .clear_margins =fbcon_cfb32_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 304a67ba4999..d00c96dccb1e 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c @@ -193,19 +193,17 @@ static int clps7111fb_blank(int blank, struct fb_info *info) } static struct fb_ops clps7111fb_ops = { - owner: THIS_MODULE, - fb_check_var: clps7111fb_check_var, - fb_set_par: clps7111fb_set_par, - fb_set_var: gen_set_var, - fb_set_cmap: gen_set_cmap, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_get_cmap: gen_get_cmap, - fb_setcolreg: clps7111fb_setcolreg, - fb_blank: clps7111fb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_check_var = clps7111fb_check_var, + .fb_set_par = clps7111fb_set_par, + .fb_set_var = gen_set_var, + .fb_set_cmap = gen_set_cmap, + .fb_get_cmap = gen_get_cmap, + .fb_setcolreg = clps7111fb_setcolreg, + .fb_blank = clps7111fb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; static int diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 183d2745d719..87b44e7865da 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -216,16 +216,16 @@ static int default_cmode __initdata = CMODE_NVRAM; static struct fb_ops controlfb_ops = { - owner: THIS_MODULE, - fb_get_fix: control_get_fix, - fb_get_var: control_get_var, - fb_set_var: control_set_var, - fb_get_cmap: control_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: controlfb_setcolreg, - fb_pan_display: control_pan_display, - fb_blank: controlfb_blank, - fb_mmap: control_mmap, + .owner = THIS_MODULE, + .fb_get_fix = control_get_fix, + .fb_get_var = control_get_var, + .fb_set_var = control_set_var, + .fb_get_cmap = control_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = controlfb_setcolreg, + .fb_pan_display =control_pan_display, + .fb_blank = controlfb_blank, + .fb_mmap = control_mmap, }; diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c index bcd6de717865..f39aa0fb9405 100644 --- a/drivers/video/creatorfb.c +++ b/drivers/video/creatorfb.c @@ -648,13 +648,13 @@ out: } static struct display_switch ffb_dispsw __initdata = { - setup: ffb_setup, - bmove: fbcon_redraw_bmove, - clear: ffb_clear, - putc: ffb_putc, - putcs: ffb_putcs, - revc: ffb_revc, - fontwidthmask: FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ + .setup = ffb_setup, + .bmove = fbcon_redraw_bmove, + .clear = ffb_clear, + .putc = ffb_putc, + .putcs = ffb_putcs, + .revc = ffb_revc, + .fontwidthmask =FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ }; static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin) diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index be4de7e4bf95..a090625f0483 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -292,14 +292,14 @@ cyber2000_accel_clear_margins(struct vc_data *conp, struct display *display, } static struct display_switch fbcon_cyber_accel = { - setup: cyber2000_accel_setup, - bmove: cyber2000_accel_bmove, - clear: cyber2000_accel_clear, - putc: cyber2000_accel_putc, - putcs: cyber2000_accel_putcs, - revc: cyber2000_accel_revc, - clear_margins: cyber2000_accel_clear_margins, - fontwidthmask: FONTWIDTH(8)|FONTWIDTH(16) + .setup = cyber2000_accel_setup, + .bmove = cyber2000_accel_bmove, + .clear = cyber2000_accel_clear, + .putc = cyber2000_accel_putc, + .putcs = cyber2000_accel_putcs, + .revc = cyber2000_accel_revc, + .clear_margins =cyber2000_accel_clear_margins, + .fontwidthmask =FONTWIDTH(8)|FONTWIDTH(16) }; /* @@ -1109,15 +1109,13 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) } static struct fb_ops cyber2000fb_ops = { - owner: THIS_MODULE, - fb_set_var: cyber2000fb_set_var, - fb_setcolreg: cyber2000fb_setcolreg, - fb_pan_display: cyber2000fb_pan_display, - fb_blank: cyber2000fb_blank, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, + .owner = THIS_MODULE, + .fb_set_var = cyber2000fb_set_var, + .fb_setcolreg = cyber2000fb_setcolreg, + .fb_pan_display = cyber2000fb_pan_display, + .fb_blank = cyber2000fb_blank, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, }; /* @@ -1208,18 +1206,18 @@ EXPORT_SYMBOL(cyber2000fb_get_fb_var); * 640x480, hsync 31.5kHz, vsync 60Hz */ static struct fb_videomode __devinitdata cyber2000fb_default_mode = { - refresh: 60, - xres: 640, - yres: 480, - pixclock: 39722, - left_margin: 56, - right_margin: 16, - upper_margin: 34, - lower_margin: 9, - hsync_len: 88, - vsync_len: 2, - sync: FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - vmode: FB_VMODE_NONINTERLACED + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39722, + .left_margin = 56, + .right_margin = 16, + .upper_margin = 34, + .lower_margin = 9, + .hsync_len = 88, + .vsync_len = 2, + .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED }; static char igs_regs[] __devinitdata = { @@ -1744,12 +1742,12 @@ static struct pci_device_id cyberpro_pci_table[] __devinitdata = { MODULE_DEVICE_TABLE(pci,cyberpro_pci_table); static struct pci_driver cyberpro_driver = { - name: "CyberPro", - probe: cyberpro_pci_probe, - remove: __devexit_p(cyberpro_pci_remove), - suspend: cyberpro_pci_suspend, - resume: cyberpro_pci_resume, - id_table: cyberpro_pci_table + .name = "CyberPro", + .probe = cyberpro_pci_probe, + .remove = __devexit_p(cyberpro_pci_remove), + .suspend = cyberpro_pci_suspend, + .resume = cyberpro_pci_resume, + .id_table = cyberpro_pci_table }; #endif diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c index 98b1cb6df92c..54c9214b9806 100644 --- a/drivers/video/cyberfb.c +++ b/drivers/video/cyberfb.c @@ -948,14 +948,14 @@ static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, } static struct fb_ops cyberfb_ops = { - owner: THIS_MODULE, - fb_get_fix: cyberfb_get_fix, - fb_get_var: cyberfb_get_var, - fb_set_var: cyberfb_set_var, - fb_get_cmap: cyberfb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: cyberfb_setcolreg, - fb_blank: cyberfb_blank, + .owner = THIS_MODULE, + .fb_get_fix = cyberfb_get_fix, + .fb_get_var = cyberfb_get_var, + .fb_set_var = cyberfb_set_var, + .fb_get_cmap = cyberfb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = cyberfb_setcolreg, + .fb_blank = cyberfb_blank, }; int __init cyberfb_setup(char *options) @@ -1188,14 +1188,14 @@ static void fbcon_cyber8_revc(struct display *p, int xx, int yy) } static struct display_switch fbcon_cyber8 = { - setup: fbcon_cfb8_setup, - bmove: fbcon_cyber8_bmove, - clear: fbcon_cyber8_clear, - putc: fbcon_cyber8_putc, - putcs: fbcon_cyber8_putcs, - revc: fbcon_cyber8_revc, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH(8) + .setup = fbcon_cfb8_setup, + .bmove = fbcon_cyber8_bmove, + .clear = fbcon_cyber8_clear, + .putc = fbcon_cyber8_putc, + .putcs = fbcon_cyber8_putcs, + .revc = fbcon_cyber8_revc, + .clear_margins =fbcon_cfb8_clear_margins, + .fontwidthmask =FONTWIDTH(8) }; #endif diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c index 3a8b4ee1cb2d..bf299d99ea67 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/dnfb.c @@ -119,36 +119,34 @@ static int dnfb_blank(int blank, struct fb_info *info); static void dnfb_copyarea(struct fb_info *info, struct fb_copyarea *area); static struct fb_ops dn_fb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_blank: dnfb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: dnfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_blank = dnfb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = dnfb_copyarea, + .fb_imageblit = cfb_imageblit, }; struct fb_var_screeninfo dnfb_var __initdata = { - xres: 1280, - yres: 1024, - xres_virtual: 2048, - yres_virtual: 1024, - bits_per_pixel: 1, - height: -1, - width: -1, - vmode: FB_VMODE_NONINTERLACED, + .xres 1280, + .yres 1024, + .xres_virtual 2048, + .yres_virtual 1024, + .bits_per_pixel 1, + .height -1, + .width -1, + .vmode FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo dnfb_fix __initdata = { - id: "Apollo Mono", - smem_start: (FRAME_BUFFER_START + IO_BASE), - smem_len: FRAME_BUFFER_LEN, - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_MONO10, - line_length: 256, + .id "Apollo Mono", + .smem_start (FRAME_BUFFER_START + IO_BASE), + .smem_len FRAME_BUFFER_LEN, + .type FB_TYPE_PACKED_PIXELS, + .visual FB_VISUAL_MONO10, + .line_length 256, }; static int dnfb_blank(int blank, struct fb_info *info) diff --git a/drivers/video/dummycon.c b/drivers/video/dummycon.c index f7a09a5d093b..82686f4b2633 100644 --- a/drivers/video/dummycon.c +++ b/drivers/video/dummycon.c @@ -57,18 +57,18 @@ static int dummycon_dummy(void) */ const struct consw dummy_con = { - con_startup: dummycon_startup, - con_init: dummycon_init, - con_deinit: DUMMY, - con_clear: DUMMY, - con_putc: DUMMY, - con_putcs: DUMMY, - con_cursor: DUMMY, - con_scroll: DUMMY, - con_bmove: DUMMY, - con_switch: DUMMY, - con_blank: DUMMY, - con_font_op: DUMMY, - con_set_palette: DUMMY, - con_scrolldelta: DUMMY, + .con_startup = dummycon_startup, + .con_init = dummycon_init, + .con_deinit = DUMMY, + .con_clear = DUMMY, + .con_putc = DUMMY, + .con_putcs = DUMMY, + .con_cursor = DUMMY, + .con_scroll = DUMMY, + .con_bmove = DUMMY, + .con_switch = DUMMY, + .con_blank = DUMMY, + .con_font_op = DUMMY, + .con_set_palette = DUMMY, + .con_scrolldelta = DUMMY, }; diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 3ea58d10e1bb..d581cb7faf1b 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -459,16 +459,16 @@ static void e1355_set_disp(const void *unused, struct display *disp, struct fbgen_hwswitch e1355_switch = { - detect: e1355_detect, - encode_fix: e1355_encode_fix, - decode_var: e1355_decode_var, - encode_var: e1355_encode_var, - get_par: e1355_get_par, - set_par: e1355_set_par, - getcolreg: e1355_getcolreg, - pan_display: e1355_pan_display, - blank: e1355_blank, - set_disp: e1355_set_disp, + .detect = e1355_detect, + .encode_fix = e1355_encode_fix, + .decode_var = e1355_decode_var, + .encode_var = e1355_encode_var, + .get_par = e1355_get_par, + .set_par = e1355_set_par, + .getcolreg = e1355_getcolreg, + .pan_display = e1355_pan_display, + .blank = e1355_blank, + .set_disp = e1355_set_disp, }; @@ -476,15 +476,15 @@ struct fbgen_hwswitch e1355_switch = { static struct fb_ops e1355fb_ops = { - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: e1355fb_setcolreg, - fb_pan_display: fbgen_pan_display, - fb_blank: fbgen_blank, + .owner = THIS_MODULE, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = e1355fb_setcolreg, + .fb_pan_display =fbgen_pan_display, + .fb_blank = fbgen_blank, }; static struct e1355fb_info fb_info; diff --git a/drivers/video/fbcon-accel.c b/drivers/video/fbcon-accel.c index 526eb1ceffc7..27119e32c5dc 100644 --- a/drivers/video/fbcon-accel.c +++ b/drivers/video/fbcon-accel.c @@ -151,14 +151,14 @@ void fbcon_accel_clear_margins(struct vc_data *vc, struct display *p, */ struct display_switch fbcon_accel = { - setup: fbcon_accel_setup, - bmove: fbcon_accel_bmove, - clear: fbcon_accel_clear, - putc: fbcon_accel_putc, - putcs: fbcon_accel_putcs, - revc: fbcon_accel_revc, - clear_margins: fbcon_accel_clear_margins, - fontwidthmask: FONTWIDTHRANGE(1, 16) + .setup = fbcon_accel_setup, + .bmove = fbcon_accel_bmove, + .clear = fbcon_accel_clear, + .putc = fbcon_accel_putc, + .putcs = fbcon_accel_putcs, + .revc = fbcon_accel_revc, + .clear_margins =fbcon_accel_clear_margins, + .fontwidthmask =FONTWIDTHRANGE(1, 16) }; #ifdef MODULE diff --git a/drivers/video/fbcon-cfb24.c b/drivers/video/fbcon-cfb24.c index 43a8bb1c86dc..878bac753eb5 100644 --- a/drivers/video/fbcon-cfb24.c +++ b/drivers/video/fbcon-cfb24.c @@ -25,7 +25,9 @@ void fbcon_cfb24_setup(struct display *p) { - p->next_line = p->line_length ? p->line_length : p->var.xres_virtual*3; + struct fb_info *info = p->fb_info; + + p->next_line = info->fix.line_length ? info->fix.line_length : p->var.xres_virtual*3; p->next_plane = 0; } diff --git a/drivers/video/fbcon-hga.c b/drivers/video/fbcon-hga.c index df6ac9774982..7e4659451dc3 100644 --- a/drivers/video/fbcon-hga.c +++ b/drivers/video/fbcon-hga.c @@ -214,14 +214,14 @@ void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p, */ struct display_switch fbcon_hga = { - setup: fbcon_hga_setup, - bmove: fbcon_hga_bmove, - clear: fbcon_hga_clear, - putc: fbcon_hga_putc, - putcs: fbcon_hga_putcs, - revc: fbcon_hga_revc, - clear_margins: fbcon_hga_clear_margins, - fontwidthmask: FONTWIDTH(8) + .setup = fbcon_hga_setup, + .bmove = fbcon_hga_bmove, + .clear = fbcon_hga_clear, + .putc = fbcon_hga_putc, + .putcs = fbcon_hga_putcs, + .revc = fbcon_hga_revc, + .clear_margins =fbcon_hga_clear_margins, + .fontwidthmask =FONTWIDTH(8) }; diff --git a/drivers/video/fbcon-sti.c b/drivers/video/fbcon-sti.c index 1cd2348fa5b5..ef6b9a49d119 100644 --- a/drivers/video/fbcon-sti.c +++ b/drivers/video/fbcon-sti.c @@ -324,14 +324,14 @@ fbcon_sti_clear_margins(struct vc_data *conp, */ struct display_switch fbcon_sti = { - setup: fbcon_sti_setup, - bmove: fbcon_sti_bmove, - clear: fbcon_sti_clear, - putc: fbcon_sti_putc, - putcs: fbcon_sti_putcs, - revc: fbcon_sti_revc, - clear_margins: fbcon_sti_clear_margins, - fontwidthmask: FONTWIDTH(8) + .setup = fbcon_sti_setup, + .bmove = fbcon_sti_bmove, + .clear = fbcon_sti_clear, + .putc = fbcon_sti_putc, + .putcs = fbcon_sti_putcs, + .revc = fbcon_sti_revc, + .clear_margins =fbcon_sti_clear_margins, + .fontwidthmask =FONTWIDTH(8) }; MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c index 7237a3b0e2ef..e680cf2b1c68 100644 --- a/drivers/video/fbcon.c +++ b/drivers/video/fbcon.c @@ -518,13 +518,15 @@ static int fbcon_changevar(int con) static __inline__ void updatescrollmode(struct display *p) { + struct fb_info *info = p->fb_info; + int m; if (p->scrollmode & __SCROLL_YFIXED) return; - if (divides(p->ywrapstep, fontheight(p)) && - divides(fontheight(p), p->var.yres_virtual)) + if (divides(info->fix.ywrapstep, fontheight(p)) && + divides(fontheight(p), info->var.yres_virtual)) m = __SCROLL_YWRAP; - else if (divides(p->ypanstep, fontheight(p)) && + else if (divides(info->fix.ypanstep, fontheight(p)) && p->var.yres_virtual >= p->var.yres+fontheight(p)) m = __SCROLL_YPAN; else if (p->scrollmode & __SCROLL_YNOMOVE) @@ -553,6 +555,7 @@ static void fbcon_font_widths(struct display *p) static void fbcon_setup(int con, int init, int logo) { struct display *p = &fb_display[con]; + struct fb_info *info = p->fb_info; struct vc_data *conp = p->conp; int nr_rows, nr_cols; int old_rows, old_cols; @@ -560,13 +563,13 @@ static void fbcon_setup(int con, int init, int logo) int i, charcnt = 256; struct fbcon_font_desc *font; - if (con != fg_console || (p->fb_info->flags & FBINFO_FLAG_MODULE) || - p->type == FB_TYPE_TEXT) + if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) || + info->fix.type == FB_TYPE_TEXT) logo = 0; p->var.xoffset = p->var.yoffset = p->yscroll = 0; /* reset wrap/pan */ - if (con == fg_console && p->type != FB_TYPE_TEXT) { + if (con == fg_console && info->fix.type != FB_TYPE_TEXT) { if (fbcon_softback_size) { if (!softback_buf) { softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL); @@ -716,7 +719,8 @@ static void fbcon_setup(int con, int init, int logo) if (p->dispsw == &fbcon_dummy) printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not " - "supported\n", p->type, p->type_aux, p->var.bits_per_pixel); + "supported\n", info->fix.type, info->fix.type_aux, + p->var.bits_per_pixel); p->dispsw->setup(p); p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1; @@ -1563,9 +1567,9 @@ static int fbcon_blank(struct vc_data *conp, int blank) if (!p->can_soft_blank) { if (blank) { - if (p->visual == FB_VISUAL_MONO01) { - if (p->fb_info->screen_base) - fb_memset255(p->fb_info->screen_base, + if (info->fix.visual == FB_VISUAL_MONO01) { + if (info->screen_base) + fb_memset255(info->screen_base, p->var.xres_virtual*p->var.yres_virtual* p->var.bits_per_pixel>>3); } else { @@ -2122,9 +2126,10 @@ static inline unsigned safe_shift(unsigned d,int n) static int __init fbcon_show_logo( void ) { struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */ + struct fb_info *info = p->fb_info; int depth = p->var.bits_per_pixel; int line = p->next_line; - unsigned char *fb = p->fb_info->screen_base; + unsigned char *fb = info->screen_base; unsigned char *logo; unsigned char *dst, *src; int i, j, n, x1, y1, x; @@ -2140,8 +2145,8 @@ static int __init fbcon_show_logo( void ) * We don't have to set the colors for the 16-color logo, since that logo * uses the standard VGA text console palette */ - if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) || - (p->visual == FB_VISUAL_DIRECTCOLOR && depth >= 24)) + if ((info->fix.visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) || + (info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 24)) for (i = 0; i < LINUX_LOGO_COLORS; i += n) { n = LINUX_LOGO_COLORS - i; if (n > 16) @@ -2157,8 +2162,7 @@ static int __init fbcon_show_logo( void ) palette_cmap.blue[j] = (linux_logo_blue[i+j] << 8) | linux_logo_blue[i+j]; } - p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console, - p->fb_info); + info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console, info); } if (depth >= 8) { @@ -2174,15 +2178,15 @@ static int __init fbcon_show_logo( void ) logo_depth = 1; } - if (p->fb_info->fbops->fb_rasterimg) - p->fb_info->fbops->fb_rasterimg(p->fb_info, 1); + if (info->fbops->fb_rasterimg) + info->fbops->fb_rasterimg(info, 1); for (x = 0; x < num_online_cpus() * (LOGO_W + 8) && x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) { #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \ defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS) - if (p->visual == FB_VISUAL_DIRECTCOLOR) { + if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { unsigned int val; /* max. depth 32! */ int bdepth; int redshift, greenshift, blueshift; @@ -2257,7 +2261,7 @@ static int __init fbcon_show_logo( void ) #endif #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \ defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS) - if ((depth % 8 == 0) && (p->visual == FB_VISUAL_TRUECOLOR)) { + if ((depth % 8 == 0) && (info->fix.visual == FB_VISUAL_TRUECOLOR)) { /* Modes without color mapping, needs special data transformation... */ unsigned int val; /* max. depth 32! */ int bdepth = depth/8; @@ -2453,24 +2457,24 @@ static int __init fbcon_show_logo( void ) */ const struct consw fb_con = { - con_startup: fbcon_startup, - con_init: fbcon_init, - con_deinit: fbcon_deinit, - con_clear: fbcon_clear, - con_putc: fbcon_putc, - con_putcs: fbcon_putcs, - con_cursor: fbcon_cursor, - con_scroll: fbcon_scroll, - con_bmove: fbcon_bmove, - con_switch: fbcon_switch, - con_blank: fbcon_blank, - con_font_op: fbcon_font_op, - con_set_palette: fbcon_set_palette, - con_scrolldelta: fbcon_scrolldelta, - con_set_origin: fbcon_set_origin, - con_invert_region: fbcon_invert_region, - con_screen_pos: fbcon_screen_pos, - con_getxy: fbcon_getxy, + .con_startup = fbcon_startup, + .con_init = fbcon_init, + .con_deinit = fbcon_deinit, + .con_clear = fbcon_clear, + .con_putc = fbcon_putc, + .con_putcs = fbcon_putcs, + .con_cursor = fbcon_cursor, + .con_scroll = fbcon_scroll, + .con_bmove = fbcon_bmove, + .con_switch = fbcon_switch, + .con_blank = fbcon_blank, + .con_font_op = fbcon_font_op, + .con_set_palette = fbcon_set_palette, + .con_scrolldelta = fbcon_scrolldelta, + .con_set_origin = fbcon_set_origin, + .con_invert_region = fbcon_invert_region, + .con_screen_pos = fbcon_screen_pos, + .con_getxy = fbcon_getxy, }; @@ -2483,12 +2487,12 @@ static void fbcon_dummy_op(void) {} #define DUMMY (void *)fbcon_dummy_op struct display_switch fbcon_dummy = { - setup: DUMMY, - bmove: DUMMY, - clear: DUMMY, - putc: DUMMY, - putcs: DUMMY, - revc: DUMMY, + .setup = DUMMY, + .bmove = DUMMY, + .clear = DUMMY, + .putc = DUMMY, + .putcs = DUMMY, + .revc = DUMMY, }; diff --git a/drivers/video/fbgen.c b/drivers/video/fbgen.c index ff376faa5b12..e13783ed31d8 100644 --- a/drivers/video/fbgen.c +++ b/drivers/video/fbgen.c @@ -30,18 +30,6 @@ #include <video/fbcon-cfb32.h> #include "fbcon-accel.h" -int gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) -{ - *fix = info->fix; - return 0; -} - -int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) -{ - *var = info->var; - return 0; -} - int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { int err; @@ -141,12 +129,6 @@ void gen_set_disp(int con, struct fb_info *info) { struct display *display = (con < 0) ? info->disp : (fb_display + con); - display->visual = info->fix.visual; - display->type = info->fix.type; - display->type_aux = info->fix.type_aux; - display->ypanstep = info->fix.ypanstep; - display->ywrapstep = info->fix.ywrapstep; - display->line_length = info->fix.line_length; if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { display->can_soft_blank = info->fbops->fb_blank ? 1 : 0; @@ -175,6 +157,8 @@ void gen_set_disp(int con, struct fb_info *info) #ifdef FBCON_HAS_ACCEL display->scrollmode = SCROLL_YNOMOVE; display->dispsw = &fbcon_accel; +#else + display->dispsw = &fbcon_dummy; #endif return; } @@ -289,8 +273,6 @@ int fbgen_blank(int blank, struct fb_info *info) } /* generic frame buffer operations */ -EXPORT_SYMBOL(gen_get_fix); -EXPORT_SYMBOL(gen_get_var); EXPORT_SYMBOL(gen_set_var); EXPORT_SYMBOL(gen_get_cmap); EXPORT_SYMBOL(gen_set_cmap); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 45f94b158904..c8f357a2944e 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -393,19 +393,16 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos) struct inode *inode = file->f_dentry->d_inode; int fbidx = GET_FB_IDX(inode->i_rdev); struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; - struct fb_fix_screeninfo fix; - if (! fb || ! info->disp) + if (!info || ! info->screen_base) return -ENODEV; - fb->fb_get_fix(&fix,PROC_CONSOLE(info), info); - if (p >= fix.smem_len) + if (p >= info->fix.smem_len) return 0; - if (count >= fix.smem_len) - count = fix.smem_len; - if (count + p > fix.smem_len) - count = fix.smem_len - p; + if (count >= info->fix.smem_len) + count = info->fix.smem_len; + if (count + p > info->fix.smem_len) + count = info->fix.smem_len - p; if (count) { char *base_addr; @@ -425,21 +422,18 @@ fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos) struct inode *inode = file->f_dentry->d_inode; int fbidx = GET_FB_IDX(inode->i_rdev); struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; - struct fb_fix_screeninfo fix; int err; - if (! fb || ! info->disp) + if (!info || !info->screen_base) return -ENODEV; - fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); - if (p > fix.smem_len) + if (p > info->fix.smem_len) return -ENOSPC; - if (count >= fix.smem_len) - count = fix.smem_len; + if (count >= info->fix.smem_len) + count = info->fix.smem_len; err = 0; - if (count + p > fix.smem_len) { - count = fix.smem_len - p; + if (count + p > info->fix.smem_len) { + count = info->fix.smem_len - p; err = -ENOSPC; } if (count) { @@ -482,9 +476,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -ENODEV; switch (cmd) { case FBIOGET_VSCREENINFO: - if ((i = fb->fb_get_var(&var, PROC_CONSOLE(info), info))) - return i; - return copy_to_user((void *) arg, &var, + return copy_to_user((void *) arg, &info->var, sizeof(var)) ? -EFAULT : 0; case FBIOPUT_VSCREENINFO: if (copy_from_user(&var, (void *) arg, sizeof(var))) @@ -498,10 +490,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -EFAULT; return 0; case FBIOGET_FSCREENINFO: - if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(info), info))) - return i; - return copy_to_user((void *) arg, &fix, sizeof(fix)) ? - -EFAULT : 0; + return copy_to_user((void *) arg, &info->fix, sizeof(fix)) ? -EFAULT : 0; case FBIOPUTCMAP: if (copy_from_user(&cmap, (void *) arg, sizeof(cmap))) return -EFAULT; @@ -568,8 +557,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) struct fb_ops *fb = info->fbops; unsigned long off; #if !defined(__sparc__) || defined(__sparc_v9__) - struct fb_fix_screeninfo fix; - struct fb_var_screeninfo var; unsigned long start; u32 len; #endif @@ -593,23 +580,20 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) return -EINVAL; #else /* !sparc32... */ - lock_kernel(); - fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); /* frame buffer memory */ - start = fix.smem_start; - len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len); + start = info->fix.smem_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); if (off >= len) { /* memory mapped io */ off -= len; - fb->fb_get_var(&var, PROC_CONSOLE(info), info); - if (var.accel_flags) { + if (info->var.accel_flags) { unlock_kernel(); return -EINVAL; } - start = fix.mmio_start; - len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len); + start = info->fix.mmio_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); } unlock_kernel(); start &= PAGE_MASK; @@ -722,15 +706,15 @@ fb_release(struct inode *inode, struct file *file) } static struct file_operations fb_fops = { - owner: THIS_MODULE, - read: fb_read, - write: fb_write, - ioctl: fb_ioctl, - mmap: fb_mmap, - open: fb_open, - release: fb_release, + .owner = THIS_MODULE, + .read = fb_read, + .write = fb_write, + .ioctl = fb_ioctl, + .mmap = fb_mmap, + .open = fb_open, + .release = fb_release, #ifdef HAVE_ARCH_FB_UNMAPPED_AREA - get_unmapped_area: get_fb_unmapped_area, + .get_unmapped_area = get_fb_unmapped_area, #endif }; diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c index 1b5b56d407b8..05ed2f341c12 100644 --- a/drivers/video/fm2fb.c +++ b/drivers/video/fm2fb.c @@ -136,12 +136,12 @@ static u32 pseudo_palette[17]; static struct display display; static struct fb_fix_screeninfo fb_fix __initdata = { - smem_len: FRAMEMASTER_REG, - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_TRUECOLOR, - line_length: (768 << 2), - mmio_len: (8), - accel: FB_ACCEL_NONE, + .smem_len = FRAMEMASTER_REG, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = (768 << 2), + .mmio_len = (8), + .accel = FB_ACCEL_NONE, }; static int fm2fb_mode __initdata = -1; @@ -175,17 +175,15 @@ static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int fm2fb_blank(int blank, struct fb_info *info); static struct fb_ops fm2fb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: fm2fb_setcolreg, - fb_blank: fm2fb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = fm2fb_setcolreg, + .fb_blank = fm2fb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; /* diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c index e09ebaf2b098..6ee7d7d0fe1c 100644 --- a/drivers/video/g364fb.c +++ b/drivers/video/g364fb.c @@ -78,23 +78,23 @@ static struct display disp; static struct fb_info fb_info; static struct fb_fix_screeninfo fb_fix __initdata = { - id: "G364 8plane", - smem_start: 0x40000000, /* physical address */ - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - ypanstep: 1, - accel: FB_ACCEL_NONE, + .id = "G364 8plane", + .smem_start = 0x40000000, /* physical address */ + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .ypanstep = 1, + .accel = FB_ACCEL_NONE, }; static struct fb_var_screeninfo fb_var __initdata = { - bits_per_pixel: 8, - red: { 0, 8, 0 }, + .bits_per_pixel =8, + .red = { 0, 8, 0 }, green: { 0, 8, 0 }, blue: { 0, 8, 0 }, - activate: FB_ACTIVATE_NOW, + activate:FB_ACTIVATE_NOW, height: -1, width: -1, - pixclock: 39722, + pixclock:39722, left_margin: 40, right_margin: 24, upper_margin: 32, @@ -117,18 +117,16 @@ static int g364fb_setcolreg(u_int regno, u_int red, u_int green, static int g364fb_blank(int blank, struct fb_info *info); static struct fb_ops g364fb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: g364fb_setcolreg, - fb_pan_display: g364fb_pan_display, - fb_blank: g364fb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = g364fb_setcolreg, + .fb_pan_display = g364fb_pan_display, + .fb_blank = g364fb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; void fbcon_g364fb_cursor(struct display *p, int mode, int x, int y) diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index 501731a19e0e..c4e3f35c9124 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c @@ -111,23 +111,23 @@ static spinlock_t hga_reg_lock = SPIN_LOCK_UNLOCKED; /* Framebuffer driver structures */ static struct fb_var_screeninfo hga_default_var = { - xres: 720, - yres: 348, - xres_virtual: 720, - yres_virtual: 348, - xoffset: 0, - yoffset: 0, - bits_per_pixel: 1, - grayscale: 0, - red: {0, 1, 0}, - green: {0, 1, 0}, - blue: {0, 1, 0}, - transp: {0, 0, 0}, - nonstd: 0, /* (FB_NONSTD_HGA ?) */ - activate: 0, - height: -1, - width: -1, - accel_flags: 0, + .xres = 720, + .yres = 348, + .xres_virtual = 720, + .yres_virtual = 348, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel =1, + .grayscale = 0, + .red = {0, 1, 0}, + .green = {0, 1, 0}, + .blue = {0, 1, 0}, + .transp = {0, 0, 0}, + .nonstd = 0, /* (FB_NONSTD_HGA ?) */ + .activate = 0, + .height = -1, + .width = -1, + .accel_flags = 0, /* pixclock */ /* left_margin, right_margin */ /* upper_margin, lower_margin */ @@ -137,19 +137,19 @@ static struct fb_var_screeninfo hga_default_var = { }; static struct fb_fix_screeninfo hga_fix = { - id: "HGA", - smem_start: (unsigned long) NULL, - smem_len: 0, - type: FB_TYPE_PACKED_PIXELS, /* (not sure) */ - type_aux: 0, /* (not sure) */ - visual: FB_VISUAL_MONO10, - xpanstep: 8, - ypanstep: 8, - ywrapstep: 0, - line_length: 90, - mmio_start: 0, - mmio_len: 0, - accel: FB_ACCEL_NONE + .id = "HGA", + .smem_start = (unsigned long) NULL, + .smem_len = 0, + .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ + .type_aux = 0, /* (not sure) */ + .visual = FB_VISUAL_MONO10, + .xpanstep = 8, + .ypanstep = 8, + .ywrapstep = 0, + .line_length = 90, + .mmio_start = 0, + .mmio_len = 0, + .accel = FB_ACCEL_NONE }; static struct fb_info fb_info; @@ -557,15 +557,13 @@ static int hgafb_blank(int blank_mode, struct fb_info *info) } static struct fb_ops hgafb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: hga_set_var, - fb_get_cmap: hga_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: hgafb_setcolreg, - fb_pan_display: hga_pan_display, - fb_blank: hgafb_blank, + .owner = THIS_MODULE, + .fb_set_var = hga_set_var, + .fb_get_cmap = hga_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = hgafb_setcolreg, + .fb_pan_display = hga_pan_display, + .fb_blank = hgafb_blank, }; diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index ced8e72bbe1f..a18844098a6c 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -32,17 +32,17 @@ #include <video/fbcon.h> static struct fb_var_screeninfo hitfb_var __initdata = { - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - vmode: FB_VMODE_NONINTERLACED, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo hitfb_fix __initdata = { - id: "Hitachi HD64461", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_TRUECOLOR, - accel_flags: FB_ACCEL_NONE, + .id = "Hitachi HD64461", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .accel_flags = FB_ACCEL_NONE, }; static u16 pseudo_palette[17]; @@ -124,18 +124,16 @@ static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops hitfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_check_var: hitfb_check_var, - fb_set_par: hitfb_set_par, - fb_setcolreg: hitfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_check_var = hitfb_check_var, + .fb_set_par = hitfb_set_par, + .fb_setcolreg = hitfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; int __init hitfb_init(void) diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index f974ddbf55ac..706eb0c6dc53 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c @@ -43,28 +43,28 @@ unsigned char fb_bitmask; #define WMOVE 0x409c static struct fb_fix_screeninfo hpfb_fix __initdata = { - id: "HP300 Topcat", - smem_len: 1024*768, - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - line_length: 1024, - accel: FB_ACCEL_NONE, + .id = "HP300 Topcat", + .smem_len = 1024*768, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .line_length = 1024, + .accel = FB_ACCEL_NONE, }; static struct fb_var_screeninfo hpfb_defined = { - xres: 1024, - yres: 768, - xres_virtual: 1024, - yres_virtual: 786, - bits_per_pixel: 1, - red: {0,2,0}, /* R */ - green: {0,2,0}, /* G */ - blue: {0,2,0}, /* B */ - activate: FB_ACTIVATE_NOW, - height: 274, - width: 195, /* 14" monitor */ - accel_flags: FB_ACCEL_NONE, - vmode: FB_VMODE_NONINTERLACED, + .xres = 1024, + .yres = 768, + .xres_virtual = 1024, + .yres_virtual = 786, + .bits_per_pixel = 1, + .red = {0,2,0}, /* R */ + .green = {0,2,0}, /* G */ + .blue = {0,2,0}, /* B */ + .activate = FB_ACTIVATE_NOW, + .height = 274, + .width = 195, /* 14" monitor */ + .accel_flags = FB_ACCEL_NONE, + .vmode = FB_VMODE_NONINTERLACED, }; static struct display display; @@ -104,16 +104,14 @@ void hpfb_copyarea(struct fb_info *info, struct fb_copyarea *area) } static struct fb_ops hpfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: hpfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: hpfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = hpfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = hpfb_copyarea, + .fb_imageblit = cfb_imageblit, }; #define TOPCAT_FBOMSB 0x5d diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c index b6c0df7fcadf..a906dcbee668 100644 --- a/drivers/video/igafb.c +++ b/drivers/video/igafb.c @@ -401,15 +401,15 @@ static int igafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, * Framebuffer option structure */ static struct fb_ops igafb_ops = { - owner: THIS_MODULE, - fb_get_fix: igafb_get_fix, - fb_get_var: igafb_get_var, - fb_set_var: igafb_set_var, - fb_get_cmap: igafb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: igafb_setcolreg, + .owner = THIS_MODULE, + .fb_get_fix = igafb_get_fix, + .fb_get_var = igafb_get_var, + .fb_set_var = igafb_set_var, + .fb_get_cmap = igafb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = igafb_setcolreg, #ifdef __sparc__ - fb_mmap: igafb_mmap, + .fb_mmap = igafb_mmap, #endif }; diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index bdd685317aba..ac64a23248a2 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -1122,58 +1122,58 @@ imsttfbcon_revc (struct display *disp, int sx, int sy) #ifdef FBCON_HAS_CFB8 static struct display_switch fbcon_imstt8 = { - setup: fbcon_cfb8_setup, - bmove: imsttfbcon_bmove, - clear: imsttfbcon_clear, - putc: fbcon_cfb8_putc, - putcs: fbcon_cfb8_putcs, - revc: imsttfbcon_revc, - cursor: imsttfbcon_cursor, - set_font: imsttfbcon_set_font, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb8_setup, + .bmove = imsttfbcon_bmove, + .clear = imsttfbcon_clear, + .putc = fbcon_cfb8_putc, + .putcs = fbcon_cfb8_putcs, + .revc = imsttfbcon_revc, + .cursor = imsttfbcon_cursor, + .set_font = imsttfbcon_set_font, + .clear_margins =fbcon_cfb8_clear_margins, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif #ifdef FBCON_HAS_CFB16 static struct display_switch fbcon_imstt16 = { - setup: fbcon_cfb16_setup, - bmove: imsttfbcon_bmove, - clear: imsttfbcon_clear, - putc: fbcon_cfb16_putc, - putcs: fbcon_cfb16_putcs, - revc: imsttfbcon_revc, - cursor: imsttfbcon_cursor, - set_font: imsttfbcon_set_font, - clear_margins: fbcon_cfb16_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb16_setup, + .bmove = imsttfbcon_bmove, + .clear = imsttfbcon_clear, + .putc = fbcon_cfb16_putc, + .putcs = fbcon_cfb16_putcs, + .revc = imsttfbcon_revc, + .cursor = imsttfbcon_cursor, + .set_font = imsttfbcon_set_font, + .clear_margins =fbcon_cfb16_clear_margins, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif #ifdef FBCON_HAS_CFB24 static struct display_switch fbcon_imstt24 = { - setup: fbcon_cfb24_setup, - bmove: imsttfbcon_bmove, - clear: imsttfbcon_clear, - putc: fbcon_cfb24_putc, - putcs: fbcon_cfb24_putcs, - revc: imsttfbcon_revc, - cursor: imsttfbcon_cursor, - set_font: imsttfbcon_set_font, - clear_margins: fbcon_cfb24_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb24_setup, + .bmove = imsttfbcon_bmove, + .clear = imsttfbcon_clear, + .putc = fbcon_cfb24_putc, + .putcs = fbcon_cfb24_putcs, + .revc = imsttfbcon_revc, + .cursor = imsttfbcon_cursor, + .set_font = imsttfbcon_set_font, + .clear_margins =fbcon_cfb24_clear_margins, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif #ifdef FBCON_HAS_CFB32 static struct display_switch fbcon_imstt32 = { - setup: fbcon_cfb32_setup, - bmove: imsttfbcon_bmove, - clear: imsttfbcon_clear, - putc: fbcon_cfb32_putc, - putcs: fbcon_cfb32_putcs, - revc: imsttfbcon_revc, - cursor: imsttfbcon_cursor, - set_font: imsttfbcon_set_font, - clear_margins: fbcon_cfb32_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb32_setup, + .bmove = imsttfbcon_bmove, + .clear = imsttfbcon_clear, + .putc = fbcon_cfb32_putc, + .putcs = fbcon_cfb32_putcs, + .revc = imsttfbcon_revc, + .cursor = imsttfbcon_cursor, + .set_font = imsttfbcon_set_font, + .clear_margins =fbcon_cfb32_clear_margins, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -1617,23 +1617,23 @@ static struct pci_device_id imsttfb_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl); static struct pci_driver imsttfb_pci_driver = { - name: "imsttfb", - id_table: imsttfb_pci_tbl, - probe: imsttfb_probe, - remove: __devexit_p(imsttfb_remove), + .name = "imsttfb", + .id_table = imsttfb_pci_tbl, + .probe = imsttfb_probe, + .remove = __devexit_p(imsttfb_remove), }; static struct fb_ops imsttfb_ops = { - owner: THIS_MODULE, - fb_get_fix: imsttfb_get_fix, - fb_get_var: imsttfb_get_var, - fb_set_var: imsttfb_set_var, - fb_get_cmap: imsttfb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: imsttfb_setcolreg, - fb_pan_display: imsttfb_pan_display, - fb_blank: imsttfb_blank, - fb_ioctl: imsttfb_ioctl, + .owner = THIS_MODULE, + .fb_get_fix = imsttfb_get_fix, + .fb_get_var = imsttfb_get_var, + .fb_set_var = imsttfb_set_var, + .fb_get_cmap = imsttfb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = imsttfb_setcolreg, + .fb_pan_display =imsttfb_pan_display, + .fb_blank = imsttfb_blank, + .fb_ioctl = imsttfb_ioctl, }; static int diff --git a/drivers/video/leofb.c b/drivers/video/leofb.c index 296c0fcbb318..bc4987e3ccd5 100644 --- a/drivers/video/leofb.c +++ b/drivers/video/leofb.c @@ -451,13 +451,13 @@ static void leo_restore_palette (struct fb_info_sbusfb *fb) } static struct display_switch leo_dispsw __initdata = { - setup: leo_setup, - bmove: fbcon_redraw_bmove, - clear: leo_clear, - putc: leo_putc, - putcs: leo_putcs, - revc: leo_revc, - fontwidthmask: FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ + .setup = leo_setup, + .bmove = fbcon_redraw_bmove, + .clear = leo_clear, + .putc = leo_putc, + .putcs = leo_putcs, + .revc = leo_revc, + .fontwidthmask =FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */ }; static void leo_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue) diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index 54c420637687..252cf713c4a2 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -58,21 +58,29 @@ #define CSC_BASE 0x50F20000 static int (*macfb_setpalette) (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) = NULL; + unsigned int green, unsigned int blue, + struct fb_info *info) = NULL; static int valkyrie_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *info); static int dafb_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static int rbv_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static int mdc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static int toby_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static int civic_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static int csc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue); + unsigned int green, unsigned int blue, + struct fb_info *fb_info); static volatile struct { unsigned char addr; @@ -148,31 +156,32 @@ struct jet_cmap_regs { static int video_slot = 0; static struct fb_var_screeninfo macfb_defined = { - bits_per_pixel: 8, - activae: FB_ACTIVATE_NOW, - width: -1, - height: -1, - right_margin: 32, - upper_margin: 16, - lower_margin: 4, - vsync_len: 4, - vmode: FB_VMODE_NONINTERLACED, + .bits_per_pixel = 8, + .activate = FB_ACTIVATE_NOW, + .width = -1, + .height = -1, + .right_margin = 32, + .upper_margin = 16, + .lower_margin = 4, + .vsync_len = 4, + .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo vesafb_fix = { - id: "Macintosh ", - type: FB_TYPE_PACKED_PIXELS, - accel: FB_ACCEL_NONE, +static struct fb_fix_screeninfo macfb_fix = { + .id = "Macintosh ", + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, }; static struct display disp; static struct fb_info fb_info; static u32 pseudo_palette[17]; -static int inverse = 0; -static int vidtest = 0; +static int inverse = 0; +static int vidtest = 0; static int valkyrie_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { unsigned long flags; @@ -180,8 +189,7 @@ static int valkyrie_setpalette (unsigned int regno, unsigned int red, green >>= 8; blue >>= 8; - save_flags(flags); - cli(); + local_irq_save(flags); /* tell clut which address to fill */ nubus_writeb(regno, &valkyrie_cmap_regs->addr); @@ -194,8 +202,7 @@ static int valkyrie_setpalette (unsigned int regno, unsigned int red, nop(); nubus_writeb(blue, &valkyrie_cmap_regs->lut); - restore_flags(flags); - + local_irq_restore(flags); return 0; } @@ -204,7 +211,8 @@ static int valkyrie_setpalette (unsigned int regno, unsigned int red, kidding!) and simply set them one by one until we hit the one we want. */ static int dafb_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { /* FIXME: really, really need to use ioremap() here, phys_to_virt() doesn't work anymore */ @@ -215,8 +223,7 @@ static int dafb_setpalette (unsigned int regno, unsigned int red, green >>= 8; blue >>= 8; - save_flags(flags); - cli(); + local_irq_save(flags); /* fbcon will set an entire colourmap, but X won't. Hopefully this should accomodate both of them */ @@ -229,11 +236,11 @@ static int dafb_setpalette (unsigned int regno, unsigned int red, /* Loop until we get to the register we want */ for (i = 0; i < regno; i++) { - nubus_writeb(palette[i].red >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap[i].red >> 8, &dafb_cmap_regs->lut); nop(); - nubus_writeb(palette[i].green >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap[i].green >> 8, &dafb_cmap_regs->lut); nop(); - nubus_writeb(palette[i].blue >> 8, &dafb_cmap_regs->lut); + nubus_writeb(info->cmap[i].blue >> 8, &dafb_cmap_regs->lut); nop(); } } @@ -244,26 +251,26 @@ static int dafb_setpalette (unsigned int regno, unsigned int red, nop(); nubus_writeb(blue, &dafb_cmap_regs->lut); - restore_flags(flags); - + local_irq_restore(flags); lastreg = regno; return 0; } /* V8 and Brazil seem to use the same DAC. Sonora does as well. */ static int v8_brazil_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { + unsigned int bpp = info->var.bits_per_pixel; unsigned char _red =red>>8; unsigned char _green=green>>8; unsigned char _blue =blue>>8; unsigned char _regno; unsigned long flags; - if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ + if (bpp > 8) return 1; /* failsafe */ - save_flags(flags); - cli(); + local_irq_save(flags); /* On these chips, the CLUT register numbers are spread out across the register space. Thus: @@ -273,7 +280,7 @@ static int v8_brazil_setpalette (unsigned int regno, unsigned int red, In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */ - _regno = (regno<<(8 - info->var.bits_per_pixel)) | (0xFF >> info->var.vits_per_pixel); + _regno = (regno << (8 - bpp)) | (0xFF >> bpp); nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop(); /* send one color channel at a time */ @@ -281,13 +288,13 @@ static int v8_brazil_setpalette (unsigned int regno, unsigned int red, nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop(); nubus_writeb(_blue, &v8_brazil_cmap_regs->lut); - restore_flags(flags); - + local_irq_restore(flags); return 0; } static int rbv_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { /* use MSBs */ unsigned char _red =red>>8; @@ -298,8 +305,7 @@ static int rbv_setpalette (unsigned int regno, unsigned int red, if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ - save_flags(flags); - cli(); + local_irq_save(flags); /* From the VideoToolbox driver. Seems to be saying that * regno #254 and #255 are the important ones for 1-bit color, @@ -318,14 +324,14 @@ static int rbv_setpalette (unsigned int regno, unsigned int red, nubus_writeb(_green, &rbv_cmap_regs->lut); nop(); nubus_writeb(_blue, &rbv_cmap_regs->lut); - restore_flags(flags); - /* done. */ + local_irq_restore(flags); /* done. */ return 0; } /* Macintosh Display Card (8x24) */ static int mdc_setpalette(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { volatile struct mdc_cmap_regs *cmap_regs = nubus_slot_addr(video_slot); @@ -336,8 +342,7 @@ static int mdc_setpalette(unsigned int regno, unsigned int red, unsigned char _regno=regno; unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); /* the nop's are there to order writes. */ nubus_writeb(_regno, &cmap_regs->addr); nop(); @@ -345,38 +350,40 @@ static int mdc_setpalette(unsigned int regno, unsigned int red, nubus_writeb(_green, &cmap_regs->lut); nop(); nubus_writeb(_blue, &cmap_regs->lut); - restore_flags(flags); + local_irq_restore(flags); return 0; } /* Toby frame buffer */ static int toby_setpalette(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { volatile struct toby_cmap_regs *cmap_regs = nubus_slot_addr(video_slot); + unsigned int bpp = info->var.bits_per_pixel; /* use MSBs */ unsigned char _red =~(red>>8); unsigned char _green=~(green>>8); unsigned char _blue =~(blue>>8); - unsigned char _regno = (regno << (8 - info->var.bits_per_pixel)) | (0xFF >> info->var.bits_per_pixel); + unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp); unsigned long flags; - save_flags(flags); - cli(); - + local_irq_save(flags); + nubus_writeb(_regno, &cmap_regs->addr); nop(); nubus_writeb(_red, &cmap_regs->lut); nop(); nubus_writeb(_green, &cmap_regs->lut); nop(); nubus_writeb(_blue, &cmap_regs->lut); - restore_flags(flags); + local_irq_restore(flags); return 0; } /* Jet frame buffer */ static int jet_setpalette(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { volatile struct jet_cmap_regs *cmap_regs = nubus_slot_addr(video_slot); @@ -386,15 +393,14 @@ static int jet_setpalette(unsigned int regno, unsigned int red, unsigned char _blue = (blue>>8); unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); nubus_writeb(regno, &cmap_regs->addr); nop(); nubus_writeb(_red, &cmap_regs->lut); nop(); nubus_writeb(_green, &cmap_regs->lut); nop(); nubus_writeb(_blue, &cmap_regs->lut); - restore_flags(flags); + local_irq_restore(flags); return 0; } @@ -410,7 +416,8 @@ static int jet_setpalette(unsigned int regno, unsigned int red, * FIXME: this doesn't seem to work anymore. */ static int civic_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { static int lastreg = -1; unsigned long flags; @@ -422,8 +429,7 @@ static int civic_setpalette (unsigned int regno, unsigned int red, green >>= 8; blue >>= 8; - save_flags(flags); - cli(); + local_irq_save(flags); /* * Set the register address @@ -437,7 +443,7 @@ static int civic_setpalette (unsigned int regno, unsigned int red, #if 0 { #define CIVIC_VBL_OFFSET 0x120 - volatile unsigned long *vbl = readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET); + volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET); /* do interrupt setup stuff here? */ *vbl = 0L; nop(); /* clear */ *vbl = 1L; nop(); /* set */ @@ -491,8 +497,7 @@ static int civic_setpalette (unsigned int regno, unsigned int red, nubus_writeb( junk, &civic_cmap_regs->lut); nop(); } - restore_flags(flags); - + local_irq_restore(flags); lastreg = regno; return 0; } @@ -504,7 +509,8 @@ static int civic_setpalette (unsigned int regno, unsigned int red, */ static int csc_setpalette (unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue) + unsigned int green, unsigned int blue, + struct fb_info *info) { mdelay(1); csc_cmap_regs->clut_waddr = regno; @@ -533,20 +539,10 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, /* We shouldn't get here */ break; case 2: - if (macfb_setpalette) - macfb_setpalette(regno, red, green, blue); - else - return 1; - break; case 4: - if (macfb_setpalette) - macfb_setpalette(regno, red, green, blue); - else - return 1; - break; case 8: if (macfb_setpalette) - macfb_setpalette(regno, red, green, blue); + macfb_setpalette(regno, red, green, blue, info); else return 1; break; @@ -591,16 +587,14 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops macfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: macfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = macfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; void __init macfb_setup(char *options, int *ints) @@ -652,7 +646,7 @@ void __init macfb_init(void) printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024); printk("macfb: mode is %dx%dx%d, linelength=%d\n", - macfb_defined.xres, macfb_defined.yres/, macfb_defined.bits_per_pixel, macfb_fix.line_length); + macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length); /* * Fill in the available video resolution @@ -968,11 +962,11 @@ void __init macfb_init(void) fb_info.disp = &disp; fb_info.switch_con = gen_switch; fb_info.updatevar = gen_update_var; - fb_info.pseudo_palatte = pseudo_palette; + fb_info.pseudo_palette = pseudo_palette; fb_info.flags = FBINFO_FLAG_DEFAULT; fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); - gen_set_disp(-1, info); + gen_set_disp(-1, &fb_info); if (register_framebuffer(&fb_info) < 0) return; diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c index 5a0048b72a35..817e45cfa078 100644 --- a/drivers/video/matrox/matroxfb_accel.c +++ b/drivers/video/matrox/matroxfb_accel.c @@ -1058,79 +1058,79 @@ static int matrox_text_setfont(struct display* p, int width, int height) { #ifdef FBCON_HAS_VGATEXT static struct display_switch matroxfb_text = { - setup: matrox_text_setup, - bmove: matrox_text_bmove, - clear: matrox_text_clear, - putc: matrox_text_putc, - putcs: matrox_text_putcs, - revc: matrox_text_revc, - cursor: matrox_text_cursor, - set_font: matrox_text_setfont, - fontwidthmask: FONTWIDTH(8)|FONTWIDTH(9) + .setup = matrox_text_setup, + .bmove = matrox_text_bmove, + .clear = matrox_text_clear, + .putc = matrox_text_putc, + .putcs = matrox_text_putcs, + .revc = matrox_text_revc, + .cursor = matrox_text_cursor, + .set_font = matrox_text_setfont, + .fontwidthmask =FONTWIDTH(8)|FONTWIDTH(9) }; #endif #ifdef FBCON_HAS_CFB4 static struct display_switch matroxfb_cfb4 = { - setup: fbcon_cfb4_setup, - bmove: matrox_cfb4_bmove, - clear: matrox_cfb4_clear, - putc: fbcon_cfb4_putc, - putcs: fbcon_cfb4_putcs, - revc: matrox_cfb4_revc, - fontwidthmask: FONTWIDTH(8) /* fix, fix, fix it */ + .setup = fbcon_cfb4_setup, + .bmove = matrox_cfb4_bmove, + .clear = matrox_cfb4_clear, + .putc = fbcon_cfb4_putc, + .putcs = fbcon_cfb4_putcs, + .revc = matrox_cfb4_revc, + .fontwidthmask =FONTWIDTH(8) /* fix, fix, fix it */ }; #endif #ifdef FBCON_HAS_CFB8 static struct display_switch matroxfb_cfb8 = { - setup: fbcon_cfb8_setup, - bmove: matrox_cfbX_bmove, - clear: matrox_cfb8_clear, - putc: matrox_cfb8_putc, - putcs: matrox_cfb8_putcs, - revc: matrox_cfb8_revc, - clear_margins: matrox_cfbX_clear_margins, - fontwidthmask: ~1 /* FONTWIDTHS */ + .setup = fbcon_cfb8_setup, + .bmove = matrox_cfbX_bmove, + .clear = matrox_cfb8_clear, + .putc = matrox_cfb8_putc, + .putcs = matrox_cfb8_putcs, + .revc = matrox_cfb8_revc, + .clear_margins =matrox_cfbX_clear_margins, + .fontwidthmask =~1 /* FONTWIDTHS */ }; #endif #ifdef FBCON_HAS_CFB16 static struct display_switch matroxfb_cfb16 = { - setup: fbcon_cfb16_setup, - bmove: matrox_cfbX_bmove, - clear: matrox_cfb16_clear, - putc: matrox_cfb16_putc, - putcs: matrox_cfb16_putcs, - revc: matrox_cfb16_revc, - clear_margins: matrox_cfbX_clear_margins, - fontwidthmask: ~1 /* FONTWIDTHS */ + .setup = fbcon_cfb16_setup, + .bmove = matrox_cfbX_bmove, + .clear = matrox_cfb16_clear, + .putc = matrox_cfb16_putc, + .putcs = matrox_cfb16_putcs, + .revc = matrox_cfb16_revc, + .clear_margins =matrox_cfbX_clear_margins, + .fontwidthmask =~1 /* FONTWIDTHS */ }; #endif #ifdef FBCON_HAS_CFB24 static struct display_switch matroxfb_cfb24 = { - setup: fbcon_cfb24_setup, - bmove: matrox_cfbX_bmove, - clear: matrox_cfb24_clear, - putc: matrox_cfb24_putc, - putcs: matrox_cfb24_putcs, - revc: matrox_cfb24_revc, - clear_margins: matrox_cfbX_clear_margins, - fontwidthmask: ~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */ + .setup = fbcon_cfb24_setup, + .bmove = matrox_cfbX_bmove, + .clear = matrox_cfb24_clear, + .putc = matrox_cfb24_putc, + .putcs = matrox_cfb24_putcs, + .revc = matrox_cfb24_revc, + .clear_margins =matrox_cfbX_clear_margins, + .fontwidthmask =~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */ }; #endif #ifdef FBCON_HAS_CFB32 static struct display_switch matroxfb_cfb32 = { - setup: fbcon_cfb32_setup, - bmove: matrox_cfbX_bmove, - clear: matrox_cfb32_clear, - putc: matrox_cfb32_putc, - putcs: matrox_cfb32_putcs, - revc: matrox_cfb32_revc, - clear_margins: matrox_cfbX_clear_margins, - fontwidthmask: ~1 /* FONTWIDTHS */ + .setup = fbcon_cfb32_setup, + .bmove = matrox_cfbX_bmove, + .clear = matrox_cfb32_clear, + .putc = matrox_cfb32_putc, + .putcs = matrox_cfb32_putcs, + .revc = matrox_cfb32_revc, + .clear_margins =matrox_cfbX_clear_margins, + .fontwidthmask =~1 /* FONTWIDTHS */ }; #endif diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 688a79656f91..9912fa946907 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -1181,18 +1181,18 @@ static int matroxfb_blank(int blank, struct fb_info *info) } static struct fb_ops matroxfb_ops = { - owner: THIS_MODULE, - fb_open: matroxfb_open, - fb_release: matroxfb_release, - fb_get_fix: matroxfb_get_fix, - fb_get_var: matroxfb_get_var, - fb_set_var: matroxfb_set_var, - fb_get_cmap: matroxfb_get_cmap, - fb_set_cmap: matroxfb_set_cmap, - fb_setcolreg: matroxfb_setcolreg, - fb_pan_display: matroxfb_pan_display, - fb_blank: matroxfb_blank, - fb_ioctl: matroxfb_ioctl, + .owner = THIS_MODULE, + .fb_open = matroxfb_open, + .fb_release = matroxfb_release, + .fb_get_fix = matroxfb_get_fix, + .fb_get_var = matroxfb_get_var, + .fb_set_var = matroxfb_set_var, + .fb_get_cmap = matroxfb_get_cmap, + .fb_set_cmap = matroxfb_set_cmap, + .fb_setcolreg = matroxfb_setcolreg, + .fb_pan_display =matroxfb_pan_display, + .fb_blank = matroxfb_blank, + .fb_ioctl = matroxfb_ioctl, }; int matroxfb_switch(int con, struct fb_info *info) @@ -2133,10 +2133,10 @@ MODULE_DEVICE_TABLE(pci, matroxfb_devices); static struct pci_driver matroxfb_driver = { - name: "matroxfb", - id_table: matroxfb_devices, - probe: matroxfb_probe, - remove: pci_remove_matrox, + .name = "matroxfb", + .id_table = matroxfb_devices, + .probe = matroxfb_probe, + .remove = pci_remove_matrox, }; /* **************************** init-time only **************************** */ diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c index a26d8e56810d..7bc8aea94f8c 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/matrox/matroxfb_crtc2.c @@ -619,18 +619,18 @@ static int matroxfb_dh_blank(int blank, struct fb_info* info) { } static struct fb_ops matroxfb_dh_ops = { - owner: THIS_MODULE, - fb_open: matroxfb_dh_open, - fb_release: matroxfb_dh_release, - fb_get_fix: matroxfb_dh_get_fix, - fb_get_var: matroxfb_dh_get_var, - fb_set_var: matroxfb_dh_set_var, - fb_get_cmap: matroxfb_dh_get_cmap, - fb_set_cmap: matroxfb_dh_set_cmap, - fb_setcolreg: matroxfb_dh_setcolreg, - fb_pan_display: matroxfb_dh_pan_display, - fb_blank: matroxfb_dh_blank, - fb_ioctl: matroxfb_dh_ioctl, + .owner = THIS_MODULE, + .fb_open = matroxfb_dh_open, + .fb_release = matroxfb_dh_release, + .fb_get_fix = matroxfb_dh_get_fix, + .fb_get_var = matroxfb_dh_get_var, + .fb_set_var = matroxfb_dh_set_var, + .fb_get_cmap = matroxfb_dh_get_cmap, + .fb_set_cmap = matroxfb_dh_set_cmap, + .fb_setcolreg = matroxfb_dh_setcolreg, + .fb_pan_display =matroxfb_dh_pan_display, + .fb_blank = matroxfb_dh_blank, + .fb_ioctl = matroxfb_dh_ioctl, }; static int matroxfb_dh_switch(int con, struct fb_info* info) { @@ -826,9 +826,9 @@ static void matroxfb_crtc2_remove(struct matrox_fb_info* minfo, void* crtc2) { } static struct matroxfb_driver crtc2 = { - name: "Matrox G400 CRTC2", - probe: matroxfb_crtc2_probe, - remove: matroxfb_crtc2_remove }; + .name = "Matrox G400 CRTC2", + .probe = matroxfb_crtc2_probe, + .remove = matroxfb_crtc2_remove }; static int matroxfb_crtc2_init(void) { matroxfb_register_driver(&crtc2); diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c index d0e58cf76150..f07d3b26209b 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/matrox/matroxfb_g450.c @@ -126,9 +126,9 @@ static void matroxfb_g450_remove(struct matrox_fb_info* minfo, void* g450) { } static struct matroxfb_driver g450 = { - name: "Matrox G450 output #2", - probe: matroxfb_g450_probe, - remove: matroxfb_g450_remove }; + .name = "Matrox G450 output #2", + .probe = matroxfb_g450_probe, + .remove = matroxfb_g450_remove }; static int matroxfb_g450_init(void) { matroxfb_register_driver(&g450); diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c index 081bbc442e3b..6e1fd2f76347 100644 --- a/drivers/video/maxinefb.c +++ b/drivers/video/maxinefb.c @@ -45,23 +45,23 @@ static struct fb_info fb_info; static struct display disp; static struct fb_var_screeninfo maxinefb_defined = { - xres: 1024, - yres: 768, - xres_virtual: 1024, - yres_virtual: 768, - bits_per_pixel: 8, - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - vmode: FB_VMODE_NONINTERLACED, + .xres = 1024, + .yres = 768, + .xres_virtual = 1024, + .yres_virtual = 768, + .bits_per_pixel =8, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo maxinefb_fix = { - id: "Maxine onboard graphics 1024x768x8", - smem_len: (1024*768), - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - line_length: 1024, + .id = "Maxine onboard graphics 1024x768x8", + .smem_len = (1024*768), + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .line_length = 1024, } /* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */ @@ -111,16 +111,14 @@ static int maxinefb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops maxinefb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: maxinefb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = maxinefb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; int __init maxinefb_init(void) diff --git a/drivers/video/mdacon.c b/drivers/video/mdacon.c index 06b76f8f124d..f1c47bfaa270 100644 --- a/drivers/video/mdacon.c +++ b/drivers/video/mdacon.c @@ -587,22 +587,22 @@ static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) */ const struct consw mda_con = { - con_startup: mdacon_startup, - con_init: mdacon_init, - con_deinit: mdacon_deinit, - con_clear: mdacon_clear, - con_putc: mdacon_putc, - con_putcs: mdacon_putcs, - con_cursor: mdacon_cursor, - con_scroll: mdacon_scroll, - con_bmove: mdacon_bmove, - con_switch: mdacon_switch, - con_blank: mdacon_blank, - con_font_op: mdacon_font_op, - con_set_palette: mdacon_set_palette, - con_scrolldelta: mdacon_scrolldelta, - con_build_attr: mdacon_build_attr, - con_invert_region: mdacon_invert_region, + .con_startup = mdacon_startup, + .con_init = mdacon_init, + .con_deinit = mdacon_deinit, + .con_clear = mdacon_clear, + .con_putc = mdacon_putc, + .con_putcs = mdacon_putcs, + .con_cursor = mdacon_cursor, + .con_scroll = mdacon_scroll, + .con_bmove = mdacon_bmove, + .con_switch = mdacon_switch, + .con_blank = mdacon_blank, + .con_font_op = mdacon_font_op, + .con_set_palette = mdacon_set_palette, + .con_scrolldelta = mdacon_scrolldelta, + .con_build_attr = mdacon_build_attr, + .con_invert_region = mdacon_invert_region, }; void __init mda_console_init(void) diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index a6780efe78d4..08174b35099a 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -1386,20 +1386,18 @@ neo2200fb_imageblit(struct fb_info *info, struct fb_image *image) } static struct fb_ops neofb_ops = { - owner: THIS_MODULE, - fb_check_var: neofb_check_var, - fb_set_par: neofb_set_par, - fb_set_var: gen_set_var, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: neofb_setcolreg, - fb_pan_display: neofb_pan_display, - fb_blank: neofb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_check_var = neofb_check_var, + .fb_set_par = neofb_set_par, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = neofb_setcolreg, + .fb_pan_display = neofb_pan_display, + .fb_blank = neofb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; /* --------------------------------------------------------------------- */ @@ -1988,10 +1986,10 @@ static struct pci_device_id neofb_devices[] __devinitdata = { MODULE_DEVICE_TABLE(pci, neofb_devices); static struct pci_driver neofb_driver = { - name: "neofb", - id_table: neofb_devices, - probe: neofb_probe, - remove: __devexit_p(neofb_remove) + .name = "neofb", + .id_table = neofb_devices, + .probe = neofb_probe, + .remove = __devexit_p(neofb_remove) }; /* **************************** init-time only **************************** */ diff --git a/drivers/video/newport_con.c b/drivers/video/newport_con.c index 8e29717b1455..364874dff50d 100644 --- a/drivers/video/newport_con.c +++ b/drivers/video/newport_con.c @@ -700,22 +700,22 @@ static int newport_dummy(struct vc_data *c) #define DUMMY (void *) newport_dummy const struct consw newport_con = { - con_startup: newport_startup, - con_init: newport_init, - con_deinit: DUMMY, - con_clear: newport_clear, - con_putc: newport_putc, - con_putcs: newport_putcs, - con_cursor: newport_cursor, - con_scroll: newport_scroll, - con_bmove: newport_bmove, - con_switch: newport_switch, - con_blank: newport_blank, - con_font_op: newport_font_op, - con_set_palette: newport_set_palette, - con_scrolldelta: newport_scrolldelta, - con_set_origin: DUMMY, - con_save_screen: DUMMY + .con_startup = newport_startup, + .con_init = newport_init, + .con_deinit = DUMMY, + .con_clear = newport_clear, + .con_putc = newport_putc, + .con_putcs = newport_putcs, + .con_cursor = newport_cursor, + .con_scroll = newport_scroll, + .con_bmove = newport_bmove, + .con_switch = newport_switch, + .con_blank = newport_blank, + .con_font_op = newport_font_op, + .con_set_palette = newport_set_palette, + .con_scrolldelta = newport_scrolldelta, + .con_set_origin = DUMMY, + .con_save_screen = DUMMY }; #ifdef MODULE diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 49a91978ef58..4186b17c0d67 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -82,17 +82,15 @@ static void offb_init_fb(const char *name, const char *full_name, unsigned long address, struct device_node *dp); static struct fb_ops offb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: offb_setcolreg, - fb_blank: offb_blank, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = offb_setcolreg, + .fb_blank = offb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; /* @@ -399,7 +397,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct fb_info *info; - int i; if (!request_mem_region(res_start, res_size, "offb")) return; @@ -414,14 +411,15 @@ static void __init offb_init_fb(const char *name, const char *full_name, return; } - info = - kmalloc(sizeof(struct fb_info) + sizeof(struct display) + - sizeof(u32) * 17, GFP_ATOMIC); + size = sizeof(struct fb_info) + sizeof(struct display) + sizeof(u32) * 17; + + info = kmalloc(size, GFP_ATOMIC); + if (info == 0) { release_mem_region(res_start, res_size); return; } - memset(info, 0, sizeof(*info)); + memset(info, 0, size); fix = &info->fix; var = &info->var; @@ -465,7 +463,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, unsigned long base = address & 0xff000000UL; par->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0; - par->cmap_data = info->cmap_adr + 1; + par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; } else if (device_is_compatible(dp, "pci1014,b7")) { unsigned long regbase = dp->addrs[0].address; @@ -555,7 +553,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, } printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", - GET_FB_IDX(info->info.node), full_name); + GET_FB_IDX(info->node), full_name); } MODULE_LICENSE("GPL"); diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 001a0eb4a2fc..3aea0686edee 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -149,14 +149,14 @@ int platinum_init(void); int platinum_setup(char*); static struct fb_ops platinumfb_ops = { - owner: THIS_MODULE, - fb_get_fix: platinum_get_fix, - fb_get_var: platinum_get_var, - fb_set_var: platinum_set_var, - fb_get_cmap: platinum_get_cmap, - fb_set_cmap: platinum_set_cmap, - fb_setcolreg: platinum_setcolreg, - fb_blank: platinum_blank, + .owner = THIS_MODULE, + .fb_get_fix = platinum_get_fix, + .fb_get_var = platinum_get_var, + .fb_set_var = platinum_set_var, + .fb_get_cmap = platinum_get_cmap, + .fb_set_cmap = platinum_set_cmap, + .fb_setcolreg = platinum_setcolreg, + .fb_blank = platinum_blank, }; static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con, diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index b83288d8b70a..168f4ec92505 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -413,15 +413,15 @@ static int pm2fb_setcolreg(unsigned regno, unsigned transp, struct fb_info* info); static struct fb_ops pm2fb_ops={ - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: fbgen_set_cmap, - fb_pan_display: fbgen_pan_display, - fb_setcolreg: pm2fb_setcolreg, - fb_blank: fbgen_blank, + .owner = THIS_MODULE, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = fbgen_set_cmap, + .fb_pan_display =fbgen_pan_display, + .fb_setcolreg = pm2fb_setcolreg, + .fb_blank = fbgen_blank, }; /*************************************************************************** @@ -1434,23 +1434,23 @@ static void pm2fb_clear_margins8(struct vc_data* conp, struct display* p, } static struct display_switch pm2_cfb8 = { - setup: fbcon_cfb8_setup, - bmove: pm2fb_pp_bmove, + .setup = fbcon_cfb8_setup, + .bmove = pm2fb_pp_bmove, #ifdef __alpha__ /* Not sure why, but this works and the other does not. */ /* Also, perhaps we need a separate routine to wait for the blitter to stop before doing this? */ /* In addition, maybe we need to do this for 16 and 32 bit depths? */ - clear: fbcon_cfb8_clear, + .clear = fbcon_cfb8_clear, #else - clear: pm2fb_clear8, + .clear = pm2fb_clear8, #endif - putc: fbcon_cfb8_putc, - putcs: fbcon_cfb8_putcs, - revc: fbcon_cfb8_revc, - cursor: pm2fb_cursor, - set_font: pm2fb_set_font, - clear_margins: pm2fb_clear_margins8, + .putc = fbcon_cfb8_putc, + .putcs = fbcon_cfb8_putcs, + .revc = fbcon_cfb8_revc, + .cursor = pm2fb_cursor, + .set_font = pm2fb_set_font, + .clear_margins =pm2fb_clear_margins8, fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif /* FBCON_HAS_CFB8 */ @@ -1487,16 +1487,16 @@ static void pm2fb_clear_margins16(struct vc_data* conp, struct display* p, } static struct display_switch pm2_cfb16 = { - setup: fbcon_cfb16_setup, - bmove: pm2fb_pp_bmove, - clear: pm2fb_clear16, - putc: fbcon_cfb16_putc, - putcs: fbcon_cfb16_putcs, - revc: fbcon_cfb16_revc, - cursor: pm2fb_cursor, - set_font: pm2fb_set_font, - clear_margins: pm2fb_clear_margins16, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb16_setup, + .bmove = pm2fb_pp_bmove, + .clear = pm2fb_clear16, + .putc = fbcon_cfb16_putc, + .putcs = fbcon_cfb16_putcs, + .revc = fbcon_cfb16_revc, + .cursor = pm2fb_cursor, + .set_font = pm2fb_set_font, + .clear_margins =pm2fb_clear_margins16, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif /* FBCON_HAS_CFB16 */ @@ -1540,16 +1540,16 @@ static void pm2fb_clear_margins24(struct vc_data* conp, struct display* p, } static struct display_switch pm2_cfb24 = { - setup: fbcon_cfb24_setup, - bmove: pm2fb_bmove, - clear: pm2fb_clear24, - putc: fbcon_cfb24_putc, - putcs: fbcon_cfb24_putcs, - revc: fbcon_cfb24_revc, - cursor: pm2fb_cursor, - set_font: pm2fb_set_font, - clear_margins: pm2fb_clear_margins24, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb24_setup, + .bmove = pm2fb_bmove, + .clear = pm2fb_clear24, + .putc = fbcon_cfb24_putc, + .putcs = fbcon_cfb24_putcs, + .revc = fbcon_cfb24_revc, + .cursor = pm2fb_cursor, + .set_font = pm2fb_set_font, + .clear_margins =pm2fb_clear_margins24, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif /* FBCON_HAS_CFB24 */ @@ -1584,16 +1584,16 @@ static void pm2fb_clear_margins32(struct vc_data* conp, struct display* p, } static struct display_switch pm2_cfb32 = { - setup: fbcon_cfb32_setup, - bmove: pm2fb_bmove, - clear: pm2fb_clear32, - putc: fbcon_cfb32_putc, - putcs: fbcon_cfb32_putcs, - revc: fbcon_cfb32_revc, - cursor: pm2fb_cursor, - set_font: pm2fb_set_font, - clear_margins: pm2fb_clear_margins32, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb32_setup, + .bmove = pm2fb_bmove, + .clear = pm2fb_clear32, + .putc = fbcon_cfb32_putc, + .putcs = fbcon_cfb32_putcs, + .revc = fbcon_cfb32_revc, + .cursor = pm2fb_cursor, + .set_font = pm2fb_set_font, + .clear_margins =pm2fb_clear_margins32, + .fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif /* FBCON_HAS_CFB32 */ diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 6faeeb8bd10c..0653a9650718 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c @@ -688,16 +688,16 @@ struct fbgen_hwswitch pm3fb_switch = { }; static struct fb_ops pm3fb_ops = { - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: fbgen_set_cmap, - fb_setcolreg: pm3fb_setcolreg, - fb_pan_display: fbgen_pan_display, - fb_blank: fbgen_blank, - fb_ioctl: pm3fb_ioctl, + .owner = THIS_MODULE, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = fbgen_set_cmap, + .fb_setcolreg = pm3fb_setcolreg, + .fb_pan_display =fbgen_pan_display, + .fb_blank = fbgen_blank, + .fb_ioctl = pm3fb_ioctl, }; #endif /* KERNEL_2_4 or KERNEL_2_5 */ #ifdef PM3FB_USE_ACCEL diff --git a/drivers/video/pm3fb.h b/drivers/video/pm3fb.h index 78d934d1d109..a3c44ca252be 100644 --- a/drivers/video/pm3fb.h +++ b/drivers/video/pm3fb.h @@ -1281,4 +1281,4 @@ do { \ } \ } while (0) -#endif PM3FB_H +#endif /* PM3FB_H */ diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index 5bea6b7eecb4..aba95ee840c4 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c @@ -55,24 +55,24 @@ static struct fb_info pmagba_fb_info[3]; static struct display pmagba_disp[3]; static struct fb_var_screeninfo pmagbafb_defined = { - xres: 1024, - yres: 864, - xres_virtual: 1024, - yres_virtual: 864, - bits_per_pixel: 8, - activate: FB_ACTIVATE_NOW, - height: 274, - width: 195, - accel: FB_ACCEL_NONE, - vmode: FB_VMODE_NONINTERLACED, + .xres = 1024, + .yres = 864, + .xres_virtual = 1024, + .yres_virtual = 864, + .bits_per_pixel =8, + .activate = FB_ACTIVATE_NOW, + .height = 274, + .width = 195, + .accel = FB_ACCEL_NONE, + .vmode = FB_VMODE_NONINTERLACED, } static struct fb_fix_screeninfo pmagbafb_fix = { - id: "PMAG-BA", - smem_len: (1024 * 864), - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - line_length: 1024, + .id = "PMAG-BA", + .smem_len = (1024 * 864), + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .line_length = 1024, } /* @@ -110,16 +110,14 @@ static int pmagbafb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops pmagbafb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: pmagbafb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = pmagbafb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, } int __init pmagbafb_init_one(int slot) diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 8396ebf49a20..9d95f157ce46 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c @@ -58,24 +58,24 @@ static struct fb_info pmagbb_fb_info[3]; static struct display pmagbb_disp[3]; static struct fb_var_screeninfo pmagbbfb_defined = { - xres: 1280, - yres: 1024, - xres_virtual: 1280, - yres_virtual: 1024, - bits_per_pixel: 8, - activate: FB_ACTIVATE_NOW, - height: 274, - width: 195, - accel_flags: FB_ACCEL_NONE, - vmode: FB_VMODE_NONINTERLACED, + .xres = 1280, + .yres = 1024, + .xres_virtual = 1280, + .yres_virtual = 1024, + .bits_per_pixel =8, + .activate = FB_ACTIVATE_NOW, + .height = 274, + .width = 195, + .accel_flags = FB_ACCEL_NONE, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo pmagbafb_fix = { - id: "PMAGB-BA", - smem_len: (1280 * 1024), - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - line_length: 1280, + .id = "PMAGB-BA", + .smem_len = (1280 * 1024), + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .line_length = 1280, } /* @@ -113,16 +113,14 @@ static int pmagbbfb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops pmagbbfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: pmagbbfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = pmagbbfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; int __init pmagbbfb_init_one(int slot) diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c index ffd2d1ca25b3..d72ce48cb3f1 100644 --- a/drivers/video/promcon.c +++ b/drivers/video/promcon.c @@ -575,22 +575,22 @@ static int promcon_dummy(void) #define DUMMY (void *) promcon_dummy const struct consw prom_con = { - con_startup: promcon_startup, - con_init: promcon_init, - con_deinit: promcon_deinit, - con_clear: promcon_clear, - con_putc: promcon_putc, - con_putcs: promcon_putcs, - con_cursor: promcon_cursor, - con_scroll: promcon_scroll, - con_bmove: promcon_bmove, - con_switch: promcon_switch, - con_blank: promcon_blank, - con_font_op: promcon_font_op, - con_set_palette: DUMMY, - con_scrolldelta: DUMMY, + .con_startup = promcon_startup, + .con_init = promcon_init, + .con_deinit = promcon_deinit, + .con_clear = promcon_clear, + .con_putc = promcon_putc, + .con_putcs = promcon_putcs, + .con_cursor = promcon_cursor, + .con_scroll = promcon_scroll, + .con_bmove = promcon_bmove, + .con_switch = promcon_switch, + .con_blank = promcon_blank, + .con_font_op = promcon_font_op, + .con_set_palette = DUMMY, + .con_scrolldelta = DUMMY, #if !(PROMCON_COLOR) - con_build_attr: promcon_build_attr, + .con_build_attr = promcon_build_attr, #endif }; diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index f9ae2cddabbb..1b0725a11cbc 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -252,15 +252,15 @@ static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, int size); static struct fb_ops pvr2fb_ops = { - owner: THIS_MODULE, - fb_get_fix: pvr2fb_get_fix, - fb_get_var: pvr2fb_get_var, - fb_set_var: pvr2fb_set_var, - fb_get_cmap: pvr2fb_get_cmap, - fb_set_cmap: pvr2fb_set_cmap, - fb_setcolreg: pvr2fb_setcolreg, - fb_pan_display: pvr2fb_pan_display, - fb_blank: pvr2fb_blank, + .owner = THIS_MODULE, + .fb_get_fix = pvr2fb_get_fix, + .fb_get_var = pvr2fb_get_var, + .fb_set_var = pvr2fb_set_var, + .fb_get_cmap = pvr2fb_get_cmap, + .fb_set_cmap = pvr2fb_set_cmap, + .fb_setcolreg = pvr2fb_setcolreg, + .fb_pan_display = pvr2fb_pan_display, + .fb_blank = pvr2fb_blank, }; static struct fb_videomode pvr2_modedb[] __initdata = { diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index a456b949efbd..97b036f6cce0 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c @@ -37,27 +37,27 @@ static struct fb_info fb_info; static struct display display; static struct fb_fix_screeninfo q40fb_fix __initdata = { - id: "Q40", - smem_len: 1024*1024, - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_TRUECOLOR, - line_length: 1024*2, - accel: FB_ACCEL_NONE, + .id = "Q40", + .smem_len = 1024*1024, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 1024*2, + .accel = FB_ACCEL_NONE, }; static struct fb_var_screeninfo q40fb_var __initdata = { - xres: 1024, - yres: 512, - xres_virtual: 1024, - yres_virtual: 512, - bits_per_pixel: 16, - red: {6, 5, 0}, - green: {11, 5, 0}, - blue: {0, 6, 0}, - activate: FB_ACTIVATE_NOW, - height: 230, - width: 300, - vmode: FB_VMODE_NONINTERLACED, + .xres = 1024, + .yres = 512, + .xres_virtual = 1024, + .yres_virtual = 512, + .bits_per_pixel = 16, + .red = {6, 5, 0}, + .green = {11, 5, 0}, + .blue = {0, 6, 0}, + .activate = FB_ACTIVATE_NOW, + .height = 230, + .width = 300, + .vmode = FB_VMODE_NONINTERLACED, }; /* frame buffer operations */ @@ -68,16 +68,14 @@ static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green, struct fb_info *info); static struct fb_ops q40fb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: q40fb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = q40fb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green, diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index 2fe5994b36c1..b55a6b503e7c 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c @@ -602,23 +602,23 @@ extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev); #endif static struct fb_ops radeon_fb_ops = { - fb_get_fix: radeonfb_get_fix, - fb_get_var: radeonfb_get_var, - fb_set_var: radeonfb_set_var, - fb_get_cmap: radeonfb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: radeonfb_setcolreg, - fb_pan_display: radeonfb_pan_display, - fb_blank: radeonfb_blank, - fb_ioctl: radeonfb_ioctl, + .fb_get_fix = radeonfb_get_fix, + .fb_get_var = radeonfb_get_var, + .fb_set_var = radeonfb_set_var, + .fb_get_cmap = radeonfb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = radeonfb_setcolreg, + .fb_pan_display = radeonfb_pan_display, + .fb_blank = radeonfb_blank, + .fb_ioctl = radeonfb_ioctl, }; static struct pci_driver radeonfb_driver = { - name: "radeonfb", - id_table: radeonfb_pci_table, - probe: radeonfb_pci_register, - remove: __devexit_p(radeonfb_pci_unregister), + .name = "radeonfb", + .id_table = radeonfb_pci_table, + .probe = radeonfb_pci_register, + .remove = __devexit_p(radeonfb_pci_unregister), }; @@ -2485,13 +2485,13 @@ static void fbcon_radeon_clear(struct vc_data *conp, struct display *p, #ifdef FBCON_HAS_CFB8 static struct display_switch fbcon_radeon8 = { - setup: fbcon_cfb8_setup, - bmove: fbcon_radeon_bmove, - clear: fbcon_radeon_clear, - putc: fbcon_cfb8_putc, - putcs: fbcon_cfb8_putcs, - revc: fbcon_cfb8_revc, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb8_setup, + .bmove = fbcon_radeon_bmove, + .clear = fbcon_radeon_clear, + .putc = fbcon_cfb8_putc, + .putcs = fbcon_cfb8_putcs, + .revc = fbcon_cfb8_revc, + .clear_margins = fbcon_cfb8_clear_margins, + .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c index 4b5fcdb71c51..52ac100708bd 100644 --- a/drivers/video/retz3fb.c +++ b/drivers/video/retz3fb.c @@ -1312,14 +1312,14 @@ static int retz3fb_blank(int blank, struct fb_info *info) } static struct fb_ops retz3fb_ops = { - owner: THIS_MODULE, - fb_get_fix: retz3fb_get_fix, - fb_get_var: retz3fb_get_var, - fb_set_var: retz3fb_set_var, - fb_get_cmap: retz3fb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: retz3fb_setcolreg, - fb_blank: retz3fb_blank, + .owner = THIS_MODULE, + .fb_get_fix = retz3fb_get_fix, + .fb_get_var = retz3fb_get_var, + .fb_set_var = retz3fb_set_var, + .fb_get_cmap = retz3fb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = retz3fb_setcolreg, + .fb_blank = retz3fb_blank, }; int __init retz3fb_setup(char *options) diff --git a/drivers/video/riva/accel.c b/drivers/video/riva/accel.c index 557ffcb26470..bea186a5f46e 100644 --- a/drivers/video/riva/accel.c +++ b/drivers/video/riva/accel.c @@ -238,14 +238,14 @@ static void fbcon_riva8_clear_margins(struct vc_data *conp, struct display *p, } struct display_switch fbcon_riva8 = { - setup: fbcon_riva8_setup, - bmove: fbcon_riva_bmove, - clear: fbcon_riva8_clear, - putc: fbcon_riva8_putc, - putcs: fbcon_riva8_putcs, - revc: fbcon_riva8_revc, - clear_margins: fbcon_riva8_clear_margins, - fontwidthmask: FONTWIDTHRANGE(4, 16) + .setup = fbcon_riva8_setup, + .bmove = fbcon_riva_bmove, + .clear = fbcon_riva8_clear, + .putc = fbcon_riva8_putc, + .putcs = fbcon_riva8_putcs, + .revc = fbcon_riva8_revc, + .clear_margins =fbcon_riva8_clear_margins, + .fontwidthmask =FONTWIDTHRANGE(4, 16) }; #endif @@ -341,14 +341,14 @@ static void fbcon_riva16_clear_margins(struct vc_data *conp, struct display *p, } struct display_switch fbcon_riva16 = { - setup: fbcon_riva16_setup, - bmove: fbcon_riva_bmove, - clear: fbcon_riva16_clear, - putc: fbcon_riva16_putc, - putcs: fbcon_riva16_putcs, - revc: fbcon_riva1632_revc, - clear_margins: fbcon_riva16_clear_margins, - fontwidthmask: FONTWIDTHRANGE(4, 16) + .setup = fbcon_riva16_setup, + .bmove = fbcon_riva_bmove, + .clear = fbcon_riva16_clear, + .putc = fbcon_riva16_putc, + .putcs = fbcon_riva16_putcs, + .revc = fbcon_riva1632_revc, + .clear_margins =fbcon_riva16_clear_margins, + .fontwidthmask =FONTWIDTHRANGE(4, 16) }; #endif @@ -415,13 +415,13 @@ static void fbcon_riva32_clear_margins(struct vc_data *conp, struct display *p, } struct display_switch fbcon_riva32 = { - setup: fbcon_riva32_setup, - bmove: fbcon_riva_bmove, - clear: fbcon_riva32_clear, - putc: fbcon_riva32_putc, - putcs: fbcon_riva32_putcs, - revc: fbcon_riva1632_revc, - clear_margins: fbcon_riva32_clear_margins, - fontwidthmask: FONTWIDTHRANGE(4, 16) + .setup = fbcon_riva32_setup, + .bmove = fbcon_riva_bmove, + .clear = fbcon_riva32_clear, + .putc = fbcon_riva32_putc, + .putcs = fbcon_riva32_putcs, + .revc = fbcon_riva1632_revc, + .clear_margins =fbcon_riva32_clear_margins, + .fontwidthmask =FONTWIDTHRANGE(4, 16) }; #endif diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 77edfb918c9a..fa083a87938c 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -266,32 +266,32 @@ static char *font = NULL; #endif static struct fb_var_screeninfo rivafb_default_var = { - xres: 640, - yres: 480, - xres_virtual: 640, - yres_virtual: 480, - xoffset: 0, - yoffset: 0, - bits_per_pixel: 8, - grayscale: 0, - red: {0, 6, 0}, - green: {0, 6, 0}, - blue: {0, 6, 0}, - transp: {0, 0, 0}, - nonstd: 0, - activate: 0, - height: -1, - width: -1, - accel_flags: 0, - pixclock: 39721, - left_margin: 40, - right_margin: 24, - upper_margin: 32, - lower_margin: 11, - hsync_len: 96, - vsync_len: 2, - sync: 0, - vmode: FB_VMODE_NONINTERLACED + .xres = 640, + .yres = 480, + .xres_virtual = 640, + .yres_virtual = 480, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel =8, + .grayscale = 0, + .red = {0, 6, 0}, + .green = {0, 6, 0}, + .blue = {0, 6, 0}, + .transp = {0, 0, 0}, + .nonstd = 0, + .activate = 0, + .height = -1, + .width = -1, + .accel_flags = 0, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED }; /* from GGI */ @@ -1744,17 +1744,17 @@ static int rivafb_blank(int blank, struct fb_info *info) /* kernel interface */ static struct fb_ops riva_fb_ops = { - owner: THIS_MODULE, - fb_get_fix: rivafb_get_fix, - fb_get_var: rivafb_get_var, - fb_set_var: rivafb_set_var, - fb_get_cmap: rivafb_get_cmap, - fb_set_cmap: rivafb_set_cmap, - fb_setcolreg: rivafb_setcolreg, - fb_pan_display: rivafb_pan_display, - fb_blank: rivafb_blank, - fb_ioctl: rivafb_ioctl, - fb_rasterimg: rivafb_rasterimg, + .owner = THIS_MODULE, + .fb_get_fix = rivafb_get_fix, + .fb_get_var = rivafb_get_var, + .fb_set_var = rivafb_set_var, + .fb_get_cmap = rivafb_get_cmap, + .fb_set_cmap = rivafb_set_cmap, + .fb_setcolreg = rivafb_setcolreg, + .fb_pan_display =rivafb_pan_display, + .fb_blank = rivafb_blank, + .fb_ioctl = rivafb_ioctl, + .fb_rasterimg = rivafb_rasterimg, }; static int __devinit riva_init_disp_var(struct rivafb_info *rinfo) @@ -2081,10 +2081,10 @@ int __init rivafb_setup(char *options) #endif /* !MODULE */ static struct pci_driver rivafb_driver = { - name: "rivafb", - id_table: rivafb_pci_tbl, - probe: rivafb_init_one, - remove: __devexit_p(rivafb_remove_one), + .name = "rivafb", + .id_table = rivafb_pci_tbl, + .probe = rivafb_init_one, + .remove = __devexit_p(rivafb_remove_one), }; diff --git a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c index 7601ae58ed0d..a9c1295d1854 100644 --- a/drivers/video/sbusfb.c +++ b/drivers/video/sbusfb.c @@ -112,18 +112,18 @@ static int sbusfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info); static struct fb_ops sbusfb_ops = { - owner: THIS_MODULE, - fb_open: sbusfb_open, - fb_release: sbusfb_release, - fb_get_fix: sbusfb_get_fix, - fb_get_var: sbusfb_get_var, - fb_set_var: sbusfb_set_var, - fb_get_cmap: sbusfb_get_cmap, - fb_set_cmap: sbusfb_set_cmap, - fb_setcolreg: sbusfb_setcolreg, - fb_blank: sbusfb_blank, - fb_ioctl: sbusfb_ioctl, - fb_mmap: sbusfb_mmap, + .owner = THIS_MODULE, + .fb_open = sbusfb_open, + .fb_release = sbusfb_release, + .fb_get_fix = sbusfb_get_fix, + .fb_get_var = sbusfb_get_var, + .fb_set_var = sbusfb_set_var, + .fb_get_cmap = sbusfb_get_cmap, + .fb_set_cmap = sbusfb_set_cmap, + .fb_setcolreg = sbusfb_setcolreg, + .fb_blank = sbusfb_blank, + .fb_ioctl = sbusfb_ioctl, + .fb_mmap = sbusfb_mmap, }; /* diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 1af77475c3f7..59400e61e448 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -55,34 +55,34 @@ static int ypan = 0; static int ywrap = 0; static struct fb_fix_screeninfo sgivwfb_fix __initdata = { - id: "SGI Vis WS FB", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - mmio_start: DBE_REG_PHYS, - mmio_len: DBE_REG_SIZE, - accel_flags: FB_ACCEL_NONE + .id = "SGI Vis WS FB", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .mmio_start = DBE_REG_PHYS, + .mmio_len = DBE_REG_SIZE, + .accel_flags = FB_ACCEL_NONE }; static struct fb_var_screeninfo sgivwfb_var __initdata = { /* 640x480, 8 bpp */ - 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}, - height: -1, - width: -1, - pixclock: 20000, - left_margin: 64, - right_margin: 64, - upper_margin: 32, - lower_margin: 32, - hsync_len: 64, - vsync_len: 2, - vmode: FB_VMODE_NONINTERLACED + .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}, + .height = -1, + .width = -1, + .pixclock = 20000, + .left_margin = 64, + .right_margin = 64, + .upper_margin = 32, + .lower_margin = 32, + .hsync_len = 64, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED }; /* console related variables */ @@ -103,19 +103,17 @@ static int sgivwfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma); static struct fb_ops sgivwfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_check_var: sgivwfb_check_var, - fb_set_par: sgivwfb_set_par, - fb_setcolreg: sgivwfb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, - fb_mmap: sgivwfb_mmap, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_check_var = sgivwfb_check_var, + .fb_set_par = sgivwfb_set_par, + .fb_setcolreg = sgivwfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = sgivwfb_mmap, }; /* diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index f112d9202103..83b4f07c6652 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -2559,18 +2559,18 @@ static int sisfb_mmap(struct fb_info *info, struct file *file, } static struct fb_ops sisfb_ops = { - owner: THIS_MODULE, - fb_get_fix: sisfb_get_fix, - fb_get_var: sisfb_get_var, - fb_set_var: sisfb_set_var, - fb_get_cmap: sisfb_get_cmap, - fb_set_cmap: sisfb_set_cmap, + .owner = THIS_MODULE, + .fb_get_fix = sisfb_get_fix, + .fb_get_var = sisfb_get_var, + .fb_set_var = sisfb_set_var, + .fb_get_cmap = sisfb_get_cmap, + .fb_set_cmap = sisfb_set_cmap, #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23) - fb_setcolreg: sisfb_setcolreg, - fb_blank: sisfb_blank, + .fb_setcolreg = sisfb_setcolreg, + .fb_blank = sisfb_blank, #endif - fb_ioctl: sisfb_ioctl, - fb_mmap: sisfb_mmap, + .fb_ioctl = sisfb_ioctl, + .fb_mmap = sisfb_mmap, }; /* ------------ Interface to the low level console driver -------------*/ diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index 0e231bc969ca..110e85dea332 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c @@ -80,13 +80,13 @@ struct xxx_par; * to get a fb_var_screeninfo. Otherwise define a default var as well. */ static struct fb_fix_screeninfo xxxfb_fix __initdata = { - id: "FB's name", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - xpanstep: 1, - ypanstep: 1, - ywrapstep: 1, - accel: FB_ACCEL_NONE, + .id = "FB's name", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_NONE, }; /* @@ -507,26 +507,24 @@ static int xxxfb_release(const struct fb_info *info, int user) } static struct fb_ops xxxfb_ops = { - owner: THIS_MODULE, - fb_open: xxxfb_open, /* only if you need it to do something */ - fb_release: xxxfb_release, /* only if you need it to do something */ + .owner = THIS_MODULE, + .fb_open = xxxfb_open, /* only if you need it to do something */ + .fb_release = xxxfb_release, /* only if you need it to do something */ /* Stuff to go away. Use generic functions for now */ - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - - fb_check_var: xxxfb_check_var, - fb_set_par: xxxfb_set_par, /* optional */ - fb_setcolreg: xxxfb_setcolreg, - fb_blank: xxxfb_blank, /* optional */ - fb_pan_display: xxxfb_pan_display, /* optional */ - fb_fillrect: xxxfb_fillrect, - fb_copyarea: xxxfb_copyarea, - fb_imageblit: xxxfb_imageblit, - fb_ioctl: xxxfb_ioctl, /* optional */ - fb_mmap: xxxfb_mmap, /* optional */ + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + + .fb_check_var = xxxfb_check_var, + .fb_set_par = xxxfb_set_par, /* optional */ + .fb_setcolreg = xxxfb_setcolreg, + .fb_blank = xxxfb_blank, /* optional */ + .fb_pan_display = xxxfb_pan_display, /* optional */ + .fb_fillrect = xxxfb_fillrect, + .fb_copyarea = xxxfb_copyarea, + .fb_imageblit = xxxfb_imageblit, + .fb_ioctl = xxxfb_ioctl, /* optional */ + .fb_mmap = xxxfb_mmap, /* optional */ }; /* ------------------------------------------------------------------------- */ diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 5051c4cbc357..cb78eeb93607 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -205,16 +205,16 @@ static int sst_init(struct sstfb_info *sst_info); static void sst_shutdown(struct sstfb_info *sst_info); static struct fb_ops sstfb_ops = { - owner : THIS_MODULE, - fb_open: sstfb_open, - fb_release: sstfb_release, - fb_get_fix: sstfb_get_fix, - fb_get_var: sstfb_get_var, - fb_set_var: sstfb_set_var, - fb_get_cmap: sstfb_get_cmap, - fb_set_cmap: sstfb_set_cmap, - fb_pan_display: sstfb_pan_display, - fb_ioctl: sstfb_ioctl, + .owner = THIS_MODULE, + .fb_open = sstfb_open, + .fb_release = sstfb_release, + .fb_get_fix = sstfb_get_fix, + .fb_get_var = sstfb_get_var, + .fb_set_var = sstfb_set_var, + .fb_get_cmap = sstfb_get_cmap, + .fb_set_cmap = sstfb_set_cmap, + .fb_pan_display = sstfb_pan_display, + .fb_ioctl = sstfb_ioctl, }; enum { @@ -225,12 +225,12 @@ enum { #define IS_VOODOO2(info) ((info)->type == ID_VOODOO2 ) static struct sst_spec voodoo_spec[] __devinitdata = { - { name : "Voodoo Graphics", - default_gfx_clock : 50000, - max_gfxclk : 60, }, - { name : "Voodoo2", - default_gfx_clock : 75000, - max_gfxclk : 85, }, + { .name = "Voodoo Graphics", + .default_gfx_clock = 50000, + .max_gfxclk = 60, }, + { .name = "Voodoo2", + .default_gfx_clock = 75000, + .max_gfxclk = 85, }, }; static struct pci_device_id sstfb_id_tbl[] __devinitdata = { @@ -242,10 +242,10 @@ static struct pci_device_id sstfb_id_tbl[] __devinitdata = { }; static struct pci_driver sstfb_driver = { - name: "sstfb", - id_table: sstfb_id_tbl, - probe: sstfb_probe, - remove: __devexit_p(sstfb_remove), + .name = "sstfb", + .id_table = sstfb_id_tbl, + .probe = sstfb_probe, + .remove = __devexit_p(sstfb_remove), }; static struct fb_var_screeninfo sstfb_default = @@ -283,19 +283,19 @@ static struct fb_var_screeninfo sstfb_default = #endif static struct dac_switch dacs[] __devinitdata = { - { name: "TI TVP3409", - detect: sst_detect_ti, - set_pll: sst_set_pll_att_ti, - set_vidmod: sst_set_vidmod_att_ti }, - - { name: "AT&T ATT20C409", - detect: sst_detect_att, - set_pll: sst_set_pll_att_ti, - set_vidmod: sst_set_vidmod_att_ti }, - { name: "ICS ICS5342", - detect: sst_detect_ics, - set_pll: sst_set_pll_ics, - set_vidmod: sst_set_vidmod_ics }, + { .name = "TI TVP3409", + .detect = sst_detect_ti, + .set_pll = sst_set_pll_att_ti, + .set_vidmod = sst_set_vidmod_att_ti }, + + { .name = "AT&T ATT20C409", + .detect = sst_detect_att, + .set_pll = sst_set_pll_att_ti, + .set_vidmod = sst_set_vidmod_att_ti }, + { .name = "ICS ICS5342", + .detect = sst_detect_ics, + .set_pll = sst_set_pll_ics, + .set_vidmod = sst_set_vidmod_ics }, }; diff --git a/drivers/video/sticon-bmode.c b/drivers/video/sticon-bmode.c index 8a81cfa9083a..3ab5077ac27a 100644 --- a/drivers/video/sticon-bmode.c +++ b/drivers/video/sticon-bmode.c @@ -182,9 +182,9 @@ static struct sti_conf_flags default_conf_flags = { static void sti_inq_conf(struct sti_struct *sti) { struct sti_conf_inptr inptr = { NULL }; - struct sti_conf_outptr_ext outptr_ext = { future_ptr: NULL }; + struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL }; struct sti_conf_outptr outptr = { - ext_ptr: STI_PTR(&outptr_ext) + .ext_ptr = STI_PTR(&outptr_ext) }; unsigned long flags; s32 ret; @@ -415,22 +415,22 @@ static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, } static struct consw sti_con = { - con_startup: sticon_startup, - con_init: sticon_init, - con_deinit: sticon_deinit, - con_clear: sticon_clear, - con_putc: sticon_putc, - con_putcs: sticon_putcs, - con_cursor: sticon_cursor, - con_scroll: sticon_scroll, - con_bmove: sticon_bmove, - con_switch: sticon_switch, - con_blank: sticon_blank, - con_font_op: sticon_font_op, - con_set_palette: sticon_set_palette, - con_scrolldelta: sticon_scrolldelta, - con_set_origin: sticon_set_origin, - con_build_attr: sticon_build_attr, + .con_startup = sticon_startup, + .con_init = sticon_init, + .con_deinit = sticon_deinit, + .con_clear = sticon_clear, + .con_putc = sticon_putc, + .con_putcs = sticon_putcs, + .con_cursor = sticon_cursor, + .con_scroll = sticon_scroll, + .con_bmove = sticon_bmove, + .con_switch = sticon_switch, + .con_blank = sticon_blank, + .con_font_op = sticon_font_op, + .con_set_palette = sticon_set_palette, + .con_scrolldelta = sticon_scrolldelta, + .con_set_origin = sticon_set_origin, + .con_build_attr = sticon_build_attr, }; #include <asm/pgalloc.h> /* need cache flush routines */ diff --git a/drivers/video/sticon.c b/drivers/video/sticon.c index cc7890a3c777..7dddbe42d40a 100644 --- a/drivers/video/sticon.c +++ b/drivers/video/sticon.c @@ -183,22 +183,22 @@ static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, } struct consw sti_con = { - con_startup: sticon_startup, - con_init: sticon_init, - con_deinit: sticon_deinit, - con_clear: sticon_clear, - con_putc: sticon_putc, - con_putcs: sticon_putcs, - con_cursor: sticon_cursor, - con_scroll: sticon_scroll, - con_bmove: sticon_bmove, - con_switch: sticon_switch, - con_blank: sticon_blank, - con_font_op: sticon_font_op, - con_set_palette: sticon_set_palette, - con_scrolldelta: sticon_scrolldelta, - con_set_origin: sticon_set_origin, - con_build_attr: sticon_build_attr, + .con_startup = sticon_startup, + .con_init = sticon_init, + .con_deinit = sticon_deinit, + .con_clear = sticon_clear, + .con_putc = sticon_putc, + .con_putcs = sticon_putcs, + .con_cursor = sticon_cursor, + .con_scroll = sticon_scroll, + .con_bmove = sticon_bmove, + .con_switch = sticon_switch, + .con_blank = sticon_blank, + .con_font_op = sticon_font_op, + .con_set_palette = sticon_set_palette, + .con_scrolldelta = sticon_scrolldelta, + .con_set_origin = sticon_set_origin, + .con_build_attr = sticon_build_attr, }; static int __init sti_init(void) diff --git a/drivers/video/sticore.c b/drivers/video/sticore.c index 3726b0a6fe12..8437e1570ed3 100644 --- a/drivers/video/sticore.c +++ b/drivers/video/sticore.c @@ -75,9 +75,9 @@ void sti_inq_conf(struct sti_struct *sti) { struct sti_conf_inptr inptr = { NULL }; - struct sti_conf_outptr_ext outptr_ext = { future_ptr: NULL }; + struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL }; struct sti_conf_outptr outptr = { - ext_ptr: STI_PTR(&outptr_ext) + .ext_ptr = STI_PTR(&outptr_ext) }; unsigned long flags; s32 ret; diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 7d32b6482c06..9f4af7cf66e1 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -123,14 +123,14 @@ sti_detect(void) /* ------------ Interfaces to hardware functions ------------ */ struct fbgen_hwswitch sti_switch = { - detect: sti_detect, - encode_fix: sti_encode_fix, - decode_var: sti_decode_var, - encode_var: sti_encode_var, - get_par: sti_get_par, - set_par: sti_set_par, - getcolreg: sti_getcolreg, - set_disp: sti_set_disp + .detect = sti_detect, + .encode_fix = sti_encode_fix, + .decode_var = sti_decode_var, + .encode_var = sti_encode_var, + .get_par = sti_get_par, + .set_par = sti_set_par, + .getcolreg = sti_getcolreg, + .set_disp = sti_set_disp }; @@ -199,12 +199,12 @@ stifb_setup(char *options) static struct fb_ops stifb_ops = { - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_pan_display: fbgen_pan_display, - fb_blank: fbgen_blank, + .owner = THIS_MODULE, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_pan_display =fbgen_pan_display, + .fb_blank = fbgen_blank, }; diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c index 46ea13c97d87..a278639af752 100644 --- a/drivers/video/sun3fb.c +++ b/drivers/video/sun3fb.c @@ -109,14 +109,14 @@ static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info); static struct fb_ops sun3fb_ops = { - owner: THIS_MODULE, - fb_get_fix: sun3fb_get_fix, - fb_get_var: sun3fb_get_var, - fb_set_var: sun3fb_set_var, - fb_get_cmap: sun3fb_get_cmap, - fb_set_cmap: sun3fb_set_cmap, - fb_setcolreg: sun3fb_setcolreg, - fb_blank: sun3fb_blank, + .owner = THIS_MODULE, + .fb_get_fix = sun3fb_get_fix, + .fb_get_var = sun3fb_get_var, + .fb_set_var = sun3fb_set_var, + .fb_get_cmap = sun3fb_get_cmap, + .fb_set_cmap = sun3fb_set_cmap, + .fb_setcolreg = sun3fb_setcolreg, + .fb_blank = sun3fb_blank, }; static void sun3fb_clear_margin(struct display *p, int s) diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 6726bb00dd5c..0543704cc7b4 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -91,36 +91,36 @@ #define VOODOO5_MAX_PIXCLOCK 350000.0 static struct fb_fix_screeninfo tdfx_fix __initdata = { - id: "3Dfx", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - ypanstep: 1, - ywrapstep: 1, - accel: FB_ACCEL_3DFX_BANSHEE + .id = "3Dfx", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_3DFX_BANSHEE }; static struct fb_var_screeninfo tdfx_var __initdata = { /* "640x480, 8 bpp @ 60 Hz */ - xres: 640, - yres: 480, - xres_virtual: 640, - yres_virtual: 1024, - bits_per_pixel: 8, - red: {0, 8, 0}, - blue: {0, 8, 0}, - green: {0, 8, 0}, - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - accel_flags: FB_ACCELF_TEXT, - pixclock: 39722, - left_margin: 40, - right_margin: 24, - upper_margin: 32, - lower_margin: 11, - hsync_len: 96, - vsync_len: 2, - vmode: FB_VMODE_NONINTERLACED + .xres = 640, + .yres = 480, + .xres_virtual = 640, + .yres_virtual = 1024, + .bits_per_pixel =8, + .red = {0, 8, 0}, + .blue = {0, 8, 0}, + .green = {0, 8, 0}, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .accel_flags = FB_ACCELF_TEXT, + .pixclock = 39722, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED }; /* @@ -143,10 +143,10 @@ static struct pci_device_id tdfxfb_id_table[] __devinitdata = { }; static struct pci_driver tdfxfb_driver = { - name: "tdfxfb", - id_table: tdfxfb_id_table, - probe: tdfxfb_probe, - remove: tdfxfb_remove, + .name = "tdfxfb", + .id_table = tdfxfb_id_table, + .probe = tdfxfb_probe, + .remove = tdfxfb_remove, }; MODULE_DEVICE_TABLE(pci, tdfxfb_id_table); @@ -168,20 +168,18 @@ static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area); static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image); static struct fb_ops tdfxfb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_check_var: tdfxfb_check_var, - fb_set_par: tdfxfb_set_par, - fb_setcolreg: tdfxfb_setcolreg, - fb_blank: tdfxfb_blank, - fb_pan_display: tdfxfb_pan_display, - fb_fillrect: tdfxfb_fillrect, - fb_copyarea: tdfxfb_copyarea, - fb_imageblit: tdfxfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_check_var = tdfxfb_check_var, + .fb_set_par = tdfxfb_set_par, + .fb_setcolreg = tdfxfb_setcolreg, + .fb_blank = tdfxfb_blank, + .fb_pan_display = tdfxfb_pan_display, + .fb_fillrect = tdfxfb_fillrect, + .fb_copyarea = tdfxfb_copyarea, + .fb_imageblit = tdfxfb_imageblit, }; /* diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index 4d2df7a59cca..3fcbcc1de024 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -867,14 +867,14 @@ struct fbgen_hwswitch tgafb_hwswitch = { */ static struct fb_ops tgafb_ops = { - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: tgafb_set_cmap, - fb_setcolreg: tgafb_setcolreg, - fb_blank: fbgen_blank, + .owner = THIS_MODULE, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = tgafb_set_cmap, + .fb_setcolreg = tgafb_setcolreg, + .fb_blank = fbgen_blank, }; diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 06c3d37c9e1c..2e53e6d53287 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -351,14 +351,14 @@ static void trident_8bpp_clear (struct vc_data *conp, struct display *p, } static struct display_switch trident_8bpp = { - setup: fbcon_cfb8_setup, - bmove: trident_bmove, - clear: trident_8bpp_clear, - putc: fbcon_cfb8_putc, - putcs: fbcon_cfb8_putcs, - revc: fbcon_cfb8_revc, - clear_margins: fbcon_cfb8_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb8_setup, + .bmove = trident_bmove, + .clear = trident_8bpp_clear, + .putc = fbcon_cfb8_putc, + .putcs = fbcon_cfb8_putcs, + .revc = fbcon_cfb8_revc, + .clear_margins =fbcon_cfb8_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif #ifdef FBCON_HAS_CFB16 @@ -372,14 +372,14 @@ static void trident_16bpp_clear (struct vc_data *conp, struct display *p, } static struct display_switch trident_16bpp = { - setup: fbcon_cfb16_setup, - bmove: trident_bmove, - clear: trident_16bpp_clear, - putc: fbcon_cfb16_putc, - putcs: fbcon_cfb16_putcs, - revc: fbcon_cfb16_revc, - clear_margins: fbcon_cfb16_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb16_setup, + .bmove = trident_bmove, + .clear = trident_16bpp_clear, + .putc = fbcon_cfb16_putc, + .putcs = fbcon_cfb16_putcs, + .revc = fbcon_cfb16_revc, + .clear_margins =fbcon_cfb16_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif #ifdef FBCON_HAS_CFB32 @@ -392,14 +392,14 @@ static void trident_32bpp_clear (struct vc_data *conp, struct display *p, } static struct display_switch trident_32bpp = { - setup: fbcon_cfb32_setup, - bmove: trident_bmove, - clear: trident_32bpp_clear, - putc: fbcon_cfb32_putc, - putcs: fbcon_cfb32_putcs, - revc: fbcon_cfb32_revc, - clear_margins: fbcon_cfb32_clear_margins, - fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) + .setup = fbcon_cfb32_setup, + .bmove = trident_bmove, + .clear = trident_32bpp_clear, + .putc = fbcon_cfb32_putc, + .putcs = fbcon_cfb32_putcs, + .revc = fbcon_cfb32_revc, + .clear_margins =fbcon_cfb32_clear_margins, + .fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16) }; #endif @@ -1286,13 +1286,13 @@ int tridentfb_setup(char *options) } static struct fb_ops tridentfb_ops = { - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: fbgen_set_cmap, - fb_setcolreg: tridentfb_setcolreg, - fb_pan_display: fbgen_pan_display, + .fb_get_fix = fbgen_get_fix, + .fb_get_var = fbgen_get_var, + .fb_set_var = fbgen_set_var, + .fb_get_cmap = fbgen_get_cmap, + .fb_set_cmap = fbgen_set_cmap, + .fb_setcolreg = tridentfb_setcolreg, + .fb_pan_display =fbgen_pan_display, }; #ifdef MODULE diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c index 0b0ab6a06c60..d395664206ec 100644 --- a/drivers/video/tx3912fb.c +++ b/drivers/video/tx3912fb.c @@ -36,44 +36,44 @@ static u32 cfb8[16]; static struct display disp; static struct fb_fix_screeninfo tx3912fb_fix __initdata = { - id: "tx3912fb", + .id = "tx3912fb", #ifdef CONFIG_NINO_16MB - smem_len: (240 * 320), + .smem_len = (240 * 320), #else - smem_len: ((240 * 320)/2), + .smem_len = ((240 * 320)/2), #endif - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_TRUECOLOR, - xpanstep: 1, - ypanstep: 1, - ywrapstep: 1, - accel: FB_ACCEL_NONE, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_NONE, }; static struct fb_var_screeninfo tx3912fb_var = { - xres: 240, - yres: 320, - xres_virtual: 240, - yres_virtual: 320, + .xres = 240, + .yres = 320, + .xres_virtual = 240, + .yres_virtual = 320, #ifdef CONFIG_NINO_16MB - bits_per_pixel: 8, - red: { 5, 3, 0 }, /* RGB 332 */ - green: { 2, 3, 0 }, - blue: { 0, 2, 0 }, + .bits_per_pixel =8, + .red = { 5, 3, 0 }, /* RGB 332 */ + .green = { 2, 3, 0 }, + .blue = { 0, 2, 0 }, #else - bits_per_pixel: 4, + .bits_per_pixel =4, #endif - activate: FB_ACTIVATE_NOW, - width: -1, - height: -1, - pixclock: 20000, - left_margin: 64, - right_margin: 64, - upper_margin: 32, - lower_margin: 32, - hsync_len: 64, - vsync_len: 2, - vmode: FB_VMODE_NONINTERLACED, + .activate = FB_ACTIVATE_NOW, + .width = -1, + .height = -1, + .pixclock = 20000, + .left_margin = 64, + .right_margin = 64, + .upper_margin = 32, + .lower_margin = 32, + .hsync_len = 64, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED, }; /* @@ -95,16 +95,14 @@ static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, * Frame buffer operations structure used by console driver */ static struct fb_ops tx3912fb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: tx3912fb_setcolreg, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = tx3912fb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 6345144a412a..a6e4e367a1b2 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -156,14 +156,14 @@ static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_scree static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p); static struct fb_ops valkyriefb_ops = { - owner: THIS_MODULE, - fb_get_fix: valkyrie_get_fix, - fb_get_var: valkyrie_get_var, - fb_set_var: valkyrie_set_var, - fb_get_cmap: valkyrie_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: valkyriefb_setcolreg, - fb_blank: valkyriefb_blank, + .owner = THIS_MODULE, + .fb_get_fix = valkyrie_get_fix, + .fb_get_var = valkyrie_get_var, + .fb_set_var = valkyrie_set_var, + .fb_get_cmap = valkyrie_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = valkyriefb_setcolreg, + .fb_blank = valkyriefb_blank, }; static int valkyriefb_getcolreg(u_int regno, u_int *red, u_int *green, diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 3fa57bb84508..1326c71bd697 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -33,20 +33,20 @@ /* --------------------------------------------------------------------- */ static struct fb_var_screeninfo vesafb_defined __initdata = { - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - right_margin: 32, - upper_margin: 16, - lower_margin: 4, - vsync_len: 4, - vmode: FB_VMODE_NONINTERLACED, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .right_margin = 32, + .upper_margin = 16, + .lower_margin = 4, + .vsync_len = 4, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo vesafb_fix __initdata = { - id: "VESA VGA", - type: FB_TYPE_PACKED_PIXELS, - accel: FB_ACCEL_NONE, + .id = "VESA VGA", + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, }; static struct display disp; @@ -174,17 +174,15 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, } static struct fb_ops vesafb_ops = { - owner: THIS_MODULE, - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: vesafb_setcolreg, - fb_pan_display: vesafb_pan_display, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, + .owner = THIS_MODULE, + .fb_set_var = gen_set_var, + .fb_get_cmap = gen_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = vesafb_setcolreg, + .fb_pan_display = vesafb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, }; int __init vesafb_setup(char *options) diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index ebd94b65836c..5ed50a49b234 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -45,35 +45,35 @@ static u32 vfb_pseudo_palette[17]; static struct display disp; static struct fb_var_screeninfo vfb_default __initdata = { - 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 }, - activate: FB_ACTIVATE_TEST, - height: -1, - width: -1, - pixclock: 20000, - left_margin: 64, - right_margin: 64, - upper_margin: 32, - lower_margin: 32, - hsync_len: 64, - vsync_len: 2, - vmode: FB_VMODE_NONINTERLACED, + .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 }, + .activate = FB_ACTIVATE_TEST, + .height = -1, + .width = -1, + .pixclock = 20000, + .left_margin = 64, + .right_margin = 64, + .upper_margin = 32, + .lower_margin = 32, + .hsync_len = 64, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo vfb_fix __initdata = { - id: "Virtual FB", - type: FB_TYPE_PACKED_PIXELS, - visual: FB_VISUAL_PSEUDOCOLOR, - xpanstep: 1, - ypanstep: 1, - ywrapstep: 1, - accel: FB_ACCEL_NONE, + .id = "Virtual FB", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_NONE, }; static int vfb_enable __initdata = 0; /* disabled by default */ @@ -96,19 +96,17 @@ static int vfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma); static struct fb_ops vfb_ops = { - fb_get_fix: gen_get_fix, - fb_get_var: gen_get_var, - fb_set_var: gen_set_var, - fb_get_cmap: gen_set_cmap, - fb_set_cmap: gen_set_cmap, - fb_check_var: vfb_check_var, - fb_set_par: vfb_set_par, - fb_setcolreg: vfb_setcolreg, - fb_pan_display: vfb_pan_display, - fb_fillrect: cfb_fillrect, - fb_copyarea: cfb_copyarea, - fb_imageblit: cfb_imageblit, - fb_mmap: vfb_mmap, + .fb_set_var gen_set_var, + .fb_get_cmap gen_set_cmap, + .fb_set_cmap gen_set_cmap, + .fb_check_var vfb_check_var, + .fb_set_par vfb_set_par, + .fb_setcolreg vfb_setcolreg, + .fb_pan_display vfb_pan_display, + .fb_fillrect cfb_fillrect, + .fb_copyarea cfb_copyarea, + .fb_imageblit cfb_imageblit, + .fb_mmap vfb_mmap, }; /* diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 911735b2f30b..e96f540178b7 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -810,15 +810,15 @@ static int vga16fb_blank(int blank, struct fb_info *fb_info) } static struct fb_ops vga16fb_ops = { - owner: THIS_MODULE, - fb_get_fix: vga16fb_get_fix, - fb_get_var: vga16fb_get_var, - fb_set_var: vga16fb_set_var, - fb_get_cmap: vga16fb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: vga16fb_setcolreg, - fb_pan_display: vga16fb_pan_display, - fb_blank: vga16fb_blank, + .owner = THIS_MODULE, + .fb_get_fix = vga16fb_get_fix, + .fb_get_var = vga16fb_get_var, + .fb_set_var = vga16fb_set_var, + .fb_get_cmap = vga16fb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = vga16fb_setcolreg, + .fb_pan_display =vga16fb_pan_display, + .fb_blank = vga16fb_blank, }; int vga16fb_setup(char *options) diff --git a/drivers/video/vgacon.c b/drivers/video/vgacon.c index 14e2a6bfcb15..b65d47810913 100644 --- a/drivers/video/vgacon.c +++ b/drivers/video/vgacon.c @@ -1032,24 +1032,24 @@ static int vgacon_dummy(struct vc_data *c) #define DUMMY (void *) vgacon_dummy const struct consw vga_con = { - con_startup: vgacon_startup, - con_init: vgacon_init, - con_deinit: vgacon_deinit, - con_clear: DUMMY, - con_putc: DUMMY, - con_putcs: DUMMY, - con_cursor: vgacon_cursor, - con_scroll: vgacon_scroll, - con_bmove: DUMMY, - con_switch: vgacon_switch, - con_blank: vgacon_blank, - con_font_op: vgacon_font_op, - con_set_palette: vgacon_set_palette, - con_scrolldelta: vgacon_scrolldelta, - con_set_origin: vgacon_set_origin, - con_save_screen: vgacon_save_screen, - con_build_attr: vgacon_build_attr, - con_invert_region: vgacon_invert_region, + .con_startup = vgacon_startup, + .con_init = vgacon_init, + .con_deinit = vgacon_deinit, + .con_clear = DUMMY, + .con_putc = DUMMY, + .con_putcs = DUMMY, + .con_cursor = vgacon_cursor, + .con_scroll = vgacon_scroll, + .con_bmove = DUMMY, + .con_switch = vgacon_switch, + .con_blank = vgacon_blank, + .con_font_op = vgacon_font_op, + .con_set_palette = vgacon_set_palette, + .con_scrolldelta = vgacon_scrolldelta, + .con_set_origin = vgacon_set_origin, + .con_save_screen = vgacon_save_screen, + .con_build_attr = vgacon_build_attr, + .con_invert_region = vgacon_invert_region, }; MODULE_LICENSE("GPL"); diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c index be06ea8ee4e6..72039504e9e7 100644 --- a/drivers/video/virgefb.c +++ b/drivers/video/virgefb.c @@ -1348,12 +1348,12 @@ static void virgefb_move_cursor(u_short x, u_short y) /* -------------------- Interfaces to hardware functions -------------------- */ static struct fb_hwswitch virgefb_hw_switch = { - init: virge_init, - encode_fix: virgefb_encode_fix, - decode_var: virgefb_decode_var, - encode_var: virgefb_encode_var, - getcolreg: virgefb_getcolreg, - blank: virgefb_gfx_on_off + .init = virge_init, + .encode_fix = virgefb_encode_fix, + .decode_var = virgefb_decode_var, + .encode_var = virgefb_encode_var, + .getcolreg = virgefb_getcolreg, + .blank = virgefb_gfx_on_off }; @@ -1626,14 +1626,14 @@ static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con, } static struct fb_ops virgefb_ops = { - owner: THIS_MODULE, - fb_get_fix: virgefb_get_fix, - fb_get_var: virgefb_get_var, - fb_set_var: virgefb_set_var, - fb_get_cmap: virgefb_get_cmap, - fb_set_cmap: gen_set_cmap, - fb_setcolreg: virgefb_setcolreg, - fb_blank: virgefb_blank, + .owner = THIS_MODULE, + .fb_get_fix = virgefb_get_fix, + .fb_get_var = virgefb_get_var, + .fb_set_var = virgefb_set_var, + .fb_get_cmap = virgefb_get_cmap, + .fb_set_cmap = gen_set_cmap, + .fb_setcolreg = virgefb_setcolreg, + .fb_blank = virgefb_blank, }; int __init virgefb_setup(char *options) @@ -1917,14 +1917,14 @@ static void fbcon_virge8_clear_margins(struct vc_data *conp, struct display *p, } static struct display_switch fbcon_virge8 = { - setup: fbcon_cfb8_setup, - bmove: fbcon_virge8_bmove, - clear: fbcon_virge8_clear, - putc: fbcon_virge8_putc, - putcs: fbcon_virge8_putcs, - revc: fbcon_virge8_revc, - clear_margins: fbcon_virge8_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb8_setup, + .bmove = fbcon_virge8_bmove, + .clear = fbcon_virge8_clear, + .putc = fbcon_virge8_putc, + .putcs = fbcon_virge8_putcs, + .revc = fbcon_virge8_revc, + .clear_margins = fbcon_virge8_clear_margins, + .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -1982,14 +1982,14 @@ static void fbcon_virge16_clear_margins(struct vc_data *conp, struct display *p, } static struct display_switch fbcon_virge16 = { - setup: fbcon_cfb16_setup, - bmove: fbcon_virge16_bmove, - clear: fbcon_virge16_clear, - putc: fbcon_virge16_putc, - putcs: fbcon_virge16_putcs, - revc: fbcon_virge16_revc, - clear_margins: fbcon_virge16_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb16_setup, + .bmove = fbcon_virge16_bmove, + .clear = fbcon_virge16_clear, + .putc = fbcon_virge16_putc, + .putcs = fbcon_virge16_putcs, + .revc = fbcon_virge16_revc, + .clear_margins = fbcon_virge16_clear_margins, + .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -2047,14 +2047,14 @@ static void fbcon_virge32_clear_margins(struct vc_data *conp, struct display *p, } static struct display_switch fbcon_virge32 = { - setup: fbcon_cfb32_setup, - bmove: fbcon_virge32_bmove, - clear: fbcon_virge32_clear, - putc: fbcon_virge32_putc, - putcs: fbcon_virge32_putcs, - revc: fbcon_virge32_revc, - clear_margins: fbcon_virge32_clear_margins, - fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) + .setup = fbcon_cfb32_setup, + .bmove = fbcon_virge32_bmove, + .clear = fbcon_virge32_clear, + .putc = fbcon_virge32_putc, + .putcs = fbcon_virge32_putcs, + .revc = fbcon_virge32_revc, + .clear_margins = fbcon_virge32_clear_margins, + .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif diff --git a/fs/block_dev.c b/fs/block_dev.c index aefe1a4302ce..7aa40fbcdc5b 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -797,7 +797,7 @@ static int blkdev_reread_part(struct block_device *bdev) part = disk->part + minor(dev) - disk->first_minor; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (down_trylock(&bdev->bd_sem)); + if (down_trylock(&bdev->bd_sem)) return -EBUSY; if (bdev->bd_part_count) { up(&bdev->bd_sem); @@ -874,7 +874,7 @@ struct file_operations def_blk_fops = { release: blkdev_close, llseek: block_llseek, read: generic_file_read, - write: generic_file_write, + write: generic_file_write_nolock, mmap: generic_file_mmap, fsync: block_fsync, ioctl: blkdev_ioctl, diff --git a/fs/fat/file.c b/fs/fat/file.c index d915d6578c9a..38b06bb5566e 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -21,6 +21,7 @@ struct file_operations fat_file_operations = { write: fat_file_write, mmap: generic_file_mmap, fsync: file_fsync, + sendfile: generic_file_sendfile, }; struct inode_operations fat_file_inode_operations = { diff --git a/fs/partitions/check.c b/fs/partitions/check.c index cc5b412bac28..4cab6f920e2b 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -137,11 +137,6 @@ char *disk_name (struct gendisk *hd, int minor, char *buf) sprintf(s, "%s%d", "md", unit); maj = s; break; - case COMPAQ_CISS_MAJOR ... COMPAQ_CISS_MAJOR+7: - sprintf(s, "cciss/c%dd%d", - hd->major - COMPAQ_CISS_MAJOR, unit); - maj = s; - break; case ATARAID_MAJOR: sprintf(s, "ataraid/d%d", unit); maj = s; diff --git a/include/asm-alpha/rtc.h b/include/asm-alpha/rtc.h new file mode 100644 index 000000000000..4e854b1333eb --- /dev/null +++ b/include/asm-alpha/rtc.h @@ -0,0 +1,10 @@ +#ifndef _ALPHA_RTC_H +#define _ALPHA_RTC_H + +/* + * Alpha uses the default access methods for the RTC. + */ + +#include <asm-generic/rtc.h> + +#endif diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 0ad91ae08c6b..4dcfdb73fb07 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -1,13 +1,34 @@ #ifndef _ASM_GENERIC_PERCPU_H_ #define _ASM_GENERIC_PERCPU_H_ +#include <linux/compiler.h> #define __GENERIC_PER_CPU -#include <linux/compiler.h> +#ifdef CONFIG_SMP extern unsigned long __per_cpu_offset[NR_CPUS]; +/* Separate out the type, so (int[3], foo) works. */ +#ifndef MODULE +#define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".percpu"))) __typeof__(type) name##__per_cpu +#endif + /* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*RELOC_HIDE(&var, __per_cpu_offset[cpu])) -#define this_cpu(var) per_cpu(var, smp_processor_id()) +#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu])) +#define __get_cpu_var(var) per_cpu(var, smp_processor_id()) + +#else /* ! SMP */ + +/* Can't define per-cpu variables in modules. Sorry --RR */ +#ifndef MODULE +#define DEFINE_PER_CPU(type, name) \ + __typeof__(type) name##__per_cpu +#endif + +#define per_cpu(var, cpu) var##__per_cpu +#define __get_cpu_var(var) var##__per_cpu +#endif + +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu #endif /* _ASM_GENERIC_PERCPU_H_ */ diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h new file mode 100644 index 000000000000..ebdeefd49822 --- /dev/null +++ b/include/asm-generic/rtc.h @@ -0,0 +1,211 @@ +/* + * inclue/asm-generic/rtc.h + * + * Author: Tom Rini <trini@mvista.com> + * + * Based on: + * drivers/char/rtc.c + * + * Please read the COPYING file for all license details. + */ + +#ifndef __ASM_RTC_H__ +#define __ASM_RTC_H__ + +#ifdef __KERNEL__ + +#include <linux/mc146818rtc.h> +#include <linux/rtc.h> + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +extern void gen_rtc_interrupt(unsigned long); + +/* some dummy definitions */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +/* + * Returns true if a clock update is in progress + */ +static inline unsigned char rtc_is_updating(void) +{ + unsigned char uip; + + spin_lock_irq(&rtc_lock); + uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); + spin_unlock_irq(&rtc_lock); + return uip; +} + +static inline void get_rtc_time(struct rtc_time *time) +{ + unsigned long uip_watchdog = jiffies; + unsigned char ctrl; +#ifdef CONFIG_DECSTATION + unsigned int real_year; +#endif + + /* + * read RTC once any update in progress is done. The update + * can take just over 2ms. We wait 10 to 20ms. There is no need to + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. + * If you need to know *exactly* when a second has started, enable + * periodic update complete interrupts, (via ioctl) and then + * immediately read /dev/rtc which will block until you get the IRQ. + * Once the read clears, read the RTC time (again via ioctl). Easy. + */ + + if (rtc_is_updating() != 0) + while (jiffies - uip_watchdog < 2*HZ/100) { + barrier(); + cpu_relax(); + } + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irq(&rtc_lock); + time->tm_sec = CMOS_READ(RTC_SECONDS); + time->tm_min = CMOS_READ(RTC_MINUTES); + time->tm_hour = CMOS_READ(RTC_HOURS); + time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); + time->tm_mon = CMOS_READ(RTC_MONTH); + time->tm_year = CMOS_READ(RTC_YEAR); +#ifdef CONFIG_DECSTATION + real_year = CMOS_READ(RTC_DEC_YEAR); +#endif + ctrl = CMOS_READ(RTC_CONTROL); + spin_unlock_irq(&rtc_lock); + + if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + { + BCD_TO_BIN(time->tm_sec); + BCD_TO_BIN(time->tm_min); + BCD_TO_BIN(time->tm_hour); + BCD_TO_BIN(time->tm_mday); + BCD_TO_BIN(time->tm_mon); + BCD_TO_BIN(time->tm_year); + } + +#ifdef CONFIG_DECSTATION + time->tm_year += real_year - 72; +#endif + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if (time->tm_year <= 69) + time->tm_year += 100; + + time->tm_mon--; +} + +/* Set the current date and time in the real time clock. */ +static inline int set_rtc_time(struct rtc_time *time) +{ + unsigned char mon, day, hrs, min, sec; + unsigned char save_control, save_freq_select; + unsigned int yrs; +#ifdef CONFIG_DECSTATION + unsigned int real_yrs, leap_yr; +#endif + + yrs = time->tm_year; + mon = time->tm_mon + 1; /* tm_mon starts at zero */ + day = time->tm_mday; + hrs = time->tm_hour; + min = time->tm_min; + sec = time->tm_sec; + + if (yrs > 255) /* They are unsigned */ + return -EINVAL; + + spin_lock_irq(&rtc_lock); +#ifdef CONFIG_DECSTATION + real_yrs = yrs; + leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || + !((yrs + 1900) % 400)); + yrs = 72; + + /* + * We want to keep the year set to 73 until March + * for non-leap years, so that Feb, 29th is handled + * correctly. + */ + if (!leap_yr && mon < 3) { + real_yrs--; + yrs = 73; + } +#endif + /* These limits and adjustments are independant of + * whether the chip is in binary mode or not. + */ + if (yrs > 169) { + spin_unlock_irq(&rtc_lock); + return -EINVAL; + } + + if (yrs >= 100) + yrs -= 100; + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) + || RTC_ALWAYS_BCD) { + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + } + + save_control = CMOS_READ(RTC_CONTROL); + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + +#ifdef CONFIG_DECSTATION + CMOS_WRITE(real_yrs, RTC_DEC_YEAR); +#endif + CMOS_WRITE(yrs, RTC_YEAR); + CMOS_WRITE(mon, RTC_MONTH); + CMOS_WRITE(day, RTC_DAY_OF_MONTH); + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static inline unsigned int get_rtc_ss(void) +{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} + +#endif /* __KERNEL__ */ +#endif /* __ASM_RTC_H__ */ diff --git a/include/asm-i386/rtc.h b/include/asm-i386/rtc.h new file mode 100644 index 000000000000..ffd02109a0e5 --- /dev/null +++ b/include/asm-i386/rtc.h @@ -0,0 +1,10 @@ +#ifndef _I386_RTC_H +#define _I386_RTC_H + +/* + * x86 uses the default access methods for the RTC. + */ + +#include <asm-generic/rtc.h> + +#endif diff --git a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h index 7f2871a8cc61..7f404b6db853 100644 --- a/include/asm-ia64/percpu.h +++ b/include/asm-ia64/percpu.h @@ -8,7 +8,7 @@ #ifdef __ASSEMBLY__ -#define THIS_CPU(var) (var) /* use this to mark accesses to per-CPU variables... */ +#define THIS_CPU(var) (var##__per_cpu) /* use this to mark accesses to per-CPU variables... */ #else /* !__ASSEMBLY__ */ @@ -16,8 +16,14 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; -#define per_cpu(var, cpu) (*(__typeof__(&(var))) ((void *) &(var) + __per_cpu_offset[cpu])) -#define this_cpu(var) (var) +#ifndef MODULE +#define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu +#endif +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu + +#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu])) +#define __get_cpu_var(var) (var##__per_cpu) #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 51993a853ac5..cd1be7a72902 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -134,7 +134,7 @@ struct ia64_psr { * CPU type, hardware bug flags, and per-CPU state. Frequently used * state comes earlier: */ -extern struct cpuinfo_ia64 { +struct cpuinfo_ia64 { /* irq_stat must be 64-bit aligned */ union { struct { @@ -175,13 +175,15 @@ extern struct cpuinfo_ia64 { __u64 prof_counter; __u64 prof_multiplier; #endif -} cpu_info __per_cpu_data; +}; + +DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info); /* * The "local" data pointer. It points to the per-CPU data of the currently executing * CPU, much like "current" points to the per-task data of the currently executing task. */ -#define local_cpu_data (&this_cpu(cpu_info)) +#define local_cpu_data (&__get_cpu_var(cpu_info)) #define cpu_data(cpu) (&per_cpu(cpu_info, cpu)) extern void identify_cpu (struct cpuinfo_ia64 *); diff --git a/include/asm-parisc/rtc.h b/include/asm-parisc/rtc.h new file mode 100644 index 000000000000..a639c86f83d1 --- /dev/null +++ b/include/asm-parisc/rtc.h @@ -0,0 +1,131 @@ +/* + * inclue/asm-parisc/rtc.h + * + * Copyright 2002 Randolph CHung <tausq@debian.org> + * + * Based on: include/asm-ppc/rtc.h and the genrtc driver in the + * 2.4 parisc linux tree + */ + +#ifndef __ASM_RTC_H__ +#define __ASM_RTC_H__ + +#ifdef __KERNEL__ + +#include <linux/rtc.h> + +#include <asm/pdc.h> + +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (SECS_PER_HOUR * 24) + + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +extern void gen_rtc_interrupt(unsigned long); + +/* some dummy definitions */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +/* How many days come before each month (0-12). */ +static const unsigned short int __mon_yday[2][13] = +{ + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +static int get_rtc_time(struct rtc_time *wtime) +{ + struct pdc_tod tod_data; + long int days, rem, y; + const unsigned short int *ip; + + if(pdc_tod_read(&tod_data) < 0) + return -1; + + + // most of the remainder of this function is: +// Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc. +// This was originally a part of the GNU C Library. +// It is distributed under the GPL, and was swiped from offtime.c + + + days = tod_data.tod_sec / SECS_PER_DAY; + rem = tod_data.tod_sec % SECS_PER_DAY; + + wtime->tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + wtime->tm_min = rem / 60; + wtime->tm_sec = rem % 60; + + y = 1970; + +#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) +#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) + + while (days < 0 || days >= (__isleap (y) ? 366 : 365)) + { + /* Guess a corrected year, assuming 365 days per year. */ + long int yg = y + days / 365 - (days % 365 < 0); + + /* Adjust DAYS and Y to match the guessed year. */ + days -= ((yg - y) * 365 + + LEAPS_THRU_END_OF (yg - 1) + - LEAPS_THRU_END_OF (y - 1)); + y = yg; + } + wtime->tm_year = y - 1900; + + ip = __mon_yday[__isleap(y)]; + for (y = 11; days < (long int) ip[y]; --y) + continue; + days -= ip[y]; + wtime->tm_mon = y; + wtime->tm_mday = days + 1; + + return 0; +} + +static int set_rtc_time(struct rtc_time *wtime) +{ + u_int32_t secs; + + secs = mktime(wtime->tm_year + 1900, wtime->tm_mon + 1, wtime->tm_mday, + wtime->tm_hour, wtime->tm_min, wtime->tm_sec); + + if(pdc_tod_set(secs, 0) < 0) + return -1; + else + return 0; + +} + +static inline unsigned int get_rtc_ss(void) +{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} + +#endif /* __KERNEL__ */ +#endif /* __ASM_RTC_H__ */ diff --git a/include/asm-ppc/rtc.h b/include/asm-ppc/rtc.h new file mode 100644 index 000000000000..72b164039fe6 --- /dev/null +++ b/include/asm-ppc/rtc.h @@ -0,0 +1,95 @@ +/* + * inclue/asm-ppc/rtc.h + * + * Copyright 2002 MontaVista Software Inc. + * Author: Tom Rini <trini@mvista.com> + * + * Based on: + * include/asm-m68k/rtc.h + * + * Copyright Richard Zidlicky + * implementation details for genrtc/q40rtc driver + * + * And the old drivers/macintosh/rtc.c which was heavily based on: + * Linux/SPARC Real Time Clock Driver + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + * + * With additional work by Paul Mackerras and Franz Sirl. + */ +/* permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ + +#ifndef __ASM_RTC_H__ +#define __ASM_RTC_H__ + +#ifdef __KERNEL__ + +#include <linux/rtc.h> + +#include <asm/machdep.h> +#include <asm/time.h> + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +extern void gen_rtc_interrupt(unsigned long); + +/* some dummy definitions */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +static inline void get_rtc_time(struct rtc_time *time) +{ + if (ppc_md.get_rtc_time) { + unsigned long nowtime; + + nowtime = (ppc_md.get_rtc_time)(); + + to_tm(nowtime, time); + + time->tm_year -= 1900; + time->tm_mon -= 1; /* Make sure userland has a 0-based month */ + } +} + +/* Set the current date and time in the real time clock. */ +static inline void set_rtc_time(struct rtc_time *time) +{ + if (ppc_md.get_rtc_time) { + unsigned long nowtime; + + nowtime = mktime(time->tm_year+1900, time->tm_mon+1, + time->tm_mday, time->tm_hour, time->tm_min, + time->tm_sec); + + (ppc_md.set_rtc_time)(nowtime); + + return 0; + } else + return -EINVAL; +} + +static inline unsigned int get_rtc_ss(void) +{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + return -EINVAL; +} + +#endif /* __KERNEL__ */ +#endif /* __ASM_RTC_H__ */ diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h index 01905126bfbc..bb91d49f92f3 100644 --- a/include/asm-x86_64/percpu.h +++ b/include/asm-x86_64/percpu.h @@ -4,7 +4,7 @@ #include <asm/pda.h> /* var is in discarded region: offset to particular copy we want */ -#define this_cpu(var) (*RELOC_HIDE(&var, read_pda(cpudata_offset))) +#define __get_cpu_var(var) (*RELOC_HIDE(&var, read_pda(cpudata_offset))) #define per_cpu(var, cpu) (*RELOC_HIDE(&var, per_cpu_pda[cpu])) void setup_per_cpu_areas(void); diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h index 732fbff874cc..ceffd587b7a8 100644 --- a/include/linux/apm_bios.h +++ b/include/linux/apm_bios.h @@ -21,8 +21,7 @@ typedef unsigned short apm_eventinfo_t; #ifdef __KERNEL__ -#define APM_40 (GDT_ENTRY_APMBIOS_BASE * 8) -#define APM_CS (APM_BASE + 8) +#define APM_CS (GDT_ENTRY_APMBIOS_BASE * 8) #define APM_CS_16 (APM_CS + 8) #define APM_DS (APM_CS_16 + 8) diff --git a/include/linux/fb.h b/include/linux/fb.h index 0340aa886918..0fd013774ac7 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -316,12 +316,6 @@ struct fb_ops { struct module *owner; int (*fb_open)(struct fb_info *info, int user); int (*fb_release)(struct fb_info *info, int user); - /* get non settable parameters */ - int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info); - /* get settable parameters */ - int (*fb_get_var)(struct fb_var_screeninfo *var, int con, - struct fb_info *info); /* set settable parameters */ int (*fb_set_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info); @@ -399,10 +393,6 @@ struct fb_info { * `Generic' versions of the frame buffer device operations */ -extern int gen_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info); -extern int gen_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); extern int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info); extern int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, diff --git a/include/linux/fs.h b/include/linux/fs.h index 192107379fd9..ec0f6edac31b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1241,6 +1241,7 @@ extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *); +extern ssize_t generic_file_write_nolock(struct file *, const char *, size_t, loff_t *); extern ssize_t generic_file_sendfile(struct file *, struct file *, loff_t *, size_t); extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t); ssize_t generic_file_direct_IO(int rw, struct inode *inode, char *buf, diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 56c6b7181796..d023d2360a71 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -5,34 +5,34 @@ #define INIT_FILES \ { \ - count: ATOMIC_INIT(1), \ - file_lock: RW_LOCK_UNLOCKED, \ - max_fds: NR_OPEN_DEFAULT, \ - max_fdset: __FD_SETSIZE, \ - next_fd: 0, \ - fd: &init_files.fd_array[0], \ - close_on_exec: &init_files.close_on_exec_init, \ - open_fds: &init_files.open_fds_init, \ - close_on_exec_init: { { 0, } }, \ - open_fds_init: { { 0, } }, \ - fd_array: { NULL, } \ + .count = ATOMIC_INIT(1), \ + .file_lock = RW_LOCK_UNLOCKED, \ + .max_fds = NR_OPEN_DEFAULT, \ + .max_fdset = __FD_SETSIZE, \ + .next_fd = 0, \ + .fd = &init_files.fd_array[0], \ + .close_on_exec = &init_files.close_on_exec_init, \ + .open_fds = &init_files.open_fds_init, \ + .close_on_exec_init = { { 0, } }, \ + .open_fds_init = { { 0, } }, \ + .fd_array = { NULL, } \ } #define INIT_MM(name) \ { \ - mm_rb: RB_ROOT, \ - pgd: swapper_pg_dir, \ - mm_users: ATOMIC_INIT(2), \ - mm_count: ATOMIC_INIT(1), \ - mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \ - page_table_lock: SPIN_LOCK_UNLOCKED, \ - mmlist: LIST_HEAD_INIT(name.mmlist), \ + .mm_rb = RB_ROOT, \ + .pgd = swapper_pg_dir, \ + .mm_users = ATOMIC_INIT(2), \ + .mm_count = ATOMIC_INIT(1), \ + .mmap_sem = __RWSEM_INITIALIZER(name.mmap_sem), \ + .page_table_lock = SPIN_LOCK_UNLOCKED, \ + .mmlist = LIST_HEAD_INIT(name.mmlist), \ } #define INIT_SIGNALS { \ - count: ATOMIC_INIT(1), \ - action: { {{0,}}, }, \ - siglock: SPIN_LOCK_UNLOCKED \ + .count = ATOMIC_INIT(1), \ + .action = { {{0,}}, }, \ + .siglock = SPIN_LOCK_UNLOCKED \ } /* @@ -41,45 +41,45 @@ */ #define INIT_TASK(tsk) \ { \ - state: 0, \ - thread_info: &init_thread_info, \ - flags: 0, \ - lock_depth: -1, \ - prio: MAX_PRIO-20, \ - static_prio: MAX_PRIO-20, \ - policy: SCHED_NORMAL, \ - cpus_allowed: -1, \ - mm: NULL, \ - active_mm: &init_mm, \ - run_list: LIST_HEAD_INIT(tsk.run_list), \ - time_slice: HZ, \ - tasks: LIST_HEAD_INIT(tsk.tasks), \ - real_parent: &tsk, \ - parent: &tsk, \ - children: LIST_HEAD_INIT(tsk.children), \ - sibling: LIST_HEAD_INIT(tsk.sibling), \ - thread_group: LIST_HEAD_INIT(tsk.thread_group), \ - wait_chldexit: __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\ - real_timer: { \ - function: it_real_fn \ - }, \ - cap_effective: CAP_INIT_EFF_SET, \ - cap_inheritable: CAP_INIT_INH_SET, \ - cap_permitted: CAP_FULL_SET, \ - keep_capabilities: 0, \ - rlim: INIT_RLIMITS, \ - user: INIT_USER, \ - comm: "swapper", \ - thread: INIT_THREAD, \ - fs: &init_fs, \ - files: &init_files, \ - sigmask_lock: SPIN_LOCK_UNLOCKED, \ - sig: &init_signals, \ - pending: { NULL, &tsk.pending.head, {{0}}}, \ - blocked: {{0}}, \ - alloc_lock: SPIN_LOCK_UNLOCKED, \ - switch_lock: SPIN_LOCK_UNLOCKED, \ - journal_info: NULL, \ + .state = 0, \ + .thread_info = &init_thread_info, \ + .flags = 0, \ + .lock_depth = -1, \ + .prio = MAX_PRIO-20, \ + .static_prio = MAX_PRIO-20, \ + .policy = SCHED_NORMAL, \ + .cpus_allowed = -1, \ + .mm = NULL, \ + .active_mm = &init_mm, \ + .run_list = LIST_HEAD_INIT(tsk.run_list), \ + .time_slice = HZ, \ + .tasks = LIST_HEAD_INIT(tsk.tasks), \ + .real_parent = &tsk, \ + .parent = &tsk, \ + .children = LIST_HEAD_INIT(tsk.children), \ + .sibling = LIST_HEAD_INIT(tsk.sibling), \ + .thread_group = LIST_HEAD_INIT(tsk.thread_group), \ + .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\ + .real_timer = { \ + .function = it_real_fn \ + }, \ + .cap_effective = CAP_INIT_EFF_SET, \ + .cap_inheritable = CAP_INIT_INH_SET, \ + .cap_permitted = CAP_FULL_SET, \ + .keep_capabilities = 0, \ + .rlim = INIT_RLIMITS, \ + .user = INIT_USER, \ + .comm = "swapper", \ + .thread = INIT_THREAD, \ + .fs = &init_fs, \ + .files = &init_files, \ + .sigmask_lock = SPIN_LOCK_UNLOCKED, \ + .sig = &init_signals, \ + .pending = { NULL, &tsk.pending.head, {{0}}}, \ + .blocked = {{0}}, \ + .alloc_lock = SPIN_LOCK_UNLOCKED, \ + .switch_lock = SPIN_LOCK_UNLOCKED, \ + .journal_info = NULL, \ } diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 577df0fbe10d..06ff863fbc95 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -1,14 +1,9 @@ #ifndef __LINUX_PERCPU_H #define __LINUX_PERCPU_H -#include <linux/config.h> - -#ifdef CONFIG_SMP -#define __per_cpu_data __attribute__((section(".data.percpu"))) +#include <linux/spinlock.h> /* For preempt_disable() */ #include <asm/percpu.h> -#else -#define __per_cpu_data -#define per_cpu(var, cpu) var -#define this_cpu(var) var -#endif + +#define get_cpu_var(var) ({ preempt_disable(); __get_cpu_var(var); }) +#define put_cpu_var(var) preempt_enable() #endif /* __LINUX_PERCPU_H */ diff --git a/include/linux/rtc.h b/include/linux/rtc.h index e99a2357ab28..33edafbe6000 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -39,10 +39,32 @@ struct rtc_wkalrm { struct rtc_time time; /* time the alarm is set to */ }; +/* + * Data structure to control PLL correction some better RTC feature + * pll_value is used to get or set current value of correction, + * the rest of the struct is used to query HW capabilities. + * This is modeled after the RTC used in Q40/Q60 computers but + * should be sufficiently flexible for other devices + * + * +ve pll_value means clock will run faster by + * pll_value*pll_posmult/pll_clock + * -ve pll_value means clock will run slower by + * pll_value*pll_negmult/pll_clock + */ + +struct rtc_pll_info { + int pll_ctrl; /* placeholder for fancier control */ + int pll_value; /* get/set correction value */ + int pll_max; /* max +ve (faster) adjustment value */ + int pll_min; /* max -ve (slower) adjustment value */ + int pll_posmult; /* factor for +ve corection */ + int pll_negmult; /* factor for -ve corection */ + long pll_clock; /* base PLL frequency */ +}; /* * ioctl calls that are permitted to the /dev/rtc interface, if - * CONFIG_RTC/CONFIG_EFI_RTC was enabled. + * any of the RTC drivers are enabled. */ #define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */ @@ -65,6 +87,8 @@ struct rtc_wkalrm { #define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/ #define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/ +#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ +#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ #ifdef __KERNEL__ diff --git a/include/linux/sched.h b/include/linux/sched.h index 7adc9c6278b7..fcd107c3d29c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -45,6 +45,10 @@ struct exec_domain; #define CLONE_THREAD 0x00010000 /* Same thread group? */ #define CLONE_NEWNS 0x00020000 /* New namespace group? */ #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ +#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ +#define CLONE_SETTID 0x00100000 /* write the TID back to userspace */ +#define CLONE_DETACHED 0x00200000 /* parent wants no child-exit signal */ +#define CLONE_RELEASE_VM 0x00400000 /* release the userspace VM */ #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD) @@ -303,6 +307,7 @@ struct task_struct { wait_queue_head_t wait_chldexit; /* for wait4() */ struct completion *vfork_done; /* for vfork() */ + long *user_vm_lock; /* for CLONE_RELEASE_VM */ unsigned long rt_priority; unsigned long it_real_value, it_prof_value, it_virt_value; diff --git a/include/linux/smp.h b/include/linux/smp.h index 9c6edbd8e6ec..6f6c6ed7a239 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -96,9 +96,6 @@ static inline void smp_send_reschedule_all(void) { } #define cpu_online_map 1 #define cpu_online(cpu) ({ cpu; 1; }) #define num_online_cpus() 1 -#define __per_cpu_data -#define per_cpu(var, cpu) var -#define this_cpu(var) var struct notifier_block; diff --git a/include/linux/stringify.h b/include/linux/stringify.h index 8a8323750228..0b4388356c87 100644 --- a/include/linux/stringify.h +++ b/include/linux/stringify.h @@ -4,10 +4,6 @@ /* Indirect stringification. Doing two levels allows the parameter to be a * macro itself. For example, compile with -DFOO=bar, __stringify(FOO) * converts to "bar". - * - * The "..." is gcc's cpp vararg macro syntax. It is required because __ALIGN, - * in linkage.h, contains a comma, which when expanded, causes it to look - * like two arguments, which breaks the standard non-vararg stringizer. */ #define __stringify_1(x) #x diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index eb118134b0c0..34cbc22c0732 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -30,6 +30,7 @@ struct svc_sock { #define SK_TEMP 4 /* temp (TCP) socket */ #define SK_QUED 5 /* on serv->sk_sockets */ #define SK_DEAD 6 /* socket closed */ +#define SK_CHNGBUF 7 /* need to change snd/rcv buffer sizes */ int sk_reserved; /* space on outq that is reserved */ diff --git a/include/linux/usb.h b/include/linux/usb.h index d9907d770a30..7f44f0ff05ef 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -734,6 +734,7 @@ extern void usb_deregister_dev(int num_minors, int start_minor); */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ #define USB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ +#define URB_NO_DMA_MAP 0x0004 /* urb->*_dma are valid on submit */ #define USB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */ #define USB_NO_FSBR 0x0020 /* UHCI-specific */ #define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ @@ -771,11 +772,15 @@ typedef void (*usb_complete_t)(struct urb *); * @transfer_flags: A variety of flags may be used to affect how URB * submission, unlinking, or operation are handled. Different * kinds of URB can use different flags. - * @transfer_buffer: For non-iso transfers, this identifies the buffer - * to (or from) which the I/O request will be performed. This - * buffer must be suitable for DMA; allocate it with kmalloc() + * @transfer_buffer: This identifies the buffer to (or from) which + * the I/O request will be performed (unless URB_NO_DMA_MAP is set). + * This buffer must be suitable for DMA; allocate it with kmalloc() * or equivalent. For transfers to "in" endpoints, contents of - * this buffer will be modified. + * this buffer will be modified. This buffer is used for data + * phases of control transfers. + * @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device + * driver is saying that it provided this DMA address, which the host + * controller driver should use instead of the transfer_buffer. * @transfer_buffer_length: How big is transfer_buffer. The transfer may * be broken up into chunks according to the current maximum packet * size for the endpoint, which is a function of the configuration @@ -789,6 +794,11 @@ typedef void (*usb_complete_t)(struct urb *); * @setup_packet: Only used for control transfers, this points to eight bytes * of setup data. Control transfers always start by sending this data * to the device. Then transfer_buffer is read or written, if needed. + * (Not used when URB_NO_DMA_MAP is set.) + * @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device + * driver has provided this DMA address for the setup packet. The + * host controller driver should use instead of setup_buffer. + * If there is a data phase, its buffer is identified by transfer_dma. * @start_frame: Returns the initial frame for interrupt or isochronous * transfers. * @number_of_packets: Lists the number of ISO transfer buffers. @@ -811,6 +821,23 @@ typedef void (*usb_complete_t)(struct urb *); * are submitted using usb_submit_urb(), and pending requests may be canceled * using usb_unlink_urb(). * + * Data Transfer Buffers: + * + * Normally drivers provide I/O buffers allocated with kmalloc() or otherwise + * taken from the general page pool. That is provided by transfer_buffer + * (control requests also use setup_packet), and host controller drivers + * perform a dma mapping (and unmapping) for each buffer transferred. Those + * mapping operations can be expensive on some platforms (such using a dma + * bounce buffer), although they're cheap on commodity x86 and ppc hardware. + * + * Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which + * tells the host controller driver that no such mapping is needed since + * the device driver is DMA-aware. For example, they might allocate a DMA + * buffer with usb_buffer_alloc(), or call usb_buffer_map(). + * When this transfer flag is provided, host controller drivers will use the + * dma addresses found in the transfer_dma and/or setup_dma fields rather than + * determing a dma address themselves. + * * Initialization: * * All URBs submitted must initialize dev, pipe, @@ -818,10 +845,10 @@ typedef void (*usb_complete_t)(struct urb *); * The USB_ASYNC_UNLINK transfer flag affects later invocations of * the usb_unlink_urb() routine. * - * All non-isochronous URBs must also initialize + * All URBs must also initialize * transfer_buffer and transfer_buffer_length. They may provide the * URB_SHORT_NOT_OK transfer flag, indicating that short reads are - * to be treated as errors. + * to be treated as errors; that flag is invalid for write requests. * * Bulk URBs may * use the USB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers @@ -896,10 +923,12 @@ struct urb int status; /* (return) non-ISO status */ unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ void *transfer_buffer; /* (in) associated data buffer */ + dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */ int transfer_buffer_length; /* (in) data buffer length */ int actual_length; /* (return) actual transfer length */ int bandwidth; /* bandwidth for INT/ISO request */ unsigned char *setup_packet; /* (in) setup packet (control only) */ + dma_addr_t setup_dma; /* (in) dma addr for setup_packet */ int start_frame; /* (modify) start frame (INT/ISO) */ int number_of_packets; /* (in) number of ISO packets */ int interval; /* (in) transfer interval (INT/ISO) */ @@ -910,6 +939,8 @@ struct urb struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */ }; +/* -------------------------------------------------------------------------- */ + /** * usb_fill_control_urb - initializes a control urb * @urb: pointer to the urb to initialize. @@ -1032,6 +1063,16 @@ extern struct urb *usb_get_urb(struct urb *urb); extern int usb_submit_urb(struct urb *urb, int mem_flags); extern int usb_unlink_urb(struct urb *urb); +#define HAVE_USB_BUFFERS +void *usb_buffer_alloc (struct usb_device *dev, size_t size, + int mem_flags, dma_addr_t *dma); +void usb_buffer_free (struct usb_device *dev, size_t size, + void *addr, dma_addr_t dma); + +struct urb *usb_buffer_map (struct urb *urb); +void usb_buffer_dmasync (struct urb *urb); +void usb_buffer_unmap (struct urb *urb); + /*-------------------------------------------------------------------* * SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 9cc67b500368..5da711fefc6f 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -1,44 +1,47 @@ -#ifndef __LINUX_VMALLOC_H -#define __LINUX_VMALLOC_H +#ifndef _LINUX_VMALLOC_H +#define _LINUX_VMALLOC_H #include <linux/spinlock.h> -#include <asm/pgtable.h> - /* bits in vm_struct->flags */ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ #define VM_ALLOC 0x00000002 /* vmalloc() */ +#define VM_MAP 0x00000004 /* vmap()ed pages */ struct vm_struct { - unsigned long flags; - void * addr; - unsigned long size; - unsigned long phys_addr; - struct vm_struct * next; + void *addr; + unsigned long size; + unsigned long flags; + struct page **pages; + unsigned int nr_pages; + unsigned long phys_addr; + struct vm_struct *next; }; -extern struct vm_struct * get_vm_area (unsigned long size, unsigned long flags); -extern void vfree(void * addr); -extern void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot); -extern long vread(char *buf, char *addr, unsigned long count); -extern void vmfree_area_pages(unsigned long address, unsigned long size); -extern int vmalloc_area_pages(unsigned long address, unsigned long size, - int gfp_mask, pgprot_t prot); -extern struct vm_struct *remove_kernel_area(void *addr); - /* - * Various ways to allocate pages. + * Highlevel APIs for driver use */ - -extern void * vmalloc(unsigned long size); -extern void * vmalloc_32(unsigned long size); +extern void *vmalloc(unsigned long size); +extern void *vmalloc_32(unsigned long size); +extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot); +extern void vfree(void *addr); + +extern void *vmap(struct page **pages, unsigned int count); +extern void vunmap(void *addr); + +/* + * Lowlevel-APIs (not for driver use!) + */ +extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); +extern struct vm_struct *remove_vm_area(void *addr); +extern int map_vm_area(struct vm_struct *area, pgprot_t prot, + struct page ***pages); +extern void unmap_vm_area(struct vm_struct *area); /* - * vmlist_lock is a read-write spinlock that protects vmlist - * Used in mm/vmalloc.c (get_vm_area() and vfree()) and fs/proc/kcore.c. + * Internals. Dont't use.. */ extern rwlock_t vmlist_lock; +extern struct vm_struct *vmlist; -extern struct vm_struct * vmlist; -#endif - +#endif /* _LINUX_VMALLOC_H */ diff --git a/include/linux/wait.h b/include/linux/wait.h index 4141ba6e6ed5..8664b02f230d 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -43,16 +43,16 @@ typedef struct __wait_queue_head wait_queue_head_t; */ #define __WAITQUEUE_INITIALIZER(name, tsk) { \ - task: tsk, \ - func: default_wake_function, \ - task_list: { NULL, NULL } } + .task = tsk, \ + .func = default_wake_function, \ + .task_list = { NULL, NULL } } #define DECLARE_WAITQUEUE(name, tsk) \ wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) #define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ - lock: SPIN_LOCK_UNLOCKED, \ - task_list: { &(name).task_list, &(name).task_list } } + .lock = SPIN_LOCK_UNLOCKED, \ + .task_list = { &(name).task_list, &(name).task_list } } #define DECLARE_WAIT_QUEUE_HEAD(name) \ wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) diff --git a/include/video/fbcon.h b/include/video/fbcon.h index e906f8ca81f5..c28fea0c10c3 100644 --- a/include/video/fbcon.h +++ b/include/video/fbcon.h @@ -55,12 +55,6 @@ struct display { struct fb_var_screeninfo var; /* variable infos. yoffset and vmode */ /* are updated by fbcon.c */ struct fb_cmap cmap; /* colormap */ - int visual; - int type; /* see FB_TYPE_* */ - int type_aux; /* Interleave for interleaved Planes */ - u_short ypanstep; /* zero if no hardware ypan */ - u_short ywrapstep; /* zero if no hardware ywrap */ - u_long line_length; /* length of a line in bytes */ u_short can_soft_blank; /* zero if no hardware blanking */ u_short inverse; /* != 0 text black on white as default */ struct display_switch *dispsw; /* low level operations */ @@ -73,7 +67,6 @@ struct display { #endif /* Filled in by the low-level console driver */ - struct vc_data *conp; /* pointer to console data */ struct fb_info *fb_info; /* frame buffer for this console */ int vrows; /* number of virtual rows */ diff --git a/init/do_mounts.c b/init/do_mounts.c index 3633d3701b37..8f3246e92e22 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -24,16 +24,16 @@ extern int get_filesystem_list(char * buf); -asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type, +extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type, unsigned long flags, void *data); -asmlinkage long sys_mkdir(char *name, int mode); -asmlinkage long sys_chdir(char *name); -asmlinkage long sys_chroot(char *name); -asmlinkage long sys_unlink(char *name); -asmlinkage long sys_symlink(char *old, char *new); -asmlinkage long sys_mknod(char *name, int mode, dev_t dev); -asmlinkage long sys_umount(char *name, int flags); -asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg); +extern asmlinkage long sys_mkdir(const char *name, int mode); +extern asmlinkage long sys_chdir(const char *name); +extern asmlinkage long sys_chroot(const char *name); +extern asmlinkage long sys_unlink(const char *name); +extern asmlinkage long sys_symlink(const char *old, const char *new); +extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev); +extern asmlinkage long sys_umount(char *name, int flags); +extern asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg); #ifdef CONFIG_BLK_DEV_INITRD unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ diff --git a/kernel/exit.c b/kernel/exit.c index 9d35d8ece02f..8c51bf9c8aee 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -56,10 +56,11 @@ static inline void __unhash_process(struct task_struct *p) static void release_task(struct task_struct * p) { - if (p == current) + if (p->state != TASK_ZOMBIE) BUG(); #ifdef CONFIG_SMP - wait_task_inactive(p); + if (p != current) + wait_task_inactive(p); #endif atomic_dec(&p->user->processes); security_ops->task_free_security(p); @@ -67,10 +68,12 @@ static void release_task(struct task_struct * p) unhash_process(p); release_thread(p); - current->cmin_flt += p->min_flt + p->cmin_flt; - current->cmaj_flt += p->maj_flt + p->cmaj_flt; - current->cnswap += p->nswap + p->cnswap; - sched_exit(p); + if (p != current) { + current->cmin_flt += p->min_flt + p->cmin_flt; + current->cmaj_flt += p->maj_flt + p->cmaj_flt; + current->cnswap += p->nswap + p->cnswap; + sched_exit(p); + } put_task_struct(p); } @@ -479,14 +482,15 @@ static void exit_notify(void) write_lock_irq(&tasklist_lock); current->state = TASK_ZOMBIE; - do_notify_parent(current, current->exit_signal); + if (current->exit_signal != -1) + do_notify_parent(current, current->exit_signal); while ((p = eldest_child(current))) { list_del_init(&p->sibling); p->ptrace = 0; p->parent = p->real_parent; list_add_tail(&p->sibling,&p->parent->children); - if (p->state == TASK_ZOMBIE) + if (p->state == TASK_ZOMBIE && p->exit_signal != -1) do_notify_parent(p, p->exit_signal); /* * process group orphan check @@ -555,6 +559,9 @@ fake_volatile: tsk->exit_code = code; exit_notify(); + preempt_disable(); + if (current->exit_signal == -1) + release_task(current); schedule(); BUG(); /* diff --git a/kernel/fork.c b/kernel/fork.c index 017740dc62c4..3cb62cfcf4fd 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -50,6 +50,31 @@ struct task_struct *pidhash[PIDHASH_SZ]; rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ +/* + * A per-CPU task cache - this relies on the fact that + * the very last portion of sys_exit() is executed with + * preemption turned off. + */ +static task_t *task_cache[NR_CPUS] __cacheline_aligned; + +void __put_task_struct(struct task_struct *tsk) +{ + if (tsk != current) { + free_thread_info(tsk->thread_info); + kmem_cache_free(task_struct_cachep,tsk); + } else { + int cpu = smp_processor_id(); + + tsk = task_cache[cpu]; + if (tsk) { + free_thread_info(tsk->thread_info); + kmem_cache_free(task_struct_cachep,tsk); + } + task_cache[cpu] = current; + } +} + +/* Protects next_safe and last_pid. */ void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; @@ -123,13 +148,6 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) return tsk; } -void __put_task_struct(struct task_struct *tsk) -{ - free_thread_info(tsk->thread_info); - kmem_cache_free(task_struct_cachep,tsk); -} - -/* Protects next_safe and last_pid. */ spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED; static int get_pid(unsigned long flags) @@ -349,6 +367,12 @@ void mm_release(void) tsk->vfork_done = NULL; complete(vfork_done); } + if (tsk->user_vm_lock) + /* + * We dont check the error code - if userspace has + * not set up a proper pointer then tough luck. + */ + put_user(0UL, tsk->user_vm_lock); } static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) @@ -737,7 +761,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, /* ok, now we should be set up.. */ p->swappable = 1; - p->exit_signal = clone_flags & CSIGNAL; + if (clone_flags & CLONE_DETACHED) + p->exit_signal = -1; + else + p->exit_signal = clone_flags & CSIGNAL; p->pdeath_signal = 0; /* diff --git a/kernel/ksyms.c b/kernel/ksyms.c index d0a08cc4ce6c..df2891739e70 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -50,6 +50,7 @@ #include <linux/namei.h> #include <linux/buffer_head.h> #include <linux/root_dev.h> +#include <linux/percpu.h> #include <asm/checksum.h> #if defined(CONFIG_PROC_FS) @@ -109,6 +110,8 @@ EXPORT_SYMBOL(vfree); EXPORT_SYMBOL(__vmalloc); EXPORT_SYMBOL(vmalloc); EXPORT_SYMBOL(vmalloc_32); +EXPORT_SYMBOL(vmap); +EXPORT_SYMBOL(vunmap); EXPORT_SYMBOL(vmalloc_to_page); EXPORT_SYMBOL(mem_map); EXPORT_SYMBOL(remap_page_range); @@ -220,6 +223,7 @@ EXPORT_SYMBOL(generic_file_read); EXPORT_SYMBOL(generic_file_sendfile); EXPORT_SYMBOL(do_generic_file_read); EXPORT_SYMBOL(generic_file_write); +EXPORT_SYMBOL(generic_file_write_nolock); EXPORT_SYMBOL(generic_file_mmap); EXPORT_SYMBOL(generic_ro_fops); EXPORT_SYMBOL(file_lock_list); @@ -595,3 +599,6 @@ EXPORT_SYMBOL(init_thread_union); EXPORT_SYMBOL(tasklist_lock); EXPORT_SYMBOL(pidhash); +#if defined(CONFIG_SMP) && defined(__GENERIC_PER_CPU) +EXPORT_SYMBOL(__per_cpu_offset); +#endif diff --git a/kernel/signal.c b/kernel/signal.c index fd9dd81c2815..b97914bf8a85 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -768,12 +768,15 @@ static void wake_up_parent(struct task_struct *parent) /* * Let a parent know about a status change of a child. */ - void do_notify_parent(struct task_struct *tsk, int sig) { struct siginfo info; int why, status; + /* is the thread detached? */ + if (sig == -1 || tsk->exit_signal == -1) + BUG(); + info.si_signo = sig; info.si_errno = 0; info.si_pid = tsk->pid; @@ -823,9 +826,11 @@ void do_notify_parent(struct task_struct *tsk, int sig) void notify_parent(struct task_struct *tsk, int sig) { - read_lock(&tasklist_lock); - do_notify_parent(tsk, sig); - read_unlock(&tasklist_lock); + if (sig != -1) { + read_lock(&tasklist_lock); + do_notify_parent(tsk, sig); + read_unlock(&tasklist_lock); + } } #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER diff --git a/kernel/softirq.c b/kernel/softirq.c index 58825a0bbc62..4405e83aaf21 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -151,16 +151,16 @@ struct tasklet_head /* Some compilers disobey section attribute on statics when not initialized -- RR */ -static struct tasklet_head tasklet_vec __per_cpu_data = { NULL }; -static struct tasklet_head tasklet_hi_vec __per_cpu_data = { NULL }; +static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec) = { NULL }; +static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec) = { NULL }; void __tasklet_schedule(struct tasklet_struct *t) { unsigned long flags; local_irq_save(flags); - t->next = this_cpu(tasklet_vec).list; - this_cpu(tasklet_vec).list = t; + t->next = __get_cpu_var(tasklet_vec).list; + __get_cpu_var(tasklet_vec).list = t; cpu_raise_softirq(smp_processor_id(), TASKLET_SOFTIRQ); local_irq_restore(flags); } @@ -170,8 +170,8 @@ void __tasklet_hi_schedule(struct tasklet_struct *t) unsigned long flags; local_irq_save(flags); - t->next = this_cpu(tasklet_hi_vec).list; - this_cpu(tasklet_hi_vec).list = t; + t->next = __get_cpu_var(tasklet_hi_vec).list; + __get_cpu_var(tasklet_hi_vec).list = t; cpu_raise_softirq(smp_processor_id(), HI_SOFTIRQ); local_irq_restore(flags); } @@ -181,8 +181,8 @@ static void tasklet_action(struct softirq_action *a) struct tasklet_struct *list; local_irq_disable(); - list = this_cpu(tasklet_vec).list; - this_cpu(tasklet_vec).list = NULL; + list = __get_cpu_var(tasklet_vec).list; + __get_cpu_var(tasklet_vec).list = NULL; local_irq_enable(); while (list) { @@ -202,8 +202,8 @@ static void tasklet_action(struct softirq_action *a) } local_irq_disable(); - t->next = this_cpu(tasklet_vec).list; - this_cpu(tasklet_vec).list = t; + t->next = __get_cpu_var(tasklet_vec).list; + __get_cpu_var(tasklet_vec).list = t; __cpu_raise_softirq(smp_processor_id(), TASKLET_SOFTIRQ); local_irq_enable(); } @@ -214,8 +214,8 @@ static void tasklet_hi_action(struct softirq_action *a) struct tasklet_struct *list; local_irq_disable(); - list = this_cpu(tasklet_hi_vec).list; - this_cpu(tasklet_hi_vec).list = NULL; + list = __get_cpu_var(tasklet_hi_vec).list; + __get_cpu_var(tasklet_hi_vec).list = NULL; local_irq_enable(); while (list) { @@ -235,8 +235,8 @@ static void tasklet_hi_action(struct softirq_action *a) } local_irq_disable(); - t->next = this_cpu(tasklet_hi_vec).list; - this_cpu(tasklet_hi_vec).list = t; + t->next = __get_cpu_var(tasklet_hi_vec).list; + __get_cpu_var(tasklet_hi_vec).list = t; __cpu_raise_softirq(smp_processor_id(), HI_SOFTIRQ); local_irq_enable(); } diff --git a/mm/filemap.c b/mm/filemap.c index e308a02bf663..c06901afd44c 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1109,7 +1109,7 @@ static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned return written; } -ssize_t generic_file_sendfile(struct file *in_file, struct file *out_file, +ssize_t generic_file_sendfile(struct file *out_file, struct file *in_file, loff_t *ppos, size_t count) { read_descriptor_t desc; @@ -1812,9 +1812,8 @@ inline void remove_suid(struct dentry *dentry) * it for writing by marking it dirty. * okir@monad.swb.de */ -ssize_t -generic_file_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) +ssize_t generic_file_write_nolock(struct file *file, const char *buf, + size_t count, loff_t *ppos) { struct address_space * mapping = file->f_dentry->d_inode->i_mapping; struct address_space_operations *a_ops = mapping->a_ops; @@ -1829,18 +1828,15 @@ generic_file_write(struct file *file, const char *buf, unsigned bytes; time_t time_now; - if (unlikely((ssize_t) count < 0)) + if (unlikely((ssize_t)count < 0)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; - down(&inode->i_sem); pos = *ppos; - if (unlikely(pos < 0)) { - err = -EINVAL; - goto out; - } + if (unlikely(pos < 0)) + return -EINVAL; if (unlikely(file->f_error)) { err = file->f_error; @@ -2037,6 +2033,18 @@ generic_file_write(struct file *file, const char *buf, out_status: err = written ? written : status; out: + return err; +} + +ssize_t generic_file_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + struct inode *inode = file->f_dentry->d_inode->i_mapping->host; + int err; + + down(&inode->i_sem); + err = generic_file_write_nolock(file, buf, count, ppos); up(&inode->i_sem); + return err; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 50cc6d13f0ff..83fbee99c1ea 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -4,27 +4,28 @@ * Copyright (C) 1993 Linus Torvalds * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 * SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000 + * Major rework to support vmap/vunmap, Christoph Hellwig, SGI, August 2002 */ -#include <linux/config.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/spinlock.h> #include <linux/mm.h> #include <linux/highmem.h> -#include <linux/smp_lock.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/vmalloc.h> #include <asm/uaccess.h> #include <asm/pgalloc.h> #include <asm/tlbflush.h> + rwlock_t vmlist_lock = RW_LOCK_UNLOCKED; -struct vm_struct * vmlist; +struct vm_struct *vmlist; -static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size) +static inline void unmap_area_pte(pmd_t *pmd, unsigned long address, + unsigned long size) { - pte_t * pte; unsigned long end; + pte_t *pte; if (pmd_none(*pmd)) return; @@ -33,11 +34,13 @@ static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned lo pmd_clear(pmd); return; } + pte = pte_offset_kernel(pmd, address); address &= ~PMD_MASK; end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; + do { pte_t page; page = ptep_get_and_clear(pte); @@ -45,24 +48,17 @@ static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned lo pte++; if (pte_none(page)) continue; - if (pte_present(page)) { - struct page *ptpage; - unsigned long pfn = pte_pfn(page); - if (!pfn_valid(pfn)) - continue; - ptpage = pfn_to_page(pfn); - if (!PageReserved(ptpage)) - __free_page(ptpage); + if (pte_present(page)) continue; - } printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n"); } while (address < end); } -static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size) +static inline void unmap_area_pmd(pgd_t *dir, unsigned long address, + unsigned long size) { - pmd_t * pmd; unsigned long end; + pmd_t *pmd; if (pgd_none(*dir)) return; @@ -71,36 +67,23 @@ static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned lo pgd_clear(dir); return; } + pmd = pmd_offset(dir, address); address &= ~PGDIR_MASK; end = address + size; if (end > PGDIR_SIZE) end = PGDIR_SIZE; + do { - free_area_pte(pmd, address, end - address); + unmap_area_pte(pmd, address, end - address); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); } -void vmfree_area_pages(unsigned long start, unsigned long size) -{ - pgd_t * dir; - unsigned long address = start; - unsigned long end = start + size; - - dir = pgd_offset_k(address); - flush_cache_all(); - do { - free_area_pmd(dir, address, end - address); - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - flush_tlb_kernel_range(start, end); -} - -static inline int alloc_area_pte (pte_t * pte, unsigned long address, - unsigned long size, int gfp_mask, pgprot_t prot) +static inline int map_area_pte(pte_t *pte, unsigned long address, + unsigned long size, pgprot_t prot, + struct page ***pages) { unsigned long end; @@ -108,23 +91,26 @@ static inline int alloc_area_pte (pte_t * pte, unsigned long address, end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; + do { - struct page * page; - spin_unlock(&init_mm.page_table_lock); - page = alloc_page(gfp_mask); - spin_lock(&init_mm.page_table_lock); + struct page *page = **pages; + if (!pte_none(*pte)) printk(KERN_ERR "alloc_area_pte: page already exists\n"); if (!page) return -ENOMEM; + set_pte(pte, mk_pte(page, prot)); address += PAGE_SIZE; pte++; + (*pages)++; } while (address < end); return 0; } -static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, int gfp_mask, pgprot_t prot) +static inline int map_area_pmd(pmd_t *pmd, unsigned long address, + unsigned long size, pgprot_t prot, + struct page ***pages) { unsigned long end; @@ -132,76 +118,108 @@ static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo end = address + size; if (end > PGDIR_SIZE) end = PGDIR_SIZE; + do { pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); if (!pte) return -ENOMEM; - if (alloc_area_pte(pte, address, end - address, gfp_mask, prot)) + if (map_area_pte(pte, address, end - address, prot, pages)) return -ENOMEM; address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); + return 0; } -inline int vmalloc_area_pages (unsigned long address, unsigned long size, - int gfp_mask, pgprot_t prot) +void unmap_vm_area(struct vm_struct *area) +{ + unsigned long address = VMALLOC_VMADDR(area->addr); + unsigned long end = (address + area->size); + pgd_t *dir; + + dir = pgd_offset_k(address); + flush_cache_all(); + do { + unmap_area_pmd(dir, address, end - address); + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_kernel_range(VMALLOC_VMADDR(area->addr), end); +} + +int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages) { - pgd_t * dir; - unsigned long end = address + size; - int ret; + unsigned long address = VMALLOC_VMADDR(area->addr); + unsigned long end = address + (area->size-PAGE_SIZE); + pgd_t *dir; dir = pgd_offset_k(address); spin_lock(&init_mm.page_table_lock); do { - pmd_t *pmd; - - pmd = pmd_alloc(&init_mm, dir, address); - ret = -ENOMEM; + pmd_t *pmd = pmd_alloc(&init_mm, dir, address); if (!pmd) - break; - - ret = -ENOMEM; - if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot)) - break; + return -ENOMEM; + if (map_area_pmd(pmd, address, end - address, prot, pages)) + return -ENOMEM; address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; - - ret = 0; } while (address && (address < end)); + spin_unlock(&init_mm.page_table_lock); flush_cache_all(); - return ret; + return 0; } -struct vm_struct * get_vm_area(unsigned long size, unsigned long flags) + +/** + * get_vm_area - reserve a contingous kernel virtual area + * + * @size: size of the area + * @flags: %VM_IOREMAP for I/O mappings or VM_ALLOC + * + * Search an area of @size in the kernel virtual mapping area, + * and reserved it for out purposes. Returns the area descriptor + * on success or %NULL on failure. + */ +struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) { - unsigned long addr; struct vm_struct **p, *tmp, *area; + unsigned long addr = VMALLOC_START; - area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); - if (!area) + area = kmalloc(sizeof(*area), GFP_KERNEL); + if (unlikely(!area)) return NULL; + + /* + * We always allocate a guard page. + */ size += PAGE_SIZE; - addr = VMALLOC_START; + write_lock(&vmlist_lock); - for (p = &vmlist; (tmp = *p) ; p = &tmp->next) { + for (p = &vmlist; (tmp = *p) ;p = &tmp->next) { if ((size + addr) < addr) goto out; - if (size + addr <= (unsigned long) tmp->addr) - break; - addr = tmp->size + (unsigned long) tmp->addr; + if (size + addr <= (unsigned long)tmp->addr) + goto found; + addr = tmp->size + (unsigned long)tmp->addr; if (addr > VMALLOC_END-size) goto out; } - area->phys_addr = 0; + +found: + area->next = *p; + *p = area; + area->flags = flags; area->addr = (void *)addr; area->size = size; - area->next = *p; - *p = area; + area->pages = NULL; + area->nr_pages = 0; + area->phys_addr = 0; write_unlock(&vmlist_lock); + return area; out: @@ -210,87 +228,203 @@ out: return NULL; } -struct vm_struct *remove_kernel_area(void *addr) +/** + * remove_vm_area - find and remove a contingous kernel virtual area + * + * @addr: base address + * + * Search for the kernel VM area starting at @addr, and remove it. + * This function returns the found VM area, but using it is NOT safe + * on SMP machines. + */ +struct vm_struct *remove_vm_area(void *addr) { struct vm_struct **p, *tmp; - write_lock(&vmlist_lock); - for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { - if (tmp->addr == addr) { - *p = tmp->next; - write_unlock(&vmlist_lock); - return tmp; - } + write_lock(&vmlist_lock); + for (p = &vmlist ; (tmp = *p) ;p = &tmp->next) { + if (tmp->addr == addr) + goto found; } write_unlock(&vmlist_lock); return NULL; -} -void vfree(void * addr) +found: + *p = tmp->next; + write_unlock(&vmlist_lock); + return tmp; +} + +void __vunmap(void *addr, int deallocate_pages) { - struct vm_struct *tmp; + struct vm_struct *area; if (!addr) return; - if ((PAGE_SIZE-1) & (unsigned long) addr) { + + if ((PAGE_SIZE-1) & (unsigned long)addr) { printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr); return; } - tmp = remove_kernel_area(addr); - if (tmp) { - vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size); - kfree(tmp); - return; + + area = remove_vm_area(addr); + if (unlikely(!area)) { + printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", + addr); + return; + } + + unmap_vm_area(area); + + if (deallocate_pages) { + int i; + + for (i = 0; i < area->nr_pages; i++) { + if (unlikely(!area->pages[i])) + BUG(); + __free_page(area->pages[i]); } - printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); + + kfree(area->pages); + } + + kfree(area); + return; } -/* - * Allocate any pages +/** + * vfree - release memory allocated by vmalloc() + * + * @addr: memory base address + * + * Free the virtually continguos memory area starting at @addr, as + * obtained from vmalloc(), vmalloc_32() or __vmalloc(). + * + * May not be called in interrupt context. */ - -void * vmalloc (unsigned long size) +void vfree(void *addr) { - return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); + __vunmap(addr, 1); } -/* - * Allocate ISA addressable pages for broke crap +/** + * vunmap - release virtual mapping obtained by vmap() + * + * @addr: memory base address + * + * Free the virtually continguos memory area starting at @addr, + * which was created from the page array passed to vmap(). + * + * May not be called in interrupt context. */ - -void * vmalloc_dma (unsigned long size) +void vunmap(void *addr) { - return __vmalloc(size, GFP_KERNEL|GFP_DMA, PAGE_KERNEL); + __vunmap(addr, 0); } -/* - * vmalloc 32bit PA addressable pages - eg for PCI 32bit devices +/** + * vmap - map an array of pages into virtually continguos space + * + * @pages: array of page pointers + * @count: number of pages to map + * + * Maps @count pages from @pages into continguos kernel virtual + * space. */ - -void * vmalloc_32(unsigned long size) +void *vmap(struct page **pages, unsigned int count) { - return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL); + struct vm_struct *area; + + if (count > num_physpages) + return NULL; + + area = get_vm_area((count << PAGE_SHIFT), VM_MAP); + if (!area) + return NULL; + if (map_vm_area(area, PAGE_KERNEL, &pages)) { + vunmap(area->addr); + return NULL; + } + + return area->addr; } -void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot) +/** + * __vmalloc - allocate virtually continguos memory + * + * @size: allocation size + * @gfp_mask: flags for the page level allocator + * @prot: protection mask for the allocated pages + * + * Allocate enough pages to cover @size from the page level + * allocator with @gfp_mask flags. Map them into continguos + * kernel virtual space, using a pagetable protection of @prot. + */ +void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot) { - void * addr; struct vm_struct *area; + struct page **pages; + unsigned int nr_pages, array_size, i; size = PAGE_ALIGN(size); - if (!size || (size >> PAGE_SHIFT) > num_physpages) { - BUG(); + if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL; - } + area = get_vm_area(size, VM_ALLOC); if (!area) return NULL; - addr = area->addr; - if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) { - vfree(addr); + + nr_pages = (size+PAGE_SIZE) >> PAGE_SHIFT; + array_size = (nr_pages * sizeof(struct page *)); + + area->nr_pages = nr_pages; + area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM)); + if (!area->pages) return NULL; + memset(area->pages, 0, array_size); + + for (i = 0; i < area->nr_pages; i++) { + area->pages[i] = alloc_page(gfp_mask); + if (unlikely(!area->pages[i])) + goto fail; } - return addr; + + if (map_vm_area(area, prot, &pages)) + goto fail; + return area->addr; + +fail: + vfree(area->addr); + return NULL; +} + +/** + * vmalloc - allocate virtually continguos memory + * + * @size: allocation size + * + * Allocate enough pages to cover @size from the page level + * allocator and map them into continguos kernel virtual space. + * + * For tight cotrol over page level allocator and protection flags + * use __vmalloc() instead. + */ +void *vmalloc(unsigned long size) +{ + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); +} + +/** + * vmalloc_32 - allocate virtually continguos memory (32bit addressable) + * + * @size: allocation size + * + * Allocate enough 32bit PA addressable pages to cover @size from the + * page level allocator and map them into continguos kernel virtual space. + */ +void *vmalloc_32(unsigned long size) +{ + return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL); } long vread(char *buf, char *addr, unsigned long count) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 86340a0ded95..ab28937c1dcd 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -481,6 +481,16 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) u32 *data; int err, len; + if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags)) + /* udp sockets need large rcvbuf as all pending + * requests are still in that buffer. sndbuf must + * also be large enough that there is enough space + * for one reply per thread. + */ + svc_sock_setbufsize(svsk->sk_sock, + (serv->sv_nrthreads+3) * serv->sv_bufsz, + (serv->sv_nrthreads+3) * serv->sv_bufsz); + clear_bit(SK_DATA, &svsk->sk_flags); while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { svc_sock_received(svsk); @@ -564,6 +574,8 @@ svc_udp_init(struct svc_sock *svsk) svsk->sk_recvfrom = svc_udp_recvfrom; svsk->sk_sendto = svc_udp_sendto; + set_bit(SK_CHNGBUF, &svsk->sk_flags); + return 0; } @@ -771,6 +783,18 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) return 0; } + if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags)) + /* sndbuf needs to have room for one request + * per thread, otherwise we can stall even when the + * network isn't a bottleneck. + * rcvbuf just needs to be able to hold a few requests. + * Normally they will be removed from the queue + * as soon a a complete request arrives. + */ + svc_sock_setbufsize(svsk->sk_sock, + (serv->sv_nrthreads+3) * serv->sv_bufsz, + 3 * serv->sv_bufsz); + clear_bit(SK_DATA, &svsk->sk_flags); /* Receive data. If we haven't got the record length yet, get @@ -787,6 +811,9 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) goto error; svsk->sk_tcplen += len; + if (len < want) + return 0; + svsk->sk_reclen = ntohl(svsk->sk_reclen); if (!(svsk->sk_reclen & 0x80000000)) { /* FIXME: technically, a record can be fragmented, @@ -887,8 +914,9 @@ svc_tcp_sendto(struct svc_rqst *rqstp) sent = svc_sendto(rqstp, bufp->iov, bufp->nriov); if (sent != bufp->len<<2) { - printk(KERN_NOTICE "rpc-srv/tcp: %s: sent only %d bytes of %d - should shutdown socket\n", + printk(KERN_NOTICE "rpc-srv/tcp: %s: %s %d when sending %d bytes - shutting down socket\n", rqstp->rq_sock->sk_server->sv_name, + (sent<0)?"got error":"sent only", sent, bufp->len << 2); svc_delete_socket(rqstp->rq_sock); sent = -EAGAIN; @@ -916,17 +944,7 @@ svc_tcp_init(struct svc_sock *svsk) svsk->sk_reclen = 0; svsk->sk_tcplen = 0; - /* sndbuf needs to have room for one request - * per thread, otherwise we can stall even when the - * network isn't a bottleneck. - * rcvbuf just needs to be able to hold a few requests. - * Normally they will be removed from the queue - * as soon a a complete request arrives. - */ - svc_sock_setbufsize(svsk->sk_sock, - (svsk->sk_server->sv_nrthreads+3) * - svsk->sk_server->sv_bufsz, - 3 * svsk->sk_server->sv_bufsz); + set_bit(SK_CHNGBUF, &svsk->sk_flags); } return 0; @@ -945,30 +963,12 @@ svc_sock_update_bufs(struct svc_serv *serv) list_for_each(le, &serv->sv_permsocks) { struct svc_sock *svsk = list_entry(le, struct svc_sock, sk_list); - struct socket *sock = svsk->sk_sock; - if (sock->type == SOCK_DGRAM) { - /* udp sockets need large rcvbuf as all pending - * requests are still in that buffer. - */ - svc_sock_setbufsize(sock, - (serv->sv_nrthreads+3) * serv->sv_bufsz, - (serv->sv_nrthreads+3) * serv->sv_bufsz); - } else if (svsk->sk_sk->state != TCP_LISTEN) { - printk(KERN_ERR "RPC update_bufs: permanent sock neither UDP or TCP_LISTEN\n"); - } + set_bit(SK_CHNGBUF, &svsk->sk_flags); } list_for_each(le, &serv->sv_tempsocks) { struct svc_sock *svsk = list_entry(le, struct svc_sock, sk_list); - struct socket *sock = svsk->sk_sock; - if (sock->type == SOCK_STREAM) { - /* See svc_tcp_init above for rationale on buffer sizes */ - svc_sock_setbufsize(sock, - (serv->sv_nrthreads+3) * - serv->sv_bufsz, - 3 * serv->sv_bufsz); - } else - printk(KERN_ERR "RPC update_bufs: temp sock not TCP\n"); + set_bit(SK_CHNGBUF, &svsk->sk_flags); } spin_unlock_bh(&serv->sv_lock); } @@ -1212,6 +1212,7 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) return error; if (sin != NULL) { + sock->sk->reuse = 1; /* allow address reuse */ error = sock->ops->bind(sock, (struct sockaddr *) sin, sizeof(*sin)); if (error < 0) |
