home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / armlinux / kernel_src / LINUX-1_001 / linux-1.3.35pl2.diff
Encoding:
Text File  |  1996-03-14  |  282.1 KB  |  10,134 lines

  1. diff -urN linux.store/linux/Makefile linux/Makefile
  2. --- linux.store/linux/Makefile    Sun Feb 11 13:47:34 1996
  3. +++ linux/Makefile    Mon Mar 11 21:10:39 1996
  4. @@ -137,7 +137,7 @@
  5.          $(LIBS) -o vmlinux
  6.      $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)\|\( A \)\|\( t L\)' | sort > System.map
  7.  
  8. -symlinks:
  9. +symlinks::
  10.      rm -f include/asm
  11.      ( cd include ; ln -sf asm-$(ARCH) asm)
  12.  
  13. diff -urN linux.store/linux/README.arm linux/README.arm
  14. --- linux.store/linux/README.arm    Thu Jan  1 01:00:00 1970
  15. +++ linux/README.arm    Tue Mar 12 23:47:01 1996
  16. @@ -0,0 +1,35 @@
  17. +ARM Linux 1.3.35
  18. +----------------
  19. +
  20. +In order to compile ARM Linux, you will need the cross-utilities
  21. +on ftp.ecs.soton.ac.uk in the /pub/armlinux/cross-compilers
  22. +subdirectory.
  23. +
  24. +To configure the kernel, edit the top-level makefile, replacing:
  25. +ARCH = i386 with ARCH = arm
  26. +
  27. +Then examine arch/arm/Makefile for sub-architecture options
  28. +(including processor and machine type), setting them as required.
  29. +
  30. +Do a make config, followed by a make dep, and finally a make all.
  31. +
  32. +Please send all patches, bug reports and code for the ARM Linux
  33. +project to rmk92@ecs.soton.ac.uk.  Patches will not be included
  34. +into future kernels unless they come to me (or the relevent
  35. +person concerned).
  36. +
  37. +Here is a list of people currently working on the project (If you
  38. +wish to be added to the list, please mail me):
  39. +
  40. +Name: Russell King
  41. +Mail: rmk92@ecs.soton.ac.uk
  42. +Desc: Origional developer of ARM Linux, A5000 code and project
  43. +      co-ordinator.
  44. +
  45. +Name: Dave Gilbert
  46. +Mail: gilbertd@cs.man.ac.uk
  47. +Desc: A3/4/5xx floppy and hard disk code maintainer.
  48. +
  49. +Name: Ian Jeffray
  50. +Mail: ian_jeffray@MENTORG.COM
  51. +Desc: A3/4/5xx serial and parrallel port code maintainer.
  52. diff -urN linux.store/linux/arch/arm/Makefile linux/arch/arm/Makefile
  53. --- linux.store/linux/arch/arm/Makefile    Sat Feb 24 13:08:03 1996
  54. +++ linux/arch/arm/Makefile    Wed Mar 13 22:55:58 1996
  55. @@ -10,38 +10,68 @@
  56.  # License.  See the file "COPYING" in the main directory of this archive
  57.  # for more details.
  58.  #
  59. -# Copyright (C) 1995 by Russell King
  60. +# Copyright (C) 1995, 1996 by Russell King
  61.  #
  62. -
  63. -#
  64. -# Set these to indicate how to link it..
  65. -# -qmagic (we need to remove the 32 byte header for bootup purposes)
  66. +# Since we are going multi-computer, I think that this ought to reflect it...
  67.  #
  68. +# THIS IS MY PATCHLEVEL:  PATCHLEVEL2
  69. +
  70. +# MACHINE can be: arc a5k rpc
  71. +# PROCESSOR can be: arm2 arm3 arm6
  72. +# Computer:    MACHINE:  PROCESSOR:
  73. +#  A3xx        arc      arm2
  74. +#  A4xx        arc      arm2
  75. +#  A5xx        arc      arm2
  76. +#  A5000    a5k      arm3
  77. +#  A4000    a5k      arm3
  78. +#  A3020    a5k      arm3 (ok)
  79.  
  80. -SUBARCH         = -m3
  81. +MACHINE         = a5k
  82. +PROCESSOR     = arm3
  83.  
  84.  CPP         = $(CC) -E $(SUBARCH)
  85. -CFLAGS        := $(CFLAGS:-fomit-frame-pointer=) $(SUBARCH)
  86. +HOSTCFLAGS    := $(CFLAGS:-fomit-frame-pointer=)
  87. +CFLAGS        := $(CFLAGS:-fomit-frame-pointer=) $(ARCHFLAGS)
  88.  LINKFLAGS     = -Ttext 0x01800000
  89.  ZLINKFLAGS     = -N -Ttext 0x01800000
  90. +GCCLIB        := `gcc --print-libgcc-file-name`
  91. +
  92. +# -------------------------- END OF USER CONFIGURATION ------------------------------
  93. +
  94. +ifeq ($(PROCESSOR),arm3)
  95. +ARCHFLAGS     = -m3
  96. +else
  97. +ifeq ($(PROCESSOR),arm2)
  98. +ARCHFLAGS     = -m2
  99. +else
  100. +ARCHFLAGS     =
  101. +endif
  102. +endif
  103. +
  104. +ifeq ($(MACHINE),a5k)
  105. +ARCHFLAGS    := $(ARCHFLAGS) -DCONFIG_ARCH_A5K
  106. +else
  107. +ifeq ($(MACHINE),arc)
  108. +ARCHFLAGS    := $(ARCHFLAGS) -DCONFIG_ARCH_ARC
  109. +endif
  110. +endif
  111.  
  112.  HEAD        := arch/arm/kernel/head.o
  113.  SUBDIRS        := arch/arm/drivers arch/arm/kernel arch/arm/mm arch/arm/lib $(SUBDIRS)
  114.  ARCHIVES    := arch/arm/kernel/kernel.o arch/arm/mm/mm.o arch/arm/lib/lib.o $(ARCHIVES)
  115. -LIBS        := $(LIBS) `gcc --print-libgcc-file-name`
  116. +LIBS        := $(LIBS) $(GCCLIB)
  117.  
  118. -DRIVERS := arch/arm/drivers/block/block.a arch/arm/drivers/char/char.a \
  119. -           arch/arm/drivers/net/net.a
  120. +DRIVERS        := arch/arm/drivers/block/block.a arch/arm/drivers/char/char.a \
  121. +               arch/arm/drivers/net/net.a
  122.  
  123.  ifdef CONFIG_SOUND
  124. -DRIVERS := $(DRIVERS) arch/arm/drivers/sound/sound.a
  125. +DRIVERS        := $(DRIVERS) arch/arm/drivers/sound/sound.a
  126.  endif
  127.  
  128.  ifdef CONFIG_SCSI
  129. -DRIVERS := $(DRIVERS) arch/arm/drivers/scsi/scsi.a
  130. +DRIVERS        := $(DRIVERS) arch/arm/drivers/scsi/scsi.a
  131.  endif
  132.  
  133. -
  134.  arch/arm/kernel: dummy
  135.      $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel
  136.  
  137. @@ -50,6 +80,10 @@
  138.  
  139.  MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
  140.  
  141. +symlinks::
  142. +    rm -f include/asm-arm/arch include/asm-arm/proc
  143. +    (cd include/asm-arm; ln -sf arch-$(MACHINE) arch; ln -sf proc-$(PROCESSOR) proc)
  144. +
  145.  install:
  146.      @$(MAKEBOOT) install
  147.  
  148. @@ -65,6 +99,7 @@
  149.      @$(MAKE) -C arch/$(ARCH)/drivers/char LINKCLEAN
  150.      @$(MAKE) -C arch/$(ARCH)/drivers/net LINKCLEAN
  151.      @$(MAKE) -C arch/$(ARCH)/drivers/scsi LINKCLEAN
  152. +    rm -f include/asm-arm/arch include/asm-arm/proc
  153.  
  154.  archdep:
  155.      @$(MAKEBOOT) dep
  156. diff -urN linux.store/linux/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
  157. --- linux.store/linux/arch/arm/boot/Makefile    Sun Feb 11 21:59:54 1996
  158. +++ linux/arch/arm/boot/Makefile    Mon Mar 11 20:46:17 1996
  159. @@ -1,11 +1,11 @@
  160.  #
  161. -# arch/i386/boot/Makefile
  162. +# arch/arm/boot/Makefile
  163.  #
  164.  # This file is subject to the terms and conditions of the GNU General Public
  165.  # License.  See the file "COPYING" in the main directory of this archive
  166.  # for more details.
  167.  #
  168. -# Copyright (C) 1994 by Linus Torvalds
  169. +# Copyright (C) 1995, 1996 Russell King
  170.  #
  171.  
  172.  Image:    $(CONFIGURE) tools/build $(TOPDIR)/vmlinux
  173. @@ -25,23 +25,10 @@
  174.      sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
  175.  
  176.  tools/build: tools/build.c
  177. -    $(HOSTCC) $(CFLAGS) -o $@ $< -I$(TOPDIR)/include
  178. +    $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include
  179.  
  180.  clean:
  181.      rm -f Image zImage tools/build
  182.      @$(MAKE) -C compressed clean
  183.  
  184.  dep:
  185. -
  186. -#zdisk: zImage
  187. -#    dd bs=8192 if=zImage of=/dev/fd0
  188. -
  189. -#zlilo: $(CONFIGURE) zImage
  190. -#    if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
  191. -#    if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
  192. -#    cat zImage > $(INSTALL_PATH)/vmlinuz
  193. -#    cp $(TOPDIR)/System.map $(INSTALL_PATH)/
  194. -#    if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
  195. -
  196. -#install: $(CONFIGURE) zImage
  197. -#    sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
  198. diff -urN linux.store/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
  199. --- linux.store/linux/arch/arm/boot/compressed/Makefile    Sun Mar  3 13:35:37 1996
  200. +++ linux/arch/arm/boot/compressed/Makefile    Mon Mar 11 20:58:20 1996
  201. @@ -7,6 +7,7 @@
  202.  CFLAGS = -O2 -DSTDC_HEADERS
  203.  LOADADDR = 0x01800000
  204.  RELADDR = 0x01960000
  205. +ARFLAGS = rcv
  206.  
  207.  SYSTEM = $(TOPDIR)/vmlinux
  208.  DECOMP_OBJS = inflate.o unzip.o misc.o ../../lib/ll_char_wr.o
  209. @@ -45,10 +46,10 @@
  210.  # rules for extracting & piggybacking the kernel
  211.  
  212.  xtract:     xtract.c
  213. -        $(HOSTCC) $(CFLAGS) -o xtract xtract.c
  214. +        $(HOSTCC) $(HOSTCFLAGS) -o xtract xtract.c
  215.  
  216.  piggyback:    piggyback.c
  217. -        $(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
  218. +        $(HOSTCC) $(HOSTCFLAGS) -o piggyback piggyback.c
  219.  
  220.  
  221.  clean:
  222. diff -urN linux.store/linux/arch/arm/boot/compressed/misc.c linux/arch/arm/boot/compressed/misc.c
  223. --- linux.store/linux/arch/arm/boot/compressed/misc.c    Sun Feb 11 09:32:12 1996
  224. +++ linux/arch/arm/boot/compressed/misc.c    Sun Mar 10 15:32:20 1996
  225. @@ -231,15 +231,15 @@
  226.  
  227.  static void puts(const char *s)
  228.  {
  229. -    extern void ll_char_write(char *, char, char, char, char);
  230. +    extern void ll_write_char(char *, unsigned long);
  231.      int x,y;
  232. -    char c;
  233. +    unsigned char c;
  234.      char *ptr;
  235.  
  236.      x = params->video_x;
  237.      y = params->video_y;
  238.  
  239. -    while ( ( c = *s++ ) != '\0' ) {
  240. +    while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
  241.          if ( c == '\n' ) {
  242.              x = 0;
  243.              if ( ++y >= video_num_lines ) {
  244. @@ -248,7 +248,7 @@
  245.              }
  246.          } else {
  247.              ptr = vidmem + (y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h;
  248. -            ll_char_write(ptr, c, white, 0, 0);
  249. +            ll_write_char (ptr, c|(white<<8));
  250.              if ( ++x >= video_num_columns ) {
  251.                  x = 0;
  252.                  if ( ++y >= video_num_lines ) {
  253. diff -urN linux.store/linux/arch/arm/config.in linux/arch/arm/config.in
  254. --- linux.store/linux/arch/arm/config.in    Sat Feb 24 21:32:58 1996
  255. +++ linux/arch/arm/config.in    Wed Mar 13 22:24:44 1996
  256. @@ -18,21 +18,14 @@
  257.  
  258.  mainmenu_option next_comment
  259.  comment 'General setup'
  260. -bool 'Compile for arm3' CONFIG_ARM3 y
  261. -if [ "$CONFIG_ARM3" = "n" ]; then
  262. -  bool 'Compile for arm610/710' CONFIG_ARM610 y
  263. -  if [ "$CONFIG_ARM610" = "n" ]; then
  264. -    bool 'Compile for StrongARM' CONFIG_ARMSTRONG y
  265. -  fi
  266. -else
  267. -  bool 'Page size as 32K' CONFIG_PAGE_32K y
  268. -  if [ "$CONFIG_PAGE_32K" = "n" ]; then
  269. -    bool 'Page size as 16K' CONFIG_PAGE_16K y
  270. -    if [ "$CONFIG_PAGE_16K" = "n" ]; then
  271. -      echo "Auto detected page size"
  272. -    fi
  273. -  fi
  274. -fi
  275. +# Other page sizes aren't supported yet...
  276. +#bool 'Page size as 32K' CONFIG_PAGE_32K y
  277. +#if [ "$CONFIG_PAGE_32K" = "n" ]; then
  278. +#  bool 'Page size as 16K' CONFIG_PAGE_16K y
  279. +#  if [ "$CONFIG_PAGE_16K" = "n" ]; then
  280. +#    echo "Auto detected page size"
  281. +#  fi
  282. +#fi
  283.  
  284.  comment 'Math emulation is provided by a run-time loadable module'
  285.  
  286. @@ -51,6 +44,9 @@
  287.  #  fi
  288.  fi
  289.  tristate 'MFM harddisk support' CONFIG_BLK_DEV_XD n
  290. +if [ "$CONFIG_BLK_DEV_XD" != "n" ]; then
  291. +  bool '  Use MFM with motherboard controller?' CONFIG_MFM_ONMAINBOARD y
  292. +fi
  293.  
  294.  bool 'Networking support' CONFIG_NET y
  295.  bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
  296. diff -urN linux.store/linux/arch/arm/drivers/block/Makefile linux/arch/arm/drivers/block/Makefile
  297. --- linux.store/linux/arch/arm/drivers/block/Makefile    Sat Feb 24 13:17:05 1996
  298. +++ linux/arch/arm/drivers/block/Makefile    Wed Mar 13 14:46:03 1996
  299. @@ -16,27 +16,37 @@
  300.  M_OBJS   :=
  301.  MOD_LIST_NAME := BLOCK_MODULES
  302.  
  303. -ifeq ($(CONFIG_BLK_DEV_FD),y)
  304. -L_OBJS += floppy.o
  305. -else
  306. -  ifeq ($(CONFIG_BLK_DEV_FD),m)
  307. -  M_OBJS += floppy.o
  308. -  endif
  309. +# Architecture dependencies
  310. +
  311. +ifeq ($(MACHINE),a5k)
  312. +  FLOPPY = floppy.o
  313.  endif
  314.  
  315. -ifeq ($(CONFIG_BLK_DEV_HD),y)
  316. -L_OBJS += hd.o
  317. +ifeq ($(MACHINE),arc)
  318. +  FLOPPY = fd1772.o
  319.  endif
  320.  
  321. -ifeq ($(CONFIG_BLK_DEV_IDE),y)
  322. -L_OBJS += ide.o
  323. +# Common dependencies
  324. +
  325. +ifdef FLOPPY
  326. +  ifeq ($(CONFIG_BLK_DEV_FD),y)
  327. +    L_OBJS += $(FLOPPY)
  328. +  else
  329. +    ifeq ($(CONFIG_BLK_DEV_FD),m)
  330. +      M_OBJS += $(FLOPPY)
  331. +    endif
  332. +  endif
  333. +endif
  334. +
  335. +ifeq ($(CONFIG_BLK_DEV_HD),y)
  336. +  L_OBJS += hd.o
  337.  endif
  338.  
  339. -ifeq ($(CONFIG_BLK_DEV_MFM),y)
  340. -L_OBJS += mfmhd.o
  341. +ifeq ($(CONFIG_BLK_DEV_XD),y)
  342. +  L_OBJS += mfmhd.o
  343.  else
  344. -  ifeq ($(CONFIG_BLK_DEV_MFM),m)
  345. -  M_OBJS += mfmhd_mod.o
  346. +  ifeq ($(CONFIG_BLK_DEV_XD),m)
  347. +    M_OBJS += mfmhd_mod.o
  348.    endif
  349.  endif
  350.  
  351. @@ -45,9 +55,9 @@
  352.  fastdep: links
  353.  
  354.  mfmhd_mod.o: mfmhd.o
  355. -    ld -r -o $@ mfmhd.o `gcc --print-libgcc-file-name`
  356. +    ld -r -o $@ mfmhd.o $(GCCLIB)
  357.  
  358. -LK = blk.h ll_rw_blk.c ramdisk.c README.fd README.hd
  359. +LK = blk.h ramdisk.c README.fd README.hd
  360.  
  361.  links:
  362.      -@for f in $(LK); do \
  363. diff -urN linux.store/linux/arch/arm/drivers/block/fd1772.c linux/arch/arm/drivers/block/fd1772.c
  364. --- linux.store/linux/arch/arm/drivers/block/fd1772.c    Thu Jan  1 01:00:00 1970
  365. +++ linux/arch/arm/drivers/block/fd1772.c    Mon Mar 11 23:26:30 1996
  366. @@ -0,0 +1,1448 @@
  367. +/*
  368. + *  linux/kernel/arch/arm/drivers/block/fd1772.c
  369. + *  Based on ataflop.c in the m68k Linux
  370. + *  Copyright (C) 1993  Greg Harp
  371. + *  Atari Support by Bjoern Brauel, Roman Hodek
  372. + *  Archimedes Support by Dave Gilbert (gilbertd@cs.man.ac.uk)
  373. + *
  374. + *  Big cleanup Sep 11..14 1994 Roman Hodek:
  375. + *   - Driver now works interrupt driven
  376. + *   - Support for two drives; should work, but I cannot test that :-(
  377. + *   - Reading is done in whole tracks and buffered to speed up things
  378. + *   - Disk change detection and drive deselecting after motor-off
  379. + *     similar to TOS
  380. + *   - Autodetection of disk format (DD/HD); untested yet, because I
  381. + *     don't have an HD drive :-(
  382. + *
  383. + *  Fixes Nov 13 1994 Martin Schaller:
  384. + *   - Autodetection works now
  385. + *   - Support for 5 1/4" disks
  386. + *   - Removed drive type (unknown on atari)
  387. + *   - Do seeks with 8 Mhz
  388. + *
  389. + *  Changes by Andreas Schwab:
  390. + *   - After errors in multiple read mode try again reading single sectors
  391. + *  (Feb 1995):
  392. + *   - Clean up error handling
  393. + *   - Set blk_size for proper size checking
  394. + *   - Initialize track register when testing presence of floppy
  395. + *   - Implement some ioctl's
  396. + *
  397. + *  Changes by Torsten Lang:
  398. + *   - When probing the floppies we should add the FDC1772CMDADD_H flag since
  399. + *     the FDC1772 will otherwise wait forever when no disk is inserted...
  400. + *
  401. + *  Things left to do:
  402. + *   - Formatting
  403. + *   - Maybe a better strategy for disk change detection (does anyone
  404. + *     know one?)
  405. + *   - There are some strange problems left: The strangest one is
  406. + *     that, at least on my TT (4+4MB), the first 2 Bytes of the last
  407. + *     page of the TT-Ram (!) change their contents (some bits get
  408. + *     set) while a floppy DMA is going on. But there are no accesses
  409. + *     to these memory locations from the kernel... (I tested that by
  410. + *     making the page read-only). I cannot explain what's going on...
  411. + *   - Sometimes the drive-change-detection stops to work. The
  412. + *     function is still called, but the WP bit always reads as 0...
  413. + *     Maybe a problem with the status reg mode or a timing problem.
  414. + *     Note 10/12/94: The change detection now seems to work reliably.
  415. + *     There is no proof, but I've seen no hang for a long time...
  416. + *
  417. + * ARCHIMEDES changes:
  418. + *     26/12/95 - Changed all names starting with FDC to FDC1772
  419. + *                Removed all references to clock speed of FDC - we're stuck with 8MHz
  420. + *                Modified disk_type structure to remove HD formats
  421. + *
  422. + *      7/ 1/96 - Wrote FIQ code, removed most remaining atariisms
  423. + *
  424. + *     13/ 1/96 - Well I think its read a single sector; but there is a problem
  425. + *                fd_rwsec_done which is called in FIQ mode starts another transfer
  426. + *                off (in fd_rwsec) while still in FIQ mode.  Because its still in
  427. + *                FIQ mode it can't service the DMA and loses data. So need to
  428. + *                heavily restructure.
  429. + *     14/ 1/96 - Found that the definitions of the register numbers of the
  430. + *                FDC were multiplied by 2 in the header for the 16bit words
  431. + *                of the atari so half the writes were going in the wrong place.
  432. + *                Also realised that the FIQ entry didn't make any attempt to
  433. + *                preserve registers or return correctly; now in assembler.
  434. + *
  435. + *     11/ 2/96 - Hmm - doesn't work on real machine.  Auto detect doesn't
  436. + *                and hacking that past seems to wait forever - check motor
  437. + *                being turned on.
  438. + *
  439. + *     17/ 2/96 - still having problems - forcing track to -1 when selecting
  440. + *                new drives seems to allow it to read first few sectors
  441. + *                but then we get solid hangs at apparently random places
  442. + *                which change depending what is happening.
  443. + *
  444. + *      9/ 3/96 - Fiddled a lot of stuff around to move to kernel 1.3.35
  445. + *                A lot of fiddling in DMA stuff. Having problems with it
  446. + *                constnatly thinking its timeing out. Ah - its timeout
  447. + *                was set to (6*HZ) rather than jiffies+(6*HZ).  Now giving
  448. + *                duff data!
  449. + */
  450. +
  451. +#include <linux/config.h>
  452. +#include <linux/sched.h>
  453. +#include <linux/fs.h>
  454. +#include <linux/fcntl.h>
  455. +#include <linux/kernel.h>
  456. +#include <linux/timer.h>
  457. +#include <linux/fd.h>
  458. +#include <linux/fd1772.h>
  459. +#include <linux/errno.h>
  460. +#include <linux/types.h>
  461. +#include <linux/delay.h>
  462. +#include <linux/mm.h>
  463. +
  464. +#include <asm/machdeps.h>
  465. +#include <asm/system.h>
  466. +#include <asm/bitops.h>
  467. +#include <asm/dma.h>
  468. +#include <asm/io.h>
  469. +#include <asm/irq.h>
  470. +#include <asm/irq-no.h>
  471. +#include <asm/pgtable.h>
  472. +
  473. +#define MAJOR_NR FLOPPY_MAJOR
  474. +#define FLOPPY_DMA 0
  475. +#include "blk.h"
  476. +
  477. +extern unsigned char *ioc;
  478. +
  479. +/* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
  480. + * little additional rework in this file). But I'm not yet sure if
  481. + * some other code depends on the number of floppies... (It is defined
  482. + * in a public header!)
  483. + */
  484. +#if 0
  485. +#undef FD_MAX_UNITS
  486. +#define    FD_MAX_UNITS    2
  487. +#endif
  488. +
  489. +/* Ditto worries for Arc - DAG */
  490. +#define FD_MAX_UNITS 4
  491. +#define TRACKBUFFER 0
  492. +/*#define DEBUG*/
  493. +
  494. +#ifdef DEBUG
  495. +#define DPRINT(a)    printk a
  496. +#else
  497. +#define DPRINT(a)
  498. +#endif
  499. +
  500. +/* Disk types: DD */
  501. +static struct atari_disk_type {
  502. +    const char    *name;
  503. +    unsigned    spt;        /* sectors per track */
  504. +    unsigned    blocks;        /* total number of blocks */
  505. +    unsigned     stretch;    /* track doubling ? */
  506. +} disk_type[] = {
  507. +    { "d360",  9, 720, 0},    /* 360kB diskette */
  508. +    { "D360",  9, 720, 1},    /* 360kb in 720kb drive */
  509. +    { "D720",  9,1440, 0},    /* 720kb diskette (DD) */    
  510. +    /*{ "D820", 10,1640, 0}, */    /* DD disk with 82 tracks/10 sectors - DAG - can't see how type detect can distinguish this from 720K until it reads block 4 by which time its too late! */
  511. +};
  512. +
  513. +#define    NUM_DISK_TYPES (sizeof(disk_type)/sizeof(*disk_type))
  514. +
  515. +/*
  516. + * Maximum disk size (in kilobytes). This default is used whenever the
  517. + * current disk size is unknown.
  518. + */
  519. +#define MAX_DISK_SIZE 720
  520. +
  521. +static int floppy_sizes[256];
  522. +static int floppy_blocksizes[256] = { 0, };
  523. +
  524. +/* current info on each unit */
  525. +static struct atari_floppy_struct {
  526. +    int connected;                /* !=0 : drive is connected */
  527. +    int autoprobe;                /* !=0 : do autoprobe        */
  528. +
  529. +    struct atari_disk_type    *disktype;    /* current type of disk */
  530. +
  531. +             int            track;        /* current head position or -1
  532. +                                         * if unknown */
  533. +    unsigned int            steprate;    /* steprate setting */
  534. +    unsigned int            wpstat;        /* current state of WP signal
  535. +                                         * (for disk change detection) */
  536. +} unit[FD_MAX_UNITS];
  537. +
  538. +/* DAG: On Arc we spin on a flag being cleared by fdc1772_comendhandler which
  539. +   is an assembler routine */
  540. +extern void fdc1772_comendhandler (void); /* Actually doens't have these parameters - see fd1772.S */
  541. +extern volatile int fdc1772_comendstatus;
  542. +extern volatile int fdc1772_fdc_int_done;
  543. +
  544. +#define FDC1772BASE (0x3210000>>2)
  545. +
  546. +#define FDC1772_READ(reg) inb(FDC1772BASE+(reg/2))
  547. +
  548. +/* DAG: You wouldn't be silly to ask why FDC1772_WRITE is a function rather
  549. +   than the #def below - well simple - the #def won't compile - and I
  550. +   don't understand why (__outwc not defined) */
  551. +/* NOTE: Reg is 0,2,4,6 as opposed to 0,1,2,3 or 0,4,8,12 to keep compatibility
  552. +   with the ST version of fd1772.h */
  553. +/*#define FDC1772_WRITE(reg,val) outw(val,(reg+FDC1772BASE)); */
  554. +void FDC1772_WRITE(int reg, unsigned char val) {
  555. +  if (reg==FDC1772REG_CMD) {
  556. +    DPRINT(("FDC1772_WRITE new command 0x%x\n",val));
  557. +    if (fdc1772_fdc_int_done) {
  558. +      DPRINT(("FDC1772_WRITE: Hmm fdc1772_fdc_int_done true - resetting\n"));
  559. +      fdc1772_fdc_int_done=0;
  560. +    };
  561. +  };
  562. +  outb(val,(reg/2)+FDC1772BASE);
  563. +};
  564. +
  565. +/* Buffering variables:
  566. + * First, there is a DMA buffer in ST-RAM that is used for floppy DMA
  567. + * operations. Second, a track buffer is used to cache a whole track
  568. + * of the disk to save read operations. These are two seperate buffers
  569. + * because that allows write operations without clearing the track buffer.
  570. + */
  571. +
  572. +#define    MAX_SECTORS    22
  573. +
  574. +unsigned char *DMABuffer;              /* buffer for writes */
  575. +/*static unsigned long PhysDMABuffer;*/   /* physical address */
  576. +/* DAG: On Arc we just go straight for the DMA buffer */
  577. +#define PhysDMABuffer DMABuffer
  578. +
  579. +/*
  580. + * These are global variables, as that's the easiest way to give
  581. + * information to interrupts. They are the data used for the current
  582. + * request.
  583. + */
  584. +static int SelectedDrive = 0;
  585. +static int ReqCmd, ReqBlock;
  586. +static int ReqSide, ReqTrack, ReqSector, ReqCnt;
  587. +static int HeadSettleFlag = 0;
  588. +static unsigned char *ReqData, *ReqBuffer;
  589. +static int MotorOn = 0, MotorOffTrys;
  590. +
  591. +/* Synchronization of FDC1772 access. */
  592. +static volatile int fdc_busy = 0;
  593. +static struct wait_queue *fdc_wait = NULL;
  594. +
  595. +
  596. +static unsigned int changed_floppies = 0xff, fake_change = 0;
  597. +#define    CHECK_CHANGE_DELAY    HZ/2
  598. +
  599. +#define    FD_MOTOR_OFF_DELAY    (3*HZ)
  600. +#define    FD_MOTOR_OFF_MAXTRY    (10*20)
  601. +
  602. +#define FLOPPY_TIMEOUT        (6*HZ)
  603. +#define RECALIBRATE_ERRORS    4    /* Atfer this many errors the drive
  604. +                                 * will be recalibrated. */
  605. +#define MAX_ERRORS            8    /* After this many errors the driver
  606. +                                 * will give up. */
  607. +
  608. +
  609. +#define    START_MOTOR_OFF_TIMER(delay)            \
  610. +    do {                                        \
  611. +        motor_off_timer.expires = (delay);        \
  612. +        add_timer( &motor_off_timer );            \
  613. +        MotorOffTrys = 0;                        \
  614. +    } while(0)
  615. +
  616. +#define    START_CHECK_CHANGE_TIMER(delay)                            \
  617. +    do {                                                        \
  618. +        timer_table[FLOPPY_TIMER].expires = jiffies + (delay);    \
  619. +        timer_active |= (1 << FLOPPY_TIMER);                    \
  620. +    } while(0)
  621. +
  622. +#define    START_TIMEOUT()                            \
  623. +    do {                                        \
  624. +        del_timer( &timeout_timer );            \
  625. +        timeout_timer.expires = jiffies + FLOPPY_TIMEOUT;    \
  626. +        add_timer( &timeout_timer );            \
  627. +    } while(0)
  628. +
  629. +#define    STOP_TIMEOUT()                            \
  630. +    do {                                        \
  631. +        del_timer( &timeout_timer );            \
  632. +    } while(0)
  633. +
  634. +#define ENABLE_IRQ() enable_irq(FIQ_FD1772+16);
  635. +
  636. +#define DISABLE_IRQ() disable_irq(FIQ_FD1772+16);
  637. +
  638. +/*
  639. + * The driver is trying to determine the correct media format
  640. + * while Probing is set. fd_rwsec_done() clears it after a
  641. + * successful access.
  642. + */
  643. +static int Probing = 0;
  644. +
  645. +/* This flag is set when a dummy seek is necesary to make the WP
  646. + * status bit accessible.
  647. + */
  648. +static int NeedSeek = 0;
  649. +
  650. +
  651. +/***************************** Prototypes *****************************/
  652. +
  653. +static void fd_select_side( int side );
  654. +static void fd_select_drive( int drive );
  655. +static void fd_deselect( void );
  656. +static void fd_motor_off_timer( unsigned long dummy );
  657. +static void check_change( void );
  658. +static __inline__ void set_head_settle_flag( void );
  659. +static __inline__ int get_head_settle_flag( void );
  660. +static void floppy_irqconsequencehandler (void);
  661. +static void fd_error( void );
  662. +static void do_fd_action( int drive );
  663. +static void fd_calibrate( void );
  664. +static void fd_calibrate_done( int status );
  665. +static void fd_seek( void );
  666. +static void fd_seek_done( int status );
  667. +static void fd_rwsec( void );
  668. +static void fd_rwsec_done( int status );
  669. +static void fd_times_out( unsigned long dummy );
  670. +static void finish_fdc( void );
  671. +static void finish_fdc_done( int dummy );
  672. +static void floppy_off( unsigned int nr);
  673. +static __inline__ void copy_buffer( void *from, void *to);
  674. +static void setup_req_params( int drive );
  675. +static void redo_fd_request( void);
  676. +static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
  677. +                     cmd, unsigned long param);
  678. +static void fd_probe( int drive );
  679. +static int fd_test_drive_present( int drive );
  680. +static void config_types( void );
  681. +static int floppy_open( struct inode *inode, struct file *filp );
  682. +static void floppy_release( struct inode * inode, struct file * filp );
  683. +
  684. +/************************* End of Prototypes **************************/
  685. +
  686. +static struct timer_list motor_off_timer =
  687. +                         { NULL, NULL, 0, 0, fd_motor_off_timer };
  688. +static struct timer_list timeout_timer =
  689. +                         { NULL, NULL, 0, 0, fd_times_out };
  690. +
  691. +/* DAG: Haven't got a clue what this is? */
  692. +int stdma_islocked(void) {
  693. +  return 0;
  694. +};
  695. +
  696. +/* Select the side to use. */
  697. +
  698. +static void fd_select_side( int side )
  699. +
  700. +{    unsigned long flags;
  701. +
  702. +    save_flags(flags);
  703. +    cli();
  704. +  
  705. +  oldlatch_aupdate(LATCHA_SIDESEL,side?0:LATCHA_SIDESEL);
  706. +    restore_flags(flags);
  707. +}
  708. +
  709. +
  710. +/* Select a drive, update the FDC1772's track register
  711. + */
  712. +
  713. +static void fd_select_drive( int drive )
  714. +
  715. +{
  716. +    unsigned long flags;
  717. +  
  718. +#ifdef DEBUG
  719. +  printk("fd_select_drive:%d\n",drive);
  720. +#endif
  721. +  /* Hmm - nowhere do we seem to turn the motor on - I'm going to do it here! */
  722. +  oldlatch_aupdate(LATCHA_MOTOR|LATCHA_INUSE,0);
  723. +
  724. +    if (drive == SelectedDrive)
  725. +      return;
  726. +
  727. +    save_flags(flags);
  728. +    cli();
  729. +  oldlatch_aupdate(LATCHA_FDSELALL,0xf-(1<<drive));
  730. +    restore_flags(flags);
  731. +
  732. +    /* restore track register to saved value */
  733. +    FDC1772_WRITE( FDC1772REG_TRACK, unit[drive].track );
  734. +    udelay(25);
  735. +
  736. +    SelectedDrive = drive;
  737. +}
  738. +
  739. +
  740. +/* Deselect both drives. */
  741. +
  742. +static void fd_deselect( void )
  743. +
  744. +{    unsigned long flags;
  745. +
  746. +  DPRINT(("fd_deselect\n"));
  747. +
  748. +    save_flags(flags);
  749. +    cli();
  750. +  oldlatch_aupdate(LATCHA_FDSELALL|LATCHA_MOTOR|LATCHA_INUSE,0xf|LATCHA_MOTOR|LATCHA_INUSE);
  751. +    restore_flags(flags);
  752. +
  753. +    SelectedDrive = -1;
  754. +}
  755. +
  756. +
  757. +/* This timer function deselects the drives when the FDC1772 switched the
  758. + * motor off. The deselection cannot happen earlier because the FDC1772
  759. + * counts the index signals, which arrive only if one drive is selected.
  760. + */
  761. +
  762. +static void fd_motor_off_timer( unsigned long dummy )
  763. +
  764. +{    unsigned long flags;
  765. +    unsigned char status;
  766. +    int              delay;
  767. +
  768. +    del_timer( &motor_off_timer );
  769. +    
  770. +    if (SelectedDrive < 0)
  771. +        /* no drive selected, needn't deselect anyone */
  772. +        return;
  773. +
  774. +    save_flags(flags);
  775. +    cli();
  776. +    
  777. +    if (fdc_busy) /* was stdma_islocked */
  778. +        goto retry;
  779. +
  780. +    status = FDC1772_READ( FDC1772REG_STATUS );
  781. +
  782. +    if (!(status & 0x80)) {
  783. +        /* motor already turned off by FDC1772 -> deselect drives */
  784. +        fd_deselect();
  785. +        restore_flags(flags);
  786. +        MotorOn = 0;
  787. +        return;
  788. +   }
  789. +    /* not yet off, try again */
  790. +
  791. +  retry:
  792. +  restore_flags(flags);
  793. +    /* Test again later; if tested too often, it seems there is no disk
  794. +     * in the drive and the FDC1772 will leave the motor on forever (or,
  795. +     * at least until a disk is inserted). So we'll test only twice
  796. +     * per second from then on...
  797. +     */
  798. +    delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ?
  799. +                (++MotorOffTrys, HZ/20) : HZ/2;
  800. +    START_MOTOR_OFF_TIMER( delay );
  801. +}
  802. +
  803. +
  804. +/* This function is repeatedly called to detect disk changes (as good
  805. + * as possible) and keep track of the current state of the write protection.
  806. + */
  807. +
  808. +static void check_change( void )
  809. +
  810. +{    static int    drive = 0;
  811. +
  812. +    unsigned long flags;
  813. +    int              stat;
  814. +
  815. +  if (fdc_busy) return; /* Don't start poking about if the fdc is busy */
  816. +
  817. +  return; /* lets just forget it for the mo DAG */
  818. +
  819. +    if (++drive > 1 || !unit[drive].connected)
  820. +        drive = 0;
  821. +
  822. +    save_flags(flags);
  823. +    cli();
  824. +
  825. +    if (!stdma_islocked()) {
  826. +    /* DAG: What the heck does this do??? */
  827. +        /*sound_ym.rd_data_reg_sel = 14;
  828. +        old_porta = sound_ym.rd_data_reg_sel;
  829. +        sound_ym.wd_data = (old_porta | DSKDRVNONE) &
  830. +                           ~(drive == 0 ? DSKDRV0 : DSKDRV1); */
  831. +        stat = !!(FDC1772_READ( FDC1772REG_STATUS ) & FDC1772STAT_WPROT);
  832. +/*        sound_ym.wd_data = old_porta; */
  833. +
  834. +        if (stat != unit[drive].wpstat) {
  835. +            DPRINT(( "wpstat[%d] = %d\n", drive, stat ));
  836. +            unit[drive].wpstat = stat;
  837. +            set_bit (drive, &changed_floppies);
  838. +        }
  839. +    }
  840. +    restore_flags(flags);
  841. +
  842. +    START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
  843. +}
  844. +
  845. +/* Handling of the Head Settling Flag: This flag should be set after each
  846. + * seek operation, because we dont't use seeks with verify.
  847. + */
  848. +
  849. +static __inline__ void set_head_settle_flag( void )
  850. +
  851. +{
  852. +    HeadSettleFlag = FDC1772CMDADD_E;
  853. +}
  854. +
  855. +static __inline__ int get_head_settle_flag( void )
  856. +
  857. +{
  858. +    int    tmp = HeadSettleFlag;
  859. +    HeadSettleFlag = 0;
  860. +    return( tmp );
  861. +}
  862. +
  863. +  
  864. +  
  865. +
  866. +/* General Interrupt Handling */
  867. +
  868. +static void (*FloppyIRQHandler)( int status ) = NULL;
  869. +
  870. +static void floppy_irqconsequencehandler (void)
  871. +
  872. +{
  873. +    unsigned char status;
  874. +    void (*handler)( int );
  875. +
  876. +  fdc1772_fdc_int_done=0;
  877. +
  878. +    handler = FloppyIRQHandler;
  879. +    FloppyIRQHandler = NULL;
  880. +
  881. +    if (handler) {
  882. +        nop();
  883. +        status = (unsigned char)fdc1772_comendstatus;
  884. +        DPRINT(("FDC1772 irq, status = %02x handler = %08lx\n",(unsigned int)status,(unsigned long)handler));
  885. +        handler( status );
  886. +    }
  887. +    else {
  888. +        DPRINT(("FDC1772 irq, no handler status=%02x\n",fdc1772_comendstatus));
  889. +    }
  890. +  DPRINT(("FDC1772 irq: end of floppy_irq\n"));
  891. +}
  892. +
  893. +
  894. +/* Error handling: If some error happened, retry some times, then
  895. + * recalibrate, then try again, and fail after MAX_ERRORS.
  896. + */
  897. +
  898. +static void fd_error( void )
  899. +
  900. +{
  901. +  DPRINT(("FDC1772: fd_error\n"));
  902. +  /*panic("fd1772: fd_error");*/ /* DAG tmp */
  903. +    if (!CURRENT) return;
  904. +    CURRENT->errors++;
  905. +    if (CURRENT->errors >= MAX_ERRORS) {
  906. +        printk( "fd%d: too many errors.\n", SelectedDrive );
  907. +        end_request( 0 );
  908. +    }
  909. +    else if (CURRENT->errors == RECALIBRATE_ERRORS) {
  910. +        printk( "fd%d: recalibrating\n", SelectedDrive );
  911. +        if (SelectedDrive != -1)
  912. +            unit[SelectedDrive].track = -1;
  913. +    }
  914. +    redo_fd_request();
  915. +}
  916. +
  917. +
  918. +
  919. +#define    SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
  920. +
  921. +
  922. +/* do_fd_action() is the general procedure for a fd request: All
  923. + * required parameter settings (drive select, side select, track
  924. + * position) are checked and set if needed. For each of these
  925. + * parameters and the actual reading or writing exist two functions:
  926. + * one that starts the setting (or skips it if possible) and one
  927. + * callback for the "done" interrupt. Each done func calls the next
  928. + * set function to propagate the request down to fd_rwsec_done().
  929. + */
  930. +
  931. +static void do_fd_action( int drive )
  932. +
  933. +{
  934. +    DPRINT(("do_fd_action unit[drive].track=%d\n",unit[drive].track));
  935. +
  936. +    if (SelectedDrive != drive) {
  937. +    unit[drive].track=-1; 
  938. +        fd_select_drive( drive );
  939. +  };
  940. +    
  941. +
  942. +    if (unit[drive].track == -1)
  943. +        fd_calibrate();
  944. +    else if (unit[drive].track != ReqTrack << unit[drive].disktype->stretch)
  945. +        fd_seek();
  946. +    else
  947. +        fd_rwsec();
  948. +}
  949. +
  950. +
  951. +/* Seek to track 0 if the current track is unknown */
  952. +
  953. +static void fd_calibrate( void )
  954. +
  955. +{
  956. +    DPRINT(("fd_calibrate\n"));
  957. +    if (unit[SelectedDrive].track >= 0) {
  958. +        fd_calibrate_done( 0 );
  959. +        return;
  960. +    }
  961. +
  962. +    DPRINT(("fd_calibrate (after track compare)\n"));
  963. +    SET_IRQ_HANDLER( fd_calibrate_done );
  964. +    /* we can't verify, since the speed may be incorrect */
  965. +    FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_RESTORE | unit[SelectedDrive].steprate );
  966. +
  967. +    NeedSeek = 1;
  968. +    MotorOn = 1;
  969. +    START_TIMEOUT();
  970. +    /* wait for IRQ */
  971. +}
  972. +
  973. +
  974. +static void fd_calibrate_done( int status )
  975. +
  976. +{
  977. +    DPRINT(("fd_calibrate_done()\n"));
  978. +    STOP_TIMEOUT();
  979. +    
  980. +    /* set the correct speed now */
  981. +    if (status & FDC1772STAT_RECNF) {
  982. +        printk( "fd%d: restore failed\n", SelectedDrive );
  983. +        fd_error();
  984. +    }
  985. +    else {
  986. +        unit[SelectedDrive].track = 0;
  987. +        fd_seek();
  988. +    }
  989. +}
  990. +  
  991. +  
  992. +/* Seek the drive to the requested track. The drive must have been
  993. + * calibrated at some point before this.
  994. + */
  995. +  
  996. +static void fd_seek( void )
  997. +  
  998. +{
  999. +    DPRINT(("fd_seek() to track %d (unit[SelectedDrive].track=%d)\n",ReqTrack,
  1000. +    unit[SelectedDrive].track));
  1001. +    if (unit[SelectedDrive].track == ReqTrack << 
  1002. +        unit[SelectedDrive].disktype->stretch) {
  1003. +        fd_seek_done( 0 );
  1004. +        return;
  1005. +    }
  1006. +
  1007. +    FDC1772_WRITE( FDC1772REG_DATA, ReqTrack << 
  1008. +        unit[SelectedDrive].disktype->stretch);
  1009. +    udelay(25);
  1010. +    SET_IRQ_HANDLER( fd_seek_done );
  1011. +    FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_SEEK | unit[SelectedDrive].steprate );
  1012. +
  1013. +    MotorOn = 1;
  1014. +    set_head_settle_flag();
  1015. +    START_TIMEOUT();
  1016. +    /* wait for IRQ */
  1017. +}
  1018. +
  1019. +
  1020. +static void fd_seek_done( int status )
  1021. +  
  1022. +{
  1023. +    DPRINT(("fd_seek_done()\n"));
  1024. +    STOP_TIMEOUT();
  1025. +    
  1026. +    /* set the correct speed */
  1027. +    if (status & FDC1772STAT_RECNF) {
  1028. +        printk( "fd%d: seek error (to track %d)\n",
  1029. +                SelectedDrive, ReqTrack );
  1030. +        /* we don't know exactly which track we are on now! */
  1031. +        unit[SelectedDrive].track = -1;
  1032. +        fd_error();
  1033. +    }
  1034. +    else {
  1035. +        unit[SelectedDrive].track = ReqTrack << 
  1036. +            unit[SelectedDrive].disktype->stretch;
  1037. +        NeedSeek = 0;
  1038. +        fd_rwsec();
  1039. +    }
  1040. +}
  1041. +
  1042. +
  1043. +/* This does the actual reading/writing after positioning the head
  1044. + * over the correct track.
  1045. + */
  1046. +
  1047. +static void fd_rwsec( void )
  1048. +    
  1049. +{
  1050. +    unsigned long paddr, flags;
  1051. +    unsigned int  rwflag, old_motoron;
  1052. +    unsigned int track;
  1053. +    
  1054. +    DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n",ReqSector, ReqCmd == WRITE ? 'w' : 'r' ));
  1055. +    if (ReqCmd == WRITE) {
  1056. +        /*cache_push( (unsigned long)ReqData, 512 );*/
  1057. +        paddr = (unsigned long)ReqData;
  1058. +        rwflag = 0x100;
  1059. +    }
  1060. +    else {
  1061. +        paddr = (unsigned long)PhysDMABuffer;
  1062. +        rwflag = 0;
  1063. +    }
  1064. +
  1065. +  DPRINT(("fd_rwsec() before sidesel rwflag=%d sec=%d trk=%d\n",rwflag,
  1066. +          ReqSector,FDC1772_READ( FDC1772REG_TRACK)));
  1067. +    fd_select_side( ReqSide );
  1068. +  
  1069. +  /*DPRINT(("fd_rwsec() before start sector \n")); */
  1070. +    /* Start sector of this operation */
  1071. +    FDC1772_WRITE( FDC1772REG_SECTOR, ReqSector );
  1072. +    /* Cheat for track if stretch != 0 */
  1073. +    if (unit[SelectedDrive].disktype->stretch) {
  1074. +        track = FDC1772_READ( FDC1772REG_TRACK);
  1075. +        FDC1772_WRITE( FDC1772REG_TRACK, track >> 
  1076. +            unit[SelectedDrive].disktype->stretch);
  1077. +    }
  1078. +    udelay(25);
  1079. +  
  1080. +  DPRINT(("fd_rwsec() before setup DMA \n"));
  1081. +    /* Setup DMA - Heavily modified by DAG */
  1082. +    save_flags(flags);  
  1083. +    cliIF();
  1084. +  disable_dma(FLOPPY_DMA);
  1085. +  set_dma_mode(FLOPPY_DMA,rwflag?DMA_MODE_WRITE:DMA_MODE_READ);
  1086. +  set_dma_addr(FLOPPY_DMA,(long)paddr); /* DAG - changed from Atari specific */
  1087. +  set_dma_count(FLOPPY_DMA,512); /* Block/sector size - going to have to change */
  1088. +    SET_IRQ_HANDLER( fd_rwsec_done );
  1089. +    /* Turn on dma int */
  1090. +  enable_dma(FLOPPY_DMA);
  1091. +    restore_flags(flags);
  1092. +  /* Now give it something to do */
  1093. +  FDC1772_WRITE(FDC1772REG_CMD,(rwflag?(FDC1772CMD_WRSEC | FDC1772CMDADD_P):FDC1772CMD_RDSEC));
  1094. +  
  1095. +  DPRINT(("fd_rwsec() after DMA setup flags=0x%08x\n",flags));
  1096. +  /*sti();*/ /* DAG - Hmm */
  1097. +  /* Hmm - should do something DAG */
  1098. +    old_motoron = MotorOn;
  1099. +    MotorOn = 1;
  1100. +    NeedSeek = 1;
  1101. +    /* wait for interrupt */
  1102. +
  1103. +  /*DPRINT(("fd_rwsec() before START_TIMEOUT \n"));*/
  1104. +    START_TIMEOUT();
  1105. +  /*DPRINT(("fd_rwsec() after START_TIMEOUT \n")); */
  1106. +}
  1107. +
  1108. +    
  1109. +static void fd_rwsec_done( int status )
  1110. +  
  1111. +{
  1112. +    unsigned int track;
  1113. +
  1114. +    DPRINT(("fd_rwsec_done() status=%d\n",status));
  1115. +
  1116. +    /* Correct the track if stretch != 0 */
  1117. +    if (unit[SelectedDrive].disktype->stretch) {
  1118. +        track = FDC1772_READ( FDC1772REG_TRACK);
  1119. +        FDC1772_WRITE( FDC1772REG_TRACK, track << 
  1120. +            unit[SelectedDrive].disktype->stretch);
  1121. +    }
  1122. +
  1123. +    if (ReqCmd == WRITE && (status & FDC1772STAT_WPROT)) {
  1124. +        printk( "fd%d: is write protected\n", SelectedDrive );
  1125. +        goto err_end;
  1126. +    }    
  1127. +    if ((status & FDC1772STAT_RECNF)
  1128. +       ) {
  1129. +        if (Probing) {
  1130. +            if (unit[SelectedDrive].disktype > disk_type) {
  1131. +                /* try another disk type */
  1132. +                unit[SelectedDrive].disktype--;
  1133. +                floppy_sizes[SelectedDrive]
  1134. +                  = unit[SelectedDrive].disktype->blocks >> 1;
  1135. +            }
  1136. +            else
  1137. +                Probing=0;
  1138. +        } else {    
  1139. +/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
  1140. +            if (unit[SelectedDrive].autoprobe) {
  1141. +                unit[SelectedDrive].disktype = disk_type + NUM_DISK_TYPES-1;
  1142. +                floppy_sizes[SelectedDrive]
  1143. +                  = unit[SelectedDrive].disktype->blocks >> 1;
  1144. +                Probing = 1;
  1145. +            }
  1146. +        }
  1147. +        if (Probing) {
  1148. +            setup_req_params( SelectedDrive );
  1149. +            do_fd_action( SelectedDrive );
  1150. +            return;
  1151. +        }
  1152. +
  1153. +        printk( "fd%d: sector %d not found (side %d, track %d)\n",
  1154. +               SelectedDrive, FDC1772_READ (FDC1772REG_SECTOR), ReqSide, ReqTrack );
  1155. +        goto err_end;
  1156. +    }
  1157. +    if (status & FDC1772STAT_CRC) {
  1158. +        printk( "fd%d: CRC error (side %d, track %d, sector %d)\n",
  1159. +               SelectedDrive, ReqSide, ReqTrack, FDC1772_READ (FDC1772REG_SECTOR) );
  1160. +        goto err_end;
  1161. +    }
  1162. +    if (status & FDC1772STAT_LOST) {
  1163. +        printk( "fd%d: lost data (side %d, track %d, sector %d)\n",
  1164. +               SelectedDrive, ReqSide, ReqTrack, FDC1772_READ (FDC1772REG_SECTOR) );
  1165. +        goto err_end;
  1166. +    }
  1167. +
  1168. +    Probing = 0;
  1169. +    
  1170. +    if (ReqCmd == READ) {
  1171. +        /*cache_clear( PhysDMABuffer, 512 );*/
  1172. +        copy_buffer( DMABuffer, ReqData );
  1173. +    }
  1174. +  
  1175. +    if (++ReqCnt < CURRENT->current_nr_sectors) {
  1176. +        /* read next sector */
  1177. +        setup_req_params( SelectedDrive );
  1178. +        do_fd_action( SelectedDrive );
  1179. +    }
  1180. +    else {
  1181. +        /* all sectors finished */
  1182. +        CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
  1183. +        CURRENT->sector += CURRENT->current_nr_sectors;
  1184. +        end_request( 1 );
  1185. +        redo_fd_request();
  1186. +    }
  1187. +    return;
  1188. +  
  1189. +  err_end:
  1190. +    fd_error();
  1191. +}
  1192. +
  1193. +
  1194. +static void fd_times_out( unsigned long dummy )
  1195. +
  1196. +{
  1197. +    SET_IRQ_HANDLER( NULL );
  1198. +    /* If the timeout occured while the readtrack_check timer was
  1199. +     * active, we need to cancel it, else bad things will happen */
  1200. +    /* del_timer( &readtrack_timer ); DAG: Only seems to be used with the TACKBUFFER */
  1201. +    FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI );
  1202. +    udelay( 25 );
  1203. +    
  1204. +    printk( "floppy timeout\n" );
  1205. +    fd_error();
  1206. +}
  1207. +
  1208. +
  1209. +/* The (noop) seek operation here is needed to make the WP bit in the
  1210. + * FDC1772 status register accessible for check_change. If the last disk
  1211. + * operation would have been a RDSEC, this bit would always read as 0
  1212. + * no matter what :-( To save time, the seek goes to the track we're
  1213. + * already on.
  1214. + */
  1215. +
  1216. +static void finish_fdc( void )
  1217. +
  1218. +{
  1219. +  if (!NeedSeek) {
  1220. +      finish_fdc_done( 0 );
  1221. +  }
  1222. +  else {
  1223. +        DPRINT(("finish_fdc: dummy seek started\n"));
  1224. +        FDC1772_WRITE (FDC1772REG_DATA, unit[SelectedDrive].track);
  1225. +        SET_IRQ_HANDLER( finish_fdc_done );
  1226. +        FDC1772_WRITE (FDC1772REG_CMD, FDC1772CMD_SEEK);
  1227. +        MotorOn = 1;
  1228. +        START_TIMEOUT();
  1229. +      /* we must wait for the IRQ here, because the ST-DMA is
  1230. +       * released immediatly afterwards and the interrupt may be
  1231. +       * delivered to the wrong driver.
  1232. +       */
  1233. +      }
  1234. +}
  1235. +
  1236. +
  1237. +static void finish_fdc_done( int dummy )
  1238. +
  1239. +{
  1240. +    unsigned long flags;
  1241. +
  1242. +    DPRINT(("finish_fdc_done entered\n"));
  1243. +    STOP_TIMEOUT();
  1244. +    NeedSeek = 0;
  1245. +
  1246. +    if ((timer_active & (1 << FLOPPY_TIMER)) &&
  1247. +        timer_table[FLOPPY_TIMER].expires < jiffies + 5)
  1248. +        /* If the check for a disk change is done too early after this
  1249. +         * last seek command, the WP bit still reads wrong :-((
  1250. +         */
  1251. +        timer_table[FLOPPY_TIMER].expires = jiffies + 5;
  1252. +    else {
  1253. +    /*    START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
  1254. +  };
  1255. +    del_timer( &motor_off_timer );
  1256. +    START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
  1257. +
  1258. +    save_flags(flags);
  1259. +    cli();
  1260. +    /* stdma_release(); - not sure if I should do something DAG  */
  1261. +    fdc_busy = 0;
  1262. +    wake_up( &fdc_wait );
  1263. +    restore_flags(flags);
  1264. +
  1265. +    DPRINT(("finish_fdc() finished\n"));
  1266. +}
  1267. +
  1268. +
  1269. +/* Prevent "aliased" accesses. */
  1270. +static fd_ref[4] = { 0,0,0,0 };
  1271. +static fd_device[4] = { 0,0,0,0 };
  1272. +
  1273. +/*
  1274. + * Current device number. Taken either from the block header or from the
  1275. + * format request descriptor.
  1276. + */
  1277. +#define CURRENT_DEVICE (CURRENT->rq_dev)
  1278. +
  1279. +/* Current error count. */
  1280. +#define CURRENT_ERRORS (CURRENT->errors)
  1281. +
  1282. +
  1283. +/* dummy for blk.h */
  1284. +static void floppy_off( unsigned int nr) {}
  1285. +
  1286. +
  1287. +/* The detection of disk changes is a dark chapter in Atari history :-(
  1288. + * Because the "Drive ready" signal isn't present in the Atari
  1289. + * hardware, one has to rely on the "Write Protect". This works fine,
  1290. + * as long as no write protected disks are used. TOS solves this
  1291. + * problem by introducing tri-state logic ("maybe changed") and
  1292. + * looking at the serial number in block 0. This isn't possible for
  1293. + * Linux, since the floppy driver can't make assumptions about the
  1294. + * filesystem used on the disk and thus the contents of block 0. I've
  1295. + * choosen the method to always say "The disk was changed" if it is
  1296. + * unsure whether it was. This implies that every open or mount
  1297. + * invalidates the disk buffers if you work with write protected
  1298. + * disks. But at least this is better than working with incorrect data
  1299. + * due to unrecognised disk changes.
  1300. + */
  1301. +
  1302. +static int check_floppy_change (dev_t dev)
  1303. +
  1304. +{    unsigned int drive = (dev & 0x03);
  1305. +
  1306. +    if (MAJOR(dev) != MAJOR_NR) {
  1307. +        printk("floppy_changed: not a floppy\n");
  1308. +        return 0;
  1309. +    }
  1310. +    
  1311. +    if (test_bit (drive, &fake_change)) {
  1312. +        /* simulated change (e.g. after formatting) */
  1313. +        return 1;
  1314. +    }
  1315. +    if (test_bit (drive, &changed_floppies)) {
  1316. +        /* surely changed (the WP signal changed at least once) */
  1317. +        return 1;
  1318. +    }
  1319. +    if (unit[drive].wpstat) {
  1320. +        /* WP is on -> could be changed: to be sure, buffers should be
  1321. +         * invalidated...
  1322. +         */
  1323. +        return 1;
  1324. +    }
  1325. +
  1326. +    return 0;
  1327. +}
  1328. +
  1329. +static int floppy_revalidate (dev_t dev)
  1330. +{
  1331. +  int drive = dev & 3;
  1332. +
  1333. +  if (test_bit (drive, &changed_floppies) || test_bit (drive, &fake_change)
  1334. +      || unit[drive].disktype == 0)
  1335. +    {
  1336. +      clear_bit (drive, &fake_change);
  1337. +      clear_bit (drive, &changed_floppies);
  1338. +      unit[drive].disktype = 0;
  1339. +    }
  1340. +  return 0;
  1341. +}
  1342. +
  1343. +static __inline__ void copy_buffer(void *from, void *to)
  1344. +
  1345. +{    ulong    *p1 = (ulong *)from, *p2 = (ulong *)to;
  1346. +    int        cnt;
  1347. +
  1348. +    for( cnt = 512/4; cnt; cnt-- )
  1349. +        *p2++ = *p1++;
  1350. +}
  1351. +
  1352. +
  1353. +/* This sets up the global variables describing the current request. */
  1354. +
  1355. +static void setup_req_params( int drive )
  1356. +
  1357. +{    int block = ReqBlock + ReqCnt;
  1358. +
  1359. +    ReqTrack = block / unit[drive].disktype->spt;
  1360. +    ReqSector = block - ReqTrack * unit[drive].disktype->spt + 1;
  1361. +    ReqSide = ReqTrack & 1;
  1362. +    ReqTrack >>= 1;
  1363. +    ReqData = ReqBuffer + 512 * ReqCnt;
  1364. +
  1365. +    DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide,
  1366. +            ReqTrack, ReqSector, (unsigned long)ReqData ));
  1367. +}
  1368. +
  1369. +
  1370. +static void redo_fd_request(void)
  1371. +
  1372. +{
  1373. +    int device, drive, type;
  1374. +    struct atari_floppy_struct *floppy;
  1375. +  
  1376. +    DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->rq_dev=%04x CURRENT->sector=%ld\n",
  1377. +        (unsigned long)CURRENT, CURRENT ? CURRENT->rq_dev : 0,
  1378. +        CURRENT ? CURRENT->sector : 0 ));
  1379. +
  1380. +    if (CURRENT && CURRENT->rq_dev < 0)
  1381. +        goto the_end;
  1382. +
  1383. +repeat:
  1384. +    
  1385. +    if (!CURRENT)
  1386. +        goto the_end;
  1387. +
  1388. +    if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
  1389. +        panic(DEVICE_NAME ": request list destroyed");
  1390. +
  1391. +    if (CURRENT->bh) {
  1392. +        if (!CURRENT->bh->b_lock)
  1393. +            panic(DEVICE_NAME ": block not locked");
  1394. +    }
  1395. +
  1396. +    device = MINOR(CURRENT_DEVICE);
  1397. +    drive = device & 3;
  1398. +    type = device >> 2;
  1399. +    floppy = &unit[drive];
  1400. +    
  1401. +    if (!floppy->connected) {
  1402. +        /* drive not connected */
  1403. +        printk( "Unknown Device: fd%d\n", drive );
  1404. +        end_request(0);
  1405. +        goto repeat;
  1406. +    }
  1407. +        
  1408. +    if (type == 0) {
  1409. +        if (!floppy->disktype) {
  1410. +            Probing = 1;
  1411. +            floppy->disktype  = disk_type + NUM_DISK_TYPES-1;
  1412. +            floppy_sizes[drive] = floppy->disktype->blocks >> 1;
  1413. +            floppy->autoprobe = 1;
  1414. +        }
  1415. +    } 
  1416. +    else {
  1417. +        /* user supplied disk type */
  1418. +        --type;
  1419. +        if (type >= NUM_DISK_TYPES) {
  1420. +            printk( "fd%d: invalid disk format", drive );
  1421. +            end_request( 0 );
  1422. +            goto repeat;
  1423. +        }
  1424. +        floppy->disktype = &disk_type[type];
  1425. +        floppy_sizes[drive] = disk_type[type].blocks >> 1;
  1426. +        floppy->autoprobe = 0;
  1427. +    }
  1428. +    
  1429. +    if (CURRENT->sector + 1 > floppy->disktype->blocks) {
  1430. +            end_request(0);
  1431. +            goto repeat;
  1432. +        }
  1433. +
  1434. +    /* stop deselect timer */
  1435. +    del_timer( &motor_off_timer );
  1436. +        
  1437. +    ReqCnt = 0;
  1438. +    ReqCmd = CURRENT->cmd;
  1439. +    ReqBlock = CURRENT->sector;
  1440. +    ReqBuffer = CURRENT->buffer;
  1441. +    setup_req_params( drive );
  1442. +    do_fd_action( drive );
  1443. +
  1444. +    return;
  1445. +
  1446. +  the_end:
  1447. +    finish_fdc();
  1448. +}
  1449. +
  1450. +
  1451. +void do_fd_request(void)
  1452. +
  1453. +{     unsigned long flags;
  1454. +
  1455. +    DPRINT(("do_fd_request for pid %d\n",current->pid));
  1456. +  if (fdc_busy) panic("do_fd_request while already busy\n");
  1457. +    save_flags(flags);
  1458. +    cli();
  1459. +    while( fdc_busy ) sleep_on( &fdc_wait );
  1460. +    fdc_busy = 1;
  1461. +    /*stdma_lock( floppy_irq, 0 ); Hmm DAG */
  1462. +    ENABLE_IRQ();
  1463. +    restore_flags(flags);
  1464. +
  1465. +  fdc1772_fdc_int_done=0;
  1466. +
  1467. +    redo_fd_request();
  1468. +
  1469. +  save_flags(flags);
  1470. +  sti();
  1471. +  while (fdc_busy) {
  1472. +    /*int stat=FDC1772_READ( FDC1772REG_STATUS );
  1473. +    DPRINT(("do_fd_request: busy process loop start %x %x %x %x\n",ioc[0x30],ioc[0x34],ioc[0x38],stat)); */
  1474. +    if (fdc1772_fdc_int_done) floppy_irqconsequencehandler();
  1475. +    /*DPRINT(("do_fd_request: busy process loop end\n"));  */
  1476. +  };
  1477. +  DPRINT(("do_fd_request: end\n"));
  1478. +  restore_flags(flags);
  1479. +}
  1480. +
  1481. +
  1482. +static int
  1483. +invalidate_drive (int rdev)
  1484. +{
  1485. +  /* invalidate the buffer track to force a reread */
  1486. +  set_bit (rdev & 3, &fake_change);
  1487. +  check_disk_change (rdev);
  1488. +  return 0;
  1489. +}
  1490. +
  1491. +static int fd_ioctl(struct inode *inode, struct file *filp,
  1492. +                    unsigned int cmd, unsigned long param)
  1493. +{
  1494. +#define IOCTL_MODE_BIT 8
  1495. +#define OPEN_WRITE_BIT 16
  1496. +#define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
  1497. +
  1498. +  int drive, device;
  1499. +
  1500. +  device = inode->i_rdev;
  1501. +  switch (cmd)
  1502. +    {
  1503. +      RO_IOCTLS (inode->i_rdev, param);
  1504. +    }
  1505. +  drive = MINOR (device);
  1506. +  if (!IOCTL_ALLOWED)
  1507. +    return -EPERM;
  1508. +  switch (cmd)
  1509. +    {
  1510. +    case FDFMTBEG:
  1511. +      return 0;
  1512. +    /* case FDC1772LRPRM:  ??? DAG what does this do?? 
  1513. +      unit[drive].disktype = NULL;
  1514. +      floppy_sizes[drive] = MAX_DISK_SIZE;
  1515. +      return invalidate_drive (device); */
  1516. +    case FDFMTEND:
  1517. +    case FDFLUSH:
  1518. +      return invalidate_drive (drive);
  1519. +    }
  1520. +  if (!suser ())
  1521. +    return -EPERM;
  1522. +  if (drive < 0 || drive > 3)
  1523. +    return -EINVAL;
  1524. +  switch (cmd)
  1525. +    {
  1526. +    default:
  1527. +      return -EINVAL;
  1528. +    }
  1529. +  return 0;
  1530. +}
  1531. +
  1532. +
  1533. +/* Initialize the 'unit' variable for drive 'drive' */
  1534. +
  1535. +static void fd_probe( int drive )
  1536. +{
  1537. +    unit[drive].connected = 0;
  1538. +    unit[drive].disktype  = NULL;
  1539. +
  1540. +    if (!fd_test_drive_present( drive ))
  1541. +        return;
  1542. +
  1543. +    unit[drive].connected = 1;
  1544. +    unit[drive].track     = 0;
  1545. +    unit[drive].steprate  = FDC1772STEP_6;
  1546. +    MotorOn = 1;    /* from probe restore operation! */
  1547. +}
  1548. +
  1549. +
  1550. +/* This function tests the physical presence of a floppy drive (not
  1551. + * whether a disk is inserted). This is done by issuing a restore
  1552. + * command, waiting max. 2 seconds (that should be enough to move the
  1553. + * head across the whole disk) and looking at the state of the "TR00"
  1554. + * signal. This should now be raised if there is a drive connected
  1555. + * (and there is no hardware failure :-) Otherwise, the drive is
  1556. + * declared absent.
  1557. + */
  1558. +
  1559. +static int fd_test_drive_present( int drive )
  1560. +
  1561. +{    unsigned long timeout;
  1562. +    unsigned char status;
  1563. +    int              ok;
  1564. +    
  1565. +  printk("fd_test_drive_present %d\n",drive);
  1566. +    if (drive > 1) return( 0 );
  1567. +  return(1); /* Simple hack for the moment - the autodetect doesn't seem to work on arc */
  1568. +    fd_select_drive( drive );
  1569. +
  1570. +    /* disable interrupt temporarily */
  1571. +    DISABLE_IRQ();
  1572. +    FDC1772_WRITE (FDC1772REG_TRACK, 0x00); /* was ff00 why? */
  1573. +    FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6 );
  1574. +
  1575. +  /*printk("fd_test_drive_present: Going into timeout loop\n");*/
  1576. +    for( ok = 0, timeout = jiffies + 2*HZ+HZ/2; jiffies < timeout; ) {
  1577. +    /*  What does this piece of atariism do? - query for an interrupt? */
  1578. +    /*    if (!(mfp.par_dt_reg & 0x20))
  1579. +        break; */
  1580. +    /* Well this is my nearest guess - quit when we get an FDC interrupt */
  1581. +    if (ioc[0x30] & 2) break;
  1582. +    }
  1583. +
  1584. +  /*printk("fd_test_drive_present: Coming out of timeout loop\n");*/
  1585. +    status = FDC1772_READ( FDC1772REG_STATUS );
  1586. +    ok = (status & FDC1772STAT_TR00) != 0;
  1587. +
  1588. +  /*printk("fd_test_drive_present: ok=%d\n",ok); */
  1589. +    /* force interrupt to abort restore operation (FDC1772 would try
  1590. +     * about 50 seconds!) */
  1591. +    FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI );
  1592. +    udelay(500);
  1593. +    status = FDC1772_READ( FDC1772REG_STATUS );
  1594. +    udelay(20);
  1595. +  /*printk("fd_test_drive_present: just before OK code %d\n",ok);*/
  1596. +
  1597. +    if (ok) {
  1598. +        /* dummy seek command to make WP bit accessible */
  1599. +        FDC1772_WRITE( FDC1772REG_DATA, 0 );
  1600. +        FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_SEEK );
  1601. +    printk("fd_test_drive_present: just before wait for int\n");
  1602. +    /* DAG: Guess means wait for interrupt */
  1603. +        while( !(ioc[0x30] &2) ) ;
  1604. +    printk("fd_test_drive_present: just after wait for int\n");
  1605. +        status = FDC1772_READ( FDC1772REG_STATUS );
  1606. +    }
  1607. +
  1608. +  printk("fd_test_drive_present: just before ENABLE_IRQ\n");
  1609. +  ENABLE_IRQ();
  1610. +  printk("fd_test_drive_present: about to return\n");
  1611. +    return( ok );
  1612. +}
  1613. +
  1614. +
  1615. +/* Look how many and which kind of drives are connected. If there are
  1616. + * floppies, additionally start the disk-change and motor-off timers.
  1617. + */
  1618. +
  1619. +static void config_types( void )
  1620. +
  1621. +{
  1622. +    int drive, cnt = 0;
  1623. +
  1624. +    printk("Probing floppy drive(s):\n");
  1625. +    for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {
  1626. +        fd_probe( drive );
  1627. +        if (unit[drive].connected) {
  1628. +            printk("fd%d\n", drive);
  1629. +            ++cnt;
  1630. +        }
  1631. +    }
  1632. +
  1633. +    if (FDC1772_READ( FDC1772REG_STATUS ) & FDC1772STAT_BUSY) {
  1634. +        /* If FDC1772 is still busy from probing, give it another FORCI
  1635. +         * command to abort the operation. If this isn't done, the FDC1772
  1636. +         * will interrupt later and its IRQ line stays low, because
  1637. +         * the status register isn't read. And this will block any
  1638. +         * interrupts on this IRQ line :-(
  1639. +         */
  1640. +        FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI );
  1641. +        udelay(500);
  1642. +        FDC1772_READ( FDC1772REG_STATUS );
  1643. +        udelay(20);
  1644. +    }
  1645. +    
  1646. +    if (cnt > 0) {
  1647. +        START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
  1648. +        if (cnt == 1) fd_select_drive( 0 );
  1649. +        /*START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
  1650. +    }
  1651. +}
  1652. +
  1653. +/*
  1654. + * floppy_open check for aliasing (/dev/fd0 can be the same as
  1655. + * /dev/PS0 etc), and disallows simultaneous access to the same
  1656. + * drive with different device numbers.
  1657. + */
  1658. +
  1659. +static int floppy_open( struct inode *inode, struct file *filp )
  1660. +
  1661. +{
  1662. +  int drive;
  1663. +  int old_dev;
  1664. +
  1665. +  if (!filp)
  1666. +    {
  1667. +      DPRINT (("Weird, open called with filp=0\n"));
  1668. +      return -EIO;
  1669. +    }
  1670. +
  1671. +  drive = MINOR (inode->i_rdev) & 3;
  1672. +  if ((MINOR (inode->i_rdev) >> 2) > NUM_DISK_TYPES)
  1673. +    return -ENXIO;
  1674. +
  1675. +  old_dev = fd_device[drive];
  1676. +
  1677. +  if (fd_ref[drive])
  1678. +    if (old_dev != inode->i_rdev)
  1679. +      return -EBUSY;
  1680. +
  1681. +  if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
  1682. +    return -EBUSY;
  1683. +
  1684. +  if (filp->f_flags & O_EXCL)
  1685. +    fd_ref[drive] = -1;
  1686. +  else
  1687. +    fd_ref[drive]++;
  1688. +
  1689. +  fd_device[drive] = inode->i_rdev;
  1690. +
  1691. +  if (old_dev && old_dev != inode->i_rdev)
  1692. +    invalidate_buffers(old_dev);
  1693. +
  1694. +  /* Allow ioctls if we have write-permissions even if read-only open */
  1695. +  if (filp->f_mode & 2 || permission (inode, 2) == 0)
  1696. +    filp->f_mode |= IOCTL_MODE_BIT;
  1697. +  if (filp->f_mode & 2)
  1698. +    filp->f_mode |= OPEN_WRITE_BIT;
  1699. +
  1700. +  if (filp->f_flags & O_NDELAY)
  1701. +    return 0;
  1702. +
  1703. +    if (filp->f_mode & 3) {
  1704. +        check_disk_change( inode->i_rdev );
  1705. +        if (filp->f_mode & 2) {
  1706. +            if (unit[drive].wpstat) {
  1707. +                floppy_release(inode, filp);
  1708. +                return -EROFS;
  1709. +            }
  1710. +        }
  1711. +    }
  1712. +
  1713. +  return 0;
  1714. +}
  1715. +
  1716. +
  1717. +static void floppy_release( struct inode * inode, struct file * filp )
  1718. +
  1719. +{
  1720. +  int drive;
  1721. +
  1722. +  drive = inode->i_rdev & 3;
  1723. +
  1724. +  if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
  1725. +    /* if the file is mounted OR (writable now AND writable at open
  1726. +       time) Linus: Does this cover all cases? */
  1727. +    block_fsync (inode, filp);
  1728. +
  1729. +  if (fd_ref[drive] < 0)
  1730. +    fd_ref[drive] = 0;
  1731. +  else if (!fd_ref[drive]--)
  1732. +    {
  1733. +      printk("floppy_release with fd_ref == 0");
  1734. +      fd_ref[drive] = 0;
  1735. +    }
  1736. +}
  1737. +
  1738. +static struct file_operations floppy_fops = {
  1739. +    NULL,            /* lseek - default */
  1740. +    block_read,        /* read - general block-dev read */
  1741. +    block_write,        /* write - general block-dev write */
  1742. +    NULL,            /* readdir - bad */
  1743. +    NULL,            /* select */
  1744. +    fd_ioctl,        /* ioctl */
  1745. +    NULL,            /* mmap */
  1746. +    floppy_open,        /* open */
  1747. +    floppy_release,     /* release */
  1748. +    block_fsync,        /* fsync */
  1749. +    NULL,            /* fasync */
  1750. +    check_floppy_change,    /* media_change */
  1751. +    floppy_revalidate,    /* revalidate */
  1752. +};
  1753. +
  1754. +
  1755. +void
  1756. +fd1772_init (void)
  1757. +
  1758. +{    int i;
  1759. +
  1760. +    if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
  1761. +        printk("Unable to get major %d for floppy\n",MAJOR_NR);
  1762. +        return ;
  1763. +    }
  1764. +
  1765. +  /* Actually this does almost nothing - we actually do this by starting DMA
  1766. +     on channel 1 */
  1767. +  /*if (request_irq(FIQ_FD1772+16,fdc1772_comendhandler,SA_INTERRUPT,"fd1772")) {
  1768. +    printk("Unable to grab IRQ%d for the floppy (1772) driver\n",FIQ_FD1772+16);
  1769. +    return ;
  1770. +  };*/
  1771. +
  1772. +  if (request_dma(FLOPPY_DMA,"fd1772")) {
  1773. +    printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA);
  1774. +    free_irq(FIQ_FD1772+16);
  1775. +    return ;
  1776. +  };
  1777. +
  1778. +  if (request_dma(FIQ_FD1772,"fd1772 end")) {
  1779. +    printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772);
  1780. +    free_irq(FIQ_FD1772+16);
  1781. +    return ;
  1782. +  };
  1783. +  enable_dma(FIQ_FD1772); /* This inserts a call to our command end routine */
  1784. +
  1785. +    /* initialize variables */
  1786. +    SelectedDrive = -1;
  1787. +
  1788. +    /* initialize check_change timer */
  1789. +    timer_table[FLOPPY_TIMER].fn = check_change;
  1790. +    timer_active &= ~(1 << FLOPPY_TIMER);
  1791. +
  1792. +  /* Allocate memory for the DMAbuffer - on the Atari this takes it
  1793. +     out of some special memory...*/
  1794. +    DMABuffer = (char *)vmalloc(2048);/* Copes with pretty large sectors */
  1795. +
  1796. +    for (i = 0; i < FD_MAX_UNITS; i++) {
  1797. +        unit[i].track = -1;
  1798. +  }
  1799. +
  1800. +    for (i = 0; i < 256; i++)
  1801. +        if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_TYPES)
  1802. +            floppy_sizes[i] = disk_type[(i >> 2) - 1].blocks >> 1;
  1803. +        else
  1804. +            floppy_sizes[i] = MAX_DISK_SIZE;
  1805. +
  1806. +    blk_size[MAJOR_NR] = floppy_sizes;
  1807. +    blksize_size[MAJOR_NR] = floppy_blocksizes;
  1808. +    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  1809. +
  1810. +    config_types();
  1811. +
  1812. +    return ;
  1813. +}
  1814. diff -urN linux.store/linux/arch/arm/drivers/block/hd.c linux/arch/arm/drivers/block/hd.c
  1815. --- linux.store/linux/arch/arm/drivers/block/hd.c    Sun Mar  3 12:24:12 1996
  1816. +++ linux/arch/arm/drivers/block/hd.c    Mon Mar 11 22:48:13 1996
  1817. @@ -118,8 +118,7 @@
  1818.      unsigned long t, flags;
  1819.      int i;
  1820.  
  1821. -    save_flags(flags);
  1822. -    cli();
  1823. +    save_flags_cli (flags);
  1824.      t = jiffies * 11932;
  1825.          outb_p(0, 0x43);
  1826.      i = inb_p(0x40);
  1827. @@ -732,11 +731,11 @@
  1828.          return;
  1829.  repeat:
  1830.      timer_active &= ~(1<<HD_TIMER);
  1831. -    sti();
  1832. +    sti ();
  1833.      INIT_REQUEST;
  1834.      if (reset) {
  1835. -        cli();
  1836. -        reset_hd();
  1837. +        cli ();
  1838. +        reset_hd ();
  1839.          return;
  1840.      }
  1841.      dev = MINOR(CURRENT->rq_dev);
  1842. @@ -745,44 +744,43 @@
  1843.      if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
  1844.  #ifdef DEBUG
  1845.          if (dev >= (NR_HD<<6))
  1846. -            printk("hd: bad minor number: device=0x%04x\n", CURRENT->rq_dev);
  1847. +            printk ("hd: bad minor number: device=0x%04x\n", CURRENT->rq_dev);
  1848.          else
  1849. -            printk("hd%c: bad access: block=%d, count=%d\n",
  1850. +            printk ("hd%c: bad access: block=%d, count=%d\n",
  1851.                  (dev>>6)+'a', block, nsect);
  1852.  #endif
  1853. -        end_request(0);
  1854. +        end_request (0);
  1855.          goto repeat;
  1856.      }
  1857.      block += hd[dev].start_sect;
  1858. -    if(dev & 0x3f)
  1859. -    { /* map sectors block to block+nsect to frags, 
  1860. -       */
  1861. -        if(!image_file_check(CURRENT->rq_dev,CURRENT->cmd))
  1862. +    if (dev & 0x3f) {
  1863. +     /* map sectors block to block+nsect to frags, 
  1864. +      */
  1865. +        if (!image_file_check(CURRENT->rq_dev,CURRENT->cmd)) {
  1866. +            end_request (0);
  1867.              goto repeat;
  1868. +        }
  1869.          frag_count = image_file_map(CURRENT->rq_dev, block, nsect, MAX_FRAGS, 
  1870.                          frag_start, frag_len);
  1871. -        if(!frag_count)
  1872. -        {
  1873. +        if (!frag_count) {
  1874. +            end_request (0);
  1875.              goto repeat;
  1876.          }
  1877.          
  1878.          block = frag_start[0];
  1879.          frag_sectors = nsect = frag_len[0];
  1880.          frag_pos = 0;
  1881. -    }
  1882. -    else
  1883. -    {
  1884. +    } else {
  1885.          frag_pos = 0;
  1886.          frag_count = 1;
  1887.          frag_sectors = nsect;
  1888. -        if(CURRENT->cmd == WRITE)
  1889. -        { /* Protect normal HD from writes */
  1890. +        if (CURRENT->cmd == WRITE) { /* Protect normal HD from writes */
  1891.              printk("hd%d : attempted write on protected drive\n",dev);
  1892.              end_request(0);
  1893.              goto repeat;
  1894.          }
  1895.      }
  1896. -    if(issue_request(dev,block,nsect, CURRENT))
  1897. +    if (issue_request(dev, block, nsect, CURRENT))
  1898.          goto repeat;
  1899.  }
  1900.  
  1901. @@ -829,7 +827,7 @@
  1902.  int issue_request(int dev, unsigned int block, unsigned int nsect, struct request *current_req)
  1903.  {
  1904.      unsigned int sec, track, head, cyl;
  1905. -int d = dev;
  1906. +    int d = dev;
  1907.      dev >>= 6;
  1908.      if (special_op[dev]) {
  1909.          if (do_special_op(dev))
  1910. @@ -856,7 +854,6 @@
  1911.          return 0;
  1912.      }
  1913.      if (current_req->cmd == WRITE) {
  1914. -#if 1
  1915.  #if 0
  1916.          if (mult_count[dev])
  1917.              hd_out(dev,nsect,sec,head,cyl,WIN_MULTWRITE,&multwrite_intr);
  1918. @@ -876,14 +873,6 @@
  1919.          } else
  1920.  #endif
  1921.              outsw(HD_DATA,current_req->buffer,256);
  1922. -if(d == 1 && block < 10) while(1);
  1923. -#else
  1924. -if(d == 1)
  1925. -        printk("write: buffer = %p (%08lX)\n", current_req->buffer, *(unsigned long *)current_req->buffer);
  1926. -{int i; for(i=0; i<0x003fffff; i++); }
  1927. -        end_request(0);
  1928. -        return 1;
  1929. -#endif
  1930.          return 0;
  1931.      }
  1932.      panic("unknown hd-command");
  1933. @@ -978,8 +967,7 @@
  1934.          case HDIO_SET_MULTCOUNT:
  1935.              if (!suser()) return -EACCES;
  1936.              if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
  1937. -            save_flags(flags);
  1938. -            cli();    /* a prior request might still be in progress */
  1939. +            save_flags_cli (flags);    /* a prior request might still be in progress */
  1940.              if (arg > max_mult[dev])
  1941.                  err = -EINVAL;    /* out of range for device */
  1942.              else if (mult_req[dev] != mult_count[dev]) {
  1943. @@ -1067,25 +1055,25 @@
  1944.  }
  1945.  
  1946.  
  1947. -void set_hdinfo(int dev,unsigned char secsptrack,unsigned char heads,
  1948. +void hd_set_geometry (kdev_t dev,unsigned char secsptrack,unsigned char heads,
  1949.                      unsigned long discsize,unsigned int secsize)
  1950.  {
  1951. -  dev=MINOR(dev);
  1952. -  if(hd_info[dev>>6].cyl==1)
  1953. -  {
  1954. -    hd_info[dev>>6].cyl=discsize/(secsptrack*heads*secsize);
  1955. -    hd_info[dev>>6].head=heads;
  1956. -    hd_info[dev>>6].wpcom=-1;
  1957. -    hd_info[dev>>6].ctl=8;
  1958. -    hd_info[dev>>6].lzone=hd_info[dev>>6].cyl-1;
  1959. -    hd_info[dev>>6].sect=secsptrack;
  1960. -  }
  1961. -  hd[dev].start_sect=0;
  1962. -  hd[dev].nr_sects=discsize/secsize;
  1963. -#if 0
  1964. -  printk("hd%c: %d cylinders, %d heads, %d sectors (%d total)\n",'a'+(dev>>6),
  1965. -    hd_info[dev>>6].cyl, heads, secsptrack, discsize);
  1966. -#endif
  1967. +    int minor = MINOR(dev);
  1968. +    /*
  1969. +     * Only set the number of cylinders if the
  1970. +     * drive hasn't reported its geometery to the
  1971. +     * driver code yet.
  1972. +     */
  1973. +    if (hd_info[minor>>6].cyl == 1) {
  1974. +    hd_info[minor>>6].cyl = discsize/(secsptrack*heads*secsize);
  1975. +    hd_info[minor>>6].head = heads;
  1976. +    hd_info[minor>>6].wpcom = -1;
  1977. +    hd_info[minor>>6].ctl = 8;
  1978. +    hd_info[minor>>6].lzone = hd_info[dev>>6].cyl-1;
  1979. +    hd_info[minor>>6].sect = secsptrack;
  1980. +    }
  1981. +    hd[minor].start_sect = 0;
  1982. +    hd[minor].nr_sects = discsize / secsize;
  1983.  }
  1984.  
  1985.  /*
  1986. @@ -1099,53 +1087,63 @@
  1987.   */
  1988.  static void hd_geninit(struct gendisk *dev)
  1989.  {
  1990. -    int drive, i;
  1991. -
  1992. -NR_HD = 0;
  1993. -    if (!NR_HD) {
  1994. -    /* Default settings */
  1995. -        for (drive=0 ; drive<2 ; drive++) {
  1996. -            bios_info[drive].cyl    = hd_info[drive].cyl    = 1;
  1997. -            bios_info[drive].head    = hd_info[drive].head    = 1;
  1998. -            bios_info[drive].wpcom    = hd_info[drive].wpcom    = -1;
  1999. -            bios_info[drive].ctl    = hd_info[drive].ctl    = 8;
  2000. -            bios_info[drive].lzone    = hd_info[drive].lzone    = 1;
  2001. -            bios_info[drive].sect    = hd_info[drive].sect    = 17;
  2002. -            if(hd_info[drive].cyl && NR_HD == drive)
  2003. -                NR_HD++;
  2004. -        }
  2005. -        }
  2006. +    int drive, i;
  2007.  
  2008. +    if (!NR_HD) {
  2009. +    /*
  2010. +     * Default settings
  2011. +     *
  2012. +     * If we don't know anything about the drive, then set it
  2013. +     * so that we have enough to read the boot sector of the
  2014. +     * ADFS drive.  This means that you *MUST* specify the
  2015. +     * drive parameters of *all* drives if you have one IDE
  2016. +     * drive that is not ADFS formatted.
  2017. +     */
  2018. +    for (drive=0 ; drive<2 ; drive++) {
  2019. +        bios_info[drive].cyl    = hd_info[drive].cyl    = 1;
  2020. +        bios_info[drive].head    = hd_info[drive].head    = 1;
  2021. +        bios_info[drive].wpcom    = hd_info[drive].wpcom    = -1;
  2022. +        bios_info[drive].ctl    = hd_info[drive].ctl    = 8;
  2023. +        bios_info[drive].lzone    = hd_info[drive].lzone    = 1;
  2024. +        bios_info[drive].sect    = hd_info[drive].sect    = 17;
  2025. +    }
  2026. +    /*
  2027. +     * We only set this to the one that the host OS gave us
  2028. +     * if the user has not defined any types.
  2029. +     */
  2030.      NR_HD = no_hds;
  2031. +    }
  2032.  
  2033. -    i = NR_HD;
  2034. -    while (i-- > 0) {
  2035. -        /*
  2036. -         * The newer E-IDE BIOSs handle drives larger than 1024
  2037. -         * cylinders by increasing the number of logical heads
  2038. -         * to keep the number of logical cylinders below the
  2039. -         * sacred INT13 limit of 1024 (10 bits).  If that is
  2040. -         * what's happening here, we'll find out and correct
  2041. -         * it later when "identifying" the drive.
  2042. -         */
  2043. -        hd[i<<6].nr_sects = bios_info[i].head *
  2044. -                bios_info[i].sect * bios_info[i].cyl;
  2045. -        hd_ident_info[i] = (struct hd_driveid *) kmalloc(512,GFP_KERNEL);
  2046. -        special_op[i] = 1;
  2047. -    }
  2048. -    if (NR_HD) {
  2049. -        if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
  2050. -            printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
  2051. -            NR_HD = 0;
  2052. -        } else {
  2053. -            request_region(HD_DATA, 8, "hd");
  2054. -            request_region(HD_CMD, 1, "hd(cmd)");
  2055. -        }
  2056. +    i = NR_HD;
  2057. +    while (i-- > 0) {
  2058. +    /*
  2059. +     * The newer E-IDE BIOSs handle drives larger than 1024
  2060. +     * cylinders by increasing the number of logical heads
  2061. +     * to keep the number of logical cylinders below the
  2062. +     * sacred INT13 limit of 1024 (10 bits).  If that is
  2063. +     * what's happening here, we'll find out and correct
  2064. +     * it later when "identifying" the drive.
  2065. +     */
  2066. +    hd[i<<6].nr_sects = bios_info[i].head *
  2067. +        bios_info[i].sect * bios_info[i].cyl;
  2068. +    hd_ident_info[i] = (struct hd_driveid *) kmalloc(512,GFP_KERNEL);
  2069. +    special_op[i] = 1;
  2070. +    }
  2071. +
  2072. +    if (NR_HD) {
  2073. +    if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
  2074. +        printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
  2075. +        NR_HD = 0;
  2076. +    } else {
  2077. +        request_region(HD_DATA, 8, "hd");
  2078. +        request_region(HD_CMD, 1, "hd(cmd)");
  2079.      }
  2080. -    hd_gendisk.nr_real = NR_HD;
  2081. +    }
  2082. +    hd_gendisk.nr_real = NR_HD;
  2083.  
  2084. -    for(i=0;i<(MAX_HD << 6);i++) hd_blocksizes[i] = 1024;
  2085. -    blksize_size[MAJOR_NR] = hd_blocksizes;
  2086. +    for (i = 0; i < (MAX_HD << 6); i++)
  2087. +    hd_blocksizes[i] = 1024;
  2088. +    blksize_size[MAJOR_NR] = hd_blocksizes;
  2089.  }
  2090.  
  2091.  static struct file_operations hd_fops = {
  2092. @@ -1203,8 +1201,7 @@
  2093.      target =  DEVICE_NR(dev);
  2094.      gdev = &GENDISK_STRUCT;
  2095.  
  2096. -    save_flags(flags);
  2097. -    cli();
  2098. +    save_flags_cli (flags);
  2099.      if (DEVICE_BUSY || USAGE > maxusage) {
  2100.          restore_flags(flags);
  2101.          return -EBUSY;
  2102. diff -urN linux.store/linux/arch/arm/drivers/block/hdsrch.c linux/arch/arm/drivers/block/hdsrch.c
  2103. --- linux.store/linux/arch/arm/drivers/block/hdsrch.c    Sun Mar  3 12:29:41 1996
  2104. +++ linux/arch/arm/drivers/block/hdsrch.c    Mon Mar 11 23:51:02 1996
  2105. @@ -11,6 +11,8 @@
  2106.  #include <linux/ctype.h>
  2107.  #include <linux/kernel.h>
  2108.  #include <linux/mm.h>
  2109. +#include <linux/kdev_t.h>
  2110. +#include <linux/major.h>
  2111.  #include <linux/malloc.h>
  2112.  #include <linux/string.h>
  2113.  #include <linux/genhd.h>
  2114. @@ -19,8 +21,6 @@
  2115.  
  2116.  #define MAX_BLK_FRAGS 64
  2117.  
  2118. -extern void print_minor_name (struct gendisk *hd, int minor);
  2119. -
  2120.  struct boot_block
  2121.  {
  2122.    unsigned char  log2secsize;
  2123. @@ -42,31 +42,32 @@
  2124.  };
  2125.  
  2126.  static struct boot_block *boot=NULL;
  2127. +static void *map=NULL;
  2128.  static unsigned int zonesize;
  2129.  static unsigned int idsperzone;
  2130.  static long rootaddr;
  2131.  static long mapaddr;
  2132.  static long maplen;
  2133. -static void *map=NULL;
  2134. -static char ignoring;
  2135. +static kdev_t ignoring;
  2136.  
  2137. -static int read_sectors(int dev,void *ptr,long address,int size)
  2138. +static int read_sectors(kdev_t dev, void *ptr, long address, int size)
  2139.  {
  2140.    struct buffer_head *bh;
  2141. -  char *p=ptr;
  2142. -  while(size>0) {
  2143. -    if((bh=bread(dev,address/1024,1024))) {
  2144. -      memcpy(p,bh->b_data+((address & 0x200)?512:0),(address & 0x200 || size<1024)?512:1024);
  2145. -      if(address & 0x200) {
  2146. +  char *p = ptr;
  2147. +  while (size > 0) {
  2148. +    if ((bh = bread(dev, address / 1024, 1024))) {
  2149. +      memcpy (p, bh->b_data + ((address & 0x200) ? 512 : 0),
  2150. +        (address & 0x200 || size < 1024) ? 512 : 1024);
  2151. +      if (address & 0x200) {
  2152.            p -= 512;
  2153.          address -= 512;
  2154.          size += 512;
  2155.        }
  2156.      } else {
  2157. -      printk("hda%c: bread failed\n",'a'+((dev & 0xc0)>>6));
  2158. +      printk ("Device %s: bread failed\n", kdevname(dev));
  2159.        return 0;
  2160.      }
  2161. -    brelse(bh);
  2162. +    brelse (bh);
  2163.      p += 1024;
  2164.      address += 1024;
  2165.      size -= 1024;
  2166. @@ -74,27 +75,46 @@
  2167.    return 1;
  2168.  }
  2169.  
  2170. +static void set_hdinfo (kdev_t dev, unsigned char sectspertrack, unsigned char heads,
  2171. +        unsigned long disksize, unsigned int sectorsize)
  2172. +{
  2173. +    extern void hd_set_geometry (kdev_t dev, unsigned char, unsigned char, unsigned long, unsigned int);
  2174. +    extern void xd_set_geometry (kdev_t dev, unsigned char, unsigned char, unsigned long, unsigned int);
  2175. +
  2176. +    switch (MAJOR(dev)) {
  2177. +#ifdef CONFIG_BLK_DEV_HD
  2178. +    case HD_MAJOR:
  2179. +    hd_set_geometry (dev, sectspertrack, heads, disksize, sectorsize);
  2180. +    break;
  2181. +#endif
  2182. +
  2183. +#ifdef CONFIG_BLK_DEV_XD
  2184. +    case XD_MAJOR:
  2185. +    xd_set_geometry (dev, sectspertrack, heads, disksize, sectorsize);
  2186. +    break;
  2187. +#endif
  2188. +    }
  2189. +}
  2190. +
  2191.  /* + Read boot block at disc address &C00 (sector 6)
  2192.   * + Calculate map address & length
  2193.   */
  2194. -
  2195. -static int getdiskinfo(int dev)
  2196. +static int getdiskinfo(kdev_t dev)
  2197.  {
  2198.    char *ptr;
  2199. -  extern void set_hdinfo(int,unsigned char,unsigned char,unsigned long,unsigned int);
  2200.  
  2201.    if(boot)
  2202.        return 1;
  2203.  
  2204.    boot=(struct boot_block *)kmalloc(sizeof(struct boot_block),GFP_KERNEL);
  2205. -  if(!boot) {
  2206. -    printk("hda%c: out of memory for bootblock\n",(dev>>6)+'a');
  2207. +  if (!boot) {
  2208. +    printk("Device %s: out of memory for bootblock\n", kdevname(dev));
  2209.      return 0;
  2210.    }
  2211.  
  2212.    ptr=(char *)kmalloc(1024,GFP_KERNEL);
  2213. -  if(!ptr) {
  2214. -    printk("hda%c: out of memory for bootblock\n",(dev>>6)+'a');
  2215. +  if (!ptr) {
  2216. +    printk("Device %s: out of memory for bootblock\n", kdevname(dev));
  2217.      return 0;
  2218.    }
  2219.  
  2220. @@ -126,7 +146,7 @@
  2221.    return check;
  2222.  }
  2223.  
  2224. -static int get_map(int dev)
  2225. +static int get_map(kdev_t dev)
  2226.  {
  2227.    if(!getdiskinfo(dev))
  2228.      return 0;
  2229. @@ -146,7 +166,7 @@
  2230.        return 0;
  2231.      if(map_cross_valid_byte()!=0xFF) {
  2232.        printk("Map 2 has invalid cross check - ignoring drive\n");
  2233. -      ignoring=dev;
  2234. +      ignoring = dev;
  2235.        return 0;
  2236.      }
  2237.    }
  2238. @@ -250,7 +270,7 @@
  2239.    }
  2240.  }
  2241.  
  2242. -static unsigned long scandir(int dev,unsigned long diraddress,char *file,int *type,
  2243. +static unsigned long scandir(kdev_t dev,unsigned long diraddress,char *file,int *type,
  2244.         unsigned long *length)
  2245.  {
  2246.    unsigned char *dir;
  2247. @@ -289,7 +309,7 @@
  2248.    return addr;
  2249.  }
  2250.  
  2251. -static int search_path(int dev,char *path,unsigned long *start,unsigned long *length, int maxbits)
  2252. +static int search_path(kdev_t dev,char *path,unsigned long *start,unsigned long *length, int maxbits)
  2253.  {
  2254.    unsigned long dir,iad,len;
  2255.    int type,i,n,fzones[MAX_BLK_FRAGS],fstart[MAX_BLK_FRAGS],fend[MAX_BLK_FRAGS];
  2256. @@ -386,7 +406,6 @@
  2257.  }
  2258.  
  2259.  #define MAX_HD_IMAGES    8
  2260. -#define TWO_HDS
  2261.  #define MAX_HD_BITS    128
  2262.  
  2263.  static int initialised[MAX_HD_IMAGES];
  2264. @@ -409,75 +428,122 @@
  2265.    {0,},
  2266.    {0,},
  2267.    {0,},
  2268. +  {0,},
  2269. +  {0,},
  2270. +  {0,},
  2271. +  {0,},
  2272.    {0,}
  2273.  };
  2274.  
  2275. +/* 
  2276. + * This function  maps a device major/minor to the internal image file number
  2277. + */
  2278. +static inline int get_dev (kdev_t dev, char *where)
  2279. +{
  2280. +    switch (MAJOR(dev)) {
  2281. +#ifdef CONFIG_BLK_DEV_HD
  2282. +    case HD_MAJOR:    /* IDE drives */
  2283. +#elif defined(CONFIG_BLK_DEV_XD)
  2284. +    case XD_MAJOR:    /* ST506 drives (map onto IDE at the moment) */
  2285. +#endif
  2286. +    if ((MINOR(dev) & 0x3f) < 1 || (MINOR(dev) & 0x3f) > 0x14) {
  2287. +        printk ("%s: bad device %s\n", where, kdevname (dev));
  2288. +        return -1;
  2289. +    }
  2290. +    switch (MINOR(dev) & 0xc0) {
  2291. +    case 0x00:  return (MINOR(dev) - 1) & 3;
  2292. +    case 0x40:  return ((MINOR(dev) - 1) & 3) + 4;
  2293. +    default:
  2294. +        printk ("%s: bad device %s\n", where, kdevname (dev));
  2295. +        return -1;
  2296. +    }
  2297. +
  2298. +    default:
  2299. +        printk ("%s: unsupported device %s\n", where, kdevname (dev));
  2300. +        return -1;
  2301. +    }
  2302. +}
  2303. +
  2304.  /*
  2305.   * Get the sectors used by device 'dev'
  2306.   */
  2307. -int image_allocate_list(int dev,int devno,struct hd_struct *part)
  2308. +int image_allocate_list(kdev_t dev, int devno, struct hd_struct *part)
  2309.  {
  2310. -    unsigned long chk1=0,chk2=0;
  2311. -    int i,sects=0;
  2312. +    unsigned long chk1 = 0, chk2 = 0;
  2313. +    int i, sects = 0;
  2314.  
  2315. -#ifndef TWO_HDS
  2316. -    if(dev!=0x300)
  2317. -    {
  2318. -        printk("Can't cope with >1 hd!\n");
  2319. +    switch (MAJOR(dev)) {
  2320. +#ifdef CONFIG_BLK_DEV_HD
  2321. +    case HD_MAJOR:    /* IDE drives */
  2322. +#elif defined(CONFIG_BLK_DEV_XD)
  2323. +    case XD_MAJOR:    /* ST506 drives (map onto IDE at the moment) */
  2324. +#endif    
  2325. +    switch (MINOR(dev) & 0xc0) {
  2326. +    case 0x00:
  2327. +        if (devno == 0 || devno > 4) {
  2328. +        printk ("image_allocate_list: only 4 images per drive allowed\n");
  2329.          return 0;
  2330. -    }
  2331. -#else
  2332. -    if(dev!=0x300 && dev!=0x340)
  2333. -    {
  2334. -        printk("Can't cope with >2 hds! (device %02X:%02X)\n",dev>>8,dev & 255);
  2335. +        }
  2336. +        devno = devno - 1;
  2337. +        break;
  2338. +    case 0x40:
  2339. +        devno &= 0x3f;
  2340. +        if (devno == 0 || devno > 4) {
  2341. +        printk ("image_allocate_list: only 4 images per drive allowed\n");
  2342.          return 0;
  2343. +        }
  2344. +        devno = devno + 3;
  2345. +        break;
  2346. +    default:
  2347. +        printk ("image_allocate_list: only two IDE drives supported\n");
  2348. +        return 0;
  2349.      }
  2350. -    if(dev == 0x340)
  2351. -      devno=(devno & 0x3f) + 4;
  2352. -#endif
  2353. -
  2354. -    if(ignoring==dev)
  2355. -        return 0;
  2356. +    break;
  2357. +    default:
  2358. +    printk ("image_allocate_list: only IDE drives supported: %s\n", kdevname (dev));
  2359. +    return 0;
  2360. +    }
  2361.  
  2362. -    devno--;
  2363. +    if (ignoring == dev)
  2364. +    return 0;
  2365.  
  2366. -    if(devno > MAX_HD_IMAGES)
  2367. -        return 0;
  2368. +    if (devno > MAX_HD_IMAGES)
  2369. +    return 0;
  2370.  
  2371. -    if(!arc_hd_files[devno][0])
  2372. -        return 0;
  2373. +    if (!arc_hd_files[devno][0])
  2374. +    return 0;
  2375.  
  2376.  #ifndef NOT_YET_TESTED
  2377. -    maxblock[devno]=search_path(dev,arc_hd_files[devno],startaddr[devno],lengthaddr[devno],MAX_HD_BITS);
  2378. +    maxblock[devno] = search_path(dev, arc_hd_files[devno], startaddr[devno], lengthaddr[devno], MAX_HD_BITS);
  2379.  #else
  2380. -    maxblock[devno]=search_path(dev,arc_hd_files[devno],startaddr[devno],lengthaddr[devno],0);
  2381. +    maxblock[devno] = search_path(dev, arc_hd_files[devno], startaddr[devno], lengthaddr[devno], 0);
  2382.  #endif
  2383. -    if(maxblock[devno]>MAX_HD_BITS)
  2384. -        panic("image allocator: image file is too fragmented\n");
  2385. -    if(!maxblock[devno])
  2386. -        return 0;
  2387. +    if (maxblock[devno] > MAX_HD_BITS)
  2388. +    panic ("image_allocate_list: image file is too fragmented\n");
  2389. +
  2390. +    if (!maxblock[devno])
  2391. +    return 0;
  2392.  
  2393. -    for(i=0; i<maxblock[devno]; i++)
  2394. -    {
  2395. -        /* convert to blocks & calculate checksums */
  2396. +    for (i = 0; i < maxblock[devno]; i++) {
  2397. +    /* convert to blocks & calculate checksums */
  2398.  #define ADDR2BLOCK(x) ((x)>>9)
  2399. -        startaddr[devno][i]=ADDR2BLOCK(startaddr[devno][i]);
  2400. -        lengthaddr[devno][i]=ADDR2BLOCK(lengthaddr[devno][i]);
  2401. -        chk1^=startaddr[devno][i];
  2402. -        chk2^=lengthaddr[devno][i];
  2403. -        sects+=lengthaddr[devno][i];
  2404. -    }
  2405. -    startchk[devno]=chk1;
  2406. -    lengthchk[devno]=chk2;
  2407. -    initialised[devno]=1;
  2408. -    part->start_sect=0;
  2409. -    part->nr_sects=sects;
  2410. +    startaddr[devno][i] = ADDR2BLOCK(startaddr[devno][i]);
  2411. +    lengthaddr[devno][i] = ADDR2BLOCK(lengthaddr[devno][i]);
  2412. +    chk1 ^= startaddr[devno][i];
  2413. +    chk2 ^= lengthaddr[devno][i];
  2414. +    sects += lengthaddr[devno][i];
  2415. +    }
  2416. +    startchk[devno] = chk1;
  2417. +    lengthchk[devno] = chk2;
  2418. +    initialised[devno] = 1;
  2419. +    part->start_sect = 0;
  2420. +    part->nr_sects = sects;
  2421.  
  2422.  #ifdef DEBUG
  2423. -    for(i=0;i<n;i++)
  2424. -        printk("%10X : %10X\n",start[devno][i],length[devno][i]);
  2425. +    for (i = 0; i < n; i++)
  2426. +    printk ("%10X : %10X\n",start[devno][i],length[devno][i]);
  2427.  #endif
  2428. -    return 1;
  2429. +    return 1;
  2430.  }
  2431.  
  2432.  /*
  2433. @@ -486,80 +552,58 @@
  2434.   * This must be called before accessing a new device
  2435.   */
  2436.  
  2437. -void image_release_dev(int dev)
  2438. +void image_release_dev (kdev_t dev)
  2439.  {
  2440. -  if(boot) {
  2441. -    kfree_s(boot,sizeof(struct boot_block));
  2442. -    boot=NULL;
  2443. -  }
  2444. +    if(boot) {
  2445. +    kfree (boot);
  2446. +    boot = NULL;
  2447. +    }
  2448.  
  2449. -  if(map) {
  2450. -    vfree(map);
  2451. -    map = NULL;
  2452. -  }
  2453. +    if(map) {
  2454. +    vfree (map);
  2455. +    map = NULL;
  2456. +    }
  2457.  
  2458. -  ignoring=0;
  2459. +    ignoring = 0;
  2460.  }
  2461.  
  2462.  /* 
  2463. - * This macro maps a device major/minor to the internal image file number
  2464. - */
  2465. -#ifndef TWO_HDS
  2466. -#define GET_DEV(dev) \
  2467. -    if((dev)<0x301 || (dev)>0x314) \
  2468. -    { \
  2469. -        printk("Bad device %X passed to image_file_check\n",(dev)); \
  2470. -        return 0; \
  2471. -    } \
  2472. -    (dev)=((dev)-1) & 3;
  2473. -#else
  2474. -#define GET_DEV(dev) \
  2475. -    if(((dev) & 0x33F)<0x301 || ((dev) & 0x33F)>0x314) \
  2476. -    { \
  2477. -        printk("Bad device %X passed to image_file_check\n",(dev)); \
  2478. -        return 0; \
  2479. -    } \
  2480. -    switch((dev) & 0xC0) \
  2481. -    { \
  2482. -        case 0x00: (dev)=((dev) -1) & 3;     break;\
  2483. -        case 0x40: (dev)=(((dev) -1) & 3)+4; break;\
  2484. -    }
  2485. -#endif
  2486. -
  2487. -/* 
  2488.   * This function is called to perform checks on the image file.
  2489.   *  Checks made: Image file has been initialised, and
  2490.   *     for writes, the checksums on the start/length data are correct.
  2491.   */
  2492. -int image_file_check(int dev,int cmd)
  2493. +int image_file_check (kdev_t dev,int cmd)
  2494.  {
  2495. -    long chk1=0,chk2=0;
  2496. -    int i;
  2497. +    unsigned long chk1 = 0, chk2 = 0;
  2498. +    int i, internal_dev;
  2499.  
  2500. -    GET_DEV(dev);
  2501. +    internal_dev = get_dev (dev, "image_file_check");
  2502.  
  2503. -    if (!initialised[dev]) {
  2504. -        printk("hd%c%d: %s of uninitialised image file.\n",(dev>>6)+'a',dev & 0x3f,
  2505. -          cmd==WRITE?"write":"read");
  2506. -        return 0;
  2507. -    }
  2508. +    if (internal_dev < 0)
  2509. +    return 0;
  2510.  
  2511. -    if (cmd==WRITE) {
  2512. -        /*
  2513. -         * Check the table! Just in case. We don't want to write to a part of the HD that
  2514. -         * is not allocated to us! It might be the map or something!
  2515. -         */
  2516. -        for(i=0; i<maxblock[dev]; i++) {
  2517. -              chk1^=startaddr[dev][i];
  2518. -              chk2^=lengthaddr[dev][i];
  2519. -        }
  2520. -        if(chk1!=startchk[dev] || chk2!=lengthchk[dev]) {
  2521. -            printk("hda%c%d: mapping tables corrupted on write.",
  2522. -                (dev>>6)+'a',dev & 0x3f);
  2523. -            return 0;
  2524. -        }
  2525. +    if (!initialised[internal_dev]) {
  2526. +    printk ("hd%c%d: %s of uninitialised image file.\n",
  2527. +        (dev >> 6) + 'a', dev & 0x3f, cmd == WRITE ? "write" : "read");
  2528. +    return 0;
  2529. +    }
  2530. +
  2531. +    if (cmd == WRITE) {
  2532. +    /*
  2533. +     * Check the table! Just in case. We don't want to write to a part of the HD that
  2534. +     * is not allocated to us! It might be the map or something!
  2535. +     */
  2536. +    for(i = 0; i < maxblock[internal_dev]; i++) {
  2537. +        chk1 ^= startaddr[internal_dev][i];
  2538. +        chk2 ^= lengthaddr[internal_dev][i];
  2539.      }
  2540. -    return 1;
  2541. +    if (chk1 != startchk[internal_dev] || chk2 != lengthchk[internal_dev]) {
  2542. +        printk ("hda%c%d: mapping tables corrupted on write.",
  2543. +            (dev >> 6) + 'a', dev & 0x3f);
  2544. +        return 0;
  2545. +    }
  2546. +    }
  2547. +    return 1;
  2548.  }
  2549.  
  2550.  /*
  2551. @@ -567,43 +611,43 @@
  2552.   * or the number of entries.  This is called quite often when accessing
  2553.   * image files.
  2554.   */
  2555. -int image_file_map(int dev,unsigned long reqblock,unsigned long reqlength,
  2556. -            unsigned long max_reqs,
  2557. -                    unsigned long *block,unsigned long *length)
  2558. -{
  2559. -    int i,num=0;
  2560. -    unsigned long blk=reqblock,totlen=0;
  2561. -
  2562. -    GET_DEV(dev);
  2563. -
  2564. -    for(i=0; i<maxblock[dev]; i++)
  2565. -    {
  2566. -        long remainder;
  2567. -        totlen+=lengthaddr[dev][i];
  2568. -        if(reqblock >= lengthaddr[dev][i])
  2569. -        {
  2570. -            reqblock-=lengthaddr[dev][i];
  2571. -            continue;
  2572. -        }
  2573. -        block[num]=reqblock+startaddr[dev][i];
  2574. -        remainder=reqblock+reqlength-lengthaddr[dev][i];
  2575. -        if(remainder<=0)
  2576. -        {
  2577. -            length[num]=reqlength;
  2578. -            return num+1;
  2579. -        }
  2580. -        length[num]=lengthaddr[dev][i]-reqblock;
  2581. -        if(num+1 >= max_reqs)
  2582. -            return num+1;
  2583. -        reqblock=0;
  2584. -        reqlength=remainder;
  2585. -        num++;
  2586. -    }
  2587. +int image_file_map(kdev_t dev, unsigned long reqblock, unsigned long reqlength,
  2588. +            unsigned long max_reqs, unsigned long *block, unsigned long *length)
  2589. +{
  2590. +    unsigned long blk = reqblock, totlen = 0;
  2591. +    int i, num = 0;
  2592. +    int internal_dev;
  2593. +
  2594. +    internal_dev = get_dev (dev, "image_file_map");
  2595.  
  2596. -    printk("hd%c%d: attempted read for sector %ld past end if image file at %ld.\n",
  2597. -        (dev>>6)+'a',dev & 0x3f,blk,totlen);
  2598. -        /* Should never happen! */
  2599. +    if (internal_dev < 0)
  2600.      return 0;
  2601. +
  2602. +    for (i = 0; i < maxblock[internal_dev]; i++) {
  2603. +    long remainder;
  2604. +    totlen += lengthaddr[internal_dev][i];
  2605. +    if (reqblock >= lengthaddr[internal_dev][i]) {
  2606. +        reqblock -= lengthaddr[internal_dev][i];
  2607. +        continue;
  2608. +    }
  2609. +    block[num] = reqblock + startaddr[internal_dev][i];
  2610. +    remainder = reqblock + reqlength - lengthaddr[internal_dev][i];
  2611. +    if (remainder <= 0) {
  2612. +        length[num] = reqlength;
  2613. +        return num + 1;
  2614. +    }
  2615. +    length[num] = lengthaddr[internal_dev][i] - reqblock;
  2616. +    if (num + 1 >= max_reqs)
  2617. +        return num + 1;
  2618. +    reqblock = 0;
  2619. +    reqlength = remainder;
  2620. +    num++;
  2621. +    }
  2622. +
  2623. +    printk ("hd%c%d: attempted read for sector %ld past end if image file at %ld.\n",
  2624. +    (dev >> 6) + 'a', dev & 0x3f, blk, totlen);
  2625. +    /* Should never happen! */
  2626. +    return 0;
  2627.  }
  2628.  
  2629.  
  2630. diff -urN linux.store/linux/arch/arm/drivers/block/ll_rw_blk.c linux/arch/arm/drivers/block/ll_rw_blk.c
  2631. --- linux.store/linux/arch/arm/drivers/block/ll_rw_blk.c    Thu Jan  1 01:00:00 1970
  2632. +++ linux/arch/arm/drivers/block/ll_rw_blk.c    Wed Mar 13 14:45:40 1996
  2633. @@ -0,0 +1,649 @@
  2634. +/*
  2635. + *  linux/drivers/block/ll_rw_blk.c
  2636. + *
  2637. + * Copyright (C) 1991, 1992 Linus Torvalds
  2638. + * Copyright (C) 1994,      Karl Keyte: Added support for disk statistics
  2639. + */
  2640. +
  2641. +/*
  2642. + * This handles all read/write requests to block devices
  2643. + */
  2644. +#include <linux/sched.h>
  2645. +#include <linux/kernel.h>
  2646. +#include <linux/kernel_stat.h>
  2647. +#include <linux/errno.h>
  2648. +#include <linux/string.h>
  2649. +#include <linux/config.h>
  2650. +#include <linux/locks.h>
  2651. +#include <linux/mm.h>
  2652. +
  2653. +#include <asm/system.h>
  2654. +#include <asm/io.h>
  2655. +#include "blk.h"
  2656. +
  2657. +/*
  2658. + * The request-struct contains all necessary data
  2659. + * to load a nr of sectors into memory
  2660. + */
  2661. +static struct request all_requests[NR_REQUEST];
  2662. +
  2663. +/*
  2664. + * used to wait on when there are no free requests
  2665. + */
  2666. +struct wait_queue * wait_for_request = NULL;
  2667. +
  2668. +/* This specifies how many sectors to read ahead on the disk.  */
  2669. +
  2670. +int read_ahead[MAX_BLKDEV] = {0, };
  2671. +
  2672. +/* blk_dev_struct is:
  2673. + *    do_request-address
  2674. + *    next-request
  2675. + */
  2676. +struct blk_dev_struct blk_dev[MAX_BLKDEV] = {
  2677. +    { NULL, NULL },        /* 0 no_dev */
  2678. +    { NULL, NULL },        /* 1 dev mem */
  2679. +    { NULL, NULL },        /* 2 dev fd */
  2680. +    { NULL, NULL },        /* 3 dev ide0 or hd */
  2681. +    { NULL, NULL },        /* 4 dev ttyx */
  2682. +    { NULL, NULL },        /* 5 dev tty */
  2683. +    { NULL, NULL },        /* 6 dev lp */
  2684. +    { NULL, NULL },        /* 7 dev pipes */
  2685. +    { NULL, NULL },        /* 8 dev sd */
  2686. +    { NULL, NULL },        /* 9 dev st */
  2687. +    { NULL, NULL },        /* 10 */
  2688. +    { NULL, NULL },        /* 11 */
  2689. +    { NULL, NULL },        /* 12 */
  2690. +    { NULL, NULL },        /* 13 */
  2691. +    { NULL, NULL },        /* 14 */
  2692. +    { NULL, NULL },        /* 15 */
  2693. +    { NULL, NULL },        /* 16 */
  2694. +    { NULL, NULL },        /* 17 */
  2695. +    { NULL, NULL },        /* 18 */
  2696. +    { NULL, NULL },        /* 19 */
  2697. +    { NULL, NULL },        /* 20 */
  2698. +    { NULL, NULL },        /* 21 */
  2699. +    { NULL, NULL }        /* 22 dev ide1 */
  2700. +};
  2701. +
  2702. +/*
  2703. + * blk_size contains the size of all block-devices in units of 1024 byte
  2704. + * sectors:
  2705. + *
  2706. + * blk_size[MAJOR][MINOR]
  2707. + *
  2708. + * if (!blk_size[MAJOR]) then no minor size checking is done.
  2709. + */
  2710. +int * blk_size[MAX_BLKDEV] = { NULL, NULL, };
  2711. +
  2712. +/*
  2713. + * blksize_size contains the size of all block-devices:
  2714. + *
  2715. + * blksize_size[MAJOR][MINOR]
  2716. + *
  2717. + * if (!blksize_size[MAJOR]) then 1024 bytes is assumed.
  2718. + */
  2719. +int * blksize_size[MAX_BLKDEV] = { NULL, NULL, };
  2720. +
  2721. +/*
  2722. + * hardsect_size contains the size of the hardware sector of a device.
  2723. + *
  2724. + * hardsect_size[MAJOR][MINOR]
  2725. + *
  2726. + * if (!hardsect_size[MAJOR])
  2727. + *        then 512 bytes is assumed.
  2728. + * else
  2729. + *        sector_size is hardsect_size[MAJOR][MINOR]
  2730. + * This is currently set by some scsi device and read by the msdos fs driver
  2731. + * This might be a some uses later.
  2732. + */
  2733. +int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
  2734. +
  2735. +/*
  2736. + * "plug" the device if there are no outstanding requests: this will
  2737. + * force the transfer to start only after we have put all the requests
  2738. + * on the list.
  2739. + */
  2740. +static void plug_device(struct blk_dev_struct * dev, struct request * plug)
  2741. +{
  2742. +    unsigned long flags;
  2743. +
  2744. +    plug->rq_status = RQ_INACTIVE;
  2745. +    plug->cmd = -1;
  2746. +    plug->next = NULL;
  2747. +    save_flags(flags);
  2748. +    cli();
  2749. +    if (!dev->current_request)
  2750. +        dev->current_request = plug;
  2751. +    restore_flags(flags);
  2752. +}
  2753. +
  2754. +/*
  2755. + * remove the plug and let it rip..
  2756. + */
  2757. +static void unplug_device(struct blk_dev_struct * dev)
  2758. +{
  2759. +    struct request * req;
  2760. +    unsigned long flags;
  2761. +
  2762. +    save_flags(flags);
  2763. +    cli();
  2764. +    req = dev->current_request;
  2765. +    if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) {
  2766. +        dev->current_request = req->next;
  2767. +        (dev->request_fn)();
  2768. +    }
  2769. +    restore_flags(flags);
  2770. +}
  2771. +
  2772. +/*
  2773. + * look for a free request in the first N entries.
  2774. + * NOTE: interrupts must be disabled on the way in, and will still
  2775. + *       be disabled on the way out.
  2776. + */
  2777. +static inline struct request * get_request(int n, kdev_t dev)
  2778. +{
  2779. +    static struct request *prev_found = NULL, *prev_limit = NULL;
  2780. +    register struct request *req, *limit;
  2781. +
  2782. +    if (n <= 0)
  2783. +        panic("get_request(%d): impossible!\n", n);
  2784. +
  2785. +    limit = all_requests + n;
  2786. +    if (limit != prev_limit) {
  2787. +        prev_limit = limit;
  2788. +        prev_found = all_requests;
  2789. +    }
  2790. +    req = prev_found;
  2791. +    for (;;) {
  2792. +        req = ((req > all_requests) ? req : limit) - 1;
  2793. +        if (req->rq_status == RQ_INACTIVE)
  2794. +            break;
  2795. +        if (req == prev_found)
  2796. +            return NULL;
  2797. +    }
  2798. +    prev_found = req;
  2799. +    req->rq_status = RQ_ACTIVE;
  2800. +    req->rq_dev = dev;
  2801. +    return req;
  2802. +}
  2803. +
  2804. +/*
  2805. + * wait until a free request in the first N entries is available.
  2806. + */
  2807. +static struct request * __get_request_wait(int n, kdev_t dev)
  2808. +{
  2809. +    register struct request *req;
  2810. +    struct wait_queue wait = { current, NULL };
  2811. +
  2812. +    add_wait_queue(&wait_for_request, &wait);
  2813. +    for (;;) {
  2814. +        unplug_device(MAJOR(dev)+blk_dev);
  2815. +        current->state = TASK_UNINTERRUPTIBLE;
  2816. +        cli();
  2817. +        req = get_request(n, dev);
  2818. +        sti();
  2819. +        if (req)
  2820. +            break;
  2821. +        schedule();
  2822. +    }
  2823. +    remove_wait_queue(&wait_for_request, &wait);
  2824. +    current->state = TASK_RUNNING;
  2825. +    return req;
  2826. +}
  2827. +
  2828. +static inline struct request * get_request_wait(int n, kdev_t dev)
  2829. +{
  2830. +    register struct request *req;
  2831. +
  2832. +    cli();
  2833. +    req = get_request(n, dev);
  2834. +    sti();
  2835. +    if (req)
  2836. +        return req;
  2837. +    return __get_request_wait(n, dev);
  2838. +}
  2839. +
  2840. +/* RO fail safe mechanism */
  2841. +
  2842. +static long ro_bits[MAX_BLKDEV][8];
  2843. +
  2844. +int is_read_only(kdev_t dev)
  2845. +{
  2846. +    int minor,major;
  2847. +
  2848. +    major = MAJOR(dev);
  2849. +    minor = MINOR(dev);
  2850. +    if (major < 0 || major >= MAX_BLKDEV) return 0;
  2851. +    return ro_bits[major][minor >> 5] & (1 << (minor & 31));
  2852. +}
  2853. +
  2854. +void set_device_ro(kdev_t dev,int flag)
  2855. +{
  2856. +    int minor,major;
  2857. +
  2858. +    major = MAJOR(dev);
  2859. +    minor = MINOR(dev);
  2860. +    if (major < 0 || major >= MAX_BLKDEV) return;
  2861. +    if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
  2862. +    else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
  2863. +}
  2864. +
  2865. +/*
  2866. + * add-request adds a request to the linked list.
  2867. + * It disables interrupts so that it can muck with the
  2868. + * request-lists in peace.
  2869. + */
  2870. +static void add_request(struct blk_dev_struct * dev, struct request * req)
  2871. +{
  2872. +    struct request * tmp;
  2873. +    short         disk_index;
  2874. +
  2875. +    switch (MAJOR(req->rq_dev)) {
  2876. +        case SCSI_DISK_MAJOR:
  2877. +            disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
  2878. +            if (disk_index < 4)
  2879. +                kstat.dk_drive[disk_index]++;
  2880. +            break;
  2881. +        case IDE0_MAJOR:    /* same as HD_MAJOR */
  2882. +        case XT_DISK_MAJOR:
  2883. +            disk_index = (MINOR(req->rq_dev) & 0x0040) >> 6;
  2884. +            kstat.dk_drive[disk_index]++;
  2885. +            break;
  2886. +        case IDE1_MAJOR:
  2887. +            disk_index = ((MINOR(req->rq_dev) & 0x0040) >> 6) + 2;
  2888. +            kstat.dk_drive[disk_index]++;
  2889. +        default:
  2890. +            break;
  2891. +    }
  2892. +
  2893. +    req->next = NULL;
  2894. +    cli();
  2895. +    if (req->bh)
  2896. +        mark_buffer_clean(req->bh);
  2897. +    if (!(tmp = dev->current_request)) {
  2898. +        dev->current_request = req;
  2899. +        (dev->request_fn)();
  2900. +        sti();
  2901. +        return;
  2902. +    }
  2903. +    for ( ; tmp->next ; tmp = tmp->next) {
  2904. +        if ((IN_ORDER(tmp,req) ||
  2905. +            !IN_ORDER(tmp,tmp->next)) &&
  2906. +            IN_ORDER(req,tmp->next))
  2907. +            break;
  2908. +    }
  2909. +    req->next = tmp->next;
  2910. +    tmp->next = req;
  2911. +
  2912. +/* for SCSI devices, call request_fn unconditionally */
  2913. +    if (scsi_major(MAJOR(req->rq_dev)))
  2914. +        (dev->request_fn)();
  2915. +
  2916. +    sti();
  2917. +}
  2918. +
  2919. +static void make_request(int major,int rw, struct buffer_head * bh)
  2920. +{
  2921. +    unsigned int sector, count;
  2922. +    struct request * req;
  2923. +    int rw_ahead, max_req;
  2924. +
  2925. +/* WRITEA/READA is special case - it is not really needed, so if the */
  2926. +/* buffer is locked, we just forget about it, else it's a normal read */
  2927. +    rw_ahead = (rw == READA || rw == WRITEA);
  2928. +    if (rw_ahead) {
  2929. +        if (bh->b_lock)
  2930. +            return;
  2931. +        if (rw == READA)
  2932. +            rw = READ;
  2933. +        else
  2934. +            rw = WRITE;
  2935. +    }
  2936. +    if (rw!=READ && rw!=WRITE) {
  2937. +        printk("Bad block dev command, must be R/W/RA/WA\n");
  2938. +        return;
  2939. +    }
  2940. +    count = bh->b_size >> 9;
  2941. +    sector = bh->b_blocknr * count;
  2942. +    if (blk_size[major])
  2943. +        if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
  2944. +            bh->b_dirt = bh->b_uptodate = 0;
  2945. +            bh->b_req = 0;
  2946. +            printk("attempt to access beyond end of device\n");
  2947. +            return;
  2948. +        }
  2949. +    /* Uhhuh.. Nasty dead-lock possible here.. */
  2950. +    if (bh->b_lock)
  2951. +        return;
  2952. +    /* Maybe the above fixes it, and maybe it doesn't boot. Life is interesting */
  2953. +    lock_buffer(bh);
  2954. +    if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
  2955. +        unlock_buffer(bh);
  2956. +        return;
  2957. +    }
  2958. +
  2959. +/* we don't allow the write-requests to fill up the queue completely:
  2960. + * we want some room for reads: they take precedence. The last third
  2961. + * of the requests are only for reads.
  2962. + */
  2963. +    max_req = (rw == READ) ? NR_REQUEST : ((NR_REQUEST*2)/3);
  2964. +
  2965. +/* look for a free request. */
  2966. +    cli();
  2967. +
  2968. +/* The scsi disk drivers and the IDE driver completely remove the request
  2969. + * from the queue when they start processing an entry.  For this reason
  2970. + * it is safe to continue to add links to the top entry for those devices.
  2971. + */
  2972. +    if ((   major == IDE0_MAJOR    /* same as HD_MAJOR */
  2973. +         || major == IDE1_MAJOR
  2974. +         || major == FLOPPY_MAJOR
  2975. +         || major == SCSI_DISK_MAJOR
  2976. +         || major == SCSI_CDROM_MAJOR
  2977. +         || major == IDE2_MAJOR
  2978. +         || major == IDE3_MAJOR)
  2979. +        && (req = blk_dev[major].current_request))
  2980. +    {
  2981. +#ifdef CONFIG_BLK_DEV_HD
  2982. +            if (major == HD_MAJOR || major == FLOPPY_MAJOR)
  2983. +#else
  2984. +        if (major == FLOPPY_MAJOR)
  2985. +#endif CONFIG_BLK_DEV_HD
  2986. +            req = req->next;
  2987. +        while (req) {
  2988. +            if (req->rq_dev == bh->b_dev &&
  2989. +                !req->sem &&
  2990. +                req->cmd == rw &&
  2991. +                req->sector + req->nr_sectors == sector &&
  2992. +                req->nr_sectors < 244)
  2993. +            {
  2994. +                req->bhtail->b_reqnext = bh;
  2995. +                req->bhtail = bh;
  2996. +                req->nr_sectors += count;
  2997. +                mark_buffer_clean(bh);
  2998. +                sti();
  2999. +                return;
  3000. +            }
  3001. +
  3002. +            if (req->rq_dev == bh->b_dev &&
  3003. +                !req->sem &&
  3004. +                req->cmd == rw &&
  3005. +                req->sector - count == sector &&
  3006. +                req->nr_sectors < 244)
  3007. +            {
  3008. +                    req->nr_sectors += count;
  3009. +                    bh->b_reqnext = req->bh;
  3010. +                    req->buffer = bh->b_data;
  3011. +                    req->current_nr_sectors = count;
  3012. +                    req->sector = sector;
  3013. +                mark_buffer_clean(bh);
  3014. +                    req->bh = bh;
  3015. +                    sti();
  3016. +                    return;
  3017. +            }    
  3018. +
  3019. +            req = req->next;
  3020. +        }
  3021. +    }
  3022. +
  3023. +/* find an unused request. */
  3024. +    req = get_request(max_req, bh->b_dev);
  3025. +    sti();
  3026. +
  3027. +/* if no request available: if rw_ahead, forget it; otherwise try again blocking.. */
  3028. +    if (!req) {
  3029. +        if (rw_ahead) {
  3030. +            unlock_buffer(bh);
  3031. +            return;
  3032. +        }
  3033. +        req = __get_request_wait(max_req, bh->b_dev);
  3034. +    }
  3035. +
  3036. +/* fill up the request-info, and add it to the queue */
  3037. +    req->cmd = rw;
  3038. +    req->errors = 0;
  3039. +    req->sector = sector;
  3040. +    req->nr_sectors = count;
  3041. +    req->current_nr_sectors = count;
  3042. +    req->buffer = bh->b_data;
  3043. +    req->sem = NULL;
  3044. +    req->bh = bh;
  3045. +    req->bhtail = bh;
  3046. +    req->next = NULL;
  3047. +    add_request(major+blk_dev,req);
  3048. +}
  3049. +
  3050. +void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer)
  3051. +{
  3052. +    struct request * req;
  3053. +    unsigned int major = MAJOR(dev);
  3054. +    unsigned long sector = page * (PAGE_SIZE / 512);
  3055. +    struct semaphore sem = MUTEX_LOCKED;
  3056. +
  3057. +    if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
  3058. +        printk("Trying to read nonexistent block-device %s (%ld)\n",
  3059. +               kdevname(dev), sector);
  3060. +        return;
  3061. +    }
  3062. +    if (rw!=READ && rw!=WRITE)
  3063. +        panic("Bad block dev command, must be R/W");
  3064. +    if (rw == WRITE && is_read_only(dev)) {
  3065. +        printk("Can't page to read-only device %s\n",
  3066. +               kdevname(dev));
  3067. +        return;
  3068. +    }
  3069. +    req = get_request_wait(NR_REQUEST, dev);
  3070. +/* fill up the request-info, and add it to the queue */
  3071. +    req->cmd = rw;
  3072. +    req->errors = 0;
  3073. +    req->sector = sector;
  3074. +    req->nr_sectors = PAGE_SIZE / 512;
  3075. +    req->current_nr_sectors = PAGE_SIZE / 512;
  3076. +    req->buffer = buffer;
  3077. +    req->sem = &sem;
  3078. +    req->bh = NULL;
  3079. +    req->next = NULL;
  3080. +    add_request(major+blk_dev,req);
  3081. +    down(&sem);
  3082. +}
  3083. +
  3084. +/* This function can be used to request a number of buffers from a block
  3085. +   device. Currently the only restriction is that all buffers must belong to
  3086. +   the same device */
  3087. +
  3088. +void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
  3089. +{
  3090. +    unsigned int major;
  3091. +    struct request plug;
  3092. +    int correct_size;
  3093. +    struct blk_dev_struct * dev;
  3094. +    int i;
  3095. +
  3096. +    /* Make sure that the first block contains something reasonable */
  3097. +    while (!*bh) {
  3098. +        bh++;
  3099. +        if (--nr <= 0)
  3100. +            return;
  3101. +    };
  3102. +
  3103. +    dev = NULL;
  3104. +    if ((major = MAJOR(bh[0]->b_dev)) < MAX_BLKDEV)
  3105. +        dev = blk_dev + major;
  3106. +    if (!dev || !dev->request_fn) {
  3107. +        printk(
  3108. +    "ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n",
  3109. +        kdevname(bh[0]->b_dev), bh[0]->b_blocknr);
  3110. +        goto sorry;
  3111. +    }
  3112. +
  3113. +    /* Determine correct block size for this device.  */
  3114. +    correct_size = BLOCK_SIZE;
  3115. +    if (blksize_size[major]) {
  3116. +        i = blksize_size[major][MINOR(bh[0]->b_dev)];
  3117. +        if (i)
  3118. +            correct_size = i;
  3119. +    }
  3120. +
  3121. +    /* Verify requested block sizes.  */
  3122. +    for (i = 0; i < nr; i++) {
  3123. +        if (bh[i] && bh[i]->b_size != correct_size) {
  3124. +            printk(
  3125. +            "ll_rw_block: only %d-char blocks implemented (%lu)\n",
  3126. +                   correct_size, bh[i]->b_size);
  3127. +            goto sorry;
  3128. +        }
  3129. +    }
  3130. +
  3131. +    if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
  3132. +        printk("Can't write to read-only device %s\n",
  3133. +               kdevname(bh[0]->b_dev));
  3134. +        goto sorry;
  3135. +    }
  3136. +
  3137. +    /* If there are no pending requests for this device, then we insert
  3138. +       a dummy request for that device.  This will prevent the request
  3139. +       from starting until we have shoved all of the blocks into the
  3140. +       queue, and then we let it rip.  */
  3141. +
  3142. +    if (nr > 1)
  3143. +        plug_device(dev, &plug);
  3144. +    for (i = 0; i < nr; i++) {
  3145. +        if (bh[i]) {
  3146. +            bh[i]->b_req = 1;
  3147. +            make_request(major, rw, bh[i]);
  3148. +            if (rw == READ || rw == READA)
  3149. +                kstat.pgpgin++;
  3150. +            else
  3151. +                kstat.pgpgout++;
  3152. +        }
  3153. +    }
  3154. +    unplug_device(dev);
  3155. +    return;
  3156. +
  3157. +      sorry:
  3158. +    for (i = 0; i < nr; i++) {
  3159. +        if (bh[i])
  3160. +            bh[i]->b_dirt = bh[i]->b_uptodate = 0;
  3161. +    }
  3162. +    return;
  3163. +}
  3164. +
  3165. +void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf)
  3166. +{
  3167. +    int i, j;
  3168. +    int buffersize;
  3169. +    struct request * req[8];
  3170. +    unsigned int major = MAJOR(dev);
  3171. +    struct semaphore sem = MUTEX_LOCKED;
  3172. +
  3173. +    if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
  3174. +        printk("ll_rw_swap_file: trying to swap nonexistent block-device\n");
  3175. +        return;
  3176. +    }
  3177. +
  3178. +    if (rw != READ && rw != WRITE) {
  3179. +        printk("ll_rw_swap: bad block dev command, must be R/W");
  3180. +        return;
  3181. +    }
  3182. +    if (rw == WRITE && is_read_only(dev)) {
  3183. +        printk("Can't swap to read-only device %s\n",
  3184. +               kdevname(dev));
  3185. +        return;
  3186. +    }
  3187. +    
  3188. +    buffersize = PAGE_SIZE / nb;
  3189. +
  3190. +    for (j=0, i=0; i<nb;)
  3191. +    {
  3192. +        for (; j < 8 && i < nb; j++, i++, buf += buffersize)
  3193. +        {
  3194. +            if (j == 0) {
  3195. +                req[j] = get_request_wait(NR_REQUEST, dev);
  3196. +            } else {
  3197. +                cli();
  3198. +                req[j] = get_request(NR_REQUEST, dev);
  3199. +                sti();
  3200. +                if (req[j] == NULL)
  3201. +                    break;
  3202. +            }
  3203. +            req[j]->cmd = rw;
  3204. +            req[j]->errors = 0;
  3205. +            req[j]->sector = (b[i] * buffersize) >> 9;
  3206. +            req[j]->nr_sectors = buffersize >> 9;
  3207. +            req[j]->current_nr_sectors = buffersize >> 9;
  3208. +            req[j]->buffer = buf;
  3209. +            req[j]->sem = &sem;
  3210. +            req[j]->bh = NULL;
  3211. +            req[j]->next = NULL;
  3212. +            add_request(major+blk_dev,req[j]);
  3213. +        }
  3214. +        while (j > 0) {
  3215. +            j--;
  3216. +            down(&sem);
  3217. +        }
  3218. +    }
  3219. +}
  3220. +
  3221. +int blk_dev_init(void)
  3222. +{
  3223. +    struct request * req;
  3224. +
  3225. +    req = all_requests + NR_REQUEST;
  3226. +    while (--req >= all_requests) {
  3227. +        req->rq_status = RQ_INACTIVE;
  3228. +        req->next = NULL;
  3229. +    }
  3230. +    memset(ro_bits,0,sizeof(ro_bits));
  3231. +#ifdef CONFIG_BLK_DEV_IDE
  3232. +    ide_init();        /* this MUST preceed hd_init */
  3233. +#endif
  3234. +#ifdef CONFIG_BLK_DEV_HD
  3235. +    hd_init();
  3236. +#endif
  3237. +#ifdef CONFIG_BLK_DEV_XD
  3238. +    xd_init();
  3239. +#endif
  3240. +#ifdef CONFIG_BLK_DEV_FD
  3241. +#ifdef CONFIG_ARCH_ARC
  3242. +    fd1772_init();
  3243. +#else
  3244. +    floppy_init();
  3245. +#endif
  3246. +#else
  3247. +#ifndef CONFIG_ARCH_ARC
  3248. +    outb_p(0xc, 0x3f2);
  3249. +#endif
  3250. +#endif
  3251. +#ifdef CONFIG_CDU31A
  3252. +    cdu31a_init();
  3253. +#endif CONFIG_CDU31A
  3254. +#ifdef CONFIG_MCD
  3255. +    mcd_init();
  3256. +#endif CONFIG_MCD
  3257. +#ifdef CONFIG_MCDX
  3258. +    mcdx_init();
  3259. +#endif CONFIG_MCDX
  3260. +#ifdef CONFIG_SBPCD
  3261. +    sbpcd_init();
  3262. +#endif CONFIG_SBPCD
  3263. +#ifdef CONFIG_AZTCD
  3264. +        aztcd_init();
  3265. +#endif CONFIG_AZTCD
  3266. +#ifdef CONFIG_CDU535
  3267. +    sony535_init();
  3268. +#endif CONFIG_CDU535
  3269. +#ifdef CONFIG_GSCD
  3270. +    gscd_init();
  3271. +#endif CONFIG_GSCD
  3272. +#ifdef CONFIG_CM206
  3273. +    cm206_init();
  3274. +#endif
  3275. +#ifdef CONFIG_OPTCD
  3276. +    optcd_init();
  3277. +#endif CONFIG_OPTCD
  3278. +#ifdef CONFIG_SJCD
  3279. +    sjcd_init();
  3280. +#endif CONFIG_SJCD
  3281. +    return 0;
  3282. +}
  3283. diff -urN linux.store/linux/arch/arm/drivers/block/mfmhd.c linux/arch/arm/drivers/block/mfmhd.c
  3284. --- linux.store/linux/arch/arm/drivers/block/mfmhd.c    Sun Mar  3 12:30:30 1996
  3285. +++ linux/arch/arm/drivers/block/mfmhd.c    Mon Mar 11 23:11:51 1996
  3286. @@ -1,11 +1,33 @@
  3287.  /*
  3288.   * linux/arch/arm/drivers/block/mfmhd.c
  3289.   *
  3290. - * Copyright (C) 1995, 1996 Russell King
  3291. + * Copyright (C) 1995, 1996 Russell King, Dave Alan Gilbert (gilbertd@cs.man.ac.uk)
  3292.   *
  3293.   * MFM hard drive code [experimental]
  3294.   */
  3295.  
  3296. +/*
  3297. + * Change list:
  3298. + *
  3299. + *  3/2/96:DAG: Started a change list :-)
  3300. + *              Set the hardsect_size pointers up since we are running 256 byte
  3301. + *                sectors
  3302. + *              Added DMA code, put it into the rw_intr
  3303. + *              Moved RCAL out of generic interrupt code - don't want to do it
  3304. + *                while DMA'ing - its now in individual handlers.
  3305. + *              Took interrupt handlers off task queue lists and called
  3306. + *                directly - not sure of implications.
  3307. + *
  3308. + *  18/2/96:DAG: Well its reading OK I think, well enough for image file code
  3309. + *              to find the image file; but now I've discovered that I actually
  3310. + *              have to put some code in for image files.
  3311. + *
  3312. + *              Added stuff for image files; seems to work, but I've not
  3313. + *              got a multisegment image file (I don't think!).
  3314. + *              Put in a hack (yep a real hack) for multiple cylinder reads.
  3315. + *              Not convinced its working.
  3316. + */
  3317. +
  3318.  #ifdef MODULE
  3319.  #include <linux/module.h>
  3320.  #include <linux/version.h>
  3321. @@ -19,18 +41,34 @@
  3322.  #include <linux/tqueue.h>
  3323.  #include <linux/mm.h>
  3324.  
  3325. -#include <linux/xd.h>
  3326.  #include <linux/errno.h>
  3327.  #include <linux/genhd.h>
  3328.  #include <linux/major.h>
  3329. +#include <linux/xd.h>
  3330.  
  3331.  #include <asm/system.h>
  3332.  #include <asm/io.h>
  3333. +#include <asm/irq-no.h>
  3334.  #include <asm/segment.h>
  3335. +#include <asm/delay.h>
  3336.  #include <asm/dma.h>
  3337.  
  3338.  #include <asm/ecard.h>
  3339.  
  3340. +#define MAX_FRAGS          16
  3341. +static unsigned long frag_start[MAX_FRAGS];        /* start of fragments */
  3342. +static unsigned long frag_len[MAX_FRAGS];          /* Fragment length */
  3343. +static int frag_count;                             /* Number of fragments to go */
  3344. +static int frag_pos;                               /* Position in fragment arrays */
  3345. +static unsigned int frag_sectors;
  3346. +
  3347. +static unsigned int PartFragRead;   /* The number of sectors which have been read
  3348. +                                       during a partial read split over two
  3349. +                                       cylinders.  If 0 it means a partial
  3350. +                                       read did not occur. */
  3351. +
  3352. +static unsigned int PartFragRead_RestartBlock; /* Where to restart on a split access */
  3353. +static unsigned int PartFragRead_SectorsLeft; /* Where to restart on a split access */
  3354.  #define MFM_DISK_MAJOR    13
  3355.  #undef  XT_DISK_MAJOR
  3356.  #define XT_DISK_MAJOR    -1
  3357. @@ -39,14 +77,14 @@
  3358.  
  3359.  XD_INFO mfm_info[XD_MAXDRIVES];
  3360.  
  3361. -#define DEBUG
  3362. +/*#define DEBUG */
  3363.  
  3364.  #define MFM_COMMAND (mfm_addr + 0)
  3365.  #define MFM_DATAOUT (mfm_addr + 1)
  3366.  #define MFM_STATUS  (mfm_addr + 8)
  3367.  #define MFM_DATAIN  (mfm_addr + 9)
  3368.  
  3369. -static void mfm_geninit (void);
  3370. +static void mfm_geninit (struct gendisk *dev);
  3371.  static int  mfm_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg);
  3372.  static int  mfm_open (struct inode *inode,struct file *file);
  3373.  static void mfm_release (struct inode *inode, struct file *file);
  3374. @@ -56,8 +94,10 @@
  3375.  static void mfm_request (void);
  3376.  static int  mfm_reread_partitions (int dev);
  3377.  static void mfm_request (void);
  3378. +static void mfm_specify (void);
  3379.  
  3380.  #define mfm_init xd_init
  3381. +#define mfm_setup xd_setup
  3382.  
  3383.  static struct hd_struct mfm[XD_MAXDRIVES << 6];
  3384.  static int mfm_sizes[XD_MAXDRIVES << 6], mfm_access[XD_MAXDRIVES] = { 0, 0 };
  3385. @@ -67,6 +107,8 @@
  3386.  
  3387.  static int mfm_irq;        /* Interrupt number */
  3388.  static int mfm_addr;        /* Controller address */
  3389. +static unsigned char *mfm_IRQPollLoc;  /* Address to read for IRQ information */
  3390. +static char mfm_IRQMask;    /* AND with *mfm_IRQPollLoc to find if there is an interrupt */
  3391.  static int mfm_drives = 0;    /* drives available */
  3392.  static int mfm_status = 0;    /* interrupt status */
  3393.  static char mfm_busy = 0;    /* mfm busy */
  3394. @@ -132,7 +174,16 @@
  3395.  #define NEED_1_RECAL -2
  3396.  #define NEED_2_RECAL -3
  3397.  
  3398. +int mfm_sectsizes[256]; /* We have to do this because we don't have 512 byte sectors */
  3399.  
  3400. +/* Stuff from the assembly routines */
  3401. +extern unsigned int hdc63463_baseaddress;    /* Controller base address */
  3402. +extern unsigned int hdc63463_irqpolladdress; /* Address to read to test for int */
  3403. +extern unsigned int hdc63463_irqpollmask;    /* Mask for irq register */
  3404. +extern unsigned int hdc63463_dataptr;        /* Pointer to kernel data space to DMA */
  3405. +extern int hdc63463_dataleft;                /* Number of bytes left to transfer */
  3406. +
  3407. +extern unsigned char *ioc;
  3408.  /* ------------------------------------------------------------------------------------------ */
  3409.  /*
  3410.   * From the HD63463 data sheet from Hitachi Ltd.
  3411. @@ -204,43 +255,105 @@
  3412.  static int mfm_prods[] = { 0x000b };
  3413.  static int mfm_manus[] = { 0x0000 };
  3414.  
  3415. -unsigned long mfm_init (unsigned long mem_start, unsigned long mem_end)
  3416. +int mfm_init (void)
  3417.  {
  3418. +  unsigned int i;
  3419. +/* DAG */
  3420. +#ifdef CONFIG_MFM_ONMAINBOARD
  3421. +  mfm_irq = IRQ_HARDDISK;
  3422. +  mfm_addr=(0x3250000>>2); /* Motherboard HDC address  - thats probably slow - what should it be? */
  3423. +  mfm_IRQPollLoc=ioc+0x20;
  3424. +  mfm_IRQMask=0x08; /* IL3 pin */
  3425. +#else
  3426.      ecs = ecard_find(0, sizeof(mfm_prods), mfm_prods, mfm_manus);
  3427.      if(!ecs)
  3428. -        return mem_start;
  3429. +        return -1;
  3430.  
  3431.      mfm_irq = ecs->irq;
  3432.      mfm_addr= ((((int)ecs->r_podaddr) & 0x03eff000) + 0x2000)>>2;
  3433.  
  3434. +  /* DAG: Temporary until I examine a podule a bit */
  3435. +  printk("mfm_init: Sorry podule based MFM cards aren't supported - need IRQ poll loc and mask\n");
  3436. +  return -1;
  3437. +
  3438. +
  3439.      ecard_claim(ecs);
  3440. +#endif
  3441.  
  3442. -    printk("mfm: controller found at address %X, interrupt %d\n", mfm_addr, mfm_irq);
  3443. +  /* Stuff for the assembler routines to get to */
  3444. +  hdc63463_baseaddress=(unsigned int)(mfm_addr<<2);
  3445. +  hdc63463_irqpolladdress=(int)mfm_IRQPollLoc;
  3446. +  hdc63463_irqpollmask=mfm_IRQMask;
  3447. +
  3448. +    printk("mfm: controller found at address %X, interrupt %d\n", mfm_addr<<2, mfm_irq);
  3449.  
  3450.      if(register_blkdev(MAJOR_NR, "mfm", &mfm_fops)) {
  3451.          printk("mfm_init: unable to get major number %d\n", MAJOR_NR);
  3452. -        return mem_start;
  3453. +        return -1;
  3454.      }
  3455.      blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  3456. -    read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahread */
  3457. +    read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB?) read ahread */
  3458. +
  3459. +  /* This stops MSDOS trying to mount it - but ll_rw_blk has tons of >>9
  3460. +     presuming 512 byte sectors - its upto us to fix it! */
  3461. +  hardsect_size[MAJOR_NR]=mfm_sectsizes;
  3462. +  for(i=0;i<256;i++)
  3463. +    mfm_sectsizes[i]=256;
  3464. +
  3465.  #ifndef MODULE
  3466.      mfm_gendisk.next = gendisk_head;
  3467.      gendisk_head = & mfm_gendisk;
  3468.  #endif
  3469.  
  3470. -    return mem_start;
  3471. +    return 0;
  3472.  }
  3473.  
  3474. +/* DAG: Gets called by the genhd code to set up the number of sectors etc. */
  3475. +void xt_set_geometry(int dev,unsigned char secsptrack,unsigned char heads,
  3476. +                   unsigned long discsize, unsigned int secsize)
  3477. +{
  3478. +  dev=MINOR(dev);
  3479. +  /* The HD version checks to see if the number of cylinders are unset */
  3480. +  /* and then causes them to be set... */
  3481. +  /* Need to set up the precomp etc. */
  3482. +  if (mfm_info[dev>>6].cylinders==1)
  3483. +  {
  3484. +    mfm_info[dev>>6].sectors=secsptrack;
  3485. +    mfm_info[dev>>6].heads=heads;
  3486. +    mfm_info[dev>>6].cylinders=discsize/(secsptrack*heads*secsize);
  3487. +
  3488. +    mfm_drive_param[dev>>6].nosectors=secsptrack;
  3489. +    mfm_drive_param[dev>>6].noheads=heads;
  3490. +    mfm_drive_param[dev>>6].nocylinders=discsize/(secsptrack*heads*secsize);
  3491. +
  3492. +    printk("mfm%c: %d cylinders, %d heads, %d sectors secsize=%d (%ld total)\n",'a'+(dev>>6),
  3493. +        mfm_info[dev>>6].cylinders, heads, secsptrack, secsize, discsize);
  3494. +    /* Should probably do a specify command here....*/
  3495. +    printk("mfm: at end of set_hdinfo: About to do a specify\n");
  3496. +    if ((heads<1) || (mfm_drive_param[dev>>6].nocylinders>1024)) {
  3497. +      /* Shouldn't be a panic - but easiest for initial debug */
  3498. +      panic("xt_set_hdinfo: Invalid heads/cylinders count\n"); 
  3499. +    };
  3500. +    mfm_specify();
  3501. +    printk("mfm: set_hdinfo after the specify\n");
  3502. +  };
  3503. +
  3504. +  mfm[dev].start_sect=0;
  3505. +  mfm[dev].nr_sects=(discsize/secsize)/2; /* This is 512 byte sectors - I want 256 but where does this get set for image files? */
  3506. +  printk("mfm set_hdinfo: mfm[%d].nr_sects=%ld\n",dev,mfm[dev].nr_sects);
  3507. +
  3508. +}
  3509. +    
  3510.  static int mfm_initdrives (void)
  3511.  {
  3512.      mfm_info[0].heads = 4;
  3513. -    mfm_info[0].cylinders = 615;
  3514. +    mfm_info[0].cylinders = 1; /* its going to have to figure it out from the drive */
  3515.      mfm_info[0].sectors = 32;
  3516.      mfm_info[0].control = 0;
  3517.      return 1;
  3518.  }
  3519.  
  3520. -static void mfm_geninit (void)
  3521. +static void mfm_geninit (struct gendisk *dev)
  3522.  {
  3523.      int i;
  3524.  
  3525. @@ -250,11 +363,14 @@
  3526.          printk("mfm%d: heads = %d, cylinders = %d, sectors = %d\n", i,
  3527.               mfm_info[i].heads, mfm_info[i].cylinders, mfm_info[i].sectors);
  3528.  
  3529. +  /*printk("mfm: Before irq register\n");*/
  3530.      if(request_irq(mfm_irq, mfm_interrupt_handler, SA_INTERRUPT, "MFM harddisk"))
  3531.          printk("mfm: unable to get IRQ%d\n", mfm_irq);
  3532.  
  3533. -    outw(0x80, mfm_addr + (0x1000 >> 2));
  3534. +  /*printk("mfm: Before wierd write\n"); */
  3535. +    /*outw(0x80, mfm_addr + (0x1000 >> 2)); *//* Pardon? DAG */
  3536.  
  3537. +  /*printk("mfm: Before data init\n");*/
  3538.      for(i = 0; i < mfm_drives; i++) {
  3539.          mfm[i << 6].nr_sects = mfm_info[i].heads * mfm_info[i].cylinders *
  3540.                  mfm_info[i].sectors;
  3541. @@ -263,16 +379,18 @@
  3542.      }
  3543.      mfm_gendisk.nr_real = mfm_drives;
  3544.  
  3545. +  /*printk("mfm: Before init blocksizes\n");*/
  3546.      for(i=0; i<(XD_MAXDRIVES << 6); i++)
  3547.          mfm_blocksizes[i] = 1024;
  3548.      blksize_size[MAJOR_NR] = mfm_blocksizes;
  3549. +  /*printk("mfm: End of init\n");*/
  3550.  }
  3551.  
  3552.  static int mfm_open (struct inode *inode,struct file *file)
  3553.  {
  3554.      int dev = DEVICE_NR(MINOR(inode->i_rdev));
  3555.  
  3556. -    if (dev < mfm_drives) {
  3557. +    if ((dev) < mfm_drives) {
  3558.          while (!mfm_valid[dev])
  3559.              sleep_on(&mfm_wait_open);
  3560.  
  3561. @@ -443,19 +561,27 @@
  3562.      do {
  3563.          status = inw(MFM_STATUS);
  3564.      } while(status & (STAT_BSY|STAT_POL));
  3565. -    if(status & STAT_CPR)
  3566. +  /*printk("issue_command: status after pol/bsy loop: %02X:\n ",status>>8); */
  3567. +    if(status & (STAT_CPR|STAT_CED|STAT_SED|STAT_DER|STAT_ABN))
  3568.      {
  3569.          outw(CMD_RCAL, MFM_COMMAND);
  3570.          while(inw(MFM_STATUS) & STAT_BSY);
  3571.      }
  3572.  
  3573. +    status = inw(MFM_STATUS);
  3574. +  /*printk("issue_command: status before parameter issue: %02X:\n ",status>>8);*/
  3575.      while(len > 0)
  3576.      {
  3577.          outw(cmdb[1] | (cmdb[0] << 8), MFM_DATAOUT);
  3578.          len -= 2;
  3579.          cmdb += 2;
  3580.      }
  3581. +    status = inw(MFM_STATUS);
  3582. +  /*printk("issue_command: status before command issue: %02X:\n ",status>>8);*/
  3583.      outw(command, MFM_COMMAND);
  3584. +    status = inw(MFM_STATUS);
  3585. +  /*printk("issue_command: status immediatly after command issue: %02X:\n ",status>>8);*/
  3586. +  udelay(20);
  3587.  }
  3588.  
  3589.  static void wait_for_completion (void)
  3590. @@ -467,17 +593,83 @@
  3591.  
  3592.  static void mfm_rw_intr (void)
  3593.  {
  3594. -    printk("mfm_rw_intr...\n");
  3595. -    if (cont)
  3596. -    {
  3597. -        cont->done(1);
  3598. -    }
  3599. -    mfm_request();
  3600. +#ifdef DEBUG
  3601. +    printk("mfm_rw_intr...dataleft=%d\n",hdc63463_dataleft);
  3602. +  print_status();
  3603. +#endif
  3604. +
  3605. +  if (mfm_status & (STAT_DER | STAT_ABN)) {
  3606. +    /* Something has gone wrong - lets try that again */
  3607. +    outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  3608. +    if (cont) {
  3609. +      cont->error();
  3610. +      cont->redo();
  3611. +    };
  3612. +    return;
  3613. +  };
  3614. +
  3615. +  /* OK so what ever happend its not an error, now I reckon we are left between
  3616. +     a choice of command end or some data which is ready to be collected */
  3617. +  /* I think we have to transfer data while the interrupt line is on and its
  3618. +     not any other type of interrupt */
  3619. +  if (CURRENT->cmd==WRITE) {
  3620. +    extern void hdc63463_writedma(void);
  3621. +    if ((hdc63463_dataleft<=0) && (!(mfm_status & STAT_CED))) {
  3622. +      printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n");
  3623. +      if (cont) {
  3624. +        cont->error();
  3625. +        cont->redo();
  3626. +      };
  3627. +      return;
  3628. +    };
  3629. +    hdc63463_writedma();
  3630. +  } else {
  3631. +    extern void hdc63463_readdma(void);
  3632. +    if ((hdc63463_dataleft<=0) && (!(mfm_status & STAT_CED))) {
  3633. +      printk("mfm_rw_intr: Apparent DMA read request when no more to DMA\n");
  3634. +      if (cont) {
  3635. +        cont->error();
  3636. +        cont->redo();
  3637. +      };
  3638. +      return;
  3639. +    };
  3640. +    /*printk("Going to try read dma..............status=0x%x\n",mfm_status); */
  3641. +    hdc63463_readdma();
  3642. +  }; /* Read */
  3643. +
  3644. +    mfm_status = inw(MFM_STATUS);
  3645. +  if (mfm_status & (STAT_DER | STAT_ABN)) {
  3646. +    /* Something has gone wrong - lets try that again */
  3647. +    if (cont) {
  3648. +      cont->error();
  3649. +      cont->redo();
  3650. +    };
  3651. +    return;
  3652. +  };
  3653. +
  3654. +  /* If end of command move on */
  3655. +  if (mfm_status & (STAT_CED)) {
  3656. +    outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  3657. +    /* End of command - trigger the next command */
  3658. +    if (cont)
  3659. +    {
  3660. +      cont->done(1);
  3661. +    }
  3662. +    /*mfm_request(); - DAG - took out because we might not have finished the whole command */
  3663. +#ifdef DEBUG
  3664. +    printk("mfm_rw_intr: returned from cont->done\n");
  3665. +#endif
  3666. +  } else {
  3667. +    /* Its going to generate another interrupt */
  3668. +    SET_INTR(mfm_rw_intr);
  3669. +  };
  3670.  }
  3671.  
  3672.  static void mfm_setup_rw (void)
  3673.  {
  3674. +#ifdef DEBUG
  3675.      printk("setting up for rw...\n");
  3676. +#endif
  3677.  #if 1
  3678.      SET_INTR(mfm_rw_intr);
  3679.      issue_command(raw_cmd.cmdcode, raw_cmd.cmddata, raw_cmd.cmdlen);
  3680. @@ -492,8 +684,11 @@
  3681.  
  3682.  static void mfm_recal_intr (void)
  3683.  {
  3684. +#ifdef DEBUG
  3685.      printk("recal intr - status = ");
  3686.      print_status();
  3687. +#endif
  3688. +  outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  3689.      if(mfm_status & (STAT_DER|STAT_ABN)) {
  3690.          printk("recal failed\n");
  3691.          MFM_DRV_PARAM.cylinder = NEED_2_RECAL;
  3692. @@ -504,12 +699,15 @@
  3693.          }
  3694.          return;
  3695.      }
  3696. +  /* Thats seek end - we are finished */
  3697.      if(mfm_status & STAT_SED) {
  3698.          issue_command(CMD_POD, NULL, 0);
  3699.          MFM_DRV_PARAM.cylinder = 0;
  3700.          mfm_seek();
  3701.          return;
  3702.      }
  3703. +  /* Command end without seek end (see data sheet p.20) for parallel seek
  3704. +     - we have to send a POL command to wait for the seek */
  3705.      if(mfm_status & STAT_CED) {
  3706.          SET_INTR(mfm_recal_intr);
  3707.          issue_command(CMD_POL, NULL, 0);
  3708. @@ -520,8 +718,11 @@
  3709.  
  3710.  static void mfm_seek_intr (void)
  3711.  {
  3712. +#ifdef DEBUG
  3713.      printk("seek intr - status = ");
  3714. -    print_status();
  3715. +    print_status();  
  3716. +#endif
  3717. +  outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  3718.      if(mfm_status & (STAT_DER|STAT_ABN)) {
  3719.          printk("seek failed\n");
  3720.          MFM_DRV_PARAM.cylinder = NEED_2_RECAL;
  3721. @@ -548,23 +749,35 @@
  3722.  
  3723.  static void mfm_specify (void)
  3724.  {
  3725. +  /* IDEA2 seems to work better - its what RiscOS sets my
  3726. +  disc to - on its SECOND call to specify! */
  3727. +#define IDEA2
  3728.      unsigned char cmdb[16];
  3729.      printk("specify...\n");
  3730. -    cmdb[0] = 0x1F;
  3731. -    cmdb[1] = 0xC3;
  3732. -    cmdb[2] = 0x16;
  3733. -    cmdb[3] = 0x02;
  3734. -    cmdb[4] = 0xFC | ((MFM_DRV_PARAM.nocylinders - 1) >> 8);
  3735. -    cmdb[5] = MFM_DRV_PARAM.nocylinders - 1;
  3736. -    cmdb[6] = MFM_DRV_PARAM.noheads - 1;
  3737. -    cmdb[7] = MFM_DRV_PARAM.nosectors - 1;
  3738. -    cmdb[8] = 0xA9;
  3739. -    cmdb[9] = 0x0A;
  3740. -    cmdb[10]= 0x0D;
  3741. -    cmdb[11]= 0x0C;
  3742. -    cmdb[12]= (MFM_DRV_PARAM.precompcylinder - 1) >> 8;
  3743. +    cmdb[0] = 0x1F; /* OM0 - !SECT,!MOD,!DIF,PADP,ECD,CRCP,CRCI,ACOR */
  3744. +    cmdb[1] = 0xC3; /* OM1 - DTM,BRST,!CEDM,!SEDM,!DERM,0,AMEX,PSK */
  3745. +#ifndef IDEA2
  3746. +    cmdb[2] = 0x16; /* OM2 - SL - step pulse low */
  3747. +#else
  3748. +    cmdb[2] = 0; /* OM2 - SL - step pulse low */
  3749. +#endif
  3750. +    cmdb[3] = 0x02; /* Connected unit list */
  3751. +    cmdb[4] = 0xFC | ((MFM_DRV_PARAM.nocylinders - 1) >> 8); /* RW time over/high part of number of cylinders */
  3752. +    cmdb[5] = MFM_DRV_PARAM.nocylinders - 1; /* low part of number of cylinders */
  3753. +    cmdb[6] = MFM_DRV_PARAM.noheads - 1; /* Number of heads */
  3754. +    cmdb[7] = MFM_DRV_PARAM.nosectors - 1; /* Number of sectors */
  3755. +#ifndef IDEA2
  3756. +    cmdb[8] = 0xA9; /* Step pulse high=21, Record Length=001 (256 bytes) */
  3757. +#else
  3758. +    cmdb[8] = 0x21; /* Step pulse high=4, Record Length=001 (256 bytes) */
  3759. +#endif
  3760. +    cmdb[9] = 0x0A; /* gap length 1 */
  3761. +    cmdb[10]= 0x0D; /* gap length 2 */
  3762. +    cmdb[11]= 0x0C; /* gap length 3 */
  3763. +  /* DAG: Note my data sheet shows precomp and low current the other way around */
  3764. +    cmdb[12]= (MFM_DRV_PARAM.precompcylinder - 1) >> 8; /* pre comp cylinder */
  3765.      cmdb[13]= MFM_DRV_PARAM.precompcylinder - 1;
  3766. -    cmdb[14]= (MFM_DRV_PARAM.lowcurrentcylinder - 1) >> 8;
  3767. +    cmdb[14]= (MFM_DRV_PARAM.lowcurrentcylinder - 1) >> 8; /* Low current cylinder */
  3768.      cmdb[15]= MFM_DRV_PARAM.lowcurrentcylinder - 1;
  3769.  
  3770.      issue_command(CMD_SPC, cmdb, 16);
  3771. @@ -574,20 +787,24 @@
  3772.  static void mfm_seek (void)
  3773.  {
  3774.      unsigned char cmdb[4];
  3775. +#ifdef DEBUG
  3776.      printk("seeking...\n");
  3777. +#endif
  3778.      if(MFM_DRV_PARAM.cylinder < 0) {
  3779.          cmdb[0] = raw_cmd.dev + 1;
  3780.          cmdb[1] = raw_cmd.head;
  3781.  
  3782.          SET_INTR(mfm_recal_intr);
  3783. +    printk("mfm_seek: about to call specify\n");
  3784. +    mfm_specify(); /* DAG added this */
  3785.          issue_command(CMD_RCLB, cmdb, 2);
  3786.          return;
  3787.      }
  3788. -    mfm_specify();
  3789. +    /*mfm_specify();*//* DAG took this out */
  3790.      if(MFM_DRV_PARAM.cylinder != raw_cmd.cylinder)
  3791.      {
  3792.          cmdb[0] = raw_cmd.dev + 1;
  3793. -        cmdb[1] = raw_cmd.head;
  3794. +        cmdb[1] = 0; /* raw_cmd.head; DAG: My data sheet says this should be 0 */
  3795.          cmdb[2] = raw_cmd.cylinder >> 8;
  3796.          cmdb[3] = raw_cmd.cylinder;
  3797.  
  3798. @@ -600,7 +817,9 @@
  3799.  
  3800.  static void mfm_initialise (void)
  3801.  {
  3802. +#ifdef DEBUG
  3803.      printk("init...\n");
  3804. +#endif
  3805.      if(raw_cmd.flags & NEED_SEEK)
  3806.          mfm_seek();
  3807.      else
  3808. @@ -616,7 +835,84 @@
  3809.          return;
  3810.      }
  3811.      if(uptodate) {
  3812. -        end_request (1);
  3813. +    /* Apparently worked - lets check bytes left to DMA */
  3814. +    if (hdc63463_dataleft!=(PartFragRead_SectorsLeft*256)) {
  3815. +      printk("mfm: request_done - dataleft=%d - should be %d\n",hdc63463_dataleft,PartFragRead_SectorsLeft*256);
  3816. +      end_request (0);
  3817. +    } else {
  3818. +      /* Potentially this means that we've done; but we might be doing
  3819. +         a partial access, (over two cylinders) or we may have a number
  3820. +         of fragments in an image file.  First lets deal with partial accesss
  3821. +      */
  3822. +      if (PartFragRead) {
  3823. +        /* Yep - a partial access */
  3824. +        CURRENT->buffer+=PartFragRead*256; /* Increment pointer to write */
  3825. +
  3826. +        /* and issue the remainder */
  3827. +        issue_request(MINOR(CURRENT->rq_dev),PartFragRead_RestartBlock,PartFragRead_SectorsLeft,CURRENT);
  3828. +        return;
  3829. +      };
  3830. +
  3831. +      /* ah well - perhaps there is another fragment to go */
  3832. +
  3833. +      /* Increment pointers/counts to start of next fragment */
  3834. +      CURRENT->nr_sectors-=frag_len[frag_pos];
  3835. +      CURRENT->sector+=frag_len[frag_pos];
  3836. +      CURRENT->buffer+=frag_len[frag_pos]*512;
  3837. +
  3838. +      if (CURRENT->nr_sectors>0) {
  3839. +        unsigned int dev,block,nsect;
  3840. +        dev=MINOR(CURRENT->rq_dev);
  3841. +
  3842. +        printk("mfm: Now about to issue fragment %d\n",frag_pos+1);
  3843. +        /* OK - time to issue another fragment */
  3844. +        /* Increment the place where we are going to store the data */
  3845. +        /* Move onto the next fragment */
  3846. +        frag_pos++;
  3847. +
  3848. +        /* But there is a possibility that we are actually going to have to
  3849. +           ask for some more fragments */
  3850. +        if (frag_pos>=MAX_FRAGS)
  3851. +        {
  3852. +          printk("mfm: Getting another block of fragments\n");
  3853. +          block=CURRENT->sector*2;
  3854. +          block+=mfm[dev].start_sect;
  3855. +          nsect=CURRENT->nr_sectors*2;
  3856. +          if (!image_file_check(CURRENT->rq_dev,CURRENT->cmd))
  3857. +          {
  3858. +            end_request(0);
  3859. +            /* Should I initiate another request here? */
  3860. +            return;
  3861. +          }
  3862. +          frag_count=image_file_map(CURRENT->rq_dev,block/2,nsect/2,MAX_FRAGS,frag_start,frag_len);
  3863. +          if (!frag_count)
  3864. +          {
  3865. +            end_request(0);
  3866. +            /* Should I initiate another request here? */
  3867. +            return;
  3868. +          };
  3869. +          frag_pos++;
  3870. +        }; /* More fragments ? */
  3871. +
  3872. +        block=frag_start[frag_pos]*2;
  3873. +        frag_sectors=nsect=frag_len[frag_pos]*2;
  3874. +
  3875. +        /* and issue it */
  3876. +        issue_request(dev,block,nsect,CURRENT);
  3877. +      } else {
  3878. +        /* No - its the end of the line */
  3879. +        end_request (1);
  3880. +
  3881. +#ifdef DEBUG
  3882. +        printk("request_done: About to mfm_request\n");
  3883. +#endif
  3884. +        /* Next one please */
  3885. +        mfm_request(); /* Moved from mfm_rw_intr */
  3886. +#ifdef DEBUG
  3887. +        printk("request_done: returned from mfm_request\n");
  3888. +#endif
  3889. +      }; 
  3890. +    };
  3891.      }
  3892.      else {
  3893.          end_request (0);
  3894. @@ -628,6 +924,7 @@
  3895.      int i;
  3896.      printk("error detected... status = ");
  3897.      print_status();
  3898. +  /*panic("mfm error");*/ /* DAG tmp */
  3899.      (*errors) ++;
  3900.      if(*errors > MFM_DRV_PARAM.errors.abort)
  3901.          cont->done(0);
  3902. @@ -637,6 +934,7 @@
  3903.  
  3904.  static void rw_interrupt(void)
  3905.  {
  3906. +  printk("rw_interrupt\n");
  3907.  }
  3908.  
  3909.  static struct cont rw_cont ={
  3910. @@ -646,62 +944,64 @@
  3911.      request_done
  3912.  };
  3913.  
  3914. -static void mfm_request (void)
  3915. +/*
  3916. + * Actually gets round to issuing the request - note everything at this
  3917. + * point is in 256 byte sectors not Linux 512 byte blocks
  3918. + */
  3919. +static void issue_request (int dev, unsigned int block, unsigned int nsect,
  3920. +                           struct request *current)
  3921.  {
  3922. -    unsigned int dev, block, nsect, track;
  3923. +    int track,start_head,start_sector;
  3924. +    int sectors_to_next_cyl;
  3925.  
  3926. -    if(CURRENT && CURRENT->dev < 0)
  3927. -        return;
  3928. +        dev >>= 6;
  3929.  
  3930. -    while(1){
  3931. -        sti();
  3932. +        track = block / mfm_info[dev].sectors;
  3933. +    start_sector=block % mfm_info[dev].sectors;
  3934. +    start_head=track % mfm_info[dev].heads;
  3935.  
  3936. -        INIT_REQUEST;
  3937. -        dev = MINOR(CURRENT->dev);
  3938. -        block = CURRENT->sector;
  3939. -        nsect = CURRENT->nr_sectors;
  3940. +    /* First get the number of whole tracks which are free before the next
  3941. +    track */
  3942. +    sectors_to_next_cyl=(mfm_info[dev].heads-(start_head+1))*mfm_info[dev].sectors;
  3943. +    /* Then add in the number of sectors left on this track */
  3944. +    sectors_to_next_cyl+=(mfm_info[dev].sectors-start_sector);
  3945.  
  3946. -        if(dev >= (mfm_drives << 6) ||
  3947. -            block >= mfm[dev].nr_sects || ((block+nsect) > mfm[dev].nr_sects)) {
  3948.  #ifdef DEBUG
  3949. -            if(dev >= (mfm_drives << 6))
  3950. -                printk("mfm: bad minor number: device=0x%04x\n", CURRENT->dev);
  3951. -            else
  3952. -                printk("mfm%c: bad access: block=%d, count=%d\n", (dev>>6)+'a',
  3953. -                    block, nsect);
  3954. +    printk("issue_request: mfm_info[dev].sectors=%d track=%d\n",mfm_info[dev].sectors,track);
  3955.  #endif
  3956. -            end_request(0);
  3957. -            continue;
  3958. -        }
  3959. -        block += mfm[dev].start_sect;
  3960. -
  3961. -        if(CURRENT->cmd != READ && CURRENT->cmd != WRITE)
  3962. -        {
  3963. -            printk("unknown mfm-command %d\n", CURRENT->cmd);
  3964. -            end_request(0);
  3965. -            continue;
  3966. -        }
  3967.  
  3968. -        dev >>= 6;
  3969. -
  3970. -        track = block / mfm_info[dev].sectors;
  3971.          raw_cmd.flags        = NEED_SEEK;
  3972.          raw_cmd.dev        = dev;
  3973. -        raw_cmd.sector        = block % mfm_info[dev].sectors;
  3974. -        raw_cmd.head        = track % mfm_info[dev].heads;
  3975. +        raw_cmd.sector        = start_sector;
  3976. +        raw_cmd.head        = start_head;
  3977.          raw_cmd.cylinder    = track / mfm_info[dev].heads;
  3978.          raw_cmd.cmdtype     = CURRENT->cmd;
  3979.          raw_cmd.cmdcode     = CURRENT->cmd == WRITE ? CMD_WD : CMD_RD;
  3980. -        raw_cmd.cmddata[0]    = dev;
  3981. +        raw_cmd.cmddata[0]    = dev+1; /* DAG: +1 to get US */
  3982.          raw_cmd.cmddata[1]    = raw_cmd.head;
  3983.          raw_cmd.cmddata[2]    = raw_cmd.cylinder >> 8;
  3984.          raw_cmd.cmddata[3]    = raw_cmd.cylinder;
  3985.          raw_cmd.cmddata[4]    = raw_cmd.head;
  3986.          raw_cmd.cmddata[5]    = raw_cmd.sector;
  3987. -        raw_cmd.cmddata[6]    = nsect >> 8;
  3988. -        raw_cmd.cmddata[7]    = nsect;
  3989. +    if (nsect<=sectors_to_next_cyl) {
  3990. +      raw_cmd.cmddata[6]    = nsect >> 8;
  3991. +      raw_cmd.cmddata[7]    = nsect;
  3992. +      PartFragRead=0; /* All in one */
  3993. +      PartFragRead_SectorsLeft=0; /* Must set this - used in DMA calcs */
  3994. +    } else {
  3995. +      raw_cmd.cmddata[6]    = sectors_to_next_cyl >> 8;
  3996. +      raw_cmd.cmddata[7]    = sectors_to_next_cyl;
  3997. +      PartFragRead=sectors_to_next_cyl; /* only do this many this time */
  3998. +      PartFragRead_RestartBlock=block+sectors_to_next_cyl; /* Where to restart from */
  3999. +      PartFragRead_SectorsLeft=nsect-sectors_to_next_cyl;
  4000. +    };
  4001.          raw_cmd.cmdlen        = 8;
  4002.  
  4003. +    /* Setup DMA pointers */
  4004. +    hdc63463_dataptr=CURRENT->buffer;
  4005. +    hdc63463_dataleft=nsect*256; /* Better way? */
  4006. +
  4007. +
  4008.  #ifdef DEBUG
  4009.          printk("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n",
  4010.              raw_cmd.dev+'a', (CURRENT->cmd == READ)?"read":"writ",
  4011. @@ -713,12 +1013,113 @@
  4012.          errors = &(CURRENT->errors);
  4013.          mfm_tq.routine = (void (*)(void *))mfm_initialise;
  4014.          queue_task(&mfm_tq, &tq_timer);
  4015. +}; /* issue_request */
  4016. +
  4017. +static void mfm_request (void)
  4018. +{
  4019. +    unsigned int dev, block, nsect;
  4020. +
  4021. +#ifdef DEBUG
  4022. +  printk("mfm_request CURRENT=%p\n",CURRENT);
  4023. +#endif
  4024. +    if(CURRENT && CURRENT->rq_dev < 0) {
  4025. +    printk("mfm_request: exit due to (CURRENT && CURRENT->rq_dev < 0)\n");
  4026. +        return;
  4027. +  };
  4028. +
  4029. +    while(1){
  4030. +#ifdef DEBUG
  4031. +    printk("mfm_request: loop start\n");
  4032. +#endif
  4033. +    /* DAG: I wonder if there wshould be a store flags here? */
  4034. +        sti();
  4035. +
  4036. +#ifdef DEBUG
  4037. +    printk("mfm_request: before INIT_REQUEST\n");
  4038. +#endif
  4039. +        INIT_REQUEST;
  4040. +#ifdef DEBUG
  4041. +    printk("mfm_request: before arg extraction\n");
  4042. +#endif
  4043. +        dev = MINOR(CURRENT->rq_dev);
  4044. +        block = CURRENT->sector;
  4045. +        nsect = CURRENT->nr_sectors;
  4046. +
  4047. +#ifdef DEBUG
  4048. +    printk("mfm_request: raw vals: dev=%d block=%d nsect=%d\n",dev,block,nsect);
  4049. +#endif
  4050. +
  4051. +    /* DAG: Linux doesn't cope with this - even though it has an array telling
  4052. +       it the hardware block size - silly */
  4053. +    block *= 2; /* Now in 256 byte sectors */
  4054. +    nsect *= 2; /* Ditto */
  4055. +
  4056. +        if(dev >= (mfm_drives << 6) ||
  4057. +            block >= (mfm[dev].nr_sects*2) || ((block+nsect) > (mfm[dev].nr_sects*2))) {
  4058. +      printk("mfm: oops dev=0x%04x mfm_drives=%d block=%d mfm[dev].nr_sects=%d nsect=%d\n",
  4059. +             dev,mfm_drives,block,mfm[dev].nr_sects,nsect);
  4060. +            if(dev >= (mfm_drives << 6))
  4061. +                printk("mfm: bad minor number: device=0x%04x\n", CURRENT->rq_dev);
  4062. +            else
  4063. +                printk("mfm%c: bad access: block=%d, count=%d\n", (dev>>6)+'a',
  4064. +                    block, nsect);
  4065. +            end_request(0);
  4066. +            continue;
  4067. +        }
  4068. +        block += mfm[dev].start_sect;
  4069. +
  4070. +    if (dev & 0x3f)
  4071. +    {
  4072. +      /* map sectors block to block+nsect to frags.
  4073. +       */
  4074. +      if (!image_file_check(CURRENT->rq_dev,CURRENT->cmd)) continue;
  4075. +      frag_count = image_file_map(CURRENT->rq_dev,block/2,nsect/2,MAX_FRAGS,frag_start,frag_len);
  4076. +      if(!frag_count)
  4077. +      {
  4078. +        continue;
  4079. +      }
  4080. +      block=frag_start[0]*2;
  4081. +      frag_sectors=nsect=frag_len[0]*2;
  4082. +      frag_pos=0;
  4083. +    } else {
  4084. +      /* OK - its not an image file - lets just push it through */
  4085. +      frag_pos=0;
  4086. +      frag_count=1;
  4087. +      frag_sectors=nsect;
  4088. +      frag_len[frag_pos]=frag_sectors/2;
  4089. +      if (CURRENT->cmd==WRITE)
  4090. +      {
  4091. +         /* Stop writing to the raw drive */
  4092. +         printk("mfm%d: attempted write on protected drive\n",dev);
  4093. +         end_request(0);
  4094. +         continue;
  4095. +      };
  4096. +    }; /* image file/normal if */
  4097. +#ifdef DEBUG
  4098. +    printk("mfm_request: block after offset=%d\n",block);
  4099. +#endif
  4100. +
  4101. +        if(CURRENT->cmd != READ && CURRENT->cmd != WRITE)
  4102. +        {
  4103. +            printk("unknown mfm-command %d\n", CURRENT->cmd);
  4104. +            end_request(0);
  4105. +            continue;
  4106. +        }
  4107. +
  4108. +    issue_request(dev,block,nsect,CURRENT);
  4109. +
  4110.          break;
  4111.      }
  4112. +#ifdef DEBUG
  4113. +  printk("mfm_request: Dropping out bottom\n");
  4114. +#endif
  4115.  }
  4116.  
  4117.  static void do_mfm_request (void)
  4118.  {
  4119. +#ifdef DEBUG
  4120. +  printk("do_mfm_request: about to mfm_request\n");
  4121. +#endif
  4122.      mfm_request();
  4123.  }
  4124.  
  4125. @@ -726,6 +1127,7 @@
  4126.  {
  4127.      printk("mfm: unexpected interrupt - status = ");
  4128.      print_status();
  4129. +  while(1);
  4130.  }
  4131.  
  4132.  static void mfm_interrupt_handler (int unused, struct pt_regs *regs)
  4133. @@ -733,9 +1135,14 @@
  4134.      int i;
  4135.      void (*handler)(void) = DEVICE_INTR;
  4136.  
  4137. +#ifdef DEBUG
  4138. +  printk("mfm_interrupt_handler (handler=0x%p)\n",handler);
  4139. +#endif
  4140.      CLEAR_INTR;
  4141.      mfm_status = inw(MFM_STATUS);
  4142.  
  4143. +  /* If CPR (Command Parameter Reject) and not busy it means that the command
  4144. +     has some return message to give us */
  4145.      if((mfm_status & (STAT_CPR|STAT_BSY)) == STAT_CPR)
  4146.      {
  4147.          int len = 0;
  4148. @@ -748,14 +1155,22 @@
  4149.          }
  4150.      }
  4151.  
  4152. -    outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  4153.  
  4154.      if(!handler) {
  4155. +    outw(CMD_RCAL, MFM_COMMAND);    /* Clear interrupt condition */
  4156.          mfm_unexpected_interrupt();
  4157.          return;
  4158.      }
  4159. -    mfm_tq.routine = (void (*)(void *))handler;
  4160. -    queue_task_irq(&mfm_tq, &tq_timer);
  4161. +    /*mfm_tq.routine = (void (*)(void *))handler;
  4162. +    queue_task_irq(&mfm_tq, &tq_timer); */
  4163. +  handler();
  4164. +}
  4165. +
  4166. +/* DAG: Called presumably to accept command line parameters */
  4167. +/* Ignore for the moment! */
  4168. +void mfm_setup(char *str, int *ints)
  4169. +{
  4170. +  return;
  4171.  }
  4172.  
  4173.  #ifdef MODULE
  4174. diff -urN linux.store/linux/arch/arm/drivers/char/Makefile linux/arch/arm/drivers/char/Makefile
  4175. --- linux.store/linux/arch/arm/drivers/char/Makefile    Sat Feb 24 14:18:57 1996
  4176. +++ linux/arch/arm/drivers/char/Makefile    Wed Mar 13 14:31:04 1996
  4177. @@ -19,12 +19,25 @@
  4178.  
  4179.  L_TARGET := char.a
  4180.  M_OBJS   :=
  4181. -L_OBJS   := tty_io.o n_tty.o console.o keyboard.o serial.o \
  4182. -    tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \
  4183. -    defkeymap.o consolemap.o iic.o
  4184. +L_OBJS   := tty_io.o n_tty.o console.o keyboard.o tty_ioctl.o \
  4185. +        pty.o vt.o mem.o vc_screen.o random.o defkeymap.o \
  4186. +        consolemap.o iic.o
  4187.  
  4188. -# vesa_blank.o selection.o
  4189. +# Architecture dependencies
  4190.  
  4191. +ifeq ($(MACHINE),a5k)
  4192. +  SERIAL = serial.o
  4193. +else
  4194. +ifeq ($(MACHINE),arc)
  4195. +endif
  4196. +  SERIAL = serial6850.o
  4197. +endif
  4198. +
  4199. +# Common dependencies
  4200. +
  4201. +ifdef SERIAL
  4202. +  L_OBJS += $(SERIAL)
  4203. +endif
  4204.  
  4205.  ifeq ($(CONFIG_PRINTER),y)
  4206.    L_OBJS += lp.o
  4207. Binary files linux.store/linux/arch/arm/drivers/char/conmakehash and linux/arch/arm/drivers/char/conmakehash differ
  4208. diff -urN linux.store/linux/arch/arm/drivers/char/console.c linux/arch/arm/drivers/char/console.c
  4209. --- linux.store/linux/arch/arm/drivers/char/console.c    Sun Mar  3 12:31:06 1996
  4210. +++ linux/arch/arm/drivers/char/console.c    Mon Mar 11 22:31:14 1996
  4211. @@ -70,8 +70,7 @@
  4212.  /* ARM Extensions */
  4213.  extern void memc_write (int reg, int val);
  4214.  extern void vidc_write (int reg, int val);
  4215. -extern void ll_char_write(unsigned long ps, int ch, unsigned char forec,
  4216. -             unsigned char backc, unsigned char flgs);
  4217. +extern void ll_write_char(unsigned long ps, unsigned long chinfo);
  4218.  extern void memfastset (void *ptr, unsigned long word, int length);
  4219.  extern void prints (const char *, ...);
  4220.  extern void map_screen_mem (unsigned long vid_base, int remap);
  4221. @@ -445,12 +444,12 @@
  4222.  
  4223.    flgs=FLAGS;
  4224.  
  4225. -  if(currcons == fg_console)
  4226. -    ll_char_write(ps, ch, forecol, backcol, flgs);
  4227. -
  4228.    index = (x + y * video_num_columns);
  4229.  
  4230.    buffer[index] = (flgs<<24)|(backcol<<16)|(forecol<<8)|ch;
  4231. +
  4232. +  if (currcons == fg_console)
  4233. +    ll_write_char(ps, buffer[index]);
  4234.  }
  4235.  
  4236.  static char cursor_on=0;
  4237. @@ -460,8 +459,7 @@
  4238.  {
  4239.    unsigned long flags;
  4240.  
  4241. -  save_flags(flags);
  4242. -  cli();
  4243. +  save_flags_cli (flags);
  4244.    if(--cursoron==0 && currcons == fg_console)
  4245.      put_cursor(0, cp);
  4246.    restore_flags(flags);
  4247. @@ -471,8 +469,7 @@
  4248.  {
  4249.    unsigned long flags;
  4250.  
  4251. -  save_flags(flags);
  4252. -  cli();
  4253. +  save_flags_cli (flags);
  4254.    if(++cursoron==1 && cursor_on && currcons == fg_console)
  4255.      put_cursor(1,cp);
  4256.    restore_flags(flags);
  4257. @@ -604,7 +601,7 @@
  4258.  {
  4259.    unsigned long flags;
  4260.    clear_selection();
  4261. -  save_flags(flags); cli();
  4262. +  save_flags_cli (flags);
  4263.    __origin = offset;
  4264.  
  4265.    memc_write(0,offset>>2);
  4266. @@ -647,8 +644,7 @@
  4267.  
  4268.      if(__real_origin != __origin)
  4269.          __set_origin(__real_origin);
  4270. -    save_flags(flags);
  4271. -    cli();
  4272. +    save_flags_cli (flags);
  4273.  
  4274.      if(deccm)
  4275.          cp = pos + video_num_columns * bytes_per_char_h * (bytes_per_char_v - 1);
  4276. @@ -1962,21 +1958,18 @@
  4277.      console_driver.throttle = con_throttle;
  4278.      console_driver.unthrottle = con_unthrottle;
  4279.  
  4280. -    if(tty_register_driver(&console_driver))
  4281. +    if (tty_register_driver(&console_driver))
  4282.            panic("Couldn't register console driver\n");
  4283.  
  4284.      con_setsize(ORIG_VIDEO_LINES,ORIG_VIDEO_COLS);
  4285.  
  4286.      timer_table[BLANK_TIMER].fn=blank_screen;
  4287.      timer_table[BLANK_TIMER].expires=0;
  4288. -    if(blankinterval) {
  4289. +    if (blankinterval) {
  4290.            timer_table[BLANK_TIMER].expires=jiffies+blankinterval;
  4291.          timer_active|=1<<BLANK_TIMER;
  4292.      }
  4293.  
  4294. -    for(i=0; i<17; i++)
  4295. -        vidc_write(i<<2, default_palette_entries[i]);
  4296. -
  4297.      /* Use ORIG_VIDEO_MODE */
  4298.      video_addr_mask= (video_num_lines * video_num_columns * bytes_per_char_h *
  4299.                   bytes_per_char_v - 1) | (PAGE_SIZE-1);
  4300. @@ -1986,13 +1979,15 @@
  4301.      map_screen_mem (video_mem_base, 1);
  4302.  
  4303.      can_do_color=1;
  4304. -    if(bytes_per_char_h == 8)
  4305. -    {
  4306. +    if (bytes_per_char_h == 8) {
  4307.          default_palette_entries = palette_8;
  4308.          color_table = color_8;
  4309.      }
  4310.  
  4311. -    for(currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
  4312. +    for (i = 0; i < 17; i++)
  4313. +        vidc_write (i << 2, default_palette_entries[i]);
  4314. +
  4315. +    for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
  4316.          vc_cons[currcons].d = (struct vc_data *) kmem_start;
  4317.          kmem_start += sizeof(struct vc_data);
  4318.          vt_cons[currcons] = (struct vt_struct *) kmem_start;
  4319. @@ -2024,7 +2019,7 @@
  4320.            (MIN_NR_CONSOLES == 1) ? "":"s",
  4321.            MAX_NR_CONSOLES);
  4322.      register_console (console_print);
  4323. -    if(request_irq (IRQ_VSYNCPULSE, vsync_irq, 0, "console"))
  4324. +    if (request_irq (IRQ_VSYNCPULSE, vsync_irq, 0, "console"))
  4325.          panic ("Unable to get VSYNC irq for console\n");
  4326.      return kmem_start;
  4327.  }
  4328. @@ -2057,8 +2052,7 @@
  4329.              pp = p + sx * bytes_per_char_h;
  4330.              for (; sx < video_num_columns; sx++)
  4331.              {
  4332. -                ll_char_write (pp, buffer[0] & 0xff, (buffer[0] >> 8) & 0xff,
  4333. -                    (buffer[0] >> 16) & 0xff, (buffer[0] >> 24) & 0xff);
  4334. +                ll_write_char (pp, *buffer);
  4335.                  pp += bytes_per_char_h;
  4336.                  buffer ++;
  4337.              }
  4338. @@ -2070,8 +2064,7 @@
  4339.      {
  4340.          for (; sx < ex; sx++)
  4341.          {
  4342. -            ll_char_write (p, buffer[0] & 0xff, (buffer[0] >> 8) & 0xff,
  4343. -                (buffer[0] >> 16) & 0xff, (buffer[0] >> 24) & 0xff);
  4344. +            ll_write_char (p, *buffer);
  4345.              p += bytes_per_char_h;
  4346.              buffer ++;
  4347.          }
  4348. @@ -2080,37 +2073,35 @@
  4349.  
  4350.  void set_scrmem(int currcons,long offset)
  4351.  {
  4352. -    unsigned long p,pp,mx,my;
  4353. +    unsigned long p, pp, my, by;
  4354.      unsigned long *buffer;
  4355.      int i;
  4356.  
  4357.      p = origin;
  4358.      buffer = (unsigned long *)vc_scrbuf[currcons];
  4359.  
  4360. -    for(my = 0; my < video_num_lines ; my++)
  4361. -    {
  4362. +    by = video_size_row;
  4363. +    for (my = video_num_lines; my > 0; my--) {
  4364. +        int mx, bx = bytes_per_char_h;
  4365.          pp = p;
  4366. -        for(mx = 0; mx < video_num_columns; mx++)
  4367. -        {
  4368. -            ll_char_write(pp,buffer[0] & 0xff,(buffer[0] >> 8) & 0xff,
  4369. -                     (buffer[0] >> 16) & 0xff,(buffer[0] >> 24) & 0xff);
  4370. -            pp+=bytes_per_char_h;
  4371. -            buffer+=1;
  4372. +        for (mx = video_num_columns; mx > 0; mx--) {
  4373. +            ll_write_char (pp, *buffer);
  4374. +            pp += bx;
  4375. +            buffer += 1;
  4376.          }
  4377. -        p+=video_size_row;
  4378. +        p += by;
  4379.      }
  4380.      pp = origin + ((video_screen_size + 0x7FFF) & PAGE_MASK);
  4381. -    while(p<pp)
  4382. -    {
  4383. -        *(unsigned long *)p=0;
  4384. -        p+=4;
  4385. -    }
  4386. -    if(!paletteentries || vcmode != KD_GRAPHICS)
  4387. -        for(i=0; i<17; i++)
  4388. -            vidc_write(i<<2, default_palette_entries[i]);
  4389. +    while (p < pp) {
  4390. +        *(unsigned long *)p = 0;
  4391. +        p += 4;
  4392. +    }
  4393. +    if (!paletteentries || vcmode != KD_GRAPHICS)
  4394. +        for (i = 0; i < 17; i++)
  4395. +            vidc_write(i << 2, default_palette_entries[i]);
  4396.      else
  4397. -        for(i=0; i<17; i++)
  4398. -            vidc_write(i<<2, paletteentries[i] & 0x1fff);
  4399. +        for (i = 0; i < 17; i++)
  4400. +            vidc_write(i << 2, paletteentries[i] & 0x1fff);
  4401.  }
  4402.  
  4403.  /* ------------------------------------------------------------------------------------- *
  4404. @@ -2408,9 +2399,9 @@
  4405.              pp = p + (hx * bytes_per_char_h);
  4406.              for(mx = hx; mx < ((my == hey)?hex+1:video_num_columns); mx++)
  4407.              {
  4408. -                ll_char_write(pp,buffer[0],buffer[1],buffer[2],buffer[3]);
  4409. -                pp+=bytes_per_char_h;
  4410. -                buffer+=4;
  4411. +                ll_write_char (pp, *(unsigned long *)buffer);
  4412. +                pp += bytes_per_char_h;
  4413. +                buffer += 4;
  4414.                  hx = 0;
  4415.              }
  4416.              p+=video_size_row;
  4417. diff -urN linux.store/linux/arch/arm/drivers/char/kbdmouse.c linux/arch/arm/drivers/char/kbdmouse.c
  4418. --- linux.store/linux/arch/arm/drivers/char/kbdmouse.c    Sun Mar  3 12:39:09 1996
  4419. +++ linux/arch/arm/drivers/char/kbdmouse.c    Mon Mar 11 22:32:06 1996
  4420. @@ -67,8 +67,7 @@
  4421.      if (mouse_active++)
  4422.      return 0;
  4423.  
  4424. -    save_flags (flags);
  4425. -    cli ();
  4426. +    save_flags_cli (flags);
  4427.      mouse_active  = 1;
  4428.      mouse_ready   = 0;
  4429.      mouse_dxpos   = 0;
  4430. @@ -98,8 +97,7 @@
  4431.      if (!mouse_ready)
  4432.      return -EAGAIN;
  4433.  
  4434. -    save_flags (flags);
  4435. -    cli ();
  4436. +    save_flags_cli (flags);
  4437.  
  4438.      dxpos = mouse_dxpos;
  4439.      dypos = mouse_dypos;
  4440. @@ -162,8 +160,7 @@
  4441.  {
  4442.      unsigned long flags;
  4443.  
  4444. -    save_flags (flags);
  4445. -    cli ();
  4446. +    save_flags_cli (flags);
  4447.  
  4448.      mouse_buttons=0;
  4449.      mouse_dxpos  =0;
  4450. diff -urN linux.store/linux/arch/arm/drivers/char/keyboard.c linux/arch/arm/drivers/char/keyboard.c
  4451. --- linux.store/linux/arch/arm/drivers/char/keyboard.c    Sun Mar  3 12:39:34 1996
  4452. +++ linux/arch/arm/drivers/char/keyboard.c    Mon Mar 11 22:32:27 1996
  4453. @@ -1219,17 +1219,18 @@
  4454.      tty = ttytab[fg_console];
  4455.      kbd = kbd_table + fg_console;
  4456.  
  4457. -    if (rep && kbd_repeatkey != -1) {
  4458. -        /*
  4459. -         * This prevents the kbd_key routine from being called
  4460. -         * twice, once by this BH, and once by the interrupt
  4461. -         * routine.  Maybe we should put the key press in a
  4462. -         * buffer or variable, and then call the BH...
  4463. -         */
  4464. +    if (rep) {
  4465. +    /*
  4466. +     * This prevents the kbd_key routine from being called
  4467. +     * twice, once by this BH, and once by the interrupt
  4468. +     * routine.  Maybe we should put the key press in a
  4469. +     * buffer or variable, and then call the BH...
  4470. +     */
  4471.          disable_irq (IRQ_KEYBOARDRX);
  4472. -    kbd_key (kbd_repeatkey, kbd_repeatrate);
  4473. +    if (kbd_repeatkey != -1)
  4474. +        kbd_key (kbd_repeatkey, kbd_repeatrate);
  4475.      enable_irq (IRQ_KEYBOARDRX);
  4476. -        rep = 0;
  4477. +    rep = 0;
  4478.      }
  4479.  
  4480.      if(want_console >= 0) {
  4481. @@ -1250,8 +1251,7 @@
  4482.      leds = ((leds & (1<<VC_SCROLLOCK))?4:0) | ((leds & (1<<VC_NUMLOCK))?2:0) |
  4483.             ((leds & (1<<VC_CAPSLOCK))?1:0);
  4484.  
  4485. -    save_flags(flags);
  4486. -    cli();
  4487. +    save_flags_cli (flags);
  4488.      intr_count -= 1;
  4489.  
  4490.      kbd_sendval(leds);
  4491. @@ -1283,8 +1283,7 @@
  4492.  
  4493.      bh_base[KEYBOARD_BH].routine = kbd_bh;
  4494.  
  4495. -    save_flags (flags);
  4496. -    cli ();
  4497. +    save_flags_cli (flags);
  4498.      if (request_irq (IRQ_KEYBOARDRX, kbd_rx, 0, "keyboard")!=0)
  4499.      panic("Could not allocate keyboard receive IRQ!");
  4500.      if (request_irq (IRQ_KEYBOARDTX, kbd_tx, 0, "Keyboard")!=0)
  4501. diff -urN linux.store/linux/arch/arm/drivers/char/serial.c linux/arch/arm/drivers/char/serial.c
  4502. --- linux.store/linux/arch/arm/drivers/char/serial.c    Sun Mar  3 12:47:09 1996
  4503. +++ linux/arch/arm/drivers/char/serial.c    Mon Mar 11 22:34:23 1996
  4504. @@ -242,7 +242,7 @@
  4505.      if (serial_paranoia_check(info, tty->device, "rs_stop"))
  4506.          return;
  4507.      
  4508. -    save_flags(flags); cli();
  4509. +    save_flags_cli (flags);
  4510.      if (info->IER & UART_IER_THRI) {
  4511.          info->IER &= ~UART_IER_THRI;
  4512.          serial_out(info, UART_IER, info->IER);
  4513. @@ -258,7 +258,7 @@
  4514.      if (serial_paranoia_check(info, tty->device, "rs_start"))
  4515.          return;
  4516.      
  4517. -    save_flags(flags); cli();
  4518. +    save_flags_cli (flags);
  4519.      if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
  4520.          info->IER |= UART_IER_THRI;
  4521.          serial_out(info, UART_IER, info->IER);
  4522. @@ -344,7 +344,6 @@
  4523.      ignore_char:
  4524.          *status = serial_inp(info, UART_LSR) & info->read_status_mask;
  4525.      } while (*status & UART_LSR_DR);
  4526. -{ unsigned long flags; save_flags (flags); if (!(flags & 0x08000000)) printk ("SERIAL IRQ ON!\n"); }
  4527.      queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
  4528.  #ifdef SERIAL_DEBUG_INTR
  4529.      printk("DR...");
  4530. @@ -831,7 +830,7 @@
  4531.              return -ENOMEM;
  4532.      }
  4533.  
  4534. -    save_flags(flags); cli();
  4535. +    save_flags_cli (flags);
  4536.  
  4537.  #ifdef SERIAL_DEBUG_OPEN
  4538.      printk("starting up ttys%d (irq %d)...", info->line, info->irq);
  4539. @@ -989,7 +988,7 @@
  4540.             info->irq);
  4541.  #endif
  4542.      
  4543. -    save_flags(flags); cli(); /* Disable interrupts */
  4544. +    save_flags_cli (flags); /* Disable interrupts */
  4545.      
  4546.      /*
  4547.       * First unlink the serial port from the IRQ chain...
  4548. @@ -1204,7 +1203,7 @@
  4549.      if (!tty || !info->xmit_buf)
  4550.          return;
  4551.  
  4552. -    save_flags(flags); cli();
  4553. +    save_flags_cli (flags);
  4554.      if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
  4555.          restore_flags(flags);
  4556.          return;
  4557. @@ -1228,7 +1227,7 @@
  4558.          !info->xmit_buf)
  4559.          return;
  4560.  
  4561. -    save_flags(flags); cli();
  4562. +    save_flags_cli (flags);
  4563.      info->IER |= UART_IER_THRI;
  4564.      serial_out(info, UART_IER, info->IER);
  4565.      restore_flags(flags);
  4566. @@ -1247,7 +1246,7 @@
  4567.      if (!tty || !info->xmit_buf || !tmp_buf)
  4568.          return 0;
  4569.          
  4570. -    save_flags(flags);
  4571. +    save_flags_cli (flags);
  4572.      while (1) {
  4573.          cli();        
  4574.          c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
  4575. @@ -1945,7 +1944,7 @@
  4576.      if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
  4577.          return;
  4578.      
  4579. -    save_flags(flags); cli();
  4580. +    save_flags_cli (flags);
  4581.      
  4582.      if (tty_hung_up_p(filp)) {
  4583.          restore_flags(flags);
  4584. @@ -2400,7 +2399,7 @@
  4585.      if (!port)
  4586.          return;
  4587.  
  4588. -    save_flags(flags); cli();
  4589. +    save_flags_cli (flags);
  4590.      
  4591.      /*
  4592.       * Do a simple existence test first; if we fail this, there's
  4593. @@ -2651,8 +2650,7 @@
  4594.      unsigned long flags;
  4595.      struct async_struct *info;
  4596.  
  4597. -    save_flags(flags);
  4598. -    cli();
  4599. +    save_flags_cli (flags);
  4600.      for (i = 0; i < NR_PORTS; i++) {
  4601.          if (rs_table[i].port == req->port)
  4602.              break;
  4603. @@ -2705,8 +2703,7 @@
  4604.      unsigned long flags;
  4605.      struct async_struct *info = &rs_table[line];
  4606.  
  4607. -    save_flags(flags);
  4608. -    cli();
  4609. +    save_flags_cli (flags);
  4610.      if (info->tty)
  4611.          tty_hangup(info->tty);
  4612.      info->type = PORT_UNKNOWN;
  4613. diff -urN linux.store/linux/arch/arm/drivers/char/serial6850.c linux/arch/arm/drivers/char/serial6850.c
  4614. --- linux.store/linux/arch/arm/drivers/char/serial6850.c    Thu Jan  1 01:00:00 1970
  4615. +++ linux/arch/arm/drivers/char/serial6850.c    Mon Mar 11 21:32:33 1996
  4616. @@ -0,0 +1,23 @@
  4617. +/*
  4618. + * Dummy serial functions
  4619. + *
  4620. + * Copyright (C) 1995, 1996 Russell King
  4621. + */
  4622. +
  4623. +#include <linux/errno.h>
  4624. +#include <linux/sched.h>
  4625. +#include <linux/serial.h>
  4626. +
  4627. +int rs_init (void)
  4628. +{
  4629. +    return 0;
  4630. +}
  4631. +
  4632. +int register_serial (struct serial_struct *dev)
  4633. +{
  4634. +    return -1;
  4635. +}
  4636. +
  4637. +void unregister_serial (int line)
  4638. +{
  4639. +}
  4640. diff -urN linux.store/linux/arch/arm/drivers/char/tty_io.c linux/arch/arm/drivers/char/tty_io.c
  4641. --- linux.store/linux/arch/arm/drivers/char/tty_io.c    Sun Mar  3 12:48:37 1996
  4642. +++ linux/arch/arm/drivers/char/tty_io.c    Mon Mar 11 23:57:46 1996
  4643. @@ -1252,8 +1252,7 @@
  4644.              return -ENOMEM;
  4645.          fa->magic = FASYNC_MAGIC;
  4646.          fa->fa_file = filp;
  4647. -        save_flags(flags);
  4648. -        cli();
  4649. +        save_flags_cli (flags);
  4650.          fa->fa_next = *fapp;
  4651.          *fapp = fa;
  4652.          restore_flags(flags);
  4653. @@ -1261,8 +1260,7 @@
  4654.      }
  4655.      if (!fa)
  4656.          return 0;
  4657. -    save_flags(flags);
  4658. -    cli();
  4659. +    save_flags_cli (flags);
  4660.      *fp = fa->fa_next;
  4661.      restore_flags(flags);
  4662.      kfree(fa);
  4663. diff -urN linux.store/linux/arch/arm/drivers/char/vc_screen.c linux/arch/arm/drivers/char/vc_screen.c
  4664. --- linux.store/linux/arch/arm/drivers/char/vc_screen.c    Sat Feb 24 18:12:00 1996
  4665. +++ linux/arch/arm/drivers/char/vc_screen.c    Sun Mar 10 15:26:14 1996
  4666. @@ -163,7 +163,7 @@
  4667.          org = screen_pos(cons, p);
  4668.          while (count-- > 0) {
  4669.              *org = (*org & 0xffffff00) | get_fs_byte(buf++);
  4670. -            ll_char_write (*org);
  4671. +/*            ll_write_char (,*org);*/
  4672.              org++;
  4673.          }
  4674.      } else {
  4675. diff -urN linux.store/linux/arch/arm/drivers/net/ether1.c linux/arch/arm/drivers/net/ether1.c
  4676. --- linux.store/linux/arch/arm/drivers/net/ether1.c    Sun Feb 18 09:28:09 1996
  4677. +++ linux/arch/arm/drivers/net/ether1.c    Mon Mar 11 22:34:57 1996
  4678. @@ -72,22 +72,41 @@
  4679.  static int ether1_manus[] = { 0x0000 };
  4680.  
  4681.  /* ------------------------------------------------------------------------- */
  4682. -#define ether1_inw(dev, addr, type, offset) ether1_inw_p (dev, addr + (int)(&((type *)0)->offset))
  4683. -#define ether1_outw(dev, val, addr, type, offset) ether1_outw_p (dev, val, addr + (int)(&((type *)0)->offset))
  4684. +
  4685. +#define DISABLEIRQS 1
  4686. +#define NORMALIRQS  0
  4687. +
  4688. +#define ether1_inw(dev, addr, type, offset, svflgs) ether1_inw_p (dev, addr + (int)(&((type *)0)->offset), svflgs)
  4689. +#define ether1_outw(dev, val, addr, type, offset, svflgs) ether1_outw_p (dev, val, addr + (int)(&((type *)0)->offset), svflgs)
  4690.  
  4691.  static inline unsigned short
  4692. -ether1_inw_p (struct device *dev, int addr)
  4693. +ether1_inw_p (struct device *dev, int addr, int svflgs)
  4694.  {
  4695. -    outb (addr >> 12, REG_PAGE);
  4696. +    unsigned long flags;
  4697. +    unsigned short ret;
  4698.  
  4699. -    return inw (ETHER1_RAM + ((addr & 4095) >> 1));
  4700. +    if (svflgs) {
  4701. +    save_flags_cli (flags);
  4702. +    }
  4703. +    outb (addr >> 12, REG_PAGE);
  4704. +    ret = inw (ETHER1_RAM + ((addr & 4095) >> 1));
  4705. +    if (svflgs)
  4706. +    restore_flags (flags);
  4707. +    return ret;
  4708.  }
  4709.  
  4710.  static inline void
  4711. -ether1_outw_p (struct device *dev, unsigned short val, int addr)
  4712. +ether1_outw_p (struct device *dev, unsigned short val, int addr, int svflgs)
  4713.  {
  4714. +    unsigned long flags;
  4715. +
  4716. +    if (svflgs) {
  4717. +    save_flags_cli (flags);
  4718. +    }
  4719.      outb (addr >> 12, REG_PAGE);
  4720.      outw (val, ETHER1_RAM + ((addr & 4095) >> 1));
  4721. +    if (svflgs)
  4722. +    restore_flags (flags);
  4723.  }
  4724.  
  4725.  static inline void *
  4726. @@ -423,7 +442,7 @@
  4727.  
  4728.      /* 586 should now unset iscp.busy */
  4729.      i = jiffies + HZ/2;
  4730. -    while (ether1_inw (dev, ISCP_ADDR, iscp_t, iscp_busy) == 1) {
  4731. +    while (ether1_inw (dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) {
  4732.      if (jiffies > i) {
  4733.          printk ("%s: can't initialise 82586: iscp is busy\n", dev->name);
  4734.          return 1;
  4735. @@ -432,7 +451,8 @@
  4736.  
  4737.      /* check status of commands that we issued */
  4738.      i += HZ/10;
  4739. -    while (((status = ether1_inw (dev, CFG_ADDR, cfg_t, cfg_status)) & STAT_COMPLETE) == 0) {
  4740. +    while (((status = ether1_inw (dev, CFG_ADDR, cfg_t, cfg_status, DISABLEIRQS))
  4741. +        & STAT_COMPLETE) == 0) {
  4742.      if (jiffies > i)
  4743.          break;
  4744.      }
  4745. @@ -444,7 +464,8 @@
  4746.      }
  4747.  
  4748.      i += HZ/10;
  4749. -    while (((status = ether1_inw (dev, SA_ADDR, sa_t, sa_status)) & STAT_COMPLETE) == 0) {
  4750. +    while (((status = ether1_inw (dev, SA_ADDR, sa_t, sa_status, DISABLEIRQS))
  4751. +        & STAT_COMPLETE) == 0) {
  4752.      if (jiffies > i)
  4753.          break;
  4754.      }
  4755. @@ -456,7 +477,8 @@
  4756.      }
  4757.  
  4758.      i += HZ/10;
  4759. -    while (((status = ether1_inw (dev, MC_ADDR, mc_t, mc_status)) & STAT_COMPLETE) == 0) {
  4760. +    while (((status = ether1_inw (dev, MC_ADDR, mc_t, mc_status, DISABLEIRQS))
  4761. +        & STAT_COMPLETE) == 0) {
  4762.      if (jiffies > i)
  4763.          break;
  4764.      }
  4765. @@ -468,7 +490,8 @@
  4766.      }
  4767.  
  4768.      i += HZ;
  4769. -    while (((status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_status)) & STAT_COMPLETE) == 0) {
  4770. +    while (((status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_status, DISABLE_IRQS))
  4771. +        & STAT_COMPLETE) == 0) {
  4772.      if (jiffies > i)
  4773.          break;
  4774.      }
  4775. @@ -478,7 +501,7 @@
  4776.      return 0;
  4777.      }
  4778.  
  4779. -    status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_result);
  4780. +    status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_result, DISABLEIRQS);
  4781.      if (status & TDR_XCVRPROB)
  4782.      printk ("%s: i/f failed tdr: transceiver problem\n", dev->name);
  4783.      else
  4784. @@ -680,6 +703,7 @@
  4785.      else {
  4786.      int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
  4787.      int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
  4788. +    unsigned long flags;
  4789.      tx_t tx;
  4790.      tbd_t tbd;
  4791.      nop_t nop;
  4792. @@ -703,15 +727,17 @@
  4793.      nop.nop_command = CMD_NOP;
  4794.      nop.nop_link = nopaddr;
  4795.  
  4796. +    save_flags_cli (flags);
  4797.      ether1_writebuffer (dev, &tx, txaddr, TX_SIZE);
  4798.      ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE);
  4799.      ether1_writebuffer (dev, skb->data, dataddr, len);
  4800.      ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE);
  4801.      tmp = priv->tx_link;
  4802.      priv->tx_link = nopaddr;
  4803. +    restore_flags (flags);
  4804.  
  4805.      /* now reset the previous nop pointer */
  4806. -    ether1_outw (dev, txaddr, tmp, nop_t, nop_link);
  4807. +    ether1_outw (dev, txaddr, tmp, nop_t, nop_link, DISABLEIRQS);
  4808.  
  4809.      /* handle transmit */
  4810.      dev->trans_start = jiffies;
  4811. @@ -743,8 +769,10 @@
  4812.      switch (nop.nop_command & CMD_MASK) {
  4813.      case CMD_TDR:
  4814.      /* special case */
  4815. -    if (ether1_inw (dev, SCB_ADDR, scb_t, scb_cbl_offset) != (unsigned short)I82586_NULL) {
  4816. -        ether1_outw (dev, SCB_CMDCUCSTART | SCB_CMDRXSTART, SCB_ADDR, scb_t, scb_command);
  4817. +    if (ether1_inw (dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
  4818. +                != (unsigned short)I82586_NULL) {
  4819. +        ether1_outw (dev, SCB_CMDCUCSTART | SCB_CMDRXSTART, SCB_ADDR, scb_t,
  4820. +        scb_command, NORMALIRQS);
  4821.          outb (CTRL_CA, REG_CONTROL);
  4822.      }
  4823.      priv->tx_tail = NOP_ADDR;
  4824. @@ -838,11 +866,11 @@
  4825.      rbd_t rbd;
  4826.  
  4827.      do {
  4828. -    status = ether1_inw (dev, priv->rx_head, rfd_t, rfd_status);
  4829. +    status = ether1_inw (dev, priv->rx_head, rfd_t, rfd_status, NORMALIRQS);
  4830.      if ((status & RFD_COMPLETE) == 0)
  4831.          break;
  4832.  
  4833. -    rbdaddr = ether1_inw (dev, priv->rx_head, rfd_t, rfd_rbdoffset);
  4834. +    rbdaddr = ether1_inw (dev, priv->rx_head, rfd_t, rfd_rbdoffset, NORMALIRQS);
  4835.      ether1_readbuffer (dev, &rbd, rbdaddr, RBD_SIZE);
  4836.  
  4837.      if ((rbd.rbd_status & (RBD_EOF | RBD_ACNTVALID)) == (RBD_EOF | RBD_ACNTVALID)) {
  4838. @@ -869,18 +897,18 @@
  4839.          priv->stats.rx_dropped ++;
  4840.      }
  4841.  
  4842. -    nexttail = ether1_inw (dev, priv->rx_tail, rfd_t, rfd_link);
  4843. +    nexttail = ether1_inw (dev, priv->rx_tail, rfd_t, rfd_link, NORMALIRQS);
  4844.      /* nexttail should be rx_head */
  4845.      if (nexttail != priv->rx_head)
  4846.          printk ("%s: receiver buffer chaining error (%04X != %04X)\n", dev->name, nexttail,
  4847.              priv->rx_head);
  4848. -    ether1_outw (dev, RFD_CMDEL | RFD_CMDSUSPEND, nexttail, rfd_t, rfd_command);
  4849. -    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_command);
  4850. -    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_status);
  4851. -    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_rbdoffset);
  4852. +    ether1_outw (dev, RFD_CMDEL | RFD_CMDSUSPEND, nexttail, rfd_t, rfd_command, NORMALIRQS);
  4853. +    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_command, NORMALIRQS);
  4854. +    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_status, NORMALIRQS);
  4855. +    ether1_outw (dev, 0, priv->rx_tail, rfd_t, rfd_rbdoffset, NORMALIRQS);
  4856.      
  4857.      priv->rx_tail = nexttail;
  4858. -    priv->rx_head = ether1_inw (dev, priv->rx_head, rfd_t, rfd_link);
  4859. +    priv->rx_head = ether1_inw (dev, priv->rx_head, rfd_t, rfd_link, NORMALIRQS);
  4860.      } while (1);
  4861.  }
  4862.  
  4863. @@ -898,10 +926,10 @@
  4864.  
  4865.      dev->interrupt = 1;
  4866.  
  4867. -    status = ether1_inw (dev, SCB_ADDR, scb_t, scb_status);
  4868. +    status = ether1_inw (dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS);
  4869.      if (status ) {
  4870.      ether1_outw (dev, status & (SCB_STRNR | SCB_STCNA | SCB_STFR | SCB_STCX),
  4871. -            SCB_ADDR, scb_t, scb_command);
  4872. +            SCB_ADDR, scb_t, scb_command, NORMALIRQS);
  4873.      outb (CTRL_CA | CTRL_ACK, REG_CONTROL);
  4874.      if (status & SCB_STCX) {
  4875.          ether1_xmit_done (dev);
  4876. @@ -909,8 +937,9 @@
  4877.      if (status & SCB_STCNA) {
  4878.          if (priv->resetting == 0)
  4879.          printk ("%s: CU went not ready ???\n", dev->name);
  4880. -        if (ether1_inw (dev, SCB_ADDR, scb_t, scb_cbl_offset) != (unsigned short)I82586_NULL) {
  4881. -        ether1_outw (dev, SCB_CMDCUCSTART, SCB_ADDR, scb_t, scb_command);
  4882. +        if (ether1_inw (dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
  4883. +                != (unsigned short)I82586_NULL) {
  4884. +        ether1_outw (dev, SCB_CMDCUCSTART, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
  4885.          outb (CTRL_CA, REG_CONTROL);
  4886.          }
  4887.          if (priv->resetting == 2)
  4888. @@ -921,7 +950,8 @@
  4889.      }
  4890.      if (status & SCB_STRNR) {
  4891.          printk ("%s: RU went not ready\n", dev->name);
  4892. -        printk ("RU ptr = %04X\n", ether1_inw (dev, SCB_ADDR, scb_t, scb_rfa_offset));
  4893. +        printk ("RU ptr = %04X\n", ether1_inw (dev, SCB_ADDR, scb_t, scb_rfa_offset,
  4894. +                    NORMALIRQS));
  4895.      }
  4896.      } else
  4897.          outb (CTRL_ACK, REG_CONTROL);
  4898. diff -urN linux.store/linux/arch/arm/drivers/net/ether3.c linux/arch/arm/drivers/net/ether3.c
  4899. --- linux.store/linux/arch/arm/drivers/net/ether3.c    Tue Mar  5 13:04:29 1996
  4900. +++ linux/arch/arm/drivers/net/ether3.c    Mon Mar 11 22:35:09 1996
  4901. @@ -3,7 +3,7 @@
  4902.   *
  4903.   * SEEQ nq8005 ethernet driver
  4904.   *
  4905. - * By Russell King.
  4906. + * By Russell King, with some suggestions from borris@ant.co.uk
  4907.   *
  4908.   * Changelog:
  4909.   *  29/02/96:    RMK    Won't pass packets that are from our ethernet address
  4910. @@ -182,7 +182,6 @@
  4911.  ether3_ramtest(struct device *dev, unsigned char byte)
  4912.  {
  4913.      unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL);
  4914. -    unsigned long flags;
  4915.      int i,ret=0;
  4916.      int max_errors = 4;
  4917.      int bad=-1;
  4918. @@ -190,9 +189,6 @@
  4919.      if (!buffer)
  4920.      return 1;
  4921.  
  4922. -    save_flags (flags);
  4923. -    cli ();
  4924. -
  4925.      memset (buffer, byte, RX_END);
  4926.      ether3_writebuffer (dev, buffer, 0, TX_END);
  4927.      ether3_writebuffer (dev, buffer+RX_START, RX_START, RX_LEN);
  4928. @@ -220,7 +216,6 @@
  4929.      if (bad != -1)
  4930.      printk (" - 0x10000\n");
  4931.      kfree (buffer);
  4932. -    restore_flags (flags);
  4933.  
  4934.      return ret;
  4935.  }
  4936. @@ -462,8 +457,7 @@
  4937.      dev->tbusy = 1;
  4938.      dev->start = 0;
  4939.  
  4940. -    save_flags (flags);
  4941. -    cli ();
  4942. +    save_flags_cli (flags);
  4943.  
  4944.      outw (CMD_RXOFF|CMD_TXOFF, REG_COMMAND);
  4945.      priv->regs.command = 0;
  4946. @@ -583,8 +577,7 @@
  4947.  
  4948.      thishdr |= htons (nextpacket);
  4949.  
  4950. -    save_flags(flags);
  4951. -    cli();
  4952. +    save_flags_cli (flags);
  4953.      ether3_writebuffer(dev, skb->data, thisdata, (length & 1) ? (length + 1) : length);
  4954.      ether3_writebuffer(dev, &nexthdr, -1, 4);
  4955.      ether3_ledincrementuse (dev);
  4956. @@ -631,17 +624,20 @@
  4957.  
  4958.          done = 0;
  4959.      status = inw(REG_STATUS);
  4960. -    outw ((status & (STAT_INTRX|STAT_INTTX|STAT_INTBUFWIN))
  4961. -        | priv->regs.command, REG_COMMAND);
  4962.  
  4963.      if (status & STAT_INTRX) { /* Got a packet(s). */
  4964. +        outw (CMD_ACKINTRX | priv->regs.command, REG_COMMAND);
  4965.          ether3_rx (dev, priv);
  4966.          done = 1;
  4967.      }
  4968.      if (status & STAT_INTTX) { /* Packets transmitted */
  4969. +        outw (CMD_ACKINTTX | priv->regs.command, REG_COMMAND);
  4970.          ether3_tx (dev, priv);
  4971.          done = 1;
  4972.      }
  4973. +    if (status & STAT_INTBUFWIN) { /* buffer window interrupt */
  4974. +        outw (CMD_ACKINTBUFWIN | priv->regs.command, REG_COMMAND);
  4975. +    }
  4976.      } while (-- boguscount && !done) ;
  4977.  
  4978.      dev->interrupt = 0;
  4979. @@ -685,10 +681,8 @@
  4980.      prev_recv_ptr = current_recv_ptr;
  4981.      ether3_readbuffer (dev, &p, current_recv_ptr, 16);
  4982.  
  4983. -    if ((p.rxhdr & RX_NEXT) == 0 || (p.rxhdr & RXSTAT_DONE) == 0
  4984. -        || (p.rxhdr & (RXHDR_CHAINCONTINUE|RXHDR_RECEIVE)) != RXHDR_CHAINCONTINUE)
  4985. +    if ((p.rxhdr & RX_NEXT) == 0 || (p.rxhdr & RXSTAT_DONE) == 0)
  4986.          break;
  4987. -
  4988.      current_recv_ptr = ntohs (p.rxhdr & RX_NEXT);
  4989.  
  4990.      /*
  4991. @@ -696,7 +690,10 @@
  4992.        */
  4993.      if (memcmp (dev->dev_addr, &p.src_addr, 6) == 0) {
  4994.          outw (current_recv_ptr >> 8, REG_RECVEND);
  4995. -        continue;
  4996. +        if (p.rxhdr & RXHDR_CHAINCONTINUE)
  4997. +        continue;
  4998. +        else
  4999. +        break;
  5000.      }
  5001.  
  5002.      if (p.rxhdr & (RXSTAT_OVERSIZE|RXSTAT_CRCERROR|RXSTAT_DRIBBLEERROR|RXSTAT_SHORTPACKET)) {
  5003. @@ -706,7 +703,10 @@
  5004.          if(p.rxhdr & RXSTAT_DRIBBLEERROR) priv->stats.rx_fifo_errors ++;
  5005.          if(p.rxhdr & RXSTAT_SHORTPACKET) priv->stats.rx_length_errors ++;
  5006.          outw (current_recv_ptr >> 8, REG_RECVEND);
  5007. -        continue;
  5008. +        if (p.rxhdr & RXHDR_CHAINCONTINUE)
  5009. +        continue;
  5010. +        else
  5011. +        break;
  5012.      }
  5013.  
  5014.      if (current_recv_ptr > prev_recv_ptr)
  5015. @@ -742,6 +742,8 @@
  5016.      skb->protocol = eth_type_trans(skb, dev);
  5017.      netif_rx (skb);
  5018.      priv->stats.rx_packets++;
  5019. +    if (!(p.rxhdr & RXHDR_CHAINCONTINUE))
  5020. +        break;
  5021.      }
  5022.      while (-- maxcnt);
  5023.  
  5024. diff -urN linux.store/linux/arch/arm/drivers/scsi/Makefile linux/arch/arm/drivers/scsi/Makefile
  5025. --- linux.store/linux/arch/arm/drivers/scsi/Makefile    Sat Feb 24 13:17:59 1996
  5026. +++ linux/arch/arm/drivers/scsi/Makefile    Wed Mar 13 22:57:35 1996
  5027. @@ -122,10 +122,10 @@
  5028.      $(LD) $(LD_RFLAG) -r -o $@ sd.o sd_ioctl.o
  5029.  
  5030.  oak_mod.o: oak.o
  5031. -    $(LD) $(LD_RFLAG) -r -o oak_mod.o oak.o `gcc --print-libgcc-file-name`
  5032. +    $(LD) $(LD_RFLAG) -r -o oak_mod.o oak.o $(GCCLIB)
  5033.  
  5034.  acornscsi_mod.o: acornscsi.o acornscsi-io.o
  5035. -    $(LD) $(LD_RFLAG) -r -o acornscsi_mod.o acornscsi.o acornscsi-io.o `gcc --print-libgcc-file-name`
  5036. +    $(LD) $(LD_RFLAG) -r -o acornscsi_mod.o acornscsi.o acornscsi-io.o $(GCCLIB)
  5037.  
  5038.  $(SYMTAB_OBJS): $(SYMTAB_OBJS:.o=.c)
  5039.  
  5040. diff -urN linux.store/linux/arch/arm/drivers/scsi/acornscsi.c linux/arch/arm/drivers/scsi/acornscsi.c
  5041. --- linux.store/linux/arch/arm/drivers/scsi/acornscsi.c    Sun Feb 11 09:32:31 1996
  5042. +++ linux/arch/arm/drivers/scsi/acornscsi.c    Mon Mar 11 22:35:55 1996
  5043. @@ -785,8 +785,7 @@
  5044.  
  5045.      dmac_write (instance, MASKREG, MASK_ON);
  5046.  
  5047. -    save_flags (flags);
  5048. -    cli ();
  5049. +    save_flags_cli (flags);
  5050.      ascmd = hostdata->connected;
  5051.      hostdata->connected = NULL;
  5052.  
  5053. diff -urN linux.store/linux/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile
  5054. --- linux.store/linux/arch/arm/kernel/Makefile    Sun Feb 11 09:32:37 1996
  5055. +++ linux/arch/arm/kernel/Makefile    Wed Mar 13 14:32:05 1996
  5056. @@ -17,6 +17,10 @@
  5057.          ioport.o arm.o setup.o time.o ecard.o sys-arm.o \
  5058.          dma.o
  5059.  
  5060. +ifeq ($(MACHINE),arc)
  5061. +  O_OBJS += oldlatches.o
  5062. +endif
  5063. +
  5064.  head.o: head.S $(TOPDIR)/include/linux/tasks.h
  5065.      $(CC) -D__ASSEMBLY__ -traditional -c $*.S -o $*.o
  5066.  
  5067. diff -urN linux.store/linux/arch/arm/kernel/dma.c linux/arch/arm/kernel/dma.c
  5068. --- linux.store/linux/arch/arm/kernel/dma.c    Sun Mar  3 13:02:49 1996
  5069. +++ linux/arch/arm/kernel/dma.c    Wed Mar 13 14:53:17 1996
  5070. @@ -15,6 +15,7 @@
  5071.  
  5072.  void enable_dma (unsigned int dmanr)
  5073.  {
  5074. +#ifdef CONFIG_BLK_DEV_FD
  5075.      if (dmanr == 2) {
  5076.          switch (dma_direction[dmanr]) {
  5077.          case 1: /* read */
  5078. @@ -42,8 +43,72 @@
  5079.          default:
  5080.          printk ("enable_dma: dma%d not initialised\n", dmanr);
  5081.          return;
  5082. -    }
  5083. -    }
  5084. +    } /* Direction switch */
  5085. +    }; /* dmanr == 2 */
  5086. +#endif
  5087. +#ifdef CONFIG_BLK_DEV_FD1772
  5088. +    switch (dmanr) {
  5089. +      case 0: /* Data DMA */
  5090. +        switch (dma_direction[dmanr]) {
  5091. +        case 1: /* read */
  5092. +                {
  5093. +            extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
  5094. +            extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
  5095. +            unsigned long flags;
  5096. +
  5097. +      /*printk("enable_dma fdc1772 data read\n");*/
  5098. +            save_flags(flags);
  5099. +            cliIF();
  5100. +            
  5101. +            memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
  5102. +                &fdc1772_dma_read_end - &fdc1772_dma_read);
  5103. +            fdc1772_setupdma(dma_count[dmanr],dma_address[dmanr]); /* Sets data pointer up */
  5104. +            enable_irq (16);
  5105. +            restore_flags(flags);
  5106. +        }
  5107. +        break;
  5108. +
  5109. +        case 0: /* write */
  5110. +            {
  5111. +            extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
  5112. +            extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
  5113. +            unsigned long flags;
  5114. +
  5115. +      /*printk("enable_dma fdc1772 data write\n");*/
  5116. +            save_flags(flags);
  5117. +            cliIF();
  5118. +            memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
  5119. +                &fdc1772_dma_write_end - &fdc1772_dma_write);
  5120. +            fdc1772_setupdma(dma_count[dmanr],dma_address[dmanr]); /* Sets data pointer up */
  5121. +            enable_irq (16);
  5122. +
  5123. +            restore_flags(flags);
  5124. +        }
  5125. +        break;
  5126. +
  5127. +            default:
  5128. +            printk ("enable_dma: dma%d not initialised\n", dmanr);
  5129. +            return;
  5130. +    } /* DMA direction switch */
  5131. +        break;
  5132. +
  5133. +      case 1: /* Command end FIQ - actually just sets a flag */
  5134. +      {
  5135. +    /* Need to build a branch at the FIQ address */
  5136. +    extern void fdc1772_comendhandler(void);
  5137. +    unsigned long flags;
  5138. +
  5139. +  /*printk("enable_dma fdc1772 command end FIQ\n");*/
  5140. +    save_flags(flags);
  5141. +    cliIF();
  5142. +    
  5143. +    *((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); /* B fdc1772_comendhandler */
  5144. +
  5145. +    restore_flags(flags);
  5146. +      };
  5147. +      break;
  5148. +    } /* dma number switch */
  5149. +#endif
  5150.  }
  5151.  
  5152.  void set_dma_mode (unsigned int dmanr, char mode)
  5153. @@ -79,9 +144,15 @@
  5154.  
  5155.  int get_dma_residue (unsigned int dmanr)
  5156.  {
  5157. +#ifdef CONFIG_BLK_DEV_FD
  5158.      extern int floppy_fiqresidual (void);
  5159.      if (dmanr == 2)
  5160.      return floppy_fiqresidual ();
  5161. +#endif
  5162. +#ifdef CONFIG_BLK_DEV_FD1772
  5163. +    extern unsigned int fdc1772_bytestogo;
  5164. +    if (dmanr == 0) return fdc1772_bytestogo; 
  5165. +#endif
  5166.  
  5167.      return -1;
  5168.  }
  5169. diff -urN linux.store/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c
  5170. --- linux.store/linux/arch/arm/kernel/ecard.c    Tue Mar  5 13:04:29 1996
  5171. +++ linux/arch/arm/kernel/ecard.c    Wed Mar 13 14:47:54 1996
  5172. @@ -20,12 +20,16 @@
  5173.  #include <asm/ecard.h>
  5174.  #include <asm/irq.h>
  5175.  #include <asm/io.h>
  5176. +#ifdef CONFIG_ARCH_ARC
  5177. +#include <asm/arch/oldlatches.h>
  5178. +#endif
  5179.  
  5180.  /*
  5181.   * from linux/arch/arm/kernel/irq.c
  5182.   */
  5183.  extern void do_fast_IRQ(int irq);
  5184.  extern unsigned char *ioc;
  5185. +int ecard_num_cards;
  5186.  
  5187.  #define MAX_ECARDS 4
  5188.  
  5189. @@ -36,7 +40,7 @@
  5190.  static char initialised = 0;
  5191.  static unsigned long kmem;
  5192.  
  5193. -void *ecard_malloc(int len)
  5194. +static void *ecard_malloc(int len)
  5195.  {
  5196.      int r;
  5197.  
  5198. @@ -53,8 +57,9 @@
  5199.  static void expansioncard_irq_noexpmask(int intr_no, struct pt_regs *regs)
  5200.  {
  5201.      int i;
  5202. +    const int num_cards = ecard_num_cards;
  5203.  
  5204. -    for(i=0; i<MAX_ECARDS; i++) {
  5205. +    for (i = 0; i < num_cards; i++) {
  5206.      if (expcard[i].r_found && expcard[i].r_claimed && expcard[i].irq) {
  5207.          if (expcard[i].r_irqmask) {
  5208.          if(expcard[i].r_irqaddr[0] & expcard[i].r_irqmask)
  5209. @@ -70,11 +75,12 @@
  5210.  static void expansioncard_irq_expmask (int intr_no, struct pt_regs *regs)
  5211.  {
  5212.      int i, ns = 0;
  5213. +    const int num_cards = ecard_num_cards;
  5214.  #if 0
  5215.      int oldexpmask;
  5216.  #endif
  5217.  
  5218. -    for (i = 0; i < MAX_ECARDS; i++) {
  5219. +    for (i = 0; i < num_cards; i++) {
  5220.      if (expmask[0] & (1 << i)) {
  5221.          if (expcard[i].r_found && expcard[i].r_claimed) {
  5222.          if (!expcard[i].r_irqmask || (expcard[i].r_irqaddr[0] & expcard[i].r_irqmask)) {
  5223. @@ -136,51 +142,73 @@
  5224.      }*/
  5225.  }
  5226.  
  5227. -static int ecard_checkirqhw(void)
  5228. +static int ecard_checkirqhw (void)
  5229.  {
  5230. -    int found;
  5231. -    expmask[4] = 0x00;
  5232. -    expmask[0] = 0xff;
  5233. -    found = (expmask[0] == 0xf0);
  5234. -    expmask[4] = 0xff;
  5235. -    return found;
  5236. +    int found;
  5237. +    expmask[4] = 0x00;
  5238. +    expmask[0] = 0xff;
  5239. +    found = (expmask[0] == 0xf0);
  5240. +    expmask[4] = 0xff;
  5241. +    return found;
  5242.  }
  5243.  
  5244. -static void ecard_readbytes(void *addr, struct expansion_card *ec, int off, int len, int useld)
  5245. +static void ecard_readbytes (void *addr, struct expansion_card *ec, int off, int len, int useld)
  5246.  {
  5247. -    extern int read_loader(int off, volatile unsigned char *pa, unsigned char *loader);
  5248. +    extern int ecard_loader_read(int off, volatile unsigned char *pa, unsigned char *loader);
  5249.    
  5250. -    unsigned char *a = (unsigned char *)addr;
  5251. +    unsigned char *a = (unsigned char *)addr;
  5252.  
  5253. -    if(!useld || !ec->r_loader) {
  5254. -        while(len--)
  5255. -            *a++ = ec->r_podaddr[(off++)*4];
  5256. -    } else {
  5257. -        while(len--) {
  5258. -            *(unsigned long *)0x108 = 0; /* hack for some loaders!!! */
  5259. -            *a++ = read_loader(off++, ec->r_podaddr, ec->r_loader);
  5260. -        }
  5261. +    if (!useld || !ec->r_loader) {
  5262. +    while(len--)
  5263. +        *a++ = ec->r_podaddr[(off++)*4];
  5264. +    } else {
  5265. +    while(len--) {
  5266. +        *(unsigned long *)0x108 = 0; /* hack for some loaders!!! */
  5267. +        *a++ = ecard_loader_read(off++, ec->r_podaddr, ec->r_loader);
  5268.      }
  5269. +    }
  5270.  }
  5271.  
  5272. -struct expansion_card *ecard_find(int cld, int num, int prod[], int manu[])
  5273. +/*
  5274. + * This is called to reset the loaders for each expansion card on reboot.
  5275. + *
  5276. + * This is required to make sure that the card is in the correct state
  5277. + * that RiscOS expects it to be.
  5278. + */
  5279. +void ecard_reset (int card)
  5280.  {
  5281. -    int i, j;
  5282. +    extern int ecard_loader_reset (volatile unsigned char *pa, unsigned char *loader);
  5283.  
  5284. -    for (i = 0 ; i<MAX_ECARDS; i++) {
  5285. -        if(expcard[i].r_found == 0 || expcard[i].r_claimed)
  5286. -            continue;
  5287. -        if((e_ecld(&expcard[i].ecld) & 0x78) != (cld & 0x78))
  5288. -            continue;
  5289. -        if((e_ecld(&expcard[i].ecld) & 0x78) != 0)
  5290. -            return &expcard[i];
  5291. -        for (j = 0; j<num; j++) {
  5292. -            if(e_prod(&expcard[i].ecld) == prod[j] &&
  5293. -                e_manu(&expcard[i].ecld) == manu[j])
  5294. -                return &expcard[i];
  5295. -        }
  5296. +    if (card >= ecard_num_cards)
  5297. +    return;
  5298. +    
  5299. +    if (card < 0) {
  5300. +    for (card = 0; card < ecard_num_cards; card++)
  5301. +        if (expcard[card].r_loader)
  5302. +        ecard_loader_reset (expcard[card].r_podaddr, expcard[card].r_loader);
  5303. +    } else
  5304. +    if (expcard[card].r_loader)
  5305. +        ecard_loader_reset (expcard[card].r_podaddr, expcard[card].r_loader);
  5306. +}
  5307. +
  5308. +struct expansion_card *ecard_find (int cld, int num, int prod[], int manu[])
  5309. +{
  5310. +    int i, j;
  5311. +
  5312. +    for (i = 0 ; i < ecard_num_cards; i++) {
  5313. +    if(expcard[i].r_found == 0 || expcard[i].r_claimed)
  5314. +        continue;
  5315. +    if((e_ecld(&expcard[i].ecld) & 0x78) != (cld & 0x78))
  5316. +        continue;
  5317. +    if((e_ecld(&expcard[i].ecld) & 0x78) != 0)
  5318. +        return &expcard[i];
  5319. +    for (j = 0; j<num; j++) {
  5320. +        if (e_prod(&expcard[i].ecld) == prod[j] &&
  5321. +        e_manu(&expcard[i].ecld) == manu[j])
  5322. +            return &expcard[i];
  5323.      }
  5324. -    return NULL;
  5325. +    }
  5326. +    return NULL;
  5327.  }
  5328.  
  5329.  int ecard_readchunk(struct chunk_dir *cd, struct expansion_card *ec, int id, int num)
  5330. @@ -230,28 +258,37 @@
  5331.  unsigned long ecard_init(unsigned long my_kmem)
  5332.  {
  5333.      int i;
  5334. +
  5335.      kmem = (my_kmem | 3) + 1;
  5336. +
  5337.      initialised = 0;
  5338. +    ecard_num_cards = 4;
  5339.  
  5340. -    for (i=0; i<MAX_ECARDS; i++) {
  5341. +    if (ecard_num_cards > MAX_ECARDS)
  5342. +    ecard_num_cards = MAX_ECARDS;
  5343. +
  5344. +    for (i = 0; i < ecard_num_cards; i++) {
  5345.      expcard[i].r_claimed = 0;
  5346.      expcard[i].r_found = 0;
  5347.      }
  5348.  
  5349. +    if (ecard_num_cards == 0)
  5350. +    return kmem;
  5351. +
  5352.      if (ecard_checkirqhw()) {
  5353.      have_expmask = 0xff;
  5354.      printk("Expansion card interrupt management hardware found\n");
  5355.      }
  5356.  
  5357. -    if (request_irq(IRQ_EXPANSIONCARD, have_expmask ? expansioncard_irq_expmask :
  5358. +    if (request_irq (IRQ_EXPANSIONCARD, have_expmask ? expansioncard_irq_expmask :
  5359.          expansioncard_irq_noexpmask, 0, "expansion cards") != 0) {
  5360. -    printk("Could not allocate interrupt for expansion cards\n");
  5361. +    printk ("Could not allocate interrupt for expansion cards\n");
  5362.      return kmem;
  5363.      }
  5364.      
  5365.      printk("Searching for expansion cards:");
  5366.  
  5367. -    for (i=0; i<MAX_ECARDS; i++) {
  5368. +    for (i = 0; i < ecard_num_cards; i++) {
  5369.      struct expansion_card *ec;
  5370.          
  5371.      ec = &expcard[i];
  5372. @@ -262,7 +299,7 @@
  5373.      ec->irq = 0;
  5374.      ec->fiq = 0;
  5375.          
  5376. -    ecard_readbytes(&ec->ecld, ec, 0, 16, 0);
  5377. +    ecard_readbytes (&ec->ecld, ec, 0, 16, 0);
  5378.          
  5379.      if (ec->ecld.r_ecld & 2) {
  5380.          have_expmask &= ~(1<<i);
  5381. @@ -306,5 +343,11 @@
  5382.  
  5383.  unsigned long bios32_init(unsigned long start_mem, unsigned long end_mem)
  5384.  {
  5385. -    return ecard_init(start_mem);
  5386. +    unsigned long mem;
  5387. +
  5388. +    mem = ecard_init(start_mem);
  5389. +
  5390. +#ifdef CONFIG_ARCH_ARC
  5391. +    oldlatch_init ();
  5392. +#endif
  5393.  }
  5394. diff -urN linux.store/linux/arch/arm/kernel/head.S linux/arch/arm/kernel/head.S
  5395. --- linux.store/linux/arch/arm/kernel/head.S    Sun Mar  3 13:03:43 1996
  5396. +++ linux/arch/arm/kernel/head.S    Thu Mar 14 23:26:08 1996
  5397. @@ -67,39 +67,32 @@
  5398.  @        4156025X = ARM 250
  5399.  @        4156020X = ARM 2
  5400.  @
  5401. -        adr    r0, undef_instr - 12
  5402. -        mov    r2, #4
  5403. -        mov    r3, #0xea000000
  5404. -        orr    r0, r3, r0, lsr #2
  5405. -        str    r0, [r2]
  5406. -
  5407. -        mrc    15, 0, r0, c0, c0
  5408. -
  5409. -continue:
  5410. +        adr    r3, undef_instr - 12
  5411. +        mov    r2, #0
  5412. +        mov    r0, #0xea000000
  5413. +        orr    r3, r0, r3, lsr #2
  5414. +        str    r3, [r2, #4]
  5415. +
  5416. +        ldr    r3, arm2_id
  5417. +        swp    r0, r0, [r2]        @ check for swp - if it can't do it, then it
  5418. +        ldr    r3, arm250_id        @ must be ARM2
  5419. +        mrc    15, 0, r0, c0, c0    @ check for CP#15 - if it can't do it, then ARM250
  5420. +        mov    r3, r0
  5421. +continue:    ldr    r0, [pc, #LC4 - . - 8]
  5422. +        str    r3, [r0]
  5423.  @
  5424.  @ Make undefined instr vector point to itself (endless loop)
  5425.  @
  5426. +        mov    r3, #0xeb000000
  5427.          sub    r3, r3, #2
  5428. -        orr    r3, r3, #0xeb000000
  5429. -        str    r3, [r2]
  5430. -        ldr    r3, [pc, #LC4 - . - 8]
  5431. -        str    r0, [r3]
  5432. +        mov    r2, #0
  5433. +        str    r3, [r2, #4]
  5434.          mov    fp, #0
  5435.          b    _start_kernel
  5436.  @
  5437. -@ IF we come in here from the mrc instruction, then we have an ARM2/250
  5438. +@ IF we come in here then one of the swp / mrc instructions must have aborted - jum
  5439.  @
  5440. -undef_instr:    adr    r0, undef_instr2 - 12
  5441. -        orr    r0, r3, r0, lsr #2
  5442. -        str    r0, [r2], #4
  5443. -        swpb    r0, r0, [r2]
  5444. -        ldr     r0, arm250_id
  5445. -        b    continue
  5446. -
  5447. -arm250_id:    .long    0x41560250
  5448. -
  5449. -undef_instr2:    ldr    r0, arm2_id
  5450. -        b    continue
  5451. +undef_instr:    b    continue
  5452.  
  5453.  arm2_id:    .long    0x41560200
  5454. -
  5455. +arm250_id:    .long    0x41560250
  5456. diff -urN linux.store/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c
  5457. --- linux.store/linux/arch/arm/kernel/irq.c    Sun Mar  3 13:04:56 1996
  5458. +++ linux/arch/arm/kernel/irq.c    Wed Mar 13 15:12:17 1996
  5459. @@ -51,8 +51,12 @@
  5460.      extern void ecard_disableirq (unsigned int);
  5461.      unsigned long flags;
  5462.  
  5463. +#ifdef cliIF
  5464.      save_flags(flags);
  5465. -    cli();
  5466. +    cliIF();
  5467. +#else
  5468. +    save_flags_cli (flags);
  5469. +#endif
  5470.  
  5471.      enabled_irqs &= ~(1 << irq_nr);
  5472.  
  5473. @@ -75,8 +79,12 @@
  5474.      extern void ecard_enableirq (unsigned int);
  5475.      unsigned long flags;
  5476.  
  5477. -    save_flags(flags);
  5478. -    cli();
  5479. +#ifdef cliIF
  5480. +    save_flags (flags);
  5481. +    cliIF();
  5482. +#else
  5483. +    save_flags_cli (flags);
  5484. +#endif
  5485.  
  5486.      enabled_irqs |= 1 << irq_nr;
  5487.  
  5488. diff -urN linux.store/linux/arch/arm/kernel/oldlatches.c linux/arch/arm/kernel/oldlatches.c
  5489. --- linux.store/linux/arch/arm/kernel/oldlatches.c    Thu Jan  1 01:00:00 1970
  5490. +++ linux/arch/arm/kernel/oldlatches.c    Mon Mar 11 23:27:12 1996
  5491. @@ -0,0 +1,47 @@
  5492. +/* Support for the latches on the old Archimedes which control the floppy,
  5493. +   hard disc and printer
  5494. +
  5495. +   (c) David Alan Gilbert 1995/1996
  5496. +
  5497. +*/
  5498. +#include <linux/config.h>
  5499. +#include <linux/kernel.h>
  5500. +
  5501. +#include <asm/machdep.h>
  5502. +#include <asm/io.h>
  5503. +
  5504. +/* They are static so that everyone who accesses them has to go through here */
  5505. +static unsigned char LatchACopy;
  5506. +static unsigned char LatchBCopy;
  5507. +
  5508. +#define LATCHAADDR 0x3250040
  5509. +#define LATCHBADDR 0x3250018
  5510. +
  5511. +/* newval=(oldval & ~mask)|newdata */
  5512. +void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
  5513. +{
  5514. +  LatchACopy=(LatchACopy & ~mask)|newdata;
  5515. +  outb(LatchACopy,(LATCHAADDR >> 2));
  5516. +#ifdef DEBUG
  5517. +  printk("oldlatch_A:0x%2x\n",LatchACopy);
  5518. +#endif
  5519. +
  5520. +};
  5521. +
  5522. +/* newval=(oldval & ~mask)|newdata */
  5523. +void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
  5524. +{
  5525. +  LatchBCopy=(LatchBCopy & ~mask)|newdata;
  5526. +  outb(LatchBCopy,(LATCHBADDR >> 2));
  5527. +#ifdef DEBUG
  5528. +  printk("oldlatch_B:0x%2x\n",LatchBCopy);
  5529. +#endif
  5530. +};
  5531. +
  5532. +void oldlatch_init(void)
  5533. +{
  5534. +  printk("oldlatch: init\n");
  5535. +  oldlatch_aupdate(0xff,0xff);
  5536. +  oldlatch_bupdate(0xff,0x8); /* Thats no FDC reset...*/
  5537. +  return ;
  5538. +}
  5539. diff -urN linux.store/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
  5540. --- linux.store/linux/arch/arm/kernel/process.c    Tue Mar  5 13:04:29 1996
  5541. +++ linux/arch/arm/kernel/process.c    Fri Mar  8 22:36:31 1996
  5542. @@ -60,12 +60,17 @@
  5543.  
  5544.  void hard_reset_now(void)
  5545.  {
  5546. +    extern void ecard_reset (int card);
  5547. +    extern unsigned long arm_id;
  5548. +    /*
  5549. +     * reset all expansion cards
  5550. +     */
  5551. +    ecard_reset (-1);
  5552.      /*
  5553.       * If we are using the ARM3, turn off the cache!
  5554.       * otherwise we get problems with 256 colour modes
  5555.       * and floppy drive accesses in RiscOS.
  5556.       */
  5557. -    extern unsigned long arm_id;
  5558.      if ((arm_id & 0xfffffff0) == 0x41560300)
  5559.      __asm__ __volatile__ ("mcr 15, 0, %0, c2, c0": : "r" (2));
  5560.  
  5561. diff -urN linux.store/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
  5562. --- linux.store/linux/arch/arm/kernel/setup.c    Thu Mar 14 23:33:06 1996
  5563. +++ linux/arch/arm/kernel/setup.c    Thu Mar 14 23:09:24 1996
  5564. @@ -30,6 +30,7 @@
  5565.  #define F_MEMC   (1<<0)
  5566.  #define F_MMU    (1<<1)
  5567.  #define F_32BIT  (1<<2)
  5568. +#define F_CACHE  (1<<3)
  5569.  #define F_IOEB   (1<<31)
  5570.  
  5571.  struct drive_info_struct { char dummy[32]; } drive_info;
  5572. @@ -74,7 +75,7 @@
  5573.  } armidlist[] = {
  5574.      { 0x41560200, 0xfffffff0, F_MEMC    , 0x03000000    , "ARM",    "arm2"        },
  5575.      { 0x41560250, 0xfffffff0, F_MEMC    , 0x03000000    , "ARM",    "arm250"    },
  5576. -    { 0x41560300, 0xfffffff0, F_MEMC    , 0x03000000    , "ARM",    "arm3"        },
  5577. +    { 0x41560300, 0xfffffff0, F_MEMC|F_CACHE, 0x03000000    , "ARM",    "arm3"        },
  5578.      { 0x41560610, 0xfffffff0, F_MMU|F_32BIT    , 0        , "ARM",    "arm610"    },
  5579.      { 0x44450000, 0xffff0000, F_MMU        , 0        , "DEC",    "SA-1"        },
  5580.      { 0x00000000, 0x00000000, 0        , 0        , "***",    "*unknown*"    }
  5581. @@ -96,7 +97,9 @@
  5582.  extern int bytes_per_char_h;
  5583.  extern int bytes_per_char_v;
  5584.  extern char arc_hd_files[8][128];
  5585. +#ifdef CONFIG_BLK_DEV_HD
  5586.  extern int no_hds;
  5587. +#endif
  5588.  extern int ramdisk_size;
  5589.  extern int root_mountflags;
  5590.  extern int _etext, _edata, _end;
  5591. @@ -140,7 +143,7 @@
  5592.  
  5593.      check_ioeb_present();
  5594.  
  5595. -    if ((arm_id & 0x0000fff0) == 0x300) {
  5596. +    if (armidlist[armidindex].features & F_CACHE) {
  5597.          __asm__ __volatile__("
  5598.          mcr    15, 0, %0, c3, c0
  5599.          mcr    15, 0, %1, c4, c0
  5600. @@ -150,7 +153,7 @@
  5601.          " : : "r" (0x000e7fff), "r" (0x000e7fff), "r" (0xf0000000), "r" (3));
  5602.      } else {
  5603.          /* ok, so this is a bit dirty... Self modifing code! */
  5604. -        extern unsigned long *arm3_flushcache;
  5605. +        extern unsigned long arm3_flushcache[2];
  5606.          arm3_flushcache[0] = arm3_flushcache[1];
  5607.      }
  5608.  
  5609. @@ -165,8 +168,9 @@
  5610.      ORIG_VIDEO_COLS = params->video_num_cols;
  5611.      ORIG_VIDEO_LINES = params->video_num_rows;
  5612.      memc_ctrl_reg = params->memc_control_reg;
  5613. +#ifdef CONFIG_BLK_DEV_HD
  5614.      no_hds = (params->adfsdrives >> 6) & 3;
  5615. -
  5616. +#endif
  5617.      aux_device_present = 0;
  5618.      memory_end = 0x02000000 + params->page_size * params->nr_pages;
  5619.      ramdisk_size = params->ramdisk_size;
  5620. diff -urN linux.store/linux/arch/arm/kernel/sys-arm.c linux/arch/arm/kernel/sys-arm.c
  5621. --- linux.store/linux/arch/arm/kernel/sys-arm.c    Tue Mar  5 13:04:29 1996
  5622. +++ linux/arch/arm/kernel/sys-arm.c    Wed Mar 13 22:19:33 1996
  5623. @@ -10,6 +10,7 @@
  5624.   */
  5625.  
  5626.  #include <linux/config.h>
  5627. +#include <linux/module.h>
  5628.  #include <linux/errno.h>
  5629.  #include <linux/sched.h>
  5630.  #include <linux/mm.h>
  5631. @@ -182,7 +183,7 @@
  5632.  asmlinkage int
  5633.  sys_arm_init_module (char *module_name, char *code, unsigned codesize, unsigned long *__p)
  5634.  {
  5635. -    extern int sys_init_module (char *, char *, unsigned, struct mod_routes *,
  5636. +    extern int sys_init_module (char *, char *, unsigned, struct mod_routines *,
  5637.              struct symbol_table *);
  5638.      return sys_init_module (module_name, code, codesize, (struct mod_routines *)__p[0],
  5639.              (struct symbol_table *)__p[1]);
  5640. diff -urN linux.store/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
  5641. --- linux.store/linux/arch/arm/kernel/time.c    Sun Mar  3 13:07:50 1996
  5642. +++ linux/arch/arm/kernel/time.c    Wed Mar 13 12:27:14 1996
  5643. @@ -31,47 +31,46 @@
  5644.  
  5645.  unsigned long do_dummy_gettimeoffset(void)
  5646.  {
  5647. -    return 0;
  5648. +    return 0;
  5649.  }
  5650.  
  5651.  static unsigned long (*do_gettimeoffset)(void) = do_dummy_gettimeoffset;
  5652.  
  5653.  void do_gettimeofday(struct timeval *tv)
  5654.  {
  5655. -    unsigned long flags;
  5656. +    unsigned long flags;
  5657.  
  5658. -    save_flags (flags);
  5659. -    cli();
  5660. -    *tv = xtime;
  5661. -    tv->tv_usec += do_gettimeoffset();
  5662. -    if (tv->tv_usec >= 1000000) {
  5663. -        tv->tv_usec -= 1000000;
  5664. -        tv->tv_sec++;
  5665. -    }
  5666. -    restore_flags(flags);
  5667. +    save_flags_cli (flags);
  5668. +    *tv = xtime;
  5669. +    tv->tv_usec += do_gettimeoffset();
  5670. +    if (tv->tv_usec >= 1000000) {
  5671. +    tv->tv_usec -= 1000000;
  5672. +    tv->tv_sec++;
  5673. +    }
  5674. +    restore_flags(flags);
  5675.  }
  5676.  
  5677.  void do_settimeofday(struct timeval *tv)
  5678.  {
  5679. -    cli();
  5680. -    /* This is revolting. We need to set the xtime.tv_usec
  5681. -     * correctly. However, the value in this location is
  5682. -     * is value at the last tick.
  5683. -     * Discover what correction gettimeofday
  5684. -     * would have done, and then undo it!
  5685. -     */
  5686. -    tv->tv_usec -= do_gettimeoffset();
  5687. -
  5688. -    if (tv->tv_usec < 0) {
  5689. -        tv->tv_usec += 1000000;
  5690. -        tv->tv_sec--;
  5691. -    }
  5692. -
  5693. -    xtime = *tv;
  5694. -    time_state = TIME_BAD;
  5695. -    time_maxerror = 0x70000000;
  5696. -    time_esterror = 0x70000000;
  5697. -    sti();
  5698. +    cli ();
  5699. +    /* This is revolting. We need to set the xtime.tv_usec
  5700. +     * correctly. However, the value in this location is
  5701. +     * is value at the last tick.
  5702. +     * Discover what correction gettimeofday
  5703. +     * would have done, and then undo it!
  5704. +     */
  5705. +    tv->tv_usec -= do_gettimeoffset();
  5706. +
  5707. +    if (tv->tv_usec < 0) {
  5708. +    tv->tv_usec += 1000000;
  5709. +    tv->tv_sec--;
  5710. +    }
  5711. +
  5712. +    xtime = *tv;
  5713. +    time_state = TIME_BAD;
  5714. +    time_maxerror = 0x70000000;
  5715. +    time_esterror = 0x70000000;
  5716. +    sti ();
  5717.  }
  5718.  
  5719.  /*
  5720. @@ -83,8 +82,8 @@
  5721.   */
  5722.  int set_rtc_mmss(unsigned long nowtime)
  5723.  {
  5724. -  int retval = 0;
  5725. -  return retval;
  5726. +    int retval = 0;
  5727. +    return retval;
  5728.  }
  5729.  
  5730.  /* last time the cmos clock got updated */
  5731. @@ -96,19 +95,20 @@
  5732.   */
  5733.  static inline void timer_interrupt(int irq, struct pt_regs *regs)
  5734.  {
  5735. -    do_timer(regs);
  5736. +    do_timer(regs);
  5737.  
  5738. -    /* If we have an externally synchronized linux clock, then update
  5739. -     * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
  5740. -     * called as close as possible to 500 ms before the new second starts.
  5741. -     */
  5742. -    if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
  5743. +    /* If we have an externally synchronized linux clock, then update
  5744. +     * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
  5745. +     * called as close as possible to 500 ms before the new second starts.
  5746. +     */
  5747. +    if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
  5748.          xtime.tv_usec > 50000 - (tick >> 1) &&
  5749. -        xtime.tv_usec < 50000 + (tick >> 1))
  5750. -      if (set_rtc_mmss(xtime.tv_sec) == 0)
  5751. +        xtime.tv_usec < 50000 + (tick >> 1)) {
  5752. +    if (set_rtc_mmss(xtime.tv_sec) == 0)
  5753.          last_rtc_update = xtime.tv_sec;
  5754. -      else
  5755. +    else
  5756.          last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
  5757. +    }
  5758.  }
  5759.  
  5760.  /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  5761. @@ -130,11 +130,11 @@
  5762.      unsigned int day, unsigned int hour,
  5763.      unsigned int min, unsigned int sec)
  5764.  {
  5765. -    if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
  5766. -        mon += 12;    /* Puts Feb last since it has leap day */
  5767. -        year -= 1;
  5768. -    }
  5769. -    return (((
  5770. +    if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
  5771. +    mon += 12;    /* Puts Feb last since it has leap day */
  5772. +    year -= 1;
  5773. +    }
  5774. +    return (((
  5775.          (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
  5776.            year*365 - 719499
  5777.          )*24 + hour /* now have hours */
  5778. @@ -144,30 +144,30 @@
  5779.  
  5780.  void time_init(void)
  5781.  {
  5782. -    unsigned int year, mon, day, hour, min, sec;
  5783. -    char buf[8];
  5784. -    extern int iic_control(unsigned char, int, char *, int);
  5785. -
  5786. -    iic_control(0xa0, 2, buf, 5);
  5787. -    sec = buf[0];
  5788. -    min = buf[1];
  5789. -    hour= buf[2];
  5790. -    day = buf[3] & 0x3f;
  5791. -    mon = buf[4] & 0x1f;
  5792. -    iic_control(0xa0, 0xc0, buf, 1);
  5793. -    year= buf[0];
  5794. -    BCD_TO_BIN(sec);
  5795. -    BCD_TO_BIN(min);
  5796. -    BCD_TO_BIN(hour);
  5797. -    BCD_TO_BIN(day);
  5798. -    BCD_TO_BIN(mon);
  5799. -
  5800. -    if ((year += 1900) < 1970)
  5801. -        year += 100;
  5802. -    xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
  5803. -    xtime.tv_usec = 0;
  5804. +    unsigned int year, mon, day, hour, min, sec;
  5805. +    char buf[8];
  5806. +    extern int iic_control(unsigned char, int, char *, int);
  5807. +
  5808. +    iic_control(0xa0, 2, buf, 5);
  5809. +    sec = buf[0];
  5810. +    min = buf[1];
  5811. +    hour= buf[2];
  5812. +    day = buf[3] & 0x3f;
  5813. +    mon = buf[4] & 0x1f;
  5814. +    iic_control(0xa0, 0xc0, buf, 1);
  5815. +    year= buf[0];
  5816. +    BCD_TO_BIN(sec);
  5817. +    BCD_TO_BIN(min);
  5818. +    BCD_TO_BIN(hour);
  5819. +    BCD_TO_BIN(day);
  5820. +    BCD_TO_BIN(mon);
  5821. +
  5822. +    if ((year += 1900) < 1970)
  5823. +    year += 100;
  5824. +    xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
  5825. +    xtime.tv_usec = 0;
  5826.  
  5827. -    if (request_irq(TIMER_IRQ, timer_interrupt, 0, "timer") != 0)
  5828. -        panic("Could not allocate timer IRQ!");
  5829. +    if (request_irq(IRQ_TIMER0, timer_interrupt, 0, "timer") != 0)
  5830. +    panic("Could not allocate timer IRQ!");
  5831.  }
  5832.  
  5833. diff -urN linux.store/linux/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile
  5834. --- linux.store/linux/arch/arm/lib/Makefile    Sun Feb 11 09:32:40 1996
  5835. +++ linux/arch/arm/lib/Makefile    Tue Mar 12 13:36:52 1996
  5836. @@ -1,8 +1,22 @@
  5837. +#
  5838. +# linux/arch/arm/lib/Makefile
  5839. +#
  5840. +# Copyright (C) 1995, 1996 Russell King
  5841. +#
  5842. +
  5843.  O_TARGET := lib.o
  5844.  O_OBJS   := backtrace.o bitops.o delay.o irqs.o \
  5845.      ll_char_wr.o io.o segment.o system.o traps.o ioc.o \
  5846.      calls.o prints.o memfastset.o fp_support.o string.o \
  5847.      floppydma.o
  5848. +
  5849. +ifdef CONFIG_BLK_DEV_FD1772
  5850. +O_OBJS += fd1772.o
  5851. +endif
  5852. +
  5853. +ifdef CONFIG_BLK_DEV_XD
  5854. +O_OBJS += mfm.o
  5855. +endif
  5856.  
  5857.  ifdef CONFIG_INET
  5858.  O_OBJS += iputils.o
  5859. diff -urN linux.store/linux/arch/arm/lib/constants.h.sample linux/arch/arm/lib/constants.h.sample
  5860. --- linux.store/linux/arch/arm/lib/constants.h.sample    Thu Jan  1 01:00:00 1970
  5861. +++ linux/arch/arm/lib/constants.h.sample    Tue Mar  5 14:57:16 1996
  5862. @@ -0,0 +1,20 @@
  5863. +/*
  5864. + *  contants.h generated by getconstants
  5865. + * DO NOT EDIT!
  5866. + */
  5867. +#define _current    _current_set
  5868. +#define PAGE_PRESENT    1
  5869. +#define PAGE_RW    2
  5870. +#define PAGE_USER    4
  5871. +#define PAGE_ACCESSED    32
  5872. +#define PAGE_DIRTY    64
  5873. +#define TSK_MM    744
  5874. +#define MM_PGDIR    4
  5875. +#define TSS_UREGS    512
  5876. +#define TSS_SREGS    532
  5877. +#define TSS_FPESAVE    576
  5878. +#define SYS_execve    9437195
  5879. +#define SYS_sigreturn    9437303
  5880. +#define KSWI_BASE    0x900000
  5881. +#define KSWI_SYS_BASE    0x9F0000
  5882. +#define SYS_ERROR0    0x9F0000
  5883. diff -urN linux.store/linux/arch/arm/lib/fd1772.S linux/arch/arm/lib/fd1772.S
  5884. --- linux.store/linux/arch/arm/lib/fd1772.S    Thu Jan  1 01:00:00 1970
  5885. +++ linux/arch/arm/lib/fd1772.S    Mon Mar 11 23:02:11 1996
  5886. @@ -0,0 +1,98 @@
  5887. +@ Code for DMA with the 1772 fdc
  5888. +.text
  5889. +
  5890. +
  5891. +_fdc1772_fiqdata:
  5892. +@ Number of bytes left to DMA
  5893. +  .global _fdc1772_bytestogo
  5894. +_fdc1772_bytestogo:
  5895. +  .word 0
  5896. +@ Place to put/get data from in DMA
  5897. +  .global _fdc1772_dataaddr
  5898. +_fdc1772_dataaddr:
  5899. +  .word 0
  5900. +  
  5901. +  .global _fdc1772_fdc_int_done
  5902. +_fdc1772_fdc_int_done:
  5903. +  .word 0
  5904. +  .global _fdc1772_comendstatus
  5905. +_fdc1772_comendstatus:
  5906. +  .word 0
  5907. +
  5908. +@ We hang this off DMA channel 1
  5909. +    .global _fdc1772_comendhandler
  5910. +_fdc1772_comendhandler:
  5911. +  mov      r8,#0x3200000
  5912. +  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  5913. +  tst      r9,#2
  5914. +  subeqs   pc,r14,#4
  5915. +  mov      r9,#0x3200000
  5916. +  orr      r9,r9,#0x10000   @ FDC base
  5917. +  adr      r8,_fdc1772_fdc_int_done
  5918. +  ldrb     r10,[r9,#0]  @ FDC status
  5919. +  mov      r9,#1        @ Got a FIQ flag
  5920. +  stmia    r8,{r9,r10}
  5921. +  subs     pc,r14,#4
  5922. +
  5923. +
  5924. +    .global _fdc1772_dma_read
  5925. +_fdc1772_dma_read:
  5926. +  mov      r8,#0x3200000
  5927. +  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  5928. +  tst      r9,#1
  5929. +  beq      _fdc1772_dma_read_notours
  5930. +  orr      r8,r8,#0x10000   @ FDC base
  5931. +  ldrb     r10,[r8,#0xc]   @ Read from FDC data reg (also clears interrupt)
  5932. +  ldmia    r11,{r8,r9}
  5933. +  subs     r8,r8,#1        @ One less byte to go
  5934. +  @ If there was somewhere for this data to go then store it and update pointers
  5935. +  strplb   r10,[r9],#1     @ Store the data and increment the pointer
  5936. +  stmplia  r11,{r8,r9}     @ Update count/pointers
  5937. +  @ Handle any other interrupts if there are any
  5938. +_fdc1772_dma_read_notours:
  5939. +  @ Cant branch because this code has been copied down to the FIQ vector
  5940. +  ldr pc,[pc,#-4]
  5941. +  .word _fdc1772_comendhandler
  5942. +  .global _fdc1772_dma_read_end
  5943. +_fdc1772_dma_read_end:
  5944. +
  5945. +    .global _fdc1772_dma_write
  5946. +_fdc1772_dma_write:
  5947. +  mov      r8,#0x3200000
  5948. +  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  5949. +  tst      r9,#1
  5950. +  beq      _fdc1772_dma_write_notours
  5951. +  orr      r8,r8,#0x10000   @ FDC base
  5952. +  ldmia    r11,{r9,r10}
  5953. +  subs     r9,r9,#1        @ One less byte to go
  5954. +  @ If there really is some data then get it, store it and update count
  5955. +  ldrplb   r12,[r10],#1
  5956. +  strplb   r12,[r8,#0xc]   @ write it to FDC data reg
  5957. +  stmplia  r11,{r9,r10}    @ Update count and pointer - should clear interrupt
  5958. +  @ Handle any other interrupts
  5959. +_fdc1772_dma_write_notours:
  5960. +  @ Cant branch because this code has been copied down to the FIQ vector
  5961. +  ldr pc,[pc,#-4]
  5962. +  .word _fdc1772_comendhandler
  5963. +
  5964. +  .global _fdc1772_dma_write_end
  5965. +_fdc1772_dma_write_end:
  5966. +  
  5967. +
  5968. +@ Setup the FIQ R11 to point to the data and store the count, address
  5969. +@ for this dma
  5970. +@ R0=count
  5971. +@ R1=address
  5972. +  .global _fdc1772_setupdma
  5973. +_fdc1772_setupdma:
  5974. +    @ The big job is flipping in and out of FIQ mode
  5975. +    adr    r2,_fdc1772_fiqdata    @ This is what we really came here for
  5976. +  stmia  r2,{r0,r1}
  5977. +    mov    r3, pc
  5978. +    teqp    pc,#0x0c000001    @ Disable FIQs, IRQs and switch to FIQ mode
  5979. +    mov    r0,r0          @ NOP
  5980. +    mov r11,r2
  5981. +    teqp    r3,#0        @ Normal mode
  5982. +    mov    r0,r0        @ NOP
  5983. +  mov pc,r14
  5984. +
  5985. diff -urN linux.store/linux/arch/arm/lib/floppydma.S linux/arch/arm/lib/floppydma.S
  5986. --- linux.store/linux/arch/arm/lib/floppydma.S    Sun Mar  3 13:11:49 1996
  5987. +++ linux/arch/arm/lib/floppydma.S    Tue Mar 12 13:40:31 1996
  5988. @@ -35,6 +35,7 @@
  5989.  @ r0 = length
  5990.  @ r1 = address
  5991.  @ r2 = floppy port
  5992. +@ Puts these into R9_fiq, R10_fiq, R11_fiq
  5993.          .global    _floppy_fiqsetup
  5994.  _floppy_fiqsetup:
  5995.          mov    ip, sp
  5996. diff -urN linux.store/linux/arch/arm/lib/io.S linux/arch/arm/lib/io.S
  5997. --- linux.store/linux/arch/arm/lib/io.S    Sun Mar  3 13:13:17 1996
  5998. +++ linux/arch/arm/lib/io.S    Fri Mar  8 22:27:50 1996
  5999. @@ -6,6 +6,7 @@
  6000.  
  6001.  #include <asm/assembler.h>
  6002.          .text
  6003. +        .align
  6004.  
  6005.  #define OUT(reg)                    \
  6006.          mov    r8, reg, lsl \#16        ;\
  6007. @@ -24,8 +25,6 @@
  6008.  @ purpose: read a byte from a hardware register.
  6009.  @ Proto  : unsigned char inb(int address);
  6010.  
  6011. -        .align
  6012. -
  6013.          .global    ___inb
  6014.          .global    ___inb_p
  6015.          .global    ___inbc
  6016. @@ -44,8 +43,6 @@
  6017.  @ purpose: read a short word from a hardware register.
  6018.  @ Proto  : unsigned char inw(int address);
  6019.  
  6020. -        .align
  6021. -
  6022.          .global    ___inw
  6023.  ___inw:        cmp    r0, #0x00c00000
  6024.          movge    r2, #0
  6025. @@ -59,8 +56,6 @@
  6026.  @ Purpose: write a byte to a hardware register.
  6027.  @ Proto  : outb(unsigned char c,int address);
  6028.  
  6029. -        .align
  6030. -
  6031.          .global    ___outb
  6032.          .global    ___outb_p
  6033.          .global    ___outbc
  6034. @@ -79,8 +74,6 @@
  6035.  @ Purpose: write a short to a hardware register.
  6036.  @ Proto  : outw(unsigned short c,int address);
  6037.  
  6038. -        .align
  6039. -
  6040.          .global    ___outw
  6041.  ___outw:    cmp    r1, #0x00c00000
  6042.          movge    r2, #0
  6043. @@ -95,8 +88,6 @@
  6044.  @ Proto  : inswb(int from_port, void *to, int len_in_bytes);
  6045.  @ Notes  : increment to
  6046.  
  6047. -        .align
  6048. -
  6049.          .global    _insw
  6050.          .global    _inswb
  6051.  _insw:        mov    r2, r2, lsl#1
  6052. @@ -175,8 +166,6 @@
  6053.  @ Proto  : outswb(int to_reg, void *from, int len_in_bytes);
  6054.  @ Notes  : increments from
  6055.  
  6056. -        .align
  6057. -
  6058.          .global    _outsw
  6059.          .global    _outswb
  6060.  _outsw:        mov    r2, r2, LSL#1
  6061. @@ -225,8 +214,6 @@
  6062.  @ Proto  : void vidc_write(int register, int value);
  6063.  @ Returns: nothing
  6064.  
  6065. -        .align
  6066. -
  6067.          .global    _vidc_write
  6068.  _vidc_write:    bic    r1, r1, #0xFF000000
  6069.          orr    r0, r1, r0, lsl #24
  6070. @@ -238,8 +225,6 @@
  6071.  @ Proto  : void memc_write(int register, int value);
  6072.  @ Returns: nothing
  6073.  
  6074. -        .align
  6075. -
  6076.          .global    _memc_write
  6077.  _memc_write:    cmp    r0, #7
  6078.          RETINSTR(movgt,pc,lr)
  6079. @@ -252,26 +237,26 @@
  6080.          RETINSTR(mov,pc,lr)
  6081.  
  6082.  @ Purpose: call an expansion card loader to read bytes.
  6083. -@ Proto  : int read_loader(int offset, int card_base, int *loader);
  6084. +@ Proto  : char read_loader(int offset, char *card_base, char *loader);
  6085.  @ Returns: byte read
  6086.  
  6087. -        .align
  6088. -
  6089. -        .global    _read_loader
  6090. -_read_loader:    stmfd    sp!, {r4 - r12, lr}
  6091. +        .global    _ecard_loader_read
  6092. +_ecard_loader_read:
  6093. +        stmfd    sp!, {r4 - r12, lr}
  6094.          mov    r11, r1
  6095.          mov    r1, r0
  6096.          mov    lr, pc
  6097.          mov    pc, r2
  6098.          LOADREGS(fd, sp!, {r4 - r12, pc})
  6099.  
  6100. -        .align
  6101. -msgg:
  6102. -        .ascii    "%08X  "
  6103. -        .align
  6104. +@ Purpose: call an expansion card loader to reset the card
  6105. +@ Proto  : void read_loader(int card_base, char *loader);
  6106. +@ Returns: byte read
  6107.  
  6108. -show:        stmfd    sp!, {r0-r12, lr}
  6109. -        mov    r1, r8
  6110. -        adr    r0, msgg
  6111. -        bl    _printk
  6112. -        LOADREGS(fd, sp!, {r0-r12, pc})
  6113. +        .global    _ecard_loader_reset
  6114. +_ecard_loader_reset:
  6115. +        stmfd    sp!, {r4 - r12, lr}
  6116. +        mov    r11, r0
  6117. +        mov    lr, pc
  6118. +        add    pc, r1, #8
  6119. +        LOADREGS(fd, sp!, {r4 - r12, pc})
  6120. diff -urN linux.store/linux/arch/arm/lib/ll_char_wr.S linux/arch/arm/lib/ll_char_wr.S
  6121. --- linux.store/linux/arch/arm/lib/ll_char_wr.S    Sun Mar  3 13:15:26 1996
  6122. +++ linux/arch/arm/lib/ll_char_wr.S    Sun Mar 10 16:31:30 1996
  6123. @@ -7,7 +7,7 @@
  6124.  #include <asm/assembler.h>
  6125.          .text
  6126.  
  6127. -        .global    _ll_char_write
  6128. +        .global    _ll_write_char
  6129.  
  6130.  #define BOLD            0x01
  6131.  #define ITALIC          0x02
  6132. @@ -15,41 +15,44 @@
  6133.  #define FLASH           0x08
  6134.  #define INVERSE         0x10
  6135.  
  6136. -@ r4 = flags
  6137. -@ r3 = backc
  6138. -@ r2 = forec
  6139. -@ r1 = ch
  6140. -@ r0 = ps
  6141. -
  6142.  LC0:
  6143.          .word    _bytes_per_char_h
  6144.          .word    _video_num_columns
  6145.          .word    _cmap_80
  6146.  
  6147. -_ll_char_write:
  6148. -        subs    r1, r1, #32
  6149. -        movlt    r1, #0
  6150. -        cmp    r1, #126-32
  6151. -        RETINSTR(movgt,pc,lr)
  6152. +_ll_write_char:
  6153.          mov    ip, sp
  6154.          stmfd    sp!, {r4 - r9, fp, ip, lr, pc}
  6155.          sub    fp, ip, #4
  6156. -@ do inverse stuff
  6157. -        ldr    r4, [fp, #4]        @ get flags
  6158. -        eor    r4, r4, #UNDERLINE
  6159. -        tst    r4, #INVERSE
  6160. -        movne    r5, r3
  6161. -        movne    r3, r2
  6162. -        movne    r2, r5
  6163. -        tst    r4, #BOLD
  6164. +        eor    r4, r1, #UNDERLINE << 24
  6165. +/*
  6166. + * calculate colours
  6167. + */
  6168. +        tst    r1, #INVERSE << 24
  6169. +        moveq    r2, r1, lsr #8
  6170. +        moveq    r3, r1, lsr #16
  6171. +        movne    r2, r1, lsr #16
  6172. +        movne    r3, r1, lsr #8
  6173. +        tst    r1, #BOLD << 24
  6174.          orrne    r2, r2, #8
  6175. -@ compute the offset required for each row
  6176. -        ldr    r5, [pc, #LC0 - . - 8]
  6177. -        ldrb    r5, [r5]
  6178. -        ldr    r6, [pc, #LC0 - . - 4]
  6179. -        ldrb    r6, [r6]
  6180. +        and    r3, r3, #255
  6181. +        and    r2, r2, #255
  6182. +/*
  6183. + * calculate offset into character table
  6184. + */
  6185. +        and    r1, r1, #255
  6186. +        subs    r1, r1, #32
  6187. +        movlt    r1, #0
  6188. +        cmp    r1, #126 - 32
  6189. +        movgt    r1, #0
  6190. +/*
  6191. + * calculate offset required for each row
  6192. + */
  6193. +        adr    r5, LC0
  6194. +        ldmia    r5, {r5, r6, r7}
  6195. +        ldr    r5, [r5]
  6196. +        ldr    r6, [r6]
  6197.          mul    r6, r5, r6
  6198. -        ldr    r7, [pc, #LC0 - .]
  6199.          mov    r1, r1, lsl #3
  6200.          teq    r5, #8
  6201.          beq    row8bpplp
  6202. @@ -57,7 +60,7 @@
  6203.          ldrb    r9, [r7, r1]
  6204.          and    r8, r1, #7
  6205.          teq    r8, #7
  6206. -        tsteq    r4, #UNDERLINE
  6207. +        tsteq    r4, #UNDERLINE << 24
  6208.          mvneq    r9, r9
  6209.          sub    r8, r5, #1
  6210.          mov    ip, #0
  6211. @@ -85,7 +88,7 @@
  6212.          tst    r9, #1<<0
  6213.          orreq    ip, ip, r3, lsl#28
  6214.          orrne    ip, ip, r2, lsl#28
  6215. -        str    ip, [r0],r6
  6216. +        str    ip, [r0], r6
  6217.          add    r1, r1,#1
  6218.          tst    r1, #7
  6219.          bne    row4bpplp
  6220. @@ -94,7 +97,7 @@
  6221.  row8bpplp:    ldrb    r9, [r7, r1]
  6222.          and    r8, r1, #7
  6223.          teq    r8, #7
  6224. -        tsteq    r4, #UNDERLINE
  6225. +        tsteq    r4, #UNDERLINE << 24
  6226.          mvneq    r9, r9
  6227.          tst    r9, #1<<7
  6228.          moveq    r5, r3
  6229. diff -urN linux.store/linux/arch/arm/lib/mfm.S linux/arch/arm/lib/mfm.S
  6230. --- linux.store/linux/arch/arm/lib/mfm.S    Thu Jan  1 01:00:00 1970
  6231. +++ linux/arch/arm/lib/mfm.S    Mon Mar 11 23:02:11 1996
  6232. @@ -0,0 +1,118 @@
  6233. +@ Read/Write DMA code for the ST506/MFM hard drive controllers on the A400
  6234. +@   motherboard on ST506 podules.
  6235. +@ (c) David Alan Gilbert (gilbertd@cs.man.ac.uk) 1996
  6236. +
  6237. +#include <asm/assembler.h>
  6238. +_hdc63463_irqdata:
  6239. +@ Controller base address
  6240. +  .global _hdc63463_baseaddress
  6241. +_hdc63463_baseaddress:
  6242. +  .word 0
  6243. +
  6244. +  .global _hdc63463_irqpolladdress
  6245. +_hdc63463_irqpolladdress:
  6246. +  .word 0
  6247. +  .global _hdc63463_irqpollmask
  6248. +_hdc63463_irqpollmask:
  6249. +  .word 0
  6250. +
  6251. +@ where to read/write data  from the kernel data space
  6252. +  .global _hdc63463_dataptr
  6253. +_hdc63463_dataptr:
  6254. +  .word 0
  6255. +
  6256. +@ Number of bytes left to transfer
  6257. +  .global _hdc63463_dataleft
  6258. +_hdc63463_dataleft:
  6259. +  .word 0
  6260. +
  6261. +@ -------------------------------------------------------------------------
  6262. +@ hdc63463_writedma: DMA from host to controller
  6263. +@  internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask
  6264. +@                      r3=data ptr, r4=data left, r5,r6=temporary
  6265. +  .global _hdc63463_writedma
  6266. +_hdc63463_writedma:
  6267. +  stmfd sp!,{r4-r9}
  6268. +  adr r5,_hdc63463_irqdata
  6269. +  ldmia r5,{r0,r1,r2,r3,r4}
  6270. +
  6271. +writedma_loop:
  6272. +  @ test number of remaining bytes to transfer
  6273. +  cmp r4,#0
  6274. +  beq writedma_end
  6275. +  bmi writedma_end
  6276. +
  6277. +  @ Check the hdc is interrupting
  6278. +  ldrb r5,[r1,#0]
  6279. +  tst r5,r2
  6280. +  beq writedma_end
  6281. +
  6282. +  @ Check the hdc is still busy and command has not ended and no errors
  6283. +  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status
  6284. +  tst r5,#0x3c00        @ Test for things which should be off
  6285. +  bne writedma_end
  6286. +  and r5,r5,#0x8000        @ This is test for things which should be on: Busy
  6287. +  cmp r5,#0x8000
  6288. +  bne writedma_end 
  6289. +
  6290. +  @ OK - pretty sure we should be doing this
  6291. +  @ Get two bytes - note it can be half word aligned; its easiest to read 2 bytes
  6292. +  ldrb r6,[r3],#1
  6293. +  ldrb r5,[r3],#1
  6294. +  orr  r6,r6,r5,lsl#8  @ Put them together, note big endian for HDC
  6295. +  orr  r6,r6,r6,lsl#16    @ Both halves of word for podule write
  6296. +  str  r6,[r0,#32+8]      @ Put the data out
  6297. +  subs r4,r4,#2        @ Decrement bytes to go
  6298. +  b writedma_loop
  6299. +
  6300. +writedma_end:
  6301. +  adr r5,_hdc63463_irqdata+12
  6302. +  stmia r5,{r3,r4}
  6303. +  ldmfd sp!,{r4-r9}
  6304. +  RETINSTR(mov,pc,lr)
  6305. +
  6306. +@ -------------------------------------------------------------------------
  6307. +@ hdc63463_readdma: DMA from controller to host
  6308. +@  internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask
  6309. +@                      r3=data ptr, r4=data left, r5,r6=temporary
  6310. +  .global _hdc63463_readdma
  6311. +_hdc63463_readdma:
  6312. +  stmfd sp!,{r4-r9}
  6313. +  adr r5,_hdc63463_irqdata
  6314. +  ldmia r5,{r0,r1,r2,r3,r4}
  6315. +
  6316. +readdma_loop:
  6317. +  @ test number of remaining bytes to transfer
  6318. +  cmp r4,#0
  6319. +  beq readdma_end
  6320. +  bmi readdma_end
  6321. +
  6322. +  @ Check the hdc is interrupting
  6323. +  ldrb r5,[r1,#0]
  6324. +  tst r5,r2
  6325. +  beq readdma_end
  6326. +
  6327. +  @ Check the hdc is still busy and command has not ended and no errors
  6328. +  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status
  6329. +  tst r5,#0x3c00      @ Test for things which should be off
  6330. +  bne readdma_end
  6331. +  and r5,r5,#0x8000        @ This is test for things which should be on: Busy
  6332. +  cmp r5,#0x8000
  6333. +  bne readdma_end 
  6334. +
  6335. +  @ OK - pretty sure we should be doing this
  6336. +  @ Get two bytes - note it can be half word aligned; its easiest to read 2 bytes
  6337. +  ldr  r6,[r0,#8]     @ Read data from hdc - its in the bottom half
  6338. +  mov  r5,r6,lsr#8     @ Move second byte to bottom
  6339. +  strb r6,[r3],#1      @ Note endian swap in here
  6340. +  strb r5,[r3],#1
  6341. +  subs r4,r4,#2        @ Decrement bytes to go
  6342. +  b readdma_loop
  6343. +
  6344. +readdma_end:
  6345. +  adr r5,_hdc63463_irqdata+12
  6346. +  stmia r5,{r3,r4}
  6347. +  ldmfd sp!,{r4-r9}
  6348. +  RETINSTR(mov,pc,lr)
  6349. diff -urN linux.store/linux/arch/arm/mm/fault.c linux/arch/arm/mm/fault.c
  6350. --- linux.store/linux/arch/arm/mm/fault.c    Sun Mar  3 13:08:26 1996
  6351. +++ linux/arch/arm/mm/fault.c    Sun Mar 10 14:34:32 1996
  6352. @@ -176,81 +176,79 @@
  6353.   */
  6354.  asmlinkage int do_dataabort (unsigned long min_addr, unsigned long max_addr, int mode, unsigned long *regs)
  6355.  {
  6356. -    unsigned long error_code;
  6357. -    int done = 0;
  6358. -    pte_t *pte;
  6359. +    unsigned long error_code;
  6360. +    int done = 0;
  6361. +    pte_t *pte;
  6362.  
  6363. -    IDEBUG(debug (min_addr, max_addr, mode, regs));
  6364. +    IDEBUG(debug (min_addr, max_addr, mode, regs));
  6365.      
  6366. -    if ((min_addr >= LOGICAL_END || max_addr >= LOGICAL_END) && (mode & 3) == 0)
  6367. -    {
  6368. -        send_sig (SIGSEGV, current, 1);
  6369. -        return 1;
  6370. -    }
  6371. +    if ((min_addr >= LOGICAL_END || max_addr >= LOGICAL_END) && (mode & 3) == 0) {
  6372. +    send_sig (SIGSEGV, current, 1);
  6373. +    return 1;
  6374. +    }
  6375.      
  6376. -    error_code = ((mode & 0x20) ? _PAGE_RW : 0) | ((mode & 3) ? 0 : _PAGE_USER);
  6377. +    error_code = ((mode & 0x20) ? _PAGE_RW : 0) | ((mode & 3) ? 0 : _PAGE_USER);
  6378.  
  6379. -    pte = pte_offset (pmd_offset (pgd_offset (current->mm, min_addr), min_addr), min_addr);
  6380. +    pte = pte_offset (pmd_offset (pgd_offset (current->mm, min_addr), min_addr), min_addr);
  6381.  
  6382. -    if (pte_present(*pte)) {
  6383. -        if ((error_code & _PAGE_USER) && !pte_read(*pte)) {
  6384. -            printk("Process (%s, %d) tried to access reserved mem %08lx mode %d (pc=%08lx, lr=%08lx)\n",
  6385. -                current->comm, current->pid, min_addr, mode, regs[15], regs[14]);
  6386. -            send_sig(SIGSEGV, current, 1);
  6387. -            return 1;
  6388. -        }
  6389. -
  6390. -        if ((mode & 0x700)==0x100 && pte_young(*pte)) {
  6391. -            printk("Page %08lx (%08lx) in but got abort (pc=%08lx) - undefined instr\n",
  6392. -                min_addr, pte_val(*pte), regs[15]);
  6393. -            return 0;
  6394. -        }
  6395. -
  6396. -        if (!pte_young (*pte)) {
  6397. -            *pte = pte_mkyoung (*pte);
  6398. -            done = 1;
  6399. -        }
  6400. -
  6401. -        if ((error_code & _PAGE_RW) && pte_write(*pte) && !pte_dirty (*pte)) {
  6402. -            *pte = pte_mkdirty (*pte);
  6403. -            done = 1;
  6404. -        }
  6405. -
  6406. -        if (done) {
  6407. -            invalidate ();
  6408. -            return 1;
  6409. -        }
  6410. +    if (pte_present(*pte)) {
  6411. +    if ((error_code & _PAGE_USER) && !pte_read(*pte)) {
  6412. +        printk("Process (%s, %d) tried to access reserved mem %08lx mode %d (pc=%08lx, lr=%08lx)\n",
  6413. +            current->comm, current->pid, min_addr, mode, regs[15], regs[14]);
  6414. +        send_sig(SIGSEGV, current, 1);
  6415. +        return 1;
  6416. +    }
  6417.  
  6418. -        error_code |= _PAGE_PRESENT;
  6419. +    if ((mode & 0x700)==0x100 && pte_young(*pte)) {
  6420. +        printk("Page %08lx (%08lx) in but got abort (pc=%08lx) - undefined instr\n",
  6421. +            min_addr, pte_val(*pte), regs[15]);
  6422. +        return 0;
  6423.      }
  6424.  
  6425. -    do_page_fault1(min_addr, error_code, (struct pt_regs *)regs);
  6426. +    if (!pte_young (*pte)) {
  6427. +        *pte = pte_mkyoung (*pte);
  6428. +       done = 1;
  6429. +    }
  6430.  
  6431. -    if ((min_addr ^ max_addr) >> PAGE_SHIFT) {
  6432. -        pte = pte_offset (pmd_offset (pgd_offset (current->mm, max_addr), max_addr), max_addr);
  6433. -        if (pte_present (*pte)) {
  6434. -            if (!pte_young (*pte)) {
  6435. -                *pte = pte_mkyoung (*pte);
  6436. -                done = 1;
  6437. -            }
  6438. -
  6439. -            if ((error_code & _PAGE_RW) && pte_write(*pte) && !pte_dirty (*pte)) {
  6440. -                *pte = pte_mkdirty (*pte);
  6441. -                done = 1;
  6442. -            }
  6443. -
  6444. -            if (done) {
  6445. -                invalidate ();
  6446. -                return 1;
  6447. -            }
  6448. -
  6449. -            error_code |= _PAGE_PRESENT;
  6450. -        }
  6451. -        else
  6452. -            error_code &= ~_PAGE_PRESENT;
  6453. -        do_page_fault1(max_addr, error_code, (struct pt_regs *)regs);
  6454. +    if ((error_code & _PAGE_RW) && pte_write(*pte) && !pte_dirty (*pte)) {
  6455. +        *pte = pte_mkdirty (*pte);
  6456. +        done = 1;
  6457.      }
  6458.  
  6459. -    invalidate();
  6460. -    return 1;
  6461. +    if (done) {
  6462. +        invalidate ();
  6463. +        return 1;
  6464. +    }
  6465. +
  6466. +    error_code |= _PAGE_PRESENT;
  6467. +    }
  6468. +
  6469. +    do_page_fault1(min_addr, error_code, (struct pt_regs *)regs);
  6470. +
  6471. +    if ((min_addr ^ max_addr) >> PAGE_SHIFT) {
  6472. +    pte = pte_offset (pmd_offset (pgd_offset (current->mm, max_addr), max_addr), max_addr);
  6473. +    if (pte_present (*pte)) {
  6474. +        if (!pte_young (*pte)) {
  6475. +        *pte = pte_mkyoung (*pte);
  6476. +        done = 1;
  6477. +        }
  6478. +
  6479. +        if ((error_code & _PAGE_RW) && pte_write(*pte) && !pte_dirty (*pte)) {
  6480. +        *pte = pte_mkdirty (*pte);
  6481. +        done = 1;
  6482. +        }
  6483. +
  6484. +        if (done) {
  6485. +        invalidate ();
  6486. +        return 1;
  6487. +        }
  6488. +
  6489. +        error_code |= _PAGE_PRESENT;
  6490. +    } else
  6491. +        error_code &= ~_PAGE_PRESENT;
  6492. +        do_page_fault1(max_addr, error_code, (struct pt_regs *)regs);
  6493. +    }
  6494. +
  6495. +    invalidate();
  6496. +    return 1;
  6497.  }
  6498. diff -urN linux.store/linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c
  6499. --- linux.store/linux/arch/arm/mm/init.c    Sun Mar  3 13:08:36 1996
  6500. +++ linux/arch/arm/mm/init.c    Sun Mar 10 14:32:18 1996
  6501. @@ -27,8 +27,8 @@
  6502.  
  6503.  unsigned long low_memory;
  6504.  int page_nr    = 256;
  6505. -pgd_t swapper_pg_dir[1024];
  6506.  int page_shift = 15;
  6507. +pgd_t swapper_pg_dir[1024];
  6508.  
  6509.  extern void memfastset (void *, unsigned long n, size_t l);
  6510.  
  6511. @@ -45,58 +45,45 @@
  6512.   * ZERO_PAGE is a special page that is used for zero-initialized
  6513.   * data and COW.
  6514.   */
  6515. -#if 0
  6516. -pte_t * __bad_pagetable(void)
  6517. -{
  6518. -    extern char empty_bad_page_table[PAGE_SIZE];
  6519. -
  6520. -    __asm__ __volatile__("cld ; rep ; stosl":
  6521. -        :"a" (pte_val(BAD_PAGE)),
  6522. -         "D" ((long) empty_bad_page_table),
  6523. -         "c" (PAGE_SIZE/4)
  6524. -        :"di","cx");
  6525. -    return (pte_t *) empty_bad_page_table;
  6526. -}
  6527. -#endif
  6528.  char *empty_bad_page;
  6529.  pte_t __bad_page(void)
  6530.  {
  6531. -        memfastset(empty_bad_page, 0, PAGE_SIZE);
  6532. -    return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
  6533. +    memfastset(empty_bad_page, 0, PAGE_SIZE);
  6534. +    return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
  6535.  }
  6536.  
  6537.  char *empty_zero_page;
  6538.  unsigned long __zero_page(void)
  6539.  {
  6540. -        memfastset(empty_zero_page, 0, PAGE_SIZE);
  6541. -    return (unsigned long) empty_zero_page;
  6542. +    memfastset(empty_zero_page, 0, PAGE_SIZE);
  6543. +    return (unsigned long) empty_zero_page;
  6544.  }
  6545.  
  6546.  void show_mem(void)
  6547.  {
  6548. -    int i,free = 0,total = 0,reserved = 0;
  6549. -    int shared = 0;
  6550. +    int i,free = 0,total = 0,reserved = 0;
  6551. +    int shared = 0;
  6552.  
  6553. -    printk("Mem-info:\n");
  6554. -    show_free_areas();
  6555. -    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
  6556. -    i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
  6557. -    while (i-- > 0) {
  6558. -        total++;
  6559. -        if (mem_map[i].reserved)
  6560. -            reserved++;
  6561. -        else if (!mem_map[i].count)
  6562. -            free++;
  6563. -        else
  6564. -            shared += mem_map[i].count-1;
  6565. -    }
  6566. -    printk("%d pages of RAM\n",total);
  6567. -    printk("%d free pages\n",free);
  6568. -    printk("%d reserved pages\n",reserved);
  6569. -    printk("%d pages shared\n",shared);
  6570. -    show_buffers();
  6571. +    printk ("Mem-info:\n");
  6572. +    show_free_areas();
  6573. +    printk ("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
  6574. +    i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
  6575. +    while (i-- > 0) {
  6576. +    total++;
  6577. +    if (mem_map[i].reserved)
  6578. +        reserved++;
  6579. +    else if (!mem_map[i].count)
  6580. +        free++;
  6581. +    else
  6582. +        shared += mem_map[i].count-1;
  6583. +    }
  6584. +    printk("%d pages of RAM\n",total);
  6585. +    printk("%d free pages\n",free);
  6586. +    printk("%d reserved pages\n",reserved);
  6587. +    printk("%d pages shared\n",shared);
  6588. +    show_buffers();
  6589.  #ifdef CONFIG_NET
  6590. -    show_net_buffers();
  6591. +    show_net_buffers();
  6592.  #endif
  6593.  }
  6594.  
  6595. @@ -105,48 +92,38 @@
  6596.  unsigned long map_screen_mem(int log_start,int update)
  6597.  {
  6598.      /* This routine needs more work to make it dynamically release/allocate mem! */
  6599. -    unsigned long address;
  6600. -    int i;
  6601. -    static int updated=0;
  6602. -#if 0
  6603. -    unsigned long screen_size = 256*1024;
  6604. -#else
  6605. -    unsigned long screen_size = 480*1024;
  6606. -#endif
  6607. -    pgd_t *pg_dir;
  6608. -    pmd_t *pm_dir;
  6609. -    pte_t *pt_entry;
  6610. -
  6611. -    if(updated)
  6612. -        return 0;
  6613. -
  6614. -    address=LOGICAL_END;
  6615. -
  6616. -    for(i = LOGICAL_END - screen_size; i<LOGICAL_END; i+=PAGE_SIZE)
  6617. -    {
  6618. -        pg_dir = swapper_pg_dir + (i >> PGDIR_SHIFT);
  6619. -        pm_dir = pmd_offset(pg_dir, i);
  6620. -        pt_entry = pte_offset(pm_dir, i);
  6621. -        if(i>=log_start)
  6622. -        {
  6623. -            *pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT|_PAGE_USER|_PAGE_RW|_PAGE_ACCESSED));
  6624. -            address+=PAGE_SIZE;
  6625. -        }
  6626. -        else
  6627. -            *pt_entry = mk_pte(0, __pgprot(0));
  6628. -    }
  6629. -    if(update)
  6630. -    {
  6631. -
  6632. -        for(; address<(LOGICAL_END + screen_size); address += PAGE_SIZE)
  6633. -        {
  6634. -            mem_map[MAP_NR(address)].count = 1;
  6635. -            free_page(address);
  6636. -        }
  6637. -        updated=1;
  6638. -        invalidate();
  6639. +    static int updated=0;
  6640. +    unsigned long screen_size = 480*1024;
  6641. +    unsigned long address;
  6642. +    int i;
  6643. +    pgd_t *pg_dir;
  6644. +    pmd_t *pm_dir;
  6645. +    pte_t *pt_entry;
  6646. +
  6647. +    if(updated)
  6648. +    return 0;
  6649. +
  6650. +    address = LOGICAL_END;
  6651. +
  6652. +    for (i = LOGICAL_END - screen_size; i < LOGICAL_END; i += PAGE_SIZE) {
  6653. +    pg_dir = swapper_pg_dir + (i >> PGDIR_SHIFT);
  6654. +    pm_dir = pmd_offset(pg_dir, i);
  6655. +    pt_entry = pte_offset(pm_dir, i);
  6656. +    if (i >= log_start) {
  6657. +        *pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT|_PAGE_USER|_PAGE_RW|_PAGE_ACCESSED));
  6658. +        address += PAGE_SIZE;
  6659. +    } else
  6660. +        *pt_entry = mk_pte(0, __pgprot(0));
  6661. +    }
  6662. +    if (update) {
  6663. +    for (; address<(LOGICAL_END + screen_size); address += PAGE_SIZE) {
  6664. +        mem_map[MAP_NR(address)].count = 1;
  6665. +        free_page(address);
  6666.      }
  6667. -    return address;
  6668. +    updated=1;
  6669. +    invalidate();
  6670. +    }
  6671. +    return address;
  6672.  }
  6673.  
  6674.  /*
  6675. @@ -158,129 +135,122 @@
  6676.   */
  6677.  unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
  6678.  {
  6679. -    extern int page_nr;
  6680. -    int address;
  6681. -    int i;
  6682. -    pgd_t *pg_dir;
  6683. -    pmd_t *pm_dir;
  6684. -    pte_t *pt_entry;
  6685. -
  6686. -    page_nr = MAP_NR(end_mem);
  6687. -/* We appear to need this */
  6688. -    current = &init_task;
  6689. +    extern int page_nr;
  6690. +    int address;
  6691. +    int i;
  6692. +    pgd_t *pg_dir;
  6693. +    pmd_t *pm_dir;
  6694. +    pte_t *pt_entry;
  6695. +
  6696. +    page_nr = MAP_NR(end_mem);
  6697. +    /*
  6698. +     * We appear to need this
  6699. +     */
  6700. +    current = &init_task;
  6701.      
  6702. -    pg_dir = swapper_pg_dir;
  6703. -    pm_dir = pmd_offset(pg_dir, 0);
  6704. -    pt_entry = pte_offset(pm_dir, 0);
  6705. -
  6706. -    /* Insert mappings for the screen memory */
  6707. -    for(i=0; i<LOGICAL_END; i+=PAGE_SIZE)
  6708. -    {
  6709. -        pt_entry[i>>PAGE_SHIFT] = mk_pte(0, __pgprot(0));
  6710. -    }
  6711. -#if 0
  6712. -    address = map_screen_mem(0x02000000 - 256*1024, 0);
  6713. -#else
  6714. -    address = map_screen_mem(LOGICAL_END - 480*1024, 0);
  6715. -#endif
  6716. -
  6717. -    /* Allocate zero page */
  6718. -    for(i=0; i<32768>>PAGE_SHIFT; i++)
  6719. -    {
  6720. -        pt_entry[i] = mk_pte(address, PAGE_READONLY);
  6721. -        address += PAGE_SIZE;
  6722. -    }
  6723. -
  6724. -    /* Allocate kernel code pages */
  6725. -    for(i=0x01800000>>PAGE_SHIFT; address < start_mem; i++)
  6726. -    {
  6727. -        pt_entry[i] = mk_pte(address, PAGE_SHARED);
  6728. -        address += PAGE_SIZE;
  6729. -    }
  6730. -
  6731. -    empty_bad_page = (unsigned char *)address;
  6732. +    pg_dir = swapper_pg_dir;
  6733. +    pm_dir = pmd_offset(pg_dir, 0);
  6734. +    pt_entry = pte_offset(pm_dir, 0);
  6735. +
  6736. +    /* Insert mappings for the screen memory */
  6737. +    for(i=0; i<LOGICAL_END; i+=PAGE_SIZE)
  6738. +    pt_entry[i>>PAGE_SHIFT] = mk_pte(0, __pgprot(0));
  6739. +
  6740. +    address = map_screen_mem(LOGICAL_END - 480*1024, 0);
  6741. +
  6742. +    /* Allocate zero page */
  6743. +    for (i = 0; i < 32768 >> PAGE_SHIFT; i++) {
  6744. +    pt_entry[i] = mk_pte(address, PAGE_READONLY);
  6745.      address += PAGE_SIZE;
  6746. -    empty_zero_page = (unsigned char *)address;
  6747. +    }
  6748. +
  6749. +    /* Allocate kernel code pages */
  6750. +    for (i = 0x01800000 >> PAGE_SHIFT; address < start_mem; i++) {
  6751. +    pt_entry[i] = mk_pte(address, PAGE_SHARED);
  6752.      address += PAGE_SIZE;
  6753. +    }
  6754.  
  6755. -    invalidate();
  6756. -    return free_area_init(address, end_mem);
  6757. +    empty_bad_page = (unsigned char *)address;
  6758. +    address += PAGE_SIZE;
  6759. +    empty_zero_page = (unsigned char *)address;
  6760. +    address += PAGE_SIZE;
  6761. +
  6762. +    invalidate();
  6763. +    return free_area_init(address, end_mem);
  6764.  }
  6765.  
  6766.  void mem_init(unsigned long start_mem, unsigned long end_mem)
  6767.  {
  6768. -    int codepages = 0;
  6769. -    int reservedpages = 0;
  6770. -    int datapages = 0;
  6771. -    unsigned long tmp;
  6772. -    extern int etext;
  6773. -    int i;
  6774. -    extern void sound_init(void);
  6775. -
  6776. -    end_mem &= PAGE_MASK;
  6777. -    high_memory = end_mem;
  6778. -
  6779. -    /* mark usable pages in the mem_map[] */
  6780. -    start_mem = PAGE_ALIGN(start_mem);
  6781. -
  6782. -    for(i=0; i<MAP_NR(start_mem); i++)
  6783. -    {
  6784. -        mem_map[i].reserved = 1;
  6785. -        mem_map[i].count = 0;
  6786. -    }
  6787. -
  6788. -    while(i < MAP_NR(end_mem))
  6789. -    {
  6790. -        mem_map[i].reserved = 0;
  6791. -        mem_map[i++].count = 0;
  6792. -    }
  6793. +    int codepages = 0;
  6794. +    int reservedpages = 0;
  6795. +    int datapages = 0;
  6796. +    unsigned long tmp;
  6797. +    extern int etext;
  6798. +    int i;
  6799. +    extern void sound_init(void);
  6800. +
  6801. +    end_mem &= PAGE_MASK;
  6802. +    high_memory = end_mem;
  6803. +
  6804. +    /* mark usable pages in the mem_map[] */
  6805. +    start_mem = PAGE_ALIGN(start_mem);
  6806. +
  6807. +    for (i = 0; i < MAP_NR(start_mem); i++) {
  6808. +    mem_map[i].reserved = 1;
  6809. +    mem_map[i].count = 0;
  6810. +    }
  6811. +
  6812. +    while (i < MAP_NR(end_mem)) {
  6813. +    mem_map[i].reserved = 0;
  6814. +    mem_map[i++].count = 0;
  6815. +    }
  6816.  
  6817.  #ifdef CONFIG_SCSI
  6818. -    scsi_mem_init(high_memory);
  6819. +    scsi_mem_init(high_memory);
  6820.  #endif
  6821. -    for (tmp = LOGICAL_END ; tmp < high_memory ; tmp += PAGE_SIZE) {
  6822. -        if (mem_map[MAP_NR(tmp)].reserved) {
  6823. -            if (tmp < LOGICAL_END + (256*1024+32*1024))
  6824. -                reservedpages++;
  6825. -            else if (tmp < ((unsigned long) &etext - 0x01800000 + 0x02048000))
  6826. -                codepages++;
  6827. -            else
  6828. -                datapages++;
  6829. -            continue;
  6830. -        }
  6831. -        mem_map[MAP_NR(tmp)].count = 1;
  6832. -        free_page(tmp);
  6833. -    }
  6834. -    tmp = nr_free_pages << PAGE_SHIFT;
  6835. -    printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
  6836. -        tmp >> 10,
  6837. -        (high_memory - LOGICAL_END) >> 10,
  6838. -        codepages << (PAGE_SHIFT-10),
  6839. -        reservedpages << (PAGE_SHIFT-10),
  6840. -        datapages << (PAGE_SHIFT-10));
  6841. +    for (tmp = LOGICAL_END ; tmp < high_memory ; tmp += PAGE_SIZE) {
  6842. +    if (mem_map[MAP_NR(tmp)].reserved) {
  6843. +        if (tmp < LOGICAL_END + (256*1024+32*1024))
  6844. +        reservedpages++;
  6845. +        else if (tmp < ((unsigned long) &etext - 0x01800000 + 0x02048000))
  6846. +        codepages++;
  6847. +        else
  6848. +        datapages++;
  6849. +        continue;
  6850. +    }
  6851. +    mem_map[MAP_NR(tmp)].count = 1;
  6852. +    free_page(tmp);
  6853. +    }
  6854. +    tmp = nr_free_pages << PAGE_SHIFT;
  6855. +    printk ("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
  6856. +    tmp >> 10,
  6857. +    (high_memory - LOGICAL_END) >> 10,
  6858. +    codepages << (PAGE_SHIFT-10),
  6859. +    reservedpages << (PAGE_SHIFT-10),
  6860. +    datapages << (PAGE_SHIFT-10));
  6861.  #ifdef CONFIG_SOUND
  6862. -    sound_init();
  6863. +    sound_init();
  6864.  #endif
  6865.  }
  6866.  
  6867.  void si_meminfo(struct sysinfo *val)
  6868.  {
  6869. -    int i;
  6870. +    int i;
  6871.  
  6872. -    i = MAP_NR(high_memory);
  6873. -    val->totalram = 0;
  6874. -    val->sharedram = 0;
  6875. -    val->freeram = nr_free_pages << PAGE_SHIFT;
  6876. -    val->bufferram = buffermem;
  6877. -    while (i-- > 0)  {
  6878. -        if (mem_map[i].reserved)
  6879. -            continue;
  6880. -        val->totalram++;
  6881. -        if (!mem_map[i].count)
  6882. -            continue;
  6883. -        val->sharedram += mem_map[i].count-1;
  6884. -    }
  6885. -    val->totalram <<= PAGE_SHIFT;
  6886. -    val->sharedram <<= PAGE_SHIFT;
  6887. -    return;
  6888. +    i = MAP_NR(high_memory);
  6889. +    val->totalram = 0;
  6890. +    val->sharedram = 0;
  6891. +    val->freeram = nr_free_pages << PAGE_SHIFT;
  6892. +    val->bufferram = buffermem;
  6893. +    while (i-- > 0)  {
  6894. +    if (mem_map[i].reserved)
  6895. +        continue;
  6896. +    val->totalram++;
  6897. +    if (!mem_map[i].count)
  6898. +        continue;
  6899. +    val->sharedram += mem_map[i].count-1;
  6900. +    }
  6901. +    val->totalram <<= PAGE_SHIFT;
  6902. +    val->sharedram <<= PAGE_SHIFT;
  6903. +    return;
  6904.  }
  6905. diff -urN linux.store/linux/include/asm-arm/a.out.h linux/include/asm-arm/a.out.h
  6906. --- linux.store/linux/include/asm-arm/a.out.h    Sun Feb 11 09:32:54 1996
  6907. +++ linux/include/asm-arm/a.out.h    Sun Feb 11 09:32:54 1996
  6908. @@ -13,18 +13,11 @@
  6909.    unsigned a_drsize;        /* length of relocation info for data, in bytes */
  6910.  };
  6911.  
  6912. -#define N_TXTADDR(a)    0x8000
  6913. -
  6914.  #define N_TRSIZE(a)    ((a).a_trsize)
  6915.  #define N_DRSIZE(a)    ((a).a_drsize)
  6916.  #define N_SYMSIZE(a)    ((a).a_syms)
  6917.  
  6918.  #define M_ARM 103
  6919.  
  6920. -#ifdef __KERNEL__
  6921. -
  6922. -#define STACK_TOP    24*1024*1024
  6923. -
  6924. -#endif
  6925. -
  6926. +#include <asm/arch/a.out.h>
  6927.  #endif /* __A_OUT_GNU_H__ */
  6928. diff -urN linux.store/linux/include/asm-arm/arch-a5k/a.out.h linux/include/asm-arm/arch-a5k/a.out.h
  6929. --- linux.store/linux/include/asm-arm/arch-a5k/a.out.h    Thu Jan  1 01:00:00 1970
  6930. +++ linux/include/asm-arm/arch-a5k/a.out.h    Sun Feb 11 09:32:54 1996
  6931. @@ -0,0 +1,17 @@
  6932. +/*
  6933. + * linux/include/asm-arm/arch-a5k/a.out.h
  6934. + *
  6935. + * Copyright (C) 1996 Russell King
  6936. + */
  6937. +
  6938. +#ifndef __ASM_ARCH_A_OUT_H
  6939. +#define __ASM_ARCH_A_OUT_H
  6940. +
  6941. +#define N_TXTADDR(a)    0x8000
  6942. +
  6943. +#ifdef __KERNEL__
  6944. +#define STACK_TOP    24*1024*1024
  6945. +#endif
  6946. +
  6947. +#endif
  6948. +
  6949. diff -urN linux.store/linux/include/asm-arm/arch-a5k/dma.h linux/include/asm-arm/arch-a5k/dma.h
  6950. --- linux.store/linux/include/asm-arm/arch-a5k/dma.h    Thu Jan  1 01:00:00 1970
  6951. +++ linux/include/asm-arm/arch-a5k/dma.h    Wed Mar 13 15:21:00 1996
  6952. @@ -0,0 +1,64 @@
  6953. +#ifndef __ASM_ARCH_DMA_H
  6954. +#define __ASM_ARCH_DMA_H
  6955. +
  6956. +/* enable/disable a specific DMA channel */
  6957. +extern void enable_dma(unsigned int dmanr);
  6958. +
  6959. +static __inline__ void disable_dma(unsigned int dmanr)
  6960. +{
  6961. +    switch(dmanr) {
  6962. +    case 2:  disable_irq(16); break;
  6963. +    default: printk("disable_dma: dma %d not supported\n", dmanr); break;
  6964. +    }
  6965. +}
  6966. +
  6967. +/* Clear the 'DMA Pointer Flip Flop'.
  6968. + * Write 0 for LSB/MSB, 1 for MSB/LSB access.
  6969. + * Use this once to initialize the FF to a known state.
  6970. + * After that, keep track of it. :-)
  6971. + * --- In order to do that, the DMA routines below should ---
  6972. + * --- only be used while interrupts are disabled! ---
  6973. + */
  6974. +static __inline__ void clear_dma_ff(unsigned int dmanr)
  6975. +{
  6976. +    switch(dmanr) {
  6977. +    case 2:  break;
  6978. +    default: printk("clear_dma_ff: dma %d not supported\n", dmanr); break;
  6979. +    }
  6980. +}
  6981. +
  6982. +/* set mode (above) for a specific DMA channel */
  6983. +extern void set_dma_mode(unsigned int dmanr, char mode);
  6984. +
  6985. +/* Set only the page register bits of the transfer address.
  6986. + * This is used for successive transfers when we know the contents of
  6987. + * the lower 16 bits of the DMA current address register, but a 64k boundary
  6988. + * may have been crossed.
  6989. + */
  6990. +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
  6991. +{
  6992. +    printk("set_dma_page: dma %d not supported\n", dmanr);
  6993. +}
  6994. +
  6995. +
  6996. +/* Set transfer address & page bits for specific DMA channel.
  6997. + * Assumes dma flipflop is clear.
  6998. + */
  6999. +extern void set_dma_addr(unsigned int dmanr, unsigned int addr);
  7000. +
  7001. +/* Set transfer size for a specific DMA channel.
  7002. + */
  7003. +extern void set_dma_count(unsigned int dmanr, unsigned int count);
  7004. +
  7005. +/* Get DMA residue count. After a DMA transfer, this
  7006. + * should return zero. Reading this while a DMA transfer is
  7007. + * still in progress will return unpredictable results.
  7008. + * If called before the channel has been used, it may return 1.
  7009. + * Otherwise, it returns the number of _bytes_ left to transfer.
  7010. + *
  7011. + * Assumes DMA flip-flop is clear.
  7012. + */
  7013. +extern int get_dma_residue(unsigned int dmanr);
  7014. +
  7015. +#endif /* _ASM_ARCH_DMA_H */
  7016. +
  7017. diff -urN linux.store/linux/include/asm-arm/arch-a5k/irqs.h linux/include/asm-arm/arch-a5k/irqs.h
  7018. --- linux.store/linux/include/asm-arm/arch-a5k/irqs.h    Thu Jan  1 01:00:00 1970
  7019. +++ linux/include/asm-arm/arch-a5k/irqs.h    Sun Feb 11 09:32:54 1996
  7020. @@ -0,0 +1,28 @@
  7021. +/*
  7022. + * linux/include/asm-arm/arch-a5k/irqs.h
  7023. + *
  7024. + * Copyright (C) 1996 Russell King
  7025. + */
  7026. +
  7027. +#define IRQ_PRINTER        0
  7028. +#define IRQ_BATLOW        1
  7029. +#define IRQ_FLOPPYINDEX        2
  7030. +#define IRQ_VSYNCPULSE        3
  7031. +#define IRQ_POWERON        4
  7032. +#define IRQ_TIMER0        5
  7033. +#define IRQ_TIMER1        6
  7034. +#define IRQ_IMMEDIATE        7
  7035. +#define IRQ_EXPCARDFIQ        8
  7036. +#define IRQ_SOUNDCHANGE        9
  7037. +#define IRQ_SERIALPORT        10
  7038. +#define IRQ_HARDDISK        11
  7039. +#define IRQ_FLOPPYDISK        12
  7040. +#define IRQ_EXPANSIONCARD    13
  7041. +#define IRQ_KEYBOARDTX        14
  7042. +#define IRQ_KEYBOARDRX        15
  7043. +
  7044. +#define FIQ_FLOPPYDATA        0
  7045. +#define FIQ_ECONET        2
  7046. +#define FIQ_SERIALPORT        4
  7047. +#define FIQ_EXPANSIONCARD    6
  7048. +#define FIQ_FORCE        7
  7049. diff -urN linux.store/linux/include/asm-arm/arch-a5k/oldlatches.h linux/include/asm-arm/arch-a5k/oldlatches.h
  7050. --- linux.store/linux/include/asm-arm/arch-a5k/oldlatches.h    Thu Jan  1 01:00:00 1970
  7051. +++ linux/include/asm-arm/arch-a5k/oldlatches.h    Sun Feb 11 09:32:54 1996
  7052. @@ -0,0 +1,9 @@
  7053. +/*
  7054. + * Dummy oldlatches.h
  7055. + *
  7056. + * Copyright (C) 1996 Russell King
  7057. + */
  7058. +
  7059. +#ifdef __need_oldlatches
  7060. +#error "Old latches not present in this (a5k) machine"
  7061. +#endif
  7062. diff -urN linux.store/linux/include/asm-arm/arch-arc/a.out.h linux/include/asm-arm/arch-arc/a.out.h
  7063. --- linux.store/linux/include/asm-arm/arch-arc/a.out.h    Thu Jan  1 01:00:00 1970
  7064. +++ linux/include/asm-arm/arch-arc/a.out.h    Sun Feb 11 09:32:57 1996
  7065. @@ -0,0 +1,17 @@
  7066. +/*
  7067. + * linux/include/asm-arm/arch-arc/a.out.h
  7068. + *
  7069. + * Copyright (C) 1996 Russell King
  7070. + */
  7071. +
  7072. +#ifndef __ASM_ARCH_A_OUT_H
  7073. +#define __ASM_ARCH_A_OUT_H
  7074. +
  7075. +#define N_TXTADDR(a)    0x8000
  7076. +
  7077. +#ifdef __KERNEL__
  7078. +#define STACK_TOP    24*1024*1024
  7079. +#endif
  7080. +
  7081. +#endif
  7082. +
  7083. diff -urN linux.store/linux/include/asm-arm/arch-arc/dma.h linux/include/asm-arm/arch-arc/dma.h
  7084. --- linux.store/linux/include/asm-arm/arch-arc/dma.h    Thu Jan  1 01:00:00 1970
  7085. +++ linux/include/asm-arm/arch-arc/dma.h    Wed Mar 13 15:20:23 1996
  7086. @@ -0,0 +1,81 @@
  7087. +#ifndef __ASM_ARCH_DMA_H
  7088. +#define __ASM_ARCH_DMA_H
  7089. +
  7090. +/* enable/disable a specific DMA channel */
  7091. +extern void enable_dma(unsigned int dmanr);
  7092. +
  7093. +static __inline__ void disable_dma(unsigned int dmanr)
  7094. +{
  7095. +    switch(dmanr) {
  7096. +#ifdef CONFIG_BLK_DEV_FD
  7097. +    /* This is a HACK - at the moment ARM Linux doesn't support two FIQs
  7098. +     being serviced together, until it does this hack must stay - DAG */
  7099. +    case 0: { /* Data DMA */
  7100. +    /* We have to replace it by FIQ code for command end */
  7101. +    unsigned long flags;
  7102. +    extern void fdc1772_comendhandler(void);
  7103. +    /*printk("disable_dma for FD1772\n");*/
  7104. +    disable_irq(16);
  7105. +
  7106. +    save_flags(flags);
  7107. +    cliIF();
  7108. +    *((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); /* B fdc1772_comendhandler */ 
  7109. +    restore_flags(flags);
  7110. +  }
  7111. +  break;
  7112. +
  7113. +#endif
  7114. +    default: printk("disable_dma: dma %d not supported\n", dmanr); break;
  7115. +    }
  7116. +}
  7117. +
  7118. +/* Clear the 'DMA Pointer Flip Flop'.
  7119. + * Write 0 for LSB/MSB, 1 for MSB/LSB access.
  7120. + * Use this once to initialize the FF to a known state.
  7121. + * After that, keep track of it. :-)
  7122. + * --- In order to do that, the DMA routines below should ---
  7123. + * --- only be used while interrupts are disabled! ---
  7124. + */
  7125. +static __inline__ void clear_dma_ff(unsigned int dmanr)
  7126. +{
  7127. +    switch(dmanr) {
  7128. +    case 2:  break;
  7129. +    default: printk("clear_dma_ff: dma %d not supported\n", dmanr); break;
  7130. +    }
  7131. +}
  7132. +
  7133. +/* set mode (above) for a specific DMA channel */
  7134. +extern void set_dma_mode(unsigned int dmanr, char mode);
  7135. +
  7136. +/* Set only the page register bits of the transfer address.
  7137. + * This is used for successive transfers when we know the contents of
  7138. + * the lower 16 bits of the DMA current address register, but a 64k boundary
  7139. + * may have been crossed.
  7140. + */
  7141. +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
  7142. +{
  7143. +    printk("set_dma_page: dma %d not supported\n", dmanr);
  7144. +}
  7145. +
  7146. +
  7147. +/* Set transfer address & page bits for specific DMA channel.
  7148. + * Assumes dma flipflop is clear.
  7149. + */
  7150. +extern void set_dma_addr(unsigned int dmanr, unsigned int addr);
  7151. +
  7152. +/* Set transfer size for a specific DMA channel.
  7153. + */
  7154. +extern void set_dma_count(unsigned int dmanr, unsigned int count);
  7155. +
  7156. +/* Get DMA residue count. After a DMA transfer, this
  7157. + * should return zero. Reading this while a DMA transfer is
  7158. + * still in progress will return unpredictable results.
  7159. + * If called before the channel has been used, it may return 1.
  7160. + * Otherwise, it returns the number of _bytes_ left to transfer.
  7161. + *
  7162. + * Assumes DMA flip-flop is clear.
  7163. + */
  7164. +extern int get_dma_residue(unsigned int dmanr);
  7165. +
  7166. +#endif /* _ASM_ARCH_DMA_H */
  7167. +
  7168. diff -urN linux.store/linux/include/asm-arm/arch-arc/irqs.h linux/include/asm-arm/arch-arc/irqs.h
  7169. --- linux.store/linux/include/asm-arm/arch-arc/irqs.h    Thu Jan  1 01:00:00 1970
  7170. +++ linux/include/asm-arm/arch-arc/irqs.h    Sun Feb 11 09:32:57 1996
  7171. @@ -0,0 +1,30 @@
  7172. +/*
  7173. + * linux/include/asm-arm/arch-arc/irqs.h
  7174. + *
  7175. + * Copyright (C) 1996 Russell King, Dave Gilbert (gilbertd@cs.man.ac.uk)
  7176. + */
  7177. +
  7178. +#define IRQ_PRINTERBUSY        0
  7179. +#define IRQ_SERIALRING        1
  7180. +#define IRQ_PRINTERACK        2
  7181. +#define IRQ_VSYNCPULSE        3
  7182. +#define IRQ_POWERON        4
  7183. +#define IRQ_TIMER0        5
  7184. +#define IRQ_TIMER1        6
  7185. +#define IRQ_IMMEDIATE        7
  7186. +#define IRQ_EXPCARDFIQ        8
  7187. +#define IRQ_SOUNDCHANGE        9
  7188. +#define IRQ_SERIALPORT        10
  7189. +#define IRQ_HARDDISK        11
  7190. +#define IRQ_FLOPPYCHANGED    12
  7191. +#define IRQ_EXPANSIONCARD    13
  7192. +#define IRQ_KEYBOARDTX        14
  7193. +#define IRQ_KEYBOARDRX        15
  7194. +
  7195. +#define FIQ_FLOPPYDATA        0
  7196. +#define FIQ_FLOPPYIRQ        1
  7197. +#define FIQ_ECONET        2
  7198. +#define FIQ_EXPANSIONCARD    6
  7199. +#define FIQ_FORCE        7
  7200. +
  7201. +#define FIQ_FD1772        FIQ_FLOPPYIRQ
  7202. diff -urN linux.store/linux/include/asm-arm/arch-arc/oldlatches.h linux/include/asm-arm/arch-arc/oldlatches.h
  7203. --- linux.store/linux/include/asm-arm/arch-arc/oldlatches.h    Thu Jan  1 01:00:00 1970
  7204. +++ linux/include/asm-arm/arch-arc/oldlatches.h    Sun Feb 11 09:32:57 1996
  7205. @@ -0,0 +1,24 @@
  7206. +#ifndef _ASM_ARM_ARCHARC_OLDLATCH_H
  7207. +#define _ASN_ARM_ARCHARC_OLDLATCH_H
  7208. +
  7209. +#define LATCHA_FDSEL0    (1<<0)
  7210. +#define LATCHA_FDSEL1    (1<<1)
  7211. +#define LATCHA_FDSEL2    (1<<2)
  7212. +#define LATCHA_FDSEL3    (1<<3)
  7213. +#define LATCHA_FDSELALL  (0xf)
  7214. +#define LATCHA_SIDESEL   (1<<4)
  7215. +#define LATCHA_MOTOR     (1<<5)
  7216. +#define LATCHA_INUSE     (1<<6)
  7217. +#define LATCHA_CHANGERST (1<<7)
  7218. +
  7219. +#define LATCHB_FDCDENSITY  (1<<1)
  7220. +#define LATCHB_FDCRESET    (1<<3)
  7221. +#define LATCHB_PRINTSTROBE (1<<4)
  7222. +
  7223. +/* newval=(oldval & mask)|newdata */
  7224. +void oldlatch_bupdate(unsigned char mask,unsigned char newdata);
  7225. +
  7226. +/* newval=(oldval & mask)|newdata */
  7227. +void oldlatch_aupdate(unsigned char mask,unsigned char newdata);
  7228. +
  7229. +#endif
  7230. diff -urN linux.store/linux/include/asm-arm/arch-arc/system.h linux/include/asm-arm/arch-arc/system.h
  7231. --- linux.store/linux/include/asm-arm/arch-arc/system.h    Thu Jan  1 01:00:00 1970
  7232. +++ linux/include/asm-arm/arch-arc/system.h    Wed Mar 13 15:10:27 1996
  7233. @@ -0,0 +1,9 @@
  7234. +#define cliIF()                \
  7235. +    do {                \
  7236. +      unsigned long temp;        \
  7237. +      __asm__ __volatile__(        \
  7238. +"    mov    %0, pc\n"        \
  7239. +"    orr %0, %0, #0x0c000000\n"    \
  7240. +"    teqp    %0, #0\n"        \
  7241. +      : "=r" (temp));
  7242. +
  7243. diff -urN linux.store/linux/include/asm-arm/arch-rpc/oldlatches.h linux/include/asm-arm/arch-rpc/oldlatches.h
  7244. --- linux.store/linux/include/asm-arm/arch-rpc/oldlatches.h    Thu Jan  1 01:00:00 1970
  7245. +++ linux/include/asm-arm/arch-rpc/oldlatches.h    Tue Mar 12 15:36:14 1996
  7246. @@ -0,0 +1,9 @@
  7247. +/*
  7248. + * Dummy oldlatches.h
  7249. + *
  7250. + * Copyright (C) 1996 Russell King
  7251. + */
  7252. +
  7253. +#ifdef __need_oldlatches
  7254. +#error "Old latches not present in this (rpc) machine"
  7255. +#endif
  7256. diff -urN linux.store/linux/include/asm-arm/assembler.h linux/include/asm-arm/assembler.h
  7257. --- linux.store/linux/include/asm-arm/assembler.h    Sun Feb 11 09:32:54 1996
  7258. +++ linux/include/asm-arm/assembler.h    Sun Feb 11 09:32:54 1996
  7259. @@ -2,50 +2,12 @@
  7260.   * linux/asm/assembler.h
  7261.   *
  7262.   * This file contains arm architecture specific defines
  7263. - * for the different processors
  7264. + * for the different processors.
  7265. + *
  7266. + * Do not include any C declarations in this file - it is included by
  7267. + * assembler source.
  7268.   */
  7269.  
  7270. -#if !defined (__arm2__) && !defined (__arm3__) && !defined (__arm6__)
  7271. -#error "Only ARN2, ARM3 and ARM6 architectures are supported"
  7272. -#endif
  7273. -
  7274. -#undef __FOUND
  7275. -#undef __ERROR
  7276. -
  7277. -#ifdef __arm2__
  7278. -#ifdef __FOUND
  7279. -#undef __ERROR
  7280. -#define __ERROR
  7281. -#else
  7282. -#define __FOUND
  7283. -#endif
  7284. -#endif
  7285. -
  7286. -#ifdef __arm3__
  7287. -#ifdef __FOUND
  7288. -#undef __ERROR
  7289. -#define __ERROR
  7290. -#else
  7291. -#define __FOUND
  7292. -#endif
  7293. -#endif
  7294. -
  7295. -#ifdef __arm6__
  7296. -#ifdef __FOUND
  7297. -#undef __ERROR
  7298. -#define __ERROR
  7299. -#else
  7300. -#define __FOUND
  7301. -#endif
  7302. -#endif
  7303. -
  7304. -#ifdef __ERROR
  7305. -#error "Only one of __arm3__ and __arm6__ may be defined"
  7306. -#endif
  7307. -
  7308. -#undef __FOUND
  7309. -#undef __ERROR
  7310. -
  7311.  /*
  7312.   * LOADREGS: multiple register load (ldm) with pc in register list
  7313.   *        (takes account of ARM6 not using ^)
  7314. @@ -69,73 +31,4 @@
  7315.   * SVCMODE: switch to SVC mode
  7316.   */
  7317.  
  7318. -#if defined (__arm2__)
  7319. -#define LOADREGS(cond, base, reglist...)\
  7320. -    ldm##cond    base,reglist^
  7321. -
  7322. -#define RETINSTR(instr, regs...)\
  7323. -    instr##s    regs
  7324. -
  7325. -#define MODENOP\
  7326. -    mov    r0, r0
  7327. -
  7328. -#define SAVEIRQS
  7329. -#define RESTOREIRQS
  7330. -
  7331. -#define DISABLEIRQS\
  7332. -    teqp    pc, #0x08000003
  7333. -
  7334. -#define ENABLEIRQS\
  7335. -    teqp    pc, #0x00000003
  7336. -
  7337. -#define USERMODE\
  7338. -    teqp    pc, #0x00000000;\
  7339. -    mov    r0, r0
  7340. -
  7341. -#define SVCMODE\
  7342. -    teqp    pc, #0x00000003;\
  7343. -    mov    r0, r0
  7344. -#endif
  7345. -
  7346. -#if defined (__arm3__)
  7347. -#define LOADREGS(cond, base, reglist...)\
  7348. -    ldm##cond    base,reglist^
  7349. -
  7350. -#define RETINSTR(instr, regs...)\
  7351. -    instr##s    regs
  7352. -
  7353. -#define MODENOP
  7354. -
  7355. -#define SAVEIRQS
  7356. -#define RESTOREIRQS
  7357. -
  7358. -#define DISABLEIRQS\
  7359. -    teqp    pc, #0x08000003
  7360. -
  7361. -#define ENABLEIRQS\
  7362. -    teqp    pc, #0x00000003
  7363. -
  7364. -#define USERMODE\
  7365. -    teqp    pc, #0x00000000
  7366. -
  7367. -#define SVCMODE\
  7368. -    teqp    pc, #0x00000003
  7369. -#endif
  7370. -
  7371. -#if defined (__arm6__)
  7372. -#define LOADREGS(cond, base, reglist...)\
  7373. -    ldm##cond    base,reglist
  7374. -
  7375. -#define RETINSTR(instr, regs...)\
  7376. -    instr    regs
  7377. -
  7378. -#define MODENOP
  7379. -
  7380. -#define SAVEIRQS
  7381. -#define RESTOREIRQS
  7382. -
  7383. -#define DISABLEIRQS
  7384. -#define ENABLEIRQS
  7385. -#define USERMODE
  7386. -#define SVCMODE
  7387. -#endif
  7388. +#include <asm/proc/assembler.h>
  7389. diff -urN linux.store/linux/include/asm-arm/bugs.h linux/include/asm-arm/bugs.h
  7390. --- linux.store/linux/include/asm-arm/bugs.h    Sun Feb 11 09:32:54 1996
  7391. +++ linux/include/asm-arm/bugs.h    Sun Feb 11 09:32:54 1996
  7392. @@ -4,14 +4,4 @@
  7393.   *  Copyright (C) 1995  Russell King
  7394.   */
  7395.  
  7396. -/*
  7397. - * This is included by init/main.c to check for architecture-dependent bugs.
  7398. - *
  7399. - * Needs:
  7400. - *      void check_bugs(void);
  7401. - */
  7402. -         
  7403. -static inline void check_bugs(void)
  7404. -{
  7405. -}
  7406. -
  7407. +#include <asm/proc/bugs.h>
  7408. diff -urN linux.store/linux/include/asm-arm/dma.h linux/include/asm-arm/dma.h
  7409. --- linux.store/linux/include/asm-arm/dma.h    Sun Feb 11 09:32:54 1996
  7410. +++ linux/include/asm-arm/dma.h    Wed Mar 13 15:18:17 1996
  7411. @@ -10,64 +10,7 @@
  7412.  #define DMA_MODE_READ        0x44
  7413.  #define DMA_MODE_WRITE        0x48
  7414.  
  7415. -/* enable/disable a specific DMA channel */
  7416. -extern void enable_dma(unsigned int dmanr);
  7417. -
  7418. -static __inline__ void disable_dma(unsigned int dmanr)
  7419. -{
  7420. -    switch(dmanr) {
  7421. -    case 2:  disable_irq(16); break;
  7422. -    default: printk("disable_dma: dma %d not supported\n", dmanr); break;
  7423. -    }
  7424. -}
  7425. -
  7426. -/* Clear the 'DMA Pointer Flip Flop'.
  7427. - * Write 0 for LSB/MSB, 1 for MSB/LSB access.
  7428. - * Use this once to initialize the FF to a known state.
  7429. - * After that, keep track of it. :-)
  7430. - * --- In order to do that, the DMA routines below should ---
  7431. - * --- only be used while interrupts are disabled! ---
  7432. - */
  7433. -static __inline__ void clear_dma_ff(unsigned int dmanr)
  7434. -{
  7435. -    switch(dmanr) {
  7436. -    case 2:  break;
  7437. -    default: printk("clear_dma_ff: dma %d not supported\n", dmanr); break;
  7438. -    }
  7439. -}
  7440. -
  7441. -/* set mode (above) for a specific DMA channel */
  7442. -extern void set_dma_mode(unsigned int dmanr, char mode);
  7443. -
  7444. -/* Set only the page register bits of the transfer address.
  7445. - * This is used for successive transfers when we know the contents of
  7446. - * the lower 16 bits of the DMA current address register, but a 64k boundary
  7447. - * may have been crossed.
  7448. - */
  7449. -static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
  7450. -{
  7451. -    printk("set_dma_page: dma %d not supported\n", dmanr);
  7452. -}
  7453. -
  7454. -
  7455. -/* Set transfer address & page bits for specific DMA channel.
  7456. - * Assumes dma flipflop is clear.
  7457. - */
  7458. -extern void set_dma_addr(unsigned int dmanr, unsigned int addr);
  7459. -
  7460. -/* Set transfer size for a specific DMA channel.
  7461. - */
  7462. -extern void set_dma_count(unsigned int dmanr, unsigned int count);
  7463. -
  7464. -/* Get DMA residue count. After a DMA transfer, this
  7465. - * should return zero. Reading this while a DMA transfer is
  7466. - * still in progress will return unpredictable results.
  7467. - * If called before the channel has been used, it may return 1.
  7468. - * Otherwise, it returns the number of _bytes_ left to transfer.
  7469. - *
  7470. - * Assumes DMA flip-flop is clear.
  7471. - */
  7472. -extern int get_dma_residue(unsigned int dmanr);
  7473. +#include <asm/arch/dma.h>
  7474.  
  7475.  /* These are in kernel/dma.c: */
  7476.  extern int request_dma(unsigned int dmanr, const char * device_id);   /* reserve a DMA channel */
  7477. diff -urN linux.store/linux/include/asm-arm/irq-no.h linux/include/asm-arm/irq-no.h
  7478. --- linux.store/linux/include/asm-arm/irq-no.h    Sun Feb 11 09:32:55 1996
  7479. +++ linux/include/asm-arm/irq-no.h    Wed Mar 13 15:28:12 1996
  7480. @@ -1,25 +1,11 @@
  7481. -#define IRQ_PRINTERBUSY        0
  7482. -#define IRQ_SERIALRING        1
  7483. -#define IRQ_PRINTERACK        2
  7484. -#define IRQ_VSYNCPULSE        3
  7485. -#define IRQ_POWERON        4
  7486. -#define IRQ_TIMER0        5
  7487. -#define IRQ_TIMER1        6
  7488. -#define IRQ_7            7
  7489. -#define IRQ_8            8
  7490. -#define IRQ_SOUNDCHANGE        9
  7491. -#define IRQ_SERIALPORT        10
  7492. -#define IRQ_HARDDISK        11
  7493. -#define IRQ_FLOPPYDISK        12
  7494. -#define IRQ_EXPANSIONCARD    13
  7495. -#define IRQ_KEYBOARDTX        14
  7496. -#define IRQ_KEYBOARDRX        15
  7497. +/*
  7498. + * linux/include/asm-arm/irq-no.h
  7499. + *
  7500. + * Machine independent interrupt numbers
  7501. + */
  7502.  
  7503. -#define FIQ_FLOPPYDATA        0
  7504. -#define FIQ_ECONET        2
  7505. -#define FIQ_EXPANSIONCARD    6
  7506. -
  7507. -#define TIMER_IRQ        IRQ_TIMER0
  7508. -
  7509. -#define NUM_IRQS        32
  7510. +#include <asm/arch/irqs.h>
  7511.  
  7512. +#ifndef NR_IRQS
  7513. +#define NR_IRQS        32
  7514. +#endif
  7515. diff -urN linux.store/linux/include/asm-arm/irq.h linux/include/asm-arm/irq.h
  7516. --- linux.store/linux/include/asm-arm/irq.h    Sun Feb 11 09:32:55 1996
  7517. +++ linux/include/asm-arm/irq.h    Sun Feb 11 09:32:54 1996
  7518. @@ -3,8 +3,7 @@
  7519.  
  7520.  #include <linux/linkage.h>
  7521.  #include <asm/segment.h>
  7522. -
  7523. -#define NR_IRQS 32
  7524. +#include <asm/irq-no.h>
  7525.  
  7526.  extern void disable_irq(unsigned int);
  7527.  extern void enable_irq(unsigned int);
  7528. diff -urN linux.store/linux/include/asm-arm/page.h linux/include/asm-arm/page.h
  7529. --- linux.store/linux/include/asm-arm/page.h    Sun Feb 11 09:32:55 1996
  7530. +++ linux/include/asm-arm/page.h    Sun Feb 11 09:32:55 1996
  7531. @@ -1,109 +1 @@
  7532. -#ifndef __ASM_ARM_PAGE_H
  7533. -#define __ASM_ARM_PAGE_H
  7534. -
  7535. -#include <linux/config.h>
  7536. -
  7537. -/* PAGE_SHIFT determines the page size */
  7538. -/* Check for 32K and 16K page sizes */
  7539. -#ifdef CONFIG_PAGE_32K
  7540. -#define PAGE_SHIFT    15
  7541. -#else
  7542. -#ifdef CONFIG_PAGE_16K
  7543. -#define PAGE_SHIFT    14
  7544. -#else
  7545. -#define PAGE_SHIFT    page_shift
  7546. -extern char page_shift;
  7547. -#endif
  7548. -#endif
  7549. -
  7550. -#define LOGICAL_END    0x02000000
  7551. -
  7552. -#define PAGE_SIZE       (1UL << PAGE_SHIFT)
  7553. -#define PAGE_MASK       (~(PAGE_SIZE-1))
  7554. -
  7555. -#ifdef __KERNEL__
  7556. -
  7557. -#define CONFIG_STRICT_MM_TYPECHECKS
  7558. -
  7559. -#ifdef CONFIG_STRICT_MM_TYPECHECKS
  7560. -/*
  7561. - * These are used to make use of C type-checking..
  7562. - */
  7563. -typedef struct { unsigned long pte; } pte_t;
  7564. -typedef struct { unsigned long pmd; } pmd_t;
  7565. -typedef struct { unsigned long pgd; } pgd_t;
  7566. -typedef struct { unsigned long pgprot; } pgprot_t;
  7567. -
  7568. -#define pte_val(x)      ((x).pte)
  7569. -#define pmd_val(x)      ((x).pmd)
  7570. -#define pgd_val(x)      ((x).pgd)
  7571. -#define pgprot_val(x)   ((x).pgprot)
  7572. -
  7573. -#define __pte(x)        ((pte_t) { (x) } )
  7574. -#define __pmd(x)        ((pmd_t) { (x) } )
  7575. -#define __pgd(x)        ((pgd_t) { (x) } )
  7576. -#define __pgprot(x)     ((pgprot_t) { (x) } )
  7577. -
  7578. -#else
  7579. -/*
  7580. - * .. while these make it easier on the compiler
  7581. - */
  7582. -typedef unsigned long pte_t;
  7583. -typedef unsigned long pmd_t;
  7584. -typedef unsigned long pgd_t;
  7585. -typedef unsigned long pgprot_t;
  7586. -
  7587. -#define pte_val(x)      (x)
  7588. -#define pmd_val(x)      (x)
  7589. -#define pgd_val(x)      (x)
  7590. -#define pgprot_val(x)   (x)
  7591. -
  7592. -#define __pte(x)        (x)
  7593. -#define __pmd(x)        (x)
  7594. -#define __pgd(x)        (x)
  7595. -#define __pgprot(x)     (x)
  7596. -
  7597. -#endif
  7598. -
  7599. -extern void remap_task (pgd_t *);
  7600. -
  7601. -/*
  7602. - * TLB invalidation:
  7603. - *
  7604. - *  - invalidate() invalidates the current task TLBs
  7605. - *  - invalidate_all() invalidates all processes TLBs
  7606. - *  - invalidate_task(task) invalidates the specified tasks TLB's
  7607. - *  - invalidate_page(task, vmaddr) invalidates one page
  7608. - */
  7609. -#define invalidate() \
  7610. -    remap_task(current->mm->pgd)
  7611. -#define invalidate_all() invalidate()
  7612. -#define invalidate_task(task) \
  7613. -do { if ((task)->mm == current->mm) invalidate(); } while (0)
  7614. -#define invalidate_page(task,addr) \
  7615. -do { if ((task)->mm == current->mm) invalidate(); } while (0)
  7616. -
  7617. -/* Certain architectures need to do special things when pte's
  7618. - * within a page table are directly modified.  Thus, the following
  7619. - * hook is made available.
  7620. - */
  7621. -#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
  7622. -
  7623. -/* to align the pointer to the (next) page boundary */
  7624. -#define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
  7625. -
  7626. -/* This handles the memory map.. */
  7627. -#define PAGE_OFFSET        0x02000000
  7628. -#define MAP_NR(addr)        (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
  7629. -
  7630. -typedef struct {
  7631. -    unsigned count:24,
  7632. -         age:6,
  7633. -         dirty:1,
  7634. -         reserved:1;
  7635. -} mem_map_t;
  7636. -
  7637. -#endif /* __KERNEL__ */
  7638. -
  7639. -#endif /* _ARM_PAGE_H */
  7640. -
  7641. +#include <asm/proc/page.h>
  7642. diff -urN linux.store/linux/include/asm-arm/param.h linux/include/asm-arm/param.h
  7643. --- linux.store/linux/include/asm-arm/param.h    Sun Feb 11 09:32:55 1996
  7644. +++ linux/include/asm-arm/param.h    Sun Feb 11 09:32:55 1996
  7645. @@ -1,21 +1 @@
  7646. -#ifndef __ASM_ARM_PARAM_H
  7647. -#define __ASM_ARM_PARAM_H
  7648. -
  7649. -#ifndef HZ
  7650. -#define HZ 100
  7651. -#endif
  7652. -
  7653. -#define EXEC_PAGESIZE   32768
  7654. -
  7655. -#ifndef NGROUPS
  7656. -#define NGROUPS         32
  7657. -#endif
  7658. -
  7659. -#ifndef NOGROUP
  7660. -#define NOGROUP         (-1)
  7661. -#endif
  7662. -
  7663. -#define MAXHOSTNAMELEN  64      /* max length of hostname */
  7664. -
  7665. -#endif
  7666. -
  7667. +#include <asm/proc/param.h>
  7668. diff -urN linux.store/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
  7669. --- linux.store/linux/include/asm-arm/pgtable.h    Sun Feb 11 09:32:55 1996
  7670. +++ linux/include/asm-arm/pgtable.h    Sun Feb 11 09:32:55 1996
  7671. @@ -1,285 +1 @@
  7672. -#ifndef __ASM_ARM_PGTABLE_H
  7673. -#define __ASM_ARM_PGTABLE_H
  7674. -
  7675. -/* PMD_SHIFT determines the size of the area a second-level page table can map */
  7676. -#define PMD_SHIFT       PAGE_SHIFT
  7677. -#define PMD_SIZE        (1UL << PMD_SHIFT)
  7678. -#define PMD_MASK        (~(PMD_SIZE-1))
  7679. -
  7680. -/* PGDIR_SHIFT determines what a third-level page table entry can map */
  7681. -#define PGDIR_SHIFT     PAGE_SHIFT
  7682. -#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
  7683. -#define PGDIR_MASK      (~(PGDIR_SIZE-1))
  7684. -
  7685. -/*
  7686. - * entries per page directory level: the i386 is two-level, so
  7687. - * we don't really have any PMD directory physically.
  7688. - */
  7689. -#define PTRS_PER_PTE    1
  7690. -#define PTRS_PER_PMD    1
  7691. -#define PTRS_PER_PGD    1024
  7692. -
  7693. -/* Just any arbitrary offset to the start of the vmalloc VM area: the
  7694. - * current 8MB value just means that there will be a 8MB "hole" after the
  7695. - * physical memory until the kernel virtual memory starts.  That means that
  7696. - * any out-of-bounds memory accesses will hopefully be caught.
  7697. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  7698. - * area for the same reason. ;)
  7699. - */
  7700. -#define VMALLOC_START    0x01A00000
  7701. -#define VMALLOC_VMADDR(x) ((unsigned long)(x))
  7702. -
  7703. -#define _PAGE_PRESENT   0x001
  7704. -#define _PAGE_RW        0x002
  7705. -#define _PAGE_USER      0x004
  7706. -#define _PAGE_PCD       0x010
  7707. -#define _PAGE_ACCESSED  0x020
  7708. -#define _PAGE_DIRTY     0x040
  7709. -#define _PAGE_COW       0x200   /* implemented in software (one of the AVL bits) */
  7710. -
  7711. -#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
  7712. -#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
  7713. -
  7714. -#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
  7715. -#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
  7716. -#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
  7717. -#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  7718. -#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  7719. -
  7720. -/*
  7721. - * The i386 can't do page protection for execute, and considers that the same are read.
  7722. - * Also, write permissions imply read permissions. This is the closest we can get..
  7723. - */
  7724. -#define __P000  PAGE_NONE
  7725. -#define __P001  PAGE_READONLY
  7726. -#define __P010  PAGE_COPY
  7727. -#define __P011  PAGE_COPY
  7728. -#define __P100  PAGE_READONLY
  7729. -#define __P101  PAGE_READONLY
  7730. -#define __P110  PAGE_COPY
  7731. -#define __P111  PAGE_COPY
  7732. -
  7733. -#define __S000  PAGE_NONE
  7734. -#define __S001  PAGE_READONLY
  7735. -#define __S010  PAGE_SHARED
  7736. -#define __S011  PAGE_SHARED
  7737. -#define __S100  PAGE_READONLY
  7738. -#define __S101  PAGE_READONLY
  7739. -#define __S110  PAGE_SHARED
  7740. -#define __S111  PAGE_SHARED
  7741. -
  7742. -/*
  7743. - * Define this if things work differently on a i386 and a i486:
  7744. - * it will (on a i486) warn about kernel memory accesses that are
  7745. - * done without a 'verify_area(VERIFY_WRITE,..)'
  7746. - */
  7747. -#undef CONFIG_TEST_VERIFY_AREA
  7748. -
  7749. -#ifndef not_yet_checked
  7750. -/* page table for 0-4MB for everybody */
  7751. -extern unsigned long pg0[1024];
  7752. -#endif
  7753. -
  7754. -/*
  7755. - * BAD_PAGE is used for a bogus page.
  7756. - *
  7757. - * ZERO_PAGE is a global shared page that is always zero: used
  7758. - * for zero-mapped memory areas etc..
  7759. - */
  7760. -extern pte_t __bad_page(void);
  7761. -extern unsigned long __zero_page(void);
  7762. -
  7763. -#define BAD_PAGE __bad_page()
  7764. -#define ZERO_PAGE __zero_page()
  7765. -
  7766. -/* number of bits that fit into a memory pointer */
  7767. -#define BITS_PER_PTR                    (8*sizeof(unsigned long))
  7768. -
  7769. -/* to align the pointer to a pointer address */
  7770. -#define PTR_MASK                        (~(sizeof(void*)-1))
  7771. -
  7772. -/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
  7773. -/* 64-bit machines, beware!  SRB. */
  7774. -#define SIZEOF_PTR_LOG2                 2
  7775. -
  7776. -/* to set the page-dir */
  7777. -#define SET_PAGE_DIR(tsk,pgdir) \
  7778. -do { \
  7779. -    if ((tsk) == current) \
  7780. -        remap_task((pgdir)); \
  7781. -} while (0)
  7782. -
  7783. -extern unsigned long physical_start;
  7784. -extern unsigned long physical_end;
  7785. -
  7786. -extern inline int pte_none(pte_t pte)           { return !pte_val(pte); }
  7787. -extern inline int pte_present(pte_t pte)        { return pte_val(pte) & _PAGE_PRESENT; }
  7788. -extern inline int pte_inuse(pte_t *ptep)        { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
  7789. -extern inline void pte_clear(pte_t *ptep)       { pte_val(*ptep) = 0; }
  7790. -extern inline void pte_reuse(pte_t * ptep)
  7791. -{
  7792. -    if (!mem_map[MAP_NR(ptep)].reserved)
  7793. -        mem_map[MAP_NR(ptep)].count++;
  7794. -}
  7795. -
  7796. -extern inline int pmd_none(pmd_t pmd)           { return 0; }
  7797. -extern inline int pmd_bad(pmd_t pmd)            { return 0; }
  7798. -extern inline int pmd_present(pmd_t pmd)        { return 1; }
  7799. -extern inline int pmd_inuse(pmd_t *pmdp)        { return 0; }
  7800. -extern inline void pmd_clear(pmd_t * pmdp)      { }
  7801. -extern inline void pmd_reuse(pmd_t * pmdp)      { }
  7802. -
  7803. -
  7804. -/*
  7805. - * The "pgd_xxx()" functions here are trivial for a folded two-level
  7806. - * setup: the pgd is never bad, and a pmd always exists (as it's folded
  7807. - * into the pgd entry)
  7808. - */
  7809. -extern inline int pgd_none(pgd_t pgd)           { return 0; }
  7810. -extern inline int pgd_bad(pgd_t pgd)            { return 0; }
  7811. -extern inline int pgd_present(pgd_t pgd)        { return 1; }
  7812. -extern inline int pgd_inuse(pgd_t * pgdp)       { return 0; }
  7813. -extern inline void pgd_clear(pgd_t * pgdp)      { }
  7814. -
  7815. -/*
  7816. - * The following only work if pte_present() is true.
  7817. - * Undefined behaviour if not..
  7818. - */
  7819. -extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  7820. -extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
  7821. -extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  7822. -extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
  7823. -extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
  7824. -extern inline int pte_cow(pte_t pte)            { return pte_val(pte) & _PAGE_COW; }
  7825. -
  7826. -extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_RW; return pte; }
  7827. -extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  7828. -extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  7829. -extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
  7830. -extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
  7831. -extern inline pte_t pte_uncow(pte_t pte)        { pte_val(pte) &= ~_PAGE_COW; return pte; }
  7832. -extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) |= _PAGE_RW; return pte; }
  7833. -extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  7834. -extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  7835. -extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
  7836. -extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
  7837. -extern inline pte_t pte_mkcow(pte_t pte)        { pte_val(pte) |= _PAGE_COW; return pte; }
  7838. -
  7839. -/*
  7840. - * Conversion functions: convert a page and protection to a page entry,
  7841. - * and a page entry and page directory to the page they refer to.
  7842. - */
  7843. -extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
  7844. -{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
  7845. -
  7846. -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  7847. -{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
  7848. -
  7849. -extern inline unsigned long pte_page(pte_t pte)
  7850. -{ return pte_val(pte) & PAGE_MASK; }
  7851. -
  7852. -extern inline unsigned long pmd_page(pmd_t pmd)
  7853. -{ return pmd_val(pmd) & PAGE_MASK; }
  7854. -
  7855. -/* to find an entry in a page-table-directory */
  7856. -extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
  7857. -{
  7858. -        return mm->pgd + (address >> PGDIR_SHIFT);
  7859. -}
  7860. -
  7861. -/* Find an entry in the second-level page table.. */
  7862. -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
  7863. -{
  7864. -        return (pmd_t *) dir;
  7865. -}
  7866. -
  7867. -/* Find an entry in the third-level page table.. */
  7868. -extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
  7869. -{
  7870. -        return (pte_t *) dir;
  7871. -}
  7872. -
  7873. -/*
  7874. - * Allocate and free page tables. The xxx_kernel() versions are
  7875. - * used to allocate a kernel page table - this turns on ASN bits
  7876. - * if any, and marks the page tables reserved.
  7877. - */
  7878. -extern inline void pte_free_kernel(pte_t * pte)
  7879. -{
  7880. -    pte_val(*pte) = 0;
  7881. -}
  7882. -
  7883. -extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
  7884. -{
  7885. -    return (pte_t *) pmd;
  7886. -}
  7887. -
  7888. -/*
  7889. - * allocating and freeing a pmd is trivial: the 1-entry pmd is
  7890. - * inside the pgd, so has no extra memory associated with it.
  7891. - */
  7892. -extern inline void pmd_free_kernel(pmd_t * pmd)
  7893. -{
  7894. -}
  7895. -
  7896. -extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
  7897. -{
  7898. -        return (pmd_t *) pgd;
  7899. -}
  7900. -
  7901. -extern inline void pte_free(pte_t * pte)
  7902. -{
  7903. -}
  7904. -
  7905. -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
  7906. -{
  7907. -    return (pte_t *) pmd;
  7908. -}
  7909. -
  7910. -/*
  7911. - * allocating and freeing a pmd is trivial: the 1-entry pmd is
  7912. - * inside the pgd, so has no extra memory associated with it.
  7913. - */
  7914. -extern inline void pmd_free(pmd_t * pmd)
  7915. -{
  7916. -}
  7917. -
  7918. -extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
  7919. -{
  7920. -        return (pmd_t *) pgd;
  7921. -}
  7922. -
  7923. -extern inline void pgd_free(pgd_t * pgd)
  7924. -{
  7925. -    extern void kfree(void *);
  7926. -    kfree((void *)pgd);
  7927. -}
  7928. -
  7929. -extern inline pgd_t * pgd_alloc(void)
  7930. -{
  7931. -    pgd_t *pgd;
  7932. -    extern void *kmalloc(unsigned int, int);
  7933. -    
  7934. -        pgd = (pgd_t *) kmalloc(32*1024*1024*4/PAGE_SIZE, GFP_KERNEL);
  7935. -        memset(pgd, 0, 32*1024*1024*4/PAGE_SIZE);
  7936. -
  7937. -        return pgd;
  7938. -}
  7939. -
  7940. -extern pgd_t swapper_pg_dir[1024];
  7941. -
  7942. -/*
  7943. - * The i386 doesn't have any external MMU info: the kernel page
  7944. - * tables contain all the necessary information.
  7945. - */
  7946. -extern inline void update_mmu_cache(struct vm_area_struct * vma,
  7947. -        unsigned long address, pte_t pte)
  7948. -{
  7949. -}
  7950. -
  7951. -#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
  7952. -#define SWP_OFFSET(entry) ((entry) >> 8)
  7953. -#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) <<  8))
  7954. -
  7955. -#endif /* _ARM_PAGE_H */
  7956. -
  7957. +#include <asm/proc/pgtable.h>
  7958. diff -urN linux.store/linux/include/asm-arm/proc-arm2/assembler.h linux/include/asm-arm/proc-arm2/assembler.h
  7959. --- linux.store/linux/include/asm-arm/proc-arm2/assembler.h    Thu Jan  1 01:00:00 1970
  7960. +++ linux/include/asm-arm/proc-arm2/assembler.h    Sun Feb 11 09:32:56 1996
  7961. @@ -0,0 +1,34 @@
  7962. +/*
  7963. + * linux/asm/proc-arm2/assembler.h
  7964. + *
  7965. + * Copyright (C) 1996 Russell King
  7966. + *
  7967. + * This file contains arm architecture specific defines
  7968. + * for the different processors
  7969. + */
  7970. +
  7971. +#define LOADREGS(cond, base, reglist...)\
  7972. +    ldm##cond    base,reglist^
  7973. +
  7974. +#define RETINSTR(instr, regs...)\
  7975. +    instr##s    regs
  7976. +
  7977. +#define MODENOP\
  7978. +    mov    r0, r0
  7979. +
  7980. +#define SAVEIRQS
  7981. +#define RESTOREIRQS
  7982. +
  7983. +#define DISABLEIRQS\
  7984. +    teqp    pc, #0x08000003
  7985. +
  7986. +#define ENABLEIRQS\
  7987. +    teqp    pc, #0x00000003
  7988. +
  7989. +#define USERMODE\
  7990. +    teqp    pc, #0x00000000;\
  7991. +    mov    r0, r0
  7992. +
  7993. +#define SVCMODE\
  7994. +    teqp    pc, #0x00000003;\
  7995. +    mov    r0, r0
  7996. diff -urN linux.store/linux/include/asm-arm/proc-arm2/bugs.h linux/include/asm-arm/proc-arm2/bugs.h
  7997. --- linux.store/linux/include/asm-arm/proc-arm2/bugs.h    Thu Jan  1 01:00:00 1970
  7998. +++ linux/include/asm-arm/proc-arm2/bugs.h    Sun Feb 11 09:32:54 1996
  7999. @@ -0,0 +1,17 @@
  8000. +/*
  8001. + *  include/asm-arm/bugs.h
  8002. + *
  8003. + *  Copyright (C) 1995  Russell King
  8004. + */
  8005. +
  8006. +/*
  8007. + * This is included by init/main.c to check for architecture-dependent bugs.
  8008. + *
  8009. + * Needs:
  8010. + *      void check_bugs(void);
  8011. + */
  8012. +         
  8013. +static inline void check_bugs(void)
  8014. +{
  8015. +}
  8016. +
  8017. diff -urN linux.store/linux/include/asm-arm/proc-arm2/page.h linux/include/asm-arm/proc-arm2/page.h
  8018. --- linux.store/linux/include/asm-arm/proc-arm2/page.h    Thu Jan  1 01:00:00 1970
  8019. +++ linux/include/asm-arm/proc-arm2/page.h    Wed Mar 13 22:26:38 1996
  8020. @@ -0,0 +1,105 @@
  8021. +/*
  8022. + * linux/include/asm-arm/proc-arm2/page.h
  8023. + *
  8024. + * Copyright (C) 1996 Russell King
  8025. + */
  8026. +
  8027. +#ifndef __ASM_PROC_PAGE_H
  8028. +#define __ASM_PROC_PAGE_H
  8029. +
  8030. +#include <linux/config.h>
  8031. +
  8032. +/* PAGE_SHIFT determines the page size */
  8033. +#define PAGE_SHIFT    15
  8034. +
  8035. +#define LOGICAL_END    0x02000000
  8036. +
  8037. +#define PAGE_SIZE       (1UL << PAGE_SHIFT)
  8038. +#define PAGE_MASK       (~(PAGE_SIZE-1))
  8039. +
  8040. +#ifdef __KERNEL__
  8041. +
  8042. +#define CONFIG_STRICT_MM_TYPECHECKS
  8043. +
  8044. +#ifdef CONFIG_STRICT_MM_TYPECHECKS
  8045. +/*
  8046. + * These are used to make use of C type-checking..
  8047. + */
  8048. +typedef struct { unsigned long pte; } pte_t;
  8049. +typedef struct { unsigned long pmd; } pmd_t;
  8050. +typedef struct { unsigned long pgd; } pgd_t;
  8051. +typedef struct { unsigned long pgprot; } pgprot_t;
  8052. +
  8053. +#define pte_val(x)      ((x).pte)
  8054. +#define pmd_val(x)      ((x).pmd)
  8055. +#define pgd_val(x)      ((x).pgd)
  8056. +#define pgprot_val(x)   ((x).pgprot)
  8057. +
  8058. +#define __pte(x)        ((pte_t) { (x) } )
  8059. +#define __pmd(x)        ((pmd_t) { (x) } )
  8060. +#define __pgd(x)        ((pgd_t) { (x) } )
  8061. +#define __pgprot(x)     ((pgprot_t) { (x) } )
  8062. +
  8063. +#else
  8064. +/*
  8065. + * .. while these make it easier on the compiler
  8066. + */
  8067. +typedef unsigned long pte_t;
  8068. +typedef unsigned long pmd_t;
  8069. +typedef unsigned long pgd_t;
  8070. +typedef unsigned long pgprot_t;
  8071. +
  8072. +#define pte_val(x)      (x)
  8073. +#define pmd_val(x)      (x)
  8074. +#define pgd_val(x)      (x)
  8075. +#define pgprot_val(x)   (x)
  8076. +
  8077. +#define __pte(x)        (x)
  8078. +#define __pmd(x)        (x)
  8079. +#define __pgd(x)        (x)
  8080. +#define __pgprot(x)     (x)
  8081. +
  8082. +#endif
  8083. +
  8084. +extern void remap_task (pgd_t *);
  8085. +
  8086. +/*
  8087. + * TLB invalidation:
  8088. + *
  8089. + *  - invalidate() invalidates the current task TLBs
  8090. + *  - invalidate_all() invalidates all processes TLBs
  8091. + *  - invalidate_task(task) invalidates the specified tasks TLB's
  8092. + *  - invalidate_page(task, vmaddr) invalidates one page
  8093. + */
  8094. +#define invalidate() \
  8095. +    remap_task(current->mm->pgd)
  8096. +#define invalidate_all() invalidate()
  8097. +#define invalidate_task(task) \
  8098. +do { if ((task)->mm == current->mm) invalidate(); } while (0)
  8099. +#define invalidate_page(task,addr) \
  8100. +do { if ((task)->mm == current->mm) invalidate(); } while (0)
  8101. +
  8102. +/* Certain architectures need to do special things when pte's
  8103. + * within a page table are directly modified.  Thus, the following
  8104. + * hook is made available.
  8105. + */
  8106. +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
  8107. +
  8108. +/* to align the pointer to the (next) page boundary */
  8109. +#define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
  8110. +
  8111. +/* This handles the memory map.. */
  8112. +#define PAGE_OFFSET        0x02000000
  8113. +#define MAP_NR(addr)        (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
  8114. +
  8115. +typedef struct {
  8116. +    unsigned count:24,
  8117. +         age:6,
  8118. +         dirty:1,
  8119. +         reserved:1;
  8120. +} mem_map_t;
  8121. +
  8122. +#endif /* __KERNEL__ */
  8123. +
  8124. +#endif /* __ASM_PROC_PAGE_H */
  8125. +
  8126. diff -urN linux.store/linux/include/asm-arm/proc-arm2/param.h linux/include/asm-arm/proc-arm2/param.h
  8127. --- linux.store/linux/include/asm-arm/proc-arm2/param.h    Thu Jan  1 01:00:00 1970
  8128. +++ linux/include/asm-arm/proc-arm2/param.h    Sun Feb 11 09:32:56 1996
  8129. @@ -0,0 +1,26 @@
  8130. +/*
  8131. + * linux/include/asm-arm/proc-arm2/param.h
  8132. + *
  8133. + * Copyright (C) 1996 Russell King
  8134. + */
  8135. +
  8136. +#ifndef __ASM_PROC_PARAM_H
  8137. +#define __ASM_PROC_PARAM_H
  8138. +
  8139. +#ifndef HZ
  8140. +#define HZ 100
  8141. +#endif
  8142. +
  8143. +#define EXEC_PAGESIZE   32768
  8144. +
  8145. +#ifndef NGROUPS
  8146. +#define NGROUPS         32
  8147. +#endif
  8148. +
  8149. +#ifndef NOGROUP
  8150. +#define NOGROUP         (-1)
  8151. +#endif
  8152. +
  8153. +#define MAXHOSTNAMELEN  64      /* max length of hostname */
  8154. +
  8155. +#endif
  8156. diff -urN linux.store/linux/include/asm-arm/proc-arm2/pgtable.h linux/include/asm-arm/proc-arm2/pgtable.h
  8157. --- linux.store/linux/include/asm-arm/proc-arm2/pgtable.h    Thu Jan  1 01:00:00 1970
  8158. +++ linux/include/asm-arm/proc-arm2/pgtable.h    Sun Feb 11 09:32:56 1996
  8159. @@ -0,0 +1,291 @@
  8160. +/*
  8161. + * linux/include/asm-arm/proc-arm2/pgtable.h
  8162. + *
  8163. + * Copyright (C) 1996 Russell King
  8164. + */
  8165. +
  8166. +#ifndef __ASM_PROC_PGTABLE_H
  8167. +#define __ASM_PROC_PGTABLE_H
  8168. +
  8169. +/* PMD_SHIFT determines the size of the area a second-level page table can map */
  8170. +#define PMD_SHIFT       PAGE_SHIFT
  8171. +#define PMD_SIZE        (1UL << PMD_SHIFT)
  8172. +#define PMD_MASK        (~(PMD_SIZE-1))
  8173. +
  8174. +/* PGDIR_SHIFT determines what a third-level page table entry can map */
  8175. +#define PGDIR_SHIFT     PAGE_SHIFT
  8176. +#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
  8177. +#define PGDIR_MASK      (~(PGDIR_SIZE-1))
  8178. +
  8179. +/*
  8180. + * entries per page directory level: the i386 is two-level, so
  8181. + * we don't really have any PMD directory physically.
  8182. + */
  8183. +#define PTRS_PER_PTE    1
  8184. +#define PTRS_PER_PMD    1
  8185. +#define PTRS_PER_PGD    1024
  8186. +
  8187. +/* Just any arbitrary offset to the start of the vmalloc VM area: the
  8188. + * current 8MB value just means that there will be a 8MB "hole" after the
  8189. + * physical memory until the kernel virtual memory starts.  That means that
  8190. + * any out-of-bounds memory accesses will hopefully be caught.
  8191. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  8192. + * area for the same reason. ;)
  8193. + */
  8194. +#define VMALLOC_START    0x01A00000
  8195. +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
  8196. +
  8197. +#define _PAGE_PRESENT   0x001
  8198. +#define _PAGE_RW        0x002
  8199. +#define _PAGE_USER      0x004
  8200. +#define _PAGE_PCD       0x010
  8201. +#define _PAGE_ACCESSED  0x020
  8202. +#define _PAGE_DIRTY     0x040
  8203. +#define _PAGE_COW       0x200   /* implemented in software (one of the AVL bits) */
  8204. +
  8205. +#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
  8206. +#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
  8207. +
  8208. +#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
  8209. +#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
  8210. +#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
  8211. +#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  8212. +#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  8213. +
  8214. +/*
  8215. + * The i386 can't do page protection for execute, and considers that the same are read.
  8216. + * Also, write permissions imply read permissions. This is the closest we can get..
  8217. + */
  8218. +#define __P000  PAGE_NONE
  8219. +#define __P001  PAGE_READONLY
  8220. +#define __P010  PAGE_COPY
  8221. +#define __P011  PAGE_COPY
  8222. +#define __P100  PAGE_READONLY
  8223. +#define __P101  PAGE_READONLY
  8224. +#define __P110  PAGE_COPY
  8225. +#define __P111  PAGE_COPY
  8226. +
  8227. +#define __S000  PAGE_NONE
  8228. +#define __S001  PAGE_READONLY
  8229. +#define __S010  PAGE_SHARED
  8230. +#define __S011  PAGE_SHARED
  8231. +#define __S100  PAGE_READONLY
  8232. +#define __S101  PAGE_READONLY
  8233. +#define __S110  PAGE_SHARED
  8234. +#define __S111  PAGE_SHARED
  8235. +
  8236. +/*
  8237. + * Define this if things work differently on a i386 and a i486:
  8238. + * it will (on a i486) warn about kernel memory accesses that are
  8239. + * done without a 'verify_area(VERIFY_WRITE,..)'
  8240. + */
  8241. +#undef CONFIG_TEST_VERIFY_AREA
  8242. +
  8243. +#ifndef not_yet_checked
  8244. +/* page table for 0-4MB for everybody */
  8245. +extern unsigned long pg0[1024];
  8246. +#endif
  8247. +
  8248. +/*
  8249. + * BAD_PAGE is used for a bogus page.
  8250. + *
  8251. + * ZERO_PAGE is a global shared page that is always zero: used
  8252. + * for zero-mapped memory areas etc..
  8253. + */
  8254. +extern pte_t __bad_page(void);
  8255. +extern unsigned long __zero_page(void);
  8256. +
  8257. +#define BAD_PAGE __bad_page()
  8258. +#define ZERO_PAGE __zero_page()
  8259. +
  8260. +/* number of bits that fit into a memory pointer */
  8261. +#define BITS_PER_PTR                    (8*sizeof(unsigned long))
  8262. +
  8263. +/* to align the pointer to a pointer address */
  8264. +#define PTR_MASK                        (~(sizeof(void*)-1))
  8265. +
  8266. +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
  8267. +/* 64-bit machines, beware!  SRB. */
  8268. +#define SIZEOF_PTR_LOG2                 2
  8269. +
  8270. +/* to set the page-dir */
  8271. +#define SET_PAGE_DIR(tsk,pgdir) \
  8272. +do { \
  8273. +    if ((tsk) == current) \
  8274. +        remap_task((pgdir)); \
  8275. +} while (0)
  8276. +
  8277. +extern unsigned long physical_start;
  8278. +extern unsigned long physical_end;
  8279. +
  8280. +extern inline int pte_none(pte_t pte)           { return !pte_val(pte); }
  8281. +extern inline int pte_present(pte_t pte)        { return pte_val(pte) & _PAGE_PRESENT; }
  8282. +extern inline int pte_inuse(pte_t *ptep)        { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
  8283. +extern inline void pte_clear(pte_t *ptep)       { pte_val(*ptep) = 0; }
  8284. +extern inline void pte_reuse(pte_t * ptep)
  8285. +{
  8286. +    if (!mem_map[MAP_NR(ptep)].reserved)
  8287. +        mem_map[MAP_NR(ptep)].count++;
  8288. +}
  8289. +
  8290. +extern inline int pmd_none(pmd_t pmd)           { return 0; }
  8291. +extern inline int pmd_bad(pmd_t pmd)            { return 0; }
  8292. +extern inline int pmd_present(pmd_t pmd)        { return 1; }
  8293. +extern inline int pmd_inuse(pmd_t *pmdp)        { return 0; }
  8294. +extern inline void pmd_clear(pmd_t * pmdp)      { }
  8295. +extern inline void pmd_reuse(pmd_t * pmdp)      { }
  8296. +
  8297. +
  8298. +/*
  8299. + * The "pgd_xxx()" functions here are trivial for a folded two-level
  8300. + * setup: the pgd is never bad, and a pmd always exists (as it's folded
  8301. + * into the pgd entry)
  8302. + */
  8303. +extern inline int pgd_none(pgd_t pgd)           { return 0; }
  8304. +extern inline int pgd_bad(pgd_t pgd)            { return 0; }
  8305. +extern inline int pgd_present(pgd_t pgd)        { return 1; }
  8306. +extern inline int pgd_inuse(pgd_t * pgdp)       { return 0; }
  8307. +extern inline void pgd_clear(pgd_t * pgdp)      { }
  8308. +
  8309. +/*
  8310. + * The following only work if pte_present() is true.
  8311. + * Undefined behaviour if not..
  8312. + */
  8313. +extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  8314. +extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
  8315. +extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  8316. +extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
  8317. +extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
  8318. +extern inline int pte_cow(pte_t pte)            { return pte_val(pte) & _PAGE_COW; }
  8319. +
  8320. +extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_RW; return pte; }
  8321. +extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  8322. +extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  8323. +extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
  8324. +extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
  8325. +extern inline pte_t pte_uncow(pte_t pte)        { pte_val(pte) &= ~_PAGE_COW; return pte; }
  8326. +extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) |= _PAGE_RW; return pte; }
  8327. +extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  8328. +extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  8329. +extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
  8330. +extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
  8331. +extern inline pte_t pte_mkcow(pte_t pte)        { pte_val(pte) |= _PAGE_COW; return pte; }
  8332. +
  8333. +/*
  8334. + * Conversion functions: convert a page and protection to a page entry,
  8335. + * and a page entry and page directory to the page they refer to.
  8336. + */
  8337. +extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
  8338. +{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
  8339. +
  8340. +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  8341. +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
  8342. +
  8343. +extern inline unsigned long pte_page(pte_t pte)
  8344. +{ return pte_val(pte) & PAGE_MASK; }
  8345. +
  8346. +extern inline unsigned long pmd_page(pmd_t pmd)
  8347. +{ return pmd_val(pmd) & PAGE_MASK; }
  8348. +
  8349. +/* to find an entry in a page-table-directory */
  8350. +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
  8351. +{
  8352. +        return mm->pgd + (address >> PGDIR_SHIFT);
  8353. +}
  8354. +
  8355. +/* Find an entry in the second-level page table.. */
  8356. +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
  8357. +{
  8358. +        return (pmd_t *) dir;
  8359. +}
  8360. +
  8361. +/* Find an entry in the third-level page table.. */
  8362. +extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
  8363. +{
  8364. +        return (pte_t *) dir;
  8365. +}
  8366. +
  8367. +/*
  8368. + * Allocate and free page tables. The xxx_kernel() versions are
  8369. + * used to allocate a kernel page table - this turns on ASN bits
  8370. + * if any, and marks the page tables reserved.
  8371. + */
  8372. +extern inline void pte_free_kernel(pte_t * pte)
  8373. +{
  8374. +    pte_val(*pte) = 0;
  8375. +}
  8376. +
  8377. +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
  8378. +{
  8379. +    return (pte_t *) pmd;
  8380. +}
  8381. +
  8382. +/*
  8383. + * allocating and freeing a pmd is trivial: the 1-entry pmd is
  8384. + * inside the pgd, so has no extra memory associated with it.
  8385. + */
  8386. +extern inline void pmd_free_kernel(pmd_t * pmd)
  8387. +{
  8388. +}
  8389. +
  8390. +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
  8391. +{
  8392. +        return (pmd_t *) pgd;
  8393. +}
  8394. +
  8395. +extern inline void pte_free(pte_t * pte)
  8396. +{
  8397. +}
  8398. +
  8399. +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
  8400. +{
  8401. +    return (pte_t *) pmd;
  8402. +}
  8403. +
  8404. +/*
  8405. + * allocating and freeing a pmd is trivial: the 1-entry pmd is
  8406. + * inside the pgd, so has no extra memory associated with it.
  8407. + */
  8408. +extern inline void pmd_free(pmd_t * pmd)
  8409. +{
  8410. +}
  8411. +
  8412. +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
  8413. +{
  8414. +        return (pmd_t *) pgd;
  8415. +}
  8416. +
  8417. +extern inline void pgd_free(pgd_t * pgd)
  8418. +{
  8419. +    extern void kfree(void *);
  8420. +    kfree((void *)pgd);
  8421. +}
  8422. +
  8423. +extern inline pgd_t * pgd_alloc(void)
  8424. +{
  8425. +    pgd_t *pgd;
  8426. +    extern void *kmalloc(unsigned int, int);
  8427. +    
  8428. +        pgd = (pgd_t *) kmalloc(32*1024*1024*4/PAGE_SIZE, GFP_KERNEL);
  8429. +        memset(pgd, 0, 32*1024*1024*4/PAGE_SIZE);
  8430. +
  8431. +        return pgd;
  8432. +}
  8433. +
  8434. +extern pgd_t swapper_pg_dir[1024];
  8435. +
  8436. +/*
  8437. + * The i386 doesn't have any external MMU info: the kernel page
  8438. + * tables contain all the necessary information.
  8439. + */
  8440. +extern inline void update_mmu_cache(struct vm_area_struct * vma,
  8441. +        unsigned long address, pte_t pte)
  8442. +{
  8443. +}
  8444. +
  8445. +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
  8446. +#define SWP_OFFSET(entry) ((entry) >> 8)
  8447. +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) <<  8))
  8448. +
  8449. +#endif /* __ASM_PROC_PAGE_H */
  8450. +
  8451. diff -urN linux.store/linux/include/asm-arm/proc-arm2/ptrace.h linux/include/asm-arm/proc-arm2/ptrace.h
  8452. --- linux.store/linux/include/asm-arm/proc-arm2/ptrace.h    Thu Jan  1 01:00:00 1970
  8453. +++ linux/include/asm-arm/proc-arm2/ptrace.h    Sun Feb 11 09:32:56 1996
  8454. @@ -0,0 +1,14 @@
  8455. +/*
  8456. + * linux/include/asm-arm/proc-arm2/ptrace.h
  8457. + *
  8458. + * Copyright (C) 1996 Russell King
  8459. + */
  8460. +
  8461. +#ifndef __ASM_PROC_PTRACE_H
  8462. +#define __ASM_PROC_PTRACE_H
  8463. +
  8464. +#define user_mode(regs)            (((regs)->ARM_pc & 3) == 0)
  8465. +#define instruction_pointer(regs)    ((regs)->ARM_pc & 0x03fffffc)
  8466. +
  8467. +#endif
  8468. +
  8469. diff -urN linux.store/linux/include/asm-arm/proc-arm2/segment.h linux/include/asm-arm/proc-arm2/segment.h
  8470. --- linux.store/linux/include/asm-arm/proc-arm2/segment.h    Thu Jan  1 01:00:00 1970
  8471. +++ linux/include/asm-arm/proc-arm2/segment.h    Sun Feb 11 09:32:56 1996
  8472. @@ -0,0 +1,121 @@
  8473. +/*
  8474. + * linux/include/asm-arm/proc-arm2/segment.h
  8475. + *
  8476. + * Copyright (C) 1996 Russell King
  8477. + */
  8478. +
  8479. +#ifndef __ASM_PROC_SEGMENT_H
  8480. +#define __ASM_PROC_SEGMENT_H
  8481. +
  8482. +static inline void __put_user(unsigned long x, void * y, int size)
  8483. +{
  8484. +    if (IS_USER_SEG) {
  8485. +        switch (size) {
  8486. +            case 1:
  8487. +                __asm__(
  8488. +                " strbt    %0, [%1]\n"
  8489. +                : : "r" (x), "r" (y)
  8490. +                : "lr", "cc");
  8491. +                break;
  8492. +            case 2:
  8493. +                { register unsigned long tmp;
  8494. +                __asm__ __volatile__(
  8495. +                " strbt %1, [%2], #1\n"
  8496. +                " mov   %0, %1, lsr #8\n"
  8497. +                " strbt %0, [%2]\n"
  8498. +                : "=&r" (tmp)
  8499. +                : "r" (x), "r" (y)
  8500. +                : "2", "lr", "cc");
  8501. +                }
  8502. +                break;
  8503. +            case 4:
  8504. +                if ((int)y & 3) {
  8505. +                register unsigned long tmp;
  8506. +                __asm__ __volatile__(
  8507. +                " strbt %1, [%2], #1\n"
  8508. +                " mov   %0, %1, lsr #8\n"
  8509. +                " strbt %0, [%2], #1\n"
  8510. +                " mov   %0, %0, lsr #8\n"
  8511. +                " strbt %0, [%2], #1\n"
  8512. +                " mov   %0, %0, lsr #8\n"
  8513. +                " strbt %0, [%2]\n"
  8514. +                : "=&r" (tmp)
  8515. +                : "r" (x), "r" (y)
  8516. +                : "2", "lr", "cc");
  8517. +                } else {
  8518. +                __asm__(
  8519. +                " strt  %0, [%1]\n"
  8520. +                : : "r" (x), "r" (y)
  8521. +                : "lr", "cc");
  8522. +                }
  8523. +                break;
  8524. +            default:
  8525. +                bad_user_access_length();
  8526. +        }
  8527. +    } else {
  8528. +        switch (size) {
  8529. +            case 1: *(unsigned char *)y = x; break;
  8530. +            case 2: *(unsigned short *)y = x; break;
  8531. +            case 4: *(unsigned long *)y = x; break;
  8532. +            default:
  8533. +                bad_user_access_length();
  8534. +        }
  8535. +    }
  8536. +}
  8537. +
  8538. +static inline unsigned long __get_user(const void *y, int size)
  8539. +{
  8540. +    unsigned long result1, result2;
  8541. +
  8542. +    if (IS_USER_SEG) {
  8543. +        switch (size) {
  8544. +            case 1:
  8545. +                __asm__(
  8546. +                " ldrbt %0, [%1]\n"
  8547. +                : "=r" (result1)
  8548. +                : "r" (y)
  8549. +                : "lr", "cc");
  8550. +                return result1;
  8551. +            case 2:
  8552. +                __asm__(
  8553. +                " ldrbt %0, [%2], #1\n"
  8554. +                " ldrbt %1, [%2]\n"
  8555. +                " orr   %0, %0, %1, lsl #8\n"
  8556. +                : "=&r" (result1), "=r" (result2)
  8557. +                : "r" (y)
  8558. +                : "lr", "cc");
  8559. +                return result1;
  8560. +            case 4:
  8561. +                if ((int)y & 3) {
  8562. +                __asm__(
  8563. +                " ldrt %0, [%2], #4\n"
  8564. +                " ldrt %1, [%2]\n"
  8565. +                : "=&r" (result1), "=r" (result2)
  8566. +                : "r" ((int)y & ~3)
  8567. +                : "lr", "cc");
  8568. +                result1 >>= ((int)y & 3)*8;
  8569. +                return result1 | (result2 << (32-((int)y & 3)*8));
  8570. +                } else {
  8571. +                __asm__(
  8572. +                " ldrt %0, [%1]\n"
  8573. +                : "=r" (result1)
  8574. +                : "r" (y)
  8575. +                : "lr", "cc");
  8576. +                return result1;
  8577. +                }
  8578. +            default:
  8579. +                return bad_user_access_length();
  8580. +        }
  8581. +    } else {
  8582. +        switch (size) {
  8583. +            case 1: return *(unsigned char *)y; break;
  8584. +            case 2: return *(unsigned short *)y; break;
  8585. +            case 4: return *(unsigned long *)y; break;
  8586. +            default:
  8587. +                return bad_user_access_length();
  8588. +        }
  8589. +    }
  8590. +}        
  8591. +
  8592. +#endif /* __ASM_PROC_SEGMENT_H */
  8593. +
  8594. diff -urN linux.store/linux/include/asm-arm/proc-arm2/shmparam.h linux/include/asm-arm/proc-arm2/shmparam.h
  8595. --- linux.store/linux/include/asm-arm/proc-arm2/shmparam.h    Thu Jan  1 01:00:00 1970
  8596. +++ linux/include/asm-arm/proc-arm2/shmparam.h    Sun Feb 11 09:32:56 1996
  8597. @@ -0,0 +1,18 @@
  8598. +/*
  8599. + * linux/include/asm-arm/proc-arm2/shmparam.h
  8600. + *
  8601. + * Copyright (C) 1996 Russell King
  8602. + *
  8603. + * definitions for the shared process memory on the ARM2
  8604. + */
  8605. +
  8606. +#ifndef __ASM_PROC_SHMPARAM_H
  8607. +#define __ASM_PROC_SHMPARAM_H
  8608. +
  8609. +#ifndef SHM_RANGE_START
  8610. +#define SHM_RANGE_START    0x00a00000
  8611. +#define SHM_RANGE_END    0x00c00000
  8612. +#endif
  8613. +
  8614. +#endif
  8615. +
  8616. diff -urN linux.store/linux/include/asm-arm/proc-arm2/system.h linux/include/asm-arm/proc-arm2/system.h
  8617. --- linux.store/linux/include/asm-arm/proc-arm2/system.h    Thu Jan  1 01:00:00 1970
  8618. +++ linux/include/asm-arm/proc-arm2/system.h    Sun Feb 11 09:32:56 1996
  8619. @@ -0,0 +1,138 @@
  8620. +/*
  8621. + * linux/include/asm-arm/proc-arm2/system.h
  8622. + *
  8623. + * Copyright (C) 1996 Russell King
  8624. + */
  8625. +
  8626. +#ifndef __ASM_PROC_SYSTEM_H
  8627. +#define __ASM_PROC_SYSTEM_H
  8628. +
  8629. +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  8630. +{
  8631. +    unsigned long temp0, temp1;
  8632. +    switch (size) {
  8633. +        case 1: __asm__ __volatile__(
  8634. +            " mov   %0, pc\n"
  8635. +            " orr   %1, %0, #0x08000000\n"
  8636. +            " teqp  %1, #0\n"
  8637. +            " mov   %1, %3\n"    /* Safe: in case it uses the same reg */
  8638. +            " ldrb  %2, [%4]\n"
  8639. +            " strb  %1, [%4]\n"
  8640. +            " teqp  %0, #0\n"
  8641. +            : "=r" (temp0), "=r" (temp1), "=r" (x)
  8642. +            : "r" (x), "r" (ptr)
  8643. +            : "memory");
  8644. +            break;
  8645. +        case 2: { unsigned long temp0, temp1;
  8646. +            if (((long)ptr) & 1)
  8647. +            {
  8648. +                void *pc;
  8649. +                __asm__("mov\t%0, pc": "=r" (pc));
  8650. +                arm_malalignedptr("xchg", pc, ptr);
  8651. +            }
  8652. +            __asm__ __volatile__(
  8653. +            " mov   %0, pc\n"
  8654. +            " orr   %1, %0, #0x08000000\n"
  8655. +            " teqp  %1, #0\n"
  8656. +            " mov   %1, %3\n"
  8657. +            " ldr    %2, [%4]\n"
  8658. +            " strb  %1, [%4]\n"
  8659. +            " mov   %1, %1, lsr #8\n"
  8660. +            " strb  %1, [%4, #1]\n"
  8661. +            " teqp  %0, #0\n"
  8662. +            : "=r" (temp0), "=r" (temp1), "=r" (x)
  8663. +            : "r" (x), "r" (ptr)
  8664. +            : "memory");
  8665. +            val &= 0xffff;
  8666. +            break;
  8667. +            }
  8668. +        case 4: { unsigned long temp0, temp1;
  8669. +            if (((long)ptr) & 3)
  8670. +            {
  8671. +                void *pc;
  8672. +                __asm__("mov\t%0, pc": "=r" (pc));
  8673. +                arm_malalignedptr("xchg", pc, ptr);
  8674. +            }
  8675. +            __asm__ __volatile__(
  8676. +            " mov   %0, pc\n"
  8677. +            " orr   %1, %0, #0x08000000\n"
  8678. +            " teqp  %1, #0\n"
  8679. +            " mov   %1, %3\n"
  8680. +            " ldr   %2, [%4]\n"
  8681. +            " str   %1, [%4]\n"
  8682. +            " teqp  %0, #0\n"
  8683. +            : "=r" (temp0), "=r" (temp1), "=r" (x)
  8684. +            : "r" (x), "r" (ptr)
  8685. +            : "memory");
  8686. +            }
  8687. +            break;
  8688. +        default:
  8689. +            {
  8690. +                void *pc;
  8691. +                __asm__("mov\t%0, pc": "=r" (pc));
  8692. +                arm_invalidptr("xchg", pc, size);
  8693. +                x = 0;
  8694. +            }
  8695. +    }
  8696. +    return x;
  8697. +}
  8698. +
  8699. +/*
  8700. + * A couple of speedups for the ARM
  8701. + */
  8702. +#define save_flags_cli(x)        \
  8703. +    do {                \
  8704. +      unsigned long temp;        \
  8705. +      __asm__ __volatile__(        \
  8706. +"    mov    %0, pc\n"        \
  8707. +"    orr    %1, %0, #0x08000000\n"    \
  8708. +"    and    %0, %0, #0x0c000000\n"    \
  8709. +"    teqp    %1, #0\n"        \
  8710. +      : "=r" (x), "=r" (temp));    \
  8711. +    } while (0)
  8712. +    
  8713. +
  8714. +#define sti()                \
  8715. +    do {                \
  8716. +      unsigned long temp;        \
  8717. +      __asm__ __volatile__(        \
  8718. +"    mov    %0, pc\n"        \
  8719. +"    bic    %0, %0, #0x08000000\n"    \
  8720. +"    teqp    %0, #0\n"        \
  8721. +      : "=r" (temp)            \
  8722. +      : );                \
  8723. +    } while(0)
  8724. +
  8725. +#define cli()                \
  8726. +    do {                \
  8727. +      unsigned long temp;        \
  8728. +      __asm__ __volatile__(        \
  8729. +"    mov    %0, pc\n"        \
  8730. +"    orr    %0, %0, #0x08000000\n"    \
  8731. +"    teqp    %0, #0\n"        \
  8732. +      : "=r" (temp)            \
  8733. +      : );                \
  8734. +    } while(0)
  8735. +
  8736. +#define save_flags(x)            \
  8737. +    do {                \
  8738. +      __asm__ __volatile__(        \
  8739. +"    mov    %0, pc\n"        \
  8740. +"    and    %0, %0, #0x0c000000\n"    \
  8741. +      : "=r" (x) : );        \
  8742. +    } while (0)
  8743. +
  8744. +#define restore_flags(x)        \
  8745. +    do {                \
  8746. +      unsigned long temp;        \
  8747. +      __asm__ __volatile__(        \
  8748. +"    mov    %0, pc\n"        \
  8749. +"    bic    %0, %0, #0x0c000000\n"    \
  8750. +"    orr    %0, %0, %1\n"        \
  8751. +"    teqp    %0, #0\n"        \
  8752. +      : "=r" (temp)            \
  8753. +      : "r" (x)            \
  8754. +      : "cc");            \
  8755. +    } while (0)
  8756. +
  8757. +#endif
  8758. diff -urN linux.store/linux/include/asm-arm/proc-arm3/assembler.h linux/include/asm-arm/proc-arm3/assembler.h
  8759. --- linux.store/linux/include/asm-arm/proc-arm3/assembler.h    Thu Jan  1 01:00:00 1970
  8760. +++ linux/include/asm-arm/proc-arm3/assembler.h    Sun Feb 11 09:32:54 1996
  8761. @@ -0,0 +1,52 @@
  8762. +/*
  8763. + * linux/asm-arm/proc-arm3/assembler.h
  8764. + *
  8765. + * This file contains arm architecture specific defines
  8766. + * for the different processors
  8767. + */
  8768. +
  8769. +/*
  8770. + * LOADREGS: multiple register load (ldm) with pc in register list
  8771. + *        (takes account of ARM6 not using ^)
  8772. + *
  8773. + * RETINSTR: return instruction: adds the 's' in at the end of the
  8774. + *        instruction if this is not an ARM6
  8775. + *
  8776. + * SAVEIRQS: save IRQ state (not required on ARM2/ARM3 - done
  8777. + *        implicitly
  8778. + *
  8779. + * RESTOREIRQS: restore IRQ state (not required on ARM2/ARM3 - done
  8780. + *        implicitly with ldm ... ^ or movs.
  8781. + *
  8782. + * These next two need thinking about - can't easily use stack... (see system.S)
  8783. + * DISABLEIRQS: disable IRQS in SVC mode
  8784. + *
  8785. + * ENABLEIRQS: enable IRQS in SVC mode
  8786. + *
  8787. + * USERMODE: switch to USER mode
  8788. + *
  8789. + * SVCMODE: switch to SVC mode
  8790. + */
  8791. +
  8792. +#define LOADREGS(cond, base, reglist...)\
  8793. +    ldm##cond    base,reglist^
  8794. +
  8795. +#define RETINSTR(instr, regs...)\
  8796. +    instr##s    regs
  8797. +
  8798. +#define MODENOP
  8799. +
  8800. +#define SAVEIRQS
  8801. +#define RESTOREIRQS
  8802. +
  8803. +#define DISABLEIRQS\
  8804. +    teqp    pc, #0x08000003
  8805. +
  8806. +#define ENABLEIRQS\
  8807. +    teqp    pc, #0x00000003
  8808. +
  8809. +#define USERMODE\
  8810. +    teqp    pc, #0x00000000
  8811. +
  8812. +#define SVCMODE\
  8813. +    teqp    pc, #0x00000003
  8814. diff -urN linux.store/linux/include/asm-arm/proc-arm3/bugs.h linux/include/asm-arm/proc-arm3/bugs.h
  8815. --- linux.store/linux/include/asm-arm/proc-arm3/bugs.h    Thu Jan  1 01:00:00 1970
  8816. +++ linux/include/asm-arm/proc-arm3/bugs.h    Sun Feb 11 09:32:54 1996
  8817. @@ -0,0 +1,17 @@
  8818. +/*
  8819. + *  include/asm-arm/bugs.h
  8820. + *
  8821. + *  Copyright (C) 1995  Russell King
  8822. + */
  8823. +
  8824. +/*
  8825. + * This is included by init/main.c to check for architecture-dependent bugs.
  8826. + *
  8827. + * Needs:
  8828. + *      void check_bugs(void);
  8829. + */
  8830. +         
  8831. +static inline void check_bugs(void)
  8832. +{
  8833. +}
  8834. +
  8835. diff -urN linux.store/linux/include/asm-arm/proc-arm3/page.h linux/include/asm-arm/proc-arm3/page.h
  8836. --- linux.store/linux/include/asm-arm/proc-arm3/page.h    Thu Jan  1 01:00:00 1970
  8837. +++ linux/include/asm-arm/proc-arm3/page.h    Wed Mar 13 22:26:56 1996
  8838. @@ -0,0 +1,105 @@
  8839. +/*
  8840. + * linux/include/asm-arm/proc-arm3/page.h
  8841. + *
  8842. + * Copyright (C) 1995, 1996 Russell King
  8843. + */
  8844. +
  8845. +#ifndef __ASM_PROC_PAGE_H
  8846. +#define __ASM_PROC_PAGE_H
  8847. +
  8848. +#include <linux/config.h>
  8849. +
  8850. +/* PAGE_SHIFT determines the page size */
  8851. +#define PAGE_SHIFT    15
  8852. +
  8853. +#define LOGICAL_END    0x02000000
  8854. +
  8855. +#define PAGE_SIZE       (1UL << PAGE_SHIFT)
  8856. +#define PAGE_MASK       (~(PAGE_SIZE-1))
  8857. +
  8858. +#ifdef __KERNEL__
  8859. +
  8860. +#define CONFIG_STRICT_MM_TYPECHECKS
  8861. +
  8862. +#ifdef CONFIG_STRICT_MM_TYPECHECKS
  8863. +/*
  8864. + * These are used to make use of C type-checking..
  8865. + */
  8866. +typedef struct { unsigned long pte; } pte_t;
  8867. +typedef struct { unsigned long pmd; } pmd_t;
  8868. +typedef struct { unsigned long pgd; } pgd_t;
  8869. +typedef struct { unsigned long pgprot; } pgprot_t;
  8870. +
  8871. +#define pte_val(x)      ((x).pte)
  8872. +#define pmd_val(x)      ((x).pmd)
  8873. +#define pgd_val(x)      ((x).pgd)
  8874. +#define pgprot_val(x)   ((x).pgprot)
  8875. +
  8876. +#define __pte(x)        ((pte_t) { (x) } )
  8877. +#define __pmd(x)        ((pmd_t) { (x) } )
  8878. +#define __pgd(x)        ((pgd_t) { (x) } )
  8879. +#define __pgprot(x)     ((pgprot_t) { (x) } )
  8880. +
  8881. +#else
  8882. +/*
  8883. + * .. while these make it easier on the compiler
  8884. + */
  8885. +typedef unsigned long pte_t;
  8886. +typedef unsigned long pmd_t;
  8887. +typedef unsigned long pgd_t;
  8888. +typedef unsigned long pgprot_t;
  8889. +
  8890. +#define pte_val(x)      (x)
  8891. +#define pmd_val(x)      (x)
  8892. +#define pgd_val(x)      (x)
  8893. +#define pgprot_val(x)   (x)
  8894. +
  8895. +#define __pte(x)        (x)
  8896. +#define __pmd(x)        (x)
  8897. +#define __pgd(x)        (x)
  8898. +#define __pgprot(x)     (x)
  8899. +
  8900. +#endif
  8901. +
  8902. +extern void remap_task (pgd_t *);
  8903. +
  8904. +/*
  8905. + * TLB invalidation:
  8906. + *
  8907. + *  - invalidate() invalidates the current task TLBs
  8908. + *  - invalidate_all() invalidates all processes TLBs
  8909. + *  - invalidate_task(task) invalidates the specified tasks TLB's
  8910. + *  - invalidate_page(task, vmaddr) invalidates one page
  8911. + */
  8912. +#define invalidate() \
  8913. +    remap_task(current->mm->pgd)
  8914. +#define invalidate_all() invalidate()
  8915. +#define invalidate_task(task) \
  8916. +do { if ((task)->mm == current->mm) invalidate(); } while (0)
  8917. +#define invalidate_page(task,addr) \
  8918. +do { if ((task)->mm == current->mm) invalidate(); } while (0)
  8919. +
  8920. +/* Certain architectures need to do special things when pte's
  8921. + * within a page table are directly modified.  Thus, the following
  8922. + * hook is made available.
  8923. + */
  8924. +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
  8925. +
  8926. +/* to align the pointer to the (next) page boundary */
  8927. +#define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
  8928. +
  8929. +/* This handles the memory map.. */
  8930. +#define PAGE_OFFSET        0x02000000
  8931. +#define MAP_NR(addr)        (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
  8932. +
  8933. +typedef struct {
  8934. +    unsigned count:24,
  8935. +         age:6,
  8936. +         dirty:1,
  8937. +         reserved:1;
  8938. +} mem_map_t;
  8939. +
  8940. +#endif /* __KERNEL__ */
  8941. +
  8942. +#endif /* __ASM_PROC_PAGE_H */
  8943. +
  8944. diff -urN linux.store/linux/include/asm-arm/proc-arm3/param.h linux/include/asm-arm/proc-arm3/param.h
  8945. --- linux.store/linux/include/asm-arm/proc-arm3/param.h    Thu Jan  1 01:00:00 1970
  8946. +++ linux/include/asm-arm/proc-arm3/param.h    Sun Feb 11 09:32:54 1996
  8947. @@ -0,0 +1,27 @@
  8948. +/*
  8949. + * linux/include/asm-arm/proc-arm3/param.h
  8950. + *
  8951. + * Copyright (C) 1995, 1996 Russell King
  8952. + */
  8953. +
  8954. +#ifndef __ASM_PROC_PARAM_H
  8955. +#define __ASM_PROC_PARAM_H
  8956. +
  8957. +#ifndef HZ
  8958. +#define HZ 100
  8959. +#endif
  8960. +
  8961. +#define EXEC_PAGESIZE   32768
  8962. +
  8963. +#ifndef NGROUPS
  8964. +#define NGROUPS         32
  8965. +#endif
  8966. +
  8967. +#ifndef NOGROUP
  8968. +#define NOGROUP         (-1)
  8969. +#endif
  8970. +
  8971. +#define MAXHOSTNAMELEN  64      /* max length of hostname */
  8972. +
  8973. +#endif
  8974. +
  8975. diff -urN linux.store/linux/include/asm-arm/proc-arm3/pgtable.h linux/include/asm-arm/proc-arm3/pgtable.h
  8976. --- linux.store/linux/include/asm-arm/proc-arm3/pgtable.h    Thu Jan  1 01:00:00 1970
  8977. +++ linux/include/asm-arm/proc-arm3/pgtable.h    Sun Feb 11 09:32:54 1996
  8978. @@ -0,0 +1,291 @@
  8979. +/*
  8980. + * linux/include/asm-arm/proc-arm3/pgtable.h
  8981. + *
  8982. + * Copyright (C) 1995, 1996 Russell King
  8983. + */
  8984. +
  8985. +#ifndef __ASM_PROC_PGTABLE_H
  8986. +#define __ASM_PROC_PGTABLE_H
  8987. +
  8988. +/* PMD_SHIFT determines the size of the area a second-level page table can map */
  8989. +#define PMD_SHIFT       PAGE_SHIFT
  8990. +#define PMD_SIZE        (1UL << PMD_SHIFT)
  8991. +#define PMD_MASK        (~(PMD_SIZE-1))
  8992. +
  8993. +/* PGDIR_SHIFT determines what a third-level page table entry can map */
  8994. +#define PGDIR_SHIFT     PAGE_SHIFT
  8995. +#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
  8996. +#define PGDIR_MASK      (~(PGDIR_SIZE-1))
  8997. +
  8998. +/*
  8999. + * entries per page directory level: the i386 is two-level, so
  9000. + * we don't really have any PMD directory physically.
  9001. + */
  9002. +#define PTRS_PER_PTE    1
  9003. +#define PTRS_PER_PMD    1
  9004. +#define PTRS_PER_PGD    1024
  9005. +
  9006. +/* Just any arbitrary offset to the start of the vmalloc VM area: the
  9007. + * current 8MB value just means that there will be a 8MB "hole" after the
  9008. + * physical memory until the kernel virtual memory starts.  That means that
  9009. + * any out-of-bounds memory accesses will hopefully be caught.
  9010. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  9011. + * area for the same reason. ;)
  9012. + */
  9013. +#define VMALLOC_START    0x01A00000
  9014. +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
  9015. +
  9016. +#define _PAGE_PRESENT   0x001
  9017. +#define _PAGE_RW        0x002
  9018. +#define _PAGE_USER      0x004
  9019. +#define _PAGE_PCD       0x010
  9020. +#define _PAGE_ACCESSED  0x020
  9021. +#define _PAGE_DIRTY     0x040
  9022. +#define _PAGE_COW       0x200   /* implemented in software (one of the AVL bits) */
  9023. +
  9024. +#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
  9025. +#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
  9026. +
  9027. +#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
  9028. +#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
  9029. +#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
  9030. +#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  9031. +#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  9032. +
  9033. +/*
  9034. + * The i386 can't do page protection for execute, and considers that the same are read.
  9035. + * Also, write permissions imply read permissions. This is the closest we can get..
  9036. + */
  9037. +#define __P000  PAGE_NONE
  9038. +#define __P001  PAGE_READONLY
  9039. +#define __P010  PAGE_COPY
  9040. +#define __P011  PAGE_COPY
  9041. +#define __P100  PAGE_READONLY
  9042. +#define __P101  PAGE_READONLY
  9043. +#define __P110  PAGE_COPY
  9044. +#define __P111  PAGE_COPY
  9045. +
  9046. +#define __S000  PAGE_NONE
  9047. +#define __S001  PAGE_READONLY
  9048. +#define __S010  PAGE_SHARED
  9049. +#define __S011  PAGE_SHARED
  9050. +#define __S100  PAGE_READONLY
  9051. +#define __S101  PAGE_READONLY
  9052. +#define __S110  PAGE_SHARED
  9053. +#define __S111  PAGE_SHARED
  9054. +
  9055. +/*
  9056. + * Define this if things work differently on a i386 and a i486:
  9057. + * it will (on a i486) warn about kernel memory accesses that are
  9058. + * done without a 'verify_area(VERIFY_WRITE,..)'
  9059. + */
  9060. +#undef CONFIG_TEST_VERIFY_AREA
  9061. +
  9062. +#ifndef not_yet_checked
  9063. +/* page table for 0-4MB for everybody */
  9064. +extern unsigned long pg0[1024];
  9065. +#endif
  9066. +
  9067. +/*
  9068. + * BAD_PAGE is used for a bogus page.
  9069. + *
  9070. + * ZERO_PAGE is a global shared page that is always zero: used
  9071. + * for zero-mapped memory areas etc..
  9072. + */
  9073. +extern pte_t __bad_page(void);
  9074. +extern unsigned long __zero_page(void);
  9075. +
  9076. +#define BAD_PAGE __bad_page()
  9077. +#define ZERO_PAGE __zero_page()
  9078. +
  9079. +/* number of bits that fit into a memory pointer */
  9080. +#define BITS_PER_PTR                    (8*sizeof(unsigned long))
  9081. +
  9082. +/* to align the pointer to a pointer address */
  9083. +#define PTR_MASK                        (~(sizeof(void*)-1))
  9084. +
  9085. +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
  9086. +/* 64-bit machines, beware!  SRB. */
  9087. +#define SIZEOF_PTR_LOG2                 2
  9088. +
  9089. +/* to set the page-dir */
  9090. +#define SET_PAGE_DIR(tsk,pgdir) \
  9091. +do { \
  9092. +    if ((tsk) == current) \
  9093. +        remap_task((pgdir)); \
  9094. +} while (0)
  9095. +
  9096. +extern unsigned long physical_start;
  9097. +extern unsigned long physical_end;
  9098. +
  9099. +extern inline int pte_none(pte_t pte)           { return !pte_val(pte); }
  9100. +extern inline int pte_present(pte_t pte)        { return pte_val(pte) & _PAGE_PRESENT; }
  9101. +extern inline int pte_inuse(pte_t *ptep)        { return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
  9102. +extern inline void pte_clear(pte_t *ptep)       { pte_val(*ptep) = 0; }
  9103. +extern inline void pte_reuse(pte_t * ptep)
  9104. +{
  9105. +    if (!mem_map[MAP_NR(ptep)].reserved)
  9106. +        mem_map[MAP_NR(ptep)].count++;
  9107. +}
  9108. +
  9109. +extern inline int pmd_none(pmd_t pmd)           { return 0; }
  9110. +extern inline int pmd_bad(pmd_t pmd)            { return 0; }
  9111. +extern inline int pmd_present(pmd_t pmd)        { return 1; }
  9112. +extern inline int pmd_inuse(pmd_t *pmdp)        { return 0; }
  9113. +extern inline void pmd_clear(pmd_t * pmdp)      { }
  9114. +extern inline void pmd_reuse(pmd_t * pmdp)      { }
  9115. +
  9116. +
  9117. +/*
  9118. + * The "pgd_xxx()" functions here are trivial for a folded two-level
  9119. + * setup: the pgd is never bad, and a pmd always exists (as it's folded
  9120. + * into the pgd entry)
  9121. + */
  9122. +extern inline int pgd_none(pgd_t pgd)           { return 0; }
  9123. +extern inline int pgd_bad(pgd_t pgd)            { return 0; }
  9124. +extern inline int pgd_present(pgd_t pgd)        { return 1; }
  9125. +extern inline int pgd_inuse(pgd_t * pgdp)       { return 0; }
  9126. +extern inline void pgd_clear(pgd_t * pgdp)      { }
  9127. +
  9128. +/*
  9129. + * The following only work if pte_present() is true.
  9130. + * Undefined behaviour if not..
  9131. + */
  9132. +extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  9133. +extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
  9134. +extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
  9135. +extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
  9136. +extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
  9137. +extern inline int pte_cow(pte_t pte)            { return pte_val(pte) & _PAGE_COW; }
  9138. +
  9139. +extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_RW; return pte; }
  9140. +extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  9141. +extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
  9142. +extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
  9143. +extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
  9144. +extern inline pte_t pte_uncow(pte_t pte)        { pte_val(pte) &= ~_PAGE_COW; return pte; }
  9145. +extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) |= _PAGE_RW; return pte; }
  9146. +extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  9147. +extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
  9148. +extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
  9149. +extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
  9150. +extern inline pte_t pte_mkcow(pte_t pte)        { pte_val(pte) |= _PAGE_COW; return pte; }
  9151. +
  9152. +/*
  9153. + * Conversion functions: convert a page and protection to a page entry,
  9154. + * and a page entry and page directory to the page they refer to.
  9155. + */
  9156. +extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
  9157. +{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
  9158. +
  9159. +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  9160. +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
  9161. +
  9162. +extern inline unsigned long pte_page(pte_t pte)
  9163. +{ return pte_val(pte) & PAGE_MASK; }
  9164. +
  9165. +extern inline unsigned long pmd_page(pmd_t pmd)
  9166. +{ return pmd_val(pmd) & PAGE_MASK; }
  9167. +
  9168. +/* to find an entry in a page-table-directory */
  9169. +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
  9170. +{
  9171. +        return mm->pgd + (address >> PGDIR_SHIFT);
  9172. +}
  9173. +
  9174. +/* Find an entry in the second-level page table.. */
  9175. +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
  9176. +{
  9177. +        return (pmd_t *) dir;
  9178. +}
  9179. +
  9180. +/* Find an entry in the third-level page table.. */
  9181. +extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
  9182. +{
  9183. +        return (pte_t *) dir;
  9184. +}
  9185. +
  9186. +/*
  9187. + * Allocate and free page tables. The xxx_kernel() versions are
  9188. + * used to allocate a kernel page table - this turns on ASN bits
  9189. + * if any, and marks the page tables reserved.
  9190. + */
  9191. +extern inline void pte_free_kernel(pte_t * pte)
  9192. +{
  9193. +    pte_val(*pte) = 0;
  9194. +}
  9195. +
  9196. +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
  9197. +{
  9198. +    return (pte_t *) pmd;
  9199. +}
  9200. +
  9201. +/*
  9202. + * allocating and freeing a pmd is trivial: the 1-entry pmd is
  9203. + * inside the pgd, so has no extra memory associated with it.
  9204. + */
  9205. +extern inline void pmd_free_kernel(pmd_t * pmd)
  9206. +{
  9207. +}
  9208. +
  9209. +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
  9210. +{
  9211. +        return (pmd_t *) pgd;
  9212. +}
  9213. +
  9214. +extern inline void pte_free(pte_t * pte)
  9215. +{
  9216. +}
  9217. +
  9218. +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
  9219. +{
  9220. +    return (pte_t *) pmd;
  9221. +}
  9222. +
  9223. +/*
  9224. + * allocating and freeing a pmd is trivial: the 1-entry pmd is
  9225. + * inside the pgd, so has no extra memory associated with it.
  9226. + */
  9227. +extern inline void pmd_free(pmd_t * pmd)
  9228. +{
  9229. +}
  9230. +
  9231. +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
  9232. +{
  9233. +        return (pmd_t *) pgd;
  9234. +}
  9235. +
  9236. +extern inline void pgd_free(pgd_t * pgd)
  9237. +{
  9238. +    extern void kfree(void *);
  9239. +    kfree((void *)pgd);
  9240. +}
  9241. +
  9242. +extern inline pgd_t * pgd_alloc(void)
  9243. +{
  9244. +    pgd_t *pgd;
  9245. +    extern void *kmalloc(unsigned int, int);
  9246. +    
  9247. +        pgd = (pgd_t *) kmalloc(32*1024*1024*4/PAGE_SIZE, GFP_KERNEL);
  9248. +        memset(pgd, 0, 32*1024*1024*4/PAGE_SIZE);
  9249. +
  9250. +        return pgd;
  9251. +}
  9252. +
  9253. +extern pgd_t swapper_pg_dir[1024];
  9254. +
  9255. +/*
  9256. + * The i386 doesn't have any external MMU info: the kernel page
  9257. + * tables contain all the necessary information.
  9258. + */
  9259. +extern inline void update_mmu_cache(struct vm_area_struct * vma,
  9260. +        unsigned long address, pte_t pte)
  9261. +{
  9262. +}
  9263. +
  9264. +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
  9265. +#define SWP_OFFSET(entry) ((entry) >> 8)
  9266. +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) <<  8))
  9267. +
  9268. +#endif /* __ASM_PROC_PAGE_H */
  9269. +
  9270. diff -urN linux.store/linux/include/asm-arm/proc-arm3/ptrace.h linux/include/asm-arm/proc-arm3/ptrace.h
  9271. --- linux.store/linux/include/asm-arm/proc-arm3/ptrace.h    Thu Jan  1 01:00:00 1970
  9272. +++ linux/include/asm-arm/proc-arm3/ptrace.h    Sun Feb 11 09:32:54 1996
  9273. @@ -0,0 +1,14 @@
  9274. +/*
  9275. + * linux/include/asm-arm/proc-arm3/ptrace.h
  9276. + *
  9277. + * Copyright (C) 1996 Russell King
  9278. + */
  9279. +
  9280. +#ifndef __ASM_PROC_PTRACE_H
  9281. +#define __ASM_PROC_PTRACE_H
  9282. +
  9283. +#define user_mode(regs)            (((regs)->ARM_pc & 3) == 0)
  9284. +#define instruction_pointer(regs)    ((regs)->ARM_pc & 0x03fffffc)
  9285. +
  9286. +#endif
  9287. +
  9288. diff -urN linux.store/linux/include/asm-arm/proc-arm3/segment.h linux/include/asm-arm/proc-arm3/segment.h
  9289. --- linux.store/linux/include/asm-arm/proc-arm3/segment.h    Thu Jan  1 01:00:00 1970
  9290. +++ linux/include/asm-arm/proc-arm3/segment.h    Sun Feb 11 09:32:54 1996
  9291. @@ -0,0 +1,121 @@
  9292. +/*
  9293. + * linux/include/asm-arm/proc-arm3/segment.h
  9294. + *
  9295. + * Copyright (C) 1996 Russell King
  9296. + */
  9297. +
  9298. +#ifndef __ASM_PROC_SEGMENT_H
  9299. +#define __ASM_PROC_SEGMENT_H
  9300. +
  9301. +static inline void __put_user(unsigned long x, void * y, int size)
  9302. +{
  9303. +    if (IS_USER_SEG) {
  9304. +        switch (size) {
  9305. +            case 1:
  9306. +                __asm__(
  9307. +                " strbt    %0, [%1]\n"
  9308. +                : : "r" (x), "r" (y)
  9309. +                : "lr", "cc");
  9310. +                break;
  9311. +            case 2:
  9312. +                { register unsigned long tmp;
  9313. +                __asm__ __volatile__(
  9314. +                " strbt %1, [%2], #1\n"
  9315. +                " mov   %0, %1, lsr #8\n"
  9316. +                " strbt %0, [%2]\n"
  9317. +                : "=&r" (tmp)
  9318. +                : "r" (x), "r" (y)
  9319. +                : "2", "lr", "cc");
  9320. +                }
  9321. +                break;
  9322. +            case 4:
  9323. +                if ((int)y & 3) {
  9324. +                register unsigned long tmp;
  9325. +                __asm__ __volatile__(
  9326. +                " strbt %1, [%2], #1\n"
  9327. +                " mov   %0, %1, lsr #8\n"
  9328. +                " strbt %0, [%2], #1\n"
  9329. +                " mov   %0, %0, lsr #8\n"
  9330. +                " strbt %0, [%2], #1\n"
  9331. +                " mov   %0, %0, lsr #8\n"
  9332. +                " strbt %0, [%2]\n"
  9333. +                : "=&r" (tmp)
  9334. +                : "r" (x), "r" (y)
  9335. +                : "2", "lr", "cc");
  9336. +                } else {
  9337. +                __asm__(
  9338. +                " strt  %0, [%1]\n"
  9339. +                : : "r" (x), "r" (y)
  9340. +                : "lr", "cc");
  9341. +                }
  9342. +                break;
  9343. +            default:
  9344. +                bad_user_access_length();
  9345. +        }
  9346. +    } else {
  9347. +        switch (size) {
  9348. +            case 1: *(unsigned char *)y = x; break;
  9349. +            case 2: *(unsigned short *)y = x; break;
  9350. +            case 4: *(unsigned long *)y = x; break;
  9351. +            default:
  9352. +                bad_user_access_length();
  9353. +        }
  9354. +    }
  9355. +}
  9356. +
  9357. +static inline unsigned long __get_user(const void *y, int size)
  9358. +{
  9359. +    unsigned long result1, result2;
  9360. +
  9361. +    if (IS_USER_SEG) {
  9362. +        switch (size) {
  9363. +            case 1:
  9364. +                __asm__(
  9365. +                " ldrbt %0, [%1]\n"
  9366. +                : "=r" (result1)
  9367. +                : "r" (y)
  9368. +                : "lr", "cc");
  9369. +                return result1;
  9370. +            case 2:
  9371. +                __asm__(
  9372. +                " ldrbt %0, [%2], #1\n"
  9373. +                " ldrbt %1, [%2]\n"
  9374. +                " orr   %0, %0, %1, lsl #8\n"
  9375. +                : "=&r" (result1), "=r" (result2)
  9376. +                : "r" (y)
  9377. +                : "lr", "cc");
  9378. +                return result1;
  9379. +            case 4:
  9380. +                if ((int)y & 3) {
  9381. +                __asm__(
  9382. +                " ldrt %0, [%2], #4\n"
  9383. +                " ldrt %1, [%2]\n"
  9384. +                : "=&r" (result1), "=r" (result2)
  9385. +                : "r" ((int)y & ~3)
  9386. +                : "lr", "cc");
  9387. +                result1 >>= ((int)y & 3)*8;
  9388. +                return result1 | (result2 << (32-((int)y & 3)*8));
  9389. +                } else {
  9390. +                __asm__(
  9391. +                " ldrt %0, [%1]\n"
  9392. +                : "=r" (result1)
  9393. +                : "r" (y)
  9394. +                : "lr", "cc");
  9395. +                return result1;
  9396. +                }
  9397. +            default:
  9398. +                return bad_user_access_length();
  9399. +        }
  9400. +    } else {
  9401. +        switch (size) {
  9402. +            case 1: return *(unsigned char *)y; break;
  9403. +            case 2: return *(unsigned short *)y; break;
  9404. +            case 4: return *(unsigned long *)y; break;
  9405. +            default:
  9406. +                return bad_user_access_length();
  9407. +        }
  9408. +    }
  9409. +}        
  9410. +
  9411. +#endif /* __ASM_PROC_SEGMENT_H */
  9412. +
  9413. diff -urN linux.store/linux/include/asm-arm/proc-arm3/shmparam.h linux/include/asm-arm/proc-arm3/shmparam.h
  9414. --- linux.store/linux/include/asm-arm/proc-arm3/shmparam.h    Thu Jan  1 01:00:00 1970
  9415. +++ linux/include/asm-arm/proc-arm3/shmparam.h    Sun Feb 11 09:32:54 1996
  9416. @@ -0,0 +1,18 @@
  9417. +/*
  9418. + * linux/include/asm-arm/proc-arm3/shmparam.h
  9419. + *
  9420. + * Copyright (C) 1996 Russell King
  9421. + *
  9422. + * definitions for the shared process memory on the ARM3
  9423. + */
  9424. +
  9425. +#ifndef __ASM_PROC_SHMPARAM_H
  9426. +#define __ASM_PROC_SHMPARAM_H
  9427. +#ifndef SHM_RANGE_START
  9428. +#define SHM_RANGE_START    0x00a00000
  9429. +#define SHM_RANGE_END    0x00c00000
  9430. +#endif
  9431. +
  9432. +#endif
  9433. +
  9434. diff -urN linux.store/linux/include/asm-arm/proc-arm3/system.h linux/include/asm-arm/proc-arm3/system.h
  9435. --- linux.store/linux/include/asm-arm/proc-arm3/system.h    Thu Jan  1 01:00:00 1970
  9436. +++ linux/include/asm-arm/proc-arm3/system.h    Sun Feb 11 09:32:54 1996
  9437. @@ -0,0 +1,124 @@
  9438. +/*
  9439. + * linux/include/asm-arm/proc-arm3/system.h
  9440. + *
  9441. + * Copyright (C) 1995, 1996 Russell King
  9442. + */
  9443. +
  9444. +#ifndef __ASM_PROC_SYSTEM_H
  9445. +#define __ASM_PROC_SYSTEM_H
  9446. +
  9447. +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  9448. +{
  9449. +    switch (size) {
  9450. +        case 1:
  9451. +            __asm__ __volatile__(
  9452. +            " swpb   %0, %1, [%2]\n\t"
  9453. +            : "=r" (x)
  9454. +            : "r" (x), "r" (ptr)
  9455. +            : "memory");
  9456. +            break;
  9457. +        case 2: { unsigned long temp0, temp1;
  9458. +            if (((long)ptr) & 1)
  9459. +            {
  9460. +                void *pc;
  9461. +                __asm__("mov\t%0, pc": "=r" (pc));
  9462. +                arm_malalignedptr("xchg", pc, ptr);
  9463. +            }
  9464. +            __asm__ __volatile__(
  9465. +            " mov   %0, pc\n"
  9466. +            " orr   %1, %0, #0x08000000\n"
  9467. +            " teqp  %1, #0\n"
  9468. +            " mov   %1, %3\n"
  9469. +            " ldr    %2, [%4]\n"
  9470. +            " strb  %1, [%4]\n"
  9471. +            " mov   %1, %1, lsr #8\n"
  9472. +            " strb  %1, [%4, #1]\n"
  9473. +            " teqp  %0, #0\n"
  9474. +            : "=r" (temp0), "=r" (temp1), "=r" (x)
  9475. +            : "r" (x), "r" (ptr)
  9476. +            : "memory");
  9477. +            x &= 0xffff;
  9478. +            break;
  9479. +            }
  9480. +        case 4: if (((long)ptr) & 3)
  9481. +            {
  9482. +                void *pc;
  9483. +                __asm__("mov\t%0, pc": "=r" (pc));
  9484. +                arm_malalignedptr("xchg", pc, ptr);
  9485. +            }
  9486. +            __asm__ __volatile__(
  9487. +            " swp   %0, %1, [%2]\n"
  9488. +            : "=r" (x)
  9489. +            : "r" (x), "r" (ptr)
  9490. +            : "memory");
  9491. +            break;
  9492. +        default:
  9493. +            {
  9494. +                void *pc;
  9495. +                __asm__("mov\t%0, pc": "=r" (pc));
  9496. +                arm_invalidptr("xchg", pc, size);
  9497. +                x = 0;
  9498. +            }
  9499. +    }
  9500. +    return x;
  9501. +}
  9502. +
  9503. +/*
  9504. + * A couple of speedups for the ARM
  9505. + */
  9506. +#define save_flags_cli(x)        \
  9507. +    do {                \
  9508. +      unsigned long temp;        \
  9509. +      __asm__ __volatile__(        \
  9510. +"    mov    %0, pc\n"        \
  9511. +"    orr    %1, %0, #0x08000000\n"    \
  9512. +"    and    %0, %0, #0x0c000000\n"    \
  9513. +"    teqp    %1, #0\n"        \
  9514. +      : "=r" (x), "=r" (temp));    \
  9515. +    } while (0)
  9516. +    
  9517. +
  9518. +#define sti()                \
  9519. +    do {                \
  9520. +      unsigned long temp;        \
  9521. +      __asm__ __volatile__(        \
  9522. +"    mov    %0, pc\n"        \
  9523. +"    bic    %0, %0, #0x08000000\n"    \
  9524. +"    teqp    %0, #0\n"        \
  9525. +      : "=r" (temp)            \
  9526. +      : );                \
  9527. +    } while(0)
  9528. +
  9529. +#define cli()                \
  9530. +    do {                \
  9531. +      unsigned long temp;        \
  9532. +      __asm__ __volatile__(        \
  9533. +"    mov    %0, pc\n"        \
  9534. +"    orr    %0, %0, #0x08000000\n"    \
  9535. +"    teqp    %0, #0\n"        \
  9536. +      : "=r" (temp)            \
  9537. +      : );                \
  9538. +    } while(0)
  9539. +
  9540. +#define save_flags(x)            \
  9541. +    do {                \
  9542. +      __asm__ __volatile__(        \
  9543. +"    mov    %0, pc\n"        \
  9544. +"    and    %0, %0, #0x0c000000\n"    \
  9545. +      : "=r" (x) : );        \
  9546. +    } while (0)
  9547. +
  9548. +#define restore_flags(x)        \
  9549. +    do {                \
  9550. +      unsigned long temp;        \
  9551. +      __asm__ __volatile__(        \
  9552. +"    mov    %0, pc\n"        \
  9553. +"    bic    %0, %0, #0x0c000000\n"    \
  9554. +"    orr    %0, %0, %1\n"        \
  9555. +"    teqp    %0, #0\n"        \
  9556. +      : "=r" (temp)            \
  9557. +      : "r" (x)            \
  9558. +      : "cc");            \
  9559. +    } while (0)
  9560. +
  9561. +#endif
  9562. diff -urN linux.store/linux/include/asm-arm/proc-arm6/assembler.h linux/include/asm-arm/proc-arm6/assembler.h
  9563. --- linux.store/linux/include/asm-arm/proc-arm6/assembler.h    Thu Jan  1 01:00:00 1970
  9564. +++ linux/include/asm-arm/proc-arm6/assembler.h    Sun Feb 11 09:32:54 1996
  9565. @@ -0,0 +1,45 @@
  9566. +/*
  9567. + * linux/asm/assembler.h
  9568. + *
  9569. + * This file contains arm architecture specific defines
  9570. + * for the different processors
  9571. + */
  9572. +
  9573. +/*
  9574. + * LOADREGS: multiple register load (ldm) with pc in register list
  9575. + *        (takes account of ARM6 not using ^)
  9576. + *
  9577. + * RETINSTR: return instruction: adds the 's' in at the end of the
  9578. + *        instruction if this is not an ARM6
  9579. + *
  9580. + * SAVEIRQS: save IRQ state (not required on ARM2/ARM3 - done
  9581. + *        implicitly
  9582. + *
  9583. + * RESTOREIRQS: restore IRQ state (not required on ARM2/ARM3 - done
  9584. + *        implicitly with ldm ... ^ or movs.
  9585. + *
  9586. + * These next two need thinking about - can't easily use stack... (see system.S)
  9587. + * DISABLEIRQS: disable IRQS in SVC mode
  9588. + *
  9589. + * ENABLEIRQS: enable IRQS in SVC mode
  9590. + *
  9591. + * USERMODE: switch to USER mode
  9592. + *
  9593. + * SVCMODE: switch to SVC mode
  9594. + */
  9595. +
  9596. +#define LOADREGS(cond, base, reglist...)\
  9597. +    ldm##cond    base,reglist
  9598. +
  9599. +#define RETINSTR(instr, regs...)\
  9600. +    instr    regs
  9601. +
  9602. +#define MODENOP
  9603. +
  9604. +#define SAVEIRQS
  9605. +#define RESTOREIRQS
  9606. +
  9607. +#define DISABLEIRQS
  9608. +#define ENABLEIRQS
  9609. +#define USERMODE
  9610. +#define SVCMODE
  9611. diff -urN linux.store/linux/include/asm-arm/proc-arm6/param.h linux/include/asm-arm/proc-arm6/param.h
  9612. --- linux.store/linux/include/asm-arm/proc-arm6/param.h    Thu Jan  1 01:00:00 1970
  9613. +++ linux/include/asm-arm/proc-arm6/param.h    Sun Feb 11 09:32:55 1996
  9614. @@ -0,0 +1,21 @@
  9615. +#ifndef __ASM_ARM_PARAM_H
  9616. +#define __ASM_ARM_PARAM_H
  9617. +
  9618. +#ifndef HZ
  9619. +#define HZ 100
  9620. +#endif
  9621. +
  9622. +#define EXEC_PAGESIZE   32768
  9623. +
  9624. +#ifndef NGROUPS
  9625. +#define NGROUPS         32
  9626. +#endif
  9627. +
  9628. +#ifndef NOGROUP
  9629. +#define NOGROUP         (-1)
  9630. +#endif
  9631. +
  9632. +#define MAXHOSTNAMELEN  64      /* max length of hostname */
  9633. +
  9634. +#endif
  9635. +
  9636. diff -urN linux.store/linux/include/asm-arm/proc-arm6/ptrace.h linux/include/asm-arm/proc-arm6/ptrace.h
  9637. --- linux.store/linux/include/asm-arm/proc-arm6/ptrace.h    Thu Jan  1 01:00:00 1970
  9638. +++ linux/include/asm-arm/proc-arm6/ptrace.h    Sun Feb 11 09:32:54 1996
  9639. @@ -0,0 +1,15 @@
  9640. +/*
  9641. + * linux/include/asm-arm/proc-arm6/ptrace.h
  9642. + *
  9643. + * Copyright (C) 1996 Russell King
  9644. + */
  9645. +
  9646. +#ifndef __ASM_PROC_PTRACE_H
  9647. +#define __ASM_PROC_PTRACE_H
  9648. +
  9649. +#error Have to modify this
  9650. +#define user_mode(regs)            (((regs)->ARM_pc & 3) == 0)
  9651. +#define instruction_pointer(regs)    ((regs)->ARM_pc & 0x03fffffc)
  9652. +
  9653. +#endif
  9654. +
  9655. diff -urN linux.store/linux/include/asm-arm/proc-arm6/shmparam.h linux/include/asm-arm/proc-arm6/shmparam.h
  9656. --- linux.store/linux/include/asm-arm/proc-arm6/shmparam.h    Thu Jan  1 01:00:00 1970
  9657. +++ linux/include/asm-arm/proc-arm6/shmparam.h    Sun Feb 11 09:32:56 1996
  9658. @@ -0,0 +1,12 @@
  9659. +/*
  9660. + * linux/include/asm-arm/proc-arm6/shmparam.h
  9661. + *
  9662. + * Copyright (C) 1996 Russell King
  9663. + *
  9664. + * definitions for the shared process memory on the ARM6
  9665. + */
  9666. +
  9667. +#ifndef SHM_RANGE_START
  9668. +#define SHM_RANGE_START    0x50000000
  9669. +#define SHM_RANGE_END    0x60000000
  9670. +#endif
  9671. diff -urN linux.store/linux/include/asm-arm/ptrace.h linux/include/asm-arm/ptrace.h
  9672. --- linux.store/linux/include/asm-arm/ptrace.h    Sun Feb 11 09:32:56 1996
  9673. +++ linux/include/asm-arm/ptrace.h    Sun Feb 11 09:32:56 1996
  9674. @@ -28,8 +28,7 @@
  9675.  #define ARM_ORIG_r0    uregs[16] /* -1 */
  9676.  
  9677.  #ifdef __KERNEL__
  9678. -#define user_mode(regs)            (((regs)->ARM_pc & 3) == 0)
  9679. -#define instruction_pointer(regs)    ((regs)->ARM_pc & 0x03fffffc)
  9680. +#include <asm/proc/ptrace.h>
  9681.  extern void show_regs(struct pt_regs *);
  9682.  #endif
  9683.  
  9684. diff -urN linux.store/linux/include/asm-arm/segment.h linux/include/asm-arm/segment.h
  9685. --- linux.store/linux/include/asm-arm/segment.h    Sun Feb 11 09:32:56 1996
  9686. +++ linux/include/asm-arm/segment.h    Sun Feb 11 09:32:56 1996
  9687. @@ -40,136 +40,11 @@
  9688.   */
  9689.  extern int bad_user_access_length(void);
  9690.  
  9691. -/*
  9692. - * dummy pointer type structure.. gcc won't try to do something strange
  9693. - * this way..
  9694. - */
  9695. -struct __segment_dummy { unsigned long a[100]; };
  9696. -#define __sd(x) ((struct __segment_dummy *) (x))
  9697. -#define __const_sd(x) ((const struct __segment_dummy *) (x))
  9698. -
  9699. -#if defined(__arm2__) || defined(__arm3__)
  9700. -/*
  9701. - * These *have* to tell gcc that lr may be clobbered (if there is an abort)
  9702. - * and the psw (if it tries too hard to optimize this
  9703. - */
  9704. -static inline void __put_user(unsigned long x, void * y, int size)
  9705. -{
  9706. -    if (IS_USER_SEG) {
  9707. -        switch (size) {
  9708. -            case 1:
  9709. -                __asm__(
  9710. -                " strbt    %0, [%1]\n"
  9711. -                : : "r" (x), "r" (y)
  9712. -                : "lr", "cc");
  9713. -                break;
  9714. -            case 2:
  9715. -                { register unsigned long tmp;
  9716. -                __asm__ __volatile__(
  9717. -                " strbt %1, [%2], #1\n"
  9718. -                " mov   %0, %1, lsr #8\n"
  9719. -                " strbt %0, [%2]\n"
  9720. -                : "=&r" (tmp)
  9721. -                : "r" (x), "r" (y)
  9722. -                : "2", "lr", "cc");
  9723. -                }
  9724. -                break;
  9725. -            case 4:
  9726. -                if ((int)y & 3) {
  9727. -                register unsigned long tmp;
  9728. -                __asm__ __volatile__(
  9729. -                " strbt %1, [%2], #1\n"
  9730. -                " mov   %0, %1, lsr #8\n"
  9731. -                " strbt %0, [%2], #1\n"
  9732. -                " mov   %0, %0, lsr #8\n"
  9733. -                " strbt %0, [%2], #1\n"
  9734. -                " mov   %0, %0, lsr #8\n"
  9735. -                " strbt %0, [%2]\n"
  9736. -                : "=&r" (tmp)
  9737. -                : "r" (x), "r" (y)
  9738. -                : "2", "lr", "cc");
  9739. -                } else {
  9740. -                __asm__(
  9741. -                " strt  %0, [%1]\n"
  9742. -                : : "r" (x), "r" (y)
  9743. -                : "lr", "cc");
  9744. -                }
  9745. -                break;
  9746. -            default:
  9747. -                bad_user_access_length();
  9748. -        }
  9749. -    } else {
  9750. -        switch (size) {
  9751. -            case 1: *(unsigned char *)y = x; break;
  9752. -            case 2: *(unsigned short *)y = x; break;
  9753. -            case 4: *(unsigned long *)y = x; break;
  9754. -            default:
  9755. -                bad_user_access_length();
  9756. -        }
  9757. -    }
  9758. -}
  9759. -
  9760. -static inline unsigned long __get_user(const void *y, int size)
  9761. -{
  9762. -    unsigned long result1, result2;
  9763. -
  9764. -    if (IS_USER_SEG) {
  9765. -        switch (size) {
  9766. -            case 1:
  9767. -                __asm__(
  9768. -                " ldrbt %0, [%1]\n"
  9769. -                : "=r" (result1)
  9770. -                : "r" (y)
  9771. -                : "lr", "cc");
  9772. -                return result1;
  9773. -            case 2:
  9774. -                __asm__(
  9775. -                " ldrbt %0, [%2], #1\n"
  9776. -                " ldrbt %1, [%2]\n"
  9777. -                " orr   %0, %0, %1, lsl #8\n"
  9778. -                : "=&r" (result1), "=r" (result2)
  9779. -                : "r" (y)
  9780. -                : "lr", "cc");
  9781. -                return result1;
  9782. -            case 4:
  9783. -                if ((int)y & 3) {
  9784. -                __asm__(
  9785. -                " ldrt %0, [%2], #4\n"
  9786. -                " ldrt %1, [%2]\n"
  9787. -                : "=&r" (result1), "=r" (result2)
  9788. -                : "r" ((int)y & ~3)
  9789. -                : "lr", "cc");
  9790. -                result1 >>= ((int)y & 3)*8;
  9791. -                return result1 | (result2 << (32-((int)y & 3)*8));
  9792. -                } else {
  9793. -                __asm__(
  9794. -                " ldrt %0, [%1]\n"
  9795. -                : "=r" (result1)
  9796. -                : "r" (y)
  9797. -                : "lr", "cc");
  9798. -                return result1;
  9799. -                }
  9800. -            default:
  9801. -                return bad_user_access_length();
  9802. -        }
  9803. -    } else {
  9804. -        switch (size) {
  9805. -            case 1: return *(unsigned char *)y; break;
  9806. -            case 2: return *(unsigned short *)y; break;
  9807. -            case 4: return *(unsigned long *)y; break;
  9808. -            default:
  9809. -                return bad_user_access_length();
  9810. -        }
  9811. -    }
  9812. -}        
  9813. -#else
  9814. -#error Adjust this for your processor
  9815. -#endif
  9816. +#include <asm/proc/segment.h>
  9817.  
  9818.  /*
  9819.   * these are depreciated..
  9820.   */
  9821. -
  9822.  static __INLINE__ unsigned char get_user_byte(const char *addr)
  9823.  {
  9824.      return __get_user(addr, 1);
  9825. diff -urN linux.store/linux/include/asm-arm/shmparam.h linux/include/asm-arm/shmparam.h
  9826. --- linux.store/linux/include/asm-arm/shmparam.h    Sun Feb 11 09:32:56 1996
  9827. +++ linux/include/asm-arm/shmparam.h    Sun Feb 11 09:32:56 1996
  9828. @@ -1,9 +1,13 @@
  9829.  #ifndef _ASMARM_SHMPARAM_H
  9830.  #define _ASMARM_SHMPARAM_H
  9831.  
  9832. -/* address range for shared memory attaches if no address passed to shmat() */
  9833. -#define SHM_RANGE_START    0x00a00000
  9834. -#define SHM_RANGE_END    0x00c00000
  9835. +/*
  9836. + * Include the machine specific shm parameters before the processor
  9837. + * dependent parameters so that the machine parameters can override
  9838. + * the processor parameters
  9839. + */
  9840. +#include <asm/arch/shmparam.h>
  9841. +#include <asm/proc/shmparam.h>
  9842.  
  9843.  /*
  9844.   * Format of a swap-entry for shared memory pages currently out in
  9845. diff -urN linux.store/linux/include/asm-arm/system.h linux/include/asm-arm/system.h
  9846. --- linux.store/linux/include/asm-arm/system.h    Sun Feb 11 09:32:57 1996
  9847. +++ linux/include/asm-arm/system.h    Sun Feb 11 09:32:57 1996
  9848. @@ -7,7 +7,6 @@
  9849.  extern void arm_invalidptr(const char *, void *, int);
  9850.  
  9851.  /* This special macro can be used to load a debugging register */
  9852. -
  9853.  #define loaddebug(register)
  9854.  
  9855.  /*
  9856. @@ -22,184 +21,13 @@
  9857.  #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  9858.  #define tas(ptr) (xchg((ptr),1))
  9859.  
  9860. -struct __xchg_dummy { unsigned long a[100]; };
  9861. -#define __xg(x) ((volatile struct __xchg_dummy *)(x))
  9862. -
  9863. -#if defined (__arm2__)
  9864. -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  9865. -{
  9866. -    unsigned long temp0, temp1;
  9867. -    switch (size) {
  9868. -        case 1: __asm__ __volatile__(
  9869. -            " mov   %0, pc\n"
  9870. -            " orr   %1, %0, #0x08000000\n"
  9871. -            " teqp  %1, #0\n"
  9872. -            " mov   %1, %3\n"    /* Safe: in case it uses the same reg */
  9873. -            " ldrb  %2, [%4]\n"
  9874. -            " strb  %1, [%4]\n"
  9875. -            " teqp  %0, #0\n"
  9876. -            : "=r" (temp0), "=r" (temp1), "=r" (x)
  9877. -            : "r" (x), "r" (ptr)
  9878. -            : "memory");
  9879. -            break;
  9880. -        case 2: { unsigned long temp0, temp1;
  9881. -            if (((long)ptr) & 1)
  9882. -            {
  9883. -                void *pc;
  9884. -                __asm__("mov\t%0, pc": "=r" (pc));
  9885. -                arm_malalignedptr("xchg", pc, ptr);
  9886. -            }
  9887. -            __asm__ __volatile__(
  9888. -            " mov   %0, pc\n"
  9889. -            " orr   %1, %0, #0x08000000\n"
  9890. -            " teqp  %1, #0\n"
  9891. -            " mov   %1, %3\n"
  9892. -            " ldr    %2, [%4]\n"
  9893. -            " strb  %1, [%4]\n"
  9894. -            " mov   %1, %1, lsr #8\n"
  9895. -            " strb  %1, [%4, #1]\n"
  9896. -            " teqp  %0, #0\n"
  9897. -            : "=r" (temp0), "=r" (temp1), "=r" (x)
  9898. -            : "r" (x), "r" (ptr)
  9899. -            : "memory");
  9900. -            val &= 0xffff;
  9901. -            break;
  9902. -            }
  9903. -        case 4: { unsigned long temp0, temp1;
  9904. -            if (((long)ptr) & 3)
  9905. -            {
  9906. -                void *pc;
  9907. -                __asm__("mov\t%0, pc": "=r" (pc));
  9908. -                arm_malalignedptr("xchg", pc, ptr);
  9909. -            }
  9910. -            __asm__ __volatile__(
  9911. -            " mov   %0, pc\n"
  9912. -            " orr   %1, %0, #0x08000000\n"
  9913. -            " teqp  %1, #0\n"
  9914. -            " mov   %1, %3\n"
  9915. -            " ldr   %2, [%4]\n"
  9916. -            " str   %1, [%4]\n"
  9917. -            " teqp  %0, #0\n"
  9918. -            : "=r" (temp0), "=r" (temp1), "=r" (x)
  9919. -            : "r" (x), "r" (ptr)
  9920. -            : "memory");
  9921. -            }
  9922. -            break;
  9923. -        default:
  9924. -            {
  9925. -                void *pc;
  9926. -                __asm__("mov\t%0, pc": "=r" (pc));
  9927. -                arm_invalidptr("xchg", pc, size);
  9928. -                x = 0;
  9929. -            }
  9930. -    }
  9931. -    return x;
  9932. -}
  9933. -#elif defined (__arm3__)
  9934. -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  9935. -{
  9936. -    switch (size) {
  9937. -        case 1:
  9938. -            __asm__ __volatile__(
  9939. -            " swpb   %0, %1, [%2]\n\t"
  9940. -            : "=r" (x)
  9941. -            : "r" (x), "r" (ptr)
  9942. -            : "memory");
  9943. -            break;
  9944. -        case 2: { unsigned long temp0, temp1;
  9945. -            if (((long)ptr) & 1)
  9946. -            {
  9947. -                void *pc;
  9948. -                __asm__("mov\t%0, pc": "=r" (pc));
  9949. -                arm_malalignedptr("xchg", pc, ptr);
  9950. -            }
  9951. -            __asm__ __volatile__(
  9952. -            " mov   %0, pc\n"
  9953. -            " orr   %1, %0, #0x08000000\n"
  9954. -            " teqp  %1, #0\n"
  9955. -            " mov   %1, %3\n"
  9956. -            " ldr    %2, [%4]\n"
  9957. -            " strb  %1, [%4]\n"
  9958. -            " mov   %1, %1, lsr #8\n"
  9959. -            " strb  %1, [%4, #1]\n"
  9960. -            " teqp  %0, #0\n"
  9961. -            : "=r" (temp0), "=r" (temp1), "=r" (x)
  9962. -            : "r" (x), "r" (ptr)
  9963. -            : "memory");
  9964. -            x &= 0xffff;
  9965. -            break;
  9966. -            }
  9967. -        case 4: if (((long)ptr) & 3)
  9968. -            {
  9969. -                void *pc;
  9970. -                __asm__("mov\t%0, pc": "=r" (pc));
  9971. -                arm_malalignedptr("xchg", pc, ptr);
  9972. -            }
  9973. -            __asm__ __volatile__(
  9974. -            " swp   %0, %1, [%2]\n"
  9975. -            : "=r" (x)
  9976. -            : "r" (x), "r" (ptr)
  9977. -            : "memory");
  9978. -            break;
  9979. -        default:
  9980. -            {
  9981. -                void *pc;
  9982. -                __asm__("mov\t%0, pc": "=r" (pc));
  9983. -                arm_invalidptr("xchg", pc, size);
  9984. -                x = 0;
  9985. -            }
  9986. -    }
  9987. -    return x;
  9988. -}
  9989. -#else
  9990. -#error Adjust this routine for your processor
  9991. -#endif
  9992. +/*
  9993. + * Include processor dependent parts
  9994. + */
  9995. +#include <asm/proc/system.h>
  9996. +#include <asm/arch/system.h>
  9997.  
  9998.  #define mb() __asm__ __volatile__ ("" : : : "memory")
  9999. -
  10000. -#define sti()                \
  10001. -    do {                \
  10002. -      unsigned long temp;        \
  10003. -      __asm__ __volatile__(        \
  10004. -      " mov %0, pc\n"        \
  10005. -      " bic %0, %0, #0x08000000\n"    \
  10006. -      " teqp %0, #0\n"        \
  10007. -      : "=r" (temp)            \
  10008. -      : );                \
  10009. -    } while(0)
  10010. -
  10011. -#define cli()                \
  10012. -    do {                \
  10013. -      unsigned long temp;        \
  10014. -      __asm__ __volatile__(        \
  10015. -      " mov %0, pc\n"        \
  10016. -      " orr %0, %0, #0x08000000\n"    \
  10017. -      " teqp %0, #0\n"        \
  10018. -      : "=r" (temp)            \
  10019. -      : );                \
  10020. -    } while(0)
  10021. -
  10022. -#define save_flags(x)            \
  10023. -    do {                \
  10024. -      __asm__ __volatile__(        \
  10025. -      " mov %0, pc\n"        \
  10026. -      : "=r" (x) : );        \
  10027. -    } while (0)
  10028. -
  10029. -#define restore_flags(x)        \
  10030. -    do {                \
  10031. -      unsigned long temp;        \
  10032. -      __asm__ __volatile__(        \
  10033. -      " mov %0, pc\n"        \
  10034. -      " bic %0, %0, #0x08000000\n"    \
  10035. -      " and %1, %1, #0x08000000\n"    \
  10036. -      " orr %0, %0, %1\n"        \
  10037. -      " teqp %0, #0\n"        \
  10038. -      : "=r" (temp)            \
  10039. -      : "r" (x)            \
  10040. -      : "cc");            \
  10041. -    } while (0)
  10042. -
  10043.  #define nop() __asm__ __volatile__("mov r0,r0\n\t");
  10044.  
  10045.  #endif
  10046. diff -urN linux.store/linux/include/linux/fd1772.h linux/include/linux/fd1772.h
  10047. --- linux.store/linux/include/linux/fd1772.h    Thu Jan  1 01:00:00 1970
  10048. +++ linux/include/linux/fd1772.h    Wed Mar 13 14:56:15 1996
  10049. @@ -0,0 +1,80 @@
  10050. +#ifndef _LINUX_FD1772REG_H
  10051. +#define _LINUX_FD1772REG_H
  10052. +
  10053. +/*
  10054. +** WD1772 stuff - originally from the M68K Linux
  10055. + * Modified for Archimedes by Dave Gilbert (gilbertd@cs.man.ac.uk)
  10056. + */
  10057. +
  10058. +/* register codes */
  10059. +
  10060. +#define FDC1772SELREG_STP   (0x80)   /* command/status register */
  10061. +#define FDC1772SELREG_TRA   (0x82)   /* track register */
  10062. +#define FDC1772SELREG_SEC   (0x84)   /* sector register */
  10063. +#define FDC1772SELREG_DTA   (0x86)   /* data register */
  10064. +
  10065. +/* register names for FDC1772_READ/WRITE macros */
  10066. +
  10067. +#define FDC1772REG_CMD        0
  10068. +#define FDC1772REG_STATUS    0
  10069. +#define FDC1772REG_TRACK    2
  10070. +#define FDC1772REG_SECTOR    4
  10071. +#define FDC1772REG_DATA        6
  10072. +
  10073. +/* command opcodes */
  10074. +
  10075. +#define FDC1772CMD_RESTORE  (0x00)   /*  -                   */
  10076. +#define FDC1772CMD_SEEK     (0x10)   /*   |                  */
  10077. +#define FDC1772CMD_STEP     (0x20)   /*   |  TYP 1 Commands  */
  10078. +#define FDC1772CMD_STIN     (0x40)   /*   |                  */
  10079. +#define FDC1772CMD_STOT     (0x60)   /*  -                   */
  10080. +#define FDC1772CMD_RDSEC    (0x80)   /*  -   TYP 2 Commands  */
  10081. +#define FDC1772CMD_WRSEC    (0xa0)   /*  -          "        */
  10082. +#define FDC1772CMD_RDADR    (0xc0)   /*  -                   */
  10083. +#define FDC1772CMD_RDTRA    (0xe0)   /*   |  TYP 3 Commands  */
  10084. +#define FDC1772CMD_WRTRA    (0xf0)   /*  -                   */
  10085. +#define FDC1772CMD_FORCI    (0xd0)   /*  -   TYP 4 Command   */
  10086. +
  10087. +/* command modifier bits */
  10088. +
  10089. +#define FDC1772CMDADD_SR6   (0x00)   /* step rate settings */
  10090. +#define FDC1772CMDADD_SR12  (0x01)
  10091. +#define FDC1772CMDADD_SR2   (0x02)
  10092. +#define FDC1772CMDADD_SR3   (0x03)
  10093. +#define FDC1772CMDADD_V     (0x04)   /* verify */
  10094. +#define FDC1772CMDADD_H     (0x08)   /* wait for spin-up */
  10095. +#define FDC1772CMDADD_U     (0x10)   /* update track register */
  10096. +#define FDC1772CMDADD_M     (0x10)   /* multiple sector access */
  10097. +#define FDC1772CMDADD_E     (0x04)   /* head settling flag */
  10098. +#define FDC1772CMDADD_P     (0x02)   /* precompensation */
  10099. +#define FDC1772CMDADD_A0    (0x01)   /* DAM flag */
  10100. +
  10101. +/* status register bits */
  10102. +
  10103. +#define    FDC1772STAT_MOTORON    (0x80)   /* motor on */
  10104. +#define    FDC1772STAT_WPROT    (0x40)   /* write protected (FDC1772CMD_WR*) */
  10105. +#define    FDC1772STAT_SPINUP    (0x20)   /* motor speed stable (Type I) */
  10106. +#define    FDC1772STAT_DELDAM    (0x20)   /* sector has deleted DAM (Type II+III) */
  10107. +#define    FDC1772STAT_RECNF    (0x10)   /* record not found */
  10108. +#define    FDC1772STAT_CRC        (0x08)   /* CRC error */
  10109. +#define    FDC1772STAT_TR00    (0x04)   /* Track 00 flag (Type I) */
  10110. +#define    FDC1772STAT_LOST    (0x04)   /* Lost Data (Type II+III) */
  10111. +#define    FDC1772STAT_IDX        (0x02)   /* Index status (Type I) */
  10112. +#define    FDC1772STAT_DRQ        (0x02)   /* DRQ status (Type II+III) */
  10113. +#define    FDC1772STAT_BUSY    (0x01)   /* FDC1772 is busy */
  10114. +
  10115. +
  10116. +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1  1 -> Side 2 */
  10117. +#define DSKSIDE     (0x01)
  10118. +        
  10119. +#define DSKDRVNONE  (0x06)
  10120. +#define DSKDRV0     (0x02)
  10121. +#define DSKDRV1     (0x04)
  10122. +
  10123. +/* step rates */
  10124. +#define    FDC1772STEP_6    0x00
  10125. +#define    FDC1772STEP_12    0x01
  10126. +#define    FDC1772STEP_2    0x02
  10127. +#define    FDC1772STEP_3    0x03
  10128. +
  10129. +#endif
  10130.