## Automatically generated incremental diff ## From: linux-2.4.21-bk22 ## To: linux-2.4.21-bk23 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.21-bk22/Makefile linux-2.4.21-bk23/Makefile --- linux-2.4.21-bk22/Makefile 2003-07-31 02:53:47.000000000 -0700 +++ linux-2.4.21-bk23/Makefile 2003-07-31 02:53:53.000000000 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 21 -EXTRAVERSION = -bk22 +EXTRAVERSION = -bk23 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.21-bk22/arch/ppc/kernel/ppc_ksyms.c linux-2.4.21-bk23/arch/ppc/kernel/ppc_ksyms.c --- linux-2.4.21-bk22/arch/ppc/kernel/ppc_ksyms.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.21-bk23/arch/ppc/kernel/ppc_ksyms.c 2003-07-31 02:53:53.000000000 -0700 @@ -353,6 +353,10 @@ EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(handle_mm_fault); /* For MOL */ +#ifdef CONFIG_SMP +extern int *hash_table_lock; +EXPORT_SYMBOL_NOVERS(hash_table_lock); /* For MOL */ +#endif EXPORT_SYMBOL_NOVERS(disarm_decr); #ifdef CONFIG_PPC_STD_MMU EXPORT_SYMBOL(flush_hash_page); /* For MOL */ diff -urN linux-2.4.21-bk22/drivers/acpi/system.c linux-2.4.21-bk23/drivers/acpi/system.c --- linux-2.4.21-bk22/drivers/acpi/system.c 2003-07-31 02:53:49.000000000 -0700 +++ linux-2.4.21-bk23/drivers/acpi/system.c 2003-07-31 02:53:54.000000000 -0700 @@ -90,9 +90,7 @@ static void acpi_power_off (void) { - acpi_enter_sleep_state_prep(ACPI_STATE_S5); - ACPI_DISABLE_IRQS(); - acpi_enter_sleep_state(ACPI_STATE_S5); + acpi_suspend(ACPI_STATE_S5); } #endif /*CONFIG_PM*/ @@ -180,7 +178,7 @@ return AE_ERROR; } - if (state < ACPI_STATE_S5) { + if (state <= ACPI_STATE_S5) { /* Tell devices to stop I/O and actually save their state. * It is theoretically possible that something could fail, * so handle that gracefully.. diff -urN linux-2.4.21-bk22/drivers/char/ipmi/ipmi_kcs_intf.c linux-2.4.21-bk23/drivers/char/ipmi/ipmi_kcs_intf.c --- linux-2.4.21-bk22/drivers/char/ipmi/ipmi_kcs_intf.c 2003-07-31 02:53:49.000000000 -0700 +++ linux-2.4.21-bk23/drivers/char/ipmi/ipmi_kcs_intf.c 2003-07-31 02:53:54.000000000 -0700 @@ -1025,7 +1025,7 @@ return rv; } -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER /* Retrieve the base physical address from ACPI tables. Originally from Hewlett-Packard simple bmc.c, a GPL KCS driver. */ @@ -1085,7 +1085,7 @@ int rv = 0; int pos = 0; int i = 0; -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER unsigned long physaddr = 0; #endif @@ -1115,7 +1115,7 @@ (because they weren't already specified above). */ if (kcs_trydefaults) { -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_INTERPRETER if ((physaddr = acpi_find_bmc())) { if (!check_mem_region(physaddr, 2)) { rv = init_one_kcs(0, diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_DAC1064.c linux-2.4.21-bk23/drivers/video/matrox/matroxfb_DAC1064.c --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_DAC1064.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_DAC1064.c 2003-07-31 02:53:55.000000000 -0700 @@ -1177,6 +1177,7 @@ DAC1064_restore_1(PMINFO2); matroxfb_vgaHWrestore(PMINFO2); + ACCESS_FBINFO(crtc1.panpos) = -1; for (i = 0; i < 6; i++) mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); DAC1064_restore_2(PMINFO p); @@ -1203,6 +1204,7 @@ if (ACCESS_FBINFO(devflags.support32MB)) mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]); #endif + ACCESS_FBINFO(crtc1.panpos) = -1; for (i = 0; i < 6; i++) mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); DAC1064_restore_2(PMINFO p); diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_Ti3026.c linux-2.4.21-bk23/drivers/video/matrox/matroxfb_Ti3026.c --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_Ti3026.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_Ti3026.c 2003-07-31 02:53:55.000000000 -0700 @@ -716,6 +716,7 @@ CRITBEGIN + ACCESS_FBINFO(crtc1.panpos) = -1; for (i = 0; i < 6; i++) mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_base.c linux-2.4.21-bk23/drivers/video/matrox/matroxfb_base.c --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_base.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_base.c 2003-07-31 02:53:55.000000000 -0700 @@ -152,6 +152,165 @@ /* --------------------------------------------------------------------- */ +static void matroxfb_crtc1_panpos(WPMINFO2) { + if (ACCESS_FBINFO(crtc1.panpos) >= 0) { + unsigned long flags; + int panpos; + + matroxfb_DAC_lock_irqsave(flags); + panpos = ACCESS_FBINFO(crtc1.panpos); + if (panpos >= 0) { + unsigned int extvga_reg; + + ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */ + extvga_reg = mga_inb(M_EXTVGA_INDEX); + mga_setr(M_EXTVGA_INDEX, 0x00, panpos); + if (extvga_reg != 0x00) { + mga_outb(M_EXTVGA_INDEX, extvga_reg); + } + } + matroxfb_DAC_unlock_irqrestore(flags); + } +} + +static void matrox_irq(int irq, void *dev_id, struct pt_regs *fp) +{ + u_int32_t status; + int handled = 0; + + MINFO_FROM(dev_id); + + status = mga_inl(M_STATUS); + + if (status & 0x20) { + mga_outl(M_ICLEAR, 0x20); + ACCESS_FBINFO(crtc1.vsync.cnt)++; + matroxfb_crtc1_panpos(PMINFO2); + wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait)); + handled = 1; + } + if (status & 0x200) { + mga_outl(M_ICLEAR, 0x200); + ACCESS_FBINFO(crtc2.vsync.cnt)++; + wake_up_interruptible(&ACCESS_FBINFO(crtc2.vsync.wait)); + handled = 1; + } + return; +} + +int matroxfb_enable_irq(WPMINFO int reenable) { + u_int32_t bm; + + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) + bm = 0x220; + else + bm = 0x020; + + if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { + if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, + SA_SHIRQ, "matroxfb", MINFO)) { + clear_bit(0, &ACCESS_FBINFO(irq_flags)); + return -EINVAL; + } + /* Clear any pending field interrupts */ + mga_outl(M_ICLEAR, bm); + mga_outl(M_IEN, mga_inl(M_IEN) | bm); + } else if (reenable) { + u_int32_t ien; + + ien = mga_inl(M_IEN); + if ((ien & bm) != bm) { + printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); + mga_outl(M_IEN, ien | bm); + } + } + return 0; +} + +static void matroxfb_disable_irq(WPMINFO2) { + if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) { + /* Flush pending pan-at-vbl request... */ + matroxfb_crtc1_panpos(PMINFO2); + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) + mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220); + else + mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20); + free_irq(ACCESS_FBINFO(pcidev)->irq, MINFO); + } +} + +#ifndef wait_event_interruptible_timeout +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) +#endif + +int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { + wait_queue_t __wait; + struct matrox_vsync *vs; + unsigned int cnt; + int ret; + + switch (crtc) { + case 0: + vs = &ACCESS_FBINFO(crtc1.vsync); + break; + case 1: + if (ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG400) { + return -ENODEV; + } + vs = &ACCESS_FBINFO(crtc2.vsync); + break; + default: + return -ENODEV; + } + ret = matroxfb_enable_irq(PMINFO 0); + if (ret) { + return ret; + } + init_waitqueue_entry(&__wait, current); + + cnt = vs->cnt; + ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10); + if (ret < 0) { + return ret; + } + if (ret == 0) { + matroxfb_enable_irq(PMINFO 1); + return -ETIMEDOUT; + } + return 0; +} + +/* --------------------------------------------------------------------- */ + static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { unsigned int pos; unsigned short p0, p1, p2; @@ -159,6 +318,8 @@ unsigned int p3; #endif struct display *disp; + int vbl; + unsigned long flags; CRITFLAGS DBG("matrox_pan_var") @@ -180,15 +341,27 @@ p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21; #endif + /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */ + vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0); + CRITBEGIN + matroxfb_DAC_lock_irqsave(flags); + mga_setr(M_CRTC_INDEX, 0x0D, p0); mga_setr(M_CRTC_INDEX, 0x0C, p1); #ifdef CONFIG_FB_MATROX_32MB if (ACCESS_FBINFO(devflags.support32MB)) mga_setr(M_EXTVGA_INDEX, 0x08, p3); #endif - mga_setr(M_EXTVGA_INDEX, 0x00, p2); + if (vbl) { + ACCESS_FBINFO(crtc1.panpos) = p2; + } else { + /* Abort any pending change */ + ACCESS_FBINFO(crtc1.panpos) = -1; + mga_setr(M_EXTVGA_INDEX, 0x00, p2); + } + matroxfb_DAC_unlock_irqrestore(flags); CRITEND } @@ -231,53 +404,61 @@ static int matroxfb_open(struct fb_info *info, int user) { -#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) - DBG_LOOP("matroxfb_open") - - if (ACCESS_FBINFO(dead)) { - return -ENXIO; + MINFO_FROM_INFO(info); + + DBG_LOOP(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + ACCESS_FBINFO(usecount)++; + if (user) { + ACCESS_FBINFO(userusecount)++; } - ACCESS_FBINFO(usecount)++; -#undef minfo - return(0); + return 0; } static int matroxfb_release(struct fb_info *info, int user) { -#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) - DBG_LOOP("matroxfb_release") - + MINFO_FROM_INFO(info); + + DBG_LOOP(__FUNCTION__) + + if (user) { + if (0 == --ACCESS_FBINFO(userusecount)) { + matroxfb_disable_irq(PMINFO2); + } + } if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) { matroxfb_remove(PMINFO 0); } -#undef minfo - return(0); + return 0; } static int matroxfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info) { -#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) - + struct display* dsp; + MINFO_FROM_INFO(info); DBG("matroxfb_pan_display") + if (con < 0) { + dsp = info->disp; + } else { + dsp = fb_display + con; + } if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset) - return -EINVAL; + return -EINVAL; } else { - if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual || - var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual) + if (var->xoffset+dsp->var.xres > dsp->var.xres_virtual || + var->yoffset+dsp->var.yres > dsp->var.yres_virtual) return -EINVAL; } if (con == ACCESS_FBINFO(currcon)) matrox_pan_var(PMINFO var); - fb_display[con].var.xoffset = var->xoffset; - fb_display[con].var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - fb_display[con].var.vmode |= FB_VMODE_YWRAP; - else - fb_display[con].var.vmode &= ~FB_VMODE_YWRAP; + dsp->var.xoffset = var->xoffset; + dsp->var.yoffset = var->yoffset; + dsp->var.vmode &= ~FB_VMODE_YWRAP; return 0; -#undef minfo } static int matroxfb_updatevar(int con, struct fb_info *info) @@ -963,10 +1144,11 @@ #undef minfo } -static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank) +static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) { unsigned int sts1; + matroxfb_enable_irq(PMINFO 0); memset(vblank, 0, sizeof(*vblank)); vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC | FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK; @@ -981,8 +1163,12 @@ vblank->flags |= FB_VBLANK_VSYNCING; if (vblank->vcount >= ACCESS_FBINFO(currcon_display)->var.yres) vblank->flags |= FB_VBLANK_VBLANKING; - vblank->hcount = 0; - vblank->count = 0; + if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { + vblank->flags |= FB_VBLANK_HAVE_COUNT; + /* Only one writer, aligned int value... + it should work without lock and without atomic_t */ + vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; + } return 0; } @@ -1015,6 +1201,15 @@ return -EFAULT; return 0; } + case FBIO_WAITFORVSYNC: + { + u_int32_t crt; + + if (get_user(crt, (u_int32_t *)arg)) + return -EFAULT; + + return matroxfb_wait_for_sync(PMINFO crt); + } case MATROXFB_SET_OUTPUT_MODE: { struct matroxioc_output_mode mom; @@ -2230,6 +2425,10 @@ spin_lock_init(&ACCESS_FBINFO(lock.accel)); init_rwsem(&ACCESS_FBINFO(crtc2.lock)); init_rwsem(&ACCESS_FBINFO(altout.lock)); + ACCESS_FBINFO(irq_flags) = 0; + init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); + init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); + ACCESS_FBINFO(crtc1.panpos) = -1; err = initMatrox2(PMINFO d, b); if (!err) { @@ -2768,6 +2967,8 @@ EXPORT_SYMBOL(matroxfb_register_driver); EXPORT_SYMBOL(matroxfb_unregister_driver); EXPORT_SYMBOL(matroxfb_switch); +EXPORT_SYMBOL(matroxfb_wait_for_sync); +EXPORT_SYMBOL(matroxfb_enable_irq); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_base.h linux-2.4.21-bk23/drivers/video/matrox/matroxfb_base.h --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_base.h 2003-07-31 02:53:50.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_base.h 2003-07-31 02:53:55.000000000 -0700 @@ -468,6 +468,11 @@ struct matroxfb_driver; struct matroxfb_dh_fb_info; +struct matrox_vsync { + wait_queue_head_t wait; + unsigned int cnt; +}; + struct matrox_fb_info { struct fb_info fbcon; @@ -476,6 +481,9 @@ int dead; unsigned int usecount; + unsigned int userusecount; + unsigned long irq_flags; + struct matroxfb_par curr; struct matrox_hw_state hw; @@ -603,10 +611,13 @@ } cursor; struct matrox_bios bios; struct { + struct matrox_vsync vsync; + int panpos; unsigned int pixclock; int mnp; } crtc1; struct { + struct matrox_vsync vsync; unsigned int pixclock; int mnp; struct matroxfb_dh_fb_info* info; @@ -663,6 +674,8 @@ #endif }; +#define info2minfo(info) list_entry(info, struct matrox_fb_info, fbcon) + #ifdef CONFIG_FB_MATROX_MULTIHEAD #define ACCESS_FBINFO2(info, x) (info->x) #define ACCESS_FBINFO(x) ACCESS_FBINFO2(minfo,x) @@ -677,12 +690,11 @@ #define PMINFO PMINFO2 , static inline struct matrox_fb_info* mxinfo(const struct display* p) { - return list_entry(p->fb_info, struct matrox_fb_info, fbcon); + return info2minfo(p->fb_info); } #define PMXINFO(p) mxinfo(p), #define MINFO_FROM(x) struct matrox_fb_info* minfo = x -#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x)) #else @@ -700,18 +712,14 @@ #define PMINFO2 #define PMINFO -#if 0 -static inline struct matrox_fb_info* mxinfo(const struct display* p) { - return &matroxfb_global_mxinfo; -} -#endif - #define PMXINFO(p) #define MINFO_FROM(x) -#define MINFO_FROM_DISP(x) #endif +#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x)) +#define MINFO_FROM_INFO(x) MINFO_FROM(info2minfo(x)) + struct matrox_switch { int (*preinit)(WPMINFO2); void (*reset)(WPMINFO2); @@ -793,7 +801,7 @@ #define M_FIFOSTATUS 0x1E10 #define M_STATUS 0x1E14 - +#define M_ICLEAR 0x1E18 #define M_IEN 0x1E1C #define M_VCOUNT 0x1E20 @@ -916,6 +924,8 @@ extern struct list_head matroxfb_list; extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt); extern int matroxfb_switch(int con, struct fb_info *); +extern int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc); +extern int matroxfb_enable_irq(WPMINFO int reenable); #ifdef MATROXFB_USE_SPINLOCKS #define CRITBEGIN spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags); diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_crtc2.c linux-2.4.21-bk23/drivers/video/matrox/matroxfb_crtc2.c --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_crtc2.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_crtc2.c 2003-07-31 02:53:55.000000000 -0700 @@ -193,7 +193,7 @@ { u_int32_t tmp; - tmp = 0x0FFF0000; /* line compare */ + tmp = mt->VDisplay << 16; /* line compare */ if (mt->sync & FB_SYNC_HOR_HIGH_ACT) tmp |= 0x00000100; if (mt->sync & FB_SYNC_VERT_HIGH_ACT) @@ -338,8 +338,14 @@ MINFO_FROM(m2info->primary_dev); if (MINFO) { - if (ACCESS_FBINFO(dead)) { - return -ENXIO; + int err; + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + err = ACCESS_FBINFO(fbcon.fbops)->fb_open(&ACCESS_FBINFO(fbcon), user); + if (err) { + return err; } } return 0; @@ -348,11 +354,13 @@ static int matroxfb_dh_release(struct fb_info* info, int user) { #define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon)) + int err = 0; MINFO_FROM(m2info->primary_dev); if (MINFO) { + err = ACCESS_FBINFO(fbcon.fbops)->fb_release(&ACCESS_FBINFO(fbcon), user); } - return 0; + return err; #undef m2info } @@ -544,13 +552,19 @@ static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, int con, struct fb_info* info) { #define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon)) - if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual || - var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual) + struct display* dsp; + + if (con < 0) + dsp = m2info->fbcon.disp; + else + dsp = fb_display + con; + if (var->xoffset + dsp->var.xres > dsp->var.xres_virtual || + var->yoffset + dsp->var.yres > dsp->var.yres_virtual) return -EINVAL; if (con == m2info->currcon) matroxfb_dh_pan_var(m2info, var); - fb_display[con].var.xoffset = var->xoffset; - fb_display[con].var.yoffset = var->yoffset; + dsp->var.xoffset = var->xoffset; + dsp->var.yoffset = var->yoffset; return 0; #undef m2info } @@ -560,6 +574,7 @@ static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) { MINFO_FROM(m2info->primary_dev); + matroxfb_enable_irq(PMINFO 0); memset(vblank, 0, sizeof(*vblank)); vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK; /* mask out reserved bits + field number (odd/even) */ @@ -567,6 +582,12 @@ /* compatibility stuff */ if (vblank->vcount >= m2info->currcon_display->var.yres) vblank->flags |= FB_VBLANK_VBLANKING; + if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { + vblank->flags |= FB_VBLANK_HAVE_COUNT; + /* Only one writer, aligned int value... + it should work without lock and without atomic_t */ + vblank->count = ACCESS_FBINFO(crtc2).vsync.cnt; + } return 0; } @@ -594,6 +615,17 @@ return -EFAULT; return 0; } + case FBIO_WAITFORVSYNC: + { + u_int32_t crt; + + if (get_user(crt, (u_int32_t *)arg)) + return -EFAULT; + + if (crt != 0) + return -ENODEV; + return matroxfb_wait_for_sync(PMINFO 1); + } case MATROXFB_SET_OUTPUT_MODE: case MATROXFB_GET_OUTPUT_MODE: case MATROXFB_GET_ALL_OUTPUTS: diff -urN linux-2.4.21-bk22/drivers/video/matrox/matroxfb_misc.c linux-2.4.21-bk23/drivers/video/matrox/matroxfb_misc.c --- linux-2.4.21-bk22/drivers/video/matrox/matroxfb_misc.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/drivers/video/matrox/matroxfb_misc.c 2003-07-31 02:53:55.000000000 -0700 @@ -223,7 +223,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p) { unsigned int hd, hs, he, hbe, ht; - unsigned int vd, vs, ve, vt; + unsigned int vd, vs, ve, vt, lc; unsigned int wd; unsigned int divider; int i; @@ -336,6 +336,7 @@ vs = m->VSyncStart - 1; ve = m->VSyncEnd - 1; vt = m->VTotal - 2; + lc = vd; /* G200 cannot work with (ht & 7) == 6 */ if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04)) ht++; @@ -367,7 +368,8 @@ hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) | ((vd & 0x400) >> 8) | /* disp end */ ((vd & 0xC00) >> 7) | /* vblanking start */ - ((vs & 0xC00) >> 5); + ((vs & 0xC00) >> 5) | + ((lc & 0x400) >> 3); if (text) hw->CRTCEXT[3] = 0x00; else @@ -387,12 +389,13 @@ ((vd & 0x100) >> 7) | ((vs & 0x100) >> 6) | ((vd & 0x100) >> 5) | - 0x10 | + ((lc & 0x100) >> 4) | ((vt & 0x200) >> 4) | ((vd & 0x200) >> 3) | ((vs & 0x200) >> 2); hw->CRTC[8] = 0x00; - hw->CRTC[9] = ((vd & 0x200) >> 4) | 0x40; + hw->CRTC[9] = ((vd & 0x200) >> 4) | + ((lc & 0x200) >> 3); if (text) hw->CRTC[9] |= fontheight(p) - 1; if (m->dblscan && !m->interlaced) @@ -417,7 +420,7 @@ hw->CRTC[20] = 0x1F; } else hw->CRTC[23] = 0xC3; - hw->CRTC[24] = 0xFF; + hw->CRTC[24] = lc; return 0; }; diff -urN linux-2.4.21-bk22/fs/coda/dir.c linux-2.4.21-bk23/fs/coda/dir.c --- linux-2.4.21-bk22/fs/coda/dir.c 2002-08-02 17:39:45.000000000 -0700 +++ linux-2.4.21-bk23/fs/coda/dir.c 2003-07-31 02:53:55.000000000 -0700 @@ -79,6 +79,7 @@ }; struct file_operations coda_dir_operations = { + llseek: generic_file_llseek, read: generic_read_dir, readdir: coda_readdir, open: coda_open, @@ -507,7 +508,11 @@ ret = coda_venus_readdir(host_file, filldir, dirent, coda_dentry); } else { /* potemkin case: we were handed a directory inode */ - ret = vfs_readdir(host_file, filldir, dirent); + /* We can't call vfs_readdir because we are already holding + * the inode semaphore. */ + ret = -ENOENT; + if (!IS_DEADDIR(host_file->f_dentry->d_inode)) + ret = host_file->f_op->readdir(host_file, filldir, dirent); } coda_file->f_pos = host_file->f_pos; diff -urN linux-2.4.21-bk22/fs/coda/file.c linux-2.4.21-bk23/fs/coda/file.c --- linux-2.4.21-bk22/fs/coda/file.c 2002-08-02 17:39:45.000000000 -0700 +++ linux-2.4.21-bk23/fs/coda/file.c 2003-07-31 02:53:55.000000000 -0700 @@ -117,16 +117,18 @@ coda_vfs_stat.open++; cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL); - if (!cfi) { - unlock_kernel(); + if (!cfi) return -ENOMEM; - } lock_kernel(); error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, &host_file); - if (error || !host_file) { + + if (!error && !host_file) + error = EBADF; + + if (error) { kfree(cfi); unlock_kernel(); return error; diff -urN linux-2.4.21-bk22/fs/namei.c linux-2.4.21-bk23/fs/namei.c --- linux-2.4.21-bk22/fs/namei.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.21-bk23/fs/namei.c 2003-07-31 02:53:55.000000000 -0700 @@ -627,6 +627,8 @@ nd->last_type = LAST_DOT; else if (this.len == 2 && this.name[1] == '.') nd->last_type = LAST_DOTDOT; + else + goto return_base; return_reval: /* * We bypassed the ordinary revalidation routines. diff -urN linux-2.4.21-bk22/include/linux/matroxfb.h linux-2.4.21-bk23/include/linux/matroxfb.h --- linux-2.4.21-bk22/include/linux/matroxfb.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.21-bk23/include/linux/matroxfb.h 2003-07-31 02:53:56.000000000 -0700 @@ -76,5 +76,7 @@ #define MATROXFB_G_TVOCTRL _IOWR('V',27,struct matroxfb_control) #define MATROXFB_S_TVOCTRL _IOW ('V',28,struct matroxfb_control) +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) + #endif diff -urN linux-2.4.21-bk22/include/linux/ncp.h linux-2.4.21-bk23/include/linux/ncp.h --- linux-2.4.21-bk22/include/linux/ncp.h 2001-11-22 11:46:18.000000000 -0800 +++ linux-2.4.21-bk23/include/linux/ncp.h 2003-07-31 02:53:56.000000000 -0700 @@ -44,7 +44,7 @@ }; #define NCP_VOLNAME_LEN (16) -#define NCP_NUMBER_OF_VOLUMES (64) +#define NCP_NUMBER_OF_VOLUMES (256) struct ncp_volume_info { __u32 total_blocks; __u32 free_blocks;