Lines Matching +full:isp +full:- +full:0
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5 * Copyright (c) 1997-2008 by Matthew Jacob
30 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
48 #include <dev/isp/isp_freebsd.h>
110 #define PCIM_CMD_INVEN 0x10
113 #define PCIM_CMD_BUSMASTEREN 0x0004
116 #define PCIM_CMD_PERRESPEN 0x0040
119 #define PCIM_CMD_SEREN 0x0100
122 #define PCIM_CMD_INTX_DISABLE 0x0400
126 #define PCIR_COMMAND 0x04
130 #define PCIR_CACHELNSZ 0x0c
134 #define PCIR_LATTIMER 0x0d
138 #define PCIR_ROMADDR 0x30
141 #define PCI_VENDOR_QLOGIC 0x1077
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
181 #define PCI_DFLT_LTNCY 0x40
182 #define PCI_DFLT_LNSZ 0x10
215 { 0, 0 }
219 "isp", isp_pci_methods, sizeof (struct isp_pcisoftc)
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;
232 device_set_desc(dev, "Qlogic ISP 2422 PCI FC-AL Adapter"); in isp_pci_probe()
235 device_set_desc(dev, "Qlogic ISP 2432 PCI FC-AL Adapter"); in isp_pci_probe()
238 device_set_desc(dev, "Qlogic ISP 2532 PCI FC-AL Adapter"); in isp_pci_probe()
241 device_set_desc(dev, "Qlogic ISP 5432 PCI FC-AL Adapter"); in isp_pci_probe()
244 device_set_desc(dev, "Qlogic ISP 2031 PCI FC-AL Adapter"); in isp_pci_probe()
247 device_set_desc(dev, "Qlogic ISP 8031 PCI FCoE Adapter"); in isp_pci_probe()
250 device_set_desc(dev, "Qlogic ISP 2684 PCI FC Adapter"); in isp_pci_probe()
253 device_set_desc(dev, "Qlogic ISP 2692 PCI FC Adapter"); in isp_pci_probe()
256 device_set_desc(dev, "Qlogic ISP 2714 PCI FC Adapter"); in isp_pci_probe()
259 device_set_desc(dev, "Qlogic ISP 2722 PCI FC Adapter"); in isp_pci_probe()
262 device_set_desc(dev, "Qlogic ISP 2812 PCI FC Adapter"); in isp_pci_probe()
265 device_set_desc(dev, "Qlogic ISP 2814 PCI FC Adapter"); in isp_pci_probe()
270 if (isp_announced == 0 && bootverbose) { in isp_pci_probe()
271 printf("Qlogic ISP Driver, FreeBSD Version %d.%d, " in isp_pci_probe()
285 isp_get_generic_options(device_t dev, ispsoftc_t *isp) in isp_get_generic_options() argument
289 tval = 0; in isp_get_generic_options()
290 …int_value(device_get_name(dev), device_get_unit(dev), "fwload_disable", &tval) == 0 && tval != 0) { in isp_get_generic_options()
291 isp->isp_confopts |= ISP_CFG_NORELOAD; in isp_get_generic_options()
293 tval = 0; in isp_get_generic_options()
294 …e_int_value(device_get_name(dev), device_get_unit(dev), "fwload_force", &tval) == 0 && tval != 0) { in isp_get_generic_options()
295 isp->isp_confopts |= ISP_CFG_FWLOAD_FORCE; in isp_get_generic_options()
297 if ((isp->isp_confopts & (ISP_CFG_NORELOAD|ISP_CFG_FWLOAD_FORCE)) == in isp_get_generic_options()
302 tval = 0; in isp_get_generic_options()
303 …e_int_value(device_get_name(dev), device_get_unit(dev), "ignore_nvram", &tval) == 0 && tval != 0) { in isp_get_generic_options()
304 isp->isp_confopts |= ISP_CFG_NONVRAM; in isp_get_generic_options()
306 tval = 0; in isp_get_generic_options()
309 isp->isp_dblev = tval; in isp_get_generic_options()
311 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; in isp_get_generic_options()
314 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; in isp_get_generic_options()
316 tval = -1; in isp_get_generic_options()
318 if (tval > 0 && tval <= 254) { in isp_get_generic_options()
327 isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp) in isp_get_specific_options() argument
330 int tval = 0; in isp_get_specific_options()
333 if (chan == 0) in isp_get_specific_options()
334 prefix[0] = 0; in isp_get_specific_options()
340 ISP_FC_PC(isp, chan)->default_id = 109 - chan; in isp_get_specific_options()
342 ISP_FC_PC(isp, chan)->default_id = tval - chan; in isp_get_specific_options()
343 isp->isp_confopts |= ISP_CFG_OWNLOOPID; in isp_get_specific_options()
346 tval = -1; in isp_get_specific_options()
349 name, &tval) == 0) { in isp_get_specific_options()
355 device_printf(dev, "Chan %d setting role to 0x%x\n", chan, tval); in isp_get_specific_options()
358 tval = -1; in isp_get_specific_options()
362 if (tval == -1) { in isp_get_specific_options()
365 ISP_FC_PC(isp, chan)->def_role = tval; in isp_get_specific_options()
367 tval = 0; in isp_get_specific_options()
370 name, &tval) == 0 && tval != 0) { in isp_get_specific_options()
371 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; in isp_get_specific_options()
376 name, (const char **) &sptr) == 0 && sptr != NULL) { in isp_get_specific_options()
377 if (strcmp(sptr, "lport") == 0) { in isp_get_specific_options()
378 isp->isp_confopts |= ISP_CFG_LPORT; in isp_get_specific_options()
379 } else if (strcmp(sptr, "nport") == 0) { in isp_get_specific_options()
380 isp->isp_confopts |= ISP_CFG_NPORT; in isp_get_specific_options()
381 } else if (strcmp(sptr, "lport-only") == 0) { in isp_get_specific_options()
382 isp->isp_confopts |= ISP_CFG_LPORT_ONLY; in isp_get_specific_options()
383 } else if (strcmp(sptr, "nport-only") == 0) { in isp_get_specific_options()
384 isp->isp_confopts |= ISP_CFG_NPORT_ONLY; in isp_get_specific_options()
389 isp->isp_confopts |= ISP_CFG_NOFCTAPE; in isp_get_specific_options()
391 isp->isp_confopts |= ISP_CFG_FCTAPE; in isp_get_specific_options()
394 tval = 0; in isp_get_specific_options()
399 isp->isp_confopts &= ~ISP_CFG_FCTAPE; in isp_get_specific_options()
400 isp->isp_confopts |= ISP_CFG_NOFCTAPE; in isp_get_specific_options()
403 tval = 0; in isp_get_specific_options()
408 isp->isp_confopts &= ~ISP_CFG_NOFCTAPE; in isp_get_specific_options()
409 isp->isp_confopts |= ISP_CFG_FCTAPE; in isp_get_specific_options()
425 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { in isp_get_specific_options()
427 ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16); in isp_get_specific_options()
428 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwpn == -1) { in isp_get_specific_options()
430 ISP_FC_PC(isp, chan)->def_wwpn = 0; in isp_get_specific_options()
438 if (tval == 0 && sptr != NULL && *sptr++ == 'w') { in isp_get_specific_options()
440 ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16); in isp_get_specific_options()
441 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwnn == 0) { in isp_get_specific_options()
443 ISP_FC_PC(isp, chan)->def_wwnn = 0; in isp_get_specific_options()
447 tval = -1; in isp_get_specific_options()
451 if (tval >= 0 && tval < 0xffff) { in isp_get_specific_options()
452 ISP_FC_PC(isp, chan)->loop_down_limit = tval; in isp_get_specific_options()
454 ISP_FC_PC(isp, chan)->loop_down_limit = isp_loop_down_limit; in isp_get_specific_options()
457 tval = -1; in isp_get_specific_options()
461 if (tval >= 0 && tval < 0xffff) { in isp_get_specific_options()
462 ISP_FC_PC(isp, chan)->gone_device_time = tval; in isp_get_specific_options()
464 ISP_FC_PC(isp, chan)->gone_device_time = isp_gone_device_time; in isp_get_specific_options()
472 ispsoftc_t *isp = &pcs->pci_isp; in isp_pci_attach() local
477 isp->isp_dev = dev; in isp_pci_attach()
478 isp->isp_nchan = 1; in isp_pci_attach()
479 mtx_init(&isp->isp_lock, "isp", NULL, MTX_DEF); in isp_pci_attach()
484 isp_nvports = 0; in isp_pci_attach()
485 isp_get_generic_options(dev, isp); in isp_pci_attach()
488 pcs->regs = pcs->regs2 = NULL; in isp_pci_attach()
489 pcs->rgd = pcs->rtp = 0; in isp_pci_attach()
491 isp->isp_nchan += isp_nvports; in isp_pci_attach()
495 isp->isp_did = 0x2400; in isp_pci_attach()
496 isp->isp_mdvec = &mdvec_2400; in isp_pci_attach()
497 isp->isp_type = ISP_HA_FC_2400; in isp_pci_attach()
500 isp->isp_did = 0x2500; in isp_pci_attach()
501 isp->isp_mdvec = &mdvec_2500; in isp_pci_attach()
502 isp->isp_type = ISP_HA_FC_2500; in isp_pci_attach()
505 isp->isp_did = 0x2500; in isp_pci_attach()
506 isp->isp_mdvec = &mdvec_2500; in isp_pci_attach()
507 isp->isp_type = ISP_HA_FC_2500; in isp_pci_attach()
511 isp->isp_did = 0x2600; in isp_pci_attach()
512 isp->isp_mdvec = &mdvec_2600; in isp_pci_attach()
513 isp->isp_type = ISP_HA_FC_2600; in isp_pci_attach()
519 isp->isp_did = 0x2700; in isp_pci_attach()
520 isp->isp_mdvec = &mdvec_2700; in isp_pci_attach()
521 isp->isp_type = ISP_HA_FC_2700; in isp_pci_attach()
525 isp->isp_did = 0x2800; in isp_pci_attach()
526 isp->isp_mdvec = &mdvec_2800; in isp_pci_attach()
527 isp->isp_type = ISP_HA_FC_2800; in isp_pci_attach()
534 isp->isp_revision = pci_get_revid(dev); in isp_pci_attach()
536 if (IS_26XX(isp)) { in isp_pci_attach()
537 pcs->rtp = SYS_RES_MEMORY; in isp_pci_attach()
538 pcs->rgd = PCIR_BAR(0); in isp_pci_attach()
539 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, in isp_pci_attach()
541 pcs->rtp1 = SYS_RES_MEMORY; in isp_pci_attach()
542 pcs->rgd1 = PCIR_BAR(2); in isp_pci_attach()
543 pcs->regs1 = bus_alloc_resource_any(dev, pcs->rtp1, &pcs->rgd1, in isp_pci_attach()
545 pcs->rtp2 = SYS_RES_MEMORY; in isp_pci_attach()
546 pcs->rgd2 = PCIR_BAR(4); in isp_pci_attach()
547 pcs->regs2 = bus_alloc_resource_any(dev, pcs->rtp2, &pcs->rgd2, in isp_pci_attach()
550 pcs->rtp = SYS_RES_MEMORY; in isp_pci_attach()
551 pcs->rgd = PCIR_BAR(1); in isp_pci_attach()
552 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, in isp_pci_attach()
554 if (pcs->regs == NULL) { in isp_pci_attach()
555 pcs->rtp = SYS_RES_IOPORT; in isp_pci_attach()
556 pcs->rgd = PCIR_BAR(0); in isp_pci_attach()
557 pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, in isp_pci_attach()
558 &pcs->rgd, RF_ACTIVE); in isp_pci_attach()
561 if (pcs->regs == NULL) { in isp_pci_attach()
567 (pcs->rtp == SYS_RES_IOPORT)? "I/O" : "Memory"); in isp_pci_attach()
569 isp->isp_regs = pcs->regs; in isp_pci_attach()
570 isp->isp_regs2 = pcs->regs2; in isp_pci_attach()
572 psize = sizeof(fcparam) * isp->isp_nchan; in isp_pci_attach()
573 xsize = sizeof(struct isp_fc) * isp->isp_nchan; in isp_pci_attach()
574 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); in isp_pci_attach()
575 if (isp->isp_param == NULL) { in isp_pci_attach()
579 isp->isp_osinfo.fc = malloc(xsize, M_DEVBUF, M_NOWAIT | M_ZERO); in isp_pci_attach()
580 if (isp->isp_osinfo.fc == NULL) { in isp_pci_attach()
588 for (i = 0; i < isp->isp_nchan; i++) { in isp_pci_attach()
589 isp_get_specific_options(dev, i, isp); in isp_pci_attach()
604 if (data == 0 || (linesz != PCI_DFLT_LNSZ && data != linesz)) { in isp_pci_attach()
605 isp_prt(isp, ISP_LOGDEBUG0, "set PCI line size to %d from %d", linesz, data); in isp_pci_attach()
616 isp_prt(isp, ISP_LOGDEBUG0, "set PCI latency to %d", data); in isp_pci_attach()
630 isp->isp_port = pci_get_function(dev); in isp_pci_attach()
635 ISP_LOCK(isp); in isp_pci_attach()
636 if (isp_reinit(isp, 1) != 0) { in isp_pci_attach()
637 ISP_UNLOCK(isp); in isp_pci_attach()
640 ISP_UNLOCK(isp); in isp_pci_attach()
641 if (isp_attach(isp)) { in isp_pci_attach()
642 ISP_LOCK(isp); in isp_pci_attach()
643 isp_shutdown(isp); in isp_pci_attach()
644 ISP_UNLOCK(isp); in isp_pci_attach()
647 return (0); in isp_pci_attach()
650 for (i = 0; i < isp->isp_nirq; i++) { in isp_pci_attach()
651 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); in isp_pci_attach()
652 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, in isp_pci_attach()
653 pcs->irq[0].irq); in isp_pci_attach()
655 if (pcs->msicount) { in isp_pci_attach()
658 if (pcs->regs) in isp_pci_attach()
659 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); in isp_pci_attach()
660 if (pcs->regs1) in isp_pci_attach()
661 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); in isp_pci_attach()
662 if (pcs->regs2) in isp_pci_attach()
663 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); in isp_pci_attach()
664 if (pcs->pci_isp.isp_param) { in isp_pci_attach()
665 free(pcs->pci_isp.isp_param, M_DEVBUF); in isp_pci_attach()
666 pcs->pci_isp.isp_param = NULL; in isp_pci_attach()
668 if (pcs->pci_isp.isp_osinfo.fc) { in isp_pci_attach()
669 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); in isp_pci_attach()
670 pcs->pci_isp.isp_osinfo.fc = NULL; in isp_pci_attach()
672 mtx_destroy(&isp->isp_lock); in isp_pci_attach()
680 ispsoftc_t *isp = &pcs->pci_isp; in isp_pci_detach() local
683 status = isp_detach(isp); in isp_pci_detach()
686 ISP_LOCK(isp); in isp_pci_detach()
687 isp_shutdown(isp); in isp_pci_detach()
688 ISP_UNLOCK(isp); in isp_pci_detach()
689 for (i = 0; i < isp->isp_nirq; i++) { in isp_pci_detach()
690 (void) bus_teardown_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih); in isp_pci_detach()
691 (void) bus_release_resource(dev, SYS_RES_IRQ, pcs->irq[i].iqd, in isp_pci_detach()
692 pcs->irq[i].irq); in isp_pci_detach()
694 if (pcs->msicount) in isp_pci_detach()
696 (void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs); in isp_pci_detach()
697 if (pcs->regs1) in isp_pci_detach()
698 (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1); in isp_pci_detach()
699 if (pcs->regs2) in isp_pci_detach()
700 (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2); in isp_pci_detach()
701 isp_pci_mbxdmafree(isp); in isp_pci_detach()
702 if (pcs->pci_isp.isp_param) { in isp_pci_detach()
703 free(pcs->pci_isp.isp_param, M_DEVBUF); in isp_pci_detach()
704 pcs->pci_isp.isp_param = NULL; in isp_pci_detach()
706 if (pcs->pci_isp.isp_osinfo.fc) { in isp_pci_detach()
707 free(pcs->pci_isp.isp_osinfo.fc, M_DEVBUF); in isp_pci_detach()
708 pcs->pci_isp.isp_osinfo.fc = NULL; in isp_pci_detach()
710 mtx_destroy(&isp->isp_lock); in isp_pci_detach()
711 return (0); in isp_pci_detach()
714 #define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off)) argument
715 #define BXW2(isp, off, v) bus_write_2((isp)->isp_regs, (off), (v)) argument
716 #define BXR4(isp, off) bus_read_4((isp)->isp_regs, (off)) argument
717 #define BXW4(isp, off, v) bus_write_4((isp)->isp_regs, (off), (v)) argument
718 #define B2R4(isp, off) bus_read_4((isp)->isp_regs2, (off)) argument
719 #define B2W4(isp, off, v) bus_write_4((isp)->isp_regs2, (off), (v)) argument
722 isp_pci_run_isr_2400(ispsoftc_t *isp) in isp_pci_run_isr_2400() argument
727 r2hisr = BXR4(isp, BIU2400_R2HSTS); in isp_pci_run_isr_2400()
728 isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr); in isp_pci_run_isr_2400()
729 if ((r2hisr & BIU_R2HST_INTR) == 0) in isp_pci_run_isr_2400()
738 isp_intr_mbox(isp, info); in isp_pci_run_isr_2400()
741 isp_intr_async(isp, info); in isp_pci_run_isr_2400()
744 isp_intr_respq(isp); in isp_pci_run_isr_2400()
750 isp_intr_respq(isp); in isp_pci_run_isr_2400()
755 isp_intr_atioq(isp); in isp_pci_run_isr_2400()
759 isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr); in isp_pci_run_isr_2400()
761 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); in isp_pci_run_isr_2400()
765 isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff) in isp_pci_rd_reg_2400() argument
771 return (BXR4(isp, regoff)); in isp_pci_rd_reg_2400()
773 return (BXR2(isp, regoff)); in isp_pci_rd_reg_2400()
775 isp_prt(isp, ISP_LOGERR, "unknown block read at 0x%x", regoff); in isp_pci_rd_reg_2400()
776 return (0xffffffff); in isp_pci_rd_reg_2400()
780 isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val) in isp_pci_wr_reg_2400() argument
786 BXW4(isp, regoff, val); in isp_pci_wr_reg_2400()
792 MEMORYBARRIERW(isp, SYNC_REG, regoff, 4, -1) in isp_pci_wr_reg_2400()
795 MEMORYBARRIER(isp, SYNC_REG, regoff, 4, -1); in isp_pci_wr_reg_2400()
798 BXW2(isp, regoff, val); in isp_pci_wr_reg_2400()
799 MEMORYBARRIER(isp, SYNC_REG, regoff, 2, -1); in isp_pci_wr_reg_2400()
802 isp_prt(isp, ISP_LOGERR, "unknown block write at 0x%x", regoff); in isp_pci_wr_reg_2400()
806 isp_pci_rd_reg_2600(ispsoftc_t *isp, int regoff) in isp_pci_rd_reg_2600() argument
813 isp_prt(isp, ISP_LOGERR, "unknown register read at 0x%x", in isp_pci_rd_reg_2600()
815 rv = 0xffffffff; in isp_pci_rd_reg_2600()
818 rv = B2R4(isp, 0x00); in isp_pci_rd_reg_2600()
821 rv = B2R4(isp, 0x04); in isp_pci_rd_reg_2600()
824 rv = B2R4(isp, 0x08); in isp_pci_rd_reg_2600()
827 rv = B2R4(isp, 0x0c); in isp_pci_rd_reg_2600()
830 rv = B2R4(isp, 0x10); in isp_pci_rd_reg_2600()
833 rv = B2R4(isp, 0x14); in isp_pci_rd_reg_2600()
836 rv = isp_pci_rd_reg_2400(isp, regoff); in isp_pci_rd_reg_2600()
843 isp_pci_wr_reg_2600(ispsoftc_t *isp, int regoff, uint32_t val) in isp_pci_wr_reg_2600() argument
850 isp_prt(isp, ISP_LOGERR, "unknown register write at 0x%x", in isp_pci_wr_reg_2600()
854 off = 0x00; in isp_pci_wr_reg_2600()
857 off = 0x04; in isp_pci_wr_reg_2600()
860 off = 0x08; in isp_pci_wr_reg_2600()
863 off = 0x0c; in isp_pci_wr_reg_2600()
866 off = 0x10; in isp_pci_wr_reg_2600()
869 off = 0x14; in isp_pci_wr_reg_2600()
872 isp_pci_wr_reg_2400(isp, regoff, val); in isp_pci_wr_reg_2600()
875 B2W4(isp, off, val); in isp_pci_wr_reg_2600()
889 if (!(imushp->error = error)) in imc()
890 imushp->maddr = segs[0].ds_addr; in imc()
894 isp_pci_mbxdma(ispsoftc_t *isp) in isp_pci_mbxdma() argument
907 if (isp->isp_xflist != NULL) in isp_pci_mbxdma()
908 return (0); in isp_pci_mbxdma()
909 if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0) in isp_pci_mbxdma()
910 return (0); in isp_pci_mbxdma()
911 ISP_UNLOCK(isp); in isp_pci_mbxdma()
913 ptag = bus_get_dma_tag(isp->isp_osinfo.dev); in isp_pci_mbxdma()
919 if (isp->isp_rquest != NULL) in isp_pci_mbxdma()
925 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); in isp_pci_mbxdma()
928 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { in isp_pci_mbxdma()
929 isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); in isp_pci_mbxdma()
932 if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base, in isp_pci_mbxdma()
933 BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) { in isp_pci_mbxdma()
934 isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory"); in isp_pci_mbxdma()
935 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); in isp_pci_mbxdma()
938 isp->isp_rquest = base; in isp_pci_mbxdma()
939 im.error = 0; in isp_pci_mbxdma()
940 if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap, in isp_pci_mbxdma()
942 isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error); in isp_pci_mbxdma()
945 isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx", in isp_pci_mbxdma()
947 isp->isp_rquest_dma = im.maddr; in isp_pci_mbxdma()
956 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { in isp_pci_mbxdma()
957 isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); in isp_pci_mbxdma()
960 if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, in isp_pci_mbxdma()
961 BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { in isp_pci_mbxdma()
962 isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); in isp_pci_mbxdma()
963 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); in isp_pci_mbxdma()
966 isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; in isp_pci_mbxdma()
967 im.error = 0; in isp_pci_mbxdma()
968 if (bus_dmamap_load(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_map, in isp_pci_mbxdma()
970 isp_prt(isp, ISP_LOGERR, "error loading ECMD DMA map %d", im.error); in isp_pci_mbxdma()
973 isp_prt(isp, ISP_LOGDEBUG0, "ecmd area @ 0x%jx/0x%jx", in isp_pci_mbxdma()
976 isp->isp_osinfo.ecmd_dma = im.maddr; in isp_pci_mbxdma()
977 isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)base; in isp_pci_mbxdma()
978 for (ecmd = isp->isp_osinfo.ecmd_free; in isp_pci_mbxdma()
979 ecmd < &isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) { in isp_pci_mbxdma()
980 if (ecmd == &isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) in isp_pci_mbxdma()
981 ecmd->next = NULL; in isp_pci_mbxdma()
983 ecmd->next = ecmd + 1; in isp_pci_mbxdma()
990 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); in isp_pci_mbxdma()
993 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.respdmat)) { in isp_pci_mbxdma()
994 isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); in isp_pci_mbxdma()
997 if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base, in isp_pci_mbxdma()
998 BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) { in isp_pci_mbxdma()
999 isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory"); in isp_pci_mbxdma()
1000 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); in isp_pci_mbxdma()
1003 isp->isp_result = base; in isp_pci_mbxdma()
1004 im.error = 0; in isp_pci_mbxdma()
1005 if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap, in isp_pci_mbxdma()
1007 isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error); in isp_pci_mbxdma()
1010 isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx", in isp_pci_mbxdma()
1012 isp->isp_result_dma = im.maddr; in isp_pci_mbxdma()
1018 len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp)); in isp_pci_mbxdma()
1021 len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) { in isp_pci_mbxdma()
1022 isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag"); in isp_pci_mbxdma()
1025 if (bus_dmamem_alloc(isp->isp_osinfo.atiodmat, (void **)&base, in isp_pci_mbxdma()
1026 BUS_DMA_COHERENT, &isp->isp_osinfo.atiomap) != 0) { in isp_pci_mbxdma()
1027 isp_prt(isp, ISP_LOGERR, "cannot allocate ATIO DMA memory"); in isp_pci_mbxdma()
1028 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); in isp_pci_mbxdma()
1031 isp->isp_atioq = base; in isp_pci_mbxdma()
1032 im.error = 0; in isp_pci_mbxdma()
1033 if (bus_dmamap_load(isp->isp_osinfo.atiodmat, isp->isp_osinfo.atiomap, in isp_pci_mbxdma()
1035 isp_prt(isp, ISP_LOGERR, "error loading ATIO DMA map %d", im.error); in isp_pci_mbxdma()
1038 isp_prt(isp, ISP_LOGDEBUG0, "ATIO area @ 0x%jx/0x%jx", in isp_pci_mbxdma()
1040 isp->isp_atioq_dma = im.maddr; in isp_pci_mbxdma()
1045 2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, NULL, NULL, in isp_pci_mbxdma()
1046 &isp->isp_osinfo.iocbdmat)) { in isp_pci_mbxdma()
1049 if (bus_dmamem_alloc(isp->isp_osinfo.iocbdmat, in isp_pci_mbxdma()
1050 (void **)&base, BUS_DMA_COHERENT, &isp->isp_osinfo.iocbmap) != 0) in isp_pci_mbxdma()
1052 isp->isp_iocb = base; in isp_pci_mbxdma()
1053 im.error = 0; in isp_pci_mbxdma()
1054 if (bus_dmamap_load(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, in isp_pci_mbxdma()
1057 isp->isp_iocb_dma = im.maddr; in isp_pci_mbxdma()
1061 ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, NULL, NULL, in isp_pci_mbxdma()
1062 &isp->isp_osinfo.scdmat)) in isp_pci_mbxdma()
1064 for (cmap = 0; cmap < isp->isp_nchan; cmap++) { in isp_pci_mbxdma()
1065 struct isp_fc *fc = ISP_FC_PC(isp, cmap); in isp_pci_mbxdma()
1066 if (bus_dmamem_alloc(isp->isp_osinfo.scdmat, in isp_pci_mbxdma()
1067 (void **)&base, BUS_DMA_COHERENT, &fc->scmap) != 0) in isp_pci_mbxdma()
1069 FCPARAM(isp, cmap)->isp_scratch = base; in isp_pci_mbxdma()
1070 im.error = 0; in isp_pci_mbxdma()
1071 if (bus_dmamap_load(isp->isp_osinfo.scdmat, fc->scmap, in isp_pci_mbxdma()
1074 bus_dmamem_free(isp->isp_osinfo.scdmat, in isp_pci_mbxdma()
1075 base, fc->scmap); in isp_pci_mbxdma()
1076 FCPARAM(isp, cmap)->isp_scratch = NULL; in isp_pci_mbxdma()
1079 FCPARAM(isp, cmap)->isp_scdma = im.maddr; in isp_pci_mbxdma()
1080 for (i = 0; i < INITIAL_NEXUS_COUNT; i++) { in isp_pci_mbxdma()
1083 while (fc->nexus_free_list) { in isp_pci_mbxdma()
1084 n = fc->nexus_free_list; in isp_pci_mbxdma()
1085 fc->nexus_free_list = n->next; in isp_pci_mbxdma()
1090 n->next = fc->nexus_free_list; in isp_pci_mbxdma()
1091 fc->nexus_free_list = n; in isp_pci_mbxdma()
1095 if (isp->isp_maxcmds == 0) { in isp_pci_mbxdma()
1096 ISP_LOCK(isp); in isp_pci_mbxdma()
1097 return (0); in isp_pci_mbxdma()
1103 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, ISP_NSEG64_MAX, in isp_pci_mbxdma()
1104 (ISP_NSEG64_MAX - 1) * PAGE_SIZE, 0, in isp_pci_mbxdma()
1105 busdma_lock_mutex, &isp->isp_lock, &isp->isp_osinfo.dmat)) in isp_pci_mbxdma()
1107 len = isp->isp_maxcmds * sizeof (struct isp_pcmd); in isp_pci_mbxdma()
1108 isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) in isp_pci_mbxdma()
1110 for (i = 0; i < isp->isp_maxcmds; i++) { in isp_pci_mbxdma()
1111 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; in isp_pci_mbxdma()
1112 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); in isp_pci_mbxdma()
1114 isp_prt(isp, ISP_LOGERR, "error %d creating per-cmd DMA maps", error); in isp_pci_mbxdma()
1115 while (--i >= 0) { in isp_pci_mbxdma()
1116 bus_dmamap_destroy(isp->isp_osinfo.dmat, in isp_pci_mbxdma()
1117 isp->isp_osinfo.pcmd_pool[i].dmap); in isp_pci_mbxdma()
1121 callout_init_mtx(&pcmd->wdog, &isp->isp_lock, 0); in isp_pci_mbxdma()
1122 if (i == isp->isp_maxcmds-1) in isp_pci_mbxdma()
1123 pcmd->next = NULL; in isp_pci_mbxdma()
1125 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; in isp_pci_mbxdma()
1127 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; in isp_pci_mbxdma()
1129 len = sizeof(isp_hdl_t) * ISP_HANDLE_NUM(isp); in isp_pci_mbxdma()
1130 isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); in isp_pci_mbxdma()
1131 for (len = 0; len < ISP_HANDLE_NUM(isp) - 1; len++) in isp_pci_mbxdma()
1132 isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; in isp_pci_mbxdma()
1133 isp->isp_xffree = isp->isp_xflist; in isp_pci_mbxdma()
1135 ISP_LOCK(isp); in isp_pci_mbxdma()
1136 return (0); in isp_pci_mbxdma()
1139 isp_pci_mbxdmafree(isp); in isp_pci_mbxdma()
1140 ISP_LOCK(isp); in isp_pci_mbxdma()
1145 isp_pci_mbxdmafree(ispsoftc_t *isp) in isp_pci_mbxdmafree() argument
1149 if (isp->isp_xflist != NULL) { in isp_pci_mbxdmafree()
1150 free(isp->isp_xflist, M_DEVBUF); in isp_pci_mbxdmafree()
1151 isp->isp_xflist = NULL; in isp_pci_mbxdmafree()
1153 if (isp->isp_osinfo.pcmd_pool != NULL) { in isp_pci_mbxdmafree()
1154 for (i = 0; i < isp->isp_maxcmds; i++) { in isp_pci_mbxdmafree()
1155 bus_dmamap_destroy(isp->isp_osinfo.dmat, in isp_pci_mbxdmafree()
1156 isp->isp_osinfo.pcmd_pool[i].dmap); in isp_pci_mbxdmafree()
1158 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); in isp_pci_mbxdmafree()
1159 isp->isp_osinfo.pcmd_pool = NULL; in isp_pci_mbxdmafree()
1161 if (isp->isp_osinfo.dmat) { in isp_pci_mbxdmafree()
1162 bus_dma_tag_destroy(isp->isp_osinfo.dmat); in isp_pci_mbxdmafree()
1163 isp->isp_osinfo.dmat = NULL; in isp_pci_mbxdmafree()
1165 for (i = 0; i < isp->isp_nchan; i++) { in isp_pci_mbxdmafree()
1166 struct isp_fc *fc = ISP_FC_PC(isp, i); in isp_pci_mbxdmafree()
1167 if (FCPARAM(isp, i)->isp_scdma != 0) { in isp_pci_mbxdmafree()
1168 bus_dmamap_unload(isp->isp_osinfo.scdmat, in isp_pci_mbxdmafree()
1169 fc->scmap); in isp_pci_mbxdmafree()
1170 FCPARAM(isp, i)->isp_scdma = 0; in isp_pci_mbxdmafree()
1172 if (FCPARAM(isp, i)->isp_scratch != NULL) { in isp_pci_mbxdmafree()
1173 bus_dmamem_free(isp->isp_osinfo.scdmat, in isp_pci_mbxdmafree()
1174 FCPARAM(isp, i)->isp_scratch, fc->scmap); in isp_pci_mbxdmafree()
1175 FCPARAM(isp, i)->isp_scratch = NULL; in isp_pci_mbxdmafree()
1177 while (fc->nexus_free_list) { in isp_pci_mbxdmafree()
1178 struct isp_nexus *n = fc->nexus_free_list; in isp_pci_mbxdmafree()
1179 fc->nexus_free_list = n->next; in isp_pci_mbxdmafree()
1183 if (isp->isp_osinfo.scdmat) { in isp_pci_mbxdmafree()
1184 bus_dma_tag_destroy(isp->isp_osinfo.scdmat); in isp_pci_mbxdmafree()
1185 isp->isp_osinfo.scdmat = NULL; in isp_pci_mbxdmafree()
1187 if (isp->isp_iocb_dma != 0) { in isp_pci_mbxdmafree()
1188 bus_dmamap_unload(isp->isp_osinfo.iocbdmat, in isp_pci_mbxdmafree()
1189 isp->isp_osinfo.iocbmap); in isp_pci_mbxdmafree()
1190 isp->isp_iocb_dma = 0; in isp_pci_mbxdmafree()
1192 if (isp->isp_iocb != NULL) { in isp_pci_mbxdmafree()
1193 bus_dmamem_free(isp->isp_osinfo.iocbdmat, in isp_pci_mbxdmafree()
1194 isp->isp_iocb, isp->isp_osinfo.iocbmap); in isp_pci_mbxdmafree()
1195 bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat); in isp_pci_mbxdmafree()
1198 if (isp->isp_atioq_dma != 0) { in isp_pci_mbxdmafree()
1199 bus_dmamap_unload(isp->isp_osinfo.atiodmat, in isp_pci_mbxdmafree()
1200 isp->isp_osinfo.atiomap); in isp_pci_mbxdmafree()
1201 isp->isp_atioq_dma = 0; in isp_pci_mbxdmafree()
1203 if (isp->isp_atioq != NULL) { in isp_pci_mbxdmafree()
1204 bus_dmamem_free(isp->isp_osinfo.atiodmat, isp->isp_atioq, in isp_pci_mbxdmafree()
1205 isp->isp_osinfo.atiomap); in isp_pci_mbxdmafree()
1206 bus_dma_tag_destroy(isp->isp_osinfo.atiodmat); in isp_pci_mbxdmafree()
1207 isp->isp_atioq = NULL; in isp_pci_mbxdmafree()
1210 if (isp->isp_result_dma != 0) { in isp_pci_mbxdmafree()
1211 bus_dmamap_unload(isp->isp_osinfo.respdmat, in isp_pci_mbxdmafree()
1212 isp->isp_osinfo.respmap); in isp_pci_mbxdmafree()
1213 isp->isp_result_dma = 0; in isp_pci_mbxdmafree()
1215 if (isp->isp_result != NULL) { in isp_pci_mbxdmafree()
1216 bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result, in isp_pci_mbxdmafree()
1217 isp->isp_osinfo.respmap); in isp_pci_mbxdmafree()
1218 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); in isp_pci_mbxdmafree()
1219 isp->isp_result = NULL; in isp_pci_mbxdmafree()
1222 if (isp->isp_osinfo.ecmd_dma != 0) { in isp_pci_mbxdmafree()
1223 bus_dmamap_unload(isp->isp_osinfo.ecmd_dmat, in isp_pci_mbxdmafree()
1224 isp->isp_osinfo.ecmd_map); in isp_pci_mbxdmafree()
1225 isp->isp_osinfo.ecmd_dma = 0; in isp_pci_mbxdmafree()
1227 if (isp->isp_osinfo.ecmd_base != NULL) { in isp_pci_mbxdmafree()
1228 bus_dmamem_free(isp->isp_osinfo.ecmd_dmat, isp->isp_osinfo.ecmd_base, in isp_pci_mbxdmafree()
1229 isp->isp_osinfo.ecmd_map); in isp_pci_mbxdmafree()
1230 bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); in isp_pci_mbxdmafree()
1231 isp->isp_osinfo.ecmd_base = NULL; in isp_pci_mbxdmafree()
1234 if (isp->isp_rquest_dma != 0) { in isp_pci_mbxdmafree()
1235 bus_dmamap_unload(isp->isp_osinfo.reqdmat, in isp_pci_mbxdmafree()
1236 isp->isp_osinfo.reqmap); in isp_pci_mbxdmafree()
1237 isp->isp_rquest_dma = 0; in isp_pci_mbxdmafree()
1239 if (isp->isp_rquest != NULL) { in isp_pci_mbxdmafree()
1240 bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest, in isp_pci_mbxdmafree()
1241 isp->isp_osinfo.reqmap); in isp_pci_mbxdmafree()
1242 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); in isp_pci_mbxdmafree()
1243 isp->isp_rquest = NULL; in isp_pci_mbxdmafree()
1248 isp_pci_irqsetup(ispsoftc_t *isp) in isp_pci_irqsetup() argument
1250 device_t dev = isp->isp_osinfo.dev; in isp_pci_irqsetup()
1256 if (isp->isp_nirq > 0) in isp_pci_irqsetup()
1257 return (0); in isp_pci_irqsetup()
1259 ISP_UNLOCK(isp); in isp_pci_irqsetup()
1260 if (ISP_CAP_MSIX(isp)) { in isp_pci_irqsetup()
1261 max_irq = IS_26XX(isp) ? 3 : (IS_25XX(isp) ? 2 : 0); in isp_pci_irqsetup()
1265 pcs->msicount = imin(pci_msix_count(dev), max_irq); in isp_pci_irqsetup()
1266 if (pcs->msicount > 0 && in isp_pci_irqsetup()
1267 pci_alloc_msix(dev, &pcs->msicount) != 0) in isp_pci_irqsetup()
1268 pcs->msicount = 0; in isp_pci_irqsetup()
1270 if (pcs->msicount == 0) { in isp_pci_irqsetup()
1275 pcs->msicount = imin(pci_msi_count(dev), max_irq); in isp_pci_irqsetup()
1276 if (pcs->msicount > 0 && in isp_pci_irqsetup()
1277 pci_alloc_msi(dev, &pcs->msicount) != 0) in isp_pci_irqsetup()
1278 pcs->msicount = 0; in isp_pci_irqsetup()
1280 for (i = 0; i < MAX(1, pcs->msicount); i++) { in isp_pci_irqsetup()
1281 pcs->irq[i].iqd = i + (pcs->msicount > 0); in isp_pci_irqsetup()
1282 pcs->irq[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, in isp_pci_irqsetup()
1283 &pcs->irq[i].iqd, RF_ACTIVE | RF_SHAREABLE); in isp_pci_irqsetup()
1284 if (pcs->irq[i].irq == NULL) { in isp_pci_irqsetup()
1288 if (i == 0) in isp_pci_irqsetup()
1294 if (bus_setup_intr(dev, pcs->irq[i].irq, ISP_IFLAGS, NULL, in isp_pci_irqsetup()
1295 f, isp, &pcs->irq[i].ih)) { in isp_pci_irqsetup()
1298 pcs->irq[i].iqd, pcs->irq[i].irq); in isp_pci_irqsetup()
1301 if (pcs->msicount > 1) { in isp_pci_irqsetup()
1302 bus_describe_intr(dev, pcs->irq[i].irq, pcs->irq[i].ih, in isp_pci_irqsetup()
1305 isp->isp_nirq = i + 1; in isp_pci_irqsetup()
1307 ISP_LOCK(isp); in isp_pci_irqsetup()
1309 return (isp->isp_nirq == 0); in isp_pci_irqsetup()