xref: /freebsd/sys/dev/ida/ida_pci.c (revision db57feb70b2a573613368679106d793efc6faadb)
1db57feb7SJonathan Lemon /*-
2db57feb7SJonathan Lemon  * Copyright (c) 1999 Jonathan Lemon
3db57feb7SJonathan Lemon  * All rights reserved.
4db57feb7SJonathan Lemon  *
5db57feb7SJonathan Lemon  * Redistribution and use in source and binary forms, with or without
6db57feb7SJonathan Lemon  * modification, are permitted provided that the following conditions
7db57feb7SJonathan Lemon  * are met:
8db57feb7SJonathan Lemon  * 1. Redistributions of source code must retain the above copyright
9db57feb7SJonathan Lemon  *    notice, this list of conditions and the following disclaimer.
10db57feb7SJonathan Lemon  * 2. Redistributions in binary form must reproduce the above copyright
11db57feb7SJonathan Lemon  *    notice, this list of conditions and the following disclaimer in the
12db57feb7SJonathan Lemon  *    documentation and/or other materials provided with the distribution.
13db57feb7SJonathan Lemon  *
14db57feb7SJonathan Lemon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15db57feb7SJonathan Lemon  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16db57feb7SJonathan Lemon  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17db57feb7SJonathan Lemon  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18db57feb7SJonathan Lemon  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19db57feb7SJonathan Lemon  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20db57feb7SJonathan Lemon  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21db57feb7SJonathan Lemon  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22db57feb7SJonathan Lemon  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23db57feb7SJonathan Lemon  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24db57feb7SJonathan Lemon  * SUCH DAMAGE.
25db57feb7SJonathan Lemon  *
26db57feb7SJonathan Lemon  *	$Id$
27db57feb7SJonathan Lemon  */
28db57feb7SJonathan Lemon 
29db57feb7SJonathan Lemon #include <pci.h>
30db57feb7SJonathan Lemon #if NPCI > 0
31db57feb7SJonathan Lemon 
32db57feb7SJonathan Lemon #include <sys/param.h>
33db57feb7SJonathan Lemon #include <sys/systm.h>
34db57feb7SJonathan Lemon #include <sys/malloc.h>
35db57feb7SJonathan Lemon #include <sys/kernel.h>
36db57feb7SJonathan Lemon 
37db57feb7SJonathan Lemon #include <sys/buf.h>
38db57feb7SJonathan Lemon #include <sys/bus.h>
39db57feb7SJonathan Lemon #include <sys/device.h>
40db57feb7SJonathan Lemon #include <sys/devicestat.h>
41db57feb7SJonathan Lemon 
42db57feb7SJonathan Lemon #include <machine/bus_memio.h>
43db57feb7SJonathan Lemon #include <machine/bus_pio.h>
44db57feb7SJonathan Lemon #include <machine/bus.h>
45db57feb7SJonathan Lemon #include <machine/resource.h>
46db57feb7SJonathan Lemon #include <sys/rman.h>
47db57feb7SJonathan Lemon 
48db57feb7SJonathan Lemon #include <pci/pcireg.h>
49db57feb7SJonathan Lemon #include <pci/pcivar.h>
50db57feb7SJonathan Lemon 
51db57feb7SJonathan Lemon #include <dev/ida/idavar.h>
52db57feb7SJonathan Lemon 
53db57feb7SJonathan Lemon #define IDA_PCI_MAX_DMA_ADDR	0xFFFFFFFF
54db57feb7SJonathan Lemon #define IDA_PCI_MAX_DMA_COUNT	0xFFFFFFFF
55db57feb7SJonathan Lemon 
56db57feb7SJonathan Lemon #define IDA_PCI_MEMADDR		(PCIR_MAPS + 4)		/* Mem I/O Address */
57db57feb7SJonathan Lemon 
58db57feb7SJonathan Lemon #define IDA_DEVICEID_SMART	0xAE100E11
59db57feb7SJonathan Lemon 
60db57feb7SJonathan Lemon static struct {
61db57feb7SJonathan Lemon         u_long	board;
62db57feb7SJonathan Lemon         char    *desc;
63db57feb7SJonathan Lemon } board_id[] = {
64db57feb7SJonathan Lemon 	{ 0x4030,	"Compaq SMART-2/P array controller" },
65db57feb7SJonathan Lemon 	{ 0x4031,	"Compaq SMART-2SL array controller" },
66db57feb7SJonathan Lemon 	{ 0x4032,	"Compaq Smart Array 3200 controller" },
67db57feb7SJonathan Lemon 	{ 0x4033,	"Compaq Smart Array 3100ES controller" },
68db57feb7SJonathan Lemon 	{ 0x4034,	"Compaq Smart Array 221 controller" },
69db57feb7SJonathan Lemon 
70db57feb7SJonathan Lemon 	{ 0,		"" },
71db57feb7SJonathan Lemon };
72db57feb7SJonathan Lemon 
73db57feb7SJonathan Lemon static int ida_pci_probe(device_t dev);
74db57feb7SJonathan Lemon static int ida_pci_attach(device_t dev);
75db57feb7SJonathan Lemon static void ida_pci_print_child(device_t bus, device_t dev);
76db57feb7SJonathan Lemon 
77db57feb7SJonathan Lemon static device_method_t ida_pci_methods[] = {
78db57feb7SJonathan Lemon 	DEVMETHOD(device_probe,		ida_pci_probe),
79db57feb7SJonathan Lemon 	DEVMETHOD(device_attach,	ida_pci_attach),
80db57feb7SJonathan Lemon 
81db57feb7SJonathan Lemon 	DEVMETHOD(bus_print_child,	ida_pci_print_child),
82db57feb7SJonathan Lemon 
83db57feb7SJonathan Lemon 	{ 0, 0 }
84db57feb7SJonathan Lemon };
85db57feb7SJonathan Lemon 
86db57feb7SJonathan Lemon static driver_t ida_pci_driver = {
87db57feb7SJonathan Lemon 	"ida",
88db57feb7SJonathan Lemon 	ida_pci_methods,
89db57feb7SJonathan Lemon 	sizeof(struct ida_softc)
90db57feb7SJonathan Lemon };
91db57feb7SJonathan Lemon 
92db57feb7SJonathan Lemon static devclass_t ida_devclass;
93db57feb7SJonathan Lemon 
94db57feb7SJonathan Lemon static int
95db57feb7SJonathan Lemon ida_pci_probe(device_t dev)
96db57feb7SJonathan Lemon {
97db57feb7SJonathan Lemon 	u_long board;
98db57feb7SJonathan Lemon 	int i;
99db57feb7SJonathan Lemon 
100db57feb7SJonathan Lemon 	if (pci_get_devid(dev) == IDA_DEVICEID_SMART) {
101db57feb7SJonathan Lemon 		board = pci_get_subdevice(dev);
102db57feb7SJonathan Lemon 		for (i = 0; board_id[i].board; i++) {
103db57feb7SJonathan Lemon 			if (board_id[i].board == board) {
104db57feb7SJonathan Lemon 				device_set_desc(dev, board_id[i].desc);
105db57feb7SJonathan Lemon 				return (0);
106db57feb7SJonathan Lemon 			}
107db57feb7SJonathan Lemon 		}
108db57feb7SJonathan Lemon 		/*
109db57feb7SJonathan Lemon 		 * It's an unknown Compaq SMART device, but assume we
110db57feb7SJonathan Lemon 		 * can support it.
111db57feb7SJonathan Lemon 		 */
112db57feb7SJonathan Lemon 		device_set_desc(dev, "Unknown Compaq Smart Array controller");
113db57feb7SJonathan Lemon 		return (0);
114db57feb7SJonathan Lemon 	}
115db57feb7SJonathan Lemon 	return (ENXIO);
116db57feb7SJonathan Lemon }
117db57feb7SJonathan Lemon 
118db57feb7SJonathan Lemon static int
119db57feb7SJonathan Lemon ida_pci_attach(device_t dev)
120db57feb7SJonathan Lemon {
121db57feb7SJonathan Lemon 	struct ida_softc *ida;
122db57feb7SJonathan Lemon 	u_int command;
123db57feb7SJonathan Lemon 	int error, rid;
124db57feb7SJonathan Lemon 
125db57feb7SJonathan Lemon 	command = pci_read_config(dev, PCIR_COMMAND, 1);
126db57feb7SJonathan Lemon 
127db57feb7SJonathan Lemon 	/*
128db57feb7SJonathan Lemon 	 * for multiple card types, need to re-determine which type is
129db57feb7SJonathan Lemon 	 * being attached here
130db57feb7SJonathan Lemon 	 */
131db57feb7SJonathan Lemon 
132db57feb7SJonathan Lemon 	/*
133db57feb7SJonathan Lemon 	 * it appears that this board only does MEMIO access.
134db57feb7SJonathan Lemon 	 */
135db57feb7SJonathan Lemon 	if ((command & PCIM_CMD_MEMEN) == 0) {
136db57feb7SJonathan Lemon                 device_printf(dev, "Only memory mapped I/O is supported\n");
137db57feb7SJonathan Lemon 		return (ENXIO);
138db57feb7SJonathan Lemon 	}
139db57feb7SJonathan Lemon 
140db57feb7SJonathan Lemon 	ida = (struct ida_softc *)device_get_softc(dev);
141db57feb7SJonathan Lemon 	ida->dev = dev;
142db57feb7SJonathan Lemon 
143db57feb7SJonathan Lemon 	ida->regs_res_type = SYS_RES_MEMORY;
144db57feb7SJonathan Lemon 	ida->regs_res_id = IDA_PCI_MEMADDR;
145db57feb7SJonathan Lemon 	ida->regs = bus_alloc_resource(dev, ida->regs_res_type,
146db57feb7SJonathan Lemon 	    &ida->regs_res_id, 0, ~0, 1, RF_ACTIVE);
147db57feb7SJonathan Lemon 	if (ida->regs == NULL) {
148db57feb7SJonathan Lemon 		device_printf(dev, "can't allocate register resources\n");
149db57feb7SJonathan Lemon 		return (ENOMEM);
150db57feb7SJonathan Lemon 	}
151db57feb7SJonathan Lemon 
152db57feb7SJonathan Lemon 	error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/0,
153db57feb7SJonathan Lemon 	    /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
154db57feb7SJonathan Lemon 	    /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL,
155db57feb7SJonathan Lemon 	    /*maxsize*/MAXBSIZE, /*nsegments*/IDA_NSEG,
156db57feb7SJonathan Lemon 	    /*maxsegsize*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/BUS_DMA_ALLOCNOW,
157db57feb7SJonathan Lemon 	    &ida->parent_dmat);
158db57feb7SJonathan Lemon 	if (error != 0) {
159db57feb7SJonathan Lemon 		device_printf(dev, "can't allocate DMA tag\n");
160db57feb7SJonathan Lemon 		ida_free(ida);
161db57feb7SJonathan Lemon 		return (ENOMEM);
162db57feb7SJonathan Lemon 	}
163db57feb7SJonathan Lemon 
164db57feb7SJonathan Lemon 	rid = 0;
165db57feb7SJonathan Lemon         ida->irq_res_type = SYS_RES_IRQ;
166db57feb7SJonathan Lemon 	ida->irq = bus_alloc_resource(dev, ida->irq_res_type, &rid,
167db57feb7SJonathan Lemon 	    0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
168db57feb7SJonathan Lemon         if (ida->irq == NULL) {
169db57feb7SJonathan Lemon                 ida_free(ida);
170db57feb7SJonathan Lemon                 return (ENOMEM);
171db57feb7SJonathan Lemon         }
172db57feb7SJonathan Lemon 	error = bus_setup_intr(dev, ida->irq, INTR_TYPE_BIO,
173db57feb7SJonathan Lemon 	    ida_intr, ida, &ida->ih);
174db57feb7SJonathan Lemon 	if (error) {
175db57feb7SJonathan Lemon 		device_printf(dev, "can't setup interrupt\n");
176db57feb7SJonathan Lemon 		ida_free(ida);
177db57feb7SJonathan Lemon 		return (ENOMEM);
178db57feb7SJonathan Lemon 	}
179db57feb7SJonathan Lemon 
180db57feb7SJonathan Lemon 	error = ida_init(ida);
181db57feb7SJonathan Lemon 	if (error) {
182db57feb7SJonathan Lemon                 ida_free(ida);
183db57feb7SJonathan Lemon                 return (error);
184db57feb7SJonathan Lemon         }
185db57feb7SJonathan Lemon 	ida_attach(ida);
186db57feb7SJonathan Lemon 	ida->flags = IDA_ATTACHED;
187db57feb7SJonathan Lemon 
188db57feb7SJonathan Lemon 	return (0);
189db57feb7SJonathan Lemon }
190db57feb7SJonathan Lemon 
191db57feb7SJonathan Lemon static void
192db57feb7SJonathan Lemon ida_pci_print_child(device_t bus, device_t dev)
193db57feb7SJonathan Lemon {
194db57feb7SJonathan Lemon 	printf(" on %s%d", device_get_name(bus), device_get_unit(bus));
195db57feb7SJonathan Lemon }
196db57feb7SJonathan Lemon 
197db57feb7SJonathan Lemon DRIVER_MODULE(ida, pci, ida_pci_driver, ida_devclass, 0, 0);
198db57feb7SJonathan Lemon 
199db57feb7SJonathan Lemon #endif /* NPCI > 0 */
200