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) 9 * aided by the Linux floppy driver modifications from David Bateman 10 * (dbateman@eng.uts.edu.au). 11 * 12 * Copyright (c) 1993, 1994 by 13 * jc@irbs.UUCP (John Capo) 14 * vak@zebub.msk.su (Serge Vakulenko) 15 * ache@astral.msk.su (Andrew A. Chernov) 16 * 17 * Copyright (c) 1993, 1994, 1995 by 18 * joerg_wunsch@uriah.sax.de (Joerg Wunsch) 19 * dufault@hda.com (Peter Dufault) 20 * 21 * Copyright (c) 2001 Joerg Wunsch, 22 * joerg_wunsch@uriah.sax.de (Joerg Wunsch) 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by the University of 35 * California, Berkeley and its contributors. 36 * 4. Neither the name of the University nor the names of its contributors 37 * may be used to endorse or promote products derived from this software 38 * without specific prior written permission. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 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 */ 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/buf.h> 57 #include <sys/bus.h> 58 #include <sys/kernel.h> 59 #include <sys/module.h> 60 61 #include "fdc.h" 62 #include "fdreg.h" 63 64 #include <bus/pccard/pccardvar.h> 65 66 #include "card_if.h" 67 #include "pccarddevs.h" 68 69 static const struct pccard_product fdc_products[] = { 70 PCMCIA_CARD(YEDATA, EXTERNAL_FDD, 0), 71 { NULL } 72 }; 73 74 static void 75 fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v) 76 { 77 bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v); 78 } 79 80 static int fdc_pccard_match(device_t dev) 81 { 82 const struct pccard_product *pp; 83 84 if ((pp = pccard_product_lookup(dev, fdc_products, 85 sizeof(fdc_products[0]), NULL)) != NULL) { 86 device_set_desc(dev, pp->pp_name); 87 return (0); 88 } 89 return (ENXIO); 90 } 91 92 static int 93 fdc_pccard_probe(device_t dev) 94 { 95 int error; 96 struct fdc_data *fdc; 97 98 fdc = device_get_softc(dev); 99 bzero(fdc, sizeof *fdc); 100 fdc->fdc_dev = dev; 101 fdc->fdctl_wr = fdctl_wr_pcmcia; 102 103 fdc->flags |= FDC_ISPCMCIA | FDC_NODMA; 104 105 /* Attempt to allocate our resources for the duration of the probe */ 106 error = fdc_alloc_resources(fdc); 107 if (error) 108 goto out; 109 110 /* First - lets reset the floppy controller */ 111 fdout_wr(fdc, 0); 112 DELAY(100); 113 fdout_wr(fdc, FDO_FRST); 114 115 /* see if it can handle a command */ 116 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 117 NE7_SPEC_2(2, 0), 0)) { 118 error = ENXIO; 119 goto out; 120 } 121 122 fdc->fdct = FDC_NE765; 123 124 out: 125 fdc_release_resources(fdc); 126 return (error); 127 } 128 129 static int 130 fdc_pccard_detach(device_t dev) 131 { 132 struct fdc_data *fdc; 133 int error; 134 135 fdc = device_get_softc(dev); 136 137 /* have our children detached first */ 138 if ((error = bus_generic_detach(dev))) 139 return (error); 140 141 if ((fdc->flags & FDC_ATTACHED) == 0) { 142 device_printf(dev, "already unloaded\n"); 143 return (0); 144 } 145 fdc->flags &= ~FDC_ATTACHED; 146 147 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 148 fdc->fdc_intr); 149 fdc_release_resources(fdc); 150 device_printf(dev, "unload\n"); 151 return (0); 152 } 153 154 static device_method_t fdc_pccard_methods[] = { 155 /* Device interface */ 156 DEVMETHOD(device_probe, pccard_compat_probe), 157 DEVMETHOD(device_attach, pccard_compat_attach), 158 DEVMETHOD(device_detach, fdc_pccard_detach), 159 DEVMETHOD(device_shutdown, bus_generic_shutdown), 160 DEVMETHOD(device_suspend, bus_generic_suspend), 161 DEVMETHOD(device_resume, bus_generic_resume), 162 163 /* Card interface */ 164 DEVMETHOD(card_compat_match, fdc_pccard_match), 165 DEVMETHOD(card_compat_probe, fdc_pccard_probe), 166 DEVMETHOD(card_compat_attach, fdc_attach), 167 /* Device interface */ 168 169 /* Bus interface */ 170 DEVMETHOD(bus_print_child, fdc_print_child), 171 DEVMETHOD(bus_read_ivar, fdc_read_ivar), 172 /* Our children never use any other bus interface methods. */ 173 174 DEVMETHOD_END 175 }; 176 177 static driver_t fdc_pccard_driver = { 178 "fdc", 179 fdc_pccard_methods, 180 sizeof(struct fdc_data) 181 }; 182 183 DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, NULL, NULL); 184