1: /* This file contains the device dependent part of the driver for the Floppy 2: * Disk Controller (FDC) using the NEC PD765 chip. 3: * 4: * The file contains two entry points: 5: * 6: * floppy_task: main entry when system is brought up 7: * floppy_stop: stop all activity 8: * 9: * Changes: 10: * 27 Oct. 1986 by Jakob Schripsema: fdc_results fixed for 8 MHz 11: * 28 Nov. 1986 by Peter Kay: better resetting for 386 12: * 06 Jan. 1988 by Al Crew: allow 1.44 MB diskettes 13: * 1989 by Bruce Evans: I/O vector to keep up with 1-1 interleave 14: * 13 May 1991 by Don Chapman: renovated the errors loop. 15: * 1991 by Bruce Evans: len[] / motors / reset / step rate / ... 16: * 14 Feb 1992 by Andy Tanenbaum: check drive density on opens only 17: * 27 Mar 1992 by Kees J. Bot: last details on density checking 18: * 04 Apr 1992 by Kees J. Bot: device dependent/independent split 19: * 14 May 2000 by Kees J. Bot: d-d/i rewrite. 20: * 12 Aug 2003 by Mike Haertel: Null seek no interrupt fix 21: */ 22: 23: #include "kernel.h" 24: #include "driver.h" 25: #include "drvlib.h" 26: #include <ibm/diskparm.h> 27: 28: /* I/O Ports used by floppy disk task. */ 29: #define DOR 0x3F2 /* motor drive control bits */ 30: #define FDC_STATUS 0x3F4 /* floppy disk controller status register */ 31: #define FDC_DATA 0x3F5 /* floppy disk controller data register */ 32: #define FDC_RATE 0x3F7 /* transfer rate register */ 33: #define DMA_ADDR 0x004 /* port for low 16 bits of DMA address */ 34: #define DMA_TOP 0x081 /* port for top 4 bits of 20-bit DMA addr */ 35: #define DMA_COUNT 0x005 /* port for DMA count (count = bytes - 1) */ 36: #define DMA_FLIPFLOP 0x00C /* DMA byte pointer flip-flop */ 37: #define DMA_MODE 0x00B /* DMA mode port */ 38: #define DMA_INIT 0x00A /* DMA init port */ 39: #define DMA_RESET_VAL 0x06 40: 41: /* Status registers returned as result of operation. */ 42: #define ST0 0x00 /* status register 0 */ 43: #define ST1 0x01 /* status register 1 */ 44: #define ST2 0x02 /* status register 2 */ 45: #define ST3 0x00 /* status register 3 (return by DRIVE_SENSE) */ 46: #define ST_CYL 0x03 /* slot where controller reports cylinder */ 47: #define ST_HEAD 0x04 /* slot where controller reports head */ 48: #define ST_SEC 0x05 /* slot where controller reports sector */ 49: #define ST_PCN 0x01 /* slot where controller reports present cyl */ 50: 51: /* Fields within the I/O ports. */ 52: /* Main status register. */ 53: #define CTL_BUSY 0x10 /* bit is set when read or write in progress */ 54: #define DIRECTION 0x40 /* bit is set when reading data reg is valid */ 55: #define MASTER 0x80 /* bit is set when data reg can be accessed */ 56: 57: /* Digital output port (DOR). */ 58: #define MOTOR_SHIFT 4 /* high 4 bits control the motors in DOR */ 59: #define ENABLE_INT 0x0C /* used for setting DOR port */ 60: 61: /* ST0. */ 62: #define ST0_BITS 0xF8 /* check top 5 bits of seek status */ 63: #define TRANS_ST0 0x00 /* top 5 bits of ST0 for READ/WRITE */ 64: #define SEEK_ST0 0x20 /* top 5 bits of ST0 for SEEK */ 65: 66: /* ST1. */ 67: #define BAD_SECTOR 0x05 /* if these bits are set in ST1, recalibrate */ 68: #define WRITE_PROTECT 0x02 /* bit is set if diskette is write protected */ 69: 70: /* ST2. */ 71: #define BAD_CYL 0x1F /* if any of these bits are set, recalibrate */ 72: 73: /* ST3 (not used). */ 74: #define ST3_FAULT 0x80 /* if this bit is set, drive is sick */ 75: #define ST3_WR_PROTECT 0x40 /* set when diskette is write protected */ 76: #define ST3_READY 0x20 /* set when drive is ready */ 77: 78: /* Floppy disk controller command bytes. */ 79: #define FDC_SEEK 0x0F /* command the drive to seek */ 80: #define FDC_READ 0xE6 /* command the drive to read */ 81: #define FDC_WRITE 0xC5 /* command the drive to write */ 82: #define FDC_SENSE 0x08 /* command the controller to tell its status */ 83: #define FDC_RECALIBRATE 0x07 /* command the drive to go to cyl 0 */ 84: #define FDC_SPECIFY 0x03 /* command the drive to accept params */ 85: #define FDC_READ_ID 0x4A /* command the drive to read sector identity */ 86: #define FDC_FORMAT 0x4D /* command the drive to format a track */ 87: 88: /* DMA channel commands. */ 89: #define DMA_READ 0x46 /* DMA read opcode */ 90: #define DMA_WRITE 0x4A /* DMA write opcode */ 91: 92: /* Parameters for the disk drive. */ 93: #define HC_SIZE 2880 /* # sectors on largest legal disk (1.44MB) */ 94: #define NR_HEADS 0x02 /* two heads (i.e., two tracks/cylinder) */ 95: #define MAX_SECTORS 18 /* largest # sectors per track */ 96: #define DTL 0xFF /* determines data length (sector size) */ 97: #define SPEC2 0x02 /* second parameter to SPECIFY */ 98: #define MOTOR_OFF (3*HZ) /* how long to wait before stopping motor */ 99: #define WAKEUP (2*HZ) /* timeout on I/O, FDC won't quit. */ 100: 101: /* Error codes */ 102: #define ERR_SEEK (-1) /* bad seek */ 103: #define ERR_TRANSFER (-2) /* bad transfer */ 104: #define ERR_STATUS (-3) /* something wrong when getting status */ 105: #define ERR_READ_ID (-4) /* bad read id */ 106: #define ERR_RECALIBRATE (-5) /* recalibrate didn't work properly */ 107: #define ERR_DRIVE (-6) /* something wrong with a drive */ 108: #define ERR_WR_PROTECT (-7) /* diskette is write protected */ 109: #define ERR_TIMEOUT (-8) /* interrupt timeout */ 110: 111: /* No retries on some errors. */ 112: #define err_no_retry(err) ((err) <= ERR_WR_PROTECT) 113: 114: /* Encoding of drive type in minor device number. */ 115: #define DEV_TYPE_BITS 0x7C /* drive type + 1, if nonzero */ 116: #define DEV_TYPE_SHIFT 2 /* right shift to normalize type bits */ 117: #define FORMAT_DEV_BIT 0x80 /* bit in minor to turn write into format */ 118: 119: /* Miscellaneous. */ 120: #define MAX_ERRORS 6 /* how often to try rd/wt before quitting */ 121: #define MAX_RESULTS 7 /* max number of bytes controller returns */ 122: #define NR_DRIVES 2 /* maximum number of drives */ 123: #define DIVISOR 128 /* used for sector size encoding */ 124: #define SECTOR_SIZE_CODE 2 /* code to say "512" to the controller */ 125: #define TIMEOUT 500000L /* microseconds waiting for FDC */ 126: #define NT 7 /* number of diskette/drive combinations */ 127: #define UNCALIBRATED 0 /* drive needs to be calibrated at next use */ 128: #define CALIBRATED 1 /* no calibration needed */ 129: #define BASE_SECTOR 1 /* sectors are numbered starting at 1 */ 130: #define NO_SECTOR (-1) /* current sector unknown */ 131: #define NO_CYL (-1) /* current cylinder unknown, must seek */ 132: #define NO_DENS 100 /* current media unknown */ 133: #define BSY_IDLE 0 /* busy doing nothing */ 134: #define BSY_IO 1 /* busy doing I/O */ 135: #define BSY_WAKEN 2 /* got a wakeup call */ 136: 137: /* Seven combinations of diskette/drive are supported. 138: * 139: * # Diskette Drive Sectors Tracks Rotation Data-rate Comment 140: * 0 360K 360K 9 40 300 RPM 250 kbps Standard PC DSDD 141: * 1 1.2M 1.2M 15 80 360 RPM 500 kbps AT disk in AT drive 142: * 2 360K 720K 9 40 300 RPM 250 kbps Quad density PC 143: * 3 720K 720K 9 80 300 RPM 250 kbps Toshiba, et al. 144: * 4 360K 1.2M 9 40 360 RPM 300 kbps PC disk in AT drive 145: * 5 720K 1.2M 9 80 360 RPM 300 kbps Toshiba in AT drive 146: * 6 1.44M 1.44M 18 80 300 RPM 500 kbps PS/2, et al. 147: * 148: * In addition, 720K diskettes can be read in 1.44MB drives, but that does 149: * not need a different set of parameters. This combination uses 150: * 151: * 3 720K 1.44M 9 80 300 RPM 250 kbps PS/2, et al. 152: */ 153: PRIVATE struct density { 154: u8_t secpt; /* sectors per track */ 155: u8_t cyls; /* tracks per side */ 156: u8_t steps; /* steps per cylinder (2 = double step) */ 157: u8_t test; /* sector to try for density test */ 158: u8_t rate; /* data rate (2=250, 1=300, 0=500 kbps) */ 159: u8_t start; /* motor start (clock ticks) */ 160: u8_t gap; /* gap size */ 161: u8_t spec1; /* first specify byte (SRT/HUT) */ 162: } fdensity[NT] = { 163: { 9, 40, 1, 4*9, 2, 4*HZ/8, 0x2A, 0xDF }, /* 360K / 360K */ 164: { 15, 80, 1, 14, 0, 4*HZ/8, 0x1B, 0xDF }, /* 1.2M / 1.2M */ 165: { 9, 40, 2, 2*9, 2, 4*HZ/8, 0x2A, 0xDF }, /* 360K / 720K */ 166: { 9, 80, 1, 4*9, 2, 6*HZ/8, 0x2A, 0xDF }, /* 720K / 720K */ 167: { 9, 40, 2, 2*9, 1, 4*HZ/8, 0x23, 0xDF }, /* 360K / 1.2M */ 168: { 9, 80, 1, 4*9, 1, 4*HZ/8, 0x23, 0xDF }, /* 720K / 1.2M */ 169: { 18, 80, 1, 17, 0, 6*HZ/8, 0x1B, 0xCF }, /* 1.44M / 1.44M */ 170: }; 171: 172: /* The following table is used with the test_sector array to recognize a 173: * drive/floppy combination. The sector to test has been determined by 174: * looking at the differences in gap size, sectors/track, and double stepping. 175: * This means that types 0 and 3 can't be told apart, only the motor start 176: * time differs. If a read test succeeds then the drive is limited to the 177: * set of densities it can support to avoid unnecessary tests in the future. 178: */ 179: 180: #define b(d) (1 << (d)) /* bit for density d. */ 181: 182: PRIVATE struct test_order { 183: u8_t t_density; /* floppy/drive type */ 184: u8_t t_class; /* limit drive to this class of densities */ 185: } test_order[NT-1] = { 186: { 6, b(3) | b(6) }, /* 1.44M {720K, 1.44M} */ 187: { 1, b(1) | b(4) | b(5) }, /* 1.2M {1.2M, 360K, 720K} */ 188: { 3, b(2) | b(3) | b(6) }, /* 720K {360K, 720K, 1.44M} */ 189: { 4, b(1) | b(4) | b(5) }, /* 360K {1.2M, 360K, 720K} */ 190: { 5, b(1) | b(4) | b(5) }, /* 720K {1.2M, 360K, 720K} */ 191: { 2, b(2) | b(3) }, /* 360K {360K, 720K} */ 192: /* Note that type 0 is missing, type 3 can read/write it too, which is 193: * why the type 3 parameters have been pessimized to be like type 0. 194: */ 195: }; 196: 197: /* Variables. */ 198: PRIVATE struct floppy { /* main drive struct, one entry per drive */ 199: unsigned fl_curcyl; /* current cylinder */ 200: unsigned fl_hardcyl; /* hardware cylinder, as opposed to: */ 201: unsigned fl_cylinder; /* cylinder number addressed */ 202: unsigned fl_sector; /* sector addressed */ 203: unsigned fl_head; /* head number addressed */ 204: char fl_calibration; /* CALIBRATED or UNCALIBRATED */ 205: u8_t fl_density; /* NO_DENS = ?, 0 = 360K; 1 = 360K/1.2M; etc.*/ 206: u8_t fl_class; /* bitmap for possible densities */ 207: timer_t fl_tmr_stop; /* timer to stop motor */ 208: struct device fl_geom; /* Geometry of the drive */ 209: struct device fl_part[NR_PARTITIONS]; /* partition's base & size */ 210: } floppy[NR_DRIVES]; 211: 212: PRIVATE int motor_status; /* bitmap of current motor status */ 213: PRIVATE int need_reset; /* set to 1 when controller must be reset */ 214: PRIVATE unsigned f_drive; /* selected drive */ 215: PRIVATE unsigned f_device; /* selected minor device */ 216: PRIVATE struct floppy *f_fp; /* current drive */ 217: PRIVATE struct density *f_dp; /* current density parameters */ 218: PRIVATE struct density *prev_dp;/* previous density parameters */ 219: PRIVATE unsigned f_sectors; /* equal to f_dp->secpt (needed a lot) */ 220: PRIVATE int f_busy; /* BSY_IDLE, BSY_IO, BSY_WAKEN */ 221: PRIVATE irq_hook_t f_hook; /* interrupt hook */ 222: PRIVATE timer_t f_tmr_timeout; /* timer for various timeouts */ 223: PRIVATE struct device *f_dv; /* device's base and size */ 224: PRIVATE struct disk_parameter_s fmt_param; /* parameters for format */ 225: PRIVATE u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */ 226: 227: 228: FORWARD _PROTOTYPE( struct device *f_prepare, (int device) ); 229: FORWARD _PROTOTYPE( char *f_name, (void) ); 230: FORWARD _PROTOTYPE( void f_cleanup, (void) ); 231: FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, off_t position, 232: iovec_t *iov, unsigned nr_req) ); 233: FORWARD _PROTOTYPE( void dma_setup, (int opcode) ); 234: FORWARD _PROTOTYPE( void start_motor, (void) ); 235: FORWARD _PROTOTYPE( void stop_motor, (timer_t *tp) ); 236: FORWARD _PROTOTYPE( int seek, (void) ); 237: FORWARD _PROTOTYPE( int fdc_transfer, (int opcode) ); 238: FORWARD _PROTOTYPE( int fdc_results, (void) ); 239: FORWARD _PROTOTYPE( int f_handler, (irq_hook_t *hook) ); 240: FORWARD _PROTOTYPE( int fdc_command, (u8_t *cmd, int len) ); 241: FORWARD _PROTOTYPE( void fdc_out, (int val) ); 242: FORWARD _PROTOTYPE( int recalibrate, (void) ); 243: FORWARD _PROTOTYPE( void f_reset, (void) ); 244: FORWARD _PROTOTYPE( int f_intr_wait, (void) ); 245: FORWARD _PROTOTYPE( void f_timeout, (timer_t *tp) ); 246: FORWARD _PROTOTYPE( int read_id, (void) ); 247: FORWARD _PROTOTYPE( int f_do_open, (struct driver *dp, message *m_ptr) ); 248: FORWARD _PROTOTYPE( int test_read, (int density) ); 249: FORWARD _PROTOTYPE( void f_geometry, (struct partition *entry)); 250: 251: 252: /* Entry points to this driver. */ 253: PRIVATE struct driver f_dtab = { 254: f_name, /* current device's name */ 255: f_do_open, /* open or mount request, sense type of diskette */ 256: do_nop, /* nothing on a close */ 257: do_diocntl, /* get or set a partitions geometry */ 258: f_prepare, /* prepare for I/O on a given minor device */ 259: f_transfer, /* do the I/O */ 260: f_cleanup, /* cleanup before sending reply to user process */ 261: f_geometry /* tell the geometry of the diskette */ 262: }; 263: 264: 265: /*===========================================================================* 266: * floppy_task * 267: *===========================================================================*/ 268: PUBLIC void floppy_task() 269: { 270: /* Initialize the floppy structure. */ 271: 272: struct floppy *fp; 273: 274: for (fp = &floppy[0]; fp < &floppy[NR_DRIVES]; fp++) { 275: fp->fl_curcyl = NO_CYL; 276: fp->fl_density = NO_DENS; 277: fp->fl_class = ~0; 278: } 279: 280: put_irq_handler(&f_hook, FLOPPY_IRQ, f_handler); 281: enable_irq(&f_hook); /* ready for floppy interrupts */ 282: 283: driver_task(&f_dtab); 284: } 285: 286: 287: /*===========================================================================* 288: * f_prepare * 289: *===========================================================================*/ 290: PRIVATE struct device *f_prepare(device) 291: int device; 292: { 293: /* Prepare for I/O on a device. */ 294: 295: f_device = device; 296: f_drive = device & ~(DEV_TYPE_BITS | FORMAT_DEV_BIT); 297: if (f_drive < 0 || f_drive >= NR_DRIVES) return(NIL_DEV); 298: 299: f_fp = &floppy[f_drive]; 300: f_dv = &f_fp->fl_geom; 301: if (f_fp->fl_density < NT) { 302: f_dp = &fdensity[f_fp->fl_density]; 303: f_sectors = f_dp->secpt; 304: f_fp->fl_geom.dv_size = mul64u((long) (NR_HEADS * f_sectors 305: * f_dp->cyls), SECTOR_SIZE); 306: } 307: 308: /* A partition? */ 309: if ((device &= DEV_TYPE_BITS) >= MINOR_fd0p0) 310: f_dv = &f_fp->fl_part[(device - MINOR_fd0p0) >> DEV_TYPE_SHIFT]; 311: 312: return f_dv; 313: } 314: 315: 316: /*===========================================================================* 317: * f_name * 318: *===========================================================================*/ 319: PRIVATE char *f_name() 320: { 321: /* Return a name for the current device. */ 322: static char name[] = "fd0"; 323: 324: name[2] = '0' + f_drive; 325: return name; 326: } 327: 328: 329: /*===========================================================================* 330: * f_cleanup * 331: *===========================================================================*/ 332: PRIVATE void f_cleanup() 333: { 334: /* Start a timer to turn the motor off in a few seconds. */ 335: tmr_arg(&f_fp->fl_tmr_stop)->ta_int = f_drive; 336: tmr_settimer(&f_fp->fl_tmr_stop, FLOPPY, get_uptime()+MOTOR_OFF, stop_motor); 337: 338: /* Exiting the floppy driver, so forget where we are. */ 339: f_fp->fl_sector = NO_SECTOR; 340: } 341: 342: 343: /*===========================================================================* 344: * f_transfer * 345: *===========================================================================*/ 346: PRIVATE int f_transfer(proc_nr, opcode, position, iov, nr_req) 347: int proc_nr; /* process doing the request */ 348: int opcode; /* DEV_GATHER or DEV_SCATTER */ 349: off_t position; /* offset on device to read or write */ 350: iovec_t *iov; /* pointer to read or write request vector */ 351: unsigned nr_req; /* length of request vector */ 352: { 353: struct floppy *fp = f_fp; 354: iovec_t *iop, *iov_end = iov + nr_req; 355: int r, errors; 356: unsigned block; /* Seen any 32M floppies lately? */ 357: unsigned nbytes, count, chunk, sector; 358: unsigned long dv_size = cv64ul(f_dv->dv_size); 359: vir_bytes user_addr; 360: vir_bytes uaddrs[MAX_SECTORS], *up; 361: u8_t cmd[3]; 362: phys_bytes user_base = proc_vir2phys(proc_addr(proc_nr), 0); 363: 364: /* Check disk address. */ 365: if ((position & SECTOR_MASK) != 0) return(EINVAL); 366: 367: errors = 0; 368: while (nr_req > 0) { 369: /* How many bytes to transfer? */ 370: nbytes = 0; 371: for (iop = iov; iop < iov_end; iop++) nbytes += iop->iov_size; 372: 373: /* Which block on disk and how close to EOF? */ 374: if (position >= dv_size) return(OK); /* At EOF */ 375: if (position + nbytes > dv_size) nbytes = dv_size - position; 376: block = div64u(add64ul(f_dv->dv_base, position), SECTOR_SIZE); 377: 378: if ((nbytes & SECTOR_MASK) != 0) return(EINVAL); 379: 380: /* Using a formatting device? */ 381: if (f_device & FORMAT_DEV_BIT) { 382: if (opcode != DEV_SCATTER) return(EIO); 383: if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param)) 384: return(EINVAL); 385: 386: phys_copy(user_base + iov->iov_addr + SECTOR_SIZE, 387: vir2phys(&fmt_param), (phys_bytes) sizeof(fmt_param)); 388: 389: /* Check that the number of sectors in the data is reasonable, 390: * to avoid division by 0. Leave checking of other data to 391: * the FDC. 392: */ 393: if (fmt_param.sectors_per_cylinder == 0) return(EIO); 394: 395: /* Only the first sector of the parameters now needed. */ 396: iov->iov_size = nbytes = SECTOR_SIZE; 397: } 398: 399: /* Only try one sector if there were errors. */ 400: if (errors > 0) nbytes = SECTOR_SIZE; 401: 402: /* Compute cylinder and head of the track to access. */ 403: fp->fl_cylinder = block / (NR_HEADS * f_sectors); 404: fp->fl_hardcyl = fp->fl_cylinder * f_dp->steps; 405: fp->fl_head = (block % (NR_HEADS * f_sectors)) / f_sectors; 406: 407: /* For each sector on this track compute the user address it is to 408: * go or to come from. 409: */ 410: for (up = uaddrs; up < uaddrs + MAX_SECTORS; up++) *up = 0; 411: count = 0; 412: iop = iov; 413: sector = block % f_sectors; 414: for (;;) { 415: user_addr = iop->iov_addr; 416: chunk = iop->iov_size; 417: if ((chunk & SECTOR_MASK) != 0) return(EINVAL); 418: 419: while (chunk > 0) { 420: uaddrs[sector++] = user_addr; 421: chunk -= SECTOR_SIZE; 422: user_addr += SECTOR_SIZE; 423: count += SECTOR_SIZE; 424: if (sector == f_sectors || count == nbytes) 425: goto track_set_up; 426: } 427: iop++; 428: } 429: track_set_up: 430: 431: /* First check to see if a reset is needed. */ 432: if (need_reset) f_reset(); 433: 434: /* See if motor is running; if not, turn it on and wait. */ 435: start_motor(); 436: 437: /* Set the stepping rate and data rate */ 438: if (f_dp != prev_dp) { 439: cmd[0] = FDC_SPECIFY; 440: cmd[1] = f_dp->spec1; 441: cmd[2] = SPEC2; 442: (void) fdc_command(cmd, 3); 443: outb(FDC_RATE, f_dp->rate); 444: prev_dp = f_dp; 445: } 446: 447: /* If we are going to a new cylinder, perform a seek. */ 448: r = seek(); 449: 450: /* Avoid read_id() if we don't plan to read much. */ 451: if (fp->fl_sector == NO_SECTOR && count < (6 * SECTOR_SIZE)) 452: fp->fl_sector = 0; 453: 454: for (nbytes = 0; nbytes < count; nbytes += SECTOR_SIZE) { 455: if (fp->fl_sector == NO_SECTOR) { 456: /* Find out what the current sector is. This often 457: * fails right after a seek, so try it twice. 458: */ 459: if (r == OK && read_id() != OK) r = read_id(); 460: } 461: 462: /* Look for the next job in uaddrs[] */ 463: if (r == OK) { 464: for (;;) { 465: if (fp->fl_sector >= f_sectors) 466: fp->fl_sector = 0; 467: 468: up = &uaddrs[fp->fl_sector]; 469: if (*up != 0) break; 470: fp->fl_sector++; 471: } 472: } 473: 474: if (r == OK && opcode == DEV_SCATTER) { 475: /* Copy the user bytes to the DMA buffer. */ 476: phys_copy(user_base + *up, tmp_phys, 477: (phys_bytes) SECTOR_SIZE); 478: } 479: 480: /* Set up the DMA chip and perform the transfer. */ 481: if (r == OK) { 482: dma_setup(opcode); 483: r = fdc_transfer(opcode); 484: } 485: 486: if (r == OK && opcode == DEV_GATHER) { 487: /* Copy the DMA buffer to user space. */ 488: phys_copy(tmp_phys, user_base + *up, 489: (phys_bytes) SECTOR_SIZE); 490: } 491: 492: if (r != OK) { 493: /* Don't retry if write protected or too many errors. */ 494: if (err_no_retry(r) || ++errors == MAX_ERRORS) 495: return(EIO); 496: 497: /* Recalibrate if halfway. */ 498: if (errors == MAX_ERRORS / 2) 499: fp->fl_calibration = UNCALIBRATED; 500: 501: nbytes = 0; 502: break; /* retry */ 503: } 504: } 505: 506: /* Book the bytes successfully transferred. */ 507: position += nbytes; 508: for (;;) { 509: if (nbytes < iov->iov_size) { 510: /* Not done with this one yet. */ 511: iov->iov_addr += nbytes; 512: iov->iov_size -= nbytes; 513: break; 514: } 515: nbytes -= iov->iov_size; 516: iov->iov_addr += iov->iov_size; 517: iov->iov_size = 0; 518: if (nbytes == 0) { 519: /* The rest is optional, so we return to give FS a 520: * chance to think it over. 521: */ 522: return(OK); 523: } 524: iov++; 525: nr_req--; 526: } 527: } 528: return(OK); 529: } 530: 531: 532: /*===========================================================================* 533: * dma_setup * 534: *===========================================================================*/ 535: PRIVATE void dma_setup(opcode) 536: int opcode; /* DEV_GATHER or DEV_SCATTER */ 537: { 538: /* The IBM PC can perform DMA operations by using the DMA chip. To use it, 539: * the DMA (Direct Memory Access) chip is loaded with the 20-bit memory address 540: * to be read from or written to, the byte count minus 1, and a read or write 541: * opcode. This routine sets up the DMA chip. Note that the chip is not 542: * capable of doing a DMA across a 64K boundary (e.g., you can't read a 543: * 512-byte block starting at physical address 65520). 544: */ 545: 546: /* Set up the DMA registers. (The comment on the reset is a bit strong, 547: * it probably only resets the floppy channel.) 548: */ 549: outb(DMA_INIT, DMA_RESET_VAL); /* reset the dma controller */ 550: outb(DMA_FLIPFLOP, 0); /* write anything to reset it */ 551: outb(DMA_MODE, opcode == DEV_SCATTER ? DMA_WRITE : DMA_READ); 552: outb(DMA_ADDR, (unsigned) tmp_phys >> 0); 553: outb(DMA_ADDR, (unsigned) tmp_phys >> 8); 554: outb(DMA_TOP, (unsigned) (tmp_phys >> 16)); 555: outb(DMA_COUNT, (SECTOR_SIZE - 1) >> 0); 556: outb(DMA_COUNT, (SECTOR_SIZE - 1) >> 8); 557: outb(DMA_INIT, 2); /* some sort of enable */ 558: } 559: 560: 561: /*===========================================================================* 562: * start_motor * 563: *===========================================================================*/ 564: PRIVATE void start_motor() 565: { 566: /* Control of the floppy disk motors is a big pain. If a motor is off, you 567: * have to turn it on first, which takes 1/2 second. You can't leave it on 568: * all the time, since that would wear out the diskette. However, if you turn 569: * the motor off after each operation, the system performance will be awful. 570: * The compromise used here is to leave it on for a few seconds after each 571: * operation. If a new operation is started in that interval, it need not be 572: * turned on again. If no new operation is started, a timer goes off and the 573: * motor is turned off. I/O port DOR has bits to control each of 4 drives. 574: */ 575: 576: int motor_bit, running; 577: message mess; 578: 579: motor_bit = 1 << f_drive; /* bit mask for this drive */ 580: running = motor_status & motor_bit; /* nonzero if this motor is running */ 581: motor_status |= motor_bit; /* want this drive running too */ 582: 583: outb(DOR, (motor_status << MOTOR_SHIFT) | ENABLE_INT | f_drive); 584: 585: /* If the motor was already running, we don't have to wait for it. */ 586: if (running) return; /* motor was already running */ 587: 588: tmr_settimer(&f_tmr_timeout, CLOCK, get_uptime() + f_dp->start, f_timeout); 589: f_busy = BSY_IO; 590: do receive(HARDWARE, &mess); while (f_busy == BSY_IO); 591: f_fp->fl_sector = NO_SECTOR; 592: } 593: 594: 595: /*===========================================================================* 596: * stop_motor * 597: *===========================================================================*/ 598: PRIVATE void stop_motor(tp) 599: timer_t *tp; 600: { 601: /* This routine is called by the clock interrupt after several seconds have 602: * elapsed with no floppy disk activity. It turns the drive motor off. 603: */ 604: 605: motor_status &= ~(1 << tmr_arg(tp)->ta_int); 606: outb(DOR, (motor_status << MOTOR_SHIFT) | ENABLE_INT); 607: } 608: 609: 610: /*===========================================================================* 611: * floppy_stop * 612: *===========================================================================*/ 613: PUBLIC void floppy_stop() 614: { 615: /* Stop all activity. */ 616: 617: outb(DOR, ENABLE_INT); 618: } 619: 620: 621: /*===========================================================================* 622: * seek * 623: *===========================================================================*/ 624: PRIVATE int seek() 625: { 626: /* Issue a SEEK command on the indicated drive unless the arm is already 627: * positioned on the correct cylinder. 628: */ 629: 630: struct floppy *fp = f_fp; 631: int r; 632: message mess; 633: u8_t cmd[3]; 634: 635: /* Are we already on the correct cylinder? */ 636: if (fp->fl_calibration == UNCALIBRATED) 637: if (recalibrate() != OK) return(ERR_SEEK); 638: if (fp->fl_curcyl == fp->fl_hardcyl) return(OK); 639: 640: /* No. Wrong cylinder. Issue a SEEK and wait for interrupt. */ 641: cmd[0] = FDC_SEEK; 642: cmd[1] = (fp->fl_head << 2) | f_drive; 643: cmd[2] = fp->fl_hardcyl; 644: if (fdc_command(cmd, 3) != OK) return(ERR_SEEK); 645: if (f_intr_wait() != OK) return(ERR_TIMEOUT); 646: 647: /* Interrupt has been received. Check drive status. */ 648: fdc_out(FDC_SENSE); /* probe FDC to make it return status */ 649: r = fdc_results(); /* get controller status bytes */ 650: if (r != OK || (f_results[ST0] & ST0_BITS) != SEEK_ST0 651: || f_results[ST1] != fp->fl_hardcyl) { 652: /* seek failed, may need a recalibrate */ 653: return(ERR_SEEK); 654: } 655: /* Give head time to settle on a format, no retrying here! */ 656: if (f_device & FORMAT_DEV_BIT) { 657: tmr_settimer(&f_tmr_timeout, CLOCK, get_uptime() + HZ/30, f_timeout); 658: f_busy = BSY_IO; 659: do receive(HARDWARE, &mess); while (f_busy == BSY_IO); 660: } 661: fp->fl_curcyl = fp->fl_hardcyl; 662: fp->fl_sector = NO_SECTOR; 663: return(OK); 664: } 665: 666: 667: /*===========================================================================* 668: * fdc_transfer * 669: *===========================================================================*/ 670: PRIVATE int fdc_transfer(opcode) 671: int opcode; /* DEV_GATHER or DEV_SCATTER */ 672: { 673: /* The drive is now on the proper cylinder. Read, write or format 1 block. */ 674: 675: struct floppy *fp = f_fp; 676: int r, s; 677: u8_t cmd[9]; 678: 679: /* Never attempt a transfer if the drive is uncalibrated or motor is off. */ 680: if (fp->fl_calibration == UNCALIBRATED) return(ERR_TRANSFER); 681: if ((motor_status & (1 << f_drive)) == 0) return(ERR_TRANSFER); 682: 683: /* The command is issued by outputting several bytes to the controller chip. 684: */ 685: if (f_device & FORMAT_DEV_BIT) { 686: cmd[0] = FDC_FORMAT; 687: cmd[1] = (fp->fl_head << 2) | f_drive; 688: cmd[2] = fmt_param.sector_size_code; 689: cmd[3] = fmt_param.sectors_per_cylinder; 690: cmd[4] = fmt_param.gap_length_for_format; 691: cmd[5] = fmt_param.fill_byte_for_format; 692: if (fdc_command(cmd, 6) != OK) return(ERR_TRANSFER); 693: } else { 694: cmd[0] = opcode == DEV_SCATTER ? FDC_WRITE : FDC_READ; 695: cmd[1] = (fp->fl_head << 2) | f_drive; 696: cmd[2] = fp->fl_cylinder; 697: cmd[3] = fp->fl_head; 698: cmd[4] = BASE_SECTOR + fp->fl_sector; 699: cmd[5] = SECTOR_SIZE_CODE; 700: cmd[6] = f_sectors; 701: cmd[7] = f_dp->gap; /* sector gap */ 702: cmd[8] = DTL; /* data length */ 703: if (fdc_command(cmd, 9) != OK) return(ERR_TRANSFER); 704: } 705: 706: /* Block, waiting for disk interrupt. */ 707: if (f_intr_wait() != OK) return(ERR_TIMEOUT); 708: 709: /* Get controller status and check for errors. */ 710: r = fdc_results(); 711: if (r != OK) return(r); 712: 713: if (f_results[ST1] & WRITE_PROTECT) { 714: printf("%s: diskette is write protected.\n", f_name()); 715: return(ERR_WR_PROTECT); 716: } 717: 718: if ((f_results[ST0] & ST0_BITS) != TRANS_ST0) return(ERR_TRANSFER); 719: if (f_results[ST1] | f_results[ST2]) return(ERR_TRANSFER); 720: 721: if (f_device & FORMAT_DEV_BIT) return(OK); 722: 723: /* Compare actual numbers of sectors transferred with expected number. */ 724: s = (f_results[ST_CYL] - fp->fl_cylinder) * NR_HEADS * f_sectors; 725: s += (f_results[ST_HEAD] - fp->fl_head) * f_sectors; 726: s += (f_results[ST_SEC] - BASE_SECTOR - fp->fl_sector); 727: if (s != 1) return(ERR_TRANSFER); 728: 729: /* This sector is next for I/O: */ 730: fp->fl_sector = f_results[ST_SEC] - BASE_SECTOR; 731: #if 0 732: if (processor < 386) fp->fl_sector++; /* Old CPU can't keep up. */ 733: #endif 734: return(OK); 735: } 736: 737: 738: /*==========================================================================* 739: * fdc_results * 740: *==========================================================================*/ 741: PRIVATE int fdc_results() 742: { 743: /* Extract results from the controller after an operation, then allow floppy 744: * interrupts again. 745: */ 746: 747: int result_nr, status; 748: struct micro_state ms; 749: 750: /* Extract bytes from FDC until it says it has no more. The loop is 751: * really an outer loop on result_nr and an inner loop on status. 752: */ 753: result_nr = 0; 754: micro_start(&ms); 755: do { 756: /* Reading one byte is almost a mirror of fdc_out() - the DIRECTION 757: * bit must be set instead of clear, but the CTL_BUSY bit destroys 758: * the perfection of the mirror. 759: */ 760: status = inb(FDC_STATUS) & (MASTER | DIRECTION | CTL_BUSY); 761: if (status == (MASTER | DIRECTION | CTL_BUSY)) { 762: if (result_nr >= MAX_RESULTS) break; /* too many results */ 763: f_results[result_nr++] = inb(FDC_DATA); 764: continue; 765: } 766: if (status == MASTER) { /* all read */ 767: enable_irq(&f_hook); 768: return(OK); /* only good exit */ 769: } 770: } while (micro_elapsed(&ms) < TIMEOUT); 771: need_reset = TRUE; /* controller chip must be reset */ 772: enable_irq(&f_hook); 773: return(ERR_STATUS); 774: } 775: 776: 777: /*==========================================================================* 778: * f_handler * 779: *==========================================================================*/ 780: PRIVATE int f_handler(hook) 781: irq_hook_t *hook; 782: { 783: /* FDC interrupt, send message to floppy task. */ 784: 785: f_busy = BSY_IDLE; 786: interrupt(FLOPPY); 787: return 0; 788: } 789: 790: 791: /*===========================================================================* 792: * fdc_command * 793: *===========================================================================*/ 794: PRIVATE int fdc_command(cmd, len) 795: u8_t *cmd; /* command bytes */ 796: int len; /* command length */ 797: { 798: /* Output a command to the controller. */ 799: 800: /* Schedule a wakeup call. */ 801: tmr_settimer(&f_tmr_timeout, CLOCK, get_uptime() + WAKEUP, f_timeout); 802: 803: f_busy = BSY_IO; 804: while (len > 0) { 805: fdc_out(*cmd++); 806: len--; 807: } 808: return(need_reset ? ERR_DRIVE : OK); 809: } 810: 811: 812: /*===========================================================================* 813: * fdc_out * 814: *===========================================================================*/ 815: PRIVATE void fdc_out(val) 816: int val; /* write this byte to floppy disk controller */ 817: { 818: /* Output a byte to the controller. This is not entirely trivial, since you 819: * can only write to it when it is listening, and it decides when to listen. 820: * If the controller refuses to listen, the FDC chip is given a hard reset. 821: */ 822: 823: struct micro_state ms; 824: 825: if (need_reset) return; /* if controller is not listening, return */ 826: 827: /* It may take several tries to get the FDC to accept a command. */ 828: micro_start(&ms); 829: while ((inb(FDC_STATUS) & (MASTER | DIRECTION)) != (MASTER | 0)) { 830: if (micro_elapsed(&ms) >= TIMEOUT) { 831: /* Controller is not listening. Hit it over the head. */ 832: need_reset = TRUE; 833: return; 834: } 835: } 836: outb(FDC_DATA, val); 837: } 838: 839: 840: /*===========================================================================* 841: * recalibrate * 842: *===========================================================================*/ 843: PRIVATE int recalibrate() 844: { 845: /* The floppy disk controller has no way of determining its absolute arm 846: * position (cylinder). Instead, it steps the arm a cylinder at a time and 847: * keeps track of where it thinks it is (in software). However, after a 848: * SEEK, the hardware reads information from the diskette telling where the 849: * arm actually is. If the arm is in the wrong place, a recalibration is done, 850: * which forces the arm to cylinder 0. This way the controller can get back 851: * into sync with reality. 852: */ 853: 854: struct floppy *fp = f_fp; 855: int r; 856: u8_t cmd[2]; 857: 858: /* Issue the RECALIBRATE command and wait for the interrupt. */ 859: cmd[0] = FDC_RECALIBRATE; /* tell drive to recalibrate itself */ 860: cmd[1] = f_drive; /* specify drive */ 861: if (fdc_command(cmd, 2) != OK) return(ERR_SEEK); 862: if (f_intr_wait() != OK) return(ERR_TIMEOUT); 863: 864: /* Determine if the recalibration succeeded. */ 865: fdc_out(FDC_SENSE); /* issue SENSE command to request results */ 866: r = fdc_results(); /* get results of the FDC_RECALIBRATE command*/ 867: fp->fl_curcyl = NO_CYL; /* force a SEEK next time */ 868: fp->fl_sector = NO_SECTOR; 869: if (r != OK || /* controller would not respond */ 870: (f_results[ST0] & ST0_BITS) != SEEK_ST0 || f_results[ST_PCN] != 0) { 871: /* Recalibration failed. FDC must be reset. */ 872: need_reset = TRUE; 873: return(ERR_RECALIBRATE); 874: } else { 875: /* Recalibration succeeded. */ 876: fp->fl_calibration = CALIBRATED; 877: fp->fl_curcyl = f_results[ST_PCN]; 878: return(OK); 879: } 880: } 881: 882: 883: /*===========================================================================* 884: * f_reset * 885: *===========================================================================*/ 886: PRIVATE void f_reset() 887: { 888: /* Issue a reset to the controller. This is done after any catastrophe, 889: * like the controller refusing to respond. 890: */ 891: 892: int i; 893: message mess; 894: 895: /* Disable interrupts and strobe reset bit low. */ 896: need_reset = FALSE; 897: 898: /* It is not clear why the next lock is needed. Writing 0 to DOR causes 899: * interrupt, while the PC documentation says turning bit 8 off disables 900: * interrupts. Without the lock: 901: * 1) the interrupt handler sets the floppy mask bit in the 8259. 902: * 2) writing ENABLE_INT to DOR causes the FDC to assert the interrupt 903: * line again, but the mask stops the cpu being interrupted. 904: * 3) the sense interrupt clears the interrupt (not clear which one). 905: * and for some reason the reset does not work. 906: */ 907: (void) fdc_command((u8_t *) 0, 0); /* need only the timer */ 908: lock(); 909: motor_status = 0; 910: outb(DOR, 0); /* strobe reset bit low */ 911: outb(DOR, ENABLE_INT); /* strobe it high again */ 912: unlock(); 913: /* collect the RESET interrupt */ 914: do receive(HARDWARE, &mess); while (f_busy == BSY_IO); 915: 916: /* The controller supports 4 drives and returns a result for each of them. 917: * Collect all the results now. The old version only collected the first 918: * result. This happens to work for 2 drives, but it doesn't work for 3 919: * or more drives, at least with only drives 0 and 2 actually connected 920: * (the controller generates an extra interrupt for the middle drive when 921: * drive 2 is accessed and the driver panics). 922: * 923: * It would be better to keep collecting results until there are no more. 924: * For this, fdc_results needs to return the number of results (instead 925: * of OK) when it succeeds. 926: */ 927: for (i = 0; i < 4; i++) { 928: fdc_out(FDC_SENSE); /* probe FDC to make it return status */ 929: (void) fdc_results(); /* flush controller */ 930: } 931: for (i = 0; i < NR_DRIVES; i++) /* clear each drive */ 932: floppy[i].fl_calibration = UNCALIBRATED; 933: 934: /* The current timing parameters must be specified again. */ 935: prev_dp = NULL; 936: } 937: 938: 939: /*===========================================================================* 940: * f_intr_wait * 941: *===========================================================================*/ 942: PRIVATE int f_intr_wait() 943: { 944: /* Wait for an interrupt, but not forever. The FDC may have all the time of 945: * the world, but we humans do not. 946: */ 947: message mess; 948: 949: do receive(HARDWARE, &mess); while (f_busy == BSY_IO); 950: 951: if (f_busy == BSY_WAKEN) { 952: /* No interrupt from the FDC, this means that there is probably no 953: * floppy in the drive. Get the FDC down to earth and return error. 954: */ 955: need_reset = TRUE; 956: return(ERR_TIMEOUT); 957: } 958: return(OK); 959: } 960: 961: 962: /*===========================================================================* 963: * f_timeout * 964: *===========================================================================*/ 965: PRIVATE void f_timeout(tp) 966: timer_t *tp; 967: { 968: /* This routine is called when a timer expires. Usually to tell that a 969: * motor has spun up, but also to forge an interrupt when it takes too long 970: * for the FDC to interrupt (no floppy in the drive). It sets a flag to tell 971: * what has happened. 972: */ 973: if (f_busy == BSY_IO) { 974: f_busy = BSY_WAKEN; 975: interrupt(FLOPPY); 976: } 977: } 978: 979: 980: /*==========================================================================* 981: * read_id * 982: *==========================================================================*/ 983: PRIVATE int read_id() 984: { 985: /* Determine current cylinder and sector. */ 986: 987: struct floppy *fp = f_fp; 988: int result; 989: u8_t cmd[2]; 990: 991: /* Never attempt a read id if the drive is uncalibrated or motor is off. */ 992: if (fp->fl_calibration == UNCALIBRATED) return(ERR_READ_ID); 993: if ((motor_status & (1 << f_drive)) == 0) return(ERR_READ_ID); 994: 995: /* The command is issued by outputting 2 bytes to the controller chip. */ 996: cmd[0] = FDC_READ_ID; /* issue the read id command */ 997: cmd[1] = (fp->fl_head << 2) | f_drive; 998: if (fdc_command(cmd, 2) != OK) return(ERR_READ_ID); 999: if (f_intr_wait() != OK) return(ERR_TIMEOUT); 1000: 1001: /* Get controller status and check for errors. */ 1002: result = fdc_results(); 1003: if (result != OK) return(result); 1004: 1005: if ((f_results[ST0] & ST0_BITS) != TRANS_ST0) return(ERR_READ_ID); 1006: if (f_results[ST1] | f_results[ST2]) return(ERR_READ_ID); 1007: 1008: /* The next sector is next for I/O: */ 1009: fp->fl_sector = f_results[ST_SEC] - BASE_SECTOR + 1; 1010: return(OK); 1011: } 1012: 1013: 1014: /*==========================================================================* 1015: * f_do_open * 1016: *==========================================================================*/ 1017: PRIVATE int f_do_open(dp, m_ptr) 1018: struct driver *dp; 1019: message *m_ptr; /* pointer to open message */ 1020: { 1021: /* Handle an open on a floppy. Determine diskette type if need be. */ 1022: 1023: int dtype; 1024: struct test_order *top; 1025: 1026: /* Decode the message parameters. */ 1027: if (f_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO); 1028: 1029: dtype = f_device & DEV_TYPE_BITS; /* get density from minor dev */ 1030: if (dtype >= MINOR_fd0p0) dtype = 0; 1031: 1032: if (dtype != 0) { 1033: /* All types except 0 indicate a specific drive/medium combination.*/ 1034: dtype = (dtype >> DEV_TYPE_SHIFT) - 1; 1035: if (dtype >= NT) return(ENXIO); 1036: f_fp->fl_density = dtype; 1037: (void) f_prepare(f_device); /* Recompute parameters. */ 1038: return(OK); 1039: } 1040: if (f_device & FORMAT_DEV_BIT) return(EIO); /* Can't format /dev/fdN */ 1041: 1042: /* The device opened is /dev/fdN. Experimentally determine drive/medium. 1043: * First check fl_density. If it is not NO_DENS, the drive has been used 1044: * before and the value of fl_density tells what was found last time. Try 1045: * that first. If the motor is still running then assume nothing changed. 1046: */ 1047: if (f_fp->fl_density != NO_DENS) { 1048: if (motor_status & (1 << f_drive)) return(OK); 1049: if (test_read(f_fp->fl_density) == OK) return(OK); 1050: } 1051: 1052: /* Either drive type is unknown or a different diskette is now present. 1053: * Use test_order to try them one by one. 1054: */ 1055: for (top = &test_order[0]; top < &test_order[NT-1]; top++) { 1056: dtype = top->t_density; 1057: 1058: /* Skip densities that have been proven to be impossible */ 1059: if (!(f_fp->fl_class & (1 << dtype))) continue; 1060: 1061: if (test_read(dtype) == OK) { 1062: /* The test succeeded, use this knowledge to limit the 1063: * drive class to match the density just read. 1064: */ 1065: f_fp->fl_class &= top->t_class; 1066: return(OK); 1067: } 1068: /* Test failed, wrong density or did it time out? */ 1069: if (f_busy == BSY_WAKEN) break; 1070: } 1071: f_fp->fl_density = NO_DENS; 1072: return(EIO); /* nothing worked */ 1073: } 1074: 1075: 1076: /*==========================================================================* 1077: * test_read * 1078: *==========================================================================*/ 1079: PRIVATE int test_read(density) 1080: int density; 1081: { 1082: /* Try to read the highest numbered sector on cylinder 2. Not all floppy 1083: * types have as many sectors per track, and trying cylinder 2 finds the 1084: * ones that need double stepping. 1085: */ 1086: int device; 1087: off_t position; 1088: iovec_t iovec1; 1089: 1090: f_fp->fl_density = density; 1091: device = ((density + 1) << DEV_TYPE_SHIFT) + f_drive; 1092: 1093: (void) f_prepare(device); 1094: position = (off_t) f_dp->test << SECTOR_SHIFT; 1095: iovec1.iov_addr = (vir_bytes) tmp_buf; 1096: iovec1.iov_size = SECTOR_SIZE; 1097: (void) f_transfer(FLOPPY, DEV_GATHER, position, &iovec1, 1); 1098: 1099: if (iovec1.iov_size != 0) return(EIO); 1100: 1101: partition(&f_dtab, f_drive, P_FLOPPY); 1102: return(OK); 1103: } 1104: 1105: 1106: /*============================================================================* 1107: * f_geometry * 1108: *============================================================================*/ 1109: PRIVATE void f_geometry(entry) 1110: struct partition *entry; 1111: { 1112: entry->cylinders = f_dp->cyls; 1113: entry->heads = NR_HEADS; 1114: entry->sectors = f_sectors; 1115: }