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)
--- 36 unchanged lines hidden (view full) ---
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
53 * $FreeBSD: head/sys/pc98/cbus/fdc.c 132210 2004-07-15 15:00:02Z nyan $
54 */
55
56#include "opt_fdc.h"
57
58#include <sys/param.h>
59#include <sys/bio.h>
60#include <sys/bus.h>
61#include <sys/devicestat.h>
--- 287 unchanged lines hidden (view full) ---
349static u_int8_t fdsts_rd(fdc_p);
350static void fddata_wr(fdc_p, u_int8_t);
351static u_int8_t fddata_rd(fdc_p);
352static int fdc_err(struct fdc_data *, const char *);
353static int enable_fifo(fdc_p fdc);
354static int fd_sense_drive_status(fdc_p, int *);
355static int fd_sense_int(fdc_p, int *, int *);
356static int fd_read_status(fdc_p);
357static void fdc_add_child(device_t, const char *, int);
358static int fd_probe(device_t);
359static int fd_attach(device_t);
360static int fd_detach(device_t);
361static void set_motor(struct fdc_data *, int, int);
362# define TURNON 1
363# define TURNOFF 0
364static timeout_t fd_turnoff;
365static timeout_t fd_motor_on;
--- 390 unchanged lines hidden (view full) ---
756#endif /* PC98 */
757
758void
759fdc_release_resources(struct fdc_data *fdc)
760{
761 device_t dev;
762
763 dev = fdc->fdc_dev;
764 if (fdc->res_irq != 0) {
765 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
766 fdc->res_irq);
767 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
768 fdc->res_irq);
769 }
770#ifndef PC98
771 if (fdc->res_ctl != 0) {
772 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
773 fdc->res_ctl);
774 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
775 fdc->res_ctl);
776 }
777#endif
778#ifdef PC98
779 if (fdc->res_fdsio != 0) {
780 bus_deactivate_resource(dev, SYS_RES_IOPORT, 3,
781 fdc->res_fdsio);
782 bus_release_resource(dev, SYS_RES_IOPORT, 3, fdc->res_fdsio);
783 }
784 if (fdc->res_fdemsio != 0) {
785 bus_deactivate_resource(dev, SYS_RES_IOPORT, 4,
786 fdc->res_fdemsio);
787 bus_release_resource(dev, SYS_RES_IOPORT, 4, fdc->res_fdemsio);
788 }
789#endif
790 if (fdc->res_ioport != 0) {
791 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
792 fdc->res_ioport);
793 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
794 fdc->res_ioport);
795 }
796 if (fdc->res_drq != 0) {
797 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
798 fdc->res_drq);
799 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
800 fdc->res_drq);
801 }
802}
803
804/*
805 * Configuration/initialization stuff, per controller.
806 */
807
808int
--- 69 unchanged lines hidden (view full) ---
878#ifdef PC98
879 /* reset controller, turn motor off */
880 fdc_reset(fdc);
881#else
882 /* reset controller, turn motor off */
883 fdout_wr(fdc, 0);
884#endif
885
886 if ((fdc->flags & FDC_ATTACHED) == 0) {
887 device_printf(dev, "already unloaded\n");
888 return (0);
889 }
890 fdc->flags &= ~FDC_ATTACHED;
891
892 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
893 fdc->fdc_intr);
894 fdc_release_resources(fdc);
895 return (0);
896}
897
898/*
899 * Add a child device to the fdc controller. It will then be probed etc.
900 */
901static void
902fdc_add_child(device_t dev, const char *name, int unit)
903{
904 int fdu, flags;
905 struct fdc_ivars *ivar;
906 device_t child;
907
908 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
909 if (ivar == NULL)
910 return;
911 child = device_add_child(dev, name, unit);
912 if (child == NULL) {
913 free(ivar, M_DEVBUF);
914 return;
915 }
916 device_set_ivars(child, ivar);
917 if (resource_int_value(name, unit, "drive", &fdu) != 0)
918 fdu = 0;
919 fdc_set_fdunit(child, fdu);
920 fdc_set_fdtype(child, FDT_NONE);
921 if (resource_int_value(name, unit, "flags", &flags) == 0)
922 device_set_flags(child, flags);
923 if (resource_disabled(name, unit))
924 device_disable(child);
925}
926
927int
928fdc_attach(device_t dev)
929{
930 struct fdc_data *fdc;
931 const char *name, *dname;
932 int i, dunit, error;
933
934 fdc = device_get_softc(dev);
935 fdc->fdc_dev = dev;
936 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
937 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
938 &fdc->fdc_intr);
939 if (error) {
940 device_printf(dev, "cannot setup interrupt\n");
941 return error;
942 }
943 fdc->fdcu = device_get_unit(dev);
944 fdc->flags |= FDC_ATTACHED | FDC_NEEDS_RESET;
945
946 fdc->state = DEVIDLE;
947
948#ifdef PC98
949 /* reset controller, turn motor off, clear fdout mirror reg */
950 fdc_reset(fdc);
951#else
952 /* reset controller, turn motor off, clear fdout mirror reg */
953 fdout_wr(fdc, fdc->fdout = 0);
954#endif
955 bioq_init(&fdc->head);
956
957 /*
958 * Probe and attach any children. We should probably detect
959 * devices from the BIOS unless overridden.
960 */
961 name = device_get_nameunit(dev);
962 i = 0;
963 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0)
964 fdc_add_child(dev, dname, dunit);
965
966 if ((error = bus_generic_attach(dev)) != 0)
967 return (error);
968
969 return (0);
970}
971
972int
973fdc_print_child(device_t me, device_t child)
974{
975 int retval = 0, flags;
976
--- 27 unchanged lines hidden (view full) ---
1004 fdc = device_get_softc(device_get_parent(dev));
1005 flags = device_get_flags(dev);
1006
1007 fd->dev = dev;
1008 fd->fdc = fdc;
1009 fd->fdsu = fdsu;
1010 fd->fdu = device_get_unit(dev);
1011
1012 type = FD_DTYPE(flags);
1013
1014 /* Auto-probe if fdinfo is present, but always allow override. */
1015 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
1016 fd->type = type;
1017 goto done;
1018 } else {
1019 /* make sure fdautoselect() will be called */
1020 fd->flags = FD_UA;
1021 fd->type = type;
1022 }
--- 77 unchanged lines hidden (view full) ---
1100
1101 if ((flags & FD_NO_PROBE) == 0 &&
1102 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
1103 return (ENXIO);
1104#endif /* PC98 */
1105
1106done:
1107#ifndef PC98
1108 /* This doesn't work before the first reset. Or set_motor?? */
1109 if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
1110 fdc->fdct == FDC_ENHANCED &&
1111 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
1112 enable_fifo(fdc) == 0) {
1113 device_printf(device_get_parent(dev),
1114 "FIFO enabled, %d bytes threshold\n", fifo_threshold);
1115 }
1116#endif /* PC98 */
--- 1678 unchanged lines hidden ---
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)
--- 36 unchanged lines hidden (view full) ---
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
53 * $FreeBSD: head/sys/pc98/cbus/fdc.c 132210 2004-07-15 15:00:02Z nyan $
54 */
55
56#include "opt_fdc.h"
57
58#include <sys/param.h>
59#include <sys/bio.h>
60#include <sys/bus.h>
61#include <sys/devicestat.h>
--- 287 unchanged lines hidden (view full) ---
349static u_int8_t fdsts_rd(fdc_p);
350static void fddata_wr(fdc_p, u_int8_t);
351static u_int8_t fddata_rd(fdc_p);
352static int fdc_err(struct fdc_data *, const char *);
353static int enable_fifo(fdc_p fdc);
354static int fd_sense_drive_status(fdc_p, int *);
355static int fd_sense_int(fdc_p, int *, int *);
356static int fd_read_status(fdc_p);
357static void fdc_add_child(device_t, const char *, int);
358static int fd_probe(device_t);
359static int fd_attach(device_t);
360static int fd_detach(device_t);
361static void set_motor(struct fdc_data *, int, int);
362# define TURNON 1
363# define TURNOFF 0
364static timeout_t fd_turnoff;
365static timeout_t fd_motor_on;
--- 390 unchanged lines hidden (view full) ---
756#endif /* PC98 */
757
758void
759fdc_release_resources(struct fdc_data *fdc)
760{
761 device_t dev;
762
763 dev = fdc->fdc_dev;
764 if (fdc->res_irq != 0) {
765 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
766 fdc->res_irq);
767 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
768 fdc->res_irq);
769 }
770#ifndef PC98
771 if (fdc->res_ctl != 0) {
772 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
773 fdc->res_ctl);
774 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
775 fdc->res_ctl);
776 }
777#endif
778#ifdef PC98
779 if (fdc->res_fdsio != 0) {
780 bus_deactivate_resource(dev, SYS_RES_IOPORT, 3,
781 fdc->res_fdsio);
782 bus_release_resource(dev, SYS_RES_IOPORT, 3, fdc->res_fdsio);
783 }
784 if (fdc->res_fdemsio != 0) {
785 bus_deactivate_resource(dev, SYS_RES_IOPORT, 4,
786 fdc->res_fdemsio);
787 bus_release_resource(dev, SYS_RES_IOPORT, 4, fdc->res_fdemsio);
788 }
789#endif
790 if (fdc->res_ioport != 0) {
791 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
792 fdc->res_ioport);
793 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
794 fdc->res_ioport);
795 }
796 if (fdc->res_drq != 0) {
797 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
798 fdc->res_drq);
799 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
800 fdc->res_drq);
801 }
802}
803
804/*
805 * Configuration/initialization stuff, per controller.
806 */
807
808int
--- 69 unchanged lines hidden (view full) ---
878#ifdef PC98
879 /* reset controller, turn motor off */
880 fdc_reset(fdc);
881#else
882 /* reset controller, turn motor off */
883 fdout_wr(fdc, 0);
884#endif
885
886 if ((fdc->flags & FDC_ATTACHED) == 0) {
887 device_printf(dev, "already unloaded\n");
888 return (0);
889 }
890 fdc->flags &= ~FDC_ATTACHED;
891
892 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
893 fdc->fdc_intr);
894 fdc_release_resources(fdc);
895 return (0);
896}
897
898/*
899 * Add a child device to the fdc controller. It will then be probed etc.
900 */
901static void
902fdc_add_child(device_t dev, const char *name, int unit)
903{
904 int fdu, flags;
905 struct fdc_ivars *ivar;
906 device_t child;
907
908 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
909 if (ivar == NULL)
910 return;
911 child = device_add_child(dev, name, unit);
912 if (child == NULL) {
913 free(ivar, M_DEVBUF);
914 return;
915 }
916 device_set_ivars(child, ivar);
917 if (resource_int_value(name, unit, "drive", &fdu) != 0)
918 fdu = 0;
919 fdc_set_fdunit(child, fdu);
920 fdc_set_fdtype(child, FDT_NONE);
921 if (resource_int_value(name, unit, "flags", &flags) == 0)
922 device_set_flags(child, flags);
923 if (resource_disabled(name, unit))
924 device_disable(child);
925}
926
927int
928fdc_attach(device_t dev)
929{
930 struct fdc_data *fdc;
931 const char *name, *dname;
932 int i, dunit, error;
933
934 fdc = device_get_softc(dev);
935 fdc->fdc_dev = dev;
936 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
937 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
938 &fdc->fdc_intr);
939 if (error) {
940 device_printf(dev, "cannot setup interrupt\n");
941 return error;
942 }
943 fdc->fdcu = device_get_unit(dev);
944 fdc->flags |= FDC_ATTACHED | FDC_NEEDS_RESET;
945
946 fdc->state = DEVIDLE;
947
948#ifdef PC98
949 /* reset controller, turn motor off, clear fdout mirror reg */
950 fdc_reset(fdc);
951#else
952 /* reset controller, turn motor off, clear fdout mirror reg */
953 fdout_wr(fdc, fdc->fdout = 0);
954#endif
955 bioq_init(&fdc->head);
956
957 /*
958 * Probe and attach any children. We should probably detect
959 * devices from the BIOS unless overridden.
960 */
961 name = device_get_nameunit(dev);
962 i = 0;
963 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0)
964 fdc_add_child(dev, dname, dunit);
965
966 if ((error = bus_generic_attach(dev)) != 0)
967 return (error);
968
969 return (0);
970}
971
972int
973fdc_print_child(device_t me, device_t child)
974{
975 int retval = 0, flags;
976
--- 27 unchanged lines hidden (view full) ---
1004 fdc = device_get_softc(device_get_parent(dev));
1005 flags = device_get_flags(dev);
1006
1007 fd->dev = dev;
1008 fd->fdc = fdc;
1009 fd->fdsu = fdsu;
1010 fd->fdu = device_get_unit(dev);
1011
1012 type = FD_DTYPE(flags);
1013
1014 /* Auto-probe if fdinfo is present, but always allow override. */
1015 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
1016 fd->type = type;
1017 goto done;
1018 } else {
1019 /* make sure fdautoselect() will be called */
1020 fd->flags = FD_UA;
1021 fd->type = type;
1022 }
--- 77 unchanged lines hidden (view full) ---
1100
1101 if ((flags & FD_NO_PROBE) == 0 &&
1102 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
1103 return (ENXIO);
1104#endif /* PC98 */
1105
1106done:
1107#ifndef PC98
1108 /* This doesn't work before the first reset. Or set_motor?? */
1109 if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
1110 fdc->fdct == FDC_ENHANCED &&
1111 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
1112 enable_fifo(fdc) == 0) {
1113 device_printf(device_get_parent(dev),
1114 "FIFO enabled, %d bytes threshold\n", fifo_threshold);
1115 }
1116#endif /* PC98 */
--- 1678 unchanged lines hidden ---