File:  [DragonFly] / src / sys / dev / disk / ncv / ncr53c500_pccard.c
Revision 1.4: download - view: text, annotated - select for diffs
Wed Aug 27 10:35:17 2003 UTC (11 years ago) by rob
Branches: MAIN
CVS tags: HEAD
remove __P() from this directory

    1: /*	$FreeBSD: src/sys/dev/ncv/ncr53c500_pccard.c,v 1.2.2.5 2001/12/17 13:30:18 non Exp $	*/
    2: /*	$DragonFly: src/sys/dev/disk/ncv/ncr53c500_pccard.c,v 1.4 2003/08/27 10:35:17 rob Exp $	*/
    3: /*	$NecBSD: ncr53c500_pisa.c,v 1.28 1998/11/26 01:59:11 honda Exp $	*/
    4: /*	$NetBSD$	*/
    5: 
    6: /*
    7:  * [Ported for FreeBSD]
    8:  *  Copyright (c) 2000
    9:  *      Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe.
   10:  *      All rights reserved.
   11:  * [NetBSD for NEC PC-98 series]
   12:  *  Copyright (c) 1995, 1996, 1997, 1998
   13:  *	NetBSD/pc98 porting staff. All rights reserved.
   14:  *  Copyright (c) 1995, 1996, 1997, 1998
   15:  *	Naofumi HONDA. All rights reserved.
   16:  * 
   17:  *  Redistribution and use in source and binary forms, with or without
   18:  *  modification, are permitted provided that the following conditions
   19:  *  are met:
   20:  *  1. Redistributions of source code must retain the above copyright
   21:  *     notice, this list of conditions and the following disclaimer.
   22:  *  2. Redistributions in binary form must reproduce the above copyright
   23:  *     notice, this list of conditions and the following disclaimer in the
   24:  *     documentation and/or other materials provided with the distribution.
   25:  *  3. The name of the author may not be used to endorse or promote products
   26:  *     derived from this software without specific prior written permission.
   27:  * 
   28:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   29:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   31:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   32:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   33:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   34:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   35:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   36:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   37:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38:  * POSSIBILITY OF SUCH DAMAGE.
   39:  */
   40: 
   41: #include <sys/param.h>
   42: #include <sys/systm.h>
   43: #include <sys/disklabel.h>
   44: #if defined(__FreeBSD__) && __FreeBSD_version >= 500001
   45: #include <sys/bio.h>
   46: #endif
   47: #include <sys/buf.h>
   48: #include <sys/queue.h>
   49: #include <sys/malloc.h>
   50: #include <sys/errno.h>
   51: 
   52: #include <vm/vm.h>
   53: 
   54: #include <machine/bus.h>
   55: #include <machine/bus_pio.h>
   56: #include <machine/dvcfg.h>
   57: 
   58: #include <sys/device_port.h>
   59: 
   60: #include <bus/cam/scsi/scsi_low.h>
   61: #include <bus/cam/scsi/scsi_low_pisa.h>
   62: 
   63: #include "ncr53c500reg.h"
   64: #include "ncr53c500hw.h"
   65: #include "ncr53c500var.h"
   66: 
   67: #define KME_KXLC004_01 0x100
   68: #define OFFSET_KME_KXLC004_01 0x10
   69: 
   70: #include	<sys/kernel.h>
   71: #include	<sys/module.h>
   72: #if !defined(__FreeBSD__) || __FreeBSD_version < 500014
   73: #include	<sys/select.h>
   74: #endif
   75: #include	<bus/pccard/cardinfo.h>
   76: #include	<bus/pccard/slot.h>
   77: 
   78: static int ncvprobe(DEVPORT_PDEVICE devi);
   79: static int ncvattach(DEVPORT_PDEVICE devi);
   80: 
   81: static void	ncv_card_unload (DEVPORT_PDEVICE);
   82: 
   83: /*
   84:  * Additional code for FreeBSD new-bus PCCard frontend
   85:  */
   86: 
   87: static void
   88: ncv_pccard_intr(void * arg)
   89: {
   90: 	ncvintr(arg);
   91: }
   92: 
   93: static void
   94: ncv_release_resource(DEVPORT_PDEVICE dev)
   95: {
   96: 	struct ncv_softc	*sc = device_get_softc(dev);
   97: 
   98: 	if (sc->ncv_intrhand) {
   99: 		bus_teardown_intr(dev, sc->irq_res, sc->ncv_intrhand);
  100: 	}
  101: 
  102: 	if (sc->port_res) {
  103: 		bus_release_resource(dev, SYS_RES_IOPORT,
  104: 				     sc->port_rid, sc->port_res);
  105: 	}
  106: 
  107: 	if (sc->port_res_dmy) {
  108: 		bus_release_resource(dev, SYS_RES_IOPORT,
  109: 				     sc->port_rid_dmy, sc->port_res_dmy);
  110: 	}
  111: 
  112: 	if (sc->irq_res) {
  113: 		bus_release_resource(dev, SYS_RES_IRQ,
  114: 				     sc->irq_rid, sc->irq_res);
  115: 	}
  116: 
  117: 	if (sc->mem_res) {
  118: 		bus_release_resource(dev, SYS_RES_MEMORY,
  119: 				     sc->mem_rid, sc->mem_res);
  120: 	}
  121: }
  122: 
  123: static int
  124: ncv_alloc_resource(DEVPORT_PDEVICE dev)
  125: {
  126: 	struct ncv_softc	*sc = device_get_softc(dev);
  127: 	u_int32_t		flags = DEVPORT_PDEVFLAGS(dev);
  128: 	u_long			ioaddr, iosize, maddr, msize;
  129: 	int			error;
  130: 	bus_addr_t		offset = 0;
  131: 
  132: 	if(flags & KME_KXLC004_01)
  133: 		offset = OFFSET_KME_KXLC004_01;
  134: 
  135: 	error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize);
  136: 	if (error || (iosize < (offset + NCVIOSZ))) {
  137: 		return(ENOMEM);
  138: 	}
  139: 
  140: 	sc->port_rid = 0;
  141: 	sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
  142: 					  ioaddr+offset, ioaddr+iosize-offset,
  143: 					  iosize-offset, RF_ACTIVE);
  144: 	if (sc->port_res == NULL) {
  145: 		ncv_release_resource(dev);
  146: 		return(ENOMEM);
  147: 	}
  148: 
  149: 	if (offset != 0) {
  150: 		sc->port_rid_dmy = 0;
  151: 		sc->port_res_dmy = bus_alloc_resource(dev, SYS_RES_IOPORT, 
  152: 						&sc->port_rid_dmy,
  153: 						ioaddr, ioaddr+offset, offset, 
  154: 						RF_ACTIVE);
  155: 		if (sc->port_res_dmy == NULL) {
  156: 			printf("Warning: cannot allocate IOPORT partially.\n");
  157: 		}
  158: 	} else {
  159: 		sc->port_rid_dmy = 0;
  160: 		sc->port_res_dmy = NULL;
  161: 	}
  162: 
  163: 	sc->irq_rid = 0;
  164: 	sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
  165: 					 0, ~0, 1, RF_ACTIVE);
  166: 	if (sc->irq_res == NULL) {
  167: 		ncv_release_resource(dev);
  168: 		return(ENOMEM);
  169: 	}
  170: 
  171: 	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
  172: 	if (error) {
  173: 		return(0);	/* XXX */
  174: 	}
  175: 
  176: 	/* no need to allocate memory if not configured */
  177: 	if (maddr == 0 || msize == 0) {
  178: 		return(0);
  179: 	}
  180: 
  181: 	sc->mem_rid = 0;
  182: 	sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
  183: 					 0, ~0, 1, RF_ACTIVE);
  184: 	if (sc->mem_res == NULL) {
  185: 		ncv_release_resource(dev);
  186: 		return(ENOMEM);
  187: 	}
  188: 
  189: 	return(0);
  190: }
  191: 
  192: static int
  193: ncv_pccard_probe(DEVPORT_PDEVICE dev)
  194: {
  195: 	struct ncv_softc	*sc = device_get_softc(dev);
  196: 	int			error;
  197: 
  198: 	bzero(sc, sizeof(struct ncv_softc));
  199: 
  200: 	error = ncv_alloc_resource(dev);
  201: 	if (error) {
  202: 		return(error);
  203: 	}
  204: 
  205: 	if (ncvprobe(dev) == 0) {
  206: 		ncv_release_resource(dev);
  207: 		return(ENXIO);
  208: 	}
  209: 
  210: 	ncv_release_resource(dev);
  211: 
  212: 	return(0);
  213: }
  214: 
  215: static int
  216: ncv_pccard_attach(DEVPORT_PDEVICE dev)
  217: {
  218: 	struct ncv_softc	*sc = device_get_softc(dev);
  219: 	int			error;
  220: 
  221: 	error = ncv_alloc_resource(dev);
  222: 	if (error) {
  223: 		return(error);
  224: 	}
  225: 
  226: 	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM,
  227: 			       ncv_pccard_intr, (void *)sc, &sc->ncv_intrhand);
  228: 	if (error) {
  229: 		ncv_release_resource(dev);
  230: 		return(error);
  231: 	}
  232: 
  233: 	if (ncvattach(dev) == 0) {
  234: 		ncv_release_resource(dev);
  235: 		return(ENXIO);
  236: 	}
  237: 
  238: 	return(0);
  239: }
  240: 
  241: static	void
  242: ncv_pccard_detach(DEVPORT_PDEVICE dev)
  243: {
  244: 	ncv_card_unload(dev);
  245: 	ncv_release_resource(dev);
  246: }
  247: 
  248: static device_method_t ncv_pccard_methods[] = {
  249: 	/* Device interface */
  250: 	DEVMETHOD(device_probe,		ncv_pccard_probe),
  251: 	DEVMETHOD(device_attach,	ncv_pccard_attach),
  252: 	DEVMETHOD(device_detach,	ncv_pccard_detach),
  253: 
  254: 	{ 0, 0 }
  255: };
  256: 
  257: static driver_t ncv_pccard_driver = {
  258: 	"ncv",
  259: 	ncv_pccard_methods,
  260: 	sizeof(struct ncv_softc),
  261: };
  262: 
  263: static devclass_t ncv_devclass;
  264: 
  265: MODULE_DEPEND(ncv, scsi_low, 1, 1, 1);
  266: DRIVER_MODULE(ncv, pccard, ncv_pccard_driver, ncv_devclass, 0, 0);
  267: 
  268: static void
  269: ncv_card_unload(DEVPORT_PDEVICE devi)
  270: {
  271: 	struct ncv_softc *sc = DEVPORT_PDEVGET_SOFTC(devi);
  272: 	intrmask_t s;
  273: 
  274: 	printf("%s: unload\n", sc->sc_sclow.sl_xname);
  275: 	s = splcam();
  276: 	scsi_low_deactivate((struct scsi_low_softc *)sc);
  277:         scsi_low_dettach(&sc->sc_sclow);
  278: 	splx(s);
  279: }
  280: 
  281: static int
  282: ncvprobe(DEVPORT_PDEVICE devi)
  283: {
  284: 	int rv;
  285: 	struct ncv_softc *sc = device_get_softc(devi);
  286: 	u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  287: 
  288: 	rv = ncvprobesubr(rman_get_bustag(sc->port_res),
  289: 			  rman_get_bushandle(sc->port_res),
  290: 			  flags, NCV_HOSTID);
  291: 
  292: 	return rv;
  293: }
  294: 
  295: static int
  296: ncvattach(DEVPORT_PDEVICE devi)
  297: {
  298: 	struct ncv_softc *sc;
  299: 	struct scsi_low_softc *slp;
  300: 	u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  301: 	intrmask_t s;
  302: 	char dvname[16]; /* SCSI_LOW_DVNAME_LEN */
  303: 
  304: 	strcpy(dvname, "ncv");
  305: 
  306: 	sc = DEVPORT_PDEVALLOC_SOFTC(devi);
  307: 	if (sc == NULL) {
  308: 		return(0);
  309: 	}
  310: 
  311: 	slp = &sc->sc_sclow;
  312: 	slp->sl_dev = devi;
  313: 	sc->sc_iot = rman_get_bustag(sc->port_res);
  314: 	sc->sc_ioh = rman_get_bushandle(sc->port_res);
  315: 
  316: 	slp->sl_hostid = NCV_HOSTID;
  317: 	slp->sl_cfgflags = flags;
  318: 
  319: 	s = splcam();
  320: 	ncvattachsubr(sc);
  321: 	splx(s);
  322: 
  323: 	return(NCVIOSZ);
  324: }