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 break;
1754 }
1755
1756 if (probing) {
1757 if (DP->flags & FTD_MSG)
1758 printk(DEVICE_NAME
1759 ": Auto-detected floppy type %s in fd%d\n",
1760 floppy->name,current_drive);
1761 current_type[current_drive] = floppy;
1762 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1763 floppy->size >> 1;
1764 probing = 0;
1765 }
1766
1767 if ( COMMAND != FD_READ || current_addr == CURRENT->buffer ){
1768
1769 cont->done(1);
1770 } else if ( COMMAND == FD_READ){
1771 buffer_track = raw_cmd.track;
1772 buffer_drive = current_drive;
1773 if ( nr_sectors + sector_t > buffer_max )
1774 buffer_max = nr_sectors + sector_t;
1775 }
1776 cont->redo();
1777 }
1778
1779
1780 static int buffer_chain_size(void)
1781 {
1782 struct buffer_head *bh;
1783 int size;
1784 char *base;
1785
1786 base = CURRENT->buffer;
1787 size = CURRENT->current_nr_sectors << 9;
1788 bh = CURRENT->bh;
1789
1790 #ifdef SANITY
1791 if ( !bh ){
1792 printk(DEVICE_NAME ": null request in buffer_chain_size\n");
1793 return size >> 9;
1794 }
1795 #endif
1796
1797 bh = bh->b_reqnext;
1798 while ( bh && bh->b_data == base + size ){
1799 size += bh->b_size;
1800 bh = bh->b_reqnext;
1801 }
1802 return size >> 9;
1803 }
1804
1805
1806 static int transfer_size(int ssize, int max_sector, int max_size)
1807 {
1808 if ( max_sector > sector_t + max_size)
1809 max_sector = sector_t + max_size;
1810
1811
1812 max_sector -= (max_sector % floppy->sect ) % ssize;
1813
1814
1815 current_count_sectors = max_sector - sector_t ;
1816
1817 return max_sector;
1818 }
1819
1820
1821
1822
1823 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
1824 {
1825 int remaining;
1826 struct buffer_head *bh;
1827 char *buffer, *dma_buffer;
1828 int size;
1829
1830 if ( max_sector > max_sector_2 )
1831 max_sector = max_sector_2;
1832
1833 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
1834
1835 if (current_count_sectors <= 0 && COMMAND == FD_WRITE &&
1836 buffer_max > sector_t + CURRENT->nr_sectors){
1837 current_count_sectors = buffer_max - sector_t;
1838 if ( current_count_sectors > CURRENT->nr_sectors )
1839 current_count_sectors = CURRENT->nr_sectors;
1840 }
1841 remaining = current_count_sectors << 9;
1842 #ifdef SANITY
1843 if ((remaining >> 9) > CURRENT->nr_sectors && COMMAND == 0xc5 ){
1844 printk(DEVICE_NAME ": in copy buffer\n");
1845 printk("current_count_sectors=%ld\n", current_count_sectors);
1846 printk("remaining=%d\n", remaining >> 9);
1847 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
1848 printk("CURRENT->current_nr_sectors=%ld\n",
1849 CURRENT->current_nr_sectors);
1850 printk("max_sector=%d\n", max_sector);
1851 printk("ssize=%d\n", ssize);
1852 }
1853 #endif
1854
1855 if ( max_sector > buffer_max )
1856 buffer_max = max_sector;
1857
1858 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
1859
1860 bh = CURRENT->bh;
1861 size = CURRENT->current_nr_sectors << 9;
1862 buffer = CURRENT->buffer;
1863
1864 while ( remaining > 0){
1865 if ( size > remaining )
1866 size = remaining;
1867 #ifdef SANITY
1868 if (!bh){
1869 printk(DEVICE_NAME
1870 ": bh=null in copy buffer before copy\n");
1871 break;
1872 }
1873 if (dma_buffer + size >
1874 floppy_track_buffer + ( 2 * MAX_BUFFER_SECTORS << 9 ) ||
1875 dma_buffer < floppy_track_buffer ){
1876 printk(DEVICE_NAME
1877 ": buffer overrun in copy buffer %d\n",
1878 (floppy_track_buffer - dma_buffer) >>9);
1879 printk("sector_t=%d buffer_min=%d\n",
1880 sector_t, buffer_min);
1881 printk("current_count_sectors=%ld\n",
1882 current_count_sectors);
1883 if ( COMMAND == FD_READ )
1884 printk("read\n");
1885 if ( COMMAND == FD_READ )
1886 printk("write\n");
1887 break;
1888 }
1889 if ( ((int)buffer) % 512 )
1890 printk(DEVICE_NAME ": %p buffer not aligned\n", buffer);
1891 #endif
1892 if ( COMMAND == FD_READ )
1893 memcpy( buffer, dma_buffer, size);
1894 else
1895 memcpy( dma_buffer, buffer, size);
1896 remaining -= size;
1897 if ( !remaining)
1898 break;
1899
1900 dma_buffer += size;
1901 bh = bh->b_reqnext;
1902 #ifdef SANITY
1903 if ( !bh){
1904 printk(DEVICE_NAME
1905 ": bh=null in copy buffer after copy\n");
1906 break;
1907 }
1908 #endif
1909 size = bh->b_size;
1910 buffer = bh->b_data;
1911 }
1912 #ifdef SANITY
1913 if ( remaining ){
1914 if ( remaining > 0 )
1915 max_sector -= remaining >> 9;
1916 printk(DEVICE_NAME
1917 ": weirdness: remaining %d\n", remaining>>9);
1918 }
1919 #endif
1920 }
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932 static int make_raw_rw_request(void)
1933 {
1934 int aligned_sector_t;
1935 int max_sector, max_size, tracksize, ssize;
1936
1937 current_drive = DRIVE(CURRENT->dev);
1938
1939 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
1940 FD_RAW_NEED_SEEK;
1941 raw_cmd.cmd_count = NR_RW;
1942 if (CURRENT->cmd == READ){
1943 raw_cmd.flags |= FD_RAW_READ;
1944 COMMAND = FD_READ;
1945 } else if (CURRENT->cmd == WRITE){
1946 raw_cmd.flags |= FD_RAW_WRITE;
1947 COMMAND = FD_WRITE;
1948 } else {
1949 printk(DEVICE_NAME
1950 ": make_raw_rw_request: unknown command\n");
1951 return 0;
1952 }
1953
1954 max_sector = floppy->sect * floppy->head;
1955 TRACK = CURRENT->sector / max_sector;
1956 sector_t = CURRENT->sector % max_sector;
1957 if ( floppy->track && TRACK >= floppy->track )
1958 return 0;
1959 HEAD = sector_t / floppy->sect;
1960
1961 if ( (DRS->flags & FD_NEED_TWADDLE) && sector_t < floppy->sect )
1962 max_sector = floppy->sect;
1963
1964
1965 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
1966 max_sector = 2 * floppy->sect / 3;
1967 if (sector_t >= max_sector){
1968 current_count_sectors = (floppy->sect - sector_t);
1969 if ( current_count_sectors > CURRENT->nr_sectors )
1970 current_count_sectors = CURRENT->nr_sectors;
1971 return 1;
1972 }
1973 SIZECODE = 2;
1974 } else
1975 SIZECODE = FD_SIZECODE(floppy);
1976 raw_cmd.rate = floppy->rate & 3;
1977 if ((floppy->rate & FD_2M) &&
1978 (TRACK || HEAD ) &&
1979 raw_cmd.rate == 2)
1980 raw_cmd.rate = 1;
1981
1982 SIZECODE2 = 0xff;
1983 raw_cmd.track = TRACK << floppy->stretch;
1984 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
1985 GAP = floppy->gap;
1986 ssize = 1 << (SIZECODE - 2 );
1987 SECT_PER_TRACK = floppy->sect / ssize;
1988 SECTOR = (sector_t % floppy->sect) / ssize + 1;
1989 tracksize = floppy->sect - floppy->sect % ssize;
1990 if ( tracksize < floppy->sect ){
1991 SECT_PER_TRACK ++;
1992 if ( tracksize <= sector_t % floppy->sect)
1993 SECTOR--;
1994 while ( tracksize <= sector_t % floppy->sect){
1995 while( tracksize + ssize > floppy->sect ){
1996 SIZECODE--;
1997 ssize >>= 1;
1998 }
1999 SECTOR++; SECT_PER_TRACK ++;
2000 tracksize += ssize;
2001 }
2002 max_sector = HEAD * floppy->sect + tracksize;
2003 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2004 max_sector = floppy->sect;
2005
2006 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2007 max_size = CURRENT->nr_sectors;
2008 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2009 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2010
2011 if (COMMAND == FD_READ) {
2012 copy_buffer(1, max_sector, buffer_max);
2013 return 1;
2014 }
2015 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2016 if (COMMAND == FD_WRITE){
2017 if(sector_t + CURRENT->nr_sectors > ssize &&
2018 sector_t + CURRENT->nr_sectors < ssize + ssize)
2019 max_size = ssize + ssize;
2020 else
2021 max_size = ssize;
2022 }
2023 raw_cmd.flags &= ~FD_RAW_WRITE;
2024 raw_cmd.flags |= FD_RAW_READ;
2025 COMMAND = FD_READ;
2026 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2027 int direct, indirect;
2028
2029 indirect= transfer_size(ssize,max_sector,MAX_BUFFER_SECTORS*2) -
2030 sector_t;
2031
2032 max_size = buffer_chain_size();
2033 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2034 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2035
2036 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2037 ((long) CURRENT->buffer ) / K_64 )
2038 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2039 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2040
2041
2042
2043
2044
2045
2046
2047 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2048 *errors < DP->max_errors.read_track &&
2049
2050 ( ( !probing || (DP->read_track &
2051 (1 <<DRS->probed_format))))){
2052 max_size = CURRENT->nr_sectors;
2053 } else {
2054 current_addr = CURRENT->buffer;
2055 raw_cmd.length = current_count_sectors << 9;
2056 return 2;
2057 }
2058 }
2059
2060 if ( COMMAND == FD_READ )
2061 max_size = max_sector;
2062
2063
2064 if (buffer_track != raw_cmd.track ||
2065 buffer_drive !=current_drive ||
2066 sector_t < buffer_min ||
2067 ((COMMAND == FD_READ ||
2068 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2069 max_sector > 2 * MAX_BUFFER_SECTORS + buffer_min &&
2070 max_size + sector_t > 2 * MAX_BUFFER_SECTORS + buffer_min)
2071 ){
2072 buffer_track = -1;
2073 buffer_drive = current_drive;
2074 buffer_max = buffer_min = aligned_sector_t;
2075 }
2076 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2077
2078 if ( COMMAND == FD_WRITE ){
2079
2080
2081
2082
2083 #ifdef SANITY
2084 if (sector_t != aligned_sector_t && buffer_track == -1 )
2085 printk(DEVICE_NAME
2086 ": internal error offset !=0 on write\n");
2087 #endif
2088 buffer_track = raw_cmd.track;
2089 buffer_drive = current_drive;
2090 copy_buffer(ssize, max_sector, 2*MAX_BUFFER_SECTORS+buffer_min);
2091 } else
2092 transfer_size(ssize, max_sector,
2093 2*MAX_BUFFER_SECTORS+buffer_min-aligned_sector_t);
2094
2095
2096 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2097 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2098 raw_cmd.length <<= 9;
2099 #ifdef SANITY
2100 if ((raw_cmd.length < current_count_sectors << 9) ||
2101 (current_addr != CURRENT->buffer && COMMAND == FD_WRITE &&
2102 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2103 aligned_sector_t < buffer_min )) ||
2104 raw_cmd.length % ( 512 << ( SIZECODE -2 )) ||
2105 raw_cmd.length <= 0 || current_count_sectors <= 0){
2106 printk(DEVICE_NAME ": fractionary current count b=%lx s=%lx\n",
2107 raw_cmd.length, current_count_sectors);
2108 if ( current_addr != CURRENT->buffer )
2109 printk("addr=%d, length=%ld\n",
2110 (current_addr - floppy_track_buffer ) >> 9,
2111 current_count_sectors);
2112 printk("st=%d ast=%d mse=%d msi=%d\n",
2113 sector_t, aligned_sector_t, max_sector, max_size);
2114 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2115 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2116 COMMAND, SECTOR, HEAD, TRACK);
2117 printk("buffer drive=%d\n", buffer_drive);
2118 printk("buffer track=%d\n", buffer_track);
2119 printk("buffer_min=%d\n", buffer_min );
2120 printk("buffer_max=%d\n", buffer_max );
2121 return 0;
2122 }
2123
2124 if (current_addr != CURRENT->buffer ){
2125 if (current_addr < floppy_track_buffer ||
2126 current_count_sectors < 0 ||
2127 raw_cmd.length < 0 ||
2128 current_addr + raw_cmd.length >
2129 floppy_track_buffer + ( 2 * MAX_BUFFER_SECTORS << 9 )){
2130 printk(DEVICE_NAME
2131 ": buffer overrun in schedule dma\n");
2132 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2133 sector_t, buffer_min,
2134 raw_cmd.length >> 9 );
2135 printk("current_count_sectors=%ld\n",
2136 current_count_sectors);
2137 if ( COMMAND == FD_READ )
2138 printk("read\n");
2139 if ( COMMAND == FD_READ )
2140 printk("write\n");
2141 return 0;
2142 }
2143 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2144 current_count_sectors > CURRENT->nr_sectors){
2145 printk(DEVICE_NAME ": buffer overrun in direct transfer\n");
2146 return 0;
2147 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2148 printk(DEVICE_NAME ": more sectors than bytes\n");
2149 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2150 printk("sectors=%ld\n", current_count_sectors);
2151 }
2152 #endif
2153 return 2;
2154 }
2155
2156 static void redo_fd_request(void)
2157 {
2158 #define REPEAT {request_done(0); continue; }
2159 int device;
2160 int tmp;
2161
2162 if (CURRENT && CURRENT->dev < 0) return;
2163
2164
2165 while(1){
2166 if (!CURRENT) {
2167 CLEAR_INTR;
2168 unlock_fdc();
2169 return;
2170 }
2171 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2172 panic(DEVICE_NAME ": request list destroyed");
2173 if (CURRENT->bh && !CURRENT->bh->b_lock)
2174 panic(DEVICE_NAME ": block not locked");
2175
2176 device = MINOR(CURRENT->dev);
2177 set_fdc( DRIVE(device));
2178 CHECK_RESET;
2179 start_motor();
2180 if (( changed_floppies | fake_change) & ( 1 << DRIVE(device))){
2181 printk(DEVICE_NAME
2182 ": disk absent or changed during operation\n");
2183 REPEAT;
2184 }
2185 set_floppy(device);
2186 if (!floppy) {
2187 if (!probing){
2188 DRS->probed_format = 0;
2189 if ( next_valid_format() ){
2190 printk(DEVICE_NAME
2191 ": no autodetectable formats\n");
2192 floppy = NULL;
2193 REPEAT;
2194 }
2195 }
2196 probing = 1;
2197 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2198 } else
2199 probing = 0;
2200 errors = & (CURRENT->errors);
2201 tmp = make_raw_rw_request();
2202 if ( tmp < 2 ){
2203 request_done(tmp);
2204 continue;
2205 }
2206 if ( DRS->flags & FD_NEED_TWADDLE )
2207 twaddle();
2208 floppy_on(current_drive);
2209 #ifdef DEBUGT
2210 debugt("queue fd request");
2211 #endif
2212 return;
2213 }
2214 #undef REPEAT
2215 }
2216
2217 static struct cont_t rw_cont={
2218 rw_interrupt,
2219 redo_fd_request,
2220 bad_flp_intr,
2221 request_done };
2222
2223 void do_fd_request(void)
2224 {
2225 lock_fdc(-1);
2226 cont = &rw_cont;
2227 redo_fd_request();
2228 }
2229
2230
2231
2232
2233
2234
2235 static void reset_intr(void)
2236 {
2237 printk("weird, reset interrupt called\n");
2238 }
2239
2240 static struct cont_t reset_cont={
2241 reset_intr,
2242 success_and_wakeup,
2243 generic_failure,
2244 generic_done };
2245
2246 static int user_reset_fdc(int drive, int arg)
2247 {
2248 int result;
2249
2250 result=0;
2251 lock_fdc(drive);
2252 switch(arg){
2253 case FD_RESET_ALWAYS:
2254 FDCS->reset=1;
2255 break;
2256 case FD_RESET_IF_RAWCMD:
2257 if(FDCS->rawcmd == 2 )
2258 reset_fdc_info(1);
2259 break;
2260 }
2261 if ( FDCS->reset ){
2262 cont = &reset_cont;
2263 timer_table[FLOPPY_TIMER].expires = jiffies + 5;
2264 timer_active |= 1 << FLOPPY_TIMER;
2265 reset_fdc();
2266 result=wait_til_done();
2267 }
2268 unlock_fdc();
2269 return result;
2270 }
2271
2272
2273
2274
2275
2276 static int fd_copyout(void *param, volatile void *address, int size)
2277 {
2278 int i;
2279
2280 i = verify_area(VERIFY_WRITE,param,size);
2281 if (i)
2282 return i;
2283 memcpy_tofs(param,(void *) address, size);
2284 return 0;
2285 }
2286 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2287 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2288
2289 static void poll_drive(int drive)
2290 {
2291 lock_fdc(drive);
2292 start_motor();
2293 unlock_fdc();
2294 }
2295
2296 static char *drive_name(int type, int drive )
2297 {
2298 struct floppy_struct *floppy;
2299
2300 if ( type )
2301 floppy = floppy_type + type;
2302 else {
2303 if ( UDP->native_format )
2304 floppy = floppy_type + UDP->native_format;
2305 else
2306 return "(null)";
2307 }
2308 if ( floppy->name )
2309 return floppy->name;
2310 else
2311 return "(null)";
2312 }
2313
2314
2315 static struct cont_t raw_cmd_cont={
2316 success_and_wakeup,
2317 failure_and_wakeup,
2318 generic_failure,
2319 generic_done };
2320
2321 static int raw_cmd_ioctl(int drive, void *param)
2322 {
2323 int i, count, ret;
2324
2325 if ( FDCS->rawcmd <= 1 )
2326 FDCS->rawcmd = 1;
2327 for ( i= 0; i < N_DRIVE; i++){
2328 if ( FDC(i) != fdc)
2329 continue;
2330 if ( i == drive ){
2331 if ( drive_state[i].fd_ref > 1 )
2332 return -EBUSY;
2333 } else if ( drive_state[i].fd_ref )
2334 return -EBUSY;
2335 }
2336
2337 if(FDCS->reset)
2338 return -EIO;
2339
2340 COPYIN(raw_cmd);
2341 raw_cmd.rate &= 0x03;
2342 count = raw_cmd.length;
2343 if ((raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)) &&
2344 count > MAX_BUFFER_SECTORS * 512 * 2 )
2345 return -ENOMEM;
2346
2347 if ( raw_cmd.flags & FD_RAW_WRITE ){
2348 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2349 if (i)
2350 return i;
2351 buffer_track = -1;
2352 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2353 }
2354
2355 current_addr = floppy_track_buffer;
2356 raw_cmd.flags |= FD_RAW_USER_SUPPLIED;
2357 cont = &raw_cmd_cont;
2358 floppy_on(current_drive);
2359 ret=wait_til_done();
2360
2361 if ( !ret && !FDCS->reset ){
2362 raw_cmd.reply_count = inr;
2363 for( i=0; i< raw_cmd.reply_count; i++)
2364 raw_cmd.reply[i] = reply_buffer[i];
2365 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2366 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2367 } else
2368 ret = -EIO;
2369 DRS->track = NO_TRACK;
2370 if ( ret )
2371 return ret;
2372
2373 if ( raw_cmd.flags & FD_RAW_READ ){
2374 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2375 if (i)
2376 return i;
2377 }
2378
2379 return COPYOUT(raw_cmd);
2380 }
2381
2382 static int invalidate_drive(int rdev)
2383 {
2384
2385 cli();
2386 fake_change |= 1 << DRIVE(rdev);
2387 sti();
2388 unlock_fdc();
2389 check_disk_change(rdev);
2390 return 0;
2391 }
2392
2393 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2394 unsigned long param)
2395 {
2396 #define IOCTL_ALLOWED (filp && (filp->f_mode & 8 ))
2397
2398 struct floppy_struct newparams;
2399 struct format_descr tmp_format_req;
2400 int i,device,drive,type,cnt;
2401 struct floppy_struct *this_floppy;
2402 char *name;
2403
2404 device = MINOR(inode->i_rdev);
2405 switch (cmd) {
2406 RO_IOCTLS(device,param);
2407 }
2408 type = TYPE(MINOR(device));
2409 drive = DRIVE(MINOR(device));
2410 switch (cmd) {
2411 case FDGETDRVTYP:
2412 i=verify_area(VERIFY_WRITE,(void *) param,16);
2413 if (i)
2414 return i;
2415 name = drive_name(type,drive);
2416 for ( cnt=0; cnt<16; cnt++){
2417 put_fs_byte(name[cnt],
2418 ((char*)param)+cnt);
2419 if ( ! *name )
2420 break;
2421 }
2422 return 0;
2423 case FDGETMAXERRS:
2424 return COPYOUT(UDP->max_errors);
2425 case FDGETPRM:
2426 if (type)
2427 this_floppy = &floppy_type[type];
2428 else if ((this_floppy = current_type[drive]) ==
2429 NULL)
2430 return -ENODEV;
2431 return COPYOUT(this_floppy[0]);
2432 case FDPOLLDRVSTAT:
2433 poll_drive(drive);
2434
2435 case FDGETDRVSTAT:
2436 return COPYOUT(*UDRS);
2437 case FDGETFDCSTAT:
2438 return COPYOUT(*UFDCS);
2439 case FDGETDRVPRM:
2440 return COPYOUT(*UDP);
2441 }
2442 if (!IOCTL_ALLOWED)
2443 return -EPERM;
2444 switch (cmd) {
2445 case FDRAWCMD:
2446 if (type)
2447 return -EINVAL;
2448 lock_fdc(drive);
2449 set_floppy(device);
2450 i = raw_cmd_ioctl(drive, (void *) param);
2451 unlock_fdc();
2452 return i;
2453 case FDFMTTRK:
2454 if (UDRS->fd_ref != 1)
2455 return -EBUSY;
2456 if (! (UDRS->flags & FD_DRIVE_PRESENT ))
2457 return -ENXIO;
2458 COPYIN(tmp_format_req);
2459 return do_format(device, &tmp_format_req);
2460 case FDSETMAXERRS:
2461 return COPYIN(UDP->max_errors);
2462 case FDFMTBEG:
2463 return 0;
2464 case FDCLRPRM:
2465 lock_fdc(drive);
2466 current_type[drive] = NULL;
2467 floppy_sizes[drive] = 2;
2468 UDRS->keep_data = 0;
2469 return invalidate_drive(device);
2470 case FDFMTEND:
2471 case FDFLUSH:
2472 lock_fdc(drive);
2473 return invalidate_drive(device);
2474 case FDSETPRM:
2475 case FDDEFPRM:
2476 COPYIN(newparams);
2477
2478 if(newparams.sect <= 0 ||
2479 newparams.head <= 0 ||
2480 newparams.track <= 0 ||
2481 newparams.track >
2482 UDP->tracks>>newparams.stretch)
2483 return -EINVAL;
2484 if ( type){
2485 if ( !suser() )
2486 return -EPERM;
2487 lock_fdc(-1);
2488 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2489 if (TYPE(drive_state[cnt].fd_device) == type &&
2490 drive_state[cnt].fd_ref){
2491 cli(); fake_change |= 1 << cnt; sti();
2492 }
2493 }
2494 floppy_type[type] = newparams;
2495 floppy_type[type].name="user format";
2496 for (cnt = type << 2 ;
2497 cnt < (type << 2 ) + 4 ;
2498 cnt++)
2499 floppy_sizes[cnt]=
2500 #ifdef HAVE_2_CONTROLLERS
2501 floppy_sizes[cnt+0x80]=
2502 #endif
2503 floppy_type[type].size>>1;
2504 unlock_fdc();
2505 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2506 if (TYPE(drive_state[cnt].fd_device) == type &&
2507 drive_state[cnt].fd_ref)
2508 check_disk_change(drive_state[cnt].
2509 fd_device);
2510 }
2511 return 0;
2512 }
2513
2514 lock_fdc(drive);
2515 if ( cmd != FDDEFPRM )
2516
2517
2518 start_motor();
2519 user_params[drive] = newparams;
2520 if (buffer_drive == drive &&
2521 buffer_max > user_params[drive].sect)
2522 buffer_max=user_params[drive].sect;
2523 current_type[drive] = &user_params[drive];
2524 floppy_sizes[drive] = user_params[drive].size >> 1;
2525 if (cmd == FDDEFPRM)
2526 DRS->keep_data = -1;
2527 else
2528 DRS->keep_data = 1;
2529
2530
2531
2532
2533
2534 if (DRS->maxblock >
2535 user_params[drive].sect ||
2536 DRS->maxtrack )
2537 return invalidate_drive(device);
2538 else
2539 return unlock_fdc();
2540 case FDRESET:
2541 return user_reset_fdc( drive, (int)param);
2542 case FDMSGON:
2543 UDP->flags |= FTD_MSG;
2544 return 0;
2545 case FDMSGOFF:
2546 UDP->flags &= ~FTD_MSG;
2547 return 0;
2548 case FDSETEMSGTRESH:
2549 UDP->max_errors.reporting =
2550 (unsigned short) (param & 0x0f);
2551 return 0;
2552 case FDTWADDLE:
2553 lock_fdc(drive);
2554 twaddle();
2555 unlock_fdc();
2556 }
2557 if ( ! suser() )
2558 return -EPERM;
2559 switch(cmd){
2560 case FDSETDRVPRM:
2561 return COPYIN(*UDP);
2562 default:
2563 return -EINVAL;
2564 }
2565 return 0;
2566 #undef IOCTL_ALLOWED
2567 }
2568
2569 #define CMOS_READ(addr) ({ \
2570 outb_p(addr,0x70); \
2571 inb_p(0x71); \
2572 })
2573
2574 static void set_base_type(int drive,int code)
2575 {
2576 if (code > 0 && code <= NUMBER(default_drive_params)) {
2577 memcpy((char *) UDP,
2578 (char *) (&default_drive_params[code].params),
2579 sizeof( struct floppy_drive_params ));
2580 printk("fd%d is %s", drive, default_drive_params[code].name);
2581 return;
2582 } else if (!code)
2583 printk("fd%d is not installed", drive);
2584 else
2585 printk("fd%d is unknown type %d",drive,code);
2586 }
2587
2588 static void config_types(void)
2589 {
2590 int drive;
2591
2592 for (drive=0; drive<N_DRIVE ; drive++){
2593
2594 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2595 sizeof( struct floppy_drive_params ));
2596 }
2597 printk("Floppy drive(s): ");
2598 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2599 if (CMOS_READ(0x10) & 15) {
2600 printk(", ");
2601 set_base_type(1, CMOS_READ(0x10) & 15);
2602 }
2603 printk("\n");
2604 }
2605
2606
2607 static void maybe_check_change(int device)
2608 {
2609 register int drive;
2610
2611 drive = DRIVE(device);
2612 if (UDRS->last_checked + UDP->checkfreq < jiffies ||
2613 UDRS->flags & FD_VERIFY ||
2614 (( changed_floppies | fake_change ) & ( 1 << drive)))
2615 check_disk_change(device);
2616 }
2617
2618 int floppy_is_wp( int minor)
2619 {
2620 maybe_check_change(minor + (MAJOR_NR << 8));
2621 return ! ( drive_state[ DRIVE(minor) ].flags & FD_DISK_WRITABLE );
2622 }
2623
2624
2625 #define WRAPPER(op) \
2626 static int floppy_##op(struct inode * inode, struct file * filp, \
2627 char * buf, int count) \
2628 { \
2629 maybe_check_change(inode->i_rdev); \
2630 if ( changed_floppies & ( 1 << DRIVE(inode->i_rdev) )) \
2631 return -ENXIO; \
2632 return block_##op(inode, filp, buf, count); \
2633 }
2634
2635 WRAPPER(read)
2636 WRAPPER(write)
2637
2638 static int exclusive = 0;
2639 static void floppy_release(struct inode * inode, struct file * filp)
2640 {
2641 int drive= DRIVE(inode->i_rdev);
2642
2643 fsync_dev(inode->i_rdev);
2644 if ( UDRS->fd_ref < 0)
2645 UDRS->fd_ref=0;
2646 else if (!UDRS->fd_ref--) {
2647 printk(DEVICE_NAME ": floppy_release with fd_ref == 0");
2648 UDRS->fd_ref = 0;
2649 }
2650 floppy_release_irq_and_dma();
2651 exclusive=0;
2652 }
2653
2654
2655
2656
2657
2658
2659 #define RETERR(x) \
2660 do{floppy_release(inode,filp); \
2661 return -(x);}while(0)
2662 static int usage_count = 0;
2663 static int floppy_open(struct inode * inode, struct file * filp)
2664 {
2665 int drive;
2666 int old_dev;
2667
2668 if (exclusive)
2669 return -EBUSY;
2670 if ( !filp ){
2671 printk(DEVICE_NAME ": Weird, open called with filp=0\n");
2672 return -EIO;
2673 }
2674
2675 drive = DRIVE(inode->i_rdev);
2676 if ( drive >= N_DRIVE )
2677 return -ENXIO;
2678
2679 if (command_status == FD_COMMAND_DETECT && drive >= current_drive){
2680 lock_fdc(-1);
2681 unlock_fdc();
2682 }
2683
2684 if ( TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2685 return -ENXIO;
2686
2687 if (filp->f_mode & 3){
2688 if ( !(UDRS->flags & FD_DRIVE_PRESENT))
2689 return -ENXIO;
2690 }
2691
2692 old_dev = UDRS->fd_device;
2693 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2694 return -EBUSY;
2695 if (floppy_grab_irq_and_dma())
2696 return -EBUSY;
2697
2698 if (filp->f_flags & O_EXCL ){
2699 if (usage_count>1){
2700 floppy_release_irq_and_dma();
2701 return -EBUSY;
2702 }else
2703 exclusive=1;
2704 }
2705
2706
2707 if (filp->f_op){
2708 if (UDRS->fd_ref == -1)
2709 return -EBUSY;
2710 UDRS->fd_ref++;
2711 UDRS->fd_device = inode->i_rdev;
2712 } else {
2713 if (UDRS->fd_ref ){
2714 floppy_release_irq_and_dma();
2715 return -EBUSY;
2716 }
2717 UDRS->fd_ref=-1;
2718 }
2719
2720 if (old_dev && old_dev != inode->i_rdev){
2721 if ( buffer_drive == drive )
2722 buffer_track = -1;
2723 invalidate_buffers(old_dev);
2724 }
2725
2726 if (filp->f_mode & 2 || permission(inode,2))
2727 filp->f_mode |= 8;
2728
2729 if (UFDCS->rawcmd == 1)
2730 UFDCS->rawcmd = 2;
2731
2732 if (filp->f_flags & O_NDELAY)
2733 return 0;
2734 if (filp->f_mode && !(UDRS->flags & FD_DRIVE_PRESENT))
2735 RETERR(ENXIO);
2736 if(user_reset_fdc(drive, FD_RESET_IF_NEEDED))
2737 RETERR(EIO);
2738
2739 if (filp->f_mode & 3){
2740 check_disk_change(inode->i_rdev);
2741 if ( changed_floppies & ( 1 << drive )){
2742 if ( suser() && filp->f_op)
2743
2744 filp->f_mode &= ~3;
2745 else
2746 RETERR(ENXIO);
2747 }
2748 }
2749 if ((filp->f_mode & 2) && UDRS->flags < FD_DISK_WRITABLE){
2750 if ( suser() && filp->f_op)
2751
2752 filp->f_mode &= ~2;
2753 else
2754 RETERR(EROFS);
2755 }
2756 return 0;
2757 #undef RETERR
2758 }
2759
2760
2761
2762
2763 static int ack_change(int drive)
2764 {
2765 unsigned int mask = 1 << drive;
2766 UDRS->maxblock = 0;
2767 UDRS->maxtrack = 0;
2768 if ( buffer_drive == drive )
2769 buffer_track = -1;
2770 fake_change &= ~mask;
2771 changed_floppies &= ~mask;
2772 return 1;
2773 }
2774
2775
2776
2777
2778 static int check_floppy_change(dev_t dev)
2779 {
2780 int drive = DRIVE( dev );
2781 unsigned int mask = 1 << drive;
2782
2783 if (MAJOR(dev) != MAJOR_NR) {
2784 printk(DEVICE_NAME ": floppy_changed: not a floppy\n");
2785 return 0;
2786 }
2787
2788 if (fake_change & mask)
2789 return ack_change(drive);
2790
2791 if ((UDRS->flags & FD_VERIFY ) || (changed_floppies & mask) ||
2792 UDRS->last_checked + UDP->checkfreq <
2793 jiffies){
2794 user_reset_fdc(drive, FD_RESET_IF_NEEDED);
2795 poll_drive(drive);
2796 if (changed_floppies & mask){
2797 UDRS->generation++;
2798 return ack_change(drive);
2799 }
2800 }
2801 return 0;
2802 }
2803
2804
2805
2806 static int floppy_revalidate(dev_t dev)
2807 {
2808 struct buffer_head * bh;
2809
2810 if ( TYPE(dev) || current_type[DRIVE(dev)] )
2811 return 0;
2812 if (!(bh = getblk(dev,0,1024)))
2813 return 1;
2814 if ( bh && ! bh->b_uptodate)
2815 ll_rw_block(READ, 1, &bh);
2816 brelse(bh);
2817 return 0;
2818 }
2819
2820 static struct file_operations floppy_fops = {
2821 NULL,
2822 floppy_read,
2823 floppy_write,
2824 NULL,
2825 NULL,
2826 fd_ioctl,
2827 NULL,
2828 floppy_open,
2829 floppy_release,
2830 block_fsync,
2831 NULL,
2832 check_floppy_change,
2833 floppy_revalidate,
2834 };
2835
2836
2837
2838
2839
2840
2841
2842
2843 static char get_fdc_version(void)
2844 {
2845 int r;
2846
2847 output_byte(FD_DUMPREGS);
2848 if ( FDCS->reset )
2849 return FDC_NONE;
2850 if ( (r = result()) <= 0x00)
2851 return FDC_NONE;
2852 if ((r==1) && (reply_buffer[0] == 0x80)){
2853 printk("FDC %d is a 8272A\n",fdc);
2854 return FDC_8272A;
2855 }
2856 if (r != 10) {
2857 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
2858 return FDC_UNKNOWN;
2859 }
2860 output_byte(FD_VERSION);
2861 r = result();
2862 if ((r == 1) && (reply_buffer[0] == 0x80)){
2863 printk("FDC %d is a 82072\n",fdc);
2864 return FDC_82072;
2865 }
2866 if ((r != 1) || (reply_buffer[0] != 0x90)) {
2867 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
2868 return FDC_UNKNOWN;
2869 }
2870 output_byte(FD_UNLOCK);
2871 r = result();
2872 if ((r == 1) && (reply_buffer[0] == 0x80)){
2873 printk("FDC %d is a pre-1991 82077\n", fdc);
2874 return FDC_82077_ORIG;
2875 }
2876 if ((r != 1) || (reply_buffer[0] != 0x00)) {
2877 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
2878 return FDC_UNKNOWN;
2879 }
2880 printk("FDC %d is a post-1991 82077\n",fdc);
2881 return FDC_82077;
2882 }
2883
2884
2885
2886
2887
2888 static void detect_interrupt(void)
2889 {
2890 if ( DRS->track == 0 )
2891 DRS->flags |= FD_DRIVE_PRESENT | FD_VERIFY;
2892 else if ( DRS->track != NEED_1_RECAL ){
2893 floppy_ready();
2894 return;
2895 }
2896 floppy_off(current_drive);
2897 current_drive++;
2898 if (current_drive == N_DRIVE ||
2899 fdc_state[FDC(current_drive)].version == FDC_NONE){
2900 set_fdc(0);
2901 unlock_fdc();
2902 floppy_release_irq_and_dma();
2903 return;
2904 }
2905 set_fdc(current_drive);
2906 floppy_ready();
2907 }
2908
2909 static struct cont_t detect_cont={
2910 detect_interrupt,
2911 detect_interrupt,
2912 empty,
2913 (done_f) empty };
2914
2915
2916
2917
2918
2919 static struct sigaction floppy_sigaction = {
2920 floppy_interrupt,
2921 0,
2922 SA_INTERRUPT,
2923 NULL
2924 };
2925
2926 void floppy_init(void)
2927 {
2928 int i;
2929
2930 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
2931 printk("Unable to get major %d for floppy\n",MAJOR_NR);
2932 return;
2933 }
2934
2935 for(i=0; i<256; i++)
2936 if ( TYPE(i))
2937 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
2938 else
2939 floppy_sizes[i] = MAX_DISK_SIZE;
2940
2941 blk_size[MAJOR_NR] = floppy_sizes;
2942 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
2943 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
2944 timer_active &= ~(1 << FLOPPY_TIMER);
2945 config_types();
2946
2947 fdc_state[0].address = 0x3f0;
2948 fdc_state[1].address = 0x370;
2949 for(fdc = 0 ; fdc < N_FDC; fdc++){
2950 FDCS->dtr = -1;
2951 FDCS->dor = 0;
2952 FDCS->reset = 0;
2953 FDCS->version = FDC_NONE;
2954 set_dor(fdc, ~0, 0xc );
2955 }
2956
2957
2958 for ( current_drive=0; current_drive < N_DRIVE ; current_drive++){
2959 DRS->flags = 0;
2960 DRS->generation = 0;
2961 DRS->keep_data = 0;
2962 DRS->fd_ref = 0;
2963 DRS->fd_device = 0;
2964 }
2965
2966 floppy_grab_irq_and_dma();
2967 for(fdc = 0 ; fdc < N_FDC; fdc++){
2968 FDCS->rawcmd = 2;
2969 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED))
2970 continue;
2971
2972 FDCS->version = get_fdc_version();
2973 if (FDCS->version == FDC_NONE)
2974 continue;
2975
2976
2977
2978
2979
2980 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
2981 user_reset_fdc(-1,FD_RESET_ALWAYS);
2982 }
2983 fdc=0;
2984 current_drive = 0;
2985 lock_fdc(-1);
2986 initialising =0;
2987 command_status = FD_COMMAND_DETECT;
2988 cont = &detect_cont;
2989 raw_cmd.cmd_count = 0;
2990 raw_cmd.flags = FD_RAW_NEED_SEEK;
2991 raw_cmd.track = 0;
2992 floppy_ready();
2993 cli();
2994 }
2995
2996 int floppy_grab_irq_and_dma(void)
2997 {
2998 if (usage_count++)
2999 return 0;
3000 if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) {
3001 printk(DEVICE_NAME
3002 ": Unable to grab IRQ%d for the floppy driver\n",
3003 FLOPPY_IRQ);
3004 return -1;
3005 }
3006 if (request_dma(FLOPPY_DMA)) {
3007 printk(DEVICE_NAME
3008 ": Unable to grab DMA%d for the floppy driver\n",
3009 FLOPPY_DMA);
3010 free_irq(FLOPPY_IRQ);
3011 return -1;
3012 }
3013 enable_irq(FLOPPY_IRQ);
3014 return 0;
3015 }
3016
3017 void floppy_release_irq_and_dma(void)
3018 {
3019 if (--usage_count)
3020 return;
3021 disable_dma(FLOPPY_DMA);
3022 free_dma(FLOPPY_DMA);
3023 disable_irq(FLOPPY_IRQ);
3024 free_irq(FLOPPY_IRQ);
3025 #ifdef HAVE_2_CONTROLLERS
3026
3027
3028 set_dor(0, ~0, 8 );
3029 set_dor(1, ~8, 0 );
3030 #endif
3031 }