vgaconsole driver SMP safe fix against linux-2.4.0-test9

From: Yong Chi (yong.chi@qwest.com)
Date: Tue Oct 10 2000 - 14:05:24 EST


My first contribution to kernel =) Someone please look over this one
carefully =)

Thanks


--- vgacon.c.bak Tue Oct 10 13:50:09 2000
+++ vgacon.c Tue Oct 10 14:48:06 2000
@@ -27,6 +27,9 @@
  * flashing on RHS of screen during heavy console scrolling .
  * Oct 1996, Paul Gortmaker.
  *
+ * Change cli()/sti() to SMP safe spin_lock_irqsave()
+ * /spin_unlock_irqrestore() calls, Yong Chi.
+ * Oct-10-2000 <ychi@home.com>
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License. See the file COPYING in the main directory of this archive for
@@ -50,6 +53,7 @@
 #include <linux/init.h>
 
 #include <asm/io.h>
+#include <asm/spinlock.h>
 
 
 #define BLANK 0x0020
@@ -122,6 +126,10 @@
 static int vga_video_font_height;
 static unsigned int vga_rolled_over = 0;
 
+/*
+ * Spinlock used for irq atomic operations
+ */
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
 
 static int __init no_scroll(char *str)
 {
@@ -152,8 +160,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(&irq_lock, flags);
 
 #ifndef SLOW_VGA
         v1 = reg + (val & 0xff00);
@@ -166,7 +173,7 @@
         outb_p(reg+1, vga_video_port_reg);
         outb_p(val & 0xff, vga_video_port_val);
 #endif
- restore_flags(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
 }
 
 static const char __init *vgacon_startup(void)
@@ -415,7 +422,7 @@
         if ((from == lastfrom) && (to == lastto)) return;
         lastfrom = from; lastto = to;
 
- save_flags(flags); cli();
+ spin_lock_irqsave(&irq_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 +435,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(&irq_lock, flags);
 }
 
 static void vgacon_cursor(struct vc_data *c, int mode)
@@ -531,13 +538,14 @@
 
 static void vga_vesa_blank(int mode)
 {
+ unsigned long flags;
         /* save original values of VGA controller registers */
         if(!vga_vesa_blanked) {
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
                 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_irqrestore(&irq_lock, flags);
 
                 outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
                 vga_state.HorizontalTotal = inb_p(vga_video_port_val);
@@ -561,7 +569,7 @@
 
         /* assure that video is enabled */
         /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
         outb_p(0x01,seq_port_reg);
         outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
 
@@ -598,13 +606,15 @@
         /* restore both index registers */
         outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
         outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
- sti();
+ spin_unlock_irqrestore(&irq_lock, flags);
 }
 
 static void vga_vesa_unblank(void)
 {
+ unsigned long flags;
+
         /* restore original values of VGA controller registers */
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
         outb_p(vga_state.CrtMiscIO,video_misc_wr);
 
         outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
@@ -629,7 +639,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_irqrestore(&irq_lock, flags);
 }
 
 static void vga_pal_blank(void)
@@ -710,6 +720,7 @@
         int beg;
         unsigned short video_port_status = vga_video_port_reg + 6;
         int font_select = 0x00;
+ unsigned long flags;
 
         if (vga_video_type != VIDEO_TYPE_EGAM) {
                 charmap = (char *)VGA_MAP_MEM(colourmap);
@@ -750,7 +761,7 @@
                 charmap += 4*cmapsz;
 #endif
 
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
         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 +777,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_irqrestore(&irq_lock, flags);
         
         if (arg) {
                 if (set)
@@ -793,7 +804,7 @@
                 }
         }
         
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
         outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
         outb_p( 0x01, seq_port_val ); /* Synchronous reset */
         outb_p( 0x02, seq_port_reg );
@@ -833,7 +844,7 @@
                 inb_p( video_port_status );
                 outb_p ( 0x20, attrib_port );
         }
- sti();
+ spin_unlock_irqrestore(&irq_lock, flags);
 
         return 0;
 }
@@ -846,6 +857,7 @@
 {
         int rows, maxscan;
         unsigned char ovr, vde, fsr;
+ unsigned long flags;
 
         if (fontheight == vga_video_font_height)
                 return 0;
@@ -865,12 +877,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_irqsave(&irq_lock, flags);
         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_unlock_irqrestore(&irq_lock, flags);
 
         vde = maxscan & 0xff; /* Vertical display end reg */
         ovr = (ovr & 0xbd) + /* Overflow register */
@@ -878,14 +890,14 @@
               ((maxscan & 0x200) >> 3);
         fsr = (fsr & 0xe0) + (fontheight-1); /* Font size register */
 
- cli();
+ spin_lock_irqsave(&irq_lock, flags);
         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_irqrestore(&irq_lock, flags);
 
         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/



This archive was generated by hypermail 2b29 : Sun Oct 15 2000 - 21:00:16 EST