fdc.c (16629bd98267290324ab100941b280835c643d79) fdc.c (a6e4d8c45383824144e371bb6adc8e877611c4c9)
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)

--- 227 unchanged lines hidden (view full) ---

236#if 0
237static u_int8_t fdin_rd(fdc_p);
238#endif
239static int fdc_err(struct fdc_data *, const char *);
240static int enable_fifo(fdc_p fdc);
241static int fd_sense_drive_status(fdc_p, int *);
242static int fd_sense_int(fdc_p, int *, int *);
243static int fd_read_status(fdc_p);
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)

--- 227 unchanged lines hidden (view full) ---

236#if 0
237static u_int8_t fdin_rd(fdc_p);
238#endif
239static int fdc_err(struct fdc_data *, const char *);
240static int enable_fifo(fdc_p fdc);
241static int fd_sense_drive_status(fdc_p, int *);
242static int fd_sense_int(fdc_p, int *, int *);
243static int fd_read_status(fdc_p);
244static void fdc_add_child(device_t, const char *, int);
245static int fd_probe(device_t);
246static int fd_attach(device_t);
247static int fd_detach(device_t);
248static void set_motor(struct fdc_data *, int, int);
249# define TURNON 1
250# define TURNOFF 0
251static timeout_t fd_turnoff;
252static timeout_t fd_motor_on;

--- 259 unchanged lines hidden (view full) ---

512}
513
514void
515fdc_release_resources(struct fdc_data *fdc)
516{
517 device_t dev;
518
519 dev = fdc->fdc_dev;
244static int fd_probe(device_t);
245static int fd_attach(device_t);
246static int fd_detach(device_t);
247static void set_motor(struct fdc_data *, int, int);
248# define TURNON 1
249# define TURNOFF 0
250static timeout_t fd_turnoff;
251static timeout_t fd_motor_on;

--- 259 unchanged lines hidden (view full) ---

511}
512
513void
514fdc_release_resources(struct fdc_data *fdc)
515{
516 device_t dev;
517
518 dev = fdc->fdc_dev;
519 if (fdc->fdc_intr) {
520 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
521 fdc->fdc_intr);
522 fdc->fdc_intr = NULL;
523 }
520 if (fdc->res_irq != 0) {
521 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
522 fdc->res_irq);
523 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
524 fdc->res_irq);
524 if (fdc->res_irq != 0) {
525 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
526 fdc->res_irq);
527 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
528 fdc->res_irq);
529 fdc->res_irq = NULL;
525 }
526 if (fdc->res_ctl != 0) {
527 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
528 fdc->res_ctl);
529 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
530 fdc->res_ctl);
530 }
531 if (fdc->res_ctl != 0) {
532 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
533 fdc->res_ctl);
534 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
535 fdc->res_ctl);
536 fdc->res_ctl = NULL;
531 }
532 if (fdc->res_ioport != 0) {
533 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
534 fdc->res_ioport);
535 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
536 fdc->res_ioport);
537 }
538 if (fdc->res_ioport != 0) {
539 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
540 fdc->res_ioport);
541 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
542 fdc->res_ioport);
543 fdc->res_ioport = NULL;
537 }
538 if (fdc->res_drq != 0) {
539 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
540 fdc->res_drq);
541 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
542 fdc->res_drq);
544 }
545 if (fdc->res_drq != 0) {
546 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
547 fdc->res_drq);
548 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
549 fdc->res_drq);
550 fdc->res_ioport = NULL;
543 }
544}
545
546/*
547 * Configuration/initialization stuff, per controller.
548 */
549
550int

--- 57 unchanged lines hidden (view full) ---

608
609 /* have our children detached first */
610 if ((error = bus_generic_detach(dev)))
611 return (error);
612
613 /* reset controller, turn motor off */
614 fdout_wr(fdc, 0);
615
551 }
552}
553
554/*
555 * Configuration/initialization stuff, per controller.
556 */
557
558int

--- 57 unchanged lines hidden (view full) ---

