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), "fwload_force", &tval) == 0 && tval != 0) { 295 isp->isp_confopts |= ISP_CFG_FWLOAD_FORCE; 296 } 297 if ((isp->isp_confopts & (ISP_CFG_NORELOAD|ISP_CFG_FWLOAD_FORCE)) == 298 (ISP_CFG_NORELOAD|ISP_CFG_FWLOAD_FORCE)) { 299 device_printf(dev, "WARNING: both fwload_disable and " 300 "fwload_force set, ispfw(4) loading disabled\n"); 301 } 302 tval = 0; 303 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "ignore_nvram", &tval) == 0 && tval != 0) { 304 isp->isp_confopts |= ISP_CFG_NONVRAM; 305 } 306 tval = 0; 307 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "debug", &tval); 308 if (tval) { 309 isp->isp_dblev = tval; 310 } else { 311 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 312 } 313 if (bootverbose) { 314 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 315 } 316 tval = -1; 317 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "vports", &tval); 318 if (tval > 0 && tval <= 254) { 319 isp_nvports = tval; 320 } 321 tval = 7; 322 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "quickboot_time", &tval); 323 isp_quickboot_time = tval; 324 } 325 326 static void 327 isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp) 328 { 329 const char *sptr; 330 int tval = 0; 331 char prefix[12], name[16]; 332 333 if (chan == 0) 334 prefix[0] = 0; 335 else 336 snprintf(prefix, sizeof(prefix), "chan%d.", chan); 337 snprintf(name, sizeof(name), "%siid", prefix); 338 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 339 name, &tval)) { 340 ISP_FC_PC(isp, chan)->default_id = 109 - chan; 341 } else { 342 ISP_FC_PC(isp, chan)->default_id = tval - chan; 343 isp->isp_confopts |= ISP_CFG_OWNLOOPID; 344 } 345 346 tval = -1; 347 snprintf(name, sizeof(name), "%srole", prefix); 348 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 349 name, &tval) == 0) { 350 switch (tval) { 351 case ISP_ROLE_NONE: 352 case ISP_ROLE_INITIATOR: 353 case ISP_ROLE_TARGET: 354 case ISP_ROLE_BOTH: 355 device_printf(dev, "Chan %d setting role to 0x%x\n", chan, tval); 356 break; 357 default: 358 tval = -1; 359 break; 360 } 361 } 362 if (tval == -1) { 363 tval = ISP_DEFAULT_ROLES; 364 } 365 ISP_FC_PC(isp, chan)->def_role = tval; 366 367 tval = 0; 368 snprintf(name, sizeof(name), "%sfullduplex", prefix); 369 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 370 name, &tval) == 0 && tval != 0) { 371 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 372 } 373 sptr = NULL; 374 snprintf(name, sizeof(name), "%stopology", prefix); 375 if (resource_string_value(device_get_name(dev), device_get_unit(dev), 376 name, (const char **) &sptr) == 0 && sptr != NULL) { 377 if (strcmp(sptr, "lport") == 0) { 378 isp->isp_confopts |= ISP_CFG_LPORT; 379 } else if (strcmp(sptr, "nport") == 0) { 380 isp->isp_confopts |= ISP_CFG_NPORT; 381 } else if (strcmp(sptr, "lport-only") == 0) { 382 isp->isp_confopts |= ISP_CFG_LPORT_ONLY; 383 } else if (strcmp(sptr, "nport-only") == 0) { 384 isp->isp_confopts |= ISP_CFG_NPORT_ONLY; 385 } 386 } 387 388 #ifdef ISP_FCTAPE_OFF 389 isp->isp_confopts |= ISP_CFG_NOFCTAPE; 390 #else 391 isp->isp_confopts |= ISP_CFG_FCTAPE; 392 #endif 393 394 tval = 0; 395 snprintf(name, sizeof(name), "%snofctape", 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_FCTAPE; 400 isp->isp_confopts |= ISP_CFG_NOFCTAPE; 401 } 402 403 tval = 0; 404 snprintf(name, sizeof(name), "%sfctape", prefix); 405 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 406 name, &tval); 407 if (tval) { 408 isp->isp_confopts &= ~ISP_CFG_NOFCTAPE; 409 isp->isp_confopts |= ISP_CFG_FCTAPE; 410 } 411 412 413 /* 414 * Because the resource_*_value functions can neither return 415 * 64 bit integer values, nor can they be directly coerced 416 * to interpret the right hand side of the assignment as 417 * you want them to interpret it, we have to force WWN 418 * hint replacement to specify WWN strings with a leading 419 * 'w' (e..g w50000000aaaa0001). Sigh. 420 */ 421 sptr = NULL; 422 snprintf(name, sizeof(name), "%sportwwn", prefix); 423 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 424 name, (const char **) &sptr); 425 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { 426 char *eptr = NULL; 427 ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16); 428 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwpn == -1) { 429 device_printf(dev, "mangled portwwn hint '%s'\n", sptr); 430 ISP_FC_PC(isp, chan)->def_wwpn = 0; 431 } 432 } 433 434 sptr = NULL; 435 snprintf(name, sizeof(name), "%snodewwn", prefix); 436 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 437 name, (const char **) &sptr); 438 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { 439 char *eptr = NULL; 440 ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16); 441 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwnn == 0) { 442 device_printf(dev, "mangled nodewwn hint '%s'\n", sptr); 443 ISP_FC_PC(isp, chan)->def_wwnn = 0; 444 } 445 } 446 447 tval = -1; 448 snprintf(name, sizeof(name), "%sloop_down_limit", prefix); 449 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 450 name, &tval); 451 if (tval >= 0 && tval < 0xffff) { 452 ISP_FC_PC(isp, chan)->loop_down_limit = tval; 453 } else { 454 ISP_FC_PC(isp, chan)->loop_down_limit = isp_loop_down_limit; 455 } 456 457 tval = -1; 458 snprintf(name, sizeof(name), "%sgone_device_time", prefix); 459 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 460 name, &tval); 461 if (tval >= 0 && tval < 0xffff) { 462 ISP_FC_PC(isp, chan)->gone_device_time = tval; 463 } else { 464 ISP_FC_PC(isp, chan)->gone_device_time = isp_gone_device_time; 465 } 466 } 467 468 static int 469 isp_pci_attach(device_t dev) 470 { 471 struct isp_pcisoftc *pcs = device_get_softc(dev); 472 ispsoftc_t *isp = &pcs->pci_isp; 473 int i; 474 uint32_t data, cmd, linesz; 475 size_t psize, xsize; 476 477 isp->isp_dev = dev; 478 isp->isp_nchan = 1; 479 mtx_init(&isp->isp_lock, "isp", NULL, MTX_DEF); 480 481 /* 482 * Get Generic Options 483 */ 484 isp_nvports = 0; 485 isp_get_generic_options(dev, isp); 486 487 linesz = PCI_DFLT_LNSZ; 488 pcs->regs = pcs->regs2 = NULL; 489 pcs->rgd = pcs->rtp = 0; 490 491 isp->isp_nchan += isp_nvports; 492 switch (pci_get_devid(dev)) { 493 case PCI_QLOGIC_ISP2422: 494 case PCI_QLOGIC_ISP2432: 495 isp->isp_did = 0x2400; 496 isp->isp_mdvec = &mdvec_2400; 497 isp->isp_type = ISP_HA_FC_2400; 498 break; 499 case PCI_QLOGIC_ISP2532: 500 isp->isp_did = 0x2500; 501 isp->isp_mdvec = &mdvec_2500; 502 isp->isp_type = ISP_HA_FC_2500; 503 break; 504 case PCI_QLOGIC_ISP5432: 505 isp->isp_did = 0x2500; 506 isp->isp_mdvec = &mdvec_2500; 507 isp->isp_type = ISP_HA_FC_2500; 508 break; 509 case PCI_QLOGIC_ISP2031: 510 case PCI_QLOGIC_ISP8031: 511 isp->isp_did = 0x2600; 512 isp->isp_mdvec = &mdvec_2600; 513 isp->isp_type = ISP_HA_FC_2600; 514 break; 515 case PCI_QLOGIC_ISP2684: 516 case PCI_QLOGIC_ISP2692: 517 case PCI_QLOGIC_ISP2714: 518 case PCI_QLOGIC_ISP2722: 519 isp->isp_did = 0x2700; 520 isp->isp_mdvec = &mdvec_2700; 521 isp->isp_type = ISP_HA_FC_2700; 522 break; 523 case PCI_QLOGIC_ISP2812: 524 case PCI_QLOGIC_ISP2814: 525 isp->isp_did = 0x2800; 526 isp->isp_mdvec = &mdvec_2800; 527 isp->isp_type = ISP_HA_FC_2800; 528 break; 529 default: 530 device_printf(dev, "unknown device type\n"); 531 goto bad; 532 break; 533 } 534 isp->isp_revision = pci_get_revid(dev); 535 536 if (IS_26XX(isp)) { 537 pcs->rtp = SYS_RES_MEMORY; 538 pcs->rgd = PCIR_BAR(0); 539 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, 540 RF_ACTIVE); 541 pcs->rtp1 = SYS_RES_MEMORY; 542 pcs->rgd1 = PCIR_BAR(2); 543 pcs->regs1 = bus_alloc_resource_any(dev, pcs->rtp1, &pcs->rgd1, 544 RF_ACTIVE); 545 pcs->rtp2 = SYS_RES_MEMORY; 546 pcs->rgd2 = PCIR_BAR(4); 547 pcs->regs2 = bus_alloc_resource_any(dev, pcs->rtp2, &pcs->rgd2, 548 RF_ACTIVE); 549 } else { 550 pcs->rtp = SYS_RES_MEMORY; 551 pcs->rgd = PCIR_BAR(1); 552 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, 553 RF_ACTIVE); 554 if (pcs->regs == NULL) { 555 pcs->rtp = SYS_RES_IOPORT; 556 pcs->rgd = PCIR_BAR(0); 557 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, 558 &pcs->rgd, RF_ACTIVE); 559 } 560 } 561 if (pcs->regs == NULL) { 562 device_printf(dev, "Unable to map any ports\n"); 563 goto bad; 564 } 565 if (bootverbose) { 566 device_printf(dev, "Using %s space register mapping\n", 567 (pcs->rtp == SYS_RES_IOPORT)? "I/O" : "Memory"); 568 } 569 isp->isp_regs = pcs->regs; 570 isp->isp_regs2 = pcs->regs2; 571 572 psize = sizeof(fcparam) * isp->isp_nchan; 573 xsize = sizeof(struct isp_fc) * isp->isp_nchan; 574 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); 575 if (isp->isp_param == NULL) { 576 device_printf(dev, "cannot allocate parameter data\n"); 577 goto bad; 578 } 579 isp->isp_osinfo.fc = malloc(xsize, M_DEVBUF, M_NOWAIT | M_ZERO); 580 if (isp->isp_osinfo.fc == NULL) { 581 device_printf(dev, "cannot allocate parameter data\n"); 582 goto bad; 583 } 584 585 /* 586 * Now that we know who we are (roughly) get/set specific options 587 */ 588 for (i = 0; i < isp->isp_nchan; i++) { 589 isp_get_specific_options(dev, i, isp); 590 } 591 592 /* 593 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. 594 */ 595 cmd = pci_read_config(dev, PCIR_COMMAND, 2); 596 cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; 597 cmd &= ~PCIM_CMD_INTX_DISABLE; 598 pci_write_config(dev, PCIR_COMMAND, cmd, 2); 599 600 /* 601 * Make sure the Cache Line Size register is set sensibly. 602 */ 603 data = pci_read_config(dev, PCIR_CACHELNSZ, 1); 604 if (data == 0 || (linesz != PCI_DFLT_LNSZ && data != linesz)) { 605 isp_prt(isp, ISP_LOGDEBUG0, "set PCI line size to %d from %d", linesz, data); 606 data = linesz; 607 pci_write_config(dev, PCIR_CACHELNSZ, data, 1); 608 } 609 610 /* 611 * Make sure the Latency Timer is sane. 612 */ 613 data = pci_read_config(dev, PCIR_LATTIMER, 1); 614 if (data < PCI_DFLT_LTNCY) { 615 data = PCI_DFLT_LTNCY; 616 isp_prt(isp, ISP_LOGDEBUG0, "set PCI latency to %d", data); 617 pci_write_config(dev, PCIR_LATTIMER, data, 1); 618 } 619 620 /* 621 * Make sure we've disabled the ROM. 622 */ 623 data = pci_read_config(dev, PCIR_ROMADDR, 4); 624 data &= ~1; 625 pci_write_config(dev, PCIR_ROMADDR, data, 4); 626 627 /* 628 * Last minute checks... 629 */ 630 isp->isp_port = pci_get_function(dev); 631 632 /* 633 * Make sure we're in reset state. 634 */ 635 ISP_LOCK(isp); 636 if (isp_reinit(isp, 1) != 0) { 637 ISP_UNLOCK(isp); 638 goto bad; 639 } 640 ISP_UNLOCK(isp); 641 if (isp_attach(isp)) { 642 ISP_LOCK(isp); 643 isp_shutdown(isp); 644 ISP_UNLOCK(isp); 645 goto bad; 646 } 647 return (0); 648 649 bad: 650 for (i = 0; i < isp->isp_nirq; i++) { 651 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); 652 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, 653 pcs->irq[0].irq); 654 } 655 if (pcs->msicount) { 656 pci_release_msi(dev); 657 } 658 if (pcs->regs) 659 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); 660 if (pcs->regs1) 661 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); 662 if (pcs->regs2) 663 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); 664 if (pcs->pci_isp.isp_param) { 665 free(pcs->pci_isp.isp_param, M_DEVBUF); 666 pcs->pci_isp.isp_param = NULL; 667 } 668 if (pcs->pci_isp.isp_osinfo.fc) { 669 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); 670 pcs->pci_isp.isp_osinfo.fc = NULL; 671 } 672 mtx_destroy(&isp->isp_lock); 673 return (ENXIO); 674 } 675 676 static int 677 isp_pci_detach(device_t dev) 678 { 679 struct isp_pcisoftc *pcs = device_get_softc(dev); 680 ispsoftc_t *isp = &pcs->pci_isp; 681 int i, status; 682 683 status = isp_detach(isp); 684 if (status) 685 return (status); 686 ISP_LOCK(isp); 687 isp_shutdown(isp); 688 ISP_UNLOCK(isp); 689 for (i = 0; i < isp->isp_nirq; i++) { 690 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); 691 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, 692 pcs->irq[i].irq); 693 } 694 if (pcs->msicount) 695 pci_release_msi(dev); 696 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); 697 if (pcs->regs1) 698 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); 699 if (pcs->regs2) 700 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); 701 isp_pci_mbxdmafree(isp); 702 if (pcs->pci_isp.isp_param) { 703 free(pcs->pci_isp.isp_param, M_DEVBUF); 704 pcs->pci_isp.isp_param = NULL; 705 } 706 if (pcs->pci_isp.isp_osinfo.fc) { 707 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); 708 pcs->pci_isp.isp_osinfo.fc = NULL; 709 } 710 mtx_destroy(&isp->isp_lock); 711 return (0); 712 } 713 714 #define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off)) 715 #define BXW2(isp, off, v) bus_write_2((isp)->isp_regs, (off), (v)) 716 #define BXR4(isp, off) bus_read_4((isp)->isp_regs, (off)) 717 #define BXW4(isp, off, v) bus_write_4((isp)->isp_regs, (off), (v)) 718 #define B2R4(isp, off) bus_read_4((isp)->isp_regs2, (off)) 719 #define B2W4(isp, off, v) bus_write_4((isp)->isp_regs2, (off), (v)) 720 721 static void 722 isp_pci_run_isr_2400(ispsoftc_t *isp) 723 { 724 uint32_t r2hisr; 725 uint16_t isr, info; 726 727 r2hisr = BXR4(isp, BIU2400_R2HSTS); 728 isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr); 729 if ((r2hisr & BIU_R2HST_INTR) == 0) 730 return; 731 isr = r2hisr & BIU_R2HST_ISTAT_MASK; 732 info = (r2hisr >> 16); 733 switch (isr) { 734 case ISPR2HST_ROM_MBX_OK: 735 case ISPR2HST_ROM_MBX_FAIL: 736 case ISPR2HST_MBX_OK: 737 case ISPR2HST_MBX_FAIL: 738 isp_intr_mbox(isp, info); 739 break; 740 case ISPR2HST_ASYNC_EVENT: 741 isp_intr_async(isp, info); 742 break; 743 case ISPR2HST_RSPQ_UPDATE: 744 isp_intr_respq(isp); 745 break; 746 case ISPR2HST_RSPQ_UPDATE2: 747 #ifdef ISP_TARGET_MODE 748 case ISPR2HST_ATIO_RSPQ_UPDATE: 749 #endif 750 isp_intr_respq(isp); 751 /* FALLTHROUGH */ 752 #ifdef ISP_TARGET_MODE 753 case ISPR2HST_ATIO_UPDATE: 754 case ISPR2HST_ATIO_UPDATE2: 755 isp_intr_atioq(isp); 756 #endif 757 break; 758 default: 759 isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr); 760 } 761 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 762 } 763 764 static uint32_t 765 isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff) 766 { 767 int block = regoff & _BLK_REG_MASK; 768 769 switch (block) { 770 case BIU_BLOCK: 771 return (BXR4(isp, regoff)); 772 case MBOX_BLOCK: 773 return (BXR2(isp, regoff)); 774 } 775 isp_prt(isp, ISP_LOGERR, "unknown block read at 0x%x", regoff); 776 return (0xffffffff); 777 } 778 779 static void 780 isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val) 781 { 782 int block = regoff & _BLK_REG_MASK; 783 784 switch (block) { 785 case BIU_BLOCK: 786 BXW4(isp, regoff, val); 787 #ifdef MEMORYBARRIERW 788 if (regoff == BIU2400_REQINP || 789 regoff == BIU2400_RSPOUTP || 790 regoff == BIU2400_PRI_REQINP || 791 regoff == BIU2400_ATIO_RSPOUTP) 792 MEMORYBARRIERW(isp, SYNC_REG, regoff, 4, -1) 793 else 794 #endif 795 MEMORYBARRIER(isp, SYNC_REG, regoff, 4, -1); 796 return; 797 case MBOX_BLOCK: 798 BXW2(isp, regoff, val); 799 MEMORYBARRIER(isp, SYNC_REG, regoff, 2, -1); 800 return; 801 } 802 isp_prt(isp, ISP_LOGERR, "unknown block write at 0x%x", regoff); 803 } 804 805 static uint32_t 806 isp_pci_rd_reg_2600(ispsoftc_t *isp, int regoff) 807 { 808 uint32_t rv; 809 810 switch (regoff) { 811 case BIU2400_PRI_REQINP: 812 case BIU2400_PRI_REQOUTP: 813 isp_prt(isp, ISP_LOGERR, "unknown register read at 0x%x", 814 regoff); 815 rv = 0xffffffff; 816 break; 817 case BIU2400_REQINP: 818 rv = B2R4(isp, 0x00); 819 break; 820 case BIU2400_REQOUTP: 821 rv = B2R4(isp, 0x04); 822 break; 823 case BIU2400_RSPINP: 824 rv = B2R4(isp, 0x08); 825 break; 826 case BIU2400_RSPOUTP: 827 rv = B2R4(isp, 0x0c); 828 break; 829 case BIU2400_ATIO_RSPINP: 830 rv = B2R4(isp, 0x10); 831 break; 832 case BIU2400_ATIO_RSPOUTP: 833 rv = B2R4(isp, 0x14); 834 break; 835 default: 836 rv = isp_pci_rd_reg_2400(isp, regoff); 837 break; 838 } 839 return (rv); 840 } 841 842 static void 843 isp_pci_wr_reg_2600(ispsoftc_t *isp, int regoff, uint32_t val) 844 { 845 int off; 846 847 switch (regoff) { 848 case BIU2400_PRI_REQINP: 849 case BIU2400_PRI_REQOUTP: 850 isp_prt(isp, ISP_LOGERR, "unknown register write at 0x%x", 851 regoff); 852 return; 853 case BIU2400_REQINP: 854 off = 0x00; 855 break; 856 case BIU2400_REQOUTP: 857 off = 0x04; 858 break; 859 case BIU2400_RSPINP: 860 off = 0x08; 861 break; 862 case BIU2400_RSPOUTP: 863 off = 0x0c; 864 break; 865 case BIU2400_ATIO_RSPINP: 866 off = 0x10; 867 break; 868 case BIU2400_ATIO_RSPOUTP: 869 off = 0x14; 870 break; 871 default: 872 isp_pci_wr_reg_2400(isp, regoff, val); 873 return; 874 } 875 B2W4(isp, off, val); 876 } 877 878 879 struct imush { 880 bus_addr_t maddr; 881 int error; 882 }; 883 884 static void 885 imc(void *arg, bus_dma_segment_t *segs, int nseg, int error) 886 { 887 struct imush *imushp = (struct imush *) arg; 888 889 if (!(imushp->error = error)) 890 imushp->maddr = segs[0].ds_addr; 891 } 892 893 static int 894 isp_pci_mbxdma(ispsoftc_t *isp) 895 { 896 bus_dma_tag_t ptag; 897 caddr_t base; 898 uint32_t len; 899 int i, error, cmap; 900 bus_size_t slim; /* segment size */ 901 struct imush im; 902 #ifdef ISP_TARGET_MODE 903 isp_ecmd_t *ecmd; 904 #endif 905 906 /* Already been here? If so, leave... */ 907 if (isp->isp_xflist != NULL) 908 return (0); 909 if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0) 910 return (0); 911 ISP_UNLOCK(isp); 912 913 ptag = bus_get_dma_tag(isp->isp_osinfo.dev); 914 if (sizeof (bus_size_t) > 4) 915 slim = (bus_size_t) (1ULL << 32); 916 else 917 slim = (bus_size_t) (1UL << 31); 918 919 if (isp->isp_rquest != NULL) 920 goto gotmaxcmds; 921 922 /* 923 * Allocate and map the request queue. 924 */ 925 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 926 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 927 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 928 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { 929 isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); 930 goto bad; 931 } 932 if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base, 933 BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) { 934 isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory"); 935 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 936 goto bad; 937 } 938 isp->isp_rquest = base; 939 im.error = 0; 940 if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap, 941 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 942 isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error); 943 goto bad; 944 } 945 isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx", 946 (uintmax_t)im.maddr, (uintmax_t)len); 947 isp->isp_rquest_dma = im.maddr; 948 949 #ifdef ISP_TARGET_MODE 950 /* 951 * Allocate region for external DMA addressable command/status structures. 952 */ 953 len = N_XCMDS * XCMD_SIZE; 954 if (bus_dma_tag_create(ptag, XCMD_SIZE, slim, 955 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 956 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { 957 isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); 958 goto bad; 959 } 960 if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, 961 BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { 962 isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); 963 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); 964 goto bad; 965 } 966 isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; 967 im.error = 0; 968 if (bus_dmamap_load(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, 969 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 970 isp_prt(isp, ISP_LOGERR, "error loading ECMD DMA map %d", im.error); 971 goto bad; 972 } 973 isp_prt(isp, ISP_LOGDEBUG0, "ecmd area @ 0x%jx/0x%jx", 974 (uintmax_t)im.maddr, (uintmax_t)len); 975 976 isp->isp_osinfo.ecmd_dma = im.maddr; 977 isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)base; 978 for (ecmd = isp->isp_osinfo.ecmd_free; 979 ecmd < &isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) { 980 if (ecmd == &isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) 981 ecmd->next = NULL; 982 else 983 ecmd->next = ecmd + 1; 984 } 985 #endif 986 987 /* 988 * Allocate and map the result queue. 989 */ 990 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); 991 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 992 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 993 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.respdmat)) { 994 isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); 995 goto bad; 996 } 997 if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base, 998 BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) { 999 isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory"); 1000 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 1001 goto bad; 1002 } 1003 isp->isp_result = base; 1004 im.error = 0; 1005 if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap, 1006 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 1007 isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error); 1008 goto bad; 1009 } 1010 isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx", 1011 (uintmax_t)im.maddr, (uintmax_t)len); 1012 isp->isp_result_dma = im.maddr; 1013 1014 #ifdef ISP_TARGET_MODE 1015 /* 1016 * Allocate and map ATIO queue. 1017 */ 1018 len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp)); 1019 if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, 1020 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1021 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) { 1022 isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag"); 1023 goto bad; 1024 } 1025 if (bus_dmamem_alloc(isp->isp_osinfo.atiodmat, (void **)&base, 1026 BUS_DMA_COHERENT, &isp->isp_osinfo.atiomap) != 0) { 1027 isp_prt(isp, ISP_LOGERR, "cannot allocate ATIO DMA memory"); 1028 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); 1029 goto bad; 1030 } 1031 isp->isp_atioq = base; 1032 im.error = 0; 1033 if (bus_dmamap_load(isp->isp_osinfo.atiodmat, isp->isp_osinfo.atiomap, 1034 base, len, imc, &im, BUS_DMA_NOWAIT) || im.error) { 1035 isp_prt(isp, ISP_LOGERR, "error loading ATIO DMA map %d", im.error); 1036 goto bad; 1037 } 1038 isp_prt(isp, ISP_LOGDEBUG0, "ATIO area @ 0x%jx/0x%jx", 1039 (uintmax_t)im.maddr, (uintmax_t)len); 1040 isp->isp_atioq_dma = im.maddr; 1041 #endif 1042 1043 if (bus_dma_tag_create(ptag, 64, slim, 1044 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1045 2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, NULL, NULL, 1046 &isp->isp_osinfo.iocbdmat)) { 1047 goto bad; 1048 } 1049 if (bus_dmamem_alloc(isp->isp_osinfo.iocbdmat, 1050 (void **)&base, BUS_DMA_COHERENT, &isp->isp_osinfo.iocbmap) != 0) 1051 goto bad; 1052 isp->isp_iocb = base; 1053 im.error = 0; 1054 if (bus_dmamap_load(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, 1055 base, 2*QENTRY_LEN, imc, &im, BUS_DMA_NOWAIT) || im.error) 1056 goto bad; 1057 isp->isp_iocb_dma = im.maddr; 1058 1059 if (bus_dma_tag_create(ptag, 64, slim, 1060 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1061 ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, NULL, NULL, 1062 &isp->isp_osinfo.scdmat)) 1063 goto bad; 1064 for (cmap = 0; cmap < isp->isp_nchan; cmap++) { 1065 struct isp_fc *fc = ISP_FC_PC(isp, cmap); 1066 if (bus_dmamem_alloc(isp->isp_osinfo.scdmat, 1067 (void **)&base, BUS_DMA_COHERENT, &fc->scmap) != 0) 1068 goto bad; 1069 FCPARAM(isp, cmap)->isp_scratch = base; 1070 im.error = 0; 1071 if (bus_dmamap_load(isp->isp_osinfo.scdmat, fc->scmap, 1072 base, ISP_FC_SCRLEN, imc, &im, BUS_DMA_NOWAIT) || 1073 im.error) { 1074 bus_dmamem_free(isp->isp_osinfo.scdmat, 1075 base, fc->scmap); 1076 FCPARAM(isp, cmap)->isp_scratch = NULL; 1077 goto bad; 1078 } 1079 FCPARAM(isp, cmap)->isp_scdma = im.maddr; 1080 for (i = 0; i < INITIAL_NEXUS_COUNT; i++) { 1081 struct isp_nexus *n = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_NOWAIT | M_ZERO); 1082 if (n == NULL) { 1083 while (fc->nexus_free_list) { 1084 n = fc->nexus_free_list; 1085 fc->nexus_free_list = n->next; 1086 free(n, M_DEVBUF); 1087 } 1088 goto bad; 1089 } 1090 n->next = fc->nexus_free_list; 1091 fc->nexus_free_list = n; 1092 } 1093 } 1094 1095 if (isp->isp_maxcmds == 0) { 1096 ISP_LOCK(isp); 1097 return (0); 1098 } 1099 1100 gotmaxcmds: 1101 if (bus_dma_tag_create(ptag, 1, slim, 1102 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 1103 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, ISP_NSEG64_MAX, 1104 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, 0, 1105 busdma_lock_mutex, &isp->isp_lock, &isp->isp_osinfo.dmat)) 1106 goto bad; 1107 len = isp->isp_maxcmds * sizeof (struct isp_pcmd); 1108 isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) 1109 malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1110 for (i = 0; i < isp->isp_maxcmds; i++) { 1111 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; 1112 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); 1113 if (error) { 1114 isp_prt(isp, ISP_LOGERR, "error %d creating per-cmd DMA maps", error); 1115 while (--i >= 0) { 1116 bus_dmamap_destroy(isp->isp_osinfo.dmat, 1117 isp->isp_osinfo.pcmd_pool[i].dmap); 1118 } 1119 goto bad; 1120 } 1121 callout_init_mtx(&pcmd->wdog, &isp->isp_lock, 0); 1122 if (i == isp->isp_maxcmds-1) 1123 pcmd->next = NULL; 1124 else 1125 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; 1126 } 1127 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; 1128 1129 len = sizeof(isp_hdl_t) * ISP_HANDLE_NUM(isp); 1130 isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1131 for (len = 0; len < ISP_HANDLE_NUM(isp) - 1; len++) 1132 isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; 1133 isp->isp_xffree = isp->isp_xflist; 1134 1135 ISP_LOCK(isp); 1136 return (0); 1137 1138 bad: 1139 isp_pci_mbxdmafree(isp); 1140 ISP_LOCK(isp); 1141 return (1); 1142 } 1143 1144 static void 1145 isp_pci_mbxdmafree(ispsoftc_t *isp) 1146 { 1147 int i; 1148 1149 if (isp->isp_xflist != NULL) { 1150 free(isp->isp_xflist, M_DEVBUF); 1151 isp->isp_xflist = NULL; 1152 } 1153 if (isp->isp_osinfo.pcmd_pool != NULL) { 1154 for (i = 0; i < isp->isp_maxcmds; i++) { 1155 bus_dmamap_destroy(isp->isp_osinfo.dmat, 1156 isp->isp_osinfo.pcmd_pool[i].dmap); 1157 } 1158 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1159 isp->isp_osinfo.pcmd_pool = NULL; 1160 } 1161 if (isp->isp_osinfo.dmat) { 1162 bus_dma_tag_destroy(isp->isp_osinfo.dmat); 1163 isp->isp_osinfo.dmat = NULL; 1164 } 1165 for (i = 0; i < isp->isp_nchan; i++) { 1166 struct isp_fc *fc = ISP_FC_PC(isp, i); 1167 if (FCPARAM(isp, i)->isp_scdma != 0) { 1168 bus_dmamap_unload(isp->isp_osinfo.scdmat, 1169 fc->scmap); 1170 FCPARAM(isp, i)->isp_scdma = 0; 1171 } 1172 if (FCPARAM(isp, i)->isp_scratch != NULL) { 1173 bus_dmamem_free(isp->isp_osinfo.scdmat, 1174 FCPARAM(isp, i)->isp_scratch, fc->scmap); 1175 FCPARAM(isp, i)->isp_scratch = NULL; 1176 } 1177 while (fc->nexus_free_list) { 1178 struct isp_nexus *n = fc->nexus_free_list; 1179 fc->nexus_free_list = n->next; 1180 free(n, M_DEVBUF); 1181 } 1182 } 1183 if (isp->isp_osinfo.scdmat) { 1184 bus_dma_tag_destroy(isp->isp_osinfo.scdmat); 1185 isp->isp_osinfo.scdmat = NULL; 1186 } 1187 if (isp->isp_iocb_dma != 0) { 1188 bus_dmamap_unload(isp->isp_osinfo.iocbdmat, 1189 isp->isp_osinfo.iocbmap); 1190 isp->isp_iocb_dma = 0; 1191 } 1192 if (isp->isp_iocb != NULL) { 1193 bus_dmamem_free(isp->isp_osinfo.iocbdmat, 1194 isp->isp_iocb, isp->isp_osinfo.iocbmap); 1195 bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat); 1196 } 1197 #ifdef ISP_TARGET_MODE 1198 if (isp->isp_atioq_dma != 0) { 1199 bus_dmamap_unload(isp->isp_osinfo.atiodmat, 1200 isp->isp_osinfo.atiomap); 1201 isp->isp_atioq_dma = 0; 1202 } 1203 if (isp->isp_atioq != NULL) { 1204 bus_dmamem_free(isp->isp_osinfo.atiodmat, isp->isp_atioq, 1205 isp->isp_osinfo.atiomap); 1206 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); 1207 isp->isp_atioq = NULL; 1208 } 1209 #endif 1210 if (isp->isp_result_dma != 0) { 1211 bus_dmamap_unload(isp->isp_osinfo.respdmat, 1212 isp->isp_osinfo.respmap); 1213 isp->isp_result_dma = 0; 1214 } 1215 if (isp->isp_result != NULL) { 1216 bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result, 1217 isp->isp_osinfo.respmap); 1218 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 1219 isp->isp_result = NULL; 1220 } 1221 #ifdef ISP_TARGET_MODE 1222 if (isp->isp_osinfo.ecmd_dma != 0) { 1223 bus_dmamap_unload(isp->isp_osinfo.ecmd_dmat, 1224 isp->isp_osinfo.ecmd_map); 1225 isp->isp_osinfo.ecmd_dma = 0; 1226 } 1227 if (isp->isp_osinfo.ecmd_base != NULL) { 1228 bus_dmamem_free(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_base, 1229 isp->isp_osinfo.ecmd_map); 1230 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); 1231 isp->isp_osinfo.ecmd_base = NULL; 1232 } 1233 #endif 1234 if (isp->isp_rquest_dma != 0) { 1235 bus_dmamap_unload(isp->isp_osinfo.reqdmat, 1236 isp->isp_osinfo.reqmap); 1237 isp->isp_rquest_dma = 0; 1238 } 1239 if (isp->isp_rquest != NULL) { 1240 bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest, 1241 isp->isp_osinfo.reqmap); 1242 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 1243 isp->isp_rquest = NULL; 1244 } 1245 } 1246 1247 static int 1248 isp_pci_irqsetup(ispsoftc_t *isp) 1249 { 1250 device_t dev = isp->isp_osinfo.dev; 1251 struct isp_pcisoftc *pcs = device_get_softc(dev); 1252 driver_intr_t *f; 1253 int i, max_irq; 1254 1255 /* Allocate IRQs only once. */ 1256 if (isp->isp_nirq > 0) 1257 return (0); 1258 1259 ISP_UNLOCK(isp); 1260 if (ISP_CAP_MSIX(isp)) { 1261 max_irq = IS_26XX(isp) ? 3 : (IS_25XX(isp) ? 2 : 0); 1262 resource_int_value(device_get_name(dev), 1263 device_get_unit(dev), "msix", &max_irq); 1264 max_irq = imin(ISP_MAX_IRQS, max_irq); 1265 pcs->msicount = imin(pci_msix_count(dev), max_irq); 1266 if (pcs->msicount > 0 && 1267 pci_alloc_msix(dev, &pcs->msicount) != 0) 1268 pcs->msicount = 0; 1269 } 1270 if (pcs->msicount == 0) { 1271 max_irq = 1; 1272 resource_int_value(device_get_name(dev), 1273 device_get_unit(dev), "msi", &max_irq); 1274 max_irq = imin(1, max_irq); 1275 pcs->msicount = imin(pci_msi_count(dev), max_irq); 1276 if (pcs->msicount > 0 && 1277 pci_alloc_msi(dev, &pcs->msicount) != 0) 1278 pcs->msicount = 0; 1279 } 1280 for (i = 0; i < MAX(1, pcs->msicount); i++) { 1281 pcs->irq[i].iqd = i + (pcs->msicount > 0); 1282 pcs->irq[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 1283 &pcs->irq[i].iqd, RF_ACTIVE | RF_SHAREABLE); 1284 if (pcs->irq[i].irq == NULL) { 1285 device_printf(dev, "could not allocate interrupt\n"); 1286 break; 1287 } 1288 if (i == 0) 1289 f = isp_platform_intr; 1290 else if (i == 1) 1291 f = isp_platform_intr_resp; 1292 else 1293 f = isp_platform_intr_atio; 1294 if (bus_setup_intr(dev, pcs->irq[i].irq, ISP_IFLAGS, NULL, 1295 f, isp, &pcs->irq[i].ih)) { 1296 device_printf(dev, "could not setup interrupt\n"); 1297 (void) bus_release_resource(dev, SYS_RES_IRQ, 1298 pcs->irq[i].iqd, pcs->irq[i].irq); 1299 break; 1300 } 1301 if (pcs->msicount > 1) { 1302 bus_describe_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih, 1303 "%d", i); 1304 } 1305 isp->isp_nirq = i + 1; 1306 } 1307 ISP_LOCK(isp); 1308 1309 return (isp->isp_nirq == 0); 1310 } 1311