warn = 1;
}
- if (st->ss->detail_platform && st->ss->detail_platform(0, 1) != 0) {
+ if (st->ss->detail_platform && st->ss->detail_platform(0, 1, NULL) != 0) {
if (c->runstop != 1 || c->verbose >= 0)
pr_err("%s unable to enumerate platform support\n"
" array may not be compatible with hardware/firmware\n",
return rv;
}
-int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export)
+int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path)
{
/* display platform capabilities for the given metadata format
* 'scan' in this context means iterate over all metadata types
int err = 1;
if (ss && export && ss->export_detail_platform)
- err = ss->export_detail_platform(verbose);
+ err = ss->export_detail_platform(verbose, controller_path);
else if (ss && ss->detail_platform)
- err = ss->detail_platform(verbose, 0);
+ err = ss->detail_platform(verbose, 0, controller_path);
else if (ss) {
if (verbose > 0)
pr_err("%s metadata is platform independent\n",
pr_err("%s metadata is platform independent\n",
meta->name ? : "[no name]");
} else if (export && meta->export_detail_platform) {
- err |= meta->export_detail_platform(verbose);
+ err |= meta->export_detail_platform(verbose, controller_path);
} else
- err |= meta->detail_platform(verbose, 0);
+ err |= meta->detail_platform(verbose, 0, controller_path);
}
return err;
.TP
.BR \-\-detail\-platform
Print details of the platform's RAID capabilities (firmware / hardware
-topology) for a given metadata format.
+topology) for a given metadata format. If used without argument, mdadm
+will scan all controllers looking for their capabilities. Otherwise, mdadm
+will only look at the controller specified by the argument in form of an
+absolute filepath or a link, e.g.
+.IR /sys/devices/pci0000:00/0000:00:1f.2 .
.TP
.BR \-Y ", " \-\-export
continue;
}
if (opt == 1) {
- /* an undecorated option - must be a device name.
+ /* an undecorated option - must be a device name.
*/
+
+ if (devs_found > 0 && devmode == DetailPlatform) {
+ pr_err("controller may only be specified once. %s ignored\n",
+ optarg);
+ continue;
+ }
+
if (devs_found > 0 && mode == MANAGE && !devmode) {
pr_err("Must give one of -a/-r/-f"
" for subsequent devices at %s\n", optarg);
}
rv = Examine(devlist, &c, ss);
} else if (devmode == DetailPlatform) {
- rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose, c.export);
+ rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1,
+ c.verbose, c.export,
+ devlist ? devlist->devname : NULL);
} else if (devlist == NULL) {
if (devmode == 'S' && c.scan)
rv = stop_scan(c.verbose);
void (*export_detail_super)(struct supertype *st);
/* Optional: platform hardware / firmware details */
- int (*detail_platform)(int verbose, int enumerate_only);
- int (*export_detail_platform)(int verbose);
+ int (*detail_platform)(int verbose, int enumerate_only, char *controller_path);
+ int (*export_detail_platform)(int verbose, char *controller_path);
/* Used:
* to get uuid to storing in bitmap metadata
struct context *c);
extern int Detail(char *dev, struct context *c);
-extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export);
+extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path);
extern int Query(char *dev);
extern int Examine(struct mddev_dev *devlist, struct context *c,
struct supertype *forcest);
extern int open_dev_excl(int devnum);
extern int is_standard(char *dev, int *nump);
extern int same_dev(char *one, char *two);
+extern int compare_paths (char* path1,char* path2);
extern int parse_auto(char *str, char *msg, int config);
extern struct mddev_ident *conf_get_ident(char *dev);
printf("IMSM_MAX_VOLUMES_PER_CONTROLLER=%d\n",orom->vphba);
}
-static int detail_platform_imsm(int verbose, int enumerate_only)
+static int detail_platform_imsm(int verbose, int enumerate_only, char *controller_path)
{
/* There are two components to imsm platform support, the ahci SATA
* controller and the option-rom. To find the SATA controller we
struct sys_dev *list, *hba;
int host_base = 0;
int port_count = 0;
- int result=0;
+ int result=1;
if (enumerate_only) {
if (check_env("IMSM_NO_PLATFORM"))
result = 2;
break;
}
+ else
+ result = 0;
}
free_sys_dev(&list);
return result;
print_found_intel_controllers(list);
for (hba = list; hba; hba = hba->next) {
+ if (controller_path && (compare_paths(hba->path,controller_path) != 0))
+ continue;
orom = find_imsm_capability(hba->type);
if (!orom)
pr_err("imsm capabilities not found for controller: %s (type %s)\n",
hba->path, get_sys_dev_type(hba->type));
- else
+ else {
+ result = 0;
print_imsm_capability(orom);
- }
-
- for (hba = list; hba; hba = hba->next) {
- printf(" I/O Controller : %s (%s)\n",
- hba->path, get_sys_dev_type(hba->type));
-
- if (hba->type == SYS_DEV_SATA) {
- host_base = ahci_get_port_count(hba->path, &port_count);
- if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
- if (verbose > 0)
- pr_err("failed to enumerate "
- "ports on SATA controller at %s.", hba->pci_id);
- result |= 2;
+ printf(" I/O Controller : %s (%s)\n",
+ hba->path, get_sys_dev_type(hba->type));
+ if (hba->type == SYS_DEV_SATA) {
+ host_base = ahci_get_port_count(hba->path, &port_count);
+ if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
+ if (verbose > 0)
+ pr_err("failed to enumerate "
+ "ports on SATA controller at %s.\n", hba->pci_id);
+ result |= 2;
+ }
}
}
}
+ if (controller_path && result == 1)
+ pr_err("no active Intel(R) RAID "
+ "controller found under %s\n",controller_path);
+
free_sys_dev(&list);
return result;
}
-static int export_detail_platform_imsm(int verbose)
+static int export_detail_platform_imsm(int verbose, char *controller_path)
{
const struct imsm_orom *orom;
struct sys_dev *list, *hba;
}
for (hba = list; hba; hba = hba->next) {
+ if (controller_path && (compare_paths(hba->path,controller_path) != 0))
+ continue;
orom = find_imsm_capability(hba->type);
if (!orom) {
if (verbose > 0)
}
}
- if (result == 1 && verbose > 0)
- pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICES\n");
-
return result;
}
}
return disks;
}
+
+/* Checks if paths point to the same device
+ * Returns 0 if they do.
+ * Returns 1 if they don't.
+ * Returns -1 if something went wrong,
+ * e.g. paths are empty or the files
+ * they point to don't exist */
+int compare_paths (char* path1, char* path2)
+{
+ struct stat st1,st2;
+
+ if (path1 == NULL || path2 == NULL)
+ return -1;
+ if (stat(path1,&st1) != 0)
+ return -1;
+ if (stat(path2,&st2) != 0)
+ return -1;
+ if ((st1.st_ino == st2.st_ino) && (st1.st_dev == st2.st_dev))
+ return 0;
+ return 1;
+}