ahc_eisa.c revision 161928
19213Swollman/*-
250479Speter * FreeBSD, EISA product support functions
31553Srgrimes *
4156813Sru *
5156813Sru * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs.
6223209Sed * All rights reserved.
738658Sgpalmer *
8266272Ssbruno * Redistribution and use in source and binary forms, with or without
9252862Sdteske * modification, are permitted provided that the following conditions
10292348Sken * are met:
1138658Sgpalmer * 1. Redistributions of source code must retain the above copyright
1238658Sgpalmer *    notice immediately at the beginning of the file, without modification,
1338658Sgpalmer *    this list of conditions, and the following disclaimer.
1438658Sgpalmer * 2. The name of the author may not be used to endorse or promote products
1538658Sgpalmer *    derived from this software without specific prior written permission.
16177633Sdfr *
17181335Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1838658Sgpalmer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19229997Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20255570Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2182547Smike * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22121468Ssimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23295131Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2475753Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2576195Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26113287Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27185032Simp * SUCH DAMAGE.
28102858Sphk *
2959247Srwatson * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#13 $
30177027Sphk */
31277434Strasz
32108441Ssimokawa#include <sys/cdefs.h>
33105756Srwatson__FBSDID("$FreeBSD: head/sys/dev/aic7xxx/ahc_eisa.c 161928 2006-09-03 00:27:42Z jmg $");
34105756Srwatson
35112444Sphk#include <dev/aic7xxx/aic7xxx_osm.h>
36187712Sraj
3755210Sshin#include <dev/eisa/eisaconf.h>
3841043Sdima
3983322Speterstatic int
4081878Speteraic7770_probe(device_t dev)
41186344Ssam{
4245412Smsmith	struct	 aic7770_identity *entry;
4352403Sbillf	struct	 resource *regs;
44196200Sscottl	uint32_t iobase;
4553127Sdfr	bus_space_handle_t bsh;
4659141Smsmith	bus_space_tag_t	tag;
47124587Sru	u_int	 irq;
48294364Sian	u_int	 intdef;
49196212Sscottl	u_int	 hcntrl;
5038658Sgpalmer	int	 shared;
51262650Sbrooks	int	 rid;
5238658Sgpalmer	int	 error;
53192811Srmacklem
5499549Sgordon	entry = aic7770_find_device(eisa_get_id(dev));
55192811Srmacklem	if (entry == NULL)
56192811Srmacklem		return (ENXIO);
57192811Srmacklem	device_set_desc(dev, entry->name);
58244562Sbrooks
59126917Scperciva	iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + AHC_EISA_SLOT_OFFSET;
60245606Seadler
6138658Sgpalmer	eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE);
6238658Sgpalmer
63142578Snjl	rid = 0;
6438658Sgpalmer	regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
6538658Sgpalmer	if (regs == NULL) {
6638658Sgpalmer		device_printf(dev, "Unable to map I/O space?!\n");
6738658Sgpalmer		return ENOMEM;
6838658Sgpalmer	}
6938658Sgpalmer
7038658Sgpalmer	tag = rman_get_bustag(regs);
7174462Salfred	bsh = rman_get_bushandle(regs);
7238658Sgpalmer	error = 0;
7338658Sgpalmer
7453494Sdillon	/* Pause the card preseving the IRQ type */
7541043Sdima	hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS;
76200743Sdougb	bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE);
77206156Sume	while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0)
78289290Sbapt		;
79178895Sjulian
80105756Srwatson	/* Make sure we have a valid interrupt vector */
81105756Srwatson	intdef = bus_space_read_1(tag, bsh, INTDEF);
82129333Sjoerg	shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL;
83148215Smarks	irq = intdef & VECTOR;
8438658Sgpalmer	switch (irq) {
8538658Sgpalmer	case 9:
86252862Sdteske	case 10:
87141381Smaxim	case 11:
8838658Sgpalmer	case 12:
8938658Sgpalmer	case 14:
9038658Sgpalmer	case 15:
9138658Sgpalmer		break;
92282974Strasz	default:
93101209Srwatson		printf("aic7770 at slot %d: illegal irq setting %d\n",
94294787Sdes		       eisa_get_slot(dev), intdef);
9538658Sgpalmer		error = ENXIO;
96195200Smbr	}
9738658Sgpalmer
98116874Ssmkelly	if (error == 0)
99212525Simp		eisa_add_intr(dev, irq, shared);
1001553Srgrimes
101183242Ssam	bus_release_resource(dev, SYS_RES_IOPORT, rid, regs);
102183242Ssam	return (error);
103183242Ssam}
104212525Simp
105212525Simpstatic int
106124587Sruaic7770_attach(device_t dev)
107124587Sru{
108183242Ssam	struct	 aic7770_identity *entry;
109212525Simp	struct	 ahc_softc *ahc;
110183242Ssam	char	*name;
111183242Ssam	int	 error;
112156813Sru
113212525Simp	entry = aic7770_find_device(eisa_get_id(dev));
114212525Simp	if (entry == NULL)
115243752Srwatson		return (ENXIO);
116243752Srwatson
117243752Srwatson	/*
118212525Simp	 * Allocate a softc for this card and
119212525Simp	 * set it up for attachment by our
120155815Srwatson	 * common detect routine.
121155815Srwatson	 */
122183242Ssam	name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT);
123212525Simp	if (name == NULL)
124183242Ssam		return (ENOMEM);
125183242Ssam	strcpy(name, device_get_nameunit(dev));
126278558Sngie	ahc = ahc_alloc(dev, name);
127278558Sngie	if (ahc == NULL)
128278558Sngie		return (ENOMEM);
129278558Sngie
130156813Sru	ahc_set_unit(ahc, device_get_unit(dev));
131212525Simp
132131768Semax	/* Allocate a dmatag for our SCB DMA maps */
133131768Semax	/* XXX Should be a child of the PCI bus dma tag */
134279505Sngie	error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev),
135279505Sngie				   /*alignment*/1, /*boundary*/0,
136279505Sngie				   /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
137279505Sngie				   /*highaddr*/BUS_SPACE_MAXADDR,
138278713Sngie				   /*filter*/NULL, /*filterarg*/NULL,
139278713Sngie				   /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
140278713Sngie				   /*nsegments*/AHC_NSEG,
141278713Sngie				   /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
142183242Ssam				   /*flags*/0,
143212525Simp				   &ahc->parent_dmat);
144124587Sru
145124587Sru	if (error != 0) {
146183242Ssam		printf("ahc_eisa_attach: Could not allocate DMA tag "
147212525Simp		       "- error %d\n", error);
148171173Smlaier		ahc_free(ahc);
149171173Smlaier		return (ENOMEM);
150183242Ssam	}
151212525Simp	ahc->dev_softc = dev;
152212525Simp	error = aic7770_config(ahc, entry, /*unused ioport arg*/0);
153212525Simp	if (error != 0) {
154212525Simp		ahc_free(ahc);
155183242Ssam		return (error);
156183242Ssam	}
157262650Sbrooks
158262650Sbrooks	ahc_attach(ahc);
159262650Sbrooks	return (0);
160262650Sbrooks}
161183242Ssam
162212525Simp
163183242Ssamstatic device_method_t ahc_eisa_device_methods[] = {
164183242Ssam	/* Device interface */
165214885Suqs	DEVMETHOD(device_probe,		aic7770_probe),
166212525Simp	DEVMETHOD(device_attach,	aic7770_attach),
167184588Sdfr	DEVMETHOD(device_detach,	ahc_detach),
168184588Sdfr	{ 0, 0 }
169213462Sgonzo};
170213462Sgonzo
171213462Sgonzostatic driver_t ahc_eisa_driver = {
172213462Sgonzo	"ahc",
173156813Sru	ahc_eisa_device_methods,
174212525Simp	sizeof(struct ahc_softc)
175212525Simp};
176212525Simp
177212525SimpDRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0);
178212525SimpMODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1);
179212525SimpMODULE_VERSION(ahc_eisa, 1);
180212525Simp