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