Merge Official Source
This commit is contained in:
commit
0136f1d13a
@ -13,7 +13,7 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/ltq-dsl-fw-$(PKG_VERSION)
|
||||
PKG_SOURCE:=ltq-dsl-fw-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
|
||||
PKG_SOURCE_URL:=https://sources.openwrt.org/
|
||||
PKG_HASH:=28676d41c4b76e5bf7a2c5eae106a61fb96b93eabc0cb71120575fff9997269f
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
@ -45,8 +45,8 @@ endef
|
||||
|
||||
define Package/kmod-ltq-adsl-$(BUILD_VARIANT)/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/
|
||||
$(CP) $(PKG_BUILD_DIR)/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/
|
||||
ln -s /lib/firmware/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/adsl.bin
|
||||
$(CP) $(PKG_BUILD_DIR)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/
|
||||
ln -s /lib/firmware/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/adsl.bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,kmod-ltq-adsl-danube-fw-a))
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
config LANTIQ_DSL_DEBUG
|
||||
config LANTIQ_ADSL_DEBUG
|
||||
bool "verbose debugging"
|
||||
depends on PACKAGE_kmod-ltq-dsl
|
||||
depends on PACKAGE_kmod-ltq-adsl
|
||||
help
|
||||
Say Y, if you need ltq-dsl to display debug messages.
|
||||
Say Y, if you need ltq-adsl to display debug messages.
|
||||
|
||||
@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=ltq-adsl
|
||||
PKG_VERSION:=3.24.4.4
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=3
|
||||
PKG_SOURCE:=drv_dsl_cpe_api_danube-$(PKG_VERSION).tar.gz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-dsl-$(BUILD_VARIANT)/drv_dsl_cpe_api-$(PKG_VERSION)
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
|
||||
PKG_SOURCE_URL:=https://mirror2.openwrt.org/sources/
|
||||
PKG_HASH:=eb2ed59715d3bf4e8a1460bbbe2f1660039e0a9f9d72afb1b2b16590094eb33c
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
@ -38,7 +38,7 @@ KernelPackage/ltq-adsl-danube=$(call KernelPackage/ltq-adsl-template,danube,(TAR
|
||||
KernelPackage/ltq-adsl-ar9=$(call KernelPackage/ltq-adsl-template,ar9,TARGET_lantiq_xway)
|
||||
KernelPackage/ltq-adsl-ase=$(call KernelPackage/ltq-adsl-template,ase,TARGET_lantiq_ase)
|
||||
|
||||
define KernelPackage/ltq-dsl/config
|
||||
define KernelPackage/ltq-adsl/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
@ -75,7 +75,7 @@ CONFIGURE_ARGS += --enable-add-drv-cflags="-DMODULE -DCONFIG_$(CONFIG_TAG_$(BUIL
|
||||
|
||||
CONFIGURE_ARGS += --enable-danube
|
||||
|
||||
ifeq ($(CONFIG_LANTIQ_DSL_DEBUG),y)
|
||||
ifeq ($(CONFIG_LANTIQ_ADSL_DEBUG),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-debug=yes \
|
||||
--enable-debug-prints=yes
|
||||
|
||||
@ -399,7 +399,7 @@ $(eval $(call KernelPackage,ip6-vti))
|
||||
define KernelPackage/xfrm-interface
|
||||
SUBMENU:=$(NETWORK_SUPPORT_MENU)
|
||||
TITLE:=IPsec XFRM Interface
|
||||
DEPENDS:=+kmod-ipsec4 +@IPV6:kmod-ipsec6 @!LINUX_4_14
|
||||
DEPENDS:=+kmod-ipsec4 +IPV6:kmod-ipsec6 @!LINUX_4_14
|
||||
KCONFIG:=CONFIG_XFRM_INTERFACE
|
||||
FILES:=$(LINUX_DIR)/net/xfrm/xfrm_interface.ko
|
||||
AUTOLOAD:=$(call AutoProbe,xfrm_interface)
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
ahb {
|
||||
apb {
|
||||
ddr_ctrl: memory-controller@18000000 {
|
||||
compatible = "qca,ar9530-ddr-controller",
|
||||
compatible = "qca,qca9530-ddr-controller",
|
||||
"qca,ar7240-ddr-controller";
|
||||
reg = <0x18000000 0x128>;
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
};
|
||||
|
||||
gpio: gpio@18040000 {
|
||||
compatible = "qca,ar9530-gpio",
|
||||
compatible = "qca,qca9530-gpio",
|
||||
"qca,ar9340-gpio";
|
||||
reg = <0x18040000 0x28>;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "qca9556_avm_fritz-repeater.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "avm,fritz1750e", "qca,qca9557";
|
||||
compatible = "avm,fritz1750e", "qca,qca9556";
|
||||
model = "AVM FRITZ!WLAN Repeater 1750E";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "qca9556_avm_fritz-repeater.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "avm,fritz450e", "qca,qca9557";
|
||||
compatible = "avm,fritz450e", "qca,qca9556";
|
||||
model = "AVM FRITZ!WLAN Repeater 450E";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mikrotik,routerboard-wap-g-5hact2hnd", "qca,qca9556";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "buffalo,bhr-4grv2", "qca,qca9557";
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "qca9558_devolo_dvl1xxx.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "devolo,dvl1200e", "qca,qca9557";
|
||||
compatible = "devolo,dvl1200e", "qca,qca9558";
|
||||
model = "devolo WiFi pro 1200e";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "qca9558_devolo_dvl1xxx.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "devolo,dvl1200i", "qca,qca9557";
|
||||
compatible = "devolo,dvl1200i", "qca,qca9558";
|
||||
model = "devolo WiFi pro 1200i";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "qca9558_devolo_dvl1xxx.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "devolo,dvl1750c", "qca,qca9557";
|
||||
compatible = "devolo,dvl1750c", "qca,qca9558";
|
||||
model = "devolo WiFi pro 1750c";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "qca9558_devolo_dvl1xxx.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "devolo,dvl1750e", "qca,qca9557";
|
||||
compatible = "devolo,dvl1750e", "qca,qca9558";
|
||||
model = "devolo WiFi pro 1750e";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "qca9558_devolo_dvl1xxx.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "devolo,dvl1750i", "qca,qca9557";
|
||||
compatible = "devolo,dvl1750i", "qca,qca9558";
|
||||
model = "devolo WiFi pro 1750i";
|
||||
|
||||
aliases {
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "domywifi,dw33d", "qca,qca9558";
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "engenius,ecb1750", "qca,qca9557";
|
||||
compatible = "engenius,ecb1750", "qca,qca9558";
|
||||
model = "EnGenius ECB1750";
|
||||
|
||||
chosen {
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "EnGenius EPG5000";
|
||||
compatible = "engenius,epg5000", "qca,qca9557";
|
||||
compatible = "engenius,epg5000", "qca,qca9558";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200n8";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "librerouter,librerouter-v1", "qca,qca9558";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mikrotik,routerboard-922uags-5hpacd", "qca,qca9558";
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "ocedo,koala", "qca,qca9557";
|
||||
compatible = "ocedo,koala", "qca,qca9558";
|
||||
model = "OCEDO Koala";
|
||||
|
||||
chosen {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "ocedo,ursus", "qca,qca9558";
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "openmesh,om5p-ac-v2", "qca,qca9557";
|
||||
compatible = "openmesh,om5p-ac-v2", "qca,qca9558";
|
||||
model = "OpenMesh OM5P-AC V2";
|
||||
|
||||
extosc: ref {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Sitecom WLR-8100 (X8 AC1750)";
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "TP-Link RE350K v1";
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wdr4900-v2", "qca,qca9558";
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
#include "qca9558_tplink_tl-wr1043nd.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wr1043nd-v2", "qca,qca9557";
|
||||
compatible = "tplink,tl-wr1043nd-v2", "qca,qca9558";
|
||||
model = "TP-Link TL-WR1043ND v2";
|
||||
};
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
#include "qca9558_tplink_tl-wr1043nd.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wr1043nd-v3", "qca,qca9557";
|
||||
compatible = "tplink,tl-wr1043nd-v3", "qca,qca9558";
|
||||
model = "TP-Link TL-WR1043ND v3";
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
#include "qca9558_tplink_tl-wr1043nd.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wr1045nd-v2", "qca,qca9557";
|
||||
compatible = "tplink,tl-wr1045nd-v2", "qca,qca9558";
|
||||
model = "TP-Link TL-WR1045ND v2";
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wr941n-v7-cn", "qca,qca9558";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "trendnet,tew-823dru", "qca,qca9558";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "qca9557.dtsi"
|
||||
#include "qca955x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "zyxel,nbg6716", "qca,qca9558";
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "ath79.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "qca,qca9557";
|
||||
compatible = "qca,qca9550";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@ -30,7 +30,7 @@
|
||||
ahb {
|
||||
apb {
|
||||
ddr_ctrl: memory-controller@18000000 {
|
||||
compatible = "qca,ar9557-ddr-controller",
|
||||
compatible = "qca,qca9550-ddr-controller",
|
||||
"qca,ar7240-ddr-controller";
|
||||
reg = <0x18000000 0x100>;
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
};
|
||||
|
||||
gpio: gpio@18040000 {
|
||||
compatible = "qca,ar9557-gpio",
|
||||
compatible = "qca,qca9550-gpio",
|
||||
"qca,ar9340-gpio";
|
||||
reg = <0x18040000 0x28>;
|
||||
|
||||
@ -110,7 +110,7 @@
|
||||
};
|
||||
|
||||
pll: pll-controller@18050000 {
|
||||
compatible = "qca,ar9557-pll",
|
||||
compatible = "qca,qca9550-pll",
|
||||
"qca,qca9550-pll", "syscon";
|
||||
reg = <0x18050000 0x50>;
|
||||
|
||||
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#define TPLINK_NUM_PARTS 5
|
||||
#define TPLINK_HEADER_V1 0x01000000
|
||||
#define TPLINK_HEADER_V2 0x02000000
|
||||
#define MD5SUM_LEN 16
|
||||
|
||||
#define TPLINK_ART_LEN 0x10000
|
||||
#define TPLINK_KERNEL_OFFS 0x20000
|
||||
#define TPLINK_64K_KERNEL_OFFS 0x10000
|
||||
|
||||
struct tplink_fw_header {
|
||||
uint32_t version; /* header version */
|
||||
char vendor_name[24];
|
||||
char fw_version[36];
|
||||
uint32_t hw_id; /* hardware id */
|
||||
uint32_t hw_rev; /* hardware revision */
|
||||
uint32_t unk1;
|
||||
uint8_t md5sum1[MD5SUM_LEN];
|
||||
uint32_t unk2;
|
||||
uint8_t md5sum2[MD5SUM_LEN];
|
||||
uint32_t unk3;
|
||||
uint32_t kernel_la; /* kernel load address */
|
||||
uint32_t kernel_ep; /* kernel entry point */
|
||||
uint32_t fw_length; /* total length of the firmware */
|
||||
uint32_t kernel_ofs; /* kernel data offset */
|
||||
uint32_t kernel_len; /* kernel data length */
|
||||
uint32_t rootfs_ofs; /* rootfs data offset */
|
||||
uint32_t rootfs_len; /* rootfs data length */
|
||||
uint32_t boot_ofs; /* bootloader data offset */
|
||||
uint32_t boot_len; /* bootloader data length */
|
||||
uint8_t pad[360];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static struct tplink_fw_header *
|
||||
tplink_read_header(struct mtd_info *mtd, size_t offset)
|
||||
{
|
||||
struct tplink_fw_header *header;
|
||||
size_t header_len;
|
||||
size_t retlen;
|
||||
int ret;
|
||||
u32 t;
|
||||
|
||||
header = vmalloc(sizeof(*header));
|
||||
if (!header)
|
||||
goto err;
|
||||
|
||||
header_len = sizeof(struct tplink_fw_header);
|
||||
ret = mtd_read(mtd, offset, header_len, &retlen,
|
||||
(unsigned char *) header);
|
||||
if (ret)
|
||||
goto err_free_header;
|
||||
|
||||
if (retlen != header_len)
|
||||
goto err_free_header;
|
||||
|
||||
/* sanity checks */
|
||||
t = be32_to_cpu(header->version);
|
||||
if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
|
||||
goto err_free_header;
|
||||
|
||||
t = be32_to_cpu(header->kernel_ofs);
|
||||
if (t != header_len)
|
||||
goto err_free_header;
|
||||
|
||||
return header;
|
||||
|
||||
err_free_header:
|
||||
vfree(header);
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
|
||||
{
|
||||
u32 magic;
|
||||
size_t retlen;
|
||||
int ret;
|
||||
|
||||
ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
|
||||
(unsigned char *) &magic);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (retlen != sizeof(magic))
|
||||
return -EIO;
|
||||
|
||||
if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
|
||||
magic != 0x19852003)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tplink_parse_partitions_offset(struct mtd_info *master,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
|
||||
struct mtd_partition **pparts,
|
||||
#else
|
||||
const struct mtd_partition **pparts,
|
||||
#endif
|
||||
struct mtd_part_parser_data *data,
|
||||
size_t offset)
|
||||
{
|
||||
struct mtd_partition *parts;
|
||||
struct tplink_fw_header *header;
|
||||
int nr_parts;
|
||||
size_t art_offset;
|
||||
size_t rootfs_offset;
|
||||
size_t squashfs_offset;
|
||||
int ret;
|
||||
|
||||
nr_parts = TPLINK_NUM_PARTS;
|
||||
parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
if (!parts) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
header = tplink_read_header(master, offset);
|
||||
if (!header) {
|
||||
pr_notice("%s: no TP-Link header found\n", master->name);
|
||||
ret = -ENODEV;
|
||||
goto err_free_parts;
|
||||
}
|
||||
|
||||
squashfs_offset = offset + sizeof(struct tplink_fw_header) +
|
||||
be32_to_cpu(header->kernel_len);
|
||||
|
||||
ret = tplink_check_rootfs_magic(master, squashfs_offset);
|
||||
if (ret == 0)
|
||||
rootfs_offset = squashfs_offset;
|
||||
else
|
||||
rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
|
||||
|
||||
art_offset = master->size - TPLINK_ART_LEN;
|
||||
|
||||
parts[0].name = "u-boot";
|
||||
parts[0].offset = 0;
|
||||
parts[0].size = offset;
|
||||
parts[0].mask_flags = MTD_WRITEABLE;
|
||||
|
||||
parts[1].name = "kernel";
|
||||
parts[1].offset = offset;
|
||||
parts[1].size = rootfs_offset - offset;
|
||||
|
||||
parts[2].name = "rootfs";
|
||||
parts[2].offset = rootfs_offset;
|
||||
parts[2].size = art_offset - rootfs_offset;
|
||||
|
||||
parts[3].name = "art";
|
||||
parts[3].offset = art_offset;
|
||||
parts[3].size = TPLINK_ART_LEN;
|
||||
parts[3].mask_flags = MTD_WRITEABLE;
|
||||
|
||||
parts[4].name = "firmware";
|
||||
parts[4].offset = offset;
|
||||
parts[4].size = art_offset - offset;
|
||||
|
||||
vfree(header);
|
||||
|
||||
*pparts = parts;
|
||||
return nr_parts;
|
||||
|
||||
err_free_parts:
|
||||
kfree(parts);
|
||||
err:
|
||||
*pparts = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tplink_parse_partitions(struct mtd_info *master,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
|
||||
struct mtd_partition **pparts,
|
||||
#else
|
||||
const struct mtd_partition **pparts,
|
||||
#endif
|
||||
struct mtd_part_parser_data *data)
|
||||
{
|
||||
return tplink_parse_partitions_offset(master, pparts, data,
|
||||
TPLINK_KERNEL_OFFS);
|
||||
}
|
||||
|
||||
static int tplink_parse_64k_partitions(struct mtd_info *master,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
|
||||
struct mtd_partition **pparts,
|
||||
#else
|
||||
const struct mtd_partition **pparts,
|
||||
#endif
|
||||
struct mtd_part_parser_data *data)
|
||||
{
|
||||
return tplink_parse_partitions_offset(master, pparts, data,
|
||||
TPLINK_64K_KERNEL_OFFS);
|
||||
}
|
||||
|
||||
static struct mtd_part_parser tplink_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
.parse_fn = tplink_parse_partitions,
|
||||
.name = "tp-link",
|
||||
};
|
||||
|
||||
static struct mtd_part_parser tplink_64k_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
.parse_fn = tplink_parse_64k_partitions,
|
||||
.name = "tp-link-64k",
|
||||
};
|
||||
|
||||
static int __init tplink_parser_init(void)
|
||||
{
|
||||
register_mtd_parser(&tplink_parser);
|
||||
register_mtd_parser(&tplink_64k_parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(tplink_parser_init);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
@ -23,3 +23,228 @@
|
||||
|
||||
# 'Users' - code which presents functionality to userspace.
|
||||
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/tplinkpart.c
|
||||
@@ -0,0 +1,222 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/magic.h>
|
||||
+
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/version.h>
|
||||
+
|
||||
+#define TPLINK_NUM_PARTS 5
|
||||
+#define TPLINK_HEADER_V1 0x01000000
|
||||
+#define TPLINK_HEADER_V2 0x02000000
|
||||
+#define MD5SUM_LEN 16
|
||||
+
|
||||
+#define TPLINK_ART_LEN 0x10000
|
||||
+#define TPLINK_KERNEL_OFFS 0x20000
|
||||
+#define TPLINK_64K_KERNEL_OFFS 0x10000
|
||||
+
|
||||
+struct tplink_fw_header {
|
||||
+ uint32_t version; /* header version */
|
||||
+ char vendor_name[24];
|
||||
+ char fw_version[36];
|
||||
+ uint32_t hw_id; /* hardware id */
|
||||
+ uint32_t hw_rev; /* hardware revision */
|
||||
+ uint32_t unk1;
|
||||
+ uint8_t md5sum1[MD5SUM_LEN];
|
||||
+ uint32_t unk2;
|
||||
+ uint8_t md5sum2[MD5SUM_LEN];
|
||||
+ uint32_t unk3;
|
||||
+ uint32_t kernel_la; /* kernel load address */
|
||||
+ uint32_t kernel_ep; /* kernel entry point */
|
||||
+ uint32_t fw_length; /* total length of the firmware */
|
||||
+ uint32_t kernel_ofs; /* kernel data offset */
|
||||
+ uint32_t kernel_len; /* kernel data length */
|
||||
+ uint32_t rootfs_ofs; /* rootfs data offset */
|
||||
+ uint32_t rootfs_len; /* rootfs data length */
|
||||
+ uint32_t boot_ofs; /* bootloader data offset */
|
||||
+ uint32_t boot_len; /* bootloader data length */
|
||||
+ uint8_t pad[360];
|
||||
+} __attribute__ ((packed));
|
||||
+
|
||||
+static struct tplink_fw_header *
|
||||
+tplink_read_header(struct mtd_info *mtd, size_t offset)
|
||||
+{
|
||||
+ struct tplink_fw_header *header;
|
||||
+ size_t header_len;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+ u32 t;
|
||||
+
|
||||
+ header = vmalloc(sizeof(*header));
|
||||
+ if (!header)
|
||||
+ goto err;
|
||||
+
|
||||
+ header_len = sizeof(struct tplink_fw_header);
|
||||
+ ret = mtd_read(mtd, offset, header_len, &retlen,
|
||||
+ (unsigned char *) header);
|
||||
+ if (ret)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ if (retlen != header_len)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ /* sanity checks */
|
||||
+ t = be32_to_cpu(header->version);
|
||||
+ if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ t = be32_to_cpu(header->kernel_ofs);
|
||||
+ if (t != header_len)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ return header;
|
||||
+
|
||||
+err_free_header:
|
||||
+ vfree(header);
|
||||
+err:
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
|
||||
+{
|
||||
+ u32 magic;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
|
||||
+ (unsigned char *) &magic);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (retlen != sizeof(magic))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
|
||||
+ magic != 0x19852003)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_partitions_offset(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data,
|
||||
+ size_t offset)
|
||||
+{
|
||||
+ struct mtd_partition *parts;
|
||||
+ struct tplink_fw_header *header;
|
||||
+ int nr_parts;
|
||||
+ size_t art_offset;
|
||||
+ size_t rootfs_offset;
|
||||
+ size_t squashfs_offset;
|
||||
+ int ret;
|
||||
+
|
||||
+ nr_parts = TPLINK_NUM_PARTS;
|
||||
+ parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
+ if (!parts) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ header = tplink_read_header(master, offset);
|
||||
+ if (!header) {
|
||||
+ pr_notice("%s: no TP-Link header found\n", master->name);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_free_parts;
|
||||
+ }
|
||||
+
|
||||
+ squashfs_offset = offset + sizeof(struct tplink_fw_header) +
|
||||
+ be32_to_cpu(header->kernel_len);
|
||||
+
|
||||
+ ret = tplink_check_rootfs_magic(master, squashfs_offset);
|
||||
+ if (ret == 0)
|
||||
+ rootfs_offset = squashfs_offset;
|
||||
+ else
|
||||
+ rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
|
||||
+
|
||||
+ art_offset = master->size - TPLINK_ART_LEN;
|
||||
+
|
||||
+ parts[0].name = "u-boot";
|
||||
+ parts[0].offset = 0;
|
||||
+ parts[0].size = offset;
|
||||
+ parts[0].mask_flags = MTD_WRITEABLE;
|
||||
+
|
||||
+ parts[1].name = "kernel";
|
||||
+ parts[1].offset = offset;
|
||||
+ parts[1].size = rootfs_offset - offset;
|
||||
+
|
||||
+ parts[2].name = "rootfs";
|
||||
+ parts[2].offset = rootfs_offset;
|
||||
+ parts[2].size = art_offset - rootfs_offset;
|
||||
+
|
||||
+ parts[3].name = "art";
|
||||
+ parts[3].offset = art_offset;
|
||||
+ parts[3].size = TPLINK_ART_LEN;
|
||||
+ parts[3].mask_flags = MTD_WRITEABLE;
|
||||
+
|
||||
+ parts[4].name = "firmware";
|
||||
+ parts[4].offset = offset;
|
||||
+ parts[4].size = art_offset - offset;
|
||||
+
|
||||
+ vfree(header);
|
||||
+
|
||||
+ *pparts = parts;
|
||||
+ return nr_parts;
|
||||
+
|
||||
+err_free_parts:
|
||||
+ kfree(parts);
|
||||
+err:
|
||||
+ *pparts = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ return tplink_parse_partitions_offset(master, pparts, data,
|
||||
+ TPLINK_KERNEL_OFFS);
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_64k_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ return tplink_parse_partitions_offset(master, pparts, data,
|
||||
+ TPLINK_64K_KERNEL_OFFS);
|
||||
+}
|
||||
+
|
||||
+static struct mtd_part_parser tplink_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = tplink_parse_partitions,
|
||||
+ .name = "tp-link",
|
||||
+};
|
||||
+
|
||||
+static struct mtd_part_parser tplink_64k_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = tplink_parse_64k_partitions,
|
||||
+ .name = "tp-link-64k",
|
||||
+};
|
||||
+
|
||||
+static int __init tplink_parser_init(void)
|
||||
+{
|
||||
+ register_mtd_parser(&tplink_parser);
|
||||
+ register_mtd_parser(&tplink_64k_parser);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+module_init(tplink_parser_init);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
|
||||
@ -1,25 +1,244 @@
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -62,6 +62,12 @@ config MTD_MYLOADER_PARTS
|
||||
--- a/drivers/mtd/parsers/Kconfig
|
||||
+++ b/drivers/mtd/parsers/Kconfig
|
||||
@@ -184,3 +184,9 @@ config MTD_MYLOADER_PARTS
|
||||
|
||||
You will still need the parsing functions to be called by the driver
|
||||
for your particular device. It won't happen automatically.
|
||||
|
||||
+
|
||||
+config MTD_TPLINK_PARTS
|
||||
+ tristate "TP-Link AR7XXX/AR9XXX partitioning support"
|
||||
+ depends on ATH79
|
||||
+ ---help---
|
||||
+ TBD.
|
||||
--- a/drivers/mtd/parsers/Makefile
|
||||
+++ b/drivers/mtd/parsers/Makefile
|
||||
@@ -11,3 +11,4 @@ obj-$(CONFIG_MTD_PARSER_TRX) += parser_
|
||||
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
|
||||
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
|
||||
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
|
||||
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/parsers/tplinkpart.c
|
||||
@@ -0,0 +1,222 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
comment "User Modules And Translation Layers"
|
||||
|
||||
#
|
||||
--- a/drivers/mtd/Makefile
|
||||
+++ b/drivers/mtd/Makefile
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD) += mtd.o
|
||||
mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o
|
||||
|
||||
obj-y += parsers/
|
||||
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
|
||||
|
||||
obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
|
||||
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/magic.h>
|
||||
+
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/version.h>
|
||||
+
|
||||
+#define TPLINK_NUM_PARTS 5
|
||||
+#define TPLINK_HEADER_V1 0x01000000
|
||||
+#define TPLINK_HEADER_V2 0x02000000
|
||||
+#define MD5SUM_LEN 16
|
||||
+
|
||||
+#define TPLINK_ART_LEN 0x10000
|
||||
+#define TPLINK_KERNEL_OFFS 0x20000
|
||||
+#define TPLINK_64K_KERNEL_OFFS 0x10000
|
||||
+
|
||||
+struct tplink_fw_header {
|
||||
+ uint32_t version; /* header version */
|
||||
+ char vendor_name[24];
|
||||
+ char fw_version[36];
|
||||
+ uint32_t hw_id; /* hardware id */
|
||||
+ uint32_t hw_rev; /* hardware revision */
|
||||
+ uint32_t unk1;
|
||||
+ uint8_t md5sum1[MD5SUM_LEN];
|
||||
+ uint32_t unk2;
|
||||
+ uint8_t md5sum2[MD5SUM_LEN];
|
||||
+ uint32_t unk3;
|
||||
+ uint32_t kernel_la; /* kernel load address */
|
||||
+ uint32_t kernel_ep; /* kernel entry point */
|
||||
+ uint32_t fw_length; /* total length of the firmware */
|
||||
+ uint32_t kernel_ofs; /* kernel data offset */
|
||||
+ uint32_t kernel_len; /* kernel data length */
|
||||
+ uint32_t rootfs_ofs; /* rootfs data offset */
|
||||
+ uint32_t rootfs_len; /* rootfs data length */
|
||||
+ uint32_t boot_ofs; /* bootloader data offset */
|
||||
+ uint32_t boot_len; /* bootloader data length */
|
||||
+ uint8_t pad[360];
|
||||
+} __attribute__ ((packed));
|
||||
+
|
||||
+static struct tplink_fw_header *
|
||||
+tplink_read_header(struct mtd_info *mtd, size_t offset)
|
||||
+{
|
||||
+ struct tplink_fw_header *header;
|
||||
+ size_t header_len;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+ u32 t;
|
||||
+
|
||||
+ header = vmalloc(sizeof(*header));
|
||||
+ if (!header)
|
||||
+ goto err;
|
||||
+
|
||||
+ header_len = sizeof(struct tplink_fw_header);
|
||||
+ ret = mtd_read(mtd, offset, header_len, &retlen,
|
||||
+ (unsigned char *) header);
|
||||
+ if (ret)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ if (retlen != header_len)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ /* sanity checks */
|
||||
+ t = be32_to_cpu(header->version);
|
||||
+ if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ t = be32_to_cpu(header->kernel_ofs);
|
||||
+ if (t != header_len)
|
||||
+ goto err_free_header;
|
||||
+
|
||||
+ return header;
|
||||
+
|
||||
+err_free_header:
|
||||
+ vfree(header);
|
||||
+err:
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
|
||||
+{
|
||||
+ u32 magic;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
|
||||
+ (unsigned char *) &magic);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (retlen != sizeof(magic))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
|
||||
+ magic != 0x19852003)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_partitions_offset(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data,
|
||||
+ size_t offset)
|
||||
+{
|
||||
+ struct mtd_partition *parts;
|
||||
+ struct tplink_fw_header *header;
|
||||
+ int nr_parts;
|
||||
+ size_t art_offset;
|
||||
+ size_t rootfs_offset;
|
||||
+ size_t squashfs_offset;
|
||||
+ int ret;
|
||||
+
|
||||
+ nr_parts = TPLINK_NUM_PARTS;
|
||||
+ parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
+ if (!parts) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ header = tplink_read_header(master, offset);
|
||||
+ if (!header) {
|
||||
+ pr_notice("%s: no TP-Link header found\n", master->name);
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_free_parts;
|
||||
+ }
|
||||
+
|
||||
+ squashfs_offset = offset + sizeof(struct tplink_fw_header) +
|
||||
+ be32_to_cpu(header->kernel_len);
|
||||
+
|
||||
+ ret = tplink_check_rootfs_magic(master, squashfs_offset);
|
||||
+ if (ret == 0)
|
||||
+ rootfs_offset = squashfs_offset;
|
||||
+ else
|
||||
+ rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
|
||||
+
|
||||
+ art_offset = master->size - TPLINK_ART_LEN;
|
||||
+
|
||||
+ parts[0].name = "u-boot";
|
||||
+ parts[0].offset = 0;
|
||||
+ parts[0].size = offset;
|
||||
+ parts[0].mask_flags = MTD_WRITEABLE;
|
||||
+
|
||||
+ parts[1].name = "kernel";
|
||||
+ parts[1].offset = offset;
|
||||
+ parts[1].size = rootfs_offset - offset;
|
||||
+
|
||||
+ parts[2].name = "rootfs";
|
||||
+ parts[2].offset = rootfs_offset;
|
||||
+ parts[2].size = art_offset - rootfs_offset;
|
||||
+
|
||||
+ parts[3].name = "art";
|
||||
+ parts[3].offset = art_offset;
|
||||
+ parts[3].size = TPLINK_ART_LEN;
|
||||
+ parts[3].mask_flags = MTD_WRITEABLE;
|
||||
+
|
||||
+ parts[4].name = "firmware";
|
||||
+ parts[4].offset = offset;
|
||||
+ parts[4].size = art_offset - offset;
|
||||
+
|
||||
+ vfree(header);
|
||||
+
|
||||
+ *pparts = parts;
|
||||
+ return nr_parts;
|
||||
+
|
||||
+err_free_parts:
|
||||
+ kfree(parts);
|
||||
+err:
|
||||
+ *pparts = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ return tplink_parse_partitions_offset(master, pparts, data,
|
||||
+ TPLINK_KERNEL_OFFS);
|
||||
+}
|
||||
+
|
||||
+static int tplink_parse_64k_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ return tplink_parse_partitions_offset(master, pparts, data,
|
||||
+ TPLINK_64K_KERNEL_OFFS);
|
||||
+}
|
||||
+
|
||||
+static struct mtd_part_parser tplink_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = tplink_parse_partitions,
|
||||
+ .name = "tp-link",
|
||||
+};
|
||||
+
|
||||
+static struct mtd_part_parser tplink_64k_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = tplink_parse_64k_partitions,
|
||||
+ .name = "tp-link-64k",
|
||||
+};
|
||||
+
|
||||
+static int __init tplink_parser_init(void)
|
||||
+{
|
||||
+ register_mtd_parser(&tplink_parser);
|
||||
+ register_mtd_parser(&tplink_64k_parser);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+module_init(tplink_parser_init);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Parse MyLoader-style flash partition tables and produce a Linux partition
|
||||
* array to match.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* This file was based on drivers/mtd/redboot.c
|
||||
* Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/myloader.h>
|
||||
|
||||
#define BLOCK_LEN_MIN 0x10000
|
||||
#define PART_NAME_LEN 32
|
||||
|
||||
struct part_data {
|
||||
struct mylo_partition_table tab;
|
||||
char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
|
||||
};
|
||||
|
||||
static int myloader_parse_partitions(struct mtd_info *master,
|
||||
const struct mtd_partition **pparts,
|
||||
struct mtd_part_parser_data *data)
|
||||
{
|
||||
struct part_data *buf;
|
||||
struct mylo_partition_table *tab;
|
||||
struct mylo_partition *part;
|
||||
struct mtd_partition *mtd_parts;
|
||||
struct mtd_partition *mtd_part;
|
||||
int num_parts;
|
||||
int ret, i;
|
||||
size_t retlen;
|
||||
char *names;
|
||||
unsigned long offset;
|
||||
unsigned long blocklen;
|
||||
|
||||
buf = vmalloc(sizeof(*buf));
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
tab = &buf->tab;
|
||||
|
||||
blocklen = master->erasesize;
|
||||
if (blocklen < BLOCK_LEN_MIN)
|
||||
blocklen = BLOCK_LEN_MIN;
|
||||
|
||||
offset = blocklen;
|
||||
|
||||
/* Find the partition table */
|
||||
for (i = 0; i < 4; i++, offset += blocklen) {
|
||||
printk(KERN_DEBUG "%s: searching for MyLoader partition table"
|
||||
" at offset 0x%lx\n", master->name, offset);
|
||||
|
||||
ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||
(void *)buf);
|
||||
if (ret)
|
||||
goto out_free_buf;
|
||||
|
||||
if (retlen != sizeof(*buf)) {
|
||||
ret = -EIO;
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
/* Check for Partition Table magic number */
|
||||
if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
|
||||
printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
|
||||
master->name);
|
||||
ret = 0;
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
/* The MyLoader and the Partition Table is always present */
|
||||
num_parts = 2;
|
||||
|
||||
/* Detect number of used partitions */
|
||||
for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
part = &tab->partitions[i];
|
||||
|
||||
if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
continue;
|
||||
|
||||
num_parts++;
|
||||
}
|
||||
|
||||
mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
|
||||
num_parts * PART_NAME_LEN), GFP_KERNEL);
|
||||
|
||||
if (!mtd_parts) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
mtd_part = mtd_parts;
|
||||
names = (char *)&mtd_parts[num_parts];
|
||||
|
||||
strncpy(names, "myloader", PART_NAME_LEN);
|
||||
mtd_part->name = names;
|
||||
mtd_part->offset = 0;
|
||||
mtd_part->size = offset;
|
||||
mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
mtd_part++;
|
||||
names += PART_NAME_LEN;
|
||||
|
||||
strncpy(names, "partition_table", PART_NAME_LEN);
|
||||
mtd_part->name = names;
|
||||
mtd_part->offset = offset;
|
||||
mtd_part->size = blocklen;
|
||||
mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
mtd_part++;
|
||||
names += PART_NAME_LEN;
|
||||
|
||||
for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
part = &tab->partitions[i];
|
||||
|
||||
if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
continue;
|
||||
|
||||
if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
|
||||
strncpy(names, buf->names[i], PART_NAME_LEN);
|
||||
else
|
||||
snprintf(names, PART_NAME_LEN, "partition%d", i);
|
||||
|
||||
mtd_part->offset = le32_to_cpu(part->addr);
|
||||
mtd_part->size = le32_to_cpu(part->size);
|
||||
mtd_part->name = names;
|
||||
mtd_part++;
|
||||
names += PART_NAME_LEN;
|
||||
}
|
||||
|
||||
*pparts = mtd_parts;
|
||||
ret = num_parts;
|
||||
|
||||
out_free_buf:
|
||||
vfree(buf);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct mtd_part_parser myloader_mtd_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
.parse_fn = myloader_parse_partitions,
|
||||
.name = "MyLoader",
|
||||
};
|
||||
|
||||
static int __init myloader_mtd_parser_init(void)
|
||||
{
|
||||
register_mtd_parser(&myloader_mtd_parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit myloader_mtd_parser_exit(void)
|
||||
{
|
||||
deregister_mtd_parser(&myloader_mtd_parser);
|
||||
}
|
||||
|
||||
module_init(myloader_mtd_parser_init);
|
||||
module_exit(myloader_mtd_parser_exit);
|
||||
|
||||
MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@ -5,10 +5,8 @@ Subject: Add myloader partition table parser
|
||||
|
||||
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
---
|
||||
drivers/mtd/Kconfig | 16 ++++++++++++++++
|
||||
drivers/mtd/Makefile | 1 +
|
||||
2 files changed, 17 insertions(+)
|
||||
[add myloader.c to patch]
|
||||
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
|
||||
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@ -45,3 +43,187 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
obj-y += parsers/
|
||||
|
||||
# 'Users' - code which presents functionality to userspace.
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/myloader.c
|
||||
@@ -0,0 +1,181 @@
|
||||
+/*
|
||||
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
|
||||
+ * array to match.
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This file was based on drivers/mtd/redboot.c
|
||||
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/byteorder/generic.h>
|
||||
+#include <linux/myloader.h>
|
||||
+
|
||||
+#define BLOCK_LEN_MIN 0x10000
|
||||
+#define PART_NAME_LEN 32
|
||||
+
|
||||
+struct part_data {
|
||||
+ struct mylo_partition_table tab;
|
||||
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
|
||||
+};
|
||||
+
|
||||
+static int myloader_parse_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ struct part_data *buf;
|
||||
+ struct mylo_partition_table *tab;
|
||||
+ struct mylo_partition *part;
|
||||
+ struct mtd_partition *mtd_parts;
|
||||
+ struct mtd_partition *mtd_part;
|
||||
+ int num_parts;
|
||||
+ int ret, i;
|
||||
+ size_t retlen;
|
||||
+ char *names;
|
||||
+ unsigned long offset;
|
||||
+ unsigned long blocklen;
|
||||
+
|
||||
+ buf = vmalloc(sizeof(*buf));
|
||||
+ if (!buf) {
|
||||
+ return -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ tab = &buf->tab;
|
||||
+
|
||||
+ blocklen = master->erasesize;
|
||||
+ if (blocklen < BLOCK_LEN_MIN)
|
||||
+ blocklen = BLOCK_LEN_MIN;
|
||||
+
|
||||
+ offset = blocklen;
|
||||
+
|
||||
+ /* Find the partition table */
|
||||
+ for (i = 0; i < 4; i++, offset += blocklen) {
|
||||
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
|
||||
+ " at offset 0x%lx\n", master->name, offset);
|
||||
+
|
||||
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||
+ (void *)buf);
|
||||
+ if (ret)
|
||||
+ goto out_free_buf;
|
||||
+
|
||||
+ if (retlen != sizeof(*buf)) {
|
||||
+ ret = -EIO;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for Partition Table magic number */
|
||||
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
|
||||
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
|
||||
+ master->name);
|
||||
+ ret = 0;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* The MyLoader and the Partition Table is always present */
|
||||
+ num_parts = 2;
|
||||
+
|
||||
+ /* Detect number of used partitions */
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ num_parts++;
|
||||
+ }
|
||||
+
|
||||
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
|
||||
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
|
||||
+
|
||||
+ if (!mtd_parts) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ mtd_part = mtd_parts;
|
||||
+ names = (char *)&mtd_parts[num_parts];
|
||||
+
|
||||
+ strncpy(names, "myloader", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = 0;
|
||||
+ mtd_part->size = offset;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ strncpy(names, "partition_table", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = offset;
|
||||
+ mtd_part->size = blocklen;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
|
||||
+ strncpy(names, buf->names[i], PART_NAME_LEN);
|
||||
+ else
|
||||
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
|
||||
+
|
||||
+ mtd_part->offset = le32_to_cpu(part->addr);
|
||||
+ mtd_part->size = le32_to_cpu(part->size);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+ }
|
||||
+
|
||||
+ *pparts = mtd_parts;
|
||||
+ ret = num_parts;
|
||||
+
|
||||
+ out_free_buf:
|
||||
+ vfree(buf);
|
||||
+ out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct mtd_part_parser myloader_mtd_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = myloader_parse_partitions,
|
||||
+ .name = "MyLoader",
|
||||
+};
|
||||
+
|
||||
+static int __init myloader_mtd_parser_init(void)
|
||||
+{
|
||||
+ register_mtd_parser(&myloader_mtd_parser);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit myloader_mtd_parser_exit(void)
|
||||
+{
|
||||
+ deregister_mtd_parser(&myloader_mtd_parser);
|
||||
+}
|
||||
+
|
||||
+module_init(myloader_mtd_parser_init);
|
||||
+module_exit(myloader_mtd_parser_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
|
||||
@ -5,10 +5,8 @@ Subject: Add myloader partition table parser
|
||||
|
||||
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
---
|
||||
drivers/mtd/Kconfig | 16 ++++++++++++++++
|
||||
drivers/mtd/Makefile | 1 +
|
||||
2 files changed, 17 insertions(+)
|
||||
[add myloader.c to patch]
|
||||
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
|
||||
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@ -45,3 +43,187 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
obj-y += parsers/
|
||||
|
||||
# 'Users' - code which presents functionality to userspace.
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/myloader.c
|
||||
@@ -0,0 +1,181 @@
|
||||
+/*
|
||||
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
|
||||
+ * array to match.
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This file was based on drivers/mtd/redboot.c
|
||||
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/byteorder/generic.h>
|
||||
+#include <linux/myloader.h>
|
||||
+
|
||||
+#define BLOCK_LEN_MIN 0x10000
|
||||
+#define PART_NAME_LEN 32
|
||||
+
|
||||
+struct part_data {
|
||||
+ struct mylo_partition_table tab;
|
||||
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
|
||||
+};
|
||||
+
|
||||
+static int myloader_parse_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ struct part_data *buf;
|
||||
+ struct mylo_partition_table *tab;
|
||||
+ struct mylo_partition *part;
|
||||
+ struct mtd_partition *mtd_parts;
|
||||
+ struct mtd_partition *mtd_part;
|
||||
+ int num_parts;
|
||||
+ int ret, i;
|
||||
+ size_t retlen;
|
||||
+ char *names;
|
||||
+ unsigned long offset;
|
||||
+ unsigned long blocklen;
|
||||
+
|
||||
+ buf = vmalloc(sizeof(*buf));
|
||||
+ if (!buf) {
|
||||
+ return -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ tab = &buf->tab;
|
||||
+
|
||||
+ blocklen = master->erasesize;
|
||||
+ if (blocklen < BLOCK_LEN_MIN)
|
||||
+ blocklen = BLOCK_LEN_MIN;
|
||||
+
|
||||
+ offset = blocklen;
|
||||
+
|
||||
+ /* Find the partition table */
|
||||
+ for (i = 0; i < 4; i++, offset += blocklen) {
|
||||
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
|
||||
+ " at offset 0x%lx\n", master->name, offset);
|
||||
+
|
||||
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||
+ (void *)buf);
|
||||
+ if (ret)
|
||||
+ goto out_free_buf;
|
||||
+
|
||||
+ if (retlen != sizeof(*buf)) {
|
||||
+ ret = -EIO;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for Partition Table magic number */
|
||||
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
|
||||
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
|
||||
+ master->name);
|
||||
+ ret = 0;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* The MyLoader and the Partition Table is always present */
|
||||
+ num_parts = 2;
|
||||
+
|
||||
+ /* Detect number of used partitions */
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ num_parts++;
|
||||
+ }
|
||||
+
|
||||
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
|
||||
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
|
||||
+
|
||||
+ if (!mtd_parts) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ mtd_part = mtd_parts;
|
||||
+ names = (char *)&mtd_parts[num_parts];
|
||||
+
|
||||
+ strncpy(names, "myloader", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = 0;
|
||||
+ mtd_part->size = offset;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ strncpy(names, "partition_table", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = offset;
|
||||
+ mtd_part->size = blocklen;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
|
||||
+ strncpy(names, buf->names[i], PART_NAME_LEN);
|
||||
+ else
|
||||
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
|
||||
+
|
||||
+ mtd_part->offset = le32_to_cpu(part->addr);
|
||||
+ mtd_part->size = le32_to_cpu(part->size);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+ }
|
||||
+
|
||||
+ *pparts = mtd_parts;
|
||||
+ ret = num_parts;
|
||||
+
|
||||
+ out_free_buf:
|
||||
+ vfree(buf);
|
||||
+ out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct mtd_part_parser myloader_mtd_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = myloader_parse_partitions,
|
||||
+ .name = "MyLoader",
|
||||
+};
|
||||
+
|
||||
+static int __init myloader_mtd_parser_init(void)
|
||||
+{
|
||||
+ register_mtd_parser(&myloader_mtd_parser);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit myloader_mtd_parser_exit(void)
|
||||
+{
|
||||
+ deregister_mtd_parser(&myloader_mtd_parser);
|
||||
+}
|
||||
+
|
||||
+module_init(myloader_mtd_parser_init);
|
||||
+module_exit(myloader_mtd_parser_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
|
||||
@ -5,17 +5,16 @@ Subject: Add myloader partition table parser
|
||||
|
||||
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
---
|
||||
drivers/mtd/Kconfig | 16 ++++++++++++++++
|
||||
drivers/mtd/Makefile | 1 +
|
||||
2 files changed, 17 insertions(+)
|
||||
[adjust for kernel 5.4, add myloader.c to patch]
|
||||
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
|
||||
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -46,6 +46,22 @@ menu "Partition parsers"
|
||||
source "drivers/mtd/parsers/Kconfig"
|
||||
endmenu
|
||||
--- a/drivers/mtd/parsers/Kconfig
|
||||
+++ b/drivers/mtd/parsers/Kconfig
|
||||
@@ -160,3 +160,19 @@ config MTD_REDBOOT_PARTS_READONLY
|
||||
'FIS directory' images, enable this option.
|
||||
|
||||
endif # MTD_REDBOOT_PARTS
|
||||
+
|
||||
+config MTD_MYLOADER_PARTS
|
||||
+ tristate "MyLoader partition parsing"
|
||||
+ depends on ADM5120 || ATH25 || ATH79
|
||||
@ -31,14 +30,194 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
+
|
||||
+ You will still need the parsing functions to be called by the driver
|
||||
+ for your particular device. It won't happen automatically.
|
||||
+
|
||||
comment "User Modules And Translation Layers"
|
||||
|
||||
#
|
||||
--- a/drivers/mtd/parsers/Makefile
|
||||
+++ b/drivers/mtd/parsers/Makefile
|
||||
@@ -9,3 +9,4 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
|
||||
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
|
||||
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
|
||||
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
|
||||
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
|
||||
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/parsers/myloader.c
|
||||
@@ -0,0 +1,181 @@
|
||||
+/*
|
||||
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
|
||||
+ * array to match.
|
||||
+ *
|
||||
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This file was based on drivers/mtd/redboot.c
|
||||
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/byteorder/generic.h>
|
||||
+#include <linux/myloader.h>
|
||||
+
|
||||
+#define BLOCK_LEN_MIN 0x10000
|
||||
+#define PART_NAME_LEN 32
|
||||
+
|
||||
+struct part_data {
|
||||
+ struct mylo_partition_table tab;
|
||||
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
|
||||
+};
|
||||
+
|
||||
+static int myloader_parse_partitions(struct mtd_info *master,
|
||||
+ const struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ struct part_data *buf;
|
||||
+ struct mylo_partition_table *tab;
|
||||
+ struct mylo_partition *part;
|
||||
+ struct mtd_partition *mtd_parts;
|
||||
+ struct mtd_partition *mtd_part;
|
||||
+ int num_parts;
|
||||
+ int ret, i;
|
||||
+ size_t retlen;
|
||||
+ char *names;
|
||||
+ unsigned long offset;
|
||||
+ unsigned long blocklen;
|
||||
+
|
||||
+ buf = vmalloc(sizeof(*buf));
|
||||
+ if (!buf) {
|
||||
+ return -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ tab = &buf->tab;
|
||||
+
|
||||
+ blocklen = master->erasesize;
|
||||
+ if (blocklen < BLOCK_LEN_MIN)
|
||||
+ blocklen = BLOCK_LEN_MIN;
|
||||
+
|
||||
+ offset = blocklen;
|
||||
+
|
||||
+ /* Find the partition table */
|
||||
+ for (i = 0; i < 4; i++, offset += blocklen) {
|
||||
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
|
||||
+ " at offset 0x%lx\n", master->name, offset);
|
||||
+
|
||||
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||
+ (void *)buf);
|
||||
+ if (ret)
|
||||
+ goto out_free_buf;
|
||||
+
|
||||
+ if (retlen != sizeof(*buf)) {
|
||||
+ ret = -EIO;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for Partition Table magic number */
|
||||
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
|
||||
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
|
||||
+ master->name);
|
||||
+ ret = 0;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ /* The MyLoader and the Partition Table is always present */
|
||||
+ num_parts = 2;
|
||||
+
|
||||
+ /* Detect number of used partitions */
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ num_parts++;
|
||||
+ }
|
||||
+
|
||||
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
|
||||
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
|
||||
+
|
||||
+ if (!mtd_parts) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out_free_buf;
|
||||
+ }
|
||||
+
|
||||
+ mtd_part = mtd_parts;
|
||||
+ names = (char *)&mtd_parts[num_parts];
|
||||
+
|
||||
+ strncpy(names, "myloader", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = 0;
|
||||
+ mtd_part->size = offset;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ strncpy(names, "partition_table", PART_NAME_LEN);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part->offset = offset;
|
||||
+ mtd_part->size = blocklen;
|
||||
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+
|
||||
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||
+ part = &tab->partitions[i];
|
||||
+
|
||||
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
|
||||
+ strncpy(names, buf->names[i], PART_NAME_LEN);
|
||||
+ else
|
||||
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
|
||||
+
|
||||
+ mtd_part->offset = le32_to_cpu(part->addr);
|
||||
+ mtd_part->size = le32_to_cpu(part->size);
|
||||
+ mtd_part->name = names;
|
||||
+ mtd_part++;
|
||||
+ names += PART_NAME_LEN;
|
||||
+ }
|
||||
+
|
||||
+ *pparts = mtd_parts;
|
||||
+ ret = num_parts;
|
||||
+
|
||||
+ out_free_buf:
|
||||
+ vfree(buf);
|
||||
+ out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct mtd_part_parser myloader_mtd_parser = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .parse_fn = myloader_parse_partitions,
|
||||
+ .name = "MyLoader",
|
||||
+};
|
||||
+
|
||||
+static int __init myloader_mtd_parser_init(void)
|
||||
+{
|
||||
+ register_mtd_parser(&myloader_mtd_parser);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit myloader_mtd_parser_exit(void)
|
||||
+{
|
||||
+ deregister_mtd_parser(&myloader_mtd_parser);
|
||||
+}
|
||||
+
|
||||
+module_init(myloader_mtd_parser_init);
|
||||
+module_exit(myloader_mtd_parser_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
|
||||
@ -43,7 +43,7 @@ Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -244,4 +244,6 @@ source "drivers/mtd/ubi/Kconfig"
|
||||
@@ -228,4 +228,6 @@ source "drivers/mtd/ubi/Kconfig"
|
||||
|
||||
source "drivers/mtd/hyperbus/Kconfig"
|
||||
|
||||
|
||||
@ -18,6 +18,17 @@ ipq40xx_setup_interfaces()
|
||||
engenius,ens620ext)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
;;
|
||||
aruba,ap-303|\
|
||||
avm,fritzrepeater-1200|\
|
||||
dlink,dap-2610 |\
|
||||
engenius,eap1300|\
|
||||
engenius,emd1|\
|
||||
meraki,mr33|\
|
||||
netgear,ex6100v2|\
|
||||
netgear,ex6150v2|\
|
||||
zyxel,wre6606)
|
||||
ucidef_set_interface_lan "eth0"
|
||||
;;
|
||||
aruba,ap-303h)
|
||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
||||
ucidef_add_switch "switch0" \
|
||||
@ -48,17 +59,6 @@ ipq40xx_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan"
|
||||
;;
|
||||
aruba,ap-303|\
|
||||
avm,fritzrepeater-1200|\
|
||||
dlink,dap-2610 |\
|
||||
engenius,eap1300|\
|
||||
engenius,emd1|\
|
||||
meraki,mr33|\
|
||||
netgear,ex6100v2|\
|
||||
netgear,ex6150v2|\
|
||||
zyxel,wre6606)
|
||||
ucidef_set_interface_lan "eth0"
|
||||
;;
|
||||
avm,fritzrepeater-3000|\
|
||||
compex,wpj419|\
|
||||
compex,wpj428|\
|
||||
|
||||
Loading…
Reference in New Issue
Block a user