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 * 8 * Changes: 9 * Sep 11, 2005 code cleanup (Andy Tanenbaum) 10 * Dec 01, 2004 floppy driver moved to user-space (Jorrit N. Herder) 11 * Sep 15, 2004 sync alarms/ local timer management (Jorrit N. Herder) 12 * Aug 12, 2003 null seek no interrupt fix (Mike Haertel) 13 * May 14, 2000 d-d/i rewrite (Kees J. Bot) 14 * Apr 04, 1992 device dependent/independent split (Kees J. Bot) 15 * Mar 27, 1992 last details on density checking (Kees J. Bot) 16 * Feb 14, 1992 check drive density on opens only (Andy Tanenbaum) 17 * 1991 len[] / motors / reset / step rate / ... (Bruce Evans) 18 * May 13, 1991 renovated the errors loop (Don Chapman) 19 * 1989 I/O vector to keep up with 1-1 interleave (Bruce Evans) 20 * Jan 06, 1988 allow 1.44 MB diskettes (Al Crew) 21 * Nov 28, 1986 better resetting for 386 (Peter Kay) 22 * Oct 27, 1986 fdc_results fixed for 8 MHz (Jakob Schripsema) 23 */ 24 25 #include "floppy.h" 26 #include <minix/timers.h> 27 #include <machine/diskparm.h> 28 #include <minix/sysutil.h> 29 #include <minix/syslib.h> 30 #include <minix/endpoint.h> 31 #include <stdio.h> 32 33 /* I/O Ports used by floppy disk task. */ 34 #define DOR 0x3F2 /* motor drive control bits */ 35 #define FDC_STATUS 0x3F4 /* floppy disk controller status register */ 36 #define FDC_DATA 0x3F5 /* floppy disk controller data register */ 37 #define FDC_RATE 0x3F7 /* transfer rate register */ 38 #define DMA_ADDR 0x004 /* port for low 16 bits of DMA address */ 39 #define DMA_TOP 0x081 /* port for top 8 bits of 24-bit DMA addr */ 40 #define DMA_COUNT 0x005 /* port for DMA count (count = bytes - 1) */ 41 #define DMA_FLIPFLOP 0x00C /* DMA byte pointer flip-flop */ 42 #define DMA_MODE 0x00B /* DMA mode port */ 43 #define DMA_INIT 0x00A /* DMA init port */ 44 #define DMA_RESET_VAL 0x006 45 46 #define DMA_ADDR_MASK 0xFFFFFF /* mask to verify DMA address is 24-bit */ 47 48 /* Status registers returned as result of operation. */ 49 #define ST0 0x00 /* status register 0 */ 50 #define ST1 0x01 /* status register 1 */ 51 #define ST2 0x02 /* status register 2 */ 52 #define ST3 0x00 /* status register 3 (return by DRIVE_SENSE) */ 53 #define ST_CYL 0x03 /* slot where controller reports cylinder */ 54 #define ST_HEAD 0x04 /* slot where controller reports head */ 55 #define ST_SEC 0x05 /* slot where controller reports sector */ 56 #define ST_PCN 0x01 /* slot where controller reports present cyl */ 57 58 /* Fields within the I/O ports. */ 59 /* Main status register. */ 60 #define CTL_BUSY 0x10 /* bit is set when read or write in progress */ 61 #define DIRECTION 0x40 /* bit is set when reading data reg is valid */ 62 #define MASTER 0x80 /* bit is set when data reg can be accessed */ 63 64 /* Digital output port (DOR). */ 65 #define MOTOR_SHIFT 4 /* high 4 bits control the motors in DOR */ 66 #define ENABLE_INT 0x0C /* used for setting DOR port */ 67 68 /* ST0. */ 69 #define ST0_BITS_TRANS 0xD8 /* check 4 bits of status */ 70 #define TRANS_ST0 0x00 /* 4 bits of ST0 for READ/WRITE */ 71 #define ST0_BITS_SEEK 0xF8 /* check top 5 bits of seek status */ 72 #define SEEK_ST0 0x20 /* top 5 bits of ST0 for SEEK */ 73 74 /* ST1. */ 75 #define BAD_SECTOR 0x05 /* if these bits are set in ST1, recalibrate */ 76 #define WRITE_PROTECT 0x02 /* bit is set if diskette is write protected */ 77 78 /* ST2. */ 79 #define BAD_CYL 0x1F /* if any of these bits are set, recalibrate */ 80 81 /* ST3 (not used). */ 82 #define ST3_FAULT 0x80 /* if this bit is set, drive is sick */ 83 #define ST3_WR_PROTECT 0x40 /* set when diskette is write protected */ 84 #define ST3_READY 0x20 /* set when drive is ready */ 85 86 /* Floppy disk controller command bytes. */ 87 #define FDC_SEEK 0x0F /* command the drive to seek */ 88 #define FDC_READ 0xE6 /* command the drive to read */ 89 #define FDC_WRITE 0xC5 /* command the drive to write */ 90 #define FDC_SENSE 0x08 /* command the controller to tell its status */ 91 #define FDC_RECALIBRATE 0x07 /* command the drive to go to cyl 0 */ 92 #define FDC_SPECIFY 0x03 /* command the drive to accept params */ 93 #define FDC_READ_ID 0x4A /* command the drive to read sector identity */ 94 #define FDC_FORMAT 0x4D /* command the drive to format a track */ 95 96 /* DMA channel commands. */ 97 #define DMA_READ 0x46 /* DMA read opcode */ 98 #define DMA_WRITE 0x4A /* DMA write opcode */ 99 100 /* Parameters for the disk drive. */ 101 #define HC_SIZE 2880 /* # sectors on largest legal disk (1.44MB) */ 102 #define NR_HEADS 0x02 /* two heads (i.e., two tracks/cylinder) */ 103 #define MAX_SECTORS 18 /* largest # sectors per track */ 104 #define DTL 0xFF /* determines data length (sector size) */ 105 #define SPEC2 0x02 /* second parameter to SPECIFY */ 106 #define MOTOR_OFF (3*system_hz) /* how long to wait before stopping motor */ 107 #define WAKEUP (2*system_hz) /* timeout on I/O, FDC won't quit. */ 108 109 /* Error codes */ 110 #define ERR_SEEK (-1) /* bad seek */ 111 #define ERR_TRANSFER (-2) /* bad transfer */ 112 #define ERR_STATUS (-3) /* something wrong when getting status */ 113 #define ERR_READ_ID (-4) /* bad read id */ 114 #define ERR_RECALIBRATE (-5) /* recalibrate didn't work properly */ 115 #define ERR_DRIVE (-6) /* something wrong with a drive */ 116 #define ERR_WR_PROTECT (-7) /* diskette is write protected */ 117 #define ERR_TIMEOUT (-8) /* interrupt timeout */ 118 119 /* No retries on some errors. */ 120 #define err_no_retry(err) ((err) <= ERR_WR_PROTECT) 121 122 /* Encoding of drive type in minor device number. */ 123 #define DEV_TYPE_BITS 0x7C /* drive type + 1, if nonzero */ 124 #define DEV_TYPE_SHIFT 2 /* right shift to normalize type bits */ 125 #define FORMAT_DEV_BIT 0x80 /* bit in minor to turn write into format */ 126 127 /* Miscellaneous. */ 128 #define MAX_ERRORS 6 /* how often to try rd/wt before quitting */ 129 #define MAX_RESULTS 7 /* max number of bytes controller returns */ 130 #define NR_DRIVES 2 /* maximum number of drives */ 131 #define DIVISOR 128 /* used for sector size encoding */ 132 #define SECTOR_SIZE_CODE 2 /* code to say "512" to the controller */ 133 #define TIMEOUT_MICROS 5000000L /* microseconds waiting for FDC */ 134 #define NT 7 /* number of diskette/drive combinations */ 135 #define UNCALIBRATED 0 /* drive needs to be calibrated at next use */ 136 #define CALIBRATED 1 /* no calibration needed */ 137 #define BASE_SECTOR 1 /* sectors are numbered starting at 1 */ 138 #define NO_SECTOR ((unsigned) -1) /* current sector unknown */ 139 #define NO_CYL (-1) /* current cylinder unknown, must seek */ 140 #define NO_DENS 100 /* current media unknown */ 141 #define BSY_IDLE 0 /* busy doing nothing */ 142 #define BSY_IO 1 /* busy doing I/O */ 143 #define BSY_WAKEN 2 /* got a wakeup call */ 144 145 /* Seven combinations of diskette/drive are supported. 146 * 147 * # Diskette Drive Sectors Tracks Rotation Data-rate Comment 148 * 0 360K 360K 9 40 300 RPM 250 kbps Standard PC DSDD 149 * 1 1.2M 1.2M 15 80 360 RPM 500 kbps AT disk in AT drive 150 * 2 360K 720K 9 40 300 RPM 250 kbps Quad density PC 151 * 3 720K 720K 9 80 300 RPM 250 kbps Toshiba, et al. 152 * 4 360K 1.2M 9 40 360 RPM 300 kbps PC disk in AT drive 153 * 5 720K 1.2M 9 80 360 RPM 300 kbps Toshiba in AT drive 154 * 6 1.44M 1.44M 18 80 300 RPM 500 kbps PS/2, et al. 155 * 156 * In addition, 720K diskettes can be read in 1.44MB drives, but that does 157 * not need a different set of parameters. This combination uses 158 * 159 * 3 720K 1.44M 9 80 300 RPM 250 kbps PS/2, et al. 160 */ 161 static struct density { 162 u8_t secpt; /* sectors per track */ 163 u8_t cyls; /* tracks per side */ 164 u8_t steps; /* steps per cylinder (2 = double step) */ 165 u8_t test; /* sector to try for density test */ 166 u8_t rate; /* data rate (2=250, 1=300, 0=500 kbps) */ 167 clock_t start_ms; /* motor start (milliseconds) */ 168 u8_t gap; /* gap size */ 169 u8_t spec1; /* first specify byte (SRT/HUT) */ 170 } fdensity[NT] = { 171 { 9, 40, 1, 4*9, 2, 500, 0x2A, 0xDF }, /* 360K / 360K */ 172 { 15, 80, 1, 14, 0, 500, 0x1B, 0xDF }, /* 1.2M / 1.2M */ 173 { 9, 40, 2, 2*9, 2, 500, 0x2A, 0xDF }, /* 360K / 720K */ 174 { 9, 80, 1, 4*9, 2, 750, 0x2A, 0xDF }, /* 720K / 720K */ 175 { 9, 40, 2, 2*9, 1, 500, 0x23, 0xDF }, /* 360K / 1.2M */ 176 { 9, 80, 1, 4*9, 1, 500, 0x23, 0xDF }, /* 720K / 1.2M */ 177 { 18, 80, 1, 17, 0, 750, 0x1B, 0xCF }, /* 1.44M / 1.44M */ 178 }; 179 180 /* The following table is used with the test_sector array to recognize a 181 * drive/floppy combination. The sector to test has been determined by 182 * looking at the differences in gap size, sectors/track, and double stepping. 183 * This means that types 0 and 3 can't be told apart, only the motor start 184 * time differs. If a read test succeeds then the drive is limited to the 185 * set of densities it can support to avoid unnecessary tests in the future. 186 */ 187 188 #define b(d) (1 << (d)) /* bit for density d. */ 189 190 static struct test_order { 191 u8_t t_density; /* floppy/drive type */ 192 u8_t t_class; /* limit drive to this class of densities */ 193 } test_order[NT-1] = { 194 { 6, b(3) | b(6) }, /* 1.44M {720K, 1.44M} */ 195 { 1, b(1) | b(4) | b(5) }, /* 1.2M {1.2M, 360K, 720K} */ 196 { 3, b(2) | b(3) | b(6) }, /* 720K {360K, 720K, 1.44M} */ 197 { 4, b(1) | b(4) | b(5) }, /* 360K {1.2M, 360K, 720K} */ 198 { 5, b(1) | b(4) | b(5) }, /* 720K {1.2M, 360K, 720K} */ 199 { 2, b(2) | b(3) }, /* 360K {360K, 720K} */ 200 /* Note that type 0 is missing, type 3 can read/write it too, which is 201 * why the type 3 parameters have been pessimized to be like type 0. 202 */ 203 }; 204 205 /* Variables. */ 206 static struct floppy { /* main drive struct, one entry per drive */ 207 unsigned fl_curcyl; /* current cylinder */ 208 unsigned fl_hardcyl; /* hardware cylinder, as opposed to: */ 209 unsigned fl_cylinder; /* cylinder number addressed */ 210 unsigned fl_sector; /* sector addressed */ 211 unsigned fl_head; /* head number addressed */ 212 char fl_calibration; /* CALIBRATED or UNCALIBRATED */ 213 u8_t fl_density; /* NO_DENS = ?, 0 = 360K; 1 = 360K/1.2M; etc.*/ 214 u8_t fl_class; /* bitmap for possible densities */ 215 minix_timer_t fl_tmr_stop; /* timer to stop motor */ 216 struct device fl_geom; /* Geometry of the drive */ 217 struct device fl_part[NR_PARTITIONS]; /* partition's base & size */ 218 } floppy[NR_DRIVES]; 219 220 static int irq_hook_id; /* id of irq hook at the kernel */ 221 int motor_status; /* bitmap of current motor status */ 222 static int need_reset; /* set to 1 when controller must be reset */ 223 unsigned f_drive; /* selected drive */ 224 static unsigned f_device; /* selected minor device */ 225 static struct floppy *f_fp; /* current drive */ 226 static struct density *f_dp; /* current density parameters */ 227 static struct density *prev_dp;/* previous density parameters */ 228 static unsigned f_sectors; /* equal to f_dp->secpt (needed a lot) */ 229 u16_t f_busy; /* BSY_IDLE, BSY_IO, BSY_WAKEN */ 230 static struct device *f_dv; /* device's base and size */ 231 static struct disk_parameter_s fmt_param; /* parameters for format */ 232 static u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */ 233 234 /* The floppy uses various timers. These are managed by the floppy driver 235 * itself, because only a single synchronous alarm is available per process. 236 * Besides the 'f_tmr_timeout' timer below, the floppy structure for each 237 * floppy disk drive contains a 'fl_tmr_stop' timer. 238 */ 239 static minix_timer_t f_tmr_timeout; /* timer for various timeouts */ 240 static u32_t system_hz; /* system clock frequency */ 241 static void f_expire_tmrs(clock_t stamp); 242 static void stop_motor(minix_timer_t *tp); 243 static void f_timeout(minix_timer_t *tp); 244 245 static struct device *f_prepare(devminor_t device); 246 static struct device *f_part(devminor_t minor); 247 static void f_cleanup(void); 248 static ssize_t f_transfer(devminor_t minor, int do_write, u64_t position, 249 endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags); 250 static int dma_setup(int do_write); 251 static void start_motor(void); 252 static int seek(void); 253 static int fdc_transfer(int do_write); 254 static int fdc_results(void); 255 static int fdc_command(const u8_t *cmd, int len); 256 static void fdc_out(int val); 257 static int recalibrate(void); 258 static void f_reset(void); 259 static int f_intr_wait(void); 260 static int read_id(void); 261 static int f_do_open(devminor_t minor, int access); 262 static int f_do_close(devminor_t minor); 263 static int test_read(int density); 264 static void f_geometry(devminor_t minor, struct part_geom *entry); 265 266 /* Entry points to this driver. */ 267 static struct blockdriver f_dtab = { 268 .bdr_type = BLOCKDRIVER_TYPE_DISK, /* handle partition requests */ 269 .bdr_open = f_do_open, /* open request, sense type of diskette */ 270 .bdr_close = f_do_close, /* nothing on a close */ 271 .bdr_transfer = f_transfer, /* do the I/O */ 272 .bdr_cleanup = f_cleanup, /* cleanup before sending reply to caller */ 273 .bdr_part = f_part, /* return partition information structure */ 274 .bdr_geometry = f_geometry, /* tell the geometry of the diskette */ 275 .bdr_alarm = f_expire_tmrs /* expire all alarm timers */ 276 }; 277 278 static char *floppy_buf; 279 static phys_bytes floppy_buf_phys; 280 281 /* SEF functions and variables. */ 282 static void sef_local_startup(void); 283 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 284 static void sef_cb_signal_handler(int signo); 285 EXTERN int sef_cb_lu_prepare(int state); 286 EXTERN int sef_cb_lu_state_isvalid(int state); 287 EXTERN void sef_cb_lu_state_dump(int state); 288 int last_was_write; 289 290 /*===========================================================================* 291 * floppy_task * 292 *===========================================================================*/ 293 int main(void) 294 { 295 /* SEF local startup. */ 296 sef_local_startup(); 297 298 /* Call the generic receive loop. */ 299 blockdriver_task(&f_dtab); 300 301 return(OK); 302 } 303 304 /*===========================================================================* 305 * sef_local_startup * 306 *===========================================================================*/ 307 static void sef_local_startup(void) 308 { 309 /* Register init callbacks. */ 310 sef_setcb_init_fresh(sef_cb_init_fresh); 311 sef_setcb_init_lu(sef_cb_init_fresh); 312 313 /* Register live update callbacks. */ 314 sef_setcb_lu_prepare(sef_cb_lu_prepare); 315 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); 316 sef_setcb_lu_state_dump(sef_cb_lu_state_dump); 317 318 /* Register signal callbacks. */ 319 sef_setcb_signal_handler(sef_cb_signal_handler); 320 321 /* Let SEF perform startup. */ 322 sef_startup(); 323 } 324 325 /*===========================================================================* 326 * sef_cb_init_fresh * 327 *===========================================================================*/ 328 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) 329 { 330 /* Initialize the floppy driver. */ 331 struct floppy *fp; 332 int s; 333 334 /* Initialize the floppy structure and the timers. */ 335 system_hz = sys_hz(); 336 337 if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE, 338 AC_LOWER16M | AC_ALIGN4K, &floppy_buf_phys))) 339 panic("couldn't allocate dma buffer"); 340 341 init_timer(&f_tmr_timeout); 342 343 for (fp = &floppy[0]; fp < &floppy[NR_DRIVES]; fp++) { 344 fp->fl_curcyl = NO_CYL; 345 fp->fl_density = NO_DENS; 346 fp->fl_class = ~0; 347 init_timer(&fp->fl_tmr_stop); 348 } 349 350 /* Set IRQ policy, only request notifications, do not automatically 351 * reenable interrupts. ID return on interrupt is the IRQ line number. 352 */ 353 irq_hook_id = FLOPPY_IRQ; 354 if ((s=sys_irqsetpolicy(FLOPPY_IRQ, 0, &irq_hook_id )) != OK) 355 panic("Couldn't set IRQ policy: %d", s); 356 if ((s=sys_irqenable(&irq_hook_id)) != OK) 357 panic("Couldn't enable IRQs: %d", s); 358 359 /* Announce we are up! */ 360 blockdriver_announce(type); 361 362 return(OK); 363 } 364 365 /*===========================================================================* 366 * sef_cb_signal_handler * 367 *===========================================================================*/ 368 static void sef_cb_signal_handler(int signo) 369 { 370 int s; 371 372 /* Only check for termination signal, ignore anything else. */ 373 if (signo != SIGTERM) return; 374 375 /* Stop all activity and cleanly exit with the system. */ 376 if ((s=sys_outb(DOR, ENABLE_INT)) != OK) 377 panic("Sys_outb failed: %d", s); 378 exit(0); 379 } 380 381 /*===========================================================================* 382 * f_expire_tmrs * 383 *===========================================================================*/ 384 static void f_expire_tmrs(clock_t stamp) 385 { 386 /* A synchronous alarm message was received. Call the watchdog function for 387 * each expired timer, if any. 388 */ 389 390 expire_timers(stamp); 391 } 392 393 /*===========================================================================* 394 * f_prepare * 395 *===========================================================================*/ 396 static struct device *f_prepare(devminor_t device) 397 { 398 /* Prepare for I/O on a device. */ 399 400 f_device = device; 401 f_drive = device & ~(DEV_TYPE_BITS | FORMAT_DEV_BIT); 402 if (device < 0 || f_drive >= NR_DRIVES) return(NULL); 403 404 f_fp = &floppy[f_drive]; 405 f_dv = &f_fp->fl_geom; 406 if (f_fp->fl_density < NT) { 407 f_dp = &fdensity[f_fp->fl_density]; 408 f_sectors = f_dp->secpt; 409 f_fp->fl_geom.dv_size = (u64_t)(NR_HEADS * f_sectors * f_dp->cyls) * 410 SECTOR_SIZE; 411 } 412 413 /* A partition? */ 414 if ((device &= DEV_TYPE_BITS) >= MINOR_fd0p0) 415 f_dv = &f_fp->fl_part[(device - MINOR_fd0p0) >> DEV_TYPE_SHIFT]; 416 417 return f_dv; 418 } 419 420 /*===========================================================================* 421 * f_part * 422 *===========================================================================*/ 423 static struct device *f_part(devminor_t minor) 424 { 425 /* Return a pointer to the partition information of the given minor device. */ 426 427 return f_prepare(minor); 428 } 429 430 /*===========================================================================* 431 * f_cleanup * 432 *===========================================================================*/ 433 static void f_cleanup(void) 434 { 435 /* Start a timer to turn the motor off in a few seconds. */ 436 set_timer(&f_fp->fl_tmr_stop, MOTOR_OFF, stop_motor, f_drive); 437 438 /* Exiting the floppy driver, so forget where we are. */ 439 f_fp->fl_sector = NO_SECTOR; 440 } 441 442 /*===========================================================================* 443 * f_transfer * 444 *===========================================================================*/ 445 static ssize_t f_transfer( 446 devminor_t minor, /* minor device number */ 447 int do_write, /* read or write? */ 448 u64_t pos64, /* offset on device to read or write */ 449 endpoint_t proc_nr, /* process doing the request */ 450 iovec_t *iov, /* pointer to read or write request vector */ 451 unsigned int nr_req, /* length of request vector */ 452 int UNUSED(flags) /* transfer flags */ 453 ) 454 { 455 #define NO_OFFSET -1 456 struct floppy *fp; 457 iovec_t *iop, *iov_end = iov + nr_req; 458 int s, r, errors, nr; 459 unsigned block, nbytes, count, chunk, sector; 460 u64_t dv_size; 461 vir_bytes user_offset, iov_offset = 0, iop_offset; 462 unsigned long position; 463 signed long uoffsets[MAX_SECTORS], *up; 464 cp_grant_id_t ugrants[MAX_SECTORS], *ug = NULL; 465 u8_t cmd[3]; 466 ssize_t total; 467 468 if (f_prepare(minor) == NULL) return(ENXIO); 469 470 fp = f_fp; 471 dv_size = f_dv->dv_size; 472 473 if (ex64hi(pos64) != 0) 474 return OK; /* Way beyond EOF */ 475 position= pos64; 476 total = 0; 477 478 /* Record the direction of the last transfer performed. */ 479 last_was_write = do_write; 480 481 /* Check disk address. */ 482 if ((position & SECTOR_MASK) != 0) return(EINVAL); 483 484 #if 0 /* XXX hack to create a disk driver that crashes */ 485 { static int count= 0; if (++count > 10) { 486 printf("floppy: time to die\n"); *(int *)-1= 42; 487 }} 488 #endif 489 490 errors = 0; 491 while (nr_req > 0) { 492 /* How many bytes to transfer? */ 493 nbytes = 0; 494 for (iop = iov; iop < iov_end; iop++) nbytes += iop->iov_size; 495 496 /* Which block on disk and how close to EOF? */ 497 if (position >= dv_size) return(total); /* At EOF */ 498 if (position + nbytes > dv_size) nbytes = dv_size - position; 499 block = (unsigned long)((f_dv->dv_base + position) / SECTOR_SIZE); 500 501 if ((nbytes & SECTOR_MASK) != 0) return(EINVAL); 502 503 /* Using a formatting device? */ 504 if (f_device & FORMAT_DEV_BIT) { 505 if (!do_write) return(EIO); 506 if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param)) 507 return(EINVAL); 508 509 if(proc_nr != SELF) { 510 s=sys_safecopyfrom(proc_nr, iov->iov_addr, 511 SECTOR_SIZE + iov_offset, (vir_bytes) &fmt_param, 512 (phys_bytes) sizeof(fmt_param)); 513 if(s != OK) 514 panic("sys_safecopyfrom failed: %d", s); 515 } else { 516 memcpy(&fmt_param, (void *) (iov->iov_addr + 517 SECTOR_SIZE + iov_offset), 518 (phys_bytes) sizeof(fmt_param)); 519 } 520 521 /* Check that the number of sectors in the data is reasonable, 522 * to avoid division by 0. Leave checking of other data to 523 * the FDC. 524 */ 525 if (fmt_param.sectors_per_cylinder == 0) return(EIO); 526 527 /* Only the first sector of the parameters now needed. */ 528 iov->iov_size = nbytes = SECTOR_SIZE; 529 } 530 531 /* Only try one sector if there were errors. */ 532 if (errors > 0) nbytes = SECTOR_SIZE; 533 534 /* Compute cylinder and head of the track to access. */ 535 fp->fl_cylinder = block / (NR_HEADS * f_sectors); 536 fp->fl_hardcyl = fp->fl_cylinder * f_dp->steps; 537 fp->fl_head = (block % (NR_HEADS * f_sectors)) / f_sectors; 538 539 /* For each sector on this track compute the user address it is to 540 * go or to come from. 541 */ 542 for (up = uoffsets; up < uoffsets + MAX_SECTORS; up++) *up = NO_OFFSET; 543 count = 0; 544 iop = iov; 545 sector = block % f_sectors; 546 nr = 0; 547 iop_offset = iov_offset; 548 for (;;) { 549 nr++; 550 user_offset = iop_offset; 551 chunk = iop->iov_size; 552 if ((chunk & SECTOR_MASK) != 0) return(EINVAL); 553 554 while (chunk > 0) { 555 ugrants[sector] = iop->iov_addr; 556 uoffsets[sector++] = user_offset; 557 chunk -= SECTOR_SIZE; 558 user_offset += SECTOR_SIZE; 559 count += SECTOR_SIZE; 560 if (sector == f_sectors || count == nbytes) 561 goto track_set_up; 562 } 563 iop_offset = 0; 564 iop++; 565 } 566 track_set_up: 567 568 /* First check to see if a reset is needed. */ 569 if (need_reset) f_reset(); 570 571 /* See if motor is running; if not, turn it on and wait. */ 572 start_motor(); 573 574 /* Set the stepping rate and data rate */ 575 if (f_dp != prev_dp) { 576 cmd[0] = FDC_SPECIFY; 577 cmd[1] = f_dp->spec1; 578 cmd[2] = SPEC2; 579 (void) fdc_command(cmd, 3); 580 if ((s=sys_outb(FDC_RATE, f_dp->rate)) != OK) 581 panic("Sys_outb failed: %d", s); 582 prev_dp = f_dp; 583 } 584 585 /* If we are going to a new cylinder, perform a seek. */ 586 r = seek(); 587 588 /* Avoid read_id() if we don't plan to read much. */ 589 if (fp->fl_sector == NO_SECTOR && count < (6 * SECTOR_SIZE)) 590 fp->fl_sector = 0; 591 592 for (nbytes = 0; nbytes < count; nbytes += SECTOR_SIZE) { 593 if (fp->fl_sector == NO_SECTOR) { 594 /* Find out what the current sector is. This often 595 * fails right after a seek, so try it twice. 596 */ 597 if (r == OK && read_id() != OK) r = read_id(); 598 } 599 600 /* Look for the next job in uoffsets[] */ 601 if (r == OK) { 602 for (;;) { 603 if (fp->fl_sector >= f_sectors) 604 fp->fl_sector = 0; 605 606 up = &uoffsets[fp->fl_sector]; 607 ug = &ugrants[fp->fl_sector]; 608 if (*up != NO_OFFSET) break; 609 fp->fl_sector++; 610 } 611 612 if (do_write) { 613 /* Copy the user bytes to the DMA buffer. */ 614 if(proc_nr != SELF) { 615 s=sys_safecopyfrom(proc_nr, *ug, *up, 616 (vir_bytes) floppy_buf, 617 (phys_bytes) SECTOR_SIZE); 618 if(s != OK) 619 panic("sys_safecopyfrom failed: %d", s); 620 } else { 621 memcpy(floppy_buf, (void *) (*ug + *up), SECTOR_SIZE); 622 } 623 } 624 } 625 626 /* Set up the DMA chip and perform the transfer. */ 627 if (r == OK) { 628 if (dma_setup(do_write) != OK) { 629 /* This can only fail for addresses above 16MB 630 * that cannot be handled by the controller, 631 * because it uses 24-bit addressing. 632 */ 633 return(EIO); 634 } 635 r = fdc_transfer(do_write); 636 } 637 638 if (r == OK && !do_write) { 639 /* Copy the DMA buffer to user space. */ 640 if(proc_nr != SELF) { 641 s=sys_safecopyto(proc_nr, *ug, *up, 642 (vir_bytes) floppy_buf, 643 (phys_bytes) SECTOR_SIZE); 644 if(s != OK) 645 panic("sys_safecopyto failed: %d", s); 646 } else { 647 memcpy((void *) (*ug + *up), floppy_buf, SECTOR_SIZE); 648 } 649 } 650 651 if (r != OK) { 652 /* Don't retry if write protected or too many errors. */ 653 if (err_no_retry(r) || ++errors == MAX_ERRORS) { 654 return(EIO); 655 } 656 657 /* Recalibrate if halfway. */ 658 if (errors == MAX_ERRORS / 2) 659 fp->fl_calibration = UNCALIBRATED; 660 661 nbytes = 0; 662 break; /* retry */ 663 } 664 } 665 666 /* Book the bytes successfully transferred. */ 667 position += nbytes; 668 total += nbytes; 669 while (nbytes > 0) { 670 if (nbytes < iov->iov_size) { 671 /* Not done with this one yet. */ 672 iov_offset += nbytes; 673 iov->iov_size -= nbytes; 674 break; 675 } 676 iov_offset = 0; 677 nbytes -= iov->iov_size; 678 iov->iov_size = 0; 679 iov++; 680 nr_req--; 681 } 682 } 683 return(total); 684 } 685 686 /*===========================================================================* 687 * dma_setup * 688 *===========================================================================*/ 689 static int dma_setup(int do_write) 690 { 691 /* The IBM PC can perform DMA operations by using the DMA chip. To use it, 692 * the DMA (Direct Memory Access) chip is loaded with the 20-bit memory address 693 * to be read from or written to, the byte count minus 1, and a read or write 694 * opcode. This routine sets up the DMA chip. Note that the chip is not 695 * capable of doing a DMA across a 64K boundary (e.g., you can't read a 696 * 512-byte block starting at physical address 65520). 697 * 698 * Warning! Also note that it's not possible to do DMA above 16 MB because 699 * the ISA bus uses 24-bit addresses. Addresses above 16 MB therefore will 700 * be interpreted modulo 16 MB, dangerously overwriting arbitrary memory. 701 * A check here denies the I/O if the address is out of range. 702 */ 703 pvb_pair_t byte_out[9]; 704 int s; 705 706 /* First check the DMA memory address not to exceed maximum. */ 707 if (floppy_buf_phys != (floppy_buf_phys & DMA_ADDR_MASK)) { 708 printf("floppy: DMA denied because address out of range\n"); 709 return(EIO); 710 } 711 712 /* Set up the DMA registers. (The comment on the reset is a bit strong, 713 * it probably only resets the floppy channel.) 714 */ 715 pv_set(byte_out[0], DMA_INIT, DMA_RESET_VAL); /* reset the dma controller */ 716 pv_set(byte_out[1], DMA_FLIPFLOP, 0); /* write anything to reset it */ 717 pv_set(byte_out[2], DMA_MODE, do_write ? DMA_WRITE : DMA_READ); 718 pv_set(byte_out[3], DMA_ADDR, (unsigned) (floppy_buf_phys >> 0) & 0xff); 719 pv_set(byte_out[4], DMA_ADDR, (unsigned) (floppy_buf_phys >> 8) & 0xff); 720 pv_set(byte_out[5], DMA_TOP, (unsigned) (floppy_buf_phys >> 16) & 0xff); 721 pv_set(byte_out[6], DMA_COUNT, (((SECTOR_SIZE - 1) >> 0)) & 0xff); 722 pv_set(byte_out[7], DMA_COUNT, (SECTOR_SIZE - 1) >> 8); 723 pv_set(byte_out[8], DMA_INIT, 2); /* some sort of enable */ 724 725 if ((s=sys_voutb(byte_out, 9)) != OK) 726 panic("Sys_voutb in dma_setup() failed: %d", s); 727 return(OK); 728 } 729 730 /*===========================================================================* 731 * start_motor * 732 *===========================================================================*/ 733 static void start_motor(void) 734 { 735 /* Control of the floppy disk motors is a big pain. If a motor is off, you 736 * have to turn it on first, which takes 1/2 second. You can't leave it on 737 * all the time, since that would wear out the diskette. However, if you turn 738 * the motor off after each operation, the system performance will be awful. 739 * The compromise used here is to leave it on for a few seconds after each 740 * operation. If a new operation is started in that interval, it need not be 741 * turned on again. If no new operation is started, a timer goes off and the 742 * motor is turned off. I/O port DOR has bits to control each of 4 drives. 743 */ 744 745 int s, motor_bit, running; 746 message mess; 747 int ipc_status; 748 749 motor_bit = 1 << f_drive; /* bit mask for this drive */ 750 running = motor_status & motor_bit; /* nonzero if this motor is running */ 751 motor_status |= motor_bit; /* want this drive running too */ 752 753 if ((s=sys_outb(DOR, 754 (motor_status << MOTOR_SHIFT) | ENABLE_INT | f_drive)) != OK) 755 panic("Sys_outb in start_motor() failed: %d", s); 756 757 /* If the motor was already running, we don't have to wait for it. */ 758 if (running) return; /* motor was already running */ 759 760 /* Set an alarm timer to force a timeout if the hardware does not interrupt 761 * in time. Expect an interrupt, but check for a timeout. 762 */ 763 set_timer(&f_tmr_timeout, f_dp->start_ms * system_hz / 1000, f_timeout, 0); 764 f_busy = BSY_IO; 765 do { 766 if ((s = driver_receive(ANY, &mess, &ipc_status)) != OK) 767 panic("Couldn't receive message: %d", s); 768 769 if (is_ipc_notify(ipc_status)) { 770 switch (_ENDPOINT_P(mess.m_source)) { 771 case CLOCK: 772 f_expire_tmrs(mess.m_notify.timestamp); 773 break; 774 default : 775 f_busy = BSY_IDLE; 776 break; 777 } 778 } else { 779 f_busy = BSY_IDLE; 780 } 781 } while (f_busy == BSY_IO); 782 f_fp->fl_sector = NO_SECTOR; 783 } 784 785 /*===========================================================================* 786 * stop_motor * 787 *===========================================================================*/ 788 static void stop_motor(minix_timer_t *tp) 789 { 790 /* This routine is called from an alarm timer after several seconds have 791 * elapsed with no floppy disk activity. It turns the drive motor off. 792 */ 793 int s; 794 motor_status &= ~(1 << tmr_arg(tp)->ta_int); 795 if ((s=sys_outb(DOR, (motor_status << MOTOR_SHIFT) | ENABLE_INT)) != OK) 796 panic("Sys_outb in stop_motor() failed: %d", s); 797 } 798 799 /*===========================================================================* 800 * seek * 801 *===========================================================================*/ 802 static int seek(void) 803 { 804 /* Issue a SEEK command on the indicated drive unless the arm is already 805 * positioned on the correct cylinder. 806 */ 807 808 struct floppy *fp = f_fp; 809 int r; 810 message mess; 811 int ipc_status; 812 u8_t cmd[3]; 813 814 /* Are we already on the correct cylinder? */ 815 if (fp->fl_calibration == UNCALIBRATED) 816 if (recalibrate() != OK) return(ERR_SEEK); 817 if (fp->fl_curcyl == fp->fl_hardcyl) return(OK); 818 819 /* No. Wrong cylinder. Issue a SEEK and wait for interrupt. */ 820 cmd[0] = FDC_SEEK; 821 cmd[1] = (fp->fl_head << 2) | f_drive; 822 cmd[2] = fp->fl_hardcyl; 823 if (fdc_command(cmd, 3) != OK) return(ERR_SEEK); 824 if (f_intr_wait() != OK) return(ERR_TIMEOUT); 825 826 /* Interrupt has been received. Check drive status. */ 827 fdc_out(FDC_SENSE); /* probe FDC to make it return status */ 828 r = fdc_results(); /* get controller status bytes */ 829 if (r != OK || (f_results[ST0] & ST0_BITS_SEEK) != SEEK_ST0 830 || f_results[ST1] != fp->fl_hardcyl) { 831 /* seek failed, may need a recalibrate */ 832 return(ERR_SEEK); 833 } 834 /* Give head time to settle on a format, no retrying here! */ 835 if (f_device & FORMAT_DEV_BIT) { 836 /* Set a synchronous alarm to force a timeout if the hardware does 837 * not interrupt. 838 */ 839 set_timer(&f_tmr_timeout, system_hz/30, f_timeout, 0); 840 f_busy = BSY_IO; 841 do { 842 if ((r = driver_receive(ANY, &mess, &ipc_status)) != OK) 843 panic("Couldn't receive message: %d", r); 844 845 if (is_ipc_notify(ipc_status)) { 846 switch (_ENDPOINT_P(mess.m_source)) { 847 case CLOCK: 848 f_expire_tmrs(mess.m_notify.timestamp); 849 break; 850 default : 851 f_busy = BSY_IDLE; 852 break; 853 } 854 } else { 855 f_busy = BSY_IDLE; 856 } 857 } while (f_busy == BSY_IO); 858 } 859 fp->fl_curcyl = fp->fl_hardcyl; 860 fp->fl_sector = NO_SECTOR; 861 return(OK); 862 } 863 864 /*===========================================================================* 865 * fdc_transfer * 866 *===========================================================================*/ 867 static int fdc_transfer(int do_write) 868 { 869 /* The drive is now on the proper cylinder. Read, write or format 1 block. */ 870 871 struct floppy *fp = f_fp; 872 int r, s; 873 u8_t cmd[9]; 874 875 /* Never attempt a transfer if the drive is uncalibrated or motor is off. */ 876 if (fp->fl_calibration == UNCALIBRATED) return(ERR_TRANSFER); 877 if ((motor_status & (1 << f_drive)) == 0) return(ERR_TRANSFER); 878 879 /* The command is issued by outputting several bytes to the controller chip. 880 */ 881 if (f_device & FORMAT_DEV_BIT) { 882 cmd[0] = FDC_FORMAT; 883 cmd[1] = (fp->fl_head << 2) | f_drive; 884 cmd[2] = fmt_param.sector_size_code; 885 cmd[3] = fmt_param.sectors_per_cylinder; 886 cmd[4] = fmt_param.gap_length_for_format; 887 cmd[5] = fmt_param.fill_byte_for_format; 888 if (fdc_command(cmd, 6) != OK) return(ERR_TRANSFER); 889 } else { 890 cmd[0] = do_write ? FDC_WRITE : FDC_READ; 891 cmd[1] = (fp->fl_head << 2) | f_drive; 892 cmd[2] = fp->fl_cylinder; 893 cmd[3] = fp->fl_head; 894 cmd[4] = BASE_SECTOR + fp->fl_sector; 895 cmd[5] = SECTOR_SIZE_CODE; 896 cmd[6] = f_sectors; 897 cmd[7] = f_dp->gap; /* sector gap */ 898 cmd[8] = DTL; /* data length */ 899 if (fdc_command(cmd, 9) != OK) return(ERR_TRANSFER); 900 } 901 902 /* Block, waiting for disk interrupt. */ 903 if (f_intr_wait() != OK) { 904 printf("fd%u: disk interrupt timed out.\n", f_drive); 905 return(ERR_TIMEOUT); 906 } 907 908 /* Get controller status and check for errors. */ 909 r = fdc_results(); 910 if (r != OK) return(r); 911 912 if (f_results[ST1] & WRITE_PROTECT) { 913 printf("fd%u: diskette is write protected.\n", f_drive); 914 return(ERR_WR_PROTECT); 915 } 916 917 if ((f_results[ST0] & ST0_BITS_TRANS) != TRANS_ST0) return(ERR_TRANSFER); 918 if (f_results[ST1] | f_results[ST2]) return(ERR_TRANSFER); 919 920 if (f_device & FORMAT_DEV_BIT) return(OK); 921 922 /* Compare actual numbers of sectors transferred with expected number. */ 923 s = (f_results[ST_CYL] - fp->fl_cylinder) * NR_HEADS * f_sectors; 924 s += (f_results[ST_HEAD] - fp->fl_head) * f_sectors; 925 s += (f_results[ST_SEC] - BASE_SECTOR - fp->fl_sector); 926 if (s != 1) return(ERR_TRANSFER); 927 928 /* This sector is next for I/O: */ 929 fp->fl_sector = f_results[ST_SEC] - BASE_SECTOR; 930 #if 0 931 if (processor < 386) fp->fl_sector++; /* Old CPU can't keep up. */ 932 #endif 933 return(OK); 934 } 935 936 /*===========================================================================* 937 * fdc_results * 938 *===========================================================================*/ 939 static int fdc_results(void) 940 { 941 /* Extract results from the controller after an operation, then allow floppy 942 * interrupts again. 943 */ 944 945 int s, result_nr; 946 u32_t status; 947 spin_t spin; 948 949 /* Extract bytes from FDC until it says it has no more. The loop is 950 * really an outer loop on result_nr and an inner loop on status. 951 * A timeout flag alarm is set. 952 */ 953 result_nr = 0; 954 SPIN_FOR(&spin, TIMEOUT_MICROS) { 955 /* Reading one byte is almost a mirror of fdc_out() - the DIRECTION 956 * bit must be set instead of clear, but the CTL_BUSY bit destroys 957 * the perfection of the mirror. 958 */ 959 if ((s=sys_inb(FDC_STATUS, &status)) != OK) 960 panic("Sys_inb in fdc_results() failed: %d", s); 961 status &= (MASTER | DIRECTION | CTL_BUSY); 962 if (status == (MASTER | DIRECTION | CTL_BUSY)) { 963 u32_t tmp_r; 964 if (result_nr >= MAX_RESULTS) break; /* too many results */ 965 if ((s=sys_inb(FDC_DATA, &tmp_r)) != OK) 966 panic("Sys_inb in fdc_results() failed: %d", s); 967 f_results[result_nr] = tmp_r; 968 result_nr ++; 969 continue; 970 } 971 if (status == MASTER) { /* all read */ 972 if ((s=sys_irqenable(&irq_hook_id)) != OK) 973 panic("Couldn't enable IRQs: %d", s); 974 975 return(OK); /* only good exit */ 976 } 977 } 978 need_reset = TRUE; /* controller chip must be reset */ 979 980 if ((s=sys_irqenable(&irq_hook_id)) != OK) 981 panic("Couldn't enable IRQs: %d", s); 982 return(ERR_STATUS); 983 } 984 985 /*===========================================================================* 986 * fdc_command * 987 *===========================================================================*/ 988 static int fdc_command( 989 const u8_t *cmd, /* command bytes */ 990 int len /* command length */ 991 ) 992 { 993 /* Output a command to the controller. */ 994 995 /* Set a synchronous alarm to force a timeout if the hardware does 996 * not interrupt. 997 * Note that the actual check is done by the code that issued the 998 * fdc_command() call. 999 */ 1000 set_timer(&f_tmr_timeout, WAKEUP, f_timeout, 0); 1001 1002 f_busy = BSY_IO; 1003 while (len > 0) { 1004 fdc_out(*cmd++); 1005 len--; 1006 } 1007 return(need_reset ? ERR_DRIVE : OK); 1008 } 1009 1010 /*===========================================================================* 1011 * fdc_out * 1012 *===========================================================================*/ 1013 static void fdc_out( 1014 int val /* write this byte to floppy disk controller */ 1015 ) 1016 { 1017 /* Output a byte to the controller. This is not entirely trivial, since you 1018 * can only write to it when it is listening, and it decides when to listen. 1019 * If the controller refuses to listen, the FDC chip is given a hard reset. 1020 */ 1021 spin_t spin; 1022 int s; 1023 u32_t status; 1024 1025 if (need_reset) return; /* if controller is not listening, return */ 1026 1027 /* It may take several tries to get the FDC to accept a command. */ 1028 SPIN_FOR(&spin, TIMEOUT_MICROS) { 1029 if ((s=sys_inb(FDC_STATUS, &status)) != OK) 1030 panic("Sys_inb in fdc_out() failed: %d", s); 1031 1032 if ((status & (MASTER | DIRECTION)) == (MASTER | 0)) { 1033 if ((s=sys_outb(FDC_DATA, val)) != OK) 1034 panic("Sys_outb in fdc_out() failed: %d", s); 1035 1036 return; 1037 } 1038 } 1039 1040 need_reset = TRUE; /* hit it over the head */ 1041 } 1042 1043 /*===========================================================================* 1044 * recalibrate * 1045 *===========================================================================*/ 1046 static int recalibrate(void) 1047 { 1048 /* The floppy disk controller has no way of determining its absolute arm 1049 * position (cylinder). Instead, it steps the arm a cylinder at a time and 1050 * keeps track of where it thinks it is (in software). However, after a 1051 * SEEK, the hardware reads information from the diskette telling where the 1052 * arm actually is. If the arm is in the wrong place, a recalibration is done, 1053 * which forces the arm to cylinder 0. This way the controller can get back 1054 * into sync with reality. 1055 */ 1056 1057 struct floppy *fp = f_fp; 1058 int r; 1059 u8_t cmd[2]; 1060 1061 /* Issue the RECALIBRATE command and wait for the interrupt. */ 1062 cmd[0] = FDC_RECALIBRATE; /* tell drive to recalibrate itself */ 1063 cmd[1] = f_drive; /* specify drive */ 1064 if (fdc_command(cmd, 2) != OK) return(ERR_SEEK); 1065 if (f_intr_wait() != OK) return(ERR_TIMEOUT); 1066 1067 /* Determine if the recalibration succeeded. */ 1068 fdc_out(FDC_SENSE); /* issue SENSE command to request results */ 1069 r = fdc_results(); /* get results of the FDC_RECALIBRATE command*/ 1070 fp->fl_curcyl = NO_CYL; /* force a SEEK next time */ 1071 fp->fl_sector = NO_SECTOR; 1072 if (r != OK || /* controller would not respond */ 1073 (f_results[ST0] & ST0_BITS_SEEK) != SEEK_ST0 || f_results[ST_PCN] != 0) { 1074 /* Recalibration failed. FDC must be reset. */ 1075 need_reset = TRUE; 1076 return(ERR_RECALIBRATE); 1077 } else { 1078 /* Recalibration succeeded. */ 1079 fp->fl_calibration = CALIBRATED; 1080 fp->fl_curcyl = f_results[ST_PCN]; 1081 return(OK); 1082 } 1083 } 1084 1085 /*===========================================================================* 1086 * f_reset * 1087 *===========================================================================*/ 1088 static void f_reset(void) 1089 { 1090 /* Issue a reset to the controller. This is done after any catastrophe, 1091 * like the controller refusing to respond. 1092 */ 1093 pvb_pair_t byte_out[2]; 1094 int s,i; 1095 message mess; 1096 int ipc_status; 1097 1098 /* Disable interrupts and strobe reset bit low. */ 1099 need_reset = FALSE; 1100 1101 /* It is not clear why the next lock is needed. Writing 0 to DOR causes 1102 * interrupt, while the PC documentation says turning bit 8 off disables 1103 * interrupts. Without the lock: 1104 * 1) the interrupt handler sets the floppy mask bit in the 8259. 1105 * 2) writing ENABLE_INT to DOR causes the FDC to assert the interrupt 1106 * line again, but the mask stops the cpu being interrupted. 1107 * 3) the sense interrupt clears the interrupt (not clear which one). 1108 * and for some reason the reset does not work. 1109 */ 1110 (void) fdc_command((u8_t *) 0, 0); /* need only the timer */ 1111 motor_status = 0; 1112 pv_set(byte_out[0], DOR, 0); /* strobe reset bit low */ 1113 pv_set(byte_out[1], DOR, ENABLE_INT); /* strobe it high again */ 1114 if ((s=sys_voutb(byte_out, 2)) != OK) 1115 panic("Sys_voutb in f_reset() failed: %d", s); 1116 1117 /* A synchronous alarm timer was set in fdc_command. Expect an interrupt, 1118 * but be prepared to handle a timeout. 1119 */ 1120 do { 1121 if ((s = driver_receive(ANY, &mess, &ipc_status)) != OK) 1122 panic("Couldn't receive message: %d", s); 1123 if (is_ipc_notify(ipc_status)) { 1124 switch (_ENDPOINT_P(mess.m_source)) { 1125 case CLOCK: 1126 f_expire_tmrs(mess.m_notify.timestamp); 1127 break; 1128 default : 1129 f_busy = BSY_IDLE; 1130 break; 1131 } 1132 } else { /* expect hw interrupt */ 1133 f_busy = BSY_IDLE; 1134 } 1135 } while (f_busy == BSY_IO); 1136 1137 /* The controller supports 4 drives and returns a result for each of them. 1138 * Collect all the results now. The old version only collected the first 1139 * result. This happens to work for 2 drives, but it doesn't work for 3 1140 * or more drives, at least with only drives 0 and 2 actually connected 1141 * (the controller generates an extra interrupt for the middle drive when 1142 * drive 2 is accessed and the driver panics). 1143 * 1144 * It would be better to keep collecting results until there are no more. 1145 * For this, fdc_results needs to return the number of results (instead 1146 * of OK) when it succeeds. 1147 */ 1148 for (i = 0; i < 4; i++) { 1149 fdc_out(FDC_SENSE); /* probe FDC to make it return status */ 1150 (void) fdc_results(); /* flush controller */ 1151 } 1152 for (i = 0; i < NR_DRIVES; i++) /* clear each drive */ 1153 floppy[i].fl_calibration = UNCALIBRATED; 1154 1155 /* The current timing parameters must be specified again. */ 1156 prev_dp = NULL; 1157 } 1158 1159 /*===========================================================================* 1160 * f_intr_wait * 1161 *===========================================================================*/ 1162 static int f_intr_wait(void) 1163 { 1164 /* Wait for an interrupt, but not forever. The FDC may have all the time of 1165 * the world, but we humans do not. 1166 */ 1167 message mess; 1168 int r, ipc_status; 1169 1170 /* We expect an interrupt, but if a timeout, occurs, report an error. */ 1171 do { 1172 if ((r = driver_receive(ANY, &mess, &ipc_status)) != OK) 1173 panic("Couldn't receive message: %d", r); 1174 if (is_ipc_notify(ipc_status)) { 1175 switch (_ENDPOINT_P(mess.m_source)) { 1176 case CLOCK: 1177 f_expire_tmrs(mess.m_notify.timestamp); 1178 break; 1179 default : 1180 f_busy = BSY_IDLE; 1181 break; 1182 } 1183 } else { 1184 f_busy = BSY_IDLE; 1185 } 1186 } while (f_busy == BSY_IO); 1187 1188 if (f_busy == BSY_WAKEN) { 1189 1190 /* No interrupt from the FDC, this means that there is probably no 1191 * floppy in the drive. Get the FDC down to earth and return error. 1192 */ 1193 need_reset = TRUE; 1194 return(ERR_TIMEOUT); 1195 } 1196 return(OK); 1197 } 1198 1199 /*===========================================================================* 1200 * f_timeout * 1201 *===========================================================================*/ 1202 static void f_timeout(minix_timer_t *UNUSED(tp)) 1203 { 1204 /* This routine is called when a timer expires. Usually to tell that a 1205 * motor has spun up, but also to forge an interrupt when it takes too long 1206 * for the FDC to interrupt (no floppy in the drive). It sets a flag to tell 1207 * what has happened. 1208 */ 1209 if (f_busy == BSY_IO) { 1210 f_busy = BSY_WAKEN; 1211 } 1212 } 1213 1214 /*===========================================================================* 1215 * read_id * 1216 *===========================================================================*/ 1217 static int read_id(void) 1218 { 1219 /* Determine current cylinder and sector. */ 1220 1221 struct floppy *fp = f_fp; 1222 int result; 1223 u8_t cmd[2]; 1224 1225 /* Never attempt a read id if the drive is uncalibrated or motor is off. */ 1226 if (fp->fl_calibration == UNCALIBRATED) return(ERR_READ_ID); 1227 if ((motor_status & (1 << f_drive)) == 0) return(ERR_READ_ID); 1228 1229 /* The command is issued by outputting 2 bytes to the controller chip. */ 1230 cmd[0] = FDC_READ_ID; /* issue the read id command */ 1231 cmd[1] = (fp->fl_head << 2) | f_drive; 1232 if (fdc_command(cmd, 2) != OK) return(ERR_READ_ID); 1233 if (f_intr_wait() != OK) return(ERR_TIMEOUT); 1234 1235 /* Get controller status and check for errors. */ 1236 result = fdc_results(); 1237 if (result != OK) return(result); 1238 1239 if ((f_results[ST0] & ST0_BITS_TRANS) != TRANS_ST0) return(ERR_READ_ID); 1240 if (f_results[ST1] | f_results[ST2]) return(ERR_READ_ID); 1241 1242 /* The next sector is next for I/O: */ 1243 fp->fl_sector = f_results[ST_SEC] - BASE_SECTOR + 1; 1244 return(OK); 1245 } 1246 1247 /*===========================================================================* 1248 * f_do_open * 1249 *===========================================================================*/ 1250 static int f_do_open(devminor_t minor, int UNUSED(access)) 1251 { 1252 /* Handle an open on a floppy. Determine diskette type if need be. */ 1253 1254 int dtype; 1255 struct test_order *top; 1256 1257 /* Decode the message parameters. */ 1258 if (f_prepare(minor) == NULL) return(ENXIO); 1259 1260 dtype = f_device & DEV_TYPE_BITS; /* get density from minor dev */ 1261 if (dtype >= MINOR_fd0p0) dtype = 0; 1262 1263 if (dtype != 0) { 1264 /* All types except 0 indicate a specific drive/medium combination.*/ 1265 dtype = (dtype >> DEV_TYPE_SHIFT) - 1; 1266 if (dtype >= NT) return(ENXIO); 1267 f_fp->fl_density = dtype; 1268 (void) f_prepare(f_device); /* Recompute parameters. */ 1269 return(OK); 1270 } 1271 if (f_device & FORMAT_DEV_BIT) return(EIO); /* Can't format /dev/fdN */ 1272 1273 /* The device opened is /dev/fdN. Experimentally determine drive/medium. 1274 * First check fl_density. If it is not NO_DENS, the drive has been used 1275 * before and the value of fl_density tells what was found last time. Try 1276 * that first. If the motor is still running then assume nothing changed. 1277 */ 1278 if (f_fp->fl_density != NO_DENS) { 1279 if (motor_status & (1 << f_drive)) return(OK); 1280 if (test_read(f_fp->fl_density) == OK) return(OK); 1281 } 1282 1283 /* Either drive type is unknown or a different diskette is now present. 1284 * Use test_order to try them one by one. 1285 */ 1286 for (top = &test_order[0]; top < &test_order[NT-1]; top++) { 1287 dtype = top->t_density; 1288 1289 /* Skip densities that have been proven to be impossible */ 1290 if (!(f_fp->fl_class & (1 << dtype))) continue; 1291 1292 if (test_read(dtype) == OK) { 1293 /* The test succeeded, use this knowledge to limit the 1294 * drive class to match the density just read. 1295 */ 1296 f_fp->fl_class &= top->t_class; 1297 return(OK); 1298 } 1299 /* Test failed, wrong density or did it time out? */ 1300 if (f_busy == BSY_WAKEN) break; 1301 } 1302 f_fp->fl_density = NO_DENS; 1303 return(EIO); /* nothing worked */ 1304 } 1305 1306 /*===========================================================================* 1307 * f_do_close * 1308 *===========================================================================*/ 1309 static int f_do_close(devminor_t UNUSED(minor)) 1310 { 1311 /* Handle a close on a floppy. Nothing to do here. */ 1312 1313 return(OK); 1314 } 1315 1316 /*===========================================================================* 1317 * test_read * 1318 *===========================================================================*/ 1319 static int test_read(int density) 1320 { 1321 /* Try to read the highest numbered sector on cylinder 2. Not all floppy 1322 * types have as many sectors per track, and trying cylinder 2 finds the 1323 * ones that need double stepping. 1324 */ 1325 int device; 1326 off_t position; 1327 iovec_t iovec1; 1328 ssize_t result; 1329 1330 f_fp->fl_density = density; 1331 device = ((density + 1) << DEV_TYPE_SHIFT) + f_drive; 1332 1333 (void) f_prepare(device); 1334 position = (off_t) f_dp->test << SECTOR_SHIFT; 1335 iovec1.iov_addr = (vir_bytes) floppy_buf; 1336 iovec1.iov_size = SECTOR_SIZE; 1337 result = f_transfer(device, FALSE /*do_write*/, position, SELF, 1338 &iovec1, 1, BDEV_NOFLAGS); 1339 1340 if (result != SECTOR_SIZE) return(EIO); 1341 1342 partition(&f_dtab, f_drive, P_FLOPPY, 0); 1343 return(OK); 1344 } 1345 1346 /*===========================================================================* 1347 * f_geometry * 1348 *===========================================================================*/ 1349 static void f_geometry(devminor_t minor, struct part_geom *entry) 1350 { 1351 if (f_prepare(minor) == NULL) return; 1352 1353 entry->cylinders = f_dp->cyls; 1354 entry->heads = NR_HEADS; 1355 entry->sectors = f_sectors; 1356 } 1357