From: "Pali Rohár" <pali.rohar@gmail.com>
To: "Michał Kępień" <kernel@kempniu.pl>
Cc: Darren Hart <dvhart@infradead.org>,
Matthew Garrett <mjg59@srcf.ucam.org>,
Richard Purdie <rpurdie@rpsys.net>,
Jacek Anaszewski <j.anaszewski@samsung.com>,
Alex Hung <alex.hung@canonical.com>,
platform-driver-x86@vger.kernel.org, linux-leds@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 01/14] dell-laptop: extract SMBIOS-related code to a separate module
Date: Sat, 16 Jan 2016 16:19:22 +0100 [thread overview]
Message-ID: <20160116151922.GA5060@pali> (raw)
In-Reply-To: <1452607380-20861-2-git-send-email-kernel@kempniu.pl>
On Tuesday 12 January 2016 15:02:47 Michał Kępień wrote:
> Extract SMBIOS-related code from dell-laptop to a new kernel module,
> dell-smbios. The static specifier was removed from exported symbols,
> otherwise code is just moved around.
>
> Signed-off-by: Michał Kępień <kernel@kempniu.pl>
> ---
> drivers/platform/x86/Kconfig | 12 ++-
> drivers/platform/x86/Makefile | 1 +
> drivers/platform/x86/dell-laptop.c | 163 +-----------------------------
> drivers/platform/x86/dell-smbios.c | 193 ++++++++++++++++++++++++++++++++++++
> drivers/platform/x86/dell-smbios.h | 51 ++++++++++
> 5 files changed, 257 insertions(+), 163 deletions(-)
> create mode 100644 drivers/platform/x86/dell-smbios.c
> create mode 100644 drivers/platform/x86/dell-smbios.h
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index f37821f..177a794 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -91,10 +91,20 @@ config ASUS_LAPTOP
>
> If you have an ACPI-compatible ASUS laptop, say Y or M here.
>
> +config DELL_SMBIOS
> + tristate "Dell SMBIOS Support"
> + depends on DCDBAS
> + default n
> + ---help---
> + This module provides common functions for kernel modules using
> + Dell SMBIOS.
> +
> + If you have a Dell laptop, say Y or M here.
> +
> config DELL_LAPTOP
> tristate "Dell Laptop Extras"
> depends on X86
> - depends on DCDBAS
> + depends on DELL_SMBIOS
> depends on BACKLIGHT_CLASS_DEVICE
> depends on ACPI_VIDEO || ACPI_VIDEO = n
> depends on RFKILL || RFKILL = n
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index 8b8df29..1128595 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
> obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
> obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
> obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
> +obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
> obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
> obj-$(CONFIG_DELL_WMI) += dell-wmi.o
> obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
> diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
> index aaeeae8..d45d356 100644
> --- a/drivers/platform/x86/dell-laptop.c
> +++ b/drivers/platform/x86/dell-laptop.c
> @@ -28,12 +28,11 @@
> #include <linux/acpi.h>
> #include <linux/mm.h>
> #include <linux/i8042.h>
> -#include <linux/slab.h>
> #include <linux/debugfs.h>
> #include <linux/seq_file.h>
> #include <acpi/video.h>
> -#include "../../firmware/dcdbas.h"
> #include "dell-rbtn.h"
> +#include "dell-smbios.h"
>
> #define BRIGHTNESS_TOKEN 0x7d
> #define KBD_LED_OFF_TOKEN 0x01E1
> @@ -44,33 +43,6 @@
> #define KBD_LED_AUTO_75_TOKEN 0x02EC
> #define KBD_LED_AUTO_100_TOKEN 0x02F6
>
> -/* This structure will be modified by the firmware when we enter
> - * system management mode, hence the volatiles */
> -
> -struct calling_interface_buffer {
> - u16 class;
> - u16 select;
> - volatile u32 input[4];
> - volatile u32 output[4];
> -} __packed;
> -
> -struct calling_interface_token {
> - u16 tokenID;
> - u16 location;
> - union {
> - u16 value;
> - u16 stringlength;
> - };
> -};
> -
> -struct calling_interface_structure {
> - struct dmi_header header;
> - u16 cmdIOAddress;
> - u8 cmdIOCode;
> - u32 supportedCmds;
> - struct calling_interface_token tokens[];
> -} __packed;
> -
> struct quirk_entry {
> u8 touchpad_led;
>
> @@ -103,11 +75,6 @@ static struct quirk_entry quirk_dell_xps13_9333 = {
> .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
> };
>
> -static int da_command_address;
> -static int da_command_code;
> -static int da_num_tokens;
> -static struct calling_interface_token *da_tokens;
> -
> static struct platform_driver platform_driver = {
> .driver = {
> .name = "dell-laptop",
> @@ -306,112 +273,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
> { }
> };
>
> -static struct calling_interface_buffer *buffer;
> -static DEFINE_MUTEX(buffer_mutex);
> -
> -static void clear_buffer(void)
> -{
> - memset(buffer, 0, sizeof(struct calling_interface_buffer));
> -}
> -
> -static void get_buffer(void)
> -{
> - mutex_lock(&buffer_mutex);
> - clear_buffer();
> -}
> -
> -static void release_buffer(void)
> -{
> - mutex_unlock(&buffer_mutex);
> -}
> -
> -static void __init parse_da_table(const struct dmi_header *dm)
> -{
> - /* Final token is a terminator, so we don't want to copy it */
> - int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
> - struct calling_interface_token *new_da_tokens;
> - struct calling_interface_structure *table =
> - container_of(dm, struct calling_interface_structure, header);
> -
> - /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least
> - 6 bytes of entry */
> -
> - if (dm->length < 17)
> - return;
> -
> - da_command_address = table->cmdIOAddress;
> - da_command_code = table->cmdIOCode;
> -
> - new_da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) *
> - sizeof(struct calling_interface_token),
> - GFP_KERNEL);
> -
> - if (!new_da_tokens)
> - return;
> - da_tokens = new_da_tokens;
> -
> - memcpy(da_tokens+da_num_tokens, table->tokens,
> - sizeof(struct calling_interface_token) * tokens);
> -
> - da_num_tokens += tokens;
> -}
> -
> -static void __init find_tokens(const struct dmi_header *dm, void *dummy)
> -{
> - switch (dm->type) {
> - case 0xd4: /* Indexed IO */
> - case 0xd5: /* Protected Area Type 1 */
> - case 0xd6: /* Protected Area Type 2 */
> - break;
> - case 0xda: /* Calling interface */
> - parse_da_table(dm);
> - break;
> - }
> -}
> -
> -static int find_token_id(int tokenid)
> -{
> - int i;
> -
> - for (i = 0; i < da_num_tokens; i++) {
> - if (da_tokens[i].tokenID == tokenid)
> - return i;
> - }
> -
> - return -1;
> -}
> -
> -static int find_token_location(int tokenid)
> -{
> - int id;
> -
> - id = find_token_id(tokenid);
> - if (id == -1)
> - return -1;
> -
> - return da_tokens[id].location;
> -}
> -
> -static struct calling_interface_buffer *
> -dell_send_request(struct calling_interface_buffer *buffer, int class,
> - int select)
> -{
> - struct smi_cmd command;
> -
> - command.magic = SMI_CMD_MAGIC;
> - command.command_address = da_command_address;
> - command.command_code = da_command_code;
> - command.ebx = virt_to_phys(buffer);
> - command.ecx = 0x42534931;
> -
> - buffer->class = class;
> - buffer->select = select;
> -
> - dcdbas_smi_request(&command);
> -
> - return buffer;
> -}
> -
> static inline int dell_smi_error(int value)
> {
> switch (value) {
> @@ -2122,13 +1983,6 @@ static int __init dell_init(void)
> /* find if this machine support other functions */
> dmi_check_system(dell_quirks);
>
> - dmi_walk(find_tokens, NULL);
> -
> - if (!da_tokens) {
> - pr_info("Unable to find dmi tokens\n");
> - return -ENODEV;
> - }
> -
> ret = platform_driver_register(&platform_driver);
> if (ret)
> goto fail_platform_driver;
> @@ -2141,16 +1995,6 @@ static int __init dell_init(void)
> if (ret)
> goto fail_platform_device2;
>
> - /*
> - * Allocate buffer below 4GB for SMI data--only 32-bit physical addr
> - * is passed to SMI handler.
> - */
> - buffer = (void *)__get_free_page(GFP_KERNEL | GFP_DMA32);
> - if (!buffer) {
> - ret = -ENOMEM;
> - goto fail_buffer;
> - }
> -
> ret = dell_setup_rfkill();
>
> if (ret) {
> @@ -2208,15 +2052,12 @@ static int __init dell_init(void)
> fail_backlight:
> dell_cleanup_rfkill();
> fail_rfkill:
> - free_page((unsigned long)buffer);
> -fail_buffer:
> platform_device_del(platform_device);
> fail_platform_device2:
> platform_device_put(platform_device);
> fail_platform_device1:
> platform_driver_unregister(&platform_driver);
> fail_platform_driver:
> - kfree(da_tokens);
> return ret;
> }
>
> @@ -2232,8 +2073,6 @@ static void __exit dell_exit(void)
> platform_device_unregister(platform_device);
> platform_driver_unregister(&platform_driver);
> }
> - kfree(da_tokens);
> - free_page((unsigned long)buffer);
> }
>
> /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
> new file mode 100644
> index 0000000..260a32a
> --- /dev/null
> +++ b/drivers/platform/x86/dell-smbios.c
> @@ -0,0 +1,193 @@
> +/*
> + * Common functions for kernel modules using Dell SMBIOS
> + *
> + * Copyright (c) Red Hat <mjg@redhat.com>
> + * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com>
> + * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com>
> + *
> + * Based on documentation in the libsmbios package:
> + * Copyright (C) 2005-2014 Dell Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/dmi.h>
> +#include <linux/gfp.h>
> +#include <linux/mutex.h>
> +#include <linux/slab.h>
> +#include "../../firmware/dcdbas.h"
> +#include "dell-smbios.h"
> +
> +struct calling_interface_structure {
> + struct dmi_header header;
> + u16 cmdIOAddress;
> + u8 cmdIOCode;
> + u32 supportedCmds;
> + struct calling_interface_token tokens[];
> +} __packed;
> +
> +static DEFINE_MUTEX(buffer_mutex);
> +struct calling_interface_buffer *buffer;
> +EXPORT_SYMBOL_GPL(buffer);
> +
> +static int da_command_address;
> +static int da_command_code;
> +static int da_num_tokens;
> +struct calling_interface_token *da_tokens;
> +EXPORT_SYMBOL_GPL(da_tokens);
> +
> +void clear_buffer(void)
> +{
> + memset(buffer, 0, sizeof(struct calling_interface_buffer));
> +}
> +EXPORT_SYMBOL_GPL(clear_buffer);
> +
> +void get_buffer(void)
> +{
> + mutex_lock(&buffer_mutex);
> + clear_buffer();
> +}
> +EXPORT_SYMBOL_GPL(get_buffer);
> +
> +void release_buffer(void)
> +{
> + mutex_unlock(&buffer_mutex);
> +}
> +EXPORT_SYMBOL_GPL(release_buffer);
> +
> +int find_token_id(int tokenid)
> +{
> + int i;
> +
> + for (i = 0; i < da_num_tokens; i++) {
> + if (da_tokens[i].tokenID == tokenid)
> + return i;
> + }
> +
> + return -1;
> +}
> +EXPORT_SYMBOL_GPL(find_token_id);
> +
> +int find_token_location(int tokenid)
> +{
> + int id;
> +
> + id = find_token_id(tokenid);
> + if (id == -1)
> + return -1;
> +
> + return da_tokens[id].location;
> +}
> +EXPORT_SYMBOL_GPL(find_token_location);
> +
> +struct calling_interface_buffer *
> +dell_send_request(struct calling_interface_buffer *buffer, int class,
> + int select)
> +{
> + struct smi_cmd command;
> +
> + command.magic = SMI_CMD_MAGIC;
> + command.command_address = da_command_address;
> + command.command_code = da_command_code;
> + command.ebx = virt_to_phys(buffer);
> + command.ecx = 0x42534931;
> +
> + buffer->class = class;
> + buffer->select = select;
> +
> + dcdbas_smi_request(&command);
> +
> + return buffer;
> +}
> +EXPORT_SYMBOL_GPL(dell_send_request);
> +
> +static void __init parse_da_table(const struct dmi_header *dm)
> +{
> + /* Final token is a terminator, so we don't want to copy it */
> + int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
> + struct calling_interface_token *new_da_tokens;
> + struct calling_interface_structure *table =
> + container_of(dm, struct calling_interface_structure, header);
> +
> + /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least
> + 6 bytes of entry */
> +
> + if (dm->length < 17)
> + return;
> +
> + da_command_address = table->cmdIOAddress;
> + da_command_code = table->cmdIOCode;
> +
> + new_da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) *
> + sizeof(struct calling_interface_token),
> + GFP_KERNEL);
> +
> + if (!new_da_tokens)
> + return;
> + da_tokens = new_da_tokens;
> +
> + memcpy(da_tokens+da_num_tokens, table->tokens,
> + sizeof(struct calling_interface_token) * tokens);
> +
> + da_num_tokens += tokens;
> +}
> +
> +static void __init find_tokens(const struct dmi_header *dm, void *dummy)
> +{
> + switch (dm->type) {
> + case 0xd4: /* Indexed IO */
> + case 0xd5: /* Protected Area Type 1 */
> + case 0xd6: /* Protected Area Type 2 */
> + break;
> + case 0xda: /* Calling interface */
> + parse_da_table(dm);
> + break;
> + }
> +}
> +
> +static int __init dell_smbios_init(void)
> +{
> + int ret;
> +
> + dmi_walk(find_tokens, NULL);
> +
> + if (!da_tokens) {
> + pr_info("Unable to find dmi tokens\n");
> + return -ENODEV;
> + }
> +
> + /*
> + * Allocate buffer below 4GB for SMI data--only 32-bit physical addr
> + * is passed to SMI handler.
> + */
> + buffer = (void *)__get_free_page(GFP_KERNEL | GFP_DMA32);
> + if (!buffer) {
> + ret = -ENOMEM;
> + goto fail_buffer;
> + }
> +
> + return 0;
> +
> +fail_buffer:
> + kfree(da_tokens);
> + return ret;
> +}
> +
> +static void __exit dell_smbios_exit(void)
> +{
> + kfree(da_tokens);
> + free_page((unsigned long)buffer);
> +}
> +
> +subsys_initcall(dell_smbios_init);
> +module_exit(dell_smbios_exit);
> +
> +MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
> +MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
> +MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
> +MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/platform/x86/dell-smbios.h b/drivers/platform/x86/dell-smbios.h
> new file mode 100644
> index 0000000..00e03b2
> --- /dev/null
> +++ b/drivers/platform/x86/dell-smbios.h
> @@ -0,0 +1,51 @@
> +/*
> + * Common functions for kernel modules using Dell SMBIOS
> + *
> + * Copyright (c) Red Hat <mjg@redhat.com>
> + * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com>
> + * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com>
> + *
> + * Based on documentation in the libsmbios package:
> + * Copyright (C) 2005-2014 Dell Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef _DELL_SMBIOS_H_
> +#define _DELL_SMBIOS_H_
> +
> +/* This structure will be modified by the firmware when we enter
> + * system management mode, hence the volatiles */
> +
> +struct calling_interface_buffer {
> + u16 class;
> + u16 select;
> + volatile u32 input[4];
> + volatile u32 output[4];
> +} __packed;
> +
> +struct calling_interface_token {
> + u16 tokenID;
> + u16 location;
> + union {
> + u16 value;
> + u16 stringlength;
> + };
> +};
After patch 12/14 you do not need to define this struct in header file.
> +extern struct calling_interface_buffer *buffer;
> +extern struct calling_interface_token *da_tokens;
Better hide this variable in dell-smbios.c code ...
> +void clear_buffer(void);
> +void get_buffer(void);
> +void release_buffer(void);
... and let those functions to get parameter to buffer.
E.g. get_buffer will return buffer and other two functions will take
buffer parameter.
> +int find_token_id(int tokenid);
> +int find_token_location(int tokenid);
> +
> +struct calling_interface_buffer *
> +dell_send_request(struct calling_interface_buffer *buffer, int class,
> + int select);
> +#endif
--
Pali Rohár
pali.rohar@gmail.com
next prev parent reply other threads:[~2016-01-16 15:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-12 14:02 [PATCH 00/14] Common Dell SMBIOS API Michał Kępień
2016-01-12 14:02 ` [PATCH 01/14] dell-laptop: extract SMBIOS-related code to a separate module Michał Kępień
2016-01-16 15:19 ` Pali Rohár [this message]
2016-01-18 10:34 ` Michał Kępień
2016-01-20 9:21 ` Michał Kępień
2016-01-21 8:35 ` Pali Rohár
2016-01-21 13:06 ` Michał Kępień
2016-01-21 13:14 ` Pali Rohár
2016-01-21 13:39 ` Michał Kępień
2016-02-08 21:42 ` Darren Hart
2016-02-09 8:33 ` Pali Rohár
2016-02-09 13:58 ` Michał Kępień
2016-02-09 16:51 ` Darren Hart
2016-02-09 19:12 ` Pali Rohár
2016-02-10 23:03 ` Darren Hart
2016-01-12 14:02 ` [PATCH 02/14] dell-smbios: don't pass a buffer to dell_send_request() Michał Kępień
2016-01-12 14:02 ` [PATCH 03/14] dell-smbios: rename buffer to dell_smbios_buffer Michał Kępień
2016-01-12 14:02 ` [PATCH 04/14] dell-smbios: rename clear_buffer() to dell_smbios_clear_buffer() Michał Kępień
2016-01-12 14:02 ` [PATCH 05/14] dell-smbios: rename get_buffer() to dell_smbios_get_buffer() Michał Kępień
2016-01-12 14:02 ` [PATCH 06/14] dell-smbios: rename release_buffer() to dell_smbios_release_buffer() Michał Kępień
2016-01-12 14:02 ` [PATCH 07/14] dell-smbios: rename dell_send_request() to dell_smbios_send_request() Michał Kępień
2016-01-12 14:02 ` [PATCH 08/14] dell-smbios: implement new function for finding DMI table 0xDA tokens Michał Kępień
2016-01-12 14:02 ` [PATCH 09/14] dell-laptop: use dell_smbios_find_token() instead of find_token_id() Michał Kępień
2016-01-12 14:02 ` [PATCH 10/14] dell-laptop: use dell_smbios_find_token() instead of find_token_location() Michał Kępień
2016-01-12 14:02 ` [PATCH 11/14] dell-smbios: remove find_token_{id,location}() Michał Kępień
2016-01-12 14:02 ` [PATCH 12/14] dell-smbios: make da_tokens static Michał Kępień
2016-01-12 14:02 ` [PATCH 13/14] dell-led: use dell_smbios_find_token() for finding mic DMI tokens Michał Kępień
2016-01-21 10:52 ` Jacek Anaszewski
2016-01-21 15:00 ` Michał Kępień
2016-01-21 15:42 ` Jacek Anaszewski
2016-01-12 14:03 ` [PATCH 14/14] dell-led: use dell_smbios_send_request() for SMBIOS requests Michał Kępień
2016-01-14 22:43 ` [PATCH 00/14] Common Dell SMBIOS API Darren Hart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160116151922.GA5060@pali \
--to=pali.rohar@gmail.com \
--cc=alex.hung@canonical.com \
--cc=dvhart@infradead.org \
--cc=j.anaszewski@samsung.com \
--cc=kernel@kempniu.pl \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rpurdie@rpsys.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).