Deleted Added
full compact
aac_pci.c (82527) aac_pci.c (83114)
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/dev/aac/aac_pci.c 82527 2001-08-29 23:34:05Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac_pci.c 83114 2001-09-05 20:43:02Z scottl $
30 */
31
32/*
33 * PCI bus interface and resource allocation.
34 */
35
36#include "opt_aac.h"
37

--- 14 unchanged lines hidden (view full) ---

52
53#include <pci/pcireg.h>
54#include <pci/pcivar.h>
55
56#include <dev/aac/aacreg.h>
57#include <dev/aac/aac_ioctl.h>
58#include <dev/aac/aacvar.h>
59
30 */
31
32/*
33 * PCI bus interface and resource allocation.
34 */
35
36#include "opt_aac.h"
37

--- 14 unchanged lines hidden (view full) ---

52
53#include <pci/pcireg.h>
54#include <pci/pcivar.h>
55
56#include <dev/aac/aacreg.h>
57#include <dev/aac/aac_ioctl.h>
58#include <dev/aac/aacvar.h>
59
60static int aac_pci_probe(device_t dev);
61static int aac_pci_attach(device_t dev);
60static int aac_pci_probe(device_t dev);
61static int aac_pci_attach(device_t dev);
62
63static device_method_t aac_methods[] = {
62
63static device_method_t aac_methods[] = {
64 /* Device interface */
65 DEVMETHOD(device_probe, aac_pci_probe),
66 DEVMETHOD(device_attach, aac_pci_attach),
67 DEVMETHOD(device_detach, aac_detach),
68 DEVMETHOD(device_suspend, aac_suspend),
69 DEVMETHOD(device_resume, aac_resume),
64 /* Device interface */
65 DEVMETHOD(device_probe, aac_pci_probe),
66 DEVMETHOD(device_attach, aac_pci_attach),
67 DEVMETHOD(device_detach, aac_detach),
68 DEVMETHOD(device_suspend, aac_suspend),
69 DEVMETHOD(device_resume, aac_resume),
70
70
71 DEVMETHOD(bus_print_child, bus_generic_print_child),
72 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
73 { 0, 0 }
71 DEVMETHOD(bus_print_child, bus_generic_print_child),
72 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
73 { 0, 0 }
74};
75
76static driver_t aac_pci_driver = {
77 "aac",
78 aac_methods,
79 sizeof(struct aac_softc)
80};
81
82DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
83
84struct aac_ident
85{
74};
75
76static driver_t aac_pci_driver = {
77 "aac",
78 aac_methods,
79 sizeof(struct aac_softc)
80};
81
82DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
83
84struct aac_ident
85{
86 u_int16_t vendor;
87 u_int16_t device;
88 u_int16_t subvendor;
89 u_int16_t subdevice;
90 int hwif;
91 char *desc;
86 u_int16_t vendor;
87 u_int16_t device;
88 u_int16_t subvendor;
89 u_int16_t subdevice;
90 int hwif;
91 char *desc;
92} aac_identifiers[] = {
92} aac_identifiers[] = {
93 {0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, "Dell PERC 2/Si"},
94 {0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
95 {0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
96 {0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
97 {0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
98 {0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
99 {0x1028, 0x0008, 0x1028, 0x00cf, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
100 {0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
101 {0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, "Adaptec AAC-364"},
102 {0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
103 "Adaptec SCSI RAID 5400S"},
104 {0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, "Dell PERC 2/QC"},
105 {0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, "HP NetRaid-4M"},
106 {0, 0, 0, 0, 0, 0}
93 {0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, "Dell PERC 2/Si"},
94 {0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
95 {0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
96 {0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
97 {0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
98 {0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
99 {0x1028, 0x0008, 0x1028, 0x00cf, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
100 {0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
101 {0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, "Adaptec AAC-364"},
102 {0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
103 "Adaptec SCSI RAID 5400S"},
104 {0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, "Dell PERC 2/QC"},
105 {0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, "HP NetRaid-4M"},
106 {0, 0, 0, 0, 0, 0}
107};
108
107};
108
109/******************************************************************************
109/*
110 * Determine whether this is one of our supported adapters.
111 */
112static int
113aac_pci_probe(device_t dev)
114{
110 * Determine whether this is one of our supported adapters.
111 */
112static int
113aac_pci_probe(device_t dev)
114{
115 struct aac_ident *m;
115 struct aac_ident *m;
116
116
117 debug_called(1);
117 debug_called(1);
118
118
119 for (m = aac_identifiers; m->vendor != 0; m++) {
120 if ((m->vendor == pci_get_vendor(dev)) &&
121 (m->device == pci_get_device(dev)) &&
122 ((m->subvendor == 0) || (m->subvendor == pci_get_subvendor(dev))) &&
123 ((m->subdevice == 0) || ((m->subdevice == pci_get_subdevice(dev))))) {
124
125 device_set_desc(dev, m->desc);
126 return(-10); /* allow room to be overridden */
119 for (m = aac_identifiers; m->vendor != 0; m++) {
120 if ((m->vendor == pci_get_vendor(dev)) &&
121 (m->device == pci_get_device(dev)) &&
122 ((m->subvendor == 0) || (m->subvendor ==
123 pci_get_subvendor(dev))) &&
124 ((m->subdevice == 0) || ((m->subdevice ==
125 pci_get_subdevice(dev))))) {
126
127 device_set_desc(dev, m->desc);
128 return(-10); /* allow room to be overridden */
129 }
127 }
130 }
128 }
129 return(ENXIO);
131 return(ENXIO);
130}
131
132}
133
132/******************************************************************************
134/*
133 * Allocate resources for our device, set up the bus interface.
134 */
135static int
136aac_pci_attach(device_t dev)
137{
135 * Allocate resources for our device, set up the bus interface.
136 */
137static int
138aac_pci_attach(device_t dev)
139{
138 struct aac_softc *sc;
139 int i, error;
140 u_int32_t command;
140 struct aac_softc *sc;
141 int i, error;
142 u_int32_t command;
141
143
142 debug_called(1);
144 debug_called(1);
143
145
144 /*
145 * Initialise softc.
146 */
147 sc = device_get_softc(dev);
148 bzero(sc, sizeof(*sc));
149 sc->aac_dev = dev;
146 /*
147 * Initialise softc.
148 */
149 sc = device_get_softc(dev);
150 bzero(sc, sizeof(*sc));
151 sc->aac_dev = dev;
150
152
151 /* assume failure is 'not configured' */
152 error = ENXIO;
153 /* assume failure is 'not configured' */
154 error = ENXIO;
153
155
154 /*
155 * Verify that the adapter is correctly set up in PCI space.
156 */
157 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
158 command |= PCIM_CMD_BUSMASTEREN;
159 pci_write_config(dev, PCIR_COMMAND, command, 2);
160 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
161 if (!(command & PCIM_CMD_BUSMASTEREN)) {
162 device_printf(sc->aac_dev, "can't enable bus-master feature\n");
163 goto out;
164 }
165 if ((command & PCIM_CMD_MEMEN) == 0) {
166 device_printf(sc->aac_dev, "memory window not available\n");
167 goto out;
168 }
156 /*
157 * Verify that the adapter is correctly set up in PCI space.
158 */
159 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
160 command |= PCIM_CMD_BUSMASTEREN;
161 pci_write_config(dev, PCIR_COMMAND, command, 2);
162 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
163 if (!(command & PCIM_CMD_BUSMASTEREN)) {
164 device_printf(sc->aac_dev, "can't enable bus-master feature\n");
165 goto out;
166 }
167 if ((command & PCIM_CMD_MEMEN) == 0) {
168 device_printf(sc->aac_dev, "memory window not available\n");
169 goto out;
170 }
169
171
170 /*
171 * Allocate the PCI register window.
172 */
173 sc->aac_regs_rid = 0x10; /* first base address register */
174 if ((sc->aac_regs_resource = bus_alloc_resource(sc->aac_dev, SYS_RES_MEMORY,
175 &sc->aac_regs_rid, 0, ~0, 1,
176 RF_ACTIVE)) == NULL) {
177 device_printf(sc->aac_dev, "couldn't allocate register window\n");
178 goto out;
179 }
180 sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
181 sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
172 /*
173 * Allocate the PCI register window.
174 */
175 sc->aac_regs_rid = 0x10; /* first base address register */
176 if ((sc->aac_regs_resource = bus_alloc_resource(sc->aac_dev,
177 SYS_RES_MEMORY,
178 &sc->aac_regs_rid,
179 0, ~0, 1,
180 RF_ACTIVE)) == NULL) {
181 device_printf(sc->aac_dev,
182 "couldn't allocate register window\n");
183 goto out;
184 }
185 sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
186 sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
182
187
183 /*
184 * Allocate and connect our interrupt.
185 */
186 sc->aac_irq_rid = 0;
187 if ((sc->aac_irq = bus_alloc_resource(sc->aac_dev, SYS_RES_IRQ,
188 &sc->aac_irq_rid, 0, ~0, 1,
189 RF_SHAREABLE | RF_ACTIVE)) == NULL) {
190 device_printf(sc->aac_dev, "can't allocate interrupt\n");
191 goto out;
192 }
188 /*
189 * Allocate and connect our interrupt.
190 */
191 sc->aac_irq_rid = 0;
192 if ((sc->aac_irq = bus_alloc_resource(sc->aac_dev, SYS_RES_IRQ,
193 &sc->aac_irq_rid, 0, ~0, 1,
194 RF_SHAREABLE |
195 RF_ACTIVE)) == NULL) {
196 device_printf(sc->aac_dev, "can't allocate interrupt\n");
197 goto out;
198 }
193#if __FreeBSD_version < 500005
194#define INTR_ENTROPY 0
195#endif
199#if __FreeBSD_version < 500005
200#define INTR_ENTROPY 0
201#endif
196 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO|INTR_ENTROPY,
197 aac_intr, sc, &sc->aac_intr)) {
198 device_printf(sc->aac_dev, "can't set up interrupt\n");
199 goto out;
200 }
202 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO|INTR_ENTROPY,
203 aac_intr, sc, &sc->aac_intr)) {
204 device_printf(sc->aac_dev, "can't set up interrupt\n");
205 goto out;
206 }
201
207
202 /* assume failure is 'out of memory' */
203 error = ENOMEM;
208 /* assume failure is 'out of memory' */
209 error = ENOMEM;
204
210
205 /*
206 * Allocate the parent bus DMA tag appropriate for our PCI interface.
207 *
208 * Note that some of these controllers are 64-bit capable.
209 */
210 if (bus_dma_tag_create(NULL, /* parent */
211 1, 0, /* algnmnt, boundary */
212 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
213 BUS_SPACE_MAXADDR, /* highaddr */
214 NULL, NULL, /* filter, filterarg */
215 MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
216 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
217 BUS_DMA_ALLOCNOW, /* flags */
218 &sc->aac_parent_dmat)) {
219 device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
220 goto out;
221 }
211 /*
212 * Allocate the parent bus DMA tag appropriate for our PCI interface.
213 *
214 * Note that some of these controllers are 64-bit capable.
215 */
216 if (bus_dma_tag_create(NULL, /* parent */
217 1, 0, /* algnmnt, boundary */
218 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
219 BUS_SPACE_MAXADDR, /* highaddr */
220 NULL, NULL, /* filter, filterarg */
221 MAXBSIZE, /* maxsize */
222 AAC_MAXSGENTRIES, /* nsegments */
223 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
224 BUS_DMA_ALLOCNOW, /* flags */
225 &sc->aac_parent_dmat)) {
226 device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
227 goto out;
228 }
222
229
223 /*
224 * Create DMA tag for mapping buffers into controller-addressable space.
225 */
226 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
230 /*
231 * Create DMA tag for mapping buffers into controller-addressable space.
232 */
233 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
227 1, 0, /* algnmnt, boundary */
228 BUS_SPACE_MAXADDR, /* lowaddr */
229 BUS_SPACE_MAXADDR, /* highaddr */
230 NULL, NULL, /* filter, filterarg */
231 MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
232 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
233 0, /* flags */
234 &sc->aac_buffer_dmat)) {
234 1, 0, /* algnmnt, boundary */
235 BUS_SPACE_MAXADDR, /* lowaddr */
236 BUS_SPACE_MAXADDR, /* highaddr */
237 NULL, NULL, /* filter, filterarg */
238 MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
239 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
240 0, /* flags */
241 &sc->aac_buffer_dmat)) {
235 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
236 goto out;
237 }
242 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
243 goto out;
244 }
238
245
239 /*
240 * Create DMA tag for mapping FIBs into controller-addressable space..
241 */
242 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
246 /*
247 * Create DMA tag for mapping FIBs into controller-addressable space..
248 */
249 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
243 1, 0, /* algnmnt, boundary */
244 BUS_SPACE_MAXADDR, /* lowaddr */
245 BUS_SPACE_MAXADDR, /* highaddr */
246 NULL, NULL, /* filter, filterarg */
247 AAC_FIB_COUNT *
248 sizeof(struct aac_fib), 1, /* maxsize, nsegments */
249 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
250 0, /* flags */
251 &sc->aac_fib_dmat)) {
250 1, 0, /* algnmnt, boundary */
251 BUS_SPACE_MAXADDR, /* lowaddr */
252 BUS_SPACE_MAXADDR, /* highaddr */
253 NULL, NULL, /* filter, filterarg */
254 AAC_FIB_COUNT *
255 sizeof(struct aac_fib), 1, /* maxsize, nsegments */
256 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
257 0, /* flags */
258 &sc->aac_fib_dmat)) {
252 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
253 goto out;
254 }
259 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
260 goto out;
261 }
255
262
256 /*
257 * Detect the hardware interface version, set up the bus interface
258 * indirection.
259 */
260 sc->aac_hwif = AAC_HWIF_UNKNOWN;
261 for (i = 0; aac_identifiers[i].vendor != 0; i++) {
262 if ((aac_identifiers[i].vendor == pci_get_vendor(dev)) &&
263 (aac_identifiers[i].device == pci_get_device(dev))) {
264 sc->aac_hwif = aac_identifiers[i].hwif;
265 switch(sc->aac_hwif) {
266 case AAC_HWIF_I960RX:
267 debug(2, "set hardware up for i960Rx");
268 sc->aac_if = aac_rx_interface;
269 break;
263 /*
264 * Detect the hardware interface version, set up the bus interface
265 * indirection.
266 */
267 sc->aac_hwif = AAC_HWIF_UNKNOWN;
268 for (i = 0; aac_identifiers[i].vendor != 0; i++) {
269 if ((aac_identifiers[i].vendor == pci_get_vendor(dev)) &&
270 (aac_identifiers[i].device == pci_get_device(dev))) {
271 sc->aac_hwif = aac_identifiers[i].hwif;
272 switch(sc->aac_hwif) {
273 case AAC_HWIF_I960RX:
274 debug(2, "set hardware up for i960Rx");
275 sc->aac_if = aac_rx_interface;
276 break;
270
277
271 case AAC_HWIF_STRONGARM:
272 debug(2, "set hardware up for StrongARM");
273 sc->aac_if = aac_sa_interface;
274 break;
275 }
276 break;
278 case AAC_HWIF_STRONGARM:
279 debug(2, "set hardware up for StrongARM");
280 sc->aac_if = aac_sa_interface;
281 break;
282 }
283 break;
284 }
277 }
285 }
278 }
279 if (sc->aac_hwif == AAC_HWIF_UNKNOWN) {
280 device_printf(sc->aac_dev, "unknown hardware type\n");
281 error = ENXIO;
282 goto out;
283 }
286 if (sc->aac_hwif == AAC_HWIF_UNKNOWN) {
287 device_printf(sc->aac_dev, "unknown hardware type\n");
288 error = ENXIO;
289 goto out;
290 }
284
291
285 /*
286 * Do bus-independent initialisation.
287 */
288 error = aac_attach(sc);
289
292 /*
293 * Do bus-independent initialisation.
294 */
295 error = aac_attach(sc);
296
290out:
297out:
291 if (error)
292 aac_free(sc);
293 return(error);
298 if (error)
299 aac_free(sc);
300 return(error);
294}
301}