summaryrefslogtreecommitdiffstats
path: root/sys/dev/mfi/mfi_pci.c
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2011-11-04 02:34:52 +0000
committerambrisko <ambrisko@FreeBSD.org>2011-11-04 02:34:52 +0000
commit096734a154b76780bd2761cf8e196c6fd4e0562d (patch)
tree1a1489b799c624639a0f10fe72c656d2f2963eab /sys/dev/mfi/mfi_pci.c
parentbea0b6754606ed3aba61b582c7d4c6765c96a158 (diff)
downloadFreeBSD-src-096734a154b76780bd2761cf8e196c6fd4e0562d.zip
FreeBSD-src-096734a154b76780bd2761cf8e196c6fd4e0562d.tar.gz
First cut at updating mfi(4) to support newer LSI MegaRAID SAS cards.
Specifically, add support for "Drake Skinny" and "ThunderBolt" LSI cards. Initial code was supplied by LSI under BSD license. Several improvements were done by myself. Such things like making it work in a static kernel, be able to boot of the RAID, performance improvements. I removed some fairly complicated code that seemed to directly access the disks under the firmware. It doesn't seem to be needed and significantly slowed down the performance of the driver and caused tons of sense errors to be reported. This code is being checked in this area so others can help me get it into shape to commit into the FreeBSD tree. Assistance has been volunteered by iXsystems. We might want to re-work the JBOD attachment that creates /dev/mfisyspd? node for each disk. Performance is faster then prior cards. It works okay with WITNESS and INVARIANTS on amd64 and i386. I recall seeing a use after free time bug with FreeBSD 8 and a Drake Skinny card with WITNESS and INVARIANTS on. First task is get all of the new structures to be named in FreeBSD style format. Next is probably to deal with the 64bit addressing changes that are mostly around the #ifdef __amd64__ checks. Thanks to LSI for providing the initial code. Obtained from: LSI
Diffstat (limited to 'sys/dev/mfi/mfi_pci.c')
-rw-r--r--sys/dev/mfi/mfi_pci.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c
index 685aa0b..06a7eb0 100644
--- a/sys/dev/mfi/mfi_pci.c
+++ b/sys/dev/mfi/mfi_pci.c
@@ -115,14 +115,20 @@ struct mfi_ident {
int flags;
const char *desc;
} mfi_identifiers[] = {
+ {0x1000, 0x005B, 0xffff, 0xffff, MFI_FLAGS_SKINNY| MFI_FLAGS_TBOLT, "ThunderBolt"},
+ {0x1000, 0x005B, 0x8086, 0x9265, MFI_FLAGS_SKINNY| MFI_FLAGS_TBOLT, "Intel (R) RAID Controller RS25DB080"},
+ {0x1000, 0x005B, 0x8086, 0x9285, MFI_FLAGS_SKINNY| MFI_FLAGS_TBOLT, "Intel (R) RAID Controller RS25NB008"},
{0x1000, 0x0060, 0x1028, 0xffff, MFI_FLAGS_1078, "Dell PERC 6"},
{0x1000, 0x0060, 0xffff, 0xffff, MFI_FLAGS_1078, "LSI MegaSAS 1078"},
+ {0x1000, 0x0071, 0xffff, 0xffff, MFI_FLAGS_SKINNY, "Drake Skinny"},
+ {0x1000, 0x0073, 0xffff, 0xffff, MFI_FLAGS_SKINNY, "Drake Skinny"},
{0x1000, 0x0078, 0xffff, 0xffff, MFI_FLAGS_GEN2, "LSI MegaSAS Gen2"},
{0x1000, 0x0079, 0x1028, 0x1f15, MFI_FLAGS_GEN2, "Dell PERC H800 Adapter"},
{0x1000, 0x0079, 0x1028, 0x1f16, MFI_FLAGS_GEN2, "Dell PERC H700 Adapter"},
{0x1000, 0x0079, 0x1028, 0x1f17, MFI_FLAGS_GEN2, "Dell PERC H700 Integrated"},
{0x1000, 0x0079, 0x1028, 0x1f18, MFI_FLAGS_GEN2, "Dell PERC H700 Modular"},
{0x1000, 0x0079, 0x1028, 0x1f19, MFI_FLAGS_GEN2, "Dell PERC H700"},
+ {0x1000, 0x0079, 0x1028, 0x1f1a, MFI_FLAGS_GEN2, "Dell PERC H800 Proto Adapter"},
{0x1000, 0x0079, 0x1028, 0x1f1b, MFI_FLAGS_GEN2, "Dell PERC H800"},
{0x1000, 0x0079, 0x1028, 0xffff, MFI_FLAGS_GEN2, "Dell PERC Gen2"},
{0x1000, 0x0079, 0xffff, 0xffff, MFI_FLAGS_GEN2, "LSI MegaSAS Gen2"},
@@ -196,8 +202,11 @@ mfi_pci_attach(device_t dev)
(sc->mfi_flags & MFI_FLAGS_1078)) {
/* 1068/1078: Memory mapped BAR is at offset 0x10 */
sc->mfi_regs_rid = PCIR_BAR(0);
- } else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
- /* GEN2: Memory mapped BAR is at offset 0x14 */
+ }
+ else if ((sc->mfi_flags & MFI_FLAGS_GEN2) ||
+ (sc->mfi_flags & MFI_FLAGS_SKINNY) ||
+ (sc->mfi_flags & MFI_FLAGS_TBOLT)) {
+ /* Gen2/Skinny: Memory mapped BAR is at offset 0x14 */
sc->mfi_regs_rid = PCIR_BAR(1);
}
if ((sc->mfi_regs_resource = bus_alloc_resource_any(sc->mfi_dev,
@@ -240,8 +249,10 @@ static int
mfi_pci_detach(device_t dev)
{
struct mfi_softc *sc;
- struct mfi_disk *ld;
- int error;
+ //struct mfi_disk *ld;
+ //struct mfi_system_pd *syspd = NULL;
+ int error, devcount, i;
+ device_t *devlist;
sc = device_get_softc(dev);
@@ -254,14 +265,41 @@ mfi_pci_detach(device_t dev)
}
sc->mfi_detaching = 1;
mtx_unlock(&sc->mfi_io_lock);
-
- while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) {
+ /*
+ BHARAT: Fixed Kernel Corruption while unloading the driver
+ */
+ if((error = device_get_children(sc->mfi_dev, &devlist, &devcount)) != 0)
+ {
+ sx_xunlock(&sc->mfi_config_lock);
+ return error;
+ }
+ for(i=0; i < devcount; i++)
+ device_delete_child(sc->mfi_dev, devlist[i]);
+ free(devlist, M_TEMP);
+ /*
+ BHARAT: Following code causes Kernel corruption during
+ multiple driver load/unload, this cleanup code was not
+ getting called up in normal run hence OS was maintaining stale dev
+ entries which were resulting to crash, so added above
+ cleanup code.
+ */
+
+ /*while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) {
if ((error = device_delete_child(dev, ld->ld_dev)) != 0) {
sc->mfi_detaching = 0;
sx_xunlock(&sc->mfi_config_lock);
return (error);
}
}
+
+ if(!TAILQ_EMPTY(&sc->mfi_syspd_tqh))
+ while ((syspd = TAILQ_FIRST(&sc->mfi_syspd_tqh)) != NULL) {
+ if ((error = device_delete_child(dev,syspd->pd_dev)) != 0) {
+ sc->mfi_detaching = 0;
+ sx_xunlock(&sc->mfi_config_lock);
+ return (error);
+ }
+ }*/
sx_xunlock(&sc->mfi_config_lock);
EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh);
OpenPOWER on IntegriCloud