From patchwork Wed Jan 25 07:56:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyril Bur X-Patchwork-Id: 719565 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3v7crt2Rcsz9sdm for ; Wed, 25 Jan 2017 18:59:26 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3v7crt1W9bzDqGj for ; Wed, 25 Jan 2017 18:59:26 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3v7crj0kB0zDqFw for ; Wed, 25 Jan 2017 18:59:16 +1100 (AEDT) Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v0P7x6BZ113236 for ; Wed, 25 Jan 2017 02:59:13 -0500 Received: from e23smtp04.au.ibm.com (e23smtp04.au.ibm.com [202.81.31.146]) by mx0a-001b2d01.pphosted.com with ESMTP id 286ahuctxa-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 25 Jan 2017 02:59:13 -0500 Received: from localhost by e23smtp04.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 25 Jan 2017 17:59:11 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp04.au.ibm.com (202.81.31.210) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 25 Jan 2017 17:59:08 +1000 Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id E94E23578057 for ; Wed, 25 Jan 2017 18:59:07 +1100 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v0P7wxVa38600804 for ; Wed, 25 Jan 2017 18:59:07 +1100 Received: from d23av04.au.ibm.com (localhost [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v0P7wZth020486 for ; Wed, 25 Jan 2017 18:58:35 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v0P7wZHS019965; Wed, 25 Jan 2017 18:58:35 +1100 Received: from camb691.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) (using TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.au.ibm.com (Postfix) with ESMTPSA id DE940A0272; Wed, 25 Jan 2017 18:58:10 +1100 (AEDT) From: Cyril Bur To: skiboot@lists.ozlabs.org Date: Wed, 25 Jan 2017 18:56:52 +1100 X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170125075653.9255-1-cyril.bur@au1.ibm.com> References: <20170125075653.9255-1-cyril.bur@au1.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17012507-0012-0000-0000-00000208E422 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17012507-0013-0000-0000-000006E0D3A8 Message-Id: <20170125075653.9255-2-cyril.bur@au1.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-01-25_04:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=4 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1701250078 Subject: [Skiboot] [RFC PATCH 1/2] libflash/blocklevel: Optionally always return opal-api return codes X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" With the introduction of the blocklevel abstraction layer some of the return code passing got neglected. This isn't a very big deal for skiboot/external tools however this can be a problem in skiboot proper. Some of the opal-api calls could pass back values from blocklevel directly along the api in which case it is quite important that the values are valid and make some sense. Signed-off-by: Cyril Bur --- libflash/Makefile.inc | 4 ++- libflash/blocklevel-errors.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ libflash/blocklevel-errors.h | 30 ++++++++++++++++++++ libflash/blocklevel.c | 59 +++++++++++++++++++++----------------- libflash/blocklevel.h | 3 ++ 5 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 libflash/blocklevel-errors.c create mode 100644 libflash/blocklevel-errors.h diff --git a/libflash/Makefile.inc b/libflash/Makefile.inc index 4db02a1f..184524f9 100644 --- a/libflash/Makefile.inc +++ b/libflash/Makefile.inc @@ -1,4 +1,6 @@ -LIBFLASH_SRCS = libflash.c libffs.c ecc.c blocklevel.c +LIBFLASH_SRCS = libflash.c libffs.c ecc.c blocklevel.c \ + blocklevel-errors.c + LIBFLASH_OBJS = $(LIBFLASH_SRCS:%.c=%.o) SUBDIRS += libflash diff --git a/libflash/blocklevel-errors.c b/libflash/blocklevel-errors.c new file mode 100644 index 00000000..16160d95 --- /dev/null +++ b/libflash/blocklevel-errors.c @@ -0,0 +1,67 @@ +/* Copyright 2017 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SKIBOOT__ +#error "It doesn't make sense to use this outside skiboot proper" +#endif + +#include + +#include +#include +#include + +int check_rc(struct blocklevel_device *bl, int rc) +{ + if (!(bl->flags & OPAL_RETURN_CODE_ONLY) || rc < 1) + return rc; + + switch (rc) { + case FLASH_ERR_MALLOC_FAILED: + return OPAL_NO_MEM; + + case FLASH_ERR_CHIP_UNKNOWN: + return OPAL_HARDWARE; + + case FLASH_ERR_PARM_ERROR: + return OPAL_PARAMETER; + + case FLASH_ERR_ERASE_BOUNDARY: + return OPAL_UNSUPPORTED; /* or just OPAL_PARAMETER? */ + + case FLASH_ERR_WREN_TIMEOUT: + case FLASH_ERR_WIP_TIMEOUT: + case FLASH_ERR_VERIFY_FAILURE: + return OPAL_INTERNAL_ERROR; + + case FLASH_ERR_4B_NOT_SUPPORTED: + return OPAL_UNSUPPORTED; + + case FLASH_ERR_CTRL_CONFIG_MISMATCH: + return OPAL_INTERNAL_ERROR; + + case FLASH_ERR_CHIP_ER_NOT_SUPPORTED: + case FLASH_ERR_CTRL_CMD_UNSUPPORTED: + return OPAL_UNSUPPORTED; + + case FLASH_ERR_CTRL_TIMEOUT: + case FLASH_ERR_ECC_INVALID: + case FLASH_ERR_BAD_READ: + return OPAL_INTERNAL_ERROR; + } + + return rc; +} diff --git a/libflash/blocklevel-errors.h b/libflash/blocklevel-errors.h new file mode 100644 index 00000000..e01f7ce3 --- /dev/null +++ b/libflash/blocklevel-errors.h @@ -0,0 +1,30 @@ +/* Copyright 2017 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBFLASH_BLOCKLEVEL_ERRORS_H +#define __LIBFLASH_BLOCKLEVEL_ERRORS_H + +#include + +#ifdef __SKIBOOT__ +int check_rc(struct blocklevel_device *bl, int rc); +#else +static inline int check_rc(struct blocklevel_device *bl __attribute__((unused)), int rc) +{ + return rc; +} +#endif +#endif /* __LIBFLASH_BLOCKLEVEL_ERRORS_H */ diff --git a/libflash/blocklevel.c b/libflash/blocklevel.c index 79ff00f4..c0057fa8 100644 --- a/libflash/blocklevel.c +++ b/libflash/blocklevel.c @@ -23,6 +23,7 @@ #include #include +#include #include "blocklevel.h" #include "ecc.h" @@ -84,18 +85,18 @@ int blocklevel_raw_read(struct blocklevel_device *bl, uint64_t pos, void *buf, u if (!bl || !bl->read || !buf) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } rc = reacquire(bl); if (rc) - return rc; + return check_rc(bl, rc); rc = bl->read(bl, pos, buf, len); release(bl); - return rc; + return check_rc(bl, rc); } int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len) @@ -106,11 +107,11 @@ int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint6 if (!bl || !buf) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } if (!ecc_protected(bl, pos, len)) - return blocklevel_raw_read(bl, pos, buf, len); + return blocklevel_raw_read(bl, pos, buf, len); /* This checks its return code */ buffer = malloc(ecc_len); if (!buffer) { @@ -130,7 +131,7 @@ int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint6 out: free(buffer); - return rc; + return check_rc(bl, rc); } int blocklevel_raw_write(struct blocklevel_device *bl, uint64_t pos, @@ -140,18 +141,18 @@ int blocklevel_raw_write(struct blocklevel_device *bl, uint64_t pos, if (!bl || !bl->write || !buf) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } rc = reacquire(bl); if (rc) - return rc; + return check_rc(bl, rc); rc = bl->write(bl, pos, buf, len); release(bl); - return rc; + return check_rc(bl, rc); } int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, @@ -163,11 +164,11 @@ int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf if (!bl || !buf) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } if (!ecc_protected(bl, pos, len)) - return blocklevel_raw_write(bl, pos, buf, len); + return blocklevel_raw_write(bl, pos, buf, len); /* This checks its return code */ buffer = malloc(ecc_len); if (!buffer) { @@ -186,7 +187,7 @@ int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf out: free(buffer); - return rc; + return check_rc(bl, rc); } int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len) @@ -194,25 +195,25 @@ int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len) int rc; if (!bl || !bl->erase) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } /* Programmer may be making a horrible mistake without knowing it */ if (len & bl->erase_mask) { fprintf(stderr, "blocklevel_erase: len (0x%"PRIx64") is not erase block (0x%08x) aligned\n", len, bl->erase_mask + 1); - return FLASH_ERR_ERASE_BOUNDARY; + return check_rc(bl, FLASH_ERR_ERASE_BOUNDARY); } rc = reacquire(bl); if (rc) - return rc; + return check_rc(bl, rc); rc = bl->erase(bl, pos, len); release(bl); - return rc; + return check_rc(bl, rc); } int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size, @@ -222,12 +223,12 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_ if (!bl || !bl->get_info) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } rc = reacquire(bl); if (rc) - return rc; + return check_rc(bl, rc); rc = bl->get_info(bl, name, total_size, erase_granule); @@ -238,7 +239,7 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_ release(bl); - return rc; + return check_rc(bl, rc); } /* @@ -280,13 +281,13 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi if (!write_buf || !bl) { errno = EINVAL; - return FLASH_ERR_PARM_ERROR; + return check_rc(bl, FLASH_ERR_PARM_ERROR); } if (!(bl->flags & WRITE_NEED_ERASE)) - return blocklevel_write(bl, pos, buf, len); + return blocklevel_write(bl, pos, buf, len); /* This checks its return code */ - rc = blocklevel_get_info(bl, NULL, NULL, &erase_size); + rc = blocklevel_get_info(bl, NULL, NULL, &erase_size); /* This checks its return code */ if (rc) return rc; @@ -296,13 +297,13 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi write_buf_start = malloc(len); if (!write_buf_start) { errno = ENOMEM; - return FLASH_ERR_MALLOC_FAILED; + return check_rc(bl, FLASH_ERR_MALLOC_FAILED); } if (memcpy_to_ecc(write_buf_start, buf, ecc_buffer_size_minus_ecc(len))) { free(write_buf_start); errno = EBADF; - return FLASH_ERR_ECC_INVALID; + return check_rc(bl, FLASH_ERR_ECC_INVALID); } write_buf = write_buf_start; } @@ -352,7 +353,7 @@ out: out_free: free(write_buf_start); free(erase_buf); - return rc; + return check_rc(bl, rc); } static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot_range range) @@ -459,3 +460,11 @@ int blocklevel_ecc_protect(struct blocklevel_device *bl, uint32_t start, uint32_ return -1; return !insert_bl_prot_range(&bl->ecc_prot, range); } + +void blocklevel_force_opal_codes(struct blocklevel_device *bl) +{ + if (!bl) + return; + + bl->flags |= OPAL_RETURN_CODE_ONLY; +} diff --git a/libflash/blocklevel.h b/libflash/blocklevel.h index 09f0096a..bf6def7a 100644 --- a/libflash/blocklevel.h +++ b/libflash/blocklevel.h @@ -32,6 +32,7 @@ struct blocklevel_range { enum blocklevel_flags { WRITE_NEED_ERASE = 1, + OPAL_RETURN_CODE_ONLY = 2, }; /* @@ -78,4 +79,6 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi /* Implemented in software at this level */ int blocklevel_ecc_protect(struct blocklevel_device *bl, uint32_t start, uint32_t len); +void blocklevel_force_opal_codes(struct blocklevel_device *bl); + #endif /* __LIBFLASH_BLOCKLEVEL_H */