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 * $DragonFly: src/sys/dev/disk/fd/fd_pccard.c,v 1.3 2006/10/25 20:55:53 dillon Exp $ 53 */ 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/buf.h> 58 #include <sys/bus.h> 59 #include <sys/kernel.h> 60 #include <sys/module.h> 61 62 #include "fdc.h" 63 #include "fdreg.h" 64 65 #include <bus/pccard/pccardvar.h> 66 #include <bus/pccard/pccarddevs.h> 67 68 #include "card_if.h" 69 70 static const struct pccard_product fdc_products[] = { 71 PCMCIA_CARD(YEDATA, EXTERNAL_FDD, 0), 72 { NULL } 73 }; 74 75 static void 76 fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v) 77 { 78 bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v); 79 } 80 81 static int fdc_pccard_match(device_t dev) 82 { 83 const struct pccard_product *pp; 84 85 if ((pp = pccard_product_lookup(dev, fdc_products, 86 sizeof(fdc_products[0]), NULL)) != NULL) { 87 device_set_desc(dev, pp->pp_name); 88 return (0); 89 } 90 return (ENXIO); 91 } 92 93 static int 94 fdc_pccard_probe(device_t dev) 95 { 96 int error; 97 struct fdc_data *fdc; 98 99 fdc = device_get_softc(dev); 100 bzero(fdc, sizeof *fdc); 101 fdc->fdc_dev = dev; 102 fdc->fdctl_wr = fdctl_wr_pcmcia; 103 104 fdc->flags |= FDC_ISPCMCIA | FDC_NODMA; 105 106 /* Attempt to allocate our resources for the duration of the probe */ 107 error = fdc_alloc_resources(fdc); 108 if (error) 109 goto out; 110 111 /* First - lets reset the floppy controller */ 112 fdout_wr(fdc, 0); 113 DELAY(100); 114 fdout_wr(fdc, FDO_FRST); 115 116 /* see if it can handle a command */ 117 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 118 NE7_SPEC_2(2, 0), 0)) { 119 error = ENXIO; 120 goto out; 121 } 122 123 fdc->fdct = FDC_NE765; 124 125 out: 126 fdc_release_resources(fdc); 127 return (error); 128 } 129 130 static int 131 fdc_pccard_detach(device_t dev) 132 { 133 struct fdc_data *fdc; 134 int error; 135 136 fdc = device_get_softc(dev); 137 138 /* have our children detached first */ 139 if ((error = bus_generic_detach(dev))) 140 return (error); 141 142 if ((fdc->flags & FDC_ATTACHED) == 0) { 143 device_printf(dev, "already unloaded\n"); 144 return (0); 145 } 146 fdc->flags &= ~FDC_ATTACHED; 147 148 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 149 fdc->fdc_intr); 150 fdc_release_resources(fdc); 151 device_printf(dev, "unload\n"); 152 return (0); 153 } 154 155 static device_method_t fdc_pccard_methods[] = { 156 /* Device interface */ 157 DEVMETHOD(device_probe, pccard_compat_probe), 158 DEVMETHOD(device_attach, pccard_compat_attach), 159 DEVMETHOD(device_detach, fdc_pccard_detach), 160 DEVMETHOD(device_shutdown, bus_generic_shutdown), 161 DEVMETHOD(device_suspend, bus_generic_suspend), 162 DEVMETHOD(device_resume, bus_generic_resume), 163 164 /* Card interface */ 165 DEVMETHOD(card_compat_match, fdc_pccard_match), 166 DEVMETHOD(card_compat_probe, fdc_pccard_probe), 167 DEVMETHOD(card_compat_attach, fdc_attach), 168 /* Device interface */ 169 170 /* Bus interface */ 171 DEVMETHOD(bus_print_child, fdc_print_child), 172 DEVMETHOD(bus_read_ivar, fdc_read_ivar), 173 /* Our children never use any other bus interface methods. */ 174 175 { 0, 0 } 176 }; 177 178 static driver_t fdc_pccard_driver = { 179 "fdc", 180 fdc_pccard_methods, 181 sizeof(struct fdc_data) 182 }; 183 184 DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0); 185