[Patchset 1/20] Support for PC-9800

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 19:40:06



This patchset add support for NEC PC-9800 architecture, against 2.5.45.

PC-9800 is one of i386 sub-architecture, made by NEC Japan.
I update patchset agaist 2.5.45 and do some cleanups.

Best regards,
Osamu tomita  sf.jp Linux/98 project
-

This is a part 1/20 of patchset. (APM)

Summary:
  APM related modules
   - adapted to BIOS spec. differences.

diffstat:
  arch/i386/kernel/apm.c   |   55 +++++++++++++++++++++++++++++++++++++++++------
  include/linux/apm_bios.h |   24 ++++++++++++++++++++
  2 files changed, 72 insertions(+), 7 deletions(-)

patch:
diff -urN linux/arch/i386/kernel/apm.c linux98/arch/i386/kernel/apm.c
--- linux/arch/i386/kernel/apm.c        Thu Oct 31 13:23:02 2002
+++ linux98/arch/i386/kernel/apm.c      Thu Oct 31 13:35:09 2002
@@ -227,6 +227,8 @@
   #include <linux/sysrq.h>
  +#include "io_ports.h"
+
  extern rwlock_t xtime_lock;
  extern spinlock_t i8253_lock;
  extern unsigned long get_cmos_time(void);
@@ -377,6 +379,15 @@
  #define DEFAULT_IDLE_PERIOD   (100 / 3)
   /*
+ * PC-9800 BIOS reports version by BCD format
+ */
+#ifdef CONFIG_PC9800
+#define BIOS_VERSION_HILO_FMT "%d.%02x"
+#else
+#define BIOS_VERSION_HILO_FMT "%d.%d"
+#endif
+
+/*
   * Local variables
   */
  static struct {
@@ -629,6 +640,9 @@
        __asm__ __volatile__(APM_DO_ZERO_SEGS
                "pushl %%edi\n\t"
                "pushl %%ebp\n\t"
+#ifdef CONFIG_PC9800
+               "pushfl\n\t"
+#endif
                "lcall *%%cs:apm_bios_entry\n\t"
                "setc %%al\n\t"
                "popl %%ebp\n\t"
@@ -690,6 +704,9 @@
                __asm__ __volatile__(APM_DO_ZERO_SEGS
                        "pushl %%edi\n\t"
                        "pushl %%ebp\n\t"
+#ifdef CONFIG_PC9800
+                       "pushfl\n\t"
+#endif
                        "lcall *%%cs:apm_bios_entry\n\t"
                        "setc %%bl\n\t"
                        "popl %%ebp\n\t"
@@ -961,7 +978,7 @@
        /*
         * This may be called on an SMP machine.
         */
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && !defined(CONFIG_PC9800)
        /* Some bioses don't like being called from CPU != 0 */
        if (smp_processor_id() != 0) {
                set_cpus_allowed(current, 1 << 0);
@@ -1241,11 +1258,11 @@
  {
  #ifdef INIT_TIMER_AFTER_SUSPEND
        /* set the clock to 100 Hz */
-       outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
+       outb_p(0x34, PIT_MODE);         /* binary, mode 2, LSB/MSB, ch 0 */
        udelay(10);
-       outb_p(LATCH & 0xff , 0x40);        /* LSB */
+       outb_p(LATCH & 0xff, PIT_CH0);      /* LSB */
        udelay(10);
-       outb(LATCH >> 8 , 0x40);  /* MSB */
+       outb(LATCH >> 8, PIT_CH0);        /* MSB */
        udelay(10);
  #endif
  }
@@ -1720,7 +1737,8 @@
              -1: Unknown
           8) min = minutes; sec = seconds */
  -     p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
+       p += sprintf(p, "%s " BIOS_VERSION_HILO_FMT +              " 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
                     driver_version,
                     (apm_info.bios.version >> 8) & 0xff,
                     apm_info.bios.version & 0xff,
@@ -1744,6 +1762,8 @@
        char *          power_stat;
        char *          bat_stat;
  +#if !defined(CONFIG_PC9800) || !defined(CONFIG_SMP)
+       /* Deamonize causes freeze on PC-9800 SMP box */
        kapmd_running = 1;
        daemonize();
@@ -1751,6 +1771,7 @@
        strcpy(current->comm, "kapmd");
        current->flags |= PF_IOTHREAD;
        sigfillset(&current->blocked);
+#endif /* !CONFIG_PC9800 || !CONFIG_SMP */
   #ifdef CONFIG_SMP
        /* 2002/08/01 - WT
@@ -1780,6 +1801,17 @@
                                /* Fall back to an APM 1.0 connection. */
                                apm_info.connection_version = 0x100;
                        }
+#ifdef CONFIG_PC9800
+                       else {
+                               printk("PC-9801 APM BIOS BUG work around: "
+                                       "fix connection_version 0x%x to ",
+                                       apm_info.connection_version);
+                               apm_info.connection_version =
+                               (apm_info.connection_version & 0xff00)
+                               | ((apm_info.connection_version & 0x00f0) >> 4);
+                               printk("0x%x\n", apm_info.connection_version);
+                       }
+#endif /* CONFIG_PC9800 */
                }
        }
  @@ -1956,8 +1988,8 @@
                printk(KERN_INFO "apm: BIOS not found.\n");
                return -ENODEV;
        }
