This source file includes following definitions.
- set_debugt
- debugt
- set_dor
- twaddle
- reset_fdc_info
- set_fdc
- lock_fdc
- unlock_fdc
- motor_off_callback
- floppy_off
- scandrives
- fd_watchdog
- main_command_interrupt
- wait_for_completion
- setup_DMA
- output_byte
- result
- perpendicular_mode
- fdc_specify
- fdc_dtr
- tell_sector
- interpret_errors
- setup_rw_floppy
- seek_interrupt
- seek_floppy
- recal_interrupt
- unexpected_floppy_interrupt
- floppy_interrupt
- recalibrate_floppy
- reset_interrupt
- reset_fdc
- floppy_shutdown
- start_motor
- floppy_ready
- floppy_on
- empty
- do_wakeup
- wait_til_done
- generic_done
- generic_success
- generic_failure
- success_and_wakeup
- failure_and_wakeup
- next_valid_format
- bad_flp_intr
- set_floppy
- format_interrupt
- setup_format_params
- redo_format
- do_format
- request_done
- rw_interrupt
- buffer_chain_size
- transfer_size
- copy_buffer
- make_raw_rw_request
- redo_fd_request
- do_fd_request
- reset_intr
- user_reset_fdc
- fd_copyout
- poll_drive
- drive_name
- raw_cmd_ioctl
- invalidate_drive
- fd_ioctl
- set_base_type
- config_types
- maybe_check_change
- floppy_is_wp
- floppy_release
- floppy_open
- ack_change
- check_floppy_change
- floppy_revalidate
- get_fdc_version
- detect_interrupt
- floppy_init
- floppy_grab_irq_and_dma
- floppy_release_irq_and_dma
1
2
3
4
5
6
7
8
9
10 #define SANITY
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 #define REALLY_SLOW_IO
94 #define FLOPPY_IRQ 6
95 #define FLOPPY_DMA 2
96
97 #define DEBUGT 2
98
99 #include <linux/sched.h>
100 #include <linux/fs.h>
101 #include <linux/kernel.h>
102 #include <linux/timer.h>
103 #define FDPATCHES
104 #include <linux/fdreg.h>
105 #include <linux/fd.h>
106 #include <linux/errno.h>
107 #include <linux/malloc.h>
108 #include <linux/string.h>
109 #include <linux/fcntl.h>
110 #include <linux/delay.h>
111
112 #include <asm/dma.h>
113 #include <asm/irq.h>
114 #include <asm/system.h>
115 #include <asm/io.h>
116 #include <asm/segment.h>
117
118 #define MAJOR_NR FLOPPY_MAJOR
119 #include "blk.h"
120
121 static unsigned int changed_floppies = 0, fake_change = 0;
122 static int initialising=1;
123
124
125 #ifdef HAVE_2_CONTROLLERS
126 #define N_FDC 2
127 #define N_DRIVE 8
128 #else
129 #define N_FDC 1
130 #define N_DRIVE 4
131 #endif
132
133 #define TYPE(x) ( ((x)>>2) & 0x1f )
134 #define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5))
135 #define UNIT(x) ( (x) & 0x03 )
136 #define FDC(x) ( ((x) & 0x04) >> 2 )
137 #define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 ))
138
139 #define DP (&drive_params[current_drive])
140 #define DRS (&drive_state[current_drive])
141 #define FDCS (&fdc_state[fdc])
142
143 #define UDP (&drive_params[drive])
144 #define UDRS (&drive_state[drive])
145 #define UFDCS (&fdc_state[FDC(drive)])
146
147
148 #define COMMAND raw_cmd.cmd[0]
149 #define DR_SELECT raw_cmd.cmd[1]
150 #define TRACK raw_cmd.cmd[2]
151 #define HEAD raw_cmd.cmd[3]
152 #define SECTOR raw_cmd.cmd[4]
153 #define SIZECODE raw_cmd.cmd[5]
154 #define SECT_PER_TRACK raw_cmd.cmd[6]
155 #define GAP raw_cmd.cmd[7]
156 #define SIZECODE2 raw_cmd.cmd[8]
157 #define NR_RW 9
158
159
160 #define F_SIZECODE raw_cmd.cmd[2]
161 #define F_SECT_PER_TRACK raw_cmd.cmd[3]
162 #define F_GAP raw_cmd.cmd[4]
163 #define F_FILL raw_cmd.cmd[5]
164 #define NR_F 6
165
166
167
168
169
170 #define MAX_DISK_SIZE 3984
171
172
173
174
175
176
177
178
179
180
181
182 #define LAST_DMA_ADDR (0x1000000)
183 #define K_64 (0x10000)
184
185
186
187
188 #define MAX_REPLIES 10
189 static unsigned char reply_buffer[MAX_REPLIES];
190 static int inr;
191 #define ST0 (reply_buffer[0])
192 #define ST1 (reply_buffer[1])
193 #define ST2 (reply_buffer[2])
194 #define ST3 (reply_buffer[0])
195 #define R_TRACK (reply_buffer[3])
196 #define R_HEAD (reply_buffer[4])
197 #define R_SECTOR (reply_buffer[5])
198 #define R_SIZECODE (reply_buffer[6])
199
200
201
202
203 static struct {
204 struct floppy_drive_params params;
205 char *name;
206 } default_drive_params[]= {
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 {{0, 500, 16, 16, 8000, 100, 300, 0, 2, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0,
223 0, { 7, 4, 8, 2, 1, 5, 3,10}, 150, 0 }, "unknown" },
224
225 {{1, 300, 16, 16, 8000, 100, 300, 0, 2, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0,
226 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 150, 1 }, "360K PC" },
227
228 {{2, 500, 16, 16, 6000, 40, 300, 14, 2, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0,
229 0, { 2, 5, 6,23,10,20,11, 0}, 150, 2 }, "1.2M" },
230
231 {{3, 250, 16, 16, 3000, 100, 300, 0, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
232 0, { 4,22,21,30, 3, 0, 0, 0}, 150, 4 }, "720k" },
233
234 {{4, 500, 16, 16, 4000, 40, 300, 10, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
235 0, { 7, 4,25,22,31,21,29,11}, 150, 7 }, "1.44M" },
236
237 {{5, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
238 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M AMI BIOS" },
239
240 {{6, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
241 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M" }
242
243
244
245
246 };
247
248 static struct floppy_drive_params drive_params[N_DRIVE];
249 static struct floppy_drive_struct volatile drive_state[N_DRIVE];
250 static struct floppy_raw_cmd raw_cmd;
251
252
253
254
255
256
257
258
259 static struct floppy_struct floppy_type[32] = {
260 { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL },
261 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" },
262 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" },
263 { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" },
264 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" },
265 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" },
266 { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" },
267 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" },
268 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" },
269 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"},
270
271 { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" },
272 { 3360,21,2,80,0,0x1C,0x00,0xCF,0x6C,"H1680" },
273 { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" },
274 { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" },
275 { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" },
276 { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" },
277 { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" },
278 { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" },
279 { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" },
280 { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" },
281
282 { 1760,11,2,80,0,0x1C,0x09,0xCF,0x6C,"d880" },
283 { 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" },
284 { 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"D1120" },
285 { 3200,20,2,80,0,0x1C,0x20,0xCF,0x6C,"h1600" },
286 { 3520,22,2,80,0,0x1C,0x08,0xCF,0x6C,"H1760" },
287 { 3840,24,2,80,0,0x1C,0x18,0xCF,0x6C,"H1920" },
288 { 6400,40,2,80,0,0x25,0x5B,0xCF,0x6C,"E3200" },
289 { 7040,44,2,80,0,0x25,0x5B,0xCF,0x6C,"E3520" },
290 { 7680,48,2,80,0,0x25,0x63,0xCF,0x6C,"E3840" },
291
292 { 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"H1840" },
293 { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" },
294 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x6C,"H1600" },
295 };
296
297 #define NUMBER(x) (sizeof(x) / sizeof(*(x)))
298 #define SECTSIZE ( _FD_SECTSIZE(*floppy))
299
300
301 struct floppy_struct *current_type[N_DRIVE] = { NULL, NULL, NULL, NULL
302 #ifdef HAVE_2_CONTROLLERS
303 ,NULL, NULL, NULL, NULL
304 #endif
305 };
306
307
308
309
310
311 struct floppy_struct user_params[N_DRIVE];
312
313 static int floppy_sizes[256];
314
315
316
317
318
319
320 static int probing = 0;
321
322
323 #define FD_COMMAND_DETECT -2
324 #define FD_COMMAND_NONE -1
325 #define FD_COMMAND_ERROR 2
326 #define FD_COMMAND_OKAY 3
327
328 static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
329 static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
330
331
332 static int format_errors;
333
334
335 static struct format_descr format_req;
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350 extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS];
351
352 int *errors;
353 typedef void (*done_f)(int);
354 struct cont_t {
355 void (*interrupt)(void);
356
357 void (*redo)(void);
358 void (*error)(void);
359 done_f done;
360 } *cont;
361
362 static void floppy_ready(void);
363 static void recalibrate_floppy(void);
364 static void seek_floppy(void);
365 static void floppy_shutdown(void);
366
367 int floppy_grab_irq_and_dma(void);
368 void floppy_release_irq_and_dma(void);
369
370
371
372
373
374
375
376
377 #define CHECK_RESET { if ( FDCS->reset ){ reset_fdc(); return ; } }
378 static void reset_fdc(void);
379
380
381
382
383
384
385 #define NO_TRACK -1
386 #define NEED_1_RECAL -2
387 #define NEED_2_RECAL -3
388
389
390 static int buffer_track = -1;
391 static int buffer_drive = -1;
392 static int buffer_min = -1;
393 static int buffer_max = -1;
394
395 #ifdef FDC_FIFO_BUG
396 static int force=0;
397 #endif
398
399
400 static struct floppy_fdc_state fdc_state[N_FDC];
401 int fdc;
402
403 static struct floppy_struct * floppy = floppy_type;
404 static unsigned char current_drive = 255;
405 static long current_count_sectors = 0;
406 static char *current_addr = 0;
407 static unsigned char sector_t;
408
409 #ifdef DEBUGT
410 long unsigned debugtimer;
411 #endif
412
413
414
415
416
417 static inline void set_debugt(void)
418 {
419 #ifdef DEBUGT
420 debugtimer = jiffies;
421 #endif
422 }
423
424 static inline void debugt(char *message)
425 {
426 #ifdef DEBUGT
427 if ( DP->flags & DEBUGT )
428 printk("%s dtime=%lu\n", message, jiffies-debugtimer );
429 #endif
430 }
431
432
433
434
435
436
437
438
439 static int set_dor(int fdc, char mask, char data)
440 {
441 register unsigned char drive, unit, newdor,olddor;
442
443 cli();
444 olddor = FDCS->dor;
445 newdor = (olddor & mask) | data;
446 if ( newdor != olddor ){
447 unit = olddor & 0x3;
448 drive = REVDRIVE(fdc,unit);
449 if ( olddor & ( 0x10 << unit )){
450 if ( inb_p( FD_DIR ) & 0x80 )
451 UDRS->flags |= FD_VERIFY;
452 else
453 UDRS->last_checked=jiffies;
454 }
455 FDCS->dor = newdor;
456 outb_p( newdor, FD_DOR);
457 }
458 sti();
459 return olddor;
460 }
461
462 static void twaddle(void)
463 {
464 cli();
465 outb_p(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
466 outb_p(FDCS->dor, FD_DOR);
467 sti();
468 }
469
470
471
472 static void reset_fdc_info(int mode)
473 {
474 int drive;
475
476 FDCS->spec1 = FDCS->spec2 = -1;
477 FDCS->need_configure = 1;
478 FDCS->perp_mode = 1;
479 FDCS->rawcmd = 0;
480 for ( drive = 0; drive < N_DRIVE; drive++)
481 if (FDC(drive) == fdc &&
482 ( mode || UDRS->track != NEED_1_RECAL))
483 UDRS->track = NEED_2_RECAL;
484 }
485
486
487 static void set_fdc(int drive)
488 {
489 if ( drive >= 0 ){
490 fdc = FDC(drive);
491 current_drive = drive;
492 }
493 set_dor(fdc,~0,8);
494 #ifdef HAVE_2_CONTROLLERS
495 set_dor(1-fdc, ~8, 0);
496 #endif
497 if ( FDCS->rawcmd == 2 )
498 reset_fdc_info(1);
499 if( inb_p(FD_STATUS) != STATUS_READY )
500 FDCS->reset = 1;
501 }
502
503
504 static void lock_fdc(int drive)
505 {
506 cli();
507 while (fdc_busy) sleep_on(&fdc_wait);
508 fdc_busy = 1;
509 sti();
510 command_status = FD_COMMAND_NONE;
511 set_fdc(drive);
512 if ( drive >= 0 ){
513 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
514 timer_active |= 1 << FLOPPY_TIMER;
515 }
516 }
517
518
519 static inline int unlock_fdc(void)
520 {
521 if (current_drive < N_DRIVE)
522 floppy_off(current_drive);
523 if (!fdc_busy)
524 printk(DEVICE_NAME ": FDC access conflict!\n");
525
526 if ( DEVICE_INTR )
527 printk(DEVICE_NAME
528 ":device interrupt still active at FDC release: %p!\n",
529 DEVICE_INTR);
530 command_status = FD_COMMAND_NONE;
531 timer_active &= ~(1 << FLOPPY_TIMER);
532 fdc_busy = 0;
533 wake_up(&fdc_wait);
534 return 0;
535 }
536
537
538 static void motor_off_callback(unsigned long nr)
539 {
540 unsigned char mask = ~(0x10 << UNIT(nr));
541
542 set_dor( FDC(nr), mask, 0 );
543 }
544
545 static struct timer_list motor_off_timer[N_DRIVE] = {
546 { NULL, NULL, 0, 0, motor_off_callback },
547 { NULL, NULL, 0, 1, motor_off_callback },
548 { NULL, NULL, 0, 2, motor_off_callback },
549 { NULL, NULL, 0, 3, motor_off_callback }
550 #ifdef HAVE_2_CONTROLLERS
551 ,{ NULL, NULL, 0, 4, motor_off_callback },
552 { NULL, NULL, 0, 5, motor_off_callback },
553 { NULL, NULL, 0, 6, motor_off_callback },
554 { NULL, NULL, 0, 7, motor_off_callback }
555 #endif
556 };
557
558
559 static void floppy_off(unsigned int nr)
560 {
561 unsigned long volatile delta;
562
563 cli();
564 del_timer(motor_off_timer+nr);
565
566
567
568 if ( drive_params[nr].rps ){
569 delta = jiffies - drive_state[nr].first_read_date + HZ -
570 drive_params[nr].spindown_offset;
571 delta = (( delta * drive_params[nr].rps) % HZ ) /
572 drive_params[nr].rps;
573 motor_off_timer[nr].expires = drive_params[nr].spindown - delta;
574 }
575 add_timer(motor_off_timer+nr);
576 sti();
577 }
578
579
580
581
582
583
584 static void scandrives(void)
585 {
586 int i, drive, saved_drive;
587
588 saved_drive = current_drive % N_DRIVE;
589 for(i=0; i< N_DRIVE; i++){
590 drive = (saved_drive + i + 1 ) % N_DRIVE;
591 if ( UDRS->fd_ref == 0 )
592 continue;
593 set_fdc(drive);
594 UDRS->select_date = jiffies;
595 if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
596 (0x10 << UNIT(drive))))
597
598
599 set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
600 }
601 current_drive = saved_drive;
602 }
603
604 typedef void (*timeout_fn)(unsigned long);
605 static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
606
607
608
609 static void fd_watchdog(void)
610 {
611 if ( inb_p( FD_DIR ) & 0x80 ){
612 floppy_shutdown();
613 } else {
614 cli();
615 del_timer(&fd_timer);
616 fd_timer.function = (timeout_fn) fd_watchdog;
617 fd_timer.expires = 10;
618 add_timer(&fd_timer);
619 sti();
620 }
621 }
622
623 static void main_command_interrupt(void)
624 {
625 del_timer(&fd_timer);
626 cont->interrupt();
627 }
628
629
630 static int wait_for_completion(int nr, int delay, timeout_fn function)
631 {
632 if ( FDCS->reset ){
633 reset_fdc();
634
635
636 return 1;
637 }
638
639 if ( jiffies < delay ){
640 del_timer(&fd_timer);
641 fd_timer.function = function;
642 fd_timer.expires = delay - jiffies;
643 add_timer(&fd_timer);
644 return 1;
645 }
646 return 0;
647 }
648
649 static void setup_DMA(void)
650 {
651 #ifdef SANITY
652 if ((!CURRENT ||
653 CURRENT->buffer != current_addr ||
654 raw_cmd.length > 512 * CURRENT->nr_sectors) &&
655 (current_addr < floppy_track_buffer ||
656 current_addr + raw_cmd.length >
657 floppy_track_buffer + 1024 * MAX_BUFFER_SECTORS)){
658 printk("bad address. start=%p lg=%lx tb=%p\n",
659 current_addr, raw_cmd.length, floppy_track_buffer);
660 if ( CURRENT ){
661 printk("buffer=%p nr=%lx cnr=%lx\n",
662 CURRENT->buffer, CURRENT->nr_sectors,
663 CURRENT->current_nr_sectors);
664 }
665 cont->done(0);
666 FDCS->reset=1;
667 return;
668 }
669 if ((long) current_addr % 512 ){
670 printk("non aligned address: %p\n", current_addr );
671 cont->done(0);
672 FDCS->reset=1;
673 return;
674 }
675 if ( ( (long)current_addr & ~(64*1024-1) ) !=
676 ((long)(current_addr + raw_cmd.length-1) & ~(64*1024-1))){
677 printk("DMA crossing 64-K boundary %p-%p\n",
678 current_addr, current_addr + raw_cmd.length);
679 cont->done(0);
680 FDCS->reset=1;
681 return;
682 }
683
684 #endif
685 cli();
686 disable_dma(FLOPPY_DMA);
687 clear_dma_ff(FLOPPY_DMA);
688 set_dma_mode(FLOPPY_DMA,
689 (raw_cmd.flags & FD_RAW_READ)?
690 DMA_MODE_READ : DMA_MODE_WRITE);
691 set_dma_addr(FLOPPY_DMA, (long) current_addr);
692 set_dma_count(FLOPPY_DMA, raw_cmd.length);
693 enable_dma(FLOPPY_DMA);
694 sti();
695 }
696
697
698 static int output_byte(char byte)
699 {
700 int counter;
701 unsigned char status;
702
703 if (FDCS->reset)
704 return -1;
705 for(counter = 0 ; counter < 10000 ; counter++) {
706 status = inb_p(FD_STATUS) &(STATUS_READY|STATUS_DIR|STATUS_DMA);
707 if (!(status & STATUS_READY))
708 continue;
709 if (status == STATUS_READY
710 #ifdef FDC_FIFO_BUG
711 || ((status == STATUS_READY|STATUS_DIR|STATUS_BUSY) &&force)
712 #endif
713 )
714 {
715 outb_p(byte,FD_DATA);
716 return 0;
717 } else
718 break;
719 }
720 FDCS->reset = 1;
721 if ( !initialising )
722 printk(DEVICE_NAME ": Unable to send byte to FDC %d (%x)\n",
723 fdc, status);
724 return -1;
725 }
726 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
727
728 #ifdef FDC_FIFO_BUG
729 #define output_byte_force(x) force=1;output_byte(x);force=0;
730 #else
731 #define output_byte_force(x) output_byte(x);
732 #endif
733
734
735 static int result(void)
736 {
737 int i = 0, counter, status;
738
739 if (FDCS->reset)
740 return -1;
741 for (counter = 0 ; counter < 10000 ; counter++) {
742 status = inb_p(FD_STATUS)&
743 (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
744 if (!(status & STATUS_READY))
745 continue;
746 if (status == STATUS_READY)
747 return i;
748 if (status & STATUS_DMA )
749 break;
750 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
751 if (i >= MAX_REPLIES) {
752 printk(DEVICE_NAME
753 ": floppy_stat reply overrun\n");
754 break;
755 }
756 reply_buffer[i++] = inb_p(FD_DATA);
757 }
758 }
759 FDCS->reset = 1;
760 if ( !initialising )
761 printk(DEVICE_NAME ": Getstatus times out (%x) on fdc %d [%d]\n",
762 status, fdc,i);
763 return -1;
764 }
765
766
767
768
769
770 static inline void perpendicular_mode(void)
771 {
772 unsigned char perp_mode;
773
774 if (!floppy)
775 return;
776 if (floppy->rate & 0x40){
777 switch(raw_cmd.rate){
778 case 0:
779 perp_mode=3;
780 break;
781 case 3:
782 perp_mode=3;
783 break;
784 default:
785 printk(DEVICE_NAME
786 ": Invalid data rate for perpendicular mode!\n");
787 cont->done(0);
788 FDCS->reset = 1;
789
790
791 return;
792 }
793 } else
794 perp_mode = 0;
795
796 if ( FDCS->perp_mode == perp_mode )
797 return;
798 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
799 output_byte(FD_PERPENDICULAR);
800 output_byte_force(perp_mode);
801 FDCS->perp_mode = perp_mode;
802 } else if (perp_mode) {
803 printk(DEVICE_NAME
804 ": perpendicular mode not supported by this FDC.\n");
805 }
806 }
807
808 #define NOMINAL_DTR 500
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829 static void fdc_specify(void)
830 {
831 unsigned char spec1, spec2;
832 int srt, hlt, hut;
833 unsigned long dtr = NOMINAL_DTR;
834 unsigned long scale_dtr = NOMINAL_DTR;
835 int hlt_max_code = 0x7f;
836 int hut_max_code = 0xf;
837
838 if (FDCS->need_configure && FDCS->has_fifo) {
839 if ( FDCS->reset )
840 return;
841
842
843 output_byte(FD_CONFIGURE);
844 output_byte_force(0);
845 output_byte(0x1A);
846 output_byte_force(0);
847 if ( FDCS->reset ){
848 FDCS->has_fifo=0;
849 return;
850 }
851 FDCS->need_configure = 0;
852
853 }
854
855 switch (raw_cmd.rate & 0x03) {
856 case 3:
857 dtr = 1000;
858 break;
859 case 1:
860 dtr = 300;
861 break;
862 case 2:
863 dtr = 250;
864 break;
865 }
866
867 if (FDCS->version >= FDC_82072) {
868 scale_dtr = dtr;
869 hlt_max_code = 0x00;
870 hut_max_code = 0x0;
871 }
872
873
874 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
875 if (srt > 0xf)
876 srt = 0xf;
877 else if (srt < 0)
878 srt = 0;
879
880 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
881 if (hlt < 0x01)
882 hlt = 0x01;
883 else if (hlt > 0x7f)
884 hlt = hlt_max_code;
885
886 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
887 if (hut < 0x1)
888 hut = 0x1;
889 else if (hut > 0xf)
890 hut = hut_max_code;
891
892 spec1 = (srt << 4) | hut;
893 #define fd_disable_dma 0
894 spec2 = (hlt << 1) | fd_disable_dma;
895
896
897 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
898
899 output_byte(FD_SPECIFY);
900 output_byte(FDCS->spec1 = spec1);
901 output_byte(FDCS->spec2 = spec2);
902 }
903 }
904
905
906
907
908
909 static void fdc_dtr(void)
910 {
911
912 if ( raw_cmd.rate == FDCS->dtr)
913 return;
914
915
916 outb_p(raw_cmd.rate, FD_DCR);
917
918
919
920
921
922
923 udelay(5000);
924 FDCS->dtr = raw_cmd.rate;
925 }
926
927 static void tell_sector(void)
928 {
929 printk(": track %d, head %d, sector %d, size %d",
930 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
931 }
932
933
934
935
936
937
938
939
940
941 static int interpret_errors(void)
942 {
943 char bad;
944
945 if (inr!=7) {
946 printk(DEVICE_NAME ": -- FDC reply error");
947 FDCS->reset = 1;
948 return 1;
949 }
950
951
952 switch ((ST0 & ST0_INTR)>>6) {
953 case 1:
954 bad = 1;
955 if (ST1 & ST1_WP) {
956 printk(DEVICE_NAME ": Drive %d is write protected\n", current_drive);
957 DRS->flags &= ~FD_DISK_WRITABLE;
958 cont->done(0);
959 bad = 2;
960 } else if (ST1 & ST1_ND) {
961 DRS->flags |= FD_NEED_TWADDLE;
962 } else if (ST1 & ST1_OR) {
963 if (DP->flags & FTD_MSG )
964 printk(DEVICE_NAME ": Over/Underrun - retrying\n");
965
966 bad = 0;
967 }else if(*errors >= DP->max_errors.reporting){
968 printk(DEVICE_NAME " %d: ", ST0 & ST0_DS);
969 if (ST0 & ST0_ECE) {
970 printk("Recalibrate failed!");
971 } else if (ST2 & ST2_CRC) {
972 printk("data CRC error");
973 tell_sector();
974 } else if (ST1 & ST1_CRC) {
975 printk("CRC error");
976 tell_sector();
977 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
978 if (!probing) {
979 printk("sector not found");
980 tell_sector();
981 } else
982 printk("probe failed...");
983 } else if (ST2 & ST2_WC) {
984 printk("wrong cylinder");
985 } else if (ST2 & ST2_BC) {
986 printk("bad cylinder");
987 } else {
988 printk("unknown error. ST[0..3] are: 0x%x 0x%x 0x%x 0x%x\n", ST0, ST1, ST2, ST3);
989 }
990 printk("\n");
991
992 }
993 if ( ST2 & ST2_WC || ST2 & ST2_BC)
994
995 DRS->track = NEED_2_RECAL;
996 return bad;
997 case 2:
998 printk(DEVICE_NAME ": Invalid FDC command given!\n");
999 cont->done(0);
1000 return 2;
1001 case 3:
1002 printk(DEVICE_NAME ": Abnormal termination caused by polling\n");
1003 cont->error();
1004 return 2;
1005 default:
1006 return 0;
1007 }
1008 }
1009
1010
1011
1012
1013
1014
1015 static void setup_rw_floppy(void)
1016 {
1017 int i,ready_date,r, flags,dflags;
1018 timeout_fn function;
1019
1020 flags = raw_cmd.flags;
1021 if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1022 flags |= FD_RAW_INTR;
1023
1024 if (flags & FD_RAW_SPIN){
1025 ready_date = DRS->spinup_date + DP->spinup;
1026
1027
1028
1029
1030 if ( ready_date > jiffies + DP->select_delay){
1031 ready_date -= DP->select_delay;
1032 function = (timeout_fn) floppy_on;
1033 } else
1034 function = (timeout_fn) setup_rw_floppy;
1035
1036
1037 if (wait_for_completion(current_drive,ready_date,function))
1038 return;
1039 }
1040 dflags = DRS->flags;
1041
1042 if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE)){
1043 if ( flags & FD_RAW_USER_SUPPLIED )
1044 buffer_track = -1;
1045 setup_DMA();
1046 }
1047
1048 if ( flags & FD_RAW_INTR )
1049 SET_INTR(main_command_interrupt);
1050
1051 r=0;
1052 for(i=0; i< raw_cmd.cmd_count; i++)
1053 r|=output_byte( raw_cmd.cmd[i] );
1054
1055 #ifdef DEBUGT
1056 debugt("rw_command: ");
1057 #endif
1058 if ( r ){
1059 reset_fdc();
1060 return;
1061 }
1062
1063 if ( ! ( flags & FD_RAW_INTR )){
1064 inr = result();
1065 cont->interrupt();
1066 } else if ( flags & FD_RAW_NEED_DISK )
1067 fd_watchdog();
1068 }
1069
1070
1071
1072
1073
1074 static void seek_interrupt(void)
1075 {
1076 #ifdef DEBUGT
1077 debugt("seek interrupt:");
1078 #endif
1079 if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1080 printk(DEVICE_NAME ": seek failed\n");
1081 DRS->track = NEED_2_RECAL;
1082 cont->error();
1083 cont->redo();
1084 return;
1085 }
1086 if ( DRS->track >= 0 && DRS->track != ST1 )
1087 DRS->flags &= ~FD_DISK_NEWCHANGE;
1088 DRS->track = ST1;
1089 seek_floppy();
1090 }
1091
1092 static void seek_floppy(void)
1093 {
1094 int track;
1095
1096 if ((raw_cmd.flags & FD_RAW_NEED_DISK) &&
1097 !(DRS->flags & FD_DISK_NEWCHANGE ) &&
1098 (inb_p(FD_DIR) & 0x80)){
1099
1100
1101
1102
1103 cont->done(0);
1104 cont->redo();
1105 return;
1106 }
1107 if ( DRS->track <= NEED_1_RECAL ){
1108 recalibrate_floppy();
1109 return;
1110 } else if ((DRS->flags & FD_DISK_NEWCHANGE) &&
1111 (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1112
1113
1114 if ( raw_cmd.track )
1115 track = raw_cmd.track - 1;
1116 else
1117 track = 1;
1118 } else if (raw_cmd.track != DRS->track)
1119 track = raw_cmd.track;
1120 else {
1121 setup_rw_floppy();
1122 return;
1123 }
1124
1125 if ( !track && DRS->track >= 0 && DRS->track < 80 ){
1126 DRS->flags &= ~FD_DISK_NEWCHANGE;
1127
1128
1129 recalibrate_floppy();
1130 } else {
1131 SET_INTR(seek_interrupt);
1132 output_byte(FD_SEEK);
1133 output_byte(UNIT(current_drive));
1134 LAST_OUT(track);
1135 #ifdef DEBUGT
1136 debugt("seek command:");
1137 #endif
1138 }
1139 }
1140
1141 static void recal_interrupt(void)
1142 {
1143 #ifdef DEBUGT
1144 debugt("recal interrupt:");
1145 #endif
1146 if (inr !=2 )
1147 FDCS->reset = 1;
1148 else if (ST0 & ST0_ECE) {
1149 switch(DRS->track){
1150 case NEED_1_RECAL:
1151
1152
1153 cont->error();
1154 cont->redo();
1155 return;
1156 case NEED_2_RECAL:
1157
1158
1159
1160
1161
1162 DRS->flags &= ~FD_DISK_NEWCHANGE;
1163
1164 default:
1165
1166
1167
1168
1169
1170 DRS->track = NEED_1_RECAL;
1171 break;
1172 }
1173 } else
1174 DRS->track = ST1;
1175 seek_floppy();
1176 }
1177
1178
1179
1180
1181
1182 static void unexpected_floppy_interrupt(void)
1183 {
1184 int i;
1185 if ( initialising )
1186 return;
1187 printk(DEVICE_NAME ": unexpected interrupt\n");
1188 if ( inr >= 0 )
1189 for(i=0; i<inr; i++)
1190 printk("%d %x\n", i, reply_buffer[i] );
1191 while(1){
1192 output_byte(FD_SENSEI);
1193 inr=result();
1194 if ( inr != 2 )
1195 break;
1196 printk("sensei\n");
1197 for(i=0; i<inr; i++)
1198 printk("%d %x\n", i, reply_buffer[i] );
1199 }
1200 FDCS->reset = 1;
1201 }
1202
1203
1204 static void floppy_interrupt(int unused)
1205 {
1206 void (*handler)(void) = DEVICE_INTR;
1207
1208 CLEAR_INTR;
1209 if ( fdc >= N_FDC )
1210 return;
1211 inr = result();
1212 if (!handler){
1213 unexpected_floppy_interrupt();
1214 return;
1215 }
1216 if ( inr == 0 ){
1217 do {
1218 output_byte(FD_SENSEI);
1219 inr = result();
1220 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1221 }
1222 sti();
1223 handler();
1224 }
1225
1226 static void recalibrate_floppy(void)
1227 {
1228 SET_INTR(recal_interrupt);
1229 output_byte(FD_RECALIBRATE);
1230 LAST_OUT(UNIT(current_drive));
1231 }
1232
1233
1234
1235
1236 static void reset_interrupt(void)
1237 {
1238 #ifdef DEBUGT
1239 debugt("reset interrupt:");
1240 #endif
1241 fdc_specify();
1242 result();
1243 if ( FDCS->reset )
1244 cont->error();
1245 cont->redo();
1246 }
1247
1248
1249
1250
1251
1252 static void reset_fdc(void)
1253 {
1254 SET_INTR(reset_interrupt);
1255 FDCS->reset = 0;
1256 reset_fdc_info(0);
1257 if ( FDCS->version >= FDC_82077 )
1258 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1259 else {
1260 cli();
1261 outb_p(FDCS->dor & ~0x04, FD_DOR);
1262 udelay(FD_RESET_DELAY);
1263 outb(FDCS->dor, FD_DOR);
1264 sti();
1265 }
1266 }
1267
1268 static void floppy_shutdown(void)
1269 {
1270 cli();
1271 if ( !DEVICE_INTR ){
1272
1273 sti();
1274 return;
1275 }
1276 CLEAR_INTR;
1277 sti();
1278 if ( !initialising )
1279 printk(DEVICE_NAME ": timeout\n");
1280 FDCS->reset = 1;
1281 cont->done(0);
1282 cont->redo();
1283 }
1284
1285
1286 static int start_motor(void)
1287 {
1288 int cnt;
1289 int dir;
1290
1291 if ( (FDCS->dor & 0x03) != UNIT(current_drive) )
1292
1293 DRS->select_date = jiffies;
1294
1295 if ( ! ( FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1296 set_debugt();
1297
1298 DRS->first_read_date = 0;
1299
1300 DRS->spinup_date = jiffies;
1301 }
1302
1303
1304 del_timer(motor_off_timer + current_drive);
1305 set_dor( fdc, 0xfc,
1306 ( 0x10 << UNIT(current_drive) ) | UNIT(current_drive) );
1307
1308 dir = inb_p( FD_DIR) & 0x80;
1309 if ( ! (dir & 0x80) )
1310 DRS->last_checked =jiffies;
1311 if ( dir || ( DRS->flags & FD_VERIFY )) {
1312 DRS->flags &= FD_DRIVE_PRESENT | FD_DISK_NEWCHANGE;
1313 DRS->flags |= FD_DISK_WRITABLE;
1314
1315
1316 output_byte( FD_GETSTATUS );
1317 output_byte( UNIT(current_drive) );
1318 if ( (cnt=result()) != 1 ){
1319 changed_floppies |= 1 << current_drive;
1320 FDCS->reset = 1;
1321 DRS->flags |= FD_VERIFY;
1322 return -1;
1323 }
1324 if ( ( ST3 & 0x60 ) == 0x60 )
1325 DRS->flags &= ~FD_DISK_WRITABLE;
1326
1327 if ( ! ( DRS->flags & FD_DISK_NEWCHANGE) ){
1328
1329
1330 changed_floppies |= 1 << current_drive;
1331 if (DRS->keep_data >= 0) {
1332 if ((DP->flags & FTD_MSG) &&
1333 current_type[current_drive] != NULL)
1334 printk(DEVICE_NAME
1335 ": Disk type is undefined after "
1336 "disk change in fd%d\n",
1337 current_drive);
1338 current_type[current_drive] = NULL;
1339 floppy_sizes[current_drive] = MAX_DISK_SIZE;
1340 }
1341 if ( ST3 & 0x10 )
1342 DRS->track = 0;
1343 }
1344 }
1345 if ( dir )
1346 DRS->flags |= FD_DISK_NEWCHANGE;
1347 else {
1348 DRS->flags &= ~FD_DISK_NEWCHANGE;
1349 DRS->last_checked =jiffies;
1350 }
1351
1352 return DRS->flags;
1353 }
1354
1355 static void floppy_ready(void)
1356 {
1357 CHECK_RESET;
1358 start_motor();
1359
1360
1361 if(wait_for_completion(current_drive,
1362 DRS->select_date+DP->select_delay,
1363 (timeout_fn) floppy_ready))
1364 return;
1365 fdc_dtr();
1366 if ( raw_cmd.flags & FD_RAW_NEED_SEEK ){
1367 perpendicular_mode();
1368 fdc_specify();
1369 seek_floppy();
1370 } else
1371 setup_rw_floppy();
1372 }
1373
1374 static void floppy_on(unsigned int drive)
1375 {
1376 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
1377 timer_active |= 1 << FLOPPY_TIMER;
1378 scandrives();
1379 floppy_ready();
1380 }
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395 static void empty(void)
1396 {
1397 }
1398
1399 static void do_wakeup(void)
1400 {
1401 timer_active &= ~(1 << FLOPPY_TIMER);
1402 command_status += 2;
1403 wake_up(&command_done);
1404 cont = 0;
1405 }
1406
1407 static struct cont_t wakeup_cont={
1408 empty,
1409 do_wakeup,
1410 empty,
1411 (done_f)empty
1412 };
1413
1414 static int wait_til_done(void)
1415 {
1416 int ret;
1417 while(command_status < 2)
1418 if (current->pid)
1419 sleep_on( & command_done );
1420 if ( FDCS->reset )
1421 command_status = FD_COMMAND_ERROR;
1422 if ( command_status == FD_COMMAND_OKAY )
1423 ret=0;
1424 else
1425 ret=-EIO;
1426 command_status = FD_COMMAND_NONE;
1427 return ret;
1428 }
1429
1430 static void generic_done(int result)
1431 {
1432 command_status = result;
1433 cont = &wakeup_cont;
1434 }
1435
1436 static void generic_success(void)
1437 {
1438 generic_done(1);
1439 }
1440
1441 static void generic_failure(void)
1442 {
1443 generic_done(0);
1444 }
1445
1446 static void success_and_wakeup(void)
1447 {
1448 generic_success();
1449 do_wakeup();
1450 }
1451
1452 static void failure_and_wakeup(void)
1453 {
1454 generic_failure();
1455 do_wakeup();
1456 }
1457
1458
1459
1460
1461
1462
1463 static int next_valid_format(void)
1464 {
1465 int probed_format;
1466 while(1){
1467 probed_format = DRS->probed_format;
1468 if ( probed_format > N_DRIVE ||
1469 ! DP->autodetect[probed_format] ){
1470 DRS->probed_format = 0;
1471 return 1;
1472 }
1473 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1474 DRS->probed_format = probed_format;
1475 return 0;
1476 }
1477 probed_format++;
1478 }
1479 }
1480
1481 static void bad_flp_intr(void)
1482 {
1483 if ( probing ){
1484 DRS->probed_format++;
1485 if ( !next_valid_format())
1486 return;
1487 }
1488 (*errors)++;
1489 if (*errors > DP->max_errors.abort)
1490 cont->done(0);
1491 if (*errors > DP->max_errors.reset)
1492 FDCS->reset = 1;
1493 else if (*errors > DP->max_errors.recal)
1494 DRS->track = NEED_2_RECAL;
1495 }
1496
1497 static void set_floppy(int device)
1498 {
1499 if (TYPE(device))
1500 floppy = TYPE(device) + floppy_type;
1501 else
1502 floppy = current_type[ DRIVE(device) ];
1503 }
1504
1505
1506
1507
1508
1509 static void format_interrupt(void)
1510 {
1511 switch (interpret_errors()){
1512 case 1:
1513 cont->error();
1514 case 2:
1515 break;
1516 case 0:
1517 cont->done(1);
1518 }
1519 cont->redo();
1520 }
1521
1522 static void setup_format_params(void)
1523 {
1524 struct fparm {
1525 unsigned char track,head,sect,size;
1526 } *here = (struct fparm *)floppy_track_buffer;
1527 int ssize,il,n;
1528 int count,head_shift,track_shift;
1529
1530 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1531 FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
1532 raw_cmd.rate = floppy->rate & 0x3;
1533 raw_cmd.cmd_count = NR_F;
1534 COMMAND = FD_FORMAT;
1535 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1536 F_SIZECODE = FD_SIZECODE(floppy);
1537 ssize = 1 << ( F_SIZECODE - 2 );
1538 F_SECT_PER_TRACK = floppy->sect / ssize;
1539 F_GAP = floppy->fmt_gap;
1540 F_FILL = FD_FILL_BYTE;
1541
1542 current_addr = floppy_track_buffer;
1543 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1544
1545
1546 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1547
1548
1549 track_shift = 2 * head_shift + 1;
1550
1551
1552 n = (track_shift * format_req.track + head_shift * format_req.head )
1553 % F_SECT_PER_TRACK;
1554
1555
1556 il = 1;
1557 if (floppy->sect > DP->interleave_sect && ssize==1)
1558 il++;
1559
1560
1561 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1562 here[count].track = format_req.track;
1563 here[count].head = format_req.head;
1564 here[count].sect = 0;
1565 here[count].size = F_SIZECODE;
1566 }
1567
1568 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1569 here[n].sect = count;
1570 n = (n+il) % F_SECT_PER_TRACK;
1571 if (here[n].sect) {
1572 ++n;
1573 if (n>= F_SECT_PER_TRACK) {
1574 n-=F_SECT_PER_TRACK;
1575 while (here[n].sect) ++n;
1576 }
1577 }
1578 }
1579 }
1580
1581 static void redo_format(void)
1582 {
1583 raw_cmd.track = format_req.track << floppy->stretch;
1584 buffer_track = -1;
1585 setup_format_params();
1586 floppy_on(current_drive);
1587 #ifdef DEBUGT
1588 debugt("queue format request");
1589 #endif
1590 }
1591
1592 static struct cont_t format_cont={
1593 format_interrupt,
1594 redo_format,
1595 bad_flp_intr,
1596 generic_done };
1597
1598 static int do_format(int device, struct format_descr *tmp_format_req)
1599 {
1600 int okay;
1601
1602 lock_fdc(DRIVE(device));
1603 set_floppy(device);
1604 if (!floppy ||
1605 tmp_format_req->track >= floppy->track ||
1606 tmp_format_req->head >= floppy->head){
1607 unlock_fdc();
1608 return -EINVAL;
1609 }
1610 format_req = *tmp_format_req;
1611 format_errors = 0;
1612 cont = &format_cont;
1613 errors = &format_errors;
1614 redo_format();
1615 okay=wait_til_done();
1616 unlock_fdc();
1617 return okay;
1618 }
1619
1620
1621
1622
1623
1624
1625
1626
1627 static void request_done(int uptodate)
1628 {
1629 int block;
1630
1631 probing = 0;
1632 timer_active &= ~(1 << FLOPPY_TIMER);
1633
1634 if (!CURRENT){
1635 printk(DEVICE_NAME
1636 ": request list destroyed in floppy request done\n");
1637 return;
1638 }
1639 if (uptodate){
1640
1641
1642 block = current_count_sectors + CURRENT->sector;
1643 if (block > DRS->maxblock)
1644 DRS->maxblock=block;
1645 if ( block > floppy->sect)
1646 DRS->maxtrack = 1;
1647
1648
1649 while (current_count_sectors && CURRENT &&
1650 current_count_sectors >= CURRENT->current_nr_sectors ){
1651 current_count_sectors -= CURRENT->current_nr_sectors;
1652 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1653 CURRENT->sector += CURRENT->current_nr_sectors;
1654 end_request(1);
1655 }
1656 if ( current_count_sectors && CURRENT){
1657
1658 CURRENT->buffer += current_count_sectors <<9;
1659 CURRENT->current_nr_sectors -= current_count_sectors;
1660 CURRENT->nr_sectors -= current_count_sectors;
1661 CURRENT->sector += current_count_sectors;
1662 return;
1663 }
1664
1665 if ( current_count_sectors && ! CURRENT )
1666 printk(DEVICE_NAME "request list destroyed in floppy request done\n");
1667
1668 } else {
1669 #ifdef NO_WEIRD_UNLOCKED
1670 if ( CURRENT->bh )
1671
1672 CURRENT->bh->b_req = 0;
1673 #endif
1674 end_request(0);
1675 }
1676 }
1677
1678
1679 static void rw_interrupt(void)
1680 {
1681 #if 0
1682 int i;
1683 #endif
1684 int nr_sectors, ssize;
1685 char bad;
1686
1687 if ( ! DRS->first_read_date )
1688 DRS->first_read_date = jiffies;
1689
1690 nr_sectors = 0;
1691 ssize = 1 << (SIZECODE - 2);
1692 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1693 floppy->sect + (R_SECTOR-SECTOR) * ssize -
1694 (sector_t % floppy->sect) % ssize;
1695
1696 #ifdef SANITY
1697 if ( nr_sectors > current_count_sectors + ssize -
1698 (current_count_sectors + sector_t) % ssize +
1699 sector_t % ssize){
1700 printk(DEVICE_NAME ": long rw: %x instead of %lx\n",
1701 nr_sectors, current_count_sectors);
1702 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1703 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1704 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1705 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1706 sector_t, ssize);
1707 }
1708 #endif
1709 if ( nr_sectors < 0 )
1710 nr_sectors = 0;
1711 if ( nr_sectors < current_count_sectors ){
1712 #if 0
1713 printk(DEVICE_NAME ": short read got %d instead of %ld\n",
1714 nr_sectors, current_count_sectors);
1715 #endif
1716 #if 0
1717 printk("command: ");
1718 for(i=0; i<raw_cmd.cmd_count; i++)
1719 printk("%x ", raw_cmd.cmd[i]);
1720 printk("rate=%x\n", raw_cmd.rate);
1721 printk("reply: ");
1722 for(i=0; i< inr; i++)
1723 printk("%x ", reply_buffer[i]);
1724 printk("\n");
1725 #endif
1726 current_count_sectors = nr_sectors;
1727 }
1728
1729 switch (interpret_errors()){
1730 case 2:
1731 cont->redo();
1732 return;
1733 case 1:
1734 if ( !current_count_sectors){
1735 cont->error();
1736 cont->redo();
1737 return;
1738 }
1739 break;
1740 case 0:
1741 if ( !current_count_sectors){
1742 int i;
1743 printk(DEVICE_NAME ": dma problem?\n");
1744 for(i=0; i< inr ; i++)
1745 printk("%2x,", reply_buffer[i]);
1746 printk("\n");
1747 bad=1;
1748 cont->error();
1749 cont->redo();
1750 return;
1751 }
1752 current_type[current_drive] = floppy;
1753 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1754 floppy->size >> 1;
1755 break;
1756 }
1757
1758 if (probing) {
1759 if (DP->flags & FTD_MSG)
1760 printk(DEVICE_NAME
1761 ": Auto-detected floppy type %s in fd%d\n",
1762 floppy->name,current_drive);
1763 current_type[current_drive] = floppy;
1764 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1765 floppy->size >> 1;
1766 probing = 0;
1767 }
1768
1769 if ( COMMAND != FD_READ || current_addr == CURRENT->buffer ){
1770
1771 cont->done(1);
1772 } else if ( COMMAND == FD_READ){
1773 buffer_track = raw_cmd.track;
1774 buffer_drive = current_drive;
1775 if ( nr_sectors + sector_t > buffer_max )
1776 buffer_max = nr_sectors + sector_t;
1777 }
1778 cont->redo();
1779 }
1780
1781
1782 static int buffer_chain_size(void)
1783 {
1784 struct buffer_head *bh;
1785 int size;
1786 char *base;
1787
1788 base = CURRENT->buffer;
1789 size = CURRENT->current_nr_sectors << 9;
1790 bh = CURRENT->bh;
1791
1792 #ifdef SANITY
1793 if ( !bh ){
1794 printk(DEVICE_NAME ": null request in buffer_chain_size\n");
1795 return size >> 9;
1796 }
1797 #endif
1798
1799 bh = bh->b_reqnext;
1800 while ( bh && bh->b_data == base + size ){
1801 size += bh->b_size;
1802 bh = bh->b_reqnext;
1803 }
1804 return size >> 9;
1805 }
1806
1807
1808 static int transfer_size(int ssize, int max_sector, int max_size)
1809 {
1810 if ( max_sector > sector_t + max_size)
1811 max_sector = sector_t + max_size;
1812
1813
1814 max_sector -= (max_sector % floppy->sect ) % ssize;
1815
1816
1817 current_count_sectors = max_sector - sector_t ;
1818
1819 return max_sector;
1820 }
1821
1822
1823
1824
1825 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
1826 {
1827 int remaining;
1828 struct buffer_head *bh;
1829 char *buffer, *dma_buffer;
1830 int size;
1831
1832 if ( max_sector > max_sector_2 )
1833 max_sector = max_sector_2;
1834
1835 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
1836
1837 if (current_count_sectors <= 0 && COMMAND == FD_WRITE &&
1838 buffer_max > sector_t + CURRENT->nr_sectors){
1839 current_count_sectors = buffer_max - sector_t;
1840 if ( current_count_sectors > CURRENT->nr_sectors )
1841 current_count_sectors = CURRENT->nr_sectors;
1842 }
1843 remaining = current_count_sectors << 9;
1844 #ifdef SANITY
1845 if ((remaining >> 9) > CURRENT->nr_sectors && COMMAND == 0xc5 ){
1846 printk(DEVICE_NAME ": in copy buffer\n");
1847 printk("current_count_sectors=%ld\n", current_count_sectors);
1848 printk("remaining=%d\n", remaining >> 9);
1849 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
1850 printk("CURRENT->current_nr_sectors=%ld\n",
1851 CURRENT->current_nr_sectors);
1852 printk("max_sector=%d\n", max_sector);
1853 printk("ssize=%d\n", ssize);
1854 }
1855 #endif
1856
1857 if ( max_sector > buffer_max )
1858 buffer_max = max_sector;
1859
1860 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
1861
1862 bh = CURRENT->bh;
1863 size = CURRENT->current_nr_sectors << 9;
1864 buffer = CURRENT->buffer;
1865
1866 while ( remaining > 0){
1867 if ( size > remaining )
1868 size = remaining;
1869 #ifdef SANITY
1870 if (!bh){
1871 printk(DEVICE_NAME
1872 ": bh=null in copy buffer before copy\n");
1873 break;
1874 }
1875 if (dma_buffer + size >
1876 floppy_track_buffer + ( 2 * MAX_BUFFER_SECTORS << 9 ) ||
1877 dma_buffer < floppy_track_buffer ){
1878 printk(DEVICE_NAME
1879 ": buffer overrun in copy buffer %d\n",
1880 (floppy_track_buffer - dma_buffer) >>9);
1881 printk("sector_t=%d buffer_min=%d\n",
1882 sector_t, buffer_min);
1883 printk("current_count_sectors=%ld\n",
1884 current_count_sectors);
1885 if ( COMMAND == FD_READ )
1886 printk("read\n");
1887 if ( COMMAND == FD_READ )
1888 printk("write\n");
1889 break;
1890 }
1891 if ( ((int)buffer) % 512 )
1892 printk(DEVICE_NAME ": %p buffer not aligned\n", buffer);
1893 #endif
1894 if ( COMMAND == FD_READ )
1895 memcpy( buffer, dma_buffer, size);
1896 else
1897 memcpy( dma_buffer, buffer, size);
1898 remaining -= size;
1899 if ( !remaining)
1900 break;
1901
1902 dma_buffer += size;
1903 bh = bh->b_reqnext;
1904 #ifdef SANITY
1905 if ( !bh){
1906 printk(DEVICE_NAME
1907 ": bh=null in copy buffer after copy\n");
1908 break;
1909 }
1910 #endif
1911 size = bh->b_size;
1912 buffer = bh->b_data;
1913 }
1914 #ifdef SANITY
1915 if ( remaining ){
1916 if ( remaining > 0 )
1917 max_sector -= remaining >> 9;
1918 printk(DEVICE_NAME
1919 ": weirdness: remaining %d\n", remaining>>9);
1920 }
1921 #endif
1922 }
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934 static int make_raw_rw_request(void)
1935 {
1936 int aligned_sector_t;
1937 int max_sector, max_size, tracksize, ssize;
1938
1939 current_drive = DRIVE(CURRENT->dev);
1940
1941 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
1942 FD_RAW_NEED_SEEK;
1943 raw_cmd.cmd_count = NR_RW;
1944 if (CURRENT->cmd == READ){
1945 raw_cmd.flags |= FD_RAW_READ;
1946 COMMAND = FD_READ;
1947 } else if (CURRENT->cmd == WRITE){
1948 raw_cmd.flags |= FD_RAW_WRITE;
1949 COMMAND = FD_WRITE;
1950 } else {
1951 printk(DEVICE_NAME
1952 ": make_raw_rw_request: unknown command\n");
1953 return 0;
1954 }
1955
1956 max_sector = floppy->sect * floppy->head;
1957 TRACK = CURRENT->sector / max_sector;
1958 sector_t = CURRENT->sector % max_sector;
1959 if ( floppy->track && TRACK >= floppy->track )
1960 return 0;
1961 HEAD = sector_t / floppy->sect;
1962
1963 if ( (DRS->flags & FD_NEED_TWADDLE) && sector_t < floppy->sect )
1964 max_sector = floppy->sect;
1965
1966
1967 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
1968 max_sector = 2 * floppy->sect / 3;
1969 if (sector_t >= max_sector){
1970 current_count_sectors = (floppy->sect - sector_t);
1971 if ( current_count_sectors > CURRENT->nr_sectors )
1972 current_count_sectors = CURRENT->nr_sectors;
1973 return 1;
1974 }
1975 SIZECODE = 2;
1976 } else
1977 SIZECODE = FD_SIZECODE(floppy);
1978 raw_cmd.rate = floppy->rate & 3;
1979 if ((floppy->rate & FD_2M) &&
1980 (TRACK || HEAD ) &&
1981 raw_cmd.rate == 2)
1982 raw_cmd.rate = 1;
1983
1984 SIZECODE2 = 0xff;
1985 raw_cmd.track = TRACK << floppy->stretch;
1986 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
1987 GAP = floppy->gap;
1988 ssize = 1 << (SIZECODE - 2 );
1989 SECT_PER_TRACK = floppy->sect / ssize;
1990 SECTOR = (sector_t % floppy->sect) / ssize + 1;
1991 tracksize = floppy->sect - floppy->sect % ssize;
1992 if ( tracksize < floppy->sect ){
1993 SECT_PER_TRACK ++;
1994 if ( tracksize <= sector_t % floppy->sect)
1995 SECTOR--;
1996 while ( tracksize <= sector_t % floppy->sect){
1997 while( tracksize + ssize > floppy->sect ){
1998 SIZECODE--;
1999 ssize >>= 1;
2000 }
2001 SECTOR++; SECT_PER_TRACK ++;
2002 tracksize += ssize;
2003 }
2004 max_sector = HEAD * floppy->sect + tracksize;
2005 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2006 max_sector = floppy->sect;
2007
2008 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2009 max_size = CURRENT->nr_sectors;
2010 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2011 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2012
2013 if (COMMAND == FD_READ) {
2014 copy_buffer(1, max_sector, buffer_max);
2015 return 1;
2016 }
2017 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2018 if (COMMAND == FD_WRITE){
2019 if(sector_t + CURRENT->nr_sectors > ssize &&
2020 sector_t + CURRENT->nr_sectors < ssize + ssize)
2021 max_size = ssize + ssize;
2022 else
2023 max_size = ssize;
2024 }
2025 raw_cmd.flags &= ~FD_RAW_WRITE;
2026 raw_cmd.flags |= FD_RAW_READ;
2027 COMMAND = FD_READ;
2028 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2029 int direct, indirect;
2030
2031 indirect= transfer_size(ssize,max_sector,MAX_BUFFER_SECTORS*2) -
2032 sector_t;
2033
2034 max_size = buffer_chain_size();
2035 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2036 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2037
2038 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2039 ((long) CURRENT->buffer ) / K_64 )
2040 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2041 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2042
2043
2044
2045
2046
2047
2048
2049 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2050 *errors < DP->max_errors.read_track &&
2051
2052 ( ( !probing || (DP->read_track &
2053 (1 <<DRS->probed_format))))){
2054 max_size = CURRENT->nr_sectors;
2055 } else {
2056 current_addr = CURRENT->buffer;
2057 raw_cmd.length = current_count_sectors << 9;
2058 return 2;
2059 }
2060 }
2061
2062 if ( COMMAND == FD_READ )
2063 max_size = max_sector;
2064
2065
2066 if (buffer_track != raw_cmd.track ||
2067 buffer_drive !=current_drive ||
2068 sector_t < buffer_min ||
2069 ((COMMAND == FD_READ ||
2070 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2071 max_sector > 2 * MAX_BUFFER_SECTORS + buffer_min &&
2072 max_size + sector_t > 2 * MAX_BUFFER_SECTORS + buffer_min)
2073 ){
2074 buffer_track = -1;
2075 buffer_drive = current_drive;
2076 buffer_max = buffer_min = aligned_sector_t;
2077 }
2078 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2079
2080 if ( COMMAND == FD_WRITE ){
2081
2082
2083
2084
2085 #ifdef SANITY
2086 if (sector_t != aligned_sector_t && buffer_track == -1 )
2087 printk(DEVICE_NAME
2088 ": internal error offset !=0 on write\n");
2089 #endif
2090 buffer_track = raw_cmd.track;
2091 buffer_drive = current_drive;
2092 copy_buffer(ssize, max_sector, 2*MAX_BUFFER_SECTORS+buffer_min);
2093 } else
2094 transfer_size(ssize, max_sector,
2095 2*MAX_BUFFER_SECTORS+buffer_min-aligned_sector_t);
2096
2097
2098 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2099 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2100 raw_cmd.length <<= 9;
2101 #ifdef SANITY
2102 if ((raw_cmd.length < current_count_sectors << 9) ||
2103 (current_addr != CURRENT->buffer && COMMAND == FD_WRITE &&
2104 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2105 aligned_sector_t < buffer_min )) ||
2106 raw_cmd.length % ( 512 << ( SIZECODE -2 )) ||
2107 raw_cmd.length <= 0 || current_count_sectors <= 0){
2108 printk(DEVICE_NAME ": fractionary current count b=%lx s=%lx\n",
2109 raw_cmd.length, current_count_sectors);
2110 if ( current_addr != CURRENT->buffer )
2111 printk("addr=%d, length=%ld\n",
2112 (current_addr - floppy_track_buffer ) >> 9,
2113 current_count_sectors);
2114 printk("st=%d ast=%d mse=%d msi=%d\n",
2115 sector_t, aligned_sector_t, max_sector, max_size);
2116 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2117 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2118 COMMAND, SECTOR, HEAD, TRACK);
2119 printk("buffer drive=%d\n", buffer_drive);
2120 printk("buffer track=%d\n", buffer_track);
2121 printk("buffer_min=%d\n", buffer_min );
2122 printk("buffer_max=%d\n", buffer_max );
2123 return 0;
2124 }
2125
2126 if (current_addr != CURRENT->buffer ){
2127 if (current_addr < floppy_track_buffer ||
2128 current_count_sectors < 0 ||
2129 raw_cmd.length < 0 ||
2130 current_addr + raw_cmd.length >
2131 floppy_track_buffer + ( 2 * MAX_BUFFER_SECTORS << 9 )){
2132 printk(DEVICE_NAME
2133 ": buffer overrun in schedule dma\n");
2134 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2135 sector_t, buffer_min,
2136 raw_cmd.length >> 9 );
2137 printk("current_count_sectors=%ld\n",
2138 current_count_sectors);
2139 if ( COMMAND == FD_READ )
2140 printk("read\n");
2141 if ( COMMAND == FD_READ )
2142 printk("write\n");
2143 return 0;
2144 }
2145 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2146 current_count_sectors > CURRENT->nr_sectors){
2147 printk(DEVICE_NAME ": buffer overrun in direct transfer\n");
2148 return 0;
2149 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2150 printk(DEVICE_NAME ": more sectors than bytes\n");
2151 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2152 printk("sectors=%ld\n", current_count_sectors);
2153 }
2154 #endif
2155 return 2;
2156 }
2157
2158 static void redo_fd_request(void)
2159 {
2160 #define REPEAT {request_done(0); continue; }
2161 int device;
2162 int tmp;
2163
2164 if (CURRENT && CURRENT->dev < 0) return;
2165
2166
2167 while(1){
2168 if (!CURRENT) {
2169 CLEAR_INTR;
2170 unlock_fdc();
2171 return;
2172 }
2173 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2174 panic(DEVICE_NAME ": request list destroyed");
2175 if (CURRENT->bh && !CURRENT->bh->b_lock)
2176 panic(DEVICE_NAME ": block not locked");
2177
2178 device = MINOR(CURRENT->dev);
2179 set_fdc( DRIVE(device));
2180 CHECK_RESET;
2181 start_motor();
2182 if (( changed_floppies | fake_change) & ( 1 << DRIVE(device))){
2183 printk(DEVICE_NAME
2184 ": disk absent or changed during operation\n");
2185 REPEAT;
2186 }
2187 set_floppy(device);
2188 if (!floppy) {
2189 if (!probing){
2190 DRS->probed_format = 0;
2191 if ( next_valid_format() ){
2192 printk(DEVICE_NAME
2193 ": no autodetectable formats\n");
2194 floppy = NULL;
2195 REPEAT;
2196 }
2197 }
2198 probing = 1;
2199 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2200 } else
2201 probing = 0;
2202 errors = & (CURRENT->errors);
2203 tmp = make_raw_rw_request();
2204 if ( tmp < 2 ){
2205 request_done(tmp);
2206 continue;
2207 }
2208 if ( DRS->flags & FD_NEED_TWADDLE )
2209 twaddle();
2210 floppy_on(current_drive);
2211 #ifdef DEBUGT
2212 debugt("queue fd request");
2213 #endif
2214 return;
2215 }
2216 #undef REPEAT
2217 }
2218
2219 static struct cont_t rw_cont={
2220 rw_interrupt,
2221 redo_fd_request,
2222 bad_flp_intr,
2223 request_done };
2224
2225 void do_fd_request(void)
2226 {
2227 lock_fdc(-1);
2228 cont = &rw_cont;
2229 redo_fd_request();
2230 }
2231
2232
2233
2234
2235
2236
2237 static void reset_intr(void)
2238 {
2239 printk("weird, reset interrupt called\n");
2240 }
2241
2242 static struct cont_t reset_cont={
2243 reset_intr,
2244 success_and_wakeup,
2245 generic_failure,
2246 generic_done };
2247
2248 static int user_reset_fdc(int drive, int arg)
2249 {
2250 int result;
2251
2252 result=0;
2253 lock_fdc(drive);
2254 switch(arg){
2255 case FD_RESET_ALWAYS:
2256 FDCS->reset=1;
2257 break;
2258 case FD_RESET_IF_RAWCMD:
2259 if(FDCS->rawcmd == 2 )
2260 reset_fdc_info(1);
2261 break;
2262 }
2263 if ( FDCS->reset ){
2264 cont = &reset_cont;
2265 timer_table[FLOPPY_TIMER].expires = jiffies + 5;
2266 timer_active |= 1 << FLOPPY_TIMER;
2267 reset_fdc();
2268 result=wait_til_done();
2269 }
2270 unlock_fdc();
2271 return result;
2272 }
2273
2274
2275
2276
2277
2278 static int fd_copyout(void *param, volatile void *address, int size)
2279 {
2280 int i;
2281
2282 i = verify_area(VERIFY_WRITE,param,size);
2283 if (i)
2284 return i;
2285 memcpy_tofs(param,(void *) address, size);
2286 return 0;
2287 }
2288 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2289 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2290
2291 static void poll_drive(int drive)
2292 {
2293 lock_fdc(drive);
2294 start_motor();
2295 unlock_fdc();
2296 }
2297
2298 static char *drive_name(int type, int drive )
2299 {
2300 struct floppy_struct *floppy;
2301
2302 if ( type )
2303 floppy = floppy_type + type;
2304 else {
2305 if ( UDP->native_format )
2306 floppy = floppy_type + UDP->native_format;
2307 else
2308 return "(null)";
2309 }
2310 if ( floppy->name )
2311 return floppy->name;
2312 else
2313 return "(null)";
2314 }
2315
2316
2317 static struct cont_t raw_cmd_cont={
2318 success_and_wakeup,
2319 failure_and_wakeup,
2320 generic_failure,
2321 generic_done };
2322
2323 static int raw_cmd_ioctl(int drive, void *param)
2324 {
2325 int i, count, ret;
2326
2327 if ( FDCS->rawcmd <= 1 )
2328 FDCS->rawcmd = 1;
2329 for ( i= 0; i < N_DRIVE; i++){
2330 if ( FDC(i) != fdc)
2331 continue;
2332 if ( i == drive ){
2333 if ( drive_state[i].fd_ref > 1 )
2334 return -EBUSY;
2335 } else if ( drive_state[i].fd_ref )
2336 return -EBUSY;
2337 }
2338
2339 if(FDCS->reset)
2340 return -EIO;
2341
2342 COPYIN(raw_cmd);
2343 raw_cmd.rate &= 0x03;
2344 count = raw_cmd.length;
2345 if ((raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)) &&
2346 count > MAX_BUFFER_SECTORS * 512 * 2 )
2347 return -ENOMEM;
2348
2349 if ( raw_cmd.flags & FD_RAW_WRITE ){
2350 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2351 if (i)
2352 return i;
2353 buffer_track = -1;
2354 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2355 }
2356
2357 current_addr = floppy_track_buffer;
2358 raw_cmd.flags |= FD_RAW_USER_SUPPLIED;
2359 cont = &raw_cmd_cont;
2360 floppy_on(current_drive);
2361 ret=wait_til_done();
2362
2363 if ( !ret && !FDCS->reset ){
2364 raw_cmd.reply_count = inr;
2365 for( i=0; i< raw_cmd.reply_count; i++)
2366 raw_cmd.reply[i] = reply_buffer[i];
2367 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2368 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2369 } else
2370 ret = -EIO;
2371 DRS->track = NO_TRACK;
2372 if ( ret )
2373 return ret;
2374
2375 if ( raw_cmd.flags & FD_RAW_READ ){
2376 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2377 if (i)
2378 return i;
2379 }
2380
2381 return COPYOUT(raw_cmd);
2382 }
2383
2384 static int invalidate_drive(int rdev)
2385 {
2386
2387 cli();
2388 fake_change |= 1 << DRIVE(rdev);
2389 sti();
2390 unlock_fdc();
2391 check_disk_change(rdev);
2392 return 0;
2393 }
2394
2395 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2396 unsigned long param)
2397 {
2398 #define IOCTL_MODE_BIT 8
2399 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2400
2401 struct floppy_struct newparams;
2402 struct format_descr tmp_format_req;
2403 int i,device,drive,type,cnt;
2404 struct floppy_struct *this_floppy;
2405 char *name;
2406
2407 device = MINOR(inode->i_rdev);
2408 switch (cmd) {
2409 RO_IOCTLS(device,param);
2410 }
2411 type = TYPE(MINOR(device));
2412 drive = DRIVE(MINOR(device));
2413 switch (cmd) {
2414 case FDGETDRVTYP:
2415 i=verify_area(VERIFY_WRITE,(void *) param,16);
2416 if (i)
2417 return i;
2418 name = drive_name(type,drive);
2419 for ( cnt=0; cnt<16; cnt++){
2420 put_fs_byte(name[cnt],
2421 ((char*)param)+cnt);
2422 if ( ! *name )
2423 break;
2424 }
2425 return 0;
2426 case FDGETMAXERRS:
2427 return COPYOUT(UDP->max_errors);
2428 case FDGETPRM:
2429 if (type)
2430 this_floppy = &floppy_type[type];
2431 else if ((this_floppy = current_type[drive]) ==
2432 NULL)
2433 return -ENODEV;
2434 return COPYOUT(this_floppy[0]);
2435 case FDPOLLDRVSTAT:
2436 poll_drive(drive);
2437
2438 case FDGETDRVSTAT:
2439 return COPYOUT(*UDRS);
2440 case FDGETFDCSTAT:
2441 return COPYOUT(*UFDCS);
2442 case FDGETDRVPRM:
2443 return COPYOUT(*UDP);
2444 }
2445 if (!IOCTL_ALLOWED)
2446 return -EPERM;
2447 switch (cmd) {
2448 case FDRAWCMD:
2449 if (type)
2450 return -EINVAL;
2451 lock_fdc(drive);
2452 set_floppy(device);
2453 i = raw_cmd_ioctl(drive, (void *) param);
2454 unlock_fdc();
2455 return i;
2456 case FDFMTTRK:
2457 if (UDRS->fd_ref != 1)
2458 return -EBUSY;
2459 if (! (UDRS->flags & FD_DRIVE_PRESENT ))
2460 return -ENXIO;
2461 COPYIN(tmp_format_req);
2462 return do_format(device, &tmp_format_req);
2463 case FDSETMAXERRS:
2464 return COPYIN(UDP->max_errors);
2465 case FDFMTBEG:
2466 return 0;
2467 case FDCLRPRM:
2468 lock_fdc(drive);
2469 current_type[drive] = NULL;
2470 floppy_sizes[drive] = 2;
2471 UDRS->keep_data = 0;
2472 return invalidate_drive(device);
2473 case FDFMTEND:
2474 case FDFLUSH:
2475 lock_fdc(drive);
2476 return invalidate_drive(device);
2477 case FDSETPRM:
2478 case FDDEFPRM:
2479 COPYIN(newparams);
2480
2481 if(newparams.sect <= 0 ||
2482 newparams.head <= 0 ||
2483 newparams.track <= 0 ||
2484 newparams.track >
2485 UDP->tracks>>newparams.stretch)
2486 return -EINVAL;
2487 if ( type){
2488 if ( !suser() )
2489 return -EPERM;
2490 lock_fdc(-1);
2491 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2492 if (TYPE(drive_state[cnt].fd_device) == type &&
2493 drive_state[cnt].fd_ref){
2494 cli(); fake_change |= 1 << cnt; sti();
2495 }
2496 }
2497 floppy_type[type] = newparams;
2498 floppy_type[type].name="user format";
2499 for (cnt = type << 2 ;
2500 cnt < (type << 2 ) + 4 ;
2501 cnt++)
2502 floppy_sizes[cnt]=
2503 #ifdef HAVE_2_CONTROLLERS
2504 floppy_sizes[cnt+0x80]=
2505 #endif
2506 floppy_type[type].size>>1;
2507 unlock_fdc();
2508 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2509 if (TYPE(drive_state[cnt].fd_device) == type &&
2510 drive_state[cnt].fd_ref)
2511 check_disk_change(drive_state[cnt].
2512 fd_device);
2513 }
2514 return 0;
2515 }
2516
2517 lock_fdc(drive);
2518 if ( cmd != FDDEFPRM )
2519
2520
2521 start_motor();
2522 user_params[drive] = newparams;
2523 if (buffer_drive == drive &&
2524 buffer_max > user_params[drive].sect)
2525 buffer_max=user_params[drive].sect;
2526 current_type[drive] = &user_params[drive];
2527 floppy_sizes[drive] = user_params[drive].size >> 1;
2528 if (cmd == FDDEFPRM)
2529 DRS->keep_data = -1;
2530 else
2531 DRS->keep_data = 1;
2532
2533
2534
2535
2536
2537 if (DRS->maxblock >
2538 user_params[drive].sect ||
2539 DRS->maxtrack )
2540 return invalidate_drive(device);
2541 else
2542 return unlock_fdc();
2543 case FDRESET:
2544 return user_reset_fdc( drive, (int)param);
2545 case FDMSGON:
2546 UDP->flags |= FTD_MSG;
2547 return 0;
2548 case FDMSGOFF:
2549 UDP->flags &= ~FTD_MSG;
2550 return 0;
2551 case FDSETEMSGTRESH:
2552 UDP->max_errors.reporting =
2553 (unsigned short) (param & 0x0f);
2554 return 0;
2555 case FDTWADDLE:
2556 lock_fdc(drive);
2557 twaddle();
2558 unlock_fdc();
2559 }
2560 if ( ! suser() )
2561 return -EPERM;
2562 switch(cmd){
2563 case FDSETDRVPRM:
2564 return COPYIN(*UDP);
2565 default:
2566 return -EINVAL;
2567 }
2568 return 0;
2569 #undef IOCTL_ALLOWED
2570 }
2571
2572 #define CMOS_READ(addr) ({ \
2573 outb_p(addr,0x70); \
2574 inb_p(0x71); \
2575 })
2576
2577 static void set_base_type(int drive,int code)
2578 {
2579 if (code > 0 && code <= NUMBER(default_drive_params)) {
2580 memcpy((char *) UDP,
2581 (char *) (&default_drive_params[code].params),
2582 sizeof( struct floppy_drive_params ));
2583 printk("fd%d is %s", drive, default_drive_params[code].name);
2584 return;
2585 } else if (!code)
2586 printk("fd%d is not installed", drive);
2587 else
2588 printk("fd%d is unknown type %d",drive,code);
2589 }
2590
2591 static void config_types(void)
2592 {
2593 int drive;
2594
2595 for (drive=0; drive<N_DRIVE ; drive++){
2596
2597 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2598 sizeof( struct floppy_drive_params ));
2599 }
2600 printk("Floppy drive(s): ");
2601 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2602 if (CMOS_READ(0x10) & 15) {
2603 printk(", ");
2604 set_base_type(1, CMOS_READ(0x10) & 15);
2605 }
2606 printk("\n");
2607 }
2608
2609
2610 static void maybe_check_change(int device)
2611 {
2612 register int drive;
2613
2614 drive = DRIVE(device);
2615 if (UDRS->last_checked + UDP->checkfreq < jiffies ||
2616 UDRS->flags & FD_VERIFY ||
2617 (( changed_floppies | fake_change ) & ( 1 << drive)))
2618 check_disk_change(device);
2619 }
2620
2621 int floppy_is_wp( int minor)
2622 {
2623 maybe_check_change(minor + (MAJOR_NR << 8));
2624 return ! ( drive_state[ DRIVE(minor) ].flags & FD_DISK_WRITABLE );
2625 }
2626
2627
2628 #define WRAPPER(op) \
2629 static int floppy_##op(struct inode * inode, struct file * filp, \
2630 char * buf, int count) \
2631 { \
2632 maybe_check_change(inode->i_rdev); \
2633 if ( changed_floppies & ( 1 << DRIVE(inode->i_rdev) )) \
2634 return -ENXIO; \
2635 return block_##op(inode, filp, buf, count); \
2636 }
2637
2638 WRAPPER(read)
2639 WRAPPER(write)
2640
2641 static int exclusive = 0;
2642 static void floppy_release(struct inode * inode, struct file * filp)
2643 {
2644 int drive= DRIVE(inode->i_rdev);
2645
2646 fsync_dev(inode->i_rdev);
2647 if ( UDRS->fd_ref < 0)
2648 UDRS->fd_ref=0;
2649 else if (!UDRS->fd_ref--) {
2650 printk(DEVICE_NAME ": floppy_release with fd_ref == 0");
2651 UDRS->fd_ref = 0;
2652 }
2653 floppy_release_irq_and_dma();
2654 exclusive=0;
2655 }
2656
2657
2658
2659
2660
2661
2662 #define RETERR(x) \
2663 do{floppy_release(inode,filp); \
2664 return -(x);}while(0)
2665 static int usage_count = 0;
2666 static int floppy_open(struct inode * inode, struct file * filp)
2667 {
2668 int drive;
2669 int old_dev;
2670
2671 if (exclusive)
2672 return -EBUSY;
2673
2674 if (!filp) {
2675 printk(DEVICE_NAME ": Weird, open called with filp=0\n");
2676 return -EIO;
2677 }
2678
2679 drive = DRIVE(inode->i_rdev);
2680 if ( drive >= N_DRIVE )
2681 return -ENXIO;
2682
2683 if (command_status == FD_COMMAND_DETECT && drive >= current_drive) {
2684 lock_fdc(-1);
2685 unlock_fdc();
2686 }
2687
2688 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2689 return -ENXIO;
2690
2691 if (filp->f_mode & 3) {
2692 if ( !(UDRS->flags & FD_DRIVE_PRESENT))
2693 return -ENXIO;
2694 }
2695
2696 old_dev = UDRS->fd_device;
2697 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2698 return -EBUSY;
2699
2700 if (filp->f_flags & O_EXCL) {
2701 if (usage_count)
2702 return -EBUSY;
2703 else
2704 exclusive = 1;
2705 }
2706
2707 if (floppy_grab_irq_and_dma())
2708 return -EBUSY;
2709
2710 UDRS->fd_ref++;
2711 UDRS->fd_device = inode->i_rdev;
2712
2713 if (old_dev && old_dev != inode->i_rdev) {
2714 if (buffer_drive == drive)
2715 buffer_track = -1;
2716 invalidate_buffers(old_dev);
2717 }
2718
2719
2720 if ((filp->f_mode & 2) || permission(inode,2))
2721 filp->f_mode |= IOCTL_MODE_BIT;
2722
2723 if (UFDCS->rawcmd == 1)
2724 UFDCS->rawcmd = 2;
2725
2726 if (filp->f_flags & O_NDELAY)
2727 return 0;
2728
2729 if (filp->f_mode && !(UDRS->flags & FD_DRIVE_PRESENT))
2730 RETERR(ENXIO);
2731
2732 if (user_reset_fdc(drive, FD_RESET_IF_NEEDED))
2733 RETERR(EIO);
2734
2735 if (filp->f_mode & 3) {
2736 check_disk_change(inode->i_rdev);
2737 if (changed_floppies & ( 1 << drive ))
2738 RETERR(ENXIO);
2739 }
2740 if ((filp->f_mode & 2) && !(UDRS->flags & FD_DISK_WRITABLE))
2741 RETERR(EROFS);
2742 return 0;
2743 #undef RETERR
2744 }
2745
2746
2747
2748
2749 static int ack_change(int drive)
2750 {
2751 unsigned int mask = 1 << drive;
2752 UDRS->maxblock = 0;
2753 UDRS->maxtrack = 0;
2754 if ( buffer_drive == drive )
2755 buffer_track = -1;
2756 fake_change &= ~mask;
2757 changed_floppies &= ~mask;
2758 return 1;
2759 }
2760
2761
2762
2763
2764 static int check_floppy_change(dev_t dev)
2765 {
2766 int drive = DRIVE( dev );
2767 unsigned int mask = 1 << drive;
2768
2769 if (MAJOR(dev) != MAJOR_NR) {
2770 printk(DEVICE_NAME ": floppy_changed: not a floppy\n");
2771 return 0;
2772 }
2773
2774 if (fake_change & mask)
2775 return ack_change(drive);
2776
2777 if ((UDRS->flags & FD_VERIFY ) || (changed_floppies & mask) ||
2778 UDRS->last_checked + UDP->checkfreq <
2779 jiffies){
2780 user_reset_fdc(drive, FD_RESET_IF_NEEDED);
2781 poll_drive(drive);
2782 if (changed_floppies & mask){
2783 UDRS->generation++;
2784 return ack_change(drive);
2785 }
2786 }
2787 return 0;
2788 }
2789
2790
2791
2792 static int floppy_revalidate(dev_t dev)
2793 {
2794 struct buffer_head * bh;
2795
2796 if ( TYPE(dev) || current_type[DRIVE(dev)] )
2797 return 0;
2798 if (!(bh = getblk(dev,0,1024)))
2799 return 1;
2800 if ( bh && ! bh->b_uptodate)
2801 ll_rw_block(READ, 1, &bh);
2802 brelse(bh);
2803 return 0;
2804 }
2805
2806 static struct file_operations floppy_fops = {
2807 NULL,
2808 floppy_read,
2809 floppy_write,
2810 NULL,
2811 NULL,
2812 fd_ioctl,
2813 NULL,
2814 floppy_open,
2815 floppy_release,
2816 block_fsync,
2817 NULL,
2818 check_floppy_change,
2819 floppy_revalidate,
2820 };
2821
2822
2823
2824
2825
2826
2827
2828
2829 static char get_fdc_version(void)
2830 {
2831 int r;
2832
2833 output_byte(FD_DUMPREGS);
2834 if ( FDCS->reset )
2835 return FDC_NONE;
2836 if ( (r = result()) <= 0x00)
2837 return FDC_NONE;
2838 if ((r==1) && (reply_buffer[0] == 0x80)){
2839 printk("FDC %d is a 8272A\n",fdc);
2840 return FDC_8272A;
2841 }
2842 if (r != 10) {
2843 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
2844 return FDC_UNKNOWN;
2845 }
2846 output_byte(FD_VERSION);
2847 r = result();
2848 if ((r == 1) && (reply_buffer[0] == 0x80)){
2849 printk("FDC %d is a 82072\n",fdc);
2850 return FDC_82072;
2851 }
2852 if ((r != 1) || (reply_buffer[0] != 0x90)) {
2853 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
2854 return FDC_UNKNOWN;
2855 }
2856 output_byte(FD_UNLOCK);
2857 r = result();
2858 if ((r == 1) && (reply_buffer[0] == 0x80)){
2859 printk("FDC %d is a pre-1991 82077\n", fdc);
2860 return FDC_82077_ORIG;
2861 }
2862 if ((r != 1) || (reply_buffer[0] != 0x00)) {
2863 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
2864 return FDC_UNKNOWN;
2865 }
2866 printk("FDC %d is a post-1991 82077\n",fdc);
2867 return FDC_82077;
2868 }
2869
2870
2871
2872
2873
2874 static void detect_interrupt(void)
2875 {
2876 if ( DRS->track == 0 )
2877 DRS->flags |= FD_DRIVE_PRESENT | FD_VERIFY;
2878 else if ( DRS->track != NEED_1_RECAL ){
2879 floppy_ready();
2880 return;
2881 }
2882 floppy_off(current_drive);
2883 current_drive++;
2884 if (current_drive == N_DRIVE ||
2885 fdc_state[FDC(current_drive)].version == FDC_NONE){
2886 set_fdc(0);
2887 unlock_fdc();
2888 floppy_release_irq_and_dma();
2889 return;
2890 }
2891 set_fdc(current_drive);
2892 floppy_ready();
2893 }
2894
2895 static struct cont_t detect_cont={
2896 detect_interrupt,
2897 detect_interrupt,
2898 empty,
2899 (done_f) empty };
2900
2901 void floppy_init(void)
2902 {
2903 int i;
2904
2905 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
2906 printk("Unable to get major %d for floppy\n",MAJOR_NR);
2907 return;
2908 }
2909
2910 for(i=0; i<256; i++)
2911 if ( TYPE(i))
2912 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
2913 else
2914 floppy_sizes[i] = MAX_DISK_SIZE;
2915
2916 blk_size[MAJOR_NR] = floppy_sizes;
2917 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
2918 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
2919 timer_active &= ~(1 << FLOPPY_TIMER);
2920 config_types();
2921
2922 fdc_state[0].address = 0x3f0;
2923 #if N_FDC > 1
2924 fdc_state[1].address = 0x370;
2925 #endif
2926 for (i = 0 ; i < N_FDC ; i++) {
2927 fdc = i;
2928 FDCS->dtr = -1;
2929 FDCS->dor = 0;
2930 FDCS->reset = 0;
2931 FDCS->version = FDC_NONE;
2932 set_dor(fdc, ~0, 0xc );
2933 }
2934
2935
2936 for (i = 0; i < N_DRIVE ; i++) {
2937 current_drive = i;
2938 DRS->flags = FD_VERIFY;
2939 DRS->generation = 0;
2940 DRS->keep_data = 0;
2941 DRS->fd_ref = 0;
2942 DRS->fd_device = 0;
2943 }
2944
2945 floppy_grab_irq_and_dma();
2946 for (i = 0 ; i < N_FDC ; i++) {
2947 fdc = i;
2948 FDCS->rawcmd = 2;
2949 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED))
2950 continue;
2951
2952 FDCS->version = get_fdc_version();
2953 if (FDCS->version == FDC_NONE)
2954 continue;
2955
2956
2957
2958
2959
2960 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
2961 user_reset_fdc(-1,FD_RESET_ALWAYS);
2962 }
2963 fdc=0;
2964 current_drive = 0;
2965 lock_fdc(-1);
2966 initialising =0;
2967 command_status = FD_COMMAND_DETECT;
2968 cont = &detect_cont;
2969 raw_cmd.cmd_count = 0;
2970 raw_cmd.flags = FD_RAW_NEED_SEEK;
2971 raw_cmd.track = 0;
2972 floppy_ready();
2973 cli();
2974 }
2975
2976 int floppy_grab_irq_and_dma(void)
2977 {
2978 if (usage_count++)
2979 return 0;
2980 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
2981 printk(DEVICE_NAME
2982 ": Unable to grab IRQ%d for the floppy driver\n",
2983 FLOPPY_IRQ);
2984 return -1;
2985 }
2986 if (request_dma(FLOPPY_DMA,"floppy")) {
2987 printk(DEVICE_NAME
2988 ": Unable to grab DMA%d for the floppy driver\n",
2989 FLOPPY_DMA);
2990 free_irq(FLOPPY_IRQ);
2991 return -1;
2992 }
2993 enable_irq(FLOPPY_IRQ);
2994 return 0;
2995 }
2996
2997 void floppy_release_irq_and_dma(void)
2998 {
2999 if (--usage_count)
3000 return;
3001 disable_dma(FLOPPY_DMA);
3002 free_dma(FLOPPY_DMA);
3003 disable_irq(FLOPPY_IRQ);
3004 free_irq(FLOPPY_IRQ);
3005 #ifdef HAVE_2_CONTROLLERS
3006
3007
3008 set_dor(0, ~0, 8 );
3009 set_dor(1, ~8, 0 );
3010 #endif
3011 }