1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org> 5 * Copyright (c) 1997-2008 by Matthew Jacob 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 immediately at the beginning of the file, without modification, 13 * this list of conditions, and the following disclaimer. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 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 FOR 21 * 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 /* 30 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 31 * FreeBSD Version. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 #include <sys/linker.h> 39 #include <sys/bus.h> 40 #include <sys/stdint.h> 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcivar.h> 43 #include <machine/bus.h> 44 #include <machine/resource.h> 45 #include <sys/rman.h> 46 #include <sys/malloc.h> 47 #include <sys/uio.h> 48 #include <dev/isp/isp_freebsd.h> 49 50 static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int); 51 static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t); 52 static uint32_t isp_pci_rd_reg_2600(ispsoftc_t *, int); 53 static void isp_pci_wr_reg_2600(ispsoftc_t *, int, uint32_t); 54 static void isp_pci_run_isr_2400(ispsoftc_t *); 55 static int isp_pci_mbxdma(ispsoftc_t *); 56 static void isp_pci_mbxdmafree(ispsoftc_t *); 57 static int isp_pci_irqsetup(ispsoftc_t *); 58 59 static struct ispmdvec mdvec_2400 = { 60 isp_pci_run_isr_2400, 61 isp_pci_rd_reg_2400, 62 isp_pci_wr_reg_2400, 63 isp_pci_mbxdma, 64 isp_send_cmd, 65 isp_pci_irqsetup, 66 NULL 67 }; 68 69 static struct ispmdvec mdvec_2500 = { 70 isp_pci_run_isr_2400, 71 isp_pci_rd_reg_2400, 72 isp_pci_wr_reg_2400, 73 isp_pci_mbxdma, 74 isp_send_cmd, 75 isp_pci_irqsetup, 76 NULL 77 }; 78 79 static struct ispmdvec mdvec_2600 = { 80 isp_pci_run_isr_2400, 81 isp_pci_rd_reg_2600, 82 isp_pci_wr_reg_2600, 83 isp_pci_mbxdma, 84 isp_send_cmd, 85 isp_pci_irqsetup, 86 NULL 87 }; 88 89 static struct ispmdvec mdvec_2700 = { 90 isp_pci_run_isr_2400, 91 isp_pci_rd_reg_2600, 92 isp_pci_wr_reg_2600, 93 isp_pci_mbxdma, 94 isp_send_cmd, 95 isp_pci_irqsetup, 96 NULL 97 }; 98 99 static struct ispmdvec mdvec_2800 = { 100 isp_pci_run_isr_2400, 101 isp_pci_rd_reg_2600, 102 isp_pci_wr_reg_2600, 103 isp_pci_mbxdma, 104 isp_send_cmd, 105 isp_pci_irqsetup, 106 NULL 107 }; 108 109 #ifndef PCIM_CMD_INVEN 110 #define PCIM_CMD_INVEN 0x10 111 #endif 112 #ifndef PCIM_CMD_BUSMASTEREN 113 #define PCIM_CMD_BUSMASTEREN 0x0004 114 #endif 115 #ifndef PCIM_CMD_PERRESPEN 116 #define PCIM_CMD_PERRESPEN 0x0040 117 #endif 118 #ifndef PCIM_CMD_SEREN 119 #define PCIM_CMD_SEREN 0x0100 120 #endif 121 #ifndef PCIM_CMD_INTX_DISABLE 122 #define PCIM_CMD_INTX_DISABLE 0x0400 123 #endif 124 125 #ifndef PCIR_COMMAND 126 #define PCIR_COMMAND 0x04 127 #endif 128 129 #ifndef PCIR_CACHELNSZ 130 #define PCIR_CACHELNSZ 0x0c 131 #endif 132 133 #ifndef PCIR_LATTIMER 134 #define PCIR_LATTIMER 0x0d 135 #endif 136 137 #ifndef PCIR_ROMADDR 138 #define PCIR_ROMADDR 0x30 139 #endif 140 141 #define PCI_VENDOR_QLOGIC 0x1077 142 143 #define PCI_PRODUCT_QLOGIC_ISP2422 0x2422 144 #define PCI_PRODUCT_QLOGIC_ISP2432 0x2432 145 #define PCI_PRODUCT_QLOGIC_ISP2532 0x2532 146 #define PCI_PRODUCT_QLOGIC_ISP5432 0x5432 147 #define PCI_PRODUCT_QLOGIC_ISP2031 0x2031 148 #define PCI_PRODUCT_QLOGIC_ISP8031 0x8031 149 #define PCI_PRODUCT_QLOGIC_ISP2684 0x2171 150 #define PCI_PRODUCT_QLOGIC_ISP2692 0x2b61 151 #define PCI_PRODUCT_QLOGIC_ISP2714 0x2071 152 #define PCI_PRODUCT_QLOGIC_ISP2722 0x2261 153 #define PCI_PRODUCT_QLOGIC_ISP2812 0x2281 154 #define PCI_PRODUCT_QLOGIC_ISP2814 0x2081 155 156 #define PCI_QLOGIC_ISP2422 \ 157 ((PCI_PRODUCT_QLOGIC_ISP2422 << 16) | PCI_VENDOR_QLOGIC) 158 #define PCI_QLOGIC_ISP2432 \ 159 ((PCI_PRODUCT_QLOGIC_ISP2432 << 16) | PCI_VENDOR_QLOGIC) 160 #define PCI_QLOGIC_ISP2532 \ 161 ((PCI_PRODUCT_QLOGIC_ISP2532 << 16) | PCI_VENDOR_QLOGIC) 162 #define PCI_QLOGIC_ISP5432 \ 163 ((PCI_PRODUCT_QLOGIC_ISP5432 << 16) | PCI_VENDOR_QLOGIC) 164 #define PCI_QLOGIC_ISP2031 \ 165 ((PCI_PRODUCT_QLOGIC_ISP2031 << 16) | PCI_VENDOR_QLOGIC) 166 #define PCI_QLOGIC_ISP8031 \ 167 ((PCI_PRODUCT_QLOGIC_ISP8031 << 16) | PCI_VENDOR_QLOGIC) 168 #define PCI_QLOGIC_ISP2684 \ 169 ((PCI_PRODUCT_QLOGIC_ISP2684 << 16) | PCI_VENDOR_QLOGIC) 170 #define PCI_QLOGIC_ISP2692 \ 171 ((PCI_PRODUCT_QLOGIC_ISP2692 << 16) | PCI_VENDOR_QLOGIC) 172 #define PCI_QLOGIC_ISP2714 \ 173 ((PCI_PRODUCT_QLOGIC_ISP2714 << 16) | PCI_VENDOR_QLOGIC) 174 #define PCI_QLOGIC_ISP2722 \ 175 ((PCI_PRODUCT_QLOGIC_ISP2722 << 16) | PCI_VENDOR_QLOGIC) 176 #define PCI_QLOGIC_ISP2812 \ 177 ((PCI_PRODUCT_QLOGIC_ISP2812 << 16) | PCI_VENDOR_QLOGIC) 178 #define PCI_QLOGIC_ISP2814 \ 179 ((PCI_PRODUCT_QLOGIC_ISP2814 << 16) | PCI_VENDOR_QLOGIC) 180 181 #define PCI_DFLT_LTNCY 0x40 182 #define PCI_DFLT_LNSZ 0x10 183 184 static int isp_pci_probe (device_t); 185 static int isp_pci_attach (device_t); 186 static int isp_pci_detach (device_t); 187 188 189 struct isp_pcisoftc { 190 ispsoftc_t pci_isp; 191 struct resource * regs; 192 struct resource * regs1; 193 struct resource * regs2; 194 struct { 195 int iqd; 196 struct resource * irq; 197 void * ih; 198 } irq[ISP_MAX_IRQS]; 199 int rtp; 200 int rgd; 201 int rtp1; 202 int rgd1; 203 int rtp2; 204 int rgd2; 205 bus_dma_tag_t dmat; 206 int msicount; 207 }; 208 209 210 static device_method_t isp_pci_methods[] = { 211 /* Device interface */ 212 DEVMETHOD(device_probe, isp_pci_probe), 213 DEVMETHOD(device_attach, isp_pci_attach), 214 DEVMETHOD(device_detach, isp_pci_detach), 215 { 0, 0 } 216 }; 217 218 static driver_t isp_pci_driver = { 219 "isp", isp_pci_methods, sizeof (struct isp_pcisoftc) 220 }; 221 222 DRIVER_MODULE(isp, pci, isp_pci_driver, 0, 0); 223 MODULE_DEPEND(isp, cam, 1, 1, 1); 224 MODULE_DEPEND(isp, firmware, 1, 1, 1); 225 static int isp_nvports = 0; 226 227 static int 228 isp_pci_probe(device_t dev) 229 { 230 switch ((pci_get_device(dev) << 16) | (pci_get_vendor(dev))) { 231 case PCI_QLOGIC_ISP2422: 232 device_set_desc(dev, "Qlogic ISP 2422 PCI FC-AL Adapter"); 233 break; 234 case PCI_QLOGIC_ISP2432: 235 device_set_desc(dev, "Qlogic ISP 2432 PCI FC-AL Adapter"); 236 break; 237 case PCI_QLOGIC_ISP2532: 238 device_set_desc(dev, "Qlogic ISP 2532 PCI FC-AL Adapter"); 239 break; 240 case PCI_QLOGIC_ISP5432: 241 device_set_desc(dev, "Qlogic ISP 5432 PCI FC-AL Adapter"); 242 break; 243 case PCI_QLOGIC_ISP2031: 244 device_set_desc(dev, "Qlogic ISP 2031 PCI FC-AL Adapter"); 245 break; 246 case PCI_QLOGIC_ISP8031: 247 device_set_desc(dev, "Qlogic ISP 8031 PCI FCoE Adapter"); 248 break; 249 case PCI_QLOGIC_ISP2684: 250 device_set_desc(dev, "Qlogic ISP 2684 PCI FC Adapter"); 251 break; 252 case PCI_QLOGIC_ISP2692: 253 device_set_desc(dev, "Qlogic ISP 2692 PCI FC Adapter"); 254 break; 255 case PCI_QLOGIC_ISP2714: 256 device_set_desc(dev, "Qlogic ISP 2714 PCI FC Adapter"); 257 break; 258 case PCI_QLOGIC_ISP2722: 259 device_set_desc(dev, "Qlogic ISP 2722 PCI FC Adapter"); 260 break; 261 case PCI_QLOGIC_ISP2812: 262 device_set_desc(dev, "Qlogic ISP 2812 PCI FC Adapter"); 263 break; 264 case PCI_QLOGIC_ISP2814: 265 device_set_desc(dev, "Qlogic ISP 2814 PCI FC Adapter"); 266 break; 267 default: 268 return (ENXIO); 269 } 270 if (isp_announced == 0 && bootverbose) { 271 printf("Qlogic ISP Driver, FreeBSD Version %d.%d, " 272 "Core Version %d.%d\n", 273 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, 274 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); 275 isp_announced++; 276 } 277 /* 278 * XXXX: Here is where we might load the f/w module 279 * XXXX: (or increase a reference count to it). 280 */ 281 return (BUS_PROBE_DEFAULT); 282 } 283 284 static void 285 isp_get_generic_options(device_t dev, ispsoftc_t *isp) 286 { 287 int tval; 288 289 tval = 0; 290 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fwload_disable", &tval) == 0 && tval != 0) { 291 isp->isp_confopts |= ISP_CFG_NORELOAD; 292 } 293 tval = 0; 294 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "ignore_nvram", &tval) == 0 && tval != 0) { 295 isp->isp_confopts |= ISP_CFG_NONVRAM; 296 } 297 tval = 0; 298 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "debug", &tval); 299 if (tval) { 300 isp->isp_dblev = tval; 301 } else { 302 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 303 } 304 if (bootverbose) { 305 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 306 } 307 tval = -1; 308 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "vports", &tval); 309 if (tval > 0 && tval <= 254) { 310 isp_nvports = tval; 311 } 312 tval = 7; 313 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "quickboot_time", &tval); 314 isp_quickboot_time = tval; 315 } 316 317 static void 318 isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp) 319 { 320 const char *sptr; 321 int tval = 0; 322 char prefix[12], name[16]; 323 324 if (chan == 0) 325 prefix[0] = 0; 326 else 327 snprintf(prefix, sizeof(prefix), "chan%d.", chan); 328 snprintf(name, sizeof(name), "%siid", prefix); 329 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 330 name, &tval)) { 331 ISP_FC_PC(isp, chan)->default_id = 109 - chan; 332 } else { 333 ISP_FC_PC(isp, chan)->default_id = tval - chan; 334 isp->isp_confopts |= ISP_CFG_OWNLOOPID; 335 } 336 337 tval = -1; 338 snprintf(name, sizeof(name), "%srole", prefix); 339 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 340 name, &tval) == 0) { 341 switch (tval) { 342 case ISP_ROLE_NONE: 343 case ISP_ROLE_INITIATOR: 344 case ISP_ROLE_TARGET: 345 case ISP_ROLE_BOTH: 346 device_printf(dev, "Chan %d setting role to 0x%x\n", chan, tval); 347 break; 348 default: 349 tval = -1; 350 break; 351 } 352 } 353 if (tval == -1) { 354 tval = ISP_DEFAULT_ROLES; 355 } 356 ISP_FC_PC(isp, chan)->def_role = tval; 357 358 tval = 0; 359 snprintf(name, sizeof(name), "%sfullduplex", prefix); 360 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 361 name, &tval) == 0 && tval != 0) { 362 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 363 } 364 sptr = NULL; 365 snprintf(name, sizeof(name), "%stopology", prefix); 366 if (resource_string_value(device_get_name(dev), device_get_unit(dev), 367 name, (const char **) &sptr) == 0 && sptr != NULL) { 368 if (strcmp(sptr, "lport") == 0) { 369 isp->isp_confopts |= ISP_CFG_LPORT; 370 } else if (strcmp(sptr, "nport") == 0) { 371 isp->isp_confopts |= ISP_CFG_NPORT; 372 } else if (strcmp(sptr, "lport-only") == 0) { 373 isp->isp_confopts |= ISP_CFG_LPORT_ONLY; 374 } else if (strcmp(sptr, "nport-only") == 0) { 375 isp->isp_confopts |= ISP_CFG_NPORT_ONLY; 376 } 377 } 378 379 #ifdef ISP_FCTAPE_OFF 380 isp->isp_confopts |= ISP_CFG_NOFCTAPE; 381 #else 382 isp->isp_confopts |= ISP_CFG_FCTAPE; 383 #endif 384 385 tval = 0; 386 snprintf(name, sizeof(name), "%snofctape", prefix); 387 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 388 name, &tval); 389 if (tval) { 390 isp->isp_confopts &= ~ISP_CFG_FCTAPE; 391 isp->isp_confopts |= ISP_CFG_NOFCTAPE; 392 } 393 394 tval = 0; 395 snprintf(name, sizeof(name), "%sfctape", prefix); 396 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 397 name, &tval); 398 if (tval) { 399 isp->isp_confopts &= ~ISP_CFG_NOFCTAPE; 400 isp->isp_confopts |= ISP_CFG_FCTAPE; 401 } 402 403 404 /* 405 * Because the resource_*_value functions can neither return 406 * 64 bit integer values, nor can they be directly coerced 407 * to interpret the right hand side of the assignment as 408 * you want them to interpret it, we have to force WWN 409 * hint replacement to specify WWN strings with a leading 410 * 'w' (e..g w50000000aaaa0001). Sigh. 411 */ 412 sptr = NULL; 413 snprintf(name, sizeof(name), "%sportwwn", prefix); 414 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 415 name, (const char **) &sptr); 416 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { 417 char *eptr = NULL; 418 ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16); 419 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwpn == -1) { 420 device_printf(dev, "mangled portwwn hint '%s'\n", sptr); 421 ISP_FC_PC(isp, chan)->def_wwpn = 0; 422 } 423 } 424 425 sptr = NULL; 426 snprintf(name, sizeof(name), "%snodewwn", prefix); 427 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 428 name, (const char **) &sptr); 429 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { 430 char *eptr = NULL; 431 ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16); 432 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwnn == 0) { 433 device_printf(dev, "mangled nodewwn hint '%s'\n", sptr); 434 ISP_FC_PC(isp, chan)->def_wwnn = 0; 435 } 436 } 437 438 tval = -1; 439 snprintf(name, sizeof(name), "%sloop_down_limit", prefix); 440 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 441 name, &tval); 442 if (tval >= 0 && tval < 0xffff) { 443 ISP_FC_PC(isp, chan)->loop_down_limit = tval; 444 } else { 445 ISP_FC_PC(isp, chan)->loop_down_limit = isp_loop_down_limit; 446 } 447 448 tval = -1; 449 snprintf(name, sizeof(name), "%sgone_device_time", prefix); 450 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 451 name, &tval); 452 if (tval >= 0 && tval < 0xffff) { 453 ISP_FC_PC(isp, chan)->gone_device_time = tval; 454 } else { 455 ISP_FC_PC(isp, chan)->gone_device_time = isp_gone_device_time; 456 } 457 } 458 459 static int 460 isp_pci_attach(device_t dev) 461 { 462 struct isp_pcisoftc *pcs = device_get_softc(dev); 463 ispsoftc_t *isp = &pcs->pci_isp; 464 int i; 465 uint32_t data, cmd, linesz; 466 size_t psize, xsize; 467 468 isp->isp_dev = dev; 469 isp->isp_nchan = 1; 470 mtx_init(&isp->isp_lock, "isp", NULL, MTX_DEF); 471 472 /* 473 * Get Generic Options 474 */ 475 isp_nvports = 0; 476 isp_get_generic_options(dev, isp); 477 478 linesz = PCI_DFLT_LNSZ; 479 pcs->regs = pcs->regs2 = NULL; 480 pcs->rgd = pcs->rtp = 0; 481 482 isp->isp_nchan += isp_nvports; 483 switch (pci_get_devid(dev)) { 484 case PCI_QLOGIC_ISP2422: 485 case PCI_QLOGIC_ISP2432: 486 isp->isp_did = 0x2400; 487 isp->isp_mdvec = &mdvec_2400; 488 isp->isp_type = ISP_HA_FC_2400; 489 break; 490 case PCI_QLOGIC_ISP2532: 491 isp->isp_did = 0x2500; 492 isp->isp_mdvec = &mdvec_2500; 493 isp->isp_type = ISP_HA_FC_2500; 494 break; 495 case PCI_QLOGIC_ISP5432: 496 isp->isp_did = 0x2500; 497 isp->isp_mdvec = &mdvec_2500; 498 isp->isp_type = ISP_HA_FC_2500; 499 break; 500 case PCI_QLOGIC_ISP2031: 501 case PCI_QLOGIC_ISP8031: 502 isp->isp_did = 0x2600; 503 isp->isp_mdvec = &mdvec_2600; 504 isp->isp_type = ISP_HA_FC_2600; 505 break; 506 case PCI_QLOGIC_ISP2684: 507 case PCI_QLOGIC_ISP2692: 508 case PCI_QLOGIC_ISP2714: 509 case PCI_QLOGIC_ISP2722: 510 isp->isp_did = 0x2700; 511 isp->isp_mdvec = &mdvec_2700; 512 isp->isp_type = ISP_HA_FC_2700; 513 break; 514 case PCI_QLOGIC_ISP2812: 515 case PCI_QLOGIC_ISP2814: 516 isp->isp_did = 0x2800; 517 isp->isp_mdvec = &mdvec_2800; 518 isp->isp_type = ISP_HA_FC_2800; 519 break; 520 default: 521 device_printf(dev, "unknown device type\n"); 522 goto bad; 523 break; 524 } 525 isp->isp_revision = pci_get_revid(dev); 526 527 if (IS_26XX(isp)) { 528 pcs->rtp = SYS_RES_MEMORY; 529 pcs->rgd = PCIR_BAR(0); 530 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, 531 RF_ACTIVE); 532 pcs->rtp1 = SYS_RES_MEMORY; 533 pcs->rgd1 = PCIR_BAR(2); 534 pcs->regs1 = bus_alloc_resource_any(dev, pcs->rtp1, &pcs->rgd1, 535 RF_ACTIVE); 536 pcs->rtp2 = SYS_RES_MEMORY; 537 pcs->rgd2 = PCIR_BAR(4); 538 pcs->regs2 = bus_alloc_resource_any(dev, pcs->rtp2, &pcs->rgd2, 539 RF_ACTIVE); 540 } else { 541 pcs->rtp = SYS_RES_MEMORY; 542 pcs->rgd = PCIR_BAR(1); 543 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, 544 RF_ACTIVE); 545 if (pcs->regs == NULL) { 546 pcs->rtp = SYS_RES_IOPORT; 547 pcs->rgd = PCIR_BAR(0); 548 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, 549 &pcs->rgd, RF_ACTIVE); 550 } 551 } 552 if (pcs->regs == NULL) { 553 device_printf(dev, "Unable to map any ports\n"); 554 goto bad; 555 } 556 if (bootverbose) { 557 device_printf(dev, "Using %s space register mapping\n", 558 (pcs->rtp == SYS_RES_IOPORT)? "I/O" : "Memory"); 559 } 560 isp->isp_regs = pcs->regs; 561 isp->isp_regs2 = pcs->regs2; 562 563 psize = sizeof(fcparam) * isp->isp_nchan; 564 xsize = sizeof(struct isp_fc) * isp->isp_nchan; 565 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); 566 if (isp->isp_param == NULL) { 567 device_printf(dev, "cannot allocate parameter data\n"); 568 goto bad; 569 } 570 isp->isp_osinfo.fc = malloc(xsize, M_DEVBUF, M_NOWAIT | M_ZERO); 571 if (isp->isp_osinfo.fc == NULL) { 572 device_printf(dev, "cannot allocate parameter data\n"); 573 goto bad; 574 } 575 576 /* 577 * Now that we know who we are (roughly) get/set specific options 578 */ 579 for (i = 0; i < isp->isp_nchan; i++) { 580 isp_get_specific_options(dev, i, isp); 581 } 582 583 /* 584 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. 585 */ 586 cmd = pci_read_config(dev, PCIR_COMMAND, 2); 587 cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; 588 cmd &= ~PCIM_CMD_INTX_DISABLE; 589 pci_write_config(dev, PCIR_COMMAND, cmd, 2); 590 591 /* 592 * Make sure the Cache Line Size register is set sensibly. 593 */ 594 data = pci_read_config(dev, PCIR_CACHELNSZ, 1); 595 if (data == 0 || (linesz != PCI_DFLT_LNSZ && data != linesz)) { 596 isp_prt(isp, ISP_LOGDEBUG0, "set PCI line size to %d from %d", linesz, data); 597 data = linesz; 598 pci_write_config(dev, PCIR_CACHELNSZ, data, 1); 599 } 600 601 /* 602 * Make sure the Latency Timer is sane. 603 */ 604 data = pci_read_config(dev, PCIR_LATTIMER, 1); 605 if (data < PCI_DFLT_LTNCY) { 606 data = PCI_DFLT_LTNCY; 607 isp_prt(isp, ISP_LOGDEBUG0, "set PCI latency to %d", data); 608 pci_write_config(dev, PCIR_LATTIMER, data, 1); 609 } 610 611 /* 612 * Make sure we've disabled the ROM. 613 */ 614 data = pci_read_config(dev, PCIR_ROMADDR, 4); 615 data &= ~1; 616 pci_write_config(dev, PCIR_ROMADDR, data, 4); 617 618 /* 619 * Last minute checks... 620 */ 621 isp->isp_port = pci_get_function(dev); 622 623 /* 624 * Make sure we're in reset state. 625 */ 626 ISP_LOCK(isp); 627 if (isp_reinit(isp, 1) != 0) { 628 ISP_UNLOCK(isp); 629 goto bad; 630 } 631 ISP_UNLOCK(isp); 632 if (isp_attach(isp)) { 633 ISP_LOCK(isp); 634 isp_shutdown(isp); 635 ISP_UNLOCK(isp); 636 goto bad; 637 } 638 return (0); 639 640 bad: 641 for (i = 0; i < isp->isp_nirq; i++) { 642 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); 643 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, 644 pcs->irq[0].irq); 645 } 646 if (pcs->msicount) { 647 pci_release_msi(dev); 648 } 649 if (pcs->regs) 650 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); 651 if (pcs->regs1) 652 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); 653 if (pcs->regs2) 654 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); 655 if (pcs->pci_isp.isp_param) { 656 free(pcs->pci_isp.isp_param, M_DEVBUF); 657 pcs->pci_isp.isp_param = NULL; 658 } 659 if (pcs->pci_isp.isp_osinfo.fc) { 660 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); 661 pcs->pci_isp.isp_osinfo.fc = NULL; 662 } 663 mtx_destroy(&isp->isp_lock); 664 return (ENXIO); 665 } 666 667 static int 668 isp_pci_detach(device_t dev) 669 { 670 struct isp_pcisoftc *pcs = device_get_softc(dev); 671 ispsoftc_t *isp = &pcs->pci_isp; 672 int i, status; 673 674 status = isp_detach(isp); 675 if (status) 676 return (status); 677 ISP_LOCK(isp); 678 isp_shutdown(isp); 679 ISP_UNLOCK(isp); 680 for (i = 0; i < isp->isp_nirq; i++) { 681 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); 682 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, 683 pcs->irq[i].irq); 684 } 685 if (pcs->msicount) 686 pci_release_msi(dev); 687 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); 688 if (pcs->regs1) 689 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); 690 if (pcs->regs2) 691 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); 692 isp_pci_mbxdmafree(isp); 693 if (pcs->pci_isp.isp_param) { 694 free(pcs->pci_isp.isp_param, M_DEVBUF); 695 pcs->pci_isp.isp_param = NULL; 696 } 697 if (pcs->pci_isp.isp_osinfo.fc) { 698 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); 699 pcs->pci_isp.isp_osinfo.fc = NULL; 700 } 701 mtx_destroy(&isp->isp_lock); 702 return (0); 703 } 704 705 #define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off)) 706 #define BXW2(isp, off, v) bus_write_2((isp)->isp_regs, (off), (v)) 707 #define BXR4(isp, off) bus_read_4((isp)->isp_regs, (off)) 708 #define BXW4(isp, off, v) bus_write_4((isp)->isp_regs, (off), (v)) 709 #define B2R4(isp, off) bus_read_4((isp)->isp_regs2, (off)) 710 #define B2W4(isp, off, v) bus_write_4((isp)->isp_regs2, (off), (v)) 711 712 static void 713 isp_pci_run_isr_2400(ispsoftc_t *isp) 714 { 715 uint32_t r2hisr; 716 uint16_t isr, info; 717 718 r2hisr = BXR4(isp, BIU2400_R2HSTS); 719 isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr); 720 if ((r2hisr & BIU_R2HST_INTR) == 0) 721 return; 722 isr = r2hisr & BIU_R2HST_ISTAT_MASK; 723 info = (r2hisr >> 16); 724 switch (isr) { 725 case ISPR2HST_ROM_MBX_OK: 726 case ISPR2HST_ROM_MBX_FAIL: 727 case ISPR2HST_MBX_OK: 728 case ISPR2HST_MBX_FAIL: 729 isp_intr_mbox(isp, info); 730 break; 731 case ISPR2HST_ASYNC_EVENT: 732 isp_intr_async(isp, info); 733 break; 734 case ISPR2HST_RSPQ_UPDATE: 735 isp_intr_respq(isp); 736 break; 737 case ISPR2HST_RSPQ_UPDATE2: 738 #ifdef ISP_TARGET_MODE 739 case ISPR2HST_ATIO_RSPQ_UPDATE: 740 #endif 741 isp_intr_respq(isp); 742 /* FALLTHROUGH */ 743 #ifdef ISP_TARGET_MODE 744 case ISPR2HST_ATIO_UPDATE: 745 case ISPR2HST_ATIO_UPDATE2: 746 isp_intr_atioq(isp); 747 #endif 748 break; 749 default: 750 isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr); 751 } 752 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 753 } 754 755 static uint32_t 756 isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff) 757 { 758 int block = regoff & _BLK_REG_MASK; 759 760 switch (block) { 761 case BIU_BLOCK: 762 return (BXR4(isp, regoff)); 763 case MBOX_BLOCK: 764 return (BXR2(isp, regoff)); 765 } 766 isp_prt(isp, ISP_LOGERR, "unknown block read at 0x%x", regoff); 767 return (0xffffffff); 768 } 769 770 static void 771 isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val) 772 { 773 int block = regoff & _BLK_REG_MASK; 774 775 switch (block) { 776 case BIU_BLOCK: 777 BXW4(isp, regoff, val); 778 #ifdef MEMORYBARRIERW 779 if (regoff == BIU2400_REQINP || 780 regoff == BIU2400_RSPOUTP || 781 regoff == BIU2400_PRI_REQINP || 782 regoff == BIU2400_ATIO_RSPOUTP) 783 MEMORYBARRIERW(isp, SYNC_REG, regoff, 4, -1) 784 else 785 #endif 786 MEMORYBARRIER(isp, SYNC_REG, regoff, 4, -1); 787 return; 788 case MBOX_BLOCK: 789 BXW2(isp, regoff, val); 790 MEMORYBARRIER(isp, SYNC_REG, regoff, 2, -1); 791 return; 792 } 793 isp_prt(isp, ISP_LOGERR, "unknown block write at 0x%x", regoff); 794 } 795 796 static uint32_t 797 isp_pci_rd_reg_2600(ispsoftc_t *isp, int regoff) 798 { 799 uint32_t rv; 800 801 switch (regoff) { 802 case BIU2400_PRI_REQINP: 803 case BIU2400_PRI_REQOUTP: 804 isp_prt(isp, ISP_LOGERR, "unknown register read at 0x%x", 805 regoff); 806 rv = 0xffffffff; 807 break; 808 case BIU2400_REQINP: 809 rv = B2R4(isp, 0x00); 810 break; 811 case BIU2400_REQOUTP: 812 rv = B2R4(isp, 0x04); 813 break; 814 case BIU2400_RSPINP: 815 rv = B2R4(isp, 0x08); 816 break; 817 case BIU2400_RSPOUTP: 818 rv = B2R4(isp, 0x0c); 819 break; 820 case BIU2400_ATIO_RSPINP: 821 rv = B2R4(isp, 0x10); 822 break; 823 case BIU2400_ATIO_RSPOUTP: 824 rv = B2R4(isp, 0x14); 825 break; 826 default: 827 rv = isp_pci_rd_reg_2400(isp, regoff); 828 break; 829 } 830 return (rv); 831 } 832 833 static void 834 isp_pci_wr_reg_2600(ispsoftc_t *isp, int regoff, uint32_t val) 835 { 836 int off; 837 838 switch (regoff) { 839 case BIU2400_PRI_REQINP: 840 case BIU2400_PRI_REQOUTP: 841 isp_prt(isp, ISP_LOGERR, "unknown register write at 0x%x", 842 regoff); 843 return; 844 case BIU2400_REQINP: 845 off = 0x00; 846 break; 847 case BIU2400_REQOUTP: 848 off = 0x04; 849 break; 850 case BIU2400_RSPINP: 851 off = 0x08; 852 break; 853 case BIU2400_RSPOUTP: 854 off = 0x0c; 855 break; 856 case BIU2400_ATIO_RSPINP: 857 off = 0x10; 858 break; 859 case BIU2400_ATIO_RSPOUTP: 860 off = 0x14; 861 break; 862 default: 863 isp_pci_wr_reg_2400(isp, regoff, val); 864 return; 865 } 866 B2W4(isp, off, val); 867 } 868 869 870 struct imush { 871 bus_addr_t maddr; 872 int error; 873 }; 874 875 static void 876 imc(void *arg, bus_dma_segment_t *segs, int nseg, int error) 877 { 878 struct imush *imushp = (struct imush *) arg; 879 880 if (!(imushp->error = error)) 881 imushp->maddr = segs[0].ds_addr; 882 } 883 884 static int 885 isp_pci_mbxdma(ispsoftc_t *isp) 886 { 887 bus_dma_tag_t ptag; 888 caddr_t base; 889 uint32_t len; 890 int i, error, cmap; 891 bus_size_t slim; /* segment size */ 892 struct imush im; 893 #ifdef ISP_TARGET_MODE 894 isp_ecmd_t *ecmd; 895 #endif 896 897 /* Already been here? If so, leave... */ 898 if (isp->isp_xflist != NULL) 899 return (0); 900 if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0) 901 return (0); 902 ISP_UNLOCK(isp); 903 904 ptag = bus_get_dma_tag(isp->isp_osinfo.dev); 905 if (sizeof (bus_size_t) > 4) 906 slim = (bus_size_t) (1ULL << 32); 907 else 908 slim = (bus_size_t) (1UL << 31); 909 910 if (isp->isp_rquest != NULL) 911 goto gotmaxcmds; 912 913 /* 914 * Allocate and map the request queue. 915 */ 916 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 917 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 918 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 919 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { 920 isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); 921 goto bad; 922 } 923 if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base, 924 BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) { 925 isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory"); 926 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 927 goto bad; 928 } 929 isp->isp_rquest = base; 930 im.error = 0; 931 if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap, 932 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 933 isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error); 934 goto bad; 935 } 936 isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx", 937 (uintmax_t)im.maddr, (uintmax_t)len); 938 isp->isp_rquest_dma = im.maddr; 939 940 #ifdef ISP_TARGET_MODE 941 /* 942 * Allocate region for external DMA addressable command/status structures. 943 */ 944 len = N_XCMDS * XCMD_SIZE; 945 if (bus_dma_tag_create(ptag, XCMD_SIZE, slim, 946 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 947 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { 948 isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); 949 goto bad; 950 } 951 if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, 952 BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { 953 isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); 954 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); 955 goto bad; 956 } 957 isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; 958 im.error = 0; 959 if (bus_dmamap_load(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, 960 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 961 isp_prt(isp, ISP_LOGERR, "error loading ECMD DMA map %d", im.error); 962 goto bad; 963 } 964 isp_prt(isp, ISP_LOGDEBUG0, "ecmd area @ 0x%jx/0x%jx", 965 (uintmax_t)im.maddr, (uintmax_t)len); 966 967 isp->isp_osinfo.ecmd_dma = im.maddr; 968 isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)base; 969 for (ecmd = isp->isp_osinfo.ecmd_free; 970 ecmd < &isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) { 971 if (ecmd == &isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) 972 ecmd->next = NULL; 973 else 974 ecmd->next = ecmd + 1; 975 } 976 #endif 977 978 /* 979 * Allocate and map the result queue. 980 */ 981 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); 982 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 983 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 984 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.respdmat)) { 985 isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); 986 goto bad; 987 } 988 if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base, 989 BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) { 990 isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory"); 991 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 992 goto bad; 993 } 994 isp->isp_result = base; 995 im.error = 0; 996 if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap, 997 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 998 isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error); 999 goto bad; 1000 } 1001 isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx", 1002 (uintmax_t)im.maddr, (uintmax_t)len); 1003 isp->isp_result_dma = im.maddr; 1004 1005 #ifdef ISP_TARGET_MODE 1006 /* 1007 * Allocate and map ATIO queue. 1008 */ 1009 len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp)); 1010 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 1011 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1012 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) { 1013 isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag"); 1014 goto bad; 1015 } 1016 if (bus_dmamem_alloc(isp->isp_osinfo.atiodmat, (void **)&base, 1017 BUS_DMA_COHERENT, &isp->isp_osinfo.atiomap) != 0) { 1018 isp_prt(isp, ISP_LOGERR, "cannot allocate ATIO DMA memory"); 1019 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); 1020 goto bad; 1021 } 1022 isp->isp_atioq = base; 1023 im.error = 0; 1024 if (bus_dmamap_load(isp->isp_osinfo.atiodmat, isp->isp_osinfo.atiomap, 1025 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 1026 isp_prt(isp, ISP_LOGERR, "error loading ATIO DMA map %d", im.error); 1027 goto bad; 1028 } 1029 isp_prt(isp, ISP_LOGDEBUG0, "ATIO area @ 0x%jx/0x%jx", 1030 (uintmax_t)im.maddr, (uintmax_t)len); 1031 isp->isp_atioq_dma = im.maddr; 1032 #endif 1033 1034 if (bus_dma_tag_create(ptag, 64, slim, 1035 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1036 2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, NULL, NULL, 1037 &isp->isp_osinfo.iocbdmat)) { 1038 goto bad; 1039 } 1040 if (bus_dmamem_alloc(isp->isp_osinfo.iocbdmat, 1041 (void **)&base, BUS_DMA_COHERENT, &isp->isp_osinfo.iocbmap) != 0) 1042 goto bad; 1043 isp->isp_iocb = base; 1044 im.error = 0; 1045 if (bus_dmamap_load(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, 1046 base, 2*QENTRY_LEN, imc, &im, BUS_DMA_NOWAIT) || im.error) 1047 goto bad; 1048 isp->isp_iocb_dma = im.maddr; 1049 1050 if (bus_dma_tag_create(ptag, 64, slim, 1051 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1052 ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, NULL, NULL, 1053 &isp->isp_osinfo.scdmat)) 1054 goto bad; 1055 for (cmap = 0; cmap < isp->isp_nchan; cmap++) { 1056 struct isp_fc *fc = ISP_FC_PC(isp, cmap); 1057 if (bus_dmamem_alloc(isp->isp_osinfo.scdmat, 1058 (void **)&base, BUS_DMA_COHERENT, &fc->scmap) != 0) 1059 goto bad; 1060 FCPARAM(isp, cmap)->isp_scratch = base; 1061 im.error = 0; 1062 if (bus_dmamap_load(isp->isp_osinfo.scdmat, fc->scmap, 1063 base, ISP_FC_SCRLEN, imc, &im, BUS_DMA_NOWAIT) || 1064 im.error) { 1065 bus_dmamem_free(isp->isp_osinfo.scdmat, 1066 base, fc->scmap); 1067 FCPARAM(isp, cmap)->isp_scratch = NULL; 1068 goto bad; 1069 } 1070 FCPARAM(isp, cmap)->isp_scdma = im.maddr; 1071 for (i = 0; i < INITIAL_NEXUS_COUNT; i++) { 1072 struct isp_nexus *n = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_NOWAIT | M_ZERO); 1073 if (n == NULL) { 1074 while (fc->nexus_free_list) { 1075 n = fc->nexus_free_list; 1076 fc->nexus_free_list = n->next; 1077 free(n, M_DEVBUF); 1078 } 1079 goto bad; 1080 } 1081 n->next = fc->nexus_free_list; 1082 fc->nexus_free_list = n; 1083 } 1084 } 1085 1086 if (isp->isp_maxcmds == 0) { 1087 ISP_LOCK(isp); 1088 return (0); 1089 } 1090 1091 gotmaxcmds: 1092 if (bus_dma_tag_create(ptag, 1, slim, 1093 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1094 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, ISP_NSEG64_MAX, 1095 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, 0, 1096 busdma_lock_mutex, &isp->isp_lock, &isp->isp_osinfo.dmat)) 1097 goto bad; 1098 len = isp->isp_maxcmds * sizeof (struct isp_pcmd); 1099 isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) 1100 malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1101 for (i = 0; i < isp->isp_maxcmds; i++) { 1102 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; 1103 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); 1104 if (error) { 1105 isp_prt(isp, ISP_LOGERR, "error %d creating per-cmd DMA maps", error); 1106 while (--i >= 0) { 1107 bus_dmamap_destroy(isp->isp_osinfo.dmat, 1108 isp->isp_osinfo.pcmd_pool[i].dmap); 1109 } 1110 goto bad; 1111 } 1112 callout_init_mtx(&pcmd->wdog, &isp->isp_lock, 0); 1113 if (i == isp->isp_maxcmds-1) 1114 pcmd->next = NULL; 1115 else 1116 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; 1117 } 1118 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; 1119 1120 len = sizeof(isp_hdl_t) * ISP_HANDLE_NUM(isp); 1121 isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1122 for (len = 0; len < ISP_HANDLE_NUM(isp) - 1; len++) 1123 isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; 1124 isp->isp_xffree = isp->isp_xflist; 1125 1126 ISP_LOCK(isp); 1127 return (0); 1128 1129 bad: 1130 isp_pci_mbxdmafree(isp); 1131 ISP_LOCK(isp); 1132 return (1); 1133 } 1134 1135 static void 1136 isp_pci_mbxdmafree(ispsoftc_t *isp) 1137 { 1138 int i; 1139 1140 if (isp->isp_xflist != NULL) { 1141 free(isp->isp_xflist, M_DEVBUF); 1142 isp->isp_xflist = NULL; 1143 } 1144 if (isp->isp_osinfo.pcmd_pool != NULL) { 1145 for (i = 0; i < isp->isp_maxcmds; i++) { 1146 bus_dmamap_destroy(isp->isp_osinfo.dmat, 1147 isp->isp_osinfo.pcmd_pool[i].dmap); 1148 } 1149 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1150 isp->isp_osinfo.pcmd_pool = NULL; 1151 } 1152 if (isp->isp_osinfo.dmat) { 1153 bus_dma_tag_destroy(isp->isp_osinfo.dmat); 1154 isp->isp_osinfo.dmat = NULL; 1155 } 1156 for (i = 0; i < isp->isp_nchan; i++) { 1157 struct isp_fc *fc = ISP_FC_PC(isp, i); 1158 if (FCPARAM(isp, i)->isp_scdma != 0) { 1159 bus_dmamap_unload(isp->isp_osinfo.scdmat, 1160 fc->scmap); 1161 FCPARAM(isp, i)->isp_scdma = 0; 1162 } 1163 if (FCPARAM(isp, i)->isp_scratch != NULL) { 1164 bus_dmamem_free(isp->isp_osinfo.scdmat, 1165 FCPARAM(isp, i)->isp_scratch, fc->scmap); 1166 FCPARAM(isp, i)->isp_scratch = NULL; 1167 } 1168 while (fc->nexus_free_list) { 1169 struct isp_nexus *n = fc->nexus_free_list; 1170 fc->nexus_free_list = n->next; 1171 free(n, M_DEVBUF); 1172 } 1173 } 1174 if (isp->isp_osinfo.scdmat) { 1175 bus_dma_tag_destroy(isp->isp_osinfo.scdmat); 1176 isp->isp_osinfo.scdmat = NULL; 1177 } 1178 if (isp->isp_iocb_dma != 0) { 1179 bus_dmamap_unload(isp->isp_osinfo.iocbdmat, 1180 isp->isp_osinfo.iocbmap); 1181 isp->isp_iocb_dma = 0; 1182 } 1183 if (isp->isp_iocb != NULL) { 1184 bus_dmamem_free(isp->isp_osinfo.iocbdmat, 1185 isp->isp_iocb, isp->isp_osinfo.iocbmap); 1186 bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat); 1187 } 1188 #ifdef ISP_TARGET_MODE 1189 if (isp->isp_atioq_dma != 0) { 1190 bus_dmamap_unload(isp->isp_osinfo.atiodmat, 1191 isp->isp_osinfo.atiomap); 1192 isp->isp_atioq_dma = 0; 1193 } 1194 if (isp->isp_atioq != NULL) { 1195 bus_dmamem_free(isp->isp_osinfo.atiodmat, isp->isp_atioq, 1196 isp->isp_osinfo.atiomap); 1197 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); 1198 isp->isp_atioq = NULL; 1199 } 1200 #endif 1201 if (isp->isp_result_dma != 0) { 1202 bus_dmamap_unload(isp->isp_osinfo.respdmat, 1203 isp->isp_osinfo.respmap); 1204 isp->isp_result_dma = 0; 1205 } 1206 if (isp->isp_result != NULL) { 1207 bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result, 1208 isp->isp_osinfo.respmap); 1209 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 1210 isp->isp_result = NULL; 1211 } 1212 #ifdef ISP_TARGET_MODE 1213 if (isp->isp_osinfo.ecmd_dma != 0) { 1214 bus_dmamap_unload(isp->isp_osinfo.ecmd_dmat, 1215 isp->isp_osinfo.ecmd_map); 1216 isp->isp_osinfo.ecmd_dma = 0; 1217 } 1218 if (isp->isp_osinfo.ecmd_base != NULL) { 1219 bus_dmamem_free(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_base, 1220 isp->isp_osinfo.ecmd_map); 1221 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); 1222 isp->isp_osinfo.ecmd_base = NULL; 1223 } 1224 #endif 1225 if (isp->isp_rquest_dma != 0) { 1226 bus_dmamap_unload(isp->isp_osinfo.reqdmat, 1227 isp->isp_osinfo.reqmap); 1228 isp->isp_rquest_dma = 0; 1229 } 1230 if (isp->isp_rquest != NULL) { 1231 bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest, 1232 isp->isp_osinfo.reqmap); 1233 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 1234 isp->isp_rquest = NULL; 1235 } 1236 } 1237 1238 static int 1239 isp_pci_irqsetup(ispsoftc_t *isp) 1240 { 1241 device_t dev = isp->isp_osinfo.dev; 1242 struct isp_pcisoftc *pcs = device_get_softc(dev); 1243 driver_intr_t *f; 1244 int i, max_irq; 1245 1246 /* Allocate IRQs only once. */ 1247 if (isp->isp_nirq > 0) 1248 return (0); 1249 1250 ISP_UNLOCK(isp); 1251 if (ISP_CAP_MSIX(isp)) { 1252 max_irq = IS_26XX(isp) ? 3 : (IS_25XX(isp) ? 2 : 0); 1253 resource_int_value(device_get_name(dev), 1254 device_get_unit(dev), "msix", &max_irq); 1255 max_irq = imin(ISP_MAX_IRQS, max_irq); 1256 pcs->msicount = imin(pci_msix_count(dev), max_irq); 1257 if (pcs->msicount > 0 && 1258 pci_alloc_msix(dev, &pcs->msicount) != 0) 1259 pcs->msicount = 0; 1260 } 1261 if (pcs->msicount == 0) { 1262 max_irq = 1; 1263 resource_int_value(device_get_name(dev), 1264 device_get_unit(dev), "msi", &max_irq); 1265 max_irq = imin(1, max_irq); 1266 pcs->msicount = imin(pci_msi_count(dev), max_irq); 1267 if (pcs->msicount > 0 && 1268 pci_alloc_msi(dev, &pcs->msicount) != 0) 1269 pcs->msicount = 0; 1270 } 1271 for (i = 0; i < MAX(1, pcs->msicount); i++) { 1272 pcs->irq[i].iqd = i + (pcs->msicount > 0); 1273 pcs->irq[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 1274 &pcs->irq[i].iqd, RF_ACTIVE | RF_SHAREABLE); 1275 if (pcs->irq[i].irq == NULL) { 1276 device_printf(dev, "could not allocate interrupt\n"); 1277 break; 1278 } 1279 if (i == 0) 1280 f = isp_platform_intr; 1281 else if (i == 1) 1282 f = isp_platform_intr_resp; 1283 else 1284 f = isp_platform_intr_atio; 1285 if (bus_setup_intr(dev, pcs->irq[i].irq, ISP_IFLAGS, NULL, 1286 f, isp, &pcs->irq[i].ih)) { 1287 device_printf(dev, "could not setup interrupt\n"); 1288 (void) bus_release_resource(dev, SYS_RES_IRQ, 1289 pcs->irq[i].iqd, pcs->irq[i].irq); 1290 break; 1291 } 1292 if (pcs->msicount > 1) { 1293 bus_describe_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih, 1294 "%d", i); 1295 } 1296 isp->isp_nirq = i + 1; 1297 } 1298 ISP_LOCK(isp); 1299 1300 return (isp->isp_nirq == 0); 1301 } 1302