diff options
author | ambrisko <ambrisko@FreeBSD.org> | 2011-11-04 02:34:52 +0000 |
---|---|---|
committer | ambrisko <ambrisko@FreeBSD.org> | 2011-11-04 02:34:52 +0000 |
commit | 096734a154b76780bd2761cf8e196c6fd4e0562d (patch) | |
tree | 1a1489b799c624639a0f10fe72c656d2f2963eab /sys/dev/mfi/mfi_pci.c | |
parent | bea0b6754606ed3aba61b582c7d4c6765c96a158 (diff) | |
download | FreeBSD-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.c | 50 |
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); |