summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpt/mpt_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mpt/mpt_pci.c')
-rw-r--r--sys/dev/mpt/mpt_pci.c116
1 files changed, 91 insertions, 25 deletions
diff --git a/sys/dev/mpt/mpt_pci.c b/sys/dev/mpt/mpt_pci.c
index ebc1ac3..cdaec8d 100644
--- a/sys/dev/mpt/mpt_pci.c
+++ b/sys/dev/mpt/mpt_pci.c
@@ -69,13 +69,6 @@ __FBSDID("$FreeBSD$");
#include <dev/mpt/mpt_cam.h>
#include <dev/mpt/mpt_raid.h>
-#if __FreeBSD_version < 500000
-#include <pci/pcireg.h>
-#include <pci/pcivar.h>
-#else
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#endif
#ifndef PCI_VENDOR_LSI
#define PCI_VENDOR_LSI 0x1000
@@ -105,12 +98,43 @@ __FBSDID("$FreeBSD$");
#define PCI_PRODUCT_LSI_1030 0x0030
#endif
+#ifndef PCI_PRODUCT_LSI_SAS1064
+#define PCI_PRODUCT_LSI_SAS1064 0x0050
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1064A
+#define PCI_PRODUCT_LSI_SAS1064A 0x005C
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1064E
+#define PCI_PRODUCT_LSI_SAS1064E 0x0056
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1066
+#define PCI_PRODUCT_LSI_SAS1066 0x005E
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1066E
+#define PCI_PRODUCT_LSI_SAS1066E 0x005A
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1068
+#define PCI_PRODUCT_LSI_SAS1068 0x0054
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1068E
+#define PCI_PRODUCT_LSI_SAS1068E 0x0058
+#endif
+
+#ifndef PCI_PRODUCT_LSI_SAS1078
+#define PCI_PRODUCT_LSI_SAS1078 0x0060
+#endif
+
#ifndef PCIM_CMD_SERRESPEN
#define PCIM_CMD_SERRESPEN 0x0100
#endif
-
#define MPT_IO_BAR 0
#define MPT_MEM_BAR 1
@@ -167,6 +191,16 @@ mpt_pci_probe(device_t dev)
case PCI_PRODUCT_LSI_1030:
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:
+ desc = "LSILogic SAS Adapter";
+ break;
default:
return (ENXIO);
}
@@ -268,6 +302,16 @@ mpt_pci_attach(device_t dev)
case PCI_PRODUCT_LSI_FC929:
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:
+ mpt->is_sas = 1;
+ break;
default:
break;
}
@@ -276,10 +320,13 @@ mpt_pci_attach(device_t dev)
mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT;
mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT;
mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT;
+ mpt->verbose = MPT_PRT_NONE;
mpt_set_options(mpt);
- mpt->verbose = MPT_PRT_INFO;
- mpt->verbose += (bootverbose != 0)? 1 : 0;
-
+ if (mpt->verbose == MPT_PRT_NONE) {
+ mpt->verbose = MPT_PRT_WARN;
+ /* Print INFO level (if any) if bootverbose is set */
+ mpt->verbose += (bootverbose != 0)? 1 : 0;
+ }
/* Make sure memory access decoders are enabled */
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
if ((cmd & PCIM_CMD_MEMEN) == 0) {
@@ -313,7 +360,8 @@ mpt_pci_attach(device_t dev)
/*
* Set up register access. PIO mode is required for
- * certain reset operations.
+ * certain reset operations (but must be disabled for
+ * some cards otherwise).
*/
mpt->pci_pio_rid = PCIR_BAR(MPT_IO_BAR);
mpt->pci_pio_reg = bus_alloc_resource(dev, SYS_RES_IOPORT,
@@ -331,6 +379,10 @@ mpt_pci_attach(device_t dev)
&mpt->pci_mem_rid, 0, ~0, 0, RF_ACTIVE);
if (mpt->pci_reg == NULL) {
device_printf(dev, "Unable to memory map registers.\n");
+ if (mpt->is_sas) {
+ device_printf(dev, "Giving Up.\n");
+ goto bad;
+ }
device_printf(dev, "Falling back to PIO mode.\n");
mpt->pci_st = mpt->pci_pio_st;
mpt->pci_sh = mpt->pci_pio_sh;
@@ -384,8 +436,14 @@ mpt_pci_attach(device_t dev)
mpt_read_config_regs(mpt);
+ /*
+ * Disable PIO until we need it
+ */
+ pci_disable_io(dev, SYS_RES_IOPORT);
+
/* Initialize the hardware */
if (mpt->disabled == 0) {
+
MPT_LOCK(mpt);
if (mpt_attach(mpt) != 0) {
MPT_UNLOCK(mpt);
@@ -497,7 +555,7 @@ mpt_pci_shutdown(device_t dev)
static int
mpt_dma_mem_alloc(struct mpt_softc *mpt)
{
- int i, error;
+ int i, error, nsegs;
uint8_t *vptr;
uint32_t pptr, end;
size_t len;
@@ -526,13 +584,13 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
#endif
/*
- * Create a parent dma tag for this device
+ * Create a parent dma tag for this device.
*
- * Align at byte boundaries, limit to 32-bit addressing
- * (The chip supports 64-bit addressing, but this driver doesn't)
+ * Align at byte boundaries, limit to 32-bit addressing for
+ * request/reply queues.
*/
if (mpt_dma_tag_create(mpt, /*parent*/NULL, /*alignment*/1,
- /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+ /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR,
/*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
/*nsegments*/BUS_SPACE_MAXSIZE_32BIT,
@@ -543,9 +601,9 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
}
/* Create a child tag for reply buffers */
- if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE,
- 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
- NULL, NULL, PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
+ if (mpt_dma_tag_create(mpt, mpt->parent_dmat, 2 * PAGE_SIZE,
+ 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
+ NULL, NULL, 2 * PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
&mpt->reply_dmat) != 0) {
device_printf(dev, "cannot create a dma tag for replies\n");
return (1);
@@ -554,8 +612,9 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
/* Allocate some DMA accessable memory for replies */
if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply,
BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) {
- device_printf(dev, "cannot allocate %lu bytes of reply memory\n",
- (u_long)PAGE_SIZE);
+ device_printf(dev,
+ "cannot allocate %lu bytes of reply memory\n",
+ (u_long) (2 * PAGE_SIZE));
return (1);
}
@@ -564,7 +623,7 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
/* Load and lock it into "bus space" */
bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply,
- PAGE_SIZE, mpt_map_rquest, &mi, 0);
+ 2 * PAGE_SIZE, mpt_map_rquest, &mi, 0);
if (mi.error) {
device_printf(dev,
@@ -574,9 +633,16 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
mpt->reply_phys = mi.phys;
/* Create a child tag for data buffers */
+
+ /*
+ * XXX: we should say that nsegs is 'unrestricted, but that
+ * XXX: tickles a horrible bug in the busdma code. Instead,
+ * XXX: we'll derive a reasonable segment limit from MAXPHYS
+ */
+ nsegs = (MAXPHYS / PAGE_SIZE) + 1;
if (mpt_dma_tag_create(mpt, mpt->parent_dmat, 1,
0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
- NULL, NULL, MAXBSIZE, MPT_SGL_MAX, BUS_SPACE_MAXSIZE_32BIT, 0,
+ NULL, NULL, MAXBSIZE, nsegs, BUS_SPACE_MAXSIZE_32BIT, 0,
&mpt->buffer_dmat) != 0) {
device_printf(dev,
"cannot create a dma tag for data buffers\n");
@@ -585,7 +651,7 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
/* Create a child tag for request buffers */
if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE,
- 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
+ 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0,
&mpt->request_dmat) != 0) {
device_printf(dev, "cannot create a dma tag for requests\n");
OpenPOWER on IntegriCloud