1258945Sroberto/*-
2258945Sroberto * [Ported for FreeBSD]
3258945Sroberto *  Copyright (c) 2000
4258945Sroberto *      Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe.
5280849Scy *      All rights reserved.
6280849Scy * [NetBSD for NEC PC-98 series]
7280849Scy *  Copyright (c) 1996, 1997, 1998
8280849Scy *	NetBSD/pc98 porting staff. All rights reserved.
9258945Sroberto *  Copyright (c) 1996, 1997, 1998
10258945Sroberto *	Naofumi HONDA. All rights reserved.
11290000Sglebius *  Copyright (c) 1996, 1997, 1998
12258945Sroberto *	Kouichi Matsuda. All rights reserved.
13258945Sroberto *
14258945Sroberto *  Redistribution and use in source and binary forms, with or without
15258945Sroberto *  modification, are permitted provided that the following conditions
16258945Sroberto *  are met:
17258945Sroberto *  1. Redistributions of source code must retain the above copyright
18258945Sroberto *     notice, this list of conditions and the following disclaimer.
19258945Sroberto *  2. Redistributions in binary form must reproduce the above copyright
20258945Sroberto *     notice, this list of conditions and the following disclaimer in the
21258945Sroberto *     documentation and/or other materials provided with the distribution.
22258945Sroberto *  3. The name of the author may not be used to endorse or promote products
23280849Scy *     derived from this software without specific prior written permission.
24258945Sroberto *
25280849Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26280849Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27280849Scy * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28258945Sroberto * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29258945Sroberto * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30258945Sroberto * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31258945Sroberto * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32258945Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33258945Sroberto * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34290000Sglebius * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35290000Sglebius * POSSIBILITY OF SUCH DAMAGE.
36258945Sroberto *
37258945Sroberto */
38258945Sroberto
39258945Sroberto#include <sys/cdefs.h>
40258945Sroberto__FBSDID("$FreeBSD$");
41280849Scy
42258945Sroberto#include <sys/param.h>
43258945Sroberto#include <sys/systm.h>
44258945Sroberto#include <sys/kernel.h>
45280849Scy#include <sys/socket.h>
46258945Sroberto
47258945Sroberto#include <sys/module.h>
48280849Scy#include <sys/bus.h>
49258945Sroberto
50280849Scy#include <machine/bus.h>
51280849Scy#include <machine/resource.h>
52280849Scy#include <sys/rman.h>
53258945Sroberto
54258945Sroberto#include <cam/scsi/scsi_low.h>
55280849Scy
56280849Scy#include <dev/stg/tmc18c30reg.h>
57280849Scy#include <dev/stg/tmc18c30var.h>
58258945Sroberto#include <dev/stg/tmc18c30.h>
59258945Sroberto
60280849Scy#define	STG_HOSTID	7
61258945Sroberto
62258945Srobertodevclass_t stg_devclass;
63258945Sroberto
64258945Srobertoint
65258945Srobertostg_alloc_resource(device_t dev)
66258945Sroberto{
67290000Sglebius	struct stg_softc *	sc = device_get_softc(dev);
68290000Sglebius	u_long			maddr, msize;
69258945Sroberto	int			error;
70258945Sroberto
71258945Sroberto	sc->port_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
72258945Sroberto					      &sc->port_rid, RF_ACTIVE);
73258945Sroberto	if (sc->port_res == NULL) {
74280849Scy		stg_release_resource(dev);
75258945Sroberto		return(ENOMEM);
76258945Sroberto	}
77280849Scy
78280849Scy	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
79280849Scy					     RF_ACTIVE);
80280849Scy	if (sc->irq_res == NULL) {
81258945Sroberto		stg_release_resource(dev);
82258945Sroberto		return(ENOMEM);
83258945Sroberto	}
84258945Sroberto	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
85258945Sroberto	if (error) {
86258945Sroberto		return(0);      /* XXX */
87258945Sroberto	}
88258945Sroberto
89258945Sroberto	/* no need to allocate memory if not configured */
90258945Sroberto	if (maddr == 0 || msize == 0) {
91258945Sroberto		return(0);
92258945Sroberto	}
93280849Scy
94280849Scy	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
95258945Sroberto					     RF_ACTIVE);
96258945Sroberto	if (sc->mem_res == NULL) {
97258945Sroberto		stg_release_resource(dev);
98258945Sroberto		return(ENOMEM);
99258945Sroberto	}
100258945Sroberto
101258945Sroberto	return(0);
102258945Sroberto}
103258945Sroberto
104258945Srobertovoid
105258945Srobertostg_release_resource(device_t dev)
106258945Sroberto{
107258945Sroberto	struct stg_softc	*sc = device_get_softc(dev);
108258945Sroberto
109258945Sroberto	if (sc->stg_intrhand)
110280849Scy		bus_teardown_intr(dev, sc->irq_res, sc->stg_intrhand);
111280849Scy	if (sc->port_res)
112280849Scy		bus_release_resource(dev, SYS_RES_IOPORT,
113280849Scy				     sc->port_rid, sc->port_res);
114280849Scy	if (sc->irq_res)
115258945Sroberto		bus_release_resource(dev, SYS_RES_IRQ,
116258945Sroberto				     sc->irq_rid, sc->irq_res);
117258945Sroberto	if (sc->mem_res)
118258945Sroberto		bus_release_resource(dev, SYS_RES_MEMORY,
119258945Sroberto				     sc->mem_rid, sc->mem_res);
120280849Scy	return;
121280849Scy}
122280849Scy
123258945Srobertoint
124258945Srobertostg_probe(device_t dev)
125280849Scy{
126258945Sroberto	int rv;
127258945Sroberto	struct stg_softc *sc = device_get_softc(dev);
128258945Sroberto
129280849Scy	rv = stgprobesubr(rman_get_bustag(sc->port_res),
130258945Sroberto			  rman_get_bushandle(sc->port_res),
131258945Sroberto			  device_get_flags(dev));
132280849Scy
133280849Scy	return rv;
134280849Scy}
135258945Sroberto
136280849Scyint
137280849Scystg_attach(device_t dev)
138258945Sroberto{
139258945Sroberto	struct stg_softc *sc;
140258945Sroberto	struct scsi_low_softc *slp;
141258945Sroberto	u_int32_t flags = device_get_flags(dev);
142258945Sroberto	intrmask_t s;
143258945Sroberto	char	dvname[16];
144
145	sc = device_get_softc(dev);
146
147	strcpy(dvname,"stg");
148
149	slp = &sc->sc_sclow;
150	slp->sl_dev = dev;
151	sc->sc_iot = rman_get_bustag(sc->port_res);
152	sc->sc_ioh = rman_get_bushandle(sc->port_res);
153
154	slp->sl_hostid = STG_HOSTID;
155	slp->sl_cfgflags = flags;
156
157	s = splcam();
158	stgattachsubr(sc);
159	splx(s);
160
161	return(STGIOSZ);
162}
163
164int
165stg_detach (device_t dev)
166{
167	struct stg_softc *sc = device_get_softc(dev);
168	intrmask_t s;
169
170	s = splcam();
171	scsi_low_deactivate((struct scsi_low_softc *)sc);
172	scsi_low_dettach(&sc->sc_sclow);
173	splx(s);
174	stg_release_resource(dev);
175	return (0);
176}
177
178void
179stg_intr (void *arg)
180{
181	stgintr(arg);
182	return;
183}
184