fdc.c (132210) | fdc.c (132286) |
---|---|
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 | 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 $ | 53 * $FreeBSD: head/sys/pc98/cbus/fdc.c 132286 2004-07-17 10:07:19Z 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); | 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; | 357static int fd_probe(device_t); 358static int fd_attach(device_t); 359static int fd_detach(device_t); 360static void set_motor(struct fdc_data *, int, int); 361# define TURNON 1 362# define TURNOFF 0 363static timeout_t fd_turnoff; 364static timeout_t fd_motor_on; --- 390 unchanged lines hidden (view full) --- 755#endif /* PC98 */ 756 757void 758fdc_release_resources(struct fdc_data *fdc) 759{ 760 device_t dev; 761 762 dev = fdc->fdc_dev; |
763 if (fdc->fdc_intr) { 764 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 765 fdc->fdc_intr); 766 fdc->fdc_intr = NULL; 767 } |
|
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); | 768 if (fdc->res_irq != 0) { 769 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 770 fdc->res_irq); 771 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 772 fdc->res_irq); |
773 fdc->res_irq = NULL; |
|
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); | 774 } 775#ifndef PC98 776 if (fdc->res_ctl != 0) { 777 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 778 fdc->res_ctl); 779 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 780 fdc->res_ctl); |
781 fdc->res_ctl = NULL; |
|
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); | 782 } 783#endif 784#ifdef PC98 785 if (fdc->res_fdsio != 0) { 786 bus_deactivate_resource(dev, SYS_RES_IOPORT, 3, 787 fdc->res_fdsio); 788 bus_release_resource(dev, SYS_RES_IOPORT, 3, fdc->res_fdsio); |
789 fdc->res_fdsio = NULL; |
|
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); | 790 } 791 if (fdc->res_fdemsio != 0) { 792 bus_deactivate_resource(dev, SYS_RES_IOPORT, 4, 793 fdc->res_fdemsio); 794 bus_release_resource(dev, SYS_RES_IOPORT, 4, fdc->res_fdemsio); |
795 fdc->res_fdemsio = NULL; |
|
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); | 796 } 797#endif 798 if (fdc->res_ioport != 0) { 799 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 800 fdc->res_ioport); 801 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 802 fdc->res_ioport); |
803 fdc->res_ioport = NULL; |
|
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); | 804 } 805 if (fdc->res_drq != 0) { 806 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 807 fdc->res_drq); 808 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 809 fdc->res_drq); |
810 fdc->res_drq = NULL; |
|
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 | 811 } 812} 813 814/* 815 * Configuration/initialization stuff, per controller. 816 */ 817 818int --- 69 unchanged lines hidden (view full) --- 888#ifdef PC98 889 /* reset controller, turn motor off */ 890 fdc_reset(fdc); 891#else 892 /* reset controller, turn motor off */ 893 fdout_wr(fdc, 0); 894#endif 895 |
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 */ | 896 fdc_release_resources(fdc); 897 return (0); 898} 899 900/* 901 * Add a child device to the fdc controller. It will then be probed etc. 902 */ |
901static void | 903device_t |
902fdc_add_child(device_t dev, const char *name, int unit) 903{ | 904fdc_add_child(device_t dev, const char *name, int unit) 905{ |
904 int fdu, flags; | 906 int 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) | 907 struct fdc_ivars *ivar; 908 device_t child; 909 910 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO); 911 if (ivar == NULL) |
910 return; | 912 return (NULL); |
911 child = device_add_child(dev, name, unit); 912 if (child == NULL) { 913 free(ivar, M_DEVBUF); | 913 child = device_add_child(dev, name, unit); 914 if (child == NULL) { 915 free(ivar, M_DEVBUF); |
914 return; | 916 return (NULL); |
915 } 916 device_set_ivars(child, ivar); | 917 } 918 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); | 919 ivar->fdunit = unit; 920 ivar->fdtype = 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); | 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 return (child); |
|
925} 926 927int 928fdc_attach(device_t dev) 929{ 930 struct fdc_data *fdc; | 926} 927 928int 929fdc_attach(device_t dev) 930{ 931 struct fdc_data *fdc; |
931 const char *name, *dname; 932 int i, dunit, error; | 932 int 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); | 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; | 944 fdc->flags |= 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 | 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 return (0); 958} 959 960int 961fdc_hints_probe(device_t dev) 962{ 963 const char *name, *dname; 964 int i, error, dunit; 965 |
|
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; | 966 /* 967 * Probe and attach any children. We should probably detect 968 * devices from the BIOS unless overridden. 969 */ 970 name = device_get_nameunit(dev); 971 i = 0; |
963 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) | 972 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) { 973 resource_int_value(dname, dunit, "drive", &dunit); |
964 fdc_add_child(dev, dname, dunit); | 974 fdc_add_child(dev, dname, dunit); |
975 } |
|
965 966 if ((error = bus_generic_attach(dev)) != 0) 967 return (error); | 976 977 if ((error = bus_generic_attach(dev)) != 0) 978 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 | 979 return (0); 980} 981 982int 983fdc_print_child(device_t me, device_t child) 984{ 985 int retval = 0, flags; 986 --- 27 unchanged lines hidden (view full) --- 1014 fdc = device_get_softc(device_get_parent(dev)); 1015 flags = device_get_flags(dev); 1016 1017 fd->dev = dev; 1018 fd->fdc = fdc; 1019 fd->fdsu = fdsu; 1020 fd->fdu = device_get_unit(dev); 1021 |
1012 type = FD_DTYPE(flags); 1013 | |
1014 /* Auto-probe if fdinfo is present, but always allow override. */ | 1022 /* Auto-probe if fdinfo is present, but always allow override. */ |
1023 type = FD_DTYPE(flags); |
|
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 | 1024 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) { 1025 fd->type = type; 1026 goto done; 1027 } else { 1028 /* make sure fdautoselect() will be called */ 1029 fd->flags = FD_UA; 1030 fd->type = type; 1031 } --- 77 unchanged lines hidden (view full) --- 1109 1110 if ((flags & FD_NO_PROBE) == 0 && 1111 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */ 1112 return (ENXIO); 1113#endif /* PC98 */ 1114 1115done: 1116#ifndef PC98 |
1108 /* This doesn't work before the first reset. Or set_motor?? */ | 1117 /* This doesn't work before the first reset. */ |
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 --- | 1118 if ((fdc->flags & FDC_HAS_FIFO) == 0 && 1119 fdc->fdct == FDC_ENHANCED && 1120 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 && 1121 enable_fifo(fdc) == 0) { 1122 device_printf(device_get_parent(dev), 1123 "FIFO enabled, %d bytes threshold\n", fifo_threshold); 1124 } 1125#endif /* PC98 */ --- 1678 unchanged lines hidden --- |