]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - platform-intel.c
2 * Intel(R) Matrix Storage Manager hardware and firmware support routines
4 * Copyright (C) 2008 Intel Corporation
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "platform-intel.h"
21 #include "probe_roms.h"
29 #include <sys/types.h>
32 void free_sys_dev(struct sys_dev
**list
)
35 struct sys_dev
*next
= (*list
)->next
;
44 struct sys_dev
*find_driver_devices(const char *bus
, const char *driver
)
46 /* search sysfs for devices driven by 'driver' */
52 struct sys_dev
*head
= NULL
;
53 struct sys_dev
*list
= NULL
;
55 sprintf(path
, "/sys/bus/%s/drivers/%s", bus
, driver
);
56 driver_dir
= opendir(path
);
59 for (de
= readdir(driver_dir
); de
; de
= readdir(driver_dir
)) {
60 /* is 'de' a device? check that the 'subsystem' link exists and
61 * that its target matches 'bus'
63 sprintf(path
, "/sys/bus/%s/drivers/%s/%s/subsystem",
64 bus
, driver
, de
->d_name
);
65 if (readlink(path
, link
, sizeof(link
)) < 0)
67 c
= strrchr(link
, '/');
70 if (strncmp(bus
, c
+1, strlen(bus
)) != 0)
73 /* start / add list entry */
75 head
= malloc(sizeof(*head
));
78 list
->next
= malloc(sizeof(*head
));
87 /* generate canonical path name for the device */
88 sprintf(path
, "/sys/bus/%s/drivers/%s/%s",
89 bus
, driver
, de
->d_name
);
90 list
->path
= canonicalize_file_name(path
);
97 __u16
devpath_to_vendor(const char *dev_path
)
99 char path
[strlen(dev_path
) + strlen("/vendor") + 1];
105 sprintf(path
, "%s/vendor", dev_path
);
107 fd
= open(path
, O_RDONLY
);
111 n
= read(fd
, vendor
, sizeof(vendor
));
112 if (n
== sizeof(vendor
)) {
113 vendor
[n
- 1] = '\0';
114 id
= strtoul(vendor
, NULL
, 16);
121 static int platform_has_intel_ahci(void)
123 struct sys_dev
*devices
= find_driver_devices("pci", "ahci");
127 for (dev
= devices
; dev
; dev
= dev
->next
)
128 if (devpath_to_vendor(dev
->path
) == 0x8086) {
133 free_sys_dev(&devices
);
139 static struct imsm_orom imsm_orom
;
140 static int scan(const void *start
, const void *end
)
143 const struct imsm_orom
*imsm_mem
;
144 int len
= (end
- start
);
146 for (offset
= 0; offset
< len
; offset
+= 4) {
147 imsm_mem
= start
+ offset
;
148 if (memcmp(imsm_mem
->signature
, "$VER", 4) == 0) {
149 imsm_orom
= *imsm_mem
;
157 const struct imsm_orom
*find_imsm_orom(void)
159 static int populated
= 0;
161 /* it's static data so we only need to read it once */
165 if (!platform_has_intel_ahci())
168 /* scan option-rom memory looking for an imsm signature */
169 if (probe_roms_init() != 0)
172 populated
= scan_adapter_roms(scan
);
180 char *devt_to_devpath(dev_t dev
)
184 sprintf(device
, "/sys/dev/block/%d:%d/device", major(dev
), minor(dev
));
185 return canonicalize_file_name(device
);
188 static char *diskfd_to_devpath(int fd
)
190 /* return the device path for a disk, return NULL on error or fd
191 * refers to a partition
195 if (fstat(fd
, &st
) != 0)
197 if (!S_ISBLK(st
.st_mode
))
200 return devt_to_devpath(st
.st_rdev
);
203 int path_attached_to_hba(const char *disk_path
, const char *hba_path
)
207 if (!disk_path
|| !hba_path
)
210 if (strncmp(disk_path
, hba_path
, strlen(hba_path
)) == 0)
218 int devt_attached_to_hba(dev_t dev
, const char *hba_path
)
220 char *disk_path
= devt_to_devpath(dev
);
221 int rc
= path_attached_to_hba(disk_path
, hba_path
);
229 int disk_attached_to_hba(int fd
, const char *hba_path
)
231 char *disk_path
= diskfd_to_devpath(fd
);
232 int rc
= path_attached_to_hba(disk_path
, hba_path
);