Skip to content

Commit

Permalink
test_firmware: add test custom fallback trigger
Browse files Browse the repository at this point in the history
We have no custom fallback mechanism test interface. Provide one.
This tests both the custom fallback mechanism and cancelling the
it.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Luis R. Rodriguez authored and Greg Kroah-Hartman committed Jan 25, 2017
1 parent eb67bc3 commit 061132d
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
45 changes: 45 additions & 0 deletions lib/test_firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,56 @@ static ssize_t trigger_async_request_store(struct device *dev,
}
static DEVICE_ATTR_WO(trigger_async_request);

static ssize_t trigger_custom_fallback_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
char *name;

name = kstrndup(buf, count, GFP_KERNEL);
if (!name)
return -ENOSPC;

pr_info("loading '%s' using custom fallback mechanism\n", name);

mutex_lock(&test_fw_mutex);
release_firmware(test_firmware);
test_firmware = NULL;
rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
dev, GFP_KERNEL, NULL,
trigger_async_request_cb);
if (rc) {
pr_info("async load of '%s' failed: %d\n", name, rc);
kfree(name);
goto out;
}
/* Free 'name' ASAP, to test for race conditions */
kfree(name);

wait_for_completion(&async_fw_done);

if (test_firmware) {
pr_info("loaded: %zu\n", test_firmware->size);
rc = count;
} else {
pr_err("failed to async load firmware\n");
rc = -ENODEV;
}

out:
mutex_unlock(&test_fw_mutex);

return rc;
}
static DEVICE_ATTR_WO(trigger_custom_fallback);

#define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr

static struct attribute *test_dev_attrs[] = {
TEST_FW_DEV_ATTR(trigger_request),
TEST_FW_DEV_ATTR(trigger_async_request),
TEST_FW_DEV_ATTR(trigger_custom_fallback),
NULL,
};

Expand Down
68 changes: 68 additions & 0 deletions tools/testing/selftests/firmware/fw_fallback.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,58 @@ load_fw_cancel()
wait
}

load_fw_custom()
{
local name="$1"
local file="$2"

echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &

# Give kernel a chance to react.
local timeout=10
while [ ! -e "$DIR"/"$name"/loading ]; do
sleep 0.1
timeout=$(( $timeout - 1 ))
if [ "$timeout" -eq 0 ]; then
echo "$0: firmware interface never appeared" >&2
exit 1
fi
done

echo 1 >"$DIR"/"$name"/loading
cat "$file" >"$DIR"/"$name"/data
echo 0 >"$DIR"/"$name"/loading

# Wait for request to finish.
wait
}


load_fw_custom_cancel()
{
local name="$1"
local file="$2"

echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &

# Give kernel a chance to react.
local timeout=10
while [ ! -e "$DIR"/"$name"/loading ]; do
sleep 0.1
timeout=$(( $timeout - 1 ))
if [ "$timeout" -eq 0 ]; then
echo "$0: firmware interface never appeared" >&2
exit 1
fi
done

echo -1 >"$DIR"/"$name"/loading

# Wait for request to finish.
wait
}


trap "test_finish" EXIT

# This is an unlikely real-world firmware content. :)
Expand Down Expand Up @@ -153,4 +205,20 @@ else
echo "$0: cancelling fallback mechanism works"
fi

load_fw_custom "$NAME" "$FW"
if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
echo "$0: firmware was not loaded" >&2
exit 1
else
echo "$0: custom fallback loading mechanism works"
fi

load_fw_custom_cancel "nope-$NAME" "$FW"
if diff -q "$FW" /dev/test_firmware >/dev/null ; then
echo "$0: firmware was expected to be cancelled" >&2
exit 1
else
echo "$0: cancelling custom fallback mechanism works"
fi

exit 0

0 comments on commit 061132d

Please sign in to comment.