home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / armlinux / kernel_src / linux-1.3.,fff / linux-1.3.35-arm.diff
Encoding:
Text File  |  1996-03-03  |  152.0 KB  |  5,397 lines

  1. diff -urNwbB linux/Makefile linux.arm/Makefile
  2. --- linux/Makefile    Sun Mar  3 11:42:06 1996
  3. +++ linux.arm/Makefile    Sun Feb 11 13:47:34 1996
  4. @@ -2,7 +2,7 @@
  5.  PATCHLEVEL = 3
  6.  SUBLEVEL = 35
  7.  
  8. -ARCH = i386
  9. +ARCH = arm
  10.  
  11.  .EXPORT_ALL_VARIABLES:
  12.  
  13. @@ -86,13 +86,19 @@
  14.  # Include the make variables (CC, etc...)
  15.  #
  16.  
  17. +# Modified 11/02/96 by Russell King
  18. +#    - Doesn't include the drivers subdirectory as standard.
  19. +#    - Modified the 'nm' line in vmlinux so that we remove local and absolute symbols.
  20. +
  21.  ARCHIVES    =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o net/network.a
  22.  FILESYSTEMS    =fs/filesystems.a
  23. -DRIVERS        =drivers/block/block.a \
  24. +DRIVERS        =
  25. +LIBS        =$(TOPDIR)/lib/lib.a
  26. +SUBDIRS        =kernel mm fs net ipc lib
  27. +
  28. +DRIVERS :=drivers/block/block.a \
  29.           drivers/char/char.a \
  30.           drivers/net/net.a
  31. -LIBS        =$(TOPDIR)/lib/lib.a
  32. -SUBDIRS        =kernel drivers mm fs net ipc lib
  33.  
  34.  ifdef CONFIG_SCSI
  35.  DRIVERS := $(DRIVERS) drivers/scsi/scsi.a
  36. @@ -108,6 +114,10 @@
  37.  
  38.  include arch/$(ARCH)/Makefile
  39.  
  40. +ifndef CONFIG_ARM
  41. +SUBDIRS := drivers $(SUBDIRS)
  42. +endif
  43. +
  44.  .S.s:
  45.      $(CC) -D__ASSEMBLY__ -traditional -E -o $*.s $<
  46.  .S.o:
  47. @@ -125,7 +135,7 @@
  48.          $(FILESYSTEMS) \
  49.          $(DRIVERS) \
  50.          $(LIBS) -o vmlinux
  51. -    $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System.map
  52. +    $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)\|\( A \)\|\( t L\)' | sort > System.map
  53.  
  54.  symlinks:
  55.      rm -f include/asm
  56. diff -urNwbB linux/arch/arm/Makefile linux.arm/arch/arm/Makefile
  57. --- linux/arch/arm/Makefile    Thu Jan  1 01:00:00 1970
  58. +++ linux.arm/arch/arm/Makefile    Sat Feb 24 13:08:03 1996
  59. @@ -0,0 +1,70 @@
  60. +#
  61. +# arch/arm/Makefile
  62. +#
  63. +# This file is included by the global makefile so that you can add your own
  64. +# architecture-specific flags and dependencies. Remember to do have actions
  65. +# for "archclean" and "archdep" for cleaning up and making dependencies for
  66. +# this architecture
  67. +#
  68. +# This file is subject to the terms and conditions of the GNU General Public
  69. +# License.  See the file "COPYING" in the main directory of this archive
  70. +# for more details.
  71. +#
  72. +# Copyright (C) 1995 by Russell King
  73. +#
  74. +
  75. +#
  76. +# Set these to indicate how to link it..
  77. +# -qmagic (we need to remove the 32 byte header for bootup purposes)
  78. +#
  79. +
  80. +SUBARCH         = -m3
  81. +
  82. +CPP         = $(CC) -E $(SUBARCH)
  83. +CFLAGS        := $(CFLAGS:-fomit-frame-pointer=) $(SUBARCH)
  84. +LINKFLAGS     = -Ttext 0x01800000
  85. +ZLINKFLAGS     = -N -Ttext 0x01800000
  86. +
  87. +HEAD        := arch/arm/kernel/head.o
  88. +SUBDIRS        := arch/arm/drivers arch/arm/kernel arch/arm/mm arch/arm/lib $(SUBDIRS)
  89. +ARCHIVES    := arch/arm/kernel/kernel.o arch/arm/mm/mm.o arch/arm/lib/lib.o $(ARCHIVES)
  90. +LIBS        := $(LIBS) `gcc --print-libgcc-file-name`
  91. +
  92. +DRIVERS := arch/arm/drivers/block/block.a arch/arm/drivers/char/char.a \
  93. +           arch/arm/drivers/net/net.a
  94. +
  95. +ifdef CONFIG_SOUND
  96. +DRIVERS := $(DRIVERS) arch/arm/drivers/sound/sound.a
  97. +endif
  98. +
  99. +ifdef CONFIG_SCSI
  100. +DRIVERS := $(DRIVERS) arch/arm/drivers/scsi/scsi.a
  101. +endif
  102. +
  103. +
  104. +arch/arm/kernel: dummy
  105. +    $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel
  106. +
  107. +arch/arm/mm: dummy
  108. +    $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm
  109. +
  110. +MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
  111. +
  112. +install:
  113. +    @$(MAKEBOOT) install
  114. +
  115. +zinstall:
  116. +    @$(MAKEBOOT) zinstall
  117. +
  118. +zImage:
  119. +    @$(MAKEBOOT) zImage
  120. +
  121. +archclean:
  122. +    @$(MAKEBOOT) clean
  123. +    @$(MAKE) -C arch/$(ARCH)/drivers/block LINKCLEAN
  124. +    @$(MAKE) -C arch/$(ARCH)/drivers/char LINKCLEAN
  125. +    @$(MAKE) -C arch/$(ARCH)/drivers/net LINKCLEAN
  126. +    @$(MAKE) -C arch/$(ARCH)/drivers/scsi LINKCLEAN
  127. +
  128. +archdep:
  129. +    @$(MAKEBOOT) dep
  130. diff -urNwbB linux/arch/arm/boot/Makefile linux.arm/arch/arm/boot/Makefile
  131. --- linux/arch/arm/boot/Makefile    Thu Jan  1 01:00:00 1970
  132. +++ linux.arm/arch/arm/boot/Makefile    Sun Feb 11 21:59:54 1996
  133. @@ -0,0 +1,47 @@
  134. +#
  135. +# arch/i386/boot/Makefile
  136. +#
  137. +# This file is subject to the terms and conditions of the GNU General Public
  138. +# License.  See the file "COPYING" in the main directory of this archive
  139. +# for more details.
  140. +#
  141. +# Copyright (C) 1994 by Linus Torvalds
  142. +#
  143. +
  144. +Image:    $(CONFIGURE) tools/build $(TOPDIR)/vmlinux
  145. +    tools/build $(TOPDIR)/vmlinux > Image
  146. +    sync
  147. +
  148. +zImage:    $(CONFIGURE) tools/build compressed/vmlinux
  149. +    tools/build compressed/vmlinux > zImage
  150. +
  151. +compressed/vmlinux: $(TOPDIR)/vmlinux dep
  152. +    @$(MAKE) -C compressed vmlinux
  153. +
  154. +install: $(CONFIGURE) Image
  155. +    sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
  156. +
  157. +zinstall: $(CONFIGURE) zImage
  158. +    sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
  159. +
  160. +tools/build: tools/build.c
  161. +    $(HOSTCC) $(CFLAGS) -o $@ $< -I$(TOPDIR)/include
  162. +
  163. +clean:
  164. +    rm -f Image zImage tools/build
  165. +    @$(MAKE) -C compressed clean
  166. +
  167. +dep:
  168. +
  169. +#zdisk: zImage
  170. +#    dd bs=8192 if=zImage of=/dev/fd0
  171. +
  172. +#zlilo: $(CONFIGURE) zImage
  173. +#    if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
  174. +#    if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
  175. +#    cat zImage > $(INSTALL_PATH)/vmlinuz
  176. +#    cp $(TOPDIR)/System.map $(INSTALL_PATH)/
  177. +#    if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
  178. +
  179. +#install: $(CONFIGURE) zImage
  180. +#    sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
  181. diff -urNwbB linux/arch/arm/boot/compressed/Makefile linux.arm/arch/arm/boot/compressed/Makefile
  182. --- linux/arch/arm/boot/compressed/Makefile    Thu Jan  1 01:00:00 1970
  183. +++ linux.arm/arch/arm/boot/compressed/Makefile    Sun Mar  3 13:35:37 1996
  184. @@ -0,0 +1,56 @@
  185. +#
  186. +# linux/arch/arm/boot/compressed/Makefile
  187. +#
  188. +# create a compressed vmlinux image from the original vmlinux
  189. +#
  190. +
  191. +CFLAGS = -O2 -DSTDC_HEADERS
  192. +LOADADDR = 0x01800000
  193. +RELADDR = 0x01960000
  194. +
  195. +SYSTEM = $(TOPDIR)/vmlinux
  196. +DECOMP_OBJS = inflate.o unzip.o misc.o ../../lib/ll_char_wr.o
  197. +
  198. +
  199. +all:        vmlinux
  200. +
  201. +vmlinux:    head.o piggy.o
  202. +        $(LD) -Ttext=$(LOADADDR) -o vmlinux head.o piggy.o
  203. +
  204. +head.o:     head.S
  205. +        $(CC) -traditional -DRELADDR=$(RELADDR) -c head.S
  206. +
  207. +piggy.o:    decomphead.o decompress.a compressed.o
  208. +        $(LD) -s -Ttext=$(RELADDR) -o a.out decomphead.o compressed.o decompress.a
  209. +        strip a.out
  210. +        ./piggyback < a.out > piggy.o
  211. +        rm -f a.out
  212. +
  213. +compressed.o:    $(SYSTEM) xtract piggyback
  214. +        ./xtract $(SYSTEM) | gzip -9 | ./piggyback > compressed.o
  215. +
  216. +
  217. +# rules for decompression part of kernel
  218. +
  219. +decompress.a:    $(DECOMP_OBJS)
  220. +        $(AR) $(ARFLAGS) decompress.a $(DECOMP_OBJS)
  221. +
  222. +decomphead.o:    decomphead.S
  223. +        $(CC) -traditional -DLOADADDR=$(LOADADDR) -c decomphead.S
  224. +
  225. +../../lib/ll_char_wr.o:
  226. +        make -C ../../lib ll_char_wr.o
  227. +
  228. +
  229. +# rules for extracting & piggybacking the kernel
  230. +
  231. +xtract:     xtract.c
  232. +        $(HOSTCC) $(CFLAGS) -o xtract xtract.c
  233. +
  234. +piggyback:    piggyback.c
  235. +        $(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
  236. +
  237. +
  238. +clean:
  239. +        rm -f xtract piggyback vmlinux decompress.a a.out
  240. +
  241. diff -urNwbB linux/arch/arm/boot/compressed/crypt.h linux.arm/arch/arm/boot/compressed/crypt.h
  242. --- linux/arch/arm/boot/compressed/crypt.h    Thu Jan  1 01:00:00 1970
  243. +++ linux.arm/arch/arm/boot/compressed/crypt.h    Sun Feb 11 09:32:10 1996
  244. @@ -0,0 +1,12 @@
  245. +/* crypt.h (dummy version) -- do not perform encryption
  246. + * Hardly worth copyrighting :-)
  247. + */
  248. +
  249. +#ifdef CRYPT
  250. +#  undef CRYPT      /* dummy version */
  251. +#endif
  252. +
  253. +#define RAND_HEAD_LEN  12  /* length of encryption random header */
  254. +
  255. +#define zencode
  256. +#define zdecode
  257. diff -urNwbB linux/arch/arm/boot/compressed/decomphead.S linux.arm/arch/arm/boot/compressed/decomphead.S
  258. --- linux/arch/arm/boot/compressed/decomphead.S    Thu Jan  1 01:00:00 1970
  259. +++ linux.arm/arch/arm/boot/compressed/decomphead.S    Sun Feb 11 09:32:10 1996
  260. @@ -0,0 +1,25 @@
  261. +/*
  262. + *  linux/arch/arm/boot/decomphead.S
  263. + */
  264. +
  265. +.text
  266. +    .global    __stext
  267. +__stext:
  268. +    b    start
  269. +LC0:
  270. +    .word    __edata
  271. +    .word    __end
  272. +    .word    LOADADDR + 0x23
  273. +    .word    __stack_start+16384
  274. +start:
  275. +    adr    r1, LC0
  276. +    ldmia    r1, {r2, r3, r4, sp}
  277. +    mov    r1, #0
  278. +clrzlp:    str    r1, [r2], #4
  279. +    cmp    r2, r3
  280. +    blt    clrzlp
  281. +    bic    r0, r4, #3
  282. +    bl    _decompress_kernel
  283. +    mov    r0, #0
  284. +    mov    pc, r4
  285. +
  286. diff -urNwbB linux/arch/arm/boot/compressed/gzip.h linux.arm/arch/arm/boot/compressed/gzip.h
  287. --- linux/arch/arm/boot/compressed/gzip.h    Thu Jan  1 01:00:00 1970
  288. +++ linux.arm/arch/arm/boot/compressed/gzip.h    Sun Feb 11 09:32:10 1996
  289. @@ -0,0 +1,284 @@
  290. +/* gzip.h -- common declarations for all gzip modules
  291. + * Copyright (C) 1992-1993 Jean-loup Gailly.
  292. + * This is free software; you can redistribute it and/or modify it under the
  293. + * terms of the GNU General Public License, see the file COPYING.
  294. + */
  295. +
  296. +#if defined(__STDC__) || defined(PROTO)
  297. +#  define OF(args)  args
  298. +#else
  299. +#  define OF(args)  ()
  300. +#endif
  301. +
  302. +#ifdef __STDC__
  303. +   typedef void *voidp;
  304. +#else
  305. +   typedef char *voidp;
  306. +#endif
  307. +
  308. +/* I don't like nested includes, but the string functions are used too often */
  309. +#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
  310. +#  include <string.h>
  311. +#  define memzero(s, n)     memset ((s), 0, (n))
  312. +#else
  313. +#  include <strings.h>
  314. +#  define strchr            index 
  315. +#  define strrchr           rindex
  316. +#  define memcpy(d, s, n)   bcopy((s), (d), (n)) 
  317. +#  define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) 
  318. +#  define memzero(s, n)     bzero((s), (n))
  319. +#endif
  320. +
  321. +#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
  322. +#  include <memory.h>
  323. +#endif
  324. +
  325. +#ifndef RETSIGTYPE
  326. +#  define RETSIGTYPE void
  327. +#endif
  328. +
  329. +#define local static
  330. +
  331. +typedef unsigned char  uch;
  332. +typedef unsigned short ush;
  333. +typedef unsigned long  ulg;
  334. +
  335. +/* Return codes from gzip */
  336. +#define OK      0
  337. +#define ERROR   1
  338. +#define WARNING 2
  339. +
  340. +/* Compression methods (see algorithm.doc) */
  341. +#define STORED     0
  342. +#define COMPRESSED 1
  343. +#define PACKED     2
  344. +/* methods 3 to 7 reserved */
  345. +#define DEFLATED   8
  346. +extern int method;         /* compression method */
  347. +
  348. +/* To save memory for 16 bit systems, some arrays are overlayed between
  349. + * the various modules:
  350. + * deflate:  prev+head   window      d_buf  l_buf  outbuf
  351. + * unlzw:    tab_prefix  tab_suffix  stack  inbuf  outbuf
  352. + * inflate:              window             inbuf
  353. + * unpack:               window             inbuf
  354. + * For compression, input is done in window[]. For decompression, output
  355. + * is done in window except for unlzw.
  356. + */
  357. +
  358. +#ifndef    INBUFSIZ
  359. +#  define INBUFSIZ  0x8000  /* input buffer size */
  360. +#endif
  361. +#define INBUF_EXTRA  64     /* required by unlzw() */
  362. +
  363. +#ifndef    OUTBUFSIZ
  364. +#  define OUTBUFSIZ  16384  /* output buffer size */
  365. +#endif
  366. +#define OUTBUF_EXTRA 2048   /* required by unlzw() */
  367. +
  368. +#define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
  369. +
  370. +#ifdef DYN_ALLOC
  371. +#  define EXTERN(type, array)  extern type * near array
  372. +#  define DECLARE(type, array, size)  type * near array
  373. +#  define ALLOC(type, array, size) { \
  374. +      array = (type*)fcalloc((unsigned)(((size)+1L)/2), 2*sizeof(type)); \
  375. +      if (array == NULL) error("insufficient memory"); \
  376. +   }
  377. +#  define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
  378. +#else
  379. +#  define EXTERN(type, array)  extern type array[]
  380. +#  define DECLARE(type, array, size)  type array[size]
  381. +#  define ALLOC(type, array, size)
  382. +#  define FREE(array)
  383. +#endif
  384. +
  385. +EXTERN(uch, inbuf);          /* input buffer */
  386. +EXTERN(uch, outbuf);         /* output buffer */
  387. +EXTERN(ush, d_buf);          /* buffer for distances, see trees.c */
  388. +EXTERN(uch, window);         /* Sliding window and suffix table (unlzw) */
  389. +#define tab_suffix window
  390. +#ifndef MAXSEG_64K
  391. +#  define tab_prefix prev    /* hash link (see deflate.c) */
  392. +#  define head (prev+WSIZE)  /* hash head (see deflate.c) */
  393. +   EXTERN(ush, tab_prefix);  /* prefix code (see unlzw.c) */
  394. +#else
  395. +#  define tab_prefix0 prev
  396. +#  define head tab_prefix1
  397. +   EXTERN(ush, tab_prefix0); /* prefix for even codes */
  398. +   EXTERN(ush, tab_prefix1); /* prefix for odd  codes */
  399. +#endif
  400. +
  401. +extern unsigned insize; /* valid bytes in inbuf */
  402. +extern unsigned inptr;  /* index of next byte to be processed in inbuf */
  403. +extern unsigned outcnt; /* bytes in output buffer */
  404. +
  405. +extern long bytes_in;   /* number of input bytes */
  406. +extern long bytes_out;  /* number of output bytes */
  407. +extern long overhead;   /* number of bytes in gzip header */
  408. +
  409. +#define isize bytes_in
  410. +/* for compatibility with old zip sources (to be cleaned) */
  411. +
  412. +extern int  ifd;        /* input file descriptor */
  413. +extern int  ofd;        /* output file descriptor */
  414. +extern char ifname[];   /* input filename or "stdin" */
  415. +extern char ofname[];   /* output filename or "stdout" */
  416. +
  417. +extern ulg time_stamp;  /* original time stamp (modification time) */
  418. +extern long ifile_size; /* input file size, -1 for devices (debug only) */
  419. +
  420. +extern int exit_code;   /* program exit code */
  421. +
  422. +typedef int file_t;     /* Do not use stdio */
  423. +#define NO_FILE  (-1)   /* in memory compression */
  424. +
  425. +
  426. +#define    GZIP_MAGIC     "\037\213" /* Magic header for gzip files, 1F 8B */
  427. +#define    OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
  428. +#define    PKZIP_MAGIC  "PK\003\004" /* Magic header for pkzip files */
  429. +#define    PACK_MAGIC     "\037\036" /* Magic header for packed files */
  430. +
  431. +/* gzip flag byte */
  432. +#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
  433. +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
  434. +#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
  435. +#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
  436. +#define COMMENT      0x10 /* bit 4 set: file comment present */
  437. +#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
  438. +#define RESERVED     0xC0 /* bit 6,7:   reserved */
  439. +
  440. +/* internal file attribute */
  441. +#define UNKNOWN (-1)
  442. +#define BINARY  0
  443. +#define ASCII   1
  444. +
  445. +#ifndef WSIZE
  446. +#  define WSIZE 0x8000     /* window size--must be a power of two, and */
  447. +#endif                     /*  at least 32K for zip's deflate method */
  448. +
  449. +#define MIN_MATCH  3
  450. +#define MAX_MATCH  258
  451. +/* The minimum and maximum match lengths */
  452. +
  453. +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
  454. +/* Minimum amount of lookahead, except at the end of the input file.
  455. + * See deflate.c for comments about the MIN_MATCH+1.
  456. + */
  457. +
  458. +#define MAX_DIST  (WSIZE-MIN_LOOKAHEAD)
  459. +/* In order to simplify the code, particularly on 16 bit machines, match
  460. + * distances are limited to MAX_DIST instead of WSIZE.
  461. + */
  462. +
  463. +extern int decrypt;        /* flag to turn on decryption */
  464. +extern int save_orig_name; /* set if original name must be saved */
  465. +extern int verbose;        /* be verbose (-v) */
  466. +extern int level;          /* compression level */
  467. +extern int test;           /* check .z file integrity */
  468. +extern int to_stdout;      /* output to stdout (-c) */
  469. +
  470. +#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  471. +
  472. +/* put_byte is used for the compressed output, put_char for the
  473. + * uncompressed output. However unlzw() uses window for its
  474. + * suffix table instead of its output buffer, so it does not use put_char.
  475. + * (to be cleaned up).
  476. + */
  477. +#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
  478. +   flush_outbuf();}
  479. +#define put_char(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\
  480. +   flush_window();}
  481. +
  482. +/* Output a 16 bit value, lsb first */
  483. +#define put_short(w) \
  484. +{ if (outcnt < OUTBUFSIZ-2) { \
  485. +    outbuf[outcnt++] = (uch) ((w) & 0xff); \
  486. +    outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \
  487. +  } else { \
  488. +    put_byte((uch)((w) & 0xff)); \
  489. +    put_byte((uch)((ush)(w) >> 8)); \
  490. +  } \
  491. +}
  492. +
  493. +/* Output a 32 bit value to the bit stream, lsb first */
  494. +#define put_long(n) { \
  495. +    put_short((n) & 0xffff); \
  496. +    put_short(((ulg)(n)) >> 16); \
  497. +}
  498. +
  499. +#define seekable()    0  /* force sequential output */
  500. +#define translate_eol 0  /* no option -a yet */
  501. +
  502. +#define tolow(c)  (isupper(c) ? (c)-'A'+'a' : (c))    /* force to lower case */
  503. +
  504. +/* Macros for getting two-byte and four-byte header values */
  505. +#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
  506. +#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
  507. +
  508. +/* Diagnostic functions */
  509. +#ifdef DEBUG
  510. +#  define Assert(cond,msg) {if(!(cond)) error(msg);}
  511. +#  define Trace(x) fprintf x
  512. +#  define Tracev(x) {if (verbose) fprintf x ;}
  513. +#  define Tracevv(x) {if (verbose>1) fprintf x ;}
  514. +#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
  515. +#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
  516. +#else
  517. +#  define Assert(cond,msg)
  518. +#  define Trace(x)
  519. +#  define Tracev(x)
  520. +#  define Tracevv(x)
  521. +#  define Tracec(c,x)
  522. +#  define Tracecv(c,x)
  523. +#endif
  524. +
  525. +    /* in zip.c: */
  526. +extern void zip    OF((int in, int out));
  527. +extern int file_read  OF((char *buf,  unsigned size));
  528. +
  529. +    /* in unzip.c */
  530. +extern void unzip        OF((int in, int out));
  531. +extern int check_zipfile OF((int in));
  532. +
  533. +    /* in unpack.c */
  534. +extern void unpack        OF((int in, int out));
  535. +
  536. +    /* in gzip.c */
  537. +RETSIGTYPE abort_gzip   OF((void));
  538. +
  539. +        /* in deflate.c */
  540. +void lm_init OF((int pack_level, ush *flags));
  541. +ulg  deflate OF((void));
  542. +
  543. +        /* in trees.c */
  544. +void ct_init     OF((ush *attr, int *method));
  545. +int  ct_tally    OF((int dist, int lc));
  546. +ulg  flush_block OF((char *buf, ulg stored_len, int eof));
  547. +
  548. +        /* in bits.c */
  549. +void     bi_init    OF((file_t zipfile));
  550. +void     send_bits  OF((int value, int length));
  551. +unsigned bi_reverse OF((unsigned value, int length));
  552. +void     bi_windup  OF((void));
  553. +void     copy_block OF((char *buf, unsigned len, int header));
  554. +extern   int (*read_buf) OF((char *buf, unsigned size));
  555. +
  556. +    /* in util.c: */
  557. +extern ulg  updcrc        OF((uch *s, unsigned n));
  558. +extern void clear_bufs    OF((void));
  559. +extern int  fill_inbuf    OF((void));
  560. +extern void flush_outbuf  OF((void));
  561. +extern void flush_window  OF((void));
  562. +extern char *strlwr       OF((char *s));
  563. +extern char *basename     OF((char *fname));
  564. +extern char *add_envopt   OF((int *argcp, char ***argvp, char *env));
  565. +extern void error         OF((char *m));
  566. +extern void warn          OF((char *a, char *b));
  567. +extern void read_error    OF((void));
  568. +extern void write_error   OF((void));
  569. +extern void display_ratio OF((long num, long den));
  570. +extern voidp xmalloc      OF((unsigned int size));
  571. +
  572. +    /* in inflate.c */
  573. +extern int inflate OF((void));
  574. diff -urNwbB linux/arch/arm/boot/compressed/head.S linux.arm/arch/arm/boot/compressed/head.S
  575. --- linux/arch/arm/boot/compressed/head.S    Thu Jan  1 01:00:00 1970
  576. +++ linux.arm/arch/arm/boot/compressed/head.S    Sun Feb 11 09:32:10 1996
  577. @@ -0,0 +1,36 @@
  578. +        .text
  579. +        .align
  580. +
  581. +@ Entry point
  582. +@ r0 = kernel info page
  583. +@ r1 = kernel length (length of this code+data)
  584. +
  585. +        .global __stext
  586. +__stext:
  587. +        b    start
  588. +LC0:
  589. +        .word    _input_data
  590. +        .word    _input_end
  591. +        .word    RELADDR
  592. +start:
  593. +        teq    r0, #0
  594. +        beq    newparams
  595. +        mov    r4,     #0x02000000
  596. +        add    r4, r4, #0x0007C000    @ = 0x0207C000 [new param location]
  597. +        mov    r3,     #0x4000
  598. +        sub    r3, r3, #4
  599. +lp2:        ldmia    r0!, {r5, r6, r7, r8, r9, r10, r11, r12}
  600. +        stmia    r4!, {r5, r6, r7, r8, r9, r10, r11, r12}
  601. +        subs    r3, r3, #32
  602. +        bpl    lp2
  603. +newparams:    adr    r3, LC0
  604. +        ldmia    r3, {r2, r3, r4}
  605. +        sub    r3, r3, r2
  606. +        mov    r1, r4
  607. +lp:        ldmia    r2!, {r5, r6, r7, r8, r9, r10, r11, r12}
  608. +        stmia    r4!, {r5, r6, r7, r8, r9, r10, r11, r12}
  609. +        subs    r3, r3, #32
  610. +        bpl    lp
  611. +        ldr    r1, [r1, #0x14]
  612. +        mov    pc, r1
  613. +
  614. diff -urNwbB linux/arch/arm/boot/compressed/inflate.c linux.arm/arch/arm/boot/compressed/inflate.c
  615. --- linux/arch/arm/boot/compressed/inflate.c    Thu Jan  1 01:00:00 1970
  616. +++ linux.arm/arch/arm/boot/compressed/inflate.c    Sat Feb 24 09:36:43 1996
  617. @@ -0,0 +1,810 @@
  618. +#define DEBG(x)
  619. +#define DEBG1(x)
  620. +/* inflate.c -- Not copyrighted 1992 by Mark Adler
  621. +   version c10p1, 10 January 1993 */
  622. +
  623. +/* 
  624. + * Adapted for booting Linux by Hannu Savolainen 1993
  625. + * based on gzip-1.0.3 
  626. + */
  627. +
  628. +#ifndef lint
  629. +static char rcsid[] = "$Id: inflate.c,v 0.10 1993/02/04 13:21:06 jloup Exp $";
  630. +#endif
  631. +
  632. +#include "gzip.h"
  633. +#define slide window
  634. +
  635. +#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)
  636. +#  include <sys/types.h>
  637. +#  include <stdlib.h>
  638. +#endif
  639. +
  640. +struct huft {
  641. +  uch e;                /* number of extra bits or operation */
  642. +  uch b;                /* number of bits in this code or subcode */
  643. +  union {
  644. +    ush n;              /* literal, length base, or distance base */
  645. +    struct huft *t;     /* pointer to next level of table */
  646. +  } v;
  647. +};
  648. +
  649. +
  650. +/* Function prototypes */
  651. +int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
  652. +                   struct huft **, int *));
  653. +int huft_free OF((struct huft *));
  654. +int inflate_codes OF((struct huft *, struct huft *, int, int));
  655. +int inflate_stored OF((void));
  656. +int inflate_fixed OF((void));
  657. +int inflate_dynamic OF((void));
  658. +int inflate_block OF((int *));
  659. +int inflate OF((void));
  660. +
  661. +
  662. +#define wp outcnt
  663. +#define flush_output(w) (wp=(w),flush_window())
  664. +
  665. +/* Tables for deflate from PKZIP's appnote.txt. */
  666. +static unsigned border[] = {    /* Order of the bit length code lengths */
  667. +        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
  668. +static ush cplens[] = {         /* Copy lengths for literal codes 257..285 */
  669. +        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
  670. +        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
  671. +        /* note: see note #13 above about the 258 in this list. */
  672. +static ush cplext[] = {         /* Extra bits for literal codes 257..285 */
  673. +        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
  674. +        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
  675. +static ush cpdist[] = {         /* Copy offsets for distance codes 0..29 */
  676. +        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
  677. +        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
  678. +        8193, 12289, 16385, 24577};
  679. +static ush cpdext[] = {         /* Extra bits for distance codes */
  680. +        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
  681. +        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
  682. +        12, 12, 13, 13};
  683. +
  684. +
  685. +ulg bb;                         /* bit buffer */
  686. +unsigned bk;                    /* bits in bit buffer */
  687. +
  688. +ush mask_bits[] = {
  689. +    0x0000,
  690. +    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
  691. +    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
  692. +};
  693. +
  694. +#ifdef CRYPT
  695. +  uch cc;
  696. +#  define NEXTBYTE() \
  697. +     (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
  698. +#else
  699. +#  define NEXTBYTE()  (uch)get_byte()
  700. +#endif
  701. +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
  702. +#define DUMPBITS(n) {b>>=(n);k-=(n);}
  703. +
  704. +int lbits = 9;          /* bits in base literal/length lookup table */
  705. +int dbits = 6;          /* bits in base distance lookup table */
  706. +
  707. +
  708. +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
  709. +#define BMAX 16         /* maximum bit length of any code (16 for explode) */
  710. +#define N_MAX 288       /* maximum number of codes in any set */
  711. +
  712. +
  713. +unsigned hufts;         /* track memory usage */
  714. +
  715. +
  716. +int huft_build(b, n, s, d, e, t, m)
  717. +unsigned *b;            /* code lengths in bits (all assumed <= BMAX) */
  718. +unsigned n;             /* number of codes (assumed <= N_MAX) */
  719. +unsigned s;             /* number of simple-valued codes (0..s-1) */
  720. +ush *d;                 /* list of base values for non-simple codes */
  721. +ush *e;                 /* list of extra bits for non-simple codes */
  722. +struct huft **t;        /* result: starting table */
  723. +int *m;                 /* maximum lookup bits, returns actual */
  724. +/* Given a list of code lengths and a maximum table size, make a set of
  725. +   tables to decode that set of codes.  Return zero on success, one if
  726. +   the given code set is incomplete (the tables are still built in this
  727. +   case), two if the input is invalid (all zero length codes or an
  728. +   oversubscribed set of lengths), and three if not enough memory. */
  729. +{
  730. +  unsigned a;                   /* counter for codes of length k */
  731. +  unsigned c[BMAX+1];           /* bit length count table */
  732. +  unsigned f;                   /* i repeats in table every f entries */
  733. +  int g;                        /* maximum code length */
  734. +  int h;                        /* table level */
  735. +  register unsigned i;          /* counter, current code */
  736. +  register unsigned j;          /* counter */
  737. +  register int k;               /* number of bits in current code */
  738. +  int l;                        /* bits per table (returned in m) */
  739. +  register unsigned *p;         /* pointer into c[], b[], or v[] */
  740. +  register struct huft *q;      /* points to current table */
  741. +  struct huft r;                /* table entry for structure assignment */
  742. +  struct huft *u[BMAX];         /* table stack */
  743. +  unsigned v[N_MAX];            /* values in order of bit length */
  744. +  register int w;               /* bits before this table == (l * h) */
  745. +  unsigned x[BMAX+1];           /* bit offsets, then code stack */
  746. +  unsigned *xp;                 /* pointer into x */
  747. +  int y;                        /* number of dummy codes added */
  748. +  unsigned z;                   /* number of entries in current table */
  749. +
  750. +DEBG("huft1 ");
  751. +
  752. +  /* Generate counts for each bit length */
  753. +  memzero(c, sizeof(c));
  754. +  p = b;  i = n;
  755. +  do {
  756. +    c[*p++]++;                  /* assume all entries <= BMAX */
  757. +  } while (--i);
  758. +  if (c[0] == n)                /* null input--all zero length codes */
  759. +  {
  760. +    *t = (struct huft *)NULL;
  761. +    *m = 0;
  762. +    return 0;
  763. +  }
  764. +
  765. +DEBG("huft2 ");
  766. +
  767. +  /* Find minimum and maximum length, bound *m by those */
  768. +  l = *m;
  769. +  for (j = 1; j <= BMAX; j++)
  770. +    if (c[j])
  771. +      break;
  772. +  k = j;                        /* minimum code length */
  773. +  if ((unsigned)l < j)
  774. +    l = j;
  775. +  for (i = BMAX; i; i--)
  776. +    if (c[i])
  777. +      break;
  778. +  g = i;                        /* maximum code length */
  779. +  if ((unsigned)l > i)
  780. +    l = i;
  781. +  *m = l;
  782. +
  783. +DEBG("huft3 ");
  784. +
  785. +  /* Adjust last length count to fill out codes, if needed */
  786. +  for (y = 1 << j; j < i; j++, y <<= 1)
  787. +    if ((y -= c[j]) < 0)
  788. +      return 2;                 /* bad input: more codes than bits */
  789. +  if ((y -= c[i]) < 0)
  790. +    return 2;
  791. +  c[i] += y;
  792. +
  793. +DEBG("huft4 ");
  794. +
  795. +  /* Generate starting offsets into the value table for each length */
  796. +  x[1] = j = 0;
  797. +  p = c + 1;  xp = x + 2;
  798. +  while (--i) {                 /* note that i == g from above */
  799. +    *xp++ = (j += *p++);
  800. +  }
  801. +
  802. +DEBG("huft5 ");
  803. +
  804. +  /* Make a table of values in order of bit lengths */
  805. +  p = b;  i = 0;
  806. +  do {
  807. +    if ((j = *p++) != 0)
  808. +      v[x[j]++] = i;
  809. +  } while (++i < n);
  810. +
  811. +DEBG("h6 ");
  812. +
  813. +  /* Generate the Huffman codes and for each, make the table entries */
  814. +  x[0] = i = 0;                 /* first Huffman code is zero */
  815. +  p = v;                        /* grab values in bit order */
  816. +  h = -1;                       /* no tables yet--level -1 */
  817. +  w = -l;                       /* bits decoded == (l * h) */
  818. +  u[0] = (struct huft *)NULL;   /* just to keep compilers happy */
  819. +  q = (struct huft *)NULL;      /* ditto */
  820. +  z = 0;                        /* ditto */
  821. +DEBG("h6a ");
  822. +
  823. +  /* go through the bit lengths (k already is bits in shortest code) */
  824. +  for (; k <= g; k++)
  825. +  {
  826. +DEBG("h6b ");
  827. +    a = c[k];
  828. +    while (a--)
  829. +    {
  830. +DEBG("h6b1 ");
  831. +      /* here i is the Huffman code of length k bits for value *p */
  832. +      /* make tables up to required level */
  833. +      while (k > w + l)
  834. +      {
  835. +DEBG1("1 ");
  836. +        h++;
  837. +        w += l;                 /* previous table always l bits */
  838. +
  839. +        /* compute minimum size table less than or equal to l bits */
  840. +        z = (z = g - w) > (unsigned)l ? l : z;  /* upper limit on table size */
  841. +        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
  842. +        {                       /* too few codes for k-w bit table */
  843. +DEBG1("2 ");
  844. +          f -= a + 1;           /* deduct codes from patterns left */
  845. +          xp = c + k;
  846. +          while (++j < z)       /* try smaller tables up to z bits */
  847. +          {
  848. +            if ((f <<= 1) <= *++xp)
  849. +              break;            /* enough codes to use up j bits */
  850. +            f -= *xp;           /* else deduct codes from patterns */
  851. +          }
  852. +        }
  853. +DEBG1("3 ");
  854. +        z = 1 << j;             /* table entries for j-bit table */
  855. +
  856. +        /* allocate and link in new table */
  857. +        q = (struct huft *)malloc((z + 1)*sizeof(struct huft));
  858. +DEBG1("4 ");
  859. +        hufts += z + 1;         /* track memory usage */
  860. +        *t = q + 1;             /* link to list for huft_free() */
  861. +        *(t = &(q->v.t)) = (struct huft *)NULL;
  862. +        u[h] = ++q;             /* table starts after link */
  863. +
  864. +DEBG1("5 ");
  865. +        /* connect to last table, if there is one */
  866. +        if (h)
  867. +        {
  868. +          x[h] = i;             /* save pattern for backing up */
  869. +          r.b = (uch)l;         /* bits to dump before this table */
  870. +          r.e = (uch)(16 + j);  /* bits in this table */
  871. +          r.v.t = q;            /* pointer to this table */
  872. +          j = i >> (w - l);     /* (get around Turbo C bug) */
  873. +          u[h-1][j] = r;        /* connect to last table */
  874. +        }
  875. +DEBG1("6 ");
  876. +      }
  877. +DEBG("h6c ");
  878. +
  879. +      /* set up table entry in r */
  880. +      r.b = (uch)(k - w);
  881. +      if (p >= v + n)
  882. +        r.e = 99;               /* out of values--invalid code */
  883. +      else if (*p < s)
  884. +      {
  885. +        r.e = (uch)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
  886. +        r.v.n = *p++;           /* simple code is just the value */
  887. +      }
  888. +      else
  889. +      {
  890. +        r.e = (uch)e[*p - s];   /* non-simple--look up in lists */
  891. +        r.v.n = d[*p++ - s];
  892. +      }
  893. +DEBG("h6d ");
  894. +
  895. +      /* fill code-like entries with r */
  896. +      f = 1 << (k - w);
  897. +      for (j = i >> w; j < z; j += f)
  898. +        q[j] = r;
  899. +
  900. +      /* backwards increment the k-bit code i */
  901. +      for (j = 1 << (k - 1); i & j; j >>= 1)
  902. +        i ^= j;
  903. +      i ^= j;
  904. +
  905. +      /* backup over finished tables */
  906. +      while ((i & ((1 << w) - 1)) != x[h])
  907. +      {
  908. +        h--;                    /* don't need to update q */
  909. +        w -= l;
  910. +      }
  911. +DEBG("h6e ");
  912. +    }
  913. +DEBG("h6f ");
  914. +  }
  915. +
  916. +DEBG("huft7 ");
  917. +
  918. +  /* Return true (1) if we were given an incomplete table */
  919. +  return y != 0 && g != 1;
  920. +}
  921. +
  922. +
  923. +
  924. +int huft_free(t)
  925. +struct huft *t;         /* table to free */
  926. +/* Free the malloc'ed tables built by huft_build(), which makes a linked
  927. +   list of the tables it made, with the links in a dummy first entry of
  928. +   each table. */
  929. +{
  930. +  register struct huft *p, *q;
  931. +
  932. +
  933. +  /* Go through linked list, freeing from the malloced (t[-1]) address. */
  934. +  p = t;
  935. +  while (p != (struct huft *)NULL)
  936. +  {
  937. +    q = (--p)->v.t;
  938. +    free(p);
  939. +    p = q;
  940. +  } 
  941. +  return 0;
  942. +}
  943. +
  944. +
  945. +int inflate_codes(tl, td, bl, bd)
  946. +struct huft *tl, *td;   /* literal/length and distance decoder tables */
  947. +int bl, bd;             /* number of bits decoded by tl[] and td[] */
  948. +/* inflate (decompress) the codes in a deflated (compressed) block.
  949. +   Return an error code or zero if it all goes ok. */
  950. +{
  951. +  register unsigned e;  /* table entry flag/number of extra bits */
  952. +  unsigned n, d;        /* length and index for copy */
  953. +  unsigned w;           /* current window position */
  954. +  struct huft *t;       /* pointer to table entry */
  955. +  unsigned ml, md;      /* masks for bl and bd bits */
  956. +  register ulg b;       /* bit buffer */
  957. +  register unsigned k;  /* number of bits in bit buffer */
  958. +
  959. +
  960. +  /* make local copies of globals */
  961. +  b = bb;                       /* initialize bit buffer */
  962. +  k = bk;
  963. +  w = wp;                       /* initialize window position */
  964. +
  965. +  /* inflate the coded data */
  966. +  ml = mask_bits[bl];           /* precompute masks for speed */
  967. +  md = mask_bits[bd];
  968. +  for (;;)                      /* do until end of block */
  969. +  {
  970. +    NEEDBITS((unsigned)bl)
  971. +    if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
  972. +      do {
  973. +        if (e == 99)
  974. +          return 1;
  975. +        DUMPBITS(t->b)
  976. +        e -= 16;
  977. +        NEEDBITS(e)
  978. +      } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
  979. +    DUMPBITS(t->b)
  980. +    if (e == 16)                /* then it's a literal */
  981. +    {
  982. +      slide[w++] = (uch)t->v.n;
  983. +      if (w == WSIZE)
  984. +      {
  985. +        flush_output(w);
  986. +        w = 0;
  987. +      }
  988. +    }
  989. +    else                        /* it's an EOB or a length */
  990. +    {
  991. +      /* exit if end of block */
  992. +      if (e == 15)
  993. +        break;
  994. +
  995. +      /* get length of block to copy */
  996. +      NEEDBITS(e)
  997. +      n = t->v.n + ((unsigned)b & mask_bits[e]);
  998. +      DUMPBITS(e);
  999. +
  1000. +      /* decode distance of block to copy */
  1001. +      NEEDBITS((unsigned)bd)
  1002. +      if ((e = (t = td + ((unsigned)b & md))->e) > 16)
  1003. +        do {
  1004. +          if (e == 99)
  1005. +            return 1;
  1006. +          DUMPBITS(t->b)
  1007. +          e -= 16;
  1008. +          NEEDBITS(e)
  1009. +        } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
  1010. +      DUMPBITS(t->b)
  1011. +      NEEDBITS(e)
  1012. +      d = w - t->v.n - ((unsigned)b & mask_bits[e]);
  1013. +      DUMPBITS(e)
  1014. +
  1015. +      /* do the copy */
  1016. +      do {
  1017. +        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
  1018. +#if !defined(NOMEMCPY) && !defined(DEBUG)
  1019. +        if (w - d >= e)         /* (this test assumes unsigned comparison) */
  1020. +        {
  1021. +          memcpy(slide + w, slide + d, e);
  1022. +          w += e;
  1023. +          d += e;
  1024. +        }
  1025. +        else                      /* do it slow to avoid memcpy() overlap */
  1026. +#endif /* !NOMEMCPY */
  1027. +          do {
  1028. +            slide[w++] = slide[d++];
  1029. +          } while (--e);
  1030. +        if (w == WSIZE)
  1031. +        {
  1032. +          flush_output(w);
  1033. +          w = 0;
  1034. +        }
  1035. +      } while (n);
  1036. +    }
  1037. +  }
  1038. +
  1039. +
  1040. +  /* restore the globals from the locals */
  1041. +  wp = w;                       /* restore global window pointer */
  1042. +  bb = b;                       /* restore global bit buffer */
  1043. +  bk = k;
  1044. +
  1045. +  /* done */
  1046. +  return 0;
  1047. +}
  1048. +
  1049. +
  1050. +
  1051. +int inflate_stored()
  1052. +/* "decompress" an inflated type 0 (stored) block. */
  1053. +{
  1054. +  unsigned n;           /* number of bytes in block */
  1055. +  unsigned w;           /* current window position */
  1056. +  register ulg b;       /* bit buffer */
  1057. +  register unsigned k;  /* number of bits in bit buffer */
  1058. +
  1059. +DEBG("<stor");
  1060. +
  1061. +  /* make local copies of globals */
  1062. +  b = bb;                       /* initialize bit buffer */
  1063. +  k = bk;
  1064. +  w = wp;                       /* initialize window position */
  1065. +
  1066. +
  1067. +  /* go to byte boundary */
  1068. +  n = k & 7;
  1069. +  DUMPBITS(n);
  1070. +
  1071. +
  1072. +  /* get the length and its complement */
  1073. +  NEEDBITS(16)
  1074. +  n = ((unsigned)b & 0xffff);
  1075. +  DUMPBITS(16)
  1076. +  NEEDBITS(16)
  1077. +  if (n != (unsigned)((~b) & 0xffff))
  1078. +    return 1;                   /* error in compressed data */
  1079. +  DUMPBITS(16)
  1080. +
  1081. +
  1082. +  /* read and output the compressed data */
  1083. +  while (n--)
  1084. +  {
  1085. +    NEEDBITS(8)
  1086. +    slide[w++] = (uch)b;
  1087. +    if (w == WSIZE)
  1088. +    {
  1089. +      flush_output(w);
  1090. +      w = 0;
  1091. +    }
  1092. +    DUMPBITS(8)
  1093. +  }
  1094. +
  1095. +
  1096. +  /* restore the globals from the locals */
  1097. +  wp = w;                       /* restore global window pointer */
  1098. +  bb = b;                       /* restore global bit buffer */
  1099. +  bk = k;
  1100. +
  1101. +  DEBG(">");
  1102. +  return 0;
  1103. +}
  1104. +
  1105. +
  1106. +
  1107. +int inflate_fixed()
  1108. +/* decompress an inflated type 1 (fixed Huffman codes) block.  We should
  1109. +   either replace this with a custom decoder, or at least precompute the
  1110. +   Huffman tables. */
  1111. +{
  1112. +  int i;                /* temporary variable */
  1113. +  struct huft *tl;      /* literal/length code table */
  1114. +  struct huft *td;      /* distance code table */
  1115. +  int bl;               /* lookup bits for tl */
  1116. +  int bd;               /* lookup bits for td */
  1117. +  unsigned l[288];      /* length list for huft_build */
  1118. +
  1119. +DEBG("<fix");
  1120. +
  1121. +  /* set up literal table */
  1122. +  for (i = 0; i < 144; i++)
  1123. +    l[i] = 8;
  1124. +  for (; i < 256; i++)
  1125. +    l[i] = 9;
  1126. +  for (; i < 280; i++)
  1127. +    l[i] = 7;
  1128. +  for (; i < 288; i++)          /* make a complete, but wrong code set */
  1129. +    l[i] = 8;
  1130. +  bl = 7;
  1131. +  if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
  1132. +    return i;
  1133. +
  1134. +
  1135. +  /* set up distance table */
  1136. +  for (i = 0; i < 30; i++)      /* make an incomplete code set */
  1137. +    l[i] = 5;
  1138. +  bd = 5;
  1139. +  if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
  1140. +  {
  1141. +    huft_free(tl);
  1142. +
  1143. +    DEBG(">");
  1144. +    return i;
  1145. +  }
  1146. +
  1147. +
  1148. +  /* decompress until an end-of-block code */
  1149. +  if (inflate_codes(tl, td, bl, bd))
  1150. +    return 1;
  1151. +
  1152. +
  1153. +  /* free the decoding tables, return */
  1154. +  huft_free(tl);
  1155. +  huft_free(td);
  1156. +  return 0;
  1157. +}
  1158. +
  1159. +
  1160. +
  1161. +int inflate_dynamic()
  1162. +/* decompress an inflated type 2 (dynamic Huffman codes) block. */
  1163. +{
  1164. +  int i;                /* temporary variables */
  1165. +  unsigned j;
  1166. +  unsigned l;           /* last length */
  1167. +  unsigned m;           /* mask for bit lengths table */
  1168. +  unsigned n;           /* number of lengths to get */
  1169. +  struct huft *tl;      /* literal/length code table */
  1170. +  struct huft *td;      /* distance code table */
  1171. +  int bl;               /* lookup bits for tl */
  1172. +  int bd;               /* lookup bits for td */
  1173. +  unsigned nb;          /* number of bit length codes */
  1174. +  unsigned nl;          /* number of literal/length codes */
  1175. +  unsigned nd;          /* number of distance codes */
  1176. +#ifdef PKZIP_BUG_WORKAROUND
  1177. +  unsigned ll[288+32];  /* literal/length and distance code lengths */
  1178. +#else
  1179. +  unsigned ll[286+30];  /* literal/length and distance code lengths */
  1180. +#endif
  1181. +  register ulg b;       /* bit buffer */
  1182. +  register unsigned k;  /* number of bits in bit buffer */
  1183. +
  1184. +DEBG("<dyn");
  1185. +
  1186. +  /* make local bit buffer */
  1187. +  b = bb;
  1188. +  k = bk;
  1189. +
  1190. +
  1191. +  /* read in table lengths */
  1192. +  NEEDBITS(5)
  1193. +  nl = 257 + ((unsigned)b & 0x1f);      /* number of literal/length codes */
  1194. +  DUMPBITS(5)
  1195. +  NEEDBITS(5)
  1196. +  nd = 1 + ((unsigned)b & 0x1f);        /* number of distance codes */
  1197. +  DUMPBITS(5)
  1198. +  NEEDBITS(4)
  1199. +  nb = 4 + ((unsigned)b & 0xf);         /* number of bit length codes */
  1200. +  DUMPBITS(4)
  1201. +#ifdef PKZIP_BUG_WORKAROUND
  1202. +  if (nl > 288 || nd > 32)
  1203. +#else
  1204. +  if (nl > 286 || nd > 30)
  1205. +#endif
  1206. +    return 1;                   /* bad lengths */
  1207. +
  1208. +DEBG("dyn1 ");
  1209. +
  1210. +  /* read in bit-length-code lengths */
  1211. +  for (j = 0; j < nb; j++)
  1212. +  {
  1213. +    NEEDBITS(3)
  1214. +    ll[border[j]] = (unsigned)b & 7;
  1215. +    DUMPBITS(3)
  1216. +  }
  1217. +  for (; j < 19; j++)
  1218. +    ll[border[j]] = 0;
  1219. +
  1220. +DEBG("dyn2 ");
  1221. +
  1222. +  /* build decoding table for trees--single level, 7 bit lookup */
  1223. +  bl = 7;
  1224. +  if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
  1225. +  {
  1226. +    if (i == 1)
  1227. +      huft_free(tl);
  1228. +    return i;                   /* incomplete code set */
  1229. +  }
  1230. +
  1231. +DEBG("dyn3 ");
  1232. +
  1233. +  /* read in literal and distance code lengths */
  1234. +  n = nl + nd;
  1235. +  m = mask_bits[bl];
  1236. +  i = l = 0;
  1237. +  while ((unsigned)i < n)
  1238. +  {
  1239. +    NEEDBITS((unsigned)bl)
  1240. +    j = (td = tl + ((unsigned)b & m))->b;
  1241. +    DUMPBITS(j)
  1242. +    j = td->v.n;
  1243. +    if (j < 16)                 /* length of code in bits (0..15) */
  1244. +      ll[i++] = l = j;          /* save last length in l */
  1245. +    else if (j == 16)           /* repeat last length 3 to 6 times */
  1246. +    {
  1247. +      NEEDBITS(2)
  1248. +      j = 3 + ((unsigned)b & 3);
  1249. +      DUMPBITS(2)
  1250. +      if ((unsigned)i + j > n)
  1251. +        return 1;
  1252. +      while (j--)
  1253. +        ll[i++] = l;
  1254. +    }
  1255. +    else if (j == 17)           /* 3 to 10 zero length codes */
  1256. +    {
  1257. +      NEEDBITS(3)
  1258. +      j = 3 + ((unsigned)b & 7);
  1259. +      DUMPBITS(3)
  1260. +      if ((unsigned)i + j > n)
  1261. +        return 1;
  1262. +      while (j--)
  1263. +        ll[i++] = 0;
  1264. +      l = 0;
  1265. +    }
  1266. +    else                        /* j == 18: 11 to 138 zero length codes */
  1267. +    {
  1268. +      NEEDBITS(7)
  1269. +      j = 11 + ((unsigned)b & 0x7f);
  1270. +      DUMPBITS(7)
  1271. +      if ((unsigned)i + j > n)
  1272. +        return 1;
  1273. +      while (j--)
  1274. +        ll[i++] = 0;
  1275. +      l = 0;
  1276. +    }
  1277. +  }
  1278. +
  1279. +DEBG("dyn4 ");
  1280. +
  1281. +  /* free decoding table for trees */
  1282. +  huft_free(tl);
  1283. +
  1284. +DEBG("dyn5 ");
  1285. +
  1286. +  /* restore the global bit buffer */
  1287. +  bb = b;
  1288. +  bk = k;
  1289. +
  1290. +DEBG("dyn5a ");
  1291. +
  1292. +  /* build the decoding tables for literal/length and distance codes */
  1293. +  bl = lbits;
  1294. +  if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
  1295. +  {
  1296. +DEBG("dyn5b ");
  1297. +    if (i == 1) {
  1298. +      error(" incomplete literal tree\n");
  1299. +      huft_free(tl);
  1300. +    }
  1301. +    return i;                   /* incomplete code set */
  1302. +  }
  1303. +DEBG("dyn5c ");
  1304. +  bd = dbits;
  1305. +  if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
  1306. +  {
  1307. +DEBG("dyn5d ");
  1308. +    if (i == 1) {
  1309. +      error(" incomplete distance tree\n");
  1310. +#ifdef PKZIP_BUG_WORKAROUND
  1311. +      i = 0;
  1312. +    }
  1313. +#else
  1314. +      huft_free(td);
  1315. +    }
  1316. +    huft_free(tl);
  1317. +    return i;                   /* incomplete code set */
  1318. +#endif
  1319. +  }
  1320. +
  1321. +DEBG("dyn6 ");
  1322. +
  1323. +  /* decompress until an end-of-block code */
  1324. +  if (inflate_codes(tl, td, bl, bd))
  1325. +    return 1;
  1326. +
  1327. +DEBG("dyn7 ");
  1328. +
  1329. +  /* free the decoding tables, return */
  1330. +  huft_free(tl);
  1331. +  huft_free(td);
  1332. +
  1333. +  DEBG(">");
  1334. +  return 0;
  1335. +}
  1336. +
  1337. +
  1338. +
  1339. +int inflate_block(e)
  1340. +int *e;                 /* last block flag */
  1341. +/* decompress an inflated block */
  1342. +{
  1343. +  unsigned t;           /* block type */
  1344. +  register ulg b;       /* bit buffer */
  1345. +  register unsigned k;  /* number of bits in bit buffer */
  1346. +
  1347. +  DEBG("<blk");
  1348. +
  1349. +  /* make local bit buffer */
  1350. +  b = bb;
  1351. +  k = bk;
  1352. +
  1353. +
  1354. +  /* read in last block bit */
  1355. +  NEEDBITS(1)
  1356. +  *e = (int)b & 1;
  1357. +  DUMPBITS(1)
  1358. +
  1359. +
  1360. +  /* read in block type */
  1361. +  NEEDBITS(2)
  1362. +  t = (unsigned)b & 3;
  1363. +  DUMPBITS(2)
  1364. +
  1365. +
  1366. +  /* restore the global bit buffer */
  1367. +  bb = b;
  1368. +  bk = k;
  1369. +
  1370. +  /* inflate that block type */
  1371. +  if (t == 2)
  1372. +    return inflate_dynamic();
  1373. +  if (t == 0)
  1374. +    return inflate_stored();
  1375. +  if (t == 1)
  1376. +    return inflate_fixed();
  1377. +
  1378. +  DEBG(">");
  1379. +
  1380. +  /* bad block type */
  1381. +  return 2;
  1382. +}
  1383. +
  1384. +
  1385. +
  1386. +int inflate()
  1387. +/* decompress an inflated entry */
  1388. +{
  1389. +  int e;                /* last block flag */
  1390. +  int r;                /* result code */
  1391. +  unsigned h;           /* maximum struct huft's malloc'ed */
  1392. +
  1393. +
  1394. +  /* initialize window, bit buffer */
  1395. +  wp = 0;
  1396. +  bk = 0;
  1397. +  bb = 0;
  1398. +
  1399. +
  1400. +  /* decompress until the last block */
  1401. +  h = 0;
  1402. +  do {
  1403. +    hufts = 0;
  1404. +    if ((r = inflate_block(&e)) != 0)
  1405. +      return r;
  1406. +    if (hufts > h)
  1407. +      h = hufts;
  1408. +  } while (!e);
  1409. +
  1410. +  /* Undo too much lookahead. The next read will be byte aligned so we
  1411. +   * can discard unused bits in the last meaningful byte.
  1412. +   */
  1413. +  while (bk >= 8) {
  1414. +    bk -= 8;
  1415. +    inptr--;
  1416. +  }
  1417. +
  1418. +  /* flush out slide */
  1419. +  flush_output(wp);
  1420. +
  1421. +
  1422. +  /* return success */
  1423. +#ifdef DEBUG
  1424. +  fprintf(stderr, "<%u> ", h);
  1425. +#endif /* DEBUG */
  1426. +  return 0;
  1427. +}
  1428. diff -urNwbB linux/arch/arm/boot/compressed/lzw.h linux.arm/arch/arm/boot/compressed/lzw.h
  1429. --- linux/arch/arm/boot/compressed/lzw.h    Thu Jan  1 01:00:00 1970
  1430. +++ linux.arm/arch/arm/boot/compressed/lzw.h    Sun Feb 11 09:32:11 1996
  1431. @@ -0,0 +1,42 @@
  1432. +/* lzw.h -- define the lzw functions.
  1433. + * Copyright (C) 1992-1993 Jean-loup Gailly.
  1434. + * This is free software; you can redistribute it and/or modify it under the
  1435. + * terms of the GNU General Public License, see the file COPYING.
  1436. + */
  1437. +
  1438. +#if !defined(OF) && defined(lint)
  1439. +#  include "gzip.h"
  1440. +#endif
  1441. +
  1442. +#ifndef BITS
  1443. +#  define BITS 16
  1444. +#endif
  1445. +#define INIT_BITS 9              /* Initial number of bits per code */
  1446. +
  1447. +#define    LZW_MAGIC  "\037\235"   /* Magic header for lzw files, 1F 9D */
  1448. +
  1449. +#define BIT_MASK    0x1f /* Mask for 'number of compression bits' */
  1450. +/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
  1451. + * It's a pity that old uncompress does not check bit 0x20. That makes
  1452. + * extension of the format actually undesirable because old compress
  1453. + * would just crash on the new format instead of giving a meaningful
  1454. + * error message. It does check the number of bits, but it's more
  1455. + * helpful to say "unsupported format, get a new version" than
  1456. + * "can only handle 16 bits".
  1457. + */
  1458. +
  1459. +#define BLOCK_MODE  0x80
  1460. +/* Block compression: if table is full and compression rate is dropping,
  1461. + * clear the dictionary.
  1462. + */
  1463. +
  1464. +#define LZW_RESERVED 0x60 /* reserved bits */
  1465. +
  1466. +#define    CLEAR  256       /* flush the dictionary */
  1467. +#define FIRST  (CLEAR+1) /* first free entry */
  1468. +
  1469. +extern int maxbits;      /* max bits per code for LZW */
  1470. +extern int block_mode;   /* block compress mode -C compatible with 2.0 */
  1471. +
  1472. +extern void lzw    OF((int in, int out));
  1473. +extern void unlzw  OF((int in, int out));
  1474. diff -urNwbB linux/arch/arm/boot/compressed/misc.c linux.arm/arch/arm/boot/compressed/misc.c
  1475. --- linux/arch/arm/boot/compressed/misc.c    Thu Jan  1 01:00:00 1970
  1476. +++ linux.arm/arch/arm/boot/compressed/misc.c    Sun Feb 11 09:32:12 1996
  1477. @@ -0,0 +1,534 @@
  1478. +/*
  1479. + * misc.c
  1480. + * 
  1481. + * This is a collection of several routines from gzip-1.0.3 
  1482. + * adapted for Linux.
  1483. + *
  1484. + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  1485. + * puts by Nick Holloway 1993
  1486. + */
  1487. +
  1488. +#include "gzip.h"
  1489. +#include "lzw.h"
  1490. +
  1491. +/*#include <asm/segment.h>*/
  1492. +
  1493. +/*
  1494. + * These are set up by the setup-routine at boot-time:
  1495. + */
  1496. +
  1497. +struct param_struct
  1498. +{
  1499. +    unsigned long page_size;
  1500. +    unsigned long nr_pages;
  1501. +    unsigned long ramdisk_size;
  1502. +    unsigned long mountrootrdonly;
  1503. +    unsigned long rootdev;
  1504. +    unsigned long video_num_cols;
  1505. +    unsigned long video_num_rows;
  1506. +    unsigned long video_x;
  1507. +    unsigned long video_y;
  1508. +    unsigned long memc_control_reg;
  1509. +    unsigned char sounddefault;
  1510. +    unsigned char adfsdrives;
  1511. +    unsigned char bytes_per_char_h;
  1512. +    unsigned char bytes_per_char_v;
  1513. +    unsigned long unused[256/4-11];
  1514. +    char paths[8][128];
  1515. +    char commandline[256];
  1516. +};
  1517. +
  1518. +static struct param_struct *params=(struct param_struct *)0x0207C000; 
  1519. +
  1520. +#define EOF -1
  1521. +
  1522. +DECLARE(uch, inbuf, INBUFSIZ);
  1523. +DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
  1524. +DECLARE(uch, window, WSIZE);
  1525. +
  1526. +unsigned outcnt;
  1527. +unsigned insize;
  1528. +unsigned inptr;
  1529. +
  1530. +extern char input_data[], input_end[];
  1531. +int input_len;
  1532. +
  1533. +int input_ptr;
  1534. +
  1535. +int method, exit_code, part_nb, last_member;
  1536. +int test = 0;
  1537. +int force = 0;
  1538. +int verbose = 1;
  1539. +long bytes_in, bytes_out;
  1540. +
  1541. +char *output_data;
  1542. +unsigned long output_ptr;
  1543. +
  1544. +extern int end;
  1545. +long free_mem_ptr = (long)&end;
  1546. +
  1547. +int to_stdout = 0;
  1548. +int hard_math = 0;
  1549. +
  1550. +void (*work)(int inf, int outf);
  1551. +void makecrc(void);
  1552. +
  1553. +local int get_method(int);
  1554. +
  1555. +char *vidmem;
  1556. +int video_num_lines, video_num_columns;
  1557. +int bytes_per_char_h;
  1558. +int white;
  1559. +
  1560. +static void puts(const char *);
  1561. +
  1562. +const char cmap_80[][8]=
  1563. +{
  1564. + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /*   */
  1565. + {0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x00}, /* ! */
  1566. + {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, /* " */
  1567. + {0x36,0x36,0x7F,0x36,0x7F,0x36,0x36,0x00}, /* # */
  1568. + {0x0C,0x3F,0x68,0x3E,0x0B,0x7E,0x18,0x00}, /* $ */
  1569. + {0x60,0x66,0x0C,0x18,0x30,0x66,0x06,0x00}, /* % */
  1570. + {0x38,0x6C,0x6C,0x38,0x6D,0x66,0x3B,0x00}, /* & */
  1571. + {0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, /* ' */
  1572. + {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, /* ( */
  1573. + {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, /* ) */
  1574. + {0x00,0x18,0x7E,0x3C,0x7E,0x18,0x00,0x00}, /* * */
  1575. + {0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00}, /* + */
  1576. + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, /* , */
  1577. + {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, /* - */
  1578. + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, /* . */
  1579. + {0x00,0x06,0x0C,0x18,0x30,0x60,0x00,0x00}, /* / */
  1580. + {0x3C,0x66,0x6E,0x7E,0x76,0x66,0x3C,0x00}, /* 0 */
  1581. + {0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00}, /* 1 */
  1582. + {0x3C,0x66,0x06,0x0C,0x18,0x30,0x7E,0x00}, /* 2 */
  1583. + {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, /* 3 */
  1584. + {0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x0C,0x00}, /* 4 */
  1585. + {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, /* 5 */
  1586. + {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, /* 6 */
  1587. + {0x7E,0x06,0x0C,0x18,0x30,0x30,0x30,0x00}, /* 7 */
  1588. + {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, /* 8 */
  1589. + {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, /* 9 */
  1590. + {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00}, /* : */
  1591. + {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30}, /* ; */
  1592. + {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, /* < */
  1593. + {0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00}, /* = */
  1594. + {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, /* > */
  1595. + {0x3C,0x66,0x0C,0x18,0x18,0x00,0x18,0x00}, /* ? */
  1596. + {0x3C,0x66,0x6E,0x6A,0x6E,0x60,0x3C,0x00}, /* @ */
  1597. + {0x3C,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, /* A */
  1598. + {0x7C,0x66,0x66,0x7C,0x66,0x66,0x7C,0x00}, /* B */
  1599. + {0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x00}, /* C */
  1600. + {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00}, /* D */
  1601. + {0x7E,0x60,0x60,0x7C,0x60,0x60,0x7E,0x00}, /* E */
  1602. + {0x7E,0x60,0x60,0x7C,0x60,0x60,0x60,0x00}, /* F */
  1603. + {0x3C,0x66,0x60,0x6E,0x66,0x66,0x3C,0x00}, /* G */
  1604. + {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, /* H */
  1605. + {0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00}, /* I */
  1606. + {0x3E,0x0C,0x0C,0x0C,0x0C,0x6C,0x38,0x00}, /* J */
  1607. + {0x66,0x6C,0x78,0x70,0x78,0x6C,0x66,0x00}, /* K */
  1608. + {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}, /* L */
  1609. + {0x63,0x77,0x7F,0x6B,0x6B,0x63,0x63,0x00}, /* M */
  1610. + {0x66,0x66,0x76,0x7E,0x6E,0x66,0x66,0x00}, /* N */
  1611. + {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00}, /* O */
  1612. + {0x7C,0x66,0x66,0x7C,0x60,0x60,0x60,0x00}, /* P */
  1613. + {0x3C,0x66,0x66,0x66,0x6A,0x6C,0x36,0x00}, /* Q */
  1614. + {0x7C,0x66,0x66,0x7C,0x6C,0x66,0x66,0x00}, /* R */
  1615. + {0x3C,0x66,0x60,0x3C,0x06,0x66,0x3C,0x00}, /* S */
  1616. + {0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, /* T */
  1617. + {0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00}, /* U */
  1618. + {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, /* V */
  1619. + {0x63,0x63,0x6B,0x6B,0x7F,0x77,0x63,0x00}, /* W */
  1620. + {0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00}, /* X */
  1621. + {0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00}, /* Y */
  1622. + {0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00}, /* Z */
  1623. + {0x7C,0x60,0x60,0x60,0x60,0x60,0x7C,0x00}, /* [ */
  1624. + {0x00,0x60,0x30,0x18,0x0C,0x06,0x00,0x00}, /* \ */
  1625. + {0x3E,0x06,0x06,0x06,0x06,0x06,0x3E,0x00}, /* ] */
  1626. + {0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00}, /* ^ */
  1627. + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, /* _ */
  1628. + {0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00}, /* ` */
  1629. + {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00}, /* a */
  1630. + {0x60,0x60,0x7C,0x66,0x66,0x66,0x7C,0x00}, /* b */
  1631. + {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, /* c */
  1632. + {0x06,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00}, /* d */
  1633. + {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, /* e */
  1634. + {0x1C,0x30,0x30,0x7C,0x30,0x30,0x30,0x00}, /* f */
  1635. + {0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x3C}, /* g */
  1636. + {0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x00}, /* h */
  1637. + {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, /* i */
  1638. + {0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x70}, /* j */
  1639. + {0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00}, /* k */
  1640. + {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, /* l */
  1641. + {0x00,0x00,0x36,0x7F,0x6B,0x6B,0x63,0x00}, /* m */
  1642. + {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, /* n */
  1643. + {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, /* o */
  1644. + {0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60}, /* p */
  1645. + {0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x07}, /* q */
  1646. + {0x00,0x00,0x6C,0x76,0x60,0x60,0x60,0x00}, /* r */
  1647. + {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, /* s */
  1648. + {0x30,0x30,0x7C,0x30,0x30,0x30,0x1C,0x00}, /* t */
  1649. + {0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00}, /* u */
  1650. + {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, /* v */
  1651. + {0x00,0x00,0x63,0x6B,0x6B,0x7F,0x36,0x00}, /* w */
  1652. + {0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00}, /* x */
  1653. + {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x3C}, /* y */
  1654. + {0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00}, /* z */
  1655. + {0x0C,0x18,0x18,0x70,0x18,0x18,0x0C,0x00}, /* { */
  1656. + {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, /* | */
  1657. + {0x30,0x18,0x18,0x0E,0x18,0x18,0x30,0x00}, /* } */
  1658. + {0x31,0x6B,0x46,0x00,0x00,0x00,0x00,0x00}, /* ~ */
  1659. + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}  /*  */
  1660. +};
  1661. +
  1662. +void *malloc(int size)
  1663. +{
  1664. +    void *p;
  1665. +
  1666. +    if (size <0) error("Malloc error\n");
  1667. +    if (free_mem_ptr <= 0) error("Memory error\n");
  1668. +
  1669. +    while(1) {
  1670. +        free_mem_ptr = (free_mem_ptr + 3) & ~3;    /* Align */
  1671. +
  1672. +        p = (void *)free_mem_ptr;
  1673. +        free_mem_ptr += size;
  1674. +
  1675. +        /*
  1676. +           * The part of the compressed kernel which has already been expanded
  1677. +         * is no longer needed. Therefore we can reuse it for malloc.
  1678. +         * With bigger kernels, this is necessary.
  1679. +         */
  1680. +        if (free_mem_ptr < (long)&end) {
  1681. +            if (free_mem_ptr > (long)&input_data[input_ptr])
  1682. +                error("\nOut of memory\n");
  1683. +
  1684. +            return p;
  1685. +        }
  1686. +        if (free_mem_ptr < 0x01a00000)
  1687. +            return p;
  1688. +        puts("large kernel, memory tight...");
  1689. +        free_mem_ptr = (long)input_data;
  1690. +    }
  1691. +}
  1692. +
  1693. +void free(void *where)
  1694. +{    /* Don't care */
  1695. +}
  1696. +
  1697. +static void scroll()
  1698. +{
  1699. +#if 0
  1700. +    int i;
  1701. +
  1702. +    memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
  1703. +    for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
  1704. +        vidmem[i] = ' ';
  1705. +#endif
  1706. +}
  1707. +
  1708. +static void puts(const char *s)
  1709. +{
  1710. +    extern void ll_char_write(char *, char, char, char, char);
  1711. +    int x,y;
  1712. +    char c;
  1713. +    char *ptr;
  1714. +
  1715. +    x = params->video_x;
  1716. +    y = params->video_y;
  1717. +
  1718. +    while ( ( c = *s++ ) != '\0' ) {
  1719. +        if ( c == '\n' ) {
  1720. +            x = 0;
  1721. +            if ( ++y >= video_num_lines ) {
  1722. +                scroll();
  1723. +                y--;
  1724. +            }
  1725. +        } else {
  1726. +            ptr = vidmem + (y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h;
  1727. +            ll_char_write(ptr, c, white, 0, 0);
  1728. +            if ( ++x >= video_num_columns ) {
  1729. +                x = 0;
  1730. +                if ( ++y >= video_num_lines ) {
  1731. +                    scroll();
  1732. +                    y--;
  1733. +                }
  1734. +            }
  1735. +        }
  1736. +    }
  1737. +
  1738. +    params->video_x = x;
  1739. +    params->video_y = y;
  1740. +}
  1741. +
  1742. +__ptr_t memset(__ptr_t s, int c, size_t n)
  1743. +{
  1744. +    int i;
  1745. +    char *ss = (char*)s;
  1746. +
  1747. +    for (i=0;i<n;i++) ss[i] = c;
  1748. +}
  1749. +
  1750. +__ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
  1751. +                size_t __n)
  1752. +{
  1753. +    int i;
  1754. +    char *d = (char *)__dest, *s = (char *)__src;
  1755. +
  1756. +    for (i=0;i<__n;i++) d[i] = s[i];
  1757. +}
  1758. +
  1759. +extern ulg crc_32_tab[];   /* crc table, defined below */
  1760. +
  1761. +/* ===========================================================================
  1762. + * Run a set of bytes through the crc shift register.  If s is a NULL
  1763. + * pointer, then initialize the crc shift register contents instead.
  1764. + * Return the current crc in either case.
  1765. + */
  1766. +ulg updcrc(s, n)
  1767. +    uch *s;                 /* pointer to bytes to pump through */
  1768. +    unsigned n;             /* number of bytes in s[] */
  1769. +{
  1770. +    register ulg c;         /* temporary variable */
  1771. +
  1772. +    static ulg crc = (ulg)0xffffffffL; /* shift register contents */
  1773. +
  1774. +    if (s == NULL) {
  1775. +    c = 0xffffffffL;
  1776. +    } else {
  1777. +    c = crc;
  1778. +    while (n--) {
  1779. +        c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
  1780. +    }
  1781. +    }
  1782. +    crc = c;
  1783. +    return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
  1784. +}
  1785. +
  1786. +/* ===========================================================================
  1787. + * Clear input and output buffers
  1788. + */
  1789. +void clear_bufs()
  1790. +{
  1791. +    outcnt = 0;
  1792. +    insize = inptr = 0;
  1793. +    bytes_in = bytes_out = 0L;
  1794. +}
  1795. +
  1796. +/* ===========================================================================
  1797. + * Fill the input buffer. This is called only when the buffer is empty
  1798. + * and at least one byte is really needed.
  1799. + */
  1800. +int fill_inbuf()
  1801. +{
  1802. +    int len, i;
  1803. +
  1804. +    /* Read as much as possible */
  1805. +    insize = 0;
  1806. +    do {
  1807. +    len = INBUFSIZ-insize;
  1808. +    if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
  1809. +        if (len == 0 || len == EOF) break;
  1810. +
  1811. +        for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
  1812. +    insize += len;
  1813. +    input_ptr += len;
  1814. +    } while (insize < INBUFSIZ);
  1815. +
  1816. +    if (insize == 0) {
  1817. +    error("unable to fill buffer\n");
  1818. +    }
  1819. +    bytes_in += (ulg)insize;
  1820. +    inptr = 1;
  1821. +    return inbuf[0];
  1822. +}
  1823. +
  1824. +/* ===========================================================================
  1825. + * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  1826. + * (Used for the decompressed data only.)
  1827. + */
  1828. +void flush_window()
  1829. +{
  1830. +    if (outcnt == 0) return;
  1831. +    updcrc(window, outcnt);
  1832. +
  1833. +    memcpy(&output_data[output_ptr], (char *)window, outcnt);
  1834. +
  1835. +    bytes_out += (ulg)outcnt;
  1836. +    output_ptr += (ulg)outcnt;
  1837. +    outcnt = 0;
  1838. +}
  1839. +
  1840. +/*
  1841. + * Code to compute the CRC-32 table. Borrowed from 
  1842. + * gzip-1.0.3/makecrc.c.
  1843. + */
  1844. +
  1845. +ulg crc_32_tab[256];
  1846. +
  1847. +void
  1848. +makecrc(void)
  1849. +{
  1850. +/* Not copyrighted 1990 Mark Adler    */
  1851. +
  1852. +  unsigned long c;      /* crc shift register */
  1853. +  unsigned long e;      /* polynomial exclusive-or pattern */
  1854. +  int i;                /* counter for all possible eight bit values */
  1855. +  int k;                /* byte being shifted into crc apparatus */
  1856. +
  1857. +  /* terms of polynomial defining this crc (except x^32): */
  1858. +  static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
  1859. +
  1860. +  /* Make exclusive-or pattern from polynomial */
  1861. +  e = 0;
  1862. +  for (i = 0; i < sizeof(p)/sizeof(int); i++)
  1863. +    e |= 1L << (31 - p[i]);
  1864. +
  1865. +  crc_32_tab[0] = 0;
  1866. +
  1867. +  for (i = 1; i < 256; i++)
  1868. +  {
  1869. +    c = 0;
  1870. +    for (k = i | 256; k != 1; k >>= 1)
  1871. +    {
  1872. +      c = c & 1 ? (c >> 1) ^ e : c >> 1;
  1873. +      if (k & 1)
  1874. +        c ^= e;
  1875. +    }
  1876. +    crc_32_tab[i] = c;
  1877. +  }
  1878. +}
  1879. +
  1880. +void error(char *x)
  1881. +{
  1882. +    puts("\n\n");
  1883. +    puts(x);
  1884. +    puts("\n\n -- System halted");
  1885. +
  1886. +    while(1);    /* Halt */
  1887. +}
  1888. +
  1889. +#define STACK_SIZE (4096)
  1890. +
  1891. +long _stack_start [STACK_SIZE];
  1892. +
  1893. +void decompress_kernel(int output_start)
  1894. +{
  1895. +    input_len = input_end - input_data;
  1896. +    vidmem = (char *)0x02000000;
  1897. +
  1898. +    video_num_lines = params->video_num_rows;
  1899. +    video_num_columns  = params->video_num_cols;
  1900. +    bytes_per_char_h = params->bytes_per_char_h;
  1901. +    white = bytes_per_char_h == 8 ? 0xfc : 7;
  1902. +    
  1903. +    if (params->nr_pages * params->page_size < 2048*1024) error("<2M of mem\n");
  1904. +
  1905. +    output_data = (char *)output_start;    /* Points to kernel start */
  1906. +    output_ptr = 0;
  1907. +
  1908. +    exit_code = 0;
  1909. +    test = 0;
  1910. +    input_ptr = 0;
  1911. +    part_nb = 0;
  1912. +
  1913. +    clear_bufs();
  1914. +    makecrc();
  1915. +
  1916. +    puts("Uncompressing Linux...");
  1917. +
  1918. +    method = get_method(0);
  1919. +
  1920. +    work(0, 0);
  1921. +
  1922. +    puts("done.\n");
  1923. +
  1924. +    puts("Now booting the kernel\n");
  1925. +}
  1926. +
  1927. +/* ========================================================================
  1928. + * Check the magic number of the input file and update ofname if an
  1929. + * original name was given and to_stdout is not set.
  1930. + * Return the compression method, -1 for error, -2 for warning.
  1931. + * Set inptr to the offset of the next byte to be processed.
  1932. + * This function may be called repeatedly for an input file consisting
  1933. + * of several contiguous gzip'ed members.
  1934. + * IN assertions: there is at least one remaining compressed member.
  1935. + *   If the member is a zip file, it must be the only one.
  1936. + */
  1937. +
  1938. +union magic
  1939. +{
  1940. +    char magic[2];
  1941. +    short s_magic;
  1942. +};
  1943. +
  1944. +local int get_method(in)
  1945. +    int in;        /* input file descriptor */
  1946. +{
  1947. +    uch flags;
  1948. +    union magic magic; /* magic header */
  1949. +    union magic gzip_magic = { GZIP_MAGIC };
  1950. +    union magic old_gzip_magic = { OLD_GZIP_MAGIC };
  1951. +
  1952. +    magic.magic[0] = (char)get_byte();
  1953. +    magic.magic[1] = (char)get_byte();
  1954. +
  1955. +    method = -1;                 /* unknown yet */
  1956. +    part_nb++;                   /* number of parts in gzip file */
  1957. +    last_member = 0;
  1958. +    /* assume multiple members in gzip file except for record oriented I/O */
  1959. +
  1960. +    if (magic.s_magic == gzip_magic.s_magic
  1961. +        || magic.s_magic == old_gzip_magic.s_magic) {
  1962. +
  1963. +    work = unzip;
  1964. +    method = (int)get_byte();
  1965. +    flags  = (uch)get_byte();
  1966. +
  1967. +    if ((flags & ENCRYPTED) != 0)
  1968. +        error("Input is encrypted\n");
  1969. +
  1970. +    if ((flags & CONTINUATION) != 0)
  1971. +        error("Multi part input\n");
  1972. +
  1973. +    if ((flags & RESERVED) != 0) {
  1974. +        error("Input has invalid flags\n");
  1975. +        exit_code = ERROR;
  1976. +        if (force <= 1)
  1977. +            return -1;
  1978. +    }
  1979. +
  1980. +    (ulg)get_byte();    /* Get timestamp */
  1981. +    ((ulg)get_byte()) << 8;
  1982. +    ((ulg)get_byte()) << 16;
  1983. +    ((ulg)get_byte()) << 24;
  1984. +
  1985. +    (void)get_byte();  /* Ignore extra flags for the moment */
  1986. +    (void)get_byte();  /* Ignore OS type for the moment */
  1987. +
  1988. +    if ((flags & EXTRA_FIELD) != 0) {
  1989. +        unsigned len = (unsigned)get_byte();
  1990. +        len |= ((unsigned)get_byte())<<8;
  1991. +        while (len--) (void)get_byte();
  1992. +    }
  1993. +
  1994. +    /* Get original file name if it was truncated */
  1995. +    if ((flags & ORIG_NAME) != 0) {
  1996. +        if (to_stdout || part_nb > 1) {
  1997. +            /* Discard the old name */
  1998. +            while (get_byte() != 0) /* null */ ;
  1999. +        } else {
  2000. +        } /* to_stdout */
  2001. +    } /* orig_name */
  2002. +
  2003. +    /* Discard file comment if any */
  2004. +    if ((flags & COMMENT) != 0) {
  2005. +        while (get_byte() != 0) /* null */ ;
  2006. +    }
  2007. +    } else
  2008. +    error("unknown compression method");
  2009. +    return method;
  2010. +}
  2011. diff -urNwbB linux/arch/arm/boot/compressed/piggyback.c linux.arm/arch/arm/boot/compressed/piggyback.c
  2012. --- linux/arch/arm/boot/compressed/piggyback.c    Thu Jan  1 01:00:00 1970
  2013. +++ linux.arm/arch/arm/boot/compressed/piggyback.c    Sun Feb 11 09:32:12 1996
  2014. @@ -0,0 +1,83 @@
  2015. +/*
  2016. + *    linux/zBoot/piggyback.c
  2017. + *
  2018. + *    (C) 1993 Hannu Savolainen
  2019. + */
  2020. +
  2021. +/*
  2022. + *    This program reads the compressed system image from stdin and
  2023. + *    encapsulates it into an object file written to the stdout.
  2024. + */
  2025. +
  2026. +#include <stdio.h>
  2027. +#include <unistd.h>
  2028. +#include <a.out.h>
  2029. +
  2030. +int main(int argc, char *argv[])
  2031. +{
  2032. +    int c, n=0, len=0;
  2033. +    char tmp_buf[512*1024];
  2034. +    
  2035. +    struct exec obj = {0x00670107};    /* object header */
  2036. +    char string_names[] = {"_input_data\0_input_end\0"};
  2037. +
  2038. +    struct nlist var_names[2] = /* Symbol table */
  2039. +        {    
  2040. +            {    /* _input_data    */
  2041. +                (char *)4, 7, 0, 0, 0
  2042. +            },
  2043. +            {    /* _input_len */
  2044. +                (char *)16, 7, 0, 0, 0
  2045. +            }
  2046. +        };
  2047. +
  2048. +
  2049. +    len = 0;
  2050. +    while ((n = read(0, &tmp_buf[len], sizeof(tmp_buf)-len+1)) > 0)
  2051. +          len += n;
  2052. +
  2053. +    len = (len + 3) & ~3;
  2054. +
  2055. +    if (n==-1)
  2056. +    {
  2057. +        perror("stdin");
  2058. +        exit(-1);
  2059. +    }
  2060. +
  2061. +    if (len >= sizeof(tmp_buf))
  2062. +    {
  2063. +        fprintf(stderr, "%s: Input too large\n", argv[0]);
  2064. +        exit(-1);
  2065. +    }
  2066. +
  2067. +    fprintf(stderr, "Compressed size %d.\n", len);
  2068. +
  2069. +/*
  2070. + *    Output object header
  2071. + */
  2072. +    obj.a_data = len /* + sizeof(long) */;
  2073. +    obj.a_syms = sizeof(var_names);
  2074. +    write(1, (char *)&obj, sizeof(obj));
  2075. +
  2076. +/*
  2077. + *    Output data segment (compressed system & len)
  2078. + */
  2079. +    write(1, tmp_buf, len);
  2080. +/*    write(1, (char *)&len, sizeof(len));*/
  2081. +
  2082. +/*
  2083. + *    Output symbol table
  2084. + */
  2085. +    var_names[1].n_value = len;
  2086. +    write(1, (char *)&var_names, sizeof(var_names));
  2087. +
  2088. +/*
  2089. + *    Output string table
  2090. + */
  2091. +    len = sizeof(string_names) + sizeof(len);
  2092. +    write(1, (char *)&len, sizeof(len));
  2093. +    write(1, string_names, sizeof(string_names));
  2094. +
  2095. +    exit(0);
  2096. +
  2097. +}
  2098. diff -urNwbB linux/arch/arm/boot/compressed/unzip.c linux.arm/arch/arm/boot/compressed/unzip.c
  2099. --- linux/arch/arm/boot/compressed/unzip.c    Thu Jan  1 01:00:00 1970
  2100. +++ linux.arm/arch/arm/boot/compressed/unzip.c    Sat Feb 24 09:36:43 1996
  2101. @@ -0,0 +1,180 @@
  2102. +/* unzip.c -- decompress files in gzip or pkzip format.
  2103. + * Copyright (C) 1992-1993 Jean-loup Gailly
  2104. + *
  2105. + * Adapted for Linux booting by Hannu Savolainen 1993
  2106. + *
  2107. + * This is free software; you can redistribute it and/or modify it under the
  2108. + * terms of the GNU General Public License, see the file COPYING.
  2109. + *
  2110. + * The code in this file is derived from the file funzip.c written
  2111. + * and put in the public domain by Mark Adler.
  2112. + */
  2113. +
  2114. +/*
  2115. +   This version can extract files in gzip or pkzip format.
  2116. +   For the latter, only the first entry is extracted, and it has to be
  2117. +   either deflated or stored.
  2118. + */
  2119. +
  2120. +#ifndef lint
  2121. +static char rcsid[] = "$Id: unzip.c,v 0.9 1993/02/10 16:07:22 jloup Exp $";
  2122. +#endif
  2123. +
  2124. +#include "gzip.h"
  2125. +#include "crypt.h"
  2126. +
  2127. +#include <stdio.h>
  2128. +
  2129. +/* PKZIP header definitions */
  2130. +#define LOCSIG 0x04034b50L      /* four-byte lead-in (lsb first) */
  2131. +#define LOCFLG 6                /* offset of bit flag */
  2132. +#define  CRPFLG 1               /*  bit for encrypted entry */
  2133. +#define  EXTFLG 8               /*  bit for extended local header */
  2134. +#define LOCHOW 8                /* offset of compression method */
  2135. +#define LOCTIM 10               /* file mod time (for decryption) */
  2136. +#define LOCCRC 14               /* offset of crc */
  2137. +#define LOCSIZ 18               /* offset of compressed size */
  2138. +#define LOCLEN 22               /* offset of uncompressed length */
  2139. +#define LOCFIL 26               /* offset of file name field length */
  2140. +#define LOCEXT 28               /* offset of extra field length */
  2141. +#define LOCHDR 30               /* size of local header, including sig */
  2142. +#define EXTHDR 16               /* size of extended local header, inc sig */
  2143. +
  2144. +
  2145. +/* Globals */
  2146. +
  2147. +int decrypt;      /* flag to turn on decryption */
  2148. +char *key;        /* not used--needed to link crypt.c */
  2149. +int pkzip = 0;    /* set for a pkzip file */
  2150. +int extended = 0; /* set if extended local header */
  2151. +
  2152. +/* ===========================================================================
  2153. + * Check zip file and advance inptr to the start of the compressed data.
  2154. + * Get ofname from the local header if necessary.
  2155. + */
  2156. +int check_zipfile(in)
  2157. +    int in;   /* input file descriptors */
  2158. +{
  2159. +    uch *h = inbuf + inptr; /* first local header */
  2160. +
  2161. +    /* ifd = in; */
  2162. +
  2163. +    /* Check validity of local header, and skip name and extra fields */
  2164. +    inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
  2165. +
  2166. +    if (inptr > insize || LG(h) != LOCSIG) {
  2167. +    error("input not a zip");
  2168. +    }
  2169. +    method = h[LOCHOW];
  2170. +    if (method != STORED && method != DEFLATED) {
  2171. +    error("first entry not deflated or stored--can't extract");
  2172. +    }
  2173. +
  2174. +    /* If entry encrypted, decrypt and validate encryption header */
  2175. +    if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
  2176. +    error("encrypted file\n");
  2177. +    exit_code = ERROR;
  2178. +    return -1;
  2179. +    }
  2180. +
  2181. +    /* Save flags for unzip() */
  2182. +    extended = (h[LOCFLG] & EXTFLG) != 0;
  2183. +    pkzip = 1;
  2184. +
  2185. +    /* Get ofname and time stamp from local header (to be done) */
  2186. +    return 0;
  2187. +}
  2188. +
  2189. +/* ===========================================================================
  2190. + * Unzip in to out.  This routine works on both gzip and pkzip files.
  2191. + *
  2192. + * IN assertions: the buffer inbuf contains already the beginning of
  2193. + *   the compressed data, from offsets inptr to insize-1 included.
  2194. + *   The magic header has already been checked. The output buffer is cleared.
  2195. + */
  2196. +void unzip(in, out)
  2197. +    int in, out;   /* input and output file descriptors */
  2198. +{
  2199. +    ulg orig_crc = 0;       /* original crc */
  2200. +    ulg orig_len = 0;       /* original uncompressed length */
  2201. +    int n;
  2202. +    uch buf[EXTHDR];        /* extended local header */
  2203. +
  2204. +    /* ifd = in;
  2205. +    ofd = out; */
  2206. +
  2207. +    updcrc(NULL, 0);           /* initialize crc */
  2208. +
  2209. +    if (pkzip && !extended) {  /* crc and length at the end otherwise */
  2210. +    orig_crc = LG(inbuf + LOCCRC);
  2211. +    orig_len = LG(inbuf + LOCLEN);
  2212. +    }
  2213. +
  2214. +    /* Decompress */
  2215. +    if (method == DEFLATED)  {
  2216. +
  2217. +    int res = inflate();
  2218. +
  2219. +    if (res == 3) {
  2220. +        error("out of memory");
  2221. +    } else if (res != 0) {
  2222. +        error("invalid compressed format");
  2223. +    }
  2224. +
  2225. +    } else if (pkzip && method == STORED) {
  2226. +
  2227. +    register ulg n = LG(inbuf + LOCLEN);
  2228. +
  2229. +    if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
  2230. +
  2231. +        error("length mismatch");
  2232. +    }
  2233. +    while (n--) {
  2234. +        uch c = (uch)get_byte();
  2235. +#ifdef CRYPT
  2236. +        if (decrypt) zdecode(c);
  2237. +#endif
  2238. +        if (!test) put_char(c);
  2239. +    }
  2240. +    } else {
  2241. +    error("internal error, invalid method");
  2242. +    }
  2243. +
  2244. +    /* Get the crc and original length */
  2245. +    if (!pkzip) {
  2246. +        /* crc32  (see algorithm.doc)
  2247. +     * uncompressed input size modulo 2^32
  2248. +         */
  2249. +    for (n = 0; n < 8; n++) {
  2250. +        buf[n] = (uch)get_byte(); /* may cause an error if EOF */
  2251. +    }
  2252. +    orig_crc = LG(buf);
  2253. +    orig_len = LG(buf+4);
  2254. +
  2255. +    } else if (extended) {  /* If extended header, check it */
  2256. +    /* signature - 4bytes: 0x50 0x4b 0x07 0x08
  2257. +     * CRC-32 value
  2258. +         * compressed size 4-bytes
  2259. +         * uncompressed size 4-bytes
  2260. +     */
  2261. +    for (n = 0; n < EXTHDR; n++) {
  2262. +        buf[n] = (uch)get_byte(); /* may cause an error if EOF */
  2263. +    }
  2264. +    orig_crc = LG(buf+4);
  2265. +    orig_len = LG(buf+12);
  2266. +    }
  2267. +
  2268. +    /* Validate decompression */
  2269. +    if (orig_crc != updcrc(outbuf, 0)) {
  2270. +    error("crc error");
  2271. +    }
  2272. +    if (orig_len != bytes_out) {
  2273. +    error("length error");
  2274. +    }
  2275. +
  2276. +    /* Check if there are more entries in a pkzip file */
  2277. +    if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
  2278. +        error("zip file has more than one entry");
  2279. +    }
  2280. +    extended = pkzip = 0; /* for next file */
  2281. +}
  2282. diff -urNwbB linux/arch/arm/boot/compressed/xtract.c linux.arm/arch/arm/boot/compressed/xtract.c
  2283. --- linux/arch/arm/boot/compressed/xtract.c    Thu Jan  1 01:00:00 1970
  2284. +++ linux.arm/arch/arm/boot/compressed/xtract.c    Sun Feb 11 09:32:12 1996
  2285. @@ -0,0 +1,86 @@
  2286. +/*
  2287. + *  linux/zBoot/xtract.c
  2288. + *
  2289. + *  Copyright (C) 1993  Hannu Savolainen
  2290. + *
  2291. + *    Extracts the system image and writes it to the stdout.
  2292. + *    based on tools/build.c by Linus Torvalds
  2293. + */
  2294. +
  2295. +#include <stdio.h>    /* fprintf */
  2296. +#include <string.h>
  2297. +#include <stdlib.h>    /* contains exit */
  2298. +#include <sys/types.h>    /* unistd.h needs this */
  2299. +#include <sys/stat.h>
  2300. +#include <sys/sysmacros.h>
  2301. +#include <unistd.h>    /* contains read/write */
  2302. +#include <fcntl.h>
  2303. +#include <a.out.h>
  2304. +
  2305. +#define N_MAGIC_OFFSET 1024
  2306. +
  2307. +static int GCC_HEADER = sizeof(struct exec);
  2308. +
  2309. +#define STRINGIFY(x) #x
  2310. +
  2311. +void die(char * str)
  2312. +{
  2313. +    fprintf(stderr,"%s\n",str);
  2314. +    exit(1);
  2315. +}
  2316. +
  2317. +void usage(void)
  2318. +{
  2319. +    die("Usage: xtract system [ | gzip | piggyback > piggy.s]");
  2320. +}
  2321. +
  2322. +int main(int argc, char ** argv)
  2323. +{
  2324. +    int i,c,id, sz;
  2325. +    char buf[1024];
  2326. +    char major_root, minor_root;
  2327. +    struct stat sb;
  2328. +
  2329. +    struct exec *ex = (struct exec *)buf;
  2330. +
  2331. +    if (argc  != 2)
  2332. +        usage();
  2333. +    
  2334. +    if ((id=open(argv[1],O_RDONLY,0))<0)
  2335. +        die("Unable to open 'system'");
  2336. +    if (read(id,buf,GCC_HEADER) != GCC_HEADER)
  2337. +        die("Unable to read header of 'system'");
  2338. +    if (N_MAGIC(*ex) == ZMAGIC) {
  2339. +        GCC_HEADER = N_MAGIC_OFFSET;
  2340. +        lseek(id, GCC_HEADER, SEEK_SET);
  2341. +    } else if (N_MAGIC(*ex) != QMAGIC)
  2342. +        die("Non-GCC header of 'system'");
  2343. +
  2344. +    sz = N_SYMOFF(*ex) - GCC_HEADER + 4;    /* +4 to get the same result than tools/build */
  2345. +
  2346. +    fprintf(stderr, "System size is %d\n", sz);
  2347. +
  2348. +    while (sz)
  2349. +    {
  2350. +        int l, n;
  2351. +
  2352. +        l = sz;
  2353. +        if (l > sizeof(buf)) l = sizeof(buf);
  2354. +
  2355. +        if ((n=read(id, buf, l)) !=l)
  2356. +        {
  2357. +            if (n == -1) 
  2358. +               perror(argv[1]);
  2359. +            else
  2360. +               fprintf(stderr, "Unexpected EOF\n");
  2361. +
  2362. +            die("Can't read system");
  2363. +        }
  2364. +
  2365. +        write(1, buf, l);
  2366. +        sz -= l;
  2367. +    }
  2368. +
  2369. +    close(id);
  2370. +    return(0);
  2371. +}
  2372. diff -urNwbB linux/arch/arm/boot/install.sh linux.arm/arch/arm/boot/install.sh
  2373. --- linux/arch/arm/boot/install.sh    Thu Jan  1 01:00:00 1970
  2374. +++ linux.arm/arch/arm/boot/install.sh    Sun Mar  3 12:16:58 1996
  2375. @@ -0,0 +1,60 @@
  2376. +#!/bin/sh
  2377. +#
  2378. +# arch/i386/boot/install.sh
  2379. +#
  2380. +# This file is subject to the terms and conditions of the GNU General Public
  2381. +# License.  See the file "COPYING" in the main directory of this archive
  2382. +# for more details.
  2383. +#
  2384. +# Copyright (C) 1995 by Linus Torvalds
  2385. +#
  2386. +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
  2387. +#
  2388. +# "make install" script for i386 architecture
  2389. +#
  2390. +# Arguments:
  2391. +#   $1 - kernel version
  2392. +#   $2 - kernel image file
  2393. +#   $3 - kernel map file
  2394. +#   $4 - default install path (blank if root directory)
  2395. +#
  2396. +
  2397. +# User may have a custom install script
  2398. +
  2399. +if [ -x /sbin/installkernel ]; then
  2400. +  exec /sbin/installkernel "$@"
  2401. +fi
  2402. +
  2403. +if [ "$2" = "zImage" ]; then
  2404. +# Compressed install
  2405. +  echo "Installing compressed kernel"
  2406. +  if [ -f $4/vmlinuz-$1 ]; then
  2407. +    mv $4/vmlinuz-$1 $4/vmlinuz.old
  2408. +  fi
  2409. +
  2410. +  if [ -f $4/System.map-$1 ]; then
  2411. +    mv $4/System.map-$1 $4/System.old
  2412. +  fi
  2413. +
  2414. +  cat $2 > $4/vmlinuz-$1
  2415. +  cp $3 $4/System.map-$1
  2416. +else
  2417. +# Normal install
  2418. +  echo "Installing normal kernel"
  2419. +  if [ -f $4/vmlinux-$1 ]; then
  2420. +    mv $4/vmlinux-$1 $4/vmlinux.old
  2421. +  fi
  2422. +
  2423. +  if [ -f $4/System.map ]; then
  2424. +    mv $4/System.map $4/System.old
  2425. +  fi
  2426. +
  2427. +  cat $2 > $4/vmlinux-$1
  2428. +  cp $3 $4/System.map
  2429. +fi
  2430. +
  2431. +if [ -x /sbin/loadmap ]; then
  2432. +  /sbin/loadmap
  2433. +else
  2434. +  echo "You have to install it yourself"
  2435. +fi
  2436. diff -urNwbB linux/arch/arm/boot/tools/build.c linux.arm/arch/arm/boot/tools/build.c
  2437. --- linux/arch/arm/boot/tools/build.c    Thu Jan  1 01:00:00 1970
  2438. +++ linux.arm/arch/arm/boot/tools/build.c    Sun Feb 11 22:01:19 1996
  2439. @@ -0,0 +1,56 @@
  2440. +#include <stdio.h>
  2441. +#include <stdlib.h>
  2442. +#include <a.out.h>
  2443. +#include <string.h>
  2444. +
  2445. +int main(int argc, char **argv)
  2446. +{
  2447. +    void *data;
  2448. +    struct exec ex;
  2449. +    FILE *f;
  2450. +    int totlen;
  2451. +
  2452. +    if (argc < 2) {
  2453. +        fprintf(stderr, "Usage: build kernel-name\n");
  2454. +        exit(1);
  2455. +    }
  2456. +
  2457. +    f = fopen(argv[1], "rb");
  2458. +
  2459. +    fread(&ex, 1, sizeof(ex), f);
  2460. +
  2461. +    if(N_MAGIC(ex) == ZMAGIC) {
  2462. +        fseek(f, 4096, SEEK_SET);
  2463. +        totlen = ex.a_text + ex.a_data + ex.a_bss;
  2464. +    } else
  2465. +    if(N_MAGIC(ex) == QMAGIC) {
  2466. +        unsigned long my_header[8];
  2467. +        
  2468. +        fseek(f, 0x20, SEEK_SET);
  2469. +
  2470. +        memset(my_header, 0, 0x20);
  2471. +
  2472. +        my_header[0] = 0xea000006;
  2473. +        
  2474. +        fwrite(my_header, 4, 8, stdout);
  2475. +        
  2476. +        totlen = ex.a_text + ex.a_data + ex.a_bss - 0x20;
  2477. +    } else {
  2478. +        fprintf(stderr, "Unacceptable a.out header on kernel\n");
  2479. +        fclose(f);
  2480. +        exit(1);
  2481. +    }
  2482. +
  2483. +    fprintf(stderr, "Kernel is %dk (%dk text, %dk data, %dk bss)\n",
  2484. +        (ex.a_text + ex.a_data + ex.a_bss)/1024,
  2485. +         ex.a_text/1024, ex.a_data/1024, ex.a_bss/1024);
  2486. +
  2487. +    data = malloc(totlen);
  2488. +    fread(data, 1, totlen, f);
  2489. +    fwrite(data, 1, totlen, stdout);
  2490. +
  2491. +    free(data);
  2492. +    fclose(f);
  2493. +    fflush(stdout);
  2494. +    return 0;
  2495. +}
  2496. diff -urNwbB linux/arch/arm/config.in linux.arm/arch/arm/config.in
  2497. --- linux/arch/arm/config.in    Thu Jan  1 01:00:00 1970
  2498. +++ linux.arm/arch/arm/config.in    Sat Feb 24 21:32:58 1996
  2499. @@ -0,0 +1,202 @@
  2500. +#
  2501. +# For a description of the syntax of this configuration file,
  2502. +# see the Configure script.
  2503. +#
  2504. +# This is to tell configure not to execute the sound configuration.
  2505. +#
  2506. +CONFIG_ARM=1
  2507. +
  2508. +mainmenu_name "Linux kernel configuration"
  2509. +
  2510. +echo "/* Automatically generated by configure.  Use Make config to change */" >> $CONFIG_H
  2511. +#
  2512. +# These are to alter the behaviour of various Makefiles and init/main.c
  2513. +# in the architecture-independent areas.
  2514. +#
  2515. +echo "#define CONFIG_ARM 1" >> $CONFIG_H
  2516. +echo "CONFIG_ARM=1" >> $CONFIG
  2517. +
  2518. +mainmenu_option next_comment
  2519. +comment 'General setup'
  2520. +bool 'Compile for arm3' CONFIG_ARM3 y
  2521. +if [ "$CONFIG_ARM3" = "n" ]; then
  2522. +  bool 'Compile for arm610/710' CONFIG_ARM610 y
  2523. +  if [ "$CONFIG_ARM610" = "n" ]; then
  2524. +    bool 'Compile for StrongARM' CONFIG_ARMSTRONG y
  2525. +  fi
  2526. +else
  2527. +  bool 'Page size as 32K' CONFIG_PAGE_32K y
  2528. +  if [ "$CONFIG_PAGE_32K" = "n" ]; then
  2529. +    bool 'Page size as 16K' CONFIG_PAGE_16K y
  2530. +    if [ "$CONFIG_PAGE_16K" = "n" ]; then
  2531. +      echo "Auto detected page size"
  2532. +    fi
  2533. +  fi
  2534. +fi
  2535. +
  2536. +comment 'Math emulation is provided by a run-time loadable module'
  2537. +
  2538. +tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
  2539. +bool 'Normal IDE disk/cdrom support' CONFIG_ST506 y
  2540. +if [ "$CONFIG_ST506" = "y" ]; then
  2541. +  comment 'Please see drivers/block/README.ide for help/info on IDE drives'
  2542. +  bool '   Use old disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y
  2543. +#  if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
  2544. +#    bool '   Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
  2545. +#  else
  2546. +#    bool '   Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE y
  2547. +#  fi
  2548. +#  if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
  2549. +#    bool '   Include support for IDE/ATAPI CDROMs' CONFIG_BLK_DEV_IDECD n
  2550. +#  fi
  2551. +fi
  2552. +tristate 'MFM harddisk support' CONFIG_BLK_DEV_XD n
  2553. +
  2554. +bool 'Networking support' CONFIG_NET y
  2555. +bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
  2556. +bool 'System V IPC' CONFIG_SYSVIPC y
  2557. +#tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF n
  2558. +
  2559. +mainmenu_option next_comment
  2560. +comment 'Loadable module support'
  2561. +bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS y
  2562. +
  2563. +if [ "$CONFIG_NET" = "y" ]; then
  2564. +  mainmenu_option next_comment
  2565. +  comment 'Networking options'
  2566. +  bool 'TCP/IP networking' CONFIG_INET y
  2567. +  if [ "$CONFIG_INET" = "y" ]; then
  2568. +    bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD n
  2569. +    bool 'IP: multicasting' CONFIG_IP_MULTICAST n
  2570. +    bool 'IP: firewalling' CONFIG_IP_FIREWALL n
  2571. +    bool 'IP: accounting' CONFIG_IP_ACCT n
  2572. +    tristate 'IP: tunneling' CONFIG_NET_IPIP n
  2573. +    if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
  2574. +      bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE y
  2575. +      bool 'IP: masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
  2576. +    fi
  2577. +    comment '(it is safe to leave these untouched)'
  2578. +    bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP n
  2579. +    tristate 'IP: Reverse ARP' CONFIG_INET_RARP n
  2580. +    bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
  2581. +    bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
  2582. +    bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
  2583. +    bool 'IP: Allow large windows (not recommended if <16MB of memory)' CONFIG_SKB_LARGE n
  2584. +  fi
  2585. +  bool 'The IPX protocol' CONFIG_IPX n
  2586. +  bool 'Appletalk DDP' CONFIG_ATALK n
  2587. +  bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
  2588. +  if [ "$CONFIG_AX25" = "y" ]; then
  2589. +    bool 'Amateur Radio NET/ROM' CONFIG_NETROM n
  2590. +  fi
  2591. +  bool 'Kernel/User network link driver(ALPHA)' CONFIG_NETLINK n
  2592. +  if [ "$CONFIG_NETLINK" = "y" ]; then
  2593. +    bool 'Routing messages' CONFIG_RTNETLINK y
  2594. +  fi
  2595. +fi
  2596. +
  2597. +mainmenu_option next_comment
  2598. +comment 'SCSI support'
  2599. +
  2600. +tristate 'SCSI support?' CONFIG_SCSI n
  2601. +
  2602. +if [ "$CONFIG_SCSI" = "n" ]; then
  2603. +
  2604. +  comment 'Skipping SCSI configuration options...'
  2605. +
  2606. +else
  2607. +
  2608. +  comment 'SCSI support type (disk, tape, CDrom)'
  2609. +
  2610. +  dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y $CONFIG_SCSI
  2611. +  dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST y $CONFIG_SCSI
  2612. +  dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y $CONFIG_SCSI
  2613. +  dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n $CONFIG_SCSI
  2614. +
  2615. +  comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
  2616. +
  2617. +  bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
  2618. +
  2619. +  mainmenu_option next_comment
  2620. +  comment 'SCSI low-level drivers'
  2621. +
  2622. +  dep_tristate 'Acorn SCSI card (aka30) support' CONFIG_SCSI_ACORNSCSI_3 y $CONFIG_SCSI
  2623. +  dep_tristate 'Cumana 1 support' CONFIG_SCSI_CUMANA_1 n $CONFIG_SCSI
  2624. +  dep_tristate 'EcoScsi support' CONFIG_SCSI_ECOSCSI n $CONFIG_SCSI
  2625. +  dep_tristate 'Oak SCSI support' CONFIG_SCSI_OAK n $CONFIG_SCSI
  2626. +  dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n $CONFIG_SCSI
  2627. +fi
  2628. +
  2629. +if [ "$CONFIG_NET" = "y" ]; then
  2630. +
  2631. +  mainmenu_option next_comment
  2632. +  comment 'Network device support'
  2633. +
  2634. +  bool 'Network device support?' CONFIG_NETDEVICES y
  2635. +  if [ "$CONFIG_NETDEVICES" = "n" ]; then
  2636. +
  2637. +  comment 'Skipping network driver configuration options...'
  2638. +
  2639. +  else
  2640. +    tristate 'Dummy net driver support' CONFIG_DUMMY y
  2641. +    tristate 'SLIP (serial line) support' CONFIG_SLIP y
  2642. +    if [ "$CONFIG_SLIP" = "y" ]; then
  2643. +      bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
  2644. +    fi
  2645. +    tristate 'PPP (point-to-point) support' CONFIG_PPP y
  2646. +    if [ ! "$CONFIG_PPP" = "n" ]; then
  2647. +      comment 'CCP compressors for PPP are only built as modules.'
  2648. +    fi
  2649. +    tristate 'PLIP (parallel port) support' CONFIG_PLIP y
  2650. +    tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER n
  2651. +    tristate 'Ether1 (82586) support' CONFIG_ETHER1 n
  2652. +    tristate 'Ether3 (NQ8005) support' CONFIG_ETHER3 n
  2653. +  fi
  2654. +fi
  2655. +
  2656. +mainmenu_option next_comment
  2657. +comment 'Filesystems'
  2658. +
  2659. +tristate 'Standard (minix) fs support' CONFIG_MINIX_FS n
  2660. +tristate 'Extended fs support' CONFIG_EXT_FS n
  2661. +tristate 'Second extended fs support' CONFIG_EXT2_FS y
  2662. +tristate 'xiafs filesystem support' CONFIG_XIA_FS n
  2663. +tristate 'msdos fs support' CONFIG_MSDOS_FS y
  2664. +if [ "$CONFIG_MSDOS_FS" = "y" ]; then
  2665. +  tristate 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
  2666. +fi
  2667. +tristate '/proc filesystem support' CONFIG_PROC_FS y
  2668. +tristate 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
  2669. +tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
  2670. +tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
  2671. +if [ "$CONFIG_INET" = "y" ]; then
  2672. +  tristate 'NFS filesystem support' CONFIG_NFS_FS y
  2673. +  tristate 'SMB filesystem (to mount WfW shares etc...) support' CONFIG_SMB_FS n
  2674. +fi
  2675. +
  2676. +mainmenu_option next_comment
  2677. +comment 'Character devices'
  2678. +
  2679. +tristate 'Parallel printer support' CONFIG_PRINTER y
  2680. +tristate 'Mouse support' CONFIG_MOUSE y
  2681. +if [ "$CONFIG_MOUSE" = "n" ]; then
  2682. +  comment 'Skipping mouse options...'
  2683. +else
  2684. +  tristate 'Keyboard mouse [all but RiscPC]' CONFIG_KBDMOUSE y
  2685. +fi
  2686. +
  2687. +mainmenu_option next_comment
  2688. +comment 'Sound'
  2689. +
  2690. +tristate 'Sound support' CONFIG_SOUND n
  2691. +
  2692. +mainmenu_option next_comment
  2693. +comment 'Kernel hacking'
  2694. +
  2695. +bool 'Kernel profiling support' CONFIG_PROFILE n
  2696. +if [ "$CONFIG_PROFILE" = "y" ]; then
  2697. +  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
  2698. +fi
  2699. +if [ "$CONFIG_SCSI" = "y" ]; then
  2700. +bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
  2701. +fi
  2702. diff -urNwbB linux/arch/arm/drivers/Makefile linux.arm/arch/arm/drivers/Makefile
  2703. --- linux/arch/arm/drivers/Makefile    Thu Jan  1 01:00:00 1970
  2704. +++ linux.arm/arch/arm/drivers/Makefile    Sun Feb 11 09:32:13 1996
  2705. @@ -0,0 +1,33 @@
  2706. +#
  2707. +# Makefile for the linux kernel device drivers.
  2708. +#
  2709. +# Note! Dependencies are done automagically by 'make dep', which also
  2710. +# removes any old dependencies. DON'T put your own dependencies here
  2711. +# unless it's something special (ie not a .c file).
  2712. +#
  2713. +# Note 2! The CFLAGS definitions are now in the main makefile...
  2714. +
  2715. +SUB_DIRS     := block char net #streams
  2716. +MOD_SUB_DIRS := $(SUB_DIRS)
  2717. +ALL_SUB_DIRS := $(SUB_DIRS) scsi sound
  2718. +
  2719. +# If CONFIG_SCSI is set, the core of scsi support will be added to the kernel,
  2720. +# but some of the low-level things may also be modules.
  2721. +ifeq ($(CONFIG_SCSI),y)
  2722. +SUB_DIRS += scsi
  2723. +MOD_SUB_DIRS += scsi
  2724. +else
  2725. +  ifeq ($(CONFIG_SCSI),m)
  2726. +  MOD_SUB_DIRS += scsi
  2727. +  endif
  2728. +endif
  2729. +
  2730. +ifeq ($(CONFIG_SOUND),y)
  2731. +SUB_DIRS += sound
  2732. +else
  2733. +  ifeq ($(CONFIG_SOUND),m)
  2734. +  MOD_SUB_DIRS += sound
  2735. +  endif
  2736. +endif
  2737. +
  2738. +include $(TOPDIR)/Rules.make
  2739. diff -urNwbB linux/arch/arm/drivers/block/Makefile linux.arm/arch/arm/drivers/block/Makefile
  2740. --- linux/arch/arm/drivers/block/Makefile    Thu Jan  1 01:00:00 1970
  2741. +++ linux.arm/arch/arm/drivers/block/Makefile    Sat Feb 24 13:17:05 1996
  2742. @@ -0,0 +1,63 @@
  2743. +#
  2744. +# Makefile for the kernel block device drivers.
  2745. +#
  2746. +# Note! Dependencies are done automagically by 'make dep', which also
  2747. +# removes any old dependencies. DON'T put your own dependencies here
  2748. +# unless it's something special (ie not a .c file).
  2749. +#
  2750. +# Note 2! The CFLAGS definition is now inherited from the
  2751. +# parent makefile.
  2752. +#
  2753. +
  2754. +all: links first_rule
  2755. +
  2756. +L_TARGET := block.a
  2757. +L_OBJS   := ll_rw_blk.o ramdisk.o genhd.o hdsrch.o
  2758. +M_OBJS   :=
  2759. +MOD_LIST_NAME := BLOCK_MODULES
  2760. +
  2761. +ifeq ($(CONFIG_BLK_DEV_FD),y)
  2762. +L_OBJS += floppy.o
  2763. +else
  2764. +  ifeq ($(CONFIG_BLK_DEV_FD),m)
  2765. +  M_OBJS += floppy.o
  2766. +  endif
  2767. +endif
  2768. +
  2769. +ifeq ($(CONFIG_BLK_DEV_HD),y)
  2770. +L_OBJS += hd.o
  2771. +endif
  2772. +
  2773. +ifeq ($(CONFIG_BLK_DEV_IDE),y)
  2774. +L_OBJS += ide.o
  2775. +endif
  2776. +
  2777. +ifeq ($(CONFIG_BLK_DEV_MFM),y)
  2778. +L_OBJS += mfmhd.o
  2779. +else
  2780. +  ifeq ($(CONFIG_BLK_DEV_MFM),m)
  2781. +  M_OBJS += mfmhd_mod.o
  2782. +  endif
  2783. +endif
  2784. +
  2785. +include $(TOPDIR)/Rules.make
  2786. +
  2787. +fastdep: links
  2788. +
  2789. +mfmhd_mod.o: mfmhd.o
  2790. +    ld -r -o $@ mfmhd.o `gcc --print-libgcc-file-name`
  2791. +
  2792. +LK = blk.h ll_rw_blk.c ramdisk.c README.fd README.hd
  2793. +
  2794. +links:
  2795. +    -@for f in $(LK); do \
  2796. +        ln -s ../../../../drivers/block/$$f .; \
  2797. +    done
  2798. +    touch links
  2799. +
  2800. +LINKCLEAN:
  2801. +    -@for f in $(LK); do \
  2802. +        if [ -L $$f ]; then rm -f $$f; fi; \
  2803. +    done
  2804. +    rm -f links
  2805. +
  2806. diff -urNwbB linux/arch/arm/drivers/block/floppy.c linux.arm/arch/arm/drivers/block/floppy.c
  2807. --- linux/arch/arm/drivers/block/floppy.c    Thu Jan  1 01:00:00 1970
  2808. +++ linux.arm/arch/arm/drivers/block/floppy.c    Sun Mar  3 12:20:41 1996
  2809. @@ -0,0 +1,4120 @@
  2810. +/*
  2811. + *  linux/arch/arm/drivers/block/floppy.c
  2812. + *  [ was linux/drivers/block/floppy.c ]
  2813. + *
  2814. + *  Copyright (C) 1991, 1992  Linus Torvalds
  2815. + *  Copyright (C) 1993, 1994  Alain Knaff
  2816. + *  Modifications Copyright (C) 1995 Russell King
  2817. + */
  2818. +/*
  2819. + * 02.12.91 - Changed to static variables to indicate need for reset
  2820. + * and recalibrate. This makes some things easier (output_byte reset
  2821. + * checking etc), and means less interrupt jumping in case of errors,
  2822. + * so the code is hopefully easier to understand.
  2823. + */
  2824. +
  2825. +/*
  2826. + * This file is certainly a mess. I've tried my best to get it working,
  2827. + * but I don't like programming floppies, and I have only one anyway.
  2828. + * Urgel. I should check for more errors, and do more graceful error
  2829. + * recovery. Seems there are problems with several drives. I've tried to
  2830. + * correct them. No promises.
  2831. + */
  2832. +
  2833. +/*
  2834. + * As with hd.c, all routines within this file can (and will) be called
  2835. + * by interrupts, so extreme caution is needed. A hardware interrupt
  2836. + * handler may not sleep, or a kernel panic will happen. Thus I cannot
  2837. + * call "floppy-on" directly, but have to set a special timer interrupt
  2838. + * etc.
  2839. + */
  2840. +
  2841. +/*
  2842. + * 28.02.92 - made track-buffering routines, based on the routines written
  2843. + * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus.
  2844. + */
  2845. +
  2846. +/*
  2847. + * Automatic floppy-detection and formatting written by Werner Almesberger
  2848. + * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with
  2849. + * the floppy-change signal detection.
  2850. + */
  2851. +
  2852. +/*
  2853. + * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
  2854. + * FDC data overrun bug, added some preliminary stuff for vertical
  2855. + * recording support.
  2856. + *
  2857. + * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
  2858. + *
  2859. + * TODO: Errors are still not counted properly.
  2860. + */
  2861. +
  2862. +/* 1992/9/20
  2863. + * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl)
  2864. + * modelled after the freeware MS/DOS program fdformat/88 V1.8 by
  2865. + * Christoph H. Hochst\"atter.
  2866. + * I have fixed the shift values to the ones I always use. Maybe a new
  2867. + * ioctl() should be created to be able to modify them.
  2868. + * There is a bug in the driver that makes it impossible to format a
  2869. + * floppy as the first thing after bootup.
  2870. + */
  2871. +
  2872. +/*
  2873. + * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
  2874. + * this helped the floppy driver as well. Much cleaner, and still seems to
  2875. + * work.
  2876. + */
  2877. +
  2878. +/* 1994/6/24 --bbroad-- added the floppy table entries and made
  2879. + * minor modifications to allow 2.88 floppies to be run.
  2880. + */
  2881. +
  2882. +/* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
  2883. + * disk types.
  2884. + */
  2885. +
  2886. +/*
  2887. + * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
  2888. + * format bug fixes, but unfortunately some new bugs too...
  2889. + */
  2890. +
  2891. +/* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write
  2892. + * errors to allow safe writing by specialized programs.
  2893. + */
  2894. +
  2895. +/* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
  2896. + * by defining bit 1 of the "stretch" parameter to mean put sectors on the
  2897. + * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
  2898. + * drives are "upside-down").
  2899. + */
  2900. +
  2901. +/*
  2902. + * 1995/8/16 -- Russell King -- altered method for turning floppy drives on
  2903. + * for the arm.
  2904. + */
  2905. +#define CONFIG_FLOPPY_SANITY
  2906. +#undef  CONFIG_FLOPPY_SILENT_DCL_CLEAR
  2907. +
  2908. +#define DEBUGT 2
  2909. +#define DCL_DEBUG /* debug disk change line */
  2910. +
  2911. +#include <linux/config.h>
  2912. +
  2913. +/* do print messages for unexpected interrupts */
  2914. +static int print_unex=1;
  2915. +
  2916. +#ifdef MODULE
  2917. +#define FD_MODULE
  2918. +
  2919. +#include <linux/module.h>
  2920. +/*
  2921. + * NB. we must include the kernel identification string to install the module.
  2922. + */
  2923. +#include <linux/version.h>
  2924. +char kernel_version[] = UTS_RELEASE;
  2925. +
  2926. +int FLOPPY_IRQ=12;
  2927. +int FLOPPY_DMA=2;
  2928. +int ALLOWED_DRIVE_MASK = 0x33;
  2929. +int FDC1 = 0x3f0;
  2930. +int FDC2 = -1;
  2931. +
  2932. +#endif
  2933. +
  2934. +#ifndef FD_MODULE
  2935. +/* the following is the mask of allowed drives. By default units 2 and
  2936. + * 3 of both floppy controllers are disabled, because switching on the
  2937. + * motor of these drives causes system hangs on some PCI computers. drive
  2938. + * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
  2939. + * a drive is allowed. */
  2940. +static int ALLOWED_DRIVE_MASK=0x33;
  2941. +
  2942. +#define FLOPPY_IRQ 12
  2943. +#define FLOPPY_DMA 2
  2944. +#define FDC1 0x3f0
  2945. +static int FDC2=-1;
  2946. +#endif
  2947. +
  2948. +#define MODULE_AWARE_DRIVER
  2949. +
  2950. +#include <linux/sched.h>
  2951. +#include <linux/fs.h>
  2952. +#include <linux/kernel.h>
  2953. +#include <linux/timer.h>
  2954. +#include <linux/tqueue.h>
  2955. +#define FDPATCHES
  2956. +#include <linux/fdreg.h>
  2957. +
  2958. +/* ============================================ *
  2959. + * old fd.h                                     *
  2960. + * =========================================== */
  2961. +
  2962. +#define OLDFDCLRPRM 0 /* clear user-defined parameters */
  2963. +#define OLDFDSETPRM 1 /* set user-defined parameters for current media */
  2964. +#define OLDFDSETMEDIAPRM 1
  2965. +#define OLDFDDEFPRM 2 /* set user-defined parameters until explicitly cleared */
  2966. +#define OLDFDDEFMEDIAPRM 2
  2967. +#define OLDFDGETPRM 3 /* get disk parameters */
  2968. +#define OLDFDGETMEDIAPRM 3
  2969. +#define OLDFDMSGON  4 /* issue kernel messages on media type change */
  2970. +#define OLDFDMSGOFF 5 /* don't issue kernel messages on media type change */
  2971. +#define OLDFDFMTBEG 6 /* begin formatting a disk */
  2972. +#define OLDFDFMTTRK 7 /* format the specified track */
  2973. +#define OLDFDFMTEND 8 /* end formatting a disk */
  2974. +#define OLDFDSETEMSGTRESH       10      /* set fdc error reporting threshold */
  2975. +#define OLDFDFLUSH  11 /* flush buffers for media; either for verifying media, or for
  2976. +                       handling a media change without closing the file
  2977. +                                              descriptor */
  2978. +#define OLDFDSETMAXERRS 12 /* set abortion and read_track threshold */
  2979. +#define OLDFDGETMAXERRS 14 /* get abortion and read_track threshold */
  2980. +#define OLDFDGETDRVTYP 16          /* get drive type: 5 1/4 or 3 1/2 */
  2981. +
  2982. +#define OLDFDSETDRVPRM 20 /* set drive parameters */
  2983. +#define OLDFDGETDRVPRM 21 /* get drive parameters */
  2984. +#define OLDFDGETDRVSTAT 22 /* get drive state */
  2985. +#define OLDFDPOLLDRVSTAT 23 /* get drive state */
  2986. +#define OLDFDRESET 24 /* reset FDC */
  2987. +
  2988. +#define OLDFD_RESET_IF_NEEDED 0
  2989. +#define OLDFD_RESET_IF_RAWCMD 1
  2990. +#define OLDFD_RESET_ALWAYS 2
  2991. +
  2992. +#define OLDFDGETFDCSTAT 25 /* get fdc state */
  2993. +#define OLDFDWERRORCLR  27 /* clear write error and badness information */
  2994. +#define OLDFDWERRORGET  28 /* get write error and badness information */
  2995. +
  2996. +#define OLDFDRAWCMD 30 /* send a raw command to the fdc */
  2997. +
  2998. +#define OLDFDTWADDLE 40 /* flicker motor-on bit before reading a sector */
  2999. +
  3000. +struct old_floppy_raw_cmd {
  3001. +  void *data;
  3002. +  long length;
  3003. +
  3004. +  unsigned char rate;
  3005. +  unsigned char flags;
  3006. +  unsigned char cmd_count;
  3007. +  unsigned char cmd[9];
  3008. +  unsigned char reply_count;
  3009. +  unsigned char reply[7];
  3010. +  int track;
  3011. +};
  3012. +
  3013. +struct old_floppy_fdc_state {
  3014. +    int spec1; /* spec1 value last used */
  3015. +    int spec2; /* spec2 value last used */
  3016. +    int dtr;
  3017. +    unsigned char version;  /* FDC version code */
  3018. +    unsigned char dor;
  3019. +    int address; /* io address */
  3020. +    unsigned int rawcmd:2;
  3021. +    unsigned int reset:1;
  3022. +    unsigned int need_configure:1;
  3023. +    unsigned int perp_mode:2;
  3024. +    unsigned int has_fifo:1;
  3025. +};
  3026. +
  3027. +
  3028. +#include <linux/fd.h>
  3029. +#include <linux/errno.h>
  3030. +#include <linux/malloc.h>
  3031. +#include <linux/mm.h>
  3032. +#include <linux/string.h>
  3033. +#include <linux/fcntl.h>
  3034. +#include <linux/delay.h>
  3035. +
  3036. +#include <linux/ioport.h>
  3037. +
  3038. +#include <asm/dma.h>
  3039. +#include <asm/irq.h>
  3040. +#include <asm/system.h>
  3041. +#include <asm/io.h>
  3042. +#include <asm/segment.h>
  3043. +
  3044. +#define MAJOR_NR FLOPPY_MAJOR
  3045. +#include "blk.h"
  3046. +
  3047. +
  3048. +/* Dma Memory related stuff */
  3049. +
  3050. +/* Pure 2^n version of get_order */
  3051. +static inline int __get_order (int size)
  3052. +{
  3053. +    int order;
  3054. +
  3055. +    for (order = 0; order < NR_MEM_LISTS; ++order)
  3056. +        if (size <= (PAGE_SIZE << order))
  3057. +            return order;
  3058. +    return NR_MEM_LISTS;
  3059. +}
  3060. +
  3061. +static unsigned long dma_mem_alloc(int size)
  3062. +{
  3063. +    int order = __get_order(size);
  3064. +
  3065. +    if (order >= NR_MEM_LISTS)
  3066. +        return(0);
  3067. +    return __get_dma_pages(GFP_KERNEL,order);
  3068. +}
  3069. +
  3070. +/* End dma memory related stuff */
  3071. +
  3072. +static unsigned int fake_change = 0;
  3073. +static int initialising=1;
  3074. +
  3075. +#define FLOPPY0_TYPE 4
  3076. +#define FLOPPY1_TYPE 0
  3077. +
  3078. +#define N_FDC 2
  3079. +#define N_DRIVE 8
  3080. +
  3081. +static inline int TYPE(kdev_t x) {
  3082. +    return  (MINOR(x)>>2) & 0x1f;
  3083. +}
  3084. +static inline int DRIVE(kdev_t x) {
  3085. +    return (MINOR(x)&0x03) | ((MINOR(x)&0x80)>>5);
  3086. +}
  3087. +#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
  3088. +#define UNIT(x) ( (x) & 0x03 )        /* drive on fdc */
  3089. +#define FDC(x) ( ((x) & 0x04) >> 2 )  /* fdc of drive */
  3090. +#define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 ))
  3091. +                /* reverse mapping from unit and fdc to drive */
  3092. +#define DP (&drive_params[current_drive])
  3093. +#define DRS (&drive_state[current_drive])
  3094. +#define DRWE (&write_errors[current_drive])
  3095. +#define FDCS (&fdc_state[fdc])
  3096. +#define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags))
  3097. +#define SETF(x) (set_bit(x##_BIT, &DRS->flags))
  3098. +#define TESTF(x) (test_bit(x##_BIT, &DRS->flags))
  3099. +
  3100. +#define UDP (&drive_params[drive])
  3101. +#define UDRS (&drive_state[drive])
  3102. +#define UDRWE (&write_errors[drive])
  3103. +#define UFDCS (&fdc_state[FDC(drive)])
  3104. +#define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags))
  3105. +#define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
  3106. +#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
  3107. +
  3108. +#define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
  3109. +
  3110. +#define DPRINT1(x,x1) printk(DEVICE_NAME "%d: " x,current_drive,(x1))
  3111. +
  3112. +#define DPRINT2(x,x1,x2) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
  3113. +
  3114. +#define DPRINT3(x,x1,x2,x3) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
  3115. +
  3116. +#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
  3117. +#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
  3118. +
  3119. +/* read/write */
  3120. +#define COMMAND raw_cmd->cmd[0]
  3121. +#define DR_SELECT raw_cmd->cmd[1]
  3122. +#define TRACK raw_cmd->cmd[2]
  3123. +#define HEAD raw_cmd->cmd[3]
  3124. +#define SECTOR raw_cmd->cmd[4]
  3125. +#define SIZECODE raw_cmd->cmd[5]
  3126. +#define SECT_PER_TRACK raw_cmd->cmd[6]
  3127. +#define GAP raw_cmd->cmd[7]
  3128. +#define SIZECODE2 raw_cmd->cmd[8]
  3129. +#define NR_RW 9
  3130. +
  3131. +/* format */
  3132. +#define F_SIZECODE raw_cmd->cmd[2]
  3133. +#define F_SECT_PER_TRACK raw_cmd->cmd[3]
  3134. +#define F_GAP raw_cmd->cmd[4]
  3135. +#define F_FILL raw_cmd->cmd[5]
  3136. +#define NR_F 6
  3137. +
  3138. +/*
  3139. + * Maximum disk size (in kilobytes). This default is used whenever the
  3140. + * current disk size is unknown.
  3141. + * [Now it is rather a minimum]
  3142. + */
  3143. +#define MAX_DISK_SIZE 2 /* 3984*/
  3144. +
  3145. +
  3146. +#define K_64    0x10000        /* 64kB */
  3147. +
  3148. +/*
  3149. + * The DMA channel used by the floppy controller cannot access data at
  3150. + * addresses >= 16MB
  3151. + *
  3152. + * Went back to the 1MB limit, as some people had problems with the floppy
  3153. + * driver otherwise. It doesn't matter much for performance anyway, as most
  3154. + * floppy accesses go through the track buffer.
  3155. + */
  3156. +#define CROSS_64KB(a,s) (0)
  3157. +#undef LAST_DMA_ADDR
  3158. +#define LAST_DMA_ADDR    (0x1)
  3159. +
  3160. +/*
  3161. + * globals used by 'result()'
  3162. + */
  3163. +#define MAX_REPLIES 10
  3164. +static unsigned char reply_buffer[MAX_REPLIES];
  3165. +static int inr; /* size of reply buffer, when called from interrupt */
  3166. +#define ST0 (reply_buffer[0])
  3167. +#define ST1 (reply_buffer[1])
  3168. +#define ST2 (reply_buffer[2])
  3169. +#define ST3 (reply_buffer[0]) /* result of GETSTATUS */
  3170. +#define R_TRACK (reply_buffer[3])
  3171. +#define R_HEAD (reply_buffer[4])
  3172. +#define R_SECTOR (reply_buffer[5])
  3173. +#define R_SIZECODE (reply_buffer[6])
  3174. +
  3175. +#define SEL_DLY (2*HZ/100)
  3176. +
  3177. +#define ARRAY_SIZE(x) (sizeof(x) / sizeof( (x)[0] ))
  3178. +/*
  3179. + * this struct defines the different floppy drive types.
  3180. + */
  3181. +static struct {
  3182. +    struct floppy_drive_params params;
  3183. +    const char *name; /* name printed while booting */
  3184. +} default_drive_params[]= {
  3185. +/* NOTE: the time values in jiffies should be in msec!
  3186. + CMOS drive type
  3187. +  |     Maximum data rate supported by drive type
  3188. +  |     |   Head load time, msec
  3189. +  |     |   |   Head unload time, msec (not used)
  3190. +  |     |   |   |     Step rate interval, usec
  3191. +  |     |   |   |     |       Time needed for spinup time (jiffies)
  3192. +  |     |   |   |     |       |      Timeout for spinning down (jiffies)
  3193. +  |     |   |   |     |       |      |   Spindown offset (where disk stops)
  3194. +  |     |   |   |     |       |      |   |     Select delay
  3195. +  |     |   |   |     |       |      |   |     |     RPS
  3196. +  |     |   |   |     |       |      |   |     |     |    Max number of tracks
  3197. +  |     |   |   |     |       |      |   |     |     |    |     Interrupt timeout
  3198. +  |     |   |   |     |       |      |   |     |     |    |     |   Max nonintlv. sectors
  3199. +  |     |   |   |     |       |      |   |     |     |    |     |   | -Max Errors- flags */
  3200. +{{0,  500, 16, 16, 8000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  80, 3*HZ, 20, {3,1,2,0,2}, 0,
  3201. +      0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" },
  3202. +
  3203. +{{1,  300, 16, 16, 8000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  40, 3*HZ, 17, {3,1,2,0,2}, 0,
  3204. +      0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/
  3205. +
  3206. +{{2,  500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6,  83, 3*HZ, 17, {3,1,2,0,2}, 0,
  3207. +      0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
  3208. +
  3209. +{{3,  250, 16, 16, 3000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,2}, 0,
  3210. +      0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/
  3211. +#if 0
  3212. +{{4,  500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,2}, 0,
  3213. +      0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/
  3214. +#else
  3215. +{{4,  500, 16, 16, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,0}, FTD_MSG,
  3216. +      0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/
  3217. +#endif
  3218. +{{5, 1000, 15,  8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 40, {3,1,2,0,2}, 0,
  3219. +      0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/
  3220. +
  3221. +{{6, 1000, 15,  8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 40, {3,1,2,0,2}, 0,
  3222. +      0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/
  3223. +/*    |  --autodetected formats---   |      |      |
  3224. + *    read_track                     |      |    Name printed when booting
  3225. + *                                   |     Native format
  3226. + *                                 Frequency of disk change checks */
  3227. +};
  3228. +
  3229. +static struct floppy_drive_params drive_params[N_DRIVE];
  3230. +static struct floppy_drive_struct drive_state[N_DRIVE];
  3231. +static struct floppy_write_errors write_errors[N_DRIVE];
  3232. +static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
  3233. +
  3234. +/*
  3235. + * This struct defines the different floppy types.
  3236. + *
  3237. + * Bit 0 of 'stretch' tells if the tracks need to be doubled for some
  3238. + * types (e.g. 360kB diskette in 1.2MB drive, etc.). Bit 1 of 'stretch'
  3239. + * tells if the disk is in Commodore 1581 format, which means side 0 sectors
  3240. + * are located on side 1 of the disk but with a side 0 ID, and vice-versa.
  3241. + * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the
  3242. + * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
  3243. + * side 0 is on physical side 0 (but with the misnamed sector IDs).
  3244. + * 'stretch' should probably be renamed to something more general, like
  3245. + * 'options'.  Other parameters should be self-explanatory (see also
  3246. + * setfdprm(8)).
  3247. + */
  3248. +/*
  3249. +             Size
  3250. +             |  Sectors per track
  3251. +             |  | Head
  3252. +             |  | |  Tracks
  3253. +             |  | |  | Stretch
  3254. +             |  | |  | |  Gap 1 size
  3255. +             |  | |  | |    |  Data rate, | 0x40 for perp
  3256. +         |  | |  | |    |    |  Spec1 (stepping rate, head unload
  3257. +             |  | |  | |    |    |    |    /fmt gap (gap2) */
  3258. +static struct floppy_struct floppy_type[32] = {
  3259. +    {    0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL    },    /*  0 no testing    */
  3260. +    {  720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360"  }, /*  1 360KB PC      */
  3261. +    { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" },    /*  2 1.2MB AT      */
  3262. +    {  720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360"  },    /*  3 360KB SS 3.5" */
  3263. +    { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720"  },    /*  4 720KB 3.5"    */
  3264. +    {  720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360"  },    /*  5 360KB AT      */
  3265. +    { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720"  },    /*  6 720KB AT      */
  3266. +    { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" },    /*  7 1.44MB 3.5"   */
  3267. +    { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" },    /*  8 2.88MB 3.5"   */
  3268. +    { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"},    /*  9 2.88MB 3.5"   */
  3269. +
  3270. +    { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25"  */
  3271. +    { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5"   */
  3272. +    {  820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410"  },    /* 12 410KB 5.25"   */
  3273. +    { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820"  },    /* 13 820KB 3.5"    */
  3274. +    { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" },    /* 14 1.48MB 5.25"  */
  3275. +    { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" },    /* 15 1.72MB 3.5"   */
  3276. +    {  840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420"  },    /* 16 420KB 5.25"   */
  3277. +    { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830"  },    /* 17 830KB 3.5"    */
  3278. +    { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" },    /* 18 1.49MB 5.25"  */
  3279. +    { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5"  */
  3280. +
  3281. +    { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880"  }, /* 20 880KB 5.25"   */
  3282. +    { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5"   */
  3283. +    { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5"   */
  3284. +    { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25"   */
  3285. +    { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5"   */
  3286. +    { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5"   */
  3287. +    { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5"   */
  3288. +    { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5"   */
  3289. +    { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5"   */
  3290. +
  3291. +    { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5"   */
  3292. +    { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800"  },    /* 30 800KB 3.5"    */
  3293. +    { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5"    */
  3294. +};
  3295. +
  3296. +#define    NUMBER(x)    (sizeof(x) / sizeof(*(x)))
  3297. +#define SECTSIZE ( _FD_SECTSIZE(*floppy))
  3298. +
  3299. +/* Auto-detection: Disk type used until the next media change occurs. */
  3300. +struct floppy_struct *current_type[N_DRIVE] = {
  3301. +    NULL, NULL, NULL, NULL,
  3302. +    NULL, NULL, NULL, NULL
  3303. +};
  3304. +
  3305. +/*
  3306. + * User-provided type information. current_type points to
  3307. + * the respective entry of this array.
  3308. + */
  3309. +struct floppy_struct user_params[N_DRIVE];
  3310. +
  3311. +static int floppy_sizes[256];
  3312. +static int floppy_blocksizes[256] = { 0, };
  3313. +
  3314. +/*
  3315. + * The driver is trying to determine the correct media format
  3316. + * while probing is set. rw_interrupt() clears it after a
  3317. + * successful access.
  3318. + */
  3319. +static int probing = 0;
  3320. +
  3321. +/* Synchronization of FDC access. */
  3322. +#define FD_COMMAND_DETECT -2
  3323. +#define FD_COMMAND_NONE -1
  3324. +#define FD_COMMAND_ERROR 2
  3325. +#define FD_COMMAND_OKAY 3
  3326. +
  3327. +static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
  3328. +static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
  3329. +#define NO_SIGNAL (!(current->signal & ~current->blocked) || !interruptible)
  3330. +#define CALL(x) if( (x) == -EINTR) return -EINTR
  3331. +#define ECALL(x) if ((ret = (x))) return ret;
  3332. +#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
  3333. +#define WAIT(x) _WAIT((x),interruptible)
  3334. +#define IWAIT(x) _WAIT((x),1)
  3335. +
  3336. +/* Errors during formatting are counted here. */
  3337. +static int format_errors;
  3338. +
  3339. +/* Format request descriptor. */
  3340. +static struct format_descr format_req;
  3341. +
  3342. +/*
  3343. + * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps
  3344. + * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
  3345. + * H is head unload time (1=16ms, 2=32ms, etc)
  3346. + */
  3347. +
  3348. +/*
  3349. + * Track buffer
  3350. + * Because these are written to by the DMA controller, they must
  3351. + * not contain a 64k byte boundary crossing, or data will be
  3352. + * corrupted/lost. Alignment of these is enforced in boot/head.S.
  3353. + * Note that you must not change the sizes below without updating head.S.
  3354. + */
  3355. +char *floppy_track_buffer=NULL;
  3356. +int max_buffer_sectors=0;
  3357. +
  3358. +int *errors;
  3359. +typedef void (*done_f)(int);
  3360. +struct cont_t {
  3361. +    void (*interrupt)(void); /* this is called after the interrupt of the
  3362. +                  * main command */
  3363. +    void (*redo)(void); /* this is called to retry the operation */
  3364. +    void (*error)(void); /* this is called to tally an error */
  3365. +    done_f done; /* this is called to say if the operation has
  3366. +              * succeeded/failed */
  3367. +} *cont=NULL;
  3368. +
  3369. +static void floppy_ready(void);
  3370. +static void floppy_start(void);
  3371. +static void process_fd_request(void);
  3372. +static void recalibrate_floppy(void);
  3373. +static void floppy_shutdown(void);
  3374. +
  3375. +static int floppy_grab_irq_and_dma(void);
  3376. +static void floppy_release_irq_and_dma(void);
  3377. +
  3378. +/*
  3379. + * The "reset" variable should be tested whenever an interrupt is scheduled,
  3380. + * after the commands have been sent. This is to ensure that the driver doesn't
  3381. + * get wedged when the interrupt doesn't come because of a failed command.
  3382. + * reset doesn't need to be tested before sending commands, because
  3383. + * output_byte is automatically disabled when reset is set.
  3384. + */
  3385. +#define CHECK_RESET { if ( FDCS->reset ){ reset_fdc(); return ; } }
  3386. +static void reset_fdc(void);
  3387. +
  3388. +/*
  3389. + * These are global variables, as that's the easiest way to give
  3390. + * information to interrupts. They are the data used for the current
  3391. + * request.
  3392. + */
  3393. +#define NO_TRACK -1
  3394. +#define NEED_1_RECAL -2
  3395. +#define NEED_2_RECAL -3
  3396. +
  3397. +/* */
  3398. +static int usage_count = 0;
  3399. +
  3400. +
  3401. +/* buffer related variables */
  3402. +static int buffer_track = -1;
  3403. +static int buffer_drive = -1;
  3404. +static int buffer_min = -1;
  3405. +static int buffer_max = -1;
  3406. +
  3407. +/* fdc related variables, should end up in a struct */
  3408. +static struct floppy_fdc_state fdc_state[N_FDC];
  3409. +static int fdc; /* current fdc */
  3410. +
  3411. +static struct floppy_struct * floppy = floppy_type;
  3412. +static unsigned char current_drive = 0;
  3413. +static long current_count_sectors = 0;
  3414. +static unsigned char sector_t; /* sector in track */
  3415. +
  3416. +#ifdef DEBUGT
  3417. +long unsigned debugtimer;
  3418. +#endif
  3419. +
  3420. +/*
  3421. + * Floppy_selects1 is the list of DOR's to select a drive n
  3422. + * Floppy_selects2 is the list of DOR's to select drive fd
  3423. + * On initialisation, the floppy list is scanned, and the drives allocated
  3424. + * in the order that they are found.  This is done by seeking the drive
  3425. + * to a non-zero track, and then restoring it to track 0.  If an error occurs,
  3426. + * then there is no floppy drive present.
  3427. + */
  3428. +/*extern*/ int no_floppies;
  3429. +unsigned char floppy_selects1[]={ 0x10, 0x21, 0x23, 0x33 };
  3430. +unsigned char floppy_selects2[]={ 0   , 0   , 0   , 0    };
  3431. +
  3432. +/*
  3433. + * Debugging
  3434. + * =========
  3435. + */
  3436. +static inline void set_debugt(void)
  3437. +{
  3438. +#ifdef DEBUGT
  3439. +    debugtimer = jiffies;
  3440. +#endif
  3441. +}
  3442. +
  3443. +static inline void debugt(const char *message)
  3444. +{
  3445. +#ifdef DEBUGT
  3446. +  if ( DP->flags & DEBUGT )
  3447. +    printk("%s dtime=%lu\n", message, jiffies-debugtimer );
  3448. +#endif
  3449. +}
  3450. +
  3451. +typedef void (*timeout_fn)(unsigned long);
  3452. +static struct timer_list fd_timeout ={ NULL, NULL, 0, 0,
  3453. +                    (timeout_fn) floppy_shutdown };
  3454. +
  3455. +static const char *timeout_message;
  3456. +
  3457. +#ifdef CONFIG_FLOPPY_SANITY
  3458. +static void is_alive(const char *message)
  3459. +{
  3460. +    /* this routine checks whether the floppy driver is "alive" */
  3461. +    if (fdc_busy && command_status < 2 && !fd_timeout.prev){
  3462. +        DPRINT1("timeout handler died: %s\n",message);
  3463. +    }
  3464. +}
  3465. +
  3466. +
  3467. +#define OLOGSIZE 20
  3468. +
  3469. +void (*lasthandler)(void) = NULL;
  3470. +int interruptjiffies=0;
  3471. +int resultjiffies=0;
  3472. +int resultsize=0;
  3473. +int lastredo=0;
  3474. +
  3475. +static struct output_log {
  3476. +    unsigned char data;
  3477. +    unsigned char status;
  3478. +    unsigned long jiffies;
  3479. +} output_log[OLOGSIZE];
  3480. +
  3481. +static int output_log_pos=0;
  3482. +#endif
  3483. +
  3484. +#define CURRENTD -1
  3485. +#define MAXTIMEOUT -2
  3486. +
  3487. +
  3488. +
  3489. +static void reschedule_timeout(int drive, const char *message, int marg)
  3490. +{
  3491. +    if (drive == CURRENTD )
  3492. +        drive = current_drive;
  3493. +    del_timer(&fd_timeout);
  3494. +    if (drive < 0 || drive > N_DRIVE) {
  3495. +        fd_timeout.expires = jiffies + 20*HZ;
  3496. +        drive = 0;
  3497. +    } else
  3498. +        fd_timeout.expires = jiffies + UDP->timeout;
  3499. +    add_timer(&fd_timeout);
  3500. +    if (UDP->flags & FD_DEBUG) {
  3501. +        DPRINT("reschedule timeout ");
  3502. +        printk(message, marg);
  3503. +        printk("\n");
  3504. +    }
  3505. +    timeout_message = message;
  3506. +}
  3507. +
  3508. +/*
  3509. + * Bottom half floppy driver.
  3510. + * ==========================
  3511. + *
  3512. + * This part of the file contains the code talking directly to the hardware,
  3513. + * and also the main service loop (seek-configure-spinup-command)
  3514. + */
  3515. +
  3516. +/*
  3517. + * disk change.
  3518. + * This routine is responsible for maintaining the FD_DISK_CHANGE flag,
  3519. + * and the last_checked date.
  3520. + *
  3521. + * last_checked is the date of the last check which showed 'no disk change'
  3522. + * FD_DISK_CHANGE is set under two conditions:
  3523. + * 1. The floppy has been changed after some i/o to that floppy already
  3524. + *    took place.
  3525. + * 2. No floppy disk is in the drive. This is done in order to ensure that
  3526. + *    requests are quickly flushed in case there is no disk in the drive. It
  3527. + *    follows that FD_DISK_CHANGE can only be cleared if there is a disk in
  3528. + *    the drive.
  3529. + *
  3530. + * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet.
  3531. + * For 2., FD_DISK_NEWCHANGE is watched. FD_DISK_NEWCHANGE is cleared on
  3532. + *  each seek. If a disk is present, the disk change line should also be
  3533. + *  cleared on each seek. Thus, if FD_DISK_NEWCHANGE is clear, but the disk
  3534. + *  change line is set, this means either that no disk is in the drive, or
  3535. + *  that it has been removed since the last seek.
  3536. + *
  3537. + * This means that we really have a third possibility too:
  3538. + *  The floppy has been changed after the last seek.
  3539. + */
  3540. +
  3541. +static int disk_change(int drive)
  3542. +{
  3543. +    int fdc=FDC(drive);
  3544. +#ifdef CONFIG_FLOPPY_SANITY
  3545. +    if(jiffies < UDP->select_delay + UDRS->select_date)
  3546. +        DPRINT("WARNING disk change called early\n");
  3547. +    if(! (FDCS->dor & (0x10 << UNIT(drive))) ||
  3548. +       (FDCS->dor & 3) != UNIT(drive) ||
  3549. +       fdc != FDC(drive)){
  3550. +           DPRINT("probing disk change on unselected drive\n");
  3551. +           DPRINT3("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
  3552. +               FDCS->dor);
  3553. +    }
  3554. +#endif
  3555. +
  3556. +#ifdef DCL_DEBUG
  3557. +    if (UDP->flags & FD_DEBUG){
  3558. +        DPRINT1("checking disk change line for drive %d\n",drive);
  3559. +        DPRINT1("jiffies=%ld\n", jiffies);
  3560. +        DPRINT1("disk change line=%x\n", inb_p(FD_DIR)&0x80);
  3561. +        DPRINT1("flags=%x\n",UDRS->flags);
  3562. +    }
  3563. +#endif
  3564. +    if (UDP->flags & FD_BROKEN_DCL)
  3565. +        return UTESTF(FD_DISK_CHANGED);
  3566. +    if( (inb_p(FD_DIR) ^ UDP->flags) & 0x80){
  3567. +        USETF(FD_VERIFY); /* verify write protection */
  3568. +        if(UDRS->maxblock){
  3569. +            /* mark it changed */
  3570. +            USETF(FD_DISK_CHANGED);
  3571. +
  3572. +            /* invalidate its geometry */
  3573. +            if (UDRS->keep_data >= 0) {
  3574. +                if ((UDP->flags & FTD_MSG) &&
  3575. +                    current_type[drive] != NULL)
  3576. +                    DPRINT("Disk type is undefined after "
  3577. +                           "disk change\n");
  3578. +                current_type[drive] = NULL;
  3579. +                floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE;
  3580. +            }
  3581. +        }
  3582. +        /*USETF(FD_DISK_NEWCHANGE);*/
  3583. +        return 1;
  3584. +    } else {
  3585. +        UDRS->last_checked=jiffies;
  3586. +        UCLEARF(FD_DISK_NEWCHANGE);
  3587. +    }
  3588. +    return 0;
  3589. +}
  3590. +
  3591. +static inline int is_selected(int dor, int unit)
  3592. +{
  3593. +    return ( (dor  & (0x10 << unit)) && (dor &3) == unit);
  3594. +}
  3595. +
  3596. +static inline void arm_set_dor(int dor)
  3597. +{
  3598. +    if(dor & 0xf0)
  3599. +        outb_p((dor & 0x0c) | floppy_selects1[dor & 3], FD_DOR);
  3600. +    else
  3601. +        outb_p((dor & 0x0c), FD_DOR);
  3602. +}
  3603. +
  3604. +static int set_dor(int fdc, char mask, char data)
  3605. +{
  3606. +    register unsigned char drive, unit, newdor,olddor;
  3607. +
  3608. +    if (FDCS->address == -1)
  3609. +        return -1;
  3610. +
  3611. +    olddor = FDCS->dor;
  3612. +    newdor =  (olddor & mask) | data;
  3613. +    if ( newdor != olddor ){
  3614. +        unit = olddor & 0x3;
  3615. +        if(is_selected(olddor, unit) && !is_selected(newdor, unit)){
  3616. +            drive = REVDRIVE(fdc,unit);
  3617. +#ifdef DCL_DEBUG
  3618. +            if (UDP->flags & FD_DEBUG){
  3619. +                DPRINT("calling disk change from set_dor\n");
  3620. +            }
  3621. +#endif
  3622. +            disk_change(drive);
  3623. +        }
  3624. +        FDCS->dor = newdor;
  3625. +        arm_set_dor(newdor);
  3626. +
  3627. +        unit = newdor & 0x3;
  3628. +        if(!is_selected(olddor, unit) && is_selected(newdor, unit)){
  3629. +            drive = REVDRIVE(fdc,unit);
  3630. +            UDRS->select_date = jiffies;
  3631. +        }
  3632. +    }
  3633. +    if ( newdor & 0xf0 )
  3634. +        floppy_grab_irq_and_dma();
  3635. +    if( olddor & 0xf0 )
  3636. +        floppy_release_irq_and_dma();
  3637. +    return olddor;
  3638. +}
  3639. +
  3640. +static void twaddle(void)
  3641. +{
  3642. +    if (DP->select_delay)
  3643. +        return;
  3644. +    arm_set_dor(FDCS->dor & ~(0x10<<UNIT(current_drive)));
  3645. +    arm_set_dor(FDCS->dor);
  3646. +    DRS->select_date = jiffies;
  3647. +}
  3648. +
  3649. +/* reset all driver information about the current fdc. This is needed after
  3650. + * a reset, and after a raw command. */
  3651. +static void reset_fdc_info(int mode)
  3652. +{
  3653. +    int drive;
  3654. +
  3655. +    FDCS->spec1 = FDCS->spec2 = -1;
  3656. +    FDCS->need_configure = 1;
  3657. +    FDCS->perp_mode = 1;
  3658. +    FDCS->rawcmd = 0;
  3659. +    for ( drive = 0; drive < N_DRIVE; drive++)
  3660. +        if (FDC(drive) == fdc &&
  3661. +            ( mode || UDRS->track != NEED_1_RECAL))
  3662. +            UDRS->track = NEED_2_RECAL;
  3663. +}
  3664. +
  3665. +/* selects the fdc and drive, and enables the fdc's input/dma. */
  3666. +static void set_fdc(int drive)
  3667. +{
  3668. +    if ( drive >= 0 && drive < N_DRIVE){
  3669. +        fdc = FDC(drive);
  3670. +        current_drive = drive;
  3671. +    }
  3672. +    set_dor(fdc,~0,8);
  3673. +    set_dor(1-fdc, ~8, 0);
  3674. +    if ( FDCS->rawcmd == 2 )
  3675. +        reset_fdc_info(1);
  3676. +    if( inb_p(FD_STATUS) != STATUS_READY )
  3677. +        FDCS->reset = 1;
  3678. +}
  3679. +
  3680. +/* locks the driver */
  3681. +static int lock_fdc(int drive, int interruptible)
  3682. +{
  3683. +    if(!usage_count){
  3684. +        printk("trying to lock fdc while usage count=0\n");
  3685. +        return -1;
  3686. +    }
  3687. +    floppy_grab_irq_and_dma();
  3688. +    cli();
  3689. +    while (fdc_busy && NO_SIGNAL)
  3690. +        interruptible_sleep_on(&fdc_wait);
  3691. +    if(fdc_busy){
  3692. +        sti();
  3693. +        return -EINTR;
  3694. +    }
  3695. +    fdc_busy = 1;
  3696. +    sti();
  3697. +    command_status = FD_COMMAND_NONE;
  3698. +    set_fdc(drive);
  3699. +    reschedule_timeout(drive, "lock fdc", 0);
  3700. +    return 0;
  3701. +}
  3702. +
  3703. +#define LOCK_FDC(drive,interruptible) \
  3704. +if(lock_fdc(drive,interruptible)) return -EINTR;
  3705. +
  3706. +
  3707. +/* unlocks the driver */
  3708. +static inline void unlock_fdc(void)
  3709. +{
  3710. +    raw_cmd = NULL;
  3711. +    if (!fdc_busy)
  3712. +        DPRINT("FDC access conflict!\n");
  3713. +
  3714. +    if ( DEVICE_INTR )
  3715. +        DPRINT1("device interrupt still active at FDC release: %p!\n",
  3716. +            DEVICE_INTR);
  3717. +    command_status = FD_COMMAND_NONE;
  3718. +    del_timer(&fd_timeout);
  3719. +    cont = NULL;
  3720. +    fdc_busy = 0;
  3721. +    floppy_release_irq_and_dma();
  3722. +    wake_up(&fdc_wait);
  3723. +}
  3724. +
  3725. +/* switches the motor off after a given timeout */
  3726. +static void motor_off_callback(unsigned long nr)
  3727. +{
  3728. +    unsigned char mask = ~(0x10 << UNIT(nr));
  3729. +
  3730. +    set_dor( FDC(nr), mask, 0 );
  3731. +}
  3732. +
  3733. +static struct timer_list motor_off_timer[N_DRIVE] = {
  3734. +    { NULL, NULL, 0, 0, motor_off_callback },
  3735. +    { NULL, NULL, 0, 1, motor_off_callback },
  3736. +    { NULL, NULL, 0, 2, motor_off_callback },
  3737. +    { NULL, NULL, 0, 3, motor_off_callback },
  3738. +    { NULL, NULL, 0, 4, motor_off_callback },
  3739. +    { NULL, NULL, 0, 5, motor_off_callback },
  3740. +    { NULL, NULL, 0, 6, motor_off_callback },
  3741. +    { NULL, NULL, 0, 7, motor_off_callback }
  3742. +};
  3743. +
  3744. +/* schedules motor off */
  3745. +static void floppy_off(unsigned int drive)
  3746. +{
  3747. +    unsigned long volatile delta;
  3748. +    register int fdc=FDC(drive);
  3749. +
  3750. +    if( !(FDCS->dor & ( 0x10 << UNIT(drive))))
  3751. +        return;
  3752. +
  3753. +    del_timer(motor_off_timer+drive);
  3754. +
  3755. +    /* make spindle stop in a position which minimizes spinup time
  3756. +     * next time */
  3757. +    if ( UDP->rps ){
  3758. +        delta = jiffies - UDRS->first_read_date + HZ -
  3759. +            UDP->spindown_offset;
  3760. +        delta = (( delta * UDP->rps) % HZ ) / UDP->rps;
  3761. +        motor_off_timer[drive].expires = jiffies + UDP->spindown - delta;
  3762. +    }
  3763. +    add_timer(motor_off_timer+drive);
  3764. +}
  3765. +
  3766. +/*
  3767. + * cycle through all N_DRIVE floppy drives, for disk change testing.
  3768. + * stopping at current drive. This is done before any long operation, to
  3769. + * be sure to have up to date disk change information.
  3770. + */
  3771. +static void scandrives(void)
  3772. +{
  3773. +    int i, drive, saved_drive;
  3774. +
  3775. +    if (DP->select_delay)
  3776. +        return;
  3777. +
  3778. +    saved_drive = current_drive;
  3779. +    for(i=0; i< N_DRIVE; i++){
  3780. +        drive = (saved_drive + i + 1 ) % N_DRIVE;
  3781. +        if ( UDRS->fd_ref == 0 || UDP->select_delay != 0)
  3782. +            continue; /* skip closed drives */
  3783. +        set_fdc(drive);
  3784. +        if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
  3785. +              (0x10 << UNIT(drive))))
  3786. +            /* switch the motor off again, if it was off to
  3787. +             * begin with */
  3788. +            set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
  3789. +    }
  3790. +    set_fdc(saved_drive);
  3791. +}
  3792. +
  3793. +static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
  3794. +
  3795. +/* this function makes sure that the disk stays in the drive during the
  3796. + * transfer */
  3797. +static void fd_watchdog(void)
  3798. +{
  3799. +#ifdef DCL_DEBUG
  3800. +    if (DP->flags & FD_DEBUG){
  3801. +        DPRINT("calling disk change from watchdog\n");
  3802. +    }
  3803. +#endif
  3804. +
  3805. +    if ( disk_change(current_drive) ){
  3806. +        DPRINT("disk removed during i/o\n");
  3807. +        floppy_shutdown();
  3808. +    } else {
  3809. +        del_timer(&fd_timer);
  3810. +        fd_timer.function = (timeout_fn) fd_watchdog;
  3811. +        fd_timer.expires = jiffies + HZ / 10;
  3812. +        add_timer(&fd_timer);
  3813. +    }
  3814. +}
  3815. +
  3816. +static void main_command_interrupt(void)
  3817. +{
  3818. +    del_timer(&fd_timer);
  3819. +    cont->interrupt();
  3820. +}
  3821. +
  3822. +/* waits for a delay (spinup or select) to pass */
  3823. +static int wait_for_completion(int delay, timeout_fn function)
  3824. +{
  3825. +    if ( FDCS->reset ){
  3826. +        reset_fdc(); /* do the reset during sleep to win time
  3827. +                  * if we don't need to sleep, it's a good
  3828. +                  * occasion anyways */
  3829. +        return 1;
  3830. +    }
  3831. +
  3832. +    if ( jiffies < delay ){
  3833. +        del_timer(&fd_timer);
  3834. +        fd_timer.function = function;
  3835. +        fd_timer.expires = delay;
  3836. +        add_timer(&fd_timer);
  3837. +        return 1;
  3838. +    }
  3839. +    return 0;
  3840. +}
  3841. +
  3842. +static int hlt_disabled=0;
  3843. +static void floppy_disable_hlt(void)
  3844. +{
  3845. +    unsigned long flags;
  3846. +    save_flags(flags);
  3847. +    cli();
  3848. +    if(!hlt_disabled){
  3849. +        hlt_disabled=1;
  3850. +#ifdef HAVE_DISABLE_HLT
  3851. +        disable_hlt();
  3852. +#endif
  3853. +    }
  3854. +    restore_flags(flags);
  3855. +}
  3856. +
  3857. +static void floppy_enable_hlt(void)
  3858. +{
  3859. +    unsigned long flags;
  3860. +    save_flags(flags);
  3861. +    cli();
  3862. +    if(hlt_disabled){
  3863. +        hlt_disabled=0;
  3864. +#ifdef HAVE_DISABLE_HLT
  3865. +        enable_hlt();
  3866. +#endif
  3867. +    }
  3868. +    restore_flags(flags);
  3869. +}
  3870. +
  3871. +
  3872. +static void setup_DMA(void)
  3873. +{
  3874. +#ifdef CONFIG_FLOPPY_SANITY
  3875. +    if (raw_cmd->length == 0){
  3876. +        int i;
  3877. +
  3878. +        printk("zero dma transfer size:");
  3879. +        for(i=0; i< raw_cmd->cmd_count; i++)
  3880. +            printk("%x,", raw_cmd->cmd[i]);
  3881. +        printk("\n");
  3882. +        cont->done(0);
  3883. +        FDCS->reset = 1;
  3884. +        return;
  3885. +    }
  3886. +#if 0
  3887. +    /* disabled because of new buffer location for raw cmd */
  3888. +    if ((!CURRENT ||
  3889. +         CURRENT->buffer != raw_cmd->kernel_data ||
  3890. +         raw_cmd->length > 512 * CURRENT->nr_sectors) &&
  3891. +        (raw_cmd->kernel_data < floppy_track_buffer ||
  3892. +         raw_cmd->kernel_data + raw_cmd->length >
  3893. +         floppy_track_buffer + 1024 * max_buffer_sectors)){
  3894. +        printk("bad address. start=%p lg=%lx tb=%p\n",
  3895. +               raw_cmd->kernel_data, raw_cmd->length,
  3896. +               floppy_track_buffer);
  3897. +        if ( CURRENT ){
  3898. +            printk("buffer=%p nr=%lx cnr=%lx\n",
  3899. +                   CURRENT->buffer, CURRENT->nr_sectors,
  3900. +                   CURRENT->current_nr_sectors);
  3901. +        }
  3902. +        cont->done(0);
  3903. +        FDCS->reset=1;
  3904. +        return;
  3905. +    }
  3906. +    if ((long) raw_cmd->kernel_data % 512 ){
  3907. +        printk("non aligned address: %p\n", raw_cmd->kernel_data );
  3908. +        cont->done(0);
  3909. +        FDCS->reset=1;
  3910. +        return;
  3911. +    }
  3912. +    if (CROSS_64KB(raw_cmd->kernel_data, raw_cmd->length)) {
  3913. +        printk("DMA crossing 64-K boundary %p-%p\n",
  3914. +               raw_cmd->kernel_data,
  3915. +               raw_cmd->kernel_data + raw_cmd->length);
  3916. +        cont->done(0);
  3917. +        FDCS->reset=1;
  3918. +        return;
  3919. +    }
  3920. +#endif
  3921. +#endif
  3922. +    cli();
  3923. +    disable_dma(FLOPPY_DMA);
  3924. +    clear_dma_ff(FLOPPY_DMA);
  3925. +    set_dma_mode(FLOPPY_DMA,
  3926. +             (raw_cmd->flags & FD_RAW_READ)?
  3927. +             DMA_MODE_READ : DMA_MODE_WRITE);
  3928. +    set_dma_addr(FLOPPY_DMA, virt_to_bus(raw_cmd->kernel_data));
  3929. +    set_dma_count(FLOPPY_DMA, raw_cmd->length);
  3930. +    enable_dma(FLOPPY_DMA);
  3931. +    sti();
  3932. +    floppy_disable_hlt();
  3933. +}
  3934. +
  3935. +/* sends a command byte to the fdc */
  3936. +static int output_byte(char byte)
  3937. +{
  3938. +    int counter;
  3939. +    unsigned char status=0;
  3940. +    unsigned char rstatus;
  3941. +
  3942. +    if (FDCS->reset)
  3943. +        return -1;
  3944. +    for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
  3945. +        rstatus = inb_p(FD_STATUS);
  3946. +        status = rstatus &(STATUS_READY|STATUS_DIR|STATUS_DMA);
  3947. +        if (!(status & STATUS_READY))
  3948. +            continue;
  3949. +        if (status == STATUS_READY){
  3950. +            outb_p(byte,FD_DATA);
  3951. +
  3952. +#ifdef CONFIG_FLOPPY_SANITY
  3953. +            output_log[output_log_pos].data = byte;
  3954. +            output_log[output_log_pos].status = rstatus;
  3955. +            output_log[output_log_pos].jiffies = jiffies;
  3956. +            output_log_pos = (output_log_pos + 1) % OLOGSIZE;
  3957. +#endif
  3958. +            return 0;
  3959. +        } else
  3960. +            break;
  3961. +    }
  3962. +    FDCS->reset = 1;
  3963. +    if ( !initialising )
  3964. +        DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
  3965. +            byte, status);
  3966. +    return -1;
  3967. +}
  3968. +#define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
  3969. +
  3970. +/* gets the response from the fdc */
  3971. +static int result(void)
  3972. +{
  3973. +    int i = 0, counter, status = 0;
  3974. +
  3975. +    if (FDCS->reset)
  3976. +        return -1;
  3977. +    for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
  3978. +        status = inb_p(FD_STATUS)&
  3979. +            (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
  3980. +        if (!(status & STATUS_READY))
  3981. +            continue;
  3982. +        if (status == STATUS_READY){
  3983. +#ifdef CONFIG_FLOPPY_SANITY
  3984. +            resultjiffies = jiffies;
  3985. +            resultsize = i;
  3986. +#endif
  3987. +            return i;
  3988. +        }
  3989. +        if (status & STATUS_DMA )
  3990. +            break;
  3991. +        if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
  3992. +            if (i >= MAX_REPLIES) {
  3993. +                DPRINT("floppy_stat reply overrun\n");
  3994. +                break;
  3995. +            }
  3996. +            reply_buffer[i++] = inb_p(FD_DATA);
  3997. +        }
  3998. +    }
  3999. +    FDCS->reset = 1;
  4000. +    if ( !initialising )
  4001. +        DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
  4002. +            status, fdc, i);
  4003. +    return -1;
  4004. +}
  4005. +
  4006. +/* Set perpendicular mode as required, based on data rate, if supported.
  4007. + * 82077 Now tested. 1Mbps data rate only possible with 82077-1.
  4008. + */
  4009. +static inline void perpendicular_mode(void)
  4010. +{
  4011. +    unsigned char perp_mode;
  4012. +
  4013. +    if (!floppy)
  4014. +        return;
  4015. +    if (floppy->rate & 0x40){
  4016. +        switch(raw_cmd->rate){
  4017. +            case 0:
  4018. +                perp_mode=2;
  4019. +                break;
  4020. +            case 3:
  4021. +                perp_mode=3;
  4022. +                break;
  4023. +            default:
  4024. +                DPRINT("Invalid data rate for perpendicular mode!\n");
  4025. +                cont->done(0);
  4026. +                FDCS->reset = 1; /* convenient way to return to
  4027. +                          * redo without to much hassle (deep
  4028. +                          * stack et al. */
  4029. +                return;
  4030. +        }
  4031. +    } else
  4032. +        perp_mode = 0;
  4033. +
  4034. +    if ( FDCS->perp_mode == perp_mode )
  4035. +        return;
  4036. +    if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
  4037. +        output_byte(FD_PERPENDICULAR);
  4038. +        output_byte(perp_mode);
  4039. +        FDCS->perp_mode = perp_mode;
  4040. +    } else if (perp_mode) {
  4041. +        DPRINT("perpendicular mode not supported by this FDC.\n");
  4042. +    }
  4043. +} /* perpendicular_mode */
  4044. +
  4045. +#define NOMINAL_DTR 500
  4046. +
  4047. +/* Issue a "SPECIFY" command to set the step rate time, head unload time,
  4048. + * head load time, and DMA disable flag to values needed by floppy.
  4049. + *
  4050. + * The value "dtr" is the data transfer rate in Kbps.  It is needed
  4051. + * to account for the data rate-based scaling done by the 82072 and 82077
  4052. + * FDC types.  This parameter is ignored for other types of FDCs (i.e.
  4053. + * 8272a).
  4054. + *
  4055. + * Note that changing the data transfer rate has a (probably deleterious)
  4056. + * effect on the parameters subject to scaling for 82072/82077 FDCs, so
  4057. + * fdc_specify is called again after each data transfer rate
  4058. + * change.
  4059. + *
  4060. + * srt: 1000 to 16000 in microseconds
  4061. + * hut: 16 to 240 milliseconds
  4062. + * hlt: 2 to 254 milliseconds
  4063. + *
  4064. + * These values are rounded up to the next highest available delay time.
  4065. + */
  4066. +static void fdc_specify(void)
  4067. +{
  4068. +    unsigned char spec1, spec2;
  4069. +    int srt, hlt, hut;
  4070. +    unsigned long dtr = NOMINAL_DTR;
  4071. +    unsigned long scale_dtr = NOMINAL_DTR;
  4072. +    int hlt_max_code = 0x7f;
  4073. +    int hut_max_code = 0xf;
  4074. +
  4075. +    if (FDCS->need_configure && FDCS->has_fifo) {
  4076. +        if ( FDCS->reset )
  4077. +            return;
  4078. +        /* Turn on FIFO for 82077-class FDC (improves performance) */
  4079. +        /* TODO: lock this in via LOCK during initialization */
  4080. +        output_byte(FD_CONFIGURE);
  4081. +        output_byte(0);
  4082. +        output_byte(0x2A);    /* FIFO on, polling off, 10 byte threshold */
  4083. +        output_byte(0);        /* precompensation from track 0 upwards */
  4084. +        if ( FDCS->reset ){
  4085. +            FDCS->has_fifo=0;
  4086. +            return;
  4087. +        }
  4088. +        FDCS->need_configure = 0;
  4089. +        /*DPRINT("FIFO enabled\n");*/
  4090. +    }
  4091. +
  4092. +    switch (raw_cmd->rate & 0x03) {
  4093. +        case 3:
  4094. +            dtr = 1000;
  4095. +            break;
  4096. +        case 1:
  4097. +            dtr = 300;
  4098. +            break;
  4099. +        case 2:
  4100. +            dtr = 250;
  4101. +            break;
  4102. +    }
  4103. +
  4104. +    if (FDCS->version >= FDC_82072) {
  4105. +        scale_dtr = dtr;
  4106. +        hlt_max_code = 0x00; /* 0==256msec*dtr0/dtr (not linear!) */
  4107. +        hut_max_code = 0x0; /* 0==256msec*dtr0/dtr (not linear!) */
  4108. +    }
  4109. +
  4110. +    /* Convert step rate from microseconds to milliseconds and 4 bits */
  4111. +    srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
  4112. +    if (srt > 0xf)
  4113. +        srt = 0xf;
  4114. +    else if (srt < 0)
  4115. +        srt = 0;
  4116. +
  4117. +    hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
  4118. +    if (hlt < 0x01)
  4119. +        hlt = 0x01;
  4120. +    else if (hlt > 0x7f)
  4121. +        hlt = hlt_max_code;
  4122. +
  4123. +    hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
  4124. +    if (hut < 0x1)
  4125. +        hut = 0x1;
  4126. +    else if (hut > 0xf)
  4127. +        hut = hut_max_code;
  4128. +
  4129. +    spec1 = (srt << 4) | hut;
  4130. +    spec2 = (hlt << 1);
  4131. +
  4132. +    /* If these parameters did not change, just return with success */
  4133. +    if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
  4134. +        /* Go ahead and set spec1 and spec2 */
  4135. +        output_byte(FD_SPECIFY);
  4136. +        output_byte(FDCS->spec1 = spec1);
  4137. +        output_byte(FDCS->spec2 = spec2);
  4138. +    }
  4139. +} /* fdc_specify */
  4140. +
  4141. +/* Set the FDC's data transfer rate on behalf of the specified drive.
  4142. + * NOTE: with 82072/82077 FDCs, changing the data rate requires a reissue
  4143. + * of the specify command (i.e. using the fdc_specify function).
  4144. + */
  4145. +static int fdc_dtr(void)
  4146. +{
  4147. +    /* If data rate not already set to desired value, set it. */
  4148. +    if ( raw_cmd->rate == FDCS->dtr)
  4149. +        return 0;
  4150. +
  4151. +    /* Set dtr */
  4152. +    outb_p(raw_cmd->rate, FD_DCR);
  4153. +
  4154. +    /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
  4155. +     * need a stabilization period of several milliseconds to be
  4156. +     * enforced after data rate changes before R/W operations.
  4157. +     * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
  4158. +     */
  4159. +    FDCS->dtr = raw_cmd->rate;
  4160. +    return(wait_for_completion(jiffies+2*HZ/100,
  4161. +                   (timeout_fn) floppy_ready));
  4162. +} /* fdc_dtr */
  4163. +
  4164. +static void tell_sector(void)
  4165. +{
  4166. +    printk(": track %d, head %d, sector %d, size %d",
  4167. +           R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
  4168. +} /* tell_sector */
  4169. +
  4170. +
  4171. +/*
  4172. + * Ok, this error interpreting routine is called after a
  4173. + * DMA read/write has succeeded
  4174. + * or failed, so we check the results, and copy any buffers.
  4175. + * hhb: Added better error reporting.
  4176. + * ak: Made this into a separate routine.
  4177. + */
  4178. +static int interpret_errors(void)
  4179. +{
  4180. +    char bad;
  4181. +int res = get_dma_residue(FLOPPY_DMA);
  4182. +if(res) {printk("\n-- DMA residue (%d)",res); tell_sector(); printk("\n");}
  4183. +    if (inr!=7) {
  4184. +        DPRINT("-- FDC reply error");
  4185. +        FDCS->reset = 1;
  4186. +        return 1;
  4187. +    }
  4188. +
  4189. +    /* check IC to find cause of interrupt */
  4190. +    switch (ST0 & ST0_INTR) {
  4191. +        case 0x40:    /* error occurred during command execution */
  4192. +            bad = 1;
  4193. +            if (ST1 & ST1_WP) {
  4194. +                DPRINT("Drive is write protected\n");
  4195. +                CLEARF(FD_DISK_WRITABLE);
  4196. +                cont->done(0);
  4197. +                bad = 2;
  4198. +            } else if (ST1 & ST1_ND) {
  4199. +                SETF(FD_NEED_TWADDLE);
  4200. +            } else if (ST1 & ST1_OR) {
  4201. +                if (DP->flags & FTD_MSG )
  4202. +                    DPRINT("Over/Underrun - retrying\n");
  4203. +                bad = 0;
  4204. +            }else if(*errors >= DP->max_errors.reporting){
  4205. +                DPRINT("");
  4206. +                if (ST0 & ST0_ECE) {
  4207. +                    printk("Recalibrate failed!");
  4208. +                } else if (ST2 & ST2_CRC) {
  4209. +                    printk("data CRC error");
  4210. +                    tell_sector();
  4211. +                } else if (ST1 & ST1_CRC) {
  4212. +                    printk("CRC error");
  4213. +                    tell_sector();
  4214. +                } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
  4215. +                    if (!probing) {
  4216. +                        printk("sector not found");
  4217. +                        tell_sector();
  4218. +                    } else
  4219. +                        printk("probe failed...");
  4220. +                } else if (ST2 & ST2_WC) {    /* seek error */
  4221. +                    printk("wrong cylinder");
  4222. +                } else if (ST2 & ST2_BC) {    /* cylinder marked as bad */
  4223. +                    printk("bad cylinder");
  4224. +                } else {
  4225. +                    printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
  4226. +                    tell_sector();
  4227. +                }
  4228. +                printk("\n");
  4229. +
  4230. +            }
  4231. +            if ( ST2 & ST2_WC || ST2 & ST2_BC)
  4232. +                /* wrong cylinder => recal */
  4233. +                DRS->track = NEED_2_RECAL;
  4234. +            return bad;
  4235. +        case 0x80: /* invalid command given */
  4236. +            DPRINT("Invalid FDC command given!\n");
  4237. +            cont->done(0);
  4238. +            return 2;
  4239. +        case 0xc0:
  4240. +            DPRINT("Abnormal termination caused by polling\n");
  4241. +            cont->error();
  4242. +            return 2;
  4243. +        default: /* (0) Normal command termination */
  4244. +            return 0;
  4245. +    }
  4246. +}
  4247. +
  4248. +/*
  4249. + * This routine is called when everything should be correctly set up
  4250. + * for the transfer (ie floppy motor is on, the correct floppy is
  4251. + * selected, and the head is sitting on the right track).
  4252. + */
  4253. +static void setup_rw_floppy(void)
  4254. +{
  4255. +    int i,ready_date,r, flags,dflags;
  4256. +    timeout_fn function;
  4257. +
  4258. +    flags = raw_cmd->flags;
  4259. +    if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
  4260. +        flags |= FD_RAW_INTR;
  4261. +
  4262. +    if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
  4263. +        ready_date = DRS->spinup_date + DP->spinup;
  4264. +        /* If spinup will take a long time, rerun scandrives
  4265. +         * again just before spinup completion. Beware that
  4266. +         * after scandrives, we must again wait for selection.
  4267. +         */
  4268. +        if ( ready_date > jiffies + DP->select_delay){
  4269. +            ready_date -= DP->select_delay;
  4270. +            function = (timeout_fn) floppy_start;
  4271. +        } else
  4272. +            function = (timeout_fn) setup_rw_floppy;
  4273. +
  4274. +        /* wait until the floppy is spinning fast enough */
  4275. +        if (wait_for_completion(ready_date,function))
  4276. +            return;
  4277. +    }
  4278. +    dflags = DRS->flags;
  4279. +
  4280. +    if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
  4281. +        setup_DMA();
  4282. +
  4283. +    if ( flags & FD_RAW_INTR )
  4284. +        SET_INTR(main_command_interrupt);
  4285. +
  4286. +    r=0;
  4287. +    for(i=0; i< raw_cmd->cmd_count; i++)
  4288. +        r|=output_byte( raw_cmd->cmd[i] );
  4289. +
  4290. +#ifdef DEBUGT
  4291. +    debugt("rw_command: ");
  4292. +#endif
  4293. +    if ( r ){
  4294. +        reset_fdc();
  4295. +        return;
  4296. +    }
  4297. +
  4298. +    if ( ! ( flags & FD_RAW_INTR )){
  4299. +        inr = result();
  4300. +        cont->interrupt();
  4301. +    } else if ( flags & FD_RAW_NEED_DISK )
  4302. +        fd_watchdog();
  4303. +}
  4304. +
  4305. +static int blind_seek;
  4306. +
  4307. +/*
  4308. + * This is the routine called after every seek (or recalibrate) interrupt
  4309. + * from the floppy controller.
  4310. + */
  4311. +static void seek_interrupt(void)
  4312. +{
  4313. +#ifdef DEBUGT
  4314. +    debugt("seek interrupt:");
  4315. +#endif
  4316. +    if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
  4317. +        DPRINT("seek failed\n");
  4318. +        DRS->track = NEED_2_RECAL;
  4319. +        cont->error();
  4320. +        cont->redo();
  4321. +        return;
  4322. +    }
  4323. +    if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
  4324. +#ifdef DCL_DEBUG
  4325. +        if (DP->flags & FD_DEBUG){
  4326. +            DPRINT("clearing NEWCHANGE flag because of effective seek\n");
  4327. +            DPRINT1("jiffies=%ld\n", jiffies);
  4328. +        }
  4329. +#endif
  4330. +        CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
  4331. +        DRS->select_date = jiffies;
  4332. +    }
  4333. +    DRS->track = ST1;
  4334. +    floppy_ready();
  4335. +}
  4336. +
  4337. +static void check_wp(void)
  4338. +{
  4339. +    if (TESTF(FD_VERIFY)) {
  4340. +        /* check write protection */
  4341. +        output_byte( FD_GETSTATUS );
  4342. +        output_byte( UNIT(current_drive) );
  4343. +        if ( result() != 1 ){
  4344. +            FDCS->reset = 1;
  4345. +            return;
  4346. +        }
  4347. +        CLEARF(FD_VERIFY);
  4348. +        CLEARF(FD_NEED_TWADDLE);
  4349. +#ifdef DCL_DEBUG
  4350. +        if (DP->flags & FD_DEBUG){
  4351. +            DPRINT("checking whether disk is write protected\n");
  4352. +            DPRINT1("wp=%x\n",ST3 & 0x40);
  4353. +        }
  4354. +#endif
  4355. +        if (!( ST3  & 0x40))
  4356. +            SETF(FD_DISK_WRITABLE);
  4357. +        else
  4358. +            CLEARF(FD_DISK_WRITABLE);
  4359. +    }
  4360. +}
  4361. +
  4362. +static void seek_floppy(void)
  4363. +{
  4364. +    int track;
  4365. +
  4366. +    blind_seek=0;
  4367. +
  4368. +#ifdef DCL_DEBUG
  4369. +    if (DP->flags & FD_DEBUG){
  4370. +        DPRINT("calling disk change from seek\n");
  4371. +    }
  4372. +#endif
  4373. +
  4374. +    if (!TESTF(FD_DISK_NEWCHANGE) &&
  4375. +        disk_change(current_drive) &&
  4376. +        (raw_cmd->flags & FD_RAW_NEED_DISK)){
  4377. +        /* the media changed flag should be cleared after the seek.
  4378. +         * If it isn't, this means that there is really no disk in
  4379. +         * the drive.
  4380. +         */
  4381. +        SETF(FD_DISK_CHANGED);
  4382. +        cont->done(0);
  4383. +        cont->redo();
  4384. +        return;
  4385. +    }
  4386. +    if ( DRS->track <= NEED_1_RECAL ){
  4387. +        recalibrate_floppy();
  4388. +        return;
  4389. +    } else if (TESTF(FD_DISK_NEWCHANGE) &&
  4390. +           (raw_cmd->flags & FD_RAW_NEED_DISK) &&
  4391. +           (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
  4392. +        /* we seek to clear the media-changed condition. Does anybody
  4393. +         * know a more elegant way, which works on all drives? */
  4394. +        if ( raw_cmd->track )
  4395. +            track = raw_cmd->track - 1;
  4396. +        else {
  4397. +            if(DP->flags & FD_SILENT_DCL_CLEAR){
  4398. +                set_dor(fdc, ~ (0x10 << UNIT(current_drive)), 0);
  4399. +                blind_seek = 1;
  4400. +                raw_cmd->flags |= FD_RAW_NEED_SEEK;
  4401. +            }
  4402. +            track = 1;
  4403. +        }
  4404. +    } else {
  4405. +        check_wp();
  4406. +        if (raw_cmd->track != DRS->track &&
  4407. +            (raw_cmd->flags & FD_RAW_NEED_SEEK))
  4408. +            track = raw_cmd->track;
  4409. +        else {
  4410. +            setup_rw_floppy();
  4411. +            return;
  4412. +        }
  4413. +    }
  4414. +
  4415. +    SET_INTR(seek_interrupt);
  4416. +    output_byte(FD_SEEK);
  4417. +    output_byte(UNIT(current_drive));
  4418. +    LAST_OUT(track);
  4419. +#ifdef DEBUGT
  4420. +    debugt("seek command:");
  4421. +#endif
  4422. +}
  4423. +
  4424. +static void recal_interrupt(void)
  4425. +{
  4426. +#ifdef DEBUGT
  4427. +    debugt("recal interrupt:");
  4428. +#endif
  4429. +    if (inr !=2 )
  4430. +        FDCS->reset = 1;
  4431. +    else if (ST0 & ST0_ECE) {
  4432. +               switch(DRS->track){
  4433. +                   case NEED_1_RECAL:
  4434. +#ifdef DEBUGT
  4435. +                debugt("recal interrupt need 1 recal:");
  4436. +#endif
  4437. +                /* after a second recalibrate, we still haven't
  4438. +                 * reached track 0. Probably no drive. Raise an
  4439. +                 * error, as failing immediately might upset
  4440. +                 * computers possessed by the Devil :-) */
  4441. +                cont->error();
  4442. +                cont->redo();
  4443. +                return;
  4444. +            case NEED_2_RECAL:
  4445. +#ifdef DEBUGT
  4446. +                debugt("recal interrupt need 2 recal:");
  4447. +#endif
  4448. +                /* If we already did a recalibrate,
  4449. +                 * and we are not at track 0, this
  4450. +                 * means we have moved. (The only way
  4451. +                 * not to move at recalibration is to
  4452. +                 * be already at track 0.) Clear the
  4453. +                 * new change flag */
  4454. +#ifdef DCL_DEBUG
  4455. +                if (DP->flags & FD_DEBUG){
  4456. +                    DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
  4457. +                }
  4458. +#endif
  4459. +
  4460. +                CLEARF(FD_DISK_NEWCHANGE);
  4461. +                DRS->select_date = jiffies;
  4462. +                /* fall through */
  4463. +            default:
  4464. +#ifdef DEBUGT
  4465. +                debugt("recal interrupt default:");
  4466. +#endif
  4467. +                /* Recalibrate moves the head by at
  4468. +                 * most 80 steps. If after one
  4469. +                 * recalibrate we don't have reached
  4470. +                 * track 0, this might mean that we
  4471. +                 * started beyond track 80.  Try
  4472. +                 * again.  */
  4473. +                DRS->track = NEED_1_RECAL;
  4474. +                break;
  4475. +        }
  4476. +    } else
  4477. +        DRS->track = ST1;
  4478. +    floppy_ready();
  4479. +}
  4480. +
  4481. +/*
  4482. + * Unexpected interrupt - Print as much debugging info as we can...
  4483. + * All bets are off...
  4484. + */
  4485. +static void unexpected_floppy_interrupt(void)
  4486. +{
  4487. +    int i;
  4488. +    if ( initialising )
  4489. +        return;
  4490. +    if(print_unex){
  4491. +        DPRINT("unexpected interrupt\n");
  4492. +        if ( inr >= 0 )
  4493. +            for(i=0; i<inr; i++)
  4494. +                printk("%d %x\n", i, reply_buffer[i] );
  4495. +    }
  4496. +    while(1){
  4497. +        output_byte(FD_SENSEI);
  4498. +        inr=result();
  4499. +        if ( inr != 2 )
  4500. +            break;
  4501. +        if(print_unex){
  4502. +            printk("sensei\n");
  4503. +            for(i=0; i<inr; i++)
  4504. +                printk("%d %x\n", i, reply_buffer[i] );
  4505. +        }
  4506. +    }
  4507. +    FDCS->reset = 1;
  4508. +}
  4509. +
  4510. +struct tq_struct floppy_tq =
  4511. +{ 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
  4512. +
  4513. +/* interrupt handler */
  4514. +static void floppy_interrupt(int irq, struct pt_regs *regs)
  4515. +{
  4516. +    void (*handler)(void) = DEVICE_INTR;
  4517. +
  4518. +    lasthandler = handler;
  4519. +    interruptjiffies = jiffies;
  4520. +
  4521. +    floppy_enable_hlt();
  4522. +    CLEAR_INTR;
  4523. +    if ( fdc >= N_FDC || FDCS->address == -1){
  4524. +        /* we don't even know which FDC is the culprit */
  4525. +        printk("DOR0=%x\n", fdc_state[0].dor);
  4526. +        printk("floppy interrupt on bizarre fdc %d\n",fdc);
  4527. +        printk("handler=%p\n", handler);
  4528. +        is_alive("bizarre fdc");
  4529. +        return;
  4530. +    }
  4531. +    inr = result();
  4532. +    if (!handler){
  4533. +        unexpected_floppy_interrupt();
  4534. +        is_alive("unexpected");
  4535. +        return;
  4536. +    }
  4537. +    if ( inr == 0 ){
  4538. +        do {
  4539. +            output_byte(FD_SENSEI);
  4540. +            inr = result();
  4541. +        } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
  4542. +    }
  4543. +    floppy_tq.routine = (void *)(void *) handler;
  4544. +    queue_task_irq(&floppy_tq, &tq_timer);
  4545. +    is_alive("normal interrupt end");
  4546. +}
  4547. +
  4548. +static void recalibrate_floppy(void)
  4549. +{
  4550. +#ifdef DEBUGT
  4551. +    debugt("recalibrate floppy:");
  4552. +#endif
  4553. +    SET_INTR(recal_interrupt);
  4554. +    output_byte(FD_RECALIBRATE);
  4555. +    LAST_OUT(UNIT(current_drive));
  4556. +}
  4557. +
  4558. +/*
  4559. + * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
  4560. + */
  4561. +static void reset_interrupt(void)
  4562. +{
  4563. +#ifdef DEBUGT
  4564. +    debugt("reset interrupt:");
  4565. +#endif
  4566. +    /* fdc_specify();       reprogram fdc */
  4567. +    result();        /* get the status ready for set_fdc */
  4568. +    if ( FDCS->reset )
  4569. +        cont->error(); /* a reset just after a reset. BAD! */
  4570. +    cont->redo();
  4571. +}
  4572. +
  4573. +/*
  4574. + * reset is done by pulling bit 2 of DOR low for a while (old FDC's),
  4575. + * or by setting the self clearing bit 7 of STATUS (newer FDC's)
  4576. + */
  4577. +static void reset_fdc(void)
  4578. +{
  4579. +    SET_INTR(reset_interrupt);
  4580. +    FDCS->reset = 0;
  4581. +    reset_fdc_info(0);
  4582. +    if ( FDCS->version >= FDC_82077 )
  4583. +        outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
  4584. +    else {
  4585. +        arm_set_dor(FDCS->dor & ~0x04);
  4586. +        udelay(FD_RESET_DELAY);
  4587. +        arm_set_dor(FDCS->dor);
  4588. +    }
  4589. +}
  4590. +
  4591. +static void empty(void)
  4592. +{
  4593. +}
  4594. +
  4595. +void show_floppy(void)
  4596. +{
  4597. +    int i;
  4598. +
  4599. +    printk("\n");
  4600. +    printk("floppy driver state\n");
  4601. +    printk("-------------------\n");
  4602. +    printk("now=%ld last interrupt=%d last called handler=%p\n",
  4603. +        jiffies, interruptjiffies, lasthandler);
  4604. +
  4605. +
  4606. +#ifdef CONFIG_FLOPPY_SANITY
  4607. +    printk("timeout_message=%s\n", timeout_message);
  4608. +    printk("last output bytes:\n");
  4609. +    for(i=0; i < OLOGSIZE; i++)
  4610. +        printk("%2x %2x %ld\n",
  4611. +            output_log[(i+output_log_pos) % OLOGSIZE].data,
  4612. +            output_log[(i+output_log_pos) % OLOGSIZE].status,
  4613. +            output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
  4614. +    printk("last result at %d\n", resultjiffies);
  4615. +    printk("last redo_fd_request at %d\n", lastredo);
  4616. +    for(i=0; i<resultsize; i++){
  4617. +        printk("%2x ", reply_buffer[i]);
  4618. +    }
  4619. +    printk("\n");
  4620. +#endif
  4621. +
  4622. +#if 0
  4623. +    for(i=0; i<N_FDC; i++){
  4624. +        if(FDCS->address != -1){
  4625. +            printk("dor %d = %x\n", i, fdc_state[i].dor );
  4626. +            outb_p(fdc_state[i].address+2, fdc_state[i].dor);
  4627. +            udelay(1000); /* maybe we'll catch an interrupt... */
  4628. +        }
  4629. +    }
  4630. +#endif
  4631. +    printk("status=%x\n", inb_p(FD_STATUS));
  4632. +    printk("fdc_busy=%d\n", fdc_busy);
  4633. +    if( DEVICE_INTR)
  4634. +        printk("DEVICE_INTR=%p\n", DEVICE_INTR);
  4635. +    if(floppy_tq.sync)
  4636. +        printk("floppy_tq.routine=%p\n", floppy_tq.routine);
  4637. +    if(fd_timer.prev)
  4638. +        printk("fd_timer.function=%p\n", fd_timer.function);
  4639. +    if(fd_timeout.prev){
  4640. +        printk("timer_table=%p\n",fd_timeout.function);
  4641. +        printk("expires=%ld\n",fd_timeout.expires-jiffies);
  4642. +        printk("now=%ld\n",jiffies);
  4643. +    }
  4644. +    printk("cont=%p\n", cont);
  4645. +    printk("CURRENT=%p\n", CURRENT);
  4646. +    printk("command_status=%d\n", command_status);
  4647. +    printk("\n");
  4648. +}
  4649. +
  4650. +static void floppy_shutdown(void)
  4651. +{
  4652. +    if (!initialising)
  4653. +        show_floppy();
  4654. +    CLEAR_INTR;
  4655. +    floppy_tq.routine = (void *)(void *) empty;
  4656. +    del_timer( &fd_timer);
  4657. +    sti();
  4658. +
  4659. +    floppy_enable_hlt();
  4660. +    disable_dma(FLOPPY_DMA);
  4661. +    /* avoid dma going to a random drive after shutdown */
  4662. +    
  4663. +    if(!initialising)
  4664. +        DPRINT("floppy timeout\n");
  4665. +    FDCS->reset = 1;
  4666. +    if (cont){
  4667. +        cont->done(0);
  4668. +        cont->redo(); /* this will recall reset when needed */
  4669. +    } else {
  4670. +        printk("no cont in shutdown!\n");
  4671. +        process_fd_request();
  4672. +    }
  4673. +    is_alive("floppy shutdown");
  4674. +}
  4675. +/*typedef void (*timeout_fn)(unsigned long);*/
  4676. +
  4677. +/* start motor, check media-changed condition and write protection */
  4678. +static int start_motor( void (*function)(void)  )
  4679. +{
  4680. +    int mask, data;
  4681. +
  4682. +    mask = 0xfc;
  4683. +    data = UNIT(current_drive);
  4684. +    if (!(raw_cmd->flags & FD_RAW_NO_MOTOR)){
  4685. +        if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
  4686. +            set_debugt();
  4687. +            /* no read since this drive is running */
  4688. +            DRS->first_read_date = 0;
  4689. +            /* note motor start time if motor is not yet running */
  4690. +            DRS->spinup_date = jiffies;
  4691. +            data |= (0x10 << UNIT(current_drive));
  4692. +        }
  4693. +    } else
  4694. +        if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
  4695. +            mask &= ~(0x10 << UNIT(current_drive));
  4696. +
  4697. +    /* starts motor and selects floppy */
  4698. +    del_timer(motor_off_timer + current_drive);
  4699. +    set_dor( fdc, mask, data);
  4700. +
  4701. +    /* wait_for_completion also schedules reset if needed. */
  4702. +    return(wait_for_completion(DRS->select_date+DP->select_delay,
  4703. +                   (timeout_fn) function));
  4704. +}
  4705. +
  4706. +static void floppy_ready(void)
  4707. +{
  4708. +    CHECK_RESET;
  4709. +    if(start_motor(floppy_ready)) return;
  4710. +    if(fdc_dtr()) return;
  4711. +
  4712. +#ifdef DCL_DEBUG
  4713. +    if (DP->flags & FD_DEBUG){
  4714. +        DPRINT("calling disk change from floppy_ready\n");
  4715. +    }
  4716. +#endif
  4717. +
  4718. +    if(!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
  4719. +       disk_change(current_drive) &&
  4720. +       !DP->select_delay)
  4721. +           twaddle(); /* this clears the dcl on certain drive/controller
  4722. +                   * combinations */
  4723. +
  4724. +    if ( raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
  4725. +        perpendicular_mode();
  4726. +        fdc_specify(); /* must be done here because of hut, hlt ... */
  4727. +        seek_floppy();
  4728. +    } else
  4729. +        setup_rw_floppy();
  4730. +}
  4731. +
  4732. +static void floppy_start(void)
  4733. +{
  4734. +    reschedule_timeout(CURRENTD, "floppy start", 0);
  4735. +
  4736. +    scandrives();
  4737. +#ifdef DCL_DEBUG
  4738. +    if (DP->flags & FD_DEBUG){
  4739. +        DPRINT("setting NEWCHANGE in floppy_start\n");
  4740. +    }
  4741. +#endif
  4742. +    SETF(FD_DISK_NEWCHANGE);
  4743. +    floppy_ready();
  4744. +}
  4745. +
  4746. +/*
  4747. + * ========================================================================
  4748. + * here ends the bottom half. Exported routines are:
  4749. + * floppy_start, floppy_off, floppy_ready, lock_fdc, unlock_fdc, set_fdc,
  4750. + * start_motor, reset_fdc, reset_fdc_info, interpret_errors.
  4751. + * Initialisation also uses output_byte, result, set_dor, floppy_interrupt
  4752. + * and set_dor.
  4753. + * ========================================================================
  4754. + */
  4755. +/*
  4756. + * General purpose continuations.
  4757. + * ==============================
  4758. + */
  4759. +
  4760. +static void do_wakeup(void)
  4761. +{
  4762. +    reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
  4763. +    cont = 0;
  4764. +    command_status += 2;
  4765. +    wake_up(&command_done);
  4766. +}
  4767. +
  4768. +static struct cont_t wakeup_cont={
  4769. +    empty,
  4770. +    do_wakeup,
  4771. +    empty,
  4772. +    (done_f)empty
  4773. +};
  4774. +
  4775. +static int wait_til_done( void (*handler)(void ), int interruptible )
  4776. +{
  4777. +    int ret;
  4778. +
  4779. +    floppy_tq.routine = (void *)(void *) handler;
  4780. +    queue_task(&floppy_tq, &tq_timer);
  4781. +
  4782. +    cli();
  4783. +    while(command_status < 2 && NO_SIGNAL){
  4784. +        is_alive("wait_til_done");
  4785. +        if (interruptible)
  4786. +            interruptible_sleep_on(&command_done);
  4787. +        else
  4788. +            sleep_on(&command_done);
  4789. +    }
  4790. +    if(command_status < 2){
  4791. +        floppy_shutdown();
  4792. +        sti();
  4793. +        process_fd_request();
  4794. +        return -EINTR;
  4795. +    }
  4796. +    sti();
  4797. +
  4798. +    if ( FDCS->reset )
  4799. +        command_status = FD_COMMAND_ERROR;
  4800. +    if ( command_status == FD_COMMAND_OKAY )
  4801. +        ret=0;
  4802. +    else
  4803. +        ret=-EIO;
  4804. +    command_status = FD_COMMAND_NONE;
  4805. +    return ret;
  4806. +}
  4807. +
  4808. +static void generic_done(int result)
  4809. +{
  4810. +    command_status = result;
  4811. +    cont = &wakeup_cont;
  4812. +}
  4813. +
  4814. +static void generic_success(void)
  4815. +{
  4816. +    cont->done(1);
  4817. +}
  4818. +
  4819. +static void generic_failure(void)
  4820. +{
  4821. +    cont->done(0);
  4822. +}
  4823. +
  4824. +static void success_and_wakeup(void)
  4825. +{
  4826. +    generic_success();
  4827. +    cont->redo();
  4828. +}
  4829. +
  4830. +
  4831. +/*
  4832. + * formatting and rw support.
  4833. + * ==========================
  4834. + */
  4835. +
  4836. +static int next_valid_format(void)
  4837. +{
  4838. +    int probed_format;
  4839. +
  4840. +    probed_format = DRS->probed_format;
  4841. +    while(1){
  4842. +        if ( probed_format >= 8 ||
  4843. +            ! DP->autodetect[probed_format] ){
  4844. +            DRS->probed_format = 0;
  4845. +            return 1;
  4846. +        }
  4847. +        if ( floppy_type[DP->autodetect[probed_format]].sect ){
  4848. +            DRS->probed_format = probed_format;
  4849. +            return 0;
  4850. +        }
  4851. +        probed_format++;
  4852. +    }
  4853. +}
  4854. +
  4855. +static void bad_flp_intr(void)
  4856. +{
  4857. +    if ( probing ){
  4858. +        DRS->probed_format++;
  4859. +        if ( !next_valid_format())
  4860. +            return;
  4861. +    }
  4862. +    (*errors)++;
  4863. +    if (*errors > DRWE->badness)
  4864. +            DRWE->badness = *errors;
  4865. +    if (*errors > DP->max_errors.abort)
  4866. +        cont->done(0);
  4867. +    if (*errors > DP->max_errors.reset)
  4868. +        FDCS->reset = 1;
  4869. +    else if (*errors > DP->max_errors.recal)
  4870. +        DRS->track = NEED_2_RECAL;
  4871. +}
  4872. +
  4873. +static void set_floppy(kdev_t device)
  4874. +{
  4875. +    if (TYPE(device))
  4876. +        floppy = TYPE(device) + floppy_type;
  4877. +    else
  4878. +        floppy = current_type[ DRIVE(device) ];
  4879. +}
  4880. +
  4881. +/*
  4882. + * formatting and support.
  4883. + * =======================
  4884. + */
  4885. +static void format_interrupt(void)
  4886. +{
  4887. +    switch (interpret_errors()){
  4888. +        case 1:
  4889. +            cont->error();
  4890. +        case 2:
  4891. +            break;
  4892. +        case 0:
  4893. +            cont->done(1);
  4894. +    }
  4895. +    cont->redo();
  4896. +}
  4897. +
  4898. +#define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
  4899. +#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
  4900. +#define CT(x) ( (x) | 0x40 )
  4901. +static void setup_format_params(int track)
  4902. +{
  4903. +    struct fparm {
  4904. +        unsigned char track,head,sect,size;
  4905. +    } *here = (struct fparm *)floppy_track_buffer;
  4906. +    int il,n;
  4907. +    int count,head_shift,track_shift;
  4908. +
  4909. +    raw_cmd = &default_raw_cmd;
  4910. +    raw_cmd->track = track;
  4911. +    
  4912. +    raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
  4913. +        /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
  4914. +    raw_cmd->rate = floppy->rate & 0x3;
  4915. +    raw_cmd->cmd_count = NR_F;
  4916. +    COMMAND = FM_MODE(floppy,FD_FORMAT);
  4917. +    DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
  4918. +    F_SIZECODE = FD_SIZECODE(floppy);
  4919. +    F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
  4920. +    F_GAP = floppy->fmt_gap;
  4921. +    F_FILL = FD_FILL_BYTE;
  4922. +
  4923. +    raw_cmd->kernel_data = floppy_track_buffer;
  4924. +    raw_cmd->length = 4 * F_SECT_PER_TRACK;
  4925. +
  4926. +    /* allow for about 30ms for data transport per track */
  4927. +    head_shift  = (F_SECT_PER_TRACK + 5) / 6;
  4928. +
  4929. +    /* a ``cylinder'' is two tracks plus a little stepping time */
  4930. +    track_shift = 2 * head_shift + 3;
  4931. +
  4932. +    /* position of logical sector 1 on this track */
  4933. +    n = (track_shift * format_req.track + head_shift * format_req.head )
  4934. +        % F_SECT_PER_TRACK;
  4935. +
  4936. +    /* determine interleave */
  4937. +    il = 1;
  4938. +    if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
  4939. +        il++;
  4940. +
  4941. +    /* initialize field */
  4942. +    for (count = 0; count < F_SECT_PER_TRACK; ++count) {
  4943. +        here[count].track = format_req.track;
  4944. +        here[count].head = format_req.head;
  4945. +        here[count].sect = 0;
  4946. +        here[count].size = F_SIZECODE;
  4947. +    }
  4948. +    /* place logical sectors */
  4949. +    for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
  4950. +        here[n].sect = count;
  4951. +        n = (n+il) % F_SECT_PER_TRACK;
  4952. +        if (here[n].sect) { /* sector busy, find next free sector */
  4953. +            ++n;
  4954. +            if (n>= F_SECT_PER_TRACK) {
  4955. +                n-=F_SECT_PER_TRACK;
  4956. +                while (here[n].sect) ++n;
  4957. +            }
  4958. +        }
  4959. +    }
  4960. +}
  4961. +
  4962. +static void redo_format(void)
  4963. +{
  4964. +    buffer_track = -1;
  4965. +    setup_format_params(format_req.track << STRETCH(floppy));
  4966. +    floppy_start();
  4967. +#ifdef DEBUGT
  4968. +    debugt("queue format request");
  4969. +#endif
  4970. +}
  4971. +
  4972. +static struct cont_t format_cont={
  4973. +    format_interrupt,
  4974. +    redo_format,
  4975. +    bad_flp_intr,
  4976. +    generic_done };
  4977. +
  4978. +static int do_format(kdev_t device, struct format_descr *tmp_format_req)
  4979. +{
  4980. +    int ret;
  4981. +    int drive=DRIVE(device);
  4982. +
  4983. +    LOCK_FDC(drive,1);
  4984. +    set_floppy(device);
  4985. +    if (!floppy ||
  4986. +        floppy->track > DP->tracks ||
  4987. +        tmp_format_req->track >= floppy->track ||
  4988. +        tmp_format_req->head >= floppy->head ||
  4989. +        (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
  4990. +        !floppy->fmt_gap) {
  4991. +        process_fd_request();
  4992. +        return -EINVAL;
  4993. +    }
  4994. +    format_req = *tmp_format_req;
  4995. +    format_errors = 0;
  4996. +    cont = &format_cont;
  4997. +    errors = &format_errors;
  4998. +    IWAIT(redo_format);
  4999. +    process_fd_request();
  5000. +    return ret;
  5001. +}
  5002. +
  5003. +/*
  5004. + * Buffer read/write and support
  5005. + * =============================
  5006. + */
  5007. +
  5008. +/* new request_done. Can handle physical sectors which are smaller than a
  5009. + * logical buffer */
  5010. +static void request_done(int uptodate)
  5011. +{
  5012. +    int block;
  5013. +
  5014. +    probing = 0;
  5015. +    reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
  5016. +
  5017. +    if (!CURRENT){
  5018. +        DPRINT("request list destroyed in floppy request done\n");
  5019. +        return;
  5020. +    }
  5021. +    if (uptodate){
  5022. +        /* maintain values for invalidation on geometry
  5023. +         * change */
  5024. +        block = current_count_sectors + CURRENT->sector;
  5025. +        if (block > DRS->maxblock)
  5026. +            DRS->maxblock=block;
  5027. +        if ( block > floppy->sect)
  5028. +            DRS->maxtrack = 1;
  5029. +
  5030. +        /* unlock chained buffers */
  5031. +        while (current_count_sectors && CURRENT &&
  5032. +               current_count_sectors >= CURRENT->current_nr_sectors ){
  5033. +            current_count_sectors -= CURRENT->current_nr_sectors;
  5034. +            CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
  5035. +            CURRENT->sector += CURRENT->current_nr_sectors;
  5036. +            end_request(1);
  5037. +        }
  5038. +        if ( current_count_sectors && CURRENT){
  5039. +            /* "unlock" last subsector */
  5040. +            CURRENT->buffer += current_count_sectors <<9;
  5041. +            CURRENT->current_nr_sectors -= current_count_sectors;
  5042. +            CURRENT->nr_sectors -= current_count_sectors;
  5043. +            CURRENT->sector += current_count_sectors;
  5044. +            return;
  5045. +        }
  5046. +
  5047. +        if ( current_count_sectors && ! CURRENT )
  5048. +            DPRINT("request list destroyed in floppy request done\n");
  5049. +
  5050. +    } else {
  5051. +        if(CURRENT->cmd == WRITE) {
  5052. +            /* record write error information */
  5053. +            DRWE->write_errors++;
  5054. +            if(DRWE->write_errors == 1) {
  5055. +                DRWE->first_error_sector = CURRENT->sector;
  5056. +                DRWE->first_error_generation = DRS->generation;
  5057. +            }
  5058. +            DRWE->last_error_sector = CURRENT->sector;
  5059. +            DRWE->last_error_generation = DRS->generation;
  5060. +        }
  5061. +        end_request(0);
  5062. +    }
  5063. +}
  5064. +
  5065. +/* Interrupt handler evaluating the result of the r/w operation */
  5066. +static void rw_interrupt(void)
  5067. +{
  5068. +    int nr_sectors, ssize;
  5069. +
  5070. +    if ( ! DRS->first_read_date )
  5071. +        DRS->first_read_date = jiffies;
  5072. +
  5073. +    nr_sectors = 0;
  5074. +    CODE2SIZE;
  5075. +    nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
  5076. +        floppy->sect + ((R_SECTOR-SECTOR) <<  SIZECODE >> 2) -
  5077. +        (sector_t % floppy->sect) % ssize;
  5078. +
  5079. +#ifdef CONFIG_FLOPPY_SANITY
  5080. +    if ( nr_sectors > current_count_sectors + ssize -
  5081. +         (current_count_sectors + sector_t) % ssize +
  5082. +         sector_t % ssize){
  5083. +        DPRINT2("long rw: %x instead of %lx\n",
  5084. +            nr_sectors, current_count_sectors);
  5085. +        printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
  5086. +        printk("rh=%d h=%d\n", R_HEAD, HEAD);
  5087. +        printk("rt=%d t=%d\n", R_TRACK, TRACK);
  5088. +        printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
  5089. +               sector_t, ssize);
  5090. +    }
  5091. +#endif
  5092. +    if ( nr_sectors < 0 )
  5093. +        nr_sectors = 0;
  5094. +    if ( nr_sectors < current_count_sectors )
  5095. +        current_count_sectors = nr_sectors;
  5096. +
  5097. +    switch (interpret_errors()){
  5098. +        case 2:
  5099. +            cont->redo();
  5100. +            return;
  5101. +        case 1:
  5102. +            if (  !current_count_sectors){
  5103. +                cont->error();
  5104. +                cont->redo();
  5105. +                return;
  5106. +            }
  5107. +            break;
  5108. +        case 0:
  5109. +            if (  !current_count_sectors){
  5110. +                cont->redo();
  5111. +                return;
  5112. +            }
  5113. +            current_type[current_drive] = floppy;
  5114. +            floppy_sizes[TOMINOR(current_drive) ]= floppy->size>>1;
  5115. +            break;
  5116. +    }
  5117. +
  5118. +    if (probing) {
  5119. +        if (DP->flags & FTD_MSG)
  5120. +            DPRINT2("Auto-detected floppy type %s in fd%d\n",
  5121. +                floppy->name,current_drive);
  5122. +        current_type[current_drive] = floppy;
  5123. +        floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1;
  5124. +        probing = 0;
  5125. +    }
  5126. +
  5127. +    if ( CT(COMMAND) != FD_READ ||
  5128. +         raw_cmd->kernel_data == CURRENT->buffer ){
  5129. +        /* transfer directly from buffer */
  5130. +        cont->done(1);
  5131. +    } else if ( CT(COMMAND) == FD_READ){
  5132. +        buffer_track = raw_cmd->track;
  5133. +        buffer_drive = current_drive;
  5134. +        if ( nr_sectors + sector_t > buffer_max )
  5135. +            buffer_max = nr_sectors + sector_t;
  5136. +    }
  5137. +    cont->redo();
  5138. +}
  5139. +
  5140. +/* Compute maximal contiguous buffer size. */
  5141. +static int buffer_chain_size(void)
  5142. +{
  5143. +    struct buffer_head *bh;
  5144. +    int size;
  5145. +    char *base;
  5146. +
  5147. +    base = CURRENT->buffer;
  5148. +    size = CURRENT->current_nr_sectors << 9;
  5149. +    bh = CURRENT->bh;
  5150. +
  5151. +    if(bh){
  5152. +        bh = bh->b_reqnext;
  5153. +        while ( bh && bh->b_data == base + size ){
  5154. +            size += bh->b_size;
  5155. +            bh = bh->b_reqnext;
  5156. +        }
  5157. +    }
  5158. +    return size >> 9;
  5159. +}
  5160. +
  5161. +/* Compute the maximal transfer size */
  5162. +static int transfer_size(int ssize, int max_sector, int max_size)
  5163. +{
  5164. +    if ( max_sector > sector_t + max_size)
  5165. +        max_sector = sector_t + max_size;
  5166. +
  5167. +    /* alignment */
  5168. +    max_sector -= (max_sector % floppy->sect ) % ssize;
  5169. +
  5170. +    /* transfer size, beginning not aligned */
  5171. +    current_count_sectors = max_sector - sector_t ;
  5172. +
  5173. +    return max_sector;
  5174. +}
  5175. +
  5176. +/*
  5177. + * Move data from/to the track buffer to/from the buffer cache.
  5178. + */
  5179. +static void copy_buffer(int ssize, int max_sector, int max_sector_2)
  5180. +{
  5181. +    int remaining; /* number of transferred 512-byte sectors */
  5182. +    struct buffer_head *bh;
  5183. +    char *buffer, *dma_buffer;
  5184. +    int size;
  5185. +
  5186. +    if ( max_sector > max_sector_2 )
  5187. +        max_sector = max_sector_2;
  5188. +
  5189. +    max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
  5190. +
  5191. +    if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
  5192. +        buffer_max > sector_t + CURRENT->nr_sectors){
  5193. +        current_count_sectors = buffer_max - sector_t;
  5194. +        if ( current_count_sectors > CURRENT->nr_sectors )
  5195. +            current_count_sectors = CURRENT->nr_sectors;
  5196. +    }
  5197. +    remaining = current_count_sectors << 9;
  5198. +#ifdef CONFIG_FLOPPY_SANITY
  5199. +    if ((remaining >> 9) > CURRENT->nr_sectors  &&
  5200. +        CT(COMMAND) == FD_WRITE ){
  5201. +        DPRINT("in copy buffer\n");
  5202. +        printk("current_count_sectors=%ld\n", current_count_sectors);
  5203. +        printk("remaining=%d\n", remaining >> 9);
  5204. +        printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
  5205. +        printk("CURRENT->current_nr_sectors=%ld\n",
  5206. +               CURRENT->current_nr_sectors);
  5207. +        printk("max_sector=%d\n", max_sector);
  5208. +        printk("ssize=%d\n", ssize);
  5209. +    }
  5210. +#endif
  5211. +
  5212. +    if ( max_sector > buffer_max )
  5213. +        buffer_max = max_sector;
  5214. +
  5215. +    dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
  5216. +
  5217. +    bh = CURRENT->bh;
  5218. +    size = CURRENT->current_nr_sectors << 9;
  5219. +    buffer = CURRENT->buffer;
  5220. +
  5221. +    while ( remaining > 0){
  5222. +        if ( size > remaining )
  5223. +            size = remaining;
  5224. +#ifdef CONFIG_FLOPPY_SANITY
  5225. +        if (dma_buffer + size >
  5226. +            floppy_track_buffer + (max_buffer_sectors << 10) ||
  5227. +            dma_buffer < floppy_track_buffer ){
  5228. +            DPRINT1("buffer overrun in copy buffer %d\n",
  5229. +                (int) ((floppy_track_buffer - dma_buffer) >>9));
  5230. +            printk("sector_t=%d buffer_min=%d\n",
  5231. +                   sector_t, buffer_min);
  5232. +            printk("current_count_sectors=%ld\n",
  5233. +                   current_count_sectors);
  5234. +            if ( CT(COMMAND) == FD_READ )
  5235. +                printk("read\n");
  5236. +            if ( CT(COMMAND) == FD_READ )
  5237. +                printk("write\n");
  5238. +            break;
  5239. +        }
  5240. +        if ( ((unsigned long)buffer) % 512 )
  5241. +            DPRINT1("%p buffer not aligned\n", buffer);
  5242. +#endif
  5243. +        if ( CT(COMMAND) == FD_READ )
  5244. +            memcpy( buffer, dma_buffer, size);
  5245. +        else
  5246. +            memcpy( dma_buffer, buffer, size);
  5247. +        remaining -= size;
  5248. +        if ( !remaining)
  5249. +            break;
  5250. +
  5251. +        dma_buffer += size;
  5252. +        bh = bh->b_reqnext;
  5253. +#ifdef CONFIG_FLOPPY_SANITY
  5254. +        if ( !bh){
  5255. +            DPRINT("bh=null in copy buffer after copy\n");
  5256. +            break;
  5257. +        }
  5258. +#endif
  5259. +        size = bh->b_size;
  5260. +        buffer = bh->b_data;
  5261. +    }
  5262. +#ifdef CONFIG_FLOPPY_SANITY
  5263. +    if ( remaining ){
  5264. +        if ( remaining > 0 )
  5265. +            max_sector -= remaining >> 9;
  5266. +        DPRINT1("weirdness: remaining %d\n", remaining>>9);
  5267. +    }
  5268. +#endif
  5269. +}
  5270. +
  5271. +/*
  5272. + * Formulate a read/write request.
  5273. + * this routine decides where to load the data (directly to buffer, or to
  5274. + * tmp floppy area), how much data to load (the size of the buffer, the whole
  5275. + * track, or a single sector)
  5276. + * All floppy_track_buffer handling goes in here. If we ever add track buffer
  5277. + * allocation on the fly, it should be done here. No other part should need
  5278. + * modification.
  5279. + */
  5280. +
  5281. +static int make_raw_rw_request(void)
  5282. +{
  5283. +    int aligned_sector_t;
  5284. +    int max_sector, max_size, tracksize, ssize;
  5285. +
  5286. +    set_fdc(DRIVE(CURRENT->rq_dev));
  5287. +
  5288. +    raw_cmd = &default_raw_cmd;
  5289. +    raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
  5290. +        FD_RAW_NEED_SEEK;
  5291. +    raw_cmd->cmd_count = NR_RW;
  5292. +    if (CURRENT->cmd == READ){
  5293. +        raw_cmd->flags |= FD_RAW_READ;
  5294. +        COMMAND = FM_MODE(floppy,FD_READ);
  5295. +    } else if (CURRENT->cmd == WRITE){
  5296. +        raw_cmd->flags |= FD_RAW_WRITE;
  5297. +        COMMAND = FM_MODE(floppy,FD_WRITE);
  5298. +    } else {
  5299. +        DPRINT("make_raw_rw_request: unknown command\n");
  5300. +        return 0;
  5301. +    }
  5302. +
  5303. +    max_sector = floppy->sect * floppy->head;
  5304. +    
  5305. +    TRACK = CURRENT->sector / max_sector;
  5306. +    sector_t = CURRENT->sector % max_sector;
  5307. +    if ( floppy->track && TRACK >= floppy->track )
  5308. +        return 0;
  5309. +    HEAD = sector_t / floppy->sect;
  5310. +
  5311. +    if (((floppy->stretch & FD_SWAPSIDES) || TESTF( FD_NEED_TWADDLE)) &&
  5312. +        sector_t < floppy->sect )
  5313. +        max_sector = floppy->sect;
  5314. +
  5315. +    /* 2M disks have phantom sectors on the first track */
  5316. +    if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
  5317. +        max_sector = 2 * floppy->sect / 3;
  5318. +        if (sector_t >= max_sector){
  5319. +            current_count_sectors =  (floppy->sect - sector_t);
  5320. +            if ( current_count_sectors > CURRENT->nr_sectors )
  5321. +                current_count_sectors = CURRENT->nr_sectors;
  5322. +            return 1;
  5323. +        }
  5324. +        SIZECODE = 2;
  5325. +    } else
  5326. +        SIZECODE = FD_SIZECODE(floppy);
  5327. +    raw_cmd->rate = floppy->rate & 3;
  5328. +    if ((floppy->rate & FD_2M) &&
  5329. +        (TRACK || HEAD ) &&
  5330. +        raw_cmd->rate == 2)
  5331. +        raw_cmd->rate = 1;
  5332. +
  5333. +    if ( SIZECODE )
  5334. +        SIZECODE2 = 0xff;
  5335. +    else
  5336. +        SIZECODE2 = 0x80;
  5337. +    raw_cmd->track = TRACK << STRETCH(floppy);
  5338. +    DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,HEAD);
  5339. +    GAP = floppy->gap;
  5340. +    CODE2SIZE;
  5341. +    SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
  5342. +    SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
  5343. +    tracksize = floppy->sect - floppy->sect % ssize;
  5344. +    if ( tracksize < floppy->sect ){
  5345. +        SECT_PER_TRACK ++;
  5346. +        if (  tracksize <= sector_t % floppy->sect)
  5347. +            SECTOR--;
  5348. +        while ( tracksize <= sector_t % floppy->sect){
  5349. +            while( tracksize + ssize > floppy->sect ){
  5350. +                SIZECODE--;
  5351. +                ssize >>= 1;
  5352. +            }
  5353. +            SECTOR++; SECT_PER_TRACK ++;
  5354. +            tracksize += ssize;
  5355. +        }
  5356. +        max_sector = HEAD * floppy->sect + tracksize;
  5357. +    } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
  5358. +        max_sector = floppy->sect;
  5359. +
  5360. +    aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
  5361. +    max_size = CURRENT->nr_sectors;
  5362. +    if ((raw_cmd->track == buffer_track) && (current_drive == buffer_drive) &&
  5363. +        (sector_t >= buffer_min) && (sector_t < buffer_max)) {
  5364. +        /* data already in track buffer */
  5365. +        if (CT(COMMAND) == FD_READ) {
  5366. +            copy_buffer(1, max_sector, buffer_max);
  5367. +            return 1;
  5368. +        }
  5369. +    } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
  5370. +        if (CT(COMMAND) == FD_WRITE){
  5371. +            if(sector_t + CURRENT->nr_sectors > ssize &&
  5372. +               sector_t + CURRENT->nr_sectors < ssize + ssize)
  5373. +                max_size = ssize + ssize;
  5374. +            else
  5375. +                max_size = ssize;
  5376. +        }
  5377. +        raw_cmd->flags &= ~FD_RAW_WRITE;
  5378. +        raw_cmd->flags |= FD_RAW_READ;
  5379. +        COMMAND = FM_MODE(floppy,FD_READ);
  5380. +    } else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS ) {
  5381. +        int direct, indirect;
  5382. +
  5383. +        indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
  5384. +            sector_t;
  5385. +
  5386. +        max_size = buffer_chain_size();
  5387. +#if 0
  5388. +        if ( max_size > ( MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9)
  5389. +            max_size=(MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9;
  5390. +        /* 64 kb boundaries */
  5391. +        if (CROSS_64KB(CURRENT->buffer, max_size << 9))
  5392. +            max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
  5393. +#endif
  5394. +        direct = transfer_size(ssize,max_sector,max_size) - sector_t;
  5395. +        /*
  5396. +         *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *