xref: /dflybsd-src/sys/dev/disk/fd/fd_pccard.c (revision dcb4b80df71308df08858318df7f148fde3b3e1b)
18c5c0470SJoerg Sonnenberger /*
28c5c0470SJoerg Sonnenberger  * Copyright (c) 1990 The Regents of the University of California.
38c5c0470SJoerg Sonnenberger  * All rights reserved.
48c5c0470SJoerg Sonnenberger  *
58c5c0470SJoerg Sonnenberger  * This code is derived from software contributed to Berkeley by
68c5c0470SJoerg Sonnenberger  * Don Ahn.
78c5c0470SJoerg Sonnenberger  *
88c5c0470SJoerg Sonnenberger  * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
98c5c0470SJoerg Sonnenberger  * aided by the Linux floppy driver modifications from David Bateman
108c5c0470SJoerg Sonnenberger  * (dbateman@eng.uts.edu.au).
118c5c0470SJoerg Sonnenberger  *
128c5c0470SJoerg Sonnenberger  * Copyright (c) 1993, 1994 by
138c5c0470SJoerg Sonnenberger  *  jc@irbs.UUCP (John Capo)
148c5c0470SJoerg Sonnenberger  *  vak@zebub.msk.su (Serge Vakulenko)
158c5c0470SJoerg Sonnenberger  *  ache@astral.msk.su (Andrew A. Chernov)
168c5c0470SJoerg Sonnenberger  *
178c5c0470SJoerg Sonnenberger  * Copyright (c) 1993, 1994, 1995 by
188c5c0470SJoerg Sonnenberger  *  joerg_wunsch@uriah.sax.de (Joerg Wunsch)
198c5c0470SJoerg Sonnenberger  *  dufault@hda.com (Peter Dufault)
208c5c0470SJoerg Sonnenberger  *
218c5c0470SJoerg Sonnenberger  * Copyright (c) 2001 Joerg Wunsch,
228c5c0470SJoerg Sonnenberger  *  joerg_wunsch@uriah.sax.de (Joerg Wunsch)
238c5c0470SJoerg Sonnenberger  *
248c5c0470SJoerg Sonnenberger  * Redistribution and use in source and binary forms, with or without
258c5c0470SJoerg Sonnenberger  * modification, are permitted provided that the following conditions
268c5c0470SJoerg Sonnenberger  * are met:
278c5c0470SJoerg Sonnenberger  * 1. Redistributions of source code must retain the above copyright
288c5c0470SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer.
298c5c0470SJoerg Sonnenberger  * 2. Redistributions in binary form must reproduce the above copyright
308c5c0470SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer in the
318c5c0470SJoerg Sonnenberger  *    documentation and/or other materials provided with the distribution.
328c5c0470SJoerg Sonnenberger  * 3. All advertising materials mentioning features or use of this software
338c5c0470SJoerg Sonnenberger  *    must display the following acknowledgement:
348c5c0470SJoerg Sonnenberger  *	This product includes software developed by the University of
358c5c0470SJoerg Sonnenberger  *	California, Berkeley and its contributors.
368c5c0470SJoerg Sonnenberger  * 4. Neither the name of the University nor the names of its contributors
378c5c0470SJoerg Sonnenberger  *    may be used to endorse or promote products derived from this software
388c5c0470SJoerg Sonnenberger  *    without specific prior written permission.
398c5c0470SJoerg Sonnenberger  *
408c5c0470SJoerg Sonnenberger  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
418c5c0470SJoerg Sonnenberger  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
428c5c0470SJoerg Sonnenberger  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
438c5c0470SJoerg Sonnenberger  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
448c5c0470SJoerg Sonnenberger  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
458c5c0470SJoerg Sonnenberger  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
468c5c0470SJoerg Sonnenberger  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
478c5c0470SJoerg Sonnenberger  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
488c5c0470SJoerg Sonnenberger  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
498c5c0470SJoerg Sonnenberger  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
508c5c0470SJoerg Sonnenberger  * SUCH DAMAGE.
518c5c0470SJoerg Sonnenberger  *
528c5c0470SJoerg Sonnenberger  */
538c5c0470SJoerg Sonnenberger 
548c5c0470SJoerg Sonnenberger #include <sys/param.h>
558c5c0470SJoerg Sonnenberger #include <sys/systm.h>
568c5c0470SJoerg Sonnenberger #include <sys/buf.h>
578c5c0470SJoerg Sonnenberger #include <sys/bus.h>
588c5c0470SJoerg Sonnenberger #include <sys/kernel.h>
598c5c0470SJoerg Sonnenberger #include <sys/module.h>
608c5c0470SJoerg Sonnenberger 
618c5c0470SJoerg Sonnenberger #include "fdc.h"
628c5c0470SJoerg Sonnenberger #include "fdreg.h"
638c5c0470SJoerg Sonnenberger 
6457f7b5a3SJoerg Sonnenberger #include <bus/pccard/pccardvar.h>
6557f7b5a3SJoerg Sonnenberger 
6657f7b5a3SJoerg Sonnenberger #include "card_if.h"
67*dcb4b80dSSascha Wildner #include "pccarddevs.h"
6857f7b5a3SJoerg Sonnenberger 
6957f7b5a3SJoerg Sonnenberger static const struct pccard_product fdc_products[] = {
7057f7b5a3SJoerg Sonnenberger   	PCMCIA_CARD(YEDATA, EXTERNAL_FDD, 0),
7157f7b5a3SJoerg Sonnenberger   	{ NULL }
7257f7b5a3SJoerg Sonnenberger };
7357f7b5a3SJoerg Sonnenberger 
748c5c0470SJoerg Sonnenberger static void
fdctl_wr_pcmcia(fdc_p fdc,u_int8_t v)758c5c0470SJoerg Sonnenberger fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v)
768c5c0470SJoerg Sonnenberger {
778c5c0470SJoerg Sonnenberger 	bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v);
788c5c0470SJoerg Sonnenberger }
798c5c0470SJoerg Sonnenberger 
fdc_pccard_match(device_t dev)8057f7b5a3SJoerg Sonnenberger static int fdc_pccard_match(device_t dev)
8157f7b5a3SJoerg Sonnenberger {
8257f7b5a3SJoerg Sonnenberger   	const struct pccard_product *pp;
8357f7b5a3SJoerg Sonnenberger 
8457f7b5a3SJoerg Sonnenberger 	if ((pp = pccard_product_lookup(dev, fdc_products,
8557f7b5a3SJoerg Sonnenberger 	    sizeof(fdc_products[0]), NULL)) != NULL) {
8657f7b5a3SJoerg Sonnenberger 		device_set_desc(dev, pp->pp_name);
8757f7b5a3SJoerg Sonnenberger 		return (0);
8857f7b5a3SJoerg Sonnenberger 	}
8957f7b5a3SJoerg Sonnenberger 	return (ENXIO);
9057f7b5a3SJoerg Sonnenberger }
9157f7b5a3SJoerg Sonnenberger 
928c5c0470SJoerg Sonnenberger static int
fdc_pccard_probe(device_t dev)938c5c0470SJoerg Sonnenberger fdc_pccard_probe(device_t dev)
948c5c0470SJoerg Sonnenberger {
958c5c0470SJoerg Sonnenberger 	int	error;
968c5c0470SJoerg Sonnenberger 	struct	fdc_data *fdc;
978c5c0470SJoerg Sonnenberger 
988c5c0470SJoerg Sonnenberger 	fdc = device_get_softc(dev);
998c5c0470SJoerg Sonnenberger 	bzero(fdc, sizeof *fdc);
1008c5c0470SJoerg Sonnenberger 	fdc->fdc_dev = dev;
1018c5c0470SJoerg Sonnenberger 	fdc->fdctl_wr = fdctl_wr_pcmcia;
1028c5c0470SJoerg Sonnenberger 
1038c5c0470SJoerg Sonnenberger 	fdc->flags |= FDC_ISPCMCIA | FDC_NODMA;
1048c5c0470SJoerg Sonnenberger 
1058c5c0470SJoerg Sonnenberger 	/* Attempt to allocate our resources for the duration of the probe */
1068c5c0470SJoerg Sonnenberger 	error = fdc_alloc_resources(fdc);
1078c5c0470SJoerg Sonnenberger 	if (error)
1088c5c0470SJoerg Sonnenberger 		goto out;
1098c5c0470SJoerg Sonnenberger 
1108c5c0470SJoerg Sonnenberger 	/* First - lets reset the floppy controller */
1118c5c0470SJoerg Sonnenberger 	fdout_wr(fdc, 0);
1128c5c0470SJoerg Sonnenberger 	DELAY(100);
1138c5c0470SJoerg Sonnenberger 	fdout_wr(fdc, FDO_FRST);
1148c5c0470SJoerg Sonnenberger 
1158c5c0470SJoerg Sonnenberger 	/* see if it can handle a command */
1168c5c0470SJoerg Sonnenberger 	if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
1178c5c0470SJoerg Sonnenberger 		   NE7_SPEC_2(2, 0), 0)) {
1188c5c0470SJoerg Sonnenberger 		error = ENXIO;
1198c5c0470SJoerg Sonnenberger 		goto out;
1208c5c0470SJoerg Sonnenberger 	}
1218c5c0470SJoerg Sonnenberger 
1228c5c0470SJoerg Sonnenberger 	fdc->fdct = FDC_NE765;
1238c5c0470SJoerg Sonnenberger 
1248c5c0470SJoerg Sonnenberger out:
1258c5c0470SJoerg Sonnenberger 	fdc_release_resources(fdc);
1268c5c0470SJoerg Sonnenberger 	return (error);
1278c5c0470SJoerg Sonnenberger }
1288c5c0470SJoerg Sonnenberger 
1298c5c0470SJoerg Sonnenberger static int
fdc_pccard_detach(device_t dev)1308c5c0470SJoerg Sonnenberger fdc_pccard_detach(device_t dev)
1318c5c0470SJoerg Sonnenberger {
1328c5c0470SJoerg Sonnenberger 	struct	fdc_data *fdc;
1338c5c0470SJoerg Sonnenberger 	int	error;
1348c5c0470SJoerg Sonnenberger 
1358c5c0470SJoerg Sonnenberger 	fdc = device_get_softc(dev);
1368c5c0470SJoerg Sonnenberger 
1378c5c0470SJoerg Sonnenberger 	/* have our children detached first */
1388c5c0470SJoerg Sonnenberger 	if ((error = bus_generic_detach(dev)))
1398c5c0470SJoerg Sonnenberger 		return (error);
1408c5c0470SJoerg Sonnenberger 
1418c5c0470SJoerg Sonnenberger 	if ((fdc->flags & FDC_ATTACHED) == 0) {
1428c5c0470SJoerg Sonnenberger 		device_printf(dev, "already unloaded\n");
1438c5c0470SJoerg Sonnenberger 		return (0);
1448c5c0470SJoerg Sonnenberger 	}
1458c5c0470SJoerg Sonnenberger 	fdc->flags &= ~FDC_ATTACHED;
1468c5c0470SJoerg Sonnenberger 
1478c5c0470SJoerg Sonnenberger 	BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
1488c5c0470SJoerg Sonnenberger 			  fdc->fdc_intr);
1498c5c0470SJoerg Sonnenberger 	fdc_release_resources(fdc);
1508c5c0470SJoerg Sonnenberger 	device_printf(dev, "unload\n");
1518c5c0470SJoerg Sonnenberger 	return (0);
1528c5c0470SJoerg Sonnenberger }
1538c5c0470SJoerg Sonnenberger 
1548c5c0470SJoerg Sonnenberger static device_method_t fdc_pccard_methods[] = {
1558c5c0470SJoerg Sonnenberger 	/* Device interface */
15657f7b5a3SJoerg Sonnenberger 	DEVMETHOD(device_probe,		pccard_compat_probe),
15757f7b5a3SJoerg Sonnenberger 	DEVMETHOD(device_attach,	pccard_compat_attach),
1588c5c0470SJoerg Sonnenberger 	DEVMETHOD(device_detach,	fdc_pccard_detach),
1598c5c0470SJoerg Sonnenberger 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1608c5c0470SJoerg Sonnenberger 	DEVMETHOD(device_suspend,	bus_generic_suspend),
1618c5c0470SJoerg Sonnenberger 	DEVMETHOD(device_resume,	bus_generic_resume),
1628c5c0470SJoerg Sonnenberger 
16357f7b5a3SJoerg Sonnenberger 	/* Card interface */
16457f7b5a3SJoerg Sonnenberger 	DEVMETHOD(card_compat_match,	fdc_pccard_match),
16557f7b5a3SJoerg Sonnenberger 	DEVMETHOD(card_compat_probe,	fdc_pccard_probe),
16657f7b5a3SJoerg Sonnenberger 	DEVMETHOD(card_compat_attach,	fdc_attach),
16757f7b5a3SJoerg Sonnenberger 	/* Device interface */
16857f7b5a3SJoerg Sonnenberger 
1698c5c0470SJoerg Sonnenberger 	/* Bus interface */
1708c5c0470SJoerg Sonnenberger 	DEVMETHOD(bus_print_child,	fdc_print_child),
1718c5c0470SJoerg Sonnenberger 	DEVMETHOD(bus_read_ivar,	fdc_read_ivar),
1728c5c0470SJoerg Sonnenberger 	/* Our children never use any other bus interface methods. */
1738c5c0470SJoerg Sonnenberger 
174d3c9c58eSSascha Wildner 	DEVMETHOD_END
1758c5c0470SJoerg Sonnenberger };
1768c5c0470SJoerg Sonnenberger 
1778c5c0470SJoerg Sonnenberger static driver_t fdc_pccard_driver = {
1788c5c0470SJoerg Sonnenberger 	"fdc",
1798c5c0470SJoerg Sonnenberger 	fdc_pccard_methods,
1808c5c0470SJoerg Sonnenberger 	sizeof(struct fdc_data)
1818c5c0470SJoerg Sonnenberger };
1828c5c0470SJoerg Sonnenberger 
183aa2b9d05SSascha Wildner DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, NULL, NULL);
184