summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpt/mpt_pci.c
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-02-11 01:35:29 +0000
committermjacob <mjacob@FreeBSD.org>2006-02-11 01:35:29 +0000
commit78626b5d46a944296fad26689ed7859f4d97a757 (patch)
treeb1e7af4c731ce5812fec41df68235828d2149ad5 /sys/dev/mpt/mpt_pci.c
parentc1c4403ced4c0e3859b204f59dbca7afd09fe1de (diff)
downloadFreeBSD-src-78626b5d46a944296fad26689ed7859f4d97a757.zip
FreeBSD-src-78626b5d46a944296fad26689ed7859f4d97a757.tar.gz
Do initial cut of SAS HBA support. These controllers (106X) seem to support
automatically both SATA and SAS drives. The async SAS event handling we catch but ignore at present (so automagic attach/detach isn't hooked up yet). Do 64 bit PCI support- we can now work on systems with > 4GB of memory. Do large transfer support- we now can support up to reported chain depth, or the length of our request area. We simply allocate additional request elements when we would run out of room for chain lists. Tested on Ultra320, FC and SAS controllers on AMD64 and i386 platforms. There were no RAID cards available for me to regression test. The error recovery for this driver still is pretty bad.
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