-       printk(KERN_INFO
-               "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
+       printk(KERN_INFO "apm: BIOS version " BIOS_VERSION_HILO_FMT
+               " Flags 0x%02x (Driver version %s)\n",
                ((apm_info.bios.version >> 8) & 0xff),
                (apm_info.bios.version & 0xff),
                apm_info.bios.flags,
@@ -1984,6 +2016,11 @@
        if (apm_info.bios.version == 0x001)
                apm_info.bios.version = 0x100;
  +#ifdef CONFIG_PC9800
+       /* In PC-9800, APM BIOS version is written in BCD...?? */
+       apm_info.bios.version = (apm_info.bios.version & 0xff00)
+                               | ((apm_info.bios.version & 0x00f0) >> 4);
+#endif
        /* BIOS < 1.2 doesn't set cseg_16_len */
        if (apm_info.bios.version < 0x102)
                apm_info.bios.cseg_16_len = 0; /* 64k */
@@ -2067,7 +2104,11 @@
        if (apm_proc)
                SET_MODULE_OWNER(apm_proc);
  +#if defined(CONFIG_PC9800) && defined(CONFIG_SMP)
+       apm(0);
+#else
        kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+#endif
        if (num_online_cpus() > 1 && !smp ) {
                printk(KERN_NOTICE
diff -urN linux/include/linux/apm_bios.h linux98/include/linux/apm_bios.h
--- linux/include/linux/apm_bios.h      Wed Aug 28 09:52:31 2002
+++ linux98/include/linux/apm_bios.h    Wed Aug 28 13:34:09 2002
@@ -20,6 +20,7 @@
  typedef unsigned short        apm_eventinfo_t;
   #ifdef __KERNEL__
+#include <linux/config.h>
   #define APM_CS               (GDT_ENTRY_APMBIOS_BASE * 8)
  #define APM_CS_16     (APM_CS + 8)
@@ -60,6 +61,7 @@
  /*
   * The APM function codes
   */
+#ifndef CONFIG_PC9800
  #define       APM_FUNC_INST_CHECK     0x5300
  #define       APM_FUNC_REAL_CONN      0x5301
  #define       APM_FUNC_16BIT_CONN     0x5302
@@ -80,6 +82,28 @@
  #define       APM_FUNC_RESUME_TIMER   0x5311
  #define       APM_FUNC_RESUME_ON_RING 0x5312
  #define       APM_FUNC_TIMER          0x5313
+#else
+#define        APM_FUNC_INST_CHECK     0x9a00
+#define        APM_FUNC_REAL_CONN      0x9a01
+#define        APM_FUNC_16BIT_CONN     0x9a02
+#define        APM_FUNC_32BIT_CONN     0x9a03
+#define        APM_FUNC_DISCONN        0x9a04
+#define        APM_FUNC_IDLE           0x9a05
+#define        APM_FUNC_BUSY           0x9a06
+#define        APM_FUNC_SET_STATE      0x9a07
+#define        APM_FUNC_ENABLE_PM      0x9a08
+#define        APM_FUNC_RESTORE_BIOS   0x9a09
+#define        APM_FUNC_GET_STATUS     0x9a3a
+#define        APM_FUNC_GET_EVENT      0x9a0b
+#define        APM_FUNC_GET_STATE      0x9a0c
+#define        APM_FUNC_ENABLE_DEV_PM  0x9a0d
+#define        APM_FUNC_VERSION        0x9a3e
+#define        APM_FUNC_ENGAGE_PM      0x9a3f
+#define        APM_FUNC_GET_CAP        0x9a10
+#define        APM_FUNC_RESUME_TIMER   0x9a11
+#define        APM_FUNC_RESUME_ON_RING 0x9a12
+#define        APM_FUNC_TIMER          0x9a13
+#endif
   /*
   * Function code for APM_FUNC_RESUME_TIMER
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 19:50:09


This is a part 2/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

Summary:
  boot related modules
   - adapted to BIOS spec. differences.

diffstat:
  arch/i386/boot98/Makefile               |   90 +++
  arch/i386/boot98/bootsect.S             |  397 +++++++++++++
  arch/i386/boot98/compressed/Makefile    |   26  arch/i386/boot98/compressed/head.S      |  128 ++++
  arch/i386/boot98/compressed/misc.c      |  375 ++++++++++++
  arch/i386/boot98/compressed/vmlinux.scr |    9  arch/i386/boot98/install.sh             |   40 +
  arch/i386/boot98/setup.S                |  950 ++++++++++++++++++++++++++++++++
  arch/i386/boot98/tools/build.c          |  188 ++++++
  arch/i386/boot98/video.S                |  262 ++++++++
  10 files changed, 2465 insertions(+)

patch:
diff -urN linux/arch/i386/boot98/Makefile linux98/arch/i386/boot98/Makefile
--- linux/arch/i386/boot98/Makefile     Thu Jan  1 09:00:00 1970
+++ linux98/arch/i386/boot98/Makefile   Sat Oct 19 13:01:49 2002
@@ -0,0 +1,90 @@
+#
+# arch/i386/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+#
+
+# ROOT_DEV specifies the default root-device when making the image.
+# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
+# the default of FLOPPY is used by 'build'.
+
+ROOT_DEV := CURRENT
+
+# If you want to preset the SVGA mode, uncomment the next line and
+# set SVGA_MODE to whatever number you want.
+# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
+# The number is the same as you would ordinarily press at bootup.
+
+SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+
+# If you want the RAM disk device, define this to be the size in blocks.
+
+#RAMDISK := -DRAMDISK=512
+
+EXTRA_TARGETS  := vmlinux.bin bootsect bootsect.o \
+                  setup setup.o zImage bzImage
+
+subdir-        := compressed
+
+host-progs     := tools/build
+
+#      Default
+
+boot: bzImage
+
+include $(TOPDIR)/Rules.make
+
+# ---------------------------------------------------------------------------
+
+$(obj)/zImage:  IMAGE_OFFSET := 0x1000
+$(obj)/zImage:  EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK)
+$(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
+$(obj)/bzImage: BUILDFLAGS   := -b
+
+quiet_cmd_image = BUILD   $(echo_target)
+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+           $(obj)/vmlinux.bin $(ROOT_DEV) > $@
+
+$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+                             $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+       $(call if_changed,image)
+
+$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
+       $(call if_changed,objcopy)
+
+LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
+LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
+
+$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+       $(call if_changed,ld)
+
+$(obj)/compressed/vmlinux: FORCE
+       +@$(call descend,$(obj)/compressed,IMAGE_OFFSET=$(IMAGE_OFFSET) \
+               $(obj)/compressed/vmlinux)
+
+
+zdisk: $(BOOTIMAGE)
+       dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
+
+zlilo: $(BOOTIMAGE)
+       if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
+       if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
+       cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
+       cp System.map $(INSTALL_PATH)/
+       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
+install: $(BOOTIMAGE)
+       sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+
+archhelp:
+       @echo  '* bzImage       - Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
+       @echo  '  install       - Install kernel using'
+       @echo  '                  (your) ~/bin/installkernel or'
+       @echo  '                  (distribution) /sbin/installkernel or'
+       @echo  '                  install to $$(INSTALL_PATH) and run lilo'
+
diff -urN linux/arch/i386/boot98/bootsect.S linux98/arch/i386/boot98/bootsect.S
--- linux/arch/i386/boot98/bootsect.S   Thu Jan  1 09:00:00 1970
+++ linux98/arch/i386/boot98/bootsect.S Wed May 22 09:13:46 2002
@@ -0,0 +1,397 @@
+/*      
+ *     bootsect.S - boot sector for NEC PC-9800 series
+ *
+ *     Linux/98 project at Kyoto University Microcomputer Club (KMC)
+ *                 FUJITA Norimasa, TAKAI Kousuke  1997-1998
+ *     rewritten by TAKAI Kousuke (as86 -> gas), Nov 1999
+ *
+ * Based on:
+ *     bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
+ *     modified by Drew Eckhardt
+ *     modified by Bruce Evans (bde)
+ *
+ * bootsect.S is loaded at 0x1FC00 or 0x1FE00 by the bios-startup routines,
+ * and moves itself out of the way to address 0x90000, and jumps there.
+ *
+ * It then loads 'setup' directly after itself (0x90200), and the system
+ * at 0x10000, using BIOS interrupts. + *
+ * NOTE! currently system is at most (8*65536-4096) bytes long. This should + * be no problem, even in the future. I want to keep it simple. This 508 kB
+ * kernel size should be enough, especially as this doesn't contain the
+ * buffer cache as in minix (and especially now that the kernel is + * compressed :-)
+ *
+ * The loader has been made as simple as possible, and continuous
+ * read errors will result in a unbreakable loop. Reboot by hand. It
+ * loads pretty fast by getting whole tracks at a time whenever possible.
+ */
+
+#include <linux/config.h>                /* for CONFIG_ROOT_RDONLY */
+#include <asm/boot.h>
+
+SETUPSECTS     = 4                     /* default nr of setup-sectors */
+BOOTSEG                = 0x1FC0                /* original address of boot-sector */
+INITSEG                = DEF_INITSEG           /* we move boot here - out of the way */
+SETUPSEG       = DEF_SETUPSEG          /* setup starts here */
+SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
+SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
+                                       /* to be loaded */
+ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
+SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
+
+#ifndef SVGA_MODE
+#define SVGA_MODE ASK_VGA
+#endif
+
+#ifndef RAMDISK
+#define RAMDISK 0
+#endif +
+#ifndef ROOT_RDONLY
+#define ROOT_RDONLY 1
+#endif
+
+/* normal/hireso text VRAM segments */
+#define NORMAL_TEXT    0xa000
+#define HIRESO_TEXT    0xe000
+
+/* bios work area addresses */
+#define EXPMMSZ                0x0401
+#define BIOS_FLAG      0x0501
+#define        DISK_BOOT       0x0584
+
+.code16
+.text
+
+.global _start
+_start:
+
+#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
+       int     $0x3
+#endif
+       jmp     real_start
+       .ascii  "Linux 98"
+       .word   0
+real_start:
+       xorw    %di, %di                /* %di = 0 */
+       movw    %di, %ss                /* %ss = 0 */
+       movw    $0x03F0, %sp
+       pushw   %cx                     /* for hint */
+
+       movw    $0x0A00, %ax            /* normal mode defaults (80x25) */
+
+       testb   $0x08, %ss:BIOS_FLAG    /* check hi-reso bit */
+       jnz     set_crt_mode
+/*
+ * Hi-Reso (high-resolution) machine.
+ *
+ * Some hi-reso machines have no RAMs on bank 8/A (0x080000 - 0x0BFFFF).
+ * On such machines we get two RAM banks from top of protect menory and
+ * map them on bank 8/A.
+ * These work-around must be done before moving myself on INITSEG (0x090000-).
+ */
+       movw    $(HIRESO_TEXT >> 8), %cs:(vram + 1)       /* text VRAM segment */
+
+       /* set memory window */
+       movb    $0x08, %al
+       outb    %al, $0x91              /* map native RAM (if any) */
+       movb    $0x0A, %al
+       outb    %al, $0x93
+
+       /* check bank ram A */
+       pushw   $0xA500
+       popw    %ds
+       movw    (%di), %cx              /* %si == 0 from entry */
+       notw    %cx
+       movw    %cx, (%di)
+
+       movw    $0x43F, %dx             /* cache flush for 486 and up. */
+       movb    $0xA0, %al
+       outb    %al, %dx
+        
+       cmpw    %cx, (%di)
+       je      hireso_done
+
+       /* +     * Write test failed; we have no native RAM on 080000h - 0BFFFFh.
+        * Take 256KB of RAM from top of protected memory.
+        */
+       movb    %ss:EXPMMSZ, %al
+       subb    $2, %al                 /* reduce 2 x 128KB */
+       movb    %al, %ss:EXPMMSZ
+       addb    %al, %al
+       addb    $0x10, %al
+       outb    %al, $0x91
+       addb    $2, %al
+       outb    %al, $0x93
+
+hireso_done:
+       movb    $0x10, %al              /* CRT mode 80x31, %ah still 0Ah */
+
+set_crt_mode:
+       int     $0x18                   /* set CRT mode */
+
+       movb    $0x0C, %ah              /* turn on text displaying */
+       int     $0x18
+
+       xorw    %dx, %dx                /* position cursor to home */
+       movb    $0x13, %ah
+       int     $0x18
+
+       movb    $0x11, %ah              /* turn cursor displaying on */
+       int     $0x18
+
+       /* move 1 kilobytes from [BOOTSEG:0000h] to [INITSEG:0000h] */
+       cld
+       xorw    %si, %si
+       pushw   $INITSEG
+       popw    %es
+       movw    $512, %cx               /* %di == 0 from entry */
+       rep
+       cs
+       movsw
+
+       ljmp    $INITSEG, $go
+
+go:
+       pushw   %cs
+       popw    %ds             /* %ds = %cs */
+
+       popw    %dx             /* %dh = saved %ch passed from BIOS */
+       movb    %ss:DISK_BOOT, %al
+       andb    $0xf0, %al      /* %al = Device Address */
+       movb    $18, %ch        /* 18 secs/track,  512 b/sec (1440 KB) */
+       cmpb    $0x30, %al
+       je      try512
+       cmpb    $0x90, %al      /* 1 MB I/F, 1 MB floppy */
+       je      try1.2M
+       cmpb    $0xf0, %al      /* 640 KB I/F, 1 MB floppy */
+       je      try1.2M
+       movb    $9, %ch         /*  9 secs/track,  512 b/sec ( 720 KB) */
+       cmpb    $0x10, %al      /* 1 MB I/F, 640 KB floppy */
+       je      try512
+       cmpb    $0x70, %al      /* 640 KB I/F, 640 KB floppy */
+       jne     error           /* unknown device? */
+
+       /* XXX: Does it make sense to support 8 secs/track, 512 b/sec +         (640 KB) floppy? */
+
+try512:        movb    $2, %cl         /* 512 b/sec */
+lasttry:call   tryload
+/*
+ * Display error message and halt
+ */
+error: movw    $error_msg, %si
+       call    print
+wait_reboot:
+       movb    $0x0, %ah
+       int     $0x18                   /* wait keyboard input */
+1:     movb    $0, %al
+       outb    %al, $0xF0              /* reset CPU */
+       jmp     1b                      /* just in case... */
+
+try1.2M:cmpb   $2, %dh
+       je      try2HC
+       movw    $0x0803, %cx    /*  8 secs/track, 1024 b/sec (1232 KB) */
+       call    tryload
+       movb    $15, %ch        /* 15 secs/track,  512 b/sec (1200 KB) */
+       jmp     try512
+try2HC:        movw    $0x0F02, %cx    /* 15 secs/track,  512 b/sec (1200 KB) */
+       call    tryload
+       movw    $0x0803, %cx    /*  8 secs/track, 1024 b/sec (1232 KB) */
+       jmp     lasttry
+
+/*
+ * Try to load SETUP and SYSTEM provided geometry information in %cx.
+ * This routine *will not* return on successful load...
+ */
+tryload:
+       movw    %cx, sectlen
+       movb    %ss:DISK_BOOT, %al
+       movb    $0x7, %ah               /* recalibrate the drive */
+       int     $0x1b
+       jc      error                   /*
...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:00:12


This is part 3/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

Summary:
  console display modules
   - add jis-x201 charset("kana") support. (display only)
   - add multi-byte char("kanji") support. (display only)

  I hope this may be base for ather multi-byte languege support.

diffstat:
  drivers/char/Makefile          |    9  drivers/char/console_macros.h  |   14 +
  drivers/char/console_pc9800.h  |   14 +
  drivers/char/consolemap.c      |   58 ++++-
  drivers/char/pc9800.uni        |  260 +++++++++++++++++++++++
  drivers/char/vt.c              |  453 +++++++++++++++++++++++++++++++++++------
  drivers/char/vt_ioctl.c        |   19 +
  include/linux/console.h        |   11  include/linux/console_struct.h |   27 ++
  include/linux/consolemap.h     |    1  include/linux/tty.h            |    4  include/linux/vt.h             |    1  include/linux/vt_buffer.h      |    4  
13 files changed, 812 insertions(+), 63 deletions(-)

patch:
diff -urN linux/drivers/char/Makefile linux98/drivers/char/Makefile
--- linux/drivers/char/Makefile Thu Oct 31 13:23:11 2002
+++ linux98/drivers/char/Makefile       Thu Oct 31 15:14:04 2002
@@ -5,7 +5,11 @@
  #
  # This file contains the font map for the default (hardware) font
  #
+ifneq ($(CONFIG_PC9800),y)
  FONTMAPFILE = cp437.uni
+else
+FONTMAPFILE = pc9800.uni
+endif
   obj-y         += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o eventpoll.o
  @@ -14,7 +18,8 @@
   export-objs     :=   busmouse.o vt.o generic_serial.o ip2main.o \
                        ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \
-                       selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o eventpoll.o
+                       selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o \
+                       eventpoll.o upd4990a.o
   obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
  obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
@@ -51,6 +56,7 @@
   obj-$(CONFIG_PRINTER) += lp.o
  obj-$(CONFIG_TIPAR) += tipar.o
+obj-$(CONFIG_PC9800_OLDLP)) += lp_old98.o
   obj-$(CONFIG_BUSMOUSE) += busmouse.o
  obj-$(CONFIG_DTLK) += dtlk.o
@@ -59,6 +65,7 @@
  obj-$(CONFIG_SONYPI) += sonypi.o
  obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
  obj-$(CONFIG_RTC) += rtc.o
+obj-$(CONFIG_RTC98) += upd4990a.o
  obj-$(CONFIG_GEN_RTC) += genrtc.o
  obj-$(CONFIG_EFI_RTC) += efirtc.o
  ifeq ($(CONFIG_PPC),)
diff -urN linux/drivers/char/console_macros.h linux98/drivers/char/console_macros.h
--- linux/drivers/char/console_macros.h Sat Oct 19 13:01:17 2002
+++ linux98/drivers/char/console_macros.h       Mon Oct 28 16:53:39 2002
@@ -55,6 +55,10 @@
  #define       s_reverse       (vc_cons[currcons].d->vc_s_reverse)
  #define       ulcolor         (vc_cons[currcons].d->vc_ulcolor)
  #define       halfcolor       (vc_cons[currcons].d->vc_halfcolor)
+#define def_attr       (vc_cons[currcons].d->vc_def_attr)
+#define ul_attr                (vc_cons[currcons].d->vc_ul_attr)
+#define half_attr      (vc_cons[currcons].d->vc_half_attr)
+#define bold_attr      (vc_cons[currcons].d->vc_bold_attr)
  #define tab_stop      (vc_cons[currcons].d->vc_tab_stop)
  #define palette               (vc_cons[currcons].d->vc_palette)
  #define bell_pitch    (vc_cons[currcons].d->vc_bell_pitch)
@@ -64,6 +68,16 @@
  #define complement_mask (vc_cons[currcons].d->vc_complement_mask)
  #define s_complement_mask (vc_cons[currcons].d->vc_s_complement_mask)
  #define hi_font_mask  (vc_cons[currcons].d->vc_hi_font_mask)
+#define kanji_mode     (vc_cons[currcons].d->vc_kanji_mode)
+#define s_kanji_mode   (vc_cons[currcons].d->vc_s_kanji_mode)
+#define kanji_char1    (vc_cons[currcons].d->vc_kanji_char1)
+#define translate_ex   (vc_cons[currcons].d->vc_translate_ex)
+#define G0_charset_ex  (vc_cons[currcons].d->vc_G0_charset_ex)
+#define G1_charset_ex  (vc_cons[currcons].d->vc_G1_charset_ex)
+#define saved_G0_ex    (vc_cons[currcons].d->vc_saved_G0_ex)
+#define saved_G1_ex    (vc_cons[currcons].d->vc_saved_G1_ex)
+#define kanji_jis_mode (vc_cons[currcons].d->vc_kanji_jis_mode)
+#define s_kanji_jis_mode (vc_cons[currcons].d->vc_s_kanji_jis_mode)
   #define vcmode               (vt_cons[currcons]->vc_mode)
  diff -urN linux/drivers/char/console_pc9800.h linux98/drivers/char/console_pc9800.h
--- linux/drivers/char/console_pc9800.h Thu Jan  1 09:00:00 1970
+++ linux98/drivers/char/console_pc9800.h       Mon Oct 28 11:48:10 2002
@@ -0,0 +1,14 @@
+#ifndef __CONSOLE_PC9800_H
+#define __CONSOLE_PC9800_H
+
+#define BLANK_ATTR     0x00E1
+
+#define JIS_CODE       0x01
+#define EUC_CODE       0x00
+#define SJIS_CODE      0x02
+#define JIS_CODE_ASCII  0x00
+#define JIS_CODE_78     0x01
+#define JIS_CODE_83     0x02
+#define JIS_CODE_90     0x03
+
+#endif /* __CONSOLE_PC9800_H */
diff -urN linux/drivers/char/consolemap.c linux98/drivers/char/consolemap.c
--- linux/drivers/char/consolemap.c     Sat Oct 19 13:02:27 2002
+++ linux98/drivers/char/consolemap.c   Mon Oct 21 13:18:03 2002
@@ -22,7 +22,7 @@
  #include <linux/console_struct.h>
  #include <linux/vt_kern.h>
  -static unsigned short translations[][256] = {
+unsigned short translations[][256] = {
    /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
    {
      0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
@@ -162,7 +162,59 @@
      0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
      0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
      0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
-  }
+  },
+  /* JIS X0201 mapped to Unicode */
+  /* code marked with ** is not defined in JIS X0201.
+        So 0x00 - 0x1f are mapped to same to Laten1,
+        and others are mapped to PC-9800 internal font# directry */
+  {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+/*    **      **      **      **      **      **      **      **    */
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+/*    **      **      **      **      **      **      **      **    */
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+/*    **      **      **      **      **      **      **      **    */
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+/*    **      **      **      **      **      **      **      **    */
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0xf07f,
+/*                                                            **   */
+    0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
+/*    **      **      **      **      **      **      **      **    */
+    0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
+/*    **      **      **      **      **      **      **      **    */
+    0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
+/*    **      **      **      **      **      **      **      **    */
+    0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
+/*    **      **      **      **      **      **      **      **    */
+    0xf0a0, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67,
+/*    **                                                            */
+    0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
+    0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77,
+    0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f,
+    0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87,
+    0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f,
+    0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97,
+    0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f,
+    0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
+/*    **      **      **      **      **      **      **      **    */
+    0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
+/*    **      **      **      **      **      **      **      **    */
+    0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
+/*    **      **      **      **      **      **      **      **    */
+    0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
+/*    **      **      **      **      **      **      **      **    */
+  },
  };
   /* The standard kernel character-to-font mappings are not invertible
@@ -176,7 +228,7 @@
        u16             **uni_pgdir[32];
        unsigned long   refcount;
        unsigned long   sum;
-       unsigned char   *inverse_translations[4];
+       unsigned char   *inverse_translations[5];
        int             readonly;
  };
  diff -urN linux/drivers/char/pc9800.uni linux98/drivers/char/pc9800.uni
--- linux/drivers/char/pc9800.uni       Thu Jan  1 09:00:00 1970
+++ linux98/drivers/char/pc9800.uni     Fri Aug 17 21:50:17 2001
@@ -0,0 +1,260 @@
+#
+# Unicode table for PC-9800 console.
+# Copyright (C) 1998,2001  Linux/98 project (project Seraphim)
+#                         Kyoto University Microcomputer Club (KMC).
+#
+
+# Kore ha unicode wo 98 no ROM no font ni taio saseru tame no
+# map desu.
+
+# Characters for control codes.
+# PC-9800 uses 2-char sequences while Unicode uses 3-char for some codes.
+0x00    
+0x01   U+2401  # SH / SOH
+0x02   U+2402  # SX / SOX
+0x03   U+2403  # EX / ETX
+0x04   U+2404  # ET / EOT
+0x05   U+2405  # EQ / ENQ
+0x06   U+2406  # AK / ACK
+0x07   U+2407  # BL / BEL
+0x08   U+2408  # BS
+0x09   U+2409  # HT
+0x0a   U+240a  # LF
+0x0b           # HM / (VT)
+0x0c           # CL / (FF)
+0x0d   U+240d  # CR
+0x0e           # SO / (SS)
+0x0f   U+240f  # SI
+0x10   U+2410  # DE / DLE
+0x11   U+2411  # D1 / DC1
+0x12   U+2412  # D2 / DC2
+0x13   U+2413  #
...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:00:15


This is a part 5/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

Summary:
  core modules (continued)

diffstat:
  include/asm-i386/bugs.h         |    2  include/asm-i386/dma.h          |    7 +
  include/asm-i386/io.h           |    6 +
  include/asm-i386/irq.h          |    4  include/asm-i386/pc9800.h       |   27 ++++
  include/asm-i386/pc9800_debug.h |  152 +++++++++++++++++++++++++
  include/asm-i386/pc9800_dma.h   |  238 ++++++++++++++++++++++++++++++++++++++++
  include/asm-i386/pc9800_sca.h   |   25 ++++
  include/asm-i386/pgtable.h      |    4  include/asm-i386/processor.h    |    2  include/asm-i386/scatterlist.h  |    6 +
  include/asm-i386/setup.h        |    1  include/asm-i386/timex.h        |    4  13 files changed, 477 insertions(+), 1 deletion(-)

patch:
diff -urN linux/include/asm-i386/bugs.h linux98/include/asm-i386/bugs.h
--- linux/include/asm-i386/bugs.h       Sun Jun  9 14:27:38 2002
+++ linux98/include/asm-i386/bugs.h     Mon Jun 10 20:49:15 2002
@@ -34,6 +34,7 @@
   __setup("no-hlt", no_halt);
  +#ifndef CONFIG_PC9800
  static int __init mca_pentium(char *s)
  {
        mca_pentium_flag = 1;
@@ -41,6 +42,7 @@
  }
   __setup("mca-pentium", mca_pentium);
+#endif
   static int __init no_387(char *s)
  {
diff -urN linux/include/asm-i386/dma.h linux98/include/asm-i386/dma.h
--- linux/include/asm-i386/dma.h        Sat Jul 21 04:52:59 2001
+++ linux98/include/asm-i386/dma.h      Fri Aug 17 22:15:06 2001
@@ -10,6 +10,9 @@
   #include <linux/config.h>
  #include <linux/spinlock.h>     /* And spinlocks */
+#ifdef CONFIG_PC9800
+#include <asm/pc9800_dma.h>
+#else /* !CONFIG_PC9800 */
  #include <asm/io.h>             /* need byte IO */
  #include <linux/delay.h>
  @@ -72,8 +75,10 @@
   #define MAX_DMA_CHANNELS     8
  +#ifndef CONFIG_PC9800
  /* The maximum address that we can perform a DMA transfer to on this platform */
  #define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x1000000)
+#endif
   /* 8237 DMA controllers */
  #define IO_DMA1_BASE  0x00    /* 8 bit slave DMA, channels 0..3 */
@@ -295,4 +300,6 @@
  #define isa_dma_bridge_buggy  (0)
  #endif
  +#endif /* CONFIG_PC9800 */
+
  #endif /* _ASM_DMA_H */
diff -urN linux/include/asm-i386/io.h linux98/include/asm-i386/io.h
--- linux/include/asm-i386/io.h Sat Oct 12 13:22:45 2002
+++ linux98/include/asm-i386/io.h       Sat Oct 12 19:25:19 2002
@@ -27,6 +27,8 @@
   *            Linus
   */
  +#include <linux/config.h>
+
   /*
    *  Bit simplified and optimized by Jan Hubicka
    *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
@@ -288,7 +290,11 @@
  #ifdef SLOW_IO_BY_JUMPING
  #define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
  #else
+#ifndef CONFIG_PC9800
  #define __SLOW_DOWN_IO "outb %%al,$0x80;"
+#else
+#define __SLOW_DOWN_IO "outb %%al,$0x5f;"
+#endif
  #endif
   static inline void slow_down_io(void) {
diff -urN linux/include/asm-i386/irq.h linux98/include/asm-i386/irq.h
--- linux/include/asm-i386/irq.h        Sat Sep 21 00:20:16 2002
+++ linux98/include/asm-i386/irq.h      Sat Sep 21 07:17:56 2002
@@ -17,7 +17,11 @@
   static __inline__ int irq_cannonicalize(int irq)
  {
+#ifndef CONFIG_PC9800
        return ((irq == 2) ? 9 : irq);
+#else
+       return ((irq == 7) ? 11 : irq);
+#endif
  }
   extern void disable_irq(unsigned int);
diff -urN linux/include/asm-i386/pc9800.h linux98/include/asm-i386/pc9800.h
--- linux/include/asm-i386/pc9800.h     Thu Jan  1 09:00:00 1970
+++ linux98/include/asm-i386/pc9800.h   Fri Aug 17 21:50:18 2001
@@ -0,0 +1,27 @@
+/*
+ *  PC-9800 machine types.
+ *
+ *  Copyright (C) 1999 TAKAI Kosuke <t...@kmc.kyoto-u.ac.jp>
+ *                     (Linux/98 Project)
+ */
+
+#ifndef _ASM_PC9800_H_
+#define _ASM_PC9800_H_
+
+#include <asm/pc9800_sca.h>
+#include <asm/types.h>
+
+#define __PC9800SCA(type, pa)  (*(type *) phys_to_virt(pa))
+#define __PC9800SCA_TEST_BIT(pa, n)    \
+       ((__PC9800SCA(u8, pa) & (1U << (n))) != 0)
+
+#define PC9800_HIGHRESO_P()    __PC9800SCA_TEST_BIT(PC9800SCA_BIOS_FLAG, 3)
+#define PC9800_8MHz_P()                __PC9800SCA_TEST_BIT(PC9800SCA_BIOS_FLAG, 7)
+
+                               /* 0x2198 is 98 21 on memory... */
+#define PC9800_9821_P()                (__PC9800SCA(u16, PC9821SCA_ROM_ID) == 0x2198)
+
+/* Note PC9821_...() are valid only when PC9800_9821_P() was true. */
+#define PC9821_IDEIF_DOUBLE_P()        __PC9800SCA_TEST_BIT(PC9821SCA_ROM_FLAG4, 4)
+
+#endif
diff -urN linux/include/asm-i386/pc9800_debug.h linux98/include/asm-i386/pc9800_debug.h
--- linux/include/asm-i386/pc9800_debug.h       Thu Jan  1 09:00:00 1970
+++ linux98/include/asm-i386/pc9800_debug.h     Fri Aug 17 22:20:21 2001
@@ -0,0 +1,152 @@
+/*
+ * linux/include/asm-i386/pc9800_debug.h: Defines for debug routines
+ *
+ * Written by Linux/98 Project, 1998.
+ *
+ * Revised by TAKAI Kousuke, Nov 1999.
+ */
+
+#ifndef _ASM_PC9800_DEBUG_H
+#define _ASM_PC9800_DEBUG_H
+
+extern unsigned char __pc9800_beep_flag;
+
+/* Don't depend on <asm/io.h> ... */
+static __inline__ void pc9800_beep_on(void)
+{
+       __asm__ ("out%B0 %0,%1" : : "a"((char) 0x6), "N"(0x37));
+       __pc9800_beep_flag = 0x6;
+}
+
+static __inline__ void pc9800_beep_off(void)
+{
+       __asm__ ("out%B0 %0,%1" : : "a"((char) 0x7), "N"(0x37));
+       __pc9800_beep_flag = 0x7;
+}
+
+static __inline__ void pc9800_beep_toggle(void)
+{
+       __pc9800_beep_flag ^= 1;
+       __asm__ ("out%B0 %0,%1" : : "a"(__pc9800_beep_flag), "N"(0x37));
+}
+
+static __inline__ void pc9800_udelay(unsigned int __usec)
+{
+       if ((__usec = __usec * 10 / 6) > 0)
+               do
+                       __asm__ ("out%B0 %%al,%0" : : "N"(0x5F));
+               while (--__usec);
+}
+
+# define assertk(expr) ({                                              \
+       if (!(expr)) {                                                  \
+               __pc9800_saveregs();                                    \
+               __assert_fail(__BASE_FILE__, __FILE__, __LINE__,        \
+                              __PRETTY_FUNCTION__,                     \
+                              __builtin_return_address (0), #expr);    \
+       }                                                               \
+})
+# define check_kernel_pointer(expr)    ({                              \
+       void *__p = (expr);                                             \
+       if ((unsigned long) __p < PAGE_OFFSET) {                     \
+               __pc9800_saveregs();                                    \
+               __invalid_kernel_pointer                                \
+                       (__BASE_FILE__, __FILE__, __LINE__,             \
+                        __PRETTY_FUNCTION__,                           \
+                        __builtin_return_address(0), #expr, __p);      \
+       }                                                               \
+})
+
+extern void __assert_fail(const char *, const char *, unsigned int,
+                          const char *, void *, const char *)
+     __attribute__ ((__noreturn__));
+extern void __invalid_kernel_pointer(const char *, const char *, unsigned int,
+                                     const char *, void *,
+                                     const char *, void *)
+     __attribute__ ((__noreturn__));
+extern void __pc9800_saveregs(void);
+
+extern void ucg_saveargs(unsigned int, ...);
+
+#ifdef NEED_UNMAP_PHYSPAGE
+
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+/*
+ * unmap_physpage (addr)
+ */
+static __inline__ void
+unmap_physpage(unsigned long addr)
+{
+       pgd_t *pgd = pgd_offset_k(addr);
+       pmd_t *pmd;
+       pte_t *pte;
+
+       if (pgd_none(*pgd))
+               panic("%s: No pgd?!?", __BASE_FILE__);
+       pmd = pmd_offset(pgd, addr);
+       if (pmd_none(*pmd))
+               panic("%s: No pmd?!?", __BASE_FILE__);
+       if (pmd_val(*pmd) & _PAGE_PSE) {
+               int i;
+               unsigned long paddr = pmd_val(*pmd) & PAGE_MASK;
+
+               pte = (pte_t *) __get_free_page(GFP_KERNEL);
+               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
+               for (i = 0; i < PTRS_PER_PTE; pte++, i++)
+                       *pte = mk_pte_phys(paddr + i * PAGE_SIZE,
+                                           PAGE_KERNEL);
+       }
+       pte = pte_offset(pmd, addr);
+
+       set_pte(pte, pte_modify(*pte, PAGE_NONE));
+       __flush_tlb_one(addr);
+}
+#endif /* NEED_UNMAP_PHYSPAGE */
+
+#ifdef NEED_KERNEL_POINTER_CHECKER
+# /* no dep */ include <asm/uaccess.h>
+
+/*
+ *  KERNEL_POINTER_VALIDP(PTR) validates kernel pointer PTR.
+ *  If PTR points vaild memory address for kernel internal use,
+ *  return nonzero; otherwise return zero.
+ *
+ *  Note PTR is invalid if PTR points user area.
+ */
+#define KERNEL_POINTER_VALIDP(PTR)     ({      \
+       const int *_ptr = (const int *) (PTR);  \
+       int _dummy;                             \
+       (unsigned long) _ptr >= PAGE_OFFSET  \
+               && !__get_user(_dummy, _ptr);   \
+})
+
+/*
+ *  Similar, but validates for a trivial string in kernel.
+ *  Here `trivial' means that the string has no non-ASCII characters
+ *  and is shorter than 80 characters.
+ *
+ *  Note this is intended for checking various `name' (I/O
+ *  resources and so on).
+ */
+#define KERNEL_POINTER_TRIVIAL_STRING_P(PTR)   ({                      \
+       const char *_ptr = (const char *) (PTR);                        \
+       char _dummy;                                                    \
+       (unsigned long) _ptr >= PAGE_OFFSET                          \
+               && ({ int _result;                                      \
+                     while (!(_result = __get_user(_dummy, _ptr))      \
+                            && _dummy)                                 \
+                             _ptr++;                                   \
+                     !_result; }); })
+
+#endif /* NEED_VALIDATE_KERNEL_POINTER */
+
+#endif /* _ASM_PC9800_DEBUG_H */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -urN linux/include/asm-i386/pc9800_dma.h linux98/include/asm-i386/pc9800_dma.h
--- linux/include/asm-i386/pc9800_dma.h Thu Jan  1 09:00:00 1970
+++ linux98/include/asm-i386/pc9800_dma.h       Fri Aug 17 22:15:01 2001
@@ -0,0 +1,238 @@
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ */
+
+#ifndef _ASM_PC9800_DMA_H
+#define _ASM_PC9800_DMA_H
+
+#include <linux/config.h>
+#include <asm/io.h>              /* need byte IO */
+#include <linux/delay.h>
+
+
+#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+#define dma_outb       outb_p
+#else
+#define dma_outb       outb
+#endif
+
+#define dma_inb                inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ *  controller 1: channels 0-3, byte operations, ports 00-1F
+ *  controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ *  - ALL registers are 8 bits only, regardless of transfer size
+ *  - channel 4 is not used - cascades 1 into 2.
+ *  - channels 0-3 are byte - addresses/counts are for physical bytes
+ *  - channels 5-7 are word - addresses/counts are for physical words
+ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ *  - transfer count loaded to registers is 1 less than actual count
+ *  - controller 2 offsets are all even (2x offsets for controller 1)
+ *  - page registers for 5-7 don't use data bit 0, represent
...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:00:16


