mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-25 10:49:17 +00:00
scsi: Add a simple plugin to enumerate SCSI hardware
We might want this to tag insecure or broken SAS drives, cough.
This commit is contained in:
parent
adfef91731
commit
a3efbe51f6
@ -47,6 +47,7 @@ meson .. \
|
||||
-Dplugin_mtd=false \
|
||||
-Dintrospection=false \
|
||||
-Dplugin_thunderbolt=false \
|
||||
-Dplugin_scsi=false \
|
||||
-Dplugin_synaptics_mst=false \
|
||||
-Dplugin_synaptics_rmi=false \
|
||||
-Dplugin_upower=false \
|
||||
|
@ -464,6 +464,7 @@ done
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_redfish.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_rts54hid.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_rts54hub.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_scsi.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_steelseries.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_superio.so
|
||||
%if 0%{?have_dell}
|
||||
|
@ -31,6 +31,7 @@ option('plugin_pixart_rf', type : 'boolean', value : true, description : 'enable
|
||||
option('plugin_realtek_mst', type : 'boolean', value : true, description : 'enable Realtek MST hub support')
|
||||
option('plugin_synaptics_mst', type: 'boolean', value: true, description : 'enable Synaptics MST hub support')
|
||||
option('plugin_synaptics_rmi', type: 'boolean', value: true, description : 'enable Synaptics RMI support')
|
||||
option('plugin_scsi', type: 'boolean', value: true, description : 'enable SCSI support')
|
||||
option('plugin_tpm', type : 'boolean', value : true, description : 'enable TPM support')
|
||||
option('plugin_thunderbolt', type : 'boolean', value : true, description : 'enable Thunderbolt support')
|
||||
option('plugin_redfish', type : 'boolean', value : true, description : 'enable Redfish support')
|
||||
|
@ -57,6 +57,7 @@ subdir('redfish')
|
||||
subdir('rts54hid')
|
||||
subdir('rts54hub')
|
||||
subdir('steelseries')
|
||||
subdir('scsi')
|
||||
subdir('superio')
|
||||
subdir('synaptics-cape')
|
||||
subdir('synaptics-cxaudio')
|
||||
|
22
plugins/scsi/README.md
Normal file
22
plugins/scsi/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# SCSI
|
||||
|
||||
## Introduction
|
||||
|
||||
This plugin adds support for SCSI storage hardware. Devices are only enumerated
|
||||
and are not updatable.
|
||||
|
||||
## GUID Generation
|
||||
|
||||
These device use the SCSI DeviceInstanceId values, e.g.
|
||||
|
||||
* `SCSI\VEN_HP&DEV_EG0900JETKB&REV_HPD4`
|
||||
* `SCSI\VEN_HP&DEV_EG0900JETKB`
|
||||
* `SCSI\VEN_HP`
|
||||
|
||||
## Vendor ID Security
|
||||
|
||||
The vendor ID is set from the vendor, for example set to `SCSI:HP`
|
||||
|
||||
## External Interface Access
|
||||
|
||||
This plugin requires only reading from sysfs.
|
25
plugins/scsi/fu-plugin-scsi.c
Normal file
25
plugins/scsi/fu-plugin-scsi.c
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#include "fu-scsi-device.h"
|
||||
|
||||
static void
|
||||
fu_plugin_scsi_init(FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_add_udev_subsystem(plugin, "scsi");
|
||||
fu_plugin_add_device_gtype(plugin, FU_TYPE_SCSI_DEVICE);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_init_vfuncs(FuPluginVfuncs *vfuncs)
|
||||
{
|
||||
vfuncs->build_hash = FU_BUILD_HASH;
|
||||
vfuncs->init = fu_plugin_scsi_init;
|
||||
}
|
139
plugins/scsi/fu-scsi-device.c
Normal file
139
plugins/scsi/fu-scsi-device.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-scsi-device.h"
|
||||
|
||||
struct _FuScsiDevice {
|
||||
FuUdevDevice parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuScsiDevice, fu_scsi_device, FU_TYPE_UDEV_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_scsi_device_probe(FuDevice *device, GError **error)
|
||||
{
|
||||
const gchar *name;
|
||||
const gchar *vendor;
|
||||
const gchar *version;
|
||||
g_autofree gchar *name_safe = NULL;
|
||||
g_autofree gchar *subsystem = NULL;
|
||||
g_autofree gchar *vendor_safe = NULL;
|
||||
g_autofree gchar *version_safe = NULL;
|
||||
g_autoptr(GPtrArray) block_devs = NULL;
|
||||
|
||||
/* ignore */
|
||||
if (g_strcmp0(fu_udev_device_get_devtype(FU_UDEV_DEVICE(device)), "scsi_target") == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"targets are not supported");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* vendor */
|
||||
vendor = fu_udev_device_get_sysfs_attr(FU_UDEV_DEVICE(device), "vendor", NULL);
|
||||
vendor_safe = fu_common_instance_id_strsafe(vendor);
|
||||
if (vendor_safe == NULL || g_strcmp0(vendor_safe, "ATA") == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"no assigned vendor");
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_vendor(device, vendor);
|
||||
|
||||
/* name */
|
||||
name = fu_udev_device_get_sysfs_attr(FU_UDEV_DEVICE(device), "model", NULL);
|
||||
name_safe = fu_common_instance_id_strsafe(name);
|
||||
if (name_safe == NULL) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"no assigned name");
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_name(device, name);
|
||||
|
||||
/* version */
|
||||
version = fu_udev_device_get_sysfs_attr(FU_UDEV_DEVICE(device), "rev", NULL);
|
||||
version_safe = fu_common_instance_id_strsafe(version);
|
||||
if (version_safe == NULL) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"no assigned version");
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_version(device, version);
|
||||
|
||||
/* add GUIDs */
|
||||
subsystem = g_utf8_strup(fu_udev_device_get_subsystem(FU_UDEV_DEVICE(device)), -1);
|
||||
if (subsystem != NULL && vendor_safe != NULL && name_safe != NULL && version_safe != NULL) {
|
||||
g_autofree gchar *devid = NULL;
|
||||
devid = g_strdup_printf("%s\\VEN_%s&DEV_%s&REV_%s",
|
||||
subsystem,
|
||||
vendor_safe,
|
||||
name_safe,
|
||||
version_safe);
|
||||
fu_device_add_instance_id(device, devid);
|
||||
}
|
||||
if (subsystem != NULL && vendor_safe != NULL && name_safe != NULL) {
|
||||
g_autofree gchar *devid = NULL;
|
||||
devid = g_strdup_printf("%s\\VEN_%s&DEV_%s", subsystem, vendor_safe, name_safe);
|
||||
fu_device_add_instance_id(device, devid);
|
||||
}
|
||||
if (subsystem != NULL && vendor_safe != NULL) {
|
||||
g_autofree gchar *devid = NULL;
|
||||
devid = g_strdup_printf("%s\\VEN_%s", subsystem, vendor_safe);
|
||||
fu_device_add_instance_id_full(device, devid, FU_DEVICE_INSTANCE_FLAG_ONLY_QUIRKS);
|
||||
}
|
||||
if (vendor_safe != NULL) {
|
||||
g_autofree gchar *vendor_id = NULL;
|
||||
vendor_id = g_strdup_printf("SCSI:%s", vendor_safe);
|
||||
fu_device_add_vendor_id(device, vendor_id);
|
||||
}
|
||||
|
||||
/* check all block devices, although there should only be one */
|
||||
block_devs = fu_udev_device_get_children_with_subsystem(FU_UDEV_DEVICE(device), "block");
|
||||
for (guint i = 0; i < block_devs->len; i++) {
|
||||
FuUdevDevice *block_dev = g_ptr_array_index(block_devs, i);
|
||||
guint64 value = 0;
|
||||
if (!fu_udev_device_get_sysfs_attr_uint64(block_dev, "removable", &value, NULL))
|
||||
continue;
|
||||
if (value == 0x0) {
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_INTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the physical ID */
|
||||
return fu_udev_device_set_physical_id(FU_UDEV_DEVICE(device), "scsi", error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_scsi_device_init(FuScsiDevice *self)
|
||||
{
|
||||
fu_device_add_icon(FU_DEVICE(self), "drive-harddisk");
|
||||
fu_device_set_version_format(FU_DEVICE(self), FWUPD_VERSION_FORMAT_PLAIN);
|
||||
fu_device_set_summary(FU_DEVICE(self), "SCSI device");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_scsi_device_finalize(GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS(fu_scsi_device_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_scsi_device_class_init(FuScsiDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
object_class->finalize = fu_scsi_device_finalize;
|
||||
klass_device->probe = fu_scsi_device_probe;
|
||||
}
|
12
plugins/scsi/fu-scsi-device.h
Normal file
12
plugins/scsi/fu-scsi-device.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#define FU_TYPE_SCSI_DEVICE (fu_scsi_device_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuScsiDevice, fu_scsi_device, FU, SCSI_DEVICE, FuUdevDevice)
|
38
plugins/scsi/meson.build
Normal file
38
plugins/scsi/meson.build
Normal file
@ -0,0 +1,38 @@
|
||||
if get_option('plugin_scsi')
|
||||
if not get_option('gudev')
|
||||
error('gudev is required for plugin_scsi')
|
||||
endif
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginScsi"']
|
||||
|
||||
install_data([
|
||||
'scsi.quirk',
|
||||
],
|
||||
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
|
||||
)
|
||||
|
||||
shared_module('fu_plugin_scsi',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-scsi.c',
|
||||
'fu-scsi-device.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
c_args : [
|
||||
cargs,
|
||||
'-DLOCALSTATEDIR="' + localstatedir + '"',
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
||||
endif
|
24
plugins/scsi/scsi.quirk
Normal file
24
plugins/scsi/scsi.quirk
Normal file
@ -0,0 +1,24 @@
|
||||
[SCSI]
|
||||
Plugin = scsi
|
||||
|
||||
[SCSI\VEN_LSI&DEV_VirtualSES]
|
||||
Flags = no-probe
|
||||
[SCSI\VEN_Marvell&DEV_Console]
|
||||
Flags = no-probe
|
||||
|
||||
[SCSI\VEN_HP&DEV_EK0800JVYPN&REV_HPD5]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_EK0800JVYPN&REV_HPD6]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_EO1600JVYPP&REV_HPD5]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_EO1600JVYPP&REV_HPD6]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_MK0800JVYPQ&REV_HPD5]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_MK0800JVYPQ&REV_HPD6]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_MO1600JVYPR&REV_HPD5]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
||||
[SCSI\VEN_HP&DEV_MO1600JVYPR&REV_HPD6]
|
||||
Issue = MTX-6f54e8621f4c490a918defdab6
|
Loading…
Reference in New Issue
Block a user