1/* 2 * linux/kernel/arch/arm/drivers/block/fd1772.c 3 * Based on ataflop.c in the m68k Linux 4 * Copyright (C) 1993 Greg Harp 5 * Atari Support by Bjoern Brauel, Roman Hodek 6 * Archimedes Support by Dave Gilbert (linux@treblig.org) 7 * 8 * Big cleanup Sep 11..14 1994 Roman Hodek: 9 * - Driver now works interrupt driven 10 * - Support for two drives; should work, but I cannot test that :-( 11 * - Reading is done in whole tracks and buffered to speed up things 12 * - Disk change detection and drive deselecting after motor-off 13 * similar to TOS 14 * - Autodetection of disk format (DD/HD); untested yet, because I 15 * don't have an HD drive :-( 16 * 17 * Fixes Nov 13 1994 Martin Schaller: 18 * - Autodetection works now 19 * - Support for 5 1/4" disks 20 * - Removed drive type (unknown on atari) 21 * - Do seeks with 8 Mhz 22 * 23 * Changes by Andreas Schwab: 24 * - After errors in multiple read mode try again reading single sectors 25 * (Feb 1995): 26 * - Clean up error handling 27 * - Set blk_size for proper size checking 28 * - Initialize track register when testing presence of floppy 29 * - Implement some ioctl's 30 * 31 * Changes by Torsten Lang: 32 * - When probing the floppies we should add the FDC1772CMDADD_H flag since 33 * the FDC1772 will otherwise wait forever when no disk is inserted... 34 * 35 * Things left to do: 36 * - Formatting 37 * - Maybe a better strategy for disk change detection (does anyone 38 * know one?) 39 * - There are some strange problems left: The strangest one is 40 * that, at least on my TT (4+4MB), the first 2 Bytes of the last 41 * page of the TT-Ram (!) change their contents (some bits get 42 * set) while a floppy DMA is going on. But there are no accesses 43 * to these memory locations from the kernel... (I tested that by 44 * making the page read-only). I cannot explain what's going on... 45 * - Sometimes the drive-change-detection stops to work. The 46 * function is still called, but the WP bit always reads as 0... 47 * Maybe a problem with the status reg mode or a timing problem. 48 * Note 10/12/94: The change detection now seems to work reliably. 49 * There is no proof, but I've seen no hang for a long time... 50 * 51 * ARCHIMEDES changes: (gilbertd@cs.man.ac.uk) 52 * 26/12/95 - Changed all names starting with FDC to FDC1772 53 * Removed all references to clock speed of FDC - we're stuck with 8MHz 54 * Modified disk_type structure to remove HD formats 55 * 56 * 7/ 1/96 - Wrote FIQ code, removed most remaining atariisms 57 * 58 * 13/ 1/96 - Well I think its read a single sector; but there is a problem 59 * fd_rwsec_done which is called in FIQ mode starts another transfer 60 * off (in fd_rwsec) while still in FIQ mode. Because its still in 61 * FIQ mode it can't service the DMA and loses data. So need to 62 * heavily restructure. 63 * 14/ 1/96 - Found that the definitions of the register numbers of the 64 * FDC were multiplied by 2 in the header for the 16bit words 65 * of the atari so half the writes were going in the wrong place. 66 * Also realised that the FIQ entry didn't make any attempt to 67 * preserve registers or return correctly; now in assembler. 68 * 69 * 11/ 2/96 - Hmm - doesn't work on real machine. Auto detect doesn't 70 * and hacking that past seems to wait forever - check motor 71 * being turned on. 72 * 73 * 17/ 2/96 - still having problems - forcing track to -1 when selecting 74 * new drives seems to allow it to read first few sectors 75 * but then we get solid hangs at apparently random places 76 * which change depending what is happening. 77 * 78 * 9/ 3/96 - Fiddled a lot of stuff around to move to kernel 1.3.35 79 * A lot of fiddling in DMA stuff. Having problems with it 80 * constnatly thinking its timeing out. Ah - its timeout 81 * was set to (6*HZ) rather than jiffies+(6*HZ). Now giving 82 * duff data! 83 * 84 * 5/ 4/96 - Made it use the new IOC_ macros rather than *ioc 85 * Hmm - giving unexpected FIQ and then timeouts 86 * 18/ 8/96 - Ran through indent -kr -i8 87 * Some changes to disc change detect; don't know how well it 88 * works. 89 * 24/ 8/96 - Put all the track buffering code back in from the atari 90 * code - I wonder if it will still work... No :-) 91 * Still works if I turn off track buffering. 92 * 25/ 8/96 - Changed the timer expires that I'd added back to be 93 * jiffies + ....; and it all sprang to life! Got 2.8K/sec 94 * off a cp -r of a 679K disc (showed 94% cpu usage!) 95 * (PC gets 14.3K/sec - 0% CPU!) Hmm - hard drive corrupt! 96 * Also perhaps that compile was with cache off. 97 * changed cli in fd_readtrack_check to cliIF 98 * changed vmallocs to kmalloc (whats the difference!!) 99 * Removed the busy wait loop in do_fd_request and replaced 100 * by a routine on tq_immediate; only 11% cpu on a dd off the 101 * raw disc - but the speed is the same. 102 * 1/ 9/96 - Idea (failed!) - set the 'disable spin-up sequence' 103 * when we read the track if we know the motor is on; didn't 104 * help - perhaps we have to do it in stepping as well. 105 * Nope. Still doesn't help. 106 * Hmm - what seems to be happening is that fd_readtrack_check 107 * is never getting called. Its job is to terminate the read 108 * just after we think we should have got the data; otherwise 109 * the fdc takes 1 second to timeout; which is what's happening 110 * Now I can see 'readtrack_timer' being set (which should do the 111 * call); but it never seems to be called - hmm! 112 * OK - I've moved the check to my tq_immediate code - 113 * and it WORKS! 13.95K/second at 19% CPU. 114 * I wish I knew why that timer didn't work..... 115 * 116 * 16/11/96 - Fiddled and frigged for 2.0.18 117 * 118 * DAG 30/01/99 - Started frobbing for 2.2.1 119 * DAG 20/06/99 - A little more frobbing: 120 * Included include/asm/uaccess.h for get_user/put_user 121 * 122 * DAG 1/09/00 - Dusted off for 2.4.0-test7 123 * MAX_SECTORS was name clashing so it is now FD1772_... 124 * Minor parameter, name layouts for 2.4.x differences 125 */ 126 127#include <linux/sched.h> 128#include <linux/fs.h> 129#include <linux/fcntl.h> 130#include <linux/slab.h> 131#include <linux/kernel.h> 132#include <linux/interrupt.h> 133#include <linux/timer.h> 134#include <linux/workqueue.h> 135#include <linux/fd.h> 136#include <linux/fd1772.h> 137#include <linux/errno.h> 138#include <linux/types.h> 139#include <linux/delay.h> 140#include <linux/mm.h> 141#include <linux/bitops.h> 142 143#include <asm/arch/oldlatches.h> 144#include <asm/dma.h> 145#include <asm/hardware.h> 146#include <asm/hardware/ioc.h> 147#include <asm/io.h> 148#include <asm/irq.h> 149#include <asm/mach-types.h> 150#include <asm/pgtable.h> 151#include <asm/system.h> 152#include <asm/uaccess.h> 153 154 155/* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with 156 * little additional rework in this file). But I'm not yet sure if 157 * some other code depends on the number of floppies... (It is defined 158 * in a public header!) 159 */ 160 161/* Ditto worries for Arc - DAG */ 162#define FD_MAX_UNITS 4 163#define TRACKBUFFER 0 164/*#define DEBUG*/ 165 166#ifdef DEBUG 167#define DPRINT(a) printk a 168#else 169#define DPRINT(a) 170#endif 171 172static struct request_queue *floppy_queue; 173 174#define MAJOR_NR FLOPPY_MAJOR 175#define FLOPPY_DMA 0 176#define DEVICE_NAME "floppy" 177#define QUEUE (floppy_queue) 178#define CURRENT elv_next_request(floppy_queue) 179 180/* Disk types: DD */ 181static struct archy_disk_type { 182 const char *name; 183 unsigned spt; /* sectors per track */ 184 unsigned blocks; /* total number of blocks */ 185 unsigned stretch; /* track doubling ? */ 186} disk_type[] = { 187 188 { "d360", 9, 720, 0 }, /* 360kB diskette */ 189 { "D360", 9, 720, 1 }, /* 360kb in 720kb drive */ 190 { "D720", 9, 1440, 0 }, /* 720kb diskette (DD) */ 191 /*{ "D820", 10,1640, 0}, *//* DD disk with 82 tracks/10 sectors 192 - DAG - can't see how type detect can distinguish this 193 from 720K until it reads block 4 by which time its too late! */ 194}; 195 196#define NUM_DISK_TYPES (sizeof(disk_type)/sizeof(*disk_type)) 197 198/* 199 * Maximum disk size (in kilobytes). This default is used whenever the 200 * current disk size is unknown. 201 */ 202#define MAX_DISK_SIZE 720 203 204static struct gendisk *disks[FD_MAX_UNIT]; 205 206/* current info on each unit */ 207static struct archy_floppy_struct { 208 int connected; /* !=0 : drive is connected */ 209 int autoprobe; /* !=0 : do autoprobe */ 210 211 struct archy_disk_type *disktype; /* current type of disk */ 212 213 int track; /* current head position or -1 214 * if unknown */ 215 unsigned int steprate; /* steprate setting */ 216 unsigned int wpstat; /* current state of WP signal 217 * (for disk change detection) */ 218} unit[FD_MAX_UNITS]; 219 220/* DAG: On Arc we spin on a flag being cleared by fdc1772_comendhandler which 221 is an assembler routine */ 222extern void fdc1772_comendhandler(void); /* Actually doens't have these parameters - see fd1772.S */ 223extern volatile int fdc1772_comendstatus; 224extern volatile int fdc1772_fdc_int_done; 225 226#define FDC1772BASE ((0x210000>>2)|0x80000000) 227 228#define FDC1772_READ(reg) inb(FDC1772BASE+(reg/2)) 229 230/* DAG: You wouldn't be silly to ask why FDC1772_WRITE is a function rather 231 than the #def below - well simple - the #def won't compile - and I 232 don't understand why (__outwc not defined) */ 233/* NOTE: Reg is 0,2,4,6 as opposed to 0,1,2,3 or 0,4,8,12 to keep compatibility 234 with the ST version of fd1772.h */ 235/*#define FDC1772_WRITE(reg,val) outw(val,(reg+FDC1772BASE)); */ 236void FDC1772_WRITE(int reg, unsigned char val) 237{ 238 if (reg == FDC1772REG_CMD) { 239 DPRINT(("FDC1772_WRITE new command 0x%x @ %d\n", val,jiffies)); 240 if (fdc1772_fdc_int_done) { 241 DPRINT(("FDC1772_WRITE: Hmm fdc1772_fdc_int_done true - resetting\n")); 242 fdc1772_fdc_int_done = 0; 243 }; 244 }; 245 outb(val, (reg / 2) + FDC1772BASE); 246}; 247 248#define FD1772_MAX_SECTORS 22 249 250unsigned char *DMABuffer; /* buffer for writes */ 251/*static unsigned long PhysDMABuffer; *//* physical address */ 252/* DAG: On Arc we just go straight for the DMA buffer */ 253#define PhysDMABuffer DMABuffer 254 255#ifdef TRACKBUFFER 256unsigned char *TrackBuffer; /* buffer for reads */ 257#define PhysTrackBuffer TrackBuffer /* physical address */ 258static int BufferDrive, BufferSide, BufferTrack; 259static int read_track; /* non-zero if we are reading whole tracks */ 260 261#define SECTOR_BUFFER(sec) (TrackBuffer + ((sec)-1)*512) 262#define IS_BUFFERED(drive,side,track) \ 263 (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track)) 264#endif 265 266/* 267 * These are global variables, as that's the easiest way to give 268 * information to interrupts. They are the data used for the current 269 * request. 270 */ 271static int SelectedDrive = 0; 272static int ReqCmd, ReqBlock; 273static int ReqSide, ReqTrack, ReqSector, ReqCnt; 274static int HeadSettleFlag = 0; 275static unsigned char *ReqData, *ReqBuffer; 276static int MotorOn = 0, MotorOffTrys; 277 278/* Synchronization of FDC1772 access. */ 279static volatile int fdc_busy = 0; 280static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); 281 282 283/* long req'd for set_bit --RR */ 284static unsigned long changed_floppies = 0xff, fake_change = 0; 285#define CHECK_CHANGE_DELAY HZ/2 286 287/* DAG - increased to 30*HZ - not sure if this is the correct thing to do */ 288#define FD_MOTOR_OFF_DELAY (10*HZ) 289#define FD_MOTOR_OFF_MAXTRY (10*20) 290 291#define FLOPPY_TIMEOUT (6*HZ) 292#define RECALIBRATE_ERRORS 4 /* After this many errors the drive 293 * will be recalibrated. */ 294#define MAX_ERRORS 8 /* After this many errors the driver 295 * will give up. */ 296 297#define START_MOTOR_OFF_TIMER(delay) \ 298 do { \ 299 motor_off_timer.expires = jiffies + (delay); \ 300 add_timer( &motor_off_timer ); \ 301 MotorOffTrys = 0; \ 302 } while(0) 303 304#define START_CHECK_CHANGE_TIMER(delay) \ 305 do { \ 306 mod_timer(&fd_timer, jiffies + (delay)); \ 307 } while(0) 308 309#define START_TIMEOUT() \ 310 do { \ 311 mod_timer(&timeout_timer, jiffies+FLOPPY_TIMEOUT); \ 312 } while(0) 313 314#define STOP_TIMEOUT() \ 315 do { \ 316 del_timer( &timeout_timer ); \ 317 } while(0) 318 319#define ENABLE_IRQ() enable_irq(FIQ_FD1772+64); 320 321#define DISABLE_IRQ() disable_irq(FIQ_FD1772+64); 322 323static void fd1772_checkint(void); 324 325DECLARE_WORK(fd1772_tq, (void *)fd1772_checkint, NULL); 326/* 327 * The driver is trying to determine the correct media format 328 * while Probing is set. fd_rwsec_done() clears it after a 329 * successful access. 330 */ 331static int Probing = 0; 332 333/* This flag is set when a dummy seek is necessary to make the WP 334 * status bit accessible. 335 */ 336static int NeedSeek = 0; 337 338 339/***************************** Prototypes *****************************/ 340 341static void fd_select_side(int side); 342static void fd_select_drive(int drive); 343static void fd_deselect(void); 344static void fd_motor_off_timer(unsigned long dummy); 345static void check_change(unsigned long dummy); 346static void floppy_irqconsequencehandler(void); 347static void fd_error(void); 348static void do_fd_action(int drive); 349static void fd_calibrate(void); 350static void fd_calibrate_done(int status); 351static void fd_seek(void); 352static void fd_seek_done(int status); 353static void fd_rwsec(void); 354#ifdef TRACKBUFFER 355static void fd_readtrack_check( unsigned long dummy ); 356#endif 357static void fd_rwsec_done(int status); 358static void fd_times_out(unsigned long dummy); 359static void finish_fdc(void); 360static void finish_fdc_done(int dummy); 361static void floppy_off(unsigned int nr); 362static void setup_req_params(int drive); 363static void redo_fd_request(void); 364static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int 365 cmd, unsigned long param); 366static void fd_probe(int drive); 367static int fd_test_drive_present(int drive); 368static void config_types(void); 369static int floppy_open(struct inode *inode, struct file *filp); 370static int floppy_release(struct inode *inode, struct file *filp); 371static void do_fd_request(request_queue_t *); 372 373/************************* End of Prototypes **************************/ 374 375static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0); 376 377#ifdef TRACKBUFFER 378static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0); 379#endif 380 381static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0); 382 383static DEFINE_TIMER(fd_timer, check_change, 0, 0); 384 385/* DAG: Haven't got a clue what this is? */ 386int stdma_islocked(void) 387{ 388 return 0; 389}; 390 391/* Select the side to use. */ 392 393static void fd_select_side(int side) 394{ 395 oldlatch_aupdate(LATCHA_SIDESEL, side ? 0 : LATCHA_SIDESEL); 396} 397 398 399/* Select a drive, update the FDC1772's track register 400 */ 401 402static void fd_select_drive(int drive) 403{ 404#ifdef DEBUG 405 printk("fd_select_drive:%d\n", drive); 406#endif 407 /* Hmm - nowhere do we seem to turn the motor on - I'm going to do it here! */ 408 oldlatch_aupdate(LATCHA_MOTOR | LATCHA_INUSE, 0); 409 410 if (drive == SelectedDrive) 411 return; 412 413 oldlatch_aupdate(LATCHA_FDSELALL, 0xf - (1 << drive)); 414 415 /* restore track register to saved value */ 416 FDC1772_WRITE(FDC1772REG_TRACK, unit[drive].track); 417 udelay(25); 418 419 SelectedDrive = drive; 420} 421 422 423/* Deselect both drives. */ 424 425static void fd_deselect(void) 426{ 427 unsigned long flags; 428 429 DPRINT(("fd_deselect\n")); 430 431 oldlatch_aupdate(LATCHA_FDSELALL | LATCHA_MOTOR | LATCHA_INUSE, 0xf | LATCHA_MOTOR | LATCHA_INUSE); 432 433 SelectedDrive = -1; 434} 435 436 437/* This timer function deselects the drives when the FDC1772 switched the 438 * motor off. The deselection cannot happen earlier because the FDC1772 439 * counts the index signals, which arrive only if one drive is selected. 440 */ 441 442static void fd_motor_off_timer(unsigned long dummy) 443{ 444 unsigned long flags; 445 unsigned char status; 446 int delay; 447 448 del_timer(&motor_off_timer); 449 450 if (SelectedDrive < 0) 451 /* no drive selected, needn't deselect anyone */ 452 return; 453 454 save_flags(flags); 455 cli(); 456 457 if (fdc_busy) /* was stdma_islocked */ 458 goto retry; 459 460 status = FDC1772_READ(FDC1772REG_STATUS); 461 462 if (!(status & 0x80)) { 463 /* 464 * motor already turned off by FDC1772 -> deselect drives 465 * In actual fact its this deselection which turns the motor 466 * off on the Arc, since the motor control is actually on 467 * Latch A 468 */ 469 DPRINT(("fdc1772: deselecting in fd_motor_off_timer\n")); 470 fd_deselect(); 471 MotorOn = 0; 472 restore_flags(flags); 473 return; 474 } 475 /* not yet off, try again */ 476 477retry: 478 restore_flags(flags); 479 /* Test again later; if tested too often, it seems there is no disk 480 * in the drive and the FDC1772 will leave the motor on forever (or, 481 * at least until a disk is inserted). So we'll test only twice 482 * per second from then on... 483 */ 484 delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ? 485 (++MotorOffTrys, HZ / 20) : HZ / 2; 486 START_MOTOR_OFF_TIMER(delay); 487} 488 489 490/* This function is repeatedly called to detect disk changes (as good 491 * as possible) and keep track of the current state of the write protection. 492 */ 493 494static void check_change(unsigned long dummy) 495{ 496 static int drive = 0; 497 498 unsigned long flags; 499 int stat; 500 501 if (fdc_busy) 502 return; /* Don't start poking about if the fdc is busy */ 503 504 return; /* let's just forget it for the mo DAG */ 505 506 if (++drive > 1 || !unit[drive].connected) 507 drive = 0; 508 509 save_flags(flags); 510 cli(); 511 512 if (!stdma_islocked()) { 513 stat = !!(FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_WPROT); 514 515 /* The idea here is that if the write protect line has changed then 516 the disc must have changed */ 517 if (stat != unit[drive].wpstat) { 518 DPRINT(("wpstat[%d] = %d\n", drive, stat)); 519 unit[drive].wpstat = stat; 520 set_bit(drive, &changed_floppies); 521 } 522 } 523 restore_flags(flags); 524 525 START_CHECK_CHANGE_TIMER(CHECK_CHANGE_DELAY); 526} 527 528 529/* Handling of the Head Settling Flag: This flag should be set after each 530 * seek operation, because we don't use seeks with verify. 531 */ 532 533static inline void set_head_settle_flag(void) 534{ 535 HeadSettleFlag = FDC1772CMDADD_E; 536} 537 538static inline int get_head_settle_flag(void) 539{ 540 int tmp = HeadSettleFlag; 541 HeadSettleFlag = 0; 542 return (tmp); 543} 544 545 546 547 548/* General Interrupt Handling */ 549 550static inline void copy_buffer(void *from, void *to) 551{ 552 ulong *p1 = (ulong *) from, *p2 = (ulong *) to; 553 int cnt; 554 555 for (cnt = 512 / 4; cnt; cnt--) 556 *p2++ = *p1++; 557} 558 559static void (*FloppyIRQHandler) (int status) = NULL; 560 561static void floppy_irqconsequencehandler(void) 562{ 563 unsigned char status; 564 void (*handler) (int); 565 566 fdc1772_fdc_int_done = 0; 567 568 handler = FloppyIRQHandler; 569 FloppyIRQHandler = NULL; 570 571 if (handler) { 572 nop(); 573 status = (unsigned char) fdc1772_comendstatus; 574 DPRINT(("FDC1772 irq, status = %02x handler = %08lx\n", (unsigned int) status, (unsigned long) handler)); 575 handler(status); 576 } else { 577 DPRINT(("FDC1772 irq, no handler status=%02x\n", fdc1772_comendstatus)); 578 } 579 DPRINT(("FDC1772 irq: end of floppy_irq\n")); 580} 581 582 583/* Error handling: If some error happened, retry some times, then 584 * recalibrate, then try again, and fail after MAX_ERRORS. 585 */ 586 587static void fd_error(void) 588{ 589 printk("FDC1772: fd_error\n"); 590 /*panic("fd1772: fd_error"); *//* DAG tmp */ 591 if (!CURRENT) 592 return; 593 CURRENT->errors++; 594 if (CURRENT->errors >= MAX_ERRORS) { 595 printk("fd%d: too many errors.\n", SelectedDrive); 596 end_request(CURRENT, 0); 597 } else if (CURRENT->errors == RECALIBRATE_ERRORS) { 598 printk("fd%d: recalibrating\n", SelectedDrive); 599 if (SelectedDrive != -1) 600 unit[SelectedDrive].track = -1; 601 } 602 redo_fd_request(); 603} 604 605 606 607#define SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0) 608 609 610/* do_fd_action() is the general procedure for a fd request: All 611 * required parameter settings (drive select, side select, track 612 * position) are checked and set if needed. For each of these 613 * parameters and the actual reading or writing exist two functions: 614 * one that starts the setting (or skips it if possible) and one 615 * callback for the "done" interrupt. Each done func calls the next 616 * set function to propagate the request down to fd_rwsec_done(). 617 */ 618 619static void do_fd_action(int drive) 620{ 621 struct request *req; 622 DPRINT(("do_fd_action unit[drive].track=%d\n", unit[drive].track)); 623 624#ifdef TRACKBUFFER 625repeat: 626 627 if (IS_BUFFERED( drive, ReqSide, ReqTrack )) { 628 req = CURRENT; 629 if (ReqCmd == READ) { 630 copy_buffer( SECTOR_BUFFER(ReqSector), ReqData ); 631 if (++ReqCnt < req->current_nr_sectors) { 632 /* read next sector */ 633 setup_req_params( drive ); 634 goto repeat; 635 } else { 636 /* all sectors finished */ 637 req->nr_sectors -= req->current_nr_sectors; 638 req->sector += req->current_nr_sectors; 639 end_request(req, 1); 640 redo_fd_request(); 641 return; 642 } 643 } else { 644 /* cmd == WRITE, pay attention to track buffer 645 * consistency! */ 646 copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) ); 647 } 648 } 649#endif 650 651 if (SelectedDrive != drive) { 652 /*unit[drive].track = -1; DAG */ 653 fd_select_drive(drive); 654 }; 655 656 657 if (unit[drive].track == -1) 658 fd_calibrate(); 659 else if (unit[drive].track != ReqTrack << unit[drive].disktype->stretch) 660 fd_seek(); 661 else 662 fd_rwsec(); 663} 664 665 666/* Seek to track 0 if the current track is unknown */ 667 668static void fd_calibrate(void) 669{ 670 DPRINT(("fd_calibrate\n")); 671 if (unit[SelectedDrive].track >= 0) { 672 fd_calibrate_done(0); 673 return; 674 } 675 DPRINT(("fd_calibrate (after track compare)\n")); 676 SET_IRQ_HANDLER(fd_calibrate_done); 677 /* we can't verify, since the speed may be incorrect */ 678 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | unit[SelectedDrive].steprate); 679 680 NeedSeek = 1; 681 MotorOn = 1; 682 START_TIMEOUT(); 683 /* wait for IRQ */ 684} 685 686 687static void fd_calibrate_done(int status) 688{ 689 DPRINT(("fd_calibrate_done()\n")); 690 STOP_TIMEOUT(); 691 692 /* set the correct speed now */ 693 if (status & FDC1772STAT_RECNF) { 694 printk("fd%d: restore failed\n", SelectedDrive); 695 fd_error(); 696 } else { 697 unit[SelectedDrive].track = 0; 698 fd_seek(); 699 } 700} 701 702 703/* Seek the drive to the requested track. The drive must have been 704 * calibrated at some point before this. 705 */ 706 707static void fd_seek(void) 708{ 709 unsigned long flags; 710 DPRINT(("fd_seek() to track %d (unit[SelectedDrive].track=%d)\n", ReqTrack, 711 unit[SelectedDrive].track)); 712 if (unit[SelectedDrive].track == ReqTrack << 713 unit[SelectedDrive].disktype->stretch) { 714 fd_seek_done(0); 715 return; 716 } 717 FDC1772_WRITE(FDC1772REG_DATA, ReqTrack << 718 unit[SelectedDrive].disktype->stretch); 719 udelay(25); 720 save_flags(flags); 721 clf(); 722 SET_IRQ_HANDLER(fd_seek_done); 723 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK | unit[SelectedDrive].steprate | 724 /* DAG */ 725 (MotorOn?FDC1772CMDADD_H:0)); 726 727 restore_flags(flags); 728 MotorOn = 1; 729 set_head_settle_flag(); 730 START_TIMEOUT(); 731 /* wait for IRQ */ 732} 733 734 735static void fd_seek_done(int status) 736{ 737 DPRINT(("fd_seek_done()\n")); 738 STOP_TIMEOUT(); 739 740 /* set the correct speed */ 741 if (status & FDC1772STAT_RECNF) { 742 printk("fd%d: seek error (to track %d)\n", 743 SelectedDrive, ReqTrack); 744 /* we don't know exactly which track we are on now! */ 745 unit[SelectedDrive].track = -1; 746 fd_error(); 747 } else { 748 unit[SelectedDrive].track = ReqTrack << 749 unit[SelectedDrive].disktype->stretch; 750 NeedSeek = 0; 751 fd_rwsec(); 752 } 753} 754 755 756/* This does the actual reading/writing after positioning the head 757 * over the correct track. 758 */ 759 760#ifdef TRACKBUFFER 761static int MultReadInProgress = 0; 762#endif 763 764 765static void fd_rwsec(void) 766{ 767 unsigned long paddr, flags; 768 unsigned int rwflag, old_motoron; 769 unsigned int track; 770 771 DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n", ReqSector, ReqCmd == WRITE ? 'w' : 'r')); 772 if (ReqCmd == WRITE) { 773 /*cache_push( (unsigned long)ReqData, 512 ); */ 774 paddr = (unsigned long) ReqData; 775 rwflag = 0x100; 776 } else { 777 paddr = (unsigned long) PhysDMABuffer; 778#ifdef TRACKBUFFER 779 if (read_track) 780 paddr = (unsigned long)PhysTrackBuffer; 781#endif 782 rwflag = 0; 783 } 784 785 DPRINT(("fd_rwsec() before sidesel rwflag=%d sec=%d trk=%d\n", rwflag, 786 ReqSector, FDC1772_READ(FDC1772REG_TRACK))); 787 fd_select_side(ReqSide); 788 789 /*DPRINT(("fd_rwsec() before start sector \n")); */ 790 /* Start sector of this operation */ 791#ifdef TRACKBUFFER 792 FDC1772_WRITE( FDC1772REG_SECTOR, !read_track ? ReqSector : 1 ); 793#else 794 FDC1772_WRITE( FDC1772REG_SECTOR, ReqSector ); 795#endif 796 797 /* Cheat for track if stretch != 0 */ 798 if (unit[SelectedDrive].disktype->stretch) { 799 track = FDC1772_READ(FDC1772REG_TRACK); 800 FDC1772_WRITE(FDC1772REG_TRACK, track >> 801 unit[SelectedDrive].disktype->stretch); 802 } 803 udelay(25); 804 805 DPRINT(("fd_rwsec() before setup DMA \n")); 806 /* Setup DMA - Heavily modified by DAG */ 807 save_flags(flags); 808 clf(); 809 disable_dma(FLOPPY_DMA); 810 set_dma_mode(FLOPPY_DMA, rwflag ? DMA_MODE_WRITE : DMA_MODE_READ); 811 set_dma_addr(FLOPPY_DMA, (long) paddr); /* DAG - changed from Atari specific */ 812#ifdef TRACKBUFFER 813 set_dma_count(FLOPPY_DMA,(!read_track ? 1 : unit[SelectedDrive].disktype->spt)*512); 814#else 815 set_dma_count(FLOPPY_DMA, 512); /* Block/sector size - going to have to change */ 816#endif 817 SET_IRQ_HANDLER(fd_rwsec_done); 818 /* Turn on dma int */ 819 enable_dma(FLOPPY_DMA); 820 /* Now give it something to do */ 821 FDC1772_WRITE(FDC1772REG_CMD, (rwflag ? (FDC1772CMD_WRSEC | FDC1772CMDADD_P) : 822#ifdef TRACKBUFFER 823 (FDC1772CMD_RDSEC | (read_track ? FDC1772CMDADD_M : 0) | 824 /* Hmm - the idea here is to stop the FDC spinning the disc 825 up when we know that we already still have it spinning */ 826 (MotorOn?FDC1772CMDADD_H:0)) 827#else 828 FDC1772CMD_RDSEC 829#endif 830 )); 831 832 restore_flags(flags); 833 DPRINT(("fd_rwsec() after DMA setup flags=0x%08x\n", flags)); 834 /*sti(); *//* DAG - Hmm */ 835 /* Hmm - should do something DAG */ 836 old_motoron = MotorOn; 837 MotorOn = 1; 838 NeedSeek = 1; 839 840 /* wait for interrupt */ 841 842#ifdef TRACKBUFFER 843 if (read_track) { 844 /* 845 * If reading a whole track, wait about one disk rotation and 846 * then check if all sectors are read. The FDC will even 847 * search for the first non-existant sector and need 1 sec to 848 * recognise that it isn't present :-( 849 */ 850 /* 1 rot. + 5 rot.s if motor was off */ 851 mod_timer(&readtrack_timer, jiffies + HZ/5 + (old_motoron ? 0 : HZ)); 852 DPRINT(("Setting readtrack_timer to %d @ %d\n", 853 readtrack_timer.expires,jiffies)); 854 MultReadInProgress = 1; 855 } 856#endif 857 858 /*DPRINT(("fd_rwsec() before START_TIMEOUT \n")); */ 859 START_TIMEOUT(); 860 /*DPRINT(("fd_rwsec() after START_TIMEOUT \n")); */ 861} 862 863 864#ifdef TRACKBUFFER 865 866static void fd_readtrack_check(unsigned long dummy) 867{ 868 unsigned long flags, addr; 869 extern unsigned char *fdc1772_dataaddr; 870 871 DPRINT(("fd_readtrack_check @ %d\n",jiffies)); 872 873 save_flags(flags); 874 clf(); 875 876 del_timer( &readtrack_timer ); 877 878 if (!MultReadInProgress) { 879 /* This prevents a race condition that could arise if the 880 * interrupt is triggered while the calling of this timer 881 * callback function takes place. The IRQ function then has 882 * already cleared 'MultReadInProgress' when control flow 883 * gets here. 884 */ 885 restore_flags(flags); 886 return; 887 } 888 889 /* get the current DMA address */ 890 addr=(unsigned long)fdc1772_dataaddr; /* DAG - ? */ 891 DPRINT(("fd_readtrack_check: addr=%x PhysTrackBuffer=%x\n",addr,PhysTrackBuffer)); 892 893 if (addr >= (unsigned int)PhysTrackBuffer + unit[SelectedDrive].disktype->spt*512) { 894 /* already read enough data, force an FDC interrupt to stop 895 * the read operation 896 */ 897 SET_IRQ_HANDLER( NULL ); 898 restore_flags(flags); 899 DPRINT(("fd_readtrack_check(): done\n")); 900 FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI ); 901 udelay(25); 902 903 /* No error until now -- the FDC would have interrupted 904 * otherwise! 905 */ 906 fd_rwsec_done( 0 ); 907 } else { 908 /* not yet finished, wait another tenth rotation */ 909 restore_flags(flags); 910 DPRINT(("fd_readtrack_check(): not yet finished\n")); 911 readtrack_timer.expires = jiffies + HZ/5/10; 912 add_timer( &readtrack_timer ); 913 } 914} 915 916#endif 917 918static void fd_rwsec_done(int status) 919{ 920 unsigned int track; 921 922 DPRINT(("fd_rwsec_done() status=%d @ %d\n", status,jiffies)); 923 924#ifdef TRACKBUFFER 925 if (read_track && !MultReadInProgress) 926 return; 927 928 MultReadInProgress = 0; 929 930 STOP_TIMEOUT(); 931 932 if (read_track) 933 del_timer( &readtrack_timer ); 934#endif 935 936 937 /* Correct the track if stretch != 0 */ 938 if (unit[SelectedDrive].disktype->stretch) { 939 track = FDC1772_READ(FDC1772REG_TRACK); 940 FDC1772_WRITE(FDC1772REG_TRACK, track << 941 unit[SelectedDrive].disktype->stretch); 942 } 943 if (ReqCmd == WRITE && (status & FDC1772STAT_WPROT)) { 944 printk("fd%d: is write protected\n", SelectedDrive); 945 goto err_end; 946 } 947 if ((status & FDC1772STAT_RECNF) 948#ifdef TRACKBUFFER 949 /* RECNF is no error after a multiple read when the FDC 950 * searched for a non-existant sector! 951 */ 952 && !(read_track && 953 FDC1772_READ(FDC1772REG_SECTOR) > unit[SelectedDrive].disktype->spt) 954#endif 955 ) { 956 if (Probing) { 957 if (unit[SelectedDrive].disktype > disk_type) { 958 /* try another disk type */ 959 unit[SelectedDrive].disktype--; 960 set_capacity(disks[SelectedDrive], 961 unit[SelectedDrive].disktype->blocks); 962 } else 963 Probing = 0; 964 } else { 965 /* record not found, but not probing. Maybe stretch wrong ? Restart probing */ 966 if (unit[SelectedDrive].autoprobe) { 967 unit[SelectedDrive].disktype = disk_type + NUM_DISK_TYPES - 1; 968 set_capacity(disks[SelectedDrive], 969 unit[SelectedDrive].disktype->blocks); 970 Probing = 1; 971 } 972 } 973 if (Probing) { 974 setup_req_params(SelectedDrive); 975#ifdef TRACKBUFFER 976 BufferDrive = -1; 977#endif 978 do_fd_action(SelectedDrive); 979 return; 980 } 981 printk("fd%d: sector %d not found (side %d, track %d)\n", 982 SelectedDrive, FDC1772_READ(FDC1772REG_SECTOR), ReqSide, ReqTrack); 983 goto err_end; 984 } 985 if (status & FDC1772STAT_CRC) { 986 printk("fd%d: CRC error (side %d, track %d, sector %d)\n", 987 SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR)); 988 goto err_end; 989 } 990 if (status & FDC1772STAT_LOST) { 991 printk("fd%d: lost data (side %d, track %d, sector %d)\n", 992 SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR)); 993 goto err_end; 994 } 995 Probing = 0; 996 997 if (ReqCmd == READ) { 998#ifdef TRACKBUFFER 999 if (!read_track) { 1000 /*cache_clear (PhysDMABuffer, 512);*/ 1001 copy_buffer (DMABuffer, ReqData); 1002 } else { 1003 /*cache_clear (PhysTrackBuffer, FD1772_MAX_SECTORS * 512);*/ 1004 BufferDrive = SelectedDrive; 1005 BufferSide = ReqSide; 1006 BufferTrack = ReqTrack; 1007 copy_buffer (SECTOR_BUFFER (ReqSector), ReqData); 1008 } 1009#else 1010 /*cache_clear( PhysDMABuffer, 512 ); */ 1011 copy_buffer(DMABuffer, ReqData); 1012#endif 1013 } 1014 if (++ReqCnt < CURRENT->current_nr_sectors) { 1015 /* read next sector */ 1016 setup_req_params(SelectedDrive); 1017 do_fd_action(SelectedDrive); 1018 } else { 1019 /* all sectors finished */ 1020 CURRENT->nr_sectors -= CURRENT->current_nr_sectors; 1021 CURRENT->sector += CURRENT->current_nr_sectors; 1022 end_request(CURRENT, 1); 1023 redo_fd_request(); 1024 } 1025 return; 1026 1027err_end: 1028#ifdef TRACKBUFFER 1029 BufferDrive = -1; 1030#endif 1031 1032 fd_error(); 1033} 1034 1035 1036static void fd_times_out(unsigned long dummy) 1037{ 1038 SET_IRQ_HANDLER(NULL); 1039 /* If the timeout occurred while the readtrack_check timer was 1040 * active, we need to cancel it, else bad things will happen */ 1041 del_timer( &readtrack_timer ); 1042 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI); 1043 udelay(25); 1044 1045 printk("floppy timeout\n"); 1046 STOP_TIMEOUT(); /* hmm - should we do this ? */ 1047 fd_error(); 1048} 1049 1050 1051/* The (noop) seek operation here is needed to make the WP bit in the 1052 * FDC1772 status register accessible for check_change. If the last disk 1053 * operation would have been a RDSEC, this bit would always read as 0 1054 * no matter what :-( To save time, the seek goes to the track we're 1055 * already on. 1056 */ 1057 1058static void finish_fdc(void) 1059{ 1060 /* DAG - just try without this dummy seek! */ 1061 finish_fdc_done(0); 1062 return; 1063 1064 if (!NeedSeek) { 1065 finish_fdc_done(0); 1066 } else { 1067 DPRINT(("finish_fdc: dummy seek started\n")); 1068 FDC1772_WRITE(FDC1772REG_DATA, unit[SelectedDrive].track); 1069 SET_IRQ_HANDLER(finish_fdc_done); 1070 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK); 1071 MotorOn = 1; 1072 START_TIMEOUT(); 1073 /* we must wait for the IRQ here, because the ST-DMA is 1074 * released immediately afterwards and the interrupt may be 1075 * delivered to the wrong driver. 1076 */ 1077 } 1078} 1079 1080 1081static void finish_fdc_done(int dummy) 1082{ 1083 unsigned long flags; 1084 1085 DPRINT(("finish_fdc_done entered\n")); 1086 STOP_TIMEOUT(); 1087 NeedSeek = 0; 1088 1089 if (timer_pending(&fd_timer) && 1090 time_after(jiffies + 5, fd_timer.expires)) 1091 /* If the check for a disk change is done too early after this 1092 * last seek command, the WP bit still reads wrong :-(( 1093 */ 1094 mod_timer(&fd_timer, jiffies + 5); 1095 else { 1096 /* START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */ 1097 }; 1098 del_timer(&motor_off_timer); 1099 START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY); 1100 1101 save_flags(flags); 1102 cli(); 1103 /* stdma_release(); - not sure if I should do something DAG */ 1104 fdc_busy = 0; 1105 wake_up(&fdc_wait); 1106 restore_flags(flags); 1107 1108 DPRINT(("finish_fdc() finished\n")); 1109} 1110 1111 1112/* Prevent "aliased" accesses. */ 1113static int fd_ref[4]; 1114static int fd_device[4]; 1115 1116/* dummy for blk.h */ 1117static void floppy_off(unsigned int nr) 1118{ 1119} 1120 1121 1122/* On the old arcs write protect depends on the particular model 1123 of machine. On the A310, R140, and A440 there is a disc changed 1124 detect, however on the A4x0/1 range there is not. There 1125 is nothing to tell you which machine your on. 1126 At the moment I'm just marking changed always. I've 1127 left the Atari's 'change on write protect change' code in this 1128 part (but nothing sets it). 1129 RiscOS apparently checks the disc serial number etc. to detect changes 1130 - but if it sees a disc change line go high (?) it flips to using 1131 it. Well maybe I'll add that in the future (!?) 1132*/ 1133static int check_floppy_change(struct gendisk *disk) 1134{ 1135 struct archy_floppy_struct *p = disk->private_data; 1136 unsigned int drive = p - unit; 1137 1138 if (test_bit(drive, &fake_change)) { 1139 /* simulated change (e.g. after formatting) */ 1140 return 1; 1141 } 1142 if (test_bit(drive, &changed_floppies)) { 1143 /* surely changed (the WP signal changed at least once) */ 1144 return 1; 1145 } 1146 if (p->wpstat) { 1147 /* WP is on -> could be changed: to be sure, buffers should be 1148 * invalidated... 1149 */ 1150 return 1; 1151 } 1152 return 1; /* DAG - was 0 */ 1153} 1154 1155static int floppy_revalidate(struct gendisk *disk) 1156{ 1157 struct archy_floppy_struct *p = disk->private_data; 1158 unsigned int drive = p - unit; 1159 1160 if (test_bit(drive, &changed_floppies) || test_bit(drive, &fake_change) 1161 || unit[drive].disktype == 0) { 1162#ifdef TRACKBUFFER 1163 BufferDrive = -1; 1164#endif 1165 clear_bit(drive, &fake_change); 1166 clear_bit(drive, &changed_floppies); 1167 p->disktype = 0; 1168 } 1169 return 0; 1170} 1171 1172/* This sets up the global variables describing the current request. */ 1173 1174static void setup_req_params(int drive) 1175{ 1176 int block = ReqBlock + ReqCnt; 1177 1178 ReqTrack = block / unit[drive].disktype->spt; 1179 ReqSector = block - ReqTrack * unit[drive].disktype->spt + 1; 1180 ReqSide = ReqTrack & 1; 1181 ReqTrack >>= 1; 1182 ReqData = ReqBuffer + 512 * ReqCnt; 1183 1184#ifdef TRACKBUFFER 1185 read_track = (ReqCmd == READ && CURRENT->errors == 0); 1186#endif 1187 1188 DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n", ReqSide, 1189 ReqTrack, ReqSector, (unsigned long) ReqData)); 1190} 1191 1192 1193static void redo_fd_request(void) 1194{ 1195 int drive, type; 1196 struct archy_floppy_struct *floppy; 1197 1198 DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n", 1199 CURRENT, CURRENT ? CURRENT->rq_disk->disk_name : "", 1200 CURRENT ? CURRENT->sector : 0)); 1201 1202repeat: 1203 1204 if (!CURRENT) 1205 goto the_end; 1206 1207 floppy = CURRENT->rq_disk->private_data; 1208 drive = floppy - unit; 1209 type = fd_device[drive]; 1210 1211 if (!floppy->connected) { 1212 /* drive not connected */ 1213 printk("Unknown Device: fd%d\n", drive); 1214 end_request(CURRENT, 0); 1215 goto repeat; 1216 } 1217 if (type == 0) { 1218 if (!floppy->disktype) { 1219 Probing = 1; 1220 floppy->disktype = disk_type + NUM_DISK_TYPES - 1; 1221 set_capacity(disks[drive], floppy->disktype->blocks); 1222 floppy->autoprobe = 1; 1223 } 1224 } else { 1225 /* user supplied disk type */ 1226 --type; 1227 if (type >= NUM_DISK_TYPES) { 1228 printk("fd%d: invalid disk format", drive); 1229 end_request(CURRENT, 0); 1230 goto repeat; 1231 } 1232 floppy->disktype = &disk_type[type]; 1233 set_capacity(disks[drive], floppy->disktype->blocks); 1234 floppy->autoprobe = 0; 1235 } 1236 1237 if (CURRENT->sector + 1 > floppy->disktype->blocks) { 1238 end_request(CURRENT, 0); 1239 goto repeat; 1240 } 1241 /* stop deselect timer */ 1242 del_timer(&motor_off_timer); 1243 1244 ReqCnt = 0; 1245 ReqCmd = CURRENT->cmd; 1246 ReqBlock = CURRENT->sector; 1247 ReqBuffer = CURRENT->buffer; 1248 setup_req_params(drive); 1249 do_fd_action(drive); 1250 1251 return; 1252 1253the_end: 1254 finish_fdc(); 1255} 1256 1257static void fd1772_checkint(void) 1258{ 1259 extern int fdc1772_bytestogo; 1260 1261 /*printk("fd1772_checkint %d\n",fdc1772_fdc_int_done);*/ 1262 if (fdc1772_fdc_int_done) 1263 floppy_irqconsequencehandler(); 1264 if ((MultReadInProgress) && (fdc1772_bytestogo==0)) fd_readtrack_check(0); 1265 if (fdc_busy) { 1266 schedule_work(&fd1772_tq); 1267 } 1268} 1269 1270static void do_fd_request(request_queue_t* q) 1271{ 1272 unsigned long flags; 1273 1274 DPRINT(("do_fd_request for pid %d\n", current->pid)); 1275 if (fdc_busy) return; 1276 save_flags(flags); 1277 cli(); 1278 wait_event(fdc_wait, !fdc_busy); 1279 fdc_busy = 1; 1280 ENABLE_IRQ(); 1281 restore_flags(flags); 1282 1283 fdc1772_fdc_int_done = 0; 1284 1285 redo_fd_request(); 1286 1287 schedule_work(&fd1772_tq); 1288} 1289 1290 1291static int invalidate_drive(struct block_device *bdev) 1292{ 1293 struct archy_floppy_struct *p = bdev->bd_disk->private_data; 1294 /* invalidate the buffer track to force a reread */ 1295#ifdef TRACKBUFFER 1296 BufferDrive = -1; 1297#endif 1298 1299 set_bit(p - unit, &fake_change); 1300 return 0; 1301} 1302 1303static int fd_ioctl(struct inode *inode, struct file *filp, 1304 unsigned int cmd, unsigned long param) 1305{ 1306 struct block_device *bdev = inode->i_bdev; 1307 1308 switch (cmd) { 1309 case FDFMTEND: 1310 case FDFLUSH: 1311 invalidate_drive(bdev); 1312 check_disk_change(bdev); 1313 case FDFMTBEG: 1314 return 0; 1315 default: 1316 return -EINVAL; 1317 } 1318} 1319 1320 1321/* Initialize the 'unit' variable for drive 'drive' */ 1322 1323static void fd_probe(int drive) 1324{ 1325 unit[drive].connected = 0; 1326 unit[drive].disktype = NULL; 1327 1328 if (!fd_test_drive_present(drive)) 1329 return; 1330 1331 unit[drive].connected = 1; 1332 unit[drive].track = -1; /* If we put the auto detect back in this can go to 0 */ 1333 unit[drive].steprate = FDC1772STEP_6; 1334 MotorOn = 1; /* from probe restore operation! */ 1335} 1336 1337 1338/* This function tests the physical presence of a floppy drive (not 1339 * whether a disk is inserted). This is done by issuing a restore 1340 * command, waiting max. 2 seconds (that should be enough to move the 1341 * head across the whole disk) and looking at the state of the "TR00" 1342 * signal. This should now be raised if there is a drive connected 1343 * (and there is no hardware failure :-) Otherwise, the drive is 1344 * declared absent. 1345 */ 1346 1347static int fd_test_drive_present(int drive) 1348{ 1349 unsigned long timeout; 1350 unsigned char status; 1351 int ok; 1352 1353 printk("fd_test_drive_present %d\n", drive); 1354 if (drive > 1) 1355 return (0); 1356 return (1); /* Simple hack for the moment - the autodetect doesn't seem to work on arc */ 1357 fd_select_drive(drive); 1358 1359 /* disable interrupt temporarily */ 1360 DISABLE_IRQ(); 1361 FDC1772_WRITE(FDC1772REG_TRACK, 0x00); /* was ff00 why? */ 1362 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6); 1363 1364 /*printk("fd_test_drive_present: Going into timeout loop\n"); */ 1365 for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; time_before(jiffies, timeout);) { 1366 /* What does this piece of atariism do? - query for an interrupt? */ 1367 /* if (!(mfp.par_dt_reg & 0x20)) 1368 break; */ 1369 /* Well this is my nearest guess - quit when we get an FDC interrupt */ 1370 if (ioc_readb(IOC_FIQSTAT) & 2) 1371 break; 1372 } 1373 1374 /*printk("fd_test_drive_present: Coming out of timeout loop\n"); */ 1375 status = FDC1772_READ(FDC1772REG_STATUS); 1376 ok = (status & FDC1772STAT_TR00) != 0; 1377 1378 /*printk("fd_test_drive_present: ok=%d\n",ok); */ 1379 /* force interrupt to abort restore operation (FDC1772 would try 1380 * about 50 seconds!) */ 1381 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI); 1382 udelay(500); 1383 status = FDC1772_READ(FDC1772REG_STATUS); 1384 udelay(20); 1385 /*printk("fd_test_drive_present: just before OK code %d\n",ok); */ 1386 1387 if (ok) { 1388 /* dummy seek command to make WP bit accessible */ 1389 FDC1772_WRITE(FDC1772REG_DATA, 0); 1390 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK); 1391 printk("fd_test_drive_present: just before wait for int\n"); 1392 /* DAG: Guess means wait for interrupt */ 1393 while (!(ioc_readb(IOC_FIQSTAT) & 2)); 1394 printk("fd_test_drive_present: just after wait for int\n"); 1395 status = FDC1772_READ(FDC1772REG_STATUS); 1396 } 1397 printk("fd_test_drive_present: just before ENABLE_IRQ\n"); 1398 ENABLE_IRQ(); 1399 printk("fd_test_drive_present: about to return\n"); 1400 return (ok); 1401} 1402 1403 1404/* Look how many and which kind of drives are connected. If there are 1405 * floppies, additionally start the disk-change and motor-off timers. 1406 */ 1407 1408static void config_types(void) 1409{ 1410 int drive, cnt = 0; 1411 1412 printk("Probing floppy drive(s):\n"); 1413 for (drive = 0; drive < FD_MAX_UNITS; drive++) { 1414 fd_probe(drive); 1415 if (unit[drive].connected) { 1416 printk("fd%d\n", drive); 1417 ++cnt; 1418 } 1419 } 1420 1421 if (FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_BUSY) { 1422 /* If FDC1772 is still busy from probing, give it another FORCI 1423 * command to abort the operation. If this isn't done, the FDC1772 1424 * will interrupt later and its IRQ line stays low, because 1425 * the status register isn't read. And this will block any 1426 * interrupts on this IRQ line :-( 1427 */ 1428 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI); 1429 udelay(500); 1430 FDC1772_READ(FDC1772REG_STATUS); 1431 udelay(20); 1432 } 1433 if (cnt > 0) { 1434 START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY); 1435 if (cnt == 1) 1436 fd_select_drive(0); 1437 /*START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */ 1438 } 1439} 1440 1441/* 1442 * floppy_open check for aliasing (/dev/fd0 can be the same as 1443 * /dev/PS0 etc), and disallows simultaneous access to the same 1444 * drive with different device numbers. 1445 */ 1446 1447static int floppy_open(struct inode *inode, struct file *filp) 1448{ 1449 int drive = iminor(inode) & 3; 1450 int type = iminor(inode) >> 2; 1451 int old_dev = fd_device[drive]; 1452 1453 if (fd_ref[drive] && old_dev != type) 1454 return -EBUSY; 1455 1456 if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL)) 1457 return -EBUSY; 1458 1459 if (filp->f_flags & O_EXCL) 1460 fd_ref[drive] = -1; 1461 else 1462 fd_ref[drive]++; 1463 1464 fd_device[drive] = type; 1465 1466 if (filp->f_flags & O_NDELAY) 1467 return 0; 1468 1469 if (filp->f_mode & 3) { 1470 check_disk_change(inode->i_bdev); 1471 if (filp->f_mode & 2) { 1472 if (unit[drive].wpstat) { 1473 floppy_release(inode, filp); 1474 return -EROFS; 1475 } 1476 } 1477 } 1478 return 0; 1479} 1480 1481 1482static int floppy_release(struct inode *inode, struct file *filp) 1483{ 1484 int drive = iminor(inode) & 3; 1485 1486 if (fd_ref[drive] < 0) 1487 fd_ref[drive] = 0; 1488 else if (!fd_ref[drive]--) { 1489 printk("floppy_release with fd_ref == 0"); 1490 fd_ref[drive] = 0; 1491 } 1492 1493 return 0; 1494} 1495 1496static struct block_device_operations floppy_fops = 1497{ 1498 .open = floppy_open, 1499 .release = floppy_release, 1500 .ioctl = fd_ioctl, 1501 .media_changed = check_floppy_change, 1502 .revalidate_disk= floppy_revalidate, 1503}; 1504 1505static struct kobject *floppy_find(dev_t dev, int *part, void *data) 1506{ 1507 int drive = *part & 3; 1508 if ((*part >> 2) > NUM_DISK_TYPES || drive >= FD_MAX_UNITS) 1509 return NULL; 1510 *part = 0; 1511 return get_disk(disks[drive]); 1512} 1513 1514int fd1772_init(void) 1515{ 1516 static DEFINE_SPINLOCK(lock); 1517 int i, err = -ENOMEM; 1518 1519 if (!machine_is_archimedes()) 1520 return 0; 1521 1522 for (i = 0; i < FD_MAX_UNITS; i++) { 1523 disks[i] = alloc_disk(1); 1524 if (!disks[i]) 1525 goto err_disk; 1526 } 1527 1528 err = register_blkdev(MAJOR_NR, "fd"); 1529 if (err) 1530 goto err_disk; 1531 1532 err = -EBUSY; 1533 if (request_dma(FLOPPY_DMA, "fd1772")) { 1534 printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA); 1535 goto err_blkdev; 1536 }; 1537 1538 if (request_dma(FIQ_FD1772, "fd1772 end")) { 1539 printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772); 1540 goto err_dma1; 1541 }; 1542 1543 /* initialize variables */ 1544 SelectedDrive = -1; 1545#ifdef TRACKBUFFER 1546 BufferDrive = BufferSide = BufferTrack = -1; 1547 /* Atari uses 512 - I want to eventually cope with 1K sectors */ 1548 DMABuffer = kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL); 1549 TrackBuffer = DMABuffer + 512; 1550#else 1551 /* Allocate memory for the DMAbuffer - on the Atari this takes it 1552 out of some special memory... */ 1553 DMABuffer = kmalloc(2048); /* Copes with pretty large sectors */ 1554#endif 1555 err = -ENOMEM; 1556 if (!DMAbuffer) 1557 goto err_dma2; 1558 1559 enable_dma(FIQ_FD1772); /* This inserts a call to our command end routine */ 1560 1561 floppy_queue = blk_init_queue(do_fd_request, &lock); 1562 if (!floppy_queue) 1563 goto err_queue; 1564 1565 for (i = 0; i < FD_MAX_UNITS; i++) { 1566 unit[i].track = -1; 1567 disks[i]->major = MAJOR_NR; 1568 disks[i]->first_minor = 0; 1569 disks[i]->fops = &floppy_fops; 1570 sprintf(disks[i]->disk_name, "fd%d", i); 1571 disks[i]->private_data = &unit[i]; 1572 disks[i]->queue = floppy_queue; 1573 set_capacity(disks[i], MAX_DISK_SIZE * 2); 1574 } 1575 blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE, 1576 floppy_find, NULL, NULL); 1577 1578 for (i = 0; i < FD_MAX_UNITS; i++) 1579 add_disk(disks[i]); 1580 1581 config_types(); 1582 1583 return 0; 1584 1585 err_queue: 1586 kfree(DMAbuffer); 1587 err_dma2: 1588 free_dma(FIQ_FD1772); 1589 1590 err_dma1: 1591 free_dma(FLOPPY_DMA); 1592 1593 err_blkdev: 1594 unregister_blkdev(MAJOR_NR, "fd"); 1595 1596 err_disk: 1597 while (i--) 1598 put_disk(disks[i]); 1599 return err; 1600} 1601