616
617 /* have our children detached first */
618 if ((error = bus_generic_detach(dev)))
619 return (error);
620
621 /* reset controller, turn motor off */
622 fdout_wr(fdc, 0);
623
616 if ((fdc->flags & FDC_ATTACHED) == 0) {
617 device_printf(dev, "already unloaded\n");
618 return (0);
619 }
620 fdc->flags &= ~FDC_ATTACHED;
621
622 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
623 fdc->fdc_intr);
624 fdc_release_resources(fdc);
625 return (0);
626}
627
628/*
629 * Add a child device to the fdc controller. It will then be probed etc.
630 */
624 fdc_release_resources(fdc);
625 return (0);
626}
627
628/*
629 * Add a child device to the fdc controller. It will then be probed etc.
630 */
631static void
631device_t
632fdc_add_child(device_t dev, const char *name, int unit)
633{
632fdc_add_child(device_t dev, const char *name, int unit)
633{
634 int fdu, flags;
634 int flags;
635 struct fdc_ivars *ivar;
636 device_t child;
637
638 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
639 if (ivar == NULL)
635 struct fdc_ivars *ivar;
636 device_t child;
637
638 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
639 if (ivar == NULL)
640 return;
640 return (NULL);
641 child = device_add_child(dev, name, unit);
642 if (child == NULL) {
643 free(ivar, M_DEVBUF);
641 child = device_add_child(dev, name, unit);
642 if (child == NULL) {
643 free(ivar, M_DEVBUF);
644 return;
644 return (NULL);
645 }
646 device_set_ivars(child, ivar);
645 }
646 device_set_ivars(child, ivar);
647 if (resource_int_value(name, unit, "drive", &fdu) != 0)
648 fdu = 0;
649 fdc_set_fdunit(child, fdu);
650 fdc_set_fdtype(child, FDT_NONE);
647 ivar->fdunit = unit;
648 ivar->fdtype = FDT_NONE;
651 if (resource_int_value(name, unit, "flags", &flags) == 0)
652 device_set_flags(child, flags);
653 if (resource_disabled(name, unit))
654 device_disable(child);
649 if (resource_int_value(name, unit, "flags", &flags) == 0)
650 device_set_flags(child, flags);
651 if (resource_disabled(name, unit))
652 device_disable(child);
653 return (child);
655}
656
657int
658fdc_attach(device_t dev)
659{
660 struct fdc_data *fdc;
654}
655
656int
657fdc_attach(device_t dev)
658{
659 struct fdc_data *fdc;
661 const char *name, *dname;
662 int i, dunit, error;
660 int error;
663
664 fdc = device_get_softc(dev);
665 fdc->fdc_dev = dev;
666 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
667 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
668 &fdc->fdc_intr);
669 if (error) {
670 device_printf(dev, "cannot setup interrupt\n");
671 return error;
672 }
673 fdc->fdcu = device_get_unit(dev);
661
662 fdc = device_get_softc(dev);
663 fdc->fdc_dev = dev;
664 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
665 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
666 &fdc->fdc_intr);
667 if (error) {
668 device_printf(dev, "cannot setup interrupt\n");
669 return error;
670 }
671 fdc->fdcu = device_get_unit(dev);
674 fdc->flags |= FDC_ATTACHED | FDC_NEEDS_RESET;
672 fdc->flags |= FDC_NEEDS_RESET;
675
676 fdc->state = DEVIDLE;
677
678 /* reset controller, turn motor off, clear fdout mirror reg */
679 fdout_wr(fdc, fdc->fdout = 0);
680 bioq_init(&fdc->head);
681
673
674 fdc->state = DEVIDLE;
675
676 /* reset controller, turn motor off, clear fdout mirror reg */
677 fdout_wr(fdc, fdc->fdout = 0);
678 bioq_init(&fdc->head);
679
680 return (0);
681}
682
683int
684fdc_hints_probe(device_t dev)
685{
686 const char *name, *dname;
687 int i, error, dunit;
688
682 /*
683 * Probe and attach any children. We should probably detect
684 * devices from the BIOS unless overridden.
685 */
686 name = device_get_nameunit(dev);
687 i = 0;
689 /*
690 * Probe and attach any children. We should probably detect
691 * devices from the BIOS unless overridden.
692 */
693 name = device_get_nameunit(dev);
694 i = 0;
688 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0)
695 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) {
696 resource_int_value(dname, dunit, "drive", &dunit);
689 fdc_add_child(dev, dname, dunit);
697 fdc_add_child(dev, dname, dunit);
698 }
690
691 if ((error = bus_generic_attach(dev)) != 0)
692 return (error);
699
700 if ((error = bus_generic_attach(dev)) != 0)
701 return (error);
693
694 return (0);
695}
696
697int
698fdc_print_child(device_t me, device_t child)
699{
700 int retval = 0, flags;
701

--- 25 unchanged lines hidden (view full) ---

727 fdc = device_get_softc(device_get_parent(dev));
728 flags = device_get_flags(dev);
729
730 fd->dev = dev;
731 fd->fdc = fdc;
732 fd->fdsu = fdsu;
733 fd->fdu = device_get_unit(dev);
734
702 return (0);
703}
704
705int
706fdc_print_child(device_t me, device_t child)
707{
708 int retval = 0, flags;
709

--- 25 unchanged lines hidden (view full) ---

735 fdc = device_get_softc(device_get_parent(dev));
736 flags = device_get_flags(dev);
737
738 fd->dev = dev;
739 fd->fdc = fdc;
740 fd->fdsu = fdsu;
741 fd->fdu = device_get_unit(dev);
742
735 type = FD_DTYPE(flags);
736
737 /* Auto-probe if fdinfo is present, but always allow override. */
743 /* Auto-probe if fdinfo is present, but always allow override. */
744 type = FD_DTYPE(flags);
738 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
739 fd->type = type;
740 goto done;
741 } else {
742 /* make sure fdautoselect() will be called */
743 fd->flags = FD_UA;
744 fd->type = type;
745 }

--- 69 unchanged lines hidden (view full) ---

815
816 set_motor(fdc, fdsu, TURNOFF);
817
818 if ((flags & FD_NO_PROBE) == 0 &&
819 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
820 return (ENXIO);
821
822done:
745 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
746 fd->type = type;
747 goto done;
748 } else {
749 /* make sure fdautoselect() will be called */
750 fd->flags = FD_UA;
751 fd->type = type;
752 }

--- 69 unchanged lines hidden (view full) ---

822
823 set_motor(fdc, fdsu, TURNOFF);
824
825 if ((flags & FD_NO_PROBE) == 0 &&
826 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
827 return (ENXIO);
828
829done:
823 /* This doesn't work before the first reset. Or set_motor?? */
830 /* This doesn't work before the first reset. */
824 if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
825 fdc->fdct == FDC_ENHANCED &&
826 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
827 enable_fifo(fdc) == 0) {
828 device_printf(device_get_parent(dev),
829 "FIFO enabled, %d bytes threshold\n", fifo_threshold);
830 }
831

--- 1492 unchanged lines hidden ---
831 if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
832 fdc->fdct == FDC_ENHANCED &&
833 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
834 enable_fifo(fdc) == 0) {
835 device_printf(device_get_parent(dev),
836 "FIFO enabled, %d bytes threshold\n", fifo_threshold);
837 }
838

--- 1492 unchanged lines hidden ---