Deleted Added
full compact
aac_pci.c (95350) aac_pci.c (95536)
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
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
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
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
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 95350 2002-04-24 05:12:50Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac_pci.c 95536 2002-04-27 01:31:17Z scottl $
30 */
31
32/*
33 * PCI bus interface and resource allocation.
34 */
35
36#include "opt_aac.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41
42#include <dev/aac/aac_compat.h>
43#include <sys/bus.h>
44#include <sys/conf.h>
45#include <sys/devicestat.h>
46#include <sys/disk.h>
47
48#include <machine/bus_memio.h>
49#include <machine/bus.h>
50#include <machine/resource.h>
51#include <sys/rman.h>
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);
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),
70
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
82static devclass_t aac_devclass;
83
84DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
85
86struct aac_ident
87{
88 u_int16_t vendor;
89 u_int16_t device;
90 u_int16_t subvendor;
91 u_int16_t subdevice;
92 int hwif;
30 */
31
32/*
33 * PCI bus interface and resource allocation.
34 */
35
36#include "opt_aac.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41
42#include <dev/aac/aac_compat.h>
43#include <sys/bus.h>
44#include <sys/conf.h>
45#include <sys/devicestat.h>
46#include <sys/disk.h>
47
48#include <machine/bus_memio.h>
49#include <machine/bus.h>
50#include <machine/resource.h>
51#include <sys/rman.h>
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);
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),
70
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
82static devclass_t aac_devclass;
83
84DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
85
86struct aac_ident
87{
88 u_int16_t vendor;
89 u_int16_t device;
90 u_int16_t subvendor;
91 u_int16_t subdevice;
92 int hwif;
93 int quirks;
93 char *desc;
94} aac_identifiers[] = {
94 char *desc;
95} aac_identifiers[] = {
95 {0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, "Dell PERC 2/Si"},
96 {0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
97 {0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
98 {0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
99 {0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
100 {0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
101 {0x1028, 0x0008, 0x1028, 0x00cf, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
102 {0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
103 {0x1028, 0x000a, 0x1028, 0x011b, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
104 {0x1028, 0x000a, 0x1028, 0x0121, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
105 {0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, "Adaptec AAC-364"},
106 {0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
107 "Adaptec SCSI RAID 5400S"},
108 {0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, "Dell PERC 2/QC"},
109 {0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, "HP NetRaid-4M"},
110 {0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX,
96 {0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
97 "Dell PERC 2/Si"},
98 {0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
99 "Dell PERC 3/Di"},
100 {0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
101 "Dell PERC 3/Si"},
102 {0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
103 "Dell PERC 3/Si"},
104 {0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
105 "Dell PERC 3/Di"},
106 {0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
107 "Dell PERC 3/Di"},
108 {0x1028, 0x0008, 0x1028, 0x00cf, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
109 "Dell PERC 3/Di"},
110 {0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
111 "Dell PERC 3/Di"},
112 {0x1028, 0x000a, 0x1028, 0x011b, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
113 "Dell PERC 3/Di"},
114 {0x1028, 0x000a, 0x1028, 0x0121, AAC_HWIF_I960RX, AAC_QUIRK_NOCAM,
115 "Dell PERC 3/Di"},
116 {0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, AAC_QUIRK_NOCAM,
117 "Adaptec AAC-364"},
118 {0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM, 0,
119 "Adaptec SCSI RAID 5400S"},
120 {0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, AAC_QUIRK_NOCAM |
121 AAC_QUIRK_PERC2QC, "Dell PERC 2/QC"},
122 {0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM,
123 AAC_QUIRK_CAM_NORESET, "HP NetRaid-4M"},
124 {0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, 0,
111 "Adaptec SCSI RAID 2200S"},
125 "Adaptec SCSI RAID 2200S"},
112 {0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX,
126 {0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, 0,
113 "Adaptec SCSI RAID 2200S"},
127 "Adaptec SCSI RAID 2200S"},
114 {0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX,
128 {0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, 0,
115 "Adaptec SCSI RAID 2120S"},
129 "Adaptec SCSI RAID 2120S"},
116 {0, 0, 0, 0, 0, 0}
130 {0, 0, 0, 0, 0, 0, 0}
117};
118
119/*
120 * Determine whether this is one of our supported adapters.
121 */
122static int
123aac_pci_probe(device_t dev)
124{
125 struct aac_ident *m;
126
127 debug_called(1);
128
129 for (m = aac_identifiers; m->vendor != 0; m++) {
130 if ((m->vendor == pci_get_vendor(dev)) &&
131 (m->device == pci_get_device(dev)) &&
132 ((m->subvendor == 0) || (m->subvendor ==
133 pci_get_subvendor(dev))) &&
134 ((m->subdevice == 0) || ((m->subdevice ==
135 pci_get_subdevice(dev))))) {
136
137 device_set_desc(dev, m->desc);
138 return(-10); /* allow room to be overridden */
139 }
140 }
141 return(ENXIO);
142}
143
144/*
145 * Allocate resources for our device, set up the bus interface.
146 */
147static int
148aac_pci_attach(device_t dev)
149{
150 struct aac_softc *sc;
151 int i, error;
152 u_int32_t command;
153
154 debug_called(1);
155
156 /*
157 * Initialise softc.
158 */
159 sc = device_get_softc(dev);
160 bzero(sc, sizeof(*sc));
161 sc->aac_dev = dev;
162
163 /* assume failure is 'not configured' */
164 error = ENXIO;
165
166 /*
167 * Verify that the adapter is correctly set up in PCI space.
168 */
169 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
170 command |= PCIM_CMD_BUSMASTEREN;
171 pci_write_config(dev, PCIR_COMMAND, command, 2);
172 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
173 if (!(command & PCIM_CMD_BUSMASTEREN)) {
174 device_printf(sc->aac_dev, "can't enable bus-master feature\n");
175 goto out;
176 }
177 if ((command & PCIM_CMD_MEMEN) == 0) {
178 device_printf(sc->aac_dev, "memory window not available\n");
179 goto out;
180 }
181
182 /*
183 * Allocate the PCI register window.
184 */
185 sc->aac_regs_rid = 0x10; /* first base address register */
186 if ((sc->aac_regs_resource = bus_alloc_resource(sc->aac_dev,
187 SYS_RES_MEMORY,
188 &sc->aac_regs_rid,
189 0, ~0, 1,
190 RF_ACTIVE)) == NULL) {
191 device_printf(sc->aac_dev,
192 "couldn't allocate register window\n");
193 goto out;
194 }
195 sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
196 sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
197
198 /*
199 * Allocate and connect our interrupt.
200 */
201 sc->aac_irq_rid = 0;
202 if ((sc->aac_irq = bus_alloc_resource(sc->aac_dev, SYS_RES_IRQ,
203 &sc->aac_irq_rid, 0, ~0, 1,
204 RF_SHAREABLE |
205 RF_ACTIVE)) == NULL) {
206 device_printf(sc->aac_dev, "can't allocate interrupt\n");
207 goto out;
208 }
209#ifndef INTR_ENTROPY
210#define INTR_ENTROPY 0
211#endif
212 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO|INTR_ENTROPY,
213 aac_intr, sc, &sc->aac_intr)) {
214 device_printf(sc->aac_dev, "can't set up interrupt\n");
215 goto out;
216 }
217
218 /* assume failure is 'out of memory' */
219 error = ENOMEM;
220
221 /*
222 * Allocate the parent bus DMA tag appropriate for our PCI interface.
223 *
224 * Note that some of these controllers are 64-bit capable.
225 */
226 if (bus_dma_tag_create(NULL, /* parent */
227 PAGE_SIZE, 0, /* algnmnt, boundary */
228 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
229 BUS_SPACE_MAXADDR, /* highaddr */
230 NULL, NULL, /* filter, filterarg */
231 MAXBSIZE, /* maxsize */
232 AAC_MAXSGENTRIES, /* nsegments */
233 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
234 BUS_DMA_ALLOCNOW, /* flags */
235 &sc->aac_parent_dmat)) {
236 device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
237 goto out;
238 }
239
240 /*
241 * Create DMA tag for mapping buffers into controller-addressable space.
242 */
243 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
244 1, 0, /* algnmnt, boundary */
245 BUS_SPACE_MAXADDR, /* lowaddr */
246 BUS_SPACE_MAXADDR, /* highaddr */
247 NULL, NULL, /* filter, filterarg */
248 MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
249 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
250 0, /* flags */
251 &sc->aac_buffer_dmat)) {
252 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
253 goto out;
254 }
255
256 /*
257 * Create DMA tag for mapping FIBs into controller-addressable space..
258 */
259 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
260 1, 0, /* algnmnt, boundary */
261 BUS_SPACE_MAXADDR, /* lowaddr */
262 BUS_SPACE_MAXADDR, /* highaddr */
263 NULL, NULL, /* filter, filterarg */
264 AAC_FIB_COUNT *
265 sizeof(struct aac_fib), 1, /* maxsize, nsegments */
266 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
267 0, /* flags */
268 &sc->aac_fib_dmat)) {
131};
132
133/*
134 * Determine whether this is one of our supported adapters.
135 */
136static int
137aac_pci_probe(device_t dev)
138{
139 struct aac_ident *m;
140
141 debug_called(1);
142
143 for (m = aac_identifiers; m->vendor != 0; m++) {
144 if ((m->vendor == pci_get_vendor(dev)) &&
145 (m->device == pci_get_device(dev)) &&
146 ((m->subvendor == 0) || (m->subvendor ==
147 pci_get_subvendor(dev))) &&
148 ((m->subdevice == 0) || ((m->subdevice ==
149 pci_get_subdevice(dev))))) {
150
151 device_set_desc(dev, m->desc);
152 return(-10); /* allow room to be overridden */
153 }
154 }
155 return(ENXIO);
156}
157
158/*
159 * Allocate resources for our device, set up the bus interface.
160 */
161static int
162aac_pci_attach(device_t dev)
163{
164 struct aac_softc *sc;
165 int i, error;
166 u_int32_t command;
167
168 debug_called(1);
169
170 /*
171 * Initialise softc.
172 */
173 sc = device_get_softc(dev);
174 bzero(sc, sizeof(*sc));
175 sc->aac_dev = dev;
176
177 /* assume failure is 'not configured' */
178 error = ENXIO;
179
180 /*
181 * Verify that the adapter is correctly set up in PCI space.
182 */
183 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
184 command |= PCIM_CMD_BUSMASTEREN;
185 pci_write_config(dev, PCIR_COMMAND, command, 2);
186 command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
187 if (!(command & PCIM_CMD_BUSMASTEREN)) {
188 device_printf(sc->aac_dev, "can't enable bus-master feature\n");
189 goto out;
190 }
191 if ((command & PCIM_CMD_MEMEN) == 0) {
192 device_printf(sc->aac_dev, "memory window not available\n");
193 goto out;
194 }
195
196 /*
197 * Allocate the PCI register window.
198 */
199 sc->aac_regs_rid = 0x10; /* first base address register */
200 if ((sc->aac_regs_resource = bus_alloc_resource(sc->aac_dev,
201 SYS_RES_MEMORY,
202 &sc->aac_regs_rid,
203 0, ~0, 1,
204 RF_ACTIVE)) == NULL) {
205 device_printf(sc->aac_dev,
206 "couldn't allocate register window\n");
207 goto out;
208 }
209 sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
210 sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
211
212 /*
213 * Allocate and connect our interrupt.
214 */
215 sc->aac_irq_rid = 0;
216 if ((sc->aac_irq = bus_alloc_resource(sc->aac_dev, SYS_RES_IRQ,
217 &sc->aac_irq_rid, 0, ~0, 1,
218 RF_SHAREABLE |
219 RF_ACTIVE)) == NULL) {
220 device_printf(sc->aac_dev, "can't allocate interrupt\n");
221 goto out;
222 }
223#ifndef INTR_ENTROPY
224#define INTR_ENTROPY 0
225#endif
226 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO|INTR_ENTROPY,
227 aac_intr, sc, &sc->aac_intr)) {
228 device_printf(sc->aac_dev, "can't set up interrupt\n");
229 goto out;
230 }
231
232 /* assume failure is 'out of memory' */
233 error = ENOMEM;
234
235 /*
236 * Allocate the parent bus DMA tag appropriate for our PCI interface.
237 *
238 * Note that some of these controllers are 64-bit capable.
239 */
240 if (bus_dma_tag_create(NULL, /* parent */
241 PAGE_SIZE, 0, /* algnmnt, boundary */
242 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
243 BUS_SPACE_MAXADDR, /* highaddr */
244 NULL, NULL, /* filter, filterarg */
245 MAXBSIZE, /* maxsize */
246 AAC_MAXSGENTRIES, /* nsegments */
247 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
248 BUS_DMA_ALLOCNOW, /* flags */
249 &sc->aac_parent_dmat)) {
250 device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
251 goto out;
252 }
253
254 /*
255 * Create DMA tag for mapping buffers into controller-addressable space.
256 */
257 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
258 1, 0, /* algnmnt, boundary */
259 BUS_SPACE_MAXADDR, /* lowaddr */
260 BUS_SPACE_MAXADDR, /* highaddr */
261 NULL, NULL, /* filter, filterarg */
262 MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
263 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
264 0, /* flags */
265 &sc->aac_buffer_dmat)) {
266 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
267 goto out;
268 }
269
270 /*
271 * Create DMA tag for mapping FIBs into controller-addressable space..
272 */
273 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
274 1, 0, /* algnmnt, boundary */
275 BUS_SPACE_MAXADDR, /* lowaddr */
276 BUS_SPACE_MAXADDR, /* highaddr */
277 NULL, NULL, /* filter, filterarg */
278 AAC_FIB_COUNT *
279 sizeof(struct aac_fib), 1, /* maxsize, nsegments */
280 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
281 0, /* flags */
282 &sc->aac_fib_dmat)) {
269 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
283 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");;
270 goto out;
271 }
272
273 /*
274 * Detect the hardware interface version, set up the bus interface
275 * indirection.
276 */
277 sc->aac_hwif = AAC_HWIF_UNKNOWN;
278 for (i = 0; aac_identifiers[i].vendor != 0; i++) {
279 if ((aac_identifiers[i].vendor == pci_get_vendor(dev)) &&
284 goto out;
285 }
286
287 /*
288 * Detect the hardware interface version, set up the bus interface
289 * indirection.
290 */
291 sc->aac_hwif = AAC_HWIF_UNKNOWN;
292 for (i = 0; aac_identifiers[i].vendor != 0; i++) {
293 if ((aac_identifiers[i].vendor == pci_get_vendor(dev)) &&
280 (aac_identifiers[i].device == pci_get_device(dev))) {
294 (aac_identifiers[i].device == pci_get_device(dev)) &&
295 (aac_identifiers[i].subvendor == pci_get_subvendor(dev)) &&
296 (aac_identifiers[i].subdevice == pci_get_subdevice(dev))) {
281 sc->aac_hwif = aac_identifiers[i].hwif;
282 switch(sc->aac_hwif) {
283 case AAC_HWIF_I960RX:
284 debug(2, "set hardware up for i960Rx");
285 sc->aac_if = aac_rx_interface;
286 break;
287
288 case AAC_HWIF_STRONGARM:
289 debug(2, "set hardware up for StrongARM");
290 sc->aac_if = aac_sa_interface;
291 break;
292 case AAC_HWIF_FALCON:
293 debug(2, "set hardware up for Falcon/PPC");
294 sc->aac_if = aac_fa_interface;
295 break;
296 }
297 sc->aac_hwif = aac_identifiers[i].hwif;
298 switch(sc->aac_hwif) {
299 case AAC_HWIF_I960RX:
300 debug(2, "set hardware up for i960Rx");
301 sc->aac_if = aac_rx_interface;
302 break;
303
304 case AAC_HWIF_STRONGARM:
305 debug(2, "set hardware up for StrongARM");
306 sc->aac_if = aac_sa_interface;
307 break;
308 case AAC_HWIF_FALCON:
309 debug(2, "set hardware up for Falcon/PPC");
310 sc->aac_if = aac_fa_interface;
311 break;
312 }
313
314 /* Set up quirks */
315 sc->quirks = aac_identifiers[i].quirks;
316
297 break;
298 }
299 }
300 if (sc->aac_hwif == AAC_HWIF_UNKNOWN) {
301 device_printf(sc->aac_dev, "unknown hardware type\n");
302 error = ENXIO;
303 goto out;
304 }
305
306
307 /*
317 break;
318 }
319 }
320 if (sc->aac_hwif == AAC_HWIF_UNKNOWN) {
321 device_printf(sc->aac_dev, "unknown hardware type\n");
322 error = ENXIO;
323 goto out;
324 }
325
326
327 /*
308 * Check for quirky hardware
309 */
310 if (pci_get_subdevice(dev) == 0x1364 &&
311 pci_get_subvendor(dev) == 0x9005)
312 sc->quirks |= AAC_QUIRK_PERC2QC;
313
314 /*
315 * Do bus-independent initialisation.
316 */
317 error = aac_attach(sc);
318
319out:
320 if (error)
321 aac_free(sc);
322 return(error);
323}
328 * Do bus-independent initialisation.
329 */
330 error = aac_attach(sc);
331
332out:
333 if (error)
334 aac_free(sc);
335 return(error);
336}