All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Norris <computersforpeace@gmail.com>
To: <linux-mtd@lists.infradead.org>
Cc: "Brian Norris" <computersforpeace@gmail.com>,
	"Rafał Miłecki" <zajec5@gmail.com>,
	"Ezequiel Garcia" <ezequiel@vanguardiasur.com.ar>,
	"Boris Brezillon" <boris.brezillon@free-electrons.com>,
	linux-kernel@vger.kernel.org,
	"Bayi Cheng" <bayi.cheng@mediatek.com>,
	"Marek Vasut" <marex@denx.de>,
	djkurtz@chromium.org
Subject: [PATCH v2 0/8] mtd: spi-nor: locking fixes and updates
Date: Fri, 29 Jan 2016 11:25:29 -0800	[thread overview]
Message-ID: <1454095537-130536-1-git-send-email-computersforpeace@gmail.com> (raw)

Hi,

These are an assortment of fixes and updates to the SPI NOR lock/unlock
feature. The biggest new features are:
(a) Status Register protection; I don't see why this shouldn't be enabled by
    default. See patch 4's description.
(b) Bottom-block protection support (via TB status bit)
(c) Lock/unlock support for a few Winbond flash

Since v1:
 * patches 3 and 7 are somewhat rewritten versions of patches 2 and 7 in v1
 * fix up several corner cases, seen in some local tests (poor, slow shell
   script appended)
 * remove SR protection (SR_SRWD) when unlocking the entire flash

Regards,
Brian

Brian Norris (8):
  mtd: spi-nor: wait for SR_WIP to clear on initial unlock
  mtd: spi-nor: silently drop lock/unlock for already locked/unlocked
    region
  mtd: spi-nor: make lock/unlock bounds checks more obvious and robust
  mtd: spi-nor: disallow further writes to SR if WP# is low
  mtd: spi-nor: use BIT() for flash_info flags
  mtd: spi-nor: add SPI_NOR_HAS_LOCK flag
  mtd: spi-nor: add TB (Top/Bottom) protect support
  mtd: spi-nor: support lock/unlock for a few Winbond chips

 drivers/mtd/spi-nor/spi-nor.c | 195 ++++++++++++++++++++++++++++++++++--------
 include/linux/mtd/spi-nor.h   |   2 +
 2 files changed, 159 insertions(+), 38 deletions(-)


Appending badly-written shell test script. Requires latest mtd-utils
(flash_lock / flash_unlock).

------8<------
#!/bin/sh
#
# License: GPLv2
# Copyright (c) 2016 Google, Inc.

MTD=/dev/mtd0

UNLOCK="flash_unlock ${MTD}"
LOCK="flash_lock ${MTD}"
ISLOCKED="flash_lock --islocked ${MTD}"

MTD_SYSFS="/sys/class/mtd"

MTDX=$(echo $MTD | grep -o '[0-9]*$')
echo "MTD #: $MTDX"

MTDX_SYSFS="${MTD_SYSFS}/mtd${MTDX}"

SIZE=$(cat ${MTDX_SYSFS}/size)
EB_SIZE=$(cat ${MTDX_SYSFS}/erasesize)
NUM_EBS=$((SIZE / EB_SIZE))

log_msg() {
	echo "${MTD}: $@"
}

err_msg() {
	log_msg $@ 1>&2
}

dbg_msg() {
	# both go to stderr for now
	[ "$DEBUG" != "" ] && err_msg $@
}

exit_err_msg() {
	err_msg $@
	exit 1
}

# echo 1 for locked, 0 for unlocked; return non-zero on error
is_locked() {
	local out="$(${ISLOCKED} $@ | grep 'Return code:')"
	[ $? -ne 0 ] && return 1
	out=$(echo "$out" | cut -d' ' -f3)
	dbg_msg "Range [$@] lock status: $out"
	echo $out
}

# check that *each* eraseblock has a particular status; return non-zero on
# error, zero for successful match
is_locked_ebs() {
	local addr=${1:-0}
	local num_ebs=${2:-${NUM_EBS}}
	local lock_status=${3:-1}
	local last_addr=$((addr + (num_ebs - 1) * EB_SIZE))
	local ret=0

	for ofs in $(seq $addr $EB_SIZE $last_addr); do
		ret=$(is_locked $ofs 1)
		[ $? -ne 0 ] && return 1
		[ "$ret" -ne "$lock_status" ] && err_msg "block $ofs has unexpected status $ret" && return 1
	done
	return 0
}

check_locked() {
	local addr=$1
	local num_ebs=$2
	local lock_status=$3

	local ret=$(is_locked $addr $num_ebs) || exit 1
	is_locked_ebs $addr $num_ebs $lock_status || exit 1
	if [ "$ret" -ne "$lock_status" ]; then
		exit_err_msg "lock status is incorrect"
	else
		log_msg "verified lock status $@"
	fi
}

if ! ${UNLOCK} ; then
	err_msg "error unlocking; MEMUNLOCK not supported?"
	exit 1
fi

