|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1992 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * File: fdi_82077_hdw.c ! 28: * Author: Alessandro Forin, Carnegie Mellon University ! 29: * Date: 1/92 ! 30: * ! 31: * Driver for the Intel 82077 Floppy Disk Controller. ! 32: */ ! 33: ! 34: #include <fd.h> ! 35: #if NFD > 0 ! 36: ! 37: #include <mach/std_types.h> ! 38: #include <machine/machspl.h> ! 39: #include <chips/busses.h> ! 40: ! 41: #include <chips/fdc_82077.h> ! 42: #include <platforms.h> ! 43: ! 44: /* ---- */ ! 45: #include <device/param.h> ! 46: #include <device/io_req.h> ! 47: #include <device/device_types.h> ! 48: #include <device/disk_status.h> ! 49: #define UNITNO(d) ((d)>>5) ! 50: #define SLAVENO(d) (((d)>>3)&0x3) ! 51: #define PARAMNO(d) ((d)&0x7) ! 52: /* ---- */ ! 53: ! 54: #ifdef MAXINE ! 55: ! 56: /* we can only take one */ ! 57: #define MAX_DRIVES 1 ! 58: ! 59: #define my_fdc_type fdc_82077aa ! 60: #define the_fdc_type fd->fdc_type ! 61: /* later: #define the_fdc_type my_fdc_type */ ! 62: ! 63: /* Registers are read/written as words, byte 0 */ ! 64: /* padding is to x40 boundaries */ ! 65: typedef struct { ! 66: volatile unsigned int fd_sra; /* r: status register A */ ! 67: int pad0[15]; ! 68: volatile unsigned int fd_srb; /* r: status register B */ ! 69: int pad1[15]; ! 70: volatile unsigned int fd_dor; /* rw: digital output reg */ ! 71: int pad2[15]; ! 72: volatile unsigned int fd_tdr; /* rw: tape drive register */ ! 73: int pad3[15]; ! 74: volatile unsigned int fd_msr; /* r: main status register */ ! 75: /*#define fd_dsr fd_msr; /* w: data rate select reg */ ! 76: int pad4[15]; ! 77: volatile unsigned int fd_data; /* rw: fifo */ ! 78: int pad5[15]; ! 79: volatile unsigned int fd_xxx; /* --reserved-- */ ! 80: int pad6[15]; ! 81: volatile unsigned int fd_dir; /* r: digital input reg */ ! 82: /*#define fd_ccr fd_dir; /* w: config control reg */ ! 83: } fd_padded_regmap_t; ! 84: ! 85: #define machdep_reset_8272a(f,r) ! 86: ! 87: #else /* MAXINE */ ! 88: ! 89: /* Pick your chip and padding */ ! 90: #define my_fdc_type fdc_8272a ! 91: #define the_fdc_type my_fdc_type ! 92: ! 93: #define fd_padded_regmap_t fd_8272a_regmap_t ! 94: ! 95: #define machdep_reset_8272a(f,r) 1 ! 96: ! 97: #endif /* MAXINE */ ! 98: ! 99: ! 100: #ifndef MAX_DRIVES ! 101: #define MAX_DRIVES DRIVES_PER_FDC ! 102: #endif ! 103: ! 104: /* ! 105: * Autoconf info ! 106: */ ! 107: ! 108: static vm_offset_t fd_std[NFD] = { 0 }; ! 109: static struct bus_device *fd_info[NFD]; ! 110: static struct bus_ctlr *fd_minfo[NFD]; ! 111: static int fd_probe(), fd_slave(), fd_go(); ! 112: static void fd_attach(); ! 113: ! 114: struct bus_driver fd_driver = ! 115: { fd_probe, fd_slave, fd_attach, fd_go, fd_std, "fd", fd_info, ! 116: "fdc", fd_minfo, /*BUS_INTR_B4_PROBE*/}; ! 117: ! 118: /* ! 119: * Externally visible functions ! 120: */ ! 121: int fd_intr(); /* kernel */ ! 122: ! 123: /* ! 124: * Media table ! 125: * ! 126: * Cyls,Sec,spc,part,Mtype,RWFpl,FGpl ! 127: */ ! 128: typedef struct { ! 129: unsigned char d_cylperunit; ! 130: unsigned char d_secpercyl; ! 131: unsigned short d_secperunit; ! 132: unsigned char d_secpertrk; ! 133: unsigned char d_gpl; ! 134: unsigned char d_fgpl; ! 135: unsigned char d_xfer_rate; ! 136: } fd_params_t; ! 137: ! 138: fd_params_t fd_params[8] = { ! 139: {80, 18, 1440, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [0] 3.50" 720 Kb */ ! 140: {80, 36, 2880, 18, 0x1b, 0x6c, FD_DSR_DD_500}, /* [1] 3.50" 1.44 Meg */ ! 141: {40, 18, 720, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [2] 5.25" 360 Kb */ ! 142: {80, 30, 2400, 15, 0x1b, 0x54, FD_DSR_DD_500}, /* [3] 5.25" 1.20 Meg */ ! 143: }; ! 144: ! 145: /* ! 146: * Software status of chip ! 147: */ ! 148: struct fd_softc { ! 149: fd_padded_regmap_t *regs; ! 150: char fdc_type; ! 151: char fdc_mode; ! 152: char messed_up; ! 153: char slave_active; ! 154: struct slave_t { ! 155: io_req_t ior; ! 156: decl_simple_lock_data(,slave_lock) ! 157: ! 158: /* status at end of last command */ ! 159: unsigned char st0; ! 160: unsigned char st1; ! 161: unsigned char st2; ! 162: unsigned char c; ! 163: unsigned char h; ! 164: unsigned char r; ! 165: unsigned char n; ! 166: unsigned char st3; ! 167: /* ... */ ! 168: unsigned char medium_status; ! 169: # define ST_MEDIUM_PRESENT 1 ! 170: # define ST_MEDIUM_KNOWN 2 ! 171: char last_command; ! 172: char bytes_expected; ! 173: fd_params_t *params; ! 174: ! 175: } slave_status[DRIVES_PER_FDC]; ! 176: } fd_softc_data[NFD]; ! 177: ! 178: typedef struct fd_softc *fd_softc_t; ! 179: ! 180: fd_softc_t fd_softc[NFD]; ! 181: ! 182: static char *chip_names[4] = { "8272-A", "82072", "82077-AA", 0 }; ! 183: static char *mode_names[4] = { "PC AT", "PS/2", "Model 30", 0 }; ! 184: ! 185: /* ! 186: * Probe chip to see if it is there ! 187: */ ! 188: static fd_probe (reg, ctlr) ! 189: vm_offset_t reg; ! 190: struct bus_ctlr *ctlr; ! 191: { ! 192: int unit = ctlr->unit; ! 193: fd_softc_t fd; ! 194: fd_padded_regmap_t *regs; ! 195: ! 196: /* ! 197: * See if we are here ! 198: */ ! 199: if (check_memory(reg, 0)) { ! 200: /* no rides today */ ! 201: return 0; ! 202: } ! 203: ! 204: fd = &fd_softc_data[unit]; ! 205: fd_softc[unit] = fd; ! 206: ! 207: regs = (fd_padded_regmap_t *)reg; ! 208: fd->regs = regs; ! 209: fd->fdc_type = my_fdc_type; ! 210: ! 211: fd_reset(fd); ! 212: ! 213: if (the_fdc_type == fdc_82077aa) { ! 214: /* See if properly functioning */ ! 215: unsigned char temp = FD_CMD_VERSION; ! 216: if (!fd_go(fd, 0, &temp, 1, 1)) ! 217: return 0; /* total brxage */ ! 218: if (!fd_get_result(fd, &temp, 1, FALSE)) ! 219: return 0; /* partial brxage */ ! 220: if (temp != FD_VERSION_82077AA) ! 221: printf( "{ %s x%x } ", ! 222: "Accepting non-82077aa version id", ! 223: temp); ! 224: } ! 225: ! 226: printf("%s%d: %s chip controller", ! 227: ctlr->name, ctlr->unit, chip_names[fd->fdc_type]); ! 228: if (the_fdc_type == fdc_82077aa) ! 229: printf(" in %s mode", mode_names[fd->fdc_mode]); ! 230: printf(".\n"); ! 231: ! 232: return 1; ! 233: } ! 234: ! 235: /* See if we like this slave */ ! 236: static fd_slave(ui, reg) ! 237: struct bus_device *ui; ! 238: vm_offset_t reg; ! 239: { ! 240: int slave = ui->slave; ! 241: fd_softc_t fd; ! 242: unsigned char sns[2]; ! 243: ! 244: if (slave >= MAX_DRIVES) return 0; ! 245: ! 246: fd = fd_softc[ui->ctlr]; ! 247: ! 248: sns[0] = FD_CMD_SENSE_DRIVE_STATUS; ! 249: sns[1] = slave & 0x3; ! 250: if (the_fdc_type == fdc_82072) ! 251: sns[1] |= FD_CMD_SDS_NO_MOT; ! 252: if (!fd_go(fd, slave, sns, 2, 1)) return 0; ! 253: if (!fd_get_result(fd, sns, 1, FALSE)) return 0; ! 254: ! 255: fd->slave_status[slave].st3 = sns[0]; ! 256: ! 257: return 1; ! 258: } ! 259: ! 260: static void ! 261: fd_attach (ui) ! 262: struct bus_device *ui; ! 263: { ! 264: /* Attach a slave */ ! 265: } ! 266: ! 267: static boolean_t ! 268: fd_go(fd, slave, cmd, cmdlen, reply_count) ! 269: fd_softc_t fd; ! 270: unsigned char cmd[]; ! 271: { ! 272: ! 273: /* XXX check who active, enque ifnot */ ! 274: ! 275: fd->slave_active = slave; ! 276: fd->slave_status[slave].bytes_expected = reply_count; ! 277: fd->slave_status[slave].last_command = *cmd; ! 278: return fd_command(fd, cmd, cmdlen); ! 279: } ! 280: ! 281: fd_intr (unit, spllevel) ! 282: { ! 283: fd_softc_t fd; ! 284: fd_padded_regmap_t *regs; ! 285: unsigned char msr; ! 286: register struct slave_t *slv; ! 287: ! 288: ! 289: splx(spllevel); ! 290: ! 291: fd = fd_softc[unit]; ! 292: regs = fd->regs; ! 293: ! 294: /* did polling see a media change */ ! 295: /* busy bit in msr sez ifasync or not */ ! 296: ! 297: msr = regs->fd_msr; ! 298: if ((msr & (FD_MSR_RQM|FD_MSR_DIO)) == (FD_MSR_RQM|FD_MSR_DIO)) { ! 299: ! 300: /* result phase */ ! 301: *(unsigned int *)0xbc040100 &= ~0x00600000; ! 302: ! 303: slv = &fd->slave_status[fd->slave_active]; ! 304: fd_get_result(fd, &slv->st0, slv->bytes_expected, FALSE); ! 305: fd_start(fd, fd->slave_active, TRUE); ! 306: return; ! 307: } ! 308: /* async interrupt, either seek complete or media change */ ! 309: while (1) { ! 310: unsigned char st[2]; ! 311: register int slave, m; ! 312: ! 313: *st = FD_CMD_SENSE_INT_STATUS; ! 314: fd_command(fd, st, 1); ! 315: ! 316: fd_get_result(fd, st, 2, FALSE); ! 317: ! 318: slave = *st & FD_ST0_DS; ! 319: slv = &fd->slave_status[slave]; ! 320: slv->c = st[1]; ! 321: ! 322: switch (*st & FD_ST0_IC_MASK) { ! 323: ! 324: case FD_ST0_IC_OK: ! 325: /* we get an FD_ST0_SE for RECALIBRATE. Wait for it or discard ? */ ! 326: ! 327: case FD_ST0_IC_AT: ! 328: ! 329: case FD_ST0_IC_BAD_CMD: ! 330: return; ! 331: ! 332: case FD_ST0_IC_AT_POLL: ! 333: m = slv->medium_status; ! 334: if (m & ST_MEDIUM_PRESENT) ! 335: m &= ~ST_MEDIUM_PRESENT; ! 336: else ! 337: m |= ST_MEDIUM_PRESENT; ! 338: slv->medium_status = m; ! 339: } ! 340: } ! 341: } ! 342: ! 343: /* ! 344: * Non-interface functions and utilities ! 345: */ ! 346: ! 347: fd_reset(fd) ! 348: fd_softc_t fd; ! 349: { ! 350: register fd_padded_regmap_t *regs; ! 351: ! 352: regs = fd->regs; ! 353: ! 354: /* ! 355: * Reset the chip ! 356: */ ! 357: if (the_fdc_type == fdc_82072) ! 358: /* Fix if your box uses an external PLL */ ! 359: regs->fd_dsr = FD_DSR_RESET | FD_DSR_EPLL; ! 360: else if (the_fdc_type == fdc_82077aa) ! 361: regs->fd_dor = 0; ! 362: else ! 363: machdep_reset_8272a(fd, regs); ! 364: ! 365: delay(5); /* 4usecs in specs */ ! 366: ! 367: /* ! 368: * Be smart with the smart ones ! 369: */ ! 370: if (the_fdc_type == fdc_82077aa) { ! 371: ! 372: /* ! 373: * See in which mood we are (it cannot be changed) ! 374: */ ! 375: int temp; ! 376: ! 377: /* Take chip out of hw reset */ ! 378: regs->fd_dor = FD_DOR_ENABLE | FD_DOR_DMA_GATE; ! 379: delay(10); ! 380: ! 381: /* what do we readback from the DIR register as datarate ? */ ! 382: regs->fd_ccr = FD_DSR_SD_125; ! 383: delay(10); ! 384: ! 385: temp = regs->fd_dir; ! 386: if ((temp & 0x7) == FD_DSR_SD_125) ! 387: fd->fdc_mode = mod30_mode; ! 388: else if ((temp & (FD_DIR_ones | FD_DIR_DR_MASK_PS2)) == ! 389: ((FD_DSR_SD_125 << FD_DIR_DR_SHIFT_PS2) | FD_DIR_ones)) ! 390: fd->fdc_mode = ps2_mode; ! 391: else ! 392: /* this assumes tri-stated bits 1&2 read the same */ ! 393: fd->fdc_mode = at_mode; ! 394: ! 395: } ! 396: ! 397: /* ! 398: * Send at least 4 sense interrupt cmds, one per slave ! 399: */ ! 400: { ! 401: ! 402: unsigned char sns, st[2]; ! 403: int i, nloops; ! 404: ! 405: sns = FD_CMD_SENSE_INT_STATUS; ! 406: i = nloops = 0; ! 407: ! 408: do { ! 409: nloops++; ! 410: ! 411: (void) fd_command(fd, &sns, 1); ! 412: ! 413: st[0] = 0; /* in case bad status */ ! 414: (void) fd_get_result(fd, st, 2, TRUE); ! 415: ! 416: if ((st[0] & FD_ST0_IC_MASK) == FD_ST0_IC_AT_POLL) { ! 417: register int slave; ! 418: ! 419: slave = st[0] & FD_ST0_DS; ! 420: fd->slave_status[slave].st0 = st[0]; ! 421: fd->slave_status[slave].c = st[1]; ! 422: i++; ! 423: } ! 424: } while ( (nloops < 30) && ! 425: ((i < 4) || (st[0] != FD_ST0_IC_BAD_CMD)) ); ! 426: ! 427: /* sanity check */ ! 428: if (nloops == 30) { ! 429: (void) fd_messed_up(fd); ! 430: return; ! 431: } ! 432: } ! 433: ! 434: /* ! 435: * Install current parameters ! 436: */ ! 437: if (the_fdc_type != fdc_8272a) { ! 438: ! 439: unsigned char cnf[4]; ! 440: ! 441: /* send configure command to turn polling off */ ! 442: cnf[0] = FD_CMD_CONFIGURE; ! 443: cnf[1] = 0x60; /* moff 110 */ ! 444: cnf[2] = 0x48; /* eis, poll, thr=8 */ ! 445: cnf[3] = 0; ! 446: if (!fd_command(fd, cnf, 4)) ! 447: return; ! 448: /* no status */ ! 449: } ! 450: ! 451: /* ! 452: * Send specify to select defaults ! 453: */ ! 454: { ! 455: unsigned char sfy[3]; ! 456: ! 457: sfy[0] = FD_CMD_SPECIFY; ! 458: #if 0 ! 459: sfy[1] = (12 << 4) | 7; /* step 4, hut 112us @500 */ ! 460: sfy[2] = 2 << 1; /* hlt 29us @500 */ ! 461: #else ! 462: sfy[1] = (13 << 4) | 15; ! 463: sfy[2] = 1 << 1; ! 464: #endif ! 465: (void) fd_command(fd, sfy, 3); ! 466: /* no status */ ! 467: } ! 468: } ! 469: ! 470: #define FD_MAX_WAIT 1000 ! 471: ! 472: boolean_t ! 473: fd_command(fd, cmd, cmd_len) ! 474: fd_softc_t fd; ! 475: char *cmd; ! 476: { ! 477: register fd_padded_regmap_t *regs; ! 478: ! 479: regs = fd->regs; ! 480: ! 481: while (cmd_len > 0) { ! 482: register int i, s; ! 483: ! 484: /* there might be long delays, so we pay this price */ ! 485: s = splhigh(); ! 486: for (i = 0; i < FD_MAX_WAIT; i++) ! 487: if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) == ! 488: FD_MSR_RQM) ! 489: break; ! 490: else ! 491: delay(10); ! 492: if (i == FD_MAX_WAIT) { ! 493: splx(s); ! 494: return fd_messed_up(fd); ! 495: } ! 496: regs->fd_data = *cmd++; ! 497: splx(s); ! 498: if (--cmd_len) delay(12); ! 499: } ! 500: ! 501: return TRUE; ! 502: } ! 503: ! 504: boolean_t ! 505: fd_get_result(fd, st, st_len, ignore_errors) ! 506: fd_softc_t fd; ! 507: char *st; ! 508: { ! 509: register fd_padded_regmap_t *regs; ! 510: ! 511: regs = fd->regs; ! 512: ! 513: while (st_len > 0) { ! 514: register int i, s; ! 515: ! 516: /* there might be long delays, so we pay this price */ ! 517: s = splhigh(); ! 518: for (i = 0; i < FD_MAX_WAIT; i++) ! 519: if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) == ! 520: (FD_MSR_RQM|FD_MSR_DIO)) ! 521: break; ! 522: else ! 523: delay(10); ! 524: if (i == FD_MAX_WAIT) { ! 525: splx(s); ! 526: return (ignore_errors) ? FALSE : fd_messed_up(fd); ! 527: } ! 528: *st++ = regs->fd_data; ! 529: splx(s); ! 530: st_len--; ! 531: } ! 532: ! 533: return TRUE; ! 534: } ! 535: ! 536: ! 537: boolean_t ! 538: fd_messed_up(fd) ! 539: fd_softc_t fd; ! 540: { ! 541: fd->messed_up++; ! 542: printf("fd%d: messed up, disabling.\n", fd - fd_softc_data); ! 543: /* here code to ! 544: ior->error = ..; ! 545: restart ! 546: */ ! 547: return FALSE; ! 548: } ! 549: ! 550: /* ! 551: * Debugging aids ! 552: */ ! 553: ! 554: fd_state(unit) ! 555: { ! 556: fd_softc_t fd = fd_softc[unit]; ! 557: fd_padded_regmap_t *regs; ! 558: ! 559: if (!fd || !fd->regs) return 0; ! 560: regs = fd->regs; ! 561: if (the_fdc_type == fdc_8272a) ! 562: printf("msr %x\n", regs->fd_msr); ! 563: else ! 564: printf("sra %x srb %x dor %x tdr %x msr %x dir %x\n", ! 565: regs->fd_sra, regs->fd_srb, regs->fd_dor, ! 566: regs->fd_tdr, regs->fd_msr, regs->fd_dir); ! 567: } ! 568: ! 569: #endif ! 570: ! 571: /* to be moved in separate file, or the above modified to live with scsi */ ! 572: ! 573: fd_open(dev, mode, ior) ! 574: int dev; ! 575: dev_mode_t mode; ! 576: io_req_t ior; ! 577: { ! 578: unsigned char cmd[2]; ! 579: fd_softc_t fd; ! 580: int slave; ! 581: ! 582: fd = fd_softc[UNITNO(dev)]; ! 583: slave = SLAVENO(dev); ! 584: ! 585: /* XXX find out what medium we have, automagically XXX */ ! 586: /* fornow, set params depending on minor */ ! 587: fd->slave_status[slave].params = &fd_params[PARAMNO(dev)]; ! 588: ! 589: /* XXXYYYXXXYYY SEND CONFIGURE if params changed */ ! 590: ! 591: /* Turn motor on */ ! 592: if (the_fdc_type == fdc_82072) { ! 593: ! 594: cmd[0] = FD_CMD_MOTOR_ON_OFF | FD_CMD_MOT_ON | ! 595: ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS); ! 596: (void) fd_go(fd, slave, cmd, 1, 0); ! 597: /* no status */ ! 598: ! 599: } else if (the_fdc_type == fdc_82077aa) { ! 600: ! 601: fd->regs->fd_dor |= ((1<<slave)<<4); ! 602: } ! 603: ! 604: /* recalibrate to track 0 */ ! 605: cmd[0] = FD_CMD_RECALIBRATE; ! 606: cmd[1] = slave; ! 607: if (!fd_go(fd, slave, cmd, 2, 0)) ! 608: return D_DEVICE_DOWN; ! 609: /* will generate a completion interrupt */ ! 610: ! 611: /* if not writeable return D_READ_ONLY ? */ ! 612: ! 613: return D_SUCCESS; ! 614: } ! 615: ! 616: fd_close(dev) ! 617: int dev; ! 618: { ! 619: fd_softc_t fd; ! 620: register int slave; ! 621: unsigned char cmd[2]; ! 622: ! 623: slave = SLAVENO(dev); ! 624: fd = fd_softc[UNITNO(dev)]; ! 625: ! 626: /* do not delete media info, do that iff interrupt sez changed */ ! 627: ! 628: /* Turn motor off */ ! 629: if (the_fdc_type == fdc_82072) { ! 630: ! 631: cmd[0] = FD_CMD_MOTOR_ON_OFF | ! 632: ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS); ! 633: (void) fd_go(fd, 0, cmd, 1, 0); ! 634: /* no status */ ! 635: ! 636: } else if (the_fdc_type == fdc_82077aa) { ! 637: ! 638: fd->regs->fd_dor &= ~((1<<slave)<<4); ! 639: } ! 640: return D_SUCCESS; ! 641: } ! 642: ! 643: fd_strategy(ior) ! 644: io_req_t ior; ! 645: { ! 646: #if 0 ! 647: if (ior->io_op & IO_READ) ! 648: bzero(ior->io_data, ior->io_count); ! 649: iodone(ior); ! 650: #else ! 651: struct slave_t *slv; ! 652: fd_softc_t fd; ! 653: unsigned int i, rec, max, dev; ! 654: fd_params_t *params; ! 655: ! 656: /* readonly */ ! 657: ! 658: dev = ior->io_unit; ! 659: ! 660: /* only one partition */ ! 661: fd = fd_softc[UNITNO(dev)]; ! 662: slv = &fd->slave_status[SLAVENO(dev)]; ! 663: params = slv->params; ! 664: max = params->d_secperunit; ! 665: rec = ior->io_recnum; ! 666: i = btodb(ior->io_count + DEV_BSIZE - 1); ! 667: if (((rec + i) > max) || (ior->io_count < 0)) { ! 668: ior->io_error = D_INVALID_SIZE; ! 669: ior->io_op |= IO_ERROR; ! 670: ior->io_residual = ior->io_count; ! 671: iodone(ior); ! 672: return; ! 673: } ! 674: ! 675: ior->io_residual = rec / params->d_secpercyl; ! 676: ! 677: /* ! 678: * Enqueue operation ! 679: */ ! 680: i = splbio(); ! 681: simple_lock(&slv->slave_lock); ! 682: if (slv->ior) { ! 683: disksort(slv->ior, ior); ! 684: simple_unlock(&slv->slave_lock); ! 685: } else { ! 686: ior->io_next = 0; ! 687: slv->ior = ior; ! 688: simple_unlock(&slv->slave_lock); ! 689: fd_start(fd, SLAVENO(dev), FALSE); ! 690: } ! 691: splx(i); ! 692: #endif ! 693: } ! 694: ! 695: fd_start(fd, slave, done) ! 696: boolean_t done; ! 697: fd_softc_t fd; ! 698: { ! 699: register io_req_t ior; ! 700: struct slave_t *slv; ! 701: ! 702: slv = &fd->slave_status[slave]; ! 703: if ((ior = slv->ior) == 0) ! 704: return; ! 705: ! 706: if (done) { ! 707: /* .. errors .. */ ! 708: /* .. partial xfers .. */ ! 709: ! 710: /* dequeue next one */ ! 711: { ! 712: io_req_t next; ! 713: ! 714: simple_lock(&slv->target_lock); ! 715: next = ior->io_next; ! 716: slv->ior = next; ! 717: simple_unlock(&slv->target_lock); ! 718: ! 719: iodone(ior); ! 720: if (next == 0) ! 721: return; ! 722: ! 723: ior = next; ! 724: } ! 725: } ! 726: ! 727: #ifdef no_eis ! 728: if (slv->c != ior->io_residual) SEEK_it; ! 729: #endif ! 730: ! 731: /* setup dma */ ! 732: #if 1 ! 733: if (ior->io_op & IO_READ) /* like SCSI */ ! 734: #else ! 735: if ((ior->io_op & IO_READ) == 0) ! 736: #endif ! 737: { ! 738: *(unsigned int *)0xbc040100 |= 0x00200000 | 0x00400000; ! 739: } else { ! 740: *(unsigned int *)0xbc040100 &= ~0x00400000; ! 741: *(unsigned int *)0xbc040100 |= 0x00200000; ! 742: } ! 743: *(unsigned int *)0xbc040070 = (((unsigned int)kvtophys(ior->io_data))>>2)<<5; ! 744: *(unsigned int *)0xbc0401a0 = 13; ! 745: ! 746: #ifdef no_eis ! 747: if (slv->c == ior->io_residual) { ! 748: #else ! 749: { ! 750: #endif ! 751: unsigned char cmd[9]; ! 752: unsigned char head, sec; ! 753: fd_params_t *params; ! 754: ! 755: params = slv->params; ! 756: ! 757: fd->regs->fd_dsr = params->d_xfer_rate; ! 758: ! 759: sec = ior->io_recnum % params->d_secpercyl; ! 760: head = sec / params->d_secpertrk; ! 761: sec = (sec % params->d_secpertrk); ! 762: ! 763: cmd[0] = (ior->io_op & IO_READ) ? ! 764: FD_CMD_MT | FD_CMD_MFM | FD_CMD_READ_DATA : ! 765: FD_CMD_MT | FD_CMD_MFM | FD_CMD_WRITE_DATA; ! 766: cmd[1] = (head << 2) | slave; ! 767: cmd[2] = ior->io_residual; ! 768: cmd[3] = head; ! 769: cmd[4] = sec + 1; /* 0 starts at 1 :-) */ ! 770: cmd[5] = 0x2; /* 512 byte sectors */ ! 771: cmd[6] = params->d_secpertrk; ! 772: cmd[7] = params->d_gpl; ! 773: cmd[8] = 0xff; ! 774: ! 775: fd_go( fd, slave, cmd, 9, 7); ! 776: ! 777: } ! 778: } ! 779: ! 780: extern minphys(); ! 781: ! 782: fd_read(dev, ior) ! 783: int dev; ! 784: io_req_t ior; ! 785: { ! 786: return block_io(fd_strategy, minphys, ior); ! 787: } ! 788: ! 789: int fdc_write_enable = 1; ! 790: ! 791: fd_write(dev, ior) ! 792: int dev; ! 793: io_req_t ior; ! 794: { ! 795: /* check if writeable */ ! 796: ! 797: if (fdc_write_enable) ! 798: return block_io(fd_strategy, minphys, ior); ! 799: else return D_SUCCESS; ! 800: } ! 801: ! 802: fd_set_status(dev, flavor, status, status_count) ! 803: int dev; ! 804: int flavor; ! 805: dev_status_t status; ! 806: unsigned int *status_count; ! 807: { ! 808: printf("fdc_set_status(%x, %x, %x, %x)", dev, flavor, status, status_count); ! 809: return D_SUCCESS; ! 810: } ! 811: ! 812: fd_get_status(dev, flavor, status, status_count) ! 813: int dev; ! 814: int flavor; ! 815: dev_status_t status; ! 816: unsigned int status_count; ! 817: { ! 818: printf("fdc_get_status(%x, %x, %x, %x)", dev, flavor, status, status_count); ! 819: return D_SUCCESS; ! 820: } ! 821:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.