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} |