This is a part 4/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

Summary:
  i386 core modules
   - IO port address change
   - IRQ number change
   - adapted to hardware memory mapping.
   - CLOCK_TICK_RATE constat to variable.
      some PC-9800 can change base clock by hardware switch!

diffstat:
  arch/i386/Kconfig                       |   30 ++
  arch/i386/Makefile                      |   18 +
  arch/i386/kernel/Makefile               |    4  arch/i386/kernel/cpu/proc.c             |    2  arch/i386/kernel/i8259.c                |  100 ++++----
  arch/i386/kernel/pc9800_debug.c         |  362 ++++++++++++++++++++++++++++++++
  arch/i386/kernel/reboot.c               |   18 -
  arch/i386/kernel/setup.c                |  101 --------
  arch/i386/kernel/time.c                 |  115 +---------
  arch/i386/kernel/timers/timer_pit.c     |   22 +
  arch/i386/kernel/timers/timer_tsc.c     |   88 -------
  arch/i386/kernel/traps.c                |   21 -
  arch/i386/kernel/vm86.c                 |   21 +
  arch/i386/mach-generic/calibrate_tsc.h  |   88 +++++++
  arch/i386/mach-generic/io_ports.h       |   30 ++
  arch/i386/mach-generic/mach_reboot.h    |   30 ++
  arch/i386/mach-generic/mach_resources.h |  113 +++++++++
  arch/i386/mach-generic/mach_time.h      |  122 ++++++++++
  arch/i386/mach-generic/mach_traps.h     |   31 ++
  arch/i386/mach-pc9800/Makefile          |   15 +
  arch/i386/mach-pc9800/calibrate_tsc.h   |   73 ++++++
  arch/i386/mach-pc9800/do_timer.h        |   80 +++++++
  arch/i386/mach-pc9800/entry_arch.h      |    1  arch/i386/mach-pc9800/io_ports.h        |   30 ++
  arch/i386/mach-pc9800/irq_vectors.h     |    1  arch/i386/mach-pc9800/mach_apic.h       |    1  arch/i386/mach-pc9800/mach_reboot.h     |   21 +
  arch/i386/mach-pc9800/mach_resources.h  |  192 ++++++++++++++++
  arch/i386/mach-pc9800/mach_time.h       |  136 ++++++++++++
  arch/i386/mach-pc9800/mach_traps.h      |   29 ++
  arch/i386/mach-pc9800/setup.c           |  117 ++++++++++
  arch/i386/mach-pc9800/setup_arch_post.h |   29 ++
  arch/i386/mach-pc9800/setup_arch_pre.h  |   36 +++
  arch/i386/mach-pc9800/smpboot_hooks.h   |   33 ++
  arch/i386/mach-summit/calibrate_tsc.h   |    1  arch/i386/mach-summit/io_ports.h        |    1  arch/i386/mach-summit/mach_reboot.h     |    1  
