Skip to content

Commit 1d46c5e

Browse files
committed
Detect FS67xx (Flashtor) devices by their PCIe Packet Switches
the AS67xx devices shouldn't have those packet switches from `lspci` on a FS6712X: 02:00.0 PCI bridge: ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch (rev 01) 03:00.0 PCI bridge: ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch (rev 01) (... and several more ...) `lspci -v -nn` then revealed that their PCI vendor ID and product ID are 1b21:2806 (vendor 0xb21 product 0x2806)
1 parent ae4aa00 commit 1d46c5e

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

asustor.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/kernel.h>
1717
#include <linux/leds.h>
1818
#include <linux/module.h>
19+
#include <linux/pci.h>
1920
#include <linux/platform_device.h>
2021
#include <linux/version.h>
2122

@@ -225,44 +226,51 @@ static struct gpiod_lookup_table asustor_600_gpio_keys_lookup = {
225226

226227
// ASUSTOR Platform.
227228
struct asustor_driver_data {
229+
const char *name;
228230
struct gpiod_lookup_table *leds;
229231
struct gpiod_lookup_table *keys;
230232
};
231233

232234
static struct asustor_driver_data asustor_fs6700_driver_data = {
235+
.name = "FS67xx",
233236
.leds = &asustor_fs6700_gpio_leds_lookup,
234237
.keys = &asustor_fs6700_gpio_keys_lookup,
235238
};
236239

237240
static struct asustor_driver_data asustor_6700_driver_data = {
241+
.name = "AS67xx",
242+
.leds = &asustor_6700_gpio_leds_lookup,
243+
.keys = &asustor_6100_gpio_keys_lookup,
244+
};
245+
246+
static struct asustor_driver_data asustor_6600_driver_data = {
247+
// NOTE: This is (currently?) the same as for AS6700
248+
// because it seems to use the same GPIO numbers,
249+
// but listed extra for the different name
250+
.name = "AS66xx",
238251
.leds = &asustor_6700_gpio_leds_lookup,
239252
.keys = &asustor_6100_gpio_keys_lookup,
240253
};
241254

242255
static struct asustor_driver_data asustor_6100_driver_data = {
256+
.name = "AS61xx",
243257
.leds = &asustor_6100_gpio_leds_lookup,
244258
.keys = &asustor_6100_gpio_keys_lookup,
245259
};
246260

247261
static struct asustor_driver_data asustor_600_driver_data = {
262+
.name = "AS6xx",
248263
.leds = &asustor_600_gpio_leds_lookup,
249264
.keys = &asustor_600_gpio_keys_lookup,
250265
};
251266

252267
static const struct dmi_system_id asustor_systems[] = {
253-
{
254-
// Note: This uses the BIOS release date to help match the FS67xx,
255-
// because otherwise it matches the AS670xT, AS540xT and others
256-
.matches = {
257-
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
258-
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jasper Lake Client Platform"),
259-
DMI_EXACT_MATCH(DMI_BIOS_DATE, "09/15/2023"),
260-
},
261-
.driver_data = &asustor_fs6700_driver_data,
262-
},
263268
{
264269
// Note: This not only matches (and works with) AS670xT (Lockerstore Gen2),
265-
// but also AS540xT (Nimbustor Gen2)
270+
// but also AS540xT (Nimbustor Gen2) and, unfortunately, also
271+
// Flashstor (FS6706T and FS6712X) which can't be detected with DMI but is
272+
// different enough from the AS67xx devices to need different treatment.
273+
// asustor_init() has additional code to detect FS67xx based on available PCIe devices
266274
.matches = {
267275
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
268276
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jasper Lake Client Platform"),
@@ -276,7 +284,7 @@ static const struct dmi_system_id asustor_systems[] = {
276284
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
277285
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "GeminiLake"),
278286
},
279-
.driver_data = &asustor_6700_driver_data,
287+
.driver_data = &asustor_6600_driver_data,
280288
},
281289
{
282290
.matches = {
@@ -349,14 +357,27 @@ static int __init asustor_init(void)
349357
return -ENODEV;
350358
}
351359

352-
if (strlen(system->matches[2].substr))
353-
pr_info("Found %s/%s/%s\n", system->matches[0].substr,
354-
system->matches[1].substr, system->matches[2].substr);
355-
else
356-
pr_info("Found %s/%s\n", system->matches[0].substr,
357-
system->matches[1].substr);
358-
359360
driver_data = system->driver_data;
361+
362+
// figure out if this is really an AS67xx or instead a FS67xx ("Flashstor"),
363+
// which has different LEDs and only supports m.2 SSDs (no SATA drives)
364+
if (driver_data == &asustor_6700_driver_data) {
365+
// this matches the "ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch" (rev 01)
366+
// PCI bridge (vendor ID 0x1b21, device ID 0x2806 aka 1b21:2806), which AFAIK is only used
367+
// in Flashtor devices (though unfortunately we only had FS6712X and AS5402T to check)
368+
// see also https://github.com/mafredri/asustor-platform-driver/pull/21#issuecomment-2420883171
369+
// and following.
370+
if (pci_get_device(0x1b21, 0x2806, NULL) != NULL) {
371+
// TODO: if necessary, we could count those devices; the current assumption
372+
// is that the bigger *A*S67xx (or AS54xx) devices don't have this at all
373+
374+
driver_data = &asustor_fs6700_driver_data;
375+
}
376+
}
377+
378+
pr_info("Found %s (%s/%s)\n", driver_data->name, system->matches[0].substr,
379+
system->matches[1].substr);
380+
360381
gpiod_add_lookup_table(driver_data->leds);
361382
gpiod_add_lookup_table(driver_data->keys);
362383

0 commit comments

Comments
 (0)