1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * [Ported for FreeBSD] 5 * Copyright (c) 2000 6 * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. 7 * All rights reserved. 8 * [NetBSD for NEC PC-98 series] 9 * Copyright (c) 1996, 1997, 1998 10 * NetBSD/pc98 porting staff. All rights reserved. 11 * Copyright (c) 1996, 1997, 1998 12 * Naofumi HONDA. All rights reserved. 13 * Copyright (c) 1996, 1997, 1998 14 * Kouichi Matsuda. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. The name of the author may not be used to endorse or promote products 25 * derived from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 * 39 */ 40 41#include <sys/cdefs.h> 42__FBSDID("$FreeBSD$"); 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/socket.h> 48 49#include <sys/module.h> 50#include <sys/bus.h> 51 52#include <machine/bus.h> 53#include <machine/resource.h> 54#include <sys/rman.h> 55 56#include <cam/scsi/scsi_low.h> 57 58#include <dev/stg/tmc18c30reg.h> 59#include <dev/stg/tmc18c30var.h> 60#include <dev/stg/tmc18c30.h> 61 62#define STG_HOSTID 7 63 64devclass_t stg_devclass; 65 66int 67stg_alloc_resource(device_t dev) 68{ 69 struct stg_softc * sc = device_get_softc(dev); 70 rman_res_t maddr, msize; 71 int error; 72 73 mtx_init(&sc->sc_sclow.sl_lock, "stg", NULL, MTX_DEF); 74 sc->port_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 75 &sc->port_rid, RF_ACTIVE); 76 if (sc->port_res == NULL) { 77 stg_release_resource(dev); 78 return(ENOMEM); 79 } 80 81 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 82 RF_ACTIVE); 83 if (sc->irq_res == NULL) { 84 stg_release_resource(dev); 85 return(ENOMEM); 86 } 87 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); 88 if (error) { 89 return(0); /* XXX */ 90 } 91 92 /* no need to allocate memory if not configured */ 93 if (maddr == 0 || msize == 0) { 94 return(0); 95 } 96 97 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 98 RF_ACTIVE); 99 if (sc->mem_res == NULL) { 100 stg_release_resource(dev); 101 return(ENOMEM); 102 } 103 104 return(0); 105} 106 107void 108stg_release_resource(device_t dev) 109{ 110 struct stg_softc *sc = device_get_softc(dev); 111 112 if (sc->stg_intrhand) 113 bus_teardown_intr(dev, sc->irq_res, sc->stg_intrhand); 114 if (sc->port_res) 115 bus_release_resource(dev, SYS_RES_IOPORT, 116 sc->port_rid, sc->port_res); 117 if (sc->irq_res) 118 bus_release_resource(dev, SYS_RES_IRQ, 119 sc->irq_rid, sc->irq_res); 120 if (sc->mem_res) 121 bus_release_resource(dev, SYS_RES_MEMORY, 122 sc->mem_rid, sc->mem_res); 123 mtx_destroy(&sc->sc_sclow.sl_lock); 124} 125 126int 127stg_probe(device_t dev) 128{ 129 int rv; 130 struct stg_softc *sc = device_get_softc(dev); 131 132 rv = stgprobesubr(sc->port_res, 133 device_get_flags(dev)); 134 135 return rv; 136} 137 138int 139stg_attach(device_t dev) 140{ 141 struct stg_softc *sc; 142 struct scsi_low_softc *slp; 143 u_int32_t flags = device_get_flags(dev); 144 145 sc = device_get_softc(dev); 146 147 slp = &sc->sc_sclow; 148 slp->sl_dev = dev; 149 150 slp->sl_hostid = STG_HOSTID; 151 slp->sl_cfgflags = flags; 152 153 stgattachsubr(sc); 154 155 return(STGIOSZ); 156} 157 158int 159stg_detach(device_t dev) 160{ 161 struct stg_softc *sc = device_get_softc(dev); 162 163 scsi_low_deactivate(&sc->sc_sclow); 164 scsi_low_detach(&sc->sc_sclow); 165 stg_release_resource(dev); 166 return (0); 167} 168 169void 170stg_intr(void *arg) 171{ 172 struct stg_softc *sc; 173 174 sc = arg; 175 SCSI_LOW_LOCK(&sc->sc_sclow); 176 stgintr(sc); 177 SCSI_LOW_UNLOCK(&sc->sc_sclow); 178} 179