amiflop.c (51520B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/amiga/amiflop.c 4 * 5 * Copyright (C) 1993 Greg Harp 6 * Portions of this driver are based on code contributed by Brad Pepers 7 * 8 * revised 28.5.95 by Joerg Dorchain 9 * - now no bugs(?) any more for both HD & DD 10 * - added support for 40 Track 5.25" drives, 80-track hopefully behaves 11 * like 3.5" dd (no way to test - are there any 5.25" drives out there 12 * that work on an A4000?) 13 * - wrote formatting routine (maybe dirty, but works) 14 * 15 * june/july 1995 added ms-dos support by Joerg Dorchain 16 * (portions based on messydos.device and various contributors) 17 * - currently only 9 and 18 sector disks 18 * 19 * - fixed a bug with the internal trackbuffer when using multiple 20 * disks the same time 21 * - made formatting a bit safer 22 * - added command line and machine based default for "silent" df0 23 * 24 * december 1995 adapted for 1.2.13pl4 by Joerg Dorchain 25 * - works but I think it's inefficient. (look in redo_fd_request) 26 * But the changes were very efficient. (only three and a half lines) 27 * 28 * january 1996 added special ioctl for tracking down read/write problems 29 * - usage ioctl(d, RAW_TRACK, ptr); the raw track buffer (MFM-encoded data 30 * is copied to area. (area should be large enough since no checking is 31 * done - 30K is currently sufficient). return the actual size of the 32 * trackbuffer 33 * - replaced udelays() by a timer (CIAA timer B) for the waits 34 * needed for the disk mechanic. 35 * 36 * february 1996 fixed error recovery and multiple disk access 37 * - both got broken the first time I tampered with the driver :-( 38 * - still not safe, but better than before 39 * 40 * revised Marts 3rd, 1996 by Jes Sorensen for use in the 1.3.28 kernel. 41 * - Minor changes to accept the kdev_t. 42 * - Replaced some more udelays with ms_delays. Udelay is just a loop, 43 * and so the delay will be different depending on the given 44 * processor :-( 45 * - The driver could use a major cleanup because of the new 46 * major/minor handling that came with kdev_t. It seems to work for 47 * the time being, but I can't guarantee that it will stay like 48 * that when we start using 16 (24?) bit minors. 49 * 50 * restructured jan 1997 by Joerg Dorchain 51 * - Fixed Bug accessing multiple disks 52 * - some code cleanup 53 * - added trackbuffer for each drive to speed things up 54 * - fixed some race conditions (who finds the next may send it to me ;-) 55 */ 56 57#include <linux/module.h> 58#include <linux/slab.h> 59 60#include <linux/fd.h> 61#include <linux/hdreg.h> 62#include <linux/delay.h> 63#include <linux/init.h> 64#include <linux/major.h> 65#include <linux/mutex.h> 66#include <linux/fs.h> 67#include <linux/blk-mq.h> 68#include <linux/interrupt.h> 69#include <linux/platform_device.h> 70 71#include <asm/setup.h> 72#include <linux/uaccess.h> 73#include <asm/amigahw.h> 74#include <asm/amigaints.h> 75#include <asm/irq.h> 76 77#undef DEBUG /* print _LOTS_ of infos */ 78 79#define RAW_IOCTL 80#ifdef RAW_IOCTL 81#define IOCTL_RAW_TRACK 0x5254524B /* 'RTRK' */ 82#endif 83 84/* 85 * Defines 86 */ 87 88/* 89 * CIAAPRA bits (read only) 90 */ 91 92#define DSKRDY (0x1<<5) /* disk ready when low */ 93#define DSKTRACK0 (0x1<<4) /* head at track zero when low */ 94#define DSKPROT (0x1<<3) /* disk protected when low */ 95#define DSKCHANGE (0x1<<2) /* low when disk removed */ 96 97/* 98 * CIAAPRB bits (read/write) 99 */ 100 101#define DSKMOTOR (0x1<<7) /* motor on when low */ 102#define DSKSEL3 (0x1<<6) /* select drive 3 when low */ 103#define DSKSEL2 (0x1<<5) /* select drive 2 when low */ 104#define DSKSEL1 (0x1<<4) /* select drive 1 when low */ 105#define DSKSEL0 (0x1<<3) /* select drive 0 when low */ 106#define DSKSIDE (0x1<<2) /* side selection: 0 = upper, 1 = lower */ 107#define DSKDIREC (0x1<<1) /* step direction: 0=in, 1=out (to trk 0) */ 108#define DSKSTEP (0x1) /* pulse low to step head 1 track */ 109 110/* 111 * DSKBYTR bits (read only) 112 */ 113 114#define DSKBYT (1<<15) /* register contains valid byte when set */ 115#define DMAON (1<<14) /* disk DMA enabled */ 116#define DISKWRITE (1<<13) /* disk write bit in DSKLEN enabled */ 117#define WORDEQUAL (1<<12) /* DSKSYNC register match when true */ 118/* bits 7-0 are data */ 119 120/* 121 * ADKCON/ADKCONR bits 122 */ 123 124#ifndef SETCLR 125#define ADK_SETCLR (1<<15) /* control bit */ 126#endif 127#define ADK_PRECOMP1 (1<<14) /* precompensation selection */ 128#define ADK_PRECOMP0 (1<<13) /* 00=none, 01=140ns, 10=280ns, 11=500ns */ 129#define ADK_MFMPREC (1<<12) /* 0=GCR precomp., 1=MFM precomp. */ 130#define ADK_WORDSYNC (1<<10) /* enable DSKSYNC auto DMA */ 131#define ADK_MSBSYNC (1<<9) /* when 1, enable sync on MSbit (for GCR) */ 132#define ADK_FAST (1<<8) /* bit cell: 0=2us (GCR), 1=1us (MFM) */ 133 134/* 135 * DSKLEN bits 136 */ 137 138#define DSKLEN_DMAEN (1<<15) 139#define DSKLEN_WRITE (1<<14) 140 141/* 142 * INTENA/INTREQ bits 143 */ 144 145#define DSKINDEX (0x1<<4) /* DSKINDEX bit */ 146 147/* 148 * Misc 149 */ 150 151#define MFM_SYNC 0x4489 /* standard MFM sync value */ 152 153/* Values for FD_COMMAND */ 154#define FD_RECALIBRATE 0x07 /* move to track 0 */ 155#define FD_SEEK 0x0F /* seek track */ 156#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ 157#define FD_WRITE 0xC5 /* write with MT, MFM */ 158#define FD_SENSEI 0x08 /* Sense Interrupt Status */ 159#define FD_SPECIFY 0x03 /* specify HUT etc */ 160#define FD_FORMAT 0x4D /* format one track */ 161#define FD_VERSION 0x10 /* get version code */ 162#define FD_CONFIGURE 0x13 /* configure FIFO operation */ 163#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */ 164 165#define FD_MAX_UNITS 4 /* Max. Number of drives */ 166#define FLOPPY_MAX_SECTORS 22 /* Max. Number of sectors per track */ 167 168struct fd_data_type { 169 char *name; /* description of data type */ 170 int sects; /* sectors per track */ 171 int (*read_fkt)(int); /* read whole track */ 172 void (*write_fkt)(int); /* write whole track */ 173}; 174 175struct fd_drive_type { 176 unsigned long code; /* code returned from drive */ 177 char *name; /* description of drive */ 178 unsigned int tracks; /* number of tracks */ 179 unsigned int heads; /* number of heads */ 180 unsigned int read_size; /* raw read size for one track */ 181 unsigned int write_size; /* raw write size for one track */ 182 unsigned int sect_mult; /* sectors and gap multiplier (HD = 2) */ 183 unsigned int precomp1; /* start track for precomp 1 */ 184 unsigned int precomp2; /* start track for precomp 2 */ 185 unsigned int step_delay; /* time (in ms) for delay after step */ 186 unsigned int settle_time; /* time to settle after dir change */ 187 unsigned int side_time; /* time needed to change sides */ 188}; 189 190struct amiga_floppy_struct { 191 struct fd_drive_type *type; /* type of floppy for this unit */ 192 struct fd_data_type *dtype; /* type of floppy for this unit */ 193 int track; /* current track (-1 == unknown) */ 194 unsigned char *trackbuf; /* current track (kmaloc()'d */ 195 196 int blocks; /* total # blocks on disk */ 197 198 int changed; /* true when not known */ 199 int disk; /* disk in drive (-1 == unknown) */ 200 int motor; /* true when motor is at speed */ 201 int busy; /* true when drive is active */ 202 int dirty; /* true when trackbuf is not on disk */ 203 int status; /* current error code for unit */ 204 struct gendisk *gendisk[2]; 205 struct blk_mq_tag_set tag_set; 206}; 207 208/* 209 * Error codes 210 */ 211#define FD_OK 0 /* operation succeeded */ 212#define FD_ERROR -1 /* general error (seek, read, write, etc) */ 213#define FD_NOUNIT 1 /* unit does not exist */ 214#define FD_UNITBUSY 2 /* unit already active */ 215#define FD_NOTACTIVE 3 /* unit is not active */ 216#define FD_NOTREADY 4 /* unit is not ready (motor not on/no disk) */ 217 218#define MFM_NOSYNC 1 219#define MFM_HEADER 2 220#define MFM_DATA 3 221#define MFM_TRACK 4 222 223/* 224 * Floppy ID values 225 */ 226#define FD_NODRIVE 0x00000000 /* response when no unit is present */ 227#define FD_DD_3 0xffffffff /* double-density 3.5" (880K) drive */ 228#define FD_HD_3 0x55555555 /* high-density 3.5" (1760K) drive */ 229#define FD_DD_5 0xaaaaaaaa /* double-density 5.25" (440K) drive */ 230 231static DEFINE_MUTEX(amiflop_mutex); 232static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it doesn't identify */ 233 234module_param(fd_def_df0, ulong, 0); 235MODULE_LICENSE("GPL"); 236 237/* 238 * Macros 239 */ 240#define MOTOR_ON (ciab.prb &= ~DSKMOTOR) 241#define MOTOR_OFF (ciab.prb |= DSKMOTOR) 242#define SELECT(mask) (ciab.prb &= ~mask) 243#define DESELECT(mask) (ciab.prb |= mask) 244#define SELMASK(drive) (1 << (3 + (drive & 3))) 245 246static struct fd_drive_type drive_types[] = { 247/* code name tr he rdsz wrsz sm pc1 pc2 sd st st*/ 248/* warning: times are now in milliseconds (ms) */ 249{ FD_DD_3, "DD 3.5", 80, 2, 14716, 13630, 1, 80,161, 3, 18, 1}, 250{ FD_HD_3, "HD 3.5", 80, 2, 28344, 27258, 2, 80,161, 3, 18, 1}, 251{ FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2}, 252{ FD_NODRIVE, "No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 253}; 254static int num_dr_types = ARRAY_SIZE(drive_types); 255 256static int amiga_read(int), dos_read(int); 257static void amiga_write(int), dos_write(int); 258static struct fd_data_type data_types[] = { 259 { "Amiga", 11 , amiga_read, amiga_write}, 260 { "MS-Dos", 9, dos_read, dos_write} 261}; 262 263/* current info on each unit */ 264static struct amiga_floppy_struct unit[FD_MAX_UNITS]; 265 266static struct timer_list flush_track_timer[FD_MAX_UNITS]; 267static struct timer_list post_write_timer; 268static unsigned long post_write_timer_drive; 269static struct timer_list motor_on_timer; 270static struct timer_list motor_off_timer[FD_MAX_UNITS]; 271static int on_attempts; 272 273/* Synchronization of FDC access */ 274/* request loop (trackbuffer) */ 275static volatile int fdc_busy = -1; 276static volatile int fdc_nested; 277static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); 278 279static DECLARE_COMPLETION(motor_on_completion); 280 281static volatile int selected = -1; /* currently selected drive */ 282 283static int writepending; 284static int writefromint; 285static char *raw_buf; 286 287static DEFINE_SPINLOCK(amiflop_lock); 288 289#define RAW_BUF_SIZE 30000 /* size of raw disk data */ 290 291/* 292 * These are global variables, as that's the easiest way to give 293 * information to interrupts. They are the data used for the current 294 * request. 295 */ 296static volatile char block_flag; 297static DECLARE_WAIT_QUEUE_HEAD(wait_fd_block); 298 299/* MS-Dos MFM Coding tables (should go quick and easy) */ 300static unsigned char mfmencode[16]={ 301 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, 302 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55 303}; 304static unsigned char mfmdecode[128]; 305 306/* floppy internal millisecond timer stuff */ 307static DECLARE_COMPLETION(ms_wait_completion); 308#define MS_TICKS ((amiga_eclock+50)/1000) 309 310/* 311 * Note that MAX_ERRORS=X doesn't imply that we retry every bad read 312 * max X times - some types of errors increase the errorcount by 2 or 313 * even 3, so we might actually retry only X/2 times before giving up. 314 */ 315#define MAX_ERRORS 12 316 317#define custom amiga_custom 318 319/* Prevent "aliased" accesses. */ 320static int fd_ref[4] = { 0,0,0,0 }; 321static int fd_device[4] = { 0, 0, 0, 0 }; 322 323/* 324 * Here come the actual hardware access and helper functions. 325 * They are not reentrant and single threaded because all drives 326 * share the same hardware and the same trackbuffer. 327 */ 328 329/* Milliseconds timer */ 330 331static irqreturn_t ms_isr(int irq, void *dummy) 332{ 333 complete(&ms_wait_completion); 334 return IRQ_HANDLED; 335} 336 337/* all waits are queued up 338 A more generic routine would do a schedule a la timer.device */ 339static void ms_delay(int ms) 340{ 341 int ticks; 342 static DEFINE_MUTEX(mutex); 343 344 if (ms > 0) { 345 mutex_lock(&mutex); 346 ticks = MS_TICKS*ms-1; 347 ciaa.tblo=ticks%256; 348 ciaa.tbhi=ticks/256; 349 ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */ 350 wait_for_completion(&ms_wait_completion); 351 mutex_unlock(&mutex); 352 } 353} 354 355/* Hardware semaphore */ 356 357/* returns true when we would get the semaphore */ 358static inline int try_fdc(int drive) 359{ 360 drive &= 3; 361 return ((fdc_busy < 0) || (fdc_busy == drive)); 362} 363 364static void get_fdc(int drive) 365{ 366 unsigned long flags; 367 368 drive &= 3; 369#ifdef DEBUG 370 printk("get_fdc: drive %d fdc_busy %d fdc_nested %d\n",drive,fdc_busy,fdc_nested); 371#endif 372 local_irq_save(flags); 373 wait_event(fdc_wait, try_fdc(drive)); 374 fdc_busy = drive; 375 fdc_nested++; 376 local_irq_restore(flags); 377} 378 379static inline void rel_fdc(void) 380{ 381#ifdef DEBUG 382 if (fdc_nested == 0) 383 printk("fd: unmatched rel_fdc\n"); 384 printk("rel_fdc: fdc_busy %d fdc_nested %d\n",fdc_busy,fdc_nested); 385#endif 386 fdc_nested--; 387 if (fdc_nested == 0) { 388 fdc_busy = -1; 389 wake_up(&fdc_wait); 390 } 391} 392 393static void fd_select (int drive) 394{ 395 unsigned char prb = ~0; 396 397 drive&=3; 398#ifdef DEBUG 399 printk("selecting %d\n",drive); 400#endif 401 if (drive == selected) 402 return; 403 get_fdc(drive); 404 selected = drive; 405 406 if (unit[drive].track % 2 != 0) 407 prb &= ~DSKSIDE; 408 if (unit[drive].motor == 1) 409 prb &= ~DSKMOTOR; 410 ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3)); 411 ciab.prb = prb; 412 prb &= ~SELMASK(drive); 413 ciab.prb = prb; 414 rel_fdc(); 415} 416 417static void fd_deselect (int drive) 418{ 419 unsigned char prb; 420 unsigned long flags; 421 422 drive&=3; 423#ifdef DEBUG 424 printk("deselecting %d\n",drive); 425#endif 426 if (drive != selected) { 427 printk(KERN_WARNING "Deselecting drive %d while %d was selected!\n",drive,selected); 428 return; 429 } 430 431 get_fdc(drive); 432 local_irq_save(flags); 433 434 selected = -1; 435 436 prb = ciab.prb; 437 prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3)); 438 ciab.prb = prb; 439 440 local_irq_restore (flags); 441 rel_fdc(); 442 443} 444 445static void motor_on_callback(struct timer_list *unused) 446{ 447 if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) { 448 complete_all(&motor_on_completion); 449 } else { 450 motor_on_timer.expires = jiffies + HZ/10; 451 add_timer(&motor_on_timer); 452 } 453} 454 455static int fd_motor_on(int nr) 456{ 457 nr &= 3; 458 459 del_timer(motor_off_timer + nr); 460 461 if (!unit[nr].motor) { 462 unit[nr].motor = 1; 463 fd_select(nr); 464 465 reinit_completion(&motor_on_completion); 466 mod_timer(&motor_on_timer, jiffies + HZ/2); 467 468 on_attempts = 10; 469 wait_for_completion(&motor_on_completion); 470 fd_deselect(nr); 471 } 472 473 if (on_attempts == 0) { 474 on_attempts = -1; 475#if 0 476 printk (KERN_ERR "motor_on failed, turning motor off\n"); 477 fd_motor_off (motor_off_timer + nr); 478 return 0; 479#else 480 printk (KERN_WARNING "DSKRDY not set after 1.5 seconds - assuming drive is spinning notwithstanding\n"); 481#endif 482 } 483 484 return 1; 485} 486 487static void fd_motor_off(struct timer_list *timer) 488{ 489 unsigned long drive = ((unsigned long)timer - 490 (unsigned long)&motor_off_timer[0]) / 491 sizeof(motor_off_timer[0]); 492 493 drive&=3; 494 if (!try_fdc(drive)) { 495 /* We would be blocked in an interrupt, so try again later */ 496 timer->expires = jiffies + 1; 497 add_timer(timer); 498 return; 499 } 500 unit[drive].motor = 0; 501 fd_select(drive); 502 udelay (1); 503 fd_deselect(drive); 504} 505 506static void floppy_off (unsigned int nr) 507{ 508 int drive; 509 510 drive = nr & 3; 511 mod_timer(motor_off_timer + drive, jiffies + 3*HZ); 512} 513 514static int fd_calibrate(int drive) 515{ 516 unsigned char prb; 517 int n; 518 519 drive &= 3; 520 get_fdc(drive); 521 if (!fd_motor_on (drive)) 522 return 0; 523 fd_select (drive); 524 prb = ciab.prb; 525 prb |= DSKSIDE; 526 prb &= ~DSKDIREC; 527 ciab.prb = prb; 528 for (n = unit[drive].type->tracks/2; n != 0; --n) { 529 if (ciaa.pra & DSKTRACK0) 530 break; 531 prb &= ~DSKSTEP; 532 ciab.prb = prb; 533 prb |= DSKSTEP; 534 udelay (2); 535 ciab.prb = prb; 536 ms_delay(unit[drive].type->step_delay); 537 } 538 ms_delay (unit[drive].type->settle_time); 539 prb |= DSKDIREC; 540 n = unit[drive].type->tracks + 20; 541 for (;;) { 542 prb &= ~DSKSTEP; 543 ciab.prb = prb; 544 prb |= DSKSTEP; 545 udelay (2); 546 ciab.prb = prb; 547 ms_delay(unit[drive].type->step_delay + 1); 548 if ((ciaa.pra & DSKTRACK0) == 0) 549 break; 550 if (--n == 0) { 551 printk (KERN_ERR "fd%d: calibrate failed, turning motor off\n", drive); 552 fd_motor_off (motor_off_timer + drive); 553 unit[drive].track = -1; 554 rel_fdc(); 555 return 0; 556 } 557 } 558 unit[drive].track = 0; 559 ms_delay(unit[drive].type->settle_time); 560 561 rel_fdc(); 562 fd_deselect(drive); 563 return 1; 564} 565 566static int fd_seek(int drive, int track) 567{ 568 unsigned char prb; 569 int cnt; 570 571#ifdef DEBUG 572 printk("seeking drive %d to track %d\n",drive,track); 573#endif 574 drive &= 3; 575 get_fdc(drive); 576 if (unit[drive].track == track) { 577 rel_fdc(); 578 return 1; 579 } 580 if (!fd_motor_on(drive)) { 581 rel_fdc(); 582 return 0; 583 } 584 if (unit[drive].track < 0 && !fd_calibrate(drive)) { 585 rel_fdc(); 586 return 0; 587 } 588 589 fd_select (drive); 590 cnt = unit[drive].track/2 - track/2; 591 prb = ciab.prb; 592 prb |= DSKSIDE | DSKDIREC; 593 if (track % 2 != 0) 594 prb &= ~DSKSIDE; 595 if (cnt < 0) { 596 cnt = - cnt; 597 prb &= ~DSKDIREC; 598 } 599 ciab.prb = prb; 600 if (track % 2 != unit[drive].track % 2) 601 ms_delay (unit[drive].type->side_time); 602 unit[drive].track = track; 603 if (cnt == 0) { 604 rel_fdc(); 605 fd_deselect(drive); 606 return 1; 607 } 608 do { 609 prb &= ~DSKSTEP; 610 ciab.prb = prb; 611 prb |= DSKSTEP; 612 udelay (1); 613 ciab.prb = prb; 614 ms_delay (unit[drive].type->step_delay); 615 } while (--cnt != 0); 616 ms_delay (unit[drive].type->settle_time); 617 618 rel_fdc(); 619 fd_deselect(drive); 620 return 1; 621} 622 623static unsigned long fd_get_drive_id(int drive) 624{ 625 int i; 626 ulong id = 0; 627 628 drive&=3; 629 get_fdc(drive); 630 /* set up for ID */ 631 MOTOR_ON; 632 udelay(2); 633 SELECT(SELMASK(drive)); 634 udelay(2); 635 DESELECT(SELMASK(drive)); 636 udelay(2); 637 MOTOR_OFF; 638 udelay(2); 639 SELECT(SELMASK(drive)); 640 udelay(2); 641 DESELECT(SELMASK(drive)); 642 udelay(2); 643 644 /* loop and read disk ID */ 645 for (i=0; i<32; i++) { 646 SELECT(SELMASK(drive)); 647 udelay(2); 648 649 /* read and store value of DSKRDY */ 650 id <<= 1; 651 id |= (ciaa.pra & DSKRDY) ? 0 : 1; /* cia regs are low-active! */ 652 653 DESELECT(SELMASK(drive)); 654 } 655 656 rel_fdc(); 657 658 /* 659 * RB: At least A500/A2000's df0: don't identify themselves. 660 * As every (real) Amiga has at least a 3.5" DD drive as df0: 661 * we default to that if df0: doesn't identify as a certain 662 * type. 663 */ 664 if(drive == 0 && id == FD_NODRIVE) 665 { 666 id = fd_def_df0; 667 printk(KERN_NOTICE "fd: drive 0 didn't identify, setting default %08lx\n", (ulong)fd_def_df0); 668 } 669 /* return the ID value */ 670 return (id); 671} 672 673static irqreturn_t fd_block_done(int irq, void *dummy) 674{ 675 if (block_flag) 676 custom.dsklen = 0x4000; 677 678 if (block_flag == 2) { /* writing */ 679 writepending = 2; 680 post_write_timer.expires = jiffies + 1; /* at least 2 ms */ 681 post_write_timer_drive = selected; 682 add_timer(&post_write_timer); 683 } 684 else { /* reading */ 685 block_flag = 0; 686 wake_up (&wait_fd_block); 687 } 688 return IRQ_HANDLED; 689} 690 691static void raw_read(int drive) 692{ 693 drive&=3; 694 get_fdc(drive); 695 wait_event(wait_fd_block, !block_flag); 696 fd_select(drive); 697 /* setup adkcon bits correctly */ 698 custom.adkcon = ADK_MSBSYNC; 699 custom.adkcon = ADK_SETCLR|ADK_WORDSYNC|ADK_FAST; 700 701 custom.dsksync = MFM_SYNC; 702 703 custom.dsklen = 0; 704 custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf); 705 custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN; 706 custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN; 707 708 block_flag = 1; 709 710 wait_event(wait_fd_block, !block_flag); 711 712 custom.dsklen = 0; 713 fd_deselect(drive); 714 rel_fdc(); 715} 716 717static int raw_write(int drive) 718{ 719 ushort adk; 720 721 drive&=3; 722 get_fdc(drive); /* corresponds to rel_fdc() in post_write() */ 723 if ((ciaa.pra & DSKPROT) == 0) { 724 rel_fdc(); 725 return 0; 726 } 727 wait_event(wait_fd_block, !block_flag); 728 fd_select(drive); 729 /* clear adkcon bits */ 730 custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC; 731 /* set appropriate adkcon bits */ 732 adk = ADK_SETCLR|ADK_FAST; 733 if ((ulong)unit[drive].track >= unit[drive].type->precomp2) 734 adk |= ADK_PRECOMP1; 735 else if ((ulong)unit[drive].track >= unit[drive].type->precomp1) 736 adk |= ADK_PRECOMP0; 737 custom.adkcon = adk; 738 739 custom.dsklen = DSKLEN_WRITE; 740 custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf); 741 custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE; 742 custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE; 743 744 block_flag = 2; 745 return 1; 746} 747 748/* 749 * to be called at least 2ms after the write has finished but before any 750 * other access to the hardware. 751 */ 752static void post_write (unsigned long drive) 753{ 754#ifdef DEBUG 755 printk("post_write for drive %ld\n",drive); 756#endif 757 drive &= 3; 758 custom.dsklen = 0; 759 block_flag = 0; 760 writepending = 0; 761 writefromint = 0; 762 unit[drive].dirty = 0; 763 wake_up(&wait_fd_block); 764 fd_deselect(drive); 765 rel_fdc(); /* corresponds to get_fdc() in raw_write */ 766} 767 768static void post_write_callback(struct timer_list *timer) 769{ 770 post_write(post_write_timer_drive); 771} 772 773/* 774 * The following functions are to convert the block contents into raw data 775 * written to disk and vice versa. 776 * (Add other formats here ;-)) 777 */ 778 779static unsigned long scan_sync(unsigned long raw, unsigned long end) 780{ 781 ushort *ptr = (ushort *)raw, *endp = (ushort *)end; 782 783 while (ptr < endp && *ptr++ != 0x4489) 784 ; 785 if (ptr < endp) { 786 while (*ptr == 0x4489 && ptr < endp) 787 ptr++; 788 return (ulong)ptr; 789 } 790 return 0; 791} 792 793static inline unsigned long checksum(unsigned long *addr, int len) 794{ 795 unsigned long csum = 0; 796 797 len /= sizeof(*addr); 798 while (len-- > 0) 799 csum ^= *addr++; 800 csum = ((csum>>1) & 0x55555555) ^ (csum & 0x55555555); 801 802 return csum; 803} 804 805static unsigned long decode (unsigned long *data, unsigned long *raw, 806 int len) 807{ 808 ulong *odd, *even; 809 810 /* convert length from bytes to longwords */ 811 len >>= 2; 812 odd = raw; 813 even = odd + len; 814 815 /* prepare return pointer */ 816 raw += len * 2; 817 818 do { 819 *data++ = ((*odd++ & 0x55555555) << 1) | (*even++ & 0x55555555); 820 } while (--len != 0); 821 822 return (ulong)raw; 823} 824 825struct header { 826 unsigned char magic; 827 unsigned char track; 828 unsigned char sect; 829 unsigned char ord; 830 unsigned char labels[16]; 831 unsigned long hdrchk; 832 unsigned long datachk; 833}; 834 835static int amiga_read(int drive) 836{ 837 unsigned long raw; 838 unsigned long end; 839 int scnt; 840 unsigned long csum; 841 struct header hdr; 842 843 drive&=3; 844 raw = (long) raw_buf; 845 end = raw + unit[drive].type->read_size; 846 847 for (scnt = 0;scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) { 848 if (!(raw = scan_sync(raw, end))) { 849 printk (KERN_INFO "can't find sync for sector %d\n", scnt); 850 return MFM_NOSYNC; 851 } 852 853 raw = decode ((ulong *)&hdr.magic, (ulong *)raw, 4); 854 raw = decode ((ulong *)&hdr.labels, (ulong *)raw, 16); 855 raw = decode ((ulong *)&hdr.hdrchk, (ulong *)raw, 4); 856 raw = decode ((ulong *)&hdr.datachk, (ulong *)raw, 4); 857 csum = checksum((ulong *)&hdr, 858 (char *)&hdr.hdrchk-(char *)&hdr); 859 860#ifdef DEBUG 861 printk ("(%x,%d,%d,%d) (%lx,%lx,%lx,%lx) %lx %lx\n", 862 hdr.magic, hdr.track, hdr.sect, hdr.ord, 863 *(ulong *)&hdr.labels[0], *(ulong *)&hdr.labels[4], 864 *(ulong *)&hdr.labels[8], *(ulong *)&hdr.labels[12], 865 hdr.hdrchk, hdr.datachk); 866#endif 867 868 if (hdr.hdrchk != csum) { 869 printk(KERN_INFO "MFM_HEADER: %08lx,%08lx\n", hdr.hdrchk, csum); 870 return MFM_HEADER; 871 } 872 873 /* verify track */ 874 if (hdr.track != unit[drive].track) { 875 printk(KERN_INFO "MFM_TRACK: %d, %d\n", hdr.track, unit[drive].track); 876 return MFM_TRACK; 877 } 878 879 raw = decode ((ulong *)(unit[drive].trackbuf + hdr.sect*512), 880 (ulong *)raw, 512); 881 csum = checksum((ulong *)(unit[drive].trackbuf + hdr.sect*512), 512); 882 883 if (hdr.datachk != csum) { 884 printk(KERN_INFO "MFM_DATA: (%x:%d:%d:%d) sc=%d %lx, %lx\n", 885 hdr.magic, hdr.track, hdr.sect, hdr.ord, scnt, 886 hdr.datachk, csum); 887 printk (KERN_INFO "data=(%lx,%lx,%lx,%lx)\n", 888 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[0], 889 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[1], 890 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[2], 891 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[3]); 892 return MFM_DATA; 893 } 894 } 895 896 return 0; 897} 898 899static void encode(unsigned long data, unsigned long *dest) 900{ 901 unsigned long data2; 902 903 data &= 0x55555555; 904 data2 = data ^ 0x55555555; 905 data |= ((data2 >> 1) | 0x80000000) & (data2 << 1); 906 907 if (*(dest - 1) & 0x00000001) 908 data &= 0x7FFFFFFF; 909 910 *dest = data; 911} 912 913static void encode_block(unsigned long *dest, unsigned long *src, int len) 914{ 915 int cnt, to_cnt = 0; 916 unsigned long data; 917 918 /* odd bits */ 919 for (cnt = 0; cnt < len / 4; cnt++) { 920 data = src[cnt] >> 1; 921 encode(data, dest + to_cnt++); 922 } 923 924 /* even bits */ 925 for (cnt = 0; cnt < len / 4; cnt++) { 926 data = src[cnt]; 927 encode(data, dest + to_cnt++); 928 } 929} 930 931static unsigned long *putsec(int disk, unsigned long *raw, int cnt) 932{ 933 struct header hdr; 934 int i; 935 936 disk&=3; 937 *raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA; 938 raw++; 939 *raw++ = 0x44894489; 940 941 hdr.magic = 0xFF; 942 hdr.track = unit[disk].track; 943 hdr.sect = cnt; 944 hdr.ord = unit[disk].dtype->sects * unit[disk].type->sect_mult - cnt; 945 for (i = 0; i < 16; i++) 946 hdr.labels[i] = 0; 947 hdr.hdrchk = checksum((ulong *)&hdr, 948 (char *)&hdr.hdrchk-(char *)&hdr); 949 hdr.datachk = checksum((ulong *)(unit[disk].trackbuf+cnt*512), 512); 950 951 encode_block(raw, (ulong *)&hdr.magic, 4); 952 raw += 2; 953 encode_block(raw, (ulong *)&hdr.labels, 16); 954 raw += 8; 955 encode_block(raw, (ulong *)&hdr.hdrchk, 4); 956 raw += 2; 957 encode_block(raw, (ulong *)&hdr.datachk, 4); 958 raw += 2; 959 encode_block(raw, (ulong *)(unit[disk].trackbuf+cnt*512), 512); 960 raw += 256; 961 962 return raw; 963} 964 965static void amiga_write(int disk) 966{ 967 unsigned int cnt; 968 unsigned long *ptr = (unsigned long *)raw_buf; 969 970 disk&=3; 971 /* gap space */ 972 for (cnt = 0; cnt < 415 * unit[disk].type->sect_mult; cnt++) 973 *ptr++ = 0xaaaaaaaa; 974 975 /* sectors */ 976 for (cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++) 977 ptr = putsec (disk, ptr, cnt); 978 *(ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8; 979} 980 981 982struct dos_header { 983 unsigned char track, /* 0-80 */ 984 side, /* 0-1 */ 985 sec, /* 0-...*/ 986 len_desc;/* 2 */ 987 unsigned short crc; /* on 68000 we got an alignment problem, 988 but this compiler solves it by adding silently 989 adding a pad byte so data won't fit 990 and this took about 3h to discover.... */ 991 unsigned char gap1[22]; /* for longword-alignedness (0x4e) */ 992}; 993 994/* crc routines are borrowed from the messydos-handler */ 995 996/* excerpt from the messydos-device 997; The CRC is computed not only over the actual data, but including 998; the SYNC mark (3 * $a1) and the 'ID/DATA - Address Mark' ($fe/$fb). 999; As we don't read or encode these fields into our buffers, we have to 1000; preload the registers containing the CRC with the values they would have 1001; after stepping over these fields. 1002; 1003; How CRCs "really" work: 1004; 1005; First, you should regard a bitstring as a series of coefficients of 1006; polynomials. We calculate with these polynomials in modulo-2 1007; arithmetic, in which both add and subtract are done the same as 1008; exclusive-or. Now, we modify our data (a very long polynomial) in 1009; such a way that it becomes divisible by the CCITT-standard 16-bit 1010; 16 12 5 1011; polynomial: x + x + x + 1, represented by $11021. The easiest 1012; way to do this would be to multiply (using proper arithmetic) our 1013; datablock with $11021. So we have: 1014; data * $11021 = 1015; data * ($10000 + $1021) = 1016; data * $10000 + data * $1021 1017; The left part of this is simple: Just add two 0 bytes. But then 1018; the right part (data $1021) remains difficult and even could have 1019; a carry into the left part. The solution is to use a modified 1020; multiplication, which has a result that is not correct, but with 1021; a difference of any multiple of $11021. We then only need to keep 1022; the 16 least significant bits of the result. 1023; 1024; The following algorithm does this for us: 1025; 1026; unsigned char *data, c, crclo, crchi; 1027; while (not done) { 1028; c = *data++ + crchi; 1029; crchi = (@ c) >> 8 + crclo; 1030; crclo = @ c; 1031; } 1032; 1033; Remember, + is done with EOR, the @ operator is in two tables (high 1034; and low byte separately), which is calculated as 1035; 1036; $1021 * (c & $F0) 1037; xor $1021 * (c & $0F) 1038; xor $1021 * (c >> 4) (* is regular multiplication) 1039; 1040; 1041; Anyway, the end result is the same as the remainder of the division of 1042; the data by $11021. I am afraid I need to study theory a bit more... 1043 1044 1045my only works was to code this from manx to C.... 1046 1047*/ 1048 1049static ushort dos_crc(void * data_a3, int data_d0, int data_d1, int data_d3) 1050{ 1051 static unsigned char CRCTable1[] = { 1052 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x81,0x91,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1, 1053 0x12,0x02,0x32,0x22,0x52,0x42,0x72,0x62,0x93,0x83,0xb3,0xa3,0xd3,0xc3,0xf3,0xe3, 1054 0x24,0x34,0x04,0x14,0x64,0x74,0x44,0x54,0xa5,0xb5,0x85,0x95,0xe5,0xf5,0xc5,0xd5, 1055 0x36,0x26,0x16,0x06,0x76,0x66,0x56,0x46,0xb7,0xa7,0x97,0x87,0xf7,0xe7,0xd7,0xc7, 1056 0x48,0x58,0x68,0x78,0x08,0x18,0x28,0x38,0xc9,0xd9,0xe9,0xf9,0x89,0x99,0xa9,0xb9, 1057 0x5a,0x4a,0x7a,0x6a,0x1a,0x0a,0x3a,0x2a,0xdb,0xcb,0xfb,0xeb,0x9b,0x8b,0xbb,0xab, 1058 0x6c,0x7c,0x4c,0x5c,0x2c,0x3c,0x0c,0x1c,0xed,0xfd,0xcd,0xdd,0xad,0xbd,0x8d,0x9d, 1059 0x7e,0x6e,0x5e,0x4e,0x3e,0x2e,0x1e,0x0e,0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f, 1060 0x91,0x81,0xb1,0xa1,0xd1,0xc1,0xf1,0xe1,0x10,0x00,0x30,0x20,0x50,0x40,0x70,0x60, 1061 0x83,0x93,0xa3,0xb3,0xc3,0xd3,0xe3,0xf3,0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72, 1062 0xb5,0xa5,0x95,0x85,0xf5,0xe5,0xd5,0xc5,0x34,0x24,0x14,0x04,0x74,0x64,0x54,0x44, 1063 0xa7,0xb7,0x87,0x97,0xe7,0xf7,0xc7,0xd7,0x26,0x36,0x06,0x16,0x66,0x76,0x46,0x56, 1064 0xd9,0xc9,0xf9,0xe9,0x99,0x89,0xb9,0xa9,0x58,0x48,0x78,0x68,0x18,0x08,0x38,0x28, 1065 0xcb,0xdb,0xeb,0xfb,0x8b,0x9b,0xab,0xbb,0x4a,0x5a,0x6a,0x7a,0x0a,0x1a,0x2a,0x3a, 1066 0xfd,0xed,0xdd,0xcd,0xbd,0xad,0x9d,0x8d,0x7c,0x6c,0x5c,0x4c,0x3c,0x2c,0x1c,0x0c, 1067 0xef,0xff,0xcf,0xdf,0xaf,0xbf,0x8f,0x9f,0x6e,0x7e,0x4e,0x5e,0x2e,0x3e,0x0e,0x1e 1068 }; 1069 1070 static unsigned char CRCTable2[] = { 1071 0x00,0x21,0x42,0x63,0x84,0xa5,0xc6,0xe7,0x08,0x29,0x4a,0x6b,0x8c,0xad,0xce,0xef, 1072 0x31,0x10,0x73,0x52,0xb5,0x94,0xf7,0xd6,0x39,0x18,0x7b,0x5a,0xbd,0x9c,0xff,0xde, 1073 0x62,0x43,0x20,0x01,0xe6,0xc7,0xa4,0x85,0x6a,0x4b,0x28,0x09,0xee,0xcf,0xac,0x8d, 1074 0x53,0x72,0x11,0x30,0xd7,0xf6,0x95,0xb4,0x5b,0x7a,0x19,0x38,0xdf,0xfe,0x9d,0xbc, 1075 0xc4,0xe5,0x86,0xa7,0x40,0x61,0x02,0x23,0xcc,0xed,0x8e,0xaf,0x48,0x69,0x0a,0x2b, 1076 0xf5,0xd4,0xb7,0x96,0x71,0x50,0x33,0x12,0xfd,0xdc,0xbf,0x9e,0x79,0x58,0x3b,0x1a, 1077 0xa6,0x87,0xe4,0xc5,0x22,0x03,0x60,0x41,0xae,0x8f,0xec,0xcd,0x2a,0x0b,0x68,0x49, 1078 0x97,0xb6,0xd5,0xf4,0x13,0x32,0x51,0x70,0x9f,0xbe,0xdd,0xfc,0x1b,0x3a,0x59,0x78, 1079 0x88,0xa9,0xca,0xeb,0x0c,0x2d,0x4e,0x6f,0x80,0xa1,0xc2,0xe3,0x04,0x25,0x46,0x67, 1080 0xb9,0x98,0xfb,0xda,0x3d,0x1c,0x7f,0x5e,0xb1,0x90,0xf3,0xd2,0x35,0x14,0x77,0x56, 1081 0xea,0xcb,0xa8,0x89,0x6e,0x4f,0x2c,0x0d,0xe2,0xc3,0xa0,0x81,0x66,0x47,0x24,0x05, 1082 0xdb,0xfa,0x99,0xb8,0x5f,0x7e,0x1d,0x3c,0xd3,0xf2,0x91,0xb0,0x57,0x76,0x15,0x34, 1083 0x4c,0x6d,0x0e,0x2f,0xc8,0xe9,0x8a,0xab,0x44,0x65,0x06,0x27,0xc0,0xe1,0x82,0xa3, 1084 0x7d,0x5c,0x3f,0x1e,0xf9,0xd8,0xbb,0x9a,0x75,0x54,0x37,0x16,0xf1,0xd0,0xb3,0x92, 1085 0x2e,0x0f,0x6c,0x4d,0xaa,0x8b,0xe8,0xc9,0x26,0x07,0x64,0x45,0xa2,0x83,0xe0,0xc1, 1086 0x1f,0x3e,0x5d,0x7c,0x9b,0xba,0xd9,0xf8,0x17,0x36,0x55,0x74,0x93,0xb2,0xd1,0xf0 1087 }; 1088 1089/* look at the asm-code - what looks in C a bit strange is almost as good as handmade */ 1090 register int i; 1091 register unsigned char *CRCT1, *CRCT2, *data, c, crch, crcl; 1092 1093 CRCT1=CRCTable1; 1094 CRCT2=CRCTable2; 1095 data=data_a3; 1096 crcl=data_d1; 1097 crch=data_d0; 1098 for (i=data_d3; i>=0; i--) { 1099 c = (*data++) ^ crch; 1100 crch = CRCT1[c] ^ crcl; 1101 crcl = CRCT2[c]; 1102 } 1103 return (crch<<8)|crcl; 1104} 1105 1106static inline ushort dos_hdr_crc (struct dos_header *hdr) 1107{ 1108 return dos_crc(&(hdr->track), 0xb2, 0x30, 3); /* precomputed magic */ 1109} 1110 1111static inline ushort dos_data_crc(unsigned char *data) 1112{ 1113 return dos_crc(data, 0xe2, 0x95 ,511); /* precomputed magic */ 1114} 1115 1116static inline unsigned char dos_decode_byte(ushort word) 1117{ 1118 register ushort w2; 1119 register unsigned char byte; 1120 register unsigned char *dec = mfmdecode; 1121 1122 w2=word; 1123 w2>>=8; 1124 w2&=127; 1125 byte = dec[w2]; 1126 byte <<= 4; 1127 w2 = word & 127; 1128 byte |= dec[w2]; 1129 return byte; 1130} 1131 1132static unsigned long dos_decode(unsigned char *data, unsigned short *raw, int len) 1133{ 1134 int i; 1135 1136 for (i = 0; i < len; i++) 1137 *data++=dos_decode_byte(*raw++); 1138 return ((ulong)raw); 1139} 1140 1141#ifdef DEBUG 1142static void dbg(unsigned long ptr) 1143{ 1144 printk("raw data @%08lx: %08lx, %08lx ,%08lx, %08lx\n", ptr, 1145 ((ulong *)ptr)[0], ((ulong *)ptr)[1], 1146 ((ulong *)ptr)[2], ((ulong *)ptr)[3]); 1147} 1148#endif 1149 1150static int dos_read(int drive) 1151{ 1152 unsigned long end; 1153 unsigned long raw; 1154 int scnt; 1155 unsigned short crc,data_crc[2]; 1156 struct dos_header hdr; 1157 1158 drive&=3; 1159 raw = (long) raw_buf; 1160 end = raw + unit[drive].type->read_size; 1161 1162 for (scnt=0; scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) { 1163 do { /* search for the right sync of each sec-hdr */ 1164 if (!(raw = scan_sync (raw, end))) { 1165 printk(KERN_INFO "dos_read: no hdr sync on " 1166 "track %d, unit %d for sector %d\n", 1167 unit[drive].track,drive,scnt); 1168 return MFM_NOSYNC; 1169 } 1170#ifdef DEBUG 1171 dbg(raw); 1172#endif 1173 } while (*((ushort *)raw)!=0x5554); /* loop usually only once done */ 1174 raw+=2; /* skip over headermark */ 1175 raw = dos_decode((unsigned char *)&hdr,(ushort *) raw,8); 1176 crc = dos_hdr_crc(&hdr); 1177 1178#ifdef DEBUG 1179 printk("(%3d,%d,%2d,%d) %x\n", hdr.track, hdr.side, 1180 hdr.sec, hdr.len_desc, hdr.crc); 1181#endif 1182 1183 if (crc != hdr.crc) { 1184 printk(KERN_INFO "dos_read: MFM_HEADER %04x,%04x\n", 1185 hdr.crc, crc); 1186 return MFM_HEADER; 1187 } 1188 if (hdr.track != unit[drive].track/unit[drive].type->heads) { 1189 printk(KERN_INFO "dos_read: MFM_TRACK %d, %d\n", 1190 hdr.track, 1191 unit[drive].track/unit[drive].type->heads); 1192 return MFM_TRACK; 1193 } 1194 1195 if (hdr.side != unit[drive].track%unit[drive].type->heads) { 1196 printk(KERN_INFO "dos_read: MFM_SIDE %d, %d\n", 1197 hdr.side, 1198 unit[drive].track%unit[drive].type->heads); 1199 return MFM_TRACK; 1200 } 1201 1202 if (hdr.len_desc != 2) { 1203 printk(KERN_INFO "dos_read: unknown sector len " 1204 "descriptor %d\n", hdr.len_desc); 1205 return MFM_DATA; 1206 } 1207#ifdef DEBUG 1208 printk("hdr accepted\n"); 1209#endif 1210 if (!(raw = scan_sync (raw, end))) { 1211 printk(KERN_INFO "dos_read: no data sync on track " 1212 "%d, unit %d for sector%d, disk sector %d\n", 1213 unit[drive].track, drive, scnt, hdr.sec); 1214 return MFM_NOSYNC; 1215 } 1216#ifdef DEBUG 1217 dbg(raw); 1218#endif 1219 1220 if (*((ushort *)raw)!=0x5545) { 1221 printk(KERN_INFO "dos_read: no data mark after " 1222 "sync (%d,%d,%d,%d) sc=%d\n", 1223 hdr.track,hdr.side,hdr.sec,hdr.len_desc,scnt); 1224 return MFM_NOSYNC; 1225 } 1226 1227 raw+=2; /* skip data mark (included in checksum) */ 1228 raw = dos_decode((unsigned char *)(unit[drive].trackbuf + (hdr.sec - 1) * 512), (ushort *) raw, 512); 1229 raw = dos_decode((unsigned char *)data_crc,(ushort *) raw,4); 1230 crc = dos_data_crc(unit[drive].trackbuf + (hdr.sec - 1) * 512); 1231 1232 if (crc != data_crc[0]) { 1233 printk(KERN_INFO "dos_read: MFM_DATA (%d,%d,%d,%d) " 1234 "sc=%d, %x %x\n", hdr.track, hdr.side, 1235 hdr.sec, hdr.len_desc, scnt,data_crc[0], crc); 1236 printk(KERN_INFO "data=(%lx,%lx,%lx,%lx,...)\n", 1237 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[0], 1238 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[1], 1239 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[2], 1240 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[3]); 1241 return MFM_DATA; 1242 } 1243 } 1244 return 0; 1245} 1246 1247static inline ushort dos_encode_byte(unsigned char byte) 1248{ 1249 register unsigned char *enc, b2, b1; 1250 register ushort word; 1251 1252 enc=mfmencode; 1253 b1=byte; 1254 b2=b1>>4; 1255 b1&=15; 1256 word=enc[b2] <<8 | enc [b1]; 1257 return (word|((word&(256|64)) ? 0: 128)); 1258} 1259 1260static void dos_encode_block(ushort *dest, unsigned char *src, int len) 1261{ 1262 int i; 1263 1264 for (i = 0; i < len; i++) { 1265 *dest=dos_encode_byte(*src++); 1266 *dest|=((dest[-1]&1)||(*dest&0x4000))? 0: 0x8000; 1267 dest++; 1268 } 1269} 1270 1271static unsigned long *ms_putsec(int drive, unsigned long *raw, int cnt) 1272{ 1273 static struct dos_header hdr={0,0,0,2,0, 1274 {78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78}}; 1275 int i; 1276 static ushort crc[2]={0,0x4e4e}; 1277 1278 drive&=3; 1279/* id gap 1 */ 1280/* the MFM word before is always 9254 */ 1281 for(i=0;i<6;i++) 1282 *raw++=0xaaaaaaaa; 1283/* 3 sync + 1 headermark */ 1284 *raw++=0x44894489; 1285 *raw++=0x44895554; 1286 1287/* fill in the variable parts of the header */ 1288 hdr.track=unit[drive].track/unit[drive].type->heads; 1289 hdr.side=unit[drive].track%unit[drive].type->heads; 1290 hdr.sec=cnt+1; 1291 hdr.crc=dos_hdr_crc(&hdr); 1292 1293/* header (without "magic") and id gap 2*/ 1294 dos_encode_block((ushort *)raw,(unsigned char *) &hdr.track,28); 1295 raw+=14; 1296 1297/*id gap 3 */ 1298 for(i=0;i<6;i++) 1299 *raw++=0xaaaaaaaa; 1300 1301/* 3 syncs and 1 datamark */ 1302 *raw++=0x44894489; 1303 *raw++=0x44895545; 1304 1305/* data */ 1306 dos_encode_block((ushort *)raw, 1307 (unsigned char *)unit[drive].trackbuf+cnt*512,512); 1308 raw+=256; 1309 1310/*data crc + jd's special gap (long words :-/) */ 1311 crc[0]=dos_data_crc(unit[drive].trackbuf+cnt*512); 1312 dos_encode_block((ushort *) raw,(unsigned char *)crc,4); 1313 raw+=2; 1314 1315/* data gap */ 1316 for(i=0;i<38;i++) 1317 *raw++=0x92549254; 1318 1319 return raw; /* wrote 652 MFM words */ 1320} 1321 1322static void dos_write(int disk) 1323{ 1324 int cnt; 1325 unsigned long raw = (unsigned long) raw_buf; 1326 unsigned long *ptr=(unsigned long *)raw; 1327 1328 disk&=3; 1329/* really gap4 + indexgap , but we write it first and round it up */ 1330 for (cnt=0;cnt<425;cnt++) 1331 *ptr++=0x92549254; 1332 1333/* the following is just guessed */ 1334 if (unit[disk].type->sect_mult==2) /* check for HD-Disks */ 1335 for(cnt=0;cnt<473;cnt++) 1336 *ptr++=0x92549254; 1337 1338/* now the index marks...*/ 1339 for (cnt=0;cnt<20;cnt++) 1340 *ptr++=0x92549254; 1341 for (cnt=0;cnt<6;cnt++) 1342 *ptr++=0xaaaaaaaa; 1343 *ptr++=0x52245224; 1344 *ptr++=0x52245552; 1345 for (cnt=0;cnt<20;cnt++) 1346 *ptr++=0x92549254; 1347 1348/* sectors */ 1349 for(cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++) 1350 ptr=ms_putsec(disk,ptr,cnt); 1351 1352 *(ushort *)ptr = 0xaaa8; /* MFM word before is always 0x9254 */ 1353} 1354 1355/* 1356 * Here comes the high level stuff (i.e. the filesystem interface) 1357 * and helper functions. 1358 * Normally this should be the only part that has to be adapted to 1359 * different kernel versions. 1360 */ 1361 1362/* FIXME: this assumes the drive is still spinning - 1363 * which is only true if we complete writing a track within three seconds 1364 */ 1365static void flush_track_callback(struct timer_list *timer) 1366{ 1367 unsigned long nr = ((unsigned long)timer - 1368 (unsigned long)&flush_track_timer[0]) / 1369 sizeof(flush_track_timer[0]); 1370 1371 nr&=3; 1372 writefromint = 1; 1373 if (!try_fdc(nr)) { 1374 /* we might block in an interrupt, so try again later */ 1375 flush_track_timer[nr].expires = jiffies + 1; 1376 add_timer(flush_track_timer + nr); 1377 return; 1378 } 1379 get_fdc(nr); 1380 (*unit[nr].dtype->write_fkt)(nr); 1381 if (!raw_write(nr)) { 1382 printk (KERN_NOTICE "floppy disk write protected\n"); 1383 writefromint = 0; 1384 writepending = 0; 1385 } 1386 rel_fdc(); 1387} 1388 1389static int non_int_flush_track (unsigned long nr) 1390{ 1391 unsigned long flags; 1392 1393 nr&=3; 1394 writefromint = 0; 1395 del_timer(&post_write_timer); 1396 get_fdc(nr); 1397 if (!fd_motor_on(nr)) { 1398 writepending = 0; 1399 rel_fdc(); 1400 return 0; 1401 } 1402 local_irq_save(flags); 1403 if (writepending != 2) { 1404 local_irq_restore(flags); 1405 (*unit[nr].dtype->write_fkt)(nr); 1406 if (!raw_write(nr)) { 1407 printk (KERN_NOTICE "floppy disk write protected " 1408 "in write!\n"); 1409 writepending = 0; 1410 return 0; 1411 } 1412 wait_event(wait_fd_block, block_flag != 2); 1413 } 1414 else { 1415 local_irq_restore(flags); 1416 ms_delay(2); /* 2 ms post_write delay */ 1417 post_write(nr); 1418 } 1419 rel_fdc(); 1420 return 1; 1421} 1422 1423static int get_track(int drive, int track) 1424{ 1425 int error, errcnt; 1426 1427 drive&=3; 1428 if (unit[drive].track == track) 1429 return 0; 1430 get_fdc(drive); 1431 if (!fd_motor_on(drive)) { 1432 rel_fdc(); 1433 return -1; 1434 } 1435 1436 if (unit[drive].dirty == 1) { 1437 del_timer (flush_track_timer + drive); 1438 non_int_flush_track (drive); 1439 } 1440 errcnt = 0; 1441 while (errcnt < MAX_ERRORS) { 1442 if (!fd_seek(drive, track)) 1443 return -1; 1444 raw_read(drive); 1445 error = (*unit[drive].dtype->read_fkt)(drive); 1446 if (error == 0) { 1447 rel_fdc(); 1448 return 0; 1449 } 1450 /* Read Error Handling: recalibrate and try again */ 1451 unit[drive].track = -1; 1452 errcnt++; 1453 } 1454 rel_fdc(); 1455 return -1; 1456} 1457 1458static blk_status_t amiflop_rw_cur_segment(struct amiga_floppy_struct *floppy, 1459 struct request *rq) 1460{ 1461 int drive = floppy - unit; 1462 unsigned int cnt, block, track, sector; 1463 char *data; 1464 1465 for (cnt = 0; cnt < blk_rq_cur_sectors(rq); cnt++) { 1466#ifdef DEBUG 1467 printk("fd: sector %ld + %d requested for %s\n", 1468 blk_rq_pos(rq), cnt, 1469 (rq_data_dir(rq) == READ) ? "read" : "write"); 1470#endif 1471 block = blk_rq_pos(rq) + cnt; 1472 track = block / (floppy->dtype->sects * floppy->type->sect_mult); 1473 sector = block % (floppy->dtype->sects * floppy->type->sect_mult); 1474 data = bio_data(rq->bio) + 512 * cnt; 1475#ifdef DEBUG 1476 printk("access to track %d, sector %d, with buffer at " 1477 "0x%08lx\n", track, sector, data); 1478#endif 1479 1480 if (get_track(drive, track) == -1) 1481 return BLK_STS_IOERR; 1482 1483 if (rq_data_dir(rq) == READ) { 1484 memcpy(data, floppy->trackbuf + sector * 512, 512); 1485 } else { 1486 memcpy(floppy->trackbuf + sector * 512, data, 512); 1487 1488 /* keep the drive spinning while writes are scheduled */ 1489 if (!fd_motor_on(drive)) 1490 return BLK_STS_IOERR; 1491 /* 1492 * setup a callback to write the track buffer 1493 * after a short (1 tick) delay. 1494 */ 1495 floppy->dirty = 1; 1496 /* reset the timer */ 1497 mod_timer (flush_track_timer + drive, jiffies + 1); 1498 } 1499 } 1500 1501 return BLK_STS_OK; 1502} 1503 1504static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx, 1505 const struct blk_mq_queue_data *bd) 1506{ 1507 struct request *rq = bd->rq; 1508 struct amiga_floppy_struct *floppy = rq->q->disk->private_data; 1509 blk_status_t err; 1510 1511 if (!spin_trylock_irq(&amiflop_lock)) 1512 return BLK_STS_DEV_RESOURCE; 1513 1514 blk_mq_start_request(rq); 1515 1516 do { 1517 err = amiflop_rw_cur_segment(floppy, rq); 1518 } while (blk_update_request(rq, err, blk_rq_cur_bytes(rq))); 1519 blk_mq_end_request(rq, err); 1520 1521 spin_unlock_irq(&amiflop_lock); 1522 return BLK_STS_OK; 1523} 1524 1525static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) 1526{ 1527 int drive = MINOR(bdev->bd_dev) & 3; 1528 1529 geo->heads = unit[drive].type->heads; 1530 geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult; 1531 geo->cylinders = unit[drive].type->tracks; 1532 return 0; 1533} 1534 1535static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, 1536 unsigned int cmd, unsigned long param) 1537{ 1538 struct amiga_floppy_struct *p = bdev->bd_disk->private_data; 1539 int drive = p - unit; 1540 static struct floppy_struct getprm; 1541 void __user *argp = (void __user *)param; 1542 1543 switch(cmd){ 1544 case FDFMTBEG: 1545 get_fdc(drive); 1546 if (fd_ref[drive] > 1) { 1547 rel_fdc(); 1548 return -EBUSY; 1549 } 1550 fsync_bdev(bdev); 1551 if (fd_motor_on(drive) == 0) { 1552 rel_fdc(); 1553 return -ENODEV; 1554 } 1555 if (fd_calibrate(drive) == 0) { 1556 rel_fdc(); 1557 return -ENXIO; 1558 } 1559 floppy_off(drive); 1560 rel_fdc(); 1561 break; 1562 case FDFMTTRK: 1563 if (param < p->type->tracks * p->type->heads) 1564 { 1565 get_fdc(drive); 1566 if (fd_seek(drive,param) != 0){ 1567 memset(p->trackbuf, FD_FILL_BYTE, 1568 p->dtype->sects * p->type->sect_mult * 512); 1569 non_int_flush_track(drive); 1570 } 1571 floppy_off(drive); 1572 rel_fdc(); 1573 } 1574 else 1575 return -EINVAL; 1576 break; 1577 case FDFMTEND: 1578 floppy_off(drive); 1579 invalidate_bdev(bdev); 1580 break; 1581 case FDGETPRM: 1582 memset((void *)&getprm, 0, sizeof (getprm)); 1583 getprm.track=p->type->tracks; 1584 getprm.head=p->type->heads; 1585 getprm.sect=p->dtype->sects * p->type->sect_mult; 1586 getprm.size=p->blocks; 1587 if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct))) 1588 return -EFAULT; 1589 break; 1590 case FDSETPRM: 1591 case FDDEFPRM: 1592 return -EINVAL; 1593 case FDFLUSH: /* unconditionally, even if not needed */ 1594 del_timer (flush_track_timer + drive); 1595 non_int_flush_track(drive); 1596 break; 1597#ifdef RAW_IOCTL 1598 case IOCTL_RAW_TRACK: 1599 if (copy_to_user(argp, raw_buf, p->type->read_size)) 1600 return -EFAULT; 1601 else 1602 return p->type->read_size; 1603#endif 1604 default: 1605 return -ENOSYS; 1606 } 1607 return 0; 1608} 1609 1610static int fd_ioctl(struct block_device *bdev, fmode_t mode, 1611 unsigned int cmd, unsigned long param) 1612{ 1613 int ret; 1614 1615 mutex_lock(&amiflop_mutex); 1616 ret = fd_locked_ioctl(bdev, mode, cmd, param); 1617 mutex_unlock(&amiflop_mutex); 1618 1619 return ret; 1620} 1621 1622static void fd_probe(int dev) 1623{ 1624 unsigned long code; 1625 int type; 1626 int drive; 1627 1628 drive = dev & 3; 1629 code = fd_get_drive_id(drive); 1630 1631 /* get drive type */ 1632 for (type = 0; type < num_dr_types; type++) 1633 if (drive_types[type].code == code) 1634 break; 1635 1636 if (type >= num_dr_types) { 1637 printk(KERN_WARNING "fd_probe: unsupported drive type " 1638 "%08lx found\n", code); 1639 unit[drive].type = &drive_types[num_dr_types-1]; /* FD_NODRIVE */ 1640 return; 1641 } 1642 1643 unit[drive].type = drive_types + type; 1644 unit[drive].track = -1; 1645 1646 unit[drive].disk = -1; 1647 unit[drive].motor = 0; 1648 unit[drive].busy = 0; 1649 unit[drive].status = -1; 1650} 1651 1652/* 1653 * floppy_open check for aliasing (/dev/fd0 can be the same as 1654 * /dev/PS0 etc), and disallows simultaneous access to the same 1655 * drive with different device numbers. 1656 */ 1657static int floppy_open(struct block_device *bdev, fmode_t mode) 1658{ 1659 int drive = MINOR(bdev->bd_dev) & 3; 1660 int system = (MINOR(bdev->bd_dev) & 4) >> 2; 1661 int old_dev; 1662 unsigned long flags; 1663 1664 mutex_lock(&amiflop_mutex); 1665 old_dev = fd_device[drive]; 1666 1667 if (fd_ref[drive] && old_dev != system) { 1668 mutex_unlock(&amiflop_mutex); 1669 return -EBUSY; 1670 } 1671 1672 if (unit[drive].type->code == FD_NODRIVE) { 1673 mutex_unlock(&amiflop_mutex); 1674 return -ENXIO; 1675 } 1676 1677 if (mode & (FMODE_READ|FMODE_WRITE)) { 1678 bdev_check_media_change(bdev); 1679 if (mode & FMODE_WRITE) { 1680 int wrprot; 1681 1682 get_fdc(drive); 1683 fd_select (drive); 1684 wrprot = !(ciaa.pra & DSKPROT); 1685 fd_deselect (drive); 1686 rel_fdc(); 1687 1688 if (wrprot) { 1689 mutex_unlock(&amiflop_mutex); 1690 return -EROFS; 1691 } 1692 } 1693 } 1694 1695 local_irq_save(flags); 1696 fd_ref[drive]++; 1697 fd_device[drive] = system; 1698 local_irq_restore(flags); 1699 1700 unit[drive].dtype=&data_types[system]; 1701 unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks* 1702 data_types[system].sects*unit[drive].type->sect_mult; 1703 set_capacity(unit[drive].gendisk[system], unit[drive].blocks); 1704 1705 printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive, 1706 unit[drive].type->name, data_types[system].name); 1707 1708 mutex_unlock(&amiflop_mutex); 1709 return 0; 1710} 1711 1712static void floppy_release(struct gendisk *disk, fmode_t mode) 1713{ 1714 struct amiga_floppy_struct *p = disk->private_data; 1715 int drive = p - unit; 1716 1717 mutex_lock(&amiflop_mutex); 1718 if (unit[drive].dirty == 1) { 1719 del_timer (flush_track_timer + drive); 1720 non_int_flush_track (drive); 1721 } 1722 1723 if (!fd_ref[drive]--) { 1724 printk(KERN_CRIT "floppy_release with fd_ref == 0"); 1725 fd_ref[drive] = 0; 1726 } 1727#ifdef MODULE 1728 floppy_off (drive); 1729#endif 1730 mutex_unlock(&amiflop_mutex); 1731} 1732 1733/* 1734 * check_events is never called from an interrupt, so we can relax a bit 1735 * here, sleep etc. Note that floppy-on tries to set current_DOR to point 1736 * to the desired drive, but it will probably not survive the sleep if 1737 * several floppies are used at the same time: thus the loop. 1738 */ 1739static unsigned amiga_check_events(struct gendisk *disk, unsigned int clearing) 1740{ 1741 struct amiga_floppy_struct *p = disk->private_data; 1742 int drive = p - unit; 1743 int changed; 1744 static int first_time = 1; 1745 1746 if (first_time) 1747 changed = first_time--; 1748 else { 1749 get_fdc(drive); 1750 fd_select (drive); 1751 changed = !(ciaa.pra & DSKCHANGE); 1752 fd_deselect (drive); 1753 rel_fdc(); 1754 } 1755 1756 if (changed) { 1757 fd_probe(drive); 1758 p->track = -1; 1759 p->dirty = 0; 1760 writepending = 0; /* if this was true before, too bad! */ 1761 writefromint = 0; 1762 return DISK_EVENT_MEDIA_CHANGE; 1763 } 1764 return 0; 1765} 1766 1767static const struct block_device_operations floppy_fops = { 1768 .owner = THIS_MODULE, 1769 .open = floppy_open, 1770 .release = floppy_release, 1771 .ioctl = fd_ioctl, 1772 .getgeo = fd_getgeo, 1773 .check_events = amiga_check_events, 1774}; 1775 1776static const struct blk_mq_ops amiflop_mq_ops = { 1777 .queue_rq = amiflop_queue_rq, 1778}; 1779 1780static int fd_alloc_disk(int drive, int system) 1781{ 1782 struct gendisk *disk; 1783 int err; 1784 1785 disk = blk_mq_alloc_disk(&unit[drive].tag_set, NULL); 1786 if (IS_ERR(disk)) 1787 return PTR_ERR(disk); 1788 1789 disk->major = FLOPPY_MAJOR; 1790 disk->first_minor = drive + system; 1791 disk->minors = 1; 1792 disk->fops = &floppy_fops; 1793 disk->flags |= GENHD_FL_NO_PART; 1794 disk->events = DISK_EVENT_MEDIA_CHANGE; 1795 if (system) 1796 sprintf(disk->disk_name, "fd%d_msdos", drive); 1797 else 1798 sprintf(disk->disk_name, "fd%d", drive); 1799 disk->private_data = &unit[drive]; 1800 set_capacity(disk, 880 * 2); 1801 1802 unit[drive].gendisk[system] = disk; 1803 err = add_disk(disk); 1804 if (err) 1805 blk_cleanup_disk(disk); 1806 return err; 1807} 1808 1809static int fd_alloc_drive(int drive) 1810{ 1811 unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL); 1812 if (!unit[drive].trackbuf) 1813 goto out; 1814 1815 memset(&unit[drive].tag_set, 0, sizeof(unit[drive].tag_set)); 1816 unit[drive].tag_set.ops = &amiflop_mq_ops; 1817 unit[drive].tag_set.nr_hw_queues = 1; 1818 unit[drive].tag_set.nr_maps = 1; 1819 unit[drive].tag_set.queue_depth = 2; 1820 unit[drive].tag_set.numa_node = NUMA_NO_NODE; 1821 unit[drive].tag_set.flags = BLK_MQ_F_SHOULD_MERGE; 1822 if (blk_mq_alloc_tag_set(&unit[drive].tag_set)) 1823 goto out_cleanup_trackbuf; 1824 1825 pr_cont(" fd%d", drive); 1826 1827 if (fd_alloc_disk(drive, 0) || fd_alloc_disk(drive, 1)) 1828 goto out_cleanup_tagset; 1829 return 0; 1830 1831out_cleanup_tagset: 1832 blk_mq_free_tag_set(&unit[drive].tag_set); 1833out_cleanup_trackbuf: 1834 kfree(unit[drive].trackbuf); 1835out: 1836 unit[drive].type->code = FD_NODRIVE; 1837 return -ENOMEM; 1838} 1839 1840static int __init fd_probe_drives(void) 1841{ 1842 int drive,drives,nomem; 1843 1844 pr_info("FD: probing units\nfound"); 1845 drives=0; 1846 nomem=0; 1847 for(drive=0;drive<FD_MAX_UNITS;drive++) { 1848 fd_probe(drive); 1849 if (unit[drive].type->code == FD_NODRIVE) 1850 continue; 1851 1852 if (fd_alloc_drive(drive) < 0) { 1853 pr_cont(" no mem for fd%d", drive); 1854 nomem = 1; 1855 continue; 1856 } 1857 drives++; 1858 } 1859 if ((drives > 0) || (nomem == 0)) { 1860 if (drives == 0) 1861 pr_cont(" no drives"); 1862 pr_cont("\n"); 1863 return drives; 1864 } 1865 pr_cont("\n"); 1866 return -ENOMEM; 1867} 1868 1869static int __init amiga_floppy_probe(struct platform_device *pdev) 1870{ 1871 int i, ret; 1872 1873 if (register_blkdev(FLOPPY_MAJOR,"fd")) 1874 return -EBUSY; 1875 1876 ret = -ENOMEM; 1877 raw_buf = amiga_chip_alloc(RAW_BUF_SIZE, "Floppy"); 1878 if (!raw_buf) { 1879 printk("fd: cannot get chip mem buffer\n"); 1880 goto out_blkdev; 1881 } 1882 1883 ret = -EBUSY; 1884 if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) { 1885 printk("fd: cannot get irq for dma\n"); 1886 goto out_irq; 1887 } 1888 1889 if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) { 1890 printk("fd: cannot get irq for timer\n"); 1891 goto out_irq2; 1892 } 1893 1894 ret = -ENODEV; 1895 if (fd_probe_drives() < 1) /* No usable drives */ 1896 goto out_probe; 1897 1898 /* initialize variables */ 1899 timer_setup(&motor_on_timer, motor_on_callback, 0); 1900 motor_on_timer.expires = 0; 1901 for (i = 0; i < FD_MAX_UNITS; i++) { 1902 timer_setup(&motor_off_timer[i], fd_motor_off, 0); 1903 motor_off_timer[i].expires = 0; 1904 timer_setup(&flush_track_timer[i], flush_track_callback, 0); 1905 flush_track_timer[i].expires = 0; 1906 1907 unit[i].track = -1; 1908 } 1909 1910 timer_setup(&post_write_timer, post_write_callback, 0); 1911 post_write_timer.expires = 0; 1912 1913 for (i = 0; i < 128; i++) 1914 mfmdecode[i]=255; 1915 for (i = 0; i < 16; i++) 1916 mfmdecode[mfmencode[i]]=i; 1917 1918 /* make sure that disk DMA is enabled */ 1919 custom.dmacon = DMAF_SETCLR | DMAF_DISK; 1920 1921 /* init ms timer */ 1922 ciaa.crb = 8; /* one-shot, stop */ 1923 return 0; 1924 1925out_probe: 1926 free_irq(IRQ_AMIGA_CIAA_TB, NULL); 1927out_irq2: 1928 free_irq(IRQ_AMIGA_DSKBLK, NULL); 1929out_irq: 1930 amiga_chip_free(raw_buf); 1931out_blkdev: 1932 unregister_blkdev(FLOPPY_MAJOR,"fd"); 1933 return ret; 1934} 1935 1936static struct platform_driver amiga_floppy_driver = { 1937 .driver = { 1938 .name = "amiga-floppy", 1939 }, 1940}; 1941 1942static int __init amiga_floppy_init(void) 1943{ 1944 return platform_driver_probe(&amiga_floppy_driver, amiga_floppy_probe); 1945} 1946 1947module_init(amiga_floppy_init); 1948 1949#ifndef MODULE 1950static int __init amiga_floppy_setup (char *str) 1951{ 1952 int n; 1953 if (!MACH_IS_AMIGA) 1954 return 0; 1955 if (!get_option(&str, &n)) 1956 return 0; 1957 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n); 1958 fd_def_df0 = n; 1959 return 1; 1960} 1961 1962__setup("floppy=", amiga_floppy_setup); 1963#endif 1964 1965MODULE_ALIAS("platform:amiga-floppy");