fdc.c (45360) | fdc.c (45720) |
---|---|
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) --- 33 unchanged lines hidden (view full) --- 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 | 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) --- 33 unchanged lines hidden (view full) --- 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 |
50 * $Id: fd.c,v 1.133 1999/02/10 00:03:32 ken Exp $ | 50 * $Id: fd.c,v 1.134 1999/04/06 03:06:51 peter Exp $ |
51 * 52 */ 53 54#include "fd.h" 55#include "opt_devfs.h" 56#include "opt_fdc.h" 57 58#if NFDC > 0 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/kernel.h> | 51 * 52 */ 53 54#include "fd.h" 55#include "opt_devfs.h" 56#include "opt_fdc.h" 57 58#if NFDC > 0 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/kernel.h> |
63#include <sys/buf.h> 64#include <sys/bus.h> |
|
63#include <sys/conf.h> | 65#include <sys/conf.h> |
64#include <sys/fcntl.h> 65#include <machine/clock.h> 66#include <machine/ioctl_fd.h> | |
67#include <sys/disklabel.h> | 66#include <sys/disklabel.h> |
68#include <sys/buf.h> | |
69#include <sys/devicestat.h> | 67#include <sys/devicestat.h> |
68#include <sys/fcntl.h> |
|
70#include <sys/malloc.h> | 69#include <sys/malloc.h> |
70#include <sys/module.h> |
|
71#include <sys/proc.h> 72#include <sys/syslog.h> | 71#include <sys/proc.h> 72#include <sys/syslog.h> |
73#include <i386/isa/isa.h> 74#include <i386/isa/isa_device.h> 75#include <i386/isa/fdreg.h> 76#include <i386/isa/fdc.h> 77#include <i386/isa/rtc.h> | 73 74#include <sys/bus.h> 75#include <machine/bus.h> 76#include <sys/rman.h> 77 78#include <machine/clock.h> 79#include <machine/ioctl_fd.h> 80#include <machine/resource.h> |
78#include <machine/stdarg.h> | 81#include <machine/stdarg.h> |
82 |
|
79#ifdef DEVFS 80#include <sys/devfsext.h> 81#endif /* DEVFS */ 82 | 83#ifdef DEVFS 84#include <sys/devfsext.h> 85#endif /* DEVFS */ 86 |
87#include <isa/isavar.h> 88#include <i386/isa/isa.h> 89#include <i386/isa/isa_dma.h> 90#include <i386/isa/fdreg.h> 91#include <i386/isa/fdc.h> 92#include <i386/isa/rtc.h> 93 |
|
83/* misuse a flag to identify format operation */ 84#define B_FORMAT B_XXX 85 86/* configuration flags */ 87#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 88#ifdef FDC_YE 89#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's 90 a PCMCIA device */ --- 55 unchanged lines hidden (view full) --- 146{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ 147}; 148 149#define DRVS_PER_CTLR 2 /* 2 floppies */ 150 151/***********************************************************************\ 152* Per controller structure. * 153\***********************************************************************/ | 94/* misuse a flag to identify format operation */ 95#define B_FORMAT B_XXX 96 97/* configuration flags */ 98#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 99#ifdef FDC_YE 100#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's 101 a PCMCIA device */ --- 55 unchanged lines hidden (view full) --- 157{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ 158}; 159 160#define DRVS_PER_CTLR 2 /* 2 floppies */ 161 162/***********************************************************************\ 163* Per controller structure. * 164\***********************************************************************/ |
154struct fdc_data fdc_data[NFDC]; | 165static devclass_t fdc_devclass; |
155 156/***********************************************************************\ 157* Per drive structure. * 158* N per controller (DRVS_PER_CTLR) * 159\***********************************************************************/ | 166 167/***********************************************************************\ 168* Per drive structure. * 169* N per controller (DRVS_PER_CTLR) * 170\***********************************************************************/ |
160static struct fd_data { | 171struct fd_data { |
161 struct fdc_data *fdc; /* pointer to controller structure */ 162 int fdsu; /* this units number on this controller */ 163 int type; /* Drive type (FD_1440...) */ 164 struct fd_type *ft; /* pointer to the type descriptor */ 165 int flags; 166#define FD_OPEN 0x01 /* it's open */ 167#define FD_ACTIVE 0x02 /* it's active */ 168#define FD_MOTOR 0x04 /* motor should be on */ --- 5 unchanged lines hidden (view full) --- 174 int options; /* user configurable options, see ioctl_fd.h */ 175 struct callout_handle toffhandle; 176 struct callout_handle tohandle; 177 struct devstat device_stats; 178#ifdef DEVFS 179 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 180 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 181#endif | 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 */ 179#define FD_MOTOR 0x04 /* motor should be on */ --- 5 unchanged lines hidden (view full) --- 185 int options; /* user configurable options, see ioctl_fd.h */ 186 struct callout_handle toffhandle; 187 struct callout_handle tohandle; 188 struct devstat device_stats; 189#ifdef DEVFS 190 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 191 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 192#endif |
182} fd_data[NFD]; | 193 device_t dev; 194 fdu_t fdu; 195}; 196static devclass_t fd_devclass; |
183 184/***********************************************************************\ 185* Throughout this file the following conventions will be used: * 186* fd is a pointer to the fd_data struct for the drive in question * 187* fdc is a pointer to the fdc_data struct for the controller * 188* fdu is the floppy drive unit number * 189* fdcu is the floppy controller unit number * 190* fdsu is the floppy drive unit number on that controller. (sub-unit) * 191\***********************************************************************/ 192 193#ifdef FDC_YE 194#include "card.h" 195static int yeattach(struct isa_device *); 196#endif 197 | 197 198/***********************************************************************\ 199* Throughout this file the following conventions will be used: * 200* fd is a pointer to the fd_data struct for the drive in question * 201* fdc is a pointer to the fdc_data struct for the controller * 202* fdu is the floppy drive unit number * 203* fdcu is the floppy controller unit number * 204* fdsu is the floppy drive unit number on that controller. (sub-unit) * 205\***********************************************************************/ 206 207#ifdef FDC_YE 208#include "card.h" 209static int yeattach(struct isa_device *); 210#endif 211 |
198/* autoconfig functions */ 199static int fdprobe(struct isa_device *); 200static int fdattach(struct isa_device *); 201 | |
202/* needed for ft driver, thus exported */ | 212/* needed for ft driver, thus exported */ |
203int in_fdc(fdcu_t); 204int out_fdc(fdcu_t, int); | 213int in_fdc(struct fdc_data *); 214int out_fdc(struct fdc_data *, int); |
205 206/* internal functions */ | 215 216/* internal functions */ |
207static void set_motor(fdcu_t, int, int); | 217static void fdc_add_device(device_t, const char *, int); 218static void fdc_intr(void *); 219static void set_motor(struct fdc_data *, int, int); |
208# define TURNON 1 209# define TURNOFF 0 210static timeout_t fd_turnoff; 211static timeout_t fd_motor_on; | 220# define TURNON 1 221# define TURNOFF 0 222static timeout_t fd_turnoff; 223static timeout_t fd_motor_on; |
212static void fd_turnon(fdu_t); | 224static void fd_turnon(struct fd_data *); |
213static void fdc_reset(fdc_p); | 225static void fdc_reset(fdc_p); |
214static int fd_in(fdcu_t, int *); 215static void fdstart(fdcu_t); | 226static int fd_in(struct fdc_data *, int *); 227static void fdstart(struct fdc_data *); |
216static timeout_t fd_iotimeout; 217static timeout_t fd_pseudointr; | 228static timeout_t fd_iotimeout; 229static timeout_t fd_pseudointr; |
218static ointhand2_t fdintr; 219static int fdstate(fdcu_t, fdc_p); 220static int retrier(fdcu_t); | 230static int fdstate(struct fdc_data *); 231static int retrier(struct fdc_data *); |
221static int fdformat(dev_t, struct fd_formb *, struct proc *); 222 223static int enable_fifo(fdc_p fdc); 224 225static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 226 227 228#define DEVIDLE 0 --- 122 unchanged lines hidden (view full) --- 351static int yeintr(struct pccard_devinfo *devi) 352{ 353 fdintr((fdcu_t)devi->isahd.id_unit); 354 return(1); 355} 356#endif /* NCARD > 0 */ 357#endif /* FDC_YE */ 358 | 232static int fdformat(dev_t, struct fd_formb *, struct proc *); 233 234static int enable_fifo(fdc_p fdc); 235 236static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 237 238 239#define DEVIDLE 0 --- 122 unchanged lines hidden (view full) --- 362static int yeintr(struct pccard_devinfo *devi) 363{ 364 fdintr((fdcu_t)devi->isahd.id_unit); 365 return(1); 366} 367#endif /* NCARD > 0 */ 368#endif /* FDC_YE */ 369 |
359 360/* autoconfig structure */ 361 362struct isa_driver fdcdriver = { 363 fdprobe, fdattach, "fdc", 364}; 365 | |
366static d_open_t Fdopen; /* NOTE, not fdopen */ 367static d_read_t fdread; 368static d_write_t fdwrite; 369static d_close_t fdclose; 370static d_ioctl_t fdioctl; 371static d_strategy_t fdstrategy; 372 373/* even if SLICE defined, these are needed for the ft support. */ 374#define CDEV_MAJOR 9 375#define BDEV_MAJOR 2 376 | 370static d_open_t Fdopen; /* NOTE, not fdopen */ 371static d_read_t fdread; 372static d_write_t fdwrite; 373static d_close_t fdclose; 374static d_ioctl_t fdioctl; 375static d_strategy_t fdstrategy; 376 377/* even if SLICE defined, these are needed for the ft support. */ 378#define CDEV_MAJOR 9 379#define BDEV_MAJOR 2 380 |
377 378static struct cdevsw fd_cdevsw = { 379 Fdopen, fdclose, fdread, fdwrite, 380 fdioctl, nostop, nullreset, nodevtotty, 381 seltrue, nommap, fdstrategy, "fd", 382 NULL, -1, nodump, nopsize, 383 D_DISK, 0, -1 }; 384 385 386static struct isa_device *fdcdevs[NFDC]; 387 388 | |
389static int | 381static int |
390fdc_err(fdcu_t fdcu, const char *s) | 382fdc_err(struct fdc_data *fdc, const char *s) |
391{ | 383{ |
392 fdc_data[fdcu].fdc_errs++; 393 if(s) { 394 if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX) 395 printf("fdc%d: %s", fdcu, s); 396 else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX) 397 printf("fdc%d: too many errors, not logging any more\n", 398 fdcu); | 384 fdc->fdc_errs++; 385 if (s) { 386 if (fdc->fdc_errs < FDC_ERRMAX) { 387 device_print_prettyname(fdc->fdc_dev); 388 printf("%s", s); 389 } else if (fdc->fdc_errs == FDC_ERRMAX) { 390 device_print_prettyname(fdc->fdc_dev); 391 printf("too many errors, not logging any more\n"); 392 } |
399 } 400 401 return FD_FAILED; 402} 403 404/* 405 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 406 * Unit number, 407 * # of output bytes, output bytes as ints ..., 408 * # of input bytes, input bytes as ints ... 409 */ | 393 } 394 395 return FD_FAILED; 396} 397 398/* 399 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 400 * Unit number, 401 * # of output bytes, output bytes as ints ..., 402 * # of input bytes, input bytes as ints ... 403 */ |
410 | |
411static int | 404static int |
412fd_cmd(fdcu_t fdcu, int n_out, ...) | 405fd_cmd(struct fdc_data *fdc, int n_out, ...) |
413{ 414 u_char cmd; 415 int n_in; 416 int n; 417 va_list ap; 418 419 va_start(ap, n_out); 420 cmd = (u_char)(va_arg(ap, int)); 421 va_end(ap); 422 va_start(ap, n_out); 423 for (n = 0; n < n_out; n++) 424 { | 406{ 407 u_char cmd; 408 int n_in; 409 int n; 410 va_list ap; 411 412 va_start(ap, n_out); 413 cmd = (u_char)(va_arg(ap, int)); 414 va_end(ap); 415 va_start(ap, n_out); 416 for (n = 0; n < n_out; n++) 417 { |
425 if (out_fdc(fdcu, va_arg(ap, int)) < 0) | 418 if (out_fdc(fdc, va_arg(ap, int)) < 0) |
426 { 427 char msg[50]; 428 snprintf(msg, sizeof(msg), 429 "cmd %x failed at out byte %d of %d\n", 430 cmd, n + 1, n_out); | 419 { 420 char msg[50]; 421 snprintf(msg, sizeof(msg), 422 "cmd %x failed at out byte %d of %d\n", 423 cmd, n + 1, n_out); |
431 return fdc_err(fdcu, msg); | 424 return fdc_err(fdc, msg); |
432 } 433 } 434 n_in = va_arg(ap, int); 435 for (n = 0; n < n_in; n++) 436 { 437 int *ptr = va_arg(ap, int *); | 425 } 426 } 427 n_in = va_arg(ap, int); 428 for (n = 0; n < n_in; n++) 429 { 430 int *ptr = va_arg(ap, int *); |
438 if (fd_in(fdcu, ptr) < 0) | 431 if (fd_in(fdc, ptr) < 0) |
439 { 440 char msg[50]; 441 snprintf(msg, sizeof(msg), 442 "cmd %02x failed at in byte %d of %d\n", 443 cmd, n + 1, n_in); | 432 { 433 char msg[50]; 434 snprintf(msg, sizeof(msg), 435 "cmd %02x failed at in byte %d of %d\n", 436 cmd, n + 1, n_in); |
444 return fdc_err(fdcu, msg); | 437 return fdc_err(fdc, msg); |
445 } 446 } 447 448 return 0; 449} 450 451static int 452enable_fifo(fdc_p fdc) --- 4 unchanged lines hidden (view full) --- 457 458 /* 459 * XXX: 460 * Cannot use fd_cmd the normal way here, since 461 * this might be an invalid command. Thus we send the 462 * first byte, and check for an early turn of data directon. 463 */ 464 | 438 } 439 } 440 441 return 0; 442} 443 444static int 445enable_fifo(fdc_p fdc) --- 4 unchanged lines hidden (view full) --- 450 451 /* 452 * XXX: 453 * Cannot use fd_cmd the normal way here, since 454 * this might be an invalid command. Thus we send the 455 * first byte, and check for an early turn of data directon. 456 */ 457 |
465 if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0) 466 return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); | 458 if (out_fdc(fdc, I8207X_CONFIGURE) < 0) 459 return fdc_err(fdc, "Enable FIFO failed\n"); |
467 468 /* If command is invalid, return */ 469 j = 100000; 470 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 471 != NE7_RQM && j-- > 0) 472 if (i == (NE7_DIO | NE7_RQM)) { 473 fdc_reset(fdc); 474 return FD_FAILED; 475 } 476 if (j<0 || | 460 461 /* If command is invalid, return */ 462 j = 100000; 463 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 464 != NE7_RQM && j-- > 0) 465 if (i == (NE7_DIO | NE7_RQM)) { 466 fdc_reset(fdc); 467 return FD_FAILED; 468 } 469 if (j<0 || |
477 fd_cmd(fdc->fdcu, 3, | 470 fd_cmd(fdc, 3, |
478 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 479 fdc_reset(fdc); | 471 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 472 fdc_reset(fdc); |
480 return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); | 473 return fdc_err(fdc, "Enable FIFO failed\n"); |
481 } 482 fdc->flags |= FDC_HAS_FIFO; 483 return 0; 484 } | 474 } 475 fdc->flags |= FDC_HAS_FIFO; 476 return 0; 477 } |
485 if (fd_cmd(fdc->fdcu, 4, | 478 if (fd_cmd(fdc, 4, |
486 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) | 479 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) |
487 return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n"); | 480 return fdc_err(fdc, "Re-enable FIFO failed\n"); |
488 return 0; 489} 490 491static int 492fd_sense_drive_status(fdc_p fdc, int *st3p) 493{ 494 int st3; 495 | 481 return 0; 482} 483 484static int 485fd_sense_drive_status(fdc_p fdc, int *st3p) 486{ 487 int st3; 488 |
496 if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) | 489 if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) |
497 { | 490 { |
498 return fdc_err(fdc->fdcu, "Sense Drive Status failed\n"); | 491 return fdc_err(fdc, "Sense Drive Status failed\n"); |
499 } 500 if (st3p) 501 *st3p = st3; 502 503 return 0; 504} 505 506static int 507fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 508{ | 492 } 493 if (st3p) 494 *st3p = st3; 495 496 return 0; 497} 498 499static int 500fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 501{ |
509 int st0, cyl; | 502 int cyl, st0, ret; |
510 | 503 |
511 int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0); 512 513 if (ret) 514 { 515 (void)fdc_err(fdc->fdcu, | 504 ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); 505 if (ret) { 506 (void)fdc_err(fdc, |
516 "sense intr err reading stat reg 0\n"); 517 return ret; 518 } 519 520 if (st0p) 521 *st0p = st0; 522 | 507 "sense intr err reading stat reg 0\n"); 508 return ret; 509 } 510 511 if (st0p) 512 *st0p = st0; 513 |
523 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) 524 { | 514 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { |
525 /* 526 * There doesn't seem to have been an interrupt. 527 */ 528 return FD_NOT_VALID; 529 } 530 | 515 /* 516 * There doesn't seem to have been an interrupt. 517 */ 518 return FD_NOT_VALID; 519 } 520 |
531 if (fd_in(fdc->fdcu, &cyl) < 0) 532 { 533 return fdc_err(fdc->fdcu, "can't get cyl num\n"); | 521 if (fd_in(fdc, &cyl) < 0) { 522 return fdc_err(fdc, "can't get cyl num\n"); |
534 } 535 536 if (cylp) 537 *cylp = cyl; 538 539 return 0; 540} 541 542 543static int 544fd_read_status(fdc_p fdc, int fdsu) 545{ 546 int i, ret; 547 | 523 } 524 525 if (cylp) 526 *cylp = cyl; 527 528 return 0; 529} 530 531 532static int 533fd_read_status(fdc_p fdc, int fdsu) 534{ 535 int i, ret; 536 |
548 for (i = 0; i < 7; i++) 549 { | 537 for (i = 0; i < 7; i++) { |
550 /* 551 * XXX types are poorly chosen. Only bytes can by read 552 * from the hardware, but fdc->status[] wants u_ints and 553 * fd_in() gives ints. 554 */ 555 int status; 556 | 538 /* 539 * XXX types are poorly chosen. Only bytes can by read 540 * from the hardware, but fdc->status[] wants u_ints and 541 * fd_in() gives ints. 542 */ 543 int status; 544 |
557 ret = fd_in(fdc->fdcu, &status); | 545 ret = fd_in(fdc, &status); |
558 fdc->status[i] = status; 559 if (ret != 0) 560 break; 561 } 562 563 if (ret == 0) 564 fdc->flags |= FDC_STAT_VALID; 565 else 566 fdc->flags &= ~FDC_STAT_VALID; 567 568 return ret; 569} 570 571/****************************************************************************/ 572/* autoconfiguration stuff */ 573/****************************************************************************/ 574 | 546 fdc->status[i] = status; 547 if (ret != 0) 548 break; 549 } 550 551 if (ret == 0) 552 fdc->flags |= FDC_STAT_VALID; 553 else 554 fdc->flags &= ~FDC_STAT_VALID; 555 556 return ret; 557} 558 559/****************************************************************************/ 560/* autoconfiguration stuff */ 561/****************************************************************************/ 562 |
575/* 576 * probe for existance of controller 577 */ | |
578static int | 563static int |
579fdprobe(struct isa_device *dev) | 564fdc_probe(device_t dev) |
580{ | 565{ |
581 fdcu_t fdcu = dev->id_unit; 582 if(fdc_data[fdcu].flags & FDC_ATTACHED) 583 { 584 printf("fdc%d: unit used multiple times\n", fdcu); 585 return 0; | 566 int error, i, ic_type; 567 struct fdc_data *fdc; 568 char myname[8]; /* better be long enough */ 569 570 fdc = device_get_softc(dev); 571 bzero(fdc, sizeof *fdc); 572 fdc->fdc_dev = dev; 573 fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; 574 fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; 575 576 fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, 577 &fdc->rid_ioport, 0ul, ~0ul, 578 IO_FDCSIZE, RF_ACTIVE); 579 if (fdc->res_ioport == 0) { 580 device_print_prettyname(dev); 581 printf("cannot reserve I/O port range\n"); 582 error = ENXIO; 583 goto out; |
586 } | 584 } |
585 fdc->baseport = fdc->res_ioport->r_start; |
|
587 | 586 |
588 fdcdevs[fdcu] = dev; 589 fdc_data[fdcu].baseport = dev->id_iobase; | 587 fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, 588 &fdc->rid_irq, 0ul, ~0ul, 1, 589 RF_ACTIVE); 590 if (fdc->res_irq == 0) { 591 device_print_prettyname(dev); 592 printf("cannot reserve interrupt line\n"); 593 error = ENXIO; 594 goto out; 595 } 596 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, 597 &fdc->rid_drq, 0ul, ~0ul, 1, 598 RF_ACTIVE); 599 if (fdc->res_drq == 0) { 600 device_print_prettyname(dev); 601 printf("cannot reserve DMA request line\n"); 602 error = ENXIO; 603 goto out; 604 } 605 fdc->dmachan = fdc->res_drq->r_start; 606 error = BUS_SETUP_INTR(device_get_parent(dev), dev, 607 fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr); |
590 591 /* First - lets reset the floppy controller */ | 608 609 /* First - lets reset the floppy controller */ |
592 outb(dev->id_iobase+FDOUT, 0); | 610 outb(fdc->baseport + FDOUT, 0); |
593 DELAY(100); | 611 DELAY(100); |
594 outb(dev->id_iobase+FDOUT, FDO_FRST); | 612 outb(fdc->baseport + FDOUT, FDO_FRST); |
595 596 /* see if it can handle a command */ | 613 614 /* see if it can handle a command */ |
597 if (fd_cmd(fdcu, 598 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 599 0)) 600 { 601 return(0); | 615 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 616 NE7_SPEC_2(2, 0), 0)) { 617 error = ENXIO; 618 goto out; |
602 } | 619 } |
620 621 if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { 622 ic_type = (u_char)ic_type; 623 switch (ic_type) { 624 case 0x80: 625 device_set_desc(dev, "NEC 765 or clone"); 626 fdc->fdct = FDC_NE765; 627 break; 628 case 0x81: 629 device_set_desc(dev, "Intel 82077 or clone"); 630 fdc->fdct = FDC_I82077; 631 break; 632 case 0x90: 633 device_set_desc(dev, "NEC 72065B or clone"); 634 fdc->fdct = FDC_NE72065; 635 break; 636 default: 637 device_set_desc(dev, "generic floppy controller"); 638 fdc->fdct = FDC_UNKNOWN; 639 break; 640 } 641 } 642 643 snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), 644 device_get_unit(dev)); 645 for (i = resource_query_string(-1, "at", myname); i != -1; 646 i = resource_query_string(i, "at", myname)) 647 fdc_add_device(dev, resource_query_name(i), 648 resource_query_unit(i)); |
|
603#ifdef FDC_YE 604 /* 605 * don't succeed on probe; wait 606 * for PCCARD subsystem to do it 607 */ 608 if (dev->id_flags & FDC_IS_PCMCIA) 609 return(0); 610#endif | 649#ifdef FDC_YE 650 /* 651 * don't succeed on probe; wait 652 * for PCCARD subsystem to do it 653 */ 654 if (dev->id_flags & FDC_IS_PCMCIA) 655 return(0); 656#endif |
611 return (IO_FDCSIZE); | 657 return (0); 658 659out: 660 if (fdc->fdc_intr) 661 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 662 fdc->fdc_intr); 663 if (fdc->res_irq != 0) { 664 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 665 fdc->res_irq); 666 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 667 fdc->res_irq); 668 } 669 if (fdc->res_ioport != 0) { 670 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 671 fdc->res_ioport); 672 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 673 fdc->res_ioport); 674 } 675 if (fdc->res_drq != 0) { 676 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 677 fdc->res_drq); 678 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 679 fdc->res_drq); 680 } 681 return (error); |
612} 613 614/* | 682} 683 684/* |
615 * wire controller into system, look for floppy units | 685 * Aped dfr@freebsd.org's isa_add_device(). |
616 */ | 686 */ |
687static void 688fdc_add_device(device_t dev, const char *name, int unit) 689{ 690 int disabled, *ivar; 691 device_t child; 692 693 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); 694 if (ivar == 0) 695 return; 696 if (resource_int_value(name, unit, "drive", ivar) == 0) 697 *ivar = 0; 698 child = device_add_child(dev, name, unit, ivar); 699 if (child == 0) 700 return; 701 if (resource_int_value(name, unit, "disabled", &disabled) == 0) 702 device_disable(child); 703} 704 |
|
617static int | 705static int |
618fdattach(struct isa_device *dev) | 706fdc_attach(device_t dev) |
619{ | 707{ |
620 unsigned fdt; 621 fdu_t fdu; 622 fdcu_t fdcu = dev->id_unit; 623 fdc_p fdc = fdc_data + fdcu; 624 fd_p fd; 625 int fdsu, st0, st3, i; 626 struct isa_device *fdup; 627 int ic_type = 0; 628#ifdef DEVFS 629 int mynor; 630 int typemynor; 631 int typesize; 632#endif | 708 struct fdc_data *fdc = device_get_softc(dev); 709 fdcu_t fdcu = device_get_unit(dev); |
633 | 710 |
634 dev->id_ointr = fdintr; | |
635 fdc->fdcu = fdcu; 636 fdc->flags |= FDC_ATTACHED; | 711 fdc->fdcu = fdcu; 712 fdc->flags |= FDC_ATTACHED; |
637 fdc->dmachan = dev->id_drq; | 713 |
638 /* Acquire the DMA channel forever, The driver will do the rest */ | 714 /* Acquire the DMA channel forever, The driver will do the rest */ |
715 /* XXX should integrate with rman */ |
|
639 isa_dma_acquire(fdc->dmachan); 640 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 641 fdc->state = DEVIDLE; | 716 isa_dma_acquire(fdc->dmachan); 717 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 718 fdc->state = DEVIDLE; |
719 |
|
642 /* reset controller, turn motor off, clear fdout mirror reg */ 643 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 644 bufq_init(&fdc->head); 645 | 720 /* reset controller, turn motor off, clear fdout mirror reg */ 721 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 722 bufq_init(&fdc->head); 723 |
646 /* check for each floppy drive */ 647 for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) { 648 if (fdup->id_iobase != dev->id_iobase) 649 continue; 650 fdu = fdup->id_unit; 651 fd = &fd_data[fdu]; 652 if (fdu >= (NFD)) 653 continue; 654 fdsu = fdup->id_physid; 655 /* look up what bios thinks we have */ 656 switch (fdu) { 657 case 0: if (dev->id_flags & FDC_PRETEND_D0) 658 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 659 else 660 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 661 break; 662 case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 663 break; 664 default: fdt = RTCFDT_NONE; 665 break; 666 } 667 /* is there a unit? */ 668 if ((fdt == RTCFDT_NONE) 669 ) { 670 fd->type = NO_TYPE; 671 continue; 672 } | 724#ifdef FIFO_BEFORE_MOTORON 725 /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ 726 if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 727 && enable_fifo(fdc) == 0) { 728 device_print_prettyname(dev); 729 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 730 } 731#endif 732 /* 733 * Probe and attach any children as were configured above. 734 */ 735 return (bus_generic_attach(dev)); 736} |
673 | 737 |
674 /* select it */ 675 set_motor(fdcu, fdsu, TURNON); 676 DELAY(1000000); /* 1 sec */ | 738static void 739fdc_print_child(device_t me, device_t child) 740{ 741 printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), 742 *(int *)device_get_ivars(child)); 743} |
677 | 744 |
678 if (ic_type == 0 && 679 fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0) 680 { 681#ifdef FDC_PRINT_BOGUS_CHIPTYPE 682 printf("fdc%d: ", fdcu); | 745static int 746fd_probe(device_t dev) 747{ 748 int i; 749 u_int fdt, st0, st3; 750 struct fd_data *fd; 751 struct fdc_data *fdc; 752 fdsu_t fdsu; 753#ifndef FIFO_BEFORE_MOTORON 754 static int fd_fifo = 0; |
683#endif | 755#endif |
684 ic_type = (u_char)ic_type; 685 switch( ic_type ) { 686 case 0x80: 687#ifdef FDC_PRINT_BOGUS_CHIPTYPE 688 printf("NEC 765\n"); | 756 757 fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ 758 fd = device_get_softc(dev); 759 fdc = device_get_softc(device_get_parent(dev)); 760 761 bzero(fd, sizeof *fd); 762 fd->dev = dev; 763 fd->fdc = fdc; 764 fd->fdsu = fdsu; 765 fd->fdu = device_get_unit(dev); 766 767 /* look up what bios thinks we have */ 768 switch (fd->fdu) { 769 case 0: 770 if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) 771 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 772 else 773 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 774 break; 775 case 1: 776 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 777 break; 778 default: 779 fdt = RTCFDT_NONE; 780 break; 781 } 782 783 /* is there a unit? */ 784 if (fdt == RTCFDT_NONE) 785 return (ENXIO); 786 787 /* select it */ 788 set_motor(fdc, fdsu, TURNON); 789 DELAY(1000000); /* 1 sec */ 790 791#ifndef FIFO_BEFORE_MOTORON 792 if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 793 && enable_fifo(fdc) == 0) { 794 device_print_prettyname(device_get_parent(dev)); 795 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 796 } 797 fd_fifo = 1; |
689#endif | 798#endif |
690 fdc->fdct = FDC_NE765; 691 break; 692 case 0x81: 693#ifdef FDC_PRINT_BOGUS_CHIPTYPE 694 printf("Intel 82077\n"); 695#endif 696 fdc->fdct = FDC_I82077; 697 break; 698 case 0x90: 699#ifdef FDC_PRINT_BOGUS_CHIPTYPE 700 printf("NEC 72065B\n"); 701#endif 702 fdc->fdct = FDC_NE72065; 703 break; 704 default: 705#ifdef FDC_PRINT_BOGUS_CHIPTYPE 706 printf("unknown IC type %02x\n", ic_type); 707#endif 708 fdc->fdct = FDC_UNKNOWN; 709 break; 710 } 711 if (fdc->fdct != FDC_NE765 && 712 fdc->fdct != FDC_UNKNOWN && 713 enable_fifo(fdc) == 0) { 714 printf("fdc%d: FIFO enabled", fdcu); 715 printf(", %d bytes threshold\n", 716 fifo_threshold); 717 } 718 } 719 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) && 720 (st3 & NE7_ST3_T0)) { 721 /* if at track 0, first seek inwards */ 722 /* seek some steps: */ 723 (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0); 724 DELAY(300000); /* ...wait a moment... */ 725 (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 726 } | |
727 | 799 |
728 /* If we're at track 0 first seek inwards. */ 729 if ((fd_sense_drive_status(fdc, &st3) == 0) && 730 (st3 & NE7_ST3_T0)) { 731 /* Seek some steps... */ 732 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 733 /* ...wait a moment... */ 734 DELAY(300000); 735 /* make ctrlr happy: */ 736 (void)fd_sense_int(fdc, 0, 0); 737 } | 800 if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) 801 && (st3 & NE7_ST3_T0)) { 802 /* if at track 0, first seek inwards */ 803 /* seek some steps: */ 804 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); 805 DELAY(300000); /* ...wait a moment... */ 806 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 807 } 808 809 /* If we're at track 0 first seek inwards. */ 810 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 811 /* Seek some steps... */ 812 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 813 /* ...wait a moment... */ 814 DELAY(300000); 815 /* make ctrlr happy: */ 816 fd_sense_int(fdc, 0, 0); |
738 } | 817 } |
818 } |
|
739 | 819 |
740 for(i = 0; i < 2; i++) { 741 /* 742 * we must recalibrate twice, just in case the 743 * heads have been beyond cylinder 76, since most 744 * FDCs still barf when attempting to recalibrate 745 * more than 77 steps 746 */ 747 /* go back to 0: */ 748 if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 749 /* a second being enough for full stroke seek*/ 750 DELAY(i == 0? 1000000: 300000); | 820 for (i = 0; i < 2; i++) { 821 /* 822 * we must recalibrate twice, just in case the 823 * heads have been beyond cylinder 76, since most 824 * FDCs still barf when attempting to recalibrate 825 * more than 77 steps 826 */ 827 /* go back to 0: */ 828 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 829 /* a second being enough for full stroke seek*/ 830 DELAY(i == 0 ? 1000000 : 300000); |
751 | 831 |
752 /* anything responding? */ 753 if (fd_sense_int(fdc, &st0, 0) == 0 && 754 (st0 & NE7_ST0_EC) == 0) 755 break; /* already probed succesfully */ 756 } | 832 /* anything responding? */ 833 if (fd_sense_int(fdc, &st0, 0) == 0 && 834 (st0 & NE7_ST0_EC) == 0) 835 break; /* already probed succesfully */ |
757 } | 836 } |
837 } |
|
758 | 838 |
759 set_motor(fdcu, fdsu, TURNOFF); | 839 set_motor(fdc, fdsu, TURNOFF); |
760 | 840 |
761 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 762 continue; | 841 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 842 return (ENXIO); |
763 | 843 |
764 fd->track = FD_NO_TRACK; 765 fd->fdc = fdc; 766 fd->fdsu = fdsu; 767 fd->options = 0; 768 callout_handle_init(&fd->toffhandle); 769 callout_handle_init(&fd->tohandle); 770 printf("fd%d: ", fdu); | 844 fd->track = FD_NO_TRACK; 845 fd->fdc = fdc; 846 fd->fdsu = fdsu; 847 fd->options = 0; 848 callout_handle_init(&fd->toffhandle); 849 callout_handle_init(&fd->tohandle); |
771 | 850 |
772 switch (fdt) { 773 case RTCFDT_12M: 774 printf("1.2MB 5.25in\n"); 775 fd->type = FD_1200; | 851 switch (fdt) { 852 case RTCFDT_12M: 853 device_set_desc(dev, "1200-KB 5.25\" drive"); 854 fd->type = FD_1200; 855 break; 856 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 857 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); 858 fdt = RTCFDT_144M; 859 fd->type = FD_1440; 860 case RTCFDT_144M: 861 device_set_desc(dev, "1440-KB 3.5\" drive"); 862 fd->type = FD_1440; 863 break; 864 case RTCFDT_288M: 865 case RTCFDT_288M_1: 866 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); 867 fd->type = FD_1440; 868 break; 869 case RTCFDT_360K: 870 device_set_desc(dev, "360-KB 5.25\" drive"); 871 fd->type = FD_360; 872 break; 873 case RTCFDT_720K: 874 printf("720-KB 3.5\" drive"); 875 fd->type = FD_720; 876 break; 877 default: 878 return (ENXIO); 879 } 880 return (0); 881} 882 883static int 884fd_attach(device_t dev) 885{ 886 struct fd_data *fd; 887 888 fd = device_get_softc(dev); 889 890#ifdef DEVFS /* XXX bitrot */ 891 mynor = fdu << 6; 892 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 893 UID_ROOT, GID_OPERATOR, 0640, 894 "fd%d", fdu); 895 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 896 UID_ROOT, GID_OPERATOR, 0640, 897 "rfd%d", fdu); 898 for (i = 1; i < 1 + NUMDENS; i++) { 899 /* 900 * XXX this and the lookup in Fdopen() should be 901 * data driven. 902 */ 903 switch (fd->type) { 904 case FD_360: 905 if (i != FD_360) 906 continue; |
776 break; | 907 break; |
777 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 778 printf("config-pretended "); 779 fdt = RTCFDT_144M; 780 /* fallthrough */ 781 case RTCFDT_144M: 782 printf("1.44MB 3.5in\n"); 783 fd->type = FD_1440; | 908 case FD_720: 909 if (i != FD_720 && i != FD_800 && i != FD_820) 910 continue; |
784 break; | 911 break; |
785 case RTCFDT_288M: 786 case RTCFDT_288M_1: 787 printf("2.88MB 3.5in - 1.44MB mode\n"); 788 fd->type = FD_1440; | 912 case FD_1200: 913 if (i != FD_360 && i != FD_720 && i != FD_800 914 && i != FD_820 && i != FD_1200 915 && i != FD_1440 && i != FD_1480) 916 continue; |
789 break; | 917 break; |
790 case RTCFDT_360K: 791 printf("360KB 5.25in\n"); 792 fd->type = FD_360; | 918 case FD_1440: 919 if (i != FD_720 && i != FD_800 && i != FD_820 920 && i != FD_1200 && i != FD_1440 921 && i != FD_1480 && i != FD_1720) 922 continue; |
793 break; | 923 break; |
794 case RTCFDT_720K: 795 printf("720KB 3.5in\n"); 796 fd->type = FD_720; 797 break; 798 default: 799 printf("unknown\n"); 800 fd->type = NO_TYPE; 801 continue; | |
802 } | 924 } |
803#ifdef DEVFS 804 mynor = fdu << 6; 805 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 806 UID_ROOT, GID_OPERATOR, 0640, 807 "fd%d", fdu); 808 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 809 UID_ROOT, GID_OPERATOR, 0640, 810 "rfd%d", fdu); 811 for (i = 1; i < 1 + NUMDENS; i++) { 812 /* 813 * XXX this and the lookup in Fdopen() should be 814 * data driven. 815 */ 816 switch (fd->type) { 817 case FD_360: 818 if (i != FD_360) 819 continue; 820 break; 821 case FD_720: 822 if (i != FD_720 && i != FD_800 && i != FD_820) 823 continue; 824 break; 825 case FD_1200: 826 if (i != FD_360 && i != FD_720 && i != FD_800 827 && i != FD_820 && i != FD_1200 828 && i != FD_1440 && i != FD_1480) 829 continue; 830 break; 831 case FD_1440: 832 if (i != FD_720 && i != FD_800 && i != FD_820 833 && i != FD_1200 && i != FD_1440 834 && i != FD_1480 && i != FD_1720) 835 continue; 836 break; 837 } 838 typesize = fd_types[i - 1].size / 2; 839 /* 840 * XXX all these conversions give bloated code and 841 * confusing names. 842 */ 843 if (typesize == 1476) 844 typesize = 1480; 845 if (typesize == 1722) 846 typesize = 1720; 847 typemynor = mynor | i; 848 fd->bdevs[i] = 849 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 850 UID_ROOT, GID_OPERATOR, 0640, 851 "fd%d.%d", fdu, typesize); 852 fd->cdevs[i] = 853 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 854 UID_ROOT, GID_OPERATOR, 0640, 855 "rfd%d.%d", fdu, typesize); 856 } 857 858 for (i = 0; i < MAXPARTITIONS; i++) { 859 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 860 "fd%d%c", fdu, 'a' + i); 861 fd->cdevs[1 + NUMDENS + i] = 862 devfs_makelink(fd->cdevs[0], 863 "rfd%d%c", fdu, 'a' + i); 864 } 865#endif /* DEVFS */ | 925 typesize = fd_types[i - 1].size / 2; |
866 /* | 926 /* |
867 * Export the drive to the devstat interface. | 927 * XXX all these conversions give bloated code and 928 * confusing names. |
868 */ | 929 */ |
869 devstat_add_entry(&fd->device_stats, "fd", 870 fdu, 512, 871 DEVSTAT_NO_ORDERED_TAGS, 872 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 873 DEVSTAT_PRIORITY_FD); 874 | 930 if (typesize == 1476) 931 typesize = 1480; 932 if (typesize == 1722) 933 typesize = 1720; 934 typemynor = mynor | i; 935 fd->bdevs[i] = 936 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 937 UID_ROOT, GID_OPERATOR, 0640, 938 "fd%d.%d", fdu, typesize); 939 fd->cdevs[i] = 940 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 941 UID_ROOT, GID_OPERATOR, 0640, 942 "rfd%d.%d", fdu, typesize); |
875 } 876 | 943 } 944 |
877 return (1); | 945 for (i = 0; i < MAXPARTITIONS; i++) { 946 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 947 "fd%d%c", fdu, 'a' + i); 948 fd->cdevs[1 + NUMDENS + i] = 949 devfs_makelink(fd->cdevs[0], 950 "rfd%d%c", fdu, 'a' + i); 951 } 952#endif /* DEVFS */ 953 /* 954 * Export the drive to the devstat interface. 955 */ 956 devstat_add_entry(&fd->device_stats, device_get_name(dev), 957 device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, 958 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 959 DEVSTAT_PRIORITY_FD); 960 return (0); |
878} 879 | 961} 962 |
880 881 | |
882#ifdef FDC_YE 883/* 884 * this is a subset of fdattach() optimized for the Y-E Data 885 * PCMCIA floppy drive. 886 */ 887static int yeattach(struct isa_device *dev) 888{ 889 fdcu_t fdcu = dev->id_unit; --- 121 unchanged lines hidden (view full) --- 1011} 1012#endif 1013 1014/****************************************************************************/ 1015/* motor control stuff */ 1016/* remember to not deselect the drive we're working on */ 1017/****************************************************************************/ 1018static void | 963#ifdef FDC_YE 964/* 965 * this is a subset of fdattach() optimized for the Y-E Data 966 * PCMCIA floppy drive. 967 */ 968static int yeattach(struct isa_device *dev) 969{ 970 fdcu_t fdcu = dev->id_unit; --- 121 unchanged lines hidden (view full) --- 1092} 1093#endif 1094 1095/****************************************************************************/ 1096/* motor control stuff */ 1097/* remember to not deselect the drive we're working on */ 1098/****************************************************************************/ 1099static void |
1019set_motor(fdcu_t fdcu, int fdsu, int turnon) | 1100set_motor(struct fdc_data *fdc, int fdsu, int turnon) |
1020{ | 1101{ |
1021 int fdout = fdc_data[fdcu].fdout; | 1102 int fdout = fdc->fdout; |
1022 int needspecify = 0; 1023 1024 if(turnon) { 1025 fdout &= ~FDO_FDSEL; 1026 fdout |= (FDO_MOEN0 << fdsu) + fdsu; 1027 } else 1028 fdout &= ~(FDO_MOEN0 << fdsu); 1029 1030 if(!turnon 1031 && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) 1032 /* gonna turn off the last drive, put FDC to bed */ 1033 fdout &= ~ (FDO_FRST|FDO_FDMAEN); 1034 else { 1035 /* make sure controller is selected and specified */ 1036 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1037 needspecify = 1; 1038 fdout |= (FDO_FRST|FDO_FDMAEN); 1039 } 1040 | 1103 int needspecify = 0; 1104 1105 if(turnon) { 1106 fdout &= ~FDO_FDSEL; 1107 fdout |= (FDO_MOEN0 << fdsu) + fdsu; 1108 } else 1109 fdout &= ~(FDO_MOEN0 << fdsu); 1110 1111 if(!turnon 1112 && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) 1113 /* gonna turn off the last drive, put FDC to bed */ 1114 fdout &= ~ (FDO_FRST|FDO_FDMAEN); 1115 else { 1116 /* make sure controller is selected and specified */ 1117 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1118 needspecify = 1; 1119 fdout |= (FDO_FRST|FDO_FDMAEN); 1120 } 1121 |
1041 outb(fdc_data[fdcu].baseport+FDOUT, fdout); 1042 fdc_data[fdcu].fdout = fdout; | 1122 outb(fdc->baseport+FDOUT, fdout); 1123 fdc->fdout = fdout; |
1043 TRACE1("[0x%x->FDOUT]", fdout); 1044 | 1124 TRACE1("[0x%x->FDOUT]", fdout); 1125 |
1045 if(needspecify) { | 1126 if (needspecify) { |
1046 /* 1047 * XXX 1048 * special case: since we have just woken up the FDC 1049 * from its sleep, we silently assume the command will 1050 * be accepted, and do not test for a timeout 1051 */ | 1127 /* 1128 * XXX 1129 * special case: since we have just woken up the FDC 1130 * from its sleep, we silently assume the command will 1131 * be accepted, and do not test for a timeout 1132 */ |
1052 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1133 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1053 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1054 0); | 1134 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1135 0); |
1055 if (fdc_data[fdcu].flags & FDC_HAS_FIFO) 1056 (void) enable_fifo(&fdc_data[fdcu]); | 1136 if (fdc->flags & FDC_HAS_FIFO) 1137 (void) enable_fifo(fdc); |
1057 } 1058} 1059 1060static void | 1138 } 1139} 1140 1141static void |
1061fd_turnoff(void *arg1) | 1142fd_turnoff(void *xfd) |
1062{ | 1143{ |
1063 fdu_t fdu = (fdu_t)arg1; | |
1064 int s; | 1144 int s; |
1065 fd_p fd = fd_data + fdu; | 1145 fd_p fd = xfd; |
1066 | 1146 |
1067 TRACE1("[fd%d: turnoff]", fdu); | 1147 TRACE1("[fd%d: turnoff]", fd->fdu); |
1068 1069 /* 1070 * Don't turn off the motor yet if the drive is active. 1071 * XXX shouldn't even schedule turnoff until drive is inactive 1072 * and nothing is queued on it. 1073 */ | 1148 1149 /* 1150 * Don't turn off the motor yet if the drive is active. 1151 * XXX shouldn't even schedule turnoff until drive is inactive 1152 * and nothing is queued on it. 1153 */ |
1074 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fdu) { 1075 fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz); | 1154 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { 1155 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); |
1076 return; 1077 } 1078 1079 s = splbio(); 1080 fd->flags &= ~FD_MOTOR; | 1156 return; 1157 } 1158 1159 s = splbio(); 1160 fd->flags &= ~FD_MOTOR; |
1081 set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF); | 1161 set_motor(fd->fdc, fd->fdsu, TURNOFF); |
1082 splx(s); 1083} 1084 1085static void | 1162 splx(s); 1163} 1164 1165static void |
1086fd_motor_on(void *arg1) | 1166fd_motor_on(void *xfd) |
1087{ | 1167{ |
1088 fdu_t fdu = (fdu_t)arg1; | |
1089 int s; | 1168 int s; |
1169 fd_p fd = xfd; |
|
1090 | 1170 |
1091 fd_p fd = fd_data + fdu; | |
1092 s = splbio(); 1093 fd->flags &= ~FD_MOTOR_WAIT; 1094 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1095 { | 1171 s = splbio(); 1172 fd->flags &= ~FD_MOTOR_WAIT; 1173 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1174 { |
1096 fdintr(fd->fdc->fdcu); | 1175 fdc_intr(fd->fdc); |
1097 } 1098 splx(s); 1099} 1100 1101static void | 1176 } 1177 splx(s); 1178} 1179 1180static void |
1102fd_turnon(fdu_t fdu) | 1181fd_turnon(fd_p fd) |
1103{ | 1182{ |
1104 fd_p fd = fd_data + fdu; | |
1105 if(!(fd->flags & FD_MOTOR)) 1106 { 1107 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); | 1183 if(!(fd->flags & FD_MOTOR)) 1184 { 1185 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); |
1108 set_motor(fd->fdc->fdcu, fd->fdsu, TURNON); 1109 timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */ | 1186 set_motor(fd->fdc, fd->fdsu, TURNON); 1187 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ |
1110 } 1111} 1112 1113static void 1114fdc_reset(fdc_p fdc) 1115{ | 1188 } 1189} 1190 1191static void 1192fdc_reset(fdc_p fdc) 1193{ |
1116 fdcu_t fdcu = fdc->fdcu; 1117 | |
1118 /* Try a reset, keep motor on */ 1119 outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1120 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1121 DELAY(100); 1122 /* enable FDC, but defer interrupts a moment */ 1123 outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN); 1124 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1125 DELAY(100); 1126 outb(fdc->baseport + FDOUT, fdc->fdout); 1127 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1128 1129 /* XXX after a reset, silently believe the FDC will accept commands */ | 1194 /* Try a reset, keep motor on */ 1195 outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1196 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1197 DELAY(100); 1198 /* enable FDC, but defer interrupts a moment */ 1199 outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN); 1200 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1201 DELAY(100); 1202 outb(fdc->baseport + FDOUT, fdc->fdout); 1203 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1204 1205 /* XXX after a reset, silently believe the FDC will accept commands */ |
1130 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1206 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1131 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1132 0); 1133 if (fdc->flags & FDC_HAS_FIFO) 1134 (void) enable_fifo(fdc); 1135} 1136 1137/****************************************************************************/ 1138/* fdc in/out */ 1139/****************************************************************************/ 1140int | 1207 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1208 0); 1209 if (fdc->flags & FDC_HAS_FIFO) 1210 (void) enable_fifo(fdc); 1211} 1212 1213/****************************************************************************/ 1214/* fdc in/out */ 1215/****************************************************************************/ 1216int |
1141in_fdc(fdcu_t fdcu) | 1217in_fdc(struct fdc_data *fdc) |
1142{ | 1218{ |
1143 int baseport = fdc_data[fdcu].baseport; | 1219 int baseport = fdc->baseport; |
1144 int i, j = 100000; 1145 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1146 != (NE7_DIO|NE7_RQM) && j-- > 0) 1147 if (i == NE7_RQM) | 1220 int i, j = 100000; 1221 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1222 != (NE7_DIO|NE7_RQM) && j-- > 0) 1223 if (i == NE7_RQM) |
1148 return fdc_err(fdcu, "ready for output in input\n"); | 1224 return fdc_err(fdc, "ready for output in input\n"); |
1149 if (j <= 0) | 1225 if (j <= 0) |
1150 return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); | 1226 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); |
1151#ifdef FDC_DEBUG 1152 i = inb(baseport+FDDATA); 1153 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1154 return(i); 1155#else /* !FDC_DEBUG */ 1156 return inb(baseport+FDDATA); 1157#endif /* FDC_DEBUG */ 1158} 1159 1160/* 1161 * fd_in: Like in_fdc, but allows you to see if it worked. 1162 */ 1163static int | 1227#ifdef FDC_DEBUG 1228 i = inb(baseport+FDDATA); 1229 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1230 return(i); 1231#else /* !FDC_DEBUG */ 1232 return inb(baseport+FDDATA); 1233#endif /* FDC_DEBUG */ 1234} 1235 1236/* 1237 * fd_in: Like in_fdc, but allows you to see if it worked. 1238 */ 1239static int |
1164fd_in(fdcu_t fdcu, int *ptr) | 1240fd_in(struct fdc_data *fdc, int *ptr) |
1165{ | 1241{ |
1166 int baseport = fdc_data[fdcu].baseport; | 1242 int baseport = fdc->baseport; |
1167 int i, j = 100000; 1168 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1169 != (NE7_DIO|NE7_RQM) && j-- > 0) 1170 if (i == NE7_RQM) | 1243 int i, j = 100000; 1244 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1245 != (NE7_DIO|NE7_RQM) && j-- > 0) 1246 if (i == NE7_RQM) |
1171 return fdc_err(fdcu, "ready for output in input\n"); | 1247 return fdc_err(fdc, "ready for output in input\n"); |
1172 if (j <= 0) | 1248 if (j <= 0) |
1173 return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); | 1249 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); |
1174#ifdef FDC_DEBUG 1175 i = inb(baseport+FDDATA); 1176 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1177 *ptr = i; 1178 return 0; 1179#else /* !FDC_DEBUG */ 1180 i = inb(baseport+FDDATA); 1181 if (ptr) 1182 *ptr = i; 1183 return 0; 1184#endif /* FDC_DEBUG */ 1185} 1186 1187int | 1250#ifdef FDC_DEBUG 1251 i = inb(baseport+FDDATA); 1252 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1253 *ptr = i; 1254 return 0; 1255#else /* !FDC_DEBUG */ 1256 i = inb(baseport+FDDATA); 1257 if (ptr) 1258 *ptr = i; 1259 return 0; 1260#endif /* FDC_DEBUG */ 1261} 1262 1263int |
1188out_fdc(fdcu_t fdcu, int x) | 1264out_fdc(struct fdc_data *fdc, int x) |
1189{ | 1265{ |
1190 int baseport = fdc_data[fdcu].baseport; | 1266 int baseport = fdc->baseport; |
1191 int i; 1192 1193 /* Check that the direction bit is set */ 1194 i = 100000; 1195 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); | 1267 int i; 1268 1269 /* Check that the direction bit is set */ 1270 i = 100000; 1271 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); |
1196 if (i <= 0) return fdc_err(fdcu, "direction bit not set\n"); | 1272 if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); |
1197 1198 /* Check that the floppy controller is ready for a command */ 1199 i = 100000; 1200 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1201 if (i <= 0) | 1273 1274 /* Check that the floppy controller is ready for a command */ 1275 i = 100000; 1276 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1277 if (i <= 0) |
1202 return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0); | 1278 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); |
1203 1204 /* Send the command and return */ 1205 outb(baseport+FDDATA, x); 1206 TRACE1("[0x%x->FDDATA]", x); 1207 return (0); 1208} 1209 1210/****************************************************************************/ 1211/* fdopen/fdclose */ 1212/****************************************************************************/ 1213int 1214Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1215{ 1216 fdu_t fdu = FDUNIT(minor(dev)); 1217 int type = FDTYPE(minor(dev)); | 1279 1280 /* Send the command and return */ 1281 outb(baseport+FDDATA, x); 1282 TRACE1("[0x%x->FDDATA]", x); 1283 return (0); 1284} 1285 1286/****************************************************************************/ 1287/* fdopen/fdclose */ 1288/****************************************************************************/ 1289int 1290Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1291{ 1292 fdu_t fdu = FDUNIT(minor(dev)); 1293 int type = FDTYPE(minor(dev)); |
1294 fd_p fd; |
|
1218 fdc_p fdc; 1219 1220 /* check bounds */ | 1295 fdc_p fdc; 1296 1297 /* check bounds */ |
1221 if (fdu >= NFD) 1222 return(ENXIO); 1223 fdc = fd_data[fdu].fdc; 1224 if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE)) 1225 return(ENXIO); | 1298 if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) 1299 return (ENXIO); 1300 fdc = fd->fdc; 1301 if ((fdc == NULL) || (fd->type == NO_TYPE)) 1302 return (ENXIO); |
1226 if (type > NUMDENS) | 1303 if (type > NUMDENS) |
1227 return(ENXIO); | 1304 return (ENXIO); |
1228 if (type == 0) | 1305 if (type == 0) |
1229 type = fd_data[fdu].type; | 1306 type = fd->type; |
1230 else { 1231 /* 1232 * For each type of basic drive, make sure we are trying 1233 * to open a type it can do, 1234 */ | 1307 else { 1308 /* 1309 * For each type of basic drive, make sure we are trying 1310 * to open a type it can do, 1311 */ |
1235 if (type != fd_data[fdu].type) { 1236 switch (fd_data[fdu].type) { | 1312 if (type != fd->type) { 1313 switch (fd->type) { |
1237 case FD_360: | 1314 case FD_360: |
1238 return(ENXIO); | 1315 return (ENXIO); |
1239 case FD_720: 1240 if ( type != FD_820 1241 && type != FD_800 1242 ) | 1316 case FD_720: 1317 if ( type != FD_820 1318 && type != FD_800 1319 ) |
1243 return(ENXIO); | 1320 return (ENXIO); |
1244 break; 1245 case FD_1200: 1246 switch (type) { 1247 case FD_1480: 1248 type = FD_1480in5_25; 1249 break; 1250 case FD_1440: 1251 type = FD_1440in5_25; --- 22 unchanged lines hidden (view full) --- 1274 && type != FD_800 1275 && type != FD_720 1276 ) 1277 return(ENXIO); 1278 break; 1279 } 1280 } 1281 } | 1321 break; 1322 case FD_1200: 1323 switch (type) { 1324 case FD_1480: 1325 type = FD_1480in5_25; 1326 break; 1327 case FD_1440: 1328 type = FD_1440in5_25; --- 22 unchanged lines hidden (view full) --- 1351 && type != FD_800 1352 && type != FD_720 1353 ) 1354 return(ENXIO); 1355 break; 1356 } 1357 } 1358 } |
1282 fd_data[fdu].ft = fd_types + type - 1; 1283 fd_data[fdu].flags |= FD_OPEN; 1284 | 1359 fd->ft = fd_types + type - 1; 1360 fd->flags |= FD_OPEN; 1361 device_busy(fd->dev); 1362 device_busy(fd->fdc->fdc_dev); |
1285 return 0; 1286} 1287 1288int 1289fdclose(dev_t dev, int flags, int mode, struct proc *p) 1290{ 1291 fdu_t fdu = FDUNIT(minor(dev)); | 1363 return 0; 1364} 1365 1366int 1367fdclose(dev_t dev, int flags, int mode, struct proc *p) 1368{ 1369 fdu_t fdu = FDUNIT(minor(dev)); |
1370 struct fd_data *fd; |
|
1292 | 1371 |
1293 fd_data[fdu].flags &= ~FD_OPEN; 1294 fd_data[fdu].options &= ~FDOPT_NORETRY; | 1372 fd = devclass_get_softc(fd_devclass, fdu); 1373 fd->flags &= ~FD_OPEN; 1374 fd->options &= ~FDOPT_NORETRY; |
1295 | 1375 |
1296 return(0); | 1376 return (0); |
1297} 1298 1299static int 1300fdread(dev_t dev, struct uio *uio, int ioflag) 1301{ 1302 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1303} 1304 --- 7 unchanged lines hidden (view full) --- 1312/****************************************************************************/ 1313/* fdstrategy */ 1314/****************************************************************************/ 1315void 1316fdstrategy(struct buf *bp) 1317{ 1318 unsigned nblocks, blknum, cando; 1319 int s; | 1377} 1378 1379static int 1380fdread(dev_t dev, struct uio *uio, int ioflag) 1381{ 1382 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1383} 1384 --- 7 unchanged lines hidden (view full) --- 1392/****************************************************************************/ 1393/* fdstrategy */ 1394/****************************************************************************/ 1395void 1396fdstrategy(struct buf *bp) 1397{ 1398 unsigned nblocks, blknum, cando; 1399 int s; |
1320 fdcu_t fdcu; | |
1321 fdu_t fdu; 1322 fdc_p fdc; 1323 fd_p fd; 1324 size_t fdblk; 1325 1326 fdu = FDUNIT(minor(bp->b_dev)); | 1400 fdu_t fdu; 1401 fdc_p fdc; 1402 fd_p fd; 1403 size_t fdblk; 1404 1405 fdu = FDUNIT(minor(bp->b_dev)); |
1327 fd = &fd_data[fdu]; | 1406 fd = devclass_get_softc(fd_devclass, fdu); 1407 if (fd == 0) 1408 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", 1409 (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); |
1328 fdc = fd->fdc; | 1410 fdc = fd->fdc; |
1329 fdcu = fdc->fdcu; | |
1330#ifdef FDC_YE 1331 if (fd->type == NO_TYPE) { 1332 bp->b_error = ENXIO; 1333 bp->b_flags |= B_ERROR; 1334 /* 1335 * I _refuse_ to use a goto 1336 */ 1337 biodone(bp); 1338 return; 1339 }; 1340#endif 1341 1342 fdblk = 128 << (fd->ft->secsize); 1343 if (!(bp->b_flags & B_FORMAT)) { | 1411#ifdef FDC_YE 1412 if (fd->type == NO_TYPE) { 1413 bp->b_error = ENXIO; 1414 bp->b_flags |= B_ERROR; 1415 /* 1416 * I _refuse_ to use a goto 1417 */ 1418 biodone(bp); 1419 return; 1420 }; 1421#endif 1422 1423 fdblk = 128 << (fd->ft->secsize); 1424 if (!(bp->b_flags & B_FORMAT)) { |
1344 if ((fdu >= NFD) || (bp->b_blkno < 0)) { | 1425 if (bp->b_blkno < 0) { |
1345 printf( 1346 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1347 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1348 bp->b_error = EINVAL; 1349 bp->b_flags |= B_ERROR; 1350 goto bad; 1351 } 1352 if ((bp->b_bcount % fdblk) != 0) { --- 28 unchanged lines hidden (view full) --- 1381 bp->b_error = EINVAL; 1382 bp->b_flags |= B_ERROR; 1383 goto bad; 1384 } 1385 } 1386 bp->b_pblkno = bp->b_blkno; 1387 s = splbio(); 1388 bufqdisksort(&fdc->head, bp); | 1426 printf( 1427 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1428 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1429 bp->b_error = EINVAL; 1430 bp->b_flags |= B_ERROR; 1431 goto bad; 1432 } 1433 if ((bp->b_bcount % fdblk) != 0) { --- 28 unchanged lines hidden (view full) --- 1462 bp->b_error = EINVAL; 1463 bp->b_flags |= B_ERROR; 1464 goto bad; 1465 } 1466 } 1467 bp->b_pblkno = bp->b_blkno; 1468 s = splbio(); 1469 bufqdisksort(&fdc->head, bp); |
1389 untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */ | 1470 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ |
1390 1391 /* Tell devstat we are starting on the transaction */ 1392 devstat_start_transaction(&fd->device_stats); 1393 | 1471 1472 /* Tell devstat we are starting on the transaction */ 1473 devstat_start_transaction(&fd->device_stats); 1474 |
1394 fdstart(fdcu); | 1475 fdstart(fdc); |
1395 splx(s); 1396 return; 1397 1398bad: 1399 biodone(bp); 1400} 1401 1402/***************************************************************\ 1403* fdstart * 1404* We have just queued something.. if the controller is not busy * 1405* then simulate the case where it has just finished a command * 1406* So that it (the interrupt routine) looks on the queue for more* 1407* work to do and picks up what we just added. * 1408* If the controller is already busy, we need do nothing, as it * 1409* will pick up our work when the present work completes * 1410\***************************************************************/ 1411static void | 1476 splx(s); 1477 return; 1478 1479bad: 1480 biodone(bp); 1481} 1482 1483/***************************************************************\ 1484* fdstart * 1485* We have just queued something.. if the controller is not busy * 1486* then simulate the case where it has just finished a command * 1487* So that it (the interrupt routine) looks on the queue for more* 1488* work to do and picks up what we just added. * 1489* If the controller is already busy, we need do nothing, as it * 1490* will pick up our work when the present work completes * 1491\***************************************************************/ 1492static void |
1412fdstart(fdcu_t fdcu) | 1493fdstart(struct fdc_data *fdc) |
1413{ 1414 int s; 1415 1416 s = splbio(); | 1494{ 1495 int s; 1496 1497 s = splbio(); |
1417 if(fdc_data[fdcu].state == DEVIDLE) | 1498 if(fdc->state == DEVIDLE) |
1418 { | 1499 { |
1419 fdintr(fdcu); | 1500 fdc_intr(fdc); |
1420 } 1421 splx(s); 1422} 1423 1424static void | 1501 } 1502 splx(s); 1503} 1504 1505static void |
1425fd_iotimeout(void *arg1) | 1506fd_iotimeout(void *xfdc) |
1426{ 1427 fdc_p fdc; | 1507{ 1508 fdc_p fdc; |
1428 fdcu_t fdcu; | |
1429 int s; 1430 | 1509 int s; 1510 |
1431 fdcu = (fdcu_t)arg1; 1432 fdc = fdc_data + fdcu; | 1511 fdc = xfdc; |
1433 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1434 1435 /* 1436 * Due to IBM's brain-dead design, the FDC has a faked ready 1437 * signal, hardwired to ready == true. Thus, any command 1438 * issued if there's no diskette in the drive will _never_ 1439 * complete, and must be aborted by resetting the FDC. 1440 * Many thanks, Big Blue! 1441 * The FDC must not be reset directly, since that would 1442 * interfere with the state machine. Instead, pretend that 1443 * the command completed but was invalid. The state machine 1444 * will reset the FDC and retry once. 1445 */ 1446 s = splbio(); 1447 fdc->status[0] = NE7_ST0_IC_IV; 1448 fdc->flags &= ~FDC_STAT_VALID; 1449 fdc->state = IOTIMEDOUT; | 1512 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1513 1514 /* 1515 * Due to IBM's brain-dead design, the FDC has a faked ready 1516 * signal, hardwired to ready == true. Thus, any command 1517 * issued if there's no diskette in the drive will _never_ 1518 * complete, and must be aborted by resetting the FDC. 1519 * Many thanks, Big Blue! 1520 * The FDC must not be reset directly, since that would 1521 * interfere with the state machine. Instead, pretend that 1522 * the command completed but was invalid. The state machine 1523 * will reset the FDC and retry once. 1524 */ 1525 s = splbio(); 1526 fdc->status[0] = NE7_ST0_IC_IV; 1527 fdc->flags &= ~FDC_STAT_VALID; 1528 fdc->state = IOTIMEDOUT; |
1450 fdintr(fdcu); | 1529 fdc_intr(fdc); |
1451 splx(s); 1452} 1453 1454/* just ensure it has the right spl */ 1455static void | 1530 splx(s); 1531} 1532 1533/* just ensure it has the right spl */ 1534static void |
1456fd_pseudointr(void *arg1) | 1535fd_pseudointr(void *xfdc) |
1457{ | 1536{ |
1458 fdcu_t fdcu = (fdcu_t)arg1; | |
1459 int s; 1460 1461 s = splbio(); | 1537 int s; 1538 1539 s = splbio(); |
1462 fdintr(fdcu); | 1540 fdc_intr(xfdc); |
1463 splx(s); 1464} 1465 1466/***********************************************************************\ 1467* fdintr * 1468* keep calling the state machine until it returns a 0 * 1469* ALWAYS called at SPLBIO * 1470\***********************************************************************/ 1471static void | 1541 splx(s); 1542} 1543 1544/***********************************************************************\ 1545* fdintr * 1546* keep calling the state machine until it returns a 0 * 1547* ALWAYS called at SPLBIO * 1548\***********************************************************************/ 1549static void |
1472fdintr(fdcu_t fdcu) | 1550fdc_intr(void *xfdc) |
1473{ | 1551{ |
1474 fdc_p fdc = fdc_data + fdcu; 1475 while(fdstate(fdcu, fdc)) 1476 ; | 1552 fdc_p fdc = xfdc; 1553 while(fdstate(fdc)) 1554 ; |
1477} 1478 1479#ifdef FDC_YE 1480/* 1481 * magic pseudo-DMA initialization for YE FDC. Sets count and 1482 * direction 1483 */ 1484#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ --- 23 unchanged lines hidden (view full) --- 1508} 1509#endif /* FDC_YE */ 1510 1511/***********************************************************************\ 1512* The controller state machine. * 1513* if it returns a non zero value, it should be called again immediatly * 1514\***********************************************************************/ 1515static int | 1555} 1556 1557#ifdef FDC_YE 1558/* 1559 * magic pseudo-DMA initialization for YE FDC. Sets count and 1560 * direction 1561 */ 1562#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ --- 23 unchanged lines hidden (view full) --- 1586} 1587#endif /* FDC_YE */ 1588 1589/***********************************************************************\ 1590* The controller state machine. * 1591* if it returns a non zero value, it should be called again immediatly * 1592\***********************************************************************/ 1593static int |
1516fdstate(fdcu_t fdcu, fdc_p fdc) | 1594fdstate(fdc_p fdc) |
1517{ 1518 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1519 unsigned blknum = 0, b_cylinder = 0; 1520 fdu_t fdu = fdc->fdu; 1521 fd_p fd; 1522 register struct buf *bp; 1523 struct fd_formb *finfo = NULL; 1524 size_t fdblk; --- 7 unchanged lines hidden (view full) --- 1532 } 1533 } 1534 if (bp == NULL) { 1535 /***********************************************\ 1536 * nothing left for this controller to do * 1537 * Force into the IDLE state, * 1538 \***********************************************/ 1539 fdc->state = DEVIDLE; | 1595{ 1596 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1597 unsigned blknum = 0, b_cylinder = 0; 1598 fdu_t fdu = fdc->fdu; 1599 fd_p fd; 1600 register struct buf *bp; 1601 struct fd_formb *finfo = NULL; 1602 size_t fdblk; --- 7 unchanged lines hidden (view full) --- 1610 } 1611 } 1612 if (bp == NULL) { 1613 /***********************************************\ 1614 * nothing left for this controller to do * 1615 * Force into the IDLE state, * 1616 \***********************************************/ 1617 fdc->state = DEVIDLE; |
1540 if(fdc->fd) 1541 { 1542 printf("fd%d: unexpected valid fd pointer\n", 1543 fdc->fdu); | 1618 if (fdc->fd) { 1619 device_print_prettyname(fdc->fdc_dev); 1620 printf("unexpected valid fd pointer\n"); |
1544 fdc->fd = (fd_p) 0; 1545 fdc->fdu = -1; 1546 } | 1621 fdc->fd = (fd_p) 0; 1622 fdc->fdu = -1; 1623 } |
1547 TRACE1("[fdc%d IDLE]", fdcu); 1548 return(0); | 1624 TRACE1("[fdc%d IDLE]", fdc->fdcu); 1625 return (0); |
1549 } 1550 fdu = FDUNIT(minor(bp->b_dev)); | 1626 } 1627 fdu = FDUNIT(minor(bp->b_dev)); |
1551 fd = fd_data + fdu; | 1628 fd = devclass_get_softc(fd_devclass, fdu); |
1552 fdblk = 128 << fd->ft->secsize; | 1629 fdblk = 128 << fd->ft->secsize; |
1553 if (fdc->fd && (fd != fdc->fd)) 1554 { 1555 printf("fd%d: confused fd pointers\n", fdu); | 1630 if (fdc->fd && (fd != fdc->fd)) { 1631 device_print_prettyname(fd->dev); 1632 printf("confused fd pointers\n"); |
1556 } 1557 read = bp->b_flags & B_READ; 1558 format = bp->b_flags & B_FORMAT; | 1633 } 1634 read = bp->b_flags & B_READ; 1635 format = bp->b_flags & B_FORMAT; |
1559 if(format) { | 1636 if (format) { |
1560 finfo = (struct fd_formb *)bp->b_data; 1561 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1562 - (char *)finfo; 1563 } 1564 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1565 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1566 fd->skip/fdblk; 1567 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1568 } 1569 TRACE1("fd%d", fdu); 1570 TRACE1("[%s]", fdstates[fdc->state]); 1571 TRACE1("(0x%x)", fd->flags); | 1637 finfo = (struct fd_formb *)bp->b_data; 1638 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1639 - (char *)finfo; 1640 } 1641 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1642 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1643 fd->skip/fdblk; 1644 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1645 } 1646 TRACE1("fd%d", fdu); 1647 TRACE1("[%s]", fdstates[fdc->state]); 1648 TRACE1("(0x%x)", fd->flags); |
1572 untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); 1573 fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 4 * hz); | 1649 untimeout(fd_turnoff, fd, fd->toffhandle); 1650 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); |
1574 switch (fdc->state) 1575 { 1576 case DEVIDLE: 1577 case FINDWORK: /* we have found new work */ 1578 fdc->retry = 0; 1579 fd->skip = 0; 1580 fdc->fd = fd; 1581 fdc->fdu = fdu; 1582 outb(fdc->baseport+FDCTL, fd->ft->trans); 1583 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1584 /*******************************************************\ 1585 * If the next drive has a motor startup pending, then * 1586 * it will start up in its own good time * 1587 \*******************************************************/ | 1651 switch (fdc->state) 1652 { 1653 case DEVIDLE: 1654 case FINDWORK: /* we have found new work */ 1655 fdc->retry = 0; 1656 fd->skip = 0; 1657 fdc->fd = fd; 1658 fdc->fdu = fdu; 1659 outb(fdc->baseport+FDCTL, fd->ft->trans); 1660 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1661 /*******************************************************\ 1662 * If the next drive has a motor startup pending, then * 1663 * it will start up in its own good time * 1664 \*******************************************************/ |
1588 if(fd->flags & FD_MOTOR_WAIT) 1589 { | 1665 if(fd->flags & FD_MOTOR_WAIT) { |
1590 fdc->state = MOTORWAIT; | 1666 fdc->state = MOTORWAIT; |
1591 return(0); /* come back later */ | 1667 return (0); /* come back later */ |
1592 } 1593 /*******************************************************\ 1594 * Maybe if it's not starting, it SHOULD be starting * 1595 \*******************************************************/ 1596 if (!(fd->flags & FD_MOTOR)) 1597 { 1598 fdc->state = MOTORWAIT; | 1668 } 1669 /*******************************************************\ 1670 * Maybe if it's not starting, it SHOULD be starting * 1671 \*******************************************************/ 1672 if (!(fd->flags & FD_MOTOR)) 1673 { 1674 fdc->state = MOTORWAIT; |
1599 fd_turnon(fdu); 1600 return(0); | 1675 fd_turnon(fd); 1676 return (0); |
1601 } 1602 else /* at least make sure we are selected */ 1603 { | 1677 } 1678 else /* at least make sure we are selected */ 1679 { |
1604 set_motor(fdcu, fd->fdsu, TURNON); | 1680 set_motor(fdc, fd->fdsu, TURNON); |
1605 } 1606 if (fdc->flags & FDC_NEEDS_RESET) { 1607 fdc->state = RESETCTLR; 1608 fdc->flags &= ~FDC_NEEDS_RESET; 1609 } else 1610 fdc->state = DOSEEK; 1611 break; 1612 case DOSEEK: 1613 if (b_cylinder == (unsigned)fd->track) 1614 { 1615 fdc->state = SEEKCOMPLETE; 1616 break; 1617 } | 1681 } 1682 if (fdc->flags & FDC_NEEDS_RESET) { 1683 fdc->state = RESETCTLR; 1684 fdc->flags &= ~FDC_NEEDS_RESET; 1685 } else 1686 fdc->state = DOSEEK; 1687 break; 1688 case DOSEEK: 1689 if (b_cylinder == (unsigned)fd->track) 1690 { 1691 fdc->state = SEEKCOMPLETE; 1692 break; 1693 } |
1618 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, | 1694 if (fd_cmd(fdc, 3, NE7CMD_SEEK, |
1619 fd->fdsu, b_cylinder * fd->ft->steptrac, 1620 0)) 1621 { 1622 /* 1623 * seek command not accepted, looks like 1624 * the FDC went off to the Saints... 1625 */ 1626 fdc->retry = 6; /* try a reset */ | 1695 fd->fdsu, b_cylinder * fd->ft->steptrac, 1696 0)) 1697 { 1698 /* 1699 * seek command not accepted, looks like 1700 * the FDC went off to the Saints... 1701 */ 1702 fdc->retry = 6; /* try a reset */ |
1627 return(retrier(fdcu)); | 1703 return(retrier(fdc)); |
1628 } 1629 fd->track = FD_NO_TRACK; 1630 fdc->state = SEEKWAIT; 1631 return(0); /* will return later */ 1632 case SEEKWAIT: 1633 /* allow heads to settle */ | 1704 } 1705 fd->track = FD_NO_TRACK; 1706 fdc->state = SEEKWAIT; 1707 return(0); /* will return later */ 1708 case SEEKWAIT: 1709 /* allow heads to settle */ |
1634 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16); | 1710 timeout(fd_pseudointr, fdc, hz / 16); |
1635 fdc->state = SEEKCOMPLETE; 1636 return(0); /* will return later */ 1637 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 1638 /* Make sure seek really happened*/ | 1711 fdc->state = SEEKCOMPLETE; 1712 return(0); /* will return later */ 1713 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 1714 /* Make sure seek really happened*/ |
1639 if(fd->track == FD_NO_TRACK) 1640 { | 1715 if(fd->track == FD_NO_TRACK) { |
1641 int descyl = b_cylinder * fd->ft->steptrac; 1642 do { 1643 /* 1644 * This might be a "ready changed" interrupt, 1645 * which cannot really happen since the 1646 * RDY pin is hardwired to + 5 volts. This 1647 * generally indicates a "bouncing" intr 1648 * line, so do one of the following: --- 15 unchanged lines hidden (view full) --- 1664 if (fd_sense_int(fdc, &st0, &cyl) 1665 == FD_NOT_VALID) 1666 return 0; 1667 if(fdc->fdct == FDC_NE765 1668 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 1669 return 0; /* hope for a real intr */ 1670 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1671 | 1716 int descyl = b_cylinder * fd->ft->steptrac; 1717 do { 1718 /* 1719 * This might be a "ready changed" interrupt, 1720 * which cannot really happen since the 1721 * RDY pin is hardwired to + 5 volts. This 1722 * generally indicates a "bouncing" intr 1723 * line, so do one of the following: --- 15 unchanged lines hidden (view full) --- 1739 if (fd_sense_int(fdc, &st0, &cyl) 1740 == FD_NOT_VALID) 1741 return 0; 1742 if(fdc->fdct == FDC_NE765 1743 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 1744 return 0; /* hope for a real intr */ 1745 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1746 |
1672 if (0 == descyl) 1673 { | 1747 if (0 == descyl) { |
1674 int failed = 0; 1675 /* 1676 * seek to cyl 0 requested; make sure we are 1677 * really there 1678 */ 1679 if (fd_sense_drive_status(fdc, &st3)) 1680 failed = 1; 1681 if ((st3 & NE7_ST3_T0) == 0) { 1682 printf( 1683 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 1684 fdu, st3, NE7_ST3BITS); 1685 failed = 1; 1686 } 1687 | 1748 int failed = 0; 1749 /* 1750 * seek to cyl 0 requested; make sure we are 1751 * really there 1752 */ 1753 if (fd_sense_drive_status(fdc, &st3)) 1754 failed = 1; 1755 if ((st3 & NE7_ST3_T0) == 0) { 1756 printf( 1757 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 1758 fdu, st3, NE7_ST3BITS); 1759 failed = 1; 1760 } 1761 |
1688 if (failed) 1689 { | 1762 if (failed) { |
1690 if(fdc->retry < 3) 1691 fdc->retry = 3; | 1763 if(fdc->retry < 3) 1764 fdc->retry = 3; |
1692 return(retrier(fdcu)); | 1765 return (retrier(fdc)); |
1693 } 1694 } 1695 | 1766 } 1767 } 1768 |
1696 if (cyl != descyl) 1697 { | 1769 if (cyl != descyl) { |
1698 printf( 1699 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 1700 fdu, descyl, cyl, st0); 1701 if (fdc->retry < 3) 1702 fdc->retry = 3; | 1770 printf( 1771 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 1772 fdu, descyl, cyl, st0); 1773 if (fdc->retry < 3) 1774 fdc->retry = 3; |
1703 return(retrier(fdcu)); | 1775 return (retrier(fdc)); |
1704 } 1705 } 1706 1707 fd->track = b_cylinder; 1708#ifdef FDC_YE 1709 if (!(fdc->flags & FDC_PCMCIA)) 1710#endif 1711 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, --- 9 unchanged lines hidden (view full) --- 1721 /* make sure the drive is writable */ 1722 if(fd_sense_drive_status(fdc, &st3) != 0) 1723 { 1724 /* stuck controller? */ 1725 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1726 format ? bp->b_bcount : fdblk, 1727 fdc->dmachan); 1728 fdc->retry = 6; /* reset the beast */ | 1776 } 1777 } 1778 1779 fd->track = b_cylinder; 1780#ifdef FDC_YE 1781 if (!(fdc->flags & FDC_PCMCIA)) 1782#endif 1783 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, --- 9 unchanged lines hidden (view full) --- 1793 /* make sure the drive is writable */ 1794 if(fd_sense_drive_status(fdc, &st3) != 0) 1795 { 1796 /* stuck controller? */ 1797 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1798 format ? bp->b_bcount : fdblk, 1799 fdc->dmachan); 1800 fdc->retry = 6; /* reset the beast */ |
1729 return(retrier(fdcu)); | 1801 return (retrier(fdc)); |
1730 } 1731 if(st3 & NE7_ST3_WP) 1732 { 1733 /* 1734 * XXX YES! this is ugly. 1735 * in order to force the current operation 1736 * to fail, we will have to fake an FDC 1737 * error - all error handling is done --- 6 unchanged lines hidden (view full) --- 1744 fdc->status[4] = head; 1745 fdc->status[5] = sec; 1746 fdc->retry = 8; /* break out immediately */ 1747 fdc->state = IOTIMEDOUT; /* not really... */ 1748 return (1); 1749 } 1750 } 1751 | 1802 } 1803 if(st3 & NE7_ST3_WP) 1804 { 1805 /* 1806 * XXX YES! this is ugly. 1807 * in order to force the current operation 1808 * to fail, we will have to fake an FDC 1809 * error - all error handling is done --- 6 unchanged lines hidden (view full) --- 1816 fdc->status[4] = head; 1817 fdc->status[5] = sec; 1818 fdc->retry = 8; /* break out immediately */ 1819 fdc->state = IOTIMEDOUT; /* not really... */ 1820 return (1); 1821 } 1822 } 1823 |
1752 if(format) 1753 { | 1824 if (format) { |
1754#ifdef FDC_YE 1755 if (fdc->flags & FDC_PCMCIA) 1756 (void)fdcpio(fdcu,bp->b_flags, 1757 bp->b_data+fd->skip, 1758 bp->b_bcount); 1759#endif 1760 /* formatting */ | 1825#ifdef FDC_YE 1826 if (fdc->flags & FDC_PCMCIA) 1827 (void)fdcpio(fdcu,bp->b_flags, 1828 bp->b_data+fd->skip, 1829 bp->b_bcount); 1830#endif 1831 /* formatting */ |
1761 if(fd_cmd(fdcu, 6, 1762 NE7CMD_FORMAT, 1763 head << 2 | fdu, | 1832 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, |
1764 finfo->fd_formb_secshift, 1765 finfo->fd_formb_nsecs, 1766 finfo->fd_formb_gaplen, | 1833 finfo->fd_formb_secshift, 1834 finfo->fd_formb_nsecs, 1835 finfo->fd_formb_gaplen, |
1767 finfo->fd_formb_fillbyte, 1768 0)) 1769 { | 1836 finfo->fd_formb_fillbyte, 0)) { |
1770 /* controller fell over */ 1771 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1772 format ? bp->b_bcount : fdblk, 1773 fdc->dmachan); 1774 fdc->retry = 6; | 1837 /* controller fell over */ 1838 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1839 format ? bp->b_bcount : fdblk, 1840 fdc->dmachan); 1841 fdc->retry = 6; |
1775 return(retrier(fdcu)); | 1842 return (retrier(fdc)); |
1776 } | 1843 } |
1777 } 1778 else 1779 { | 1844 } else { |
1780#ifdef FDC_YE 1781 if (fdc->flags & FDC_PCMCIA) { 1782 /* 1783 * this seems to be necessary even when 1784 * reading data 1785 */ 1786 SET_BCDR(1,fdblk,fdc->baseport); 1787 1788 /* 1789 * perform the write pseudo-DMA before 1790 * the WRITE command is sent 1791 */ 1792 if (!read) 1793 (void)fdcpio(fdcu,bp->b_flags, 1794 bp->b_data+fd->skip, 1795 fdblk); 1796 } 1797#endif | 1845#ifdef FDC_YE 1846 if (fdc->flags & FDC_PCMCIA) { 1847 /* 1848 * this seems to be necessary even when 1849 * reading data 1850 */ 1851 SET_BCDR(1,fdblk,fdc->baseport); 1852 1853 /* 1854 * perform the write pseudo-DMA before 1855 * the WRITE command is sent 1856 */ 1857 if (!read) 1858 (void)fdcpio(fdcu,bp->b_flags, 1859 bp->b_data+fd->skip, 1860 fdblk); 1861 } 1862#endif |
1798 if (fd_cmd(fdcu, 9, | 1863 if (fd_cmd(fdc, 9, |
1799 (read ? NE7CMD_READ : NE7CMD_WRITE), 1800 head << 2 | fdu, /* head & unit */ 1801 fd->track, /* track */ 1802 head, 1803 sec, /* sector + 1 */ 1804 fd->ft->secsize, /* sector size */ 1805 sectrac, /* sectors/track */ 1806 fd->ft->gap, /* gap size */ 1807 fd->ft->datalen, /* data length */ | 1864 (read ? NE7CMD_READ : NE7CMD_WRITE), 1865 head << 2 | fdu, /* head & unit */ 1866 fd->track, /* track */ 1867 head, 1868 sec, /* sector + 1 */ 1869 fd->ft->secsize, /* sector size */ 1870 sectrac, /* sectors/track */ 1871 fd->ft->gap, /* gap size */ 1872 fd->ft->datalen, /* data length */ |
1808 0)) 1809 { | 1873 0)) { |
1810 /* the beast is sleeping again */ 1811 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1812 format ? bp->b_bcount : fdblk, 1813 fdc->dmachan); 1814 fdc->retry = 6; | 1874 /* the beast is sleeping again */ 1875 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1876 format ? bp->b_bcount : fdblk, 1877 fdc->dmachan); 1878 fdc->retry = 6; |
1815 return(retrier(fdcu)); | 1879 return (retrier(fdc)); |
1816 } 1817 } 1818#ifdef FDC_YE 1819 if (fdc->flags & FDC_PCMCIA) 1820 /* 1821 * if this is a read, then simply await interrupt 1822 * before performing PIO 1823 */ --- 5 unchanged lines hidden (view full) --- 1829 }; 1830 1831 /* 1832 * write (or format) operation will fall through and 1833 * await completion interrupt 1834 */ 1835#endif 1836 fdc->state = IOCOMPLETE; | 1880 } 1881 } 1882#ifdef FDC_YE 1883 if (fdc->flags & FDC_PCMCIA) 1884 /* 1885 * if this is a read, then simply await interrupt 1886 * before performing PIO 1887 */ --- 5 unchanged lines hidden (view full) --- 1893 }; 1894 1895 /* 1896 * write (or format) operation will fall through and 1897 * await completion interrupt 1898 */ 1899#endif 1900 fdc->state = IOCOMPLETE; |
1837 fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz); 1838 return(0); /* will return later */ | 1901 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 1902 return (0); /* will return later */ |
1839#ifdef FDC_YE 1840 case PIOREAD: 1841 /* 1842 * actually perform the PIO read. The IOCOMPLETE case 1843 * removes the timeout for us. 1844 */ 1845 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 1846 fdc->state = IOCOMPLETE; 1847 /* FALLTHROUGH */ 1848#endif 1849 case IOCOMPLETE: /* IO DONE, post-analyze */ | 1903#ifdef FDC_YE 1904 case PIOREAD: 1905 /* 1906 * actually perform the PIO read. The IOCOMPLETE case 1907 * removes the timeout for us. 1908 */ 1909 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 1910 fdc->state = IOCOMPLETE; 1911 /* FALLTHROUGH */ 1912#endif 1913 case IOCOMPLETE: /* IO DONE, post-analyze */ |
1850 untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle); | 1914 untimeout(fd_iotimeout, fdc, fd->tohandle); |
1851 | 1915 |
1852 if (fd_read_status(fdc, fd->fdsu)) 1853 { | 1916 if (fd_read_status(fdc, fd->fdsu)) { |
1854 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1855 format ? bp->b_bcount : fdblk, 1856 fdc->dmachan); 1857 if (fdc->retry < 6) 1858 fdc->retry = 6; /* force a reset */ | 1917 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1918 format ? bp->b_bcount : fdblk, 1919 fdc->dmachan); 1920 if (fdc->retry < 6) 1921 fdc->retry = 6; /* force a reset */ |
1859 return retrier(fdcu); | 1922 return (retrier(fdc)); |
1860 } 1861 1862 fdc->state = IOTIMEDOUT; 1863 1864 /* FALLTHROUGH */ 1865 1866 case IOTIMEDOUT: 1867#ifdef FDC_YE 1868 if (!(fdc->flags & FDC_PCMCIA)) 1869#endif 1870 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1871 format ? bp->b_bcount : fdblk, fdc->dmachan); | 1923 } 1924 1925 fdc->state = IOTIMEDOUT; 1926 1927 /* FALLTHROUGH */ 1928 1929 case IOTIMEDOUT: 1930#ifdef FDC_YE 1931 if (!(fdc->flags & FDC_PCMCIA)) 1932#endif 1933 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1934 format ? bp->b_bcount : fdblk, fdc->dmachan); |
1872 if (fdc->status[0] & NE7_ST0_IC) 1873 { | 1935 if (fdc->status[0] & NE7_ST0_IC) { |
1874 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1875 && fdc->status[1] & NE7_ST1_OR) { 1876 /* 1877 * DMA overrun. Someone hogged the bus 1878 * and didn't release it in time for the 1879 * next FDC transfer. 1880 * Just restart it, don't increment retry 1881 * count. (vak) 1882 */ 1883 fdc->state = SEEKCOMPLETE; 1884 return (1); 1885 } 1886 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 1887 && fdc->retry < 6) 1888 fdc->retry = 6; /* force a reset */ 1889 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1890 && fdc->status[2] & NE7_ST2_WC 1891 && fdc->retry < 3) 1892 fdc->retry = 3; /* force recalibrate */ | 1936 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1937 && fdc->status[1] & NE7_ST1_OR) { 1938 /* 1939 * DMA overrun. Someone hogged the bus 1940 * and didn't release it in time for the 1941 * next FDC transfer. 1942 * Just restart it, don't increment retry 1943 * count. (vak) 1944 */ 1945 fdc->state = SEEKCOMPLETE; 1946 return (1); 1947 } 1948 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 1949 && fdc->retry < 6) 1950 fdc->retry = 6; /* force a reset */ 1951 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1952 && fdc->status[2] & NE7_ST2_WC 1953 && fdc->retry < 3) 1954 fdc->retry = 3; /* force recalibrate */ |
1893 return(retrier(fdcu)); | 1955 return (retrier(fdc)); |
1894 } 1895 /* All OK */ 1896 fd->skip += fdblk; | 1956 } 1957 /* All OK */ 1958 fd->skip += fdblk; |
1897 if (!format && fd->skip < bp->b_bcount - bp->b_resid) 1898 { | 1959 if (!format && fd->skip < bp->b_bcount - bp->b_resid) { |
1899 /* set up next transfer */ 1900 fdc->state = DOSEEK; | 1960 /* set up next transfer */ 1961 fdc->state = DOSEEK; |
1901 } 1902 else 1903 { | 1962 } else { |
1904 /* ALL DONE */ 1905 fd->skip = 0; 1906 fdc->bp = NULL; 1907 /* Tell devstat we have finished with the transaction */ 1908 devstat_end_transaction(&fd->device_stats, 1909 bp->b_bcount - bp->b_resid, 1910 DEVSTAT_TAG_NONE, 1911 (bp->b_flags & B_READ) ? 1912 DEVSTAT_READ : DEVSTAT_WRITE); 1913 biodone(bp); 1914 fdc->fd = (fd_p) 0; 1915 fdc->fdu = -1; 1916 fdc->state = FINDWORK; 1917 } | 1963 /* ALL DONE */ 1964 fd->skip = 0; 1965 fdc->bp = NULL; 1966 /* Tell devstat we have finished with the transaction */ 1967 devstat_end_transaction(&fd->device_stats, 1968 bp->b_bcount - bp->b_resid, 1969 DEVSTAT_TAG_NONE, 1970 (bp->b_flags & B_READ) ? 1971 DEVSTAT_READ : DEVSTAT_WRITE); 1972 biodone(bp); 1973 fdc->fd = (fd_p) 0; 1974 fdc->fdu = -1; 1975 fdc->state = FINDWORK; 1976 } |
1918 return(1); | 1977 return (1); |
1919 case RESETCTLR: 1920 fdc_reset(fdc); 1921 fdc->retry++; 1922 fdc->state = RESETCOMPLETE; 1923 return (0); 1924 case RESETCOMPLETE: 1925 /* 1926 * Discard all the results from the reset so that they 1927 * can't cause an unexpected interrupt later. 1928 */ 1929 for (i = 0; i < 4; i++) 1930 (void)fd_sense_int(fdc, &st0, &cyl); 1931 fdc->state = STARTRECAL; 1932 /* Fall through. */ 1933 case STARTRECAL: | 1978 case RESETCTLR: 1979 fdc_reset(fdc); 1980 fdc->retry++; 1981 fdc->state = RESETCOMPLETE; 1982 return (0); 1983 case RESETCOMPLETE: 1984 /* 1985 * Discard all the results from the reset so that they 1986 * can't cause an unexpected interrupt later. 1987 */ 1988 for (i = 0; i < 4; i++) 1989 (void)fd_sense_int(fdc, &st0, &cyl); 1990 fdc->state = STARTRECAL; 1991 /* Fall through. */ 1992 case STARTRECAL: |
1934 if(fd_cmd(fdcu, 1935 2, NE7CMD_RECAL, fdu, 1936 0)) /* Recalibrate Function */ 1937 { | 1993 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { |
1938 /* arrgl */ 1939 fdc->retry = 6; | 1994 /* arrgl */ 1995 fdc->retry = 6; |
1940 return(retrier(fdcu)); | 1996 return (retrier(fdc)); |
1941 } 1942 fdc->state = RECALWAIT; | 1997 } 1998 fdc->state = RECALWAIT; |
1943 return(0); /* will return later */ | 1999 return (0); /* will return later */ |
1944 case RECALWAIT: 1945 /* allow heads to settle */ | 2000 case RECALWAIT: 2001 /* allow heads to settle */ |
1946 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8); | 2002 timeout(fd_pseudointr, fdc, hz / 8); |
1947 fdc->state = RECALCOMPLETE; | 2003 fdc->state = RECALCOMPLETE; |
1948 return(0); /* will return later */ | 2004 return (0); /* will return later */ |
1949 case RECALCOMPLETE: 1950 do { 1951 /* 1952 * See SEEKCOMPLETE for a comment on this: 1953 */ 1954 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 1955 return 0; 1956 if(fdc->fdct == FDC_NE765 --- 9 unchanged lines hidden (view full) --- 1966 * since people used to complain much about 1967 * the failure message, try not logging 1968 * this one if it seems to be the first 1969 * time in a line 1970 */ 1971 printf("fd%d: recal failed ST0 %b cyl %d\n", 1972 fdu, st0, NE7_ST0BITS, cyl); 1973 if(fdc->retry < 3) fdc->retry = 3; | 2005 case RECALCOMPLETE: 2006 do { 2007 /* 2008 * See SEEKCOMPLETE for a comment on this: 2009 */ 2010 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2011 return 0; 2012 if(fdc->fdct == FDC_NE765 --- 9 unchanged lines hidden (view full) --- 2022 * since people used to complain much about 2023 * the failure message, try not logging 2024 * this one if it seems to be the first 2025 * time in a line 2026 */ 2027 printf("fd%d: recal failed ST0 %b cyl %d\n", 2028 fdu, st0, NE7_ST0BITS, cyl); 2029 if(fdc->retry < 3) fdc->retry = 3; |
1974 return(retrier(fdcu)); | 2030 return (retrier(fdc)); |
1975 } 1976 fd->track = 0; 1977 /* Seek (probably) necessary */ 1978 fdc->state = DOSEEK; | 2031 } 2032 fd->track = 0; 2033 /* Seek (probably) necessary */ 2034 fdc->state = DOSEEK; |
1979 return(1); /* will return immediatly */ | 2035 return (1); /* will return immediatly */ |
1980 case MOTORWAIT: 1981 if(fd->flags & FD_MOTOR_WAIT) 1982 { | 2036 case MOTORWAIT: 2037 if(fd->flags & FD_MOTOR_WAIT) 2038 { |
1983 return(0); /* time's not up yet */ | 2039 return (0); /* time's not up yet */ |
1984 } 1985 if (fdc->flags & FDC_NEEDS_RESET) { 1986 fdc->state = RESETCTLR; 1987 fdc->flags &= ~FDC_NEEDS_RESET; 1988 } else { 1989 /* 1990 * If all motors were off, then the controller was 1991 * reset, so it has lost track of the current 1992 * cylinder. Recalibrate to handle this case. 1993 */ 1994 fdc->state = STARTRECAL; 1995 } | 2040 } 2041 if (fdc->flags & FDC_NEEDS_RESET) { 2042 fdc->state = RESETCTLR; 2043 fdc->flags &= ~FDC_NEEDS_RESET; 2044 } else { 2045 /* 2046 * If all motors were off, then the controller was 2047 * reset, so it has lost track of the current 2048 * cylinder. Recalibrate to handle this case. 2049 */ 2050 fdc->state = STARTRECAL; 2051 } |
1996 return(1); /* will return immediatly */ | 2052 return (1); /* will return immediatly */ |
1997 default: | 2053 default: |
1998 printf("fdc%d: Unexpected FD int->", fdcu); | 2054 device_print_prettyname(fdc->fdc_dev); 2055 printf("unexpected FD int->"); |
1999 if (fd_read_status(fdc, fd->fdsu) == 0) 2000 printf("FDC status :%x %x %x %x %x %x %x ", 2001 fdc->status[0], 2002 fdc->status[1], 2003 fdc->status[2], 2004 fdc->status[3], 2005 fdc->status[4], 2006 fdc->status[5], 2007 fdc->status[6] ); 2008 else 2009 printf("No status available "); 2010 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2011 { 2012 printf("[controller is dead now]\n"); | 2056 if (fd_read_status(fdc, fd->fdsu) == 0) 2057 printf("FDC status :%x %x %x %x %x %x %x ", 2058 fdc->status[0], 2059 fdc->status[1], 2060 fdc->status[2], 2061 fdc->status[3], 2062 fdc->status[4], 2063 fdc->status[5], 2064 fdc->status[6] ); 2065 else 2066 printf("No status available "); 2067 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2068 { 2069 printf("[controller is dead now]\n"); |
2013 return(0); | 2070 return (0); |
2014 } 2015 printf("ST0 = %x, PCN = %x\n", st0, cyl); | 2071 } 2072 printf("ST0 = %x, PCN = %x\n", st0, cyl); |
2016 return(0); | 2073 return (0); |
2017 } 2018 /*XXX confusing: some branches return immediately, others end up here*/ | 2074 } 2075 /*XXX confusing: some branches return immediately, others end up here*/ |
2019 return(1); /* Come back immediatly to new state */ | 2076 return (1); /* Come back immediatly to new state */ |
2020} 2021 2022static int | 2077} 2078 2079static int |
2023retrier(fdcu) 2024 fdcu_t fdcu; | 2080retrier(struct fdc_data *fdc) |
2025{ | 2081{ |
2026 fdc_p fdc = fdc_data + fdcu; | |
2027 register struct buf *bp; | 2082 register struct buf *bp; |
2083 struct fd_data *fd; 2084 int fdu; |
|
2028 2029 bp = fdc->bp; 2030 | 2085 2086 bp = fdc->bp; 2087 |
2031 if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY) | 2088 /* XXX shouldn't this be cached somewhere? */ 2089 fdu = FDUNIT(minor(bp->b_dev)); 2090 fd = devclass_get_softc(fd_devclass, fdu); 2091 if (fd->options & FDOPT_NORETRY) |
2032 goto fail; | 2092 goto fail; |
2033 switch(fdc->retry) 2034 { | 2093 2094 switch (fdc->retry) { |
2035 case 0: case 1: case 2: 2036 fdc->state = SEEKCOMPLETE; 2037 break; 2038 case 3: case 4: case 5: 2039 fdc->state = STARTRECAL; 2040 break; 2041 case 6: 2042 fdc->state = RESETCTLR; --- 36 unchanged lines hidden (view full) --- 2079 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2080 DEVSTAT_WRITE); 2081 fdc->fd->skip = 0; 2082 biodone(bp); 2083 fdc->state = FINDWORK; 2084 fdc->flags |= FDC_NEEDS_RESET; 2085 fdc->fd = (fd_p) 0; 2086 fdc->fdu = -1; | 2095 case 0: case 1: case 2: 2096 fdc->state = SEEKCOMPLETE; 2097 break; 2098 case 3: case 4: case 5: 2099 fdc->state = STARTRECAL; 2100 break; 2101 case 6: 2102 fdc->state = RESETCTLR; --- 36 unchanged lines hidden (view full) --- 2139 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2140 DEVSTAT_WRITE); 2141 fdc->fd->skip = 0; 2142 biodone(bp); 2143 fdc->state = FINDWORK; 2144 fdc->flags |= FDC_NEEDS_RESET; 2145 fdc->fd = (fd_p) 0; 2146 fdc->fdu = -1; |
2087 return(1); | 2147 return (1); |
2088 } 2089 fdc->retry++; | 2148 } 2149 fdc->retry++; |
2090 return(1); | 2150 return (1); |
2091} 2092 2093static int 2094fdformat(dev, finfo, p) 2095 dev_t dev; 2096 struct fd_formb *finfo; 2097 struct proc *p; 2098{ 2099 fdu_t fdu; 2100 fd_p fd; 2101 2102 struct buf *bp; 2103 int rv = 0, s; 2104 size_t fdblk; 2105 2106 fdu = FDUNIT(minor(dev)); | 2151} 2152 2153static int 2154fdformat(dev, finfo, p) 2155 dev_t dev; 2156 struct fd_formb *finfo; 2157 struct proc *p; 2158{ 2159 fdu_t fdu; 2160 fd_p fd; 2161 2162 struct buf *bp; 2163 int rv = 0, s; 2164 size_t fdblk; 2165 2166 fdu = FDUNIT(minor(dev)); |
2107 fd = &fd_data[fdu]; | 2167 fd = devclass_get_softc(fd_devclass, fdu); |
2108 fdblk = 128 << fd->ft->secsize; 2109 2110 /* set up a buffer header for fdstrategy() */ 2111 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2112 if(bp == 0) 2113 return ENOBUFS; 2114 /* 2115 * keep the process from being swapped --- 14 unchanged lines hidden (view full) --- 2130 bp->b_data = (caddr_t)finfo; 2131 2132 /* now do the format */ 2133 bp->b_dev = dev; 2134 fdstrategy(bp); 2135 2136 /* ...and wait for it to complete */ 2137 s = splbio(); | 2168 fdblk = 128 << fd->ft->secsize; 2169 2170 /* set up a buffer header for fdstrategy() */ 2171 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2172 if(bp == 0) 2173 return ENOBUFS; 2174 /* 2175 * keep the process from being swapped --- 14 unchanged lines hidden (view full) --- 2190 bp->b_data = (caddr_t)finfo; 2191 2192 /* now do the format */ 2193 bp->b_dev = dev; 2194 fdstrategy(bp); 2195 2196 /* ...and wait for it to complete */ 2197 s = splbio(); |
2138 while(!(bp->b_flags & B_DONE)) 2139 { | 2198 while(!(bp->b_flags & B_DONE)) { |
2140 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); | 2199 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); |
2141 if(rv == EWOULDBLOCK) | 2200 if (rv == EWOULDBLOCK) |
2142 break; 2143 } 2144 splx(s); 2145 | 2201 break; 2202 } 2203 splx(s); 2204 |
2146 if(rv == EWOULDBLOCK) { | 2205 if (rv == EWOULDBLOCK) { |
2147 /* timed out */ 2148 rv = EIO; 2149 biodone(bp); 2150 } | 2206 /* timed out */ 2207 rv = EIO; 2208 biodone(bp); 2209 } |
2151 if(bp->b_flags & B_ERROR) | 2210 if (bp->b_flags & B_ERROR) |
2152 rv = bp->b_error; 2153 /* 2154 * allow the process to be swapped 2155 */ 2156 PRELE(p); 2157 free(bp, M_TEMP); 2158 return rv; 2159} --- 6 unchanged lines hidden (view full) --- 2166fdioctl(dev, cmd, addr, flag, p) 2167 dev_t dev; 2168 u_long cmd; 2169 caddr_t addr; 2170 int flag; 2171 struct proc *p; 2172{ 2173 fdu_t fdu = FDUNIT(minor(dev)); | 2211 rv = bp->b_error; 2212 /* 2213 * allow the process to be swapped 2214 */ 2215 PRELE(p); 2216 free(bp, M_TEMP); 2217 return rv; 2218} --- 6 unchanged lines hidden (view full) --- 2225fdioctl(dev, cmd, addr, flag, p) 2226 dev_t dev; 2227 u_long cmd; 2228 caddr_t addr; 2229 int flag; 2230 struct proc *p; 2231{ 2232 fdu_t fdu = FDUNIT(minor(dev)); |
2174 fd_p fd = &fd_data[fdu]; | 2233 fd_p fd = devclass_get_softc(fd_devclass, fdu); |
2175 size_t fdblk; 2176 2177 struct fd_type *fdt; 2178 struct disklabel *dl; 2179 char buffer[DEV_BSIZE]; 2180 int error = 0; 2181 2182 fdblk = 128 << fd->ft->secsize; 2183 | 2234 size_t fdblk; 2235 2236 struct fd_type *fdt; 2237 struct disklabel *dl; 2238 char buffer[DEV_BSIZE]; 2239 int error = 0; 2240 2241 fdblk = 128 << fd->ft->secsize; 2242 |
2184 switch (cmd) 2185 { | 2243 switch (cmd) { |
2186 case DIOCGDINFO: 2187 bzero(buffer, sizeof (buffer)); 2188 dl = (struct disklabel *)buffer; 2189 dl->d_secsize = fdblk; | 2244 case DIOCGDINFO: 2245 bzero(buffer, sizeof (buffer)); 2246 dl = (struct disklabel *)buffer; 2247 dl->d_secsize = fdblk; |
2190 fdt = fd_data[FDUNIT(minor(dev))].ft; | 2248 fdt = fd->ft; |
2191 dl->d_secpercyl = fdt->size / fdt->tracks; 2192 dl->d_type = DTYPE_FLOPPY; 2193 2194 if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl) 2195 == NULL) 2196 error = 0; 2197 else 2198 error = EINVAL; --- 7 unchanged lines hidden (view full) --- 2206 break; 2207 2208 case DIOCWLABEL: 2209 if ((flag & FWRITE) == 0) 2210 error = EBADF; 2211 break; 2212 2213 case DIOCWDINFO: | 2249 dl->d_secpercyl = fdt->size / fdt->tracks; 2250 dl->d_type = DTYPE_FLOPPY; 2251 2252 if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl) 2253 == NULL) 2254 error = 0; 2255 else 2256 error = EINVAL; --- 7 unchanged lines hidden (view full) --- 2264 break; 2265 2266 case DIOCWLABEL: 2267 if ((flag & FWRITE) == 0) 2268 error = EBADF; 2269 break; 2270 2271 case DIOCWDINFO: |
2214 if ((flag & FWRITE) == 0) 2215 { | 2272 if ((flag & FWRITE) == 0) { |
2216 error = EBADF; 2217 break; 2218 } 2219 2220 dl = (struct disklabel *)addr; 2221 2222 if ((error = setdisklabel((struct disklabel *)buffer, dl, 2223 (u_long)0)) != 0) 2224 break; 2225 2226 error = writedisklabel(dev, fdstrategy, 2227 (struct disklabel *)buffer); 2228 break; 2229 case FD_FORM: | 2273 error = EBADF; 2274 break; 2275 } 2276 2277 dl = (struct disklabel *)addr; 2278 2279 if ((error = setdisklabel((struct disklabel *)buffer, dl, 2280 (u_long)0)) != 0) 2281 break; 2282 2283 error = writedisklabel(dev, fdstrategy, 2284 (struct disklabel *)buffer); 2285 break; 2286 case FD_FORM: |
2230 if((flag & FWRITE) == 0) | 2287 if ((flag & FWRITE) == 0) |
2231 error = EBADF; /* must be opened for writing */ | 2288 error = EBADF; /* must be opened for writing */ |
2232 else if(((struct fd_formb *)addr)->format_version != | 2289 else if (((struct fd_formb *)addr)->format_version != |
2233 FD_FORMAT_VERSION) 2234 error = EINVAL; /* wrong version of formatting prog */ 2235 else 2236 error = fdformat(dev, (struct fd_formb *)addr, p); 2237 break; 2238 2239 case FD_GTYPE: /* get drive type */ 2240 *(struct fd_type *)addr = *fd->ft; 2241 break; 2242 2243 case FD_STYPE: /* set drive type */ 2244 /* this is considered harmful; only allow for superuser */ | 2290 FD_FORMAT_VERSION) 2291 error = EINVAL; /* wrong version of formatting prog */ 2292 else 2293 error = fdformat(dev, (struct fd_formb *)addr, p); 2294 break; 2295 2296 case FD_GTYPE: /* get drive type */ 2297 *(struct fd_type *)addr = *fd->ft; 2298 break; 2299 2300 case FD_STYPE: /* set drive type */ 2301 /* this is considered harmful; only allow for superuser */ |
2245 if(suser(p->p_ucred, &p->p_acflag) != 0) | 2302 if (suser(p->p_ucred, &p->p_acflag) != 0) |
2246 return EPERM; 2247 *fd->ft = *(struct fd_type *)addr; 2248 break; 2249 2250 case FD_GOPTS: /* get drive options */ 2251 *(int *)addr = fd->options; 2252 break; 2253 2254 case FD_SOPTS: /* set drive options */ 2255 fd->options = *(int *)addr; 2256 break; 2257 2258 default: 2259 error = ENOTTY; 2260 break; 2261 } 2262 return (error); 2263} 2264 | 2303 return EPERM; 2304 *fd->ft = *(struct fd_type *)addr; 2305 break; 2306 2307 case FD_GOPTS: /* get drive options */ 2308 *(int *)addr = fd->options; 2309 break; 2310 2311 case FD_SOPTS: /* set drive options */ 2312 fd->options = *(int *)addr; 2313 break; 2314 2315 default: 2316 error = ENOTTY; 2317 break; 2318 } 2319 return (error); 2320} 2321 |
2322static device_method_t fdc_methods[] = { 2323 /* Device interface */ 2324 DEVMETHOD(device_probe, fdc_probe), 2325 DEVMETHOD(device_attach, fdc_attach), 2326 DEVMETHOD(device_detach, bus_generic_detach), 2327 DEVMETHOD(device_shutdown, bus_generic_shutdown), 2328 DEVMETHOD(device_suspend, bus_generic_suspend), 2329 DEVMETHOD(device_resume, bus_generic_resume), |
|
2265 | 2330 |
2266static fd_devsw_installed = 0; | 2331 /* Bus interface */ 2332 DEVMETHOD(bus_print_child, fdc_print_child), 2333 /* Our children never use any other bus interface methods. */ |
2267 | 2334 |
2268static void fd_drvinit(void *notused ) 2269{ | 2335 { 0, 0 } 2336}; |
2270 | 2337 |
2271 if( ! fd_devsw_installed ) { 2272 cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw); 2273 fd_devsw_installed = 1; 2274 } 2275} | 2338static driver_t fdc_driver = { 2339 "fdc", 2340 fdc_methods, 2341 DRIVER_TYPE_BIO, 2342 sizeof(struct fdc_data) 2343}; |
2276 | 2344 |
2277SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL) | 2345DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); |
2278 | 2346 |
2347static device_method_t fd_methods[] = { 2348 /* Device interface */ 2349 DEVMETHOD(device_probe, fd_probe), 2350 DEVMETHOD(device_attach, fd_attach), 2351 DEVMETHOD(device_detach, bus_generic_detach), 2352 DEVMETHOD(device_shutdown, bus_generic_shutdown), 2353 DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */ 2354 DEVMETHOD(device_resume, bus_generic_resume), /* XXX */ |
|
2279 | 2355 |
2280#endif | 2356 { 0, 0 } 2357}; |
2281 | 2358 |
2359static driver_t fd_driver = { 2360 "fd", 2361 fd_methods, 2362 DRIVER_TYPE_BIO, 2363 sizeof(struct fd_data) 2364}; 2365 2366static struct cdevsw fd_cdevsw = { 2367 Fdopen, fdclose, fdread, fdwrite, 2368 fdioctl, nostop, nullreset, nodevtotty, 2369 seltrue, nommap, fdstrategy, "fd", 2370 NULL, -1, nodump, nopsize, 2371 D_DISK, 0, -1 2372}; 2373 2374BDEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, BDEV_MAJOR, CDEV_MAJOR, 2375 fd_cdevsw, 0, 0); 2376 2377#endif /* NFDC > 0 */ 2378 |
|
2282/* 2283 * Hello emacs, these are the 2284 * Local Variables: 2285 * c-indent-level: 8 2286 * c-continued-statement-offset: 8 2287 * c-continued-brace-offset: 0 2288 * c-brace-offset: -8 2289 * c-brace-imaginary-offset: 0 2290 * c-argdecl-indent: 8 2291 * c-label-offset: -8 2292 * c++-hanging-braces: 1 2293 * c++-access-specifier-offset: -8 2294 * c++-empty-arglist-indent: 8 2295 * c++-friend-offset: 0 2296 * End: 2297 */ | 2379/* 2380 * Hello emacs, these are the 2381 * Local Variables: 2382 * c-indent-level: 8 2383 * c-continued-statement-offset: 8 2384 * c-continued-brace-offset: 0 2385 * c-brace-offset: -8 2386 * c-brace-imaginary-offset: 0 2387 * c-argdecl-indent: 8 2388 * c-label-offset: -8 2389 * c++-hanging-braces: 1 2390 * c++-access-specifier-offset: -8 2391 * c++-empty-arglist-indent: 8 2392 * c++-friend-offset: 0 2393 * End: 2394 */ |