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 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); |
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 } |
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; |
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; |
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; |
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; |
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; |
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; |
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 |
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 */ |
903device_t |
904fdc_add_child(device_t dev, const char *name, int unit) 905{ |
906 int flags; |
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) |
912 return (NULL); |
913 child = device_add_child(dev, name, unit); 914 if (child == NULL) { 915 free(ivar, M_DEVBUF); |
916 return (NULL); |
917 } 918 device_set_ivars(child, ivar); |
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); |
925 return (child); |
926} 927 928int 929fdc_attach(device_t dev) 930{ 931 struct fdc_data *fdc; |
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); |
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 |
957 return (0); 958} 959 960int 961fdc_hints_probe(device_t dev) 962{ 963 const char *name, *dname; 964 int i, error, dunit; 965 |
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; |
972 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) { 973 resource_int_value(dname, dunit, "drive", &dunit); |
974 fdc_add_child(dev, dname, dunit); |
975 } |
976 977 if ((error = bus_generic_attach(dev)) != 0) 978 return (error); |
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 |
1022 /* Auto-probe if fdinfo is present, but always allow override. */ |
1023 type = FD_DTYPE(flags); |
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 |
1117 /* This doesn't work before the first reset. */ |
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 --- |