File:  [DragonFly] / src / sys / dev / disk / ncv / ncr53c500_pccard.c
Revision 1.5: download - view: text, annotated - select for diffs
Thu Feb 12 00:00:14 2004 UTC (10 years, 10 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
sys/dev __FreeBSD__ -> __DragonFly__ cleanups.

Submitted-by: Aaron Malone <aaron@munge.net>

    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.5 2004/02/12 00:00:14 dillon 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: #include <sys/buf.h>
   45: #include <sys/queue.h>
   46: #include <sys/malloc.h>
   47: #include <sys/errno.h>
   48: 
   49: #include <vm/vm.h>
   50: 
   51: #include <machine/bus.h>
   52: #include <machine/bus_pio.h>
   53: #include <machine/dvcfg.h>
   54: 
   55: #include <sys/device_port.h>
   56: 
   57: #include <bus/cam/scsi/scsi_low.h>
   58: #include <bus/cam/scsi/scsi_low_pisa.h>
   59: 
   60: #include "ncr53c500reg.h"
   61: #include "ncr53c500hw.h"
   62: #include "ncr53c500var.h"
   63: 
   64: #define KME_KXLC004_01 0x100
   65: #define OFFSET_KME_KXLC004_01 0x10
   66: 
   67: #include	<sys/kernel.h>
   68: #include	<sys/module.h>
   69: #include	<bus/pccard/cardinfo.h>
   70: #include	<bus/pccard/slot.h>
   71: 
   72: static int ncvprobe(DEVPORT_PDEVICE devi);
   73: static int ncvattach(DEVPORT_PDEVICE devi);
   74: 
   75: static void	ncv_card_unload (DEVPORT_PDEVICE);
   76: 
   77: /*
   78:  * Additional code for FreeBSD new-bus PCCard frontend
   79:  */
   80: 
   81: static void
   82: ncv_pccard_intr(void * arg)
   83: {
   84: 	ncvintr(arg);
   85: }
   86: 
   87: static void
   88: ncv_release_resource(DEVPORT_PDEVICE dev)
   89: {
   90: 	struct ncv_softc	*sc = device_get_softc(dev);
   91: 
   92: 	if (sc->ncv_intrhand) {
   93: 		bus_teardown_intr(dev, sc->irq_res, sc->ncv_intrhand);
   94: 	}
   95: 
   96: 	if (sc->port_res) {
   97: 		bus_release_resource(dev, SYS_RES_IOPORT,
   98: 				     sc->port_rid, sc->port_res);
   99: 	}
  100: 
  101: 	if (sc->port_res_dmy) {
  102: 		bus_release_resource(dev, SYS_RES_IOPORT,
  103: 				     sc->port_rid_dmy, sc->port_res_dmy);
  104: 	}
  105: 
  106: 	if (sc->irq_res) {
  107: 		bus_release_resource(dev, SYS_RES_IRQ,
  108: 				     sc->irq_rid, sc->irq_res);
  109: 	}
  110: 
  111: 	if (sc->mem_res) {
  112: 		bus_release_resource(dev, SYS_RES_MEMORY,
  113: 				     sc->mem_rid, sc->mem_res);
  114: 	}
  115: }
  116: 
  117: static int
  118: ncv_alloc_resource(DEVPORT_PDEVICE dev)
  119: {
  120: 	struct ncv_softc	*sc = device_get_softc(dev);
  121: 	u_int32_t		flags = DEVPORT_PDEVFLAGS(dev);
  122: 	u_long			ioaddr, iosize, maddr, msize;
  123: 	int			error;
  124: 	bus_addr_t		offset = 0;
  125: 
  126: 	if(flags & KME_KXLC004_01)
  127: 		offset = OFFSET_KME_KXLC004_01;
  128: 
  129: 	error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize);
  130: 	if (error || (iosize < (offset + NCVIOSZ))) {
  131: 		return(ENOMEM);
  132: 	}
  133: 
  134: 	sc->port_rid = 0;
  135: 	sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
  136: 					  ioaddr+offset, ioaddr+iosize-offset,
  137: 					  iosize-offset, RF_ACTIVE);
  138: 	if (sc->port_res == NULL) {
  139: 		ncv_release_resource(dev);
  140: 		return(ENOMEM);
  141: 	}
  142: 
  143: 	if (offset != 0) {
  144: 		sc->port_rid_dmy = 0;
  145: 		sc->port_res_dmy = bus_alloc_resource(dev, SYS_RES_IOPORT, 
  146: 						&sc->port_rid_dmy,
  147: 						ioaddr, ioaddr+offset, offset, 
  148: 						RF_ACTIVE);
  149: 		if (sc->port_res_dmy == NULL) {
  150: 			printf("Warning: cannot allocate IOPORT partially.\n");
  151: 		}
  152: 	} else {
  153: 		sc->port_rid_dmy = 0;
  154: 		sc->port_res_dmy = NULL;
  155: 	}
  156: 
  157: 	sc->irq_rid = 0;
  158: 	sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
  159: 					 0, ~0, 1, RF_ACTIVE);
  160: 	if (sc->irq_res == NULL) {
  161: 		ncv_release_resource(dev);
  162: 		return(ENOMEM);
  163: 	}
  164: 
  165: 	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
  166: 	if (error) {
  167: 		return(0);	/* XXX */
  168: 	}
  169: 
  170: 	/* no need to allocate memory if not configured */
  171: 	if (maddr == 0 || msize == 0) {
  172: 		return(0);
  173: 	}
  174: 
  175: 	sc->mem_rid = 0;
  176: 	sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
  177: 					 0, ~0, 1, RF_ACTIVE);
  178: 	if (sc->mem_res == NULL) {
  179: 		ncv_release_resource(dev);
  180: 		return(ENOMEM);
  181: 	}
  182: 
  183: 	return(0);
  184: }
  185: 
  186: static int
  187: ncv_pccard_probe(DEVPORT_PDEVICE dev)
  188: {
  189: 	struct ncv_softc	*sc = device_get_softc(dev);
  190: 	int			error;
  191: 
  192: 	bzero(sc, sizeof(struct ncv_softc));
  193: 
  194: 	error = ncv_alloc_resource(dev);
  195: 	if (error) {
  196: 		return(error);
  197: 	}
  198: 
  199: 	if (ncvprobe(dev) == 0) {
  200: 		ncv_release_resource(dev);
  201: 		return(ENXIO);
  202: 	}
  203: 
  204: 	ncv_release_resource(dev);
  205: 
  206: 	return(0);
  207: }
  208: 
  209: static int
  210: ncv_pccard_attach(DEVPORT_PDEVICE dev)
  211: {
  212: 	struct ncv_softc	*sc = device_get_softc(dev);
  213: 	int			error;
  214: 
  215: 	error = ncv_alloc_resource(dev);
  216: 	if (error) {
  217: 		return(error);
  218: 	}
  219: 
  220: 	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM,
  221: 			       ncv_pccard_intr, (void *)sc, &sc->ncv_intrhand);
  222: 	if (error) {
  223: 		ncv_release_resource(dev);
  224: 		return(error);
  225: 	}
  226: 
  227: 	if (ncvattach(dev) == 0) {
  228: 		ncv_release_resource(dev);
  229: 		return(ENXIO);
  230: 	}
  231: 
  232: 	return(0);
  233: }
  234: 
  235: static	void
  236: ncv_pccard_detach(DEVPORT_PDEVICE dev)
  237: {
  238: 	ncv_card_unload(dev);
  239: 	ncv_release_resource(dev);
  240: }
  241: 
  242: static device_method_t ncv_pccard_methods[] = {
  243: 	/* Device interface */
  244: 	DEVMETHOD(device_probe,		ncv_pccard_probe),
  245: 	DEVMETHOD(device_attach,	ncv_pccard_attach),
  246: 	DEVMETHOD(device_detach,	ncv_pccard_detach),
  247: 
  248: 	{ 0, 0 }
  249: };
  250: 
  251: static driver_t ncv_pccard_driver = {
  252: 	"ncv",
  253: 	ncv_pccard_methods,
  254: 	sizeof(struct ncv_softc),
  255: };
  256: 
  257: static devclass_t ncv_devclass;
  258: 
  259: MODULE_DEPEND(ncv, scsi_low, 1, 1, 1);
  260: DRIVER_MODULE(ncv, pccard, ncv_pccard_driver, ncv_devclass, 0, 0);
  261: 
  262: static void
  263: ncv_card_unload(DEVPORT_PDEVICE devi)
  264: {
  265: 	struct ncv_softc *sc = DEVPORT_PDEVGET_SOFTC(devi);
  266: 	intrmask_t s;
  267: 
  268: 	printf("%s: unload\n", sc->sc_sclow.sl_xname);
  269: 	s = splcam();
  270: 	scsi_low_deactivate((struct scsi_low_softc *)sc);
  271:         scsi_low_dettach(&sc->sc_sclow);
  272: 	splx(s);
  273: }
  274: 
  275: static int
  276: ncvprobe(DEVPORT_PDEVICE devi)
  277: {
  278: 	int rv;
  279: 	struct ncv_softc *sc = device_get_softc(devi);
  280: 	u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  281: 
  282: 	rv = ncvprobesubr(rman_get_bustag(sc->port_res),
  283: 			  rman_get_bushandle(sc->port_res),
  284: 			  flags, NCV_HOSTID);
  285: 
  286: 	return rv;
  287: }
  288: 
  289: static int
  290: ncvattach(DEVPORT_PDEVICE devi)
  291: {
  292: 	struct ncv_softc *sc;
  293: 	struct scsi_low_softc *slp;
  294: 	u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  295: 	intrmask_t s;
  296: 	char dvname[16]; /* SCSI_LOW_DVNAME_LEN */
  297: 
  298: 	strcpy(dvname, "ncv");
  299: 
  300: 	sc = DEVPORT_PDEVALLOC_SOFTC(devi);
  301: 	if (sc == NULL) {
  302: 		return(0);
  303: 	}
  304: 
  305: 	slp = &sc->sc_sclow;
  306: 	slp->sl_dev = devi;
  307: 	sc->sc_iot = rman_get_bustag(sc->port_res);
  308: 	sc->sc_ioh = rman_get_bushandle(sc->port_res);
  309: 
  310: 	slp->sl_hostid = NCV_HOSTID;
  311: 	slp->sl_cfgflags = flags;
  312: 
  313: 	s = splcam();
  314: 	ncvattachsubr(sc);
  315: 	splx(s);
  316: 
  317: 	return(NCVIOSZ);
  318: }