// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> * Copyright (c) 2003-2004 Joern Engel <joern@wh.fh-wedel.de> * * Usage: * * one commend line parameter per device, each in the form: * phram=<name>,<start>,<len>[,<erasesize>] * <name> may be up to 63 characters. * <start>, <len>, and <erasesize> can be octal, decimal or hexadecimal. If followed * by "ki", "Mi" or "Gi", the numbers will be interpreted as kilo, mega or * gigabytes. <erasesize> is optional and defaults to PAGE_SIZE. * * Example: * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi,64Ki
*/
#define parse_err(fmt, args...) do { \
pr_err(fmt , ## args); \ return 1; \
} while (0)
#ifndef MODULE staticint phram_init_called; /* * This shall contain the module parameter if any. It is of the form: * - phram=<device>,<address>,<size>[,<erasesize>] for module case * - phram.phram=<device>,<address>,<size>[,<erasesize>] for built-in case * We leave 64 bytes for the device name, 20 for the address , 20 for the * size and 20 for the erasesize. * Example: phram.phram=rootfs,0xa0000000,512Mi,65536
*/ staticchar phram_paramline[64 + 20 + 20 + 20]; #endif
if (strnlen(val, sizeof(buf)) >= sizeof(buf))
parse_err("parameter too long\n");
strcpy(str, val);
kill_final_newline(str);
for (i = 0; i < 4; i++)
token[i] = strsep(&str, ",");
if (str)
parse_err("too many arguments\n");
if (!token[2])
parse_err("not enough arguments\n");
ret = parse_name(&name, token[0]); if (ret) return ret;
ret = parse_num64(&start, token[1]); if (ret) {
parse_err("illegal start address\n"); goto error;
}
ret = parse_num64(&len, token[2]); if (ret) {
parse_err("illegal device length\n"); goto error;
}
if (token[3]) {
ret = parse_num64(&erasesize, token[3]); if (ret) {
parse_err("illegal erasesize\n"); goto error;
}
}
if (len == 0 || erasesize == 0 || erasesize > len
|| erasesize > UINT_MAX) {
parse_err("illegal erasesize or len\n");
ret = -EINVAL; goto error;
}
div_u64_rem(len, (uint32_t)erasesize, &rem); if (rem) {
parse_err("len is not multiple of erasesize\n");
ret = -EINVAL; goto error;
}
ret = register_device(NULL, name, start, len, (uint32_t)erasesize); if (ret) goto error;
pr_info("%s device: %#llx at %#llx for erasesize %#llx\n", name, len, start, erasesize); return 0;
error:
kfree(name); return ret;
}
staticint phram_param_call(constchar *val, conststruct kernel_param *kp)
{ #ifdef MODULE return phram_setup(val); #else /* * If more parameters are later passed in via * /sys/module/phram/parameters/phram * and init_phram() has already been called, * we can parse the argument now.
*/
if (phram_init_called) return phram_setup(val);
/* * During early boot stage, we only save the parameters * here. We must parse them later: if the param passed * from kernel boot command line, phram_param_call() is * called so early that it is not possible to resolve * the device (even kmalloc() fails). Defer that work to * phram_setup().
*/
if (strlen(val) >= sizeof(phram_paramline)) return -ENOSPC;
strcpy(phram_paramline, val);
return 0; #endif
}
module_param_call(phram, phram_param_call, NULL, NULL, 0200);
MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\"");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.