main() {
	log_msg "unlocked device"
	check_locked 0 $NUM_EBS 0

	log_msg "locking upper half"
	${LOCK} $((SIZE / 2)) $((NUM_EBS / 2)) || exit 1
	check_locked $((SIZE / 2)) $((NUM_EBS / 2)) 1
	check_locked 0 $((NUM_EBS / 2)) 0

	log_msg "relocking 4th quadrant"
	${LOCK} $((SIZE * 3 / 4)) $((NUM_EBS / 4)) || exit 1
	check_locked $((SIZE / 2)) $((NUM_EBS / 2)) 1
	check_locked 0 $((NUM_EBS / 2)) 0

	log_msg "relocking ranges"
	## Picked some arbitrary increments, since an exhaustive loop takes too
	## long
	for i in $(seq $((SIZE / 2)) $((EB_SIZE * 5)) $((SIZE - EB_SIZE))); do
		for j in $(seq 0 7 $(((SIZE - i) / EB_SIZE - 1))); do
			log_msg "Range: $i $j"
			${LOCK} $i $j || exit 1
		done
	done
	check_locked $((SIZE / 2)) $((NUM_EBS / 2)) 1
	check_locked 0 $((NUM_EBS / 2)) 0

	log_msg "unlocking 3rd quadrant"
	${UNLOCK} $((SIZE / 2)) $((NUM_EBS / 4)) || exit 1
	check_locked $((SIZE * 3 / 4)) $((NUM_EBS / 4)) 1
	check_locked 0 $((NUM_EBS * 3 / 4)) 0

	log_msg "unlocking 1st quadrant (again)"
	${UNLOCK} 0 $((NUM_EBS / 4)) || exit 1
	check_locked $((SIZE * 3 / 4)) $((NUM_EBS / 4)) 1
	check_locked 0 $((NUM_EBS * 3 / 4)) 0

	log_msg "unlocking 4th quadrant"
	${UNLOCK} $((SIZE * 3 / 4)) $((NUM_EBS / 4)) || exit 1
	check_locked 0 $NUM_EBS 0

	log_msg "locking 1st half"
	if ! ${LOCK} 0 $((NUM_EBS / 2)) ; then
		err_msg "does not support bottom-block protection? skipping tests"
		return 0
	fi
	check_locked 0 $((NUM_EBS / 2)) 1
	check_locked $((SIZE / 2)) $((NUM_EBS / 2)) 0

	${UNLOCK} 0 $((NUM_EBS / 4)) && \
		exit_err_msg "error: was able to unlock 1st quadrant"
	log_msg "saw error, expected"
	check_locked 0 $((NUM_EBS / 2)) 1
	check_locked $((SIZE / 2)) $((NUM_EBS / 2)) 0

	log_msg "unlocking 2nd quadrant"
	${UNLOCK} $((SIZE / 4)) $((NUM_EBS / 4)) || exit 1
	check_locked 0 $((NUM_EBS / 4)) 1
	check_locked $((SIZE / 4)) $((NUM_EBS * 3 / 4)) 0

	log_msg "unlocking top 3 quadrants (again)"
	${UNLOCK} $((SIZE / 4)) $((NUM_EBS * 3 / 4)) || exit 1
	check_locked 0 $((NUM_EBS / 4)) 1
	check_locked $((SIZE / 4)) $((NUM_EBS * 3 / 4)) 0
}

main
log_msg "test complete"

             reply	other threads:[~2016-01-29 19:26 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-29 19:25 Brian Norris [this message]
2016-01-29 19:25 ` [PATCH v2 1/8] mtd: spi-nor: wait for SR_WIP to clear on initial unlock Brian Norris
2016-01-29 19:25 ` [PATCH v2 2/8] mtd: spi-nor: silently drop lock/unlock for already locked/unlocked region Brian Norris
2016-01-29 19:25 ` [PATCH v2 3/8] mtd: spi-nor: make lock/unlock bounds checks more obvious and robust Brian Norris
2016-01-29 19:25 ` [PATCH v2 4/8] mtd: spi-nor: disallow further writes to SR if WP# is low Brian Norris
2016-01-29 19:25 ` [PATCH v2 5/8] mtd: spi-nor: use BIT() for flash_info flags Brian Norris
2016-01-29 19:25 ` [PATCH v2 6/8] mtd: spi-nor: add SPI_NOR_HAS_LOCK flag Brian Norris
2016-02-28 19:23   ` Ezequiel Garcia
2016-01-29 19:25 ` [PATCH v2 7/8] mtd: spi-nor: add TB (Top/Bottom) protect support Brian Norris
2016-02-29 20:35   ` Ezequiel Garcia
2016-03-08  2:12     ` Brian Norris
2016-01-29 19:25 ` [PATCH v2 8/8] mtd: spi-nor: support lock/unlock for a few Winbond chips Brian Norris
2016-02-27  2:04 ` [PATCH v2 0/8] mtd: spi-nor: locking fixes and updates Ezequiel Garcia
2016-03-08  2:18 ` Brian Norris

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=1454095537-130536-1-git-send-email-computersforpeace@gmail.com \
    --to=computersforpeace@gmail.com \
    --cc=bayi.cheng@mediatek.com \
    --cc=boris.brezillon@free-electrons.com \
    --cc=djkurtz@chromium.org \
    --cc=ezequiel@vanguardiasur.com.ar \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=marex@denx.de \
    --cc=zajec5@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.