Skip to content

Commit 9ad4f50

Browse files
committed
asustor.c: Implement force_device argument to override device detection
can be used like `modprobe asustor force_device=AS66xx` or by adding /etc/modprobe.d/asustor.conf with a line like options asustor force_device=FS67xx (Also ran clang-format)
1 parent 1d46c5e commit 9ad4f50

File tree

1 file changed

+69
-25
lines changed

1 file changed

+69
-25
lines changed

asustor.c

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ struct asustor_driver_data {
231231
struct gpiod_lookup_table *keys;
232232
};
233233

234+
// NOTE: if you add another device here, update VALID_OVERRIDE_NAMES accordingly!
235+
234236
static struct asustor_driver_data asustor_fs6700_driver_data = {
235237
.name = "FS67xx",
236238
.leds = &asustor_fs6700_gpio_leds_lookup,
@@ -264,6 +266,8 @@ static struct asustor_driver_data asustor_600_driver_data = {
264266
.keys = &asustor_600_gpio_keys_lookup,
265267
};
266268

269+
#define VALID_OVERRIDE_NAMES "AS6xx, AS61xx, AS66xx, AS67xx, FS67xx"
270+
267271
static const struct dmi_system_id asustor_systems[] = {
268272
{
269273
// Note: This not only matches (and works with) AS670xT (Lockerstore Gen2),
@@ -344,39 +348,78 @@ static struct gpio_chip *find_chip_by_name(const char *name)
344348
}
345349
#endif
346350

351+
static char *force_device = "";
352+
module_param(force_device, charp, S_IRUSR | S_IRGRP | S_IROTH);
353+
MODULE_PARM_DESC(
354+
force_device,
355+
"Don't try to detect ASUSTOR device, use the given one instead. "
356+
"Valid values: " VALID_OVERRIDE_NAMES);
357+
347358
// TODO(mafredri): Allow force model for testing.
348359
static int __init asustor_init(void)
349360
{
350361
const struct dmi_system_id *system;
351362
const struct gpiod_lookup *keys_table;
352363
int ret, i;
353364

354-
system = dmi_first_match(asustor_systems);
355-
if (!system) {
356-
pr_info("No supported ASUSTOR mainboard found");
357-
return -ENODEV;
358-
}
359-
360-
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-
365+
driver_data = NULL;
366+
// allow overriding detection with force_device kernel parameter
367+
if (force_device && *force_device) {
368+
// special case: FS67xx isn't in the asustor_systems table, as it can't
369+
// be detected through DMI
370+
if (strcmp(force_device, "FS67xx") == 0) {
374371
driver_data = &asustor_fs6700_driver_data;
372+
} else {
373+
for (i = 0; i < ARRAY_SIZE(asustor_systems); i++) {
374+
struct asustor_driver_data *dd =
375+
asustor_systems[i].driver_data;
376+
if (dd && dd->name &&
377+
strcmp(force_device, dd->name) == 0) {
378+
driver_data = dd;
379+
break;
380+
}
381+
}
382+
if (driver_data == NULL) {
383+
pr_err("force_device parameter set to invalid value \"%s\"!\n",
384+
force_device);
385+
pr_info(" valid force_device values are: %s\n",
386+
VALID_OVERRIDE_NAMES);
387+
return -EINVAL;
388+
}
389+
}
390+
pr_info("force_device parameter is set to \"%s\", treating your machine as "
391+
"that device instead of trying to detect it!\n",
392+
force_device);
393+
} else { // try to detect the ASUSTOR device
394+
system = dmi_first_match(asustor_systems);
395+
if (!system) {
396+
pr_info("No supported ASUSTOR mainboard found");
397+
return -ENODEV;
375398
}
376-
}
377399

378-
pr_info("Found %s (%s/%s)\n", driver_data->name, system->matches[0].substr,
379-
system->matches[1].substr);
400+
driver_data = system->driver_data;
401+
402+
// figure out if this is really an AS67xx or instead a FS67xx ("Flashstor"),
403+
// which has different LEDs and only supports m.2 SSDs (no SATA drives)
404+
if (driver_data == &asustor_6700_driver_data) {
405+
// this matches the "ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3
406+
// Packet Switch" (rev 01) PCI bridge (vendor ID 0x1b21, device ID 0x2806
407+
// aka 1b21:2806), which AFAIK is only used in Flashtor devices
408+
// (though unfortunately we only had FS6712X and AS5402T to check)
409+
// see also https://github.com/mafredri/asustor-platform-driver/pull/21#issuecomment-2420883171
410+
// and following.
411+
if (pci_get_device(0x1b21, 0x2806, NULL) != NULL) {
412+
// TODO: if necessary, we could count those devices; the current
413+
// assumption is that even the bigger *A*S67xx (or AS54xx)
414+
// devices don't have this at all
415+
416+
driver_data = &asustor_fs6700_driver_data;
417+
}
418+
}
419+
420+
pr_info("Found %s or similar (%s/%s)\n", driver_data->name,
421+
system->matches[0].substr, system->matches[1].substr);
422+
}
380423

381424
gpiod_add_lookup_table(driver_data->leds);
382425
gpiod_add_lookup_table(driver_data->keys);
@@ -406,8 +449,9 @@ static int __init asustor_init(void)
406449
goto err;
407450
}
408451

409-
asustor_keys_pdev = asustor_create_pdev(
410-
"gpio-keys-polled", &asustor_keys_pdata, sizeof(asustor_keys_pdata));
452+
asustor_keys_pdev =
453+
asustor_create_pdev("gpio-keys-polled", &asustor_keys_pdata,
454+
sizeof(asustor_keys_pdata));
411455
if (IS_ERR(asustor_keys_pdev)) {
412456
ret = PTR_ERR(asustor_keys_pdev);
413457
platform_device_unregister(asustor_leds_pdev);

0 commit comments

Comments
 (0)