lkml.org 
[lkml]   [2000]   [Oct]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] spinlock fix for vgacon

Hi!

Please test this patch for fixing the SMP deadlock issues Keith Owens
was talking about. As for my other vgacon work. Well that needs alot more
time. These deadlock issues are really important and need to be
fixed. Thank you.

--- vgacon.c.orig Tue Oct 24 18:45:58 2000
+++ vgacon.c Tue Oct 24 19:08:51 2000
@@ -46,11 +46,13 @@
#include <linux/malloc.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
+#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/init.h>

#include <asm/io.h>

+static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED;

#define BLANK 0x0020

@@ -152,8 +154,7 @@
* ddprintk might set the console position from interrupt
* handlers, thus the write has to be IRQ-atomic.
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&vga_lock, flags);

#ifndef SLOW_VGA
v1 = reg + (val & 0xff00);
@@ -166,7 +167,7 @@
outb_p(reg+1, vga_video_port_reg);
outb_p(val & 0xff, vga_video_port_val);
#endif
- restore_flags(flags);
+ spin_unlock_irqrestore(&vga_lock, flags);
}

static const char __init *vgacon_startup(void)
@@ -415,7 +416,7 @@
if ((from == lastfrom) && (to == lastto)) return;
lastfrom = from; lastto = to;

- save_flags(flags); cli();
+ spin_lock_irqsave(&vga_lock, flags);
outb_p(0x0a, vga_video_port_reg); /* Cursor start */
curs = inb_p(vga_video_port_val);
outb_p(0x0b, vga_video_port_reg); /* Cursor end */
@@ -428,7 +429,7 @@
outb_p(curs, vga_video_port_val);
outb_p(0x0b, vga_video_port_reg); /* Cursor end */
outb_p(cure, vga_video_port_val);
- restore_flags(flags);
+ spin_unlock_irqrestore(&vga_lock, flags);
}

static void vgacon_cursor(struct vc_data *c, int mode)
@@ -533,11 +534,11 @@
{
/* save original values of VGA controller registers */
if(!vga_vesa_blanked) {
- cli();
+ spin_lock_irq(&vga_lock);
vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
vga_state.CrtMiscIO = inb_p(video_misc_rd);
- sti();
+ spin_unlock_irq(&vga_lock);

outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
vga_state.HorizontalTotal = inb_p(vga_video_port_val);
@@ -561,7 +562,7 @@

/* assure that video is enabled */
/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
- cli();
+ spin_lock_irq(&vga_lock);
outb_p(0x01,seq_port_reg);
outb_p(vga_state.ClockingMode | 0x20,seq_port_val);

@@ -598,13 +599,13 @@
/* restore both index registers */
outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
- sti();
+ spin_unlock_irq(&vga_lock);
}

static void vga_vesa_unblank(void)
{
/* restore original values of VGA controller registers */
- cli();
+ spin_lock_irq(&vga_lock);
outb_p(vga_state.CrtMiscIO,video_misc_wr);

outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
@@ -629,7 +630,7 @@
/* restore index/control registers */
outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
- sti();
+ spin_unlock_irq(&vga_lock);
}

static void vga_pal_blank(void)
@@ -750,7 +751,7 @@
charmap += 4*cmapsz;
#endif

- cli();
+ spin_lock_irq(&vga_lock);
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
outb_p( 0x02, seq_port_reg );
@@ -766,7 +767,7 @@
outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */
outb_p( 0x06, gr_port_reg );
outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */
- sti();
+ spin_unlock_irq(&vga_lock);

if (arg) {
if (set)
@@ -793,7 +794,7 @@
}
}

- cli();
+ spin_lock_irq(&vga_lock);
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
outb_p( 0x02, seq_port_reg );
@@ -833,8 +834,7 @@
inb_p( video_port_status );
outb_p ( 0x20, attrib_port );
}
- sti();
-
+ spin_unlock_irq(&vga_lock);
return 0;
}

@@ -865,12 +865,12 @@
registers; they are write-only on EGA, but it appears that they
are all don't care bits on EGA, so I guess it doesn't matter. */

- cli();
+ spin_lock_irq(&vga_lock);
outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */
ovr = inb_p(vga_video_port_val);
outb_p( 0x09, vga_video_port_reg ); /* Font size register */
fsr = inb_p(vga_video_port_val);
- sti();
+ spin_lock_irq(&vga_lock);

vde = maxscan & 0xff; /* Vertical display end reg */
ovr = (ovr & 0xbd) + /* Overflow register */
@@ -878,14 +878,14 @@
((maxscan & 0x200) >> 3);
fsr = (fsr & 0xe0) + (fontheight-1); /* Font size register */

- cli();
+ spin_lock_irq(&vga_lock);
outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */
outb_p( ovr, vga_video_port_val );
outb_p( 0x09, vga_video_port_reg ); /* Font size */
outb_p( fsr, vga_video_port_val );
outb_p( 0x12, vga_video_port_reg ); /* Vertical display limit */
outb_p( vde, vga_video_port_val );
- sti();
+ spin_unlock_irq(&vga_lock);

vc_resize_all(rows, 0); /* Adjust console size */
return 0;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 12:41    [W:0.032 / U:3.624 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site