arch/i386/mach-summit/mach_resources.h  |    1  arch/i386/mach-summit/mach_time.h       |    1  arch/i386/mach-summit/mach_traps.h      |    1  
arch/i386/mach-visws/calibrate_tsc.h    |    1  arch/i386/mach-visws/io_ports.h         |    1  arch/i386/mach-visws/mach_reboot.h      |    1  
arch/i386/mach-visws/mach_resources.h   |    1  arch/i386/mach-visws/mach_time.h        |    1  arch/i386/mach-visws/mach_traps.h       |    1  
arch/i386/mach-voyager/calibrate_tsc.h  |    1  arch/i386/mach-voyager/io_ports.h       |    1  arch/i386/mach-voyager/mach_reboot.h    |    1  
arch/i386/mach-voyager/mach_resources.h |    1  arch/i386/mach-voyager/mach_time.h      |    1  arch/i386/mach-voyager/mach_traps.h     |    1  52 files
changed, 1764 insertions(+), 364 deletions(-)

patch:
diff -urN linux/arch/i386/Makefile linux98/arch/i386/Makefile
--- linux/arch/i386/Makefile    Thu Oct 31 13:23:02 2002
+++ linux98/arch/i386/Makefile  Thu Oct 31 13:56:57 2002
@@ -48,8 +48,14 @@
  ifdef CONFIG_VISWS
  MACHINE       := mach-visws
  else
+ifdef CONFIG_PC9800
+MACHINE        := mach-pc9800
+else
+ifndef MACHINE
  MACHINE       := mach-generic
  endif
+endif
+endif
   HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
  @@ -65,15 +71,20 @@
  CFLAGS += -Iarch/i386/$(MACHINE)
  AFLAGS += -Iarch/i386/$(MACHINE)
  -makeboot = $(call descend,arch/i386/boot,$(1))
+ifndef CONFIG_PC9800
+ARCHDIR=arch/i386/boot
+else
+ARCHDIR=arch/i386/boot98
+endif
+makeboot = $(call descend,$(ARCHDIR),$(1))
   .PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
                clean archclean archmrproper
   all: bzImage
  -BOOTIMAGE=arch/i386/boot/bzImage
-zImage zlilo zdisk: BOOTIMAGE=arch/i386/boot/zImage
+BOOTIMAGE=$(ARCHDIR)/bzImage
+zImage zlilo zdisk: BOOTIMAGE=$(ARCHDIR)/zImage
   zImage bzImage: vmlinux
        +@$(call makeboot,$(BOOTIMAGE))
@@ -91,5 +102,6 @@
   archclean:
        @$(MAKE) -f scripts/Makefile.clean obj=arch/i386/boot
+       @$(MAKE) -f scripts/Makefile.clean obj=arch/i386/boot98
   archmrproper:
diff -urN linux/arch/i386/Kconfig linux98/arch/i386/Kconfig
--- linux/arch/i386/Kconfig     Thu Oct 31 13:23:02 2002
+++ linux98/arch/i386/Kconfig   Sat Nov  2 15:11:17 2002
@@ -964,6 +964,12 @@
  # Visual Workstation support is utterly broken.
  # If you want to see it working mail an VW540 to h...@infradead.org 8)
  #bool 'SGI Visual Workstation support' CONFIG_VISWS
+config PC9800
+       bool "NEC PC-9800 architecture support"
+       help
+         To make kernel for NEC PC-9801/PC-9821 architecture, say Y.
+         If say Y, kernel works -ONLY- on PC-9800 architecture.
+
  config X86_VISWS_APIC
        bool
        depends on VISWS
@@ -1056,7 +1062,7 @@
   config EISA
        bool "EISA support"
-       depends on ISA
+       depends on ISA && !PC9800
        ---help---
          The Extended Industry Standard Architecture (EISA) bus was
          developed as an open alternative to the IBM MicroChannel bus.
@@ -1072,7 +1078,7 @@
   config MCA
        bool "MCA support"
-       depends on !VISWS
+       depends on !(VISWS || PC9800)
        help
          MicroChannel Architecture is found in some IBM PS/2 machines and
          laptops.  It is a bus system similar to PCI or ISA. See
@@ -1420,6 +1426,7 @@
   config VGA_CONSOLE
        bool "VGA text console"
+       depends on !PC9800
        help
          Saying Y here will allow you to use Linux in text mode through a
          display that complies with the generic VGA standard. Virtually
@@ -1433,6 +1440,7 @@
   config VIDEO_SELECT
        bool "Video mode selection support"
+       depends on !PC9800
        ---help---
          This enables support for text mode selection on kernel startup. If
          you want to take advantage of some high-resolution text mode your
@@ -1446,6 +1454,18 @@
          Read the file <file:Documentation/svga.txt> for more information
          about the Video mode selection support. If unsure, say N.
  +config GDC_CONSOLE
+       bool "PC-9800 GDC text console"
+       depends on PC9800
+       default y
+       help
+         This enables support for PC-9800 standard text mode console.
+         If use PC-9801/PC-9821, Say Y.
+
+config GDC_32BITACCESS
+       bool "Enable 32-bit access to text video RAM"
+       depends on GDC_CONSOLE
+
  if EXPERIMENTAL
   config MDA_CONSOLE
@@ -1612,6 +1632,12 @@
          symbolic stack backtraces. This increases the size of the kernel
          somewhat, as all symbols have to be loaded into the kernel image.
  +config PC9800_UCGLOG
+       bool "Save kernel messages into UCG-RAM"
+       depends on PC9800
+       help
+         This enables saving kernel messases into PC-9800's NVRAM.
+
  config X86_EXTRA_IRQS
        bool
        depends on X86_LOCAL_APIC
diff -urN linux/arch/i386/kernel/Makefile linux98/arch/i386/kernel/Makefile
--- linux/arch/i386/kernel/Makefile     Wed Oct 16 13:20:28 2002
+++ linux98/arch/i386/kernel/Makefile   Wed Oct 16 14:27:17 2002
@@ -10,6 +10,10 @@
                ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
                pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o \
                bootflag.o
+ifeq ($(CONFIG_PC9800),y)
+export-objs                    += pc9800_debug.o
+obj-$(CONFIG_PC9800)           += pc9800_debug.o
+endif
   obj-y                                += cpu/
  obj-y                         += timers/
diff -urN linux/arch/i386/kernel/cpu/proc.c linux98/arch/i386/kernel/cpu/proc.c
--- linux/arch/i386/kernel/cpu/proc.c   Mon Jun 17 11:31:35 2002
+++ linux98/arch/i386/kernel/cpu/proc.c Mon Jun 17 23:49:02 2002
@@ -76,7 +76,7 @@
                seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);

        /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
-       fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
+       fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
        seq_printf(m, "fdiv_bug\t: %s\n"
                        "hlt_bug\t\t: %s\n"
                        "f00f_bug\t: %s\n"
diff -urN linux/arch/i386/kernel/i8259.c linux98/arch/i386/kernel/i8259.c
--- linux/arch/i386/kernel/i8259.c      Tue Oct  8 03:25:15 2002
+++ linux98/arch/i386/kernel/i8259.c    Thu Oct 10 21:46:44 2002
@@ -25,6 +25,8 @@
   #include <linux/irq.h>
  +#include "io_ports.h"
+
  /*
   * This is the 'legacy' 8259A Programmable Interrupt Controller,
   * present in the majority of PC/AT boxes.
@@ -74,8 +76,8 @@
  static unsigned int cached_irq_mask = 0xffff;
   #define __byte(x,y)  (((unsigned char *)&(y))[x])
-#define cached_21      (__byte(0,cached_irq_mask))
-#define cached_A1      (__byte(1,cached_irq_mask))
+#define cached_master_mask     (__byte(0,cached_irq_mask))
+#define cached_slave_mask      (__byte(1,cached_irq_mask))
   /*
   * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
@@ -96,9 +98,9 @@
        spin_lock_irqsave(&i8259A_lock, flags);
        cached_irq_mask |= mask;
        if (irq & 8)
-               outb(cached_A1,0xA1);
+               outb(cached_slave_mask, PIC_SLAVE_IMR);
        else
-               outb(cached_21,0x21);
+               outb(cached_master_mask, PIC_MASTER_IMR);
        spin_unlock_irqrestore(&i8259A_lock, flags);
  }
  @@ -110,9 +112,9 @@
        spin_lock_irqsave(&i8259A_lock, flags);
        cached_irq_mask &= mask;
        if (irq & 8)
-               outb(cached_A1,0xA1);
+               outb(cached_slave_mask, PIC_SLAVE_IMR);
        else
-               outb(cached_21,0x21);
+               outb(cached_master_mask, PIC_MASTER_IMR);
        spin_unlock_irqrestore(&i8259A_lock, flags);
  }
  @@ -124,9 +126,9 @@
        spin_lock_irqsave(&i8259A_lock, flags);
        if (irq < 8)
-               ret = inb(0x20) & mask;
+               ret = inb(PIC_MASTER_CMD) & mask;
        else
-               ret = inb(0xA0) & (mask >> 8);
+               ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
        spin_unlock_irqrestore(&i8259A_lock, flags);
        return ret;
@@ -152,14 +154,14 @@
        int irqmask = 1<<irq;
        if (irq < 8) {
-               outb(0x0B,0x20);                /* ISR register */
-               value = inb(0x20) & irqmask;
-               outb(0x0A,0x20);                /* back to the IRR register */
+               outb(0x0B,PIC_MASTER_CMD);      /* ISR register */
+               value = inb(PIC_MASTER_CMD) & irqmask;
+               outb(0x0A,PIC_MASTER_CMD);      /* back to the IRR register */
                return value;
        }
- ...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:10:09


This is part 8/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

Summary:
  file system modules
   - add support PC-9800 partition table.
   - small hack for access FAT partition made by PC-9800 DOS.

diffstat:
  fs/fat/inode.c         |    5  fs/partitions/Kconfig  |   11 +
  fs/partitions/Makefile |    1  fs/partitions/check.c  |    4  fs/partitions/msdos.c  |   15 ++
  fs/partitions/nec98.c  |  277 +++++++++++++++++++++++++++++++++++++++++++++++++
  fs/partitions/nec98.h  |   10 +
  7 files changed, 322 insertions(+), 1 deletion(-)

patch:
diff -urN linux/fs/fat/inode.c linux98/fs/fat/inode.c
--- linux/fs/fat/inode.c        Thu Oct 31 13:23:37 2002
+++ linux98/fs/fat/inode.c      Thu Oct 31 16:41:16 2002
@@ -49,6 +49,7 @@
  #define FAT_HASH_MASK (FAT_HASH_SIZE-1)
  static struct list_head fat_inode_hashtable[FAT_HASH_SIZE];
  spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
+extern int pc98;       /* whether PC-9801 architecutre or not */
   void fat_hash_init(void)
  {
@@ -928,7 +929,9 @@
                error = first;
                goto out_fail;
        }
-       if (FAT_FIRST_ENT(sb, media) != first) {
+       if (FAT_FIRST_ENT(sb, media) != first
+           && (!pc98 || media != 0xf8 || (first & 0xff) != 0xfe))
+       {
                if (!silent) {
                        printk(KERN_ERR "FAT: invalid first entry of FAT "
                               "(0x%x != 0x%x)\n",
diff -urN linux/fs/partitions/Kconfig linux98/fs/partitions/Kconfig
--- linux/fs/partitions/Kconfig Thu Oct 31 13:23:38 2002
+++ linux98/fs/partitions/Kconfig       Thu Oct 31 16:27:06 2002
@@ -177,6 +177,17 @@
          If unsure, say N.
  +config NEC98_PARTITION
+       bool "NEC PC-9800 partition table support" if PARTITION_ADVANCED
+       default y if !PARTITION_ADVANCED && PC9800
+       help
+         Say Y here if you would like to be able to read the hard disk
+         partition table format used by NEC PC-9800 machines.
+
+config NEC98_BSD_DISKLABEL
+       bool "BSD disklabel support for NEC PC-9800 type partitions"
+       depends on NEC98_PARTITION
+
  config SGI_PARTITION
        bool "SGI partition support" if PARTITION_ADVANCED
        default y if !PARTITION_ADVANCED && (SGI_IP22 || SGI_IP27)
diff -urN linux/fs/partitions/Makefile linux98/fs/partitions/Makefile
--- linux/fs/partitions/Makefile        Sat Oct 19 13:01:50 2002
+++ linux98/fs/partitions/Makefile      Sat Oct 19 17:00:39 2002
@@ -18,6 +18,7 @@
  obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
  obj-$(CONFIG_IBM_PARTITION) += ibm.o
  obj-$(CONFIG_EFI_PARTITION) += efi.o
+obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
   include $(TOPDIR)/Rules.make
  diff -urN linux/fs/partitions/check.c linux98/fs/partitions/check.c
--- linux/fs/partitions/check.c Thu Oct 31 13:23:38 2002
+++ linux98/fs/partitions/check.c       Thu Oct 31 16:16:41 2002
@@ -29,6 +29,7 @@
  #include "ldm.h"
  #include "mac.h"
  #include "msdos.h"
+#include "nec98.h"
  #include "osf.h"
  #include "sgi.h"
  #include "sun.h"
@@ -52,6 +53,9 @@
  #ifdef CONFIG_LDM_PARTITION
        ldm_partition,          /* this must come before msdos */
  #endif
+#ifdef CONFIG_NEC98_PARTITION
+       nec98_partition,        /* must be come before `msdos_partition' */
+#endif
  #ifdef CONFIG_MSDOS_PARTITION
        msdos_partition,
  #endif
diff -urN linux/fs/partitions/msdos.c linux98/fs/partitions/msdos.c
--- linux/fs/partitions/msdos.c Sat Oct 12 13:22:10 2002
+++ linux98/fs/partitions/msdos.c       Sun Oct 13 22:23:58 2002
@@ -20,6 +20,11 @@
   */
   #include <linux/config.h>
+
+#ifdef CONFIG_NEC98_BSD_DISKLABEL
+# define CONFIG_BSD_DISKLABEL
+#endif
+
  #include <linux/buffer_head.h>          /* for invalidate_bdev() */
   #ifdef CONFIG_BLK_DEV_IDE
@@ -37,6 +42,7 @@
  #include "msdos.h"
  #include "efi.h"
  +#if !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION)
  /*
   * Many architectures don't like unaligned accesses, which is
   * frequently the case with the nr_sects and start_sect partition
@@ -171,6 +177,7 @@
  done:
        put_dev_sector(sect);
  }
+#endif /* !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION) */
   /* ja...@bpgc.com: Solaris has a nasty indicator: 0x82 which also
     indicates linux swap.  Be careful before believing this is Solaris. */
@@ -179,6 +186,7 @@
  parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
                        u32 offset, u32 size, int origin)
  {
+#if !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION)
  #ifdef CONFIG_SOLARIS_X86_PARTITION
        Sector sect;
        struct solaris_x86_vtoc *v;
@@ -212,6 +220,7 @@
        put_dev_sector(sect);
        printk(" >\n");
  #endif
+#endif /* !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION) */
  }
   #ifdef CONFIG_BSD_DISKLABEL
@@ -219,7 +228,11 @@
   * Create devices for BSD partitions listed in a disklabel, under a
   * dos-like partition. See parse_extended() for more information.
   */
+#ifndef CONFIG_NEC98_BSD_DISKLABEL
  static void
+#else
+void
+#endif
  parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
                u32 offset, u32 size, int origin, char *flavour,
                int max_partitions)
@@ -292,6 +305,7 @@
  #endif
  }
  +#if !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION)
  /*
   * Create devices for Unixware partitions listed in a disklabel, under a
   * dos-like partition. See parse_extended() for more information.
@@ -461,3 +475,4 @@
        put_dev_sector(sect);
        return 1;
  }
+#endif /* !defined(CONFIG_PC9800) || defined(CONFIG_MSDOS_PARTITION) */
diff -urN linux/fs/partitions/nec98.c linux98/fs/partitions/nec98.c
--- linux/fs/partitions/nec98.c Thu Jan  1 09:00:00 1970
+++ linux98/fs/partitions/nec98.c       Sat Nov  2 17:12:51 2002
@@ -0,0 +1,277 @@
+/*
+ *  NEC PC-9800 series partition supports
+ *
+ *  Copyright (C) 1999 Kyoto University Microcomputer Club
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_NEC98_BSD_DISKLABEL
+#define CONFIG_BSD_DISKLABEL
+#endif
+
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/blk.h>
+#include <linux/major.h>
+
+#include "check.h"
+#include "nec98.h"
+
+/* #ifdef CONFIG_BLK_DEV_IDEDISK */
+#include <linux/ide.h>
+/* #endif */
+
+/* #ifdef CONFIG_BLK_DEV_SD */
+#include "../../drivers/scsi/scsi.h"
+#include "../../drivers/scsi/hosts.h"
+#include <scsi/scsicam.h>
+/* #endif */
+
+struct nec98_partition {
+       __u8    mid;            /* 0x80 - active */
+       __u8    sid;            /* 0x80 - bootable */
+       __u16   pad1;           /* dummy for padding */
+       __u8    ipl_sector;     /* IPL sector   */
+       __u8    ipl_head;       /* IPL head     */
+       __u16   ipl_cyl;        /* IPL cylinder */
+       __u8    sector;         /* starting sector      */
+       __u8    head;           /* starting head        */
+       __u16   cyl;            /* starting cylinder    */
+       __u8    end_sector;     /* end sector   */
+       __u8    end_head;       /* end head     */
+       __u16   end_cyl;        /* end cylinder */
+       unsigned char name[16];
+} __attribute__((__packed__));
+
+#define NEC98_BSD_PARTITION_MID 0x14
+#define NEC98_BSD_PARTITION_SID 0x44
+#define MID_SID_16(mid, sid)   (((mid) & 0xFF) | (((sid) & 0xFF) << 8))
+#define NEC98_BSD_PARTITION_MID_SID    \
+       MID_SID_16(NEC98_BSD_PARTITION_MID, NEC98_BSD_PARTITION_SID)
+#define NEC98_VALID_PTABLE_ENTRY(P) \
+       (!(P)->pad1 && (P)->cyl <= (P)->end_cyl)
+
+static inline int
+is_valid_nec98_partition_table(const struct nec98_partition *ptable,
+                               __u8 nsectors, __u8 nheads)
+{
+       int i;
+       int valid = 0;
+
+       for (i = 0; i < 16; i++) {
+               if (!*(__u16 *)&ptable[i])
+                       continue;       /* empty slot */
+               if (ptable[i].pad1      /* `pad1' contains junk */
+                   || ptable[i].ipl_sector     >= nsectors
+                   || ptable[i].sector         >= nsectors
+                   || ptable[i].end_sector     >= nsectors
+                   || ptable[i].ipl_head       >= nheads
+                   || ptable[i].head           >= nheads
+                   || ptable[i].end_head       >= nheads
+                   || ptable[i].cyl > ptable[i].end_cyl)
+                       return 0;
+               valid = 1;      /* We have a valid partition.  */
+       }
+       /* If no valid PC-9800-style partitions found,
+          the disk may have other type of partition table.  */
+       return valid;
+}
+
+#ifdef CONFIG_NEC98_BSD_DISKLABEL
+extern void parse_bsd(struct parsed_partitions *state,
+                       struct block_device *bdev,
+                       u32 offset, u32 size, int origin, char *flavour,
+                       int max_partitions);
+#endif
+
+extern struct scsi_device *sd_find_params_by_bdev(struct block_device *, char **, sector_t *);
+
+int nec98_partition(struct parsed_partitions *state, struct block_device *bdev)
+{
+       unsigned int nr;
+       int g_head, g_sect;
+       Sector sect;
+       const struct nec98_partition *part;
+       unsigned char *data;
+       int sector_size = bdev_hardsect_size(bdev);
+       int major = major(to_kdev_t(bdev->bd_dev));
+       int minor = minor(to_kdev_t(bdev->bd_dev));
+
+       switch (major) {
+#if defined CONFIG_BLK_DEV_HD_ONLY
+       case HD_MAJOR:
+       {
+               extern struct hd_i_struct hd_info[2];
+
+               g_head = hd_info[minor >> 6].head;
+               g_sect = hd_info[minor >> 6].sect;
+               break;
+       }
+#endif /* CONFIG_BLK_DEV_HD_ONLY */
+#if defined CONFIG_BLK_DEV_SD || defined CONFIG_BLK_DEV_SD_MODULE
+       case SCSI_DISK0_MAJOR:
+       case SCSI_DISK1_MAJOR:
+       case SCSI_DISK2_MAJOR:
+       case SCSI_DISK3_MAJOR:
+       case SCSI_DISK4_MAJOR:
+       case SCSI_DISK5_MAJOR:
+       case SCSI_DISK6_MAJOR:
+       case SCSI_DISK7_MAJOR:
+       {
+               int diskinfo[3] = { 0, 0, 0 };
+               sector_t capacity;
+
+               (void)sd_find_params_by_bdev(bdev, NULL, &capacity);
+               scsicam_bios_param(bdev, capacity, diskinfo);
+
+               if ((g_head = diskinfo[0]) <= 0)
+                       g_head = 8;
+               if ((g_sect = diskinfo[1]) <= 0)
+                       g_sect = 17;
+               break;
+       }
+#endif /* CONFIG_BLK_DEV_SD(_MODULE) */
+#if defined CONFIG_BLK_DEV_IDEDISK || defined CONFIG_BLK_DEV_IDEDISK_MODULE
+       case IDE0_MAJOR:
+       case IDE1_MAJOR:
+       case IDE2_MAJOR:
+       case IDE3_MAJOR:
+       case IDE4_MAJOR:
+       case IDE5_MAJOR:
+       case IDE6_MAJOR:
+       case IDE7_MAJOR:
+       case IDE8_MAJOR:
+       case IDE9_MAJOR:
+       {
+               ide_drive_t *drive;
+               unsigned int    h;
+
+               for (h = 0; h < MAX_HWIFS; ++h) {
+                       ide_hwif_t  *hwif = &ide_hwifs[h];
+                       if (hwif->present && major == hwif->major) {
+                               unsigned unit = minor >> PARTN_BITS;
+                               if (unit < MAX_DRIVES) {
+                                       drive = &hwif->drives[unit];
+                                       if (drive->present) {
+                                               g_head = drive->head;
+                                               g_sect = drive->sect;
+                                               goto found;
+                                       }
+                               }
+                               break;
+                       }
+               }
+       }
+#endif /* CONFIG_BLK_DEV_IDEDISK(_MODULE) */
+       default:
+               printk(" unsupported disk (major =
...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:10:08


This is a part 6/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

floppy98.c is splited to 2 patches. Please apply this before floppy2.

Summary:
  floppy driver modules
   - add PC-9800 standard FDD support.
     based on floppy.c, enhanced media check and auto detect.

diffstat:
  drivers/block/Makefile   |    4  drivers/block/floppy98.c | 2337 +++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 2341 insertions(+)

patch:
diff -urN linux/drivers/block/Makefile linux98/drivers/block/Makefile
--- linux/drivers/block/Makefile        Wed Oct 16 13:20:33 2002
+++ linux98/drivers/block/Makefile      Wed Oct 16 14:56:42 2002
@@ -14,7 +14,11 @@
  obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o deadline-iosched.o
   obj-$(CONFIG_MAC_FLOPPY)     += swim3.o
+ifneq ($(CONFIG_PC9800),y)
  obj-$(CONFIG_BLK_DEV_FD)      += floppy.o
+else
+obj-$(CONFIG_BLK_DEV_FD)       += floppy98.o
+endif
  obj-$(CONFIG_AMIGA_FLOPPY)    += amiflop.o
  obj-$(CONFIG_ATARI_FLOPPY)    += ataflop.o
  obj-$(CONFIG_BLK_DEV_SWIM_IOP)        += swim_iop.o
diff -urN linux/drivers/block/floppy98.c linux98/drivers/block/floppy98.c
--- linux/drivers/block/floppy98.c      Thu Jan  1 09:00:00 1970
+++ linux98/drivers/block/floppy98.c    Thu Oct 31 16:11:27 2002
@@ -0,0 +1,2337 @@
+/*
+ *  linux/drivers/block/floppy.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1993, 1994  Alain Knaff
+ *  Copyright (C) 1998 Alan Cox
+ */
+/*
+ * 02.12.91 - Changed to static variables to indicate need for reset
+ * and recalibrate. This makes some things easier (output_byte reset
+ * checking etc), and means less interrupt jumping in case of errors,
+ * so the code is hopefully easier to understand.
+ */
+
+/*
+ * This file is certainly a mess. I've tried my best to get it working,
+ * but I don't like programming floppies, and I have only one anyway.
+ * Urgel. I should check for more errors, and do more graceful error
+ * recovery. Seems there are problems with several drives. I've tried to
+ * correct them. No promises.
+ */
+
+/*
+ * As with hd.c, all routines within this file can (and will) be called
+ * by interrupts, so extreme caution is needed. A hardware interrupt
+ * handler may not sleep, or a kernel panic will happen. Thus I cannot
+ * call "floppy-on" directly, but have to set a special timer interrupt
+ * etc.
+ */
+
+/*
+ * 28.02.92 - made track-buffering routines, based on the routines written
+ * by entr...@wintermute.wpi.edu (Lawrence Foard). Linus.
+ */
+
+/*
+ * Automatic floppy-detection and formatting written by Werner Almesberger
+ * (almes...@nessie.cs.id.ethz.ch), who also corrected some problems with
+ * the floppy-change signal detection.
+ */
+
+/*
+ * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
+ * FDC data overrun bug, added some preliminary stuff for vertical
+ * recording support.
+ *
+ * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
+ *
+ * TODO: Errors are still not counted properly.
+ */
+
+/* 1992/9/20
+ * Modifications for ``Sector Shifting'' by Rob Hooft (ho...@chem.ruu.nl)
+ * modeled after the freeware MS-DOS program fdformat/88 V1.8 by
+ * Christoph H. Hochst\"atter.
+ * I have fixed the shift values to the ones I always use. Maybe a new
+ * ioctl() should be created to be able to modify them.
+ * There is a bug in the driver that makes it impossible to format a
+ * floppy as the first thing after bootup.
+ */
+
+/*
+ * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
+ * this helped the floppy driver as well. Much cleaner, and still seems to
+ * work.
+ */
+
+/* 1994/6/24 --bbroad-- added the floppy table entries and made
+ * minor modifications to allow 2.88 floppies to be run.
+ */
+
+/* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
+ * disk types.
+ */
+
+/*
+ * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
+ * format bug fixes, but unfortunately some new bugs too...
+ */
+
+/* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write
+ * errors to allow safe writing by specialized programs.
+ */
+
+/* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
+ * by defining bit 1 of the "stretch" parameter to mean put sectors on the
+ * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
+ * drives are "upside-down").
+ */
+
+/*
+ * 1995/8/26 -- Andreas Busse -- added Mips support.
+ */
+
+/*
+ * 1995/10/18 -- Ralf Baechle -- Portability cleanup; move machine dependent
+ * features to asm/floppy.h.
+ */
+
+/*
+ * 1998/05/07 -- Russell King -- More portability cleanups; moved definition of
+ * interrupt and dma channel to asm/floppy.h. Cleaned up some formatting &
+ * use of '0' for NULL.
+ */
+ +/*
+ * 1998/06/07 -- Alan Cox -- Merged the 2.0.34 fixes for resource allocation
+ * failures.
+ */
+
+/*
+ * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives.
+ */
+
+/*
+ * 1999/01/19 -- N.Fujita & Linux/98 Project -- Added code for NEC PC-9800
+ * series.
+ */
+
+/*
+ * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24
+ * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were
+ * being used to store jiffies, which are unsigned longs).
+ */
+
+/*
+ * 2000/08/28 -- Arnaldo Carvalho de Melo <a...@conectiva.com.br>
+ * - get rid of check_region
+ * - s/suser/capable/
+ */
+
+/*
+ * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
+ * floppy controller (lingering task on list after module is gone... boom.)
+ */
+
+/*
+ * 2002/02/07 -- Anton Altaparmakov - Fix io ports reservation to correct range
+ * (0x3f2-0x3f5, 0x3f7). This fix is a bit of a hack but the proper fix
+ * requires many non-obvious changes in arch dependent code.
+ */
+
+/*
+ * 2002/10/12 -- Osamu Tomita <tom...@cinet.co.jp>
+ * split code from floppy.c
+ * support NEC PC-9800 only
+ */
+
+#define FLOPPY_SANITY_CHECK
+#undef  FLOPPY_SILENT_DCL_CLEAR
+
+/*
+#define PC9800_DEBUG_FLOPPY
+#define PC9800_DEBUG_FLOPPY2
+*/
+
+#define REALLY_SLOW_IO
+
+#define DEBUGT 2
+#define DCL_DEBUG /* debug disk change line */
+
+/* do print messages for unexpected interrupts */
+static int print_unex=1;
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#define FDPATCHES
+#include <linux/fdreg.h>
+
+/*
+ * 1998/1/21 -- Richard Gooch <rgo...@atnf.csiro.au> -- devfs support
+ */
+
+
+#include <linux/fd.h>
+#include <linux/hdreg.h>
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/bio.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <linux/mc146818rtc.h> /* CMOS defines */
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/device.h>
+#include <linux/buffer_head.h>           /* for invalidate_buffers() */
+
+/*
+ * PS/2 floppies have much slower step rates than regular floppies.
+ * It's been recommended that take about 1/4 of the default speed
+ * in some more extreme cases.
+ */
+static int slow_floppy;
+
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#ifndef DEFAULT_FLOPPY_IRQ
+# define DEFAULT_FLOPPY_IRQ    11
+#endif
+#ifndef DEFAULT_FLOPPY_DMA
+# define DEFAULT_FLOPPY_DMA    2
+#endif
+
+static int FLOPPY_IRQ=DEFAULT_FLOPPY_IRQ;
+static int FLOPPY_DMA=DEFAULT_FLOPPY_DMA;
+static int can_use_virtual_dma=2;
+static int auto_detect_mode = 0;
+static int retry_auto_detect = 0;
+#define FD_AFTER_RESET_DELAY 1000
+
+/* =======
+ * can use virtual DMA:
+ * 0 = use of virtual DMA disallowed by config
+ * 1 = use of virtual DMA prescribed by config
+ * 2 = no virtual DMA preference configured.  By default try hard DMA,
+ * but fall back on virtual DMA when not enough memory available
+ */
+
+static int use_virtual_dma;
+/* =======
+ * use virtual DMA
+ * 0 using hard DMA
+ * 1 using virtual DMA
+ * This variable is set to virtual when a DMA mem problem arises, and
+ * reset back in floppy_grab_irq_and_dma.
+ * It is not safe to reset it in other circumstances, because the floppy
+ * driver may have several buffers in use at once, and we do currently not
+ * record each buffers capabilities
+ */
+
+static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned short virtual_dma_port=0x3f0;
+void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static int set_mode(char mask, char data);
+static void register_devfs_entries (int drive) __init;
+static devfs_handle_t devfs_handle;
+
+#define K_64   0x10000         /* 64KB */
+
+/* the following is the mask of allowed drives. By default units 2 and
+ * 3 of both floppy controllers are disabled, because switching on the
+ * motor of these drives causes system hangs on some PCI computers. drive
+ * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
+ * a drive is allowed.
+ *
+ * NOTE: This must come before we include the arch floppy header because
+ *       some ports reference this variable from there. -DaveM
+ */
+
+static int allowed_drive_mask = 0x0f;
+
+#include <asm/floppy.h>
+
+static int irqdma_allocated;
+
+#define LOCAL_END_REQUEST
+#define MAJOR_NR FLOPPY_MAJOR
+#define DEVICE_NAME "floppy"
+#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
+#include <linux/blk.h>
+#include <linux/blkpg.h>
+#include <linux/cdrom.h> /* for the compatibility eject ioctl */
+#include <linux/completion.h>
+
+static struct request *current_req;
+static struct request_queue floppy_queue;
+
+#ifndef fd_get_dma_residue
+#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
+#endif
+
+/* Dma Memory related stuff */
+
+#ifndef fd_dma_mem_free
+#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
+#endif
+
+#ifndef fd_dma_mem_alloc
+#define fd_dma_mem_alloc(size) ...

read more »

 
 
 

[Patchset 1/20] Support for PC-9800

Post by Osamu Tomit » Sun, 03 Nov 2002 20:10:10


This is a part 7/20 of patchset for add support NEC PC-9800 architecture,
against 2.5.45.

floppy98.c is splited to 2 patches. Please apply this after floppy1.

Summary:
  floppy driver modules

diffstat:
  drivers/block/floppy98.c  | 2303 ++++++++++++++++++++++++++++++++++++++++++++++
  include/asm-i386/floppy.h |   11  include/linux/fdreg.h     |   24  3 files changed, 2338 insertions(+)

patch:
diff -urN linux/drivers/block/floppy98.c linux98/drivers/block/floppy98.c
--- linux/drivers/block/floppy98.c      Thu Oct 31 16:11:27 2002
+++ linux98/drivers/block/floppy98.c    Thu Oct 31 16:09:02 2002
@@ -2335,3 +2335,2306 @@
        return ret;
  }
  +/*
+ * Buffer read/write and support
+ * =============================
+ */
+
+static inline void end_request(struct request *req, int uptodate)
+{
+       if (end_that_request_first(req, uptodate, current_count_sectors))
+               return;
+       add_disk_randomness(req->rq_disk);
+       floppy_off((int)req->rq_disk->private_data);
+       blkdev_dequeue_request(req);
+       end_that_request_last(req);
+
+       /* We're done with the request */
+       current_req = NULL;
+}
+
+
+/* new request_done. Can handle physical sectors which are smaller than a
+ * logical buffer */
+static void request_done(int uptodate)
+{
+       struct request_queue *q = &floppy_queue;
+       struct request *req = current_req;
+       unsigned long flags;
+       int block;
+
+       probing = 0;
+       reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
+
+       if (!req) {
+               printk("floppy.c: no request in request_done\n");
+               return;
+       }
+
+       if (uptodate){
+               /* maintain values for invalidation on geometry
+                * change */
+               block = current_count_sectors + req->sector;
+               INFBOUND(DRS->maxblock, block);
+               if (block > _floppy->sect)
+                       DRS->maxtrack = 1;
+
+               /* unlock chained buffers */
+               spin_lock_irqsave(q->queue_lock, flags);
+               end_request(req, 1);
+               spin_unlock_irqrestore(q->queue_lock, flags);
+       } else {
+               if (rq_data_dir(req) == WRITE) {
+                       /* record write error information */
+                       DRWE->write_errors++;
+                       if (DRWE->write_errors == 1) {
+                               DRWE->first_error_sector = req->sector;
+                               DRWE->first_error_generation = DRS->generation;
+                       }
+                       DRWE->last_error_sector = req->sector;
+                       DRWE->last_error_generation = DRS->generation;
+               }
+               spin_lock_irqsave(q->queue_lock, flags);
+               end_request(req, 0);
+               spin_unlock_irqrestore(q->queue_lock, flags);
+       }
+}
+
+/* Interrupt handler evaluating the result of the r/w operation */
+static void rw_interrupt(void)
+{
+       int nr_sectors, ssize, eoc, heads;
+
+       if (R_HEAD >= 2) {
+           /* some Toshiba floppy controllers occasionnally seem to
+            * return bogus interrupts after read/write operations, which
+            * can be recognized by a bad head number (>= 2) */
+            return;
+       }  +
+       if (!DRS->first_read_date)
+               DRS->first_read_date = jiffies;
+
+       nr_sectors = 0;
+       CODE2SIZE;
+
+       if (ST1 & ST1_EOC)
+               eoc = 1;
+       else
+               eoc = 0;
+
+       if (COMMAND & 0x80)
+               heads = 2;
+       else
+               heads = 1;
+
+       nr_sectors = (((R_TRACK-TRACK) * heads +
+                                  R_HEAD-HEAD) * SECT_PER_TRACK +
+                                  R_SECTOR-SECTOR + eoc) << SIZECODE >> 2;
+
+#ifdef FLOPPY_SANITY_CHECK
+       if (nr_sectors / ssize > +           (in_sector_offset + current_count_sectors + ssize - 1) / ssize) {
+               DPRINT("long rw: %x instead of %lx\n",
+                       nr_sectors, current_count_sectors);
+               printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
+               printk("rh=%d h=%d\n", R_HEAD, HEAD);
+               printk("rt=%d t=%d\n", R_TRACK, TRACK);
+               printk("heads=%d eoc=%d\n", heads, eoc);
+               printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
+                      fsector_t, ssize);
+               printk("in_sector_offset=%d\n", in_sector_offset);
+       }
+#endif
+
+       nr_sectors -= in_sector_offset;
+       INFBOUND(nr_sectors,0);
+       SUPBOUND(current_count_sectors, nr_sectors);
+
+       switch (interpret_errors()){
+               case 2:
+                       cont->redo();
+                       return;
+               case 1:
+                       if (!current_count_sectors){
+                               cont->error();
+                               cont->redo();
+                               return;
+                       }
+                       break;
+               case 0:
+                       if (!current_count_sectors){
+                               cont->redo();
+                               return;
+                       }
+                       current_type[current_drive] = _floppy;
+                       floppy_sizes[TOMINOR(current_drive) ]= _floppy->size;
+                       break;
+       }
+
+       if (probing) {
+               if (DP->flags & FTD_MSG)
+                       DPRINT("Auto-detected floppy type %s in fd%d\n",
+                               _floppy->name,current_drive);
+               current_type[current_drive] = _floppy;
+               floppy_sizes[TOMINOR(current_drive)] = _floppy->size;
+               probing = 0;
+       }
+
+       if (CT(COMMAND) != FD_READ || +      raw_cmd->kernel_data == current_req->buffer){
+               /* transfer directly from buffer */
+               cont->done(1);
+       } else if (CT(COMMAND) == FD_READ){
+               buffer_track = raw_cmd->track;
+               buffer_drive = current_drive;
+               INFBOUND(buffer_max, nr_sectors + fsector_t);
+       }
+       cont->redo();
+}
+
+/* Compute maximal contiguous buffer size. */
+static int buffer_chain_size(void)
+{
+       struct bio *bio;
+       struct bio_vec *bv;
+       int size, i;
+       char *base;
+
+       base = bio_data(current_req->bio);
+       size = 0;
+
+       rq_for_each_bio(bio, current_req) {
+               bio_for_each_segment(bv, bio, i) {
+                       if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+                               break;
+
+                       size += bv->bv_len;
+               }
+       }
+
+       return size >> 9;
+}
+
+/* Compute the maximal transfer size */
+static int transfer_size(int ssize, int max_sector, int max_size)
+{
+       SUPBOUND(max_sector, fsector_t + max_size);
+
+       /* alignment */
+       max_sector -= (max_sector % _floppy->sect) % ssize;
+
+       /* transfer size, beginning not aligned */
+       current_count_sectors = max_sector - fsector_t ;
+
+       return max_sector;
+}
+
+/*
+ * Move data from/to the track buffer to/from the buffer cache.
+ */
+static void copy_buffer(int ssize, int max_sector, int max_sector_2)
+{
+       int remaining; /* number of transferred 512-byte sectors */
+       struct bio_vec *bv;
+       struct bio *bio;
+       char *buffer, *dma_buffer;
+       int size, i;
+
+       max_sector = transfer_size(ssize,
+                                  minimum(max_sector, max_sector_2),
+                                  current_req->nr_sectors);
+
+       if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
+           buffer_max > fsector_t + current_req->nr_sectors)
+               current_count_sectors = minimum(buffer_max - fsector_t,
+                                               current_req->nr_sectors);
+
+       remaining = current_count_sectors << 9;
+#ifdef FLOPPY_SANITY_CHECK
+       if ((remaining >> 9) > current_req->nr_sectors  &&
+           CT(COMMAND) == FD_WRITE){
+               DPRINT("in copy buffer\n");
+               printk("current_count_sectors=%ld\n", current_count_sectors);
+               printk("remaining=%d\n", remaining >> 9);
+               printk("current_req->nr_sectors=%ld\n",current_req->nr_sectors);
+               printk("current_req->current_nr_sectors=%u\n",
+                      current_req->current_nr_sectors);
+               printk("max_sector=%d\n", max_sector);
+               printk("ssize=%d\n", ssize);
+       }
+#endif
+
+       buffer_max = maximum(max_sector, buffer_max);
+
+       dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9);
+
+       size = current_req->current_nr_sectors << 9;
+
+       rq_for_each_bio(bio, current_req) {
+               bio_for_each_segment(bv, bio, i) {
+                       if (!remaining)
+                               break;
+
+                       size = bv->bv_len;
+                       SUPBOUND(size, remaining);
+
+                       buffer = page_address(bv->bv_page) + bv->bv_offset;
+#ifdef FLOPPY_SANITY_CHECK
+               if (dma_buffer + size >
+                   floppy_track_buffer + (max_buffer_sectors << 10) ||
+                   dma_buffer < floppy_track_buffer){
+                       DPRINT("buffer overrun in copy buffer %d\n",
+                               (int) ((floppy_track_buffer - dma_buffer) >>9));
+                       printk("fsector_t=%d buffer_min=%d\n",
+                              fsector_t, buffer_min);
+                       printk("current_count_sectors=%ld\n",
+                              current_count_sectors);
+                       if (CT(COMMAND) == FD_READ)
+                               printk("read\n");
+                       if (CT(COMMAND) == FD_READ)
+                               printk("write\n");
+                       break;
+               }
+               if (((unsigned long)buffer) % 512)
+                       DPRINT("%p buffer not aligned\n", buffer);
+#endif
+                       if (CT(COMMAND) == FD_READ)
+                               memcpy(buffer, dma_buffer, size);
+                       else
+                               memcpy(dma_buffer, buffer, size);
+
+                       remaining -= size;
+                       dma_buffer += size;
+               }
+       }
+#ifdef FLOPPY_SANITY_CHECK
+       if (remaining){
+               if (remaining > 0)
+                       max_sector -= remaining >> 9;
+               DPRINT("weirdness: remaining %d\n", remaining>>9);
+       }
+#endif
+}
+
+#if 0
+static inline int check_dma_crossing(char *start, +                                 unsigned long length, char *message)
+{
+       if (CROSS_64KB(start, length)) {
+               printk("DMA xfer crosses 64KB boundary in %s %p-%p\n", +                     message, start, start+length);
+               return 1;
+       } else
+               return 0;
+}
+#endif
+
+/* work around a bug in pseudo DMA
+ * (on some FDCs) pseudo DMA does not stop when the CPU stops
+ * sending data.  Hence we need a different way to signal the
+ * transfer length:  We use SECT_PER_TRACK.  Unfortunately, this
+ * does not work with MT, hence we can only transfer one head at
+ * a time
+ */
+static void virtualdmabug_workaround(void)
+{
+       int hard_sectors, end_sector;
+
+       if(CT(COMMAND) == FD_WRITE) {
+               COMMAND &= ~0x80; /* switch off multiple track mode */
+
+               hard_sectors = raw_cmd->length >> (7 + SIZECODE);
+               end_sector = SECTOR + hard_sectors - 1;
+#ifdef FLOPPY_SANITY_CHECK
+               if(end_sector > SECT_PER_TRACK) {
+                       printk("too many sectors %d > %d\n",
+                              end_sector, SECT_PER_TRACK);
+                       return;
+               }
+#endif
+               SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points
+                                             * to end of transfer */
+       }
+}
+
+/*
+ * Formulate a read/write request.
+ * this routine decides where to load the data (directly to buffer, or to
+ * tmp floppy area), how much data to load (the size of the buffer, the whole
+ * track, or a single sector)
+ * All floppy_track_buffer handling goes in here. If we ever add track buffer
+ * allocation on the fly, it should be done here. No other part should need
+ * modification.
+ */
+
+static int make_raw_rw_request(void)
+{
+       int aligned_sector_t;
+       int max_sector, max_size, tracksize, ssize;
+
+       if(max_buffer_sectors == 0) {
+               printk("VFS: Block I/O scheduled on unopened device\n");
+               return 0;
+       }
+
+       set_fdc(DRIVE(current_req->rq_dev));
+
+       raw_cmd = &default_raw_cmd;
+       raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
+               FD_RAW_NEED_SEEK;
+       raw_cmd->cmd_count = NR_RW;
+       if
...

read more »