Re: [PATCH 4/5] platform/x86: msi-ec: Add EC bit operation functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 10/11/23 14:59, Ilpo Järvinen wrote:
> On Tue, 10 Oct 2023, Nikita Kravets wrote:
> 
>> The EC of MSI laptops supports several features represented by a single
>> bit. Add ec_set_bit and ec_check_bit functions to operate on these bits.
>>
>> Cc: Aakash Singh <mail@xxxxxxxxxxxxxxx>
>> Cc: Jose Angel Pastrana <japp0005@xxxxxxxxxxxx>
>> Signed-off-by: Nikita Kravets <teackot@xxxxxxxxx>
>> ---
>>  drivers/platform/x86/msi-ec.c | 28 ++++++++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>
>> diff --git a/drivers/platform/x86/msi-ec.c b/drivers/platform/x86/msi-ec.c
>> index 09472b21e093..ae73dcf01d09 100644
>> --- a/drivers/platform/x86/msi-ec.c
>> +++ b/drivers/platform/x86/msi-ec.c
>> @@ -699,6 +699,34 @@ static int ec_read_seq(u8 addr, u8 *buf, u8 len)
>>  	return 0;
>>  }
>>  
>> +static int ec_set_bit(u8 addr, u8 bit, bool value)
>> +{
>> +	int result;
>> +	u8 stored;
>> +
>> +	result = ec_read(addr, &stored);
>> +	if (result < 0)
>> +		return result;
>> +
>> +	stored ^= (-(u8) value ^ stored) & (1 << bit);
> 
> So first you case bool to u8 and then take negation of that unsigned 
> number? ...My head is already hurting even without all the other logic.
> 
> This has to be rewritten to something that mere mortals can understand 
> which doesn't explore all those odd corners of C spec. :-)
> 
> I didn't try to parse that logic through but I assuming it's the usual 
> construct perhaps this could be simplified with (please be sure to check 
> this throughoutly as I didn't try to understand what the original really 
> does):
> 
> 	bit = 1 << bit;
> 	stored &= ~bit;
> 	stored |= value ? bit : 0;

Right instead of using a bit variable I would suggest
using the BIT(x) macro here:

 	stored &= ~BIT(bit);
 	stored |= value ? BIT(bit) : 0;

Also since you are exposing multiple userspace
entry points into the kernel this function may
race with itself, so I think you need to add
a mutex and lock this while doing the
read-modify-write to avoid 2 read-modify-write
cycles from racing with each other.

Regards,

Hans






> 
>> +
>> +	return ec_write(addr, stored);
>> +}
>> +
>> +static int ec_check_bit(u8 addr, u8 bit, bool *output)
>> +{
>> +	int result;
>> +	u8 stored;
>> +
>> +	result = ec_read(addr, &stored);
>> +	if (result < 0)
>> +		return result;
>> +
>> +	*output = (stored >> bit) & 1;
>> +
>> +	return 0;
>> +}
>> +
>>  static int ec_get_firmware_version(u8 buf[MSI_EC_FW_VERSION_LENGTH + 1])
>>  {
>>  	int result;
>>
> 




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux