[PATCH 02/14] Platform-intel: support for OROM SAS and AHCIcontroller

[PATCH 02/14] Platform-intel: support for OROM SAS and AHCIcontroller

am 08.03.2011 16:20:33 von Marcin.Labun

From 65ddd52114b70837c8f2e69e2e5200dff1eab90a Mon Sep 17 00:00:00 2001
From: Marcin Labun
Date: Thu, 3 Mar 2011 13:41:41 +0100
Subject: [PATCH 02/14] Platform-intel: support for OROM SAS and AHCI controller

Signed-off-by: Marcin Labun
---
platform-intel.c | 130 +++++++++++++++++++++++++++++++++++++++++------------
platform-intel.h | 8 +++-
2 files changed, 106 insertions(+), 32 deletions(-)

diff --git a/platform-intel.c b/platform-intel.c
index 0dc90b7..95e3a1a 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -28,6 +28,10 @@
#include
#include
#include
+#include
+
+
+static __u16 devpath_to_vendor(const char *dev_path);

void free_sys_dev(struct sys_dev **list)
{
@@ -113,7 +117,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
return head;
}

-__u16 devpath_to_vendor(const char *dev_path)
+
+static __u16 devpath_to_vendor(const char *dev_path)
{
char path[strlen(dev_path) + strlen("/vendor") + 1];
char vendor[7];
@@ -167,19 +172,21 @@ static int platform_has_intel_devices(void)
}

/*
- * PCI Expansion ROM Data Structure Format
- */
+ * PCI Expansion ROM Data Structure Format */
struct pciExpDataStructFormat {
__u8 ver[4];
__u16 vendorID;
__u16 deviceID;
} __attribute__ ((packed));

-static struct imsm_orom imsm_orom;
+static struct imsm_orom imsm_orom[SYS_DEV_MAX];
+static int populated_orom[SYS_DEV_MAX];
+
static int scan(const void *start, const void *end, const void *data)
{
int offset;
const struct imsm_orom *imsm_mem;
+ int dev;
int len = (end - start);
struct pciExpDataStructFormat *ptr= (struct pciExpDataStructFormat *)data;

@@ -187,46 +194,85 @@ static int scan(const void *start, const void *end, const void *data)
(ulong) __le16_to_cpu(ptr->vendorID),
(ulong) __le16_to_cpu(ptr->deviceID));

- if (!((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
- (__le16_to_cpu(ptr->deviceID) == 0x2822)))
+ if ((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
+ (__le16_to_cpu(ptr->deviceID) == 0x2822))
+ dev = SYS_DEV_SATA;
+ else if ((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
+ (__le16_to_cpu(ptr->deviceID) == 0x1D60))
+ dev = SYS_DEV_SAS;
+ else
return 0;

for (offset = 0; offset < len; offset += 4) {
imsm_mem = start + offset;
if (memcmp(imsm_mem->signature, "$VER", 4) == 0) {
- imsm_orom = *imsm_mem;
- return 1;
+ imsm_orom[dev] = *imsm_mem;
+ populated_orom[dev] = 1;
+ return populated_orom[SYS_DEV_SATA] && populated_orom[SYS_DEV_SAS];
}
}
return 0;
}

-const struct imsm_orom *find_imsm_orom(void)
-{
- static int populated = 0;
- unsigned long align;
-
- /* it's static data so we only need to read it once */
- if (populated)
- return &imsm_orom;

- if (check_env("IMSM_TEST_OROM")) {
- memset(&imsm_orom, 0, sizeof(imsm_orom));
- imsm_orom.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
+const struct imsm_orom *imsm_platform_test(enum sys_dev_type hba_id, int *populated,
+ struct imsm_orom *imsm_orom)
+{
+ memset(imsm_orom, 0, sizeof(*imsm_orom));
+ imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5;
- imsm_orom.sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB |
+ imsm_orom->sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB |
IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB |
IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB |
IMSM_OROM_SSS_256kB | IMSM_OROM_SSS_512kB |
IMSM_OROM_SSS_1MB | IMSM_OROM_SSS_2MB;
- imsm_orom.dpa = 6;
- imsm_orom.tds = 6;
- imsm_orom.vpa = 2;
- imsm_orom.vphba = 4;
- imsm_orom.attr = imsm_orom.rlc | IMSM_OROM_ATTR_ChecksumVerify;
- populated = 1;
- return &imsm_orom;
+ imsm_orom->dpa = IMSM_OROM_DISKS_PER_ARRAY;
+ imsm_orom->tds = IMSM_OROM_TOTAL_DISKS;
+ imsm_orom->vpa = IMSM_OROM_VOLUMES_PER_ARRAY;
+ imsm_orom->vphba = IMSM_OROM_VOLUMES_PER_HBA;
+ imsm_orom->attr = imsm_orom->rlc | IMSM_OROM_ATTR_ChecksumVerify;
+ *populated = 1;
+
+ if (check_env("IMSM_TEST_OROM_NORAID5")) {
+ imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
+ IMSM_OROM_RLC_RAID10;
+ }
+ if (check_env("IMSM_TEST_AHCI_EFI_NORAID5") && (hba_id == SYS_DEV_SAS)) {
+ imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
+ IMSM_OROM_RLC_RAID10;
+ }
+ if (check_env("IMSM_TEST_SCU_EFI_NORAID5") && (hba_id == SYS_DEV_SATA)) {
+ imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
+ IMSM_OROM_RLC_RAID10;
+ }
+
+ return imsm_orom;
+}
+
+
+
+static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id)
+{
+ unsigned long align;
+
+ if (hba_id >= SYS_DEV_MAX)
+ return NULL;
+
+ /* it's static data so we only need to read it once */
+ if (populated_orom[hba_id]) {
+ dprintf("OROM CAP: %p, pid: %d pop: %d\n",
+ &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]);
+ return &imsm_orom[hba_id];
+ }
+ if (check_env("IMSM_TEST_OROM")) {
+ dprintf("OROM CAP: %p, pid: %d pop: %d\n",
+ &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]);
+ return imsm_platform_test(hba_id, &populated_orom[hba_id], &imsm_orom[hba_id]);
}
+ /* return empty OROM capabilities in EFI test mode */
+ if (check_env("IMSM_TEST_AHCI_EFI") ||
+ check_env("IMSM_TEST_SCU_EFI"))
+ return NULL;

if (!platform_has_intel_devices())
return NULL;
@@ -239,11 +285,30 @@ const struct imsm_orom *find_imsm_orom(void)
if (probe_roms_init(align) != 0)
return NULL;
probe_roms();
- populated = scan_adapter_roms(scan);
+ /* ignore result - True is returned if both are found */
+ scan_adapter_roms(scan);
probe_roms_exit();

- if (populated)
- return &imsm_orom;
+ if (populated_orom[hba_id])
+ return &imsm_orom[hba_id];
+ return NULL;
+}
+
+
+/*
+ * backward interface compatibility
+ */
+const struct imsm_orom *find_imsm_orom(void)
+{
+ return find_imsm_hba_orom(SYS_DEV_SATA);
+}
+
+const struct imsm_orom *find_imsm_capability(enum sys_dev_type hba_id)
+{
+ const struct imsm_orom *cap=NULL;
+
+ if ((cap = find_imsm_hba_orom(hba_id)) != NULL)
+ return cap;
return NULL;
}

@@ -273,6 +338,11 @@ char *diskfd_to_devpath(int fd)
int path_attached_to_hba(const char *disk_path, const char *hba_path)
{
int rc;
+
+ if (check_env("IMSM_TEST_AHCI_DEV") ||
+ check_env("IMSM_TEST_SCU_DEV")) {
+ return 1;
+ }

if (!disk_path || !hba_path)
return 0;
diff --git a/platform-intel.h b/platform-intel.h
index 82cc85e..18f1ea2 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -19,7 +19,7 @@
#include
#include

-/* The IMSM OROM Version Table definition */
+/* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */
struct imsm_orom {
__u8 signature[4];
__u8 table_ver_major; /* Currently 2 (can change with future revs) */
@@ -58,9 +58,13 @@ struct imsm_orom {
#define IMSM_OROM_SSS_32MB (1 << 14)
#define IMSM_OROM_SSS_64MB (1 << 15)
__u16 dpa; /* Disks Per Array supported */
+ #define IMSM_OROM_DISKS_PER_ARRAY 6
__u16 tds; /* Total Disks Supported */
+ #define IMSM_OROM_TOTAL_DISKS 6
__u8 vpa; /* # Volumes Per Array supported */
+ #define IMSM_OROM_VOLUMES_PER_ARRAY 2
__u8 vphba; /* # Volumes Per Host Bus Adapter supported */
+ #define IMSM_OROM_VOLUMES_PER_HBA 4
/* Attributes supported. This should map to the
* attributes in the MPB. Also, lower 16 bits
* should match/duplicate RLC bits above.
@@ -184,8 +188,8 @@ struct sys_dev {
char *diskfd_to_devpath(int fd);
struct sys_dev *find_driver_devices(const char *bus, const char *driver);
struct sys_dev *find_intel_devices(void);
-__u16 devpath_to_vendor(const char *dev_path);
void free_sys_dev(struct sys_dev **list);
+const struct imsm_orom *find_imsm_capability(enum sys_dev_type hba_id);
const struct imsm_orom *find_imsm_orom(void);
int disk_attached_to_hba(int fd, const char *hba_path);
char *devt_to_devpath(dev_t dev);
--
1.6.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

Re: [PATCH 02/14] Platform-intel: support for OROM SAS and AHCIcontroller

am 09.03.2011 00:17:37 von dan.j.williams

On Tue, 2011-03-08 at 07:20 -0800, Labun, Marcin wrote:
> -static struct imsm_orom imsm_orom;
> +static struct imsm_orom imsm_orom[SYS_DEV_MAX];
> +static int populated_orom[SYS_DEV_MAX];
> +
> static int scan(const void *start, const void *end, const void *data)
> {
> int offset;
> const struct imsm_orom *imsm_mem;
> + int dev;
> int len = (end - start);
> struct pciExpDataStructFormat *ptr= (struct pciExpDataStructFormat *)data;

Why add another parameter to this function? The scan routine can simply
look at offset 0x18 right?

> @@ -187,46 +194,85 @@ static int scan(const void *start, const void *end, const void *data)
> (ulong) __le16_to_cpu(ptr->vendorID),
> (ulong) __le16_to_cpu(ptr->deviceID));
>
> - if (!((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
> - (__le16_to_cpu(ptr->deviceID) == 0x2822)))
> + if ((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
> + (__le16_to_cpu(ptr->deviceID) == 0x2822))
> + dev = SYS_DEV_SATA;
> + else if ((__le16_to_cpu(ptr->vendorID) == 0x8086) &&
> + (__le16_to_cpu(ptr->deviceID) == 0x1D60))
> + dev = SYS_DEV_SAS;
> + else

Are you sure this list is sufficient? I don't think we want to get into
the responsibility of maintaining pci device ids in mdadm. There are
many ahci raid devices, and at least 14 other sas device ids that might
match. The orom might also be using the device list, i.e. the first id
in the pci firmware data structure might not match the pci device in the
system.

The driver will always have the latest knowledge of the supported device
ids so we can always rely on it to identify our raid controller (i.e.
pci devices with vendor id == 0x8086 and driven by isci or ahci)

I recently submitted a patch to update the kernel's probe_roms interface
[1]. It might be cleaner and more future-proof if find_imsm_orom() took
a parameter as to which orom it should find, like pci_map_biosrom. At
alloc_super() time we would just find all the relevant oroms based on
what devices are in the system, rather than blindly scanning option-rom
space and comparing against a device id list that may get out of date.

--
Dan

[1]: http://marc.info/?l=linux-kernel&m=129960935312751&w=2


--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html