Deleted Added
full compact
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 */