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,18,31,11,11, 0, 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,14,13,10, 0, 0, 0, 0}, 150, 4 }, "720k" },
233
234 {{4, 500, 16, 16, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
235 0, { 7, 4,24,14,20,13,23,21}, 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,24,27,14,20,13}, 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,24,27,14,20,13}, 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,0x0a,0xcf,0x6c,"D1040" },
284 { 2240,14,2,80,0,0x1c,0x1a,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,"H800" },
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 adrress. 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 errror");
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 = (void *)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_ALLOWED (filp && (filp->f_mode & 8 ))
2399
2400 struct floppy_struct newparams;
2401 struct format_descr tmp_format_req;
2402 int i,device,drive,type,cnt;
2403 struct floppy_struct *this_floppy;
2404 char *name;
2405
2406 device = MINOR(inode->i_rdev);
2407 switch (cmd) {
2408 RO_IOCTLS(device,param);
2409 }
2410 type = TYPE(MINOR(device));
2411 drive = DRIVE(MINOR(device));
2412 switch (cmd) {
2413 case FDGETDRVTYP:
2414 i=verify_area(VERIFY_WRITE,(void *) param,16);
2415 if (i)
2416 return i;
2417 name = drive_name(type,drive);
2418 for ( cnt=0; cnt<16; cnt++){
2419 put_fs_byte(name[cnt],
2420 ((char*)param)+cnt);
2421 if ( ! *name )
2422 break;
2423 }
2424 return 0;
2425 case FDGETMAXERRS:
2426 return COPYOUT(UDP->max_errors);
2427 case FDGETPRM:
2428 if (type)
2429 this_floppy = &floppy_type[type];
2430 else if ((this_floppy = current_type[drive]) ==
2431 NULL)
2432 return -ENODEV;
2433 return COPYOUT(this_floppy[0]);
2434 case FDPOLLDRVSTAT:
2435 poll_drive(drive);
2436
2437 case FDGETDRVSTAT:
2438 return COPYOUT(*UDRS);
2439 case FDGETFDCSTAT:
2440 return COPYOUT(*UFDCS);
2441 case FDGETDRVPRM:
2442 return COPYOUT(*UDP);
2443 }
2444 if (!IOCTL_ALLOWED)
2445 return -EPERM;
2446 switch (cmd) {
2447 case FDRAWCMD:
2448 if (type)
2449 return -EINVAL;
2450 lock_fdc(drive);
2451 set_floppy(device);
2452 i = raw_cmd_ioctl(drive, (void *) param);
2453 unlock_fdc();
2454 return i;
2455 case FDFMTTRK:
2456 if (UDRS->fd_ref != 1)
2457 return -EBUSY;
2458 if (! (UDRS->flags & FD_DRIVE_PRESENT ))
2459 return -ENXIO;
2460 COPYIN(tmp_format_req);
2461 return do_format(device, &tmp_format_req);
2462 case FDSETMAXERRS:
2463 return COPYIN(UDP->max_errors);
2464 case FDFMTBEG:
2465 return 0;
2466 case FDCLRPRM:
2467 lock_fdc(drive);
2468 current_type[drive] = NULL;
2469 floppy_sizes[drive] = 2;
2470 UDRS->keep_data = 0;
2471 return invalidate_drive(device);
2472 case FDFMTEND:
2473 case FDFLUSH:
2474 lock_fdc(drive);
2475 return invalidate_drive(device);
2476 case FDSETPRM:
2477 case FDDEFPRM:
2478 COPYIN(newparams);
2479
2480 if(newparams.sect <= 0 ||
2481 newparams.head <= 0 ||
2482 newparams.track <= 0 ||
2483 newparams.track >
2484 UDP->tracks>>newparams.stretch)
2485 return -EINVAL;
2486 if ( type){
2487 if ( !suser() )
2488 return -EPERM;
2489 lock_fdc(-1);
2490 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2491 if (TYPE(drive_state[cnt].fd_device) == type &&
2492 drive_state[cnt].fd_ref){
2493 cli(); fake_change |= 1 << cnt; sti();
2494 }
2495 }
2496 floppy_type[type] = newparams;
2497 floppy_type[type].name="user format";
2498 for (cnt = type << 2 ;
2499 cnt < (type << 2 ) + 4 ;
2500 cnt++)
2501 floppy_sizes[cnt]=
2502 #ifdef HAVE_2_CONTROLLERS
2503 floppy_sizes[cnt+0x80]=
2504 #endif
2505 floppy_type[type].size>>1;
2506 unlock_fdc();
2507 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2508 if (TYPE(drive_state[cnt].fd_device) == type &&
2509 drive_state[cnt].fd_ref)
2510 check_disk_change(drive_state[cnt].
2511 fd_device);
2512 }
2513 return 0;
2514 }
2515
2516 lock_fdc(drive);
2517 if ( cmd != FDDEFPRM )
2518
2519
2520 start_motor();
2521 user_params[drive] = newparams;
2522 if (buffer_drive == drive &&
2523 buffer_max > user_params[drive].sect)
2524 buffer_max=user_params[drive].sect;
2525 current_type[drive] = &user_params[drive];
2526 floppy_sizes[drive] = user_params[drive].size >> 1;
2527 if (cmd == FDDEFPRM)
2528 DRS->keep_data = -1;
2529 else
2530 DRS->keep_data = 1;
2531
2532
2533
2534
2535
2536 if (DRS->maxblock >
2537 user_params[drive].sect ||
2538 DRS->maxtrack )
2539 return invalidate_drive(device);
2540 else
2541 return unlock_fdc();
2542 case FDRESET:
2543 return user_reset_fdc( drive, (int)param);
2544 case FDMSGON:
2545 UDP->flags |= FTD_MSG;
2546 return 0;
2547 case FDMSGOFF:
2548 UDP->flags &= ~FTD_MSG;
2549 return 0;
2550 case FDSETEMSGTRESH:
2551 UDP->max_errors.reporting =
2552 (unsigned short) (param & 0x0f);
2553 return 0;
2554 case FDTWADDLE:
2555 lock_fdc(drive);
2556 twaddle();
2557 unlock_fdc();
2558 }
2559 if ( ! suser() )
2560 return -EPERM;
2561 switch(cmd){
2562 case FDSETDRVPRM:
2563 return COPYIN(*UDP);
2564 default:
2565 return -EINVAL;
2566 }
2567 return 0;
2568 #undef IOCTL_ALLOWED
2569 }
2570
2571 #define CMOS_READ(addr) ({ \
2572 outb_p(addr,0x70); \
2573 inb_p(0x71); \
2574 })
2575
2576 static void set_base_type(int drive,int code)
2577 {
2578 if (code > 0 && code <= NUMBER(default_drive_params)) {
2579 memcpy((char *) UDP,
2580 (char *) (&default_drive_params[code].params),
2581 sizeof( struct floppy_drive_params ));
2582 printk("fd%d is %s", drive, default_drive_params[code].name);
2583 return;
2584 } else if (!code)
2585 printk("fd%d is not installed", drive);
2586 else
2587 printk("fd%d is unknown type %d",drive,code);
2588 }
2589
2590 static void config_types(void)
2591 {
2592 int drive;
2593
2594 for (drive=0; drive<N_DRIVE ; drive++){
2595
2596 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2597 sizeof( struct floppy_drive_params ));
2598 }
2599 printk("Floppy drive(s): ");
2600 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2601 if (CMOS_READ(0x10) & 15) {
2602 printk(", ");
2603 set_base_type(1, CMOS_READ(0x10) & 15);
2604 }
2605 printk("\n");
2606 }
2607
2608
2609 static void maybe_check_change(int device)
2610 {
2611 register int drive;
2612
2613 drive = DRIVE(device);
2614 if (UDRS->last_checked + UDP->checkfreq < jiffies ||
2615 UDRS->flags & FD_VERIFY ||
2616 (( changed_floppies | fake_change ) & ( 1 << drive)))
2617 check_disk_change(device);
2618 }
2619
2620 int floppy_is_wp( int minor)
2621 {
2622 maybe_check_change(minor + (MAJOR_NR << 8));
2623 return ! ( drive_state[ DRIVE(minor) ].flags & FD_DISK_WRITABLE );
2624 }
2625
2626
2627 #define WRAPPER(op) \
2628 static int floppy_##op(struct inode * inode, struct file * filp, \
2629 char * buf, int count) \
2630 { \
2631 maybe_check_change(inode->i_rdev); \
2632 if ( changed_floppies & ( 1 << DRIVE(inode->i_rdev) )) \
2633 return -ENXIO; \
2634 return block_##op(inode, filp, buf, count); \
2635 }
2636
2637 WRAPPER(read)
2638 WRAPPER(write)
2639
2640 static int exclusive = 0;
2641 static void floppy_release(struct inode * inode, struct file * filp)
2642 {
2643 int drive= DRIVE(inode->i_rdev);
2644
2645 fsync_dev(inode->i_rdev);
2646 if ( UDRS->fd_ref < 0)
2647 UDRS->fd_ref=0;
2648 else if (!UDRS->fd_ref--) {
2649 printk(DEVICE_NAME ": floppy_release with fd_ref == 0");
2650 UDRS->fd_ref = 0;
2651 }
2652 floppy_release_irq_and_dma();
2653 exclusive=0;
2654 }
2655
2656
2657
2658
2659
2660
2661 #define RETERR(x) \
2662 do{floppy_release(inode,filp); \
2663 return -(x);}while(0)
2664 static int usage_count = 0;
2665 static int floppy_open(struct inode * inode, struct file * filp)
2666 {
2667 int drive;
2668 int old_dev;
2669
2670 if (exclusive)
2671 return -EBUSY;
2672 if ( !filp ){
2673 printk(DEVICE_NAME ": Weird, open called with filp=0\n");
2674 return -EIO;
2675 }
2676
2677 drive = DRIVE(inode->i_rdev);
2678 if ( drive >= N_DRIVE )
2679 return -ENXIO;
2680
2681 if (command_status == FD_COMMAND_DETECT && drive >= current_drive){
2682 lock_fdc(-1);
2683 unlock_fdc();
2684 }
2685
2686 if ( TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2687 return -ENXIO;
2688
2689 if (filp->f_mode & 3){
2690 if ( !(UDRS->flags & FD_DRIVE_PRESENT))
2691 return -ENXIO;
2692 }
2693
2694 old_dev = UDRS->fd_device;
2695 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2696 return -EBUSY;
2697 if (floppy_grab_irq_and_dma())
2698 return -EBUSY;
2699
2700 if (filp->f_flags & O_EXCL ){
2701 if (usage_count>1){
2702 floppy_release_irq_and_dma();
2703 return -EBUSY;
2704 }else
2705 exclusive=1;
2706 }
2707
2708
2709 if (filp->f_op){
2710 if (UDRS->fd_ref == -1)
2711 return -EBUSY;
2712 UDRS->fd_ref++;
2713 UDRS->fd_device = inode->i_rdev;
2714 } else {
2715 if (UDRS->fd_ref ){
2716 floppy_release_irq_and_dma();
2717 return -EBUSY;
2718 }
2719 UDRS->fd_ref=-1;
2720 }
2721
2722 if (old_dev && old_dev != inode->i_rdev){
2723 if ( buffer_drive == drive )
2724 buffer_track = -1;
2725 invalidate_buffers(old_dev);
2726 }
2727
2728 if (filp->f_mode & 2 || permission(inode,2))
2729 filp->f_mode |= 8;
2730
2731 if (UFDCS->rawcmd == 1)
2732 UFDCS->rawcmd = 2;
2733
2734 if (filp->f_flags & O_NDELAY)
2735 return 0;
2736 if (filp->f_mode && !(UDRS->flags & FD_DRIVE_PRESENT))
2737 RETERR(ENXIO);
2738 if(user_reset_fdc(drive, FD_RESET_IF_NEEDED))
2739 RETERR(EIO);
2740
2741 if (filp->f_mode & 3){
2742 check_disk_change(inode->i_rdev);
2743 if ( changed_floppies & ( 1 << drive )){
2744 if ( suser() && filp->f_op)
2745
2746 filp->f_mode &= ~3;
2747 else
2748 RETERR(ENXIO);
2749 }
2750 }
2751 if ((filp->f_mode & 2) && UDRS->flags < FD_DISK_WRITABLE){
2752 if ( suser() && filp->f_op)
2753
2754 filp->f_mode &= ~2;
2755 else
2756 RETERR(EROFS);
2757 }
2758 return 0;
2759 #undef RETERR
2760 }
2761
2762
2763
2764
2765 static int ack_change(int drive)
2766 {
2767 unsigned int mask = 1 << drive;
2768 UDRS->maxblock = 0;
2769 UDRS->maxtrack = 0;
2770 if ( buffer_drive == drive )
2771 buffer_track = -1;
2772 fake_change &= ~mask;
2773 changed_floppies &= ~mask;
2774 return 1;
2775 }
2776
2777
2778
2779
2780 static int check_floppy_change(dev_t dev)
2781 {
2782 int drive = DRIVE( dev );
2783 unsigned int mask = 1 << drive;
2784
2785 if (MAJOR(dev) != MAJOR_NR) {
2786 printk(DEVICE_NAME ": floppy_changed: not a floppy\n");
2787 return 0;
2788 }
2789
2790 if (fake_change & mask)
2791 return ack_change(drive);
2792
2793 if ((UDRS->flags & FD_VERIFY ) || (changed_floppies & mask) ||
2794 UDRS->last_checked + UDP->checkfreq <
2795 jiffies){
2796 user_reset_fdc(drive, FD_RESET_IF_NEEDED);
2797 poll_drive(drive);
2798 if (changed_floppies & mask){
2799 UDRS->generation++;
2800 return ack_change(drive);
2801 }
2802 }
2803 return 0;
2804 }
2805
2806
2807
2808 static int floppy_revalidate(dev_t dev)
2809 {
2810 struct buffer_head * bh;
2811
2812 if ( TYPE(dev) || current_type[DRIVE(dev)] )
2813 return 0;
2814 if (!(bh = getblk(dev,0,1024)))
2815 return 1;
2816 if ( bh && ! bh->b_uptodate)
2817 ll_rw_block(READ, 1, &bh);
2818 brelse(bh);
2819 return 0;
2820 }
2821
2822 static struct file_operations floppy_fops = {
2823 NULL,
2824 floppy_read,
2825 floppy_write,
2826 NULL,
2827 NULL,
2828 fd_ioctl,
2829 NULL,
2830 floppy_open,
2831 floppy_release,
2832 block_fsync,
2833 NULL,
2834 check_floppy_change,
2835 floppy_revalidate,
2836 };
2837
2838
2839
2840
2841
2842
2843
2844
2845 static char get_fdc_version(void)
2846 {
2847 int r;
2848
2849 output_byte(FD_DUMPREGS);
2850 if ( FDCS->reset )
2851 return FDC_NONE;
2852 if ( (r = result()) <= 0x00)
2853 return FDC_NONE;
2854 if ((r==1) && (reply_buffer[0] == 0x80)){
2855 printk("FDC %d is a 8272A\n",fdc);
2856 return FDC_8272A;
2857 }
2858 if (r != 10) {
2859 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
2860 return FDC_UNKNOWN;
2861 }
2862 output_byte(FD_VERSION);
2863 r = result();
2864 if ((r == 1) && (reply_buffer[0] == 0x80)){
2865 printk("FDC %d is a 82072\n",fdc);
2866 return FDC_82072;
2867 }
2868 if ((r != 1) || (reply_buffer[0] != 0x90)) {
2869 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
2870 return FDC_UNKNOWN;
2871 }
2872 output_byte(FD_UNLOCK);
2873 r = result();
2874 if ((r == 1) && (reply_buffer[0] == 0x80)){
2875 printk("FDC %d is a pre-1991 82077\n", fdc);
2876 return FDC_82077_ORIG;
2877 }
2878 if ((r != 1) || (reply_buffer[0] != 0x00)) {
2879 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
2880 return FDC_UNKNOWN;
2881 }
2882 printk("FDC %d is a post-1991 82077\n",fdc);
2883 return FDC_82077;
2884 }
2885
2886
2887
2888
2889
2890 static void detect_interrupt(void)
2891 {
2892 if ( DRS->track == 0 )
2893 DRS->flags |= FD_DRIVE_PRESENT | FD_VERIFY;
2894 else if ( DRS->track != NEED_1_RECAL ){
2895 floppy_ready();
2896 return;
2897 }
2898 floppy_off(current_drive);
2899 current_drive++;
2900 if (current_drive == N_DRIVE ||
2901 fdc_state[FDC(current_drive)].version == FDC_NONE){
2902 set_fdc(0);
2903 unlock_fdc();
2904 floppy_release_irq_and_dma();
2905 return;
2906 }
2907 set_fdc(current_drive);
2908 floppy_ready();
2909 }
2910
2911 static struct cont_t detect_cont={
2912 detect_interrupt,
2913 detect_interrupt,
2914 empty,
2915 (done_f) empty };
2916
2917
2918
2919
2920
2921 static struct sigaction floppy_sigaction = {
2922 floppy_interrupt,
2923 0,
2924 SA_INTERRUPT,
2925 NULL
2926 };
2927
2928 void floppy_init(void)
2929 {
2930 int i;
2931
2932 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
2933 printk("Unable to get major %d for floppy\n",MAJOR_NR);
2934 return;
2935 }
2936
2937 for(i=0; i<256; i++)
2938 if ( TYPE(i))
2939 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
2940 else
2941 floppy_sizes[i] = MAX_DISK_SIZE;
2942
2943 blk_size[MAJOR_NR] = floppy_sizes;
2944 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
2945 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
2946 timer_active &= ~(1 << FLOPPY_TIMER);
2947 config_types();
2948
2949 fdc_state[0].address = 0x3f0;
2950 fdc_state[1].address = 0x370;
2951 for(fdc = 0 ; fdc < N_FDC; fdc++){
2952 FDCS->dtr = -1;
2953 FDCS->dor = 0;
2954 FDCS->reset = 0;
2955 FDCS->version = FDC_NONE;
2956 set_dor(fdc, ~0, 0xc );
2957 }
2958
2959
2960 for ( current_drive=0; current_drive < N_DRIVE ; current_drive++){
2961 DRS->flags = 0;
2962 DRS->generation = 0;
2963 DRS->keep_data = 0;
2964 DRS->fd_ref = 0;
2965 DRS->fd_device = 0;
2966 }
2967
2968 floppy_grab_irq_and_dma();
2969 for(fdc = 0 ; fdc < N_FDC; fdc++){
2970 FDCS->rawcmd = 2;
2971 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED))
2972 continue;
2973
2974 FDCS->version = get_fdc_version();
2975 if (FDCS->version == FDC_NONE)
2976 continue;
2977
2978
2979
2980
2981
2982 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
2983 user_reset_fdc(-1,FD_RESET_ALWAYS);
2984 }
2985 fdc=0;
2986 current_drive = 0;
2987 lock_fdc(-1);
2988 initialising =0;
2989 command_status = FD_COMMAND_DETECT;
2990 cont = &detect_cont;
2991 raw_cmd.cmd_count = 0;
2992 raw_cmd.flags = FD_RAW_NEED_SEEK;
2993 raw_cmd.track = 0;
2994 floppy_ready();
2995 cli();
2996 }
2997
2998 int floppy_grab_irq_and_dma(void)
2999 {
3000 if (usage_count++)
3001 return 0;
3002 if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) {
3003 printk(DEVICE_NAME
3004 ": Unable to grab IRQ%d for the floppy driver\n",
3005 FLOPPY_IRQ);
3006 return -1;
3007 }
3008 if (request_dma(FLOPPY_DMA)) {
3009 printk(DEVICE_NAME
3010 ": Unable to grab DMA%d for the floppy driver\n",
3011 FLOPPY_DMA);
3012 free_irq(FLOPPY_IRQ);
3013 return -1;
3014 }
3015 enable_irq(FLOPPY_IRQ);
3016 return 0;
3017 }
3018
3019 void floppy_release_irq_and_dma(void)
3020 {
3021 if (--usage_count)
3022 return;
3023 disable_dma(FLOPPY_DMA);
3024 free_dma(FLOPPY_DMA);
3025 disable_irq(FLOPPY_IRQ);
3026 free_irq(FLOPPY_IRQ);
3027 #ifdef HAVE_2_CONTROLLERS
3028
3029
3030 set_dor(0, ~0, 8 );
3031 set_dor(1, ~8, 0 );
3032 #endif
3033 }