X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/f3c3de585db0822eb4ec29588b57f95ff7d00221..f0731c1e48b5fcc4040fc3922524bdb6ba4af230:/sys/dev/disk/mpt/mpt_pci.c diff --git a/sys/dev/disk/mpt/mpt_pci.c b/sys/dev/disk/mpt/mpt_pci.c index b6d60c462d..ae8f8cade4 100644 --- a/sys/dev/disk/mpt/mpt_pci.c +++ b/sys/dev/disk/mpt/mpt_pci.c @@ -97,95 +97,53 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.61 2011/04/22 09:59:16 marius Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.70 2012/04/04 20:42:45 marius Exp $ */ #include #include #include -#ifndef PCI_VENDOR_LSI -#define PCI_VENDOR_LSI 0x1000 -#endif - -#ifndef PCI_PRODUCT_LSI_FC909 -#define PCI_PRODUCT_LSI_FC909 0x0620 -#endif - -#ifndef PCI_PRODUCT_LSI_FC909A -#define PCI_PRODUCT_LSI_FC909A 0x0621 -#endif - -#ifndef PCI_PRODUCT_LSI_FC919 -#define PCI_PRODUCT_LSI_FC919 0x0624 -#endif - -#ifndef PCI_PRODUCT_LSI_FC929 -#define PCI_PRODUCT_LSI_FC929 0x0622 -#endif - -#ifndef PCI_PRODUCT_LSI_FC929X -#define PCI_PRODUCT_LSI_FC929X 0x0626 -#endif - -#ifndef PCI_PRODUCT_LSI_FC919X -#define PCI_PRODUCT_LSI_FC919X 0x0628 -#endif - -#ifndef PCI_PRODUCT_LSI_FC7X04X -#define PCI_PRODUCT_LSI_FC7X04X 0x0640 -#endif - -#ifndef PCI_PRODUCT_LSI_FC646 -#define PCI_PRODUCT_LSI_FC646 0x0646 -#endif - -#ifndef PCI_PRODUCT_LSI_1030 -#define PCI_PRODUCT_LSI_1030 0x0030 -#endif - -#ifndef PCI_PRODUCT_LSI_SAS1064 -#define PCI_PRODUCT_LSI_SAS1064 0x0050 -#endif +/* + * XXX it seems no other MPT driver knows about the following chips. + */ -#ifndef PCI_PRODUCT_LSI_SAS1064A -#define PCI_PRODUCT_LSI_SAS1064A 0x005C +#ifndef MPI_MANUFACTPAGE_DEVICEID_FC909_FB +#define MPI_MANUFACTPAGE_DEVICEID_FC909_FB 0x0620 #endif -#ifndef PCI_PRODUCT_LSI_SAS1064E -#define PCI_PRODUCT_LSI_SAS1064E 0x0056 +#ifndef MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB +#define MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB 0x0625 #endif -#ifndef PCI_PRODUCT_LSI_SAS1066 -#define PCI_PRODUCT_LSI_SAS1066 0x005E +#ifndef MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB +#define MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB 0x0623 #endif -#ifndef PCI_PRODUCT_LSI_SAS1066E -#define PCI_PRODUCT_LSI_SAS1066E 0x005A +#ifndef MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB +#define MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB 0x0627 #endif -#ifndef PCI_PRODUCT_LSI_SAS1068 -#define PCI_PRODUCT_LSI_SAS1068 0x0054 +#ifndef MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB +#define MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB 0x0629 #endif -#ifndef PCI_PRODUCT_LSI_SAS1068E -#define PCI_PRODUCT_LSI_SAS1068E 0x0058 +#ifndef MPI_MANUFACTPAGE_DEVID_SAS1068A_FB +#define MPI_MANUFACTPAGE_DEVID_SAS1068A_FB 0x0055 #endif -#ifndef PCI_PRODUCT_LSI_SAS1078 -#define PCI_PRODUCT_LSI_SAS1078 0x0062 +#ifndef MPI_MANUFACTPAGE_DEVID_SAS1068E_FB +#define MPI_MANUFACTPAGE_DEVID_SAS1068E_FB 0x0059 #endif -#ifndef PCI_PRODUCT_LSI_SAS1078DE -#define PCI_PRODUCT_LSI_SAS1078DE 0x007C +#ifndef MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB +#define MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB 0x007C #endif #ifndef PCIM_CMD_SERRESPEN #define PCIM_CMD_SERRESPEN 0x0100 #endif - - static int mpt_pci_probe(device_t); static int mpt_pci_attach(device_t); static void mpt_free_bus_resources(struct mpt_softc *mpt); @@ -193,7 +151,10 @@ static int mpt_pci_detach(device_t); static int mpt_pci_shutdown(device_t); static int mpt_dma_mem_alloc(struct mpt_softc *mpt); static void mpt_dma_mem_free(struct mpt_softc *mpt); +#if 0 static void mpt_read_config_regs(struct mpt_softc *mpt); +static void mpt_set_config_regs(struct mpt_softc *mpt); +#endif static void mpt_pci_intr(void *); static device_method_t mpt_methods[] = { @@ -216,49 +177,71 @@ MODULE_VERSION(mpt, 1); static int mpt_pci_probe(device_t dev) { - char *desc; + const char *desc; + int rval; - if (pci_get_vendor(dev) != PCI_VENDOR_LSI) { + if (pci_get_vendor(dev) != MPI_MANUFACTPAGE_VENDORID_LSILOGIC) return (ENXIO); - } - switch ((pci_get_device(dev) & ~1)) { - case PCI_PRODUCT_LSI_FC909: + rval = BUS_PROBE_DEFAULT; + switch (pci_get_device(dev)) { + case MPI_MANUFACTPAGE_DEVICEID_FC909_FB: desc = "LSILogic FC909 FC Adapter"; break; - case PCI_PRODUCT_LSI_FC909A: + case MPI_MANUFACTPAGE_DEVICEID_FC909: desc = "LSILogic FC909A FC Adapter"; break; - case PCI_PRODUCT_LSI_FC919: + case MPI_MANUFACTPAGE_DEVICEID_FC919: desc = "LSILogic FC919 FC Adapter"; break; - case PCI_PRODUCT_LSI_FC929: + case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB: + desc = "LSILogic FC919 LAN Adapter"; + break; + case MPI_MANUFACTPAGE_DEVICEID_FC929: desc = "Dual LSILogic FC929 FC Adapter"; break; - case PCI_PRODUCT_LSI_FC919X: + case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: + desc = "Dual LSILogic FC929 LAN Adapter"; + break; + case MPI_MANUFACTPAGE_DEVICEID_FC919X: desc = "LSILogic FC919 FC PCI-X Adapter"; break; - case PCI_PRODUCT_LSI_FC929X: + case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB: + desc = "LSILogic FC919 LAN PCI-X Adapter"; + break; + case MPI_MANUFACTPAGE_DEVICEID_FC929X: desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter"; break; - case PCI_PRODUCT_LSI_FC646: + case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB: + desc = "Dual LSILogic FC929X LAN PCI-X Adapter"; + break; + case MPI_MANUFACTPAGE_DEVICEID_FC949E: desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter"; break; - case PCI_PRODUCT_LSI_FC7X04X: + case MPI_MANUFACTPAGE_DEVICEID_FC949X: desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter"; break; - case PCI_PRODUCT_LSI_1030: + case MPI_MANUFACTPAGE_DEVID_53C1030: + case MPI_MANUFACTPAGE_DEVID_53C1030ZC: desc = "LSILogic 1030 Ultra4 Adapter"; break; - case PCI_PRODUCT_LSI_SAS1064: - case PCI_PRODUCT_LSI_SAS1064A: - case PCI_PRODUCT_LSI_SAS1064E: - case PCI_PRODUCT_LSI_SAS1066: - case PCI_PRODUCT_LSI_SAS1066E: - case PCI_PRODUCT_LSI_SAS1068: - case PCI_PRODUCT_LSI_SAS1068E: - case PCI_PRODUCT_LSI_SAS1078: - case PCI_PRODUCT_LSI_SAS1078DE: + case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB: + /* + * Allow mfi(4) to claim this device in case it's in MegaRAID + * mode. + */ + rval = BUS_PROBE_LOW_PRIORITY; + /* FALLTHROUGH */ + case MPI_MANUFACTPAGE_DEVID_SAS1064: + case MPI_MANUFACTPAGE_DEVID_SAS1064A: + case MPI_MANUFACTPAGE_DEVID_SAS1064E: + case MPI_MANUFACTPAGE_DEVID_SAS1066: + case MPI_MANUFACTPAGE_DEVID_SAS1066E: + case MPI_MANUFACTPAGE_DEVID_SAS1068: + case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB: + case MPI_MANUFACTPAGE_DEVID_SAS1068E: + case MPI_MANUFACTPAGE_DEVID_SAS1078: + case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB: desc = "LSILogic SAS/SATA Adapter"; break; default: @@ -266,13 +249,14 @@ mpt_pci_probe(device_t dev) } device_set_desc(dev, desc); - return (0); + return (rval); } static void mpt_set_options(struct mpt_softc *mpt) { int bitmap; + int tval; bitmap = 0; if (kgetenv_int("mpt_disable", &bitmap)) { @@ -327,10 +311,14 @@ mpt_set_options(struct mpt_softc *mpt) } mpt->do_cfg_role = 1; } + tval = 0; mpt->msi_enable = 0; + if (mpt->is_sas) + mpt->msi_enable = 1; + if (kgetenv_int("hw.mpt.msi.enable", &tval)) + mpt->msi_enable = tval; } - static void mpt_link_peer(struct mpt_softc *mpt) { @@ -364,12 +352,12 @@ mpt_link_peer(struct mpt_softc *mpt) static void mpt_unlink_peer(struct mpt_softc *mpt) { + if (mpt->mpt2) { mpt->mpt2->mpt2 = NULL; } } - static int mpt_pci_attach(device_t dev) { @@ -377,33 +365,38 @@ mpt_pci_attach(device_t dev) int iqd; uint32_t data, cmd; int mpt_io_bar, mpt_mem_bar; + u_int irq_flags; - /* Allocate the softc structure */ mpt = (struct mpt_softc*)device_get_softc(dev); - if (mpt == NULL) { - device_printf(dev, "cannot allocate softc\n"); - return (ENOMEM); - } - memset(mpt, 0, sizeof(struct mpt_softc)); - switch ((pci_get_device(dev) & ~1)) { - case PCI_PRODUCT_LSI_FC909: - case PCI_PRODUCT_LSI_FC909A: - case PCI_PRODUCT_LSI_FC919: - case PCI_PRODUCT_LSI_FC929: - case PCI_PRODUCT_LSI_FC919X: - case PCI_PRODUCT_LSI_FC646: - case PCI_PRODUCT_LSI_FC7X04X: + + switch (pci_get_device(dev)) { + case MPI_MANUFACTPAGE_DEVICEID_FC909_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC909: + case MPI_MANUFACTPAGE_DEVICEID_FC919: + case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC929: + case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC929X: + case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC919X: + case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC949E: + case MPI_MANUFACTPAGE_DEVICEID_FC949X: mpt->is_fc = 1; break; - case PCI_PRODUCT_LSI_SAS1064: - case PCI_PRODUCT_LSI_SAS1064A: - case PCI_PRODUCT_LSI_SAS1064E: - case PCI_PRODUCT_LSI_SAS1066: - case PCI_PRODUCT_LSI_SAS1066E: - case PCI_PRODUCT_LSI_SAS1068: - case PCI_PRODUCT_LSI_SAS1068E: - case PCI_PRODUCT_LSI_SAS1078: - case PCI_PRODUCT_LSI_SAS1078DE: + case MPI_MANUFACTPAGE_DEVID_SAS1078: + case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB: + mpt->is_1078 = 1; + /* FALLTHROUGH */ + case MPI_MANUFACTPAGE_DEVID_SAS1064: + case MPI_MANUFACTPAGE_DEVID_SAS1064A: + case MPI_MANUFACTPAGE_DEVID_SAS1064E: + case MPI_MANUFACTPAGE_DEVID_SAS1066: + case MPI_MANUFACTPAGE_DEVID_SAS1066E: + case MPI_MANUFACTPAGE_DEVID_SAS1068: + case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB: + case MPI_MANUFACTPAGE_DEVID_SAS1068E: + case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB: mpt->is_sas = 1; break; default: @@ -450,11 +443,17 @@ mpt_pci_attach(device_t dev) * Is this part a dual? * If so, link with our partner (around yet) */ - if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 || - (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC646 || - (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC7X04X || - (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) { + switch (pci_get_device(dev)) { + case MPI_MANUFACTPAGE_DEVICEID_FC929: + case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: + case MPI_MANUFACTPAGE_DEVICEID_FC949E: + case MPI_MANUFACTPAGE_DEVICEID_FC949X: + case MPI_MANUFACTPAGE_DEVID_53C1030: + case MPI_MANUFACTPAGE_DEVID_53C1030ZC: mpt_link_peer(mpt); + break; + default: + break; } /* @@ -476,27 +475,34 @@ mpt_pci_attach(device_t dev) * certain reset operations (but must be disabled for * some cards otherwise). */ - mpt->pci_pio_rid = PCIR_BAR(mpt_io_bar); + mpt_io_bar = PCIR_BAR(mpt_io_bar); mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, - &mpt->pci_pio_rid, RF_ACTIVE); + &mpt_io_bar, RF_ACTIVE); if (mpt->pci_pio_reg == NULL) { - device_printf(dev, "unable to map registers in PIO mode\n"); - goto bad; + if (bootverbose) { + device_printf(dev, + "unable to map registers in PIO mode\n"); + } + } else { + mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg); + mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); } - mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg); - mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); - /* Allocate kernel virtual memory for the 9x9's Mem0 region */ - mpt->pci_mem_rid = PCIR_BAR(mpt_mem_bar); + mpt_mem_bar = PCIR_BAR(mpt_mem_bar); mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &mpt->pci_mem_rid, RF_ACTIVE); + &mpt_mem_bar, RF_ACTIVE); if (mpt->pci_reg == NULL) { - device_printf(dev, "Unable to memory map registers.\n"); - if (mpt->is_sas) { + if (bootverbose || mpt->is_sas || mpt->pci_pio_reg == NULL) { + device_printf(dev, + "Unable to memory map registers.\n"); + } + if (mpt->is_sas || mpt->pci_pio_reg == NULL) { device_printf(dev, "Giving Up.\n"); goto bad; } - device_printf(dev, "Falling back to PIO mode.\n"); + if (bootverbose) { + device_printf(dev, "Falling back to PIO mode.\n"); + } mpt->pci_st = mpt->pci_pio_st; mpt->pci_sh = mpt->pci_pio_sh; } else { @@ -520,18 +526,12 @@ mpt_pci_attach(device_t dev) mpt->pci_msi_count = 0; } } - if (iqd == 0 && pci_msi_count(dev) == 1) { - mpt->pci_msi_count = 1; - if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) { - iqd = 1; - } else { - mpt->pci_msi_count = 0; - } - } } #endif + mpt->irq_type = pci_alloc_1intr(dev, mpt->msi_enable, &iqd, + &irq_flags); mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, - RF_ACTIVE | RF_SHAREABLE); + irq_flags); if (mpt->pci_irq == NULL) { device_printf(dev, "could not allocate interrupt\n"); goto bad; @@ -543,19 +543,19 @@ mpt_pci_attach(device_t dev) mpt_disable_ints(mpt); /* Register the interrupt handler */ - if (mpt_setup_intr(dev, mpt->pci_irq, 0, NULL, mpt_pci_intr, + if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr, mpt, &mpt->ih)) { device_printf(dev, "could not setup interrupt\n"); goto bad; } /* Allocate dma memory */ -/* XXX JGibbs -Should really be done based on IOCFacts. */ if (mpt_dma_mem_alloc(mpt)) { mpt_prt(mpt, "Could not allocate DMA memory\n"); goto bad; } +#if 0 /* * Save the PCI config register values * @@ -567,6 +567,7 @@ mpt_pci_attach(device_t dev) */ mpt_read_config_regs(mpt); +#endif /* * Disable PIO until we need it @@ -614,36 +615,34 @@ bad: static void mpt_free_bus_resources(struct mpt_softc *mpt) { + if (mpt->ih) { bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih); - mpt->ih = 0; + mpt->ih = NULL; } if (mpt->pci_irq) { bus_release_resource(mpt->dev, SYS_RES_IRQ, - mpt->pci_msi_count ? 1 : 0, mpt->pci_irq); - mpt->pci_irq = 0; + rman_get_rid(mpt->pci_irq), mpt->pci_irq); + mpt->pci_irq = NULL; } - if (mpt->pci_msi_count) { + if (mpt->irq_type == PCI_INTR_TYPE_MSI) pci_release_msi(mpt->dev); - mpt->pci_msi_count = 0; - } if (mpt->pci_pio_reg) { - bus_release_resource(mpt->dev, SYS_RES_IOPORT, mpt->pci_pio_rid, - mpt->pci_pio_reg); - mpt->pci_pio_reg = 0; + bus_release_resource(mpt->dev, SYS_RES_IOPORT, + rman_get_rid(mpt->pci_pio_reg), mpt->pci_pio_reg); + mpt->pci_pio_reg = NULL; } if (mpt->pci_reg) { - bus_release_resource(mpt->dev, SYS_RES_MEMORY, mpt->pci_mem_rid, - mpt->pci_reg); - mpt->pci_reg = 0; + bus_release_resource(mpt->dev, SYS_RES_MEMORY, + rman_get_rid(mpt->pci_reg), mpt->pci_reg); + mpt->pci_reg = NULL; } MPT_LOCK_DESTROY(mpt); } - /* * Disconnect ourselves from the system. */ @@ -668,7 +667,6 @@ mpt_pci_detach(device_t dev) return(0); } - /* * Disable the hardware */ @@ -755,8 +753,6 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt) return (0); } - - /* Deallocate memory that was allocated by mpt_dma_mem_alloc */ static void @@ -773,18 +769,17 @@ mpt_dma_mem_free(struct mpt_softc *mpt) bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap); bus_dma_tag_destroy(mpt->reply_dmat); bus_dma_tag_destroy(mpt->parent_dmat); - mpt->reply_dmat = 0; + mpt->reply_dmat = NULL; kfree(mpt->request_pool, M_DEVBUF); - mpt->request_pool = 0; - + mpt->request_pool = NULL; } - - +#if 0 /* Reads modifiable (via PCI transactions) config registers */ static void mpt_read_config_regs(struct mpt_softc *mpt) { + mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2); mpt->pci_cfg.LatencyTimer_LineSize = pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2); @@ -799,7 +794,7 @@ mpt_read_config_regs(struct mpt_softc *mpt) } /* Sets modifiable config registers */ -void +static void mpt_set_config_regs(struct mpt_softc *mpt) { uint32_t val; @@ -838,6 +833,7 @@ mpt_set_config_regs(struct mpt_softc *mpt) pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1); pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4); } +#endif static void mpt_pci_intr(void *arg)