Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4321432imu; Mon, 14 Jan 2019 20:28:02 -0800 (PST) X-Google-Smtp-Source: ALg8bN7OsxTqQ9sQdkXr2fQzjsrx9eRfjSZTVWPJjm8FYfdAv4o6gE/bH+LGmDstIcORbe6M5UZB X-Received: by 2002:a65:434d:: with SMTP id k13mr2001550pgq.269.1547526482070; Mon, 14 Jan 2019 20:28:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547526482; cv=none; d=google.com; s=arc-20160816; b=rVGTCHsmfJgmQtPxaQ/J3rW4WE4p69CKS8t9Nli/6q0hw9ZHqTj70ZRZGRBPoETG3Q unxuMocy/Qh3yifyCXolTjS1bbYB6jIZlrLS5+vjQEwx/s4sVV7qasCoQ7g1EBJMjZ1P zZoI6gnQt2URREu7xLjtSLHo7Pr5FM3GeL2DU8khumvPsNTZbLY8SY2EQP3UKPCDw4Mm 8WUHarV3dWLNKRw/J+/Bjt78cnseHjlTLEODdR1mkfZlJ52L0IwdvEvPQGFi6Ut7Lc2W X1OwqjYnVLiVvHlX1a2YQALgxr8urCRM8pRtnPvBAms5e2p/a4yoqX1QjzIWqPQUOL5F gpUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:subject:from:references:in-reply-to :message-id:cc:to; bh=OS/2Buy6dSaolzlekr2SSx2qDq2AyQU437CiUtYyulc=; b=M053KOf5tBCw4mGiXAjYzLGPW+y5AqwrXd5a+v5duJUf8utBNOQCMVNE+1CfhsLwpd LV6dR07oua+xpBq34qar7X7fJS/khGLG39Mv9ucogWZGwJt+YPxK8nbKv62b2LV+/nhk 3/aNT0vi2D2oZgloZb9o+Ku0iJC+Df0f2Rw8wrpJ3Ma3+HvIuW9wmJneWxYrgwQw64Ly hc9oteZbN5aMUcSD4Mht3N9H985XE4oZeneU2QSDdKS8sZ8pIH4fZioOljOLcmOKoZhJ dbeYNnXAEknqm4HhIPInoKI9u+jLs0eQpSwJPM7+k8sgBjDiNYZCVqHgFmkQ+lo5po8h bDIw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si2222949pld.353.2019.01.14.20.27.46; Mon, 14 Jan 2019 20:28:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728406AbfAOEXv (ORCPT + 99 others); Mon, 14 Jan 2019 23:23:51 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:37474 "EHLO kvm5.telegraphics.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728144AbfAOEW0 (ORCPT ); Mon, 14 Jan 2019 23:22:26 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 3DAC829E6A; Mon, 14 Jan 2019 23:22:24 -0500 (EST) To: Arnd Bergmann , Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linuxppc-dev@lists.ozlabs.org Message-Id: In-Reply-To: References: From: Finn Thain Subject: [PATCH v9 08/22] char/nvram: Allow the set_checksum and initialize ioctls to be omitted Date: Tue, 15 Jan 2019 15:18:56 +1100 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The drivers/char/nvram.c module has previously supported only RTC "CMOS" NVRAM, for which it provides appropriate checksum ioctls. Make these ioctls optional so the module can be re-used with other kinds of NVRAM. The ops struct methods that implement the ioctls now return error codes so that a multi-platform kernel binary can do the right thing when running on hardware without a suitable NVRAM. Signed-off-by: Finn Thain --- Changed since v8: - Renamed nvram_* functions to avoid name collisions. --- drivers/char/nvram.c | 70 ++++++++++++++++++++++++------------------- include/linux/nvram.h | 2 ++ 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 2df391f78986..f88ef41d0598 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -136,16 +136,25 @@ static void __nvram_set_checksum(void) __nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1); } -#if 0 -void nvram_set_checksum(void) +static long pc_nvram_set_checksum(void) { - unsigned long flags; + spin_lock_irq(&rtc_lock); + __nvram_set_checksum(); + spin_unlock_irq(&rtc_lock); + return 0; +} - spin_lock_irqsave(&rtc_lock, flags); +static long pc_nvram_initialize(void) +{ + ssize_t i; + + spin_lock_irq(&rtc_lock); + for (i = 0; i < NVRAM_BYTES; ++i) + __nvram_write_byte(0, i); __nvram_set_checksum(); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irq(&rtc_lock); + return 0; } -#endif /* 0 */ static ssize_t pc_nvram_get_size(void) { @@ -156,6 +165,8 @@ const struct nvram_ops arch_nvram_ops = { .read_byte = pc_nvram_read_byte, .write_byte = pc_nvram_write_byte, .get_size = pc_nvram_get_size, + .set_checksum = pc_nvram_set_checksum, + .initialize = pc_nvram_initialize, }; EXPORT_SYMBOL(arch_nvram_ops); #endif /* CONFIG_X86 */ @@ -241,51 +252,50 @@ static ssize_t nvram_misc_write(struct file *file, const char __user *buf, static long nvram_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int i; + long ret = -ENOTTY; switch (cmd) { - case NVRAM_INIT: /* initialize NVRAM contents and checksum */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; - mutex_lock(&nvram_mutex); - spin_lock_irq(&rtc_lock); - - for (i = 0; i < NVRAM_BYTES; ++i) - __nvram_write_byte(0, i); - __nvram_set_checksum(); - - spin_unlock_irq(&rtc_lock); - mutex_unlock(&nvram_mutex); - return 0; - + if (arch_nvram_ops.initialize != NULL) { + mutex_lock(&nvram_mutex); + ret = arch_nvram_ops.initialize(); + mutex_unlock(&nvram_mutex); + } + break; case NVRAM_SETCKS: /* just set checksum, contents unchanged (maybe useful after * checksum garbaged somehow...) */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; - mutex_lock(&nvram_mutex); - spin_lock_irq(&rtc_lock); - __nvram_set_checksum(); - spin_unlock_irq(&rtc_lock); - mutex_unlock(&nvram_mutex); - return 0; - - default: - return -ENOTTY; + if (arch_nvram_ops.set_checksum != NULL) { + mutex_lock(&nvram_mutex); + ret = arch_nvram_ops.set_checksum(); + mutex_unlock(&nvram_mutex); + } + break; } + return ret; } static int nvram_misc_open(struct inode *inode, struct file *file) { spin_lock(&nvram_state_lock); + /* Prevent multiple readers/writers if desired. */ if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || - (nvram_open_mode & NVRAM_EXCL) || - ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { + (nvram_open_mode & NVRAM_EXCL)) { + spin_unlock(&nvram_state_lock); + return -EBUSY; + } + + /* Prevent multiple writers if the set_checksum ioctl is implemented. */ + if ((arch_nvram_ops.set_checksum != NULL) && + (file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE)) { spin_unlock(&nvram_state_lock); return -EBUSY; } diff --git a/include/linux/nvram.h b/include/linux/nvram.h index bb4ea8cc6ea6..31c763087746 100644 --- a/include/linux/nvram.h +++ b/include/linux/nvram.h @@ -31,6 +31,8 @@ struct nvram_ops { void (*write_byte)(unsigned char, int); ssize_t (*read)(char *, size_t, loff_t *); ssize_t (*write)(char *, size_t, loff_t *); + long (*initialize)(void); + long (*set_checksum)(void); }; extern const struct nvram_ops arch_nvram_ops; -- 2.19.2