root/drivers/block/floppy.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __get_order
  2. dma_mem_alloc
  3. set_debugt
  4. debugt
  5. is_alive
  6. reschedule_timeout
  7. disk_change
  8. is_selected
  9. set_dor
  10. twaddle
  11. reset_fdc_info
  12. set_fdc
  13. lock_fdc
  14. unlock_fdc
  15. motor_off_callback
  16. floppy_off
  17. scandrives
  18. fd_watchdog
  19. main_command_interrupt
  20. wait_for_completion
  21. floppy_disable_hlt
  22. floppy_enable_hlt
  23. setup_DMA
  24. output_byte
  25. result
  26. perpendicular_mode
  27. fdc_specify
  28. fdc_dtr
  29. tell_sector
  30. interpret_errors
  31. setup_rw_floppy
  32. seek_interrupt
  33. check_wp
  34. seek_floppy
  35. recal_interrupt
  36. unexpected_floppy_interrupt
  37. floppy_interrupt
  38. recalibrate_floppy
  39. reset_interrupt
  40. reset_fdc
  41. empty
  42. show_floppy
  43. floppy_shutdown
  44. start_motor
  45. floppy_ready
  46. floppy_start
  47. do_wakeup
  48. wait_til_done
  49. generic_done
  50. generic_success
  51. generic_failure
  52. success_and_wakeup
  53. failure_and_wakeup
  54. next_valid_format
  55. bad_flp_intr
  56. set_floppy
  57. format_interrupt
  58. setup_format_params
  59. redo_format
  60. do_format
  61. request_done
  62. rw_interrupt
  63. buffer_chain_size
  64. transfer_size
  65. copy_buffer
  66. make_raw_rw_request
  67. redo_fd_request
  68. process_fd_request
  69. do_fd_request
  70. poll_drive
  71. reset_intr
  72. user_reset_fdc
  73. fd_copyout
  74. drive_name
  75. raw_cmd_ioctl
  76. invalidate_drive
  77. fd_ioctl
  78. config_types
  79. floppy_read
  80. floppy_write
  81. floppy_release
  82. floppy_open
  83. check_floppy_change
  84. floppy_revalidate
  85. get_fdc_version
  86. floppy_invert_dcl
  87. daring
  88. allow_drives
  89. fdc2_adr
  90. unex
  91. set_cmos
  92. floppy_setup
  93. floppy_init
  94. floppy_grab_irq_and_dma
  95. floppy_release_irq_and_dma
  96. mod_setup
  97. init_module
  98. cleanup_module

   1 /*
   2  *  linux/kernel/floppy.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *  Copyright (C) 1993, 1994  Alain Knaff
   6  */
   7 /*
   8  * 02.12.91 - Changed to static variables to indicate need for reset
   9  * and recalibrate. This makes some things easier (output_byte reset
  10  * checking etc), and means less interrupt jumping in case of errors,
  11  * so the code is hopefully easier to understand.
  12  */
  13 
  14 /*
  15  * This file is certainly a mess. I've tried my best to get it working,
  16  * but I don't like programming floppies, and I have only one anyway.
  17  * Urgel. I should check for more errors, and do more graceful error
  18  * recovery. Seems there are problems with several drives. I've tried to
  19  * correct them. No promises.
  20  */
  21 
  22 /*
  23  * As with hd.c, all routines within this file can (and will) be called
  24  * by interrupts, so extreme caution is needed. A hardware interrupt
  25  * handler may not sleep, or a kernel panic will happen. Thus I cannot
  26  * call "floppy-on" directly, but have to set a special timer interrupt
  27  * etc.
  28  */
  29 
  30 /*
  31  * 28.02.92 - made track-buffering routines, based on the routines written
  32  * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus.
  33  */
  34 
  35 /*
  36  * Automatic floppy-detection and formatting written by Werner Almesberger
  37  * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with
  38  * the floppy-change signal detection.
  39  */
  40 
  41 /*
  42  * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
  43  * FDC data overrun bug, added some preliminary stuff for vertical
  44  * recording support.
  45  *
  46  * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
  47  *
  48  * TODO: Errors are still not counted properly.
  49  */
  50 
  51 /* 1992/9/20
  52  * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl)
  53  * modelled after the freeware MS/DOS program fdformat/88 V1.8 by
  54  * Christoph H. Hochst\"atter.
  55  * I have fixed the shift values to the ones I always use. Maybe a new
  56  * ioctl() should be created to be able to modify them.
  57  * There is a bug in the driver that makes it impossible to format a
  58  * floppy as the first thing after bootup.
  59  */
  60 
  61 /*
  62  * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
  63  * this helped the floppy driver as well. Much cleaner, and still seems to
  64  * work.
  65  */
  66 
  67 /* 1994/6/24 --bbroad-- added the floppy table entries and made
  68  * minor modifications to allow 2.88 floppies to be run.
  69  */
  70 
  71 /* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
  72  * disk types.
  73  */
  74 
  75 /*
  76  * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
  77  * format bug fixes, but unfortunately some new bugs too...
  78  */
  79 
  80 /* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write 
  81  * errors to allow safe writing by specialized programs.
  82  */
  83 
  84 /* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
  85  * by defining bit 1 of the "stretch" parameter to mean put sectors on the
  86  * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
  87  * drives are "upside-down").
  88  */
  89 
  90 #define CONFIG_FLOPPY_SANITY
  91 #undef  CONFIG_FLOPPY_SILENT_DCL_CLEAR
  92 
  93 #define REALLY_SLOW_IO
  94 
  95 #define DEBUGT 2
  96 #define DCL_DEBUG /* debug disk change line */
  97 
  98 #include <linux/config.h>
  99 
 100 /* do print messages for unexpected interrupts */
 101 static int print_unex=1;
 102 
 103 #ifdef MODULE
 104 #define FD_MODULE
 105 
 106 #include <linux/module.h>
 107 /*
 108  * NB. we must include the kernel idenfication string in to install the module.
 109  */
 110 #include <linux/version.h>
 111 char kernel_version[] = UTS_RELEASE;
 112 
 113 int FLOPPY_IRQ=6;
 114 int FLOPPY_DMA=2;
 115 int ALLOWED_DRIVE_MASK = 0x33;
 116 int FDC1 = 0x3f0;
 117 int FDC2 = -1;
 118 
 119 #endif
 120 
 121 #ifndef FD_MODULE
 122 /* the following is the mask of allowed drives. By default units 2 and
 123  * 3 of both floppy controllers are disabled, because switching on the
 124  * motor of these drives causes system hangs on some PCI computers. drive
 125  * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
 126  * a drive is allowed. */
 127 static int ALLOWED_DRIVE_MASK=0x33;
 128 
 129 #define FLOPPY_IRQ 6
 130 #define FLOPPY_DMA 2
 131 #define FDC1 0x3f0
 132 static int FDC2=-1;
 133 #endif
 134 
 135 #define MODULE_AWARE_DRIVER
 136 
 137 #include <linux/sched.h>
 138 #include <linux/fs.h>
 139 #include <linux/kernel.h>
 140 #include <linux/timer.h>
 141 #include <linux/tqueue.h>
 142 #define FDPATCHES
 143 #include <linux/fdreg.h>
 144 #include <linux/fd.h>
 145 #include <linux/errno.h>
 146 #include <linux/malloc.h>
 147 #include <linux/mm.h>
 148 #include <linux/string.h>
 149 #include <linux/fcntl.h>
 150 #include <linux/delay.h>
 151 #include <linux/mc146818rtc.h> /* CMOS defines */
 152 #include <linux/ioport.h>
 153 
 154 #include <asm/dma.h>
 155 #include <asm/irq.h>
 156 #include <asm/system.h>
 157 #include <asm/io.h>
 158 #include <asm/segment.h>
 159 
 160 #define MAJOR_NR FLOPPY_MAJOR
 161 #include "blk.h"
 162 
 163 
 164 /* Dma Memory related stuff */
 165 
 166 /* Pure 2^n version of get_order */
 167 static inline int __get_order (int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169         int order;
 170 
 171 #ifdef  _ASM_IO_H2
 172         __asm__ __volatile__("bsr %1,%0"
 173                              : "=r" (order)
 174                              : "r" (size / PAGE_SIZE) );        
 175 #else
 176         for (order = 0; order < NR_MEM_LISTS; ++order)
 177                 if (size <= (PAGE_SIZE << order))
 178                         return order; 
 179 #endif
 180         return NR_MEM_LISTS;
 181 }
 182 
 183 static unsigned long dma_mem_alloc(int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185         int order = __get_order(size);
 186         
 187         if (order >= NR_MEM_LISTS)
 188                 return(0);
 189         return __get_dma_pages(GFP_KERNEL,order);
 190 }
 191 
 192 /* End dma memory related stuff */
 193 
 194 static unsigned int fake_change = 0;
 195 static int initialising=1;
 196 
 197 /*
 198  * Again, the CMOS information doesn't work on the alpha..
 199  */
 200 #ifdef __alpha__
 201 #define FLOPPY0_TYPE 6
 202 #define FLOPPY1_TYPE 0
 203 #else
 204 #define FLOPPY0_TYPE    ((CMOS_READ(0x10) >> 4) & 15)
 205 #define FLOPPY1_TYPE    (CMOS_READ(0x10) & 15)
 206 #endif
 207 
 208 #define N_FDC 2
 209 #define N_DRIVE 8
 210 
 211 #define TYPE(x) ( ((x)>>2) & 0x1f )
 212 #define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5))
 213 #define UNIT(x) ( (x) & 0x03 )          /* drive on fdc */
 214 #define FDC(x) ( ((x) & 0x04) >> 2 )  /* fdc of drive */
 215 #define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 ))
 216                                 /* reverse mapping from unit and fdc to drive */
 217 #define DP (&drive_params[current_drive])
 218 #define DRS (&drive_state[current_drive])
 219 #define DRWE (&write_errors[current_drive])
 220 #define FDCS (&fdc_state[fdc])
 221 #define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags))
 222 #define SETF(x) (set_bit(x##_BIT, &DRS->flags))
 223 #define TESTF(x) (test_bit(x##_BIT, &DRS->flags))
 224 
 225 #define UDP (&drive_params[drive])
 226 #define UDRS (&drive_state[drive])
 227 #define UDRWE (&write_errors[drive])
 228 #define UFDCS (&fdc_state[FDC(drive)])
 229 #define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags))
 230 #define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
 231 #define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
 232 
 233 #define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
 234 
 235 #define DPRINT1(x,x1) \
 236 printk(DEVICE_NAME "%d: " x,current_drive,(x1))
 237 
 238 #define DPRINT2(x,x1,x2) \
 239 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
 240 
 241 #define DPRINT3(x,x1,x2,x3) \
 242 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
 243 
 244 #define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
 245 #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
 246 
 247 /* read/write */
 248 #define COMMAND raw_cmd.cmd[0]
 249 #define DR_SELECT raw_cmd.cmd[1]
 250 #define TRACK raw_cmd.cmd[2]
 251 #define HEAD raw_cmd.cmd[3]
 252 #define SECTOR raw_cmd.cmd[4]
 253 #define SIZECODE raw_cmd.cmd[5]
 254 #define SECT_PER_TRACK raw_cmd.cmd[6]
 255 #define GAP raw_cmd.cmd[7]
 256 #define SIZECODE2 raw_cmd.cmd[8]
 257 #define NR_RW 9
 258 
 259 /* format */
 260 #define F_SIZECODE raw_cmd.cmd[2]
 261 #define F_SECT_PER_TRACK raw_cmd.cmd[3]
 262 #define F_GAP raw_cmd.cmd[4]
 263 #define F_FILL raw_cmd.cmd[5]
 264 #define NR_F 6
 265 
 266 /*
 267  * Maximum disk size (in kilobytes). This default is used whenever the
 268  * current disk size is unknown.
 269  * [Now it is rather a minimum]
 270  */
 271 #define MAX_DISK_SIZE 2 /* 3984*/
 272 
 273 
 274 #define K_64    0x10000         /* 64KB */
 275 
 276 /*
 277  * The DMA channel used by the floppy controller cannot access data at
 278  * addresses >= 16MB
 279  *
 280  * Went back to the 1MB limit, as some people had problems with the floppy
 281  * driver otherwise. It doesn't matter much for performance anyway, as most
 282  * floppy accesses go through the track buffer.
 283  */
 284 #ifdef __alpha__
 285 # define CROSS_64KB(a,s)        (0)
 286 #else
 287 # define CROSS_64KB(a,s) \
 288         ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
 289 #endif
 290 
 291 /*
 292  * globals used by 'result()'
 293  */
 294 #define MAX_REPLIES 10
 295 static unsigned char reply_buffer[MAX_REPLIES];
 296 static int inr; /* size of reply buffer, when called from interrupt */
 297 #define ST0 (reply_buffer[0])
 298 #define ST1 (reply_buffer[1])
 299 #define ST2 (reply_buffer[2])
 300 #define ST3 (reply_buffer[0]) /* result of GETSTATUS */
 301 #define R_TRACK (reply_buffer[3])
 302 #define R_HEAD (reply_buffer[4])
 303 #define R_SECTOR (reply_buffer[5])
 304 #define R_SIZECODE (reply_buffer[6])
 305 
 306 #define SEL_DLY (2*HZ/100)
 307 
 308 #define ARRAY_SIZE(x) (sizeof(x) / sizeof( (x)[0] ))
 309 /*
 310  * this struct defines the different floppy drive types.
 311  */
 312 static struct {
 313         struct floppy_drive_params params;
 314         const char *name; /* name printed while booting */
 315 } default_drive_params[]= {
 316 /* NOTE: the time values in jiffies should be in msec!
 317  CMOS drive type
 318   |     Maximum data rate supported by drive type
 319   |     |   Head load time, msec
 320   |     |   |   Head unload time, msec (not used)
 321   |     |   |   |     Step rate interval, usec
 322   |     |   |   |     |       Time needed for spinup time (jiffies)
 323   |     |   |   |     |       |      Timeout for spinning down (jiffies)
 324   |     |   |   |     |       |      |   Spindown offset (where disk stops)
 325   |     |   |   |     |       |      |   |     Select delay
 326   |     |   |   |     |       |      |   |     |     RPS
 327   |     |   |   |     |       |      |   |     |     |    Max number of tracks
 328   |     |   |   |     |       |      |   |     |     |    |     Interrupt timeout
 329   |     |   |   |     |       |      |   |     |     |    |     |   Max nonintlv. sectors
 330   |     |   |   |     |       |      |   |     |     |    |     |   | -Max Errors- flags */
 331 {{0,  500, 16, 16, 8000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  80, 3*HZ, 20, {3,1,2,0,2}, 0,
 332       0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" },
 333 
 334 {{1,  300, 16, 16, 8000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  40, 3*HZ, 17, {3,1,2,0,2}, 0,
 335       0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/
 336 
 337 {{2,  500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6,  83, 3*HZ, 17, {3,1,2,0,2}, 0,
 338       0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
 339 
 340 {{3,  250, 16, 16, 3000,    1*HZ, 3*HZ,  0, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,2}, 0,
 341       0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/
 342 
 343 {{4,  500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 20, {3,1,2,0,2}, 0,
 344       0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/
 345 
 346 {{5, 1000, 15,  8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 40, {3,1,2,0,2}, 0,
 347       0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/
 348 
 349 {{6, 1000, 15,  8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5,  83, 3*HZ, 40, {3,1,2,0,2}, 0,
 350       0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/
 351 /*    |  ---autodetected formats--   |      |      |
 352       read_track                     |      |    Name printed when booting
 353                                      |     Native format
 354                                    Frequency of disk change checks */
 355 };
 356 
 357 static struct floppy_drive_params drive_params[N_DRIVE];
 358 static struct floppy_drive_struct drive_state[N_DRIVE];
 359 static struct floppy_write_errors write_errors[N_DRIVE];
 360 static struct floppy_raw_cmd raw_cmd;
 361 
 362 /*
 363  * This struct defines the different floppy types.
 364  *
 365  * Bit 0 of 'stretch' tells if the tracks need to be doubled for some
 366  * types (e.g. 360kB diskette in 1.2MB drive, etc.).  Bit 1 of 'stretch'
 367  * tells if the disk is in Commodore 1581 format, which means side 0 sectors
 368  * are located on side 1 of the disk but with a side 0 ID, and vice-versa.
 369  * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the
 370  * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
 371  * side 0 is on physical side 0 (but with the misnamed sector IDs).
 372  * 'stretch' should probably be renamed to something more general, like
 373  * 'options'.  Other parameters should be self-explanatory (see also
 374  * setfdprm(8)).
 375  */
 376 static struct floppy_struct floppy_type[32] = {
 377         {    0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL    }, /*  0 no testing    */
 378         {  720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360"  }, /*  1 360KB PC      */
 379         { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" }, /*  2 1.2MB AT      */
 380         {  720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360"  }, /*  3 360KB SS 3.5" */
 381         { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720"  }, /*  4 720KB 3.5"    */
 382         {  720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360"  }, /*  5 360KB AT      */
 383         { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720"  }, /*  6 720KB AT      */
 384         { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" }, /*  7 1.44MB 3.5"   */
 385         { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" }, /*  8 2.88MB 3.5"   */
 386         { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"}, /*  9 2.88MB 3.5"   */
 387 
 388         { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25"  */
 389         { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5"   */
 390         {  820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410"  }, /* 12 410KB 5.25"   */
 391         { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820"  }, /* 13 820KB 3.5"    */
 392         { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25"  */
 393         { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" }, /* 15 1.72MB 3.5"   */
 394         {  840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420"  }, /* 16 420KB 5.25"   */
 395         { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830"  }, /* 17 830KB 3.5"    */
 396         { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" }, /* 18 1.49MB 5.25"  */
 397         { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5"  */
 398 
 399         { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880"  }, /* 20 880KB 5.25"   */
 400         { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5"   */
 401         { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5"   */
 402         { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25"   */
 403         { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5"   */
 404         { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5"   */
 405         { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5"   */
 406         { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5"   */
 407         { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5"   */
 408 
 409         { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5"   */
 410         { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800"  }, /* 30 800KB 3.5"    */
 411         { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5"    */
 412 };
 413 
 414 #define NUMBER(x)       (sizeof(x) / sizeof(*(x)))
 415 #define SECTSIZE ( _FD_SECTSIZE(*floppy))
 416 
 417 /* Auto-detection: Disk type used until the next media change occurs. */
 418 struct floppy_struct *current_type[N_DRIVE] = {
 419         NULL, NULL, NULL, NULL,
 420         NULL, NULL, NULL, NULL
 421 };
 422 
 423 /*
 424  * User-provided type information. current_type points to
 425  * the respective entry of this array.
 426  */
 427 struct floppy_struct user_params[N_DRIVE];
 428 
 429 static int floppy_sizes[256];
 430 static int floppy_blocksizes[256] = { 0, };
 431 
 432 /*
 433  * The driver is trying to determine the correct media format
 434  * while probing is set. rw_interrupt() clears it after a
 435  * successful access.
 436  */
 437 static int probing = 0;
 438 
 439 /* Synchronization of FDC access. */
 440 #define FD_COMMAND_DETECT -2
 441 #define FD_COMMAND_NONE -1
 442 #define FD_COMMAND_ERROR 2
 443 #define FD_COMMAND_OKAY 3
 444 
 445 static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
 446 static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
 447 #define NO_SIGNAL (!(current->signal & ~current->blocked) || !interruptible)
 448 #define CALL(x) if( (x) == -EINTR) return -EINTR;
 449 #define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
 450 #define WAIT(x) _WAIT((x),interruptible)
 451 #define IWAIT(x) _WAIT((x),1)
 452 
 453 /* Errors during formatting are counted here. */
 454 static int format_errors;
 455 
 456 /* Format request descriptor. */
 457 static struct format_descr format_req;
 458 
 459 /*
 460  * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps
 461  * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
 462  * H is head unload time (1=16ms, 2=32ms, etc)
 463  */
 464 
 465 /*
 466  * Track buffer
 467  * Because these are written to by the DMA controller, they must
 468  * not contain a 64k byte boundary crossing, or data will be
 469  * corrupted/lost. Alignment of these is enforced in boot/head.S.
 470  * Note that you must not change the sizes below without updating head.S.
 471  */
 472 char *floppy_track_buffer=0;
 473 int max_buffer_sectors=0;
 474 
 475 int *errors;
 476 typedef void (*done_f)(int);
 477 struct cont_t {
 478 void (*interrupt)(void); /* this is called after the interrupt of the
 479                           * main command */
 480 void (*redo)(void); /* this is called to retry the operation */
 481 void (*error)(void); /* this is called to tally an error */
 482 done_f done; /* this is called to say if the operation has succeeded/failed */
 483 } *cont=NULL;
 484 
 485 static void floppy_ready(void);
 486 static void floppy_start(void);
 487 static void process_fd_request(void);
 488 static void recalibrate_floppy(void);
 489 static void floppy_shutdown(void);
 490 
 491 static int floppy_grab_irq_and_dma(void);
 492 static void floppy_release_irq_and_dma(void);
 493 
 494 /*
 495  * The "reset" variable should be tested whenever an interrupt is scheduled,
 496  * after the commands have been sent. This is to ensure that the driver doesn't
 497  * get wedged when the interrupt doesn't come because of a failed command.
 498  * reset doesn't need to be tested before sending commands, because
 499  * output_byte is automatically disabled when reset is set.
 500  */
 501 #define CHECK_RESET { if ( FDCS->reset ){ reset_fdc(); return ; } }
 502 static void reset_fdc(void);
 503 
 504 /*
 505  * These are global variables, as that's the easiest way to give
 506  * information to interrupts. They are the data used for the current
 507  * request.
 508  */
 509 #define NO_TRACK -1
 510 #define NEED_1_RECAL -2
 511 #define NEED_2_RECAL -3
 512 
 513 /* */
 514 static int usage_count = 0;
 515 
 516 
 517 /* buffer related variables */
 518 static int buffer_track = -1;
 519 static int buffer_drive = -1;
 520 static int buffer_min = -1;
 521 static int buffer_max = -1;
 522 
 523 /* fdc related variables, should end up in a struct */
 524 static struct floppy_fdc_state fdc_state[N_FDC];
 525 static int fdc; /* current fdc */
 526 
 527 static struct floppy_struct * floppy = floppy_type;
 528 static unsigned char current_drive = 0;
 529 static long current_count_sectors = 0;
 530 static char *current_addr = 0;
 531 static unsigned char sector_t; /* sector in track */
 532 
 533 #ifdef DEBUGT
 534 long unsigned debugtimer;
 535 #endif
 536 
 537 /*
 538  * Debugging
 539  * =========
 540  */
 541 static inline void set_debugt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 542 {
 543 #ifdef DEBUGT
 544         debugtimer = jiffies;
 545 #endif
 546 }
 547 
 548 static inline void debugt(const char *message)
     /* [previous][next][first][last][top][bottom][index][help] */
 549 {
 550 #ifdef DEBUGT
 551   if ( DP->flags & DEBUGT )
 552         printk("%s dtime=%lu\n", message, jiffies-debugtimer );
 553 #endif
 554 }
 555 
 556 typedef void (*timeout_fn)(unsigned long);
 557 static struct timer_list fd_timeout ={ NULL, NULL, 0, 0, 
 558                                                (timeout_fn) floppy_shutdown };
 559 
 560 static const char *timeout_message;
 561 
 562 #ifdef CONFIG_FLOPPY_SANITY
 563 static void is_alive(const char *message)
     /* [previous][next][first][last][top][bottom][index][help] */
 564 {
 565         /* this routine checks whether the floppy driver is "alive" */
 566         if (fdc_busy && command_status < 2 && !fd_timeout.prev){
 567                 DPRINT1("timeout handler died: %s\n",message);
 568         }
 569 }
 570 #endif
 571 
 572 #ifdef CONFIG_FLOPPY_SANITY
 573 
 574 #define OLOGSIZE 20
 575 
 576 void (*lasthandler)(void) = NULL;
 577 int interruptjiffies=0;
 578 int resultjiffies=0;
 579 int resultsize=0;
 580 int lastredo=0;
 581 
 582 static struct output_log {
 583         unsigned char data;
 584         unsigned char status;
 585         unsigned long jiffies;
 586 } output_log[OLOGSIZE];
 587 
 588 static int output_log_pos=0;
 589 #endif
 590 
 591 #define CURRENTD -1
 592 #define MAXTIMEOUT -2
 593 
 594 
 595 
 596 static void reschedule_timeout(int drive, const char *message, int marg)
     /* [previous][next][first][last][top][bottom][index][help] */
 597 {
 598         if (drive == CURRENTD )
 599                 drive = current_drive;
 600         del_timer(&fd_timeout);
 601         if (drive < 0 || drive > N_DRIVE) {
 602                 fd_timeout.expires = jiffies + 20*HZ;
 603                 drive=0;
 604         } else
 605                 fd_timeout.expires = jiffies + UDP->timeout;
 606         add_timer(&fd_timeout);
 607         if (UDP->flags & FD_DEBUG){
 608                 DPRINT("reschedule timeout ");
 609                 printk(message, marg);
 610                 printk("\n");
 611         }
 612         timeout_message = message;
 613 }
 614 
 615 /*
 616  * Bottom half floppy driver.
 617  * ==========================
 618  *
 619  * This part of the file contains the code talking directly to the hardware,
 620  * and also the main service loop (seek-configure-spinup-command)
 621  */
 622 
 623 /*
 624  * disk change.
 625  * This routine is responsible for maintaining the FD_DISK_CHANGE flag,
 626  * and the last_checked date.
 627  *
 628  * last_checked is the date of the last check which showed 'no disk change'
 629  * FD_DISK_CHANGE is set under two conditions:
 630  * 1. The floppy has been changed after some i/o to that floppy already
 631  *    took place.
 632  * 2. No floppy disk is in the drive. This is done in order to ensure that
 633  *    requests are quickly flushed in case there is no disk in the drive. It
 634  *    follows that FD_DISK_CHANGE can only be cleared if there is a disk in
 635  *    the drive.
 636  *
 637  * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet.
 638  * For 2., FD_DISK_NEWCHANGE is watched. FD_DISK_NEWCHANGE is cleared on
 639  *  each seek. If a disk is present, the disk change line should also be
 640  *  cleared on each seek. Thus, if FD_DISK_NEWCHANGE is clear, but the disk
 641  *  change line is set, this means either that no disk is in the drive, or
 642  *  that it has been removed since the last seek.
 643  *
 644  * This means that we really have a third possibility too:
 645  *  The floppy has been changed after the last seek.
 646  */
 647 
 648 static int disk_change(int drive)
     /* [previous][next][first][last][top][bottom][index][help] */
 649 {
 650         int fdc=FDC(drive);
 651 #ifdef CONFIG_FLOPPY_SANITY
 652         if(jiffies < UDP->select_delay + UDRS->select_date)
 653                 DPRINT("WARNING disk change called early\n");
 654         if(! (FDCS->dor & (0x10 << UNIT(drive))) ||
 655            (FDCS->dor & 3) != UNIT(drive) ||
 656            fdc != FDC(drive)){
 657                 DPRINT("probing disk change on unselected drive\n");
 658                 DPRINT3("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
 659                         FDCS->dor);
 660         }
 661 #endif
 662 
 663 #ifdef DCL_DEBUG
 664         if (UDP->flags & FD_DEBUG){
 665                 DPRINT1("checking disk change line for drive %d\n",drive);
 666                 DPRINT1("jiffies=%ld\n", jiffies);
 667                 DPRINT1("disk change line=%x\n",inb_p(FD_DIR)&0x80);
 668                 DPRINT1("flags=%x\n",UDRS->flags);
 669         }
 670 #endif
 671         if (UDP->flags & FD_BROKEN_DCL)
 672                 return UTESTF(FD_DISK_CHANGED);
 673         if( (inb_p(FD_DIR) ^ UDP->flags) & 0x80){
 674                 USETF(FD_VERIFY); /* verify write protection */
 675                 if(UDRS->maxblock){
 676                         /* mark it changed */
 677                         USETF(FD_DISK_CHANGED);
 678 
 679                         /* invalidate its geometry */
 680                         if (UDRS->keep_data >= 0) {
 681                                 if ((UDP->flags & FTD_MSG) &&
 682                                     current_type[drive] != NULL)
 683                                         DPRINT("Disk type is undefined after "
 684                                                "disk change\n");
 685                                 current_type[drive] = NULL;
 686                                 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] = MAX_DISK_SIZE;
 687                         }
 688                 }
 689                 /*USETF(FD_DISK_NEWCHANGE);*/
 690                 return 1;
 691         } else {
 692                 UDRS->last_checked=jiffies;
 693                 UCLEARF(FD_DISK_NEWCHANGE);
 694         }
 695         return 0;
 696 }
 697 
 698 static inline int is_selected(int dor, int unit)
     /* [previous][next][first][last][top][bottom][index][help] */
 699 {
 700         return ( (dor  & (0x10 << unit)) && (dor &3) == unit);
 701 }
 702 
 703 static int set_dor(int fdc, char mask, char data)
     /* [previous][next][first][last][top][bottom][index][help] */
 704 {
 705         register unsigned char drive, unit, newdor,olddor;
 706 
 707         if(FDCS->address == -1)
 708                 return -1;
 709 
 710         olddor = FDCS->dor;
 711         newdor =  (olddor & mask) | data;
 712         if ( newdor != olddor ){
 713                 unit = olddor & 0x3;
 714                 if(is_selected(olddor, unit) && !is_selected(newdor,unit)){
 715                         drive = REVDRIVE(fdc,unit);
 716 #ifdef DCL_DEBUG
 717                         if (UDP->flags & FD_DEBUG){
 718                                 DPRINT("calling disk change from set_dor\n");
 719                         }
 720 #endif
 721                         disk_change(drive);
 722                 }
 723                 FDCS->dor = newdor;
 724                 outb_p(newdor, FD_DOR);
 725 
 726                 unit = newdor & 0x3;
 727                 if(!is_selected(olddor, unit) && is_selected(newdor,unit)){
 728                         drive = REVDRIVE(fdc,unit);
 729                         UDRS->select_date = jiffies;
 730                 }
 731         }
 732         if ( newdor & 0xf0 )
 733                 floppy_grab_irq_and_dma();
 734         if( olddor & 0xf0 )
 735                 floppy_release_irq_and_dma();
 736         return olddor;
 737 }
 738 
 739 static void twaddle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 740 {
 741         if (DP->select_delay)
 742                 return;
 743         outb_p(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
 744         outb_p(FDCS->dor, FD_DOR);
 745         DRS->select_date = jiffies;
 746 }
 747 
 748 /* reset all driver information about the current fdc. This is needed after
 749  * a reset, and after a raw command. */
 750 static void reset_fdc_info(int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 751 {
 752         int drive;
 753 
 754         FDCS->spec1 = FDCS->spec2 = -1;
 755         FDCS->need_configure = 1;
 756         FDCS->perp_mode = 1;
 757         FDCS->rawcmd = 0;
 758         for ( drive = 0; drive < N_DRIVE; drive++)
 759                 if (FDC(drive) == fdc &&
 760                     ( mode || UDRS->track != NEED_1_RECAL))
 761                         UDRS->track = NEED_2_RECAL;
 762 }
 763 
 764 /* selects the fdc and drive, and enables the fdc's input/dma. */
 765 static void set_fdc(int drive)
     /* [previous][next][first][last][top][bottom][index][help] */
 766 {
 767         if (drive >= 0 && drive < N_DRIVE){
 768                 fdc = FDC(drive);
 769                 current_drive = drive;
 770         }
 771         set_dor(fdc,~0,8);
 772         set_dor(1-fdc, ~8, 0);
 773         if ( FDCS->rawcmd == 2 )
 774                 reset_fdc_info(1);
 775         if( inb_p(FD_STATUS) != STATUS_READY )
 776                 FDCS->reset = 1;
 777 }
 778 
 779 /* locks the driver */
 780 static int lock_fdc(int drive, int interruptible)
     /* [previous][next][first][last][top][bottom][index][help] */
 781 {
 782         if(!usage_count){
 783                 printk("trying to lock fdc while usage count=0\n");
 784                 return -1;
 785         }
 786         floppy_grab_irq_and_dma();
 787         if (!current->pid)
 788                 run_task_queue(&tq_timer);
 789         cli();
 790         while (fdc_busy && NO_SIGNAL)
 791                 interruptible_sleep_on(&fdc_wait);
 792         if(fdc_busy){
 793                 sti();
 794                 return -EINTR;
 795         }
 796         fdc_busy = 1;
 797         sti();
 798         command_status = FD_COMMAND_NONE;
 799         set_fdc(drive);
 800         reschedule_timeout(drive, "lock fdc", 0);
 801         return 0;
 802 }
 803 
 804 #define LOCK_FDC(drive,interruptible) \
 805 if(lock_fdc(drive,interruptible)) return -EINTR;
 806 
 807 
 808 /* unlocks the driver */
 809 static inline void unlock_fdc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 810 {
 811         if (!fdc_busy)
 812                 DPRINT("FDC access conflict!\n");
 813 
 814         if ( DEVICE_INTR )
 815                 DPRINT1("device interrupt still active at FDC release: %p!\n",
 816                         DEVICE_INTR);
 817         command_status = FD_COMMAND_NONE;
 818         del_timer(&fd_timeout);
 819         cont = NULL;
 820         fdc_busy = 0;
 821         floppy_release_irq_and_dma();
 822         wake_up(&fdc_wait);
 823 }
 824 
 825 /* switches the motor off after a given timeout */
 826 static void motor_off_callback(unsigned long nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 827 {
 828         unsigned char mask = ~(0x10 << UNIT(nr));
 829 
 830         set_dor( FDC(nr), mask, 0 );
 831 }
 832 
 833 static struct timer_list motor_off_timer[N_DRIVE] = {
 834         { NULL, NULL, 0, 0, motor_off_callback },
 835         { NULL, NULL, 0, 1, motor_off_callback },
 836         { NULL, NULL, 0, 2, motor_off_callback },
 837         { NULL, NULL, 0, 3, motor_off_callback },
 838         { NULL, NULL, 0, 4, motor_off_callback },
 839         { NULL, NULL, 0, 5, motor_off_callback },
 840         { NULL, NULL, 0, 6, motor_off_callback },
 841         { NULL, NULL, 0, 7, motor_off_callback }
 842 };
 843 
 844 /* schedules motor off */
 845 static void floppy_off(unsigned int drive)
     /* [previous][next][first][last][top][bottom][index][help] */
 846 {
 847         unsigned long volatile delta;
 848         register int fdc=FDC(drive);
 849 
 850         if( !(FDCS->dor & ( 0x10 << UNIT(drive))))
 851                 return;
 852 
 853         del_timer(motor_off_timer+drive);
 854 
 855         /* make spindle stop in a position which minimizes spinup time
 856          * next time */
 857         if (UDP->rps ){
 858                 delta = jiffies - UDRS->first_read_date + HZ -
 859                         UDP->spindown_offset;
 860                 delta = (( delta * UDP->rps) % HZ ) / UDP->rps;
 861                 motor_off_timer[drive].expires = jiffies + UDP->spindown - delta;
 862         }
 863         add_timer(motor_off_timer+drive);
 864 }
 865 
 866 /*
 867  * cycle through all N_DRIVE floppy drives, for disk change testing.
 868  * stopping at current drive. This is done before any long operation, to
 869  * be sure to have up to date disk change information.
 870  */
 871 static void scandrives(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873         int i, drive, saved_drive;
 874         
 875         if (DP->select_delay)
 876                 return;
 877 
 878         saved_drive = current_drive;
 879         for(i=0; i< N_DRIVE; i++){
 880                 drive = (saved_drive + i + 1 ) % N_DRIVE;
 881                 if ( UDRS->fd_ref == 0 || UDP->select_delay != 0)
 882                         continue; /* skip closed drives */
 883                 set_fdc(drive);
 884                 if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
 885                       (0x10 << UNIT(drive))))
 886                         /* switch the motor off again, if it was off to
 887                          * begin with */
 888                         set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
 889         }
 890         set_fdc(saved_drive);
 891 }
 892 
 893 static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
 894 
 895 /* this function makes sure that the disk stays in the drive during the
 896  * transfer */
 897 static void fd_watchdog(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 898 {
 899 #ifdef DCL_DEBUG
 900         if (DP->flags & FD_DEBUG){
 901                 DPRINT("calling disk change from watchdog\n");
 902         }
 903 #endif
 904 
 905         if ( disk_change(current_drive) ){
 906                 DPRINT("disk removed during i/o\n");
 907                 floppy_shutdown();
 908         } else {                
 909                 del_timer(&fd_timer);
 910                 fd_timer.function = (timeout_fn) fd_watchdog;
 911                 fd_timer.expires = jiffies + 10;
 912                 add_timer(&fd_timer);
 913         }
 914 }
 915 
 916 static void main_command_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 917 {
 918         del_timer(&fd_timer);
 919         cont->interrupt();
 920 }
 921 
 922 /* waits for a delay (spinup or select) to pass */
 923 static int wait_for_completion(int delay, timeout_fn function)
     /* [previous][next][first][last][top][bottom][index][help] */
 924 {
 925         if ( FDCS->reset ){
 926                 reset_fdc(); /* do the reset during sleep to win time
 927                               * if we don't need to sleep, it's a good
 928                               * occasion anyways */
 929                 return 1;
 930         }
 931 
 932         if ( jiffies < delay ){
 933                 del_timer(&fd_timer);
 934                 fd_timer.function = function;
 935                 fd_timer.expires = delay;
 936                 add_timer(&fd_timer);
 937                 return 1;
 938         }
 939         return 0;
 940 }
 941 
 942 static int hlt_disabled=0;
 943 static void floppy_disable_hlt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 944 {
 945         unsigned long flags;
 946         save_flags(flags);
 947         cli();
 948         if(!hlt_disabled){
 949                 hlt_disabled=1;
 950 #ifdef HAVE_DISABLE_HLT
 951                 disable_hlt();
 952 #endif
 953         }
 954         restore_flags(flags);
 955 }
 956 
 957 static void floppy_enable_hlt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 958 {
 959         unsigned long flags;
 960         save_flags(flags);
 961         cli();
 962         if(hlt_disabled){
 963                 hlt_disabled=0;
 964 #ifdef HAVE_DISABLE_HLT
 965                 enable_hlt();
 966 #endif
 967         }
 968         restore_flags(flags);
 969 }
 970                 
 971 
 972 static void setup_DMA(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 973 {
 974 #ifdef CONFIG_FLOPPY_SANITY
 975         if (raw_cmd.length == 0){
 976                 int i;
 977 
 978                 printk("zero dma transfer size:");
 979                 for(i=0; i< raw_cmd.cmd_count; i++)
 980                         printk("%x,", raw_cmd.cmd[i]);
 981                 printk("\n");
 982                 cont->done(0);
 983                 FDCS->reset = 1;
 984                 return;
 985         }
 986         if ((!CURRENT ||
 987              CURRENT->buffer != current_addr ||
 988              raw_cmd.length > 512 * CURRENT->nr_sectors) &&
 989             (current_addr < floppy_track_buffer ||
 990              current_addr + raw_cmd.length >
 991              floppy_track_buffer + 1024 * max_buffer_sectors)){
 992                 printk("bad address. start=%p lg=%lx tb=%p\n",
 993                        current_addr, raw_cmd.length, floppy_track_buffer);
 994                 if ( CURRENT ){
 995                         printk("buffer=%p nr=%lx cnr=%lx\n",
 996                                CURRENT->buffer, CURRENT->nr_sectors,
 997                                CURRENT->current_nr_sectors);
 998                 }
 999                 cont->done(0);
1000                 FDCS->reset=1;
1001                 return;
1002         }
1003         if ((long) current_addr % 512 ){
1004                 printk("non aligned address: %p\n", current_addr );
1005                 cont->done(0);
1006                 FDCS->reset=1;
1007                 return;
1008         }
1009         if (CROSS_64KB(current_addr, raw_cmd.length)) {
1010                 printk("DMA crossing 64-K boundary %p-%p\n",
1011                        current_addr, current_addr + raw_cmd.length);
1012                 cont->done(0);
1013                 FDCS->reset=1;
1014                 return;
1015         }
1016 #endif
1017         cli();
1018         disable_dma(FLOPPY_DMA);
1019         clear_dma_ff(FLOPPY_DMA);
1020         set_dma_mode(FLOPPY_DMA,
1021                      (raw_cmd.flags & FD_RAW_READ)?
1022                      DMA_MODE_READ : DMA_MODE_WRITE);
1023         set_dma_addr(FLOPPY_DMA, virt_to_bus(current_addr));
1024         set_dma_count(FLOPPY_DMA, raw_cmd.length);
1025         enable_dma(FLOPPY_DMA);
1026         sti();
1027         floppy_disable_hlt();
1028 }
1029 
1030 /* sends a command byte to the fdc */
1031 static int output_byte(char byte)
     /* [previous][next][first][last][top][bottom][index][help] */
1032 {
1033         int counter;
1034         unsigned char status;
1035         unsigned char rstatus;
1036 
1037         if (FDCS->reset)
1038                 return -1;
1039         for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
1040                 rstatus = inb_p(FD_STATUS); 
1041                 status =  rstatus &(STATUS_READY|STATUS_DIR|STATUS_DMA);
1042                 if (!(status & STATUS_READY))
1043                         continue;
1044                 if (status == STATUS_READY){
1045                         outb_p(byte,FD_DATA);
1046 
1047 #ifdef CONFIG_FLOPPY_SANITY
1048                         output_log[output_log_pos].data = byte;
1049                         output_log[output_log_pos].status = rstatus;
1050                         output_log[output_log_pos].jiffies = jiffies;
1051                         output_log_pos = (output_log_pos + 1) % OLOGSIZE;
1052 #endif
1053                         return 0;
1054                 } else
1055                         break;
1056         }
1057         FDCS->reset = 1;
1058         if ( !initialising )
1059                 DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
1060                         byte, status);
1061         return -1;
1062 }
1063 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
1064 
1065 /* gets the response from the fdc */
1066 static int result(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1067 {
1068         int i = 0, counter, status;
1069 
1070         if (FDCS->reset)
1071                 return -1;
1072         for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
1073                 status = inb_p(FD_STATUS)&
1074                         (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
1075                 if (!(status & STATUS_READY))
1076                         continue;
1077                 if (status == STATUS_READY){
1078 #ifdef CONFIG_FLOPPY_SANITY
1079                         resultjiffies = jiffies;
1080                         resultsize = i;
1081 #endif
1082                         return i;
1083                 }
1084                 if (status & STATUS_DMA )
1085                         break;
1086                 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
1087                         if (i >= MAX_REPLIES) {
1088                                 DPRINT("floppy_stat reply overrun\n");
1089                                 break;
1090                         }
1091                         reply_buffer[i++] = inb_p(FD_DATA);
1092                 }
1093         }
1094         FDCS->reset = 1;
1095         if ( !initialising )
1096                 DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
1097                         status, fdc, i);
1098         return -1;
1099 }
1100 
1101 /* Set perpendicular mode as required, based on data rate, if supported.
1102  * 82077 Now tested. 1Mbps data rate only possible with 82077-1.
1103  */
1104 static inline void perpendicular_mode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1105 {
1106         unsigned char perp_mode;
1107 
1108         if (!floppy)
1109                 return;
1110         if (floppy->rate & 0x40){
1111                 switch(raw_cmd.rate){
1112                 case 0:
1113                         perp_mode=2;
1114                         break;
1115                 case 3:
1116                         perp_mode=3;
1117                         break;
1118                 default:
1119                         DPRINT("Invalid data rate for perpendicular mode!\n");
1120                         cont->done(0);
1121                         FDCS->reset = 1; /* convenient way to return to
1122                                           * redo without to much hassle (deep
1123                                           * stack et al. */
1124                         return;
1125                 }
1126         } else
1127                 perp_mode = 0;
1128                         
1129         if ( FDCS->perp_mode == perp_mode )
1130                 return;
1131         if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
1132                 output_byte(FD_PERPENDICULAR);
1133                 output_byte(perp_mode);
1134                 FDCS->perp_mode = perp_mode;
1135         } else if (perp_mode) {
1136                 DPRINT("perpendicular mode not supported by this FDC.\n");
1137         }
1138 } /* perpendicular_mode */
1139 
1140 #define NOMINAL_DTR 500
1141 
1142 /* Issue a "SPECIFY" command to set the step rate time, head unload time,
1143  * head load time, and DMA disable flag to values needed by floppy.
1144  *
1145  * The value "dtr" is the data transfer rate in Kbps.  It is needed
1146  * to account for the data rate-based scaling done by the 82072 and 82077
1147  * FDC types.  This parameter is ignored for other types of FDCs (i.e.
1148  * 8272a).
1149  *
1150  * Note that changing the data transfer rate has a (probably deleterious)
1151  * effect on the parameters subject to scaling for 82072/82077 FDCs, so
1152  * fdc_specify is called again after each data transfer rate
1153  * change.
1154  *
1155  * srt: 1000 to 16000 in microseconds
1156  * hut: 16 to 240 milliseconds
1157  * hlt: 2 to 254 milliseconds
1158  *
1159  * These values are rounded up to the next highest available delay time.
1160  */
1161 static void fdc_specify(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1162 {
1163         unsigned char spec1, spec2;
1164         int srt, hlt, hut;
1165         unsigned long dtr = NOMINAL_DTR;
1166         unsigned long scale_dtr = NOMINAL_DTR;
1167         int hlt_max_code = 0x7f;
1168         int hut_max_code = 0xf;
1169 
1170         if (FDCS->need_configure && FDCS->has_fifo) {
1171                 if ( FDCS->reset )
1172                         return;
1173                 /* Turn on FIFO for 82077-class FDC (improves performance) */
1174                 /* TODO: lock this in via LOCK during initialization */
1175                 output_byte(FD_CONFIGURE);
1176                 output_byte(0);
1177                 output_byte(0x2A);      /* FIFO on, polling off, 10 byte threshold */
1178                 output_byte(0);         /* precompensation from track 0 upwards */
1179                 if ( FDCS->reset ){
1180                         FDCS->has_fifo=0;
1181                         return;
1182                 }
1183                 FDCS->need_configure = 0;
1184                 /*DPRINT("FIFO enabled\n");*/
1185         }
1186 
1187         switch (raw_cmd.rate & 0x03) {
1188         case 3:
1189                 dtr = 1000;
1190                 break;
1191         case 1:
1192                 dtr = 300;
1193                 break;
1194         case 2:
1195                 dtr = 250;
1196                 break;
1197         }
1198 
1199         if (FDCS->version >= FDC_82072) {
1200                 scale_dtr = dtr;
1201                 hlt_max_code = 0x00; /* 0==256msec*dtr0/dtr (not linear!) */
1202                 hut_max_code = 0x0; /* 0==256msec*dtr0/dtr (not linear!) */
1203         }
1204 
1205         /* Convert step rate from microseconds to milliseconds and 4 bits */
1206         srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1207         if (srt > 0xf)
1208                 srt = 0xf;
1209         else if (srt < 0)
1210                 srt = 0;
1211 
1212         hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1213         if (hlt < 0x01)
1214                 hlt = 0x01;
1215         else if (hlt > 0x7f)
1216                 hlt = hlt_max_code;
1217 
1218         hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1219         if (hut < 0x1)
1220                 hut = 0x1;
1221         else if (hut > 0xf)
1222                 hut = hut_max_code;
1223 
1224         spec1 = (srt << 4) | hut;
1225         spec2 = (hlt << 1);
1226 
1227         /* If these parameters did not change, just return with success */
1228         if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
1229                 /* Go ahead and set spec1 and spec2 */
1230                 output_byte(FD_SPECIFY);
1231                 output_byte(FDCS->spec1 = spec1);
1232                 output_byte(FDCS->spec2 = spec2);
1233         }
1234 } /* fdc_specify */
1235 
1236 /* Set the FDC's data transfer rate on behalf of the specified drive.
1237  * NOTE: with 82072/82077 FDCs, changing the data rate requires a reissue
1238  * of the specify command (i.e. using the fdc_specify function).
1239  */
1240 static int fdc_dtr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1241 {
1242         /* If data rate not already set to desired value, set it. */
1243         if ( raw_cmd.rate == FDCS->dtr)
1244                 return 0;
1245         
1246         /* Set dtr */
1247         outb_p(raw_cmd.rate, FD_DCR);
1248         
1249         /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
1250          * need a stabilization period of several milliseconds to be
1251          * enforced after data rate changes before R/W operations.
1252          * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
1253          */
1254         FDCS->dtr = raw_cmd.rate;
1255         return(wait_for_completion(jiffies+2*HZ/100,
1256                                    (timeout_fn) floppy_ready));
1257 } /* fdc_dtr */
1258 
1259 static void tell_sector(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1260 {
1261         printk(": track %d, head %d, sector %d, size %d",
1262                R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1263 } /* tell_sector */
1264 
1265 
1266 /*
1267  * Ok, this error interpreting routine is called after a
1268  * DMA read/write has succeeded
1269  * or failed, so we check the results, and copy any buffers.
1270  * hhb: Added better error reporting.
1271  * ak: Made this into a separate routine.
1272  */
1273 static int interpret_errors(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1274 {
1275         char bad;
1276 
1277         if (inr!=7) {
1278                 DPRINT("-- FDC reply error");
1279                 FDCS->reset = 1;
1280                 return 1;
1281         }
1282 
1283         /* check IC to find cause of interrupt */
1284         switch ((ST0 & ST0_INTR)>>6) {
1285                 case 1: /* error occurred during command execution */
1286                         bad = 1;
1287                         if (ST1 & ST1_WP) {
1288                                 DPRINT("Drive is write protected\n");
1289                                 CLEARF(FD_DISK_WRITABLE);
1290                                 cont->done(0);
1291                                 bad = 2;
1292                         } else if (ST1 & ST1_ND) {
1293                                 SETF(FD_NEED_TWADDLE);
1294                         } else if (ST1 & ST1_OR) {
1295                                 if (DP->flags & FTD_MSG )
1296                                         DPRINT("Over/Underrun - retrying\n");
1297                                 bad = 0;
1298                         }else if(*errors >= DP->max_errors.reporting){
1299                                 DPRINT("");
1300                                 if (ST0 & ST0_ECE) {
1301                                         printk("Recalibrate failed!");
1302                                 } else if (ST2 & ST2_CRC) {
1303                                         printk("data CRC error");
1304                                         tell_sector();
1305                                 } else if (ST1 & ST1_CRC) {
1306                                         printk("CRC error");
1307                                         tell_sector();
1308                                 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1309                                         if (!probing) {
1310                                                 printk("sector not found");
1311                                                 tell_sector();
1312                                         } else
1313                                                 printk("probe failed...");
1314                                 } else if (ST2 & ST2_WC) {      /* seek error */
1315                                         printk("wrong cylinder");
1316                                 } else if (ST2 & ST2_BC) {      /* cylinder marked as bad */
1317                                         printk("bad cylinder");
1318                                 } else {
1319                                         printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1320                                         tell_sector();
1321                                 }
1322                                 printk("\n");
1323 
1324                         }
1325                         if ( ST2 & ST2_WC || ST2 & ST2_BC)
1326                                 /* wrong cylinder => recal */
1327                                 DRS->track = NEED_2_RECAL;
1328                         return bad;
1329                 case 2: /* invalid command given */
1330                         DPRINT("Invalid FDC command given!\n");
1331                         cont->done(0);
1332                         return 2;
1333                 case 3:
1334                         DPRINT("Abnormal termination caused by polling\n");
1335                         cont->error();
1336                         return 2;
1337                 default: /* (0) Normal command termination */
1338                         return 0;
1339         }
1340 }
1341 
1342 /*
1343  * This routine is called when everything should be correctly set up
1344  * for the transfer (ie floppy motor is on, the correct floppy is
1345  * selected, and the head is sitting on the right track).
1346  */
1347 static void setup_rw_floppy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1348 {
1349         int i,ready_date,r, flags,dflags;
1350         timeout_fn function;
1351 
1352         flags = raw_cmd.flags;
1353         if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1354                 flags |= FD_RAW_INTR;
1355 
1356         if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1357                 ready_date = DRS->spinup_date + DP->spinup;             
1358                 /* If spinup will take a long time, rerun scandrives
1359                  * again just before spinup completion. Beware that
1360                  * after scandrives, we must again wait for selection.
1361                  */
1362                 if ( ready_date > jiffies + DP->select_delay){
1363                         ready_date -= DP->select_delay;
1364                         function = (timeout_fn) floppy_start;
1365                 } else
1366                         function = (timeout_fn) setup_rw_floppy;
1367 
1368                 /* wait until the floppy is spinning fast enough */
1369                 if (wait_for_completion(ready_date,function))
1370                         return;
1371         }
1372         dflags = DRS->flags;
1373 
1374         if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1375                 setup_DMA();
1376         
1377         if ( flags & FD_RAW_INTR )
1378                 SET_INTR(main_command_interrupt);
1379 
1380         r=0;
1381         for(i=0; i< raw_cmd.cmd_count; i++)
1382                 r|=output_byte( raw_cmd.cmd[i] );
1383 
1384 #ifdef DEBUGT
1385         debugt("rw_command: ");
1386 #endif
1387         if ( r ){
1388                 reset_fdc();
1389                 return;
1390         }
1391 
1392         if ( ! ( flags & FD_RAW_INTR )){
1393                 inr = result();
1394                 cont->interrupt();
1395         } else if ( flags & FD_RAW_NEED_DISK )
1396                 fd_watchdog();
1397 }
1398 
1399 static int blind_seek;
1400 
1401 /*
1402  * This is the routine called after every seek (or recalibrate) interrupt
1403  * from the floppy controller.
1404  */
1405 static void seek_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1406 {
1407 #ifdef DEBUGT
1408         debugt("seek interrupt:");
1409 #endif
1410         if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1411                 DPRINT("seek failed\n");
1412                 DRS->track = NEED_2_RECAL;
1413                 cont->error();
1414                 cont->redo();
1415                 return;
1416         }
1417         if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
1418 #ifdef DCL_DEBUG
1419                 if (DP->flags & FD_DEBUG){
1420                         DPRINT("clearing NEWCHANGE flag because of effective seek\n");
1421                         DPRINT1("jiffies=%ld\n", jiffies);
1422                 }
1423 #endif
1424                 CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
1425                 DRS->select_date = jiffies;
1426         }
1427         DRS->track = ST1;
1428         floppy_ready();
1429 }
1430 
1431 static void check_wp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1432 {
1433         if (TESTF(FD_VERIFY)) {
1434                 /* check write protection */
1435                 output_byte( FD_GETSTATUS );
1436                 output_byte( UNIT(current_drive) );
1437                 if ( result() != 1 ){
1438                         FDCS->reset = 1;
1439                         return;
1440                 }
1441                 CLEARF(FD_VERIFY);
1442                 CLEARF(FD_NEED_TWADDLE);
1443 #ifdef DCL_DEBUG
1444                 if (DP->flags & FD_DEBUG){
1445                         DPRINT("checking whether disk is write protected\n");
1446                         DPRINT1("wp=%x\n",ST3 & 0x40);
1447                 }
1448 #endif
1449                 if (!( ST3  & 0x40))
1450                         SETF(FD_DISK_WRITABLE);
1451                 else
1452                         CLEARF(FD_DISK_WRITABLE);
1453         }
1454 }
1455 
1456 static void seek_floppy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1457 {
1458         int track;
1459 
1460         blind_seek=0;
1461 
1462 #ifdef DCL_DEBUG
1463         if (DP->flags & FD_DEBUG){
1464                 DPRINT("calling disk change from seek\n");
1465         }
1466 #endif
1467 
1468         if (!TESTF(FD_DISK_NEWCHANGE) &&
1469             disk_change(current_drive) &&
1470             (raw_cmd.flags & FD_RAW_NEED_DISK)){
1471                 /* the media changed flag should be cleared after the seek.
1472                  * If it isn't, this means that there is really no disk in
1473                  * the drive.
1474                  */
1475                 SETF(FD_DISK_CHANGED);
1476                 cont->done(0);
1477                 cont->redo();
1478                 return;
1479         }
1480         if ( DRS->track <= NEED_1_RECAL ){
1481                 recalibrate_floppy();
1482                 return;
1483         } else if (TESTF(FD_DISK_NEWCHANGE) &&
1484                    (raw_cmd.flags & FD_RAW_NEED_DISK) &&
1485                    (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1486                 /* we seek to clear the media-changed condition. Does anybody
1487                  * know a more elegant way, which works on all drives? */
1488                 if ( raw_cmd.track )
1489                         track = raw_cmd.track - 1;
1490                 else {
1491                         if(DP->flags & FD_SILENT_DCL_CLEAR){
1492                                 set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
1493                                 blind_seek = 1;
1494                                 raw_cmd.flags |= FD_RAW_NEED_SEEK;
1495                         }
1496                         track = 1;
1497                 }
1498         } else {
1499                 check_wp();
1500                 if (raw_cmd.track != DRS->track &&
1501                     (raw_cmd.flags & FD_RAW_NEED_SEEK))
1502                         track = raw_cmd.track;
1503                 else {
1504                         setup_rw_floppy();
1505                         return;
1506                 }
1507         }
1508 
1509         SET_INTR(seek_interrupt);
1510         output_byte(FD_SEEK);
1511         output_byte(UNIT(current_drive));
1512         LAST_OUT(track);
1513 #ifdef DEBUGT
1514         debugt("seek command:");
1515 #endif
1516 }
1517 
1518 static void recal_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1519 {
1520 #ifdef DEBUGT
1521         debugt("recal interrupt:");
1522 #endif
1523         if (inr !=2 )
1524                 FDCS->reset = 1;
1525         else if (ST0 & ST0_ECE) {
1526                 switch(DRS->track){
1527                 case NEED_1_RECAL:
1528 #ifdef DEBUGT
1529                         debugt("recal interrupt need 1 recal:");
1530 #endif
1531                         /* after a second recalibrate, we still haven't
1532                          * reached track 0. Probably no drive. Raise an
1533                          * error, as failing immediately might upset 
1534                          * computers possessed by the Devil :-) */
1535                         cont->error();
1536                         cont->redo();
1537                         return;
1538                 case NEED_2_RECAL:
1539 #ifdef DEBUGT
1540                         debugt("recal interrupt need 2 recal:");
1541 #endif
1542                         /* If we already did a recalibrate, and we are not at
1543                          * track 0, this means we have moved. (The only way
1544                          * not to move at recalibration is to be already at
1545                          * track 0.) Clear the new change flag
1546                          */
1547 #ifdef DCL_DEBUG
1548                         if (DP->flags & FD_DEBUG){
1549                                 DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
1550                         }
1551 #endif
1552 
1553                         CLEARF(FD_DISK_NEWCHANGE);
1554                         DRS->select_date = jiffies;
1555                         /* fall through */
1556                 default:
1557 #ifdef DEBUGT
1558                         debugt("recal interrupt default:");
1559 #endif
1560                         /* Recalibrate moves the head by at most 80 steps. If
1561                          * after one recalibrate we don't have reached track
1562                          * 0, this might mean that we started beyond track 80.
1563                          * Try again.
1564                          */
1565                         DRS->track = NEED_1_RECAL;
1566                         break;
1567                 }
1568         } else
1569                 DRS->track = ST1;
1570         floppy_ready();
1571 }
1572 
1573 /*
1574  * Unexpected interrupt - Print as much debugging info as we can...
1575  * All bets are off...
1576  */
1577 static void unexpected_floppy_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1578 {
1579         int i;
1580         if ( initialising )
1581                 return;
1582         if(print_unex){
1583                 DPRINT("unexpected interrupt\n");
1584                 if ( inr >= 0 )
1585                         for(i=0; i<inr; i++)
1586                                 printk("%d %x\n", i, reply_buffer[i] );
1587         }
1588         while(1){
1589                 output_byte(FD_SENSEI);
1590                 inr=result();
1591                 if ( inr != 2 )
1592                         break;
1593                 if(print_unex){
1594                         printk("sensei\n");
1595                         for(i=0; i<inr; i++)
1596                                 printk("%d %x\n", i, reply_buffer[i] );
1597                 }
1598         }
1599         FDCS->reset = 1;
1600 }
1601 
1602 struct tq_struct floppy_tq = 
1603 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1604 
1605 /* interrupt handler */
1606 static void floppy_interrupt(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
1607 {
1608         void (*handler)(void) = DEVICE_INTR;
1609 
1610         lasthandler = handler;
1611         interruptjiffies = jiffies;
1612 
1613         floppy_enable_hlt();
1614         CLEAR_INTR;
1615         if ( fdc >= N_FDC || FDCS->address == -1){
1616                 /* we don't even know which FDC is the culprit */
1617                 printk("DOR0=%x\n", fdc_state[0].dor);
1618                 printk("floppy interrupt on bizarre fdc %d\n",fdc);
1619                 printk("handler=%p\n", handler);
1620                 is_alive("bizarre fdc");
1621                 return;
1622         }
1623         inr = result();
1624         if (!handler){
1625                 unexpected_floppy_interrupt();
1626                 is_alive("unexpected");
1627                 return;
1628         }
1629         if ( inr == 0 ){
1630                 do {
1631                         output_byte(FD_SENSEI);
1632                         inr = result();
1633                 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1634         }
1635         floppy_tq.routine = (void *)(void *) handler;
1636         queue_task_irq(&floppy_tq, &tq_timer);
1637         is_alive("normal interrupt end");
1638 }
1639 
1640 static void recalibrate_floppy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1641 {
1642 #ifdef DEBUGT
1643         debugt("recalibrate floppy:");
1644 #endif
1645         SET_INTR(recal_interrupt);
1646         output_byte(FD_RECALIBRATE);
1647         LAST_OUT(UNIT(current_drive));
1648 }
1649 
1650 /*
1651  * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
1652  */
1653 static void reset_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1654 {
1655 #ifdef DEBUGT
1656         debugt("reset interrupt:");
1657 #endif
1658         fdc_specify();          /* reprogram fdc */
1659         result();               /* get the status ready for set_fdc */
1660         if ( FDCS->reset )
1661                 cont->error(); /* a reset just after a reset. BAD! */
1662         cont->redo();
1663 }
1664 
1665 /*
1666  * reset is done by pulling bit 2 of DOR low for a while (old FDC's),
1667  * or by setting the self clearing bit 7 of STATUS (newer FDC's)
1668  */
1669 static void reset_fdc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1670 {
1671         SET_INTR(reset_interrupt);
1672         FDCS->reset = 0;
1673         reset_fdc_info(0);
1674         if ( FDCS->version >= FDC_82077 )
1675                 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1676         else {
1677                 outb_p(FDCS->dor & ~0x04, FD_DOR);
1678                 udelay(FD_RESET_DELAY);
1679                 outb(FDCS->dor, FD_DOR);
1680         }
1681 }
1682 
1683 static void empty(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1684 {
1685 }
1686 
1687 void show_floppy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1688 {
1689         int i;
1690 
1691         printk("\n");
1692         printk("floppy driver state\n");
1693         printk("-------------------\n");
1694         printk("now=%ld last interrupt=%d last called handler=%p\n", 
1695                jiffies, interruptjiffies, lasthandler);
1696 
1697 
1698 #ifdef CONFIG_FLOPPY_SANITY
1699         printk("timeout_message=%s\n", timeout_message);
1700         printk("last output bytes:\n");
1701         for(i=0; i < OLOGSIZE; i++)
1702                 printk("%2x %2x %ld\n",                
1703                        output_log[(i+output_log_pos) % OLOGSIZE].data,
1704                        output_log[(i+output_log_pos) % OLOGSIZE].status,
1705                        output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
1706         printk("last result at %d\n", resultjiffies);
1707         printk("last redo_fd_request at %d\n", lastredo);
1708         for(i=0; i<resultsize; i++){
1709                 printk("%2x ", reply_buffer[i]);
1710         }
1711         printk("\n");
1712 #endif
1713 
1714 #if 0
1715         for(i=0; i<N_FDC; i++){
1716                 if(FDCS->address != -1){
1717                         printk("dor %d = %x\n", i, fdc_state[i].dor );
1718                         outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1719                         udelay(1000); /* maybe we'll catch an interrupt... */
1720                 }
1721         }
1722 #endif
1723         printk("status=%x\n", inb_p(FD_STATUS));
1724         printk("fdc_busy=%d\n", fdc_busy);
1725         if( DEVICE_INTR)
1726                 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1727         if(floppy_tq.sync)
1728                 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1729         if(fd_timer.prev)
1730                 printk("fd_timer.function=%p\n", fd_timer.function);
1731         if(fd_timeout.prev){
1732                 printk("timer_table=%p\n",fd_timeout.function);
1733                 printk("expires=%ld\n",fd_timeout.expires-jiffies);
1734                 printk("now=%ld\n",jiffies);
1735         }
1736         printk("cont=%p\n", cont);
1737         printk("CURRENT=%p\n", CURRENT);
1738         printk("command_status=%d\n", command_status);
1739         printk("\n");
1740 }
1741 
1742 static void floppy_shutdown(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1743 {
1744         if(!initialising)
1745                 show_floppy();
1746         CLEAR_INTR;
1747         floppy_tq.routine = (void *)(void *) empty;
1748         del_timer( &fd_timer);
1749 
1750         floppy_enable_hlt();
1751         disable_dma(FLOPPY_DMA);
1752         /* avoid dma going to a random drive after shutdown */
1753 
1754         if(!initialising)
1755                 DPRINT("floppy timeout\n");
1756         FDCS->reset = 1;
1757         if (cont){
1758                 cont->done(0);
1759                 cont->redo(); /* this will recall reset when needed */
1760         } else {
1761                 printk("no cont in shutdown!\n");
1762                 process_fd_request();
1763         }
1764         is_alive("floppy shutdown");
1765 }
1766 /*typedef void (*timeout_fn)(unsigned long);*/
1767 
1768 /* start motor, check media-changed condition and write protection */
1769 static int start_motor( void (*function)(void)  )
     /* [previous][next][first][last][top][bottom][index][help] */
1770 {
1771         int mask, data;
1772 
1773         mask = 0xfc;
1774         data = UNIT(current_drive);
1775         if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1776                 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1777                         set_debugt();
1778                         /* no read since this drive is running */
1779                         DRS->first_read_date = 0;
1780                         /* note motor start time if motor is not yet running */
1781                         DRS->spinup_date = jiffies;
1782                         data |= (0x10 << UNIT(current_drive));
1783                 }
1784         } else
1785                 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1786                         mask &= ~(0x10 << UNIT(current_drive));
1787 
1788         /* starts motor and selects floppy */
1789         del_timer(motor_off_timer + current_drive);
1790         set_dor( fdc, mask, data);
1791 
1792         /* wait_for_completion also schedules reset if needed. */
1793         return(wait_for_completion(DRS->select_date+DP->select_delay,
1794                                    (timeout_fn) function));
1795 }
1796 
1797 static void floppy_ready(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1798 {
1799         CHECK_RESET;
1800         if(start_motor(floppy_ready)) return;
1801         if(fdc_dtr()) return;
1802 
1803 #ifdef DCL_DEBUG
1804         if (DP->flags & FD_DEBUG){
1805                 DPRINT("calling disk change from floppy_ready\n");
1806         }
1807 #endif
1808 
1809         if(!(raw_cmd.flags & FD_RAW_NO_MOTOR) &&
1810            disk_change(current_drive) &&
1811            !DP->select_delay)
1812                 twaddle(); /* this clears the dcl on certain drive/controller
1813                             * combinations */
1814 
1815         if ( raw_cmd.flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
1816                 perpendicular_mode();
1817                 fdc_specify(); /* must be done here because of hut, hlt ... */
1818                 seek_floppy();
1819         } else
1820                 setup_rw_floppy();
1821 }
1822 
1823 static void floppy_start(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1824 {
1825         reschedule_timeout(CURRENTD, "floppy start", 0);
1826 
1827         scandrives();
1828 #ifdef DCL_DEBUG
1829                 if (DP->flags & FD_DEBUG){
1830                         DPRINT("setting NEWCHANGE in floppy_start\n");
1831                 }
1832 #endif
1833         SETF(FD_DISK_NEWCHANGE);
1834         floppy_ready();
1835 }
1836 
1837 /*
1838  * ========================================================================
1839  * here ends the bottom half. Exported routines are:
1840  * floppy_start, floppy_off, floppy_ready, lock_fdc, unlock_fdc, set_fdc,
1841  * start_motor, reset_fdc, reset_fdc_info, interpret_errors.
1842  * Initialisation also uses output_byte, result, set_dor, floppy_interrupt
1843  * and set_dor.
1844  * ========================================================================
1845  */
1846 /*
1847  * General purpose continuations.
1848  * ==============================
1849  */
1850 
1851 static void do_wakeup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1852 {
1853         reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
1854         cont = 0;
1855         command_status += 2;
1856         wake_up(&command_done);
1857 }
1858 
1859 static struct cont_t wakeup_cont={
1860         empty,
1861         do_wakeup,
1862         empty,
1863         (done_f)empty
1864 };
1865 
1866 static int wait_til_done( void (*handler)(void ), int interruptible )
     /* [previous][next][first][last][top][bottom][index][help] */
1867 {
1868         int ret;
1869 
1870         floppy_tq.routine = (void *)(void *) handler;
1871         queue_task(&floppy_tq, &tq_timer);
1872 
1873         cli();
1874         while(command_status < 2 && NO_SIGNAL){
1875                 is_alive("wait_til_done");      
1876                 if (current->pid)
1877                         interruptible_sleep_on(&command_done);
1878                 else {
1879                         sti();
1880                         run_task_queue(&tq_timer);
1881                         cli();
1882                 }
1883         }
1884         if(command_status < 2){
1885                 sti();
1886                 floppy_shutdown();
1887                 process_fd_request();
1888                 return -EINTR;
1889         }
1890         sti();
1891 
1892         if ( FDCS->reset )
1893                 command_status = FD_COMMAND_ERROR;
1894         if ( command_status == FD_COMMAND_OKAY )
1895                 ret=0;
1896         else
1897                 ret=-EIO;
1898         command_status = FD_COMMAND_NONE;
1899         return ret;
1900 }
1901 
1902 static void generic_done(int result)
     /* [previous][next][first][last][top][bottom][index][help] */
1903 {
1904         command_status = result;
1905         cont = &wakeup_cont;
1906 }
1907 
1908 static void generic_success(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1909 {
1910         generic_done(1);
1911 }
1912 
1913 static void generic_failure(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1914 {
1915         generic_done(0);
1916 }
1917 
1918 static void success_and_wakeup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1919 {
1920         generic_success();
1921         do_wakeup();
1922 }
1923 
1924 static void failure_and_wakeup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1925 {
1926         generic_failure();
1927         do_wakeup();
1928 }
1929 
1930 /*
1931  * formatting and rw support.
1932  * ==========================
1933  */
1934 
1935 static int next_valid_format(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1936 {
1937         int probed_format;
1938 
1939         probed_format = DRS->probed_format;
1940         while(1){
1941                 if ( probed_format >= 8 ||
1942                     ! DP->autodetect[probed_format] ){
1943                         DRS->probed_format = 0;
1944                         return 1;
1945                 }
1946                 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1947                         DRS->probed_format = probed_format;
1948                         return 0;
1949                 }
1950                 probed_format++;
1951         }
1952 }
1953 
1954 static void bad_flp_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1955 {
1956         if ( probing ){
1957                 DRS->probed_format++;
1958                 if ( !next_valid_format())
1959                         return;
1960         }
1961         (*errors)++;
1962         if (*errors > DRWE->badness)
1963                 DRWE->badness = *errors;
1964         if (*errors > DP->max_errors.abort)
1965                 cont->done(0);
1966         if (*errors > DP->max_errors.reset)
1967                 FDCS->reset = 1;
1968         else if (*errors > DP->max_errors.recal)
1969                 DRS->track = NEED_2_RECAL;
1970 }
1971 
1972 static void set_floppy(int device)
     /* [previous][next][first][last][top][bottom][index][help] */
1973 {
1974         if (TYPE(device))
1975                 floppy = TYPE(device) + floppy_type;
1976         else
1977                 floppy = current_type[ DRIVE(device) ];
1978 }
1979 
1980 /*
1981  * formatting and support.
1982  * =======================
1983  */
1984 static void format_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1985 {
1986         switch (interpret_errors()){
1987         case 1:
1988                 cont->error();
1989         case 2:
1990                 break;
1991         case 0:
1992                 cont->done(1);
1993         }
1994         cont->redo();
1995 }
1996 
1997 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1998 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1999 #define CT(x) ( (x) | 0x40 )
2000 static void setup_format_params(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2001 {
2002         struct fparm {
2003                 unsigned char track,head,sect,size;
2004         } *here = (struct fparm *)floppy_track_buffer;
2005         int il,n;
2006         int count,head_shift,track_shift;
2007 
2008         raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
2009                 /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
2010         raw_cmd.rate = floppy->rate & 0x3;
2011         raw_cmd.cmd_count = NR_F;
2012         COMMAND = FM_MODE(floppy,FD_FORMAT);
2013         DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
2014         F_SIZECODE = FD_SIZECODE(floppy);
2015         F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
2016         F_GAP = floppy->fmt_gap;
2017         F_FILL = FD_FILL_BYTE;
2018 
2019         current_addr = floppy_track_buffer;
2020         raw_cmd.length = 4 * F_SECT_PER_TRACK;
2021 
2022         /* allow for about 30ms for data transport per track */
2023         head_shift  = (F_SECT_PER_TRACK + 5) / 6;
2024 
2025         /* a ``cylinder'' is two tracks plus a little stepping time */
2026         track_shift = 2 * head_shift + 1;
2027 
2028         /* position of logical sector 1 on this track */
2029         n = (track_shift * format_req.track + head_shift * format_req.head )
2030                 % F_SECT_PER_TRACK;
2031 
2032         /* determine interleave */
2033         il = 1;
2034         if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
2035                 il++;
2036 
2037         /* initialize field */
2038         for (count = 0; count < F_SECT_PER_TRACK; ++count) {
2039                 here[count].track = format_req.track;
2040                 here[count].head = format_req.head;
2041                 here[count].sect = 0;
2042                 here[count].size = F_SIZECODE;
2043         }
2044         /* place logical sectors */
2045         for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
2046                 here[n].sect = count;
2047                 n = (n+il) % F_SECT_PER_TRACK;
2048                 if (here[n].sect) { /* sector busy, find next free sector */
2049                         ++n;
2050                         if (n>= F_SECT_PER_TRACK) {
2051                                 n-=F_SECT_PER_TRACK;
2052                                 while (here[n].sect) ++n;
2053                         }
2054                 }
2055         }
2056 }
2057 
2058 static void redo_format(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2059 {
2060         raw_cmd.track = format_req.track << STRETCH(floppy);
2061         buffer_track = -1;
2062         setup_format_params();
2063         floppy_start();
2064 #ifdef DEBUGT
2065         debugt("queue format request");
2066 #endif
2067 }
2068 
2069 static struct cont_t format_cont={
2070         format_interrupt,
2071         redo_format,
2072         bad_flp_intr,
2073         generic_done };
2074 
2075 static int do_format(int device, struct format_descr *tmp_format_req)
     /* [previous][next][first][last][top][bottom][index][help] */
2076 {
2077         int ret;
2078         int drive=DRIVE(device);
2079 
2080         LOCK_FDC(drive,1);
2081         set_floppy(device);
2082         if (!floppy ||
2083             floppy->track > DP->tracks ||
2084             tmp_format_req->track >= floppy->track ||
2085             tmp_format_req->head >= floppy->head ||
2086             (floppy->sect << 2) % (1 <<  FD_SIZECODE(floppy)) ||
2087             !floppy->fmt_gap) {
2088                 process_fd_request();
2089                 return -EINVAL;
2090         }
2091         format_req = *tmp_format_req;
2092         format_errors = 0;
2093         cont = &format_cont;
2094         errors = &format_errors;
2095         IWAIT(redo_format);
2096         process_fd_request();
2097         return ret;
2098 }
2099 
2100 /*
2101  * Buffer read/write and support
2102  * =============================
2103  */
2104 
2105 /* new request_done. Can handle physical sectors which are smaller than a
2106  * logical buffer */
2107 static void request_done(int uptodate)
     /* [previous][next][first][last][top][bottom][index][help] */
2108 {
2109         int block;
2110 
2111         probing = 0;
2112         reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
2113 
2114         if (!CURRENT){
2115                 DPRINT("request list destroyed in floppy request done\n");
2116                 return;
2117         }
2118         if (uptodate){
2119                 /* maintain values for invalidation on geometry
2120                    change */
2121                 block = current_count_sectors + CURRENT->sector;
2122                 if (block > DRS->maxblock)
2123                         DRS->maxblock=block;
2124                 if ( block > floppy->sect)
2125                         DRS->maxtrack = 1;
2126 
2127                 /* unlock chained buffers */
2128                 while (current_count_sectors && CURRENT &&
2129                        current_count_sectors >= CURRENT->current_nr_sectors ){
2130                         current_count_sectors -= CURRENT->current_nr_sectors;
2131                         CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
2132                         CURRENT->sector += CURRENT->current_nr_sectors;
2133                         end_request(1);
2134                 }
2135                 if ( current_count_sectors && CURRENT){
2136                         /* "unlock" last subsector */
2137                         CURRENT->buffer += current_count_sectors <<9;
2138                         CURRENT->current_nr_sectors -= current_count_sectors;
2139                         CURRENT->nr_sectors -= current_count_sectors;
2140                         CURRENT->sector += current_count_sectors;
2141                         return;
2142                 }
2143 
2144                 if ( current_count_sectors && ! CURRENT )
2145                         DPRINT("request list destroyed in floppy request done\n");
2146 
2147         } else {
2148                 if(CURRENT->cmd == WRITE) {
2149                         /* record write error information */
2150                         DRWE->write_errors++;
2151                         if(DRWE->write_errors == 1) {
2152                                 DRWE->first_error_sector = CURRENT->sector;
2153                                 DRWE->first_error_generation = DRS->generation;
2154                         }
2155                         DRWE->last_error_sector = CURRENT->sector;
2156                         DRWE->last_error_generation = DRS->generation;
2157                 }
2158                 end_request(0);
2159         }
2160 }
2161 
2162 /* Interrupt handler evaluating the result of the r/w operation */
2163 static void rw_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2164 {
2165         int nr_sectors, ssize;
2166 
2167         if ( ! DRS->first_read_date )
2168                 DRS->first_read_date = jiffies;
2169 
2170         nr_sectors = 0;
2171         CODE2SIZE;
2172         nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
2173                 floppy->sect + ((R_SECTOR-SECTOR) <<  SIZECODE >> 2) -
2174                         (sector_t % floppy->sect) % ssize;
2175 
2176 #ifdef CONFIG_FLOPPY_SANITY
2177         if ( nr_sectors > current_count_sectors + ssize -
2178             (current_count_sectors + sector_t) % ssize +
2179             sector_t % ssize){
2180                 DPRINT2("long rw: %x instead of %lx\n",
2181                         nr_sectors, current_count_sectors);
2182                 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
2183                 printk("rh=%d h=%d\n", R_HEAD, HEAD);
2184                 printk("rt=%d t=%d\n", R_TRACK, TRACK);
2185                 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
2186                        sector_t, ssize);
2187         }
2188 #endif
2189         if ( nr_sectors < 0 )
2190                 nr_sectors = 0;
2191         if ( nr_sectors < current_count_sectors )
2192                 current_count_sectors = nr_sectors;
2193 
2194         switch (interpret_errors()){
2195         case 2:
2196                 cont->redo();
2197                 return;
2198         case 1:
2199                 if (  !current_count_sectors){
2200                         cont->error();
2201                         cont->redo();
2202                         return;
2203                 }
2204                 break;
2205         case 0:
2206                 if (  !current_count_sectors){
2207                         cont->redo();
2208                         return;
2209                 }
2210                 current_type[current_drive] = floppy;
2211                 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
2212                         floppy->size >> 1;
2213                 break;
2214         }
2215 
2216         if (probing) {
2217                 if (DP->flags & FTD_MSG)
2218                         DPRINT2("Auto-detected floppy type %s in fd%d\n",
2219                                 floppy->name,current_drive);
2220                 current_type[current_drive] = floppy;
2221                 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
2222                         floppy->size >> 1;
2223                 probing = 0;
2224         }
2225 
2226         if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
2227                 /* transfer directly from buffer */
2228                 cont->done(1);
2229         } else if ( CT(COMMAND) == FD_READ){
2230                 buffer_track = raw_cmd.track;
2231                 buffer_drive = current_drive;
2232                 if ( nr_sectors + sector_t > buffer_max )
2233                         buffer_max = nr_sectors + sector_t;
2234         }
2235         cont->redo();
2236 }
2237 
2238 /* Compute maximal contiguous buffer size. */
2239 static int buffer_chain_size(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2240 {
2241         struct buffer_head *bh;
2242         int size;
2243         char *base;
2244 
2245         base = CURRENT->buffer;
2246         size = CURRENT->current_nr_sectors << 9;
2247         bh = CURRENT->bh;
2248 
2249         if (bh){
2250                 bh = bh->b_reqnext;
2251                 while ( bh && bh->b_data == base + size ){
2252                         size += bh->b_size;
2253                         bh = bh->b_reqnext;
2254                 }
2255         }
2256         return size >> 9;
2257 }
2258 
2259 /* Compute the maximal transfer size */
2260 static int transfer_size(int ssize, int max_sector, int max_size)
     /* [previous][next][first][last][top][bottom][index][help] */
2261 {
2262         if ( max_sector > sector_t + max_size)
2263                 max_sector = sector_t + max_size;
2264 
2265         /* alignment */
2266         max_sector -= (max_sector % floppy->sect ) % ssize;
2267 
2268         /* transfer size, beginning not aligned */
2269         current_count_sectors = max_sector - sector_t ;
2270 
2271         return max_sector;
2272 }
2273 
2274 /*
2275  * Move data from/to the track buffer to/from the buffer cache.
2276  */
2277 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
     /* [previous][next][first][last][top][bottom][index][help] */
2278 {
2279         int remaining; /* number of transferred 512-byte sectors */
2280         struct buffer_head *bh;
2281         char *buffer, *dma_buffer;
2282         int size;
2283 
2284         if ( max_sector > max_sector_2 )
2285                 max_sector = max_sector_2;
2286 
2287         max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
2288 
2289         if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2290             buffer_max > sector_t + CURRENT->nr_sectors){
2291                 current_count_sectors = buffer_max - sector_t;
2292                 if ( current_count_sectors > CURRENT->nr_sectors )
2293                         current_count_sectors = CURRENT->nr_sectors;
2294         }
2295         remaining = current_count_sectors << 9;
2296 #ifdef CONFIG_FLOPPY_SANITY
2297         if ((remaining >> 9) > CURRENT->nr_sectors  && 
2298             CT(COMMAND) == FD_WRITE ){
2299                 DPRINT("in copy buffer\n");
2300                 printk("current_count_sectors=%ld\n", current_count_sectors);
2301                 printk("remaining=%d\n", remaining >> 9);
2302                 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
2303                 printk("CURRENT->current_nr_sectors=%ld\n",
2304                        CURRENT->current_nr_sectors);
2305                 printk("max_sector=%d\n", max_sector);
2306                 printk("ssize=%d\n", ssize);
2307         }
2308 #endif
2309 
2310         if ( max_sector > buffer_max )
2311                 buffer_max = max_sector;
2312 
2313         dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2314 
2315         bh = CURRENT->bh;
2316         size = CURRENT->current_nr_sectors << 9;
2317         buffer = CURRENT->buffer;
2318 
2319         while ( remaining > 0){
2320                 if ( size > remaining )
2321                         size = remaining;
2322 #ifdef CONFIG_FLOPPY_SANITY
2323                 if (dma_buffer + size >
2324                     floppy_track_buffer + (max_buffer_sectors << 10) ||
2325                     dma_buffer < floppy_track_buffer ){
2326                         DPRINT1("buffer overrun in copy buffer %d\n",
2327                                 (int) ((floppy_track_buffer - dma_buffer) >>9));
2328                         printk("sector_t=%d buffer_min=%d\n",
2329                                sector_t, buffer_min);
2330                         printk("current_count_sectors=%ld\n",
2331                                current_count_sectors);
2332                         if ( CT(COMMAND) == FD_READ )
2333                                 printk("read\n");
2334                         if ( CT(COMMAND) == FD_READ )
2335                                 printk("write\n");
2336                         break;
2337                 }
2338                 if ( ((unsigned long)buffer) % 512 )
2339                         DPRINT1("%p buffer not aligned\n", buffer);
2340 #endif
2341                 if ( CT(COMMAND) == FD_READ )
2342                         memcpy( buffer, dma_buffer, size);
2343                 else
2344                         memcpy( dma_buffer, buffer, size);
2345                 remaining -= size;
2346                 if ( !remaining)
2347                         break;
2348 
2349                 dma_buffer += size;
2350                 bh = bh->b_reqnext;
2351 #ifdef CONFIG_FLOPPY_SANITY
2352                 if ( !bh){
2353                         DPRINT("bh=null in copy buffer after copy\n");
2354                         break;
2355                 }
2356 #endif
2357                 size = bh->b_size;
2358                 buffer = bh->b_data;
2359         }
2360 #ifdef CONFIG_FLOPPY_SANITY
2361         if ( remaining ){
2362                 if ( remaining > 0 )
2363                         max_sector -= remaining >> 9;
2364                 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2365         }
2366 #endif
2367 }
2368 
2369 /*
2370  * Formulate a read/write request.
2371  * this routine decides where to load the data (directly to buffer, or to
2372  * tmp floppy area), how much data to load (the size of the buffer, the whole
2373  * track, or a single sector)
2374  * All floppy_track_buffer handling goes in here. If we ever add track buffer
2375  * allocation on the fly, it should be done here. No other part should need
2376  * modification.
2377  */
2378 
2379 static int make_raw_rw_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2380 {
2381         int aligned_sector_t;
2382         int max_sector, max_size, tracksize, ssize;
2383 
2384         set_fdc(DRIVE(CURRENT->dev));
2385 
2386         raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2387                 FD_RAW_NEED_SEEK;
2388         raw_cmd.cmd_count = NR_RW;
2389         if (CURRENT->cmd == READ){
2390                 raw_cmd.flags |= FD_RAW_READ;
2391                 COMMAND = FM_MODE(floppy,FD_READ);
2392         } else if (CURRENT->cmd == WRITE){
2393                 raw_cmd.flags |= FD_RAW_WRITE;
2394                 COMMAND = FM_MODE(floppy,FD_WRITE);
2395         } else {
2396                 DPRINT("make_raw_rw_request: unknown command\n");
2397                 return 0;
2398         }
2399 
2400         max_sector = floppy->sect * floppy->head;
2401 
2402         TRACK = CURRENT->sector / max_sector;
2403         sector_t = CURRENT->sector % max_sector;
2404         if ( floppy->track && TRACK >= floppy->track )
2405                 return 0;
2406         HEAD = sector_t / floppy->sect;
2407 
2408         if (((floppy->stretch & FD_SWAPSIDES) || TESTF( FD_NEED_TWADDLE)) && 
2409             sector_t < floppy->sect )
2410                 max_sector = floppy->sect;
2411 
2412         /* 2M disks have phantom sectors on the first track */
2413         if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2414                 max_sector = 2 * floppy->sect / 3;
2415                 if (sector_t >= max_sector){
2416                         current_count_sectors =  (floppy->sect - sector_t);
2417                         if ( current_count_sectors > CURRENT->nr_sectors )
2418                                 current_count_sectors = CURRENT->nr_sectors;
2419                         return 1;
2420                 }
2421                 SIZECODE = 2;
2422         } else
2423                 SIZECODE = FD_SIZECODE(floppy);
2424         raw_cmd.rate = floppy->rate & 3;
2425         if ((floppy->rate & FD_2M) &&
2426             (TRACK || HEAD ) &&
2427             raw_cmd.rate == 2)
2428                 raw_cmd.rate = 1;
2429 
2430         if ( SIZECODE )
2431                 SIZECODE2 = 0xff;
2432         else
2433                 SIZECODE2 = 0x80;
2434         raw_cmd.track = TRACK << STRETCH(floppy);
2435         DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,HEAD);
2436         GAP = floppy->gap;
2437         CODE2SIZE;
2438         SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2439         SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2440         tracksize = floppy->sect - floppy->sect % ssize;
2441         if ( tracksize < floppy->sect ){
2442                 SECT_PER_TRACK ++;
2443                 if (  tracksize <= sector_t % floppy->sect)
2444                         SECTOR--;
2445                 while ( tracksize <= sector_t % floppy->sect){
2446                         while( tracksize + ssize > floppy->sect ){
2447                                 SIZECODE--;
2448                                 ssize >>= 1;
2449                         }
2450                         SECTOR++; SECT_PER_TRACK ++;
2451                         tracksize += ssize;
2452                 }
2453                 max_sector = HEAD * floppy->sect + tracksize;
2454         } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2455                 max_sector = floppy->sect;
2456 
2457         aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2458         max_size = CURRENT->nr_sectors;
2459         if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2460             (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2461                 /* data already in track buffer */
2462                 if (CT(COMMAND) == FD_READ) {
2463                         copy_buffer(1, max_sector, buffer_max);
2464                         return 1;
2465                 }
2466         } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2467                 if (CT(COMMAND) == FD_WRITE){
2468                         if(sector_t + CURRENT->nr_sectors > ssize &&
2469                            sector_t + CURRENT->nr_sectors < ssize + ssize)
2470                                 max_size = ssize + ssize;
2471                         else
2472                                 max_size = ssize;
2473                 }
2474                 raw_cmd.flags &= ~FD_RAW_WRITE;
2475                 raw_cmd.flags |= FD_RAW_READ;
2476                 COMMAND = FM_MODE(floppy,FD_READ);
2477         } else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS ) {
2478                 int direct, indirect;
2479 
2480                 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2481                         sector_t;
2482 
2483                 max_size = buffer_chain_size();
2484                 if ( max_size > ( MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9)
2485                         max_size=(MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9;
2486                 /* 64 kb boundaries */
2487                 if (CROSS_64KB(CURRENT->buffer, max_size << 9))
2488                         max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2489                 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2490                 /*
2491                  * We try to read tracks, but if we get too many errors, we
2492                  * go back to reading just one sector at a time.
2493                  *
2494                  * This means we should be able to read a sector even if there
2495                  * are other bad sectors on this track.
2496                  */
2497                 if (!direct ||
2498                     (indirect * 2 > direct * 3 &&
2499                      *errors < DP->max_errors.read_track &&
2500                      /*!TESTF( FD_NEED_TWADDLE) &&*/
2501                      ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
2502                         max_size = CURRENT->nr_sectors;
2503                 } else {
2504                         current_addr = CURRENT->buffer;
2505                         raw_cmd.length = current_count_sectors << 9;
2506                         if (raw_cmd.length == 0){
2507                                 DPRINT("zero dma transfer attempted from make_raw_request\n");
2508                                 DPRINT3("indirect=%d direct=%d sector_t=%d",
2509                                         indirect, direct, sector_t);
2510                                 return 0;
2511                         }
2512                         return 2;
2513                 }
2514         }
2515 
2516         if ( CT(COMMAND) == FD_READ )
2517                 max_size = max_sector; /* unbounded */
2518 
2519         /* claim buffer track if needed */
2520         if (buffer_track != raw_cmd.track ||  /* bad track */
2521             buffer_drive !=current_drive || /* bad drive */
2522             sector_t > buffer_max ||
2523             sector_t < buffer_min ||
2524             ((CT(COMMAND) == FD_READ ||
2525               (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2526              max_sector > 2 * max_buffer_sectors + buffer_min &&
2527              max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2528             /* not enough space */ ){
2529                 buffer_track = -1;
2530                 buffer_drive = current_drive;
2531                 buffer_max = buffer_min = aligned_sector_t;
2532         }
2533         current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2534 
2535         if ( CT(COMMAND) == FD_WRITE ){
2536                 /* copy write buffer to track buffer.
2537                  * if we get here, we know that the write
2538                  * is either aligned or the data already in the buffer
2539                  * (buffer will be overwritten) */
2540 #ifdef CONFIG_FLOPPY_SANITY
2541                 if (sector_t != aligned_sector_t && buffer_track == -1 )
2542                         DPRINT("internal error offset !=0 on write\n");
2543 #endif
2544                 buffer_track = raw_cmd.track;
2545                 buffer_drive = current_drive;
2546                 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2547         } else
2548                 transfer_size(ssize, max_sector,
2549                               2*max_buffer_sectors+buffer_min-aligned_sector_t);
2550 
2551         /* round up current_count_sectors to get dma xfer size */
2552         raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2553         raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2554         raw_cmd.length <<= 9;
2555 #ifdef CONFIG_FLOPPY_SANITY
2556         if ((raw_cmd.length < current_count_sectors << 9) ||
2557             (current_addr != CURRENT->buffer &&
2558              CT(COMMAND) == FD_WRITE &&
2559              (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2560               aligned_sector_t < buffer_min )) ||
2561             raw_cmd.length % ( 128 << SIZECODE ) ||
2562             raw_cmd.length <= 0 || current_count_sectors <= 0){
2563                 DPRINT2("fractionary current count b=%lx s=%lx\n",
2564                         raw_cmd.length, current_count_sectors);
2565                 if ( current_addr != CURRENT->buffer )
2566                         printk("addr=%d, length=%ld\n",
2567                                (int) ((current_addr - floppy_track_buffer ) >> 9),
2568                                current_count_sectors);
2569                 printk("st=%d ast=%d mse=%d msi=%d\n",
2570                        sector_t, aligned_sector_t, max_sector, max_size);
2571                 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2572                 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2573                        COMMAND, SECTOR, HEAD, TRACK);
2574                 printk("buffer drive=%d\n", buffer_drive);
2575                 printk("buffer track=%d\n", buffer_track);
2576                 printk("buffer_min=%d\n", buffer_min );
2577                 printk("buffer_max=%d\n", buffer_max );
2578                 return 0;
2579         }
2580 
2581         if (current_addr != CURRENT->buffer ){
2582                 if (current_addr < floppy_track_buffer ||
2583                     current_count_sectors < 0 ||
2584                     raw_cmd.length < 0 ||
2585                     current_addr + raw_cmd.length >
2586                     floppy_track_buffer + (max_buffer_sectors  << 10)){
2587                         DPRINT("buffer overrun in schedule dma\n");
2588                         printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2589                                sector_t, buffer_min,
2590                                raw_cmd.length >> 9 );
2591                         printk("current_count_sectors=%ld\n",
2592                                current_count_sectors);
2593                         if ( CT(COMMAND) == FD_READ )
2594                                 printk("read\n");
2595                         if ( CT(COMMAND) == FD_READ )
2596                                 printk("write\n");
2597                         return 0;
2598                 }
2599         } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2600                    current_count_sectors > CURRENT->nr_sectors){
2601                 DPRINT("buffer overrun in direct transfer\n");
2602                 return 0;
2603         } else if ( raw_cmd.length < current_count_sectors << 9 ){
2604                 DPRINT("more sectors than bytes\n");
2605                 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2606                 printk("sectors=%ld\n", current_count_sectors);
2607         }
2608         if (raw_cmd.length == 0){
2609                 DPRINT("zero dma transfer attempted from make_raw_request\n");
2610                 return 0;
2611         }
2612 #endif
2613         return 2;
2614 }
2615 
2616 static void redo_fd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2617 {
2618 #define REPEAT {request_done(0); continue; }
2619         int device;
2620         int tmp;
2621         int error;
2622 
2623 
2624         error = -1;
2625         lastredo = jiffies;
2626         if (current_drive < N_DRIVE)
2627                 floppy_off(current_drive);
2628 
2629         if (CURRENT && CURRENT->dev < 0){
2630                 DPRINT("current dev < 0!\n");
2631                 return;
2632         }
2633 
2634         while(1){
2635                 if (!CURRENT) {
2636                         CLEAR_INTR;
2637                         unlock_fdc();
2638                         return;
2639                 }
2640                 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2641                         panic(DEVICE_NAME ": request list destroyed");
2642                 if (CURRENT->bh && !CURRENT->bh->b_lock)
2643                         panic(DEVICE_NAME ": block not locked");
2644 #if 0
2645                 if (!CURRENT->bh->b_count && 
2646                     (CURRENT->errors || error == CURRENT->dev)){
2647                         error=CURRENT->dev;
2648                         DPRINT("skipping read ahead buffer\n");
2649                         REPEAT;
2650                 }
2651 #endif
2652                 error=-1;
2653                 device = CURRENT->dev;
2654                 set_fdc( DRIVE(device));
2655                 reschedule_timeout(CURRENTD, "redo fd request", 0);
2656 
2657                 set_floppy(device);
2658                 if(start_motor(redo_fd_request)) return;
2659                 if(test_bit(current_drive, &fake_change) ||
2660                    TESTF(FD_DISK_CHANGED)){
2661                         DPRINT("disk absent or changed during operation\n");
2662                         REPEAT;
2663                 }
2664                 if (!floppy) { /* Autodetection */
2665                         if (!probing){
2666                                 DRS->probed_format = 0;
2667                                 if ( next_valid_format() ){
2668                                         DPRINT("no autodetectable formats\n");
2669                                         floppy = NULL;
2670                                         REPEAT;
2671                                 }
2672                         }
2673                         probing = 1;
2674                         floppy = floppy_type+DP->autodetect[DRS->probed_format];
2675                 } else
2676                         probing = 0;
2677                 errors = & (CURRENT->errors);
2678                 tmp = make_raw_rw_request();
2679                 if ( tmp < 2 ){
2680                         request_done(tmp);
2681                         continue;
2682                 }
2683 
2684                 if (TESTF(FD_NEED_TWADDLE))
2685                         twaddle();
2686                 floppy_tq.routine = (void *)(void *) floppy_start;
2687                 queue_task(&floppy_tq, &tq_timer);
2688 #ifdef DEBUGT
2689                 debugt("queue fd request");
2690 #endif
2691                 return;
2692         }
2693 #undef REPEAT
2694 }
2695 
2696 static struct cont_t rw_cont={
2697         rw_interrupt,
2698         redo_fd_request,
2699         bad_flp_intr,
2700         request_done };
2701 
2702 struct tq_struct request_tq = 
2703 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2704 
2705 static void process_fd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2706 {
2707         cont = &rw_cont;
2708         queue_task(&request_tq, &tq_timer);
2709 }
2710 
2711 static void do_fd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2712 {
2713         if (fdc_busy){
2714                 /* fdc busy, this new request will be treated when the
2715                    current one is done */
2716                 is_alive("do fd request, old request running");
2717                 return;
2718         }
2719         /* fdc_busy cannot be set by an interrupt or a bh */
2720         floppy_grab_irq_and_dma();
2721         fdc_busy=1;
2722         reschedule_timeout(MAXTIMEOUT, "do fd request",0);
2723         process_fd_request();
2724         is_alive("do fd request");
2725 }
2726 
2727 static struct cont_t poll_cont={
2728         success_and_wakeup,
2729         floppy_ready,
2730         generic_failure,
2731         generic_done };
2732 
2733 static int poll_drive(int interruptible, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
2734 {
2735         int ret;
2736         /* no auto-sense, just clear dcl */
2737         raw_cmd.flags= flag;
2738         raw_cmd.track=0;
2739         raw_cmd.cmd_count=0;
2740         cont = &poll_cont;
2741 #ifdef DCL_DEBUG
2742                 if (DP->flags & FD_DEBUG){
2743                         DPRINT("setting NEWCHANGE in poll_drive\n");
2744                 }
2745 #endif
2746         SETF(FD_DISK_NEWCHANGE);
2747         WAIT(floppy_ready);
2748         return ret;
2749 }
2750 
2751 /*
2752  * User triggered reset
2753  * ====================
2754  */
2755 
2756 static void reset_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2757 {
2758         printk("weird, reset interrupt called\n");
2759 }
2760 
2761 static struct cont_t reset_cont={
2762         reset_intr,
2763         success_and_wakeup,
2764         generic_failure,
2765         generic_done };
2766 
2767 static int user_reset_fdc(int drive, int arg, int interruptible)
     /* [previous][next][first][last][top][bottom][index][help] */
2768 {
2769         int ret;
2770 
2771         ret=0;
2772         if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2773                 return 0;
2774         LOCK_FDC(drive,interruptible);
2775         if(arg == FD_RESET_ALWAYS)
2776                 FDCS->reset=1;
2777         if ( FDCS->reset ){
2778                 cont = &reset_cont;
2779                 reschedule_timeout(CURRENTD, "user reset fdc", 0);
2780                 WAIT(reset_fdc);
2781         }
2782         process_fd_request();
2783         return ret;
2784 }
2785 
2786 /*
2787  * Misc Ioctl's and support
2788  * ========================
2789  */
2790 static int fd_copyout(void *param, volatile void *address, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
2791 {
2792         int i;
2793 
2794         i = verify_area(VERIFY_WRITE,param,size);
2795         if (i)
2796                 return i;
2797         memcpy_tofs(param,(void *) address, size);
2798         return 0;
2799 }
2800 
2801 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2802 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2803 
2804 static const char *drive_name(int type, int drive )
     /* [previous][next][first][last][top][bottom][index][help] */
2805 {
2806         struct floppy_struct *floppy;   
2807 
2808         if ( type )
2809                 floppy = floppy_type + type;
2810         else {
2811                 if ( UDP->native_format )
2812                         floppy = floppy_type + UDP->native_format;
2813                 else
2814                         return "(null)";
2815         }
2816         if ( floppy->name )
2817                 return floppy->name;
2818         else
2819                 return "(null)";
2820 }
2821 
2822 /* raw commands */
2823 static struct cont_t raw_cmd_cont={
2824         success_and_wakeup,
2825         failure_and_wakeup,
2826         generic_failure,
2827         generic_done };
2828 
2829 static int raw_cmd_ioctl(void *param)
     /* [previous][next][first][last][top][bottom][index][help] */
2830 {
2831         int i, drive, count, ret;
2832 
2833         if ( FDCS->rawcmd <= 1 )
2834                 FDCS->rawcmd = 1;
2835         for ( drive= 0; drive < N_DRIVE; drive++){
2836                 if ( FDC(drive) != fdc)
2837                         continue;
2838                 if ( drive == current_drive ){
2839                         if ( UDRS->fd_ref > 1 ){
2840                                 FDCS->rawcmd = 2;
2841                                 break;
2842                         }
2843                 } else if ( UDRS->fd_ref ){
2844                         FDCS->rawcmd = 2;
2845                         break;
2846                 }
2847         }
2848 
2849         if(FDCS->reset)
2850                 return -EIO;
2851 
2852         COPYIN(raw_cmd);
2853         raw_cmd.rate &= 0x03;   
2854         count = raw_cmd.length;
2855         if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2856                 if(count > max_buffer_sectors * 1024 )
2857                         return -ENOMEM;
2858                 if(count == 0){
2859                         printk("attempt to do a 0 byte dma transfer\n");
2860                         return -EINVAL;
2861                 }
2862                 buffer_track = -1;
2863         }
2864         if ( raw_cmd.flags & FD_RAW_WRITE ){
2865                 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2866                 if (i)
2867                         return i;
2868                 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2869         }
2870 
2871         current_addr = floppy_track_buffer;
2872         cont = &raw_cmd_cont;
2873         IWAIT(floppy_start);
2874 #ifdef DCL_DEBUG
2875         if (DP->flags & FD_DEBUG){
2876                 DPRINT("calling disk change from raw_cmd ioctl\n");
2877         }
2878 #endif
2879         if( disk_change(current_drive) )
2880                 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2881         else
2882                 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2883         if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2884                 motor_off_callback(current_drive);      
2885 
2886         if ( !ret && !FDCS->reset ){
2887                 raw_cmd.reply_count = inr;
2888                 for( i=0; i< raw_cmd.reply_count; i++)
2889                         raw_cmd.reply[i] = reply_buffer[i];
2890                 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2891                         raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2892         } else
2893                 ret = -EIO;
2894         DRS->track = NO_TRACK;
2895         if ( ret )
2896                 return ret;
2897 
2898         if ( raw_cmd.flags & FD_RAW_READ ){
2899                 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2900                 if (i)
2901                         return i;
2902         }
2903        
2904         return COPYOUT(raw_cmd);
2905 }
2906 
2907 static int invalidate_drive(int rdev)
     /* [previous][next][first][last][top][bottom][index][help] */
2908 {
2909         /* invalidate the buffer track to force a reread */
2910         set_bit( DRIVE(rdev), &fake_change);
2911         process_fd_request();
2912         check_disk_change(rdev);
2913         return 0;
2914 }
2915 
2916 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
2917     unsigned long param)
2918 {
2919 #define IOCTL_MODE_BIT 8
2920 #define OPEN_WRITE_BIT 16
2921 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2922 
2923         struct floppy_struct newparams;
2924         struct format_descr tmp_format_req;
2925         int i,device,drive,type,cnt;
2926         struct floppy_struct *this_floppy;
2927         const char *name;
2928 
2929         device = inode->i_rdev;
2930         switch (cmd) {
2931                 RO_IOCTLS(device,param);
2932         }
2933         type = TYPE(device);
2934         drive = DRIVE(device);
2935         switch (cmd) {
2936         case FDGETDRVTYP:
2937                 i=verify_area(VERIFY_WRITE,(void *) param,16);
2938                 if (i)
2939                         return i;
2940                 name = drive_name(type,drive);
2941                 for ( cnt=0; cnt<16; cnt++){
2942                         put_user(name[cnt], ((char*)param)+cnt);
2943                         if ( ! *name )
2944                                 break;
2945                 }
2946                 return 0;
2947         case FDGETMAXERRS:
2948                 return COPYOUT(UDP->max_errors);
2949         case FDGETPRM:
2950                 if (type)
2951                         this_floppy = &floppy_type[type];
2952                 else if ((this_floppy = current_type[drive]) ==
2953                          NULL)
2954                         return -ENODEV;
2955                 return COPYOUT(this_floppy[0]);
2956         case FDPOLLDRVSTAT:
2957                 LOCK_FDC(drive,1);
2958                 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2959                 process_fd_request();
2960                 /* fall through */
2961         case FDGETDRVSTAT:
2962                 return COPYOUT(*UDRS);
2963         case FDGETFDCSTAT:
2964                 return COPYOUT(*UFDCS);
2965         case FDGETDRVPRM:
2966                 return COPYOUT(*UDP);
2967         case FDWERRORGET:
2968                 return COPYOUT(*UDRWE);
2969         }
2970         if (!IOCTL_ALLOWED)
2971                 return -EPERM;
2972         switch (cmd) {
2973         case FDWERRORCLR:
2974                 UDRWE->write_errors = 0;
2975                 UDRWE->first_error_sector = 0;
2976                 UDRWE->first_error_generation = 0;
2977                 UDRWE->last_error_sector = 0;
2978                 UDRWE->last_error_generation = 0;
2979                 UDRWE->badness = 0;
2980                 return 0;
2981         case FDRAWCMD:
2982                 if (type)
2983                         return -EINVAL;
2984                 LOCK_FDC(drive,1);
2985                 set_floppy(device);
2986                 CALL(i = raw_cmd_ioctl((void *) param));
2987                 process_fd_request();
2988                 return i;
2989         case FDFMTTRK:
2990                 if (UDRS->fd_ref != 1)
2991                         return -EBUSY;
2992                 COPYIN(tmp_format_req);
2993                 return do_format(device, &tmp_format_req);
2994         case FDSETMAXERRS:
2995                 return COPYIN(UDP->max_errors);
2996         case FDFMTBEG:
2997                 return 0;
2998         case FDCLRPRM:
2999                 LOCK_FDC(drive,1);
3000                 current_type[drive] = NULL;
3001                 floppy_sizes[drive] = MAX_DISK_SIZE;
3002                 UDRS->keep_data = 0;
3003                 return invalidate_drive(device);
3004         case FDFMTEND:
3005         case FDFLUSH:
3006                 LOCK_FDC(drive,1);
3007                 return invalidate_drive(device);
3008         case FDSETPRM:
3009         case FDDEFPRM:
3010                 COPYIN(newparams);
3011                 /* sanity checking for parameters.*/
3012                 if(newparams.sect <= 0 ||
3013                    newparams.head <= 0 ||
3014                    newparams.track <= 0 ||
3015                    newparams.track > UDP->tracks>> STRETCH(&newparams) ||
3016                    /* check if reserved bits are set */
3017                    (newparams.stretch & ~(FD_STRETCH | FD_SWAPSIDES)) != 0)
3018                         return -EINVAL;
3019                 if ( type){
3020                         if ( !suser() )
3021                                 return -EPERM;
3022                         LOCK_FDC(drive,1);
3023                         for ( cnt = 0; cnt < N_DRIVE; cnt++){
3024                                 if (TYPE(drive_state[cnt].fd_device) == type &&
3025                                     drive_state[cnt].fd_ref)
3026                                         set_bit(drive, &fake_change);
3027                         }
3028                         floppy_type[type] = newparams;
3029                         floppy_type[type].name="user format";
3030                         for (cnt = type << 2 ;
3031                              cnt < (type << 2 ) + 4 ;
3032                              cnt++)
3033                                 floppy_sizes[cnt]=
3034                                         floppy_sizes[cnt+0x80]=
3035                                                 floppy_type[type].size>>1;
3036                         process_fd_request();
3037                         for ( cnt = 0; cnt < N_DRIVE; cnt++){
3038                                 if (TYPE(drive_state[cnt].fd_device) == type &&
3039                                     drive_state[cnt].fd_ref)
3040                                         check_disk_change(drive_state[cnt].
3041                                                           fd_device);
3042                         }
3043                         return 0;
3044                 }
3045 
3046                 LOCK_FDC(drive,1);
3047                 if ( cmd != FDDEFPRM )
3048                         /* notice a disk change immediately, else
3049                          * we loose our settings immediately*/
3050                         CALL(poll_drive(1,0));
3051                 user_params[drive] = newparams;
3052                 if (buffer_drive == drive &&
3053                     buffer_max > user_params[drive].sect)
3054                         buffer_max=user_params[drive].sect;
3055                 current_type[drive] = &user_params[drive];
3056                 floppy_sizes[drive] = user_params[drive].size >> 1;
3057                 if (cmd == FDDEFPRM)
3058                         DRS->keep_data = -1;
3059                 else
3060                         DRS->keep_data = 1;
3061                 /* invalidation. Invalidate only when needed, i.e.
3062                  * when there are already sectors in the buffer cache
3063                  * whose number will change. This is useful, because
3064                  * mtools often changes the geometry of the disk after
3065                  * looking at the boot block */
3066                 if (DRS->maxblock >
3067                     user_params[drive].sect ||
3068                     DRS->maxtrack )
3069                         invalidate_drive(device);
3070                 else
3071                         process_fd_request();
3072                 return 0;
3073         case FDRESET:
3074                 return user_reset_fdc( drive, (int)param, 1);
3075         case FDMSGON:
3076                 UDP->flags |= FTD_MSG;
3077                 return 0;
3078         case FDMSGOFF:
3079                 UDP->flags &= ~FTD_MSG;
3080                 return 0;
3081         case FDSETEMSGTRESH:
3082                 UDP->max_errors.reporting =
3083                         (unsigned short) (param & 0x0f);
3084                 return 0;
3085         case FDTWADDLE:
3086                 LOCK_FDC(drive,1);
3087                 twaddle();
3088                 process_fd_request();
3089         }
3090         if ( ! suser() )
3091                 return -EPERM;
3092         switch(cmd){
3093         case FDSETDRVPRM:
3094                 return COPYIN(*UDP);
3095         default:
3096                 return -EINVAL;
3097         }
3098         return 0;
3099 #undef IOCTL_ALLOWED
3100 }
3101 
3102 static void config_types(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3103 {
3104         int first=1;
3105         int drive;
3106 
3107         /* read drive info out of physical cmos */
3108         drive=0;
3109         if (!UDP->cmos )
3110                 UDP->cmos= FLOPPY0_TYPE;
3111         drive=1;
3112         if (!UDP->cmos && FLOPPY1_TYPE)
3113                 UDP->cmos = FLOPPY1_TYPE;
3114 
3115         /* XXX */
3116         /* additional physical CMOS drive detection should go here */
3117 
3118         for (drive=0; drive < N_DRIVE; drive++){
3119                 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
3120                         memcpy((char *) UDP,
3121                                (char *) (&default_drive_params[(int)UDP->cmos].params),
3122                                sizeof(struct floppy_drive_params));
3123                 if (UDP->cmos){
3124                         if (first)
3125                                 printk("Floppy drive(s): ");
3126                         else
3127                                 printk(", ");
3128                         first=0;
3129                         if (UDP->cmos > 0 ){
3130                                 ALLOWED_DRIVE_MASK |= 1 << drive;
3131                                 printk("fd%d is %s", drive,
3132                                        default_drive_params[(int)UDP->cmos].name);
3133                         } else
3134                                 printk("fd%d is unknown type %d",drive,
3135                                        UDP->cmos);
3136                 }
3137         }
3138         if(!first)
3139                 printk("\n");
3140 }
3141 
3142 static int floppy_read(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
3143                        char * buf, int count)
3144 {
3145         int drive = DRIVE(inode->i_rdev);
3146 
3147         check_disk_change(inode->i_rdev);
3148         if (UTESTF(FD_DISK_CHANGED))
3149                 return -ENXIO;
3150         return block_read(inode, filp, buf, count);
3151 }
3152 
3153 static int floppy_write(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
3154                         const char * buf, int count)
3155 {
3156         int block;
3157         int ret;
3158         int drive = DRIVE(inode->i_rdev);
3159 
3160         if(!UDRS->maxblock)
3161                 UDRS->maxblock=1;/* make change detectable */
3162         check_disk_change(inode->i_rdev);
3163         if (UTESTF(FD_DISK_CHANGED)) 
3164                 return -ENXIO;
3165         if(!UTESTF(FD_DISK_WRITABLE))
3166                 return -EROFS;
3167         block = (filp->f_pos + count) >> 9;
3168         if(block > UDRS->maxblock)
3169                 UDRS->maxblock = block;
3170         ret= block_write(inode, filp, buf, count);
3171         return ret;
3172 }
3173 
3174 static void floppy_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
3175 {
3176         int drive;
3177         
3178         drive = DRIVE(inode->i_rdev);
3179 
3180         if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
3181                 /* if the file is mounted OR (writable now AND writable at
3182                  * open time) Linus: Does this cover all cases? */
3183                 block_fsync(inode,filp);
3184                         
3185         if (UDRS->fd_ref < 0)
3186                 UDRS->fd_ref=0;
3187         else if (!UDRS->fd_ref--) {
3188                 DPRINT("floppy_release with fd_ref == 0");
3189                 UDRS->fd_ref = 0;
3190         }
3191         floppy_release_irq_and_dma();
3192 }
3193 
3194 /*
3195  * floppy_open check for aliasing (/dev/fd0 can be the same as
3196  * /dev/PS0 etc), and disallows simultaneous access to the same
3197  * drive with different device numbers.
3198  */
3199 #define RETERR(x) \
3200         do{floppy_release(inode,filp); \
3201            return -(x);}while(0)
3202 
3203 static int floppy_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
3204 {
3205         int drive;
3206         int old_dev;
3207         int try;
3208         char *tmp;
3209 
3210         if (!filp) {
3211                 DPRINT("Weird, open called with filp=0\n");
3212                 return -EIO;
3213         }
3214 
3215         drive = DRIVE(inode->i_rdev);
3216 
3217         if (drive >= N_DRIVE || 
3218             !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
3219             fdc_state[FDC(drive)].version == FDC_NONE)
3220                 return -ENXIO;
3221 
3222         if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3223                 return -ENXIO;
3224         old_dev = UDRS->fd_device;
3225         if (UDRS->fd_ref && old_dev != inode->i_rdev)
3226                 return -EBUSY;
3227 
3228         if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3229                 USETF(FD_DISK_CHANGED);
3230                 USETF(FD_VERIFY);
3231         }
3232 
3233         if(UDRS->fd_ref == -1 ||
3234            (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3235                 return -EBUSY;
3236 
3237         if (floppy_grab_irq_and_dma())
3238                 return -EBUSY;
3239 
3240         if (filp->f_flags & O_EXCL)
3241                 UDRS->fd_ref = -1;
3242         else
3243                 UDRS->fd_ref++;
3244 
3245         if (!floppy_track_buffer){
3246                 /* if opening an ED drive, reserve a big buffer,
3247                  * else reserve a small one */
3248                 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3249                         try = 64; /* Only 48 actually useful */
3250                 else
3251                         try = 32; /* Only 24 actually useful */
3252 
3253                 tmp=(char *)dma_mem_alloc(1024 * try);
3254                 if (!tmp) {
3255                         try >>= 1; /* buffer only one side */
3256                         if (try < 16)
3257                                 try=16;
3258                         tmp= (char *)dma_mem_alloc(1024*try);
3259                 }
3260                 if (!tmp) {
3261                         DPRINT("Unable to allocate DMA memory\n");
3262                         RETERR(ENXIO);
3263                 }
3264                 if (floppy_track_buffer){
3265                         free_pages((unsigned long)tmp,__get_order(try*1024));
3266                 }else {
3267                         floppy_track_buffer = tmp;
3268                         max_buffer_sectors = try;
3269                 }
3270         }
3271 
3272         UDRS->fd_device = inode->i_rdev;
3273 
3274         if (old_dev && old_dev != inode->i_rdev) {
3275                 if (buffer_drive == drive)
3276                         buffer_track = -1;
3277                 invalidate_buffers(old_dev);
3278         }
3279 
3280         /* Allow ioctls if we have write-permissions even if read-only open */
3281         if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3282                 filp->f_mode |= IOCTL_MODE_BIT;
3283         if (filp->f_mode & 2)
3284                 filp->f_mode |= OPEN_WRITE_BIT;
3285 
3286         if (UFDCS->rawcmd == 1)
3287                UFDCS->rawcmd = 2;
3288 
3289         if (filp->f_flags & O_NDELAY)
3290                 return 0;
3291         if (filp->f_mode & 3) {
3292                 UDRS->last_checked = 0;
3293                 check_disk_change(inode->i_rdev);
3294                 if (UTESTF(FD_DISK_CHANGED))
3295                         RETERR(ENXIO);
3296         }
3297         if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3298                 RETERR(EROFS);
3299         return 0;
3300 #undef RETERR
3301 }
3302 
3303 /*
3304  * Check if the disk has been changed or if a change has been faked.
3305  */
3306 static int check_floppy_change(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
3307 {
3308         int drive = DRIVE( dev );
3309 
3310         if (MAJOR(dev) != MAJOR_NR) {
3311                 DPRINT("floppy_changed: not a floppy\n");
3312                 return 0;
3313         }
3314 
3315         if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
3316                 return 1;
3317 
3318         if(UDRS->last_checked + UDP->checkfreq < jiffies){
3319                 lock_fdc(drive,0);
3320                 poll_drive(0,0);
3321                 process_fd_request();
3322         }
3323 
3324         if(UTESTF(FD_DISK_CHANGED) ||
3325            UTESTF(FD_VERIFY) ||
3326            test_bit(drive, &fake_change) ||
3327            (!TYPE(dev) && !current_type[drive]))
3328                 return 1;
3329         return 0;
3330 }
3331 
3332 /* revalidate the floppy disk, i.e. trigger format autodetection by reading
3333  * the bootblock (block 0). "Autodetection" is also needed to check whether
3334  * there is a disk in the drive at all... Thus we also do it for fixed
3335  * geometry formats */
3336 static int floppy_revalidate(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
3337 {
3338 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3339         struct buffer_head * bh;
3340         int drive=DRIVE(dev);
3341         int cf;
3342 
3343         if(UTESTF(FD_DISK_CHANGED) || 
3344            UTESTF(FD_VERIFY) ||
3345            test_bit(drive, &fake_change) || 
3346            NO_GEOM){
3347                 lock_fdc(drive,0);
3348                 cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
3349                 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3350                         process_fd_request(); /*already done by another thread*/
3351                         return 0;
3352                 }
3353                 UDRS->maxblock = 0;
3354                 UDRS->maxtrack = 0;
3355                 if ( buffer_drive == drive)
3356                         buffer_track = -1;
3357                 clear_bit(drive, &fake_change);
3358                 UCLEARF(FD_DISK_CHANGED);
3359                 if(cf)
3360                         UDRS->generation++;
3361                 if(NO_GEOM){
3362                         /* auto-sensing */
3363                         int size = floppy_blocksizes[MINOR(dev)];
3364                         if (!size)
3365                                 size = 1024;
3366                         if (!(bh = getblk(dev,0,size))){
3367                                 process_fd_request();
3368                                 return 1;
3369                         }
3370                         if ( bh && ! bh->b_uptodate)
3371                                 ll_rw_block(READ, 1, &bh);
3372                         process_fd_request();
3373                         wait_on_buffer(bh);
3374                         brelse(bh);
3375                         return 0;
3376                 } 
3377                 if(cf)
3378                                 poll_drive(0, FD_RAW_NEED_DISK);
3379                 process_fd_request();
3380         }
3381         return 0;
3382 }
3383 
3384 static struct file_operations floppy_fops = {
3385         NULL,                   /* lseek - default */
3386         floppy_read,            /* read - general block-dev read */
3387         floppy_write,           /* write - general block-dev write */
3388         NULL,                   /* readdir - bad */
3389         NULL,                   /* select */
3390         fd_ioctl,               /* ioctl */
3391         NULL,                   /* mmap */
3392         floppy_open,            /* open */
3393         floppy_release,         /* release */
3394         block_fsync,            /* fsync */
3395         NULL,                   /* fasync */
3396         check_floppy_change,    /* media_change */
3397         floppy_revalidate,      /* revalidate */
3398 };
3399 
3400 /*
3401  * Floppy Driver initialisation
3402  * =============================
3403  */
3404 
3405 /* Determine the floppy disk controller type */
3406 /* This routine was written by David C. Niemi */
3407 static char get_fdc_version(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3408 {
3409         int r;
3410 
3411         output_byte(FD_DUMPREGS);       /* 82072 and better know DUMPREGS */
3412         if ( FDCS->reset )
3413                 return FDC_NONE;
3414         if ( (r = result()) <= 0x00)
3415                 return FDC_NONE;        /* No FDC present ??? */
3416         if ((r==1) && (reply_buffer[0] == 0x80)){
3417                 printk("FDC %d is a 8272A\n",fdc);
3418                 return FDC_8272A;               /* 8272a/765 don't know DUMPREGS */
3419         }
3420         if (r != 10) {
3421                 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3422                 return FDC_UNKNOWN;
3423         }
3424         output_byte(FD_VERSION);
3425         r = result();
3426         if ((r == 1) && (reply_buffer[0] == 0x80)){
3427                 printk("FDC %d is a 82072\n",fdc);
3428                 return FDC_82072;               /* 82072 doesn't know VERSION */
3429         }
3430         if ((r != 1) || (reply_buffer[0] != 0x90)) {
3431                 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3432                 return FDC_UNKNOWN;
3433         }
3434         output_byte(FD_UNLOCK);
3435         r = result();
3436         if ((r == 1) && (reply_buffer[0] == 0x80)){
3437                 printk("FDC %d is a pre-1991 82077\n", fdc);
3438                 return FDC_82077_ORIG;  /* Pre-1991 82077 doesn't know LOCK/UNLOCK */
3439         }
3440         if ((r != 1) || (reply_buffer[0] != 0x00)) {
3441                 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3442                 return FDC_UNKNOWN;
3443         }
3444         printk("FDC %d is a post-1991 82077\n",fdc);
3445         return FDC_82077;       /* Revised 82077AA passes all the tests */
3446 } /* get_fdc_version */
3447 
3448 /* lilo configuration */
3449 
3450 /* we make the invert_dcl function global. One day, somebody might
3451 want to centralize all thinkpad related options into one lilo option,
3452 there are just so many thinkpad related quirks! */
3453 void floppy_invert_dcl(int *ints,int param)
     /* [previous][next][first][last][top][bottom][index][help] */
3454 {
3455         int i;
3456         
3457         for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3458                 if (param)
3459                         default_drive_params[i].params.flags |= 0x80;
3460                 else
3461                         default_drive_params[i].params.flags &= ~0x80;
3462         }
3463         DPRINT("Configuring drives for inverted dcl\n");
3464 }
3465 
3466 static void daring(int *ints,int param)
     /* [previous][next][first][last][top][bottom][index][help] */
3467 {
3468         int i;
3469 
3470         for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3471                 if (param){
3472                         default_drive_params[i].params.select_delay = 0;
3473                         default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3474                 } else {
3475                         default_drive_params[i].params.select_delay = 2*HZ/100;
3476                         default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3477                 }
3478         }
3479         DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3480 }
3481 
3482 static void allow_drives(int *ints, int param)
     /* [previous][next][first][last][top][bottom][index][help] */
3483 {
3484         ALLOWED_DRIVE_MASK=param;
3485         DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3486 }
3487 
3488 static void fdc2_adr(int *ints, int param)
     /* [previous][next][first][last][top][bottom][index][help] */
3489 {
3490         FDC2 = param;
3491         if(param)
3492                 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3493         else
3494                 DPRINT("disabling second fdc\n");
3495 }
3496 
3497 static void unex(int *ints,int param)
     /* [previous][next][first][last][top][bottom][index][help] */
3498 {
3499         print_unex = param;
3500         DPRINT1("%sprinting messages for unexpected interrupts\n",
3501                 param ? "" : "not ");
3502 }
3503 
3504 static void set_cmos(int *ints, int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
3505 {
3506         int current_drive=0;
3507 
3508         if ( ints[0] != 2 ){
3509                 DPRINT("wrong number of parameter for cmos\n");
3510                 return;
3511         }
3512         current_drive = ints[1];
3513         if (current_drive < 0 || current_drive >= 8 ){
3514                 DPRINT("bad drive for set_cmos\n");
3515                 return;
3516         }
3517         if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3518                 DPRINT1("bad cmos code %d\n", ints[2]);
3519                 return;
3520         }
3521         DP->cmos = ints[2];
3522         DPRINT1("setting cmos code to %d\n", ints[2]);
3523 }
3524                 
3525 static struct param_table {
3526         const char *name;
3527         void (*fn)(int *ints, int param);
3528         int def_param;
3529 } config_params[]={
3530 { "allowed_drive_mask", allow_drives, 0xff },
3531 { "all_drives", allow_drives, 0xff },
3532 { "asus_pci", allow_drives, 0x33 },
3533 
3534 { "daring", daring, 1},
3535 
3536 { "two_fdc", fdc2_adr, 0x370 },
3537 { "one_fdc", fdc2_adr, 0 },
3538 
3539 { "thinkpad", floppy_invert_dcl, 1 },
3540 
3541 { "cmos", set_cmos, 0 },
3542 
3543 { "unexpected_interrupts", unex, 1 },
3544 { "no_unexpected_interrupts", unex, 0 },
3545 { "L40SX", unex, 0 } };
3546 
3547 #define FLOPPY_SETUP
3548 void floppy_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
3549 {
3550         int i;
3551         int param;
3552         if(!str)
3553                 return;
3554         for(i=0; i< ARRAY_SIZE(config_params); i++){
3555                 if (strcmp(str,config_params[i].name) == 0 ){
3556                         if (ints[0] )
3557                                 param = ints[1];
3558                         else
3559                                 param = config_params[i].def_param;
3560                         config_params[i].fn(ints,param);
3561                         return;
3562                 }
3563         }
3564         DPRINT1("unknown floppy option [%s]\n", str);
3565         DPRINT("allowed options are:");
3566         for(i=0; i< ARRAY_SIZE(config_params); i++)
3567                 printk(" %s",config_params[i].name);
3568         printk("\n");
3569         DPRINT("Read linux/drivers/block/README.fd\n");
3570 }
3571 
3572 int floppy_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3573 {
3574         int i,drive;
3575         int have_no_fdc=0;
3576 
3577         sti();
3578 
3579         if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3580                 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3581                 return -EBUSY;
3582         }
3583 
3584         for(i=0; i<256; i++)
3585                 if ( TYPE(i))
3586                         floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3587                 else
3588                         floppy_sizes[i] = MAX_DISK_SIZE;
3589 
3590         blk_size[MAJOR_NR] = floppy_sizes;
3591         blksize_size[MAJOR_NR] = floppy_blocksizes;
3592         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3593         reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
3594         config_types();
3595 
3596         fdc_state[0].address = FDC1;
3597         fdc_state[0].dor = 0;
3598 #if N_FDC > 1
3599         fdc_state[1].address = FDC2;
3600         fdc_state[1].dor = 0;
3601 #endif
3602 
3603         for (i = 0 ; i < N_FDC ; i++) {
3604                 fdc = i;
3605                 FDCS->dtr = -1;
3606                 FDCS->dor = 0x4;
3607                 FDCS->reset = 0;
3608                 FDCS->version = FDC_NONE;
3609         }
3610 
3611         if(floppy_grab_irq_and_dma()){
3612                 unregister_blkdev(MAJOR_NR,"fd");
3613                 return -EBUSY;
3614         }
3615 
3616         /* initialise drive state */
3617         for (drive = 0; drive < N_DRIVE ; drive++) {
3618                 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3619                 UDRS->generation = 0;
3620                 UDRS->keep_data = 0;
3621                 UDRS->fd_ref = 0;
3622                 UDRS->fd_device = 0;
3623                 floppy_track_buffer = NULL;
3624                 max_buffer_sectors = 0;
3625                 UDRWE->write_errors = 0;
3626                 UDRWE->first_error_sector = 0;
3627                 UDRWE->first_error_generation = 0;
3628                 UDRWE->last_error_sector = 0;
3629                 UDRWE->last_error_generation = 0;
3630                 UDRWE->badness = 0;
3631         }
3632 
3633         for (i = 0 ; i < N_FDC ; i++) {
3634                 fdc = i;
3635                 if (FDCS->address == -1 )
3636                         continue;
3637                 FDCS->rawcmd = 2;
3638                 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3639                         FDCS->address = -1;
3640                         continue;
3641                 }
3642                 /* Try to determine the floppy controller type */
3643                 FDCS->version = get_fdc_version();
3644                 if (FDCS->version == FDC_NONE){
3645                         FDCS->address = -1;
3646                         continue;
3647                 }
3648                 
3649                 request_region(FDCS->address, 6, "floppy");
3650                 request_region(FDCS->address+7, 1, "floppy DIR");
3651                 /* address + 6 is reserved, and may be taken by IDE.
3652                  * Unfortunately, Adaptec doesn't know this :-(, */
3653 
3654                 have_no_fdc = 0;
3655                 /* Not all FDCs seem to be able to handle the version command
3656                  * properly, so force a reset for the standard FDC clones,
3657                  * to avoid interrupt garbage.
3658                  */
3659                 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3660                 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3661         }
3662         fdc=0;
3663         del_timer(&fd_timeout);
3664         current_drive = 0;
3665         floppy_release_irq_and_dma();
3666         initialising=0;
3667         if(have_no_fdc)
3668                 unregister_blkdev(MAJOR_NR,"fd");
3669         return have_no_fdc;
3670 }
3671 
3672 static int floppy_grab_irq_and_dma(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3673 {
3674         int i;
3675         cli();
3676         if (usage_count++){
3677                 sti();
3678                 return 0;
3679         }
3680         sti();
3681 #ifdef FD_MODULE
3682         MOD_INC_USE_COUNT;
3683 #endif
3684         for(i=0; i< N_FDC; i++){
3685                 if(FDCS->address != -1){        
3686                         fdc = i;
3687                         reset_fdc_info(1);
3688                         outb_p(FDCS->dor, FD_DOR);
3689                 }
3690         }
3691         set_dor(0, ~0, 8);  /* avoid immediate interrupt */
3692 
3693         if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3694                 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3695                         FLOPPY_IRQ);
3696                 return -1;
3697         }
3698         if (request_dma(FLOPPY_DMA,"floppy")) {
3699                 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3700                         FLOPPY_DMA);
3701                 free_irq(FLOPPY_IRQ);
3702                 return -1;
3703         }
3704         for(fdc = 0; fdc < N_FDC ; fdc++)
3705                 if(FDCS->address != -1)
3706                         outb_p(FDCS->dor, FD_DOR);
3707         fdc = 0;
3708         enable_irq(FLOPPY_IRQ);
3709         return 0;
3710 }
3711 
3712 static void floppy_release_irq_and_dma(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3713 {
3714 #ifdef CONFIG_FLOPPY_SANITY
3715         int drive;
3716 #endif
3717         long tmpsize;
3718         void *tmpaddr;
3719 
3720         cli();
3721         if (--usage_count){
3722                 sti();
3723                 return;
3724         }
3725         sti();
3726 #ifdef FD_MODULE
3727         MOD_DEC_USE_COUNT;
3728 #endif
3729         disable_dma(FLOPPY_DMA);
3730         free_dma(FLOPPY_DMA);
3731         disable_irq(FLOPPY_IRQ);
3732         free_irq(FLOPPY_IRQ);
3733 
3734         set_dor(0, ~0, 8);
3735 #if N_FDC > 1
3736         set_dor(1, ~8, 0);
3737 #endif
3738         floppy_enable_hlt();
3739 
3740         if (floppy_track_buffer && max_buffer_sectors) {
3741                 tmpsize = max_buffer_sectors*1024;
3742                 tmpaddr = (void *)floppy_track_buffer;
3743                 floppy_track_buffer = 0;
3744                 max_buffer_sectors = 0;
3745                 free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
3746         }
3747 
3748 #ifdef CONFIG_FLOPPY_SANITY
3749         for(drive=0; drive < N_FDC * 4; drive++)
3750                 if( motor_off_timer[drive].next )
3751                         printk("motor off timer %d still active\n", drive);
3752         
3753         if(fd_timeout.next)
3754                 printk("floppy timer still active:%s\n", timeout_message);
3755         if (fd_timer.next)
3756                 printk("auxiliary floppy timer still active\n");
3757         if(floppy_tq.sync)
3758                 printk("task queue still active\n");
3759 #endif
3760 }
3761 
3762 
3763 #ifdef MODULE
3764 
3765 extern char *get_options(char *str, int *ints);
3766 
3767 static void mod_setup(char *pattern, void (*setup)(char *, int *))
     /* [previous][next][first][last][top][bottom][index][help] */
3768 {
3769         int i;
3770         char c;
3771         int j;
3772         int match;
3773         char buffer[100];
3774         int ints[11];
3775         int length = strlen(pattern)+1;
3776 
3777         match=0;
3778         j=1;
3779 
3780         for(i=current->mm->env_start; 
3781             i< current->mm->env_end; 
3782             i ++){
3783                 c= get_fs_byte(i);
3784                 if(match){
3785                         if(j==99)
3786                                 c='\0';
3787                         buffer[j] = c;
3788                         if(!c || c == ' ' || c == '\t'){
3789                                 if(j){
3790                                         buffer[j] = '\0';
3791                                         setup(get_options(buffer,ints),ints);
3792                                 }
3793                                 j=0;
3794                         } else
3795                                 j++;
3796                         if(!c)
3797                                 break;
3798                         continue;
3799                 }
3800                 if( (!j && !c) ||
3801                    ( j && c == pattern[j-1]))
3802                         j++;
3803                 else
3804                         j=0;
3805                 if(j==length){
3806                         match=1;
3807                         j=0;
3808                 }
3809         }
3810 }
3811 
3812 
3813 #ifdef __cplusplus
3814 extern "C" {
3815 #endif
3816 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3817 {
3818         int ret;
3819         printk("inserting floppy driver for %s\n", kernel_version);
3820 
3821         mod_setup("floppy=", floppy_setup);
3822 
3823         ret = floppy_init();
3824         return 0;
3825 }
3826 
3827 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3828 {
3829         int fdc;
3830 
3831         for(fdc=0; fdc<2; fdc++)
3832                 if (FDCS->address != -1){
3833                         release_region(FDCS->address, 6);
3834                         release_region(FDCS->address+7, 1);
3835                       }
3836 
3837         unregister_blkdev(MAJOR_NR, "fd");
3838 
3839         blk_dev[MAJOR_NR].request_fn = 0;
3840 }
3841 
3842 #ifdef __cplusplus
3843 }
3844 #endif
3845 
3846 #endif

/* [previous][next][first][last][top][bottom][index][help] */