fdc.c (0e17a5bcdb67947fa764ed9bd651e9d55b9cc149) | fdc.c (246ed35d55139bbc97f5fb1d2132fb62031be1ad) |
---|---|
1/* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 69 unchanged lines hidden (view full) --- 78 79#include <machine/clock.h> 80#include <machine/resource.h> 81#include <machine/stdarg.h> 82 83#include <isa/isavar.h> 84#include <isa/isareg.h> 85#include <isa/fdreg.h> | 1/* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 69 unchanged lines hidden (view full) --- 78 79#include <machine/clock.h> 80#include <machine/resource.h> 81#include <machine/stdarg.h> 82 83#include <isa/isavar.h> 84#include <isa/isareg.h> 85#include <isa/fdreg.h> |
86#include <isa/fdc.h> | |
87#include <isa/rtc.h> 88 | 86#include <isa/rtc.h> 87 |
88enum fdc_type 89{ 90 FDC_NE765, FDC_I82077, FDC_NE72065, FDC_UNKNOWN = -1 91}; 92 93enum fdc_states { 94 DEVIDLE, 95 FINDWORK, 96 DOSEEK, 97 SEEKCOMPLETE , 98 IOCOMPLETE, 99 RECALCOMPLETE, 100 STARTRECAL, 101 RESETCTLR, 102 SEEKWAIT, 103 RECALWAIT, 104 MOTORWAIT, 105 IOTIMEDOUT, 106 RESETCOMPLETE, 107 PIOREAD 108}; 109 110#ifdef FDC_DEBUG 111static char const * const fdstates[] = { 112 "DEVIDLE", 113 "FINDWORK", 114 "DOSEEK", 115 "SEEKCOMPLETE", 116 "IOCOMPLETE", 117 "RECALCOMPLETE", 118 "STARTRECAL", 119 "RESETCTLR", 120 "SEEKWAIT", 121 "RECALWAIT", 122 "MOTORWAIT", 123 "IOTIMEDOUT", 124 "RESETCOMPLETE", 125 "PIOREAD" 126}; 127#endif 128 129/* 130 * Per controller structure (softc). 131 */ 132struct fdc_data 133{ 134 int fdcu; /* our unit number */ 135 int dmachan; 136 int flags; 137#define FDC_ATTACHED 0x01 138#define FDC_STAT_VALID 0x08 139#define FDC_HAS_FIFO 0x10 140#define FDC_NEEDS_RESET 0x20 141#define FDC_NODMA 0x40 142#define FDC_ISPNP 0x80 143#define FDC_ISPCMCIA 0x100 144 struct fd_data *fd; 145 int fdu; /* the active drive */ 146 enum fdc_states state; 147 int retry; 148 int fdout; /* mirror of the w/o digital output reg */ 149 u_int status[7]; /* copy of the registers */ 150 enum fdc_type fdct; /* chip version of FDC */ 151 int fdc_errs; /* number of logged errors */ 152 int dma_overruns; /* number of DMA overruns */ 153 struct bio_queue_head head; 154 struct bio *bp; /* active buffer */ 155 struct resource *res_ioport, *res_ctl, *res_irq, *res_drq; 156 int rid_ioport, rid_ctl, rid_irq, rid_drq; 157 int port_off; 158 bus_space_tag_t portt; 159 bus_space_handle_t porth; 160 bus_space_tag_t ctlt; 161 bus_space_handle_t ctlh; 162 void *fdc_intr; 163 struct device *fdc_dev; 164 void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v); 165}; 166 167typedef int fdu_t; 168typedef int fdcu_t; 169typedef int fdsu_t; 170typedef struct fd_data *fd_p; 171typedef struct fdc_data *fdc_p; 172typedef enum fdc_type fdc_t; 173 174#define FDUNIT(s) (((s) >> 6) & 3) 175#define FDTYPE(s) ((s) & 0x3f) 176 177/* 178 * fdc maintains a set (1!) of ivars per child of each controller. 179 */ 180enum fdc_device_ivars { 181 FDC_IVAR_FDUNIT, 182}; 183 184/* 185 * Simple access macros for the ivars. 186 */ 187#define FDC_ACCESSOR(A, B, T) \ 188static __inline T fdc_get_ ## A(device_t dev) \ 189{ \ 190 uintptr_t v; \ 191 BUS_READ_IVAR(device_get_parent(dev), dev, FDC_IVAR_ ## B, &v); \ 192 return (T) v; \ 193} 194FDC_ACCESSOR(fdunit, FDUNIT, int) 195 |
|
89/* configuration flags */ 90#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 91#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */ 92 93/* internally used only, not really from CMOS: */ 94#define RTCFDT_144M_PRETENDED 0x1000 95 96/* error returns for fd_cmd() */ --- 6 unchanged lines hidden (view full) --- 103 * seconds which the read attempt will block in case the DMA overrun 104 * is persistent. 105 */ 106#define FDC_DMAOV_MAX 25 107 108#define NUMTYPES 17 109#define NUMDENS (NUMTYPES - 7) 110 | 196/* configuration flags */ 197#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 198#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */ 199 200/* internally used only, not really from CMOS: */ 201#define RTCFDT_144M_PRETENDED 0x1000 202 203/* error returns for fd_cmd() */ --- 6 unchanged lines hidden (view full) --- 210 * seconds which the read attempt will block in case the DMA overrun 211 * is persistent. 212 */ 213#define FDC_DMAOV_MAX 25 214 215#define NUMTYPES 17 216#define NUMDENS (NUMTYPES - 7) 217 |
111#define NO_TYPE 0 /* must match NO_TYPE in ft.c */ | 218#define NO_TYPE 0 |
112#define FD_1720 1 113#define FD_1480 2 114#define FD_1440 3 115#define FD_1200 4 116#define FD_820 5 117#define FD_800 6 118#define FD_720 7 119#define FD_360 8 --- 34 unchanged lines hidden (view full) --- 154 155#define DRVS_PER_CTLR 2 /* 2 floppies */ 156 157#define MAX_SEC_SIZE (128 << 3) 158#define MAX_CYLINDER 85 /* some people really stress their drives 159 * up to cyl 82 */ 160#define MAX_HEAD 1 161 | 219#define FD_1720 1 220#define FD_1480 2 221#define FD_1440 3 222#define FD_1200 4 223#define FD_820 5 224#define FD_800 6 225#define FD_720 7 226#define FD_360 8 --- 34 unchanged lines hidden (view full) --- 261 262#define DRVS_PER_CTLR 2 /* 2 floppies */ 263 264#define MAX_SEC_SIZE (128 << 3) 265#define MAX_CYLINDER 85 /* some people really stress their drives 266 * up to cyl 82 */ 267#define MAX_HEAD 1 268 |
162/***********************************************************************\ 163* Per controller structure. * 164\***********************************************************************/ | |
165static devclass_t fdc_devclass; 166 | 269static devclass_t fdc_devclass; 270 |
167/***********************************************************************\ 168* Per drive structure. * 169* N per controller (DRVS_PER_CTLR) * 170\***********************************************************************/ | 271/* 272 * Per drive structure (softc). 273 */ |
171struct fd_data { 172 struct fdc_data *fdc; /* pointer to controller structure */ 173 int fdsu; /* this units number on this controller */ 174 int type; /* Drive type (FD_1440...) */ 175 struct fd_type *ft; /* pointer to the type descriptor */ 176 int flags; 177#define FD_OPEN 0x01 /* it's open */ 178#define FD_ACTIVE 0x02 /* it's active */ --- 15 unchanged lines hidden (view full) --- 194 fdu_t fdu; 195}; 196 197struct fdc_ivars { 198 int fdunit; 199}; 200static devclass_t fd_devclass; 201 | 274struct fd_data { 275 struct fdc_data *fdc; /* pointer to controller structure */ 276 int fdsu; /* this units number on this controller */ 277 int type; /* Drive type (FD_1440...) */ 278 struct fd_type *ft; /* pointer to the type descriptor */ 279 int flags; 280#define FD_OPEN 0x01 /* it's open */ 281#define FD_ACTIVE 0x02 /* it's active */ --- 15 unchanged lines hidden (view full) --- 297 fdu_t fdu; 298}; 299 300struct fdc_ivars { 301 int fdunit; 302}; 303static devclass_t fd_devclass; 304 |
202/***********************************************************************\ 203* Throughout this file the following conventions will be used: * 204* fd is a pointer to the fd_data struct for the drive in question * 205* fdc is a pointer to the fdc_data struct for the controller * 206* fdu is the floppy drive unit number * 207* fdcu is the floppy controller unit number * 208* fdsu is the floppy drive unit number on that controller. (sub-unit) * 209\***********************************************************************/ | 305/* 306 * Throughout this file the following conventions will be used: 307 * 308 * fd is a pointer to the fd_data struct for the drive in question 309 * fdc is a pointer to the fdc_data struct for the controller 310 * fdu is the floppy drive unit number 311 * fdcu is the floppy controller unit number 312 * fdsu is the floppy drive unit number on that controller. (sub-unit) 313 */ |
210 | 314 |
211/* internal functions */ 212static driver_intr_t fdc_intr; | 315/* 316 * Function declarations, same (chaotic) order as they appear in the 317 * file. Re-ordering is too late now, it would only obfuscate the 318 * diffs against old and offspring versions (like the PC98 one). 319 * 320 * Anyone adding functions here, please keep this sequence the same 321 * as below -- makes locating a particular function in the body much 322 * easier. 323 */ 324static void fdout_wr(fdc_p, u_int8_t); 325static u_int8_t fdsts_rd(fdc_p); 326static void fddata_wr(fdc_p, u_int8_t); 327static u_int8_t fddata_rd(fdc_p); 328static void fdctl_wr_isa(fdc_p, u_int8_t); 329#if NCARD > 0 330static void fdctl_wr_pcmcia(fdc_p, u_int8_t); 331#endif 332#if 0 333static u_int8_t fdin_rd(fdc_p); 334#endif 335static int fdc_err(struct fdc_data *, const char *); 336static int fd_cmd(struct fdc_data *, int, ...); 337static int enable_fifo(fdc_p fdc); 338static int fd_sense_drive_status(fdc_p, int *); 339static int fd_sense_int(fdc_p, int *, int *); 340static int fd_read_status(fdc_p); 341static int fdc_alloc_resources(struct fdc_data *); 342static void fdc_release_resources(struct fdc_data *); 343static int fdc_read_ivar(device_t, device_t, int, uintptr_t *); 344static int fdc_probe(device_t); 345#if NCARD > 0 346static int fdc_pccard_probe(device_t); 347#endif 348static int fdc_detach(device_t dev); 349static void fdc_add_child(device_t, const char *, int); 350static int fdc_attach(device_t); 351static int fdc_print_child(device_t, device_t); 352static void fd_clone (void *, char *, int, dev_t *); 353static int fd_probe(device_t); 354static int fd_attach(device_t); 355static int fd_detach(device_t); |
213static void set_motor(struct fdc_data *, int, int); 214# define TURNON 1 215# define TURNOFF 0 216static timeout_t fd_turnoff; 217static timeout_t fd_motor_on; 218static void fd_turnon(struct fd_data *); 219static void fdc_reset(fdc_p); 220static int fd_in(struct fdc_data *, int *); 221static int out_fdc(struct fdc_data *, int); | 356static void set_motor(struct fdc_data *, int, int); 357# define TURNON 1 358# define TURNOFF 0 359static timeout_t fd_turnoff; 360static timeout_t fd_motor_on; 361static void fd_turnon(struct fd_data *); 362static void fdc_reset(fdc_p); 363static int fd_in(struct fdc_data *, int *); 364static int out_fdc(struct fdc_data *, int); |
365/* 366 * The open function is named Fdopen() to avoid confusion with fdopen() 367 * in fd(4). The difference is now only meaningful for debuggers. 368 */ 369static d_open_t Fdopen; 370static d_close_t fdclose; 371static d_strategy_t fdstrategy; |
|
222static void fdstart(struct fdc_data *); 223static timeout_t fd_iotimeout; 224static timeout_t fd_pseudointr; | 372static void fdstart(struct fdc_data *); 373static timeout_t fd_iotimeout; 374static timeout_t fd_pseudointr; |
375static driver_intr_t fdc_intr; 376static int fdcpio(fdc_p, long, caddr_t, u_int); |
|
225static int fdstate(struct fdc_data *); 226static int retrier(struct fdc_data *); | 377static int fdstate(struct fdc_data *); 378static int retrier(struct fdc_data *); |
379static void fdbiodone(struct bio *); |
|
227static int fdmisccmd(dev_t, u_int, void *); | 380static int fdmisccmd(dev_t, u_int, void *); |
381static d_ioctl_t fdioctl; |
|
228 | 382 |
229static int enable_fifo(fdc_p fdc); 230static void fd_clone (void *arg, char *name, int namelen, dev_t *dev); 231 | |
232static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 233 234#ifdef FDC_DEBUG | 383static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 384 385#ifdef FDC_DEBUG |
235static char const * const fdstates[] = 236{ 237"DEVIDLE", 238"FINDWORK", 239"DOSEEK", 240"SEEKCOMPLETE", 241"IOCOMPLETE", 242"RECALCOMPLETE", 243"STARTRECAL", 244"RESETCTLR", 245"SEEKWAIT", 246"RECALWAIT", 247"MOTORWAIT", 248"IOTIMEDOUT", 249"RESETCOMPLETE", 250"PIOREAD", 251}; 252 | |
253/* CAUTION: fd_debug causes huge amounts of logging output */ 254static int volatile fd_debug = 0; 255#define TRACE0(arg) do { if (fd_debug) printf(arg); } while (0) 256#define TRACE1(arg1, arg2) do { if (fd_debug) printf(arg1, arg2); } while (0) 257#else /* FDC_DEBUG */ 258#define TRACE0(arg) do { } while (0) 259#define TRACE1(arg1, arg2) do { } while (0) 260#endif /* FDC_DEBUG */ 261 | 386/* CAUTION: fd_debug causes huge amounts of logging output */ 387static int volatile fd_debug = 0; 388#define TRACE0(arg) do { if (fd_debug) printf(arg); } while (0) 389#define TRACE1(arg1, arg2) do { if (fd_debug) printf(arg1, arg2); } while (0) 390#else /* FDC_DEBUG */ 391#define TRACE0(arg) do { } while (0) 392#define TRACE1(arg1, arg2) do { } while (0) 393#endif /* FDC_DEBUG */ 394 |
395/* 396 * Bus space handling (access to low-level IO). 397 */ |
|
262static void 263fdout_wr(fdc_p fdc, u_int8_t v) 264{ 265 bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v); 266} 267 268static u_int8_t 269fdsts_rd(fdc_p fdc) --- 32 unchanged lines hidden (view full) --- 302static u_int8_t 303fdin_rd(fdc_p fdc) 304{ 305 return bus_space_read_1(fdc->portt, fdc->porth, FDIN); 306} 307 308#endif 309 | 398static void 399fdout_wr(fdc_p fdc, u_int8_t v) 400{ 401 bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v); 402} 403 404static u_int8_t 405fdsts_rd(fdc_p fdc) --- 32 unchanged lines hidden (view full) --- 438static u_int8_t 439fdin_rd(fdc_p fdc) 440{ 441 return bus_space_read_1(fdc->portt, fdc->porth, FDIN); 442} 443 444#endif 445 |
310/* 311 * The open function is named Fdopen() to avoid confusion with fdopen() 312 * in fd(4). The difference is now only meaningful for debuggers. 313 */ 314static d_open_t Fdopen; 315static d_close_t fdclose; 316static d_ioctl_t fdioctl; 317static d_strategy_t fdstrategy; 318 | |
319#define CDEV_MAJOR 9 320static struct cdevsw fd_cdevsw = { 321 /* open */ Fdopen, 322 /* close */ fdclose, 323 /* read */ physread, 324 /* write */ physwrite, 325 /* ioctl */ fdioctl, 326 /* poll */ nopoll, 327 /* mmap */ nommap, 328 /* strategy */ fdstrategy, 329 /* name */ "fd", 330 /* maj */ CDEV_MAJOR, 331 /* dump */ nodump, 332 /* psize */ nopsize, 333 /* flags */ D_DISK, 334}; 335 | 446#define CDEV_MAJOR 9 447static struct cdevsw fd_cdevsw = { 448 /* open */ Fdopen, 449 /* close */ fdclose, 450 /* read */ physread, 451 /* write */ physwrite, 452 /* ioctl */ fdioctl, 453 /* poll */ nopoll, 454 /* mmap */ nommap, 455 /* strategy */ fdstrategy, 456 /* name */ "fd", 457 /* maj */ CDEV_MAJOR, 458 /* dump */ nodump, 459 /* psize */ nopsize, 460 /* flags */ D_DISK, 461}; 462 |
463/* 464 * Auxiliary functions. Well, some only. Others are scattered 465 * throughout the entire file. 466 */ |
|
336static int 337fdc_err(struct fdc_data *fdc, const char *s) 338{ 339 fdc->fdc_errs++; 340 if (s) { 341 if (fdc->fdc_errs < FDC_ERRMAX) 342 device_printf(fdc->fdc_dev, "%s", s); 343 else if (fdc->fdc_errs == FDC_ERRMAX) --- 137 unchanged lines hidden (view full) --- 481} 482 483 484static int 485fd_read_status(fdc_p fdc) 486{ 487 int i, ret; 488 | 467static int 468fdc_err(struct fdc_data *fdc, const char *s) 469{ 470 fdc->fdc_errs++; 471 if (s) { 472 if (fdc->fdc_errs < FDC_ERRMAX) 473 device_printf(fdc->fdc_dev, "%s", s); 474 else if (fdc->fdc_errs == FDC_ERRMAX) --- 137 unchanged lines hidden (view full) --- 612} 613 614 615static int 616fd_read_status(fdc_p fdc) 617{ 618 int i, ret; 619 |
489 for (i = 0; i < 7; i++) { | 620 for (i = ret = 0; i < 7; i++) { |
490 /* 491 * XXX types are poorly chosen. Only bytes can be read 492 * from the hardware, but fdc->status[] wants u_ints and 493 * fd_in() gives ints. 494 */ 495 int status; 496 497 ret = fd_in(fdc, &status); --- 5 unchanged lines hidden (view full) --- 503 if (ret == 0) 504 fdc->flags |= FDC_STAT_VALID; 505 else 506 fdc->flags &= ~FDC_STAT_VALID; 507 508 return ret; 509} 510 | 621 /* 622 * XXX types are poorly chosen. Only bytes can be read 623 * from the hardware, but fdc->status[] wants u_ints and 624 * fd_in() gives ints. 625 */ 626 int status; 627 628 ret = fd_in(fdc, &status); --- 5 unchanged lines hidden (view full) --- 634 if (ret == 0) 635 fdc->flags |= FDC_STAT_VALID; 636 else 637 fdc->flags &= ~FDC_STAT_VALID; 638 639 return ret; 640} 641 |
511/****************************************************************************/ 512/* autoconfiguration stuff */ 513/****************************************************************************/ 514 | |
515static int 516fdc_alloc_resources(struct fdc_data *fdc) 517{ 518 device_t dev; 519 int ispnp, ispcmcia, nports; 520 521 dev = fdc->fdc_dev; 522 ispnp = (fdc->flags & FDC_ISPNP) != 0; --- 122 unchanged lines hidden (view full) --- 645 if (fdc->res_drq != 0) { 646 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 647 fdc->res_drq); 648 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 649 fdc->res_drq); 650 } 651} 652 | 642static int 643fdc_alloc_resources(struct fdc_data *fdc) 644{ 645 device_t dev; 646 int ispnp, ispcmcia, nports; 647 648 dev = fdc->fdc_dev; 649 ispnp = (fdc->flags & FDC_ISPNP) != 0; --- 122 unchanged lines hidden (view full) --- 772 if (fdc->res_drq != 0) { 773 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 774 fdc->res_drq); 775 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 776 fdc->res_drq); 777 } 778} 779 |
653/****************************************************************************/ 654/* autoconfiguration stuff */ 655/****************************************************************************/ | 780/* 781 * Configuration/initialization stuff, per controller. 782 */ |
656 657static struct isa_pnp_id fdc_ids[] = { 658 {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */ 659 {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ 660 {0} 661}; 662 663static int --- 6 unchanged lines hidden (view full) --- 670 *result = ivars->fdunit; 671 break; 672 default: 673 return ENOENT; 674 } 675 return 0; 676} 677 | 783 784static struct isa_pnp_id fdc_ids[] = { 785 {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */ 786 {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ 787 {0} 788}; 789 790static int --- 6 unchanged lines hidden (view full) --- 797 *result = ivars->fdunit; 798 break; 799 default: 800 return ENOENT; 801 } 802 return 0; 803} 804 |
678/* 679 * fdc controller section. 680 */ | |
681static int 682fdc_probe(device_t dev) 683{ 684 int error, ic_type; 685 struct fdc_data *fdc; 686 687 fdc = device_get_softc(dev); 688 bzero(fdc, sizeof *fdc); --- 291 unchanged lines hidden (view full) --- 980 { "c", 0, 1 }, 981 { "d", 0, 1 }, 982 { "e", 0, 1 }, 983 { "f", 0, 1 }, 984 { "g", 0, 1 }, 985 { "h", 0, 1 }, 986 { 0, 0 } 987}; | 805static int 806fdc_probe(device_t dev) 807{ 808 int error, ic_type; 809 struct fdc_data *fdc; 810 811 fdc = device_get_softc(dev); 812 bzero(fdc, sizeof *fdc); --- 291 unchanged lines hidden (view full) --- 1104 { "c", 0, 1 }, 1105 { "d", 0, 1 }, 1106 { "e", 0, 1 }, 1107 { "f", 0, 1 }, 1108 { "g", 0, 1 }, 1109 { "h", 0, 1 }, 1110 { 0, 0 } 1111}; |
1112 |
|
988static void 989fd_clone(void *arg, char *name, int namelen, dev_t *dev) 990{ 991 struct fd_data *fd; 992 int u, d, i; 993 char *n; 994 995 fd = (struct fd_data *)arg; --- 13 unchanged lines hidden (view full) --- 1009 *dev = make_dev(&fd_cdevsw, (u << 6) + d, 1010 UID_ROOT, GID_OPERATOR, 0640, name); 1011 fd->clonedevs[i] = *dev; 1012 } else { 1013 *dev = make_dev_alias(fd->masterdev, name); 1014 } 1015} 1016 | 1113static void 1114fd_clone(void *arg, char *name, int namelen, dev_t *dev) 1115{ 1116 struct fd_data *fd; 1117 int u, d, i; 1118 char *n; 1119 1120 fd = (struct fd_data *)arg; --- 13 unchanged lines hidden (view full) --- 1134 *dev = make_dev(&fd_cdevsw, (u << 6) + d, 1135 UID_ROOT, GID_OPERATOR, 0640, name); 1136 fd->clonedevs[i] = *dev; 1137 } else { 1138 *dev = make_dev_alias(fd->masterdev, name); 1139 } 1140} 1141 |
1017/******************************************************************/ | |
1018/* | 1142/* |
1019 * devices attached to the controller section. | 1143 * Configuration/initialization, per drive. |
1020 */ 1021static int 1022fd_probe(device_t dev) 1023{ 1024 int i; 1025 u_int fdt, st0, st3; 1026 struct fd_data *fd; 1027 struct fdc_data *fdc; --- 191 unchanged lines hidden (view full) --- 1219static driver_t fd_driver = { 1220 "fd", 1221 fd_methods, 1222 sizeof(struct fd_data) 1223}; 1224 1225DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0); 1226 | 1144 */ 1145static int 1146fd_probe(device_t dev) 1147{ 1148 int i; 1149 u_int fdt, st0, st3; 1150 struct fd_data *fd; 1151 struct fdc_data *fdc; --- 191 unchanged lines hidden (view full) --- 1343static driver_t fd_driver = { 1344 "fd", 1345 fd_methods, 1346 sizeof(struct fd_data) 1347}; 1348 1349DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0); 1350 |
1227/****************************************************************************/ 1228/* motor control stuff */ 1229/* remember to not deselect the drive we're working on */ 1230/****************************************************************************/ | 1351/* 1352 * More auxiliary functions. 1353 */ 1354/* 1355 * Motor control stuff. 1356 * Remember to not deselect the drive we're working on. 1357 */ |
1231static void 1232set_motor(struct fdc_data *fdc, int fdsu, int turnon) 1233{ 1234 int fdout; 1235 1236 fdout = fdc->fdout; 1237 if (turnon) { 1238 fdout &= ~FDO_FDSEL; --- 76 unchanged lines hidden (view full) --- 1315 /* XXX after a reset, silently believe the FDC will accept commands */ 1316 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1317 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1318 0); 1319 if (fdc->flags & FDC_HAS_FIFO) 1320 (void) enable_fifo(fdc); 1321} 1322 | 1358static void 1359set_motor(struct fdc_data *fdc, int fdsu, int turnon) 1360{ 1361 int fdout; 1362 1363 fdout = fdc->fdout; 1364 if (turnon) { 1365 fdout &= ~FDO_FDSEL; --- 76 unchanged lines hidden (view full) --- 1442 /* XXX after a reset, silently believe the FDC will accept commands */ 1443 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1444 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1445 0); 1446 if (fdc->flags & FDC_HAS_FIFO) 1447 (void) enable_fifo(fdc); 1448} 1449 |
1323/****************************************************************************/ 1324/* fdc in/out */ 1325/****************************************************************************/ | 1450/* 1451 * FDC IO functions, take care of the main status register, timeout 1452 * in case the desired status bits are never set. 1453 */ |
1326static int 1327fd_in(struct fdc_data *fdc, int *ptr) 1328{ 1329 int i, j = 100000; 1330 while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) 1331 != (NE7_DIO|NE7_RQM) && j-- > 0) 1332 if (i == NE7_RQM) 1333 return fdc_err(fdc, "ready for output in input\n"); --- 29 unchanged lines hidden (view full) --- 1363 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); 1364 1365 /* Send the command and return */ 1366 fddata_wr(fdc, x); 1367 TRACE1("[0x%x->FDDATA]", x); 1368 return (0); 1369} 1370 | 1454static int 1455fd_in(struct fdc_data *fdc, int *ptr) 1456{ 1457 int i, j = 100000; 1458 while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) 1459 != (NE7_DIO|NE7_RQM) && j-- > 0) 1460 if (i == NE7_RQM) 1461 return fdc_err(fdc, "ready for output in input\n"); --- 29 unchanged lines hidden (view full) --- 1491 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); 1492 1493 /* Send the command and return */ 1494 fddata_wr(fdc, x); 1495 TRACE1("[0x%x->FDDATA]", x); 1496 return (0); 1497} 1498 |
1371/****************************************************************************/ 1372/* fdopen/fdclose */ 1373/****************************************************************************/ | 1499/* 1500 * Block device driver interface functions (interspersed with even more 1501 * auxiliary functions). 1502 */ |
1374int 1375Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1376{ 1377 fdu_t fdu = FDUNIT(minor(dev)); 1378 int type = FDTYPE(minor(dev)); 1379 fd_p fd; 1380 fdc_p fdc; 1381 --- 92 unchanged lines hidden (view full) --- 1474 1475 fd = devclass_get_softc(fd_devclass, fdu); 1476 fd->flags &= ~FD_OPEN; 1477 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR); 1478 1479 return (0); 1480} 1481 | 1503int 1504Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1505{ 1506 fdu_t fdu = FDUNIT(minor(dev)); 1507 int type = FDTYPE(minor(dev)); 1508 fd_p fd; 1509 fdc_p fdc; 1510 --- 92 unchanged lines hidden (view full) --- 1603 1604 fd = devclass_get_softc(fd_devclass, fdu); 1605 fd->flags &= ~FD_OPEN; 1606 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR); 1607 1608 return (0); 1609} 1610 |
1482/****************************************************************************/ 1483/* fdstrategy */ 1484/****************************************************************************/ | |
1485void 1486fdstrategy(struct bio *bp) 1487{ 1488 long blknum, nblocks; 1489 int s; 1490 fdu_t fdu; 1491 fdc_p fdc; 1492 fd_p fd; --- 62 unchanged lines hidden (view full) --- 1555 fdstart(fdc); 1556 splx(s); 1557 return; 1558 1559bad: 1560 biodone(bp); 1561} 1562 | 1611void 1612fdstrategy(struct bio *bp) 1613{ 1614 long blknum, nblocks; 1615 int s; 1616 fdu_t fdu; 1617 fdc_p fdc; 1618 fd_p fd; --- 62 unchanged lines hidden (view full) --- 1681 fdstart(fdc); 1682 splx(s); 1683 return; 1684 1685bad: 1686 biodone(bp); 1687} 1688 |
1563/***************************************************************\ 1564* fdstart * 1565* We have just queued something.. if the controller is not busy * 1566* then simulate the case where it has just finished a command * 1567* So that it (the interrupt routine) looks on the queue for more* 1568* work to do and picks up what we just added. * 1569* If the controller is already busy, we need do nothing, as it * 1570* will pick up our work when the present work completes * 1571\***************************************************************/ | 1689/* 1690 * fdstart 1691 * 1692 * We have just queued something. If the controller is not busy 1693 * then simulate the case where it has just finished a command 1694 * So that it (the interrupt routine) looks on the queue for more 1695 * work to do and picks up what we just added. 1696 * 1697 * If the controller is already busy, we need do nothing, as it 1698 * will pick up our work when the present work completes. 1699 */ |
1572static void 1573fdstart(struct fdc_data *fdc) 1574{ 1575 int s; 1576 1577 s = splbio(); 1578 if(fdc->state == DEVIDLE) 1579 { --- 25 unchanged lines hidden (view full) --- 1605 s = splbio(); 1606 fdc->status[0] = NE7_ST0_IC_IV; 1607 fdc->flags &= ~FDC_STAT_VALID; 1608 fdc->state = IOTIMEDOUT; 1609 fdc_intr(fdc); 1610 splx(s); 1611} 1612 | 1700static void 1701fdstart(struct fdc_data *fdc) 1702{ 1703 int s; 1704 1705 s = splbio(); 1706 if(fdc->state == DEVIDLE) 1707 { --- 25 unchanged lines hidden (view full) --- 1733 s = splbio(); 1734 fdc->status[0] = NE7_ST0_IC_IV; 1735 fdc->flags &= ~FDC_STAT_VALID; 1736 fdc->state = IOTIMEDOUT; 1737 fdc_intr(fdc); 1738 splx(s); 1739} 1740 |
1613/* just ensure it has the right spl */ | 1741/* Just ensure it has the right spl. */ |
1614static void 1615fd_pseudointr(void *xfdc) 1616{ 1617 int s; 1618 1619 s = splbio(); 1620 fdc_intr(xfdc); 1621 splx(s); 1622} 1623 | 1742static void 1743fd_pseudointr(void *xfdc) 1744{ 1745 int s; 1746 1747 s = splbio(); 1748 fdc_intr(xfdc); 1749 splx(s); 1750} 1751 |
1624/***********************************************************************\ 1625* fdc_intr * 1626* keep calling the state machine until it returns a 0 * 1627* ALWAYS called at SPLBIO * 1628\***********************************************************************/ | 1752/* 1753 * fdc_intr 1754 * 1755 * Keep calling the state machine until it returns a 0. 1756 * Always called at splbio. 1757 */ |
1629static void 1630fdc_intr(void *xfdc) 1631{ 1632 fdc_p fdc = xfdc; 1633 while(fdstate(fdc)) 1634 ; 1635} 1636 1637/* | 1758static void 1759fdc_intr(void *xfdc) 1760{ 1761 fdc_p fdc = xfdc; 1762 while(fdstate(fdc)) 1763 ; 1764} 1765 1766/* |
1638 * magic pseudo-DMA initialization for YE FDC. Sets count and 1639 * direction | 1767 * Magic pseudo-DMA initialization for YE FDC. Sets count and 1768 * direction. |
1640 */ 1641#define SET_BCDR(fdc,wr,cnt,port) \ 1642 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port, \ 1643 ((cnt)-1) & 0xff); \ 1644 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \ 1645 ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))); 1646 1647/* | 1769 */ 1770#define SET_BCDR(fdc,wr,cnt,port) \ 1771 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port, \ 1772 ((cnt)-1) & 0xff); \ 1773 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \ 1774 ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))); 1775 1776/* |
1648 * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy | 1777 * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy. |
1649 */ 1650static int 1651fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count) 1652{ 1653 u_char *cptr = (u_char *)addr; 1654 1655 if (flags == BIO_READ) { 1656 if (fdc->state != PIOREAD) { --- 6 unchanged lines hidden (view full) --- 1663 } else { 1664 bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off + 1665 FDC_YE_DATAPORT, cptr, count); 1666 SET_BCDR(fdc, 0, count, 0); 1667 } 1668 return(1); 1669} 1670 | 1778 */ 1779static int 1780fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count) 1781{ 1782 u_char *cptr = (u_char *)addr; 1783 1784 if (flags == BIO_READ) { 1785 if (fdc->state != PIOREAD) { --- 6 unchanged lines hidden (view full) --- 1792 } else { 1793 bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off + 1794 FDC_YE_DATAPORT, cptr, count); 1795 SET_BCDR(fdc, 0, count, 0); 1796 } 1797 return(1); 1798} 1799 |
1671/***********************************************************************\ 1672* The controller state machine. * 1673* if it returns a non zero value, it should be called again immediatly * 1674\***********************************************************************/ | 1800/* 1801 * The controller state machine. 1802 * 1803 * If it returns a non zero value, it should be called again immediately. 1804 */ |
1675static int 1676fdstate(fdc_p fdc) 1677{ 1678 struct fdc_readid *idp; 1679 int read, format, rdsectid, cylinder, head, i, sec = 0, sectrac; 1680 int st0, cyl, st3, idf; 1681 unsigned long blknum; 1682 fdu_t fdu = fdc->fdu; --- 6 unchanged lines hidden (view full) --- 1689 if (bp == NULL) { 1690 bp = bioq_first(&fdc->head); 1691 if (bp != NULL) { 1692 bioq_remove(&fdc->head, bp); 1693 fdc->bp = bp; 1694 } 1695 } 1696 if (bp == NULL) { | 1805static int 1806fdstate(fdc_p fdc) 1807{ 1808 struct fdc_readid *idp; 1809 int read, format, rdsectid, cylinder, head, i, sec = 0, sectrac; 1810 int st0, cyl, st3, idf; 1811 unsigned long blknum; 1812 fdu_t fdu = fdc->fdu; --- 6 unchanged lines hidden (view full) --- 1819 if (bp == NULL) { 1820 bp = bioq_first(&fdc->head); 1821 if (bp != NULL) { 1822 bioq_remove(&fdc->head, bp); 1823 fdc->bp = bp; 1824 } 1825 } 1826 if (bp == NULL) { |
1697 /***********************************************\ 1698 * nothing left for this controller to do * 1699 * Force into the IDLE state, * 1700 \***********************************************/ | 1827 /* 1828 * Nothing left for this controller to do, 1829 * force into the IDLE state. 1830 */ |
1701 fdc->state = DEVIDLE; 1702 if (fdc->fd) { 1703 device_printf(fdc->fdc_dev, 1704 "unexpected valid fd pointer\n"); 1705 fdc->fd = (fd_p) 0; 1706 fdc->fdu = -1; 1707 } 1708 TRACE1("[fdc%d IDLE]", fdc->fdcu); --- 23 unchanged lines hidden (view full) --- 1732 case DEVIDLE: 1733 case FINDWORK: /* we have found new work */ 1734 fdc->retry = 0; 1735 fd->skip = 0; 1736 fdc->fd = fd; 1737 fdc->fdu = fdu; 1738 fdc->fdctl_wr(fdc, fd->ft->trans); 1739 TRACE1("[0x%x->FDCTL]", fd->ft->trans); | 1831 fdc->state = DEVIDLE; 1832 if (fdc->fd) { 1833 device_printf(fdc->fdc_dev, 1834 "unexpected valid fd pointer\n"); 1835 fdc->fd = (fd_p) 0; 1836 fdc->fdu = -1; 1837 } 1838 TRACE1("[fdc%d IDLE]", fdc->fdcu); --- 23 unchanged lines hidden (view full) --- 1862 case DEVIDLE: 1863 case FINDWORK: /* we have found new work */ 1864 fdc->retry = 0; 1865 fd->skip = 0; 1866 fdc->fd = fd; 1867 fdc->fdu = fdu; 1868 fdc->fdctl_wr(fdc, fd->ft->trans); 1869 TRACE1("[0x%x->FDCTL]", fd->ft->trans); |
1740 /*******************************************************\ 1741 * If the next drive has a motor startup pending, then * 1742 * it will start up in its own good time * 1743 \*******************************************************/ | 1870 /* 1871 * If the next drive has a motor startup pending, then 1872 * it will start up in its own good time. 1873 */ |
1744 if(fd->flags & FD_MOTOR_WAIT) { 1745 fdc->state = MOTORWAIT; | 1874 if(fd->flags & FD_MOTOR_WAIT) { 1875 fdc->state = MOTORWAIT; |
1746 return (0); /* come back later */ | 1876 return (0); /* will return later */ |
1747 } | 1877 } |
1748 /*******************************************************\ 1749 * Maybe if it's not starting, it SHOULD be starting * 1750 \*******************************************************/ | 1878 /* 1879 * Maybe if it's not starting, it SHOULD be starting. 1880 */ |
1751 if (!(fd->flags & FD_MOTOR)) 1752 { 1753 fdc->state = MOTORWAIT; 1754 fd_turnon(fd); | 1881 if (!(fd->flags & FD_MOTOR)) 1882 { 1883 fdc->state = MOTORWAIT; 1884 fd_turnon(fd); |
1755 return (0); | 1885 return (0); /* will return later */ |
1756 } 1757 else /* at least make sure we are selected */ 1758 { 1759 set_motor(fdc, fd->fdsu, TURNON); 1760 } 1761 if (fdc->flags & FDC_NEEDS_RESET) { 1762 fdc->state = RESETCTLR; 1763 fdc->flags &= ~FDC_NEEDS_RESET; 1764 } else 1765 fdc->state = DOSEEK; | 1886 } 1887 else /* at least make sure we are selected */ 1888 { 1889 set_motor(fdc, fd->fdsu, TURNON); 1890 } 1891 if (fdc->flags & FDC_NEEDS_RESET) { 1892 fdc->state = RESETCTLR; 1893 fdc->flags &= ~FDC_NEEDS_RESET; 1894 } else 1895 fdc->state = DOSEEK; |
1766 return (1); /* come back immediately */ | 1896 return (1); /* will return immediately */ |
1767 1768 case DOSEEK: 1769 blknum = bp->bio_pblkno + fd->skip / fdblk; 1770 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1771 if (cylinder == fd->track) 1772 { 1773 fdc->state = SEEKCOMPLETE; | 1897 1898 case DOSEEK: 1899 blknum = bp->bio_pblkno + fd->skip / fdblk; 1900 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1901 if (cylinder == fd->track) 1902 { 1903 fdc->state = SEEKCOMPLETE; |
1774 return (1); /* come back immediately */ | 1904 return (1); /* will return immediately */ |
1775 } 1776 if (fd_cmd(fdc, 3, NE7CMD_SEEK, 1777 fd->fdsu, cylinder * fd->ft->steptrac, 1778 0)) 1779 { 1780 /* | 1905 } 1906 if (fd_cmd(fdc, 3, NE7CMD_SEEK, 1907 fd->fdsu, cylinder * fd->ft->steptrac, 1908 0)) 1909 { 1910 /* |
1781 * seek command not accepted, looks like | 1911 * Seek command not accepted, looks like |
1782 * the FDC went off to the Saints... 1783 */ 1784 fdc->retry = 6; /* try a reset */ 1785 return(retrier(fdc)); 1786 } 1787 fd->track = FD_NO_TRACK; 1788 fdc->state = SEEKWAIT; 1789 return(0); /* will return later */ 1790 1791 case SEEKWAIT: 1792 /* allow heads to settle */ 1793 timeout(fd_pseudointr, fdc, hz / 16); 1794 fdc->state = SEEKCOMPLETE; 1795 return(0); /* will return later */ 1796 | 1912 * the FDC went off to the Saints... 1913 */ 1914 fdc->retry = 6; /* try a reset */ 1915 return(retrier(fdc)); 1916 } 1917 fd->track = FD_NO_TRACK; 1918 fdc->state = SEEKWAIT; 1919 return(0); /* will return later */ 1920 1921 case SEEKWAIT: 1922 /* allow heads to settle */ 1923 timeout(fd_pseudointr, fdc, hz / 16); 1924 fdc->state = SEEKCOMPLETE; 1925 return(0); /* will return later */ 1926 |
1797 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ | 1927 case SEEKCOMPLETE : /* seek done, start DMA */ |
1798 blknum = bp->bio_pblkno + fd->skip / fdblk; 1799 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1800 | 1928 blknum = bp->bio_pblkno + fd->skip / fdblk; 1929 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1930 |
1801 /* Make sure seek really happened*/ | 1931 /* Make sure seek really happened. */ |
1802 if(fd->track == FD_NO_TRACK) { 1803 int descyl = cylinder * fd->ft->steptrac; 1804 do { 1805 /* 1806 * This might be a "ready changed" interrupt, 1807 * which cannot really happen since the 1808 * RDY pin is hardwired to + 5 volts. This 1809 * generally indicates a "bouncing" intr --- 10 unchanged lines hidden (view full) --- 1820 * provide up to four dummy RC interrupt 1821 * conditions right after reset (for the 1822 * corresponding four drives), so this is 1823 * our only chance to get notice that it 1824 * was not the FDC that caused the interrupt. 1825 */ 1826 if (fd_sense_int(fdc, &st0, &cyl) 1827 == FD_NOT_VALID) | 1932 if(fd->track == FD_NO_TRACK) { 1933 int descyl = cylinder * fd->ft->steptrac; 1934 do { 1935 /* 1936 * This might be a "ready changed" interrupt, 1937 * which cannot really happen since the 1938 * RDY pin is hardwired to + 5 volts. This 1939 * generally indicates a "bouncing" intr --- 10 unchanged lines hidden (view full) --- 1950 * provide up to four dummy RC interrupt 1951 * conditions right after reset (for the 1952 * corresponding four drives), so this is 1953 * our only chance to get notice that it 1954 * was not the FDC that caused the interrupt. 1955 */ 1956 if (fd_sense_int(fdc, &st0, &cyl) 1957 == FD_NOT_VALID) |
1828 return 0; | 1958 return (0); /* will return later */ |
1829 if(fdc->fdct == FDC_NE765 1830 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) | 1959 if(fdc->fdct == FDC_NE765 1960 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) |
1831 return 0; /* hope for a real intr */ | 1961 return (0); /* hope for a real intr */ |
1832 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1833 1834 if (0 == descyl) { 1835 int failed = 0; 1836 /* 1837 * seek to cyl 0 requested; make sure we are 1838 * really there 1839 */ --- 63 unchanged lines hidden (view full) --- 1903 fdc->status[0] = NE7_ST0_IC_AT; 1904 fdc->status[1] = NE7_ST1_NW; 1905 fdc->status[2] = 0; 1906 fdc->status[3] = fd->track; 1907 fdc->status[4] = head; 1908 fdc->status[5] = sec; 1909 fdc->retry = 8; /* break out immediately */ 1910 fdc->state = IOTIMEDOUT; /* not really... */ | 1962 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1963 1964 if (0 == descyl) { 1965 int failed = 0; 1966 /* 1967 * seek to cyl 0 requested; make sure we are 1968 * really there 1969 */ --- 63 unchanged lines hidden (view full) --- 2033 fdc->status[0] = NE7_ST0_IC_AT; 2034 fdc->status[1] = NE7_ST1_NW; 2035 fdc->status[2] = 0; 2036 fdc->status[3] = fd->track; 2037 fdc->status[4] = head; 2038 fdc->status[5] = sec; 2039 fdc->retry = 8; /* break out immediately */ 2040 fdc->state = IOTIMEDOUT; /* not really... */ |
1911 return (1); | 2041 return (1); /* will return immediately */ |
1912 } 1913 } 1914 1915 if (format) { 1916 if (fdc->flags & FDC_NODMA) { 1917 /* 1918 * This seems to be necessary for 1919 * whatever obscure reason; if we omit --- 33 unchanged lines hidden (view full) --- 1953 /* controller jamming */ 1954 fdc->retry = 6; 1955 return (retrier(fdc)); 1956 } 1957 } else { 1958 /* read or write operation */ 1959 if (fdc->flags & FDC_NODMA) { 1960 /* | 2042 } 2043 } 2044 2045 if (format) { 2046 if (fdc->flags & FDC_NODMA) { 2047 /* 2048 * This seems to be necessary for 2049 * whatever obscure reason; if we omit --- 33 unchanged lines hidden (view full) --- 2083 /* controller jamming */ 2084 fdc->retry = 6; 2085 return (retrier(fdc)); 2086 } 2087 } else { 2088 /* read or write operation */ 2089 if (fdc->flags & FDC_NODMA) { 2090 /* |
1961 * this seems to be necessary even when 1962 * reading data | 2091 * This seems to be necessary even when 2092 * reading data. |
1963 */ 1964 SET_BCDR(fdc, 1, fdblk, 0); 1965 1966 /* | 2093 */ 2094 SET_BCDR(fdc, 1, fdblk, 0); 2095 2096 /* |
1967 * perform the write pseudo-DMA before 1968 * the WRITE command is sent | 2097 * Perform the write pseudo-DMA before 2098 * the WRITE command is sent. |
1969 */ 1970 if (!read) 1971 (void)fdcpio(fdc,bp->bio_cmd, 1972 bp->bio_data+fd->skip, 1973 fdblk); 1974 } 1975 if (fd_cmd(fdc, 9, 1976 (read ? NE7CMD_READ : NE7CMD_WRITE), --- 13 unchanged lines hidden (view full) --- 1990 format ? bp->bio_bcount : fdblk, 1991 fdc->dmachan); 1992 fdc->retry = 6; 1993 return (retrier(fdc)); 1994 } 1995 } 1996 if (!rdsectid && (fdc->flags & FDC_NODMA)) 1997 /* | 2099 */ 2100 if (!read) 2101 (void)fdcpio(fdc,bp->bio_cmd, 2102 bp->bio_data+fd->skip, 2103 fdblk); 2104 } 2105 if (fd_cmd(fdc, 9, 2106 (read ? NE7CMD_READ : NE7CMD_WRITE), --- 13 unchanged lines hidden (view full) --- 2120 format ? bp->bio_bcount : fdblk, 2121 fdc->dmachan); 2122 fdc->retry = 6; 2123 return (retrier(fdc)); 2124 } 2125 } 2126 if (!rdsectid && (fdc->flags & FDC_NODMA)) 2127 /* |
1998 * if this is a read, then simply await interrupt 1999 * before performing PIO | 2128 * If this is a read, then simply await interrupt 2129 * before performing PIO. |
2000 */ 2001 if (read && !fdcpio(fdc,bp->bio_cmd, 2002 bp->bio_data+fd->skip,fdblk)) { 2003 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2004 return(0); /* will return later */ 2005 } 2006 2007 /* | 2130 */ 2131 if (read && !fdcpio(fdc,bp->bio_cmd, 2132 bp->bio_data+fd->skip,fdblk)) { 2133 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2134 return(0); /* will return later */ 2135 } 2136 2137 /* |
2008 * write (or format) operation will fall through and 2009 * await completion interrupt | 2138 * Write (or format) operation will fall through and 2139 * await completion interrupt. |
2010 */ 2011 fdc->state = IOCOMPLETE; 2012 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2013 return (0); /* will return later */ 2014 2015 case PIOREAD: 2016 /* | 2140 */ 2141 fdc->state = IOCOMPLETE; 2142 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2143 return (0); /* will return later */ 2144 2145 case PIOREAD: 2146 /* |
2017 * actually perform the PIO read. The IOCOMPLETE case 2018 * removes the timeout for us. | 2147 * Actually perform the PIO read. The IOCOMPLETE case 2148 * removes the timeout for us. |
2019 */ 2020 (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk); 2021 fdc->state = IOCOMPLETE; 2022 /* FALLTHROUGH */ | 2149 */ 2150 (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk); 2151 fdc->state = IOCOMPLETE; 2152 /* FALLTHROUGH */ |
2023 case IOCOMPLETE: /* IO DONE, post-analyze */ | 2153 case IOCOMPLETE: /* IO done, post-analyze */ |
2024 untimeout(fd_iotimeout, fdc, fd->tohandle); 2025 2026 if (fd_read_status(fdc)) { 2027 if (!rdsectid && !(fdc->flags & FDC_NODMA)) 2028 isa_dmadone(idf, bp->bio_data + fd->skip, 2029 format ? bp->bio_bcount : fdblk, 2030 fdc->dmachan); 2031 if (fdc->retry < 6) --- 20 unchanged lines hidden (view full) --- 2052 * the retry counter. However, in case 2053 * something is seriously messed up (like 2054 * broken hardware), we rather limit the 2055 * number of retries so the IO operation 2056 * doesn't block indefinately. 2057 */ 2058 if (fdc->dma_overruns++ < FDC_DMAOV_MAX) { 2059 fdc->state = SEEKCOMPLETE; | 2154 untimeout(fd_iotimeout, fdc, fd->tohandle); 2155 2156 if (fd_read_status(fdc)) { 2157 if (!rdsectid && !(fdc->flags & FDC_NODMA)) 2158 isa_dmadone(idf, bp->bio_data + fd->skip, 2159 format ? bp->bio_bcount : fdblk, 2160 fdc->dmachan); 2161 if (fdc->retry < 6) --- 20 unchanged lines hidden (view full) --- 2182 * the retry counter. However, in case 2183 * something is seriously messed up (like 2184 * broken hardware), we rather limit the 2185 * number of retries so the IO operation 2186 * doesn't block indefinately. 2187 */ 2188 if (fdc->dma_overruns++ < FDC_DMAOV_MAX) { 2189 fdc->state = SEEKCOMPLETE; |
2060 return (1); | 2190 return (1);/* will return immediately */ |
2061 } /* else fall through */ 2062 } 2063 if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 2064 && fdc->retry < 6) 2065 fdc->retry = 6; /* force a reset */ 2066 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2067 && fdc->status[2] & NE7_ST2_WC 2068 && fdc->retry < 3) --- 21 unchanged lines hidden (view full) --- 2090 bp->bio_resid = 0; 2091 fdc->bp = NULL; 2092 device_unbusy(fd->dev); 2093 biofinish(bp, &fd->device_stats, 0); 2094 fdc->fd = (fd_p) 0; 2095 fdc->fdu = -1; 2096 fdc->state = FINDWORK; 2097 } | 2191 } /* else fall through */ 2192 } 2193 if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 2194 && fdc->retry < 6) 2195 fdc->retry = 6; /* force a reset */ 2196 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2197 && fdc->status[2] & NE7_ST2_WC 2198 && fdc->retry < 3) --- 21 unchanged lines hidden (view full) --- 2220 bp->bio_resid = 0; 2221 fdc->bp = NULL; 2222 device_unbusy(fd->dev); 2223 biofinish(bp, &fd->device_stats, 0); 2224 fdc->fd = (fd_p) 0; 2225 fdc->fdu = -1; 2226 fdc->state = FINDWORK; 2227 } |
2098 return (1); | 2228 return (1); /* will return immediately */ |
2099 2100 case RESETCTLR: 2101 fdc_reset(fdc); 2102 fdc->retry++; 2103 fdc->state = RESETCOMPLETE; | 2229 2230 case RESETCTLR: 2231 fdc_reset(fdc); 2232 fdc->retry++; 2233 fdc->state = RESETCOMPLETE; |
2104 return (0); | 2234 return (0); /* will return later */ |
2105 2106 case RESETCOMPLETE: 2107 /* 2108 * Discard all the results from the reset so that they 2109 * can't cause an unexpected interrupt later. 2110 */ 2111 for (i = 0; i < 4; i++) 2112 (void)fd_sense_int(fdc, &st0, &cyl); --- 15 unchanged lines hidden (view full) --- 2128 return (0); /* will return later */ 2129 2130 case RECALCOMPLETE: 2131 do { 2132 /* 2133 * See SEEKCOMPLETE for a comment on this: 2134 */ 2135 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) | 2235 2236 case RESETCOMPLETE: 2237 /* 2238 * Discard all the results from the reset so that they 2239 * can't cause an unexpected interrupt later. 2240 */ 2241 for (i = 0; i < 4; i++) 2242 (void)fd_sense_int(fdc, &st0, &cyl); --- 15 unchanged lines hidden (view full) --- 2258 return (0); /* will return later */ 2259 2260 case RECALCOMPLETE: 2261 do { 2262 /* 2263 * See SEEKCOMPLETE for a comment on this: 2264 */ 2265 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) |
2136 return 0; | 2266 return (0); /* will return later */ |
2137 if(fdc->fdct == FDC_NE765 2138 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) | 2267 if(fdc->fdct == FDC_NE765 2268 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) |
2139 return 0; /* hope for a real intr */ | 2269 return (0); /* hope for a real intr */ |
2140 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2141 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) 2142 { 2143 if(fdc->retry > 3) 2144 /* | 2270 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2271 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) 2272 { 2273 if(fdc->retry > 3) 2274 /* |
2145 * a recalibrate from beyond cylinder 77 | 2275 * A recalibrate from beyond cylinder 77 |
2146 * will "fail" due to the FDC limitations; 2147 * since people used to complain much about 2148 * the failure message, try not logging 2149 * this one if it seems to be the first | 2276 * will "fail" due to the FDC limitations; 2277 * since people used to complain much about 2278 * the failure message, try not logging 2279 * this one if it seems to be the first |
2150 * time in a line | 2280 * time in a line. |
2151 */ 2152 printf("fd%d: recal failed ST0 %b cyl %d\n", 2153 fdu, st0, NE7_ST0BITS, cyl); 2154 if(fdc->retry < 3) fdc->retry = 3; 2155 return (retrier(fdc)); 2156 } 2157 fd->track = 0; 2158 /* Seek (probably) necessary */ 2159 fdc->state = DOSEEK; | 2281 */ 2282 printf("fd%d: recal failed ST0 %b cyl %d\n", 2283 fdu, st0, NE7_ST0BITS, cyl); 2284 if(fdc->retry < 3) fdc->retry = 3; 2285 return (retrier(fdc)); 2286 } 2287 fd->track = 0; 2288 /* Seek (probably) necessary */ 2289 fdc->state = DOSEEK; |
2160 return (1); /* will return immediatly */ | 2290 return (1); /* will return immediately */ |
2161 2162 case MOTORWAIT: 2163 if(fd->flags & FD_MOTOR_WAIT) 2164 { 2165 return (0); /* time's not up yet */ 2166 } 2167 if (fdc->flags & FDC_NEEDS_RESET) { 2168 fdc->state = RESETCTLR; 2169 fdc->flags &= ~FDC_NEEDS_RESET; 2170 } else 2171 fdc->state = DOSEEK; | 2291 2292 case MOTORWAIT: 2293 if(fd->flags & FD_MOTOR_WAIT) 2294 { 2295 return (0); /* time's not up yet */ 2296 } 2297 if (fdc->flags & FDC_NEEDS_RESET) { 2298 fdc->state = RESETCTLR; 2299 fdc->flags &= ~FDC_NEEDS_RESET; 2300 } else 2301 fdc->state = DOSEEK; |
2172 return (1); /* will return immediatly */ | 2302 return (1); /* will return immediately */ |
2173 2174 default: 2175 device_printf(fdc->fdc_dev, "unexpected FD int->"); 2176 if (fd_read_status(fdc) == 0) 2177 printf("FDC status :%x %x %x %x %x %x %x ", 2178 fdc->status[0], 2179 fdc->status[1], 2180 fdc->status[2], 2181 fdc->status[3], 2182 fdc->status[4], 2183 fdc->status[5], 2184 fdc->status[6] ); 2185 else 2186 printf("No status available "); 2187 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2188 { 2189 printf("[controller is dead now]\n"); | 2303 2304 default: 2305 device_printf(fdc->fdc_dev, "unexpected FD int->"); 2306 if (fd_read_status(fdc) == 0) 2307 printf("FDC status :%x %x %x %x %x %x %x ", 2308 fdc->status[0], 2309 fdc->status[1], 2310 fdc->status[2], 2311 fdc->status[3], 2312 fdc->status[4], 2313 fdc->status[5], 2314 fdc->status[6] ); 2315 else 2316 printf("No status available "); 2317 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2318 { 2319 printf("[controller is dead now]\n"); |
2190 return (0); | 2320 return (0); /* will return later */ |
2191 } 2192 printf("ST0 = %x, PCN = %x\n", st0, cyl); | 2321 } 2322 printf("ST0 = %x, PCN = %x\n", st0, cyl); |
2193 return (0); | 2323 return (0); /* will return later */ |
2194 } | 2324 } |
2195 /* keep the compiler happy -- noone should ever get here */ 2196 return (999999); | 2325 /* noone should ever get here */ |
2197} 2198 2199static int 2200retrier(struct fdc_data *fdc) 2201{ 2202 struct bio *bp; 2203 struct fd_data *fd; 2204 int fdu; --- 245 unchanged lines hidden --- | 2326} 2327 2328static int 2329retrier(struct fdc_data *fdc) 2330{ 2331 struct bio *bp; 2332 struct fd_data *fd; 2333 int fdu; --- 245 unchanged lines hidden --- |