diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2019-03-25 15:29:06 +0100 |
---|---|---|
committer | Hauke Mehrtens <hauke@hauke-m.de> | 2019-05-03 22:41:38 +0200 |
commit | 1325e74e0c2f9ebdafe05b1492cec77a60059920 (patch) | |
tree | af21c4890a4ae5c08dc08ee7cabdc14a651f33ad /target/linux/generic/pending-3.18 | |
parent | 675832de79ec14ddc1183a66d1084aff7a856289 (diff) | |
download | upstream-1325e74e0c2f9ebdafe05b1492cec77a60059920.tar.gz upstream-1325e74e0c2f9ebdafe05b1492cec77a60059920.tar.bz2 upstream-1325e74e0c2f9ebdafe05b1492cec77a60059920.zip |
kernel: Remove support for kernel 3.18
No target is using kernel 3.18 anymore, remove all the generic
support for kernel 3.18.
The removed packages are depending on kernel 3.18 only and are not used on
any recent kernel.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Diffstat (limited to 'target/linux/generic/pending-3.18')
243 files changed, 0 insertions, 35772 deletions
diff --git a/target/linux/generic/pending-3.18/001-mtdsplit_backport.patch b/target/linux/generic/pending-3.18/001-mtdsplit_backport.patch deleted file mode 100644 index a558f6ff82..0000000000 --- a/target/linux/generic/pending-3.18/001-mtdsplit_backport.patch +++ /dev/null @@ -1,142 +0,0 @@ ---- a/drivers/mtd/mtdsplit/mtdsplit_brnimage.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_brnimage.c -@@ -27,7 +27,7 @@ - #define BRNIMAGE_MAX_OVERHEAD (BRNIMAGE_ALIGN_BYTES + BRNIMAGE_FOOTER_SIZE) - - static int mtdsplit_parse_brnimage(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct mtd_partition *parts; ---- a/drivers/mtd/mtdsplit/mtdsplit_eva.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_eva.c -@@ -29,7 +29,7 @@ struct eva_image_header { - }; - - static int mtdsplit_parse_eva(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct mtd_partition *parts; ---- a/drivers/mtd/mtdsplit/mtdsplit_fit.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_fit.c -@@ -45,8 +45,7 @@ struct fdt_header { - }; - - static int --mtdsplit_fit_parse(struct mtd_info *mtd, -- const struct mtd_partition **pparts, -+mtdsplit_fit_parse(struct mtd_info *mtd, struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct fdt_header hdr; ---- a/drivers/mtd/mtdsplit/mtdsplit_lzma.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_lzma.c -@@ -28,7 +28,7 @@ struct lzma_header { - }; - - static int mtdsplit_parse_lzma(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct lzma_header hdr; ---- a/drivers/mtd/mtdsplit/mtdsplit_seama.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_seama.c -@@ -30,7 +30,7 @@ struct seama_header { - }; - - static int mtdsplit_parse_seama(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct seama_header hdr; ---- a/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -@@ -23,7 +23,7 @@ - - static int - mtdsplit_parse_squashfs(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct mtd_partition *part; ---- a/drivers/mtd/mtdsplit/mtdsplit_tplink.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_tplink.c -@@ -83,8 +83,8 @@ struct tplink_fw_header { - }; - - static int mtdsplit_parse_tplink(struct mtd_info *master, -- const struct mtd_partition **pparts, -- struct mtd_part_parser_data *data) -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) - { - struct tplink_fw_header hdr; - size_t hdr_len, retlen, kernel_size; ---- a/drivers/mtd/mtdsplit/mtdsplit_trx.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_trx.c -@@ -56,7 +56,7 @@ read_trx_header(struct mtd_info *mtd, si - - static int - mtdsplit_parse_trx(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct mtd_partition *parts; ---- a/drivers/mtd/mtdsplit/mtdsplit_uimage.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_uimage.c -@@ -82,7 +82,7 @@ read_uimage_header(struct mtd_info *mtd, - * of a valid uImage header if found - */ - static int __mtdsplit_parse_uimage(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len)) - { -@@ -233,7 +233,7 @@ static ssize_t uimage_verify_default(u_c - - static int - mtdsplit_uimage_parse_generic(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - return __mtdsplit_parse_uimage(master, pparts, data, -@@ -300,7 +300,7 @@ static ssize_t uimage_verify_wndr3700(u_ - - static int - mtdsplit_uimage_parse_netgear(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - return __mtdsplit_parse_uimage(master, pparts, data, -@@ -352,7 +352,7 @@ static ssize_t uimage_find_edimax(u_char - - static int - mtdsplit_uimage_parse_edimax(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - return __mtdsplit_parse_uimage(master, pparts, data, ---- a/drivers/mtd/mtdsplit/mtdsplit_wrgg.c -+++ b/drivers/mtd/mtdsplit/mtdsplit_wrgg.c -@@ -51,8 +51,8 @@ struct wrg_header { - - - static int mtdsplit_parse_wrgg(struct mtd_info *master, -- const struct mtd_partition **pparts, -- struct mtd_part_parser_data *data) -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) - { - struct wrgg03_header hdr; - size_t hdr_len, retlen, kernel_ent_size; diff --git a/target/linux/generic/pending-3.18/002-phy_drivers_backport.patch b/target/linux/generic/pending-3.18/002-phy_drivers_backport.patch deleted file mode 100644 index e2ca05384a..0000000000 --- a/target/linux/generic/pending-3.18/002-phy_drivers_backport.patch +++ /dev/null @@ -1,552 +0,0 @@ ---- a/drivers/net/phy/adm6996.c -+++ b/drivers/net/phy/adm6996.c -@@ -289,7 +289,7 @@ static u16 - adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg) - { - struct phy_device *phydev = priv->priv; -- struct mii_bus *bus = phydev->mdio.bus; -+ struct mii_bus *bus = phydev->bus; - - return bus->read(bus, PHYADDR(reg)); - } -@@ -298,7 +298,7 @@ static void - adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val) - { - struct phy_device *phydev = priv->priv; -- struct mii_bus *bus = phydev->mdio.bus; -+ struct mii_bus *bus = phydev->bus; - - bus->write(bus, PHYADDR(reg), val); - } -@@ -1050,13 +1050,13 @@ static int adm6996_config_init(struct ph - pdev->supported = ADVERTISED_100baseT_Full; - pdev->advertising = ADVERTISED_100baseT_Full; - -- if (pdev->mdio.addr != 0) { -+ if (pdev->addr != 0) { - pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n" -- , pdev->attached_dev->name, pdev->mdio.addr); -+ , pdev->attached_dev->name, pdev->addr); - return 0; - } - -- priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL); -+ priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - -@@ -1076,7 +1076,7 @@ static int adm6996_config_init(struct ph - } - - /* -- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0 -+ * Warning: phydev->priv is NULL if phydev->addr != 0 - */ - static int adm6996_read_status(struct phy_device *phydev) - { -@@ -1092,7 +1092,7 @@ static int adm6996_read_status(struct ph - } - - /* -- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0 -+ * Warning: phydev->priv is NULL if phydev->addr != 0 - */ - static int adm6996_config_aneg(struct phy_device *phydev) - { -@@ -1101,11 +1101,11 @@ static int adm6996_config_aneg(struct ph - - static int adm6996_fixup(struct phy_device *dev) - { -- struct mii_bus *bus = dev->mdio.bus; -+ struct mii_bus *bus = dev->bus; - u16 reg; - - /* Our custom registers are at PHY addresses 0-10. Claim those. */ -- if (dev->mdio.addr > 10) -+ if (dev->addr > 10) - return 0; - - /* look for the switch on the bus */ -@@ -1152,6 +1152,7 @@ static struct phy_driver adm6996_phy_dri - .config_aneg = &adm6996_config_aneg, - .read_status = &adm6996_read_status, - .soft_reset = adm6996_soft_reset, -+ .driver = { .owner = THIS_MODULE,}, - }; - - static int adm6996_gpio_probe(struct platform_device *pdev) -@@ -1220,7 +1221,7 @@ static int __init adm6996_init(void) - int err; - - phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup); -- err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE); -+ err = phy_driver_register(&adm6996_phy_driver); - if (err) - return err; - ---- a/drivers/net/phy/ar8216.c -+++ b/drivers/net/phy/ar8216.c -@@ -177,7 +177,7 @@ ar8xxx_phy_check_aneg(struct phy_device - if (ret & BMCR_ANENABLE) - return 0; - -- dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n"); -+ dev_info(&phydev->dev, "ANEG disabled, re-enabling ...\n"); - ret |= BMCR_ANENABLE | BMCR_ANRESTART; - return phy_write(phydev, MII_BMCR, ret); - } -@@ -2021,7 +2021,7 @@ ar8xxx_phy_config_init(struct phy_device - - priv->phy = phydev; - -- if (phydev->mdio.addr != 0) { -+ if (phydev->addr != 0) { - if (chip_is_ar8316(priv)) { - /* switch device has been initialized, reinit */ - priv->dev.ports = (AR8216_NUM_PORTS - 1); -@@ -2069,7 +2069,7 @@ ar8xxx_check_link_states(struct ar8xxx_p - /* flush ARL entries for this port if it went down*/ - if (!link_new) - priv->chip->atu_flush_port(priv, i); -- dev_info(&priv->phy->mdio.dev, "Port %d is %s\n", -+ dev_info(&priv->phy->dev, "Port %d is %s\n", - i, link_new ? "up" : "down"); - } - -@@ -2088,10 +2088,10 @@ ar8xxx_phy_read_status(struct phy_device - if (phydev->state == PHY_CHANGELINK) - ar8xxx_check_link_states(priv); - -- if (phydev->mdio.addr != 0) -+ if (phydev->addr != 0) - return genphy_read_status(phydev); - -- ar8216_read_port_link(priv, phydev->mdio.addr, &link); -+ ar8216_read_port_link(priv, phydev->addr, &link); - phydev->link = !!link.link; - if (!phydev->link) - return 0; -@@ -2122,7 +2122,7 @@ ar8xxx_phy_read_status(struct phy_device - static int - ar8xxx_phy_config_aneg(struct phy_device *phydev) - { -- if (phydev->mdio.addr == 0) -+ if (phydev->addr == 0) - return 0; - - return genphy_config_aneg(phydev); -@@ -2177,15 +2177,15 @@ ar8xxx_phy_probe(struct phy_device *phyd - int ret; - - /* skip PHYs at unused adresses */ -- if (phydev->mdio.addr != 0 && phydev->mdio.addr != 3 && phydev->mdio.addr != 4) -+ if (phydev->addr != 0 && phydev->addr != 3 && phydev->addr != 4) - return -ENODEV; - -- if (!ar8xxx_is_possible(phydev->mdio.bus)) -+ if (!ar8xxx_is_possible(phydev->bus)) - return -ENODEV; - - mutex_lock(&ar8xxx_dev_list_lock); - list_for_each_entry(priv, &ar8xxx_dev_list, list) -- if (priv->mii_bus == phydev->mdio.bus) -+ if (priv->mii_bus == phydev->bus) - goto found; - - priv = ar8xxx_create(); -@@ -2194,7 +2194,7 @@ ar8xxx_phy_probe(struct phy_device *phyd - goto unlock; - } - -- priv->mii_bus = phydev->mdio.bus; -+ priv->mii_bus = phydev->bus; - - ret = ar8xxx_probe_switch(priv); - if (ret) -@@ -2215,7 +2215,7 @@ ar8xxx_phy_probe(struct phy_device *phyd - found: - priv->use_count++; - -- if (phydev->mdio.addr == 0) { -+ if (phydev->addr == 0) { - if (ar8xxx_has_gige(priv)) { - phydev->supported = SUPPORTED_1000baseT_Full; - phydev->advertising = ADVERTISED_1000baseT_Full; -@@ -2305,21 +2305,33 @@ ar8xxx_phy_soft_reset(struct phy_device - return 0; - } - --static struct phy_driver ar8xxx_phy_driver[] = { -- { -- .phy_id = 0x004d0000, -- .name = "Atheros AR8216/AR8236/AR8316", -- .phy_id_mask = 0xffff0000, -- .features = PHY_BASIC_FEATURES, -- .probe = ar8xxx_phy_probe, -- .remove = ar8xxx_phy_remove, -- .detach = ar8xxx_phy_detach, -- .config_init = ar8xxx_phy_config_init, -- .config_aneg = ar8xxx_phy_config_aneg, -- .read_status = ar8xxx_phy_read_status, -- .soft_reset = ar8xxx_phy_soft_reset, -- } -+static struct phy_driver ar8xxx_phy_driver = { -+ .phy_id = 0x004d0000, -+ .name = "Atheros AR8216/AR8236/AR8316", -+ .phy_id_mask = 0xffff0000, -+ .features = PHY_BASIC_FEATURES, -+ .probe = ar8xxx_phy_probe, -+ .remove = ar8xxx_phy_remove, -+ .detach = ar8xxx_phy_detach, -+ .config_init = ar8xxx_phy_config_init, -+ .config_aneg = ar8xxx_phy_config_aneg, -+ .read_status = ar8xxx_phy_read_status, -+ .soft_reset = ar8xxx_phy_soft_reset, -+ .driver = { .owner = THIS_MODULE }, - }; - --module_phy_driver(ar8xxx_phy_driver); -+int __init -+ar8xxx_init(void) -+{ -+ return phy_driver_register(&ar8xxx_phy_driver); -+} -+ -+void __exit -+ar8xxx_exit(void) -+{ -+ phy_driver_unregister(&ar8xxx_phy_driver); -+} -+ -+module_init(ar8xxx_init); -+module_exit(ar8xxx_exit); - MODULE_LICENSE("GPL"); ---- a/drivers/net/phy/ar8327.c -+++ b/drivers/net/phy/ar8327.c -@@ -662,11 +662,11 @@ ar8327_hw_init(struct ar8xxx_priv *priv) - if (!priv->chip_data) - return -ENOMEM; - -- if (priv->phy->mdio.dev.of_node) -- ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node); -+ if (priv->phy->dev.of_node) -+ ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node); - else - ret = ar8327_hw_config_pdata(priv, -- priv->phy->mdio.dev.platform_data); -+ priv->phy->dev.platform_data); - - if (ret) - return ret; ---- a/drivers/net/phy/ip17xx.c -+++ b/drivers/net/phy/ip17xx.c -@@ -1273,7 +1273,7 @@ static int ip17xx_probe(struct phy_devic - int err; - - /* We only attach to PHY 0, but use all available PHYs */ -- if (pdev->mdio.addr != 0) -+ if (pdev->addr != 0) - return -ENODEV; - - state = kzalloc(sizeof(*state), GFP_KERNEL); -@@ -1283,7 +1283,7 @@ static int ip17xx_probe(struct phy_devic - dev = &state->dev; - - pdev->priv = state; -- state->mii_bus = pdev->mdio.bus; -+ state->mii_bus = pdev->bus; - - err = get_model(state); - if (err < 0) -@@ -1295,7 +1295,7 @@ static int ip17xx_probe(struct phy_devic - dev->name = state->regs->NAME; - dev->ops = &ip17xx_ops; - -- pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->mdio.dev)); -+ pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev)); - return 0; - - error: -@@ -1353,25 +1353,58 @@ static int ip17xx_read_status(struct phy - return 0; - } - --static struct phy_driver ip17xx_driver[] = { -- { -- .name = "IC+ IP17xx", -- .phy_id = 0x02430c00, -- .phy_id_mask = 0x0ffffc00, -- .features = PHY_BASIC_FEATURES, -- .probe = ip17xx_probe, -- .remove = ip17xx_remove, -- .config_init = ip17xx_config_init, -- .config_aneg = ip17xx_config_aneg, -- .aneg_done = ip17xx_aneg_done, -- .update_link = ip17xx_update_link, -- .read_status = ip17xx_read_status, -- } -+static struct phy_driver ip17xx_driver = { -+ .name = "IC+ IP17xx", -+ .phy_id = 0x02430c00, -+ .phy_id_mask = 0x0ffffc00, -+ .features = PHY_BASIC_FEATURES, -+ .probe = ip17xx_probe, -+ .remove = ip17xx_remove, -+ .config_init = ip17xx_config_init, -+ .config_aneg = ip17xx_config_aneg, -+ .aneg_done = ip17xx_aneg_done, -+ .update_link = ip17xx_update_link, -+ .read_status = ip17xx_read_status, -+ .driver = { .owner = THIS_MODULE }, - }; - --module_phy_driver(ip17xx_driver); -+static struct phy_driver ip175a_driver = { -+ .name = "IC+ IP175A", -+ .phy_id = 0x02430c50, -+ .phy_id_mask = 0x0ffffff0, -+ .features = PHY_BASIC_FEATURES, -+ .probe = ip17xx_probe, -+ .remove = ip17xx_remove, -+ .config_init = ip17xx_config_init, -+ .config_aneg = ip17xx_config_aneg, -+ .aneg_done = ip17xx_aneg_done, -+ .update_link = ip17xx_update_link, -+ .read_status = ip17xx_read_status, -+ .driver = { .owner = THIS_MODULE }, -+}; -+ -+ -+int __init ip17xx_init(void) -+{ -+ int ret; -+ -+ ret = phy_driver_register(&ip175a_driver); -+ if (ret < 0) -+ return ret; -+ -+ return phy_driver_register(&ip17xx_driver); -+} -+ -+void __exit ip17xx_exit(void) -+{ -+ phy_driver_unregister(&ip17xx_driver); -+ phy_driver_unregister(&ip175a_driver); -+} - - MODULE_AUTHOR("Patrick Horn <patrick.horn@gmail.com>"); - MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>"); - MODULE_AUTHOR("Martin Mares <mj@ucw.cz>"); - MODULE_LICENSE("GPL"); -+ -+module_init(ip17xx_init); -+module_exit(ip17xx_exit); ---- a/drivers/net/phy/mvswitch.c -+++ b/drivers/net/phy/mvswitch.c -@@ -50,17 +50,13 @@ struct mvswitch_priv { - static inline u16 - r16(struct phy_device *phydev, int addr, int reg) - { -- struct mii_bus *bus = phydev->mdio.bus; -- -- return bus->read(bus, addr, reg); -+ return phydev->bus->read(phydev->bus, addr, reg); - } - - static inline void - w16(struct phy_device *phydev, int addr, int reg, u16 val) - { -- struct mii_bus *bus = phydev->mdio.bus; -- -- bus->write(bus, addr, reg, val); -+ phydev->bus->write(phydev->bus, addr, reg, val); - } - - -@@ -398,13 +394,12 @@ mvswitch_probe(struct phy_device *pdev) - static int - mvswitch_fixup(struct phy_device *dev) - { -- struct mii_bus *bus = dev->mdio.bus; - u16 reg; - -- if (dev->mdio.addr != 0x10) -+ if (dev->addr != 0x10) - return 0; - -- reg = bus->read(bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK; -+ reg = dev->bus->read(dev->bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK; - if (reg != MV_IDENT_VALUE) - return 0; - -@@ -425,13 +420,14 @@ static struct phy_driver mvswitch_driver - .config_aneg = &mvswitch_config_aneg, - .aneg_done = &mvswitch_aneg_done, - .read_status = &mvswitch_read_status, -+ .driver = { .owner = THIS_MODULE,}, - }; - - static int __init - mvswitch_init(void) - { - phy_register_fixup_for_id(PHY_ANY_ID, mvswitch_fixup); -- return phy_driver_register(&mvswitch_driver, THIS_MODULE); -+ return phy_driver_register(&mvswitch_driver); - } - - static void __exit ---- a/drivers/net/phy/psb6970.c -+++ b/drivers/net/phy/psb6970.c -@@ -70,16 +70,12 @@ struct psb6970_priv { - - static u16 psb6970_mii_read(struct phy_device *phydev, int reg) - { -- struct mii_bus *bus = phydev->mdio.bus; -- -- return bus->read(bus, PHYADDR(reg)); -+ return phydev->bus->read(phydev->bus, PHYADDR(reg)); - } - - static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val) - { -- struct mii_bus *bus = phydev->mdio.bus; -- -- bus->write(bus, PHYADDR(reg), val); -+ phydev->bus->write(phydev->bus, PHYADDR(reg), val); - } - - static int -@@ -316,11 +312,11 @@ static int psb6970_config_init(struct ph - - priv->phy = pdev; - -- if (pdev->mdio.addr == 0) -+ if (pdev->addr == 0) - printk(KERN_INFO "%s: psb6970 switch driver attached.\n", - pdev->attached_dev->name); - -- if (pdev->mdio.addr != 0) { -+ if (pdev->addr != 0) { - kfree(priv); - return 0; - } -@@ -388,14 +384,14 @@ static void psb6970_remove(struct phy_de - if (!priv) - return; - -- if (pdev->mdio.addr == 0) -+ if (pdev->addr == 0) - unregister_switch(&priv->dev); - kfree(priv); - } - - static int psb6970_fixup(struct phy_device *dev) - { -- struct mii_bus *bus = dev->mdio.bus; -+ struct mii_bus *bus = dev->bus; - u16 reg; - - /* look for the switch on the bus */ -@@ -419,12 +415,13 @@ static struct phy_driver psb6970_driver - .config_init = &psb6970_config_init, - .config_aneg = &psb6970_config_aneg, - .read_status = &psb6970_read_status, -+ .driver = {.owner = THIS_MODULE}, - }; - - int __init psb6970_init(void) - { - phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup); -- return phy_driver_register(&psb6970_driver, THIS_MODULE); -+ return phy_driver_register(&psb6970_driver); - } - - module_init(psb6970_init); ---- a/drivers/net/phy/rtl8306.c -+++ b/drivers/net/phy/rtl8306.c -@@ -877,7 +877,7 @@ rtl8306_config_init(struct phy_device *p - int err; - - /* Only init the switch for the primary PHY */ -- if (pdev->mdio.addr != 0) -+ if (pdev->addr != 0) - return 0; - - val.value.i = 1; -@@ -887,7 +887,7 @@ rtl8306_config_init(struct phy_device *p - priv->dev.ops = &rtl8306_ops; - priv->do_cpu = 0; - priv->page = -1; -- priv->bus = pdev->mdio.bus; -+ priv->bus = pdev->bus; - - chipid = rtl_get(dev, RTL_REG_CHIPID); - chipver = rtl_get(dev, RTL_REG_CHIPVER); -@@ -933,13 +933,13 @@ rtl8306_fixup(struct phy_device *pdev) - u16 chipid; - - /* Attach to primary LAN port and WAN port */ -- if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4) -+ if (pdev->addr != 0 && pdev->addr != 4) - return 0; - - memset(&priv, 0, sizeof(priv)); - priv.fixup = true; - priv.page = -1; -- priv.bus = pdev->mdio.bus; -+ priv.bus = pdev->bus; - chipid = rtl_get(&priv.dev, RTL_REG_CHIPID); - if (chipid == 0x5988) - pdev->phy_id = RTL8306_MAGIC; -@@ -957,14 +957,14 @@ rtl8306_probe(struct phy_device *pdev) - * share one rtl_priv instance between virtual phy - * devices on the same bus - */ -- if (priv->bus == pdev->mdio.bus) -+ if (priv->bus == pdev->bus) - goto found; - } - priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - -- priv->bus = pdev->mdio.bus; -+ priv->bus = pdev->bus; - - found: - pdev->priv = priv; -@@ -985,7 +985,7 @@ rtl8306_config_aneg(struct phy_device *p - struct rtl_priv *priv = pdev->priv; - - /* Only for WAN */ -- if (pdev->mdio.addr == 0) -+ if (pdev->addr == 0) - return 0; - - /* Restart autonegotiation */ -@@ -1001,7 +1001,7 @@ rtl8306_read_status(struct phy_device *p - struct rtl_priv *priv = pdev->priv; - struct switch_dev *dev = &priv->dev; - -- if (pdev->mdio.addr == 4) { -+ if (pdev->addr == 4) { - /* WAN */ - pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10; - pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF; -@@ -1044,6 +1044,7 @@ static struct phy_driver rtl8306_driver - .config_init = &rtl8306_config_init, - .config_aneg = &rtl8306_config_aneg, - .read_status = &rtl8306_read_status, -+ .driver = { .owner = THIS_MODULE,}, - }; - - -@@ -1051,7 +1052,7 @@ static int __init - rtl_init(void) - { - phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup); -- return phy_driver_register(&rtl8306_driver, THIS_MODULE); -+ return phy_driver_register(&rtl8306_driver); - } - - static void __exit diff --git a/target/linux/generic/pending-3.18/003-myloader_backport.patch b/target/linux/generic/pending-3.18/003-myloader_backport.patch deleted file mode 100644 index 846b25dc04..0000000000 --- a/target/linux/generic/pending-3.18/003-myloader_backport.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/mtd/myloader.c -+++ b/drivers/mtd/myloader.c -@@ -33,7 +33,7 @@ struct part_data { - }; - - static int myloader_parse_partitions(struct mtd_info *master, -- const struct mtd_partition **pparts, -+ struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { - struct part_data *buf; diff --git a/target/linux/generic/pending-3.18/020-ssb_update.patch b/target/linux/generic/pending-3.18/020-ssb_update.patch deleted file mode 100644 index f94d160fc6..0000000000 --- a/target/linux/generic/pending-3.18/020-ssb_update.patch +++ /dev/null @@ -1,134 +0,0 @@ ---- a/drivers/ssb/pcihost_wrapper.c -+++ b/drivers/ssb/pcihost_wrapper.c -@@ -11,15 +11,17 @@ - * Licensed under the GNU/GPL. See COPYING for details. - */ - -+#include <linux/pm.h> - #include <linux/pci.h> - #include <linux/export.h> - #include <linux/slab.h> - #include <linux/ssb/ssb.h> - - --#ifdef CONFIG_PM --static int ssb_pcihost_suspend(struct pci_dev *dev, pm_message_t state) -+#ifdef CONFIG_PM_SLEEP -+static int ssb_pcihost_suspend(struct device *d) - { -+ struct pci_dev *dev = to_pci_dev(d); - struct ssb_bus *ssb = pci_get_drvdata(dev); - int err; - -@@ -28,17 +30,23 @@ static int ssb_pcihost_suspend(struct pc - return err; - pci_save_state(dev); - pci_disable_device(dev); -- pci_set_power_state(dev, pci_choose_state(dev, state)); -+ -+ /* if there is a wakeup enabled child device on ssb bus, -+ enable pci wakeup posibility. */ -+ device_set_wakeup_enable(d, d->power.wakeup_path); -+ -+ pci_prepare_to_sleep(dev); - - return 0; - } - --static int ssb_pcihost_resume(struct pci_dev *dev) -+static int ssb_pcihost_resume(struct device *d) - { -+ struct pci_dev *dev = to_pci_dev(d); - struct ssb_bus *ssb = pci_get_drvdata(dev); - int err; - -- pci_set_power_state(dev, PCI_D0); -+ pci_back_from_sleep(dev); - err = pci_enable_device(dev); - if (err) - return err; -@@ -49,10 +57,12 @@ static int ssb_pcihost_resume(struct pci - - return 0; - } --#else /* CONFIG_PM */ --# define ssb_pcihost_suspend NULL --# define ssb_pcihost_resume NULL --#endif /* CONFIG_PM */ -+ -+static const struct dev_pm_ops ssb_pcihost_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(ssb_pcihost_suspend, ssb_pcihost_resume) -+}; -+ -+#endif /* CONFIG_PM_SLEEP */ - - static int ssb_pcihost_probe(struct pci_dev *dev, - const struct pci_device_id *id) -@@ -115,8 +125,9 @@ int ssb_pcihost_register(struct pci_driv - { - driver->probe = ssb_pcihost_probe; - driver->remove = ssb_pcihost_remove; -- driver->suspend = ssb_pcihost_suspend; -- driver->resume = ssb_pcihost_resume; -+#ifdef CONFIG_PM_SLEEP -+ driver->driver.pm = &ssb_pcihost_pm_ops; -+#endif - - return pci_register_driver(driver); - } ---- a/drivers/ssb/driver_pcicore.c -+++ b/drivers/ssb/driver_pcicore.c -@@ -357,6 +357,16 @@ static void ssb_pcicore_init_hostmode(st - pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, - SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); - -+ /* -+ * Accessing PCI config without a proper delay after devices reset (not -+ * GPIO reset) was causing reboots on WRT300N v1.0 (BCM4704). -+ * Tested delay 850 us lowered reboot chance to 50-80%, 1000 us fixed it -+ * completely. Flushing all writes was also tested but with no luck. -+ * The same problem was reported for WRT350N v1 (BCM4705), so we just -+ * sleep here unconditionally. -+ */ -+ usleep_range(1000, 2000); -+ - /* Enable PCI bridge BAR0 prefetch and burst */ - val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); ---- a/drivers/ssb/main.c -+++ b/drivers/ssb/main.c -@@ -90,25 +90,6 @@ found: - } - #endif /* CONFIG_SSB_PCMCIAHOST */ - --#ifdef CONFIG_SSB_SDIOHOST --struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func) --{ -- struct ssb_bus *bus; -- -- ssb_buses_lock(); -- list_for_each_entry(bus, &buses, list) { -- if (bus->bustype == SSB_BUSTYPE_SDIO && -- bus->host_sdio == func) -- goto found; -- } -- bus = NULL; --found: -- ssb_buses_unlock(); -- -- return bus; --} --#endif /* CONFIG_SSB_SDIOHOST */ -- - int ssb_for_each_bus_call(unsigned long data, - int (*func)(struct ssb_bus *bus, unsigned long data)) - { -@@ -1154,6 +1135,8 @@ static u32 ssb_tmslow_reject_bitmask(str - case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */ - case SSB_IDLOW_SSBREV_27: /* same here */ - return SSB_TMSLOW_REJECT; /* this is a guess */ -+ case SSB_IDLOW_SSBREV: -+ break; - default: - WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); - } diff --git a/target/linux/generic/pending-3.18/021-ssb_sprom.patch b/target/linux/generic/pending-3.18/021-ssb_sprom.patch deleted file mode 100644 index 52d8080dfe..0000000000 --- a/target/linux/generic/pending-3.18/021-ssb_sprom.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/include/linux/ssb/ssb.h -+++ b/include/linux/ssb/ssb.h -@@ -29,10 +29,13 @@ struct ssb_sprom { - u8 il0mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11b/g */ - u8 et0mac[6] __aligned(sizeof(u16)); /* MAC address for Ethernet */ - u8 et1mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11a */ -+ u8 et2mac[6] __aligned(sizeof(u16)); /* MAC address for extra Ethernet */ - u8 et0phyaddr; /* MII address for enet0 */ - u8 et1phyaddr; /* MII address for enet1 */ -+ u8 et2phyaddr; /* MII address for enet2 */ - u8 et0mdcport; /* MDIO for enet0 */ - u8 et1mdcport; /* MDIO for enet1 */ -+ u8 et2mdcport; /* MDIO for enet2 */ - u16 dev_id; /* Device ID overriding e.g. PCI ID */ - u16 board_rev; /* Board revision number from SPROM. */ - u16 board_num; /* Board number from SPROM. */ -@@ -88,11 +91,14 @@ struct ssb_sprom { - u32 ofdm5glpo; /* 5.2GHz OFDM power offset */ - u32 ofdm5gpo; /* 5.3GHz OFDM power offset */ - u32 ofdm5ghpo; /* 5.8GHz OFDM power offset */ -+ u32 boardflags; -+ u32 boardflags2; -+ u32 boardflags3; -+ /* TODO: Switch all drivers to new u32 fields and drop below ones */ - u16 boardflags_lo; /* Board flags (bits 0-15) */ - u16 boardflags_hi; /* Board flags (bits 16-31) */ - u16 boardflags2_lo; /* Board flags (bits 32-47) */ - u16 boardflags2_hi; /* Board flags (bits 48-63) */ -- /* TODO store board flags in a single u64 */ - - struct ssb_sprom_core_pwr_info core_pwr_info[4]; - diff --git a/target/linux/generic/pending-3.18/025-bcma_backport.patch b/target/linux/generic/pending-3.18/025-bcma_backport.patch deleted file mode 100644 index ec1cb004b7..0000000000 --- a/target/linux/generic/pending-3.18/025-bcma_backport.patch +++ /dev/null @@ -1,286 +0,0 @@ ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -22,6 +22,7 @@ struct bcma_bus; - /* main.c */ - bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, - int timeout); -+void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); - int bcma_bus_register(struct bcma_bus *bus); - void bcma_bus_unregister(struct bcma_bus *bus); - int __init bcma_bus_early_register(struct bcma_bus *bus, ---- a/drivers/bcma/driver_chipcommon.c -+++ b/drivers/bcma/driver_chipcommon.c -@@ -339,7 +339,7 @@ void bcma_chipco_serial_init(struct bcma - return; - } - -- irq = bcma_core_irq(cc->core); -+ irq = bcma_core_irq(cc->core, 0); - - /* Determine the registers of the UARTs */ - cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); ---- a/drivers/bcma/driver_gpio.c -+++ b/drivers/bcma/driver_gpio.c -@@ -152,7 +152,7 @@ static int bcma_gpio_irq_domain_init(str - handle_simple_irq); - } - -- hwirq = bcma_core_irq(cc->core); -+ hwirq = bcma_core_irq(cc->core, 0); - err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", - cc); - if (err) -@@ -183,7 +183,7 @@ static void bcma_gpio_irq_domain_exit(st - return; - - bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); -- free_irq(bcma_core_irq(cc->core), cc); -+ free_irq(bcma_core_irq(cc->core, 0), cc); - for (gpio = 0; gpio < chip->ngpio; gpio++) { - int irq = irq_find_mapping(cc->irq_domain, gpio); - ---- a/drivers/bcma/driver_mips.c -+++ b/drivers/bcma/driver_mips.c -@@ -115,7 +115,7 @@ static u32 bcma_core_mips_irqflag(struct - * If disabled, 5 is returned. - * If not supported, 6 is returned. - */ --static unsigned int bcma_core_mips_irq(struct bcma_device *dev) -+unsigned int bcma_core_mips_irq(struct bcma_device *dev) - { - struct bcma_device *mdev = dev->bus->drv_mips.core; - u32 irqflag; -@@ -133,13 +133,6 @@ static unsigned int bcma_core_mips_irq(s - return 5; - } - --unsigned int bcma_core_irq(struct bcma_device *dev) --{ -- unsigned int mips_irq = bcma_core_mips_irq(dev); -- return mips_irq <= 4 ? mips_irq + 2 : 0; --} --EXPORT_SYMBOL(bcma_core_irq); -- - static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) - { - unsigned int oldirq = bcma_core_mips_irq(dev); -@@ -423,7 +416,7 @@ void bcma_core_mips_init(struct bcma_drv - break; - default: - list_for_each_entry(core, &bus->cores, list) { -- core->irq = bcma_core_irq(core); -+ core->irq = bcma_core_irq(core, 0); - } - bcma_err(bus, - "Unknown device (0x%x) found, can not configure IRQs\n", ---- a/drivers/bcma/driver_pci_host.c -+++ b/drivers/bcma/driver_pci_host.c -@@ -593,7 +593,7 @@ int bcma_core_pci_plat_dev_init(struct p - pr_info("PCI: Fixing up device %s\n", pci_name(dev)); - - /* Fix up interrupt lines */ -- dev->irq = bcma_core_irq(pc_host->pdev->core); -+ dev->irq = bcma_core_irq(pc_host->pdev->core, 0); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - - readrq = pcie_get_readrq(dev); -@@ -617,6 +617,6 @@ int bcma_core_pci_pcibios_map_irq(const - - pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, - pci_ops); -- return bcma_core_irq(pc_host->pdev->core); -+ return bcma_core_irq(pc_host->pdev->core, 0); - } - EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -11,6 +11,7 @@ - #include <linux/bcma/bcma.h> - #include <linux/slab.h> - #include <linux/of_address.h> -+#include <linux/of_irq.h> - - MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); - MODULE_LICENSE("GPL"); -@@ -153,6 +154,46 @@ static struct device_node *bcma_of_find_ - return NULL; - } - -+static int bcma_of_irq_parse(struct platform_device *parent, -+ struct bcma_device *core, -+ struct of_phandle_args *out_irq, int num) -+{ -+ __be32 laddr[1]; -+ int rc; -+ -+ if (core->dev.of_node) { -+ rc = of_irq_parse_one(core->dev.of_node, num, out_irq); -+ if (!rc) -+ return rc; -+ } -+ -+ out_irq->np = parent->dev.of_node; -+ out_irq->args_count = 1; -+ out_irq->args[0] = num; -+ -+ laddr[0] = cpu_to_be32(core->addr); -+ return of_irq_parse_raw(laddr, out_irq); -+} -+ -+static unsigned int bcma_of_get_irq(struct platform_device *parent, -+ struct bcma_device *core, int num) -+{ -+ struct of_phandle_args out_irq; -+ int ret; -+ -+ if (!parent || !parent->dev.of_node) -+ return 0; -+ -+ ret = bcma_of_irq_parse(parent, core, &out_irq, num); -+ if (ret) { -+ bcma_debug(core->bus, "bcma_of_get_irq() failed with rc=%d\n", -+ ret); -+ return 0; -+ } -+ -+ return irq_create_of_mapping(&out_irq); -+} -+ - static void bcma_of_fill_device(struct platform_device *parent, - struct bcma_device *core) - { -@@ -161,18 +202,47 @@ static void bcma_of_fill_device(struct p - node = bcma_of_find_child_device(parent, core); - if (node) - core->dev.of_node = node; -+ -+ core->irq = bcma_of_get_irq(parent, core, 0); - } - #else - static void bcma_of_fill_device(struct platform_device *parent, - struct bcma_device *core) - { - } -+static inline unsigned int bcma_of_get_irq(struct platform_device *parent, -+ struct bcma_device *core, int num) -+{ -+ return 0; -+} - #endif /* CONFIG_OF */ - --static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) -+unsigned int bcma_core_irq(struct bcma_device *core, int num) - { -- int err; -+ struct bcma_bus *bus = core->bus; -+ unsigned int mips_irq; -+ -+ switch (bus->hosttype) { -+ case BCMA_HOSTTYPE_PCI: -+ return bus->host_pci->irq; -+ case BCMA_HOSTTYPE_SOC: -+ if (bus->drv_mips.core && num == 0) { -+ mips_irq = bcma_core_mips_irq(core); -+ return mips_irq <= 4 ? mips_irq + 2 : 0; -+ } -+ if (bus->host_pdev) -+ return bcma_of_get_irq(bus->host_pdev, core, num); -+ return 0; -+ case BCMA_HOSTTYPE_SDIO: -+ return 0; -+ } - -+ return 0; -+} -+EXPORT_SYMBOL(bcma_core_irq); -+ -+void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) -+{ - core->dev.release = bcma_release_core_dev; - core->dev.bus = &bcma_bus_type; - dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); -@@ -196,6 +266,11 @@ static void bcma_register_core(struct bc - case BCMA_HOSTTYPE_SDIO: - break; - } -+} -+ -+static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) -+{ -+ int err; - - err = device_register(&core->dev); - if (err) { ---- a/drivers/bcma/scan.c -+++ b/drivers/bcma/scan.c -@@ -505,6 +505,7 @@ int bcma_bus_scan(struct bcma_bus *bus) - bus->nr_cores++; - other_core = bcma_find_core_reverse(bus, core->id.id); - core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1; -+ bcma_prepare_core(bus, core); - - bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", - core->core_index, bcma_device_name(&core->id), ---- a/include/linux/bcma/bcma.h -+++ b/include/linux/bcma/bcma.h -@@ -448,4 +448,6 @@ extern u32 bcma_chipco_pll_read(struct b - #define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */ - extern u32 bcma_core_dma_translation(struct bcma_device *core); - -+extern unsigned int bcma_core_irq(struct bcma_device *core, int num); -+ - #endif /* LINUX_BCMA_H_ */ ---- a/include/linux/bcma/bcma_driver_mips.h -+++ b/include/linux/bcma/bcma_driver_mips.h -@@ -43,12 +43,12 @@ struct bcma_drv_mips { - extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); - extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); - --extern unsigned int bcma_core_irq(struct bcma_device *core); -+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); - #else - static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } - static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } - --static inline unsigned int bcma_core_irq(struct bcma_device *core) -+static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) - { - return 0; - } ---- a/Documentation/devicetree/bindings/bus/bcma.txt -+++ b/Documentation/devicetree/bindings/bus/bcma.txt -@@ -8,6 +8,11 @@ Required properties: - - The cores on the AXI bus are automatically detected by bcma with the - memory ranges they are using and they get registered afterwards. -+Automatic detection of the IRQ number is not working on -+BCM47xx/BCM53xx ARM SoCs. To assign IRQ numbers to the cores, provide -+them manually through device tree. Use an interrupt-map to specify the -+IRQ used by the devices on the bus. The first address is just an index, -+because we do not have any special register. - - The top-level axi bus may contain children representing attached cores - (devices). This is needed since some hardware details can't be auto -@@ -22,6 +27,22 @@ Example: - ranges = <0x00000000 0x18000000 0x00100000>; - #address-cells = <1>; - #size-cells = <1>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0x000fffff 0xffff>; -+ interrupt-map = -+ /* Ethernet Controller 0 */ -+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, -+ -+ /* Ethernet Controller 1 */ -+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; -+ -+ /* PCIe Controller 0 */ -+ <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, -+ <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>, -+ <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, -+ <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, -+ <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, -+ <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; - - chipcommon { - reg = <0x00000000 0x1000>; diff --git a/target/linux/generic/pending-3.18/026-bcma-from-3.20.patch b/target/linux/generic/pending-3.18/026-bcma-from-3.20.patch deleted file mode 100644 index 628b0bd389..0000000000 --- a/target/linux/generic/pending-3.18/026-bcma-from-3.20.patch +++ /dev/null @@ -1,527 +0,0 @@ ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -23,22 +23,18 @@ struct bcma_bus; - bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, - int timeout); - void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); -+void bcma_init_bus(struct bcma_bus *bus); - int bcma_bus_register(struct bcma_bus *bus); - void bcma_bus_unregister(struct bcma_bus *bus); --int __init bcma_bus_early_register(struct bcma_bus *bus, -- struct bcma_device *core_cc, -- struct bcma_device *core_mips); -+int __init bcma_bus_early_register(struct bcma_bus *bus); - #ifdef CONFIG_PM - int bcma_bus_suspend(struct bcma_bus *bus); - int bcma_bus_resume(struct bcma_bus *bus); - #endif - - /* scan.c */ -+void bcma_detect_chip(struct bcma_bus *bus); - int bcma_bus_scan(struct bcma_bus *bus); --int __init bcma_bus_scan_early(struct bcma_bus *bus, -- struct bcma_device_id *match, -- struct bcma_device *core); --void bcma_init_bus(struct bcma_bus *bus); - - /* sprom.c */ - int bcma_sprom_get(struct bcma_bus *bus); -@@ -109,6 +105,14 @@ extern int bcma_chipco_watchdog_register - #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE - bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc); - void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); -+#else -+static inline bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) -+{ -+ return false; -+} -+static inline void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) -+{ -+} - #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ - - #ifdef CONFIG_BCMA_DRIVER_GPIO ---- a/drivers/bcma/driver_chipcommon.c -+++ b/drivers/bcma/driver_chipcommon.c -@@ -79,7 +79,9 @@ static int bcma_chipco_watchdog_ticks_pe - - if (cc->capabilities & BCMA_CC_CAP_PMU) { - if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) -- /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */ -+ /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP -+ * clock -+ */ - return bcma_chipco_get_alp_clock(cc) / 4000; - else - /* based on 32KHz ILP clock */ -@@ -97,7 +99,8 @@ int bcma_chipco_watchdog_register(struct - wdt.driver_data = cc; - wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; - wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; -- wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; -+ wdt.max_timer_ms = -+ bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; - - pdev = platform_device_register_data(NULL, "bcm47xx-wdt", - cc->core->bus->num, &wdt, -@@ -175,7 +178,6 @@ void bcma_core_chipcommon_init(struct bc - u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) - { - u32 maxt; -- enum bcma_clkmode clkmode; - - maxt = bcma_chipco_watchdog_get_max_timer(cc); - if (cc->capabilities & BCMA_CC_CAP_PMU) { -@@ -185,8 +187,13 @@ u32 bcma_chipco_watchdog_timer_set(struc - ticks = maxt; - bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); - } else { -- clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC; -- bcma_core_set_clockmode(cc->core, clkmode); -+ struct bcma_bus *bus = cc->core->bus; -+ -+ if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && -+ bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) -+ bcma_core_set_clockmode(cc->core, -+ ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); -+ - if (ticks > maxt) - ticks = maxt; - /* instant NMI */ -@@ -335,7 +342,8 @@ void bcma_chipco_serial_init(struct bcma - | BCMA_CC_CORECTL_UARTCLKEN); - } - } else { -- bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); -+ bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", -+ ccrev); - return; - } - ---- a/drivers/bcma/driver_pci.c -+++ b/drivers/bcma/driver_pci.c -@@ -145,6 +145,47 @@ static u16 bcma_pcie_mdio_writeread(stru - } - - /************************************************** -+ * Early init. -+ **************************************************/ -+ -+static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc) -+{ -+ struct bcma_device *core = pc->core; -+ u16 val16, core_index; -+ uint regoff; -+ -+ regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET); -+ core_index = (u16)core->core_index; -+ -+ val16 = pcicore_read16(pc, regoff); -+ if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT) -+ != core_index) { -+ val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) | -+ (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK); -+ pcicore_write16(pc, regoff, val16); -+ } -+} -+ -+/* -+ * Apply some early fixes required before accessing SPROM. -+ * See also si_pci_fixcfg. -+ */ -+void bcma_core_pci_early_init(struct bcma_drv_pci *pc) -+{ -+ if (pc->early_setup_done) -+ return; -+ -+ pc->hostmode = bcma_core_pci_is_in_hostmode(pc); -+ if (pc->hostmode) -+ goto out; -+ -+ bcma_core_pci_fixcfg(pc); -+ -+out: -+ pc->early_setup_done = true; -+} -+ -+/************************************************** - * Workarounds. - **************************************************/ - -@@ -175,24 +216,6 @@ static void bcma_pcicore_serdes_workarou - tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); - } - --static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc) --{ -- struct bcma_device *core = pc->core; -- u16 val16, core_index; -- uint regoff; -- -- regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET); -- core_index = (u16)core->core_index; -- -- val16 = pcicore_read16(pc, regoff); -- if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT) -- != core_index) { -- val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) | -- (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK); -- pcicore_write16(pc, regoff, val16); -- } --} -- - /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ - /* Needs to happen when coming out of 'standby'/'hibernate' */ - static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) -@@ -216,7 +239,6 @@ static void bcma_core_pci_config_fixup(s - - static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) - { -- bcma_core_pci_fixcfg(pc); - bcma_pcicore_serdes_workaround(pc); - bcma_core_pci_config_fixup(pc); - } -@@ -226,13 +248,11 @@ void bcma_core_pci_init(struct bcma_drv_ - if (pc->setup_done) - return; - --#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE -- pc->hostmode = bcma_core_pci_is_in_hostmode(pc); -+ bcma_core_pci_early_init(pc); -+ - if (pc->hostmode) - bcma_core_pci_hostmode_init(pc); --#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ -- -- if (!pc->hostmode) -+ else - bcma_core_pci_clientmode_init(pc); - } - ---- a/drivers/bcma/host_pci.c -+++ b/drivers/bcma/host_pci.c -@@ -13,10 +13,12 @@ - - static void bcma_host_pci_switch_core(struct bcma_device *core) - { -+ int win2 = core->bus->host_is_pcie2 ? -+ BCMA_PCIE2_BAR0_WIN2 : BCMA_PCI_BAR0_WIN2; -+ - pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, - core->addr); -- pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2, -- core->wrap); -+ pci_write_config_dword(core->bus->host_pci, win2, core->wrap); - core->bus->mapped_core = core; - bcma_debug(core->bus, "Switched to core: 0x%X\n", core->id.id); - } ---- a/drivers/bcma/host_soc.c -+++ b/drivers/bcma/host_soc.c -@@ -193,7 +193,7 @@ int __init bcma_host_soc_init(struct bcm - int err; - - /* Scan bus and initialize it */ -- err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); -+ err = bcma_bus_early_register(bus); - if (err) - iounmap(bus->mmio); - ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -268,6 +268,18 @@ void bcma_prepare_core(struct bcma_bus * - } - } - -+void bcma_init_bus(struct bcma_bus *bus) -+{ -+ mutex_lock(&bcma_buses_mutex); -+ bus->num = bcma_bus_next_num++; -+ mutex_unlock(&bcma_buses_mutex); -+ -+ INIT_LIST_HEAD(&bus->cores); -+ bus->nr_cores = 0; -+ -+ bcma_detect_chip(bus); -+} -+ - static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) - { - int err; -@@ -356,12 +368,19 @@ static void bcma_unregister_cores(struct - struct bcma_device *core, *tmp; - - list_for_each_entry_safe(core, tmp, &bus->cores, list) { -+ if (!core->dev_registered) -+ continue; - list_del(&core->list); -- if (core->dev_registered) -- device_unregister(&core->dev); -+ device_unregister(&core->dev); - } - if (bus->hosttype == BCMA_HOSTTYPE_SOC) - platform_device_unregister(bus->drv_cc.watchdog); -+ -+ /* Now noone uses internally-handled cores, we can free them */ -+ list_for_each_entry_safe(core, tmp, &bus->cores, list) { -+ list_del(&core->list); -+ kfree(core); -+ } - } - - int bcma_bus_register(struct bcma_bus *bus) -@@ -369,10 +388,6 @@ int bcma_bus_register(struct bcma_bus *b - int err; - struct bcma_device *core; - -- mutex_lock(&bcma_buses_mutex); -- bus->num = bcma_bus_next_num++; -- mutex_unlock(&bcma_buses_mutex); -- - /* Scan for devices (cores) */ - err = bcma_bus_scan(bus); - if (err) { -@@ -387,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *b - bcma_core_chipcommon_early_init(&bus->drv_cc); - } - -+ /* Early init PCIE core */ -+ core = bcma_find_core(bus, BCMA_CORE_PCIE); -+ if (core) { -+ bus->drv_pci[0].core = core; -+ bcma_core_pci_early_init(&bus->drv_pci[0]); -+ } -+ - /* Cores providing flash access go before SPROM init */ - list_for_each_entry(core, &bus->cores, list) { - if (bcma_is_core_needed_early(core->id.id)) -@@ -459,7 +481,6 @@ int bcma_bus_register(struct bcma_bus *b - - void bcma_bus_unregister(struct bcma_bus *bus) - { -- struct bcma_device *cores[3]; - int err; - - err = bcma_gpio_unregister(&bus->drv_cc); -@@ -470,46 +491,23 @@ void bcma_bus_unregister(struct bcma_bus - - bcma_core_chipcommon_b_free(&bus->drv_cc_b); - -- cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); -- cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); -- cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); -- - bcma_unregister_cores(bus); -- -- kfree(cores[2]); -- kfree(cores[1]); -- kfree(cores[0]); - } - --int __init bcma_bus_early_register(struct bcma_bus *bus, -- struct bcma_device *core_cc, -- struct bcma_device *core_mips) -+/* -+ * This is a special version of bus registration function designed for SoCs. -+ * It scans bus and performs basic initialization of main cores only. -+ * Please note it requires memory allocation, however it won't try to sleep. -+ */ -+int __init bcma_bus_early_register(struct bcma_bus *bus) - { - int err; - struct bcma_device *core; -- struct bcma_device_id match; -- -- match.manuf = BCMA_MANUF_BCM; -- match.id = bcma_cc_core_id(bus); -- match.class = BCMA_CL_SIM; -- match.rev = BCMA_ANY_REV; - -- /* Scan for chip common core */ -- err = bcma_bus_scan_early(bus, &match, core_cc); -- if (err) { -- bcma_err(bus, "Failed to scan for common core: %d\n", err); -- return -1; -- } -- -- match.manuf = BCMA_MANUF_MIPS; -- match.id = BCMA_CORE_MIPS_74K; -- match.class = BCMA_CL_SIM; -- match.rev = BCMA_ANY_REV; -- -- /* Scan for mips core */ -- err = bcma_bus_scan_early(bus, &match, core_mips); -+ /* Scan for devices (cores) */ -+ err = bcma_bus_scan(bus); - if (err) { -- bcma_err(bus, "Failed to scan for mips core: %d\n", err); -+ bcma_err(bus, "Failed to scan bus: %d\n", err); - return -1; - } - ---- a/drivers/bcma/scan.c -+++ b/drivers/bcma/scan.c -@@ -435,15 +435,12 @@ static int bcma_get_next_core(struct bcm - return 0; - } - --void bcma_init_bus(struct bcma_bus *bus) -+void bcma_detect_chip(struct bcma_bus *bus) - { - s32 tmp; - struct bcma_chipinfo *chipinfo = &(bus->chipinfo); - char chip_id[8]; - -- INIT_LIST_HEAD(&bus->cores); -- bus->nr_cores = 0; -- - bcma_scan_switch_core(bus, BCMA_ADDR_BASE); - - tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); -@@ -464,6 +461,10 @@ int bcma_bus_scan(struct bcma_bus *bus) - - int err, core_num = 0; - -+ /* Skip if bus was already scanned (e.g. during early register) */ -+ if (bus->nr_cores) -+ return 0; -+ - erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); - if (bus->hosttype == BCMA_HOSTTYPE_SOC) { - eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); -@@ -519,64 +520,6 @@ int bcma_bus_scan(struct bcma_bus *bus) - out: - if (bus->hosttype == BCMA_HOSTTYPE_SOC) - iounmap(eromptr); -- -- return err; --} -- --int __init bcma_bus_scan_early(struct bcma_bus *bus, -- struct bcma_device_id *match, -- struct bcma_device *core) --{ -- u32 erombase; -- u32 __iomem *eromptr, *eromend; -- -- int err = -ENODEV; -- int core_num = 0; -- -- erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); -- if (bus->hosttype == BCMA_HOSTTYPE_SOC) { -- eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); -- if (!eromptr) -- return -ENOMEM; -- } else { -- eromptr = bus->mmio; -- } -- -- eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32); -- -- bcma_scan_switch_core(bus, erombase); -- -- while (eromptr < eromend) { -- memset(core, 0, sizeof(*core)); -- INIT_LIST_HEAD(&core->list); -- core->bus = bus; -- -- err = bcma_get_next_core(bus, &eromptr, match, core_num, core); -- if (err == -ENODEV) { -- core_num++; -- continue; -- } else if (err == -ENXIO) -- continue; -- else if (err == -ESPIPE) -- break; -- else if (err < 0) -- goto out; -- -- core->core_index = core_num++; -- bus->nr_cores++; -- bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", -- core->core_index, bcma_device_name(&core->id), -- core->id.manuf, core->id.id, core->id.rev, -- core->id.class); -- -- list_add_tail(&core->list, &bus->cores); -- err = 0; -- break; -- } -- --out: -- if (bus->hosttype == BCMA_HOSTTYPE_SOC) -- iounmap(eromptr); - - return err; - } ---- a/drivers/bcma/sprom.c -+++ b/drivers/bcma/sprom.c -@@ -579,7 +579,8 @@ int bcma_sprom_get(struct bcma_bus *bus) - u16 offset = BCMA_CC_SPROM; - u16 *sprom; - size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, -- SSB_SPROMSIZE_WORDS_R10, }; -+ SSB_SPROMSIZE_WORDS_R10, -+ SSB_SPROMSIZE_WORDS_R11, }; - int i, err = 0; - - if (!bus->drv_cc.core) ---- a/include/linux/bcma/bcma.h -+++ b/include/linux/bcma/bcma.h -@@ -319,6 +319,7 @@ struct bcma_bus { - const struct bcma_host_ops *ops; - - enum bcma_hosttype hosttype; -+ bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */ - union { - /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */ - struct pci_dev *host_pci; ---- a/include/linux/bcma/bcma_driver_pci.h -+++ b/include/linux/bcma/bcma_driver_pci.h -@@ -223,6 +223,7 @@ struct bcma_drv_pci_host { - - struct bcma_drv_pci { - struct bcma_device *core; -+ u8 early_setup_done:1; - u8 setup_done:1; - u8 hostmode:1; - -@@ -237,6 +238,7 @@ struct bcma_drv_pci { - #define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) - #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) - -+extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); - extern void bcma_core_pci_init(struct bcma_drv_pci *pc); - extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, - struct bcma_device *core, bool enable); ---- a/include/linux/bcma/bcma_regs.h -+++ b/include/linux/bcma/bcma_regs.h -@@ -64,6 +64,8 @@ - #define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ - #define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ - -+#define BCMA_PCIE2_BAR0_WIN2 0x70 -+ - /* SiliconBackplane Address Map. - * All regions may not exist on all chips. - */ ---- a/include/linux/bcma/bcma_soc.h -+++ b/include/linux/bcma/bcma_soc.h -@@ -5,8 +5,6 @@ - - struct bcma_soc { - struct bcma_bus bus; -- struct bcma_device core_cc; -- struct bcma_device core_mips; - }; - - int __init bcma_host_soc_register(struct bcma_soc *soc); ---- a/include/linux/ssb/ssb_regs.h -+++ b/include/linux/ssb/ssb_regs.h -@@ -173,6 +173,7 @@ - #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) - #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) - #define SSB_SPROMSIZE_WORDS_R10 230 -+#define SSB_SPROMSIZE_WORDS_R11 234 - #define SSB_SPROM_BASE1 0x1000 - #define SSB_SPROM_BASE31 0x0800 - #define SSB_SPROM_REVISION 0x007E diff --git a/target/linux/generic/pending-3.18/027-bcma-from-4.1.patch b/target/linux/generic/pending-3.18/027-bcma-from-4.1.patch deleted file mode 100644 index c88a816fef..0000000000 --- a/target/linux/generic/pending-3.18/027-bcma-from-4.1.patch +++ /dev/null @@ -1,680 +0,0 @@ ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -24,6 +24,7 @@ bool bcma_wait_value(struct bcma_device - int timeout); - void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); - void bcma_init_bus(struct bcma_bus *bus); -+void bcma_unregister_cores(struct bcma_bus *bus); - int bcma_bus_register(struct bcma_bus *bus); - void bcma_bus_unregister(struct bcma_bus *bus); - int __init bcma_bus_early_register(struct bcma_bus *bus); -@@ -40,6 +41,9 @@ int bcma_bus_scan(struct bcma_bus *bus); - int bcma_sprom_get(struct bcma_bus *bus); - - /* driver_chipcommon.c */ -+void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); -+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); -+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); - #ifdef CONFIG_BCMA_DRIVER_MIPS - void bcma_chipco_serial_init(struct bcma_drv_cc *cc); - extern struct platform_device bcma_pflash_dev; -@@ -50,6 +54,8 @@ int bcma_core_chipcommon_b_init(struct b - void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb); - - /* driver_chipcommon_pmu.c */ -+void bcma_pmu_early_init(struct bcma_drv_cc *cc); -+void bcma_pmu_init(struct bcma_drv_cc *cc); - u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); - u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); - -@@ -98,7 +104,35 @@ static inline void __exit bcma_host_soc_ - #endif /* CONFIG_BCMA_HOST_SOC && CONFIG_OF */ - - /* driver_pci.c */ -+#ifdef CONFIG_BCMA_DRIVER_PCI - u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); -+void bcma_core_pci_early_init(struct bcma_drv_pci *pc); -+void bcma_core_pci_init(struct bcma_drv_pci *pc); -+void bcma_core_pci_up(struct bcma_drv_pci *pc); -+void bcma_core_pci_down(struct bcma_drv_pci *pc); -+#else -+static inline void bcma_core_pci_early_init(struct bcma_drv_pci *pc) -+{ -+ WARN_ON(pc->core->bus->hosttype == BCMA_HOSTTYPE_PCI); -+} -+static inline void bcma_core_pci_init(struct bcma_drv_pci *pc) -+{ -+ /* Initialization is required for PCI hosted bus */ -+ WARN_ON(pc->core->bus->hosttype == BCMA_HOSTTYPE_PCI); -+} -+#endif -+ -+/* driver_pcie2.c */ -+#ifdef CONFIG_BCMA_DRIVER_PCI -+void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2); -+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2); -+#else -+static inline void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) -+{ -+ /* Initialization is required for PCI hosted bus */ -+ WARN_ON(pcie2->core->bus->hosttype == BCMA_HOSTTYPE_PCI); -+} -+#endif - - extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc); - -@@ -115,6 +149,39 @@ static inline void bcma_core_pci_hostmod - } - #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ - -+/************************************************** -+ * driver_mips.c -+ **************************************************/ -+ -+#ifdef CONFIG_BCMA_DRIVER_MIPS -+unsigned int bcma_core_mips_irq(struct bcma_device *dev); -+void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); -+void bcma_core_mips_init(struct bcma_drv_mips *mcore); -+#else -+static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) -+{ -+ return 0; -+} -+static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) -+{ -+} -+static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) -+{ -+} -+#endif -+ -+/************************************************** -+ * driver_gmac_cmn.c -+ **************************************************/ -+ -+#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN -+void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc); -+#else -+static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) -+{ -+} -+#endif -+ - #ifdef CONFIG_BCMA_DRIVER_GPIO - /* driver_gpio.c */ - int bcma_gpio_init(struct bcma_drv_cc *cc); ---- a/drivers/bcma/driver_gpio.c -+++ b/drivers/bcma/driver_gpio.c -@@ -17,6 +17,8 @@ - - #include "bcma_private.h" - -+#define BCMA_GPIO_MAX_PINS 32 -+ - static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip) - { - return container_of(chip, struct bcma_drv_cc, gpio); -@@ -76,7 +78,7 @@ static void bcma_gpio_free(struct gpio_c - bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); - } - --#if IS_BUILTIN(CONFIG_BCM47XX) -+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) - static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) - { - struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); -@@ -204,6 +206,7 @@ static void bcma_gpio_irq_domain_exit(st - - int bcma_gpio_init(struct bcma_drv_cc *cc) - { -+ struct bcma_bus *bus = cc->core->bus; - struct gpio_chip *chip = &cc->gpio; - int err; - -@@ -215,14 +218,14 @@ int bcma_gpio_init(struct bcma_drv_cc *c - chip->set = bcma_gpio_set_value; - chip->direction_input = bcma_gpio_direction_input; - chip->direction_output = bcma_gpio_direction_output; --#if IS_BUILTIN(CONFIG_BCM47XX) -+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) - chip->to_irq = bcma_gpio_to_irq; - #endif - #if IS_BUILTIN(CONFIG_OF) - if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) - chip->of_node = cc->core->dev.of_node; - #endif -- switch (cc->core->bus->chipinfo.id) { -+ switch (bus->chipinfo.id) { - case BCMA_CHIP_ID_BCM5357: - case BCMA_CHIP_ID_BCM53572: - chip->ngpio = 32; -@@ -231,13 +234,17 @@ int bcma_gpio_init(struct bcma_drv_cc *c - chip->ngpio = 16; - } - -- /* There is just one SoC in one device and its GPIO addresses should be -- * deterministic to address them more easily. The other buses could get -- * a random base number. */ -- if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) -- chip->base = 0; -- else -- chip->base = -1; -+ /* -+ * On MIPS we register GPIO devices (LEDs, buttons) using absolute GPIO -+ * pin numbers. We don't have Device Tree there and we can't really use -+ * relative (per chip) numbers. -+ * So let's use predictable base for BCM47XX and "random" for all other. -+ */ -+#if IS_BUILTIN(CONFIG_BCM47XX) -+ chip->base = bus->num * BCMA_GPIO_MAX_PINS; -+#else -+ chip->base = -1; -+#endif - - err = bcma_gpio_irq_domain_init(cc); - if (err) ---- a/drivers/bcma/driver_pci.c -+++ b/drivers/bcma/driver_pci.c -@@ -282,39 +282,6 @@ void bcma_core_pci_power_save(struct bcm - } - EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); - --int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, -- bool enable) --{ -- struct pci_dev *pdev; -- u32 coremask, tmp; -- int err = 0; -- -- if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { -- /* This bcma device is not on a PCI host-bus. So the IRQs are -- * not routed through the PCI core. -- * So we must not enable routing through the PCI core. */ -- goto out; -- } -- -- pdev = pc->core->bus->host_pci; -- -- err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); -- if (err) -- goto out; -- -- coremask = BIT(core->core_index) << 8; -- if (enable) -- tmp |= coremask; -- else -- tmp &= ~coremask; -- -- err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp); -- --out: -- return err; --} --EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl); -- - static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend) - { - u32 w; -@@ -328,28 +295,12 @@ static void bcma_core_pci_extend_L1timer - bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); - } - --void bcma_core_pci_up(struct bcma_bus *bus) -+void bcma_core_pci_up(struct bcma_drv_pci *pc) - { -- struct bcma_drv_pci *pc; -- -- if (bus->hosttype != BCMA_HOSTTYPE_PCI) -- return; -- -- pc = &bus->drv_pci[0]; -- - bcma_core_pci_extend_L1timer(pc, true); - } --EXPORT_SYMBOL_GPL(bcma_core_pci_up); - --void bcma_core_pci_down(struct bcma_bus *bus) -+void bcma_core_pci_down(struct bcma_drv_pci *pc) - { -- struct bcma_drv_pci *pc; -- -- if (bus->hosttype != BCMA_HOSTTYPE_PCI) -- return; -- -- pc = &bus->drv_pci[0]; -- - bcma_core_pci_extend_L1timer(pc, false); - } --EXPORT_SYMBOL_GPL(bcma_core_pci_down); ---- a/drivers/bcma/driver_pci_host.c -+++ b/drivers/bcma/driver_pci_host.c -@@ -11,6 +11,7 @@ - - #include "bcma_private.h" - #include <linux/pci.h> -+#include <linux/slab.h> - #include <linux/export.h> - #include <linux/bcma/bcma.h> - #include <asm/paccess.h> ---- a/drivers/bcma/driver_pcie2.c -+++ b/drivers/bcma/driver_pcie2.c -@@ -10,6 +10,7 @@ - - #include "bcma_private.h" - #include <linux/bcma/bcma.h> -+#include <linux/pci.h> - - /************************************************** - * R/W ops. -@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(st - - void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) - { -- struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; -+ struct bcma_bus *bus = pcie2->core->bus; -+ struct bcma_chipinfo *ci = &bus->chipinfo; - u32 tmp; - - tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); - if ((tmp & 0xe) >> 1 == 2) - bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); - -- /* TODO: Do we need pcie_reqsize? */ -+ switch (bus->chipinfo.id) { -+ case BCMA_CHIP_ID_BCM4360: -+ case BCMA_CHIP_ID_BCM4352: -+ pcie2->reqsize = 1024; -+ break; -+ default: -+ pcie2->reqsize = 128; -+ break; -+ } - - if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) - bcma_core_pcie2_war_delay_perst_enab(pcie2, true); -@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_dr - pciedev_crwlpciegen2_180(pcie2); - pciedev_crwlpciegen2_182(pcie2); - } -+ -+/************************************************** -+ * Runtime ops. -+ **************************************************/ -+ -+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2) -+{ -+ struct bcma_bus *bus = pcie2->core->bus; -+ struct pci_dev *dev = bus->host_pci; -+ int err; -+ -+ err = pcie_set_readrq(dev, pcie2->reqsize); -+ if (err) -+ bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err); -+} ---- a/drivers/bcma/host_pci.c -+++ b/drivers/bcma/host_pci.c -@@ -213,16 +213,26 @@ static int bcma_host_pci_probe(struct pc - /* Initialize struct, detect chip */ - bcma_init_bus(bus); - -+ /* Scan bus to find out generation of PCIe core */ -+ err = bcma_bus_scan(bus); -+ if (err) -+ goto err_pci_unmap_mmio; -+ -+ if (bcma_find_core(bus, BCMA_CORE_PCIE2)) -+ bus->host_is_pcie2 = true; -+ - /* Register */ - err = bcma_bus_register(bus); - if (err) -- goto err_pci_unmap_mmio; -+ goto err_unregister_cores; - - pci_set_drvdata(dev, bus); - - out: - return err; - -+err_unregister_cores: -+ bcma_unregister_cores(bus); - err_pci_unmap_mmio: - pci_iounmap(dev, bus->mmio); - err_pci_release_regions: -@@ -283,9 +293,12 @@ static const struct pci_device_id bcma_p - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ -@@ -310,3 +323,65 @@ void __exit bcma_host_pci_exit(void) - { - pci_unregister_driver(&bcma_pci_bridge_driver); - } -+ -+/************************************************** -+ * Runtime ops for drivers. -+ **************************************************/ -+ -+/* See also pcicore_up */ -+void bcma_host_pci_up(struct bcma_bus *bus) -+{ -+ if (bus->hosttype != BCMA_HOSTTYPE_PCI) -+ return; -+ -+ if (bus->host_is_pcie2) -+ bcma_core_pcie2_up(&bus->drv_pcie2); -+ else -+ bcma_core_pci_up(&bus->drv_pci[0]); -+} -+EXPORT_SYMBOL_GPL(bcma_host_pci_up); -+ -+/* See also pcicore_down */ -+void bcma_host_pci_down(struct bcma_bus *bus) -+{ -+ if (bus->hosttype != BCMA_HOSTTYPE_PCI) -+ return; -+ -+ if (!bus->host_is_pcie2) -+ bcma_core_pci_down(&bus->drv_pci[0]); -+} -+EXPORT_SYMBOL_GPL(bcma_host_pci_down); -+ -+/* See also si_pci_setup */ -+int bcma_host_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core, -+ bool enable) -+{ -+ struct pci_dev *pdev; -+ u32 coremask, tmp; -+ int err = 0; -+ -+ if (bus->hosttype != BCMA_HOSTTYPE_PCI) { -+ /* This bcma device is not on a PCI host-bus. So the IRQs are -+ * not routed through the PCI core. -+ * So we must not enable routing through the PCI core. */ -+ goto out; -+ } -+ -+ pdev = bus->host_pci; -+ -+ err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); -+ if (err) -+ goto out; -+ -+ coremask = BIT(core->core_index) << 8; -+ if (enable) -+ tmp |= coremask; -+ else -+ tmp &= ~coremask; -+ -+ err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp); -+ -+out: -+ return err; -+} -+EXPORT_SYMBOL_GPL(bcma_host_pci_irq_ctl); ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -363,7 +363,7 @@ static int bcma_register_devices(struct - return 0; - } - --static void bcma_unregister_cores(struct bcma_bus *bus) -+void bcma_unregister_cores(struct bcma_bus *bus) - { - struct bcma_device *core, *tmp; - ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -4770,7 +4770,7 @@ static void b43_wireless_core_exit(struc - switch (dev->dev->bus_type) { - #ifdef CONFIG_B43_BCMA - case B43_BUS_BCMA: -- bcma_core_pci_down(dev->dev->bdev->bus); -+ bcma_host_pci_down(dev->dev->bdev->bus); - break; - #endif - #ifdef CONFIG_B43_SSB -@@ -4817,9 +4817,9 @@ static int b43_wireless_core_init(struct - switch (dev->dev->bus_type) { - #ifdef CONFIG_B43_BCMA - case B43_BUS_BCMA: -- bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], -+ bcma_host_pci_irq_ctl(dev->dev->bdev->bus, - dev->dev->bdev, true); -- bcma_core_pci_up(dev->dev->bdev->bus); -+ bcma_host_pci_up(dev->dev->bdev->bus); - break; - #endif - #ifdef CONFIG_B43_SSB ---- a/drivers/net/wireless/brcm80211/brcmsmac/main.c -+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c -@@ -4669,7 +4669,7 @@ static int brcms_b_attach(struct brcms_c - brcms_c_coredisable(wlc_hw); - - /* Match driver "down" state */ -- bcma_core_pci_down(wlc_hw->d11core->bus); -+ bcma_host_pci_down(wlc_hw->d11core->bus); - - /* turn off pll and xtal to match driver "down" state */ - brcms_b_xtal(wlc_hw, OFF); -@@ -4960,7 +4960,7 @@ static int brcms_b_up_prep(struct brcms_ - * Configure pci/pcmcia here instead of in brcms_c_attach() - * to allow mfg hotswap: down, hotswap (chip power cycle), up. - */ -- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, -+ bcma_host_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core, - true); - - /* -@@ -4970,12 +4970,12 @@ static int brcms_b_up_prep(struct brcms_ - */ - if (brcms_b_radio_read_hwdisabled(wlc_hw)) { - /* put SB PCI in down state again */ -- bcma_core_pci_down(wlc_hw->d11core->bus); -+ bcma_host_pci_down(wlc_hw->d11core->bus); - brcms_b_xtal(wlc_hw, OFF); - return -ENOMEDIUM; - } - -- bcma_core_pci_up(wlc_hw->d11core->bus); -+ bcma_host_pci_up(wlc_hw->d11core->bus); - - /* reset the d11 core */ - brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); -@@ -5172,7 +5172,7 @@ static int brcms_b_down_finish(struct br - - /* turn off primary xtal and pll */ - if (!wlc_hw->noreset) { -- bcma_core_pci_down(wlc_hw->d11core->bus); -+ bcma_host_pci_down(wlc_hw->d11core->bus); - brcms_b_xtal(wlc_hw, OFF); - } - } ---- a/include/linux/bcma/bcma.h -+++ b/include/linux/bcma/bcma.h -@@ -435,6 +435,27 @@ static inline struct bcma_device *bcma_f - return bcma_find_core_unit(bus, coreid, 0); - } - -+#ifdef CONFIG_BCMA_HOST_PCI -+extern void bcma_host_pci_up(struct bcma_bus *bus); -+extern void bcma_host_pci_down(struct bcma_bus *bus); -+extern int bcma_host_pci_irq_ctl(struct bcma_bus *bus, -+ struct bcma_device *core, bool enable); -+#else -+static inline void bcma_host_pci_up(struct bcma_bus *bus) -+{ -+} -+static inline void bcma_host_pci_down(struct bcma_bus *bus) -+{ -+} -+static inline int bcma_host_pci_irq_ctl(struct bcma_bus *bus, -+ struct bcma_device *core, bool enable) -+{ -+ if (bus->hosttype == BCMA_HOSTTYPE_PCI) -+ return -ENOTSUPP; -+ return 0; -+} -+#endif -+ - extern bool bcma_core_is_enabled(struct bcma_device *core); - extern void bcma_core_disable(struct bcma_device *core, u32 flags); - extern int bcma_core_enable(struct bcma_device *core, u32 flags); ---- a/include/linux/bcma/bcma_driver_pci.h -+++ b/include/linux/bcma/bcma_driver_pci.h -@@ -238,13 +238,13 @@ struct bcma_drv_pci { - #define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) - #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) - --extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); --extern void bcma_core_pci_init(struct bcma_drv_pci *pc); --extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, -- struct bcma_device *core, bool enable); --extern void bcma_core_pci_up(struct bcma_bus *bus); --extern void bcma_core_pci_down(struct bcma_bus *bus); -+#ifdef CONFIG_BCMA_DRIVER_PCI - extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); -+#else -+static inline void bcma_core_pci_power_save(struct bcma_bus *bus, bool up) -+{ -+} -+#endif - - extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); - extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); ---- a/include/linux/bcma/bcma_driver_pcie2.h -+++ b/include/linux/bcma/bcma_driver_pcie2.h -@@ -143,6 +143,8 @@ - - struct bcma_drv_pcie2 { - struct bcma_device *core; -+ -+ u16 reqsize; - }; - - #define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset) -@@ -153,6 +155,4 @@ struct bcma_drv_pcie2 { - #define pcie2_set32(pcie2, offset, set) bcma_set32((pcie2)->core, offset, set) - #define pcie2_mask32(pcie2, offset, mask) bcma_mask32((pcie2)->core, offset, mask) - --void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2); -- - #endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */ ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -26,6 +26,7 @@ config BCMA_HOST_PCI_POSSIBLE - config BCMA_HOST_PCI - bool "Support for BCMA on PCI-host bus" - depends on BCMA_HOST_PCI_POSSIBLE -+ select BCMA_DRIVER_PCI - default y - - config BCMA_DRIVER_PCI_HOSTMODE -@@ -44,6 +45,22 @@ config BCMA_HOST_SOC - - If unsure, say N - -+config BCMA_DRIVER_PCI -+ bool "BCMA Broadcom PCI core driver" -+ depends on BCMA && PCI -+ default y -+ help -+ BCMA bus may have many versions of PCIe core. This driver -+ supports: -+ 1) PCIe core working in clientmode -+ 2) PCIe Gen 2 clientmode core -+ -+ In general PCIe (Gen 2) clientmode core is required on PCIe -+ hosted buses. It's responsible for initialization and basic -+ hardware management. -+ This driver is also prerequisite for a hostmode PCIe core -+ support. -+ - config BCMA_DRIVER_MIPS - bool "BCMA Broadcom MIPS core driver" - depends on BCMA && MIPS ---- a/drivers/bcma/Makefile -+++ b/drivers/bcma/Makefile -@@ -3,8 +3,8 @@ bcma-y += driver_chipcommon.o driver - bcma-y += driver_chipcommon_b.o - bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o - bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o --bcma-y += driver_pci.o --bcma-y += driver_pcie2.o -+bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o -+bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pcie2.o - bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o - bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o - bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o ---- a/include/linux/bcma/bcma_driver_chipcommon.h -+++ b/include/linux/bcma/bcma_driver_chipcommon.h -@@ -663,14 +663,6 @@ struct bcma_drv_cc_b { - #define bcma_cc_maskset32(cc, offset, mask, set) \ - bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) - --extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); --extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); -- --extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); --extern void bcma_chipco_resume(struct bcma_drv_cc *cc); -- --void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); -- - extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); - - extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc); -@@ -690,9 +682,6 @@ u32 bcma_chipco_gpio_pullup(struct bcma_ - u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value); - - /* PMU support */ --extern void bcma_pmu_init(struct bcma_drv_cc *cc); --extern void bcma_pmu_early_init(struct bcma_drv_cc *cc); -- - extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, - u32 value); - extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, ---- a/include/linux/bcma/bcma_driver_gmac_cmn.h -+++ b/include/linux/bcma/bcma_driver_gmac_cmn.h -@@ -91,10 +91,4 @@ struct bcma_drv_gmac_cmn { - #define gmac_cmn_write16(gc, offset, val) bcma_write16((gc)->core, offset, val) - #define gmac_cmn_write32(gc, offset, val) bcma_write32((gc)->core, offset, val) - --#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN --extern void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc); --#else --static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) { } --#endif -- - #endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */ ---- a/include/linux/bcma/bcma_driver_mips.h -+++ b/include/linux/bcma/bcma_driver_mips.h -@@ -39,21 +39,6 @@ struct bcma_drv_mips { - u8 early_setup_done:1; - }; - --#ifdef CONFIG_BCMA_DRIVER_MIPS --extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); --extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); -- --extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); --#else --static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } --static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } -- --static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) --{ -- return 0; --} --#endif -- - extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); - - #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ diff --git a/target/linux/generic/pending-3.18/028-bcma-from-4.2.patch b/target/linux/generic/pending-3.18/028-bcma-from-4.2.patch deleted file mode 100644 index ba3df18bdd..0000000000 --- a/target/linux/generic/pending-3.18/028-bcma-from-4.2.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- a/drivers/bcma/driver_gpio.c -+++ b/drivers/bcma/driver_gpio.c -@@ -226,6 +226,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c - chip->of_node = cc->core->dev.of_node; - #endif - switch (bus->chipinfo.id) { -+ case BCMA_CHIP_ID_BCM4707: - case BCMA_CHIP_ID_BCM5357: - case BCMA_CHIP_ID_BCM53572: - chip->ngpio = 32; -@@ -235,16 +236,17 @@ int bcma_gpio_init(struct bcma_drv_cc *c - } - - /* -- * On MIPS we register GPIO devices (LEDs, buttons) using absolute GPIO -- * pin numbers. We don't have Device Tree there and we can't really use -- * relative (per chip) numbers. -- * So let's use predictable base for BCM47XX and "random" for all other. -+ * Register SoC GPIO devices with absolute GPIO pin base. -+ * On MIPS, we don't have Device Tree and we can't use relative (per chip) -+ * GPIO numbers. -+ * On some ARM devices, user space may want to access some system GPIO -+ * pins directly, which is easier to do with a predictable GPIO base. - */ --#if IS_BUILTIN(CONFIG_BCM47XX) -- chip->base = bus->num * BCMA_GPIO_MAX_PINS; --#else -- chip->base = -1; --#endif -+ if (IS_BUILTIN(CONFIG_BCM47XX) || -+ cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) -+ chip->base = bus->num * BCMA_GPIO_MAX_PINS; -+ else -+ chip->base = -1; - - err = bcma_gpio_irq_domain_init(cc); - if (err) ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -29,12 +29,6 @@ config BCMA_HOST_PCI - select BCMA_DRIVER_PCI - default y - --config BCMA_DRIVER_PCI_HOSTMODE -- bool "Driver for PCI core working in hostmode" -- depends on BCMA && MIPS && BCMA_HOST_PCI -- help -- PCI core hostmode operation (external PCI bus). -- - config BCMA_HOST_SOC - bool "Support for BCMA in a SoC" - depends on BCMA -@@ -61,6 +55,12 @@ config BCMA_DRIVER_PCI - This driver is also prerequisite for a hostmode PCIe core - support. - -+config BCMA_DRIVER_PCI_HOSTMODE -+ bool "Driver for PCI core working in hostmode" -+ depends on BCMA && MIPS && BCMA_DRIVER_PCI -+ help -+ PCI core hostmode operation (external PCI bus). -+ - config BCMA_DRIVER_MIPS - bool "BCMA Broadcom MIPS core driver" - depends on BCMA && MIPS ---- a/include/linux/bcma/bcma_driver_pci.h -+++ b/include/linux/bcma/bcma_driver_pci.h -@@ -246,7 +246,18 @@ static inline void bcma_core_pci_power_s - } - #endif - -+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE - extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); - extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); -+#else -+static inline int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) -+{ -+ return -ENOTSUPP; -+} -+static inline int bcma_core_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ return -ENOTSUPP; -+} -+#endif - - #endif /* LINUX_BCMA_DRIVER_PCI_H_ */ diff --git a/target/linux/generic/pending-3.18/029-bcma-from-4.4.patch b/target/linux/generic/pending-3.18/029-bcma-from-4.4.patch deleted file mode 100644 index 5704081ee4..0000000000 --- a/target/linux/generic/pending-3.18/029-bcma-from-4.4.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 55acca90da52b85299c033354e51ddaa7b73e019 -Author: Hante Meuleman <meuleman@broadcom.com> -Date: Fri Sep 18 22:08:17 2015 +0200 - - brcmfmac: Add support for the BCM4365 and BCM4366 PCIE devices. - - This patch adds support for the BCM4365 and BCM4366 11ac Wave2 - PCIE devices. - - Reviewed-by: Arend Van Spriel <arend@broadcom.com> - Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> - Signed-off-by: Hante Meuleman <meuleman@broadcom.com> - Signed-off-by: Arend van Spriel <arend@broadcom.com> - Signed-off-by: Kalle Valo <kvalo@codeaurora.org> - ---- a/include/linux/bcma/bcma.h -+++ b/include/linux/bcma/bcma.h -@@ -151,6 +151,8 @@ struct bcma_host_ops { - #define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */ - #define BCMA_CORE_USB30_DEV 0x83D - #define BCMA_CORE_ARM_CR4 0x83E -+#define BCMA_CORE_ARM_CA7 0x847 -+#define BCMA_CORE_SYS_MEM 0x849 - #define BCMA_CORE_DEFAULT 0xFFF - - #define BCMA_MAX_NR_CORES 16 diff --git a/target/linux/generic/pending-3.18/030-backport_bcm47xx_nvram.patch b/target/linux/generic/pending-3.18/030-backport_bcm47xx_nvram.patch deleted file mode 100644 index 7ae8b1db6c..0000000000 --- a/target/linux/generic/pending-3.18/030-backport_bcm47xx_nvram.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- /dev/null -+++ b/include/linux/bcm47xx_nvram.h -@@ -0,0 +1,49 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#ifndef __BCM47XX_NVRAM_H -+#define __BCM47XX_NVRAM_H -+ -+#include <linux/types.h> -+#include <linux/kernel.h> -+#include <linux/vmalloc.h> -+ -+#ifdef CONFIG_BCM47XX_NVRAM -+int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); -+int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); -+int bcm47xx_nvram_gpio_pin(const char *name); -+char *bcm47xx_nvram_get_contents(size_t *val_len); -+static inline void bcm47xx_nvram_release_contents(char *nvram) -+{ -+ vfree(nvram); -+}; -+#else -+static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) -+{ -+ return -ENOTSUPP; -+}; -+static inline int bcm47xx_nvram_getenv(const char *name, char *val, -+ size_t val_len) -+{ -+ return -ENOTSUPP; -+}; -+static inline int bcm47xx_nvram_gpio_pin(const char *name) -+{ -+ return -ENOTSUPP; -+}; -+ -+static inline char *bcm47xx_nvram_get_contents(size_t *val_len) -+{ -+ return NULL; -+}; -+ -+static inline void bcm47xx_nvram_release_contents(char *nvram) -+{ -+}; -+#endif -+ -+#endif /* __BCM47XX_NVRAM_H */ diff --git a/target/linux/generic/pending-3.18/030-nl80211-Allow-set-network-namespace-by-fd.patch b/target/linux/generic/pending-3.18/030-nl80211-Allow-set-network-namespace-by-fd.patch deleted file mode 100644 index 80f9708306..0000000000 --- a/target/linux/generic/pending-3.18/030-nl80211-Allow-set-network-namespace-by-fd.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Vadim Kochan <vadim4j@gmail.com> -Date: Mon, 12 Jan 2015 16:34:05 +0200 -Subject: [PATCH] nl80211: Allow set network namespace by fd - -Added new NL80211_ATTR_NETNS_FD which allows to -set namespace via nl80211 by fd. - -Signed-off-by: Vadim Kochan <vadim4j@gmail.com> -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/net/core/net_namespace.c -+++ b/net/core/net_namespace.c -@@ -380,6 +380,7 @@ struct net *get_net_ns_by_fd(int fd) - return ERR_PTR(-EINVAL); - } - #endif -+EXPORT_SYMBOL_GPL(get_net_ns_by_fd); - - struct net *get_net_ns_by_pid(pid_t pid) - { diff --git a/target/linux/generic/pending-3.18/031-bcma-from-4.5.patch b/target/linux/generic/pending-3.18/031-bcma-from-4.5.patch deleted file mode 100644 index 171395dcec..0000000000 --- a/target/linux/generic/pending-3.18/031-bcma-from-4.5.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -637,11 +637,36 @@ static int bcma_device_uevent(struct dev - core->id.rev, core->id.class); - } - --static int __init bcma_modinit(void) -+static unsigned int bcma_bus_registered; -+ -+/* -+ * If built-in, bus has to be registered early, before any driver calls -+ * bcma_driver_register. -+ * Otherwise registering driver would trigger BUG in driver_register. -+ */ -+static int __init bcma_init_bus_register(void) - { - int err; - -+ if (bcma_bus_registered) -+ return 0; -+ - err = bus_register(&bcma_bus_type); -+ if (!err) -+ bcma_bus_registered = 1; -+ -+ return err; -+} -+#ifndef MODULE -+fs_initcall(bcma_init_bus_register); -+#endif -+ -+/* Main initialization has to be done with SPI/mtd/NAND/SPROM available */ -+static int __init bcma_modinit(void) -+{ -+ int err; -+ -+ err = bcma_init_bus_register(); - if (err) - return err; - -@@ -660,7 +685,7 @@ static int __init bcma_modinit(void) - - return err; - } --fs_initcall(bcma_modinit); -+module_init(bcma_modinit); - - static void __exit bcma_modexit(void) - { diff --git a/target/linux/generic/pending-3.18/032-bcma-from-4.6.patch b/target/linux/generic/pending-3.18/032-bcma-from-4.6.patch deleted file mode 100644 index 85eeaad4d3..0000000000 --- a/target/linux/generic/pending-3.18/032-bcma-from-4.6.patch +++ /dev/null @@ -1,716 +0,0 @@ ---- a/drivers/bcma/driver_chipcommon.c -+++ b/drivers/bcma/driver_chipcommon.c -@@ -15,6 +15,8 @@ - #include <linux/platform_device.h> - #include <linux/bcma/bcma.h> - -+static void bcma_chipco_serial_init(struct bcma_drv_cc *cc); -+ - static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, - u32 mask, u32 value) - { -@@ -113,8 +115,37 @@ int bcma_chipco_watchdog_register(struct - return 0; - } - -+static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc) -+{ -+ struct bcma_bus *bus = cc->core->bus; -+ -+ switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { -+ case BCMA_CC_FLASHT_STSER: -+ case BCMA_CC_FLASHT_ATSER: -+ bcma_debug(bus, "Found serial flash\n"); -+ bcma_sflash_init(cc); -+ break; -+ case BCMA_CC_FLASHT_PARA: -+ bcma_debug(bus, "Found parallel flash\n"); -+ bcma_pflash_init(cc); -+ break; -+ default: -+ bcma_err(bus, "Flash type not supported\n"); -+ } -+ -+ if (cc->core->id.rev == 38 || -+ bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { -+ if (cc->capabilities & BCMA_CC_CAP_NFLASH) { -+ bcma_debug(bus, "Found NAND flash\n"); -+ bcma_nflash_init(cc); -+ } -+ } -+} -+ - void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) - { -+ struct bcma_bus *bus = cc->core->bus; -+ - if (cc->early_setup_done) - return; - -@@ -129,6 +160,12 @@ void bcma_core_chipcommon_early_init(str - if (cc->capabilities & BCMA_CC_CAP_PMU) - bcma_pmu_early_init(cc); - -+ if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC) -+ bcma_chipco_serial_init(cc); -+ -+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) -+ bcma_core_chipcommon_flash_detect(cc); -+ - cc->early_setup_done = true; - } - -@@ -185,11 +222,12 @@ u32 bcma_chipco_watchdog_timer_set(struc - ticks = 2; - else if (ticks > maxt) - ticks = maxt; -- bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); - } else { - struct bcma_bus *bus = cc->core->bus; - - if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && -+ bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 && - bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) - bcma_core_set_clockmode(cc->core, - ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); -@@ -314,9 +352,9 @@ u32 bcma_chipco_gpio_pulldown(struct bcm - return res; - } - --#ifdef CONFIG_BCMA_DRIVER_MIPS --void bcma_chipco_serial_init(struct bcma_drv_cc *cc) -+static void bcma_chipco_serial_init(struct bcma_drv_cc *cc) - { -+#if IS_BUILTIN(CONFIG_BCM47XX) - unsigned int irq; - u32 baud_base; - u32 i; -@@ -358,5 +396,5 @@ void bcma_chipco_serial_init(struct bcma - ports[i].baud_base = baud_base; - ports[i].reg_shift = 0; - } -+#endif /* CONFIG_BCM47XX */ - } --#endif /* CONFIG_BCMA_DRIVER_MIPS */ ---- a/drivers/bcma/driver_chipcommon_pmu.c -+++ b/drivers/bcma/driver_chipcommon_pmu.c -@@ -15,44 +15,44 @@ - - u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) - { -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); -- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); -- return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); -+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); -+ return bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); - } - EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); - - void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) - { -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); -- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); -+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); - } - EXPORT_SYMBOL_GPL(bcma_chipco_pll_write); - - void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, - u32 set) - { -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); -- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); -- bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); -+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); -+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_PLLCTL_DATA, mask, set); - } - EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset); - - void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, - u32 offset, u32 mask, u32 set) - { -- bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); -- bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); -- bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_CHIPCTL_ADDR, offset); -+ bcma_pmu_read32(cc, BCMA_CC_PMU_CHIPCTL_ADDR); -+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_CHIPCTL_DATA, mask, set); - } - EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset); - - void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, - u32 set) - { -- bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset); -- bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR); -- bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_REGCTL_ADDR, offset); -+ bcma_pmu_read32(cc, BCMA_CC_PMU_REGCTL_ADDR); -+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_REGCTL_DATA, mask, set); - } - EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); - -@@ -60,18 +60,18 @@ static u32 bcma_pmu_xtalfreq(struct bcma - { - u32 ilp_ctl, alp_hz; - -- if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & -+ if (!(bcma_pmu_read32(cc, BCMA_CC_PMU_STAT) & - BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) - return 0; - -- bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, -- BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, -+ BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); - usleep_range(1000, 2000); - -- ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); -+ ilp_ctl = bcma_pmu_read32(cc, BCMA_CC_PMU_XTAL_FREQ); - ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; - -- bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); - - alp_hz = ilp_ctl * 32768 / 4; - return (alp_hz + 50000) / 100000 * 100; -@@ -127,8 +127,8 @@ static void bcma_pmu2_pll_init0(struct b - mask = (u32)~(BCMA_RES_4314_HT_AVAIL | - BCMA_RES_4314_MACPHY_CLK_AVAIL); - -- bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); -- bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); -+ bcma_pmu_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); -+ bcma_pmu_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); - bcma_wait_value(cc->core, BCMA_CLKCTLST, - BCMA_CLKCTLST_HAVEHT, 0, 20000); - break; -@@ -140,7 +140,7 @@ static void bcma_pmu2_pll_init0(struct b - - /* Flush */ - if (cc->pmu.rev >= 2) -- bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); -+ bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); - - /* TODO: Do we need to update OTP? */ - } -@@ -195,9 +195,9 @@ static void bcma_pmu_resources_init(stru - - /* Set the resource masks. */ - if (min_msk) -- bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); - if (max_msk) -- bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); - - /* - * Add some delay; allow resources to come up and settle. -@@ -269,23 +269,33 @@ static void bcma_pmu_workarounds(struct - - void bcma_pmu_early_init(struct bcma_drv_cc *cc) - { -+ struct bcma_bus *bus = cc->core->bus; - u32 pmucap; - -- pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP); -+ if (cc->core->id.rev >= 35 && -+ cc->capabilities_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) { -+ cc->pmu.core = bcma_find_core(bus, BCMA_CORE_PMU); -+ if (!cc->pmu.core) -+ bcma_warn(bus, "Couldn't find expected PMU core"); -+ } -+ if (!cc->pmu.core) -+ cc->pmu.core = cc->core; -+ -+ pmucap = bcma_pmu_read32(cc, BCMA_CC_PMU_CAP); - cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION); - -- bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", -- cc->pmu.rev, pmucap); -+ bcma_debug(bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, -+ pmucap); - } - - void bcma_pmu_init(struct bcma_drv_cc *cc) - { - if (cc->pmu.rev == 1) -- bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, -- ~BCMA_CC_PMU_CTL_NOILPONW); -+ bcma_pmu_mask32(cc, BCMA_CC_PMU_CTL, -+ ~BCMA_CC_PMU_CTL_NOILPONW); - else -- bcma_cc_set32(cc, BCMA_CC_PMU_CTL, -- BCMA_CC_PMU_CTL_NOILPONW); -+ bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, -+ BCMA_CC_PMU_CTL_NOILPONW); - - bcma_pmu_pll_init(cc); - bcma_pmu_resources_init(cc); -@@ -472,8 +482,8 @@ u32 bcma_pmu_get_cpu_clock(struct bcma_d - static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, - u32 value) - { -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); - } - - void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) -@@ -497,20 +507,20 @@ void bcma_pmu_spuravoid_pllupdate(struct - bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0; - - /* RMW only the P1 divider */ -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, - BCMA_CC_PMU_PLL_CTL0 + phypll_offset); -- tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); -+ tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); - tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK)); - tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT); -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); - - /* RMW only the int feedback divider */ -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, - BCMA_CC_PMU_PLL_CTL2 + phypll_offset); -- tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); -+ tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); - tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK); - tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; -- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); - - tmp = BCMA_CC_PMU_CTL_PLL_UPD; - break; -@@ -646,7 +656,7 @@ void bcma_pmu_spuravoid_pllupdate(struct - break; - } - -- tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL); -- bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp); -+ tmp |= bcma_pmu_read32(cc, BCMA_CC_PMU_CTL); -+ bcma_pmu_write32(cc, BCMA_CC_PMU_CTL, tmp); - } - EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate); ---- a/drivers/bcma/driver_chipcommon_sflash.c -+++ b/drivers/bcma/driver_chipcommon_sflash.c -@@ -38,6 +38,7 @@ static const struct bcma_sflash_tbl_e bc - { "M25P32", 0x15, 0x10000, 64, }, - { "M25P64", 0x16, 0x10000, 128, }, - { "M25FL128", 0x17, 0x10000, 256, }, -+ { "MX25L25635F", 0x18, 0x10000, 512, }, - { NULL }, - }; - ---- a/drivers/bcma/scan.c -+++ b/drivers/bcma/scan.c -@@ -98,6 +98,9 @@ static const struct bcma_device_id_name - { BCMA_CORE_SHIM, "SHIM" }, - { BCMA_CORE_PCIE2, "PCIe Gen2" }, - { BCMA_CORE_ARM_CR4, "ARM CR4" }, -+ { BCMA_CORE_GCI, "GCI" }, -+ { BCMA_CORE_CMEM, "CNDS DDR2/3 memory controller" }, -+ { BCMA_CORE_ARM_CA7, "ARM CA7" }, - { BCMA_CORE_DEFAULT, "Default" }, - }; - -@@ -315,6 +318,8 @@ static int bcma_get_next_core(struct bcm - switch (core->id.id) { - case BCMA_CORE_4706_MAC_GBIT_COMMON: - case BCMA_CORE_NS_CHIPCOMMON_B: -+ case BCMA_CORE_PMU: -+ case BCMA_CORE_GCI: - /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ - break; - default: ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -1215,10 +1215,10 @@ void b43_wireless_core_phy_pll_reset(str - case B43_BUS_BCMA: - bcma_cc = &dev->dev->bdev->bus->drv_cc; - -- bcma_cc_write32(bcma_cc, BCMA_CC_CHIPCTL_ADDR, 0); -- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); -- bcma_cc_set32(bcma_cc, BCMA_CC_CHIPCTL_DATA, 0x4); -- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); -+ bcma_cc_write32(bcma_cc, BCMA_CC_PMU_CHIPCTL_ADDR, 0); -+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4); -+ bcma_cc_set32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, 0x4); -+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4); - break; - #endif - #ifdef CONFIG_B43_SSB ---- a/include/linux/bcma/bcma.h -+++ b/include/linux/bcma/bcma.h -@@ -151,6 +151,8 @@ struct bcma_host_ops { - #define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */ - #define BCMA_CORE_USB30_DEV 0x83D - #define BCMA_CORE_ARM_CR4 0x83E -+#define BCMA_CORE_GCI 0x840 -+#define BCMA_CORE_CMEM 0x846 /* CNDS DDR2/3 memory controller */ - #define BCMA_CORE_ARM_CA7 0x847 - #define BCMA_CORE_SYS_MEM 0x849 - #define BCMA_CORE_DEFAULT 0xFFF -@@ -200,6 +202,7 @@ struct bcma_host_ops { - #define BCMA_PKG_ID_BCM4707 1 - #define BCMA_PKG_ID_BCM4708 2 - #define BCMA_PKG_ID_BCM4709 0 -+#define BCMA_CHIP_ID_BCM47094 53030 - #define BCMA_CHIP_ID_BCM53018 53018 - - /* Board types (on PCI usually equals to the subsystem dev id) */ ---- a/include/linux/bcma/bcma_driver_chipcommon.h -+++ b/include/linux/bcma/bcma_driver_chipcommon.h -@@ -217,6 +217,11 @@ - #define BCMA_CC_CLKDIV_JTAG_SHIFT 8 - #define BCMA_CC_CLKDIV_UART 0x000000FF - #define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */ -+#define BCMA_CC_CAP_EXT_SECI_PRESENT 0x00000001 -+#define BCMA_CC_CAP_EXT_GSIO_PRESENT 0x00000002 -+#define BCMA_CC_CAP_EXT_GCI_PRESENT 0x00000004 -+#define BCMA_CC_CAP_EXT_SECI_PUART_PRESENT 0x00000008 /* UART present */ -+#define BCMA_CC_CAP_EXT_AOB_PRESENT 0x00000040 - #define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */ - #define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */ - #define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */ -@@ -351,12 +356,12 @@ - #define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */ - #define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */ - #define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */ --#define BCMA_CC_CHIPCTL_ADDR 0x0650 --#define BCMA_CC_CHIPCTL_DATA 0x0654 --#define BCMA_CC_REGCTL_ADDR 0x0658 --#define BCMA_CC_REGCTL_DATA 0x065C --#define BCMA_CC_PLLCTL_ADDR 0x0660 --#define BCMA_CC_PLLCTL_DATA 0x0664 -+#define BCMA_CC_PMU_CHIPCTL_ADDR 0x0650 -+#define BCMA_CC_PMU_CHIPCTL_DATA 0x0654 -+#define BCMA_CC_PMU_REGCTL_ADDR 0x0658 -+#define BCMA_CC_PMU_REGCTL_DATA 0x065C -+#define BCMA_CC_PMU_PLLCTL_ADDR 0x0660 -+#define BCMA_CC_PMU_PLLCTL_DATA 0x0664 - #define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */ - #define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */ - #define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF -@@ -566,17 +571,16 @@ - * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) - */ - struct bcma_chipcommon_pmu { -+ struct bcma_device *core; /* Can be separated core or just ChipCommon one */ - u8 rev; /* PMU revision */ - u32 crystalfreq; /* The active crystal frequency (in kHz) */ - }; - --#ifdef CONFIG_BCMA_DRIVER_MIPS -+#ifdef CONFIG_BCMA_PFLASH - struct bcma_pflash { - bool present; -- u8 buswidth; -- u32 window; -- u32 window_size; - }; -+#endif - - #ifdef CONFIG_BCMA_SFLASH - struct bcma_sflash { -@@ -602,6 +606,7 @@ struct bcma_nflash { - }; - #endif - -+#ifdef CONFIG_BCMA_DRIVER_MIPS - struct bcma_serial_port { - void *regs; - unsigned long clockspeed; -@@ -621,8 +626,9 @@ struct bcma_drv_cc { - /* Fast Powerup Delay constant */ - u16 fast_pwrup_delay; - struct bcma_chipcommon_pmu pmu; --#ifdef CONFIG_BCMA_DRIVER_MIPS -+#ifdef CONFIG_BCMA_PFLASH - struct bcma_pflash pflash; -+#endif - #ifdef CONFIG_BCMA_SFLASH - struct bcma_sflash sflash; - #endif -@@ -630,6 +636,7 @@ struct bcma_drv_cc { - struct bcma_nflash nflash; - #endif - -+#ifdef CONFIG_BCMA_DRIVER_MIPS - int nr_serial_ports; - struct bcma_serial_port serial_ports[4]; - #endif /* CONFIG_BCMA_DRIVER_MIPS */ -@@ -663,6 +670,19 @@ struct bcma_drv_cc_b { - #define bcma_cc_maskset32(cc, offset, mask, set) \ - bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) - -+/* PMU registers access */ -+#define bcma_pmu_read32(cc, offset) \ -+ bcma_read32((cc)->pmu.core, offset) -+#define bcma_pmu_write32(cc, offset, val) \ -+ bcma_write32((cc)->pmu.core, offset, val) -+ -+#define bcma_pmu_mask32(cc, offset, mask) \ -+ bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) & (mask)) -+#define bcma_pmu_set32(cc, offset, set) \ -+ bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) | (set)) -+#define bcma_pmu_maskset32(cc, offset, mask, set) \ -+ bcma_pmu_write32(cc, offset, (bcma_pmu_read32(cc, offset) & (mask)) | (set)) -+ - extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); - - extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc); ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -44,10 +44,6 @@ int bcma_sprom_get(struct bcma_bus *bus) - void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); - void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); - void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); --#ifdef CONFIG_BCMA_DRIVER_MIPS --void bcma_chipco_serial_init(struct bcma_drv_cc *cc); --extern struct platform_device bcma_pflash_dev; --#endif /* CONFIG_BCMA_DRIVER_MIPS */ - - /* driver_chipcommon_b.c */ - int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb); -@@ -59,6 +55,21 @@ void bcma_pmu_init(struct bcma_drv_cc *c - u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); - u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); - -+/************************************************** -+ * driver_chipcommon_sflash.c -+ **************************************************/ -+ -+#ifdef CONFIG_BCMA_PFLASH -+extern struct platform_device bcma_pflash_dev; -+int bcma_pflash_init(struct bcma_drv_cc *cc); -+#else -+static inline int bcma_pflash_init(struct bcma_drv_cc *cc) -+{ -+ bcma_err(cc->core->bus, "Parallel flash not supported\n"); -+ return 0; -+} -+#endif /* CONFIG_BCMA_PFLASH */ -+ - #ifdef CONFIG_BCMA_SFLASH - /* driver_chipcommon_sflash.c */ - int bcma_sflash_init(struct bcma_drv_cc *cc); ---- a/drivers/bcma/driver_gpio.c -+++ b/drivers/bcma/driver_gpio.c -@@ -229,6 +229,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c - case BCMA_CHIP_ID_BCM4707: - case BCMA_CHIP_ID_BCM5357: - case BCMA_CHIP_ID_BCM53572: -+ case BCMA_CHIP_ID_BCM47094: - chip->ngpio = 32; - break; - default: ---- a/drivers/bcma/driver_mips.c -+++ b/drivers/bcma/driver_mips.c -@@ -14,8 +14,6 @@ - - #include <linux/bcma/bcma.h> - --#include <linux/mtd/physmap.h> --#include <linux/platform_device.h> - #include <linux/serial.h> - #include <linux/serial_core.h> - #include <linux/serial_reg.h> -@@ -29,26 +27,6 @@ enum bcma_boot_dev { - BCMA_BOOT_DEV_NAND, - }; - --static const char * const part_probes[] = { "bcm47xxpart", NULL }; -- --static struct physmap_flash_data bcma_pflash_data = { -- .part_probe_types = part_probes, --}; -- --static struct resource bcma_pflash_resource = { -- .name = "bcma_pflash", -- .flags = IORESOURCE_MEM, --}; -- --struct platform_device bcma_pflash_dev = { -- .name = "physmap-flash", -- .dev = { -- .platform_data = &bcma_pflash_data, -- }, -- .resource = &bcma_pflash_resource, -- .num_resources = 1, --}; -- - /* The 47162a0 hangs when reading MIPS DMP registers registers */ - static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) - { -@@ -269,48 +247,11 @@ static enum bcma_boot_dev bcma_boot_dev( - return BCMA_BOOT_DEV_SERIAL; - } - --static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) -+static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore) - { - struct bcma_bus *bus = mcore->core->bus; -- struct bcma_drv_cc *cc = &bus->drv_cc; -- struct bcma_pflash *pflash = &cc->pflash; - enum bcma_boot_dev boot_dev; - -- switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { -- case BCMA_CC_FLASHT_STSER: -- case BCMA_CC_FLASHT_ATSER: -- bcma_debug(bus, "Found serial flash\n"); -- bcma_sflash_init(cc); -- break; -- case BCMA_CC_FLASHT_PARA: -- bcma_debug(bus, "Found parallel flash\n"); -- pflash->present = true; -- pflash->window = BCMA_SOC_FLASH2; -- pflash->window_size = BCMA_SOC_FLASH2_SZ; -- -- if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & -- BCMA_CC_FLASH_CFG_DS) == 0) -- pflash->buswidth = 1; -- else -- pflash->buswidth = 2; -- -- bcma_pflash_data.width = pflash->buswidth; -- bcma_pflash_resource.start = pflash->window; -- bcma_pflash_resource.end = pflash->window + pflash->window_size; -- -- break; -- default: -- bcma_err(bus, "Flash type not supported\n"); -- } -- -- if (cc->core->id.rev == 38 || -- bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { -- if (cc->capabilities & BCMA_CC_CAP_NFLASH) { -- bcma_debug(bus, "Found NAND flash\n"); -- bcma_nflash_init(cc); -- } -- } -- - /* Determine flash type this SoC boots from */ - boot_dev = bcma_boot_dev(bus); - switch (boot_dev) { -@@ -328,13 +269,10 @@ static void bcma_core_mips_flash_detect( - - void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) - { -- struct bcma_bus *bus = mcore->core->bus; -- - if (mcore->early_setup_done) - return; - -- bcma_chipco_serial_init(&bus->drv_cc); -- bcma_core_mips_flash_detect(mcore); -+ bcma_core_mips_nvram_init(mcore); - - mcore->early_setup_done = true; - } ---- a/drivers/bcma/host_pci.c -+++ b/drivers/bcma/host_pci.c -@@ -294,7 +294,7 @@ static const struct pci_device_id bcma_p - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, -- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -70,6 +70,11 @@ config BCMA_DRIVER_MIPS - - If unsure, say N - -+config BCMA_PFLASH -+ bool -+ depends on BCMA_DRIVER_MIPS -+ default y -+ - config BCMA_SFLASH - bool - depends on BCMA_DRIVER_MIPS ---- a/drivers/bcma/Makefile -+++ b/drivers/bcma/Makefile -@@ -1,6 +1,7 @@ - bcma-y += main.o scan.o core.o sprom.o - bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o - bcma-y += driver_chipcommon_b.o -+bcma-$(CONFIG_BCMA_PFLASH) += driver_chipcommon_pflash.o - bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o - bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o - bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o ---- /dev/null -+++ b/drivers/bcma/driver_chipcommon_pflash.c -@@ -0,0 +1,49 @@ -+/* -+ * Broadcom specific AMBA -+ * ChipCommon parallel flash -+ * -+ * Licensed under the GNU/GPL. See COPYING for details. -+ */ -+ -+#include "bcma_private.h" -+ -+#include <linux/bcma/bcma.h> -+#include <linux/mtd/physmap.h> -+#include <linux/platform_device.h> -+ -+static const char * const part_probes[] = { "bcm47xxpart", NULL }; -+ -+static struct physmap_flash_data bcma_pflash_data = { -+ .part_probe_types = part_probes, -+}; -+ -+static struct resource bcma_pflash_resource = { -+ .name = "bcma_pflash", -+ .flags = IORESOURCE_MEM, -+}; -+ -+struct platform_device bcma_pflash_dev = { -+ .name = "physmap-flash", -+ .dev = { -+ .platform_data = &bcma_pflash_data, -+ }, -+ .resource = &bcma_pflash_resource, -+ .num_resources = 1, -+}; -+ -+int bcma_pflash_init(struct bcma_drv_cc *cc) -+{ -+ struct bcma_pflash *pflash = &cc->pflash; -+ -+ pflash->present = true; -+ -+ if (!(bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS)) -+ bcma_pflash_data.width = 1; -+ else -+ bcma_pflash_data.width = 2; -+ -+ bcma_pflash_resource.start = BCMA_SOC_FLASH2; -+ bcma_pflash_resource.end = BCMA_SOC_FLASH2 + BCMA_SOC_FLASH2_SZ; -+ -+ return 0; -+} ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -325,7 +325,7 @@ static int bcma_register_devices(struct - bcma_register_core(bus, core); - } - --#ifdef CONFIG_BCMA_DRIVER_MIPS -+#ifdef CONFIG_BCMA_PFLASH - if (bus->drv_cc.pflash.present) { - err = platform_device_register(&bcma_pflash_dev); - if (err) diff --git a/target/linux/generic/pending-3.18/040-mtd-bcm47xxpart-backports-from-3.19.patch b/target/linux/generic/pending-3.18/040-mtd-bcm47xxpart-backports-from-3.19.patch deleted file mode 100644 index b2d53f9f8a..0000000000 --- a/target/linux/generic/pending-3.18/040-mtd-bcm47xxpart-backports-from-3.19.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -15,8 +15,12 @@ - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> - --/* 10 parts were found on sflash on Netgear WNDR4500 */ --#define BCM47XXPART_MAX_PARTS 12 -+/* -+ * NAND flash on Netgear R6250 was verified to contain 15 partitions. -+ * This will result in allocating too big array for some old devices, but the -+ * memory will be freed soon anyway (see mtd_device_parse_register). -+ */ -+#define BCM47XXPART_MAX_PARTS 20 - - /* - * Amount of bytes we read when analyzing each block of flash memory. -@@ -168,18 +172,26 @@ static int bcm47xxpart_parse(struct mtd_ - i++; - } - -- bcm47xxpart_add_part(&parts[curr_part++], "linux", -- offset + trx->offset[i], 0); -- i++; -+ if (trx->offset[i]) { -+ bcm47xxpart_add_part(&parts[curr_part++], -+ "linux", -+ offset + trx->offset[i], -+ 0); -+ i++; -+ } - - /* - * Pure rootfs size is known and can be calculated as: - * trx->length - trx->offset[i]. We don't fill it as - * we want to have jffs2 (overlay) in the same mtd. - */ -- bcm47xxpart_add_part(&parts[curr_part++], "rootfs", -- offset + trx->offset[i], 0); -- i++; -+ if (trx->offset[i]) { -+ bcm47xxpart_add_part(&parts[curr_part++], -+ "rootfs", -+ offset + trx->offset[i], -+ 0); -+ i++; -+ } - - last_trx_part = curr_part - 1; - diff --git a/target/linux/generic/pending-3.18/041-mtd-bcm47xxpart-backports-from-3.20.patch b/target/linux/generic/pending-3.18/041-mtd-bcm47xxpart-backports-from-3.20.patch deleted file mode 100644 index f3dfa901f1..0000000000 --- a/target/linux/generic/pending-3.18/041-mtd-bcm47xxpart-backports-from-3.20.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -15,6 +15,8 @@ - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> - -+#include <uapi/linux/magic.h> -+ - /* - * NAND flash on Netgear R6250 was verified to contain 15 partitions. - * This will result in allocating too big array for some old devices, but the -@@ -39,7 +41,8 @@ - #define ML_MAGIC1 0x39685a42 - #define ML_MAGIC2 0x26594131 - #define TRX_MAGIC 0x30524448 --#define SQSH_MAGIC 0x71736873 /* shsq */ -+#define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */ -+#define UBI_EC_MAGIC 0x23494255 /* UBI# */ - - struct trx_header { - uint32_t magic; -@@ -50,7 +53,7 @@ struct trx_header { - uint32_t offset[3]; - } __packed; - --static void bcm47xxpart_add_part(struct mtd_partition *part, char *name, -+static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, - u64 offset, uint32_t mask_flags) - { - part->name = name; -@@ -58,6 +61,26 @@ static void bcm47xxpart_add_part(struct - part->mask_flags = mask_flags; - } - -+static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, -+ size_t offset) -+{ -+ uint32_t buf; -+ size_t bytes_read; -+ -+ if (mtd_read(master, offset, sizeof(buf), &bytes_read, -+ (uint8_t *)&buf) < 0) { -+ pr_err("mtd_read error while parsing (offset: 0x%X)!\n", -+ offset); -+ goto out_default; -+ } -+ -+ if (buf == UBI_EC_MAGIC) -+ return "ubi"; -+ -+out_default: -+ return "rootfs"; -+} -+ - static int bcm47xxpart_parse(struct mtd_info *master, - struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -73,8 +96,12 @@ static int bcm47xxpart_parse(struct mtd_ - int last_trx_part = -1; - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; - -- if (blocksize <= 0x10000) -- blocksize = 0x10000; -+ /* -+ * Some really old flashes (like AT45DB*) had smaller erasesize-s, but -+ * partitions were aligned to at least 0x1000 anyway. -+ */ -+ if (blocksize < 0x1000) -+ blocksize = 0x1000; - - /* Alloc */ - parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, -@@ -186,8 +213,11 @@ static int bcm47xxpart_parse(struct mtd_ - * we want to have jffs2 (overlay) in the same mtd. - */ - if (trx->offset[i]) { -+ const char *name; -+ -+ name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); - bcm47xxpart_add_part(&parts[curr_part++], -- "rootfs", -+ name, - offset + trx->offset[i], - 0); - i++; -@@ -203,7 +233,8 @@ static int bcm47xxpart_parse(struct mtd_ - } - - /* Squashfs on devices not using TRX */ -- if (buf[0x000 / 4] == SQSH_MAGIC) { -+ if (le32_to_cpu(buf[0x000 / 4]) == SQUASHFS_MAGIC || -+ buf[0x000 / 4] == SHSQ_MAGIC) { - bcm47xxpart_add_part(&parts[curr_part++], "rootfs", - offset, 0); - continue; diff --git a/target/linux/generic/pending-3.18/043-mtd_GD25Q128B_support_backport_from_3.19.patch b/target/linux/generic/pending-3.18/043-mtd_GD25Q128B_support_backport_from_3.19.patch deleted file mode 100644 index b7bae34aa7..0000000000 --- a/target/linux/generic/pending-3.18/043-mtd_GD25Q128B_support_backport_from_3.19.patch +++ /dev/null @@ -1,15 +0,0 @@ -mtd: spi-nor: support for (GigaDevice) GD25Q128B - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: Brian Norris <computersforpeace@gmail.com> - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -510,6 +510,7 @@ static const struct spi_device_id spi_no - /* GigaDevice */ - { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, - { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) }, - - /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, diff --git a/target/linux/generic/pending-3.18/044-backport-m25p80-jedec-probe.patch b/target/linux/generic/pending-3.18/044-backport-m25p80-jedec-probe.patch deleted file mode 100644 index 24c264ba97..0000000000 --- a/target/linux/generic/pending-3.18/044-backport-m25p80-jedec-probe.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/mtd/devices/m25p80.c -+++ b/drivers/mtd/devices/m25p80.c -@@ -310,11 +310,21 @@ static const struct spi_device_id m25p_i - }; - MODULE_DEVICE_TABLE(spi, m25p_ids); - -+static const struct of_device_id m25p_of_table[] = { -+ /* -+ * Generic compatibility for SPI NOR that can be identified by the -+ * JEDEC READ ID opcode (0x9F). Use this, if possible. -+ */ -+ { .compatible = "jedec,spi-nor" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, m25p_of_table); - - static struct spi_driver m25p80_driver = { - .driver = { - .name = "m25p80", - .owner = THIS_MODULE, -+ .of_match_table = m25p_of_table, - }, - .id_table = m25p_ids, - .probe = m25p_probe, ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -934,8 +934,11 @@ int spi_nor_scan(struct spi_nor *nor, co - if (ret) - return ret; - -- id = spi_nor_match_id(name); -+ if (name) -+ id = spi_nor_match_id(name); - if (!id) -+ id = nor->read_id(nor); -+ if (IS_ERR_OR_NULL(id)) - return -ENOENT; - - info = (void *)id->driver_data; diff --git a/target/linux/generic/pending-3.18/050-backport_netfilter_rtcache.patch b/target/linux/generic/pending-3.18/050-backport_netfilter_rtcache.patch deleted file mode 100644 index 9f23db6a79..0000000000 --- a/target/linux/generic/pending-3.18/050-backport_netfilter_rtcache.patch +++ /dev/null @@ -1,509 +0,0 @@ -Subject: netfilter: conntrack: cache route for forwarded connections - -... to avoid per-packet FIB lookup if possible. - -The cached dst is re-used provided the input interface -is the same as that of the previous packet in the same direction. - -If not, the cached dst is invalidated. - -For ipv6 we also need to store sernum, else dst_check doesn't work, -pointed out by Eric Dumazet. - -This should speed up forwarding when conntrack is already in use -anyway, especially when using reverse path filtering -- active RPF -enforces two FIB lookups for each packet. - -Before the routing cache removal this didn't matter since RPF was performed -only when route cache didn't yield a result; but without route cache it -comes at higher price. - -Julian Anastasov suggested to add NETDEV_UNREGISTER handler to -avoid holding on to dsts of 'frozen' conntracks. - -Signed-off-by: Florian Westphal <fw@strlen.de> - ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -30,6 +30,9 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) - NF_CT_EXT_SYNPROXY, - #endif -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -+ NF_CT_EXT_RTCACHE, -+#endif - NF_CT_EXT_NUM, - }; - -@@ -43,6 +46,7 @@ enum nf_ct_ext_id { - #define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout - #define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels - #define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy -+#define NF_CT_EXT_RTCACHE_TYPE struct nf_conn_rtcache - - /* Extensions: optional stuff which isn't permanently in struct. */ - struct nf_ct_ext { ---- /dev/null -+++ b/include/net/netfilter/nf_conntrack_rtcache.h -@@ -0,0 +1,34 @@ -+#include <linux/gfp.h> -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_extend.h> -+ -+struct dst_entry; -+ -+struct nf_conn_dst_cache { -+ struct dst_entry *dst; -+ int iif; -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ u32 cookie; -+#endif -+ -+}; -+ -+struct nf_conn_rtcache { -+ struct nf_conn_dst_cache cached_dst[IP_CT_DIR_MAX]; -+}; -+ -+static inline -+struct nf_conn_rtcache *nf_ct_rtcache_find(const struct nf_conn *ct) -+{ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -+ return nf_ct_ext_find(ct, NF_CT_EXT_RTCACHE); -+#else -+ return NULL; -+#endif -+} -+ -+static inline int nf_conn_rtcache_iif_get(const struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ return rtc->cached_dst[dir].iif; -+} ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -106,6 +106,18 @@ config NF_CONNTRACK_EVENTS - - If unsure, say `N'. - -+config NF_CONNTRACK_RTCACHE -+ tristate "Cache route entries in conntrack objects" -+ depends on NETFILTER_ADVANCED -+ depends on NF_CONNTRACK -+ help -+ If this option is enabled, the connection tracking code will -+ cache routing information for each connection that is being -+ forwarded, at a cost of 32 bytes per conntrack object. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ The module will be called nf_conntrack_rtcache. -+ - config NF_CONNTRACK_TIMEOUT - bool 'Connection tracking timeout' - depends on NETFILTER_ADVANCED ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -18,6 +18,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += n - # connection tracking - obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o - -+# optional conntrack route cache extension -+obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o -+ - # SCTP protocol connection tracking - obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o - obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ---- /dev/null -+++ b/net/netfilter/nf_conntrack_rtcache.c -@@ -0,0 +1,391 @@ -+/* route cache for netfilter. -+ * -+ * (C) 2014 Red Hat GmbH -+ * -+ * 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. -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include <linux/types.h> -+#include <linux/netfilter.h> -+#include <linux/skbuff.h> -+#include <linux/stddef.h> -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/export.h> -+#include <linux/module.h> -+ -+#include <net/dst.h> -+ -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_core.h> -+#include <net/netfilter/nf_conntrack_extend.h> -+#include <net/netfilter/nf_conntrack_rtcache.h> -+ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+#include <net/ip6_fib.h> -+#endif -+ -+static void __nf_conn_rtcache_destroy(struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ struct dst_entry *dst = rtc->cached_dst[dir].dst; -+ -+ dst_release(dst); -+} -+ -+static void nf_conn_rtcache_destroy(struct nf_conn *ct) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ -+ if (!rtc) -+ return; -+ -+ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_ORIGINAL); -+ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_REPLY); -+} -+ -+static void nf_ct_rtcache_ext_add(struct nf_conn *ct) -+{ -+ struct nf_conn_rtcache *rtc; -+ -+ rtc = nf_ct_ext_add(ct, NF_CT_EXT_RTCACHE, GFP_ATOMIC); -+ if (rtc) { -+ rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif = -1; -+ rtc->cached_dst[IP_CT_DIR_ORIGINAL].dst = NULL; -+ rtc->cached_dst[IP_CT_DIR_REPLY].iif = -1; -+ rtc->cached_dst[IP_CT_DIR_REPLY].dst = NULL; -+ } -+} -+ -+static struct nf_conn_rtcache *nf_ct_rtcache_find_usable(struct nf_conn *ct) -+{ -+ if (nf_ct_is_untracked(ct)) -+ return NULL; -+ return nf_ct_rtcache_find(ct); -+} -+ -+static struct dst_entry * -+nf_conn_rtcache_dst_get(const struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ return rtc->cached_dst[dir].dst; -+} -+ -+static u32 nf_rtcache_get_cookie(int pf, const struct dst_entry *dst) -+{ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ if (pf == NFPROTO_IPV6) { -+ const struct rt6_info *rt = (const struct rt6_info *)dst; -+ -+ if (rt->rt6i_node) -+ return (u32)rt->rt6i_node->fn_sernum; -+ } -+#endif -+ return 0; -+} -+ -+static void nf_conn_rtcache_dst_set(int pf, -+ struct nf_conn_rtcache *rtc, -+ struct dst_entry *dst, -+ enum ip_conntrack_dir dir, int iif) -+{ -+ if (rtc->cached_dst[dir].iif != iif) -+ rtc->cached_dst[dir].iif = iif; -+ -+ if (rtc->cached_dst[dir].dst != dst) { -+ struct dst_entry *old; -+ -+ dst_hold(dst); -+ -+ old = xchg(&rtc->cached_dst[dir].dst, dst); -+ dst_release(old); -+ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ if (pf == NFPROTO_IPV6) -+ rtc->cached_dst[dir].cookie = -+ nf_rtcache_get_cookie(pf, dst); -+#endif -+ } -+} -+ -+static void nf_conn_rtcache_dst_obsolete(struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ struct dst_entry *old; -+ -+ pr_debug("Invalidate iif %d for dir %d on cache %p\n", -+ rtc->cached_dst[dir].iif, dir, rtc); -+ -+ old = xchg(&rtc->cached_dst[dir].dst, NULL); -+ dst_release(old); -+ rtc->cached_dst[dir].iif = -1; -+} -+ -+static unsigned int nf_rtcache_in(const struct nf_hook_ops *ops, -+ struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct nf_conn_rtcache *rtc; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct dst_entry *dst; -+ struct nf_conn *ct; -+ int iif; -+ u32 cookie; -+ -+ if (skb_dst(skb) || skb->sk) -+ return NF_ACCEPT; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct) -+ return NF_ACCEPT; -+ -+ rtc = nf_ct_rtcache_find_usable(ct); -+ if (!rtc) -+ return NF_ACCEPT; -+ -+ /* if iif changes, don't use cache and let ip stack -+ * do route lookup. -+ * -+ * If rp_filter is enabled it might toss skb, so -+ * we don't want to avoid these checks. -+ */ -+ dir = CTINFO2DIR(ctinfo); -+ iif = nf_conn_rtcache_iif_get(rtc, dir); -+ if (in->ifindex != iif) { -+ pr_debug("ct %p, iif %d, cached iif %d, skip cached entry\n", -+ ct, iif, in->ifindex); -+ return NF_ACCEPT; -+ } -+ dst = nf_conn_rtcache_dst_get(rtc, dir); -+ if (dst == NULL) -+ return NF_ACCEPT; -+ -+ cookie = nf_rtcache_get_cookie(ops->pf, dst); -+ -+ dst = dst_check(dst, cookie); -+ pr_debug("obtained dst %p for skb %p, cookie %d\n", dst, skb, cookie); -+ if (likely(dst)) -+ skb_dst_set_noref_force(skb, dst); -+ else -+ nf_conn_rtcache_dst_obsolete(rtc, dir); -+ -+ return NF_ACCEPT; -+} -+ -+static unsigned int nf_rtcache_forward(const struct nf_hook_ops *ops, -+ struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct nf_conn_rtcache *rtc; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct nf_conn *ct; -+ struct dst_entry *dst = skb_dst(skb); -+ int iif; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct) -+ return NF_ACCEPT; -+ -+ if (dst && dst_xfrm(dst)) -+ return NF_ACCEPT; -+ -+ if (!nf_ct_is_confirmed(ct)) { -+ if (WARN_ON(nf_ct_rtcache_find(ct))) -+ return NF_ACCEPT; -+ nf_ct_rtcache_ext_add(ct); -+ return NF_ACCEPT; -+ } -+ -+ rtc = nf_ct_rtcache_find_usable(ct); -+ if (!rtc) -+ return NF_ACCEPT; -+ -+ dir = CTINFO2DIR(ctinfo); -+ iif = nf_conn_rtcache_iif_get(rtc, dir); -+ pr_debug("ct %p, skb %p, dir %d, iif %d, cached iif %d\n", -+ ct, skb, dir, iif, in->ifindex); -+ if (likely(in->ifindex == iif)) -+ return NF_ACCEPT; -+ -+ nf_conn_rtcache_dst_set(ops->pf, rtc, skb_dst(skb), dir, in->ifindex); -+ return NF_ACCEPT; -+} -+ -+static int nf_rtcache_dst_remove(struct nf_conn *ct, void *data) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ struct net_device *dev = data; -+ -+ if (!rtc) -+ return 0; -+ -+ if (dev->ifindex == rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif || -+ dev->ifindex == rtc->cached_dst[IP_CT_DIR_REPLY].iif) { -+ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_ORIGINAL); -+ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_REPLY); -+ } -+ -+ return 0; -+} -+ -+static int nf_rtcache_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct net *net = dev_net(dev); -+ -+ if (event == NETDEV_DOWN) -+ nf_ct_iterate_cleanup(net, nf_rtcache_dst_remove, dev, 0, 0); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block nf_rtcache_notifier = { -+ .notifier_call = nf_rtcache_netdev_event, -+}; -+ -+static struct nf_hook_ops rtcache_ops[] = { -+ { -+ .hook = nf_rtcache_in, -+ .owner = THIS_MODULE, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_LAST, -+ }, -+ { -+ .hook = nf_rtcache_forward, -+ .owner = THIS_MODULE, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_FORWARD, -+ .priority = NF_IP_PRI_LAST, -+ }, -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ { -+ .hook = nf_rtcache_in, -+ .owner = THIS_MODULE, -+ .pf = NFPROTO_IPV6, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_LAST, -+ }, -+ { -+ .hook = nf_rtcache_forward, -+ .owner = THIS_MODULE, -+ .pf = NFPROTO_IPV6, -+ .hooknum = NF_INET_FORWARD, -+ .priority = NF_IP_PRI_LAST, -+ }, -+#endif -+}; -+ -+static struct nf_ct_ext_type rtcache_extend __read_mostly = { -+ .len = sizeof(struct nf_conn_rtcache), -+ .align = __alignof__(struct nf_conn_rtcache), -+ .id = NF_CT_EXT_RTCACHE, -+ .destroy = nf_conn_rtcache_destroy, -+}; -+ -+static int __init nf_conntrack_rtcache_init(void) -+{ -+ int ret = nf_ct_extend_register(&rtcache_extend); -+ -+ if (ret < 0) { -+ pr_err("nf_conntrack_rtcache: Unable to register extension\n"); -+ return ret; -+ } -+ -+ ret = nf_register_hooks(rtcache_ops, ARRAY_SIZE(rtcache_ops)); -+ if (ret < 0) { -+ nf_ct_extend_unregister(&rtcache_extend); -+ return ret; -+ } -+ -+ ret = register_netdevice_notifier(&nf_rtcache_notifier); -+ if (ret) { -+ nf_unregister_hooks(rtcache_ops, ARRAY_SIZE(rtcache_ops)); -+ nf_ct_extend_unregister(&rtcache_extend); -+ } -+ -+ return ret; -+} -+ -+static int nf_rtcache_ext_remove(struct nf_conn *ct, void *data) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ -+ return rtc != NULL; -+} -+ -+static bool __exit nf_conntrack_rtcache_wait_for_dying(struct net *net) -+{ -+ bool wait = false; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ struct nf_conntrack_tuple_hash *h; -+ struct hlist_nulls_node *n; -+ struct nf_conn *ct; -+ struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); -+ -+ rcu_read_lock(); -+ spin_lock_bh(&pcpu->lock); -+ -+ hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) { -+ ct = nf_ct_tuplehash_to_ctrack(h); -+ if (nf_ct_rtcache_find(ct) != NULL) { -+ wait = true; -+ break; -+ } -+ } -+ spin_unlock_bh(&pcpu->lock); -+ rcu_read_unlock(); -+ } -+ -+ return wait; -+} -+ -+static void __exit nf_conntrack_rtcache_fini(void) -+{ -+ struct net *net; -+ int count = 0; -+ -+ /* remove hooks so no new connections get rtcache extension */ -+ nf_unregister_hooks(rtcache_ops, ARRAY_SIZE(rtcache_ops)); -+ -+ synchronize_net(); -+ -+ unregister_netdevice_notifier(&nf_rtcache_notifier); -+ -+ rtnl_lock(); -+ -+ /* zap all conntracks with rtcache extension */ -+ for_each_net(net) -+ nf_ct_iterate_cleanup(net, nf_rtcache_ext_remove, NULL, 0, 0); -+ -+ for_each_net(net) { -+ /* .. and make sure they're gone from dying list, too */ -+ while (nf_conntrack_rtcache_wait_for_dying(net)) { -+ msleep(200); -+ WARN_ONCE(++count > 25, "Waiting for all rtcache conntracks to go away\n"); -+ } -+ } -+ -+ rtnl_unlock(); -+ synchronize_net(); -+ nf_ct_extend_unregister(&rtcache_extend); -+} -+module_init(nf_conntrack_rtcache_init); -+module_exit(nf_conntrack_rtcache_fini); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Florian Westphal <fw@strlen.de>"); -+MODULE_DESCRIPTION("Conntrack route cache extension"); diff --git a/target/linux/generic/pending-3.18/051-02-bridge-allow-setting-hash_max-multicast_router-if-in.patch b/target/linux/generic/pending-3.18/051-02-bridge-allow-setting-hash_max-multicast_router-if-in.patch deleted file mode 100644 index f7f88f8134..0000000000 --- a/target/linux/generic/pending-3.18/051-02-bridge-allow-setting-hash_max-multicast_router-if-in.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 6ae4ae8e512bd229f806c22f8a2cd751e4f987c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> -Date: Sat, 23 May 2015 03:12:34 +0200 -Subject: [PATCH] bridge: allow setting hash_max + multicast_router if - interface is down -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Network managers like netifd (used in OpenWRT for instance) try to -configure interface options after creation but before setting the -interface up. - -Unfortunately the sysfs / bridge currently only allows to configure the -hash_max and multicast_router options when the bridge interface is up. -But since br_multicast_init() doesn't start any timers and only sets -default values and initializes timers it should be save to reconfigure -the default values after that, before things actually get active after -the bridge is set up. - -Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/bridge/br_multicast.c | 24 +++--------------------- - 1 file changed, 3 insertions(+), 21 deletions(-) - ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1948,11 +1948,9 @@ out: - - int br_multicast_set_router(struct net_bridge *br, unsigned long val) - { -- int err = -ENOENT; -+ int err = -EINVAL; - - spin_lock_bh(&br->multicast_lock); -- if (!netif_running(br->dev)) -- goto unlock; - - switch (val) { - case 0: -@@ -1963,13 +1961,8 @@ int br_multicast_set_router(struct net_b - br->multicast_router = val; - err = 0; - break; -- -- default: -- err = -EINVAL; -- break; - } - --unlock: - spin_unlock_bh(&br->multicast_lock); - - return err; -@@ -1978,11 +1971,9 @@ unlock: - int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - { - struct net_bridge *br = p->br; -- int err = -ENOENT; -+ int err = -EINVAL; - - spin_lock(&br->multicast_lock); -- if (!netif_running(br->dev) || p->state == BR_STATE_DISABLED) -- goto unlock; - - switch (val) { - case 0: -@@ -2004,13 +1995,8 @@ int br_multicast_set_port_router(struct - - br_multicast_add_router(br, p); - break; -- -- default: -- err = -EINVAL; -- break; - } - --unlock: - spin_unlock(&br->multicast_lock); - - return err; -@@ -2115,15 +2101,11 @@ unlock: - - int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) - { -- int err = -ENOENT; -+ int err = -EINVAL; - u32 old; - struct net_bridge_mdb_htable *mdb; - - spin_lock_bh(&br->multicast_lock); -- if (!netif_running(br->dev)) -- goto unlock; -- -- err = -EINVAL; - if (!is_power_of_2(val)) - goto unlock; - diff --git a/target/linux/generic/pending-3.18/060-mips_decompressor_memmove.patch b/target/linux/generic/pending-3.18/060-mips_decompressor_memmove.patch deleted file mode 100644 index d215b80ab2..0000000000 --- a/target/linux/generic/pending-3.18/060-mips_decompressor_memmove.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/arch/mips/boot/compressed/string.c -+++ b/arch/mips/boot/compressed/string.c -@@ -26,3 +26,19 @@ void *memset(void *s, int c, size_t n) - ss[i] = c; - return s; - } -+ -+void *memmove(void *__dest, __const void *__src, size_t count) -+{ -+ unsigned char *d = __dest; -+ const unsigned char *s = __src; -+ -+ if (__dest == __src) -+ return __dest; -+ -+ if (__dest < __src) -+ return memcpy(__dest, __src, count); -+ -+ while (count--) -+ d[count] = s[count]; -+ return __dest; -+} diff --git a/target/linux/generic/pending-3.18/070-bgmac-register-napi-before-the-device.patch b/target/linux/generic/pending-3.18/070-bgmac-register-napi-before-the-device.patch deleted file mode 100644 index 0e7e4f8b12..0000000000 --- a/target/linux/generic/pending-3.18/070-bgmac-register-napi-before-the-device.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 6216642f200258708e47170ff14ba8ecb486f4f0 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Sun, 18 Jan 2015 19:49:58 +0100 -Subject: [PATCH] bgmac: register napi before the device - -napi should get registered before the netdev and not after. - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/broadcom/bgmac.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -1521,6 +1521,8 @@ static int bgmac_probe(struct bcma_devic - if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) - bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); - -+ netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); -+ - err = bgmac_mii_register(bgmac); - if (err) { - bgmac_err(bgmac, "Cannot register MDIO\n"); -@@ -1535,8 +1537,6 @@ static int bgmac_probe(struct bcma_devic - - netif_carrier_off(net_dev); - -- netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); -- - return 0; - - err_mii_unregister: -@@ -1555,9 +1555,9 @@ static void bgmac_remove(struct bcma_dev - { - struct bgmac *bgmac = bcma_get_drvdata(core); - -- netif_napi_del(&bgmac->napi); - unregister_netdev(bgmac->net_dev); - bgmac_mii_unregister(bgmac); -+ netif_napi_del(&bgmac->napi); - bgmac_dma_free(bgmac); - bcma_set_drvdata(core, NULL); - free_netdev(bgmac->net_dev); diff --git a/target/linux/generic/pending-3.18/071-bgmac-activate-irqs-only-if-there-is-nothing-to-poll.patch b/target/linux/generic/pending-3.18/071-bgmac-activate-irqs-only-if-there-is-nothing-to-poll.patch deleted file mode 100644 index cc43d367cc..0000000000 --- a/target/linux/generic/pending-3.18/071-bgmac-activate-irqs-only-if-there-is-nothing-to-poll.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 43f159c60a99318b1ef7d1d7c16c4dfdd06bfd90 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Sun, 18 Jan 2015 19:49:59 +0100 -Subject: [PATCH] bgmac: activate irqs only if there is nothing to poll - -IRQs should only get activated when there is nothing to poll in the -queue any more and to after every poll. - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/broadcom/bgmac.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -1167,10 +1167,10 @@ static int bgmac_poll(struct napi_struct - bgmac->int_status = 0; - } - -- if (handled < weight) -+ if (handled < weight) { - napi_complete(napi); -- -- bgmac_chip_intrs_on(bgmac); -+ bgmac_chip_intrs_on(bgmac); -+ } - - return handled; - } diff --git a/target/linux/generic/pending-3.18/073-bgmac-Clean-warning-messages.patch b/target/linux/generic/pending-3.18/073-bgmac-Clean-warning-messages.patch deleted file mode 100644 index 17fe5dff5e..0000000000 --- a/target/linux/generic/pending-3.18/073-bgmac-Clean-warning-messages.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8edfe3b6fad28da191c8fa15e4e0d8f7335a0091 Mon Sep 17 00:00:00 2001 -From: Peter Senna Tschudin <peter.senna@gmail.com> -Date: Sat, 7 Mar 2015 12:10:26 +0100 -Subject: [PATCH] bgmac: Clean warning messages -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On my test environment the throughput of a file transfer drops -from 4.4MBps to 116KBps due the number of repeated warning -messages. This patch removes the warning messages as DMA works -correctly with addresses using 0xC0000000 bits. - -Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com> -Acked-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/broadcom/bgmac.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -302,9 +302,6 @@ static int bgmac_dma_rx_skb_for_slot(str - slot->skb = skb; - slot->dma_addr = dma_addr; - -- if (slot->dma_addr & 0xC0000000) -- bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); -- - return 0; - } - -@@ -505,8 +502,6 @@ static int bgmac_dma_alloc(struct bgmac - ring->mmio_base); - goto err_dma_free; - } -- if (ring->dma_base & 0xC0000000) -- bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); - - ring->unaligned = bgmac_dma_unaligned(bgmac, ring, - BGMAC_DMA_RING_TX); -@@ -536,8 +531,6 @@ static int bgmac_dma_alloc(struct bgmac - err = -ENOMEM; - goto err_dma_free; - } -- if (ring->dma_base & 0xC0000000) -- bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); - - ring->unaligned = bgmac_dma_unaligned(bgmac, ring, - BGMAC_DMA_RING_RX); diff --git a/target/linux/generic/pending-3.18/074-bgmac-register-fixed-PHY-for-ARM-BCM470X-BCM5301X-ch.patch b/target/linux/generic/pending-3.18/074-bgmac-register-fixed-PHY-for-ARM-BCM470X-BCM5301X-ch.patch deleted file mode 100644 index 9f0baff0ee..0000000000 --- a/target/linux/generic/pending-3.18/074-bgmac-register-fixed-PHY-for-ARM-BCM470X-BCM5301X-ch.patch +++ /dev/null @@ -1,76 +0,0 @@ -From c25b23b8a387e7d31f7a74af8e37b61e9e6ebb21 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Fri, 20 Mar 2015 23:14:31 +0100 -Subject: [PATCH] bgmac: register fixed PHY for ARM BCM470X / BCM5301X chipsets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On ARM SoCs with bgmac Ethernet hardware we don't have any normal PHY. -There is always a switch attached but it's not even controlled over MDIO -like in case of MIPS devices. -We need a fixed PHY to be able to send/receive packets from the switch. - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/broadcom/bgmac.c | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -14,6 +14,7 @@ - #include <linux/etherdevice.h> - #include <linux/mii.h> - #include <linux/phy.h> -+#include <linux/phy_fixed.h> - #include <linux/interrupt.h> - #include <linux/dma-mapping.h> - #include <bcm47xx_nvram.h> -@@ -1330,13 +1331,46 @@ static void bgmac_adjust_link(struct net - } - } - -+static int bgmac_fixed_phy_register(struct bgmac *bgmac) -+{ -+ struct fixed_phy_status fphy_status = { -+ .link = 1, -+ .speed = SPEED_1000, -+ .duplex = DUPLEX_FULL, -+ }; -+ struct phy_device *phy_dev; -+ int err; -+ -+ phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); -+ if (!phy_dev || IS_ERR(phy_dev)) { -+ bgmac_err(bgmac, "Failed to register fixed PHY device\n"); -+ return -ENODEV; -+ } -+ -+ err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, -+ PHY_INTERFACE_MODE_MII); -+ if (err) { -+ bgmac_err(bgmac, "Connecting PHY failed\n"); -+ return err; -+ } -+ -+ bgmac->phy_dev = phy_dev; -+ -+ return err; -+} -+ - static int bgmac_mii_register(struct bgmac *bgmac) - { -+ struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo; - struct mii_bus *mii_bus; - struct phy_device *phy_dev; - char bus_id[MII_BUS_ID_SIZE + 3]; - int i, err = 0; - -+ if (ci->id == BCMA_CHIP_ID_BCM4707 || -+ ci->id == BCMA_CHIP_ID_BCM53018) -+ return bgmac_fixed_phy_register(bgmac); -+ - mii_bus = mdiobus_alloc(); - if (!mii_bus) - return -ENOMEM; diff --git a/target/linux/generic/pending-3.18/075-bgmac-allow-enabling-on-ARCH_BCM_5301X.patch b/target/linux/generic/pending-3.18/075-bgmac-allow-enabling-on-ARCH_BCM_5301X.patch deleted file mode 100644 index 4513667e3a..0000000000 --- a/target/linux/generic/pending-3.18/075-bgmac-allow-enabling-on-ARCH_BCM_5301X.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fc300dc3733fdc328e6e10c7b8379b60c26cd648 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Fri, 20 Mar 2015 23:14:32 +0100 -Subject: [PATCH] bgmac: allow enabling on ARCH_BCM_5301X -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Home routers based on ARM SoCs like BCM4708 also have bcma bus with core -supported by bgmac. - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/ethernet/broadcom/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/Kconfig -+++ b/drivers/net/ethernet/broadcom/Kconfig -@@ -143,7 +143,7 @@ config BNX2X_SRIOV - - config BGMAC - tristate "BCMA bus GBit core support" -- depends on BCMA_HOST_SOC && HAS_DMA && BCM47XX -+ depends on BCMA_HOST_SOC && HAS_DMA && (BCM47XX || ARCH_BCM_5301X) - select PHYLIB - ---help--- - This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. diff --git a/target/linux/generic/pending-3.18/076-net-phy-export-fixed_phy_register.patch b/target/linux/generic/pending-3.18/076-net-phy-export-fixed_phy_register.patch deleted file mode 100644 index 939016c2e8..0000000000 --- a/target/linux/generic/pending-3.18/076-net-phy-export-fixed_phy_register.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 37e9a6904520b525b542ecd67201164d06fdb95a Mon Sep 17 00:00:00 2001 -From: Mark Salter <msalter@redhat.com> -Date: Thu, 11 Dec 2014 23:03:26 -0500 -Subject: [PATCH] net: phy: export fixed_phy_register() - -When building the bcmgenet driver as module, I get: - -ERROR: "fixed_phy_register" [drivers/net/ethernet/broadcom/genet/genet.ko] undefined! - -commit b0ba512e225d72 ("net: bcmgenet: enable driver to work without device -tree") which added a call to fixed_phy_register. But fixed_phy_register -needs to be exported if used from a module. - -Signed-off-by: Mark Salter <msalter@redhat.com> -Acked-by: Florian Fainelli <f.fainelli@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/phy/fixed.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/fixed.c -+++ b/drivers/net/phy/fixed.c -@@ -274,6 +274,7 @@ struct phy_device *fixed_phy_register(un - - return phy; - } -+EXPORT_SYMBOL_GPL(fixed_phy_register); - - static int __init fixed_mdio_bus_init(void) - { diff --git a/target/linux/generic/pending-3.18/077-01-bgmac-fix-descriptor-frame-start-end-definitions.patch b/target/linux/generic/pending-3.18/077-01-bgmac-fix-descriptor-frame-start-end-definitions.patch deleted file mode 100644 index fe8a602160..0000000000 --- a/target/linux/generic/pending-3.18/077-01-bgmac-fix-descriptor-frame-start-end-definitions.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 23 Mar 2015 02:40:06 +0100 -Subject: [PATCH] bgmac: fix descriptor frame start/end definitions - -The start-of-frame and end-of-frame bits were accidentally swapped. -In the current code it does not make any difference, since they are -always used together. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -345,8 +345,8 @@ - - #define BGMAC_DESC_CTL0_EOT 0x10000000 /* End of ring */ - #define BGMAC_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */ --#define BGMAC_DESC_CTL0_SOF 0x40000000 /* Start of frame */ --#define BGMAC_DESC_CTL0_EOF 0x80000000 /* End of frame */ -+#define BGMAC_DESC_CTL0_EOF 0x40000000 /* End of frame */ -+#define BGMAC_DESC_CTL0_SOF 0x80000000 /* Start of frame */ - #define BGMAC_DESC_CTL1_LEN 0x00001FFF - - #define BGMAC_PHY_NOREGS 0x1E diff --git a/target/linux/generic/pending-3.18/077-02-bgmac-implement-GRO-and-use-build_skb.patch b/target/linux/generic/pending-3.18/077-02-bgmac-implement-GRO-and-use-build_skb.patch deleted file mode 100644 index 8dc5242b5a..0000000000 --- a/target/linux/generic/pending-3.18/077-02-bgmac-implement-GRO-and-use-build_skb.patch +++ /dev/null @@ -1,189 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 23 Mar 2015 02:41:25 +0100 -Subject: [PATCH] bgmac: implement GRO and use build_skb - -This improves performance for routing and local rx - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -276,31 +276,31 @@ static int bgmac_dma_rx_skb_for_slot(str - struct bgmac_slot_info *slot) - { - struct device *dma_dev = bgmac->core->dma_dev; -- struct sk_buff *skb; - dma_addr_t dma_addr; - struct bgmac_rx_header *rx; -+ void *buf; - - /* Alloc skb */ -- skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); -- if (!skb) -+ buf = netdev_alloc_frag(BGMAC_RX_ALLOC_SIZE); -+ if (!buf) - return -ENOMEM; - - /* Poison - if everything goes fine, hardware will overwrite it */ -- rx = (struct bgmac_rx_header *)skb->data; -+ rx = buf; - rx->len = cpu_to_le16(0xdead); - rx->flags = cpu_to_le16(0xbeef); - - /* Map skb for the DMA */ -- dma_addr = dma_map_single(dma_dev, skb->data, -- BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); -+ dma_addr = dma_map_single(dma_dev, buf, BGMAC_RX_BUF_SIZE, -+ DMA_FROM_DEVICE); - if (dma_mapping_error(dma_dev, dma_addr)) { - bgmac_err(bgmac, "DMA mapping error\n"); -- dev_kfree_skb(skb); -+ put_page(virt_to_head_page(buf)); - return -ENOMEM; - } - - /* Update the slot */ -- slot->skb = skb; -+ slot->buf = buf; - slot->dma_addr = dma_addr; - - return 0; -@@ -343,8 +343,9 @@ static int bgmac_dma_rx_read(struct bgma - while (ring->start != ring->end) { - struct device *dma_dev = bgmac->core->dma_dev; - struct bgmac_slot_info *slot = &ring->slots[ring->start]; -- struct sk_buff *skb = slot->skb; -- struct bgmac_rx_header *rx; -+ struct bgmac_rx_header *rx = slot->buf; -+ struct sk_buff *skb; -+ void *buf = slot->buf; - u16 len, flags; - - /* Unmap buffer to make it accessible to the CPU */ -@@ -352,7 +353,6 @@ static int bgmac_dma_rx_read(struct bgma - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - - /* Get info from the header */ -- rx = (struct bgmac_rx_header *)skb->data; - len = le16_to_cpu(rx->len); - flags = le16_to_cpu(rx->flags); - -@@ -393,12 +393,13 @@ static int bgmac_dma_rx_read(struct bgma - dma_unmap_single(dma_dev, old_dma_addr, - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - -+ skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); - skb_put(skb, BGMAC_RX_FRAME_OFFSET + len); - skb_pull(skb, BGMAC_RX_FRAME_OFFSET); - - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, bgmac->net_dev); -- netif_receive_skb(skb); -+ napi_gro_receive(&bgmac->napi, skb); - handled++; - } while (0); - -@@ -434,12 +435,11 @@ static bool bgmac_dma_unaligned(struct b - return false; - } - --static void bgmac_dma_ring_free(struct bgmac *bgmac, -- struct bgmac_dma_ring *ring) -+static void bgmac_dma_tx_ring_free(struct bgmac *bgmac, -+ struct bgmac_dma_ring *ring) - { - struct device *dma_dev = bgmac->core->dma_dev; - struct bgmac_slot_info *slot; -- int size; - int i; - - for (i = 0; i < ring->num_slots; i++) { -@@ -451,23 +451,55 @@ static void bgmac_dma_ring_free(struct b - dev_kfree_skb(slot->skb); - } - } -+} -+ -+static void bgmac_dma_rx_ring_free(struct bgmac *bgmac, -+ struct bgmac_dma_ring *ring) -+{ -+ struct device *dma_dev = bgmac->core->dma_dev; -+ struct bgmac_slot_info *slot; -+ int i; -+ -+ for (i = 0; i < ring->num_slots; i++) { -+ slot = &ring->slots[i]; -+ if (!slot->buf) -+ continue; - -- if (ring->cpu_base) { -- /* Free ring of descriptors */ -- size = ring->num_slots * sizeof(struct bgmac_dma_desc); -- dma_free_coherent(dma_dev, size, ring->cpu_base, -- ring->dma_base); -+ if (slot->dma_addr) -+ dma_unmap_single(dma_dev, slot->dma_addr, -+ BGMAC_RX_BUF_SIZE, -+ DMA_FROM_DEVICE); -+ put_page(virt_to_head_page(slot->buf)); - } - } - -+static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, -+ struct bgmac_dma_ring *ring) -+{ -+ struct device *dma_dev = bgmac->core->dma_dev; -+ int size; -+ -+ if (!ring->cpu_base) -+ return; -+ -+ /* Free ring of descriptors */ -+ size = ring->num_slots * sizeof(struct bgmac_dma_desc); -+ dma_free_coherent(dma_dev, size, ring->cpu_base, -+ ring->dma_base); -+} -+ - static void bgmac_dma_free(struct bgmac *bgmac) - { - int i; - -- for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) -- bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]); -- for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) -- bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]); -+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { -+ bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]); -+ bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); -+ } -+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { -+ bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]); -+ bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); -+ } - } - - static int bgmac_dma_alloc(struct bgmac *bgmac) ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -362,6 +362,8 @@ - #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ - #define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ - #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) -+#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE) + \ -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) - - #define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ - #define BGMAC_BFL_ENETADM 0x0080 /* has ADMtek switch */ -@@ -383,7 +385,10 @@ - #define ETHER_MAX_LEN 1518 - - struct bgmac_slot_info { -- struct sk_buff *skb; -+ union { -+ struct sk_buff *skb; -+ void *buf; -+ }; - dma_addr_t dma_addr; - }; - diff --git a/target/linux/generic/pending-3.18/077-03-bgmac-implement-scatter-gather-support.patch b/target/linux/generic/pending-3.18/077-03-bgmac-implement-scatter-gather-support.patch deleted file mode 100644 index 642dd2ad73..0000000000 --- a/target/linux/generic/pending-3.18/077-03-bgmac-implement-scatter-gather-support.patch +++ /dev/null @@ -1,267 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 23 Mar 2015 02:42:26 +0100 -Subject: [PATCH] bgmac: implement scatter/gather support - -Always use software checksumming, since the hardware does not have any -checksum offload support. -This significantly improves local TCP tx performance. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -115,53 +115,91 @@ static void bgmac_dma_tx_enable(struct b - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl); - } - -+static void -+bgmac_dma_tx_add_buf(struct bgmac *bgmac, struct bgmac_dma_ring *ring, -+ int i, int len, u32 ctl0) -+{ -+ struct bgmac_slot_info *slot; -+ struct bgmac_dma_desc *dma_desc; -+ u32 ctl1; -+ -+ if (i == ring->num_slots - 1) -+ ctl0 |= BGMAC_DESC_CTL0_EOT; -+ -+ ctl1 = len & BGMAC_DESC_CTL1_LEN; -+ -+ slot = &ring->slots[i]; -+ dma_desc = &ring->cpu_base[i]; -+ dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); -+ dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); -+ dma_desc->ctl0 = cpu_to_le32(ctl0); -+ dma_desc->ctl1 = cpu_to_le32(ctl1); -+} -+ - static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, - struct bgmac_dma_ring *ring, - struct sk_buff *skb) - { - struct device *dma_dev = bgmac->core->dma_dev; - struct net_device *net_dev = bgmac->net_dev; -- struct bgmac_dma_desc *dma_desc; -- struct bgmac_slot_info *slot; -- u32 ctl0, ctl1; -+ struct bgmac_slot_info *slot = &ring->slots[ring->end]; - int free_slots; -+ int nr_frags; -+ u32 flags; -+ int index = ring->end; -+ int i; - - if (skb->len > BGMAC_DESC_CTL1_LEN) { - bgmac_err(bgmac, "Too long skb (%d)\n", skb->len); -- goto err_stop_drop; -+ goto err_drop; - } - -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ skb_checksum_help(skb); -+ -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ - if (ring->start <= ring->end) - free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; - else - free_slots = ring->start - ring->end; -- if (free_slots == 1) { -+ -+ if (free_slots <= nr_frags + 1) { - bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); - netif_stop_queue(net_dev); - return NETDEV_TX_BUSY; - } - -- slot = &ring->slots[ring->end]; -- slot->skb = skb; -- slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len, -+ slot->dma_addr = dma_map_single(dma_dev, skb->data, skb_headlen(skb), - DMA_TO_DEVICE); -- if (dma_mapping_error(dma_dev, slot->dma_addr)) { -- bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", -- ring->mmio_base); -- goto err_stop_drop; -- } -+ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) -+ goto err_dma_head; - -- ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF; -- if (ring->end == ring->num_slots - 1) -- ctl0 |= BGMAC_DESC_CTL0_EOT; -- ctl1 = skb->len & BGMAC_DESC_CTL1_LEN; -+ flags = BGMAC_DESC_CTL0_SOF; -+ if (!nr_frags) -+ flags |= BGMAC_DESC_CTL0_EOF | BGMAC_DESC_CTL0_IOC; -+ -+ bgmac_dma_tx_add_buf(bgmac, ring, index, skb_headlen(skb), flags); -+ flags = 0; -+ -+ for (i = 0; i < nr_frags; i++) { -+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; -+ int len = skb_frag_size(frag); -+ -+ index = (index + 1) % BGMAC_TX_RING_SLOTS; -+ slot = &ring->slots[index]; -+ slot->dma_addr = skb_frag_dma_map(dma_dev, frag, 0, -+ len, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) -+ goto err_dma; - -- dma_desc = ring->cpu_base; -- dma_desc += ring->end; -- dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); -- dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); -- dma_desc->ctl0 = cpu_to_le32(ctl0); -- dma_desc->ctl1 = cpu_to_le32(ctl1); -+ if (i == nr_frags - 1) -+ flags |= BGMAC_DESC_CTL0_EOF | BGMAC_DESC_CTL0_IOC; -+ -+ bgmac_dma_tx_add_buf(bgmac, ring, index, len, flags); -+ } -+ -+ slot->skb = skb; - - netdev_sent_queue(net_dev, skb->len); - -@@ -170,20 +208,35 @@ static netdev_tx_t bgmac_dma_tx_add(stru - /* Increase ring->end to point empty slot. We tell hardware the first - * slot it should *not* read. - */ -- if (++ring->end >= BGMAC_TX_RING_SLOTS) -- ring->end = 0; -+ ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, - ring->index_base + - ring->end * sizeof(struct bgmac_dma_desc)); - -- /* Always keep one slot free to allow detecting bugged calls. */ -- if (--free_slots == 1) -+ free_slots -= nr_frags + 1; -+ if (free_slots < 8) - netif_stop_queue(net_dev); - - return NETDEV_TX_OK; - --err_stop_drop: -- netif_stop_queue(net_dev); -+err_dma: -+ dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb), -+ DMA_TO_DEVICE); -+ -+ while (i > 0) { -+ int index = (ring->end + i) % BGMAC_TX_RING_SLOTS; -+ struct bgmac_slot_info *slot = &ring->slots[index]; -+ u32 ctl1 = le32_to_cpu(ring->cpu_base[index].ctl1); -+ int len = ctl1 & BGMAC_DESC_CTL1_LEN; -+ -+ dma_unmap_page(dma_dev, slot->dma_addr, len, DMA_TO_DEVICE); -+ } -+ -+err_dma_head: -+ bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", -+ ring->mmio_base); -+ -+err_drop: - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } -@@ -205,32 +258,45 @@ static void bgmac_dma_tx_free(struct bgm - - while (ring->start != empty_slot) { - struct bgmac_slot_info *slot = &ring->slots[ring->start]; -+ u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); -+ int len = ctl1 & BGMAC_DESC_CTL1_LEN; - -- if (slot->skb) { -+ if (!slot->dma_addr) { -+ bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", -+ ring->start, ring->end); -+ goto next; -+ } -+ -+ if (ctl1 & BGMAC_DESC_CTL0_SOF) - /* Unmap no longer used buffer */ -- dma_unmap_single(dma_dev, slot->dma_addr, -- slot->skb->len, DMA_TO_DEVICE); -- slot->dma_addr = 0; -+ dma_unmap_single(dma_dev, slot->dma_addr, len, -+ DMA_TO_DEVICE); -+ else -+ dma_unmap_page(dma_dev, slot->dma_addr, len, -+ DMA_TO_DEVICE); - -+ if (slot->skb) { - bytes_compl += slot->skb->len; - pkts_compl++; - - /* Free memory! :) */ - dev_kfree_skb(slot->skb); - slot->skb = NULL; -- } else { -- bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", -- ring->start, ring->end); - } - -+next: -+ slot->dma_addr = 0; - if (++ring->start >= BGMAC_TX_RING_SLOTS) - ring->start = 0; - freed = true; - } - -+ if (!pkts_compl) -+ return; -+ - netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl); - -- if (freed && netif_queue_stopped(bgmac->net_dev)) -+ if (netif_queue_stopped(bgmac->net_dev)) - netif_wake_queue(bgmac->net_dev); - } - -@@ -439,17 +505,25 @@ static void bgmac_dma_tx_ring_free(struc - struct bgmac_dma_ring *ring) - { - struct device *dma_dev = bgmac->core->dma_dev; -+ struct bgmac_dma_desc *dma_desc = ring->cpu_base; - struct bgmac_slot_info *slot; - int i; - - for (i = 0; i < ring->num_slots; i++) { -+ int len = dma_desc[i].ctl1 & BGMAC_DESC_CTL1_LEN; -+ - slot = &ring->slots[i]; -- if (slot->skb) { -- if (slot->dma_addr) -- dma_unmap_single(dma_dev, slot->dma_addr, -- slot->skb->len, DMA_TO_DEVICE); -- dev_kfree_skb(slot->skb); -- } -+ dev_kfree_skb(slot->skb); -+ -+ if (!slot->dma_addr) -+ continue; -+ -+ if (slot->skb) -+ dma_unmap_single(dma_dev, slot->dma_addr, -+ len, DMA_TO_DEVICE); -+ else -+ dma_unmap_page(dma_dev, slot->dma_addr, -+ len, DMA_TO_DEVICE); - } - } - -@@ -1588,6 +1662,10 @@ static int bgmac_probe(struct bcma_devic - goto err_dma_free; - } - -+ net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; -+ net_dev->hw_features = net_dev->features; -+ net_dev->vlan_features = net_dev->features; -+ - err = register_netdev(bgmac->net_dev); - if (err) { - bgmac_err(bgmac, "Cannot register net device\n"); diff --git a/target/linux/generic/pending-3.18/077-04-bgmac-simplify-tx-ring-index-handling.patch b/target/linux/generic/pending-3.18/077-04-bgmac-simplify-tx-ring-index-handling.patch deleted file mode 100644 index bf4a22dbea..0000000000 --- a/target/linux/generic/pending-3.18/077-04-bgmac-simplify-tx-ring-index-handling.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 09:58:56 +0200 -Subject: [PATCH] bgmac: simplify tx ring index handling - -Keep incrementing ring->start and ring->end instead of pointing it to -the actual ring slot entry. This simplifies the calculation of the -number of free slots. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru - { - struct device *dma_dev = bgmac->core->dma_dev; - struct net_device *net_dev = bgmac->net_dev; -- struct bgmac_slot_info *slot = &ring->slots[ring->end]; -- int free_slots; -+ int index = ring->end % BGMAC_TX_RING_SLOTS; -+ struct bgmac_slot_info *slot = &ring->slots[index]; - int nr_frags; - u32 flags; -- int index = ring->end; - int i; - - if (skb->len > BGMAC_DESC_CTL1_LEN) { -@@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru - - nr_frags = skb_shinfo(skb)->nr_frags; - -- if (ring->start <= ring->end) -- free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; -- else -- free_slots = ring->start - ring->end; -- -- if (free_slots <= nr_frags + 1) { -+ /* ring->end - ring->start will return the number of valid slots, -+ * even when ring->end overflows -+ */ -+ if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) { - bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); - netif_stop_queue(net_dev); - return NETDEV_TX_BUSY; -@@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(stru - } - - slot->skb = skb; -- -+ ring->end += nr_frags + 1; - netdev_sent_queue(net_dev, skb->len); - - wmb(); -@@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(stru - /* Increase ring->end to point empty slot. We tell hardware the first - * slot it should *not* read. - */ -- ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, - ring->index_base + -- ring->end * sizeof(struct bgmac_dma_desc)); -+ (ring->end % BGMAC_TX_RING_SLOTS) * -+ sizeof(struct bgmac_dma_desc)); - -- free_slots -= nr_frags + 1; -- if (free_slots < 8) -+ if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8) - netif_stop_queue(net_dev); - - return NETDEV_TX_OK; -@@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgm - empty_slot &= BGMAC_DMA_TX_STATDPTR; - empty_slot /= sizeof(struct bgmac_dma_desc); - -- while (ring->start != empty_slot) { -- struct bgmac_slot_info *slot = &ring->slots[ring->start]; -- u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); -- int len = ctl1 & BGMAC_DESC_CTL1_LEN; -+ while (ring->start != ring->end) { -+ int slot_idx = ring->start % BGMAC_TX_RING_SLOTS; -+ struct bgmac_slot_info *slot = &ring->slots[slot_idx]; -+ u32 ctl1; -+ int len; - -- if (!slot->dma_addr) { -- bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", -- ring->start, ring->end); -- goto next; -- } -+ if (slot_idx == empty_slot) -+ break; - -+ ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1); -+ len = ctl1 & BGMAC_DESC_CTL1_LEN; - if (ctl1 & BGMAC_DESC_CTL0_SOF) - /* Unmap no longer used buffer */ - dma_unmap_single(dma_dev, slot->dma_addr, len, -@@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgm - slot->skb = NULL; - } - --next: - slot->dma_addr = 0; -- if (++ring->start >= BGMAC_TX_RING_SLOTS) -- ring->start = 0; -+ ring->start++; - freed = true; - } - ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -414,10 +414,10 @@ enum bgmac_dma_ring_type { - * empty. - */ - struct bgmac_dma_ring { -- u16 num_slots; -- u16 start; -- u16 end; -+ u32 start; -+ u32 end; - -+ u16 num_slots; - u16 mmio_base; - struct bgmac_dma_desc *cpu_base; - dma_addr_t dma_base; diff --git a/target/linux/generic/pending-3.18/077-05-bgmac-leave-interrupts-disabled-as-long-as-there-is-.patch b/target/linux/generic/pending-3.18/077-05-bgmac-leave-interrupts-disabled-as-long-as-there-is-.patch deleted file mode 100644 index 4e5e2e720a..0000000000 --- a/target/linux/generic/pending-3.18/077-05-bgmac-leave-interrupts-disabled-as-long-as-there-is-.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 10:08:04 +0200 -Subject: [PATCH] bgmac: leave interrupts disabled as long as there is work - to do - -Always poll rx and tx during NAPI poll instead of relying on the status -of the first interrupt. This prevents bgmac_poll from leaving unfinished -work around until the next IRQ. -In my tests this makes bridging/routing throughput under heavy load more -stable and ensures that no new IRQs arrive as long as bgmac_poll uses up -the entire budget. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgma - bgmac_phy_init(bgmac); - - netdev_reset_queue(bgmac->net_dev); -- -- bgmac->int_status = 0; - } - - static void bgmac_chip_intrs_on(struct bgmac *bgmac) -@@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int i - if (!int_status) - return IRQ_NONE; - -- /* Ack */ -- bgmac_write(bgmac, BGMAC_INT_STATUS, int_status); -+ int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX); -+ if (int_status) -+ bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status); - - /* Disable new interrupts until handling existing ones */ - bgmac_chip_intrs_off(bgmac); - -- bgmac->int_status = int_status; -- - napi_schedule(&bgmac->napi); - - return IRQ_HANDLED; -@@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int i - static int bgmac_poll(struct napi_struct *napi, int weight) - { - struct bgmac *bgmac = container_of(napi, struct bgmac, napi); -- struct bgmac_dma_ring *ring; - int handled = 0; - -- if (bgmac->int_status & BGMAC_IS_TX0) { -- ring = &bgmac->tx_ring[0]; -- bgmac_dma_tx_free(bgmac, ring); -- bgmac->int_status &= ~BGMAC_IS_TX0; -- } -+ /* Ack */ -+ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); - -- if (bgmac->int_status & BGMAC_IS_RX) { -- ring = &bgmac->rx_ring[0]; -- handled += bgmac_dma_rx_read(bgmac, ring, weight); -- bgmac->int_status &= ~BGMAC_IS_RX; -- } -+ bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]); -+ handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight); - -- if (bgmac->int_status) { -- bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); -- bgmac->int_status = 0; -- } -+ /* Poll again if more events arrived in the meantime */ -+ if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX)) -+ return handled; - - if (handled < weight) { - napi_complete(napi); ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -452,7 +452,6 @@ struct bgmac { - - /* Int */ - u32 int_mask; -- u32 int_status; - - /* Current MAC state */ - int mac_speed; diff --git a/target/linux/generic/pending-3.18/077-06-bgmac-set-received-skb-headroom-to-NET_SKB_PAD.patch b/target/linux/generic/pending-3.18/077-06-bgmac-set-received-skb-headroom-to-NET_SKB_PAD.patch deleted file mode 100644 index 1b0742cd3a..0000000000 --- a/target/linux/generic/pending-3.18/077-06-bgmac-set-received-skb-headroom-to-NET_SKB_PAD.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 10:13:28 +0200 -Subject: [PATCH] bgmac: set received skb headroom to NET_SKB_PAD - -A packet buffer offset of 30 bytes is inefficient, because the first 2 -bytes end up in a different cacheline. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -346,13 +346,13 @@ static int bgmac_dma_rx_skb_for_slot(str - return -ENOMEM; - - /* Poison - if everything goes fine, hardware will overwrite it */ -- rx = buf; -+ rx = buf + BGMAC_RX_BUF_OFFSET; - rx->len = cpu_to_le16(0xdead); - rx->flags = cpu_to_le16(0xbeef); - - /* Map skb for the DMA */ -- dma_addr = dma_map_single(dma_dev, buf, BGMAC_RX_BUF_SIZE, -- DMA_FROM_DEVICE); -+ dma_addr = dma_map_single(dma_dev, buf + BGMAC_RX_BUF_OFFSET, -+ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_dev, dma_addr)) { - bgmac_err(bgmac, "DMA mapping error\n"); - put_page(virt_to_head_page(buf)); -@@ -403,7 +403,7 @@ static int bgmac_dma_rx_read(struct bgma - while (ring->start != ring->end) { - struct device *dma_dev = bgmac->core->dma_dev; - struct bgmac_slot_info *slot = &ring->slots[ring->start]; -- struct bgmac_rx_header *rx = slot->buf; -+ struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; - struct sk_buff *skb; - void *buf = slot->buf; - u16 len, flags; -@@ -454,8 +454,10 @@ static int bgmac_dma_rx_read(struct bgma - BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); - - skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); -- skb_put(skb, BGMAC_RX_FRAME_OFFSET + len); -- skb_pull(skb, BGMAC_RX_FRAME_OFFSET); -+ skb_put(skb, BGMAC_RX_FRAME_OFFSET + -+ BGMAC_RX_BUF_OFFSET + len); -+ skb_pull(skb, BGMAC_RX_FRAME_OFFSET + -+ BGMAC_RX_BUF_OFFSET); - - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, bgmac->net_dev); ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -360,9 +360,11 @@ - - #define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ - #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ -+#define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \ -+ BGMAC_RX_FRAME_OFFSET) - #define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ - #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) --#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE) + \ -+#define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \ - SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) - - #define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ diff --git a/target/linux/generic/pending-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch b/target/linux/generic/pending-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch deleted file mode 100644 index 2be65b4544..0000000000 --- a/target/linux/generic/pending-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch +++ /dev/null @@ -1,130 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 22:23:07 +0200 -Subject: [PATCH] bgmac: simplify/optimize rx DMA error handling - -Allocate a new buffer before processing the completed one. If allocation -fails, reuse the old buffer. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -386,6 +386,19 @@ static void bgmac_dma_rx_setup_desc(stru - dma_desc->ctl1 = cpu_to_le32(ctl1); - } - -+static void bgmac_dma_rx_poison_buf(struct device *dma_dev, -+ struct bgmac_slot_info *slot) -+{ -+ struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; -+ -+ dma_sync_single_for_cpu(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE, -+ DMA_FROM_DEVICE); -+ rx->len = cpu_to_le16(0xdead); -+ rx->flags = cpu_to_le16(0xbeef); -+ dma_sync_single_for_device(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE, -+ DMA_FROM_DEVICE); -+} -+ - static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, - int weight) - { -@@ -406,53 +419,35 @@ static int bgmac_dma_rx_read(struct bgma - struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; - struct sk_buff *skb; - void *buf = slot->buf; -+ dma_addr_t dma_addr = slot->dma_addr; - u16 len, flags; - -- /* Unmap buffer to make it accessible to the CPU */ -- dma_sync_single_for_cpu(dma_dev, slot->dma_addr, -- BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); -- -- /* Get info from the header */ -- len = le16_to_cpu(rx->len); -- flags = le16_to_cpu(rx->flags); -- - do { -- dma_addr_t old_dma_addr = slot->dma_addr; -- int err; -+ /* Prepare new skb as replacement */ -+ if (bgmac_dma_rx_skb_for_slot(bgmac, slot)) { -+ bgmac_dma_rx_poison_buf(dma_dev, slot); -+ break; -+ } -+ -+ /* Unmap buffer to make it accessible to the CPU */ -+ dma_unmap_single(dma_dev, dma_addr, -+ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); -+ -+ /* Get info from the header */ -+ len = le16_to_cpu(rx->len); -+ flags = le16_to_cpu(rx->flags); - - /* Check for poison and drop or pass the packet */ - if (len == 0xdead && flags == 0xbeef) { - bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", - ring->start); -- dma_sync_single_for_device(dma_dev, -- slot->dma_addr, -- BGMAC_RX_BUF_SIZE, -- DMA_FROM_DEVICE); -+ put_page(virt_to_head_page(buf)); - break; - } - - /* Omit CRC. */ - len -= ETH_FCS_LEN; - -- /* Prepare new skb as replacement */ -- err = bgmac_dma_rx_skb_for_slot(bgmac, slot); -- if (err) { -- /* Poison the old skb */ -- rx->len = cpu_to_le16(0xdead); -- rx->flags = cpu_to_le16(0xbeef); -- -- dma_sync_single_for_device(dma_dev, -- slot->dma_addr, -- BGMAC_RX_BUF_SIZE, -- DMA_FROM_DEVICE); -- break; -- } -- bgmac_dma_rx_setup_desc(bgmac, ring, ring->start); -- -- /* Unmap old skb, we'll pass it to the netfif */ -- dma_unmap_single(dma_dev, old_dma_addr, -- BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); -- - skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); - skb_put(skb, BGMAC_RX_FRAME_OFFSET + - BGMAC_RX_BUF_OFFSET + len); -@@ -465,6 +460,8 @@ static int bgmac_dma_rx_read(struct bgma - handled++; - } while (0); - -+ bgmac_dma_rx_setup_desc(bgmac, ring, ring->start); -+ - if (++ring->start >= BGMAC_RX_RING_SLOTS) - ring->start = 0; - -@@ -532,14 +529,14 @@ static void bgmac_dma_rx_ring_free(struc - - for (i = 0; i < ring->num_slots; i++) { - slot = &ring->slots[i]; -- if (!slot->buf) -+ if (!slot->dma_addr) - continue; - -- if (slot->dma_addr) -- dma_unmap_single(dma_dev, slot->dma_addr, -- BGMAC_RX_BUF_SIZE, -- DMA_FROM_DEVICE); -+ dma_unmap_single(dma_dev, slot->dma_addr, -+ BGMAC_RX_BUF_SIZE, -+ DMA_FROM_DEVICE); - put_page(virt_to_head_page(slot->buf)); -+ slot->dma_addr = 0; - } - } - diff --git a/target/linux/generic/pending-3.18/077-08-bgmac-add-check-for-oversized-packets.patch b/target/linux/generic/pending-3.18/077-08-bgmac-add-check-for-oversized-packets.patch deleted file mode 100644 index 6bb4747686..0000000000 --- a/target/linux/generic/pending-3.18/077-08-bgmac-add-check-for-oversized-packets.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 22:28:20 +0200 -Subject: [PATCH] bgmac: add check for oversized packets - -In very rare cases, the MAC can catch an internal buffer that is bigger -than it's supposed to be. Instead of crashing the kernel, simply pass -the buffer back to the hardware - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -445,6 +445,13 @@ static int bgmac_dma_rx_read(struct bgma - break; - } - -+ if (len > BGMAC_RX_ALLOC_SIZE) { -+ bgmac_err(bgmac, "Found oversized packet at slot %d, DMA issue!\n", -+ ring->start); -+ put_page(virt_to_head_page(buf)); -+ break; -+ } -+ - /* Omit CRC. */ - len -= ETH_FCS_LEN; - diff --git a/target/linux/generic/pending-3.18/077-09-bgmac-increase-rx-ring-size-from-511-to-512.patch b/target/linux/generic/pending-3.18/077-09-bgmac-increase-rx-ring-size-from-511-to-512.patch deleted file mode 100644 index 1fc4ed03f1..0000000000 --- a/target/linux/generic/pending-3.18/077-09-bgmac-increase-rx-ring-size-from-511-to-512.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 22:36:16 +0200 -Subject: [PATCH] bgmac: increase rx ring size from 511 to 512 - -Limiting it to 511 looks like a failed attempt at leaving one descriptor -empty to allow the hardware to stop processing a buffer that has not -been prepared yet. However, this doesn't work because this affects the -total ring size as well - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -356,7 +356,7 @@ - #define BGMAC_MAX_RX_RINGS 1 - - #define BGMAC_TX_RING_SLOTS 128 --#define BGMAC_RX_RING_SLOTS 512 - 1 /* Why -1? Well, Broadcom does that... */ -+#define BGMAC_RX_RING_SLOTS 512 - - #define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ - #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ diff --git a/target/linux/generic/pending-3.18/077-10-bgmac-simplify-dma-init-cleanup.patch b/target/linux/generic/pending-3.18/077-10-bgmac-simplify-dma-init-cleanup.patch deleted file mode 100644 index a49bd5f5e7..0000000000 --- a/target/linux/generic/pending-3.18/077-10-bgmac-simplify-dma-init-cleanup.patch +++ /dev/null @@ -1,184 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 23:19:32 +0200 -Subject: [PATCH] bgmac: simplify dma init/cleanup - -Instead of allocating buffers at device init time and initializing -descriptors at device open, do both at the same time (during open). -Free all buffers when closing the device. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -562,18 +562,26 @@ static void bgmac_dma_ring_desc_free(str - ring->dma_base); - } - --static void bgmac_dma_free(struct bgmac *bgmac) -+static void bgmac_dma_cleanup(struct bgmac *bgmac) - { - int i; - -- for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { -+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) - bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]); -- bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); -- } -- for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { -+ -+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) - bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]); -+} -+ -+static void bgmac_dma_free(struct bgmac *bgmac) -+{ -+ int i; -+ -+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) -+ bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); -+ -+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) - bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); -- } - } - - static int bgmac_dma_alloc(struct bgmac *bgmac) -@@ -621,8 +629,6 @@ static int bgmac_dma_alloc(struct bgmac - } - - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { -- int j; -- - ring = &bgmac->rx_ring[i]; - ring->num_slots = BGMAC_RX_RING_SLOTS; - ring->mmio_base = ring_base[i]; -@@ -645,15 +651,6 @@ static int bgmac_dma_alloc(struct bgmac - ring->index_base = lower_32_bits(ring->dma_base); - else - ring->index_base = 0; -- -- /* Alloc RX slots */ -- for (j = 0; j < ring->num_slots; j++) { -- err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); -- if (err) { -- bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n"); -- goto err_dma_free; -- } -- } - } - - return 0; -@@ -663,10 +660,10 @@ err_dma_free: - return -ENOMEM; - } - --static void bgmac_dma_init(struct bgmac *bgmac) -+static int bgmac_dma_init(struct bgmac *bgmac) - { - struct bgmac_dma_ring *ring; -- int i; -+ int i, err; - - for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { - ring = &bgmac->tx_ring[i]; -@@ -698,8 +695,13 @@ static void bgmac_dma_init(struct bgmac - if (ring->unaligned) - bgmac_dma_rx_enable(bgmac, ring); - -- for (j = 0; j < ring->num_slots; j++) -+ for (j = 0; j < ring->num_slots; j++) { -+ err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); -+ if (err) -+ goto error; -+ - bgmac_dma_rx_setup_desc(bgmac, ring, j); -+ } - - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, - ring->index_base + -@@ -708,6 +710,12 @@ static void bgmac_dma_init(struct bgmac - ring->start = 0; - ring->end = 0; - } -+ -+ return 0; -+ -+error: -+ bgmac_dma_cleanup(bgmac); -+ return err; - } - - /************************************************** -@@ -1183,11 +1191,8 @@ static void bgmac_enable(struct bgmac *b - } - - /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ --static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) -+static void bgmac_chip_init(struct bgmac *bgmac) - { -- struct bgmac_dma_ring *ring; -- int i; -- - /* 1 interrupt per received frame */ - bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); - -@@ -1205,16 +1210,7 @@ static void bgmac_chip_init(struct bgmac - - bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); - -- if (full_init) { -- bgmac_dma_init(bgmac); -- if (1) /* FIXME: is there any case we don't want IRQs? */ -- bgmac_chip_intrs_on(bgmac); -- } else { -- for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { -- ring = &bgmac->rx_ring[i]; -- bgmac_dma_rx_enable(bgmac, ring); -- } -- } -+ bgmac_chip_intrs_on(bgmac); - - bgmac_enable(bgmac); - } -@@ -1274,23 +1270,27 @@ static int bgmac_open(struct net_device - int err = 0; - - bgmac_chip_reset(bgmac); -+ -+ err = bgmac_dma_init(bgmac); -+ if (err) -+ return err; -+ - /* Specs say about reclaiming rings here, but we do that in DMA init */ -- bgmac_chip_init(bgmac, true); -+ bgmac_chip_init(bgmac); - - err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED, - KBUILD_MODNAME, net_dev); - if (err < 0) { - bgmac_err(bgmac, "IRQ request error: %d!\n", err); -- goto err_out; -+ bgmac_dma_cleanup(bgmac); -+ return err; - } - napi_enable(&bgmac->napi); - - phy_start(bgmac->phy_dev); - - netif_carrier_on(net_dev); -- --err_out: -- return err; -+ return 0; - } - - static int bgmac_stop(struct net_device *net_dev) -@@ -1306,6 +1306,7 @@ static int bgmac_stop(struct net_device - free_irq(bgmac->core->irq, net_dev); - - bgmac_chip_reset(bgmac); -+ bgmac_dma_cleanup(bgmac); - - return 0; - } diff --git a/target/linux/generic/pending-3.18/077-11-bgmac-fix-DMA-rx-corruption.patch b/target/linux/generic/pending-3.18/077-11-bgmac-fix-DMA-rx-corruption.patch deleted file mode 100644 index e7a7987f43..0000000000 --- a/target/linux/generic/pending-3.18/077-11-bgmac-fix-DMA-rx-corruption.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 11:59:47 +0200 -Subject: [PATCH] bgmac: fix DMA rx corruption - -The driver needs to inform the hardware about the first invalid (not yet -filled) rx slot, by writing its DMA descriptor pointer offset to the -BGMAC_DMA_RX_INDEX register. - -This register was set to a value exceeding the rx ring size, effectively -allowing the hardware constant access to the full ring, regardless of -which slots are initialized. - -To fix this issue, always mark the last filled rx slot as invalid. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -366,6 +366,16 @@ static int bgmac_dma_rx_skb_for_slot(str - return 0; - } - -+static void bgmac_dma_rx_update_index(struct bgmac *bgmac, -+ struct bgmac_dma_ring *ring) -+{ -+ wmb(); -+ -+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, -+ ring->index_base + -+ ring->end * sizeof(struct bgmac_dma_desc)); -+} -+ - static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac, - struct bgmac_dma_ring *ring, int desc_idx) - { -@@ -384,6 +394,8 @@ static void bgmac_dma_rx_setup_desc(stru - dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr)); - dma_desc->ctl0 = cpu_to_le32(ctl0); - dma_desc->ctl1 = cpu_to_le32(ctl1); -+ -+ ring->end = desc_idx; - } - - static void bgmac_dma_rx_poison_buf(struct device *dma_dev, -@@ -411,9 +423,7 @@ static int bgmac_dma_rx_read(struct bgma - end_slot &= BGMAC_DMA_RX_STATDPTR; - end_slot /= sizeof(struct bgmac_dma_desc); - -- ring->end = end_slot; -- -- while (ring->start != ring->end) { -+ while (ring->start != end_slot) { - struct device *dma_dev = bgmac->core->dma_dev; - struct bgmac_slot_info *slot = &ring->slots[ring->start]; - struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; -@@ -476,6 +486,8 @@ static int bgmac_dma_rx_read(struct bgma - break; - } - -+ bgmac_dma_rx_update_index(bgmac, ring); -+ - return handled; - } - -@@ -695,6 +707,8 @@ static int bgmac_dma_init(struct bgmac * - if (ring->unaligned) - bgmac_dma_rx_enable(bgmac, ring); - -+ ring->start = 0; -+ ring->end = 0; - for (j = 0; j < ring->num_slots; j++) { - err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); - if (err) -@@ -703,12 +717,7 @@ static int bgmac_dma_init(struct bgmac * - bgmac_dma_rx_setup_desc(bgmac, ring, j); - } - -- bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, -- ring->index_base + -- ring->num_slots * sizeof(struct bgmac_dma_desc)); -- -- ring->start = 0; -- ring->end = 0; -+ bgmac_dma_rx_update_index(bgmac, ring); - } - - return 0; diff --git a/target/linux/generic/pending-3.18/077-12-bgmac-drop-ring-num_slots.patch b/target/linux/generic/pending-3.18/077-12-bgmac-drop-ring-num_slots.patch deleted file mode 100644 index 4dbb6f48de..0000000000 --- a/target/linux/generic/pending-3.18/077-12-bgmac-drop-ring-num_slots.patch +++ /dev/null @@ -1,132 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 12 Apr 2015 23:28:38 +0200 -Subject: [PATCH] bgmac: drop ring->num_slots - -The ring size is always known at compile time, so make the code a bit -more efficient - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -123,7 +123,7 @@ bgmac_dma_tx_add_buf(struct bgmac *bgmac - struct bgmac_dma_desc *dma_desc; - u32 ctl1; - -- if (i == ring->num_slots - 1) -+ if (i == BGMAC_TX_RING_SLOTS - 1) - ctl0 |= BGMAC_DESC_CTL0_EOT; - - ctl1 = len & BGMAC_DESC_CTL1_LEN; -@@ -382,7 +382,7 @@ static void bgmac_dma_rx_setup_desc(stru - struct bgmac_dma_desc *dma_desc = ring->cpu_base + desc_idx; - u32 ctl0 = 0, ctl1 = 0; - -- if (desc_idx == ring->num_slots - 1) -+ if (desc_idx == BGMAC_RX_RING_SLOTS - 1) - ctl0 |= BGMAC_DESC_CTL0_EOT; - ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN; - /* Is there any BGMAC device that requires extension? */ -@@ -521,7 +521,7 @@ static void bgmac_dma_tx_ring_free(struc - struct bgmac_slot_info *slot; - int i; - -- for (i = 0; i < ring->num_slots; i++) { -+ for (i = 0; i < BGMAC_TX_RING_SLOTS; i++) { - int len = dma_desc[i].ctl1 & BGMAC_DESC_CTL1_LEN; - - slot = &ring->slots[i]; -@@ -546,7 +546,7 @@ static void bgmac_dma_rx_ring_free(struc - struct bgmac_slot_info *slot; - int i; - -- for (i = 0; i < ring->num_slots; i++) { -+ for (i = 0; i < BGMAC_RX_RING_SLOTS; i++) { - slot = &ring->slots[i]; - if (!slot->dma_addr) - continue; -@@ -560,7 +560,8 @@ static void bgmac_dma_rx_ring_free(struc - } - - static void bgmac_dma_ring_desc_free(struct bgmac *bgmac, -- struct bgmac_dma_ring *ring) -+ struct bgmac_dma_ring *ring, -+ int num_slots) - { - struct device *dma_dev = bgmac->core->dma_dev; - int size; -@@ -569,7 +570,7 @@ static void bgmac_dma_ring_desc_free(str - return; - - /* Free ring of descriptors */ -- size = ring->num_slots * sizeof(struct bgmac_dma_desc); -+ size = num_slots * sizeof(struct bgmac_dma_desc); - dma_free_coherent(dma_dev, size, ring->cpu_base, - ring->dma_base); - } -@@ -590,10 +591,12 @@ static void bgmac_dma_free(struct bgmac - int i; - - for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) -- bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]); -+ bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i], -+ BGMAC_TX_RING_SLOTS); - - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) -- bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]); -+ bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i], -+ BGMAC_RX_RING_SLOTS); - } - - static int bgmac_dma_alloc(struct bgmac *bgmac) -@@ -616,11 +619,10 @@ static int bgmac_dma_alloc(struct bgmac - - for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { - ring = &bgmac->tx_ring[i]; -- ring->num_slots = BGMAC_TX_RING_SLOTS; - ring->mmio_base = ring_base[i]; - - /* Alloc ring of descriptors */ -- size = ring->num_slots * sizeof(struct bgmac_dma_desc); -+ size = BGMAC_TX_RING_SLOTS * sizeof(struct bgmac_dma_desc); - ring->cpu_base = dma_zalloc_coherent(dma_dev, size, - &ring->dma_base, - GFP_KERNEL); -@@ -642,11 +644,10 @@ static int bgmac_dma_alloc(struct bgmac - - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { - ring = &bgmac->rx_ring[i]; -- ring->num_slots = BGMAC_RX_RING_SLOTS; - ring->mmio_base = ring_base[i]; - - /* Alloc ring of descriptors */ -- size = ring->num_slots * sizeof(struct bgmac_dma_desc); -+ size = BGMAC_RX_RING_SLOTS * sizeof(struct bgmac_dma_desc); - ring->cpu_base = dma_zalloc_coherent(dma_dev, size, - &ring->dma_base, - GFP_KERNEL); -@@ -709,7 +710,7 @@ static int bgmac_dma_init(struct bgmac * - - ring->start = 0; - ring->end = 0; -- for (j = 0; j < ring->num_slots; j++) { -+ for (j = 0; j < BGMAC_RX_RING_SLOTS; j++) { - err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]); - if (err) - goto error; ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -419,11 +419,10 @@ struct bgmac_dma_ring { - u32 start; - u32 end; - -- u16 num_slots; -- u16 mmio_base; - struct bgmac_dma_desc *cpu_base; - dma_addr_t dma_base; - u32 index_base; /* Used for unaligned rings only, otherwise 0 */ -+ u16 mmio_base; - bool unaligned; - - struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS]; diff --git a/target/linux/generic/pending-3.18/078-bgmac-reset-enable-Ethernet-core-before-using-it.patch b/target/linux/generic/pending-3.18/078-bgmac-reset-enable-Ethernet-core-before-using-it.patch deleted file mode 100644 index a4c7876d7f..0000000000 --- a/target/linux/generic/pending-3.18/078-bgmac-reset-enable-Ethernet-core-before-using-it.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b4dfd8e92956b396d3438212bc9a0be6267b8b34 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Tue, 12 Apr 2016 13:30:45 +0200 -Subject: [PATCH] bgmac: reset & enable Ethernet core before using it -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes Ethernet on D-Link DIR-885L with BCM47094 SoC. Felix reported -similar fix was needed for his BCM4709 device (Buffalo WXR-1900DHP?). -I tested this for regressions on BCM4706, BCM4708A0 and BCM47081A0. - -Cc: Felix Fietkau <nbd@nbd.name> -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -1569,6 +1569,11 @@ static int bgmac_probe(struct bcma_devic - */ - bcma_core_enable(core, 0); - -+ /* This (reset &) enable is not preset in specs or reference driver but -+ * Broadcom does it in arch PCI code when enabling fake PCI device. -+ */ -+ bcma_core_enable(core, 0); -+ - /* Allocation and references */ - net_dev = alloc_etherdev(sizeof(*bgmac)); - if (!net_dev) diff --git a/target/linux/generic/pending-3.18/079-bgmac-fix-MAC-soft-reset-bit-for-corerev-4.patch b/target/linux/generic/pending-3.18/079-bgmac-fix-MAC-soft-reset-bit-for-corerev-4.patch deleted file mode 100644 index f8d0a58769..0000000000 --- a/target/linux/generic/pending-3.18/079-bgmac-fix-MAC-soft-reset-bit-for-corerev-4.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c02bc350f9dbce7d637c394a6e1c4d29dc5b28b2 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau <nbd@nbd.name> -Date: Tue, 12 Apr 2016 18:27:29 +0200 -Subject: [PATCH] bgmac: fix MAC soft-reset bit for corerev > 4 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only core revisions older than 4 use BGMAC_CMDCFG_SR_REV0. This mainly -fixes support for BCM4708A0KF SoCs with Ethernet core rev 5 (it means -only some devices as most of BCM4708A0KF-s got core rev 4). -This was tested for regressions on BCM47094 which doesn't seem to care -which bit gets used. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -198,9 +198,9 @@ - #define BGMAC_CMDCFG_TAI 0x00000200 - #define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ - #define BGMAC_CMDCFG_HD_SHIFT 10 --#define BGMAC_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for other revs */ --#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, only for core rev 4 */ --#define BGMAC_CMDCFG_SR(rev) ((rev == 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REV0) -+#define BGMAC_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for core rev 0-3 */ -+#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, for core rev >= 4 */ -+#define BGMAC_CMDCFG_SR(rev) ((rev >= 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REV0) - #define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ - #define BGMAC_CMDCFG_AE 0x00400000 - #define BGMAC_CMDCFG_CFE 0x00800000 diff --git a/target/linux/generic/pending-3.18/080-00-fib_trie-Fix-proc-net-fib_trie-when-CONFIG_IP_MULTIP.patch b/target/linux/generic/pending-3.18/080-00-fib_trie-Fix-proc-net-fib_trie-when-CONFIG_IP_MULTIP.patch deleted file mode 100644 index 5d99367ad4..0000000000 --- a/target/linux/generic/pending-3.18/080-00-fib_trie-Fix-proc-net-fib_trie-when-CONFIG_IP_MULTIP.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Tue, 2 Dec 2014 10:58:21 -0800 -Subject: [PATCH] fib_trie: Fix /proc/net/fib_trie when - CONFIG_IP_MULTIPLE_TABLES is not defined - -In recent testing I had disabled CONFIG_IP_MULTIPLE_TABLES and as a result -when I ran "cat /proc/net/fib_trie" the main trie was displayed multiple -times. I found that the problem line of code was in the function -fib_trie_seq_next. Specifically the line below caused the indexes to go in -the opposite direction of our traversal: - - h = tb->tb_id & (FIB_TABLE_HASHSZ - 1); - -This issue was that the RT tables are defined such that RT_TABLE_LOCAL is ID -255, while it is located at TABLE_LOCAL_INDEX of 0, and RT_TABLE_MAIN is 254 -with a TABLE_MAIN_INDEX of 1. This means that the above line will return 1 -for the local table and 0 for main. The result is that fib_trie_seq_next -will return NULL at the end of the local table, fib_trie_seq_start will -return the start of the main table, and then fib_trie_seq_next will loop on -main forever as h will always return 0. - -The fix for this is to reverse the ordering of the two tables. It has the -advantage of making it so that the tables now print in the same order -regardless of if multiple tables are enabled or not. In order to make the -definition consistent with the multiple tables case I simply masked the to -RT_TABLE_XXX values by (FIB_TABLE_HASHSZ - 1). This way the two table -layouts should always stay consistent. - -Fixes: 93456b6 ("[IPV4]: Unify access to the routing tables") -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -201,8 +201,8 @@ void fib_free_table(struct fib_table *tb - - #ifndef CONFIG_IP_MULTIPLE_TABLES - --#define TABLE_LOCAL_INDEX 0 --#define TABLE_MAIN_INDEX 1 -+#define TABLE_LOCAL_INDEX (RT_TABLE_LOCAL & (FIB_TABLE_HASHSZ - 1)) -+#define TABLE_MAIN_INDEX (RT_TABLE_MAIN & (FIB_TABLE_HASHSZ - 1)) - - static inline struct fib_table *fib_get_table(struct net *net, u32 id) - { diff --git a/target/linux/generic/pending-3.18/080-01-fib_trie-Fix-trie-balancing-issue-if-new-node-pushes.patch b/target/linux/generic/pending-3.18/080-01-fib_trie-Fix-trie-balancing-issue-if-new-node-pushes.patch deleted file mode 100644 index 4e09f8a189..0000000000 --- a/target/linux/generic/pending-3.18/080-01-fib_trie-Fix-trie-balancing-issue-if-new-node-pushes.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 10 Dec 2014 21:49:22 -0800 -Subject: [PATCH] fib_trie: Fix trie balancing issue if new node pushes down - existing node - -This patch addresses an issue with the level compression of the fib_trie. -Specifically in the case of adding a new leaf that triggers a new node to -be added that takes the place of the old node. The result is a trie where -the 1 child tnode is on one side and one leaf is on the other which gives -you a very deep trie. Below is the script I used to generate a trie on -dummy0 with a 10.X.X.X family of addresses. - - ip link add type dummy - ipval=184549374 - bit=2 - for i in `seq 1 23` - do - ifconfig dummy0:$bit $ipval/8 - ipval=`expr $ipval - $bit` - bit=`expr $bit \* 2` - done - cat /proc/net/fib_triestat - -Running the script before the patch: - - Local: - Aver depth: 10.82 - Max depth: 23 - Leaves: 29 - Prefixes: 30 - Internal nodes: 27 - 1: 26 2: 1 - Pointers: 56 - Null ptrs: 1 - Total size: 5 kB - -After applying the patch and repeating: - - Local: - Aver depth: 4.72 - Max depth: 9 - Leaves: 29 - Prefixes: 30 - Internal nodes: 12 - 1: 3 2: 2 3: 7 - Pointers: 70 - Null ptrs: 30 - Total size: 4 kB - -What this fix does is start the rebalance at the newly created tnode -instead of at the parent tnode. This way if there is a gap between the -parent and the new node it doesn't prevent the new tnode from being -coalesced with any pre-existing nodes that may have been pushed into one -of the new nodes child branches. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1143,8 +1143,9 @@ static struct list_head *fib_insert_node - put_child(tp, cindex, (struct rt_trie_node *)tn); - } else { - rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); -- tp = tn; - } -+ -+ tp = tn; - } - - if (tp && tp->pos + tp->bits > 32) diff --git a/target/linux/generic/pending-3.18/080-02-fib_trie-Update-usage-stats-to-be-percpu-instead-of-.patch b/target/linux/generic/pending-3.18/080-02-fib_trie-Update-usage-stats-to-be-percpu-instead-of-.patch deleted file mode 100644 index 2e6deb5bbc..0000000000 --- a/target/linux/generic/pending-3.18/080-02-fib_trie-Update-usage-stats-to-be-percpu-instead-of-.patch +++ /dev/null @@ -1,200 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:55:29 -0800 -Subject: [PATCH] fib_trie: Update usage stats to be percpu instead of - global variables - -The trie usage stats were currently being shared by all threads that were -calling fib_table_lookup. As a result when multiple threads were -performing lookups simultaneously the trie would begin to cache bounce -between those threads. - -In order to prevent this I have updated the usage stats to use a set of -percpu variables. By doing this we should be able to avoid the cache -bouncing and still make use of these stats. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_frontend.c -+++ b/net/ipv4/fib_frontend.c -@@ -67,7 +67,7 @@ static int __net_init fib4_rules_init(st - return 0; - - fail: -- kfree(local_table); -+ fib_free_table(local_table); - return -ENOMEM; - } - #else ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -153,7 +153,7 @@ struct trie_stat { - struct trie { - struct rt_trie_node __rcu *trie; - #ifdef CONFIG_IP_FIB_TRIE_STATS -- struct trie_use_stats stats; -+ struct trie_use_stats __percpu *stats; - #endif - }; - -@@ -631,7 +631,7 @@ static struct rt_trie_node *resize(struc - if (IS_ERR(tn)) { - tn = old_tn; - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.resize_node_skipped++; -+ this_cpu_inc(t->stats->resize_node_skipped); - #endif - break; - } -@@ -658,7 +658,7 @@ static struct rt_trie_node *resize(struc - if (IS_ERR(tn)) { - tn = old_tn; - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.resize_node_skipped++; -+ this_cpu_inc(t->stats->resize_node_skipped); - #endif - break; - } -@@ -1357,7 +1357,7 @@ static int check_leaf(struct fib_table * - err = fib_props[fa->fa_type].error; - if (err) { - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.semantic_match_passed++; -+ this_cpu_inc(t->stats->semantic_match_passed); - #endif - return err; - } -@@ -1372,7 +1372,7 @@ static int check_leaf(struct fib_table * - continue; - - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.semantic_match_passed++; -+ this_cpu_inc(t->stats->semantic_match_passed); - #endif - res->prefixlen = li->plen; - res->nh_sel = nhsel; -@@ -1388,7 +1388,7 @@ static int check_leaf(struct fib_table * - } - - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.semantic_match_miss++; -+ this_cpu_inc(t->stats->semantic_match_miss); - #endif - } - -@@ -1399,6 +1399,9 @@ int fib_table_lookup(struct fib_table *t - struct fib_result *res, int fib_flags) - { - struct trie *t = (struct trie *) tb->tb_data; -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ struct trie_use_stats __percpu *stats = t->stats; -+#endif - int ret; - struct rt_trie_node *n; - struct tnode *pn; -@@ -1417,7 +1420,7 @@ int fib_table_lookup(struct fib_table *t - goto failed; - - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.gets++; -+ this_cpu_inc(stats->gets); - #endif - - /* Just a leaf? */ -@@ -1441,7 +1444,7 @@ int fib_table_lookup(struct fib_table *t - - if (n == NULL) { - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.null_node_hit++; -+ this_cpu_inc(stats->null_node_hit); - #endif - goto backtrace; - } -@@ -1576,7 +1579,7 @@ backtrace: - chopped_off = 0; - - #ifdef CONFIG_IP_FIB_TRIE_STATS -- t->stats.backtrack++; -+ this_cpu_inc(stats->backtrack); - #endif - goto backtrace; - } -@@ -1830,6 +1833,11 @@ int fib_table_flush(struct fib_table *tb - - void fib_free_table(struct fib_table *tb) - { -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ struct trie *t = (struct trie *)tb->tb_data; -+ -+ free_percpu(t->stats); -+#endif /* CONFIG_IP_FIB_TRIE_STATS */ - kfree(tb); - } - -@@ -1973,7 +1981,14 @@ struct fib_table *fib_trie_table(u32 id) - tb->tb_num_default = 0; - - t = (struct trie *) tb->tb_data; -- memset(t, 0, sizeof(*t)); -+ RCU_INIT_POINTER(t->trie, NULL); -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ t->stats = alloc_percpu(struct trie_use_stats); -+ if (!t->stats) { -+ kfree(tb); -+ tb = NULL; -+ } -+#endif - - return tb; - } -@@ -2139,18 +2154,31 @@ static void trie_show_stats(struct seq_f - - #ifdef CONFIG_IP_FIB_TRIE_STATS - static void trie_show_usage(struct seq_file *seq, -- const struct trie_use_stats *stats) -+ const struct trie_use_stats __percpu *stats) - { -+ struct trie_use_stats s = { 0 }; -+ int cpu; -+ -+ /* loop through all of the CPUs and gather up the stats */ -+ for_each_possible_cpu(cpu) { -+ const struct trie_use_stats *pcpu = per_cpu_ptr(stats, cpu); -+ -+ s.gets += pcpu->gets; -+ s.backtrack += pcpu->backtrack; -+ s.semantic_match_passed += pcpu->semantic_match_passed; -+ s.semantic_match_miss += pcpu->semantic_match_miss; -+ s.null_node_hit += pcpu->null_node_hit; -+ s.resize_node_skipped += pcpu->resize_node_skipped; -+ } -+ - seq_printf(seq, "\nCounters:\n---------\n"); -- seq_printf(seq, "gets = %u\n", stats->gets); -- seq_printf(seq, "backtracks = %u\n", stats->backtrack); -+ seq_printf(seq, "gets = %u\n", s.gets); -+ seq_printf(seq, "backtracks = %u\n", s.backtrack); - seq_printf(seq, "semantic match passed = %u\n", -- stats->semantic_match_passed); -- seq_printf(seq, "semantic match miss = %u\n", -- stats->semantic_match_miss); -- seq_printf(seq, "null node hit= %u\n", stats->null_node_hit); -- seq_printf(seq, "skipped node resize = %u\n\n", -- stats->resize_node_skipped); -+ s.semantic_match_passed); -+ seq_printf(seq, "semantic match miss = %u\n", s.semantic_match_miss); -+ seq_printf(seq, "null node hit= %u\n", s.null_node_hit); -+ seq_printf(seq, "skipped node resize = %u\n\n", s.resize_node_skipped); - } - #endif /* CONFIG_IP_FIB_TRIE_STATS */ - -@@ -2191,7 +2219,7 @@ static int fib_triestat_seq_show(struct - trie_collect_stats(t, &stat); - trie_show_stats(seq, &stat); - #ifdef CONFIG_IP_FIB_TRIE_STATS -- trie_show_usage(seq, &t->stats); -+ trie_show_usage(seq, t->stats); - #endif - } - } diff --git a/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch b/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch deleted file mode 100644 index 4c727cdfce..0000000000 --- a/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch +++ /dev/null @@ -1,421 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:55:35 -0800 -Subject: [PATCH] fib_trie: Make leaf and tnode more uniform - -This change makes some fundamental changes to the way leaves and tnodes are -constructed. The big differences are: -1. Leaves now populate pos and bits indicating their full key size. -2. Trie nodes now mask out their lower bits to be consistent with the leaf -3. Both structures have been reordered so that rt_trie_node now consisists - of a much larger region including the pos, bits, and rcu portions of - the tnode structure. - -On 32b systems this will result in the leaf being 4B larger as the pos and -bits values were added to a hole created by the key as it was only 4B in -length. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -87,24 +87,38 @@ - - typedef unsigned int t_key; - --#define T_TNODE 0 --#define T_LEAF 1 --#define NODE_TYPE_MASK 0x1UL --#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK) -+#define IS_TNODE(n) ((n)->bits) -+#define IS_LEAF(n) (!(n)->bits) - --#define IS_TNODE(n) (!(n->parent & T_LEAF)) --#define IS_LEAF(n) (n->parent & T_LEAF) -+struct tnode { -+ t_key key; -+ unsigned char bits; /* 2log(KEYLENGTH) bits needed */ -+ unsigned char pos; /* 2log(KEYLENGTH) bits needed */ -+ struct tnode __rcu *parent; -+ union { -+ struct rcu_head rcu; -+ struct tnode *tnode_free; -+ }; -+ unsigned int full_children; /* KEYLENGTH bits needed */ -+ unsigned int empty_children; /* KEYLENGTH bits needed */ -+ struct rt_trie_node __rcu *child[0]; -+}; - - struct rt_trie_node { -- unsigned long parent; - t_key key; -+ unsigned char bits; -+ unsigned char pos; -+ struct tnode __rcu *parent; -+ struct rcu_head rcu; - }; - - struct leaf { -- unsigned long parent; - t_key key; -- struct hlist_head list; -+ unsigned char bits; -+ unsigned char pos; -+ struct tnode __rcu *parent; - struct rcu_head rcu; -+ struct hlist_head list; - }; - - struct leaf_info { -@@ -115,20 +129,6 @@ struct leaf_info { - struct rcu_head rcu; - }; - --struct tnode { -- unsigned long parent; -- t_key key; -- unsigned char pos; /* 2log(KEYLENGTH) bits needed */ -- unsigned char bits; /* 2log(KEYLENGTH) bits needed */ -- unsigned int full_children; /* KEYLENGTH bits needed */ -- unsigned int empty_children; /* KEYLENGTH bits needed */ -- union { -- struct rcu_head rcu; -- struct tnode *tnode_free; -- }; -- struct rt_trie_node __rcu *child[0]; --}; -- - #ifdef CONFIG_IP_FIB_TRIE_STATS - struct trie_use_stats { - unsigned int gets; -@@ -176,38 +176,27 @@ static const int sync_pages = 128; - static struct kmem_cache *fn_alias_kmem __read_mostly; - static struct kmem_cache *trie_leaf_kmem __read_mostly; - --/* -- * caller must hold RTNL -- */ --static inline struct tnode *node_parent(const struct rt_trie_node *node) --{ -- unsigned long parent; -+/* caller must hold RTNL */ -+#define node_parent(n) rtnl_dereference((n)->parent) - -- parent = rcu_dereference_index_check(node->parent, lockdep_rtnl_is_held()); -+/* caller must hold RCU read lock or RTNL */ -+#define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) - -- return (struct tnode *)(parent & ~NODE_TYPE_MASK); --} -- --/* -- * caller must hold RCU read lock or RTNL -- */ --static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node) -+/* wrapper for rcu_assign_pointer */ -+static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr) - { -- unsigned long parent; -- -- parent = rcu_dereference_index_check(node->parent, rcu_read_lock_held() || -- lockdep_rtnl_is_held()); -- -- return (struct tnode *)(parent & ~NODE_TYPE_MASK); -+ if (node) -+ rcu_assign_pointer(node->parent, ptr); - } - --/* Same as rcu_assign_pointer -- * but that macro() assumes that value is a pointer. -+#define NODE_INIT_PARENT(n, p) RCU_INIT_POINTER((n)->parent, p) -+ -+/* This provides us with the number of children in this node, in the case of a -+ * leaf this will return 0 meaning none of the children are accessible. - */ --static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr) -+static inline int tnode_child_length(const struct tnode *tn) - { -- smp_wmb(); -- node->parent = (unsigned long)ptr | NODE_TYPE(node); -+ return (1ul << tn->bits) & ~(1ul); - } - - /* -@@ -215,7 +204,7 @@ static inline void node_set_parent(struc - */ - static inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i) - { -- BUG_ON(i >= 1U << tn->bits); -+ BUG_ON(i >= tnode_child_length(tn)); - - return rtnl_dereference(tn->child[i]); - } -@@ -225,16 +214,11 @@ static inline struct rt_trie_node *tnode - */ - static inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) - { -- BUG_ON(i >= 1U << tn->bits); -+ BUG_ON(i >= tnode_child_length(tn)); - - return rcu_dereference_rtnl(tn->child[i]); - } - --static inline int tnode_child_length(const struct tnode *tn) --{ -- return 1 << tn->bits; --} -- - static inline t_key mask_pfx(t_key k, unsigned int l) - { - return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l); -@@ -336,11 +320,6 @@ static inline int tkey_mismatch(t_key a, - - */ - --static inline void check_tnode(const struct tnode *tn) --{ -- WARN_ON(tn && tn->pos+tn->bits > 32); --} -- - static const int halve_threshold = 25; - static const int inflate_threshold = 50; - static const int halve_threshold_root = 15; -@@ -426,11 +405,20 @@ static void tnode_free_flush(void) - } - } - --static struct leaf *leaf_new(void) -+static struct leaf *leaf_new(t_key key) - { - struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); - if (l) { -- l->parent = T_LEAF; -+ l->parent = NULL; -+ /* set key and pos to reflect full key value -+ * any trailing zeros in the key should be ignored -+ * as the nodes are searched -+ */ -+ l->key = key; -+ l->pos = KEYLENGTH; -+ /* set bits to 0 indicating we are not a tnode */ -+ l->bits = 0; -+ - INIT_HLIST_HEAD(&l->list); - } - return l; -@@ -451,12 +439,16 @@ static struct tnode *tnode_new(t_key key - { - size_t sz = sizeof(struct tnode) + (sizeof(struct rt_trie_node *) << bits); - struct tnode *tn = tnode_alloc(sz); -+ unsigned int shift = pos + bits; -+ -+ /* verify bits and pos their msb bits clear and values are valid */ -+ BUG_ON(!bits || (shift > KEYLENGTH)); - - if (tn) { -- tn->parent = T_TNODE; -+ tn->parent = NULL; - tn->pos = pos; - tn->bits = bits; -- tn->key = key; -+ tn->key = mask_pfx(key, pos); - tn->full_children = 0; - tn->empty_children = 1<<bits; - } -@@ -473,10 +465,7 @@ static struct tnode *tnode_new(t_key key - - static inline int tnode_full(const struct tnode *tn, const struct rt_trie_node *n) - { -- if (n == NULL || IS_LEAF(n)) -- return 0; -- -- return ((struct tnode *) n)->pos == tn->pos + tn->bits; -+ return n && IS_TNODE(n) && (n->pos == (tn->pos + tn->bits)); - } - - static inline void put_child(struct tnode *tn, int i, -@@ -514,8 +503,7 @@ static void tnode_put_child_reorg(struct - else if (!wasfull && isfull) - tn->full_children++; - -- if (n) -- node_set_parent(n, tn); -+ node_set_parent(n, tn); - - rcu_assign_pointer(tn->child[i], n); - } -@@ -523,7 +511,7 @@ static void tnode_put_child_reorg(struct - #define MAX_WORK 10 - static struct rt_trie_node *resize(struct trie *t, struct tnode *tn) - { -- int i; -+ struct rt_trie_node *n = NULL; - struct tnode *old_tn; - int inflate_threshold_use; - int halve_threshold_use; -@@ -536,12 +524,11 @@ static struct rt_trie_node *resize(struc - tn, inflate_threshold, halve_threshold); - - /* No children */ -- if (tn->empty_children == tnode_child_length(tn)) { -- tnode_free_safe(tn); -- return NULL; -- } -+ if (tn->empty_children > (tnode_child_length(tn) - 1)) -+ goto no_children; -+ - /* One child */ -- if (tn->empty_children == tnode_child_length(tn) - 1) -+ if (tn->empty_children == (tnode_child_length(tn) - 1)) - goto one_child; - /* - * Double as long as the resulting node has a number of -@@ -607,11 +594,9 @@ static struct rt_trie_node *resize(struc - * - */ - -- check_tnode(tn); -- - /* Keep root node larger */ - -- if (!node_parent((struct rt_trie_node *)tn)) { -+ if (!node_parent(tn)) { - inflate_threshold_use = inflate_threshold_root; - halve_threshold_use = halve_threshold_root; - } else { -@@ -637,8 +622,6 @@ static struct rt_trie_node *resize(struc - } - } - -- check_tnode(tn); -- - /* Return if at least one inflate is run */ - if (max_work != MAX_WORK) - return (struct rt_trie_node *) tn; -@@ -666,21 +649,16 @@ static struct rt_trie_node *resize(struc - - - /* Only one child remains */ -- if (tn->empty_children == tnode_child_length(tn) - 1) { -+ if (tn->empty_children == (tnode_child_length(tn) - 1)) { -+ unsigned long i; - one_child: -- for (i = 0; i < tnode_child_length(tn); i++) { -- struct rt_trie_node *n; -- -- n = rtnl_dereference(tn->child[i]); -- if (!n) -- continue; -- -- /* compress one level */ -- -- node_set_parent(n, NULL); -- tnode_free_safe(tn); -- return n; -- } -+ for (i = tnode_child_length(tn); !n && i;) -+ n = tnode_get_child(tn, --i); -+no_children: -+ /* compress one level */ -+ node_set_parent(n, NULL); -+ tnode_free_safe(tn); -+ return n; - } - return (struct rt_trie_node *) tn; - } -@@ -760,8 +738,7 @@ static struct tnode *inflate(struct trie - - /* A leaf or an internal node with skipped bits */ - -- if (IS_LEAF(node) || ((struct tnode *) node)->pos > -- tn->pos + tn->bits - 1) { -+ if (IS_LEAF(node) || (node->pos > (tn->pos + tn->bits - 1))) { - put_child(tn, - tkey_extract_bits(node->key, oldtnode->pos, oldtnode->bits + 1), - node); -@@ -958,11 +935,9 @@ fib_find_node(struct trie *t, u32 key) - pos = 0; - n = rcu_dereference_rtnl(t->trie); - -- while (n != NULL && NODE_TYPE(n) == T_TNODE) { -+ while (n && IS_TNODE(n)) { - tn = (struct tnode *) n; - -- check_tnode(tn); -- - if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { - pos = tn->pos + tn->bits; - n = tnode_get_child_rcu(tn, -@@ -988,7 +963,7 @@ static void trie_rebalance(struct trie * - - key = tn->key; - -- while (tn != NULL && (tp = node_parent((struct rt_trie_node *)tn)) != NULL) { -+ while (tn != NULL && (tp = node_parent(tn)) != NULL) { - cindex = tkey_extract_bits(key, tp->pos, tp->bits); - wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); - tn = (struct tnode *)resize(t, tn); -@@ -996,7 +971,7 @@ static void trie_rebalance(struct trie * - tnode_put_child_reorg(tp, cindex, - (struct rt_trie_node *)tn, wasfull); - -- tp = node_parent((struct rt_trie_node *) tn); -+ tp = node_parent(tn); - if (!tp) - rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); - -@@ -1048,11 +1023,9 @@ static struct list_head *fib_insert_node - * If it doesn't, we need to replace it with a T_TNODE. - */ - -- while (n != NULL && NODE_TYPE(n) == T_TNODE) { -+ while (n && IS_TNODE(n)) { - tn = (struct tnode *) n; - -- check_tnode(tn); -- - if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { - tp = tn; - pos = tn->pos + tn->bits; -@@ -1087,12 +1060,11 @@ static struct list_head *fib_insert_node - insert_leaf_info(&l->list, li); - goto done; - } -- l = leaf_new(); -+ l = leaf_new(key); - - if (!l) - return NULL; - -- l->key = key; - li = leaf_info_new(plen); - - if (!li) { -@@ -1569,7 +1541,7 @@ backtrace: - if (chopped_off <= pn->bits) { - cindex &= ~(1 << (chopped_off-1)); - } else { -- struct tnode *parent = node_parent_rcu((struct rt_trie_node *) pn); -+ struct tnode *parent = node_parent_rcu(pn); - if (!parent) - goto failed; - -@@ -1597,7 +1569,7 @@ EXPORT_SYMBOL_GPL(fib_table_lookup); - */ - static void trie_leaf_remove(struct trie *t, struct leaf *l) - { -- struct tnode *tp = node_parent((struct rt_trie_node *) l); -+ struct tnode *tp = node_parent(l); - - pr_debug("entering trie_leaf_remove(%p)\n", l); - -@@ -2374,7 +2346,7 @@ static int fib_trie_seq_show(struct seq_ - - if (IS_TNODE(n)) { - struct tnode *tn = (struct tnode *) n; -- __be32 prf = htonl(mask_pfx(tn->key, tn->pos)); -+ __be32 prf = htonl(tn->key); - - seq_indent(seq, iter->depth-1); - seq_printf(seq, " +-- %pI4/%d %d %d %d\n", diff --git a/target/linux/generic/pending-3.18/080-04-fib_trie-Merge-tnode_free-and-leaf_free-into-node_fr.patch b/target/linux/generic/pending-3.18/080-04-fib_trie-Merge-tnode_free-and-leaf_free-into-node_fr.patch deleted file mode 100644 index 3f8d03067d..0000000000 --- a/target/linux/generic/pending-3.18/080-04-fib_trie-Merge-tnode_free-and-leaf_free-into-node_fr.patch +++ /dev/null @@ -1,209 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:55:41 -0800 -Subject: [PATCH] fib_trie: Merge tnode_free and leaf_free into node_free - -Both the leaf and the tnode had an rcu_head in them, but they had them in -slightly different places. Since we now have them in the same spot and -know that any node with bits == 0 is a leaf and the rest are either vmalloc -or kmalloc tnodes depending on the value of bits it makes it easy to combine -the functions and reduce overhead. - -In addition I have taken advantage of the rcu_head pointer to go ahead and -put together a simple linked list instead of using the tnode pointer as -this way we can merge either type of structure for freeing. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -95,15 +95,17 @@ struct tnode { - unsigned char bits; /* 2log(KEYLENGTH) bits needed */ - unsigned char pos; /* 2log(KEYLENGTH) bits needed */ - struct tnode __rcu *parent; -- union { -- struct rcu_head rcu; -- struct tnode *tnode_free; -- }; -+ struct rcu_head rcu; -+ /* everything above this comment must be the same as rt_trie_node */ - unsigned int full_children; /* KEYLENGTH bits needed */ - unsigned int empty_children; /* KEYLENGTH bits needed */ - struct rt_trie_node __rcu *child[0]; - }; - -+/* This struct represents the shared bits between tnode and leaf. If any -+ * ordering is changed here is must also be updated in tnode and leaf as -+ * well. -+ */ - struct rt_trie_node { - t_key key; - unsigned char bits; -@@ -118,6 +120,7 @@ struct leaf { - unsigned char pos; - struct tnode __rcu *parent; - struct rcu_head rcu; -+ /* everything above this comment must be the same as rt_trie_node */ - struct hlist_head list; - }; - -@@ -163,7 +166,7 @@ static struct rt_trie_node *resize(struc - static struct tnode *inflate(struct trie *t, struct tnode *tn); - static struct tnode *halve(struct trie *t, struct tnode *tn); - /* tnodes to free after resize(); protected by RTNL */ --static struct tnode *tnode_free_head; -+static struct callback_head *tnode_free_head; - static size_t tnode_free_size; - - /* -@@ -336,17 +339,23 @@ static inline void alias_free_mem_rcu(st - call_rcu(&fa->rcu, __alias_free_mem); - } - --static void __leaf_free_rcu(struct rcu_head *head) --{ -- struct leaf *l = container_of(head, struct leaf, rcu); -- kmem_cache_free(trie_leaf_kmem, l); --} -+#define TNODE_KMALLOC_MAX \ -+ ilog2((PAGE_SIZE - sizeof(struct tnode)) / sizeof(struct rt_trie_node *)) - --static inline void free_leaf(struct leaf *l) -+static void __node_free_rcu(struct rcu_head *head) - { -- call_rcu(&l->rcu, __leaf_free_rcu); -+ struct rt_trie_node *n = container_of(head, struct rt_trie_node, rcu); -+ -+ if (IS_LEAF(n)) -+ kmem_cache_free(trie_leaf_kmem, n); -+ else if (n->bits <= TNODE_KMALLOC_MAX) -+ kfree(n); -+ else -+ vfree(n); - } - -+#define node_free(n) call_rcu(&n->rcu, __node_free_rcu) -+ - static inline void free_leaf_info(struct leaf_info *leaf) - { - kfree_rcu(leaf, rcu); -@@ -360,43 +369,24 @@ static struct tnode *tnode_alloc(size_t - return vzalloc(size); - } - --static void __tnode_free_rcu(struct rcu_head *head) --{ -- struct tnode *tn = container_of(head, struct tnode, rcu); -- size_t size = sizeof(struct tnode) + -- (sizeof(struct rt_trie_node *) << tn->bits); -- -- if (size <= PAGE_SIZE) -- kfree(tn); -- else -- vfree(tn); --} -- --static inline void tnode_free(struct tnode *tn) --{ -- if (IS_LEAF(tn)) -- free_leaf((struct leaf *) tn); -- else -- call_rcu(&tn->rcu, __tnode_free_rcu); --} -- - static void tnode_free_safe(struct tnode *tn) - { - BUG_ON(IS_LEAF(tn)); -- tn->tnode_free = tnode_free_head; -- tnode_free_head = tn; -- tnode_free_size += sizeof(struct tnode) + -- (sizeof(struct rt_trie_node *) << tn->bits); -+ tn->rcu.next = tnode_free_head; -+ tnode_free_head = &tn->rcu; - } - - static void tnode_free_flush(void) - { -- struct tnode *tn; -+ struct callback_head *head; -+ -+ while ((head = tnode_free_head)) { -+ struct tnode *tn = container_of(head, struct tnode, rcu); -+ -+ tnode_free_head = head->next; -+ tnode_free_size += offsetof(struct tnode, child[1 << tn->bits]); - -- while ((tn = tnode_free_head)) { -- tnode_free_head = tn->tnode_free; -- tn->tnode_free = NULL; -- tnode_free(tn); -+ node_free(tn); - } - - if (tnode_free_size >= PAGE_SIZE * sync_pages) { -@@ -437,7 +427,7 @@ static struct leaf_info *leaf_info_new(i - - static struct tnode *tnode_new(t_key key, int pos, int bits) - { -- size_t sz = sizeof(struct tnode) + (sizeof(struct rt_trie_node *) << bits); -+ size_t sz = offsetof(struct tnode, child[1 << bits]); - struct tnode *tn = tnode_alloc(sz); - unsigned int shift = pos + bits; - -@@ -666,15 +656,15 @@ no_children: - - static void tnode_clean_free(struct tnode *tn) - { -+ struct rt_trie_node *tofree; - int i; -- struct tnode *tofree; - - for (i = 0; i < tnode_child_length(tn); i++) { -- tofree = (struct tnode *)rtnl_dereference(tn->child[i]); -+ tofree = rtnl_dereference(tn->child[i]); - if (tofree) -- tnode_free(tofree); -+ node_free(tofree); - } -- tnode_free(tn); -+ node_free(tn); - } - - static struct tnode *inflate(struct trie *t, struct tnode *tn) -@@ -717,7 +707,7 @@ static struct tnode *inflate(struct trie - inode->bits - 1); - - if (!right) { -- tnode_free(left); -+ node_free(left); - goto nomem; - } - -@@ -1068,7 +1058,7 @@ static struct list_head *fib_insert_node - li = leaf_info_new(plen); - - if (!li) { -- free_leaf(l); -+ node_free(l); - return NULL; - } - -@@ -1100,7 +1090,7 @@ static struct list_head *fib_insert_node - - if (!tn) { - free_leaf_info(li); -- free_leaf(l); -+ node_free(l); - return NULL; - } - -@@ -1580,7 +1570,7 @@ static void trie_leaf_remove(struct trie - } else - RCU_INIT_POINTER(t->trie, NULL); - -- free_leaf(l); -+ node_free(l); - } - - /* diff --git a/target/linux/generic/pending-3.18/080-05-fib_trie-Merge-leaf-into-tnode.patch b/target/linux/generic/pending-3.18/080-05-fib_trie-Merge-leaf-into-tnode.patch deleted file mode 100644 index a3393bf93f..0000000000 --- a/target/linux/generic/pending-3.18/080-05-fib_trie-Merge-leaf-into-tnode.patch +++ /dev/null @@ -1,928 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:55:47 -0800 -Subject: [PATCH] fib_trie: Merge leaf into tnode - -This change makes it so that leaf and tnode are the same struct. As a -result there is no need for rt_trie_node anymore since everyting can be -merged into tnode. - -On 32b systems this results in the leaf being 4 bytes larger, however I -don't know if that is really an issue as this and an eariler patch that -added bits & pos have increased the size from 20 to 28. If I am not -mistaken slub/slab allocate on power of 2 sizes so 20 was likely being -rounded up to 32 anyway. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -96,32 +96,16 @@ struct tnode { - unsigned char pos; /* 2log(KEYLENGTH) bits needed */ - struct tnode __rcu *parent; - struct rcu_head rcu; -- /* everything above this comment must be the same as rt_trie_node */ -- unsigned int full_children; /* KEYLENGTH bits needed */ -- unsigned int empty_children; /* KEYLENGTH bits needed */ -- struct rt_trie_node __rcu *child[0]; --}; -- --/* This struct represents the shared bits between tnode and leaf. If any -- * ordering is changed here is must also be updated in tnode and leaf as -- * well. -- */ --struct rt_trie_node { -- t_key key; -- unsigned char bits; -- unsigned char pos; -- struct tnode __rcu *parent; -- struct rcu_head rcu; --}; -- --struct leaf { -- t_key key; -- unsigned char bits; -- unsigned char pos; -- struct tnode __rcu *parent; -- struct rcu_head rcu; -- /* everything above this comment must be the same as rt_trie_node */ -- struct hlist_head list; -+ union { -+ /* The fields in this struct are valid if bits > 0 (TNODE) */ -+ struct { -+ unsigned int full_children; /* KEYLENGTH bits needed */ -+ unsigned int empty_children; /* KEYLENGTH bits needed */ -+ struct tnode __rcu *child[0]; -+ }; -+ /* This list pointer if valid if bits == 0 (LEAF) */ -+ struct hlist_head list; -+ }; - }; - - struct leaf_info { -@@ -154,15 +138,15 @@ struct trie_stat { - }; - - struct trie { -- struct rt_trie_node __rcu *trie; -+ struct tnode __rcu *trie; - #ifdef CONFIG_IP_FIB_TRIE_STATS - struct trie_use_stats __percpu *stats; - #endif - }; - --static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n, -+static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, - int wasfull); --static struct rt_trie_node *resize(struct trie *t, struct tnode *tn); -+static struct tnode *resize(struct trie *t, struct tnode *tn); - static struct tnode *inflate(struct trie *t, struct tnode *tn); - static struct tnode *halve(struct trie *t, struct tnode *tn); - /* tnodes to free after resize(); protected by RTNL */ -@@ -186,10 +170,10 @@ static struct kmem_cache *trie_leaf_kmem - #define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) - - /* wrapper for rcu_assign_pointer */ --static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr) -+static inline void node_set_parent(struct tnode *n, struct tnode *tp) - { -- if (node) -- rcu_assign_pointer(node->parent, ptr); -+ if (n) -+ rcu_assign_pointer(n->parent, tp); - } - - #define NODE_INIT_PARENT(n, p) RCU_INIT_POINTER((n)->parent, p) -@@ -205,7 +189,7 @@ static inline int tnode_child_length(con - /* - * caller must hold RTNL - */ --static inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i) -+static inline struct tnode *tnode_get_child(const struct tnode *tn, unsigned int i) - { - BUG_ON(i >= tnode_child_length(tn)); - -@@ -215,7 +199,7 @@ static inline struct rt_trie_node *tnode - /* - * caller must hold RCU read lock or RTNL - */ --static inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) -+static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) - { - BUG_ON(i >= tnode_child_length(tn)); - -@@ -340,11 +324,11 @@ static inline void alias_free_mem_rcu(st - } - - #define TNODE_KMALLOC_MAX \ -- ilog2((PAGE_SIZE - sizeof(struct tnode)) / sizeof(struct rt_trie_node *)) -+ ilog2((PAGE_SIZE - sizeof(struct tnode)) / sizeof(struct tnode *)) - - static void __node_free_rcu(struct rcu_head *head) - { -- struct rt_trie_node *n = container_of(head, struct rt_trie_node, rcu); -+ struct tnode *n = container_of(head, struct tnode, rcu); - - if (IS_LEAF(n)) - kmem_cache_free(trie_leaf_kmem, n); -@@ -395,9 +379,9 @@ static void tnode_free_flush(void) - } - } - --static struct leaf *leaf_new(t_key key) -+static struct tnode *leaf_new(t_key key) - { -- struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); -+ struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); - if (l) { - l->parent = NULL; - /* set key and pos to reflect full key value -@@ -444,7 +428,7 @@ static struct tnode *tnode_new(t_key key - } - - pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), -- sizeof(struct rt_trie_node *) << bits); -+ sizeof(struct tnode *) << bits); - return tn; - } - -@@ -453,13 +437,13 @@ static struct tnode *tnode_new(t_key key - * and no bits are skipped. See discussion in dyntree paper p. 6 - */ - --static inline int tnode_full(const struct tnode *tn, const struct rt_trie_node *n) -+static inline int tnode_full(const struct tnode *tn, const struct tnode *n) - { - return n && IS_TNODE(n) && (n->pos == (tn->pos + tn->bits)); - } - - static inline void put_child(struct tnode *tn, int i, -- struct rt_trie_node *n) -+ struct tnode *n) - { - tnode_put_child_reorg(tn, i, n, -1); - } -@@ -469,10 +453,10 @@ static inline void put_child(struct tnod - * Update the value of full_children and empty_children. - */ - --static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n, -+static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, - int wasfull) - { -- struct rt_trie_node *chi = rtnl_dereference(tn->child[i]); -+ struct tnode *chi = rtnl_dereference(tn->child[i]); - int isfull; - - BUG_ON(i >= 1<<tn->bits); -@@ -499,10 +483,9 @@ static void tnode_put_child_reorg(struct - } - - #define MAX_WORK 10 --static struct rt_trie_node *resize(struct trie *t, struct tnode *tn) -+static struct tnode *resize(struct trie *t, struct tnode *tn) - { -- struct rt_trie_node *n = NULL; -- struct tnode *old_tn; -+ struct tnode *old_tn, *n = NULL; - int inflate_threshold_use; - int halve_threshold_use; - int max_work; -@@ -614,7 +597,7 @@ static struct rt_trie_node *resize(struc - - /* Return if at least one inflate is run */ - if (max_work != MAX_WORK) -- return (struct rt_trie_node *) tn; -+ return tn; - - /* - * Halve as long as the number of empty children in this -@@ -650,13 +633,13 @@ no_children: - tnode_free_safe(tn); - return n; - } -- return (struct rt_trie_node *) tn; -+ return tn; - } - - - static void tnode_clean_free(struct tnode *tn) - { -- struct rt_trie_node *tofree; -+ struct tnode *tofree; - int i; - - for (i = 0; i < tnode_child_length(tn); i++) { -@@ -667,10 +650,10 @@ static void tnode_clean_free(struct tnod - node_free(tn); - } - --static struct tnode *inflate(struct trie *t, struct tnode *tn) -+static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) - { -- struct tnode *oldtnode = tn; -- int olen = tnode_child_length(tn); -+ int olen = tnode_child_length(oldtnode); -+ struct tnode *tn; - int i; - - pr_debug("In inflate\n"); -@@ -690,11 +673,8 @@ static struct tnode *inflate(struct trie - for (i = 0; i < olen; i++) { - struct tnode *inode; - -- inode = (struct tnode *) tnode_get_child(oldtnode, i); -- if (inode && -- IS_TNODE(inode) && -- inode->pos == oldtnode->pos + oldtnode->bits && -- inode->bits > 1) { -+ inode = tnode_get_child(oldtnode, i); -+ if (tnode_full(oldtnode, inode) && inode->bits > 1) { - struct tnode *left, *right; - t_key m = ~0U << (KEYLENGTH - 1) >> inode->pos; - -@@ -711,33 +691,29 @@ static struct tnode *inflate(struct trie - goto nomem; - } - -- put_child(tn, 2*i, (struct rt_trie_node *) left); -- put_child(tn, 2*i+1, (struct rt_trie_node *) right); -+ put_child(tn, 2*i, left); -+ put_child(tn, 2*i+1, right); - } - } - - for (i = 0; i < olen; i++) { -- struct tnode *inode; -- struct rt_trie_node *node = tnode_get_child(oldtnode, i); -+ struct tnode *inode = tnode_get_child(oldtnode, i); - struct tnode *left, *right; - int size, j; - - /* An empty child */ -- if (node == NULL) -+ if (inode == NULL) - continue; - - /* A leaf or an internal node with skipped bits */ -- -- if (IS_LEAF(node) || (node->pos > (tn->pos + tn->bits - 1))) { -+ if (!tnode_full(oldtnode, inode)) { - put_child(tn, -- tkey_extract_bits(node->key, oldtnode->pos, oldtnode->bits + 1), -- node); -+ tkey_extract_bits(inode->key, tn->pos, tn->bits), -+ inode); - continue; - } - - /* An internal node with two children */ -- inode = (struct tnode *) node; -- - if (inode->bits == 1) { - put_child(tn, 2*i, rtnl_dereference(inode->child[0])); - put_child(tn, 2*i+1, rtnl_dereference(inode->child[1])); -@@ -769,12 +745,12 @@ static struct tnode *inflate(struct trie - * bit to zero. - */ - -- left = (struct tnode *) tnode_get_child(tn, 2*i); -+ left = tnode_get_child(tn, 2*i); - put_child(tn, 2*i, NULL); - - BUG_ON(!left); - -- right = (struct tnode *) tnode_get_child(tn, 2*i+1); -+ right = tnode_get_child(tn, 2*i+1); - put_child(tn, 2*i+1, NULL); - - BUG_ON(!right); -@@ -796,12 +772,11 @@ nomem: - return ERR_PTR(-ENOMEM); - } - --static struct tnode *halve(struct trie *t, struct tnode *tn) -+static struct tnode *halve(struct trie *t, struct tnode *oldtnode) - { -- struct tnode *oldtnode = tn; -- struct rt_trie_node *left, *right; -+ int olen = tnode_child_length(oldtnode); -+ struct tnode *tn, *left, *right; - int i; -- int olen = tnode_child_length(tn); - - pr_debug("In halve\n"); - -@@ -830,7 +805,7 @@ static struct tnode *halve(struct trie * - if (!newn) - goto nomem; - -- put_child(tn, i/2, (struct rt_trie_node *)newn); -+ put_child(tn, i/2, newn); - } - - } -@@ -855,7 +830,7 @@ static struct tnode *halve(struct trie * - } - - /* Two nonempty children */ -- newBinNode = (struct tnode *) tnode_get_child(tn, i/2); -+ newBinNode = tnode_get_child(tn, i/2); - put_child(tn, i/2, NULL); - put_child(newBinNode, 0, left); - put_child(newBinNode, 1, right); -@@ -871,7 +846,7 @@ nomem: - /* readside must use rcu_read_lock currently dump routines - via get_fa_head and dump */ - --static struct leaf_info *find_leaf_info(struct leaf *l, int plen) -+static struct leaf_info *find_leaf_info(struct tnode *l, int plen) - { - struct hlist_head *head = &l->list; - struct leaf_info *li; -@@ -883,7 +858,7 @@ static struct leaf_info *find_leaf_info( - return NULL; - } - --static inline struct list_head *get_fa_head(struct leaf *l, int plen) -+static inline struct list_head *get_fa_head(struct tnode *l, int plen) - { - struct leaf_info *li = find_leaf_info(l, plen); - -@@ -915,32 +890,25 @@ static void insert_leaf_info(struct hlis - - /* rcu_read_lock needs to be hold by caller from readside */ - --static struct leaf * --fib_find_node(struct trie *t, u32 key) -+static struct tnode *fib_find_node(struct trie *t, u32 key) - { -- int pos; -- struct tnode *tn; -- struct rt_trie_node *n; -- -- pos = 0; -- n = rcu_dereference_rtnl(t->trie); -+ struct tnode *n = rcu_dereference_rtnl(t->trie); -+ int pos = 0; - - while (n && IS_TNODE(n)) { -- tn = (struct tnode *) n; -- -- if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { -- pos = tn->pos + tn->bits; -- n = tnode_get_child_rcu(tn, -+ if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) { -+ pos = n->pos + n->bits; -+ n = tnode_get_child_rcu(n, - tkey_extract_bits(key, -- tn->pos, -- tn->bits)); -+ n->pos, -+ n->bits)); - } else - break; - } - /* Case we have found a leaf. Compare prefixes */ - - if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) -- return (struct leaf *)n; -+ return n; - - return NULL; - } -@@ -956,14 +924,13 @@ static void trie_rebalance(struct trie * - while (tn != NULL && (tp = node_parent(tn)) != NULL) { - cindex = tkey_extract_bits(key, tp->pos, tp->bits); - wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); -- tn = (struct tnode *)resize(t, tn); -+ tn = resize(t, tn); - -- tnode_put_child_reorg(tp, cindex, -- (struct rt_trie_node *)tn, wasfull); -+ tnode_put_child_reorg(tp, cindex, tn, wasfull); - - tp = node_parent(tn); - if (!tp) -- rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); -+ rcu_assign_pointer(t->trie, tn); - - tnode_free_flush(); - if (!tp) -@@ -973,9 +940,9 @@ static void trie_rebalance(struct trie * - - /* Handle last (top) tnode */ - if (IS_TNODE(tn)) -- tn = (struct tnode *)resize(t, tn); -+ tn = resize(t, tn); - -- rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); -+ rcu_assign_pointer(t->trie, tn); - tnode_free_flush(); - } - -@@ -985,8 +952,8 @@ static struct list_head *fib_insert_node - { - int pos, newpos; - struct tnode *tp = NULL, *tn = NULL; -- struct rt_trie_node *n; -- struct leaf *l; -+ struct tnode *n; -+ struct tnode *l; - int missbit; - struct list_head *fa_head = NULL; - struct leaf_info *li; -@@ -1014,17 +981,15 @@ static struct list_head *fib_insert_node - */ - - while (n && IS_TNODE(n)) { -- tn = (struct tnode *) n; -- -- if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { -- tp = tn; -- pos = tn->pos + tn->bits; -- n = tnode_get_child(tn, -+ if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) { -+ tp = n; -+ pos = n->pos + n->bits; -+ n = tnode_get_child(n, - tkey_extract_bits(key, -- tn->pos, -- tn->bits)); -+ n->pos, -+ n->bits)); - -- BUG_ON(n && node_parent(n) != tn); -+ BUG_ON(n && node_parent(n) != tp); - } else - break; - } -@@ -1040,14 +1005,13 @@ static struct list_head *fib_insert_node - /* Case 1: n is a leaf. Compare prefixes */ - - if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) { -- l = (struct leaf *) n; - li = leaf_info_new(plen); - - if (!li) - return NULL; - - fa_head = &li->falh; -- insert_leaf_info(&l->list, li); -+ insert_leaf_info(&n->list, li); - goto done; - } - l = leaf_new(key); -@@ -1068,10 +1032,10 @@ static struct list_head *fib_insert_node - if (t->trie && n == NULL) { - /* Case 2: n is NULL, and will just insert a new leaf */ - -- node_set_parent((struct rt_trie_node *)l, tp); -+ node_set_parent(l, tp); - - cindex = tkey_extract_bits(key, tp->pos, tp->bits); -- put_child(tp, cindex, (struct rt_trie_node *)l); -+ put_child(tp, cindex, l); - } else { - /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ - /* -@@ -1094,17 +1058,17 @@ static struct list_head *fib_insert_node - return NULL; - } - -- node_set_parent((struct rt_trie_node *)tn, tp); -+ node_set_parent(tn, tp); - - missbit = tkey_extract_bits(key, newpos, 1); -- put_child(tn, missbit, (struct rt_trie_node *)l); -+ put_child(tn, missbit, l); - put_child(tn, 1-missbit, n); - - if (tp) { - cindex = tkey_extract_bits(key, tp->pos, tp->bits); -- put_child(tp, cindex, (struct rt_trie_node *)tn); -+ put_child(tp, cindex, tn); - } else { -- rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); -+ rcu_assign_pointer(t->trie, tn); - } - - tp = tn; -@@ -1134,7 +1098,7 @@ int fib_table_insert(struct fib_table *t - u8 tos = cfg->fc_tos; - u32 key, mask; - int err; -- struct leaf *l; -+ struct tnode *l; - - if (plen > 32) - return -EINVAL; -@@ -1292,7 +1256,7 @@ err: - } - - /* should be called with rcu_read_lock */ --static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, -+static int check_leaf(struct fib_table *tb, struct trie *t, struct tnode *l, - t_key key, const struct flowi4 *flp, - struct fib_result *res, int fib_flags) - { -@@ -1365,7 +1329,7 @@ int fib_table_lookup(struct fib_table *t - struct trie_use_stats __percpu *stats = t->stats; - #endif - int ret; -- struct rt_trie_node *n; -+ struct tnode *n; - struct tnode *pn; - unsigned int pos, bits; - t_key key = ntohl(flp->daddr); -@@ -1387,11 +1351,11 @@ int fib_table_lookup(struct fib_table *t - - /* Just a leaf? */ - if (IS_LEAF(n)) { -- ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags); -+ ret = check_leaf(tb, t, n, key, flp, res, fib_flags); - goto found; - } - -- pn = (struct tnode *) n; -+ pn = n; - chopped_off = 0; - - while (pn) { -@@ -1412,13 +1376,13 @@ int fib_table_lookup(struct fib_table *t - } - - if (IS_LEAF(n)) { -- ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags); -+ ret = check_leaf(tb, t, n, key, flp, res, fib_flags); - if (ret > 0) - goto backtrace; - goto found; - } - -- cn = (struct tnode *)n; -+ cn = n; - - /* - * It's a tnode, and we can do some extra checks here if we -@@ -1506,7 +1470,7 @@ int fib_table_lookup(struct fib_table *t - current_prefix_length = mp; - } - -- pn = (struct tnode *)n; /* Descend */ -+ pn = n; /* Descend */ - chopped_off = 0; - continue; - -@@ -1557,7 +1521,7 @@ EXPORT_SYMBOL_GPL(fib_table_lookup); - /* - * Remove the leaf and return parent. - */ --static void trie_leaf_remove(struct trie *t, struct leaf *l) -+static void trie_leaf_remove(struct trie *t, struct tnode *l) - { - struct tnode *tp = node_parent(l); - -@@ -1584,7 +1548,7 @@ int fib_table_delete(struct fib_table *t - u8 tos = cfg->fc_tos; - struct fib_alias *fa, *fa_to_delete; - struct list_head *fa_head; -- struct leaf *l; -+ struct tnode *l; - struct leaf_info *li; - - if (plen > 32) -@@ -1682,7 +1646,7 @@ static int trie_flush_list(struct list_h - return found; - } - --static int trie_flush_leaf(struct leaf *l) -+static int trie_flush_leaf(struct tnode *l) - { - int found = 0; - struct hlist_head *lih = &l->list; -@@ -1704,7 +1668,7 @@ static int trie_flush_leaf(struct leaf * - * Scan for the next right leaf starting at node p->child[idx] - * Since we have back pointer, no recursion necessary. - */ --static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c) -+static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) - { - do { - t_key idx; -@@ -1720,47 +1684,46 @@ static struct leaf *leaf_walk_rcu(struct - continue; - - if (IS_LEAF(c)) -- return (struct leaf *) c; -+ return c; - - /* Rescan start scanning in new node */ -- p = (struct tnode *) c; -+ p = c; - idx = 0; - } - - /* Node empty, walk back up to parent */ -- c = (struct rt_trie_node *) p; -+ c = p; - } while ((p = node_parent_rcu(c)) != NULL); - - return NULL; /* Root of trie */ - } - --static struct leaf *trie_firstleaf(struct trie *t) -+static struct tnode *trie_firstleaf(struct trie *t) - { -- struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie); -+ struct tnode *n = rcu_dereference_rtnl(t->trie); - - if (!n) - return NULL; - - if (IS_LEAF(n)) /* trie is just a leaf */ -- return (struct leaf *) n; -+ return n; - - return leaf_walk_rcu(n, NULL); - } - --static struct leaf *trie_nextleaf(struct leaf *l) -+static struct tnode *trie_nextleaf(struct tnode *l) - { -- struct rt_trie_node *c = (struct rt_trie_node *) l; -- struct tnode *p = node_parent_rcu(c); -+ struct tnode *p = node_parent_rcu(l); - - if (!p) - return NULL; /* trie with just one leaf */ - -- return leaf_walk_rcu(p, c); -+ return leaf_walk_rcu(p, l); - } - --static struct leaf *trie_leafindex(struct trie *t, int index) -+static struct tnode *trie_leafindex(struct trie *t, int index) - { -- struct leaf *l = trie_firstleaf(t); -+ struct tnode *l = trie_firstleaf(t); - - while (l && index-- > 0) - l = trie_nextleaf(l); -@@ -1775,7 +1738,7 @@ static struct leaf *trie_leafindex(struc - int fib_table_flush(struct fib_table *tb) - { - struct trie *t = (struct trie *) tb->tb_data; -- struct leaf *l, *ll = NULL; -+ struct tnode *l, *ll = NULL; - int found = 0; - - for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { -@@ -1840,7 +1803,7 @@ static int fn_trie_dump_fa(t_key key, in - return skb->len; - } - --static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb, -+static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, - struct sk_buff *skb, struct netlink_callback *cb) - { - struct leaf_info *li; -@@ -1876,7 +1839,7 @@ static int fn_trie_dump_leaf(struct leaf - int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, - struct netlink_callback *cb) - { -- struct leaf *l; -+ struct tnode *l; - struct trie *t = (struct trie *) tb->tb_data; - t_key key = cb->args[2]; - int count = cb->args[3]; -@@ -1922,7 +1885,7 @@ void __init fib_trie_init(void) - 0, SLAB_PANIC, NULL); - - trie_leaf_kmem = kmem_cache_create("ip_fib_trie", -- max(sizeof(struct leaf), -+ max(sizeof(struct tnode), - sizeof(struct leaf_info)), - 0, SLAB_PANIC, NULL); - } -@@ -1965,7 +1928,7 @@ struct fib_trie_iter { - unsigned int depth; - }; - --static struct rt_trie_node *fib_trie_get_next(struct fib_trie_iter *iter) -+static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) - { - struct tnode *tn = iter->tnode; - unsigned int cindex = iter->index; -@@ -1979,7 +1942,7 @@ static struct rt_trie_node *fib_trie_get - iter->tnode, iter->index, iter->depth); - rescan: - while (cindex < (1<<tn->bits)) { -- struct rt_trie_node *n = tnode_get_child_rcu(tn, cindex); -+ struct tnode *n = tnode_get_child_rcu(tn, cindex); - - if (n) { - if (IS_LEAF(n)) { -@@ -1987,7 +1950,7 @@ rescan: - iter->index = cindex + 1; - } else { - /* push down one level */ -- iter->tnode = (struct tnode *) n; -+ iter->tnode = n; - iter->index = 0; - ++iter->depth; - } -@@ -1998,7 +1961,7 @@ rescan: - } - - /* Current node exhausted, pop back up */ -- p = node_parent_rcu((struct rt_trie_node *)tn); -+ p = node_parent_rcu(tn); - if (p) { - cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1; - tn = p; -@@ -2010,10 +1973,10 @@ rescan: - return NULL; - } - --static struct rt_trie_node *fib_trie_get_first(struct fib_trie_iter *iter, -+static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter, - struct trie *t) - { -- struct rt_trie_node *n; -+ struct tnode *n; - - if (!t) - return NULL; -@@ -2023,7 +1986,7 @@ static struct rt_trie_node *fib_trie_get - return NULL; - - if (IS_TNODE(n)) { -- iter->tnode = (struct tnode *) n; -+ iter->tnode = n; - iter->index = 0; - iter->depth = 1; - } else { -@@ -2037,7 +2000,7 @@ static struct rt_trie_node *fib_trie_get - - static void trie_collect_stats(struct trie *t, struct trie_stat *s) - { -- struct rt_trie_node *n; -+ struct tnode *n; - struct fib_trie_iter iter; - - memset(s, 0, sizeof(*s)); -@@ -2045,7 +2008,6 @@ static void trie_collect_stats(struct tr - rcu_read_lock(); - for (n = fib_trie_get_first(&iter, t); n; n = fib_trie_get_next(&iter)) { - if (IS_LEAF(n)) { -- struct leaf *l = (struct leaf *)n; - struct leaf_info *li; - - s->leaves++; -@@ -2053,18 +2015,17 @@ static void trie_collect_stats(struct tr - if (iter.depth > s->maxdepth) - s->maxdepth = iter.depth; - -- hlist_for_each_entry_rcu(li, &l->list, hlist) -+ hlist_for_each_entry_rcu(li, &n->list, hlist) - ++s->prefixes; - } else { -- const struct tnode *tn = (const struct tnode *) n; - int i; - - s->tnodes++; -- if (tn->bits < MAX_STAT_DEPTH) -- s->nodesizes[tn->bits]++; -+ if (n->bits < MAX_STAT_DEPTH) -+ s->nodesizes[n->bits]++; - -- for (i = 0; i < (1<<tn->bits); i++) -- if (!tn->child[i]) -+ for (i = 0; i < tnode_child_length(n); i++) -+ if (!rcu_access_pointer(n->child[i])) - s->nullpointers++; - } - } -@@ -2088,7 +2049,7 @@ static void trie_show_stats(struct seq_f - seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth); - - seq_printf(seq, "\tLeaves: %u\n", stat->leaves); -- bytes = sizeof(struct leaf) * stat->leaves; -+ bytes = sizeof(struct tnode) * stat->leaves; - - seq_printf(seq, "\tPrefixes: %u\n", stat->prefixes); - bytes += sizeof(struct leaf_info) * stat->prefixes; -@@ -2109,7 +2070,7 @@ static void trie_show_stats(struct seq_f - seq_putc(seq, '\n'); - seq_printf(seq, "\tPointers: %u\n", pointers); - -- bytes += sizeof(struct rt_trie_node *) * pointers; -+ bytes += sizeof(struct tnode *) * pointers; - seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers); - seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024); - } -@@ -2163,7 +2124,7 @@ static int fib_triestat_seq_show(struct - seq_printf(seq, - "Basic info: size of leaf:" - " %Zd bytes, size of tnode: %Zd bytes.\n", -- sizeof(struct leaf), sizeof(struct tnode)); -+ sizeof(struct tnode), sizeof(struct tnode)); - - for (h = 0; h < FIB_TABLE_HASHSZ; h++) { - struct hlist_head *head = &net->ipv4.fib_table_hash[h]; -@@ -2202,7 +2163,7 @@ static const struct file_operations fib_ - .release = single_release_net, - }; - --static struct rt_trie_node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) -+static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos) - { - struct fib_trie_iter *iter = seq->private; - struct net *net = seq_file_net(seq); -@@ -2214,7 +2175,7 @@ static struct rt_trie_node *fib_trie_get - struct fib_table *tb; - - hlist_for_each_entry_rcu(tb, head, tb_hlist) { -- struct rt_trie_node *n; -+ struct tnode *n; - - for (n = fib_trie_get_first(iter, - (struct trie *) tb->tb_data); -@@ -2243,7 +2204,7 @@ static void *fib_trie_seq_next(struct se - struct fib_table *tb = iter->tb; - struct hlist_node *tb_node; - unsigned int h; -- struct rt_trie_node *n; -+ struct tnode *n; - - ++*pos; - /* next node in same table */ -@@ -2329,29 +2290,26 @@ static inline const char *rtn_type(char - static int fib_trie_seq_show(struct seq_file *seq, void *v) - { - const struct fib_trie_iter *iter = seq->private; -- struct rt_trie_node *n = v; -+ struct tnode *n = v; - - if (!node_parent_rcu(n)) - fib_table_print(seq, iter->tb); - - if (IS_TNODE(n)) { -- struct tnode *tn = (struct tnode *) n; -- __be32 prf = htonl(tn->key); -+ __be32 prf = htonl(n->key); - -- seq_indent(seq, iter->depth-1); -+ seq_indent(seq, iter->depth - 1); - seq_printf(seq, " +-- %pI4/%d %d %d %d\n", -- &prf, tn->pos, tn->bits, tn->full_children, -- tn->empty_children); -- -+ &prf, n->pos, n->bits, n->full_children, -+ n->empty_children); - } else { -- struct leaf *l = (struct leaf *) n; - struct leaf_info *li; -- __be32 val = htonl(l->key); -+ __be32 val = htonl(n->key); - - seq_indent(seq, iter->depth); - seq_printf(seq, " |-- %pI4\n", &val); - -- hlist_for_each_entry_rcu(li, &l->list, hlist) { -+ hlist_for_each_entry_rcu(li, &n->list, hlist) { - struct fib_alias *fa; - - list_for_each_entry_rcu(fa, &li->falh, fa_list) { -@@ -2401,9 +2359,9 @@ struct fib_route_iter { - t_key key; - }; - --static struct leaf *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) -+static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) - { -- struct leaf *l = NULL; -+ struct tnode *l = NULL; - struct trie *t = iter->main_trie; - - /* use cache location of last found key */ -@@ -2448,7 +2406,7 @@ static void *fib_route_seq_start(struct - static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) - { - struct fib_route_iter *iter = seq->private; -- struct leaf *l = v; -+ struct tnode *l = v; - - ++*pos; - if (v == SEQ_START_TOKEN) { -@@ -2494,7 +2452,7 @@ static unsigned int fib_flag_trans(int t - */ - static int fib_route_seq_show(struct seq_file *seq, void *v) - { -- struct leaf *l = v; -+ struct tnode *l = v; - struct leaf_info *li; - - if (v == SEQ_START_TOKEN) { diff --git a/target/linux/generic/pending-3.18/080-06-fib_trie-Optimize-fib_table_lookup-to-avoid-wasting-.patch b/target/linux/generic/pending-3.18/080-06-fib_trie-Optimize-fib_table_lookup-to-avoid-wasting-.patch deleted file mode 100644 index e84412687d..0000000000 --- a/target/linux/generic/pending-3.18/080-06-fib_trie-Optimize-fib_table_lookup-to-avoid-wasting-.patch +++ /dev/null @@ -1,343 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:55:54 -0800 -Subject: [PATCH] fib_trie: Optimize fib_table_lookup to avoid wasting - time on loops/variables - -This patch is meant to reduce the complexity of fib_table_lookup by reducing -the number of variables to the bare minimum while still keeping the same if -not improved functionality versus the original. - -Most of this change was started off by the desire to rid the function of -chopped_off and current_prefix_length as they actually added very little to -the function since they only applied when computing the cindex. I was able -to replace them mostly with just a check for the prefix match. As long as -the prefix between the key and the node being tested was the same we know -we can search the tnode fully versus just testing cindex 0. - -The second portion of the change ended up being a massive reordering. -Originally the calls to check_leaf were up near the start of the loop, and -the backtracing and descending into lower levels of tnodes was later. This -didn't make much sense as the structure of the tree means the leaves are -always the last thing to be tested. As such I reordered things so that we -instead have a loop that will delve into the tree and only exit when we -have either found a leaf or we have exhausted the tree. The advantage of -rearranging things like this is that we can fully inline check_leaf since -there is now only one reference to it in the function. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -90,6 +90,9 @@ typedef unsigned int t_key; - #define IS_TNODE(n) ((n)->bits) - #define IS_LEAF(n) (!(n)->bits) - -+#define get_shift(_kv) (KEYLENGTH - (_kv)->pos - (_kv)->bits) -+#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> get_shift(_kv)) -+ - struct tnode { - t_key key; - unsigned char bits; /* 2log(KEYLENGTH) bits needed */ -@@ -1281,7 +1284,7 @@ static int check_leaf(struct fib_table * - continue; - fib_alias_accessed(fa); - err = fib_props[fa->fa_type].error; -- if (err) { -+ if (unlikely(err < 0)) { - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->semantic_match_passed); - #endif -@@ -1303,7 +1306,7 @@ static int check_leaf(struct fib_table * - res->prefixlen = li->plen; - res->nh_sel = nhsel; - res->type = fa->fa_type; -- res->scope = fa->fa_info->fib_scope; -+ res->scope = fi->fib_scope; - res->fi = fi; - res->table = tb; - res->fa_head = &li->falh; -@@ -1321,23 +1324,24 @@ static int check_leaf(struct fib_table * - return 1; - } - -+static inline t_key prefix_mismatch(t_key key, struct tnode *n) -+{ -+ t_key prefix = n->key; -+ -+ return (key ^ prefix) & (prefix | -prefix); -+} -+ - int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, - struct fib_result *res, int fib_flags) - { -- struct trie *t = (struct trie *) tb->tb_data; -+ struct trie *t = (struct trie *)tb->tb_data; - #ifdef CONFIG_IP_FIB_TRIE_STATS - struct trie_use_stats __percpu *stats = t->stats; - #endif -- int ret; -- struct tnode *n; -- struct tnode *pn; -- unsigned int pos, bits; -- t_key key = ntohl(flp->daddr); -- unsigned int chopped_off; -- t_key cindex = 0; -- unsigned int current_prefix_length = KEYLENGTH; -- struct tnode *cn; -- t_key pref_mismatch; -+ const t_key key = ntohl(flp->daddr); -+ struct tnode *n, *pn; -+ t_key cindex; -+ int ret = 1; - - rcu_read_lock(); - -@@ -1349,170 +1353,102 @@ int fib_table_lookup(struct fib_table *t - this_cpu_inc(stats->gets); - #endif - -- /* Just a leaf? */ -- if (IS_LEAF(n)) { -- ret = check_leaf(tb, t, n, key, flp, res, fib_flags); -- goto found; -- } -- - pn = n; -- chopped_off = 0; -- -- while (pn) { -- pos = pn->pos; -- bits = pn->bits; -+ cindex = 0; - -- if (!chopped_off) -- cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length), -- pos, bits); -- -- n = tnode_get_child_rcu(pn, cindex); -- -- if (n == NULL) { --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(stats->null_node_hit); --#endif -- goto backtrace; -- } -+ /* Step 1: Travel to the longest prefix match in the trie */ -+ for (;;) { -+ unsigned long index = get_index(key, n); -+ -+ /* This bit of code is a bit tricky but it combines multiple -+ * checks into a single check. The prefix consists of the -+ * prefix plus zeros for the "bits" in the prefix. The index -+ * is the difference between the key and this value. From -+ * this we can actually derive several pieces of data. -+ * if !(index >> bits) -+ * we know the value is child index -+ * else -+ * we have a mismatch in skip bits and failed -+ */ -+ if (index >> n->bits) -+ break; - -- if (IS_LEAF(n)) { -- ret = check_leaf(tb, t, n, key, flp, res, fib_flags); -- if (ret > 0) -- goto backtrace; -+ /* we have found a leaf. Prefixes have already been compared */ -+ if (IS_LEAF(n)) - goto found; -- } -- -- cn = n; - -- /* -- * It's a tnode, and we can do some extra checks here if we -- * like, to avoid descending into a dead-end branch. -- * This tnode is in the parent's child array at index -- * key[p_pos..p_pos+p_bits] but potentially with some bits -- * chopped off, so in reality the index may be just a -- * subprefix, padded with zero at the end. -- * We can also take a look at any skipped bits in this -- * tnode - everything up to p_pos is supposed to be ok, -- * and the non-chopped bits of the index (se previous -- * paragraph) are also guaranteed ok, but the rest is -- * considered unknown. -- * -- * The skipped bits are key[pos+bits..cn->pos]. -- */ -- -- /* If current_prefix_length < pos+bits, we are already doing -- * actual prefix matching, which means everything from -- * pos+(bits-chopped_off) onward must be zero along some -- * branch of this subtree - otherwise there is *no* valid -- * prefix present. Here we can only check the skipped -- * bits. Remember, since we have already indexed into the -- * parent's child array, we know that the bits we chopped of -- * *are* zero. -+ /* only record pn and cindex if we are going to be chopping -+ * bits later. Otherwise we are just wasting cycles. - */ -- -- /* NOTA BENE: Checking only skipped bits -- for the new node here */ -- -- if (current_prefix_length < pos+bits) { -- if (tkey_extract_bits(cn->key, current_prefix_length, -- cn->pos - current_prefix_length) -- || !(cn->child[0])) -- goto backtrace; -+ if (index) { -+ pn = n; -+ cindex = index; - } - -- /* -- * If chopped_off=0, the index is fully validated and we -- * only need to look at the skipped bits for this, the new, -- * tnode. What we actually want to do is to find out if -- * these skipped bits match our key perfectly, or if we will -- * have to count on finding a matching prefix further down, -- * because if we do, we would like to have some way of -- * verifying the existence of such a prefix at this point. -- */ -- -- /* The only thing we can do at this point is to verify that -- * any such matching prefix can indeed be a prefix to our -- * key, and if the bits in the node we are inspecting that -- * do not match our key are not ZERO, this cannot be true. -- * Thus, find out where there is a mismatch (before cn->pos) -- * and verify that all the mismatching bits are zero in the -- * new tnode's key. -- */ -+ n = rcu_dereference(n->child[index]); -+ if (unlikely(!n)) -+ goto backtrace; -+ } - -- /* -- * Note: We aren't very concerned about the piece of -- * the key that precede pn->pos+pn->bits, since these -- * have already been checked. The bits after cn->pos -- * aren't checked since these are by definition -- * "unknown" at this point. Thus, what we want to see -- * is if we are about to enter the "prefix matching" -- * state, and in that case verify that the skipped -- * bits that will prevail throughout this subtree are -- * zero, as they have to be if we are to find a -- * matching prefix. -+ /* Step 2: Sort out leaves and begin backtracing for longest prefix */ -+ for (;;) { -+ /* record the pointer where our next node pointer is stored */ -+ struct tnode __rcu **cptr = n->child; -+ -+ /* This test verifies that none of the bits that differ -+ * between the key and the prefix exist in the region of -+ * the lsb and higher in the prefix. - */ -+ if (unlikely(prefix_mismatch(key, n))) -+ goto backtrace; - -- pref_mismatch = mask_pfx(cn->key ^ key, cn->pos); -+ /* exit out and process leaf */ -+ if (unlikely(IS_LEAF(n))) -+ break; - -- /* -- * In short: If skipped bits in this node do not match -- * the search key, enter the "prefix matching" -- * state.directly. -+ /* Don't bother recording parent info. Since we are in -+ * prefix match mode we will have to come back to wherever -+ * we started this traversal anyway - */ -- if (pref_mismatch) { -- /* fls(x) = __fls(x) + 1 */ -- int mp = KEYLENGTH - __fls(pref_mismatch) - 1; -- -- if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0) -- goto backtrace; -- -- if (current_prefix_length >= cn->pos) -- current_prefix_length = mp; -- } -- -- pn = n; /* Descend */ -- chopped_off = 0; -- continue; - -+ while ((n = rcu_dereference(*cptr)) == NULL) { - backtrace: -- chopped_off++; -- -- /* As zero don't change the child key (cindex) */ -- while ((chopped_off <= pn->bits) -- && !(cindex & (1<<(chopped_off-1)))) -- chopped_off++; -- -- /* Decrease current_... with bits chopped off */ -- if (current_prefix_length > pn->pos + pn->bits - chopped_off) -- current_prefix_length = pn->pos + pn->bits -- - chopped_off; -- -- /* -- * Either we do the actual chop off according or if we have -- * chopped off all bits in this tnode walk up to our parent. -- */ -- -- if (chopped_off <= pn->bits) { -- cindex &= ~(1 << (chopped_off-1)); -- } else { -- struct tnode *parent = node_parent_rcu(pn); -- if (!parent) -- goto failed; -- -- /* Get Child's index */ -- cindex = tkey_extract_bits(pn->key, parent->pos, parent->bits); -- pn = parent; -- chopped_off = 0; -- - #ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(stats->backtrack); -+ if (!n) -+ this_cpu_inc(stats->null_node_hit); - #endif -- goto backtrace; -+ /* If we are at cindex 0 there are no more bits for -+ * us to strip at this level so we must ascend back -+ * up one level to see if there are any more bits to -+ * be stripped there. -+ */ -+ while (!cindex) { -+ t_key pkey = pn->key; -+ -+ pn = node_parent_rcu(pn); -+ if (unlikely(!pn)) -+ goto failed; -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(stats->backtrack); -+#endif -+ /* Get Child's index */ -+ cindex = get_index(pkey, pn); -+ } -+ -+ /* strip the least significant bit from the cindex */ -+ cindex &= cindex - 1; -+ -+ /* grab pointer for next child node */ -+ cptr = &pn->child[cindex]; - } - } --failed: -- ret = 1; -+ - found: -+ /* Step 3: Process the leaf, if that fails fall back to backtracing */ -+ ret = check_leaf(tb, t, n, key, flp, res, fib_flags); -+ if (unlikely(ret > 0)) -+ goto backtrace; -+failed: - rcu_read_unlock(); - return ret; - } diff --git a/target/linux/generic/pending-3.18/080-07-fib_trie-Optimize-fib_find_node.patch b/target/linux/generic/pending-3.18/080-07-fib_trie-Optimize-fib_find_node.patch deleted file mode 100644 index 0193f758f6..0000000000 --- a/target/linux/generic/pending-3.18/080-07-fib_trie-Optimize-fib_find_node.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:00 -0800 -Subject: [PATCH] fib_trie: Optimize fib_find_node - -This patch makes use of the same features I made use of for -fib_table_lookup to streamline fib_find_node. The resultant code should be -smaller and run faster than the original. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -892,28 +892,34 @@ static void insert_leaf_info(struct hlis - } - - /* rcu_read_lock needs to be hold by caller from readside */ -- - static struct tnode *fib_find_node(struct trie *t, u32 key) - { - struct tnode *n = rcu_dereference_rtnl(t->trie); -- int pos = 0; - -- while (n && IS_TNODE(n)) { -- if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) { -- pos = n->pos + n->bits; -- n = tnode_get_child_rcu(n, -- tkey_extract_bits(key, -- n->pos, -- n->bits)); -- } else -+ while (n) { -+ unsigned long index = get_index(key, n); -+ -+ /* This bit of code is a bit tricky but it combines multiple -+ * checks into a single check. The prefix consists of the -+ * prefix plus zeros for the bits in the cindex. The index -+ * is the difference between the key and this value. From -+ * this we can actually derive several pieces of data. -+ * if !(index >> bits) -+ * we know the value is cindex -+ * else -+ * we have a mismatch in skip bits and failed -+ */ -+ if (index >> n->bits) -+ return NULL; -+ -+ /* we have found a leaf. Prefixes have already been compared */ -+ if (IS_LEAF(n)) - break; -- } -- /* Case we have found a leaf. Compare prefixes */ - -- if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) -- return n; -+ n = rcu_dereference_rtnl(n->child[index]); -+ } - -- return NULL; -+ return n; - } - - static void trie_rebalance(struct trie *t, struct tnode *tn) diff --git a/target/linux/generic/pending-3.18/080-08-fib_trie-Optimize-fib_table_insert.patch b/target/linux/generic/pending-3.18/080-08-fib_trie-Optimize-fib_table_insert.patch deleted file mode 100644 index b328d2c5d2..0000000000 --- a/target/linux/generic/pending-3.18/080-08-fib_trie-Optimize-fib_table_insert.patch +++ /dev/null @@ -1,276 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:06 -0800 -Subject: [PATCH] fib_trie: Optimize fib_table_insert - -This patch updates the fib_table_insert function to take advantage of the -changes made to improve the performance of fib_table_lookup. As a result -the code should be smaller and run faster then the original. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -222,31 +222,6 @@ static inline t_key tkey_extract_bits(t_ - return 0; - } - --static inline int tkey_equals(t_key a, t_key b) --{ -- return a == b; --} -- --static inline int tkey_sub_equals(t_key a, int offset, int bits, t_key b) --{ -- if (bits == 0 || offset >= KEYLENGTH) -- return 1; -- bits = bits > KEYLENGTH ? KEYLENGTH : bits; -- return ((a ^ b) << offset) >> (KEYLENGTH - bits) == 0; --} -- --static inline int tkey_mismatch(t_key a, int offset, t_key b) --{ -- t_key diff = a ^ b; -- int i = offset; -- -- if (!diff) -- return 0; -- while ((diff << i) >> (KEYLENGTH-1) == 0) -- i++; -- return i; --} -- - /* - To understand this stuff, an understanding of keys and all their bits is - necessary. Every node in the trie has a key associated with it, but not -@@ -485,6 +460,15 @@ static void tnode_put_child_reorg(struct - rcu_assign_pointer(tn->child[i], n); - } - -+static void put_child_root(struct tnode *tp, struct trie *t, -+ t_key key, struct tnode *n) -+{ -+ if (tp) -+ put_child(tp, get_index(key, tp), n); -+ else -+ rcu_assign_pointer(t->trie, n); -+} -+ - #define MAX_WORK 10 - static struct tnode *resize(struct trie *t, struct tnode *tn) - { -@@ -959,138 +943,100 @@ static void trie_rebalance(struct trie * - - static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) - { -- int pos, newpos; -- struct tnode *tp = NULL, *tn = NULL; -- struct tnode *n; -- struct tnode *l; -- int missbit; - struct list_head *fa_head = NULL; -+ struct tnode *l, *n, *tp = NULL; - struct leaf_info *li; -- t_key cindex; - -- pos = 0; -+ li = leaf_info_new(plen); -+ if (!li) -+ return NULL; -+ fa_head = &li->falh; -+ - n = rtnl_dereference(t->trie); - - /* If we point to NULL, stop. Either the tree is empty and we should - * just put a new leaf in if, or we have reached an empty child slot, - * and we should just put our new leaf in that. -- * If we point to a T_TNODE, check if it matches our key. Note that -- * a T_TNODE might be skipping any number of bits - its 'pos' need -- * not be the parent's 'pos'+'bits'! -- * -- * If it does match the current key, get pos/bits from it, extract -- * the index from our key, push the T_TNODE and walk the tree. -- * -- * If it doesn't, we have to replace it with a new T_TNODE. - * -- * If we point to a T_LEAF, it might or might not have the same key -- * as we do. If it does, just change the value, update the T_LEAF's -- * value, and return it. -- * If it doesn't, we need to replace it with a T_TNODE. -+ * If we hit a node with a key that does't match then we should stop -+ * and create a new tnode to replace that node and insert ourselves -+ * and the other node into the new tnode. - */ -+ while (n) { -+ unsigned long index = get_index(key, n); - -- while (n && IS_TNODE(n)) { -- if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) { -- tp = n; -- pos = n->pos + n->bits; -- n = tnode_get_child(n, -- tkey_extract_bits(key, -- n->pos, -- n->bits)); -- -- BUG_ON(n && node_parent(n) != tp); -- } else -+ /* This bit of code is a bit tricky but it combines multiple -+ * checks into a single check. The prefix consists of the -+ * prefix plus zeros for the "bits" in the prefix. The index -+ * is the difference between the key and this value. From -+ * this we can actually derive several pieces of data. -+ * if !(index >> bits) -+ * we know the value is child index -+ * else -+ * we have a mismatch in skip bits and failed -+ */ -+ if (index >> n->bits) - break; -- } -- -- /* -- * n ----> NULL, LEAF or TNODE -- * -- * tp is n's (parent) ----> NULL or TNODE -- */ - -- BUG_ON(tp && IS_LEAF(tp)); -- -- /* Case 1: n is a leaf. Compare prefixes */ -- -- if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) { -- li = leaf_info_new(plen); -- -- if (!li) -- return NULL; -+ /* we have found a leaf. Prefixes have already been compared */ -+ if (IS_LEAF(n)) { -+ /* Case 1: n is a leaf, and prefixes match*/ -+ insert_leaf_info(&n->list, li); -+ return fa_head; -+ } - -- fa_head = &li->falh; -- insert_leaf_info(&n->list, li); -- goto done; -+ tp = n; -+ n = rcu_dereference_rtnl(n->child[index]); - } -- l = leaf_new(key); -- -- if (!l) -- return NULL; - -- li = leaf_info_new(plen); -- -- if (!li) { -- node_free(l); -+ l = leaf_new(key); -+ if (!l) { -+ free_leaf_info(li); - return NULL; - } - -- fa_head = &li->falh; - insert_leaf_info(&l->list, li); - -- if (t->trie && n == NULL) { -- /* Case 2: n is NULL, and will just insert a new leaf */ -- -- node_set_parent(l, tp); -- -- cindex = tkey_extract_bits(key, tp->pos, tp->bits); -- put_child(tp, cindex, l); -- } else { -- /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ -- /* -- * Add a new tnode here -- * first tnode need some special handling -- */ -+ /* Case 2: n is a LEAF or a TNODE and the key doesn't match. -+ * -+ * Add a new tnode here -+ * first tnode need some special handling -+ * leaves us in position for handling as case 3 -+ */ -+ if (n) { -+ struct tnode *tn; -+ int newpos; - -- if (n) { -- pos = tp ? tp->pos+tp->bits : 0; -- newpos = tkey_mismatch(key, pos, n->key); -- tn = tnode_new(n->key, newpos, 1); -- } else { -- newpos = 0; -- tn = tnode_new(key, newpos, 1); /* First tnode */ -- } -+ newpos = KEYLENGTH - __fls(n->key ^ key) - 1; - -+ tn = tnode_new(key, newpos, 1); - if (!tn) { - free_leaf_info(li); - node_free(l); - return NULL; - } - -- node_set_parent(tn, tp); -- -- missbit = tkey_extract_bits(key, newpos, 1); -- put_child(tn, missbit, l); -- put_child(tn, 1-missbit, n); -- -- if (tp) { -- cindex = tkey_extract_bits(key, tp->pos, tp->bits); -- put_child(tp, cindex, tn); -- } else { -- rcu_assign_pointer(t->trie, tn); -- } -+ /* initialize routes out of node */ -+ NODE_INIT_PARENT(tn, tp); -+ put_child(tn, get_index(key, tn) ^ 1, n); -+ -+ /* start adding routes into the node */ -+ put_child_root(tp, t, key, tn); -+ node_set_parent(n, tn); - -+ /* parent now has a NULL spot where the leaf can go */ - tp = tn; - } - -- if (tp && tp->pos + tp->bits > 32) -- pr_warn("fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n", -- tp, tp->pos, tp->bits, key, plen); -- -- /* Rebalance the trie */ -+ /* Case 3: n is NULL, and will just insert a new leaf */ -+ if (tp) { -+ NODE_INIT_PARENT(l, tp); -+ put_child(tp, get_index(key, tp), l); -+ trie_rebalance(t, tp); -+ } else { -+ rcu_assign_pointer(t->trie, l); -+ } - -- trie_rebalance(t, tp); --done: - return fa_head; - } - -@@ -1470,11 +1416,11 @@ static void trie_leaf_remove(struct trie - pr_debug("entering trie_leaf_remove(%p)\n", l); - - if (tp) { -- t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); -- put_child(tp, cindex, NULL); -+ put_child(tp, get_index(l->key, tp), NULL); - trie_rebalance(t, tp); -- } else -+ } else { - RCU_INIT_POINTER(t->trie, NULL); -+ } - - node_free(l); - } diff --git a/target/linux/generic/pending-3.18/080-09-fib_trie-Update-meaning-of-pos-to-represent-unchecke.patch b/target/linux/generic/pending-3.18/080-09-fib_trie-Update-meaning-of-pos-to-represent-unchecke.patch deleted file mode 100644 index a0d34762b8..0000000000 --- a/target/linux/generic/pending-3.18/080-09-fib_trie-Update-meaning-of-pos-to-represent-unchecke.patch +++ /dev/null @@ -1,346 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:12 -0800 -Subject: [PATCH] fib_trie: Update meaning of pos to represent unchecked - bits - -This change moves the pos value to the other side of the "bits" field. By -doing this it actually simplifies a significant amount of code in the trie. - -For example when halving a tree we know that the bit lost exists at -oldnode->pos, and if we inflate the tree the new bit being add is at -tn->pos. Previously to find those bits you would have to subtract pos and -bits from the keylength or start with a value of (1 << 31) and then shift -that. - -There are a number of spots throughout the code that benefit from this. In -the case of the hot-path searches the main advantage is that we can drop 2 -or more operations from the search path as we no longer need to compute the -value for the index to be shifted by and can instead just use the raw pos -value. - -In addition the tkey_extract_bits is now defunct and can be replaced by -get_index since the two operations were doing the same thing, but now -get_index does it much more quickly as it is only an xor and shift versus a -pair of shifts and a subtraction. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -90,8 +90,7 @@ typedef unsigned int t_key; - #define IS_TNODE(n) ((n)->bits) - #define IS_LEAF(n) (!(n)->bits) - --#define get_shift(_kv) (KEYLENGTH - (_kv)->pos - (_kv)->bits) --#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> get_shift(_kv)) -+#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos) - - struct tnode { - t_key key; -@@ -209,81 +208,64 @@ static inline struct tnode *tnode_get_ch - return rcu_dereference_rtnl(tn->child[i]); - } - --static inline t_key mask_pfx(t_key k, unsigned int l) --{ -- return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l); --} -- --static inline t_key tkey_extract_bits(t_key a, unsigned int offset, unsigned int bits) --{ -- if (offset < KEYLENGTH) -- return ((t_key)(a << offset)) >> (KEYLENGTH - bits); -- else -- return 0; --} -- --/* -- To understand this stuff, an understanding of keys and all their bits is -- necessary. Every node in the trie has a key associated with it, but not -- all of the bits in that key are significant. -- -- Consider a node 'n' and its parent 'tp'. -- -- If n is a leaf, every bit in its key is significant. Its presence is -- necessitated by path compression, since during a tree traversal (when -- searching for a leaf - unless we are doing an insertion) we will completely -- ignore all skipped bits we encounter. Thus we need to verify, at the end of -- a potentially successful search, that we have indeed been walking the -- correct key path. -- -- Note that we can never "miss" the correct key in the tree if present by -- following the wrong path. Path compression ensures that segments of the key -- that are the same for all keys with a given prefix are skipped, but the -- skipped part *is* identical for each node in the subtrie below the skipped -- bit! trie_insert() in this implementation takes care of that - note the -- call to tkey_sub_equals() in trie_insert(). -- -- if n is an internal node - a 'tnode' here, the various parts of its key -- have many different meanings. -- -- Example: -- _________________________________________________________________ -- | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C | -- ----------------------------------------------------------------- -- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -- -- _________________________________________________________________ -- | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u | -- ----------------------------------------------------------------- -- 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -- -- tp->pos = 7 -- tp->bits = 3 -- n->pos = 15 -- n->bits = 4 -- -- First, let's just ignore the bits that come before the parent tp, that is -- the bits from 0 to (tp->pos-1). They are *known* but at this point we do -- not use them for anything. -- -- The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the -- index into the parent's child array. That is, they will be used to find -- 'n' among tp's children. -- -- The bits from (tp->pos + tp->bits) to (n->pos - 1) - "S" - are skipped bits -- for the node n. -- -- All the bits we have seen so far are significant to the node n. The rest -- of the bits are really not needed or indeed known in n->key. -- -- The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into -- n's child array, and will of course be different for each child. -- -- -- The rest of the bits, from (n->pos + n->bits) onward, are completely unknown -- at this point. -- --*/ -+/* To understand this stuff, an understanding of keys and all their bits is -+ * necessary. Every node in the trie has a key associated with it, but not -+ * all of the bits in that key are significant. -+ * -+ * Consider a node 'n' and its parent 'tp'. -+ * -+ * If n is a leaf, every bit in its key is significant. Its presence is -+ * necessitated by path compression, since during a tree traversal (when -+ * searching for a leaf - unless we are doing an insertion) we will completely -+ * ignore all skipped bits we encounter. Thus we need to verify, at the end of -+ * a potentially successful search, that we have indeed been walking the -+ * correct key path. -+ * -+ * Note that we can never "miss" the correct key in the tree if present by -+ * following the wrong path. Path compression ensures that segments of the key -+ * that are the same for all keys with a given prefix are skipped, but the -+ * skipped part *is* identical for each node in the subtrie below the skipped -+ * bit! trie_insert() in this implementation takes care of that. -+ * -+ * if n is an internal node - a 'tnode' here, the various parts of its key -+ * have many different meanings. -+ * -+ * Example: -+ * _________________________________________________________________ -+ * | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C | -+ * ----------------------------------------------------------------- -+ * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 -+ * -+ * _________________________________________________________________ -+ * | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u | -+ * ----------------------------------------------------------------- -+ * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -+ * -+ * tp->pos = 22 -+ * tp->bits = 3 -+ * n->pos = 13 -+ * n->bits = 4 -+ * -+ * First, let's just ignore the bits that come before the parent tp, that is -+ * the bits from (tp->pos + tp->bits) to 31. They are *known* but at this -+ * point we do not use them for anything. -+ * -+ * The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the -+ * index into the parent's child array. That is, they will be used to find -+ * 'n' among tp's children. -+ * -+ * The bits from (n->pos + n->bits) to (tn->pos - 1) - "S" - are skipped bits -+ * for the node n. -+ * -+ * All the bits we have seen so far are significant to the node n. The rest -+ * of the bits are really not needed or indeed known in n->key. -+ * -+ * The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into -+ * n's child array, and will of course be different for each child. -+ * -+ * The rest of the bits, from 0 to (n->pos + n->bits), are completely unknown -+ * at this point. -+ */ - - static const int halve_threshold = 25; - static const int inflate_threshold = 50; -@@ -367,7 +349,7 @@ static struct tnode *leaf_new(t_key key) - * as the nodes are searched - */ - l->key = key; -- l->pos = KEYLENGTH; -+ l->pos = 0; - /* set bits to 0 indicating we are not a tnode */ - l->bits = 0; - -@@ -400,7 +382,7 @@ static struct tnode *tnode_new(t_key key - tn->parent = NULL; - tn->pos = pos; - tn->bits = bits; -- tn->key = mask_pfx(key, pos); -+ tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; - tn->full_children = 0; - tn->empty_children = 1<<bits; - } -@@ -410,14 +392,12 @@ static struct tnode *tnode_new(t_key key - return tn; - } - --/* -- * Check whether a tnode 'n' is "full", i.e. it is an internal node -+/* Check whether a tnode 'n' is "full", i.e. it is an internal node - * and no bits are skipped. See discussion in dyntree paper p. 6 - */ -- - static inline int tnode_full(const struct tnode *tn, const struct tnode *n) - { -- return n && IS_TNODE(n) && (n->pos == (tn->pos + tn->bits)); -+ return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); - } - - static inline void put_child(struct tnode *tn, int i, -@@ -641,11 +621,12 @@ static struct tnode *inflate(struct trie - { - int olen = tnode_child_length(oldtnode); - struct tnode *tn; -+ t_key m; - int i; - - pr_debug("In inflate\n"); - -- tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1); -+ tn = tnode_new(oldtnode->key, oldtnode->pos - 1, oldtnode->bits + 1); - - if (!tn) - return ERR_PTR(-ENOMEM); -@@ -656,21 +637,18 @@ static struct tnode *inflate(struct trie - * fails. In case of failure we return the oldnode and inflate - * of tnode is ignored. - */ -+ for (i = 0, m = 1u << tn->pos; i < olen; i++) { -+ struct tnode *inode = tnode_get_child(oldtnode, i); - -- for (i = 0; i < olen; i++) { -- struct tnode *inode; -- -- inode = tnode_get_child(oldtnode, i); -- if (tnode_full(oldtnode, inode) && inode->bits > 1) { -+ if (tnode_full(oldtnode, inode) && (inode->bits > 1)) { - struct tnode *left, *right; -- t_key m = ~0U << (KEYLENGTH - 1) >> inode->pos; - -- left = tnode_new(inode->key&(~m), inode->pos + 1, -+ left = tnode_new(inode->key & ~m, inode->pos, - inode->bits - 1); - if (!left) - goto nomem; - -- right = tnode_new(inode->key|m, inode->pos + 1, -+ right = tnode_new(inode->key | m, inode->pos, - inode->bits - 1); - - if (!right) { -@@ -694,9 +672,7 @@ static struct tnode *inflate(struct trie - - /* A leaf or an internal node with skipped bits */ - if (!tnode_full(oldtnode, inode)) { -- put_child(tn, -- tkey_extract_bits(inode->key, tn->pos, tn->bits), -- inode); -+ put_child(tn, get_index(inode->key, tn), inode); - continue; - } - -@@ -767,7 +743,7 @@ static struct tnode *halve(struct trie * - - pr_debug("In halve\n"); - -- tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1); -+ tn = tnode_new(oldtnode->key, oldtnode->pos + 1, oldtnode->bits - 1); - - if (!tn) - return ERR_PTR(-ENOMEM); -@@ -787,7 +763,7 @@ static struct tnode *halve(struct trie * - if (left && right) { - struct tnode *newn; - -- newn = tnode_new(left->key, tn->pos + tn->bits, 1); -+ newn = tnode_new(left->key, oldtnode->pos, 1); - - if (!newn) - goto nomem; -@@ -915,7 +891,7 @@ static void trie_rebalance(struct trie * - key = tn->key; - - while (tn != NULL && (tp = node_parent(tn)) != NULL) { -- cindex = tkey_extract_bits(key, tp->pos, tp->bits); -+ cindex = get_index(key, tp); - wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); - tn = resize(t, tn); - -@@ -1005,11 +981,8 @@ static struct list_head *fib_insert_node - */ - if (n) { - struct tnode *tn; -- int newpos; -- -- newpos = KEYLENGTH - __fls(n->key ^ key) - 1; - -- tn = tnode_new(key, newpos, 1); -+ tn = tnode_new(key, __fls(key ^ n->key), 1); - if (!tn) { - free_leaf_info(li); - node_free(l); -@@ -1559,12 +1532,7 @@ static int trie_flush_leaf(struct tnode - static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) - { - do { -- t_key idx; -- -- if (c) -- idx = tkey_extract_bits(c->key, p->pos, p->bits) + 1; -- else -- idx = 0; -+ t_key idx = c ? idx = get_index(c->key, p) + 1 : 0; - - while (idx < 1u << p->bits) { - c = tnode_get_child_rcu(p, idx++); -@@ -1851,7 +1819,7 @@ rescan: - /* Current node exhausted, pop back up */ - p = node_parent_rcu(tn); - if (p) { -- cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1; -+ cindex = get_index(tn->key, p) + 1; - tn = p; - --iter->depth; - goto rescan; -@@ -2186,10 +2154,10 @@ static int fib_trie_seq_show(struct seq_ - if (IS_TNODE(n)) { - __be32 prf = htonl(n->key); - -- seq_indent(seq, iter->depth - 1); -- seq_printf(seq, " +-- %pI4/%d %d %d %d\n", -- &prf, n->pos, n->bits, n->full_children, -- n->empty_children); -+ seq_indent(seq, iter->depth-1); -+ seq_printf(seq, " +-- %pI4/%zu %u %u %u\n", -+ &prf, KEYLENGTH - n->pos - n->bits, n->bits, -+ n->full_children, n->empty_children); - } else { - struct leaf_info *li; - __be32 val = htonl(n->key); diff --git a/target/linux/generic/pending-3.18/080-10-fib_trie-Use-unsigned-long-for-anything-dealing-with.patch b/target/linux/generic/pending-3.18/080-10-fib_trie-Use-unsigned-long-for-anything-dealing-with.patch deleted file mode 100644 index 487a25f0d9..0000000000 --- a/target/linux/generic/pending-3.18/080-10-fib_trie-Use-unsigned-long-for-anything-dealing-with.patch +++ /dev/null @@ -1,186 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:18 -0800 -Subject: [PATCH] fib_trie: Use unsigned long for anything dealing with a - shift by bits - -This change makes it so that anything that can be shifted by, or compared -to a value shifted by bits is updated to be an unsigned long. This is -mostly a precaution against an insanely huge address space that somehow -starts coming close to the 2^32 root node size which would require -something like 1.5 billion addresses. - -I chose unsigned long instead of unsigned long long since I do not believe -it is possible to allocate a 32 bit tnode on a 32 bit system as the memory -consumed would be 16GB + 28B which exceeds the addressible space for any -one process. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -146,8 +146,8 @@ struct trie { - #endif - }; - --static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, -- int wasfull); -+static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, -+ struct tnode *n, int wasfull); - static struct tnode *resize(struct trie *t, struct tnode *tn); - static struct tnode *inflate(struct trie *t, struct tnode *tn); - static struct tnode *halve(struct trie *t, struct tnode *tn); -@@ -183,25 +183,23 @@ static inline void node_set_parent(struc - /* This provides us with the number of children in this node, in the case of a - * leaf this will return 0 meaning none of the children are accessible. - */ --static inline int tnode_child_length(const struct tnode *tn) -+static inline unsigned long tnode_child_length(const struct tnode *tn) - { - return (1ul << tn->bits) & ~(1ul); - } - --/* -- * caller must hold RTNL -- */ --static inline struct tnode *tnode_get_child(const struct tnode *tn, unsigned int i) -+/* caller must hold RTNL */ -+static inline struct tnode *tnode_get_child(const struct tnode *tn, -+ unsigned long i) - { - BUG_ON(i >= tnode_child_length(tn)); - - return rtnl_dereference(tn->child[i]); - } - --/* -- * caller must hold RCU read lock or RTNL -- */ --static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) -+/* caller must hold RCU read lock or RTNL */ -+static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, -+ unsigned long i) - { - BUG_ON(i >= tnode_child_length(tn)); - -@@ -400,7 +398,7 @@ static inline int tnode_full(const struc - return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); - } - --static inline void put_child(struct tnode *tn, int i, -+static inline void put_child(struct tnode *tn, unsigned long i, - struct tnode *n) - { - tnode_put_child_reorg(tn, i, n, -1); -@@ -411,13 +409,13 @@ static inline void put_child(struct tnod - * Update the value of full_children and empty_children. - */ - --static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, -- int wasfull) -+static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, -+ struct tnode *n, int wasfull) - { - struct tnode *chi = rtnl_dereference(tn->child[i]); - int isfull; - -- BUG_ON(i >= 1<<tn->bits); -+ BUG_ON(i >= tnode_child_length(tn)); - - /* update emptyChildren */ - if (n == NULL && chi != NULL) -@@ -607,10 +605,10 @@ no_children: - static void tnode_clean_free(struct tnode *tn) - { - struct tnode *tofree; -- int i; -+ unsigned long i; - - for (i = 0; i < tnode_child_length(tn); i++) { -- tofree = rtnl_dereference(tn->child[i]); -+ tofree = tnode_get_child(tn, i); - if (tofree) - node_free(tofree); - } -@@ -619,10 +617,10 @@ static void tnode_clean_free(struct tnod - - static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) - { -- int olen = tnode_child_length(oldtnode); -+ unsigned long olen = tnode_child_length(oldtnode); - struct tnode *tn; -+ unsigned long i; - t_key m; -- int i; - - pr_debug("In inflate\n"); - -@@ -664,7 +662,7 @@ static struct tnode *inflate(struct trie - for (i = 0; i < olen; i++) { - struct tnode *inode = tnode_get_child(oldtnode, i); - struct tnode *left, *right; -- int size, j; -+ unsigned long size, j; - - /* An empty child */ - if (inode == NULL) -@@ -737,7 +735,7 @@ nomem: - - static struct tnode *halve(struct trie *t, struct tnode *oldtnode) - { -- int olen = tnode_child_length(oldtnode); -+ unsigned long olen = tnode_child_length(oldtnode); - struct tnode *tn, *left, *right; - int i; - -@@ -1532,9 +1530,9 @@ static int trie_flush_leaf(struct tnode - static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) - { - do { -- t_key idx = c ? idx = get_index(c->key, p) + 1 : 0; -+ unsigned long idx = c ? idx = get_index(c->key, p) + 1 : 0; - -- while (idx < 1u << p->bits) { -+ while (idx < tnode_child_length(p)) { - c = tnode_get_child_rcu(p, idx++); - if (!c) - continue; -@@ -1786,8 +1784,8 @@ struct fib_trie_iter { - - static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) - { -+ unsigned long cindex = iter->index; - struct tnode *tn = iter->tnode; -- unsigned int cindex = iter->index; - struct tnode *p; - - /* A single entry routing table */ -@@ -1797,7 +1795,7 @@ static struct tnode *fib_trie_get_next(s - pr_debug("get_next iter={node=%p index=%d depth=%d}\n", - iter->tnode, iter->index, iter->depth); - rescan: -- while (cindex < (1<<tn->bits)) { -+ while (cindex < tnode_child_length(tn)) { - struct tnode *n = tnode_get_child_rcu(tn, cindex); - - if (n) { -@@ -1874,15 +1872,16 @@ static void trie_collect_stats(struct tr - hlist_for_each_entry_rcu(li, &n->list, hlist) - ++s->prefixes; - } else { -- int i; -+ unsigned long i; - - s->tnodes++; - if (n->bits < MAX_STAT_DEPTH) - s->nodesizes[n->bits]++; - -- for (i = 0; i < tnode_child_length(n); i++) -+ for (i = 0; i < tnode_child_length(n); i++) { - if (!rcu_access_pointer(n->child[i])) - s->nullpointers++; -+ } - } - } - rcu_read_unlock(); diff --git a/target/linux/generic/pending-3.18/080-11-fib_trie-Push-rcu_read_lock-unlock-to-callers.patch b/target/linux/generic/pending-3.18/080-11-fib_trie-Push-rcu_read_lock-unlock-to-callers.patch deleted file mode 100644 index 29bec8387d..0000000000 --- a/target/linux/generic/pending-3.18/080-11-fib_trie-Push-rcu_read_lock-unlock-to-callers.patch +++ /dev/null @@ -1,403 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:24 -0800 -Subject: [PATCH] fib_trie: Push rcu_read_lock/unlock to callers - -This change is to start cleaning up some of the rcu_read_lock/unlock -handling. I realized while reviewing the code there are several spots that -I don't believe are being handled correctly or are masking warnings by -locally calling rcu_read_lock/unlock instead of calling them at the correct -level. - -A common example is a call to fib_get_table followed by fib_table_lookup. -The rcu_read_lock/unlock ought to wrap both but there are several spots where -they were not wrapped. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -222,16 +222,19 @@ static inline struct fib_table *fib_new_ - static inline int fib_lookup(struct net *net, const struct flowi4 *flp, - struct fib_result *res) - { -- struct fib_table *table; -+ int err = -ENETUNREACH; - -- table = fib_get_table(net, RT_TABLE_LOCAL); -- if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) -- return 0; -- -- table = fib_get_table(net, RT_TABLE_MAIN); -- if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) -- return 0; -- return -ENETUNREACH; -+ rcu_read_lock(); -+ -+ if (!fib_table_lookup(fib_get_table(net, RT_TABLE_LOCAL), flp, res, -+ FIB_LOOKUP_NOREF) || -+ !fib_table_lookup(fib_get_table(net, RT_TABLE_MAIN), flp, res, -+ FIB_LOOKUP_NOREF)) -+ err = 0; -+ -+ rcu_read_unlock(); -+ -+ return err; - } - - #else /* CONFIG_IP_MULTIPLE_TABLES */ -@@ -247,20 +250,25 @@ static inline int fib_lookup(struct net - struct fib_result *res) - { - if (!net->ipv4.fib_has_custom_rules) { -+ int err = -ENETUNREACH; -+ -+ rcu_read_lock(); -+ - res->tclassid = 0; -- if (net->ipv4.fib_local && -- !fib_table_lookup(net->ipv4.fib_local, flp, res, -- FIB_LOOKUP_NOREF)) -- return 0; -- if (net->ipv4.fib_main && -- !fib_table_lookup(net->ipv4.fib_main, flp, res, -- FIB_LOOKUP_NOREF)) -- return 0; -- if (net->ipv4.fib_default && -- !fib_table_lookup(net->ipv4.fib_default, flp, res, -- FIB_LOOKUP_NOREF)) -- return 0; -- return -ENETUNREACH; -+ if ((net->ipv4.fib_local && -+ !fib_table_lookup(net->ipv4.fib_local, flp, res, -+ FIB_LOOKUP_NOREF)) || -+ (net->ipv4.fib_main && -+ !fib_table_lookup(net->ipv4.fib_main, flp, res, -+ FIB_LOOKUP_NOREF)) || -+ (net->ipv4.fib_default && -+ !fib_table_lookup(net->ipv4.fib_default, flp, res, -+ FIB_LOOKUP_NOREF))) -+ err = 0; -+ -+ rcu_read_unlock(); -+ -+ return err; - } - return __fib_lookup(net, flp, res); - } ---- a/net/ipv4/fib_frontend.c -+++ b/net/ipv4/fib_frontend.c -@@ -109,6 +109,7 @@ struct fib_table *fib_new_table(struct n - return tb; - } - -+/* caller must hold either rtnl or rcu read lock */ - struct fib_table *fib_get_table(struct net *net, u32 id) - { - struct fib_table *tb; -@@ -119,15 +120,11 @@ struct fib_table *fib_get_table(struct n - id = RT_TABLE_MAIN; - h = id & (FIB_TABLE_HASHSZ - 1); - -- rcu_read_lock(); - head = &net->ipv4.fib_table_hash[h]; - hlist_for_each_entry_rcu(tb, head, tb_hlist) { -- if (tb->tb_id == id) { -- rcu_read_unlock(); -+ if (tb->tb_id == id) - return tb; -- } - } -- rcu_read_unlock(); - return NULL; - } - #endif /* CONFIG_IP_MULTIPLE_TABLES */ -@@ -167,16 +164,18 @@ static inline unsigned int __inet_dev_ad - if (ipv4_is_multicast(addr)) - return RTN_MULTICAST; - -+ rcu_read_lock(); -+ - local_table = fib_get_table(net, RT_TABLE_LOCAL); - if (local_table) { - ret = RTN_UNICAST; -- rcu_read_lock(); - if (!fib_table_lookup(local_table, &fl4, &res, FIB_LOOKUP_NOREF)) { - if (!dev || dev == res.fi->fib_dev) - ret = res.type; - } -- rcu_read_unlock(); - } -+ -+ rcu_read_unlock(); - return ret; - } - -@@ -923,7 +922,7 @@ no_promotions: - #undef BRD1_OK - } - --static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) -+static void nl_fib_lookup(struct net *net, struct fib_result_nl *frn) - { - - struct fib_result res; -@@ -933,6 +932,11 @@ static void nl_fib_lookup(struct fib_res - .flowi4_tos = frn->fl_tos, - .flowi4_scope = frn->fl_scope, - }; -+ struct fib_table *tb; -+ -+ rcu_read_lock(); -+ -+ tb = fib_get_table(net, frn->tb_id_in); - - frn->err = -ENOENT; - if (tb) { -@@ -949,6 +953,8 @@ static void nl_fib_lookup(struct fib_res - } - local_bh_enable(); - } -+ -+ rcu_read_unlock(); - } - - static void nl_fib_input(struct sk_buff *skb) -@@ -956,7 +962,6 @@ static void nl_fib_input(struct sk_buff - struct net *net; - struct fib_result_nl *frn; - struct nlmsghdr *nlh; -- struct fib_table *tb; - u32 portid; - - net = sock_net(skb->sk); -@@ -972,9 +977,7 @@ static void nl_fib_input(struct sk_buff - nlh = nlmsg_hdr(skb); - - frn = (struct fib_result_nl *) nlmsg_data(nlh); -- tb = fib_get_table(net, frn->tb_id_in); -- -- nl_fib_lookup(frn, tb); -+ nl_fib_lookup(net, frn); - - portid = NETLINK_CB(skb).portid; /* netlink portid */ - NETLINK_CB(skb).portid = 0; /* from kernel */ ---- a/net/ipv4/fib_rules.c -+++ b/net/ipv4/fib_rules.c -@@ -81,27 +81,25 @@ static int fib4_rule_action(struct fib_r - break; - - case FR_ACT_UNREACHABLE: -- err = -ENETUNREACH; -- goto errout; -+ return -ENETUNREACH; - - case FR_ACT_PROHIBIT: -- err = -EACCES; -- goto errout; -+ return -EACCES; - - case FR_ACT_BLACKHOLE: - default: -- err = -EINVAL; -- goto errout; -+ return -EINVAL; - } - -+ rcu_read_lock(); -+ - tbl = fib_get_table(rule->fr_net, rule->table); -- if (!tbl) -- goto errout; -+ if (tbl) -+ err = fib_table_lookup(tbl, &flp->u.ip4, -+ (struct fib_result *)arg->result, -+ arg->flags); - -- err = fib_table_lookup(tbl, &flp->u.ip4, (struct fib_result *) arg->result, arg->flags); -- if (err > 0) -- err = -EAGAIN; --errout: -+ rcu_read_unlock(); - return err; - } - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1181,72 +1181,6 @@ err: - return err; - } - --/* should be called with rcu_read_lock */ --static int check_leaf(struct fib_table *tb, struct trie *t, struct tnode *l, -- t_key key, const struct flowi4 *flp, -- struct fib_result *res, int fib_flags) --{ -- struct leaf_info *li; -- struct hlist_head *hhead = &l->list; -- -- hlist_for_each_entry_rcu(li, hhead, hlist) { -- struct fib_alias *fa; -- -- if (l->key != (key & li->mask_plen)) -- continue; -- -- list_for_each_entry_rcu(fa, &li->falh, fa_list) { -- struct fib_info *fi = fa->fa_info; -- int nhsel, err; -- -- if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) -- continue; -- if (fi->fib_dead) -- continue; -- if (fa->fa_info->fib_scope < flp->flowi4_scope) -- continue; -- fib_alias_accessed(fa); -- err = fib_props[fa->fa_type].error; -- if (unlikely(err < 0)) { --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(t->stats->semantic_match_passed); --#endif -- return err; -- } -- if (fi->fib_flags & RTNH_F_DEAD) -- continue; -- for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { -- const struct fib_nh *nh = &fi->fib_nh[nhsel]; -- -- if (nh->nh_flags & RTNH_F_DEAD) -- continue; -- if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif) -- continue; -- --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(t->stats->semantic_match_passed); --#endif -- res->prefixlen = li->plen; -- res->nh_sel = nhsel; -- res->type = fa->fa_type; -- res->scope = fi->fib_scope; -- res->fi = fi; -- res->table = tb; -- res->fa_head = &li->falh; -- if (!(fib_flags & FIB_LOOKUP_NOREF)) -- atomic_inc(&fi->fib_clntref); -- return 0; -- } -- } -- --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(t->stats->semantic_match_miss); --#endif -- } -- -- return 1; --} -- - static inline t_key prefix_mismatch(t_key key, struct tnode *n) - { - t_key prefix = n->key; -@@ -1254,6 +1188,7 @@ static inline t_key prefix_mismatch(t_ke - return (key ^ prefix) & (prefix | -prefix); - } - -+/* should be called with rcu_read_lock */ - int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, - struct fib_result *res, int fib_flags) - { -@@ -1263,14 +1198,12 @@ int fib_table_lookup(struct fib_table *t - #endif - const t_key key = ntohl(flp->daddr); - struct tnode *n, *pn; -+ struct leaf_info *li; - t_key cindex; -- int ret = 1; -- -- rcu_read_lock(); - - n = rcu_dereference(t->trie); - if (!n) -- goto failed; -+ return -EAGAIN; - - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(stats->gets); -@@ -1350,7 +1283,7 @@ backtrace: - - pn = node_parent_rcu(pn); - if (unlikely(!pn)) -- goto failed; -+ return -EAGAIN; - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(stats->backtrack); - #endif -@@ -1368,12 +1301,62 @@ backtrace: - - found: - /* Step 3: Process the leaf, if that fails fall back to backtracing */ -- ret = check_leaf(tb, t, n, key, flp, res, fib_flags); -- if (unlikely(ret > 0)) -- goto backtrace; --failed: -- rcu_read_unlock(); -- return ret; -+ hlist_for_each_entry_rcu(li, &n->list, hlist) { -+ struct fib_alias *fa; -+ -+ if ((key ^ n->key) & li->mask_plen) -+ continue; -+ -+ list_for_each_entry_rcu(fa, &li->falh, fa_list) { -+ struct fib_info *fi = fa->fa_info; -+ int nhsel, err; -+ -+ if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) -+ continue; -+ if (fi->fib_dead) -+ continue; -+ if (fa->fa_info->fib_scope < flp->flowi4_scope) -+ continue; -+ fib_alias_accessed(fa); -+ err = fib_props[fa->fa_type].error; -+ if (unlikely(err < 0)) { -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(stats->semantic_match_passed); -+#endif -+ return err; -+ } -+ if (fi->fib_flags & RTNH_F_DEAD) -+ continue; -+ for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { -+ const struct fib_nh *nh = &fi->fib_nh[nhsel]; -+ -+ if (nh->nh_flags & RTNH_F_DEAD) -+ continue; -+ if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif) -+ continue; -+ -+ if (!(fib_flags & FIB_LOOKUP_NOREF)) -+ atomic_inc(&fi->fib_clntref); -+ -+ res->prefixlen = li->plen; -+ res->nh_sel = nhsel; -+ res->type = fa->fa_type; -+ res->scope = fi->fib_scope; -+ res->fi = fi; -+ res->table = tb; -+ res->fa_head = &li->falh; -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(stats->semantic_match_passed); -+#endif -+ return err; -+ } -+ } -+ -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(stats->semantic_match_miss); -+#endif -+ } -+ goto backtrace; - } - EXPORT_SYMBOL_GPL(fib_table_lookup); - diff --git a/target/linux/generic/pending-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch b/target/linux/generic/pending-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch deleted file mode 100644 index a373add1d2..0000000000 --- a/target/linux/generic/pending-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch +++ /dev/null @@ -1,345 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:31 -0800 -Subject: [PATCH] fib_trie: Move resize to after inflate/halve - -This change consists of a cut/paste of resize to behind inflate and halve -so that I could remove the two function prototypes. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -149,8 +149,6 @@ struct trie { - static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, - struct tnode *n, int wasfull); - static struct tnode *resize(struct trie *t, struct tnode *tn); --static struct tnode *inflate(struct trie *t, struct tnode *tn); --static struct tnode *halve(struct trie *t, struct tnode *tn); - /* tnodes to free after resize(); protected by RTNL */ - static struct callback_head *tnode_free_head; - static size_t tnode_free_size; -@@ -447,161 +445,6 @@ static void put_child_root(struct tnode - rcu_assign_pointer(t->trie, n); - } - --#define MAX_WORK 10 --static struct tnode *resize(struct trie *t, struct tnode *tn) --{ -- struct tnode *old_tn, *n = NULL; -- int inflate_threshold_use; -- int halve_threshold_use; -- int max_work; -- -- if (!tn) -- return NULL; -- -- pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", -- tn, inflate_threshold, halve_threshold); -- -- /* No children */ -- if (tn->empty_children > (tnode_child_length(tn) - 1)) -- goto no_children; -- -- /* One child */ -- if (tn->empty_children == (tnode_child_length(tn) - 1)) -- goto one_child; -- /* -- * Double as long as the resulting node has a number of -- * nonempty nodes that are above the threshold. -- */ -- -- /* -- * From "Implementing a dynamic compressed trie" by Stefan Nilsson of -- * the Helsinki University of Technology and Matti Tikkanen of Nokia -- * Telecommunications, page 6: -- * "A node is doubled if the ratio of non-empty children to all -- * children in the *doubled* node is at least 'high'." -- * -- * 'high' in this instance is the variable 'inflate_threshold'. It -- * is expressed as a percentage, so we multiply it with -- * tnode_child_length() and instead of multiplying by 2 (since the -- * child array will be doubled by inflate()) and multiplying -- * the left-hand side by 100 (to handle the percentage thing) we -- * multiply the left-hand side by 50. -- * -- * The left-hand side may look a bit weird: tnode_child_length(tn) -- * - tn->empty_children is of course the number of non-null children -- * in the current node. tn->full_children is the number of "full" -- * children, that is non-null tnodes with a skip value of 0. -- * All of those will be doubled in the resulting inflated tnode, so -- * we just count them one extra time here. -- * -- * A clearer way to write this would be: -- * -- * to_be_doubled = tn->full_children; -- * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - -- * tn->full_children; -- * -- * new_child_length = tnode_child_length(tn) * 2; -- * -- * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / -- * new_child_length; -- * if (new_fill_factor >= inflate_threshold) -- * -- * ...and so on, tho it would mess up the while () loop. -- * -- * anyway, -- * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= -- * inflate_threshold -- * -- * avoid a division: -- * 100 * (not_to_be_doubled + 2*to_be_doubled) >= -- * inflate_threshold * new_child_length -- * -- * expand not_to_be_doubled and to_be_doubled, and shorten: -- * 100 * (tnode_child_length(tn) - tn->empty_children + -- * tn->full_children) >= inflate_threshold * new_child_length -- * -- * expand new_child_length: -- * 100 * (tnode_child_length(tn) - tn->empty_children + -- * tn->full_children) >= -- * inflate_threshold * tnode_child_length(tn) * 2 -- * -- * shorten again: -- * 50 * (tn->full_children + tnode_child_length(tn) - -- * tn->empty_children) >= inflate_threshold * -- * tnode_child_length(tn) -- * -- */ -- -- /* Keep root node larger */ -- -- if (!node_parent(tn)) { -- inflate_threshold_use = inflate_threshold_root; -- halve_threshold_use = halve_threshold_root; -- } else { -- inflate_threshold_use = inflate_threshold; -- halve_threshold_use = halve_threshold; -- } -- -- max_work = MAX_WORK; -- while ((tn->full_children > 0 && max_work-- && -- 50 * (tn->full_children + tnode_child_length(tn) -- - tn->empty_children) -- >= inflate_threshold_use * tnode_child_length(tn))) { -- -- old_tn = tn; -- tn = inflate(t, tn); -- -- if (IS_ERR(tn)) { -- tn = old_tn; --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(t->stats->resize_node_skipped); --#endif -- break; -- } -- } -- -- /* Return if at least one inflate is run */ -- if (max_work != MAX_WORK) -- return tn; -- -- /* -- * Halve as long as the number of empty children in this -- * node is above threshold. -- */ -- -- max_work = MAX_WORK; -- while (tn->bits > 1 && max_work-- && -- 100 * (tnode_child_length(tn) - tn->empty_children) < -- halve_threshold_use * tnode_child_length(tn)) { -- -- old_tn = tn; -- tn = halve(t, tn); -- if (IS_ERR(tn)) { -- tn = old_tn; --#ifdef CONFIG_IP_FIB_TRIE_STATS -- this_cpu_inc(t->stats->resize_node_skipped); --#endif -- break; -- } -- } -- -- -- /* Only one child remains */ -- if (tn->empty_children == (tnode_child_length(tn) - 1)) { -- unsigned long i; --one_child: -- for (i = tnode_child_length(tn); !n && i;) -- n = tnode_get_child(tn, --i); --no_children: -- /* compress one level */ -- node_set_parent(n, NULL); -- tnode_free_safe(tn); -- return n; -- } -- return tn; --} -- -- - static void tnode_clean_free(struct tnode *tn) - { - struct tnode *tofree; -@@ -804,6 +647,160 @@ nomem: - return ERR_PTR(-ENOMEM); - } - -+#define MAX_WORK 10 -+static struct tnode *resize(struct trie *t, struct tnode *tn) -+{ -+ struct tnode *old_tn, *n = NULL; -+ int inflate_threshold_use; -+ int halve_threshold_use; -+ int max_work; -+ -+ if (!tn) -+ return NULL; -+ -+ pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", -+ tn, inflate_threshold, halve_threshold); -+ -+ /* No children */ -+ if (tn->empty_children > (tnode_child_length(tn) - 1)) -+ goto no_children; -+ -+ /* One child */ -+ if (tn->empty_children == (tnode_child_length(tn) - 1)) -+ goto one_child; -+ /* -+ * Double as long as the resulting node has a number of -+ * nonempty nodes that are above the threshold. -+ */ -+ -+ /* -+ * From "Implementing a dynamic compressed trie" by Stefan Nilsson of -+ * the Helsinki University of Technology and Matti Tikkanen of Nokia -+ * Telecommunications, page 6: -+ * "A node is doubled if the ratio of non-empty children to all -+ * children in the *doubled* node is at least 'high'." -+ * -+ * 'high' in this instance is the variable 'inflate_threshold'. It -+ * is expressed as a percentage, so we multiply it with -+ * tnode_child_length() and instead of multiplying by 2 (since the -+ * child array will be doubled by inflate()) and multiplying -+ * the left-hand side by 100 (to handle the percentage thing) we -+ * multiply the left-hand side by 50. -+ * -+ * The left-hand side may look a bit weird: tnode_child_length(tn) -+ * - tn->empty_children is of course the number of non-null children -+ * in the current node. tn->full_children is the number of "full" -+ * children, that is non-null tnodes with a skip value of 0. -+ * All of those will be doubled in the resulting inflated tnode, so -+ * we just count them one extra time here. -+ * -+ * A clearer way to write this would be: -+ * -+ * to_be_doubled = tn->full_children; -+ * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - -+ * tn->full_children; -+ * -+ * new_child_length = tnode_child_length(tn) * 2; -+ * -+ * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / -+ * new_child_length; -+ * if (new_fill_factor >= inflate_threshold) -+ * -+ * ...and so on, tho it would mess up the while () loop. -+ * -+ * anyway, -+ * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= -+ * inflate_threshold -+ * -+ * avoid a division: -+ * 100 * (not_to_be_doubled + 2*to_be_doubled) >= -+ * inflate_threshold * new_child_length -+ * -+ * expand not_to_be_doubled and to_be_doubled, and shorten: -+ * 100 * (tnode_child_length(tn) - tn->empty_children + -+ * tn->full_children) >= inflate_threshold * new_child_length -+ * -+ * expand new_child_length: -+ * 100 * (tnode_child_length(tn) - tn->empty_children + -+ * tn->full_children) >= -+ * inflate_threshold * tnode_child_length(tn) * 2 -+ * -+ * shorten again: -+ * 50 * (tn->full_children + tnode_child_length(tn) - -+ * tn->empty_children) >= inflate_threshold * -+ * tnode_child_length(tn) -+ * -+ */ -+ -+ /* Keep root node larger */ -+ -+ if (!node_parent(tn)) { -+ inflate_threshold_use = inflate_threshold_root; -+ halve_threshold_use = halve_threshold_root; -+ } else { -+ inflate_threshold_use = inflate_threshold; -+ halve_threshold_use = halve_threshold; -+ } -+ -+ max_work = MAX_WORK; -+ while ((tn->full_children > 0 && max_work-- && -+ 50 * (tn->full_children + tnode_child_length(tn) -+ - tn->empty_children) -+ >= inflate_threshold_use * tnode_child_length(tn))) { -+ -+ old_tn = tn; -+ tn = inflate(t, tn); -+ -+ if (IS_ERR(tn)) { -+ tn = old_tn; -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(t->stats->resize_node_skipped); -+#endif -+ break; -+ } -+ } -+ -+ /* Return if at least one inflate is run */ -+ if (max_work != MAX_WORK) -+ return tn; -+ -+ /* -+ * Halve as long as the number of empty children in this -+ * node is above threshold. -+ */ -+ -+ max_work = MAX_WORK; -+ while (tn->bits > 1 && max_work-- && -+ 100 * (tnode_child_length(tn) - tn->empty_children) < -+ halve_threshold_use * tnode_child_length(tn)) { -+ -+ old_tn = tn; -+ tn = halve(t, tn); -+ if (IS_ERR(tn)) { -+ tn = old_tn; -+#ifdef CONFIG_IP_FIB_TRIE_STATS -+ this_cpu_inc(t->stats->resize_node_skipped); -+#endif -+ break; -+ } -+ } -+ -+ -+ /* Only one child remains */ -+ if (tn->empty_children == (tnode_child_length(tn) - 1)) { -+ unsigned long i; -+one_child: -+ for (i = tnode_child_length(tn); !n && i;) -+ n = tnode_get_child(tn, --i); -+no_children: -+ /* compress one level */ -+ node_set_parent(n, NULL); -+ tnode_free_safe(tn); -+ return n; -+ } -+ return tn; -+} -+ - /* readside must use rcu_read_lock currently dump routines - via get_fa_head and dump */ - diff --git a/target/linux/generic/pending-3.18/080-13-fib_trie-Add-functions-should_inflate-and-should_hal.patch b/target/linux/generic/pending-3.18/080-13-fib_trie-Add-functions-should_inflate-and-should_hal.patch deleted file mode 100644 index c01d57af0f..0000000000 --- a/target/linux/generic/pending-3.18/080-13-fib_trie-Add-functions-should_inflate-and-should_hal.patch +++ /dev/null @@ -1,250 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:37 -0800 -Subject: [PATCH] fib_trie: Add functions should_inflate and should_halve - -This change pulls the logic for if we should inflate/halve the nodes out -into separate functions. It also addresses what I believe is a bug where 1 -full node is all that is needed to keep a node from ever being halved. - -Simple script to reproduce the issue: - modprobe dummy; ifconfig dummy0 up - for i in `seq 0 255`; do ifconfig dummy0:$i 10.0.${i}.1/24 up; done - ifconfig dummy0:256 10.0.255.33/16 up - for i in `seq 0 254`; do ifconfig dummy0:$i down; done - -Results from /proc/net/fib_triestat -Before: - Local: - Aver depth: 3.00 - Max depth: 4 - Leaves: 17 - Prefixes: 18 - Internal nodes: 11 - 1: 8 2: 2 10: 1 - Pointers: 1048 - Null ptrs: 1021 - Total size: 11 kB -After: - Local: - Aver depth: 3.41 - Max depth: 5 - Leaves: 17 - Prefixes: 18 - Internal nodes: 12 - 1: 8 2: 3 3: 1 - Pointers: 36 - Null ptrs: 8 - Total size: 3 kB - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -647,12 +647,94 @@ nomem: - return ERR_PTR(-ENOMEM); - } - -+/* From "Implementing a dynamic compressed trie" by Stefan Nilsson of -+ * the Helsinki University of Technology and Matti Tikkanen of Nokia -+ * Telecommunications, page 6: -+ * "A node is doubled if the ratio of non-empty children to all -+ * children in the *doubled* node is at least 'high'." -+ * -+ * 'high' in this instance is the variable 'inflate_threshold'. It -+ * is expressed as a percentage, so we multiply it with -+ * tnode_child_length() and instead of multiplying by 2 (since the -+ * child array will be doubled by inflate()) and multiplying -+ * the left-hand side by 100 (to handle the percentage thing) we -+ * multiply the left-hand side by 50. -+ * -+ * The left-hand side may look a bit weird: tnode_child_length(tn) -+ * - tn->empty_children is of course the number of non-null children -+ * in the current node. tn->full_children is the number of "full" -+ * children, that is non-null tnodes with a skip value of 0. -+ * All of those will be doubled in the resulting inflated tnode, so -+ * we just count them one extra time here. -+ * -+ * A clearer way to write this would be: -+ * -+ * to_be_doubled = tn->full_children; -+ * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - -+ * tn->full_children; -+ * -+ * new_child_length = tnode_child_length(tn) * 2; -+ * -+ * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / -+ * new_child_length; -+ * if (new_fill_factor >= inflate_threshold) -+ * -+ * ...and so on, tho it would mess up the while () loop. -+ * -+ * anyway, -+ * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= -+ * inflate_threshold -+ * -+ * avoid a division: -+ * 100 * (not_to_be_doubled + 2*to_be_doubled) >= -+ * inflate_threshold * new_child_length -+ * -+ * expand not_to_be_doubled and to_be_doubled, and shorten: -+ * 100 * (tnode_child_length(tn) - tn->empty_children + -+ * tn->full_children) >= inflate_threshold * new_child_length -+ * -+ * expand new_child_length: -+ * 100 * (tnode_child_length(tn) - tn->empty_children + -+ * tn->full_children) >= -+ * inflate_threshold * tnode_child_length(tn) * 2 -+ * -+ * shorten again: -+ * 50 * (tn->full_children + tnode_child_length(tn) - -+ * tn->empty_children) >= inflate_threshold * -+ * tnode_child_length(tn) -+ * -+ */ -+static bool should_inflate(const struct tnode *tn) -+{ -+ unsigned long used = tnode_child_length(tn); -+ unsigned long threshold = used; -+ -+ /* Keep root node larger */ -+ threshold *= node_parent(tn) ? inflate_threshold : -+ inflate_threshold_root; -+ used += tn->full_children; -+ used -= tn->empty_children; -+ -+ return tn->pos && ((50 * used) >= threshold); -+} -+ -+static bool should_halve(const struct tnode *tn) -+{ -+ unsigned long used = tnode_child_length(tn); -+ unsigned long threshold = used; -+ -+ /* Keep root node larger */ -+ threshold *= node_parent(tn) ? halve_threshold : -+ halve_threshold_root; -+ used -= tn->empty_children; -+ -+ return (tn->bits > 1) && ((100 * used) < threshold); -+} -+ - #define MAX_WORK 10 - static struct tnode *resize(struct trie *t, struct tnode *tn) - { - struct tnode *old_tn, *n = NULL; -- int inflate_threshold_use; -- int halve_threshold_use; - int max_work; - - if (!tn) -@@ -668,86 +750,12 @@ static struct tnode *resize(struct trie - /* One child */ - if (tn->empty_children == (tnode_child_length(tn) - 1)) - goto one_child; -- /* -- * Double as long as the resulting node has a number of -- * nonempty nodes that are above the threshold. -- */ - -- /* -- * From "Implementing a dynamic compressed trie" by Stefan Nilsson of -- * the Helsinki University of Technology and Matti Tikkanen of Nokia -- * Telecommunications, page 6: -- * "A node is doubled if the ratio of non-empty children to all -- * children in the *doubled* node is at least 'high'." -- * -- * 'high' in this instance is the variable 'inflate_threshold'. It -- * is expressed as a percentage, so we multiply it with -- * tnode_child_length() and instead of multiplying by 2 (since the -- * child array will be doubled by inflate()) and multiplying -- * the left-hand side by 100 (to handle the percentage thing) we -- * multiply the left-hand side by 50. -- * -- * The left-hand side may look a bit weird: tnode_child_length(tn) -- * - tn->empty_children is of course the number of non-null children -- * in the current node. tn->full_children is the number of "full" -- * children, that is non-null tnodes with a skip value of 0. -- * All of those will be doubled in the resulting inflated tnode, so -- * we just count them one extra time here. -- * -- * A clearer way to write this would be: -- * -- * to_be_doubled = tn->full_children; -- * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - -- * tn->full_children; -- * -- * new_child_length = tnode_child_length(tn) * 2; -- * -- * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / -- * new_child_length; -- * if (new_fill_factor >= inflate_threshold) -- * -- * ...and so on, tho it would mess up the while () loop. -- * -- * anyway, -- * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= -- * inflate_threshold -- * -- * avoid a division: -- * 100 * (not_to_be_doubled + 2*to_be_doubled) >= -- * inflate_threshold * new_child_length -- * -- * expand not_to_be_doubled and to_be_doubled, and shorten: -- * 100 * (tnode_child_length(tn) - tn->empty_children + -- * tn->full_children) >= inflate_threshold * new_child_length -- * -- * expand new_child_length: -- * 100 * (tnode_child_length(tn) - tn->empty_children + -- * tn->full_children) >= -- * inflate_threshold * tnode_child_length(tn) * 2 -- * -- * shorten again: -- * 50 * (tn->full_children + tnode_child_length(tn) - -- * tn->empty_children) >= inflate_threshold * -- * tnode_child_length(tn) -- * -+ /* Double as long as the resulting node has a number of -+ * nonempty nodes that are above the threshold. - */ -- -- /* Keep root node larger */ -- -- if (!node_parent(tn)) { -- inflate_threshold_use = inflate_threshold_root; -- halve_threshold_use = halve_threshold_root; -- } else { -- inflate_threshold_use = inflate_threshold; -- halve_threshold_use = halve_threshold; -- } -- - max_work = MAX_WORK; -- while ((tn->full_children > 0 && max_work-- && -- 50 * (tn->full_children + tnode_child_length(tn) -- - tn->empty_children) -- >= inflate_threshold_use * tnode_child_length(tn))) { -- -+ while (should_inflate(tn) && max_work--) { - old_tn = tn; - tn = inflate(t, tn); - -@@ -764,16 +772,11 @@ static struct tnode *resize(struct trie - if (max_work != MAX_WORK) - return tn; - -- /* -- * Halve as long as the number of empty children in this -+ /* Halve as long as the number of empty children in this - * node is above threshold. - */ -- - max_work = MAX_WORK; -- while (tn->bits > 1 && max_work-- && -- 100 * (tnode_child_length(tn) - tn->empty_children) < -- halve_threshold_use * tnode_child_length(tn)) { -- -+ while (should_halve(tn) && max_work--) { - old_tn = tn; - tn = halve(t, tn); - if (IS_ERR(tn)) { diff --git a/target/linux/generic/pending-3.18/080-14-fib_trie-Push-assignment-of-child-to-parent-down-int.patch b/target/linux/generic/pending-3.18/080-14-fib_trie-Push-assignment-of-child-to-parent-down-int.patch deleted file mode 100644 index 8f26e32d3d..0000000000 --- a/target/linux/generic/pending-3.18/080-14-fib_trie-Push-assignment-of-child-to-parent-down-int.patch +++ /dev/null @@ -1,336 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:43 -0800 -Subject: [PATCH] fib_trie: Push assignment of child to parent down into - inflate/halve - -This change makes it so that the assignment of the tnode to the parent is -handled directly within whatever function is currently handling the node be -it inflate, halve, or resize. By doing this we can avoid some of the need -to set NULL pointers in the tree while we are resizing the subnodes. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -146,9 +146,7 @@ struct trie { - #endif - }; - --static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, -- struct tnode *n, int wasfull); --static struct tnode *resize(struct trie *t, struct tnode *tn); -+static void resize(struct trie *t, struct tnode *tn); - /* tnodes to free after resize(); protected by RTNL */ - static struct callback_head *tnode_free_head; - static size_t tnode_free_size; -@@ -396,22 +394,13 @@ static inline int tnode_full(const struc - return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); - } - --static inline void put_child(struct tnode *tn, unsigned long i, -- struct tnode *n) --{ -- tnode_put_child_reorg(tn, i, n, -1); --} -- -- /* -- * Add a child at position i overwriting the old value. -- * Update the value of full_children and empty_children. -- */ -- --static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, -- struct tnode *n, int wasfull) -+/* Add a child at position i overwriting the old value. -+ * Update the value of full_children and empty_children. -+ */ -+static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) - { - struct tnode *chi = rtnl_dereference(tn->child[i]); -- int isfull; -+ int isfull, wasfull; - - BUG_ON(i >= tnode_child_length(tn)); - -@@ -422,10 +411,9 @@ static void tnode_put_child_reorg(struct - tn->empty_children--; - - /* update fullChildren */ -- if (wasfull == -1) -- wasfull = tnode_full(tn, chi); -- -+ wasfull = tnode_full(tn, chi); - isfull = tnode_full(tn, n); -+ - if (wasfull && !isfull) - tn->full_children--; - else if (!wasfull && isfull) -@@ -458,9 +446,10 @@ static void tnode_clean_free(struct tnod - node_free(tn); - } - --static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) -+static int inflate(struct trie *t, struct tnode *oldtnode) - { - unsigned long olen = tnode_child_length(oldtnode); -+ struct tnode *tp = node_parent(oldtnode); - struct tnode *tn; - unsigned long i; - t_key m; -@@ -468,9 +457,8 @@ static struct tnode *inflate(struct trie - pr_debug("In inflate\n"); - - tn = tnode_new(oldtnode->key, oldtnode->pos - 1, oldtnode->bits + 1); -- - if (!tn) -- return ERR_PTR(-ENOMEM); -+ return -ENOMEM; - - /* - * Preallocate and store tnodes before the actual work so we -@@ -564,30 +552,36 @@ static struct tnode *inflate(struct trie - put_child(left, j, rtnl_dereference(inode->child[j])); - put_child(right, j, rtnl_dereference(inode->child[j + size])); - } -- put_child(tn, 2*i, resize(t, left)); -- put_child(tn, 2*i+1, resize(t, right)); -+ -+ put_child(tn, 2 * i, left); -+ put_child(tn, 2 * i + 1, right); - - tnode_free_safe(inode); -+ -+ resize(t, left); -+ resize(t, right); - } -+ -+ put_child_root(tp, t, tn->key, tn); - tnode_free_safe(oldtnode); -- return tn; -+ return 0; - nomem: - tnode_clean_free(tn); -- return ERR_PTR(-ENOMEM); -+ return -ENOMEM; - } - --static struct tnode *halve(struct trie *t, struct tnode *oldtnode) -+static int halve(struct trie *t, struct tnode *oldtnode) - { - unsigned long olen = tnode_child_length(oldtnode); -+ struct tnode *tp = node_parent(oldtnode); - struct tnode *tn, *left, *right; - int i; - - pr_debug("In halve\n"); - - tn = tnode_new(oldtnode->key, oldtnode->pos + 1, oldtnode->bits - 1); -- - if (!tn) -- return ERR_PTR(-ENOMEM); -+ return -ENOMEM; - - /* - * Preallocate and store tnodes before the actual work so we -@@ -606,8 +600,10 @@ static struct tnode *halve(struct trie * - - newn = tnode_new(left->key, oldtnode->pos, 1); - -- if (!newn) -- goto nomem; -+ if (!newn) { -+ tnode_clean_free(tn); -+ return -ENOMEM; -+ } - - put_child(tn, i/2, newn); - } -@@ -635,16 +631,18 @@ static struct tnode *halve(struct trie * - - /* Two nonempty children */ - newBinNode = tnode_get_child(tn, i/2); -- put_child(tn, i/2, NULL); - put_child(newBinNode, 0, left); - put_child(newBinNode, 1, right); -- put_child(tn, i/2, resize(t, newBinNode)); -+ -+ put_child(tn, i / 2, newBinNode); -+ -+ resize(t, newBinNode); - } -+ -+ put_child_root(tp, t, tn->key, tn); - tnode_free_safe(oldtnode); -- return tn; --nomem: -- tnode_clean_free(tn); -- return ERR_PTR(-ENOMEM); -+ -+ return 0; - } - - /* From "Implementing a dynamic compressed trie" by Stefan Nilsson of -@@ -704,45 +702,48 @@ nomem: - * tnode_child_length(tn) - * - */ --static bool should_inflate(const struct tnode *tn) -+static bool should_inflate(const struct tnode *tp, const struct tnode *tn) - { - unsigned long used = tnode_child_length(tn); - unsigned long threshold = used; - - /* Keep root node larger */ -- threshold *= node_parent(tn) ? inflate_threshold : -- inflate_threshold_root; -+ threshold *= tp ? inflate_threshold : inflate_threshold_root; - used += tn->full_children; - used -= tn->empty_children; - - return tn->pos && ((50 * used) >= threshold); - } - --static bool should_halve(const struct tnode *tn) -+static bool should_halve(const struct tnode *tp, const struct tnode *tn) - { - unsigned long used = tnode_child_length(tn); - unsigned long threshold = used; - - /* Keep root node larger */ -- threshold *= node_parent(tn) ? halve_threshold : -- halve_threshold_root; -+ threshold *= tp ? halve_threshold : halve_threshold_root; - used -= tn->empty_children; - - return (tn->bits > 1) && ((100 * used) < threshold); - } - - #define MAX_WORK 10 --static struct tnode *resize(struct trie *t, struct tnode *tn) -+static void resize(struct trie *t, struct tnode *tn) - { -- struct tnode *old_tn, *n = NULL; -+ struct tnode *tp = node_parent(tn), *n = NULL; -+ struct tnode __rcu **cptr; - int max_work; - -- if (!tn) -- return NULL; -- - pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", - tn, inflate_threshold, halve_threshold); - -+ /* track the tnode via the pointer from the parent instead of -+ * doing it ourselves. This way we can let RCU fully do its -+ * thing without us interfering -+ */ -+ cptr = tp ? &tp->child[get_index(tn->key, tp)] : &t->trie; -+ BUG_ON(tn != rtnl_dereference(*cptr)); -+ - /* No children */ - if (tn->empty_children > (tnode_child_length(tn) - 1)) - goto no_children; -@@ -755,39 +756,35 @@ static struct tnode *resize(struct trie - * nonempty nodes that are above the threshold. - */ - max_work = MAX_WORK; -- while (should_inflate(tn) && max_work--) { -- old_tn = tn; -- tn = inflate(t, tn); -- -- if (IS_ERR(tn)) { -- tn = old_tn; -+ while (should_inflate(tp, tn) && max_work--) { -+ if (inflate(t, tn)) { - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); - #endif - break; - } -+ -+ tn = rtnl_dereference(*cptr); - } - - /* Return if at least one inflate is run */ - if (max_work != MAX_WORK) -- return tn; -+ return; - - /* Halve as long as the number of empty children in this - * node is above threshold. - */ - max_work = MAX_WORK; -- while (should_halve(tn) && max_work--) { -- old_tn = tn; -- tn = halve(t, tn); -- if (IS_ERR(tn)) { -- tn = old_tn; -+ while (should_halve(tp, tn) && max_work--) { -+ if (halve(t, tn)) { - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); - #endif - break; - } -- } - -+ tn = rtnl_dereference(*cptr); -+ } - - /* Only one child remains */ - if (tn->empty_children == (tnode_child_length(tn) - 1)) { -@@ -797,11 +794,12 @@ one_child: - n = tnode_get_child(tn, --i); - no_children: - /* compress one level */ -- node_set_parent(n, NULL); -+ put_child_root(tp, t, tn->key, n); -+ node_set_parent(n, tp); -+ -+ /* drop dead node */ - tnode_free_safe(tn); -- return n; - } -- return tn; - } - - /* readside must use rcu_read_lock currently dump routines -@@ -882,34 +880,19 @@ static struct tnode *fib_find_node(struc - - static void trie_rebalance(struct trie *t, struct tnode *tn) - { -- int wasfull; -- t_key cindex, key; - struct tnode *tp; - -- key = tn->key; -- -- while (tn != NULL && (tp = node_parent(tn)) != NULL) { -- cindex = get_index(key, tp); -- wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); -- tn = resize(t, tn); -- -- tnode_put_child_reorg(tp, cindex, tn, wasfull); -- -- tp = node_parent(tn); -- if (!tp) -- rcu_assign_pointer(t->trie, tn); -+ while ((tp = node_parent(tn)) != NULL) { -+ resize(t, tn); - - tnode_free_flush(); -- if (!tp) -- break; - tn = tp; - } - - /* Handle last (top) tnode */ - if (IS_TNODE(tn)) -- tn = resize(t, tn); -+ resize(t, tn); - -- rcu_assign_pointer(t->trie, tn); - tnode_free_flush(); - } - diff --git a/target/linux/generic/pending-3.18/080-15-fib_trie-Push-tnode-flushing-down-to-inflate-halve.patch b/target/linux/generic/pending-3.18/080-15-fib_trie-Push-tnode-flushing-down-to-inflate-halve.patch deleted file mode 100644 index 51178a0f14..0000000000 --- a/target/linux/generic/pending-3.18/080-15-fib_trie-Push-tnode-flushing-down-to-inflate-halve.patch +++ /dev/null @@ -1,237 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:49 -0800 -Subject: [PATCH] fib_trie: Push tnode flushing down to inflate/halve - -This change pushes the tnode freeing down into the inflate and halve -functions. It makes more sense here as we have a better grasp of what is -going on and when a given cluster of nodes is ready to be freed. - -I believe this may address a bug in the freeing logic as well. For some -reason if the freelist got to a certain size we would call -synchronize_rcu(). I'm assuming that what they meant to do is call -synchronize_rcu() after they had handed off that much memory via -call_rcu(). As such that is what I have updated the behavior to be. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -147,8 +147,6 @@ struct trie { - }; - - static void resize(struct trie *t, struct tnode *tn); --/* tnodes to free after resize(); protected by RTNL */ --static struct callback_head *tnode_free_head; - static size_t tnode_free_size; - - /* -@@ -307,32 +305,6 @@ static struct tnode *tnode_alloc(size_t - return vzalloc(size); - } - --static void tnode_free_safe(struct tnode *tn) --{ -- BUG_ON(IS_LEAF(tn)); -- tn->rcu.next = tnode_free_head; -- tnode_free_head = &tn->rcu; --} -- --static void tnode_free_flush(void) --{ -- struct callback_head *head; -- -- while ((head = tnode_free_head)) { -- struct tnode *tn = container_of(head, struct tnode, rcu); -- -- tnode_free_head = head->next; -- tnode_free_size += offsetof(struct tnode, child[1 << tn->bits]); -- -- node_free(tn); -- } -- -- if (tnode_free_size >= PAGE_SIZE * sync_pages) { -- tnode_free_size = 0; -- synchronize_rcu(); -- } --} -- - static struct tnode *leaf_new(t_key key) - { - struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); -@@ -433,17 +405,33 @@ static void put_child_root(struct tnode - rcu_assign_pointer(t->trie, n); - } - --static void tnode_clean_free(struct tnode *tn) -+static inline void tnode_free_init(struct tnode *tn) - { -- struct tnode *tofree; -- unsigned long i; -+ tn->rcu.next = NULL; -+} -+ -+static inline void tnode_free_append(struct tnode *tn, struct tnode *n) -+{ -+ n->rcu.next = tn->rcu.next; -+ tn->rcu.next = &n->rcu; -+} - -- for (i = 0; i < tnode_child_length(tn); i++) { -- tofree = tnode_get_child(tn, i); -- if (tofree) -- node_free(tofree); -+static void tnode_free(struct tnode *tn) -+{ -+ struct callback_head *head = &tn->rcu; -+ -+ while (head) { -+ head = head->next; -+ tnode_free_size += offsetof(struct tnode, child[1 << tn->bits]); -+ node_free(tn); -+ -+ tn = container_of(head, struct tnode, rcu); -+ } -+ -+ if (tnode_free_size >= PAGE_SIZE * sync_pages) { -+ tnode_free_size = 0; -+ synchronize_rcu(); - } -- node_free(tn); - } - - static int inflate(struct trie *t, struct tnode *oldtnode) -@@ -476,20 +464,23 @@ static int inflate(struct trie *t, struc - inode->bits - 1); - if (!left) - goto nomem; -+ tnode_free_append(tn, left); - - right = tnode_new(inode->key | m, inode->pos, - inode->bits - 1); - -- if (!right) { -- node_free(left); -+ if (!right) - goto nomem; -- } -+ tnode_free_append(tn, right); - - put_child(tn, 2*i, left); - put_child(tn, 2*i+1, right); - } - } - -+ /* prepare oldtnode to be freed */ -+ tnode_free_init(oldtnode); -+ - for (i = 0; i < olen; i++) { - struct tnode *inode = tnode_get_child(oldtnode, i); - struct tnode *left, *right; -@@ -505,12 +496,13 @@ static int inflate(struct trie *t, struc - continue; - } - -+ /* drop the node in the old tnode free list */ -+ tnode_free_append(oldtnode, inode); -+ - /* An internal node with two children */ - if (inode->bits == 1) { - put_child(tn, 2*i, rtnl_dereference(inode->child[0])); - put_child(tn, 2*i+1, rtnl_dereference(inode->child[1])); -- -- tnode_free_safe(inode); - continue; - } - -@@ -556,17 +548,19 @@ static int inflate(struct trie *t, struc - put_child(tn, 2 * i, left); - put_child(tn, 2 * i + 1, right); - -- tnode_free_safe(inode); -- -+ /* resize child nodes */ - resize(t, left); - resize(t, right); - } - - put_child_root(tp, t, tn->key, tn); -- tnode_free_safe(oldtnode); -+ -+ /* we completed without error, prepare to free old node */ -+ tnode_free(oldtnode); - return 0; - nomem: -- tnode_clean_free(tn); -+ /* all pointers should be clean so we are done */ -+ tnode_free(tn); - return -ENOMEM; - } - -@@ -599,17 +593,20 @@ static int halve(struct trie *t, struct - struct tnode *newn; - - newn = tnode_new(left->key, oldtnode->pos, 1); -- - if (!newn) { -- tnode_clean_free(tn); -+ tnode_free(tn); - return -ENOMEM; - } -+ tnode_free_append(tn, newn); - - put_child(tn, i/2, newn); - } - - } - -+ /* prepare oldtnode to be freed */ -+ tnode_free_init(oldtnode); -+ - for (i = 0; i < olen; i += 2) { - struct tnode *newBinNode; - -@@ -636,11 +633,14 @@ static int halve(struct trie *t, struct - - put_child(tn, i / 2, newBinNode); - -+ /* resize child node */ - resize(t, newBinNode); - } - - put_child_root(tp, t, tn->key, tn); -- tnode_free_safe(oldtnode); -+ -+ /* all pointers should be clean so we are done */ -+ tnode_free(oldtnode); - - return 0; - } -@@ -798,7 +798,8 @@ no_children: - node_set_parent(n, tp); - - /* drop dead node */ -- tnode_free_safe(tn); -+ tnode_free_init(tn); -+ tnode_free(tn); - } - } - -@@ -884,16 +885,12 @@ static void trie_rebalance(struct trie * - - while ((tp = node_parent(tn)) != NULL) { - resize(t, tn); -- -- tnode_free_flush(); - tn = tp; - } - - /* Handle last (top) tnode */ - if (IS_TNODE(tn)) - resize(t, tn); -- -- tnode_free_flush(); - } - - /* only used from updater-side */ diff --git a/target/linux/generic/pending-3.18/080-16-fib_trie-inflate-halve-nodes-in-a-more-RCU-friendly-.patch b/target/linux/generic/pending-3.18/080-16-fib_trie-inflate-halve-nodes-in-a-more-RCU-friendly-.patch deleted file mode 100644 index d6b600c5dd..0000000000 --- a/target/linux/generic/pending-3.18/080-16-fib_trie-inflate-halve-nodes-in-a-more-RCU-friendly-.patch +++ /dev/null @@ -1,345 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:56:55 -0800 -Subject: [PATCH] fib_trie: inflate/halve nodes in a more RCU friendly - way - -This change pulls the node_set_parent functionality out of put_child_reorg -and instead leaves that to the function to take care of as well. By doing -this we can fully construct the new cluster of tnodes and all of the -pointers out of it before we start routing pointers into it. - -I am suspecting this will likely fix some concurency issues though I don't -have a good test to show as such. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -391,8 +391,6 @@ static void put_child(struct tnode *tn, - else if (!wasfull && isfull) - tn->full_children++; - -- node_set_parent(n, tn); -- - rcu_assign_pointer(tn->child[i], n); - } - -@@ -436,10 +434,8 @@ static void tnode_free(struct tnode *tn) - - static int inflate(struct trie *t, struct tnode *oldtnode) - { -- unsigned long olen = tnode_child_length(oldtnode); -- struct tnode *tp = node_parent(oldtnode); -- struct tnode *tn; -- unsigned long i; -+ struct tnode *inode, *node0, *node1, *tn, *tp; -+ unsigned long i, j, k; - t_key m; - - pr_debug("In inflate\n"); -@@ -448,43 +444,13 @@ static int inflate(struct trie *t, struc - if (!tn) - return -ENOMEM; - -- /* -- * Preallocate and store tnodes before the actual work so we -- * don't get into an inconsistent state if memory allocation -- * fails. In case of failure we return the oldnode and inflate -- * of tnode is ignored. -+ /* Assemble all of the pointers in our cluster, in this case that -+ * represents all of the pointers out of our allocated nodes that -+ * point to existing tnodes and the links between our allocated -+ * nodes. - */ -- for (i = 0, m = 1u << tn->pos; i < olen; i++) { -- struct tnode *inode = tnode_get_child(oldtnode, i); -- -- if (tnode_full(oldtnode, inode) && (inode->bits > 1)) { -- struct tnode *left, *right; -- -- left = tnode_new(inode->key & ~m, inode->pos, -- inode->bits - 1); -- if (!left) -- goto nomem; -- tnode_free_append(tn, left); -- -- right = tnode_new(inode->key | m, inode->pos, -- inode->bits - 1); -- -- if (!right) -- goto nomem; -- tnode_free_append(tn, right); -- -- put_child(tn, 2*i, left); -- put_child(tn, 2*i+1, right); -- } -- } -- -- /* prepare oldtnode to be freed */ -- tnode_free_init(oldtnode); -- -- for (i = 0; i < olen; i++) { -- struct tnode *inode = tnode_get_child(oldtnode, i); -- struct tnode *left, *right; -- unsigned long size, j; -+ for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { -+ inode = tnode_get_child(oldtnode, --i); - - /* An empty child */ - if (inode == NULL) -@@ -496,65 +462,99 @@ static int inflate(struct trie *t, struc - continue; - } - -- /* drop the node in the old tnode free list */ -- tnode_free_append(oldtnode, inode); -- - /* An internal node with two children */ - if (inode->bits == 1) { -- put_child(tn, 2*i, rtnl_dereference(inode->child[0])); -- put_child(tn, 2*i+1, rtnl_dereference(inode->child[1])); -+ put_child(tn, 2 * i + 1, tnode_get_child(inode, 1)); -+ put_child(tn, 2 * i, tnode_get_child(inode, 0)); - continue; - } - -- /* An internal node with more than two children */ -- - /* We will replace this node 'inode' with two new -- * ones, 'left' and 'right', each with half of the -+ * ones, 'node0' and 'node1', each with half of the - * original children. The two new nodes will have - * a position one bit further down the key and this - * means that the "significant" part of their keys - * (see the discussion near the top of this file) - * will differ by one bit, which will be "0" in -- * left's key and "1" in right's key. Since we are -+ * node0's key and "1" in node1's key. Since we are - * moving the key position by one step, the bit that - * we are moving away from - the bit at position -- * (inode->pos) - is the one that will differ between -- * left and right. So... we synthesize that bit in the -- * two new keys. -- * The mask 'm' below will be a single "one" bit at -- * the position (inode->pos) -+ * (tn->pos) - is the one that will differ between -+ * node0 and node1. So... we synthesize that bit in the -+ * two new keys. - */ -+ node1 = tnode_new(inode->key | m, inode->pos, inode->bits - 1); -+ if (!node1) -+ goto nomem; -+ tnode_free_append(tn, node1); -+ -+ node0 = tnode_new(inode->key & ~m, inode->pos, inode->bits - 1); -+ if (!node0) -+ goto nomem; -+ tnode_free_append(tn, node0); -+ -+ /* populate child pointers in new nodes */ -+ for (k = tnode_child_length(inode), j = k / 2; j;) { -+ put_child(node1, --j, tnode_get_child(inode, --k)); -+ put_child(node0, j, tnode_get_child(inode, j)); -+ put_child(node1, --j, tnode_get_child(inode, --k)); -+ put_child(node0, j, tnode_get_child(inode, j)); -+ } -+ -+ /* link new nodes to parent */ -+ NODE_INIT_PARENT(node1, tn); -+ NODE_INIT_PARENT(node0, tn); -+ -+ /* link parent to nodes */ -+ put_child(tn, 2 * i + 1, node1); -+ put_child(tn, 2 * i, node0); -+ } -+ -+ /* setup the parent pointer into and out of this node */ -+ tp = node_parent(oldtnode); -+ NODE_INIT_PARENT(tn, tp); -+ put_child_root(tp, t, tn->key, tn); - -- /* Use the old key, but set the new significant -- * bit to zero. -- */ -+ /* prepare oldtnode to be freed */ -+ tnode_free_init(oldtnode); - -- left = tnode_get_child(tn, 2*i); -- put_child(tn, 2*i, NULL); -+ /* update all child nodes parent pointers to route to us */ -+ for (i = tnode_child_length(oldtnode); i;) { -+ inode = tnode_get_child(oldtnode, --i); - -- BUG_ON(!left); -+ /* A leaf or an internal node with skipped bits */ -+ if (!tnode_full(oldtnode, inode)) { -+ node_set_parent(inode, tn); -+ continue; -+ } - -- right = tnode_get_child(tn, 2*i+1); -- put_child(tn, 2*i+1, NULL); -+ /* drop the node in the old tnode free list */ -+ tnode_free_append(oldtnode, inode); - -- BUG_ON(!right); -+ /* fetch new nodes */ -+ node1 = tnode_get_child(tn, 2 * i + 1); -+ node0 = tnode_get_child(tn, 2 * i); - -- size = tnode_child_length(left); -- for (j = 0; j < size; j++) { -- put_child(left, j, rtnl_dereference(inode->child[j])); -- put_child(right, j, rtnl_dereference(inode->child[j + size])); -+ /* bits == 1 then node0 and node1 represent inode's children */ -+ if (inode->bits == 1) { -+ node_set_parent(node1, tn); -+ node_set_parent(node0, tn); -+ continue; - } - -- put_child(tn, 2 * i, left); -- put_child(tn, 2 * i + 1, right); -+ /* update parent pointers in child node's children */ -+ for (k = tnode_child_length(inode), j = k / 2; j;) { -+ node_set_parent(tnode_get_child(inode, --k), node1); -+ node_set_parent(tnode_get_child(inode, --j), node0); -+ node_set_parent(tnode_get_child(inode, --k), node1); -+ node_set_parent(tnode_get_child(inode, --j), node0); -+ } - - /* resize child nodes */ -- resize(t, left); -- resize(t, right); -+ resize(t, node1); -+ resize(t, node0); - } - -- put_child_root(tp, t, tn->key, tn); -- - /* we completed without error, prepare to free old node */ - tnode_free(oldtnode); - return 0; -@@ -566,10 +566,8 @@ nomem: - - static int halve(struct trie *t, struct tnode *oldtnode) - { -- unsigned long olen = tnode_child_length(oldtnode); -- struct tnode *tp = node_parent(oldtnode); -- struct tnode *tn, *left, *right; -- int i; -+ struct tnode *tn, *tp, *inode, *node0, *node1; -+ unsigned long i; - - pr_debug("In halve\n"); - -@@ -577,68 +575,64 @@ static int halve(struct trie *t, struct - if (!tn) - return -ENOMEM; - -- /* -- * Preallocate and store tnodes before the actual work so we -- * don't get into an inconsistent state if memory allocation -- * fails. In case of failure we return the oldnode and halve -- * of tnode is ignored. -+ /* Assemble all of the pointers in our cluster, in this case that -+ * represents all of the pointers out of our allocated nodes that -+ * point to existing tnodes and the links between our allocated -+ * nodes. - */ -+ for (i = tnode_child_length(oldtnode); i;) { -+ node1 = tnode_get_child(oldtnode, --i); -+ node0 = tnode_get_child(oldtnode, --i); - -- for (i = 0; i < olen; i += 2) { -- left = tnode_get_child(oldtnode, i); -- right = tnode_get_child(oldtnode, i+1); -+ /* At least one of the children is empty */ -+ if (!node1 || !node0) { -+ put_child(tn, i / 2, node1 ? : node0); -+ continue; -+ } - - /* Two nonempty children */ -- if (left && right) { -- struct tnode *newn; -- -- newn = tnode_new(left->key, oldtnode->pos, 1); -- if (!newn) { -- tnode_free(tn); -- return -ENOMEM; -- } -- tnode_free_append(tn, newn); -- -- put_child(tn, i/2, newn); -+ inode = tnode_new(node0->key, oldtnode->pos, 1); -+ if (!inode) { -+ tnode_free(tn); -+ return -ENOMEM; - } -+ tnode_free_append(tn, inode); - -+ /* initialize pointers out of node */ -+ put_child(inode, 1, node1); -+ put_child(inode, 0, node0); -+ NODE_INIT_PARENT(inode, tn); -+ -+ /* link parent to node */ -+ put_child(tn, i / 2, inode); - } - -+ /* setup the parent pointer out of and back into this node */ -+ tp = node_parent(oldtnode); -+ NODE_INIT_PARENT(tn, tp); -+ put_child_root(tp, t, tn->key, tn); -+ - /* prepare oldtnode to be freed */ - tnode_free_init(oldtnode); - -- for (i = 0; i < olen; i += 2) { -- struct tnode *newBinNode; -- -- left = tnode_get_child(oldtnode, i); -- right = tnode_get_child(oldtnode, i+1); -- -- /* At least one of the children is empty */ -- if (left == NULL) { -- if (right == NULL) /* Both are empty */ -- continue; -- put_child(tn, i/2, right); -- continue; -- } -- -- if (right == NULL) { -- put_child(tn, i/2, left); -+ /* update all of the child parent pointers */ -+ for (i = tnode_child_length(tn); i;) { -+ inode = tnode_get_child(tn, --i); -+ -+ /* only new tnodes will be considered "full" nodes */ -+ if (!tnode_full(tn, inode)) { -+ node_set_parent(inode, tn); - continue; - } - - /* Two nonempty children */ -- newBinNode = tnode_get_child(tn, i/2); -- put_child(newBinNode, 0, left); -- put_child(newBinNode, 1, right); -- -- put_child(tn, i / 2, newBinNode); -+ node_set_parent(tnode_get_child(inode, 1), inode); -+ node_set_parent(tnode_get_child(inode, 0), inode); - - /* resize child node */ -- resize(t, newBinNode); -+ resize(t, inode); - } - -- put_child_root(tp, t, tn->key, tn); -- - /* all pointers should be clean so we are done */ - tnode_free(oldtnode); - diff --git a/target/linux/generic/pending-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch b/target/linux/generic/pending-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch deleted file mode 100644 index 8f7c671ac6..0000000000 --- a/target/linux/generic/pending-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:57:02 -0800 -Subject: [PATCH] fib_trie: Remove checks for index >= tnode_child_length - from tnode_get_child - -For some reason the compiler doesn't seem to understand that when we are in -a loop that runs from tnode_child_length - 1 to 0 we don't expect the value -of tn->bits to change. As such every call to tnode_get_child was rerunning -tnode_chile_length which ended up consuming quite a bit of space in the -resultant assembly code. - -I have gone though and verified that in all cases where tnode_get_child -is used we are either winding though a fixed loop from tnode_child_length - -1 to 0, or are in a fastpath case where we are verifying the value by -either checking for any remaining bits after shifting index by bits and -testing for leaf, or by using tnode_child_length. - -size net/ipv4/fib_trie.o -Before: - text data bss dec hex filename - 15506 376 8 15890 3e12 net/ipv4/fib_trie.o - -After: - text data bss dec hex filename - 14827 376 8 15211 3b6b net/ipv4/fib_trie.o - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -186,8 +186,6 @@ static inline unsigned long tnode_child_ - static inline struct tnode *tnode_get_child(const struct tnode *tn, - unsigned long i) - { -- BUG_ON(i >= tnode_child_length(tn)); -- - return rtnl_dereference(tn->child[i]); - } - -@@ -195,8 +193,6 @@ static inline struct tnode *tnode_get_ch - static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, - unsigned long i) - { -- BUG_ON(i >= tnode_child_length(tn)); -- - return rcu_dereference_rtnl(tn->child[i]); - } - -@@ -371,7 +367,7 @@ static inline int tnode_full(const struc - */ - static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) - { -- struct tnode *chi = rtnl_dereference(tn->child[i]); -+ struct tnode *chi = tnode_get_child(tn, i); - int isfull, wasfull; - - BUG_ON(i >= tnode_child_length(tn)); -@@ -867,7 +863,7 @@ static struct tnode *fib_find_node(struc - if (IS_LEAF(n)) - break; - -- n = rcu_dereference_rtnl(n->child[index]); -+ n = tnode_get_child_rcu(n, index); - } - - return n; -@@ -934,7 +930,7 @@ static struct list_head *fib_insert_node - } - - tp = n; -- n = rcu_dereference_rtnl(n->child[index]); -+ n = tnode_get_child_rcu(n, index); - } - - l = leaf_new(key); -@@ -1215,7 +1211,7 @@ int fib_table_lookup(struct fib_table *t - cindex = index; - } - -- n = rcu_dereference(n->child[index]); -+ n = tnode_get_child_rcu(n, index); - if (unlikely(!n)) - goto backtrace; - } -@@ -1835,7 +1831,7 @@ static void trie_collect_stats(struct tr - if (n->bits < MAX_STAT_DEPTH) - s->nodesizes[n->bits]++; - -- for (i = 0; i < tnode_child_length(n); i++) { -+ for (i = tnode_child_length(n); i--;) { - if (!rcu_access_pointer(n->child[i])) - s->nullpointers++; - } diff --git a/target/linux/generic/pending-3.18/080-18-fib_trie-Add-tracking-value-for-suffix-length.patch b/target/linux/generic/pending-3.18/080-18-fib_trie-Add-tracking-value-for-suffix-length.patch deleted file mode 100644 index 6a4a45e952..0000000000 --- a/target/linux/generic/pending-3.18/080-18-fib_trie-Add-tracking-value-for-suffix-length.patch +++ /dev/null @@ -1,234 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Wed, 31 Dec 2014 10:57:08 -0800 -Subject: [PATCH] fib_trie: Add tracking value for suffix length - -This change adds a tracking value for the maximum suffix length of all -prefixes stored in any given tnode. With this value we can determine if we -need to backtrace or not based on if the suffix is greater than the pos -value. - -By doing this we can reduce the CPU overhead for lookups in the local table -as many of the prefixes there are 32b long and have a suffix length of 0 -meaning we can immediately backtrace to the root node without needing to -test any of the nodes between it and where we ended up. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -96,6 +96,7 @@ struct tnode { - t_key key; - unsigned char bits; /* 2log(KEYLENGTH) bits needed */ - unsigned char pos; /* 2log(KEYLENGTH) bits needed */ -+ unsigned char slen; - struct tnode __rcu *parent; - struct rcu_head rcu; - union { -@@ -311,6 +312,7 @@ static struct tnode *leaf_new(t_key key) - * as the nodes are searched - */ - l->key = key; -+ l->slen = 0; - l->pos = 0; - /* set bits to 0 indicating we are not a tnode */ - l->bits = 0; -@@ -342,6 +344,7 @@ static struct tnode *tnode_new(t_key key - - if (tn) { - tn->parent = NULL; -+ tn->slen = pos; - tn->pos = pos; - tn->bits = bits; - tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; -@@ -387,6 +390,9 @@ static void put_child(struct tnode *tn, - else if (!wasfull && isfull) - tn->full_children++; - -+ if (n && (tn->slen < n->slen)) -+ tn->slen = n->slen; -+ - rcu_assign_pointer(tn->child[i], n); - } - -@@ -635,6 +641,41 @@ static int halve(struct trie *t, struct - return 0; - } - -+static unsigned char update_suffix(struct tnode *tn) -+{ -+ unsigned char slen = tn->pos; -+ unsigned long stride, i; -+ -+ /* search though the list of children looking for nodes that might -+ * have a suffix greater than the one we currently have. This is -+ * why we start with a stride of 2 since a stride of 1 would -+ * represent the nodes with suffix length equal to tn->pos -+ */ -+ for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) { -+ struct tnode *n = tnode_get_child(tn, i); -+ -+ if (!n || (n->slen <= slen)) -+ continue; -+ -+ /* update stride and slen based on new value */ -+ stride <<= (n->slen - slen); -+ slen = n->slen; -+ i &= ~(stride - 1); -+ -+ /* if slen covers all but the last bit we can stop here -+ * there will be nothing longer than that since only node -+ * 0 and 1 << (bits - 1) could have that as their suffix -+ * length. -+ */ -+ if ((slen + 1) >= (tn->pos + tn->bits)) -+ break; -+ } -+ -+ tn->slen = slen; -+ -+ return slen; -+} -+ - /* From "Implementing a dynamic compressed trie" by Stefan Nilsson of - * the Helsinki University of Technology and Matti Tikkanen of Nokia - * Telecommunications, page 6: -@@ -790,6 +831,19 @@ no_children: - /* drop dead node */ - tnode_free_init(tn); - tnode_free(tn); -+ return; -+ } -+ -+ /* Return if at least one deflate was run */ -+ if (max_work != MAX_WORK) -+ return; -+ -+ /* push the suffix length to the parent node */ -+ if (tn->slen > tn->pos) { -+ unsigned char slen = update_suffix(tn); -+ -+ if (tp && (slen > tp->slen)) -+ tp->slen = slen; - } - } - -@@ -818,8 +872,58 @@ static inline struct list_head *get_fa_h - return &li->falh; - } - --static void insert_leaf_info(struct hlist_head *head, struct leaf_info *new) -+static void leaf_pull_suffix(struct tnode *l) -+{ -+ struct tnode *tp = node_parent(l); -+ -+ while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) { -+ if (update_suffix(tp) > l->slen) -+ break; -+ tp = node_parent(tp); -+ } -+} -+ -+static void leaf_push_suffix(struct tnode *l) -+{ -+ struct tnode *tn = node_parent(l); -+ -+ /* if this is a new leaf then tn will be NULL and we can sort -+ * out parent suffix lengths as a part of trie_rebalance -+ */ -+ while (tn && (tn->slen < l->slen)) { -+ tn->slen = l->slen; -+ tn = node_parent(tn); -+ } -+} -+ -+static void remove_leaf_info(struct tnode *l, struct leaf_info *old) -+{ -+ struct hlist_node *prev; -+ -+ /* record the location of the pointer to this object */ -+ prev = rtnl_dereference(hlist_pprev_rcu(&old->hlist)); -+ -+ /* remove the leaf info from the list */ -+ hlist_del_rcu(&old->hlist); -+ -+ /* if we emptied the list this leaf will be freed and we can sort -+ * out parent suffix lengths as a part of trie_rebalance -+ */ -+ if (hlist_empty(&l->list)) -+ return; -+ -+ /* if we removed the tail then we need to update slen */ -+ if (!rcu_access_pointer(hlist_next_rcu(prev))) { -+ struct leaf_info *li = hlist_entry(prev, typeof(*li), hlist); -+ -+ l->slen = KEYLENGTH - li->plen; -+ leaf_pull_suffix(l); -+ } -+} -+ -+static void insert_leaf_info(struct tnode *l, struct leaf_info *new) - { -+ struct hlist_head *head = &l->list; - struct leaf_info *li = NULL, *last = NULL; - - if (hlist_empty(head)) { -@@ -836,6 +940,12 @@ static void insert_leaf_info(struct hlis - else - hlist_add_before_rcu(&new->hlist, &li->hlist); - } -+ -+ /* if we added to the tail node then we need to update slen */ -+ if (!rcu_access_pointer(hlist_next_rcu(&new->hlist))) { -+ l->slen = KEYLENGTH - new->plen; -+ leaf_push_suffix(l); -+ } - } - - /* rcu_read_lock needs to be hold by caller from readside */ -@@ -925,7 +1035,7 @@ static struct list_head *fib_insert_node - /* we have found a leaf. Prefixes have already been compared */ - if (IS_LEAF(n)) { - /* Case 1: n is a leaf, and prefixes match*/ -- insert_leaf_info(&n->list, li); -+ insert_leaf_info(n, li); - return fa_head; - } - -@@ -939,7 +1049,7 @@ static struct list_head *fib_insert_node - return NULL; - } - -- insert_leaf_info(&l->list, li); -+ insert_leaf_info(l, li); - - /* Case 2: n is a LEAF or a TNODE and the key doesn't match. - * -@@ -1206,7 +1316,7 @@ int fib_table_lookup(struct fib_table *t - /* only record pn and cindex if we are going to be chopping - * bits later. Otherwise we are just wasting cycles. - */ -- if (index) { -+ if (n->slen > n->pos) { - pn = n; - cindex = index; - } -@@ -1225,7 +1335,7 @@ int fib_table_lookup(struct fib_table *t - * between the key and the prefix exist in the region of - * the lsb and higher in the prefix. - */ -- if (unlikely(prefix_mismatch(key, n))) -+ if (unlikely(prefix_mismatch(key, n)) || (n->slen == n->pos)) - goto backtrace; - - /* exit out and process leaf */ -@@ -1425,7 +1535,7 @@ int fib_table_delete(struct fib_table *t - tb->tb_num_default--; - - if (list_empty(fa_head)) { -- hlist_del_rcu(&li->hlist); -+ remove_leaf_info(l, li); - free_leaf_info(li); - } - diff --git a/target/linux/generic/pending-3.18/080-19-fib_trie-Use-index-0ul-n-bits-instead-of-index-n-bit.patch b/target/linux/generic/pending-3.18/080-19-fib_trie-Use-index-0ul-n-bits-instead-of-index-n-bit.patch deleted file mode 100644 index d5fc112563..0000000000 --- a/target/linux/generic/pending-3.18/080-19-fib_trie-Use-index-0ul-n-bits-instead-of-index-n-bit.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:08 -0800 -Subject: [PATCH] fib_trie: Use index & (~0ul << n->bits) instead of index >> - n->bits - -In doing performance testing and analysis of the changes I recently found -that by shifting the index I had created an unnecessary dependency. - -I have updated the code so that we instead shift a mask by bits and then -just test against that as that should save us about 2 CPU cycles since we -can generate the mask while the key and pos are being processed. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -961,12 +961,12 @@ static struct tnode *fib_find_node(struc - * prefix plus zeros for the bits in the cindex. The index - * is the difference between the key and this value. From - * this we can actually derive several pieces of data. -- * if !(index >> bits) -- * we know the value is cindex -- * else -+ * if (index & (~0ul << bits)) - * we have a mismatch in skip bits and failed -+ * else -+ * we know the value is cindex - */ -- if (index >> n->bits) -+ if (index & (~0ul << n->bits)) - return NULL; - - /* we have found a leaf. Prefixes have already been compared */ -@@ -1301,12 +1301,12 @@ int fib_table_lookup(struct fib_table *t - * prefix plus zeros for the "bits" in the prefix. The index - * is the difference between the key and this value. From - * this we can actually derive several pieces of data. -- * if !(index >> bits) -- * we know the value is child index -- * else -+ * if (index & (~0ul << bits)) - * we have a mismatch in skip bits and failed -+ * else -+ * we know the value is cindex - */ -- if (index >> n->bits) -+ if (index & (~0ul << n->bits)) - break; - - /* we have found a leaf. Prefixes have already been compared */ diff --git a/target/linux/generic/pending-3.18/080-20-fib_trie-Fix-RCU-bug-and-merge-similar-bits-of-infla.patch b/target/linux/generic/pending-3.18/080-20-fib_trie-Fix-RCU-bug-and-merge-similar-bits-of-infla.patch deleted file mode 100644 index 7e26127084..0000000000 --- a/target/linux/generic/pending-3.18/080-20-fib_trie-Fix-RCU-bug-and-merge-similar-bits-of-infla.patch +++ /dev/null @@ -1,267 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:14 -0800 -Subject: [PATCH] fib_trie: Fix RCU bug and merge similar bits of inflate/halve - -This patch addresses two issues. - -The first issue is the fact that I believe I had the RCU freeing sequence -slightly out of order. As a result we could get into an issue if a caller -went into a child of a child of the new node, then backtraced into the to be -freed parent, and then attempted to access a child of a child that may have -been consumed in a resize of one of the new nodes children. To resolve this I -have moved the resize after we have freed the oldtnode. The only side effect -of this is that we will now be calling resize on more nodes in the case of -inflate due to the fact that we don't have a good way to test to see if a -full_tnode on the new node was there before or after the allocation. This -should have minimal impact however since the node should already be -correctly size so it is just the cost of calling should_inflate that we -will be taking on the node which is only a couple of cycles. - -The second issue is the fact that inflate and halve were essentially doing -the same thing after the new node was added to the trie replacing the old -one. As such it wasn't really necessary to keep the code in both functions -so I have split it out into two other functions, called replace and -update_children. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -396,8 +396,30 @@ static void put_child(struct tnode *tn, - rcu_assign_pointer(tn->child[i], n); - } - --static void put_child_root(struct tnode *tp, struct trie *t, -- t_key key, struct tnode *n) -+static void update_children(struct tnode *tn) -+{ -+ unsigned long i; -+ -+ /* update all of the child parent pointers */ -+ for (i = tnode_child_length(tn); i;) { -+ struct tnode *inode = tnode_get_child(tn, --i); -+ -+ if (!inode) -+ continue; -+ -+ /* Either update the children of a tnode that -+ * already belongs to us or update the child -+ * to point to ourselves. -+ */ -+ if (node_parent(inode) == tn) -+ update_children(inode); -+ else -+ node_set_parent(inode, tn); -+ } -+} -+ -+static inline void put_child_root(struct tnode *tp, struct trie *t, -+ t_key key, struct tnode *n) - { - if (tp) - put_child(tp, get_index(key, tp), n); -@@ -434,10 +456,35 @@ static void tnode_free(struct tnode *tn) - } - } - -+static void replace(struct trie *t, struct tnode *oldtnode, struct tnode *tn) -+{ -+ struct tnode *tp = node_parent(oldtnode); -+ unsigned long i; -+ -+ /* setup the parent pointer out of and back into this node */ -+ NODE_INIT_PARENT(tn, tp); -+ put_child_root(tp, t, tn->key, tn); -+ -+ /* update all of the child parent pointers */ -+ update_children(tn); -+ -+ /* all pointers should be clean so we are done */ -+ tnode_free(oldtnode); -+ -+ /* resize children now that oldtnode is freed */ -+ for (i = tnode_child_length(tn); i;) { -+ struct tnode *inode = tnode_get_child(tn, --i); -+ -+ /* resize child node */ -+ if (tnode_full(tn, inode)) -+ resize(t, inode); -+ } -+} -+ - static int inflate(struct trie *t, struct tnode *oldtnode) - { -- struct tnode *inode, *node0, *node1, *tn, *tp; -- unsigned long i, j, k; -+ struct tnode *tn; -+ unsigned long i; - t_key m; - - pr_debug("In inflate\n"); -@@ -446,13 +493,18 @@ static int inflate(struct trie *t, struc - if (!tn) - return -ENOMEM; - -+ /* prepare oldtnode to be freed */ -+ tnode_free_init(oldtnode); -+ - /* Assemble all of the pointers in our cluster, in this case that - * represents all of the pointers out of our allocated nodes that - * point to existing tnodes and the links between our allocated - * nodes. - */ - for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { -- inode = tnode_get_child(oldtnode, --i); -+ struct tnode *inode = tnode_get_child(oldtnode, --i); -+ struct tnode *node0, *node1; -+ unsigned long j, k; - - /* An empty child */ - if (inode == NULL) -@@ -464,6 +516,9 @@ static int inflate(struct trie *t, struc - continue; - } - -+ /* drop the node in the old tnode free list */ -+ tnode_free_append(oldtnode, inode); -+ - /* An internal node with two children */ - if (inode->bits == 1) { - put_child(tn, 2 * i + 1, tnode_get_child(inode, 1)); -@@ -488,9 +543,9 @@ static int inflate(struct trie *t, struc - node1 = tnode_new(inode->key | m, inode->pos, inode->bits - 1); - if (!node1) - goto nomem; -- tnode_free_append(tn, node1); -+ node0 = tnode_new(inode->key, inode->pos, inode->bits - 1); - -- node0 = tnode_new(inode->key & ~m, inode->pos, inode->bits - 1); -+ tnode_free_append(tn, node1); - if (!node0) - goto nomem; - tnode_free_append(tn, node0); -@@ -512,53 +567,9 @@ static int inflate(struct trie *t, struc - put_child(tn, 2 * i, node0); - } - -- /* setup the parent pointer into and out of this node */ -- tp = node_parent(oldtnode); -- NODE_INIT_PARENT(tn, tp); -- put_child_root(tp, t, tn->key, tn); -+ /* setup the parent pointers into and out of this node */ -+ replace(t, oldtnode, tn); - -- /* prepare oldtnode to be freed */ -- tnode_free_init(oldtnode); -- -- /* update all child nodes parent pointers to route to us */ -- for (i = tnode_child_length(oldtnode); i;) { -- inode = tnode_get_child(oldtnode, --i); -- -- /* A leaf or an internal node with skipped bits */ -- if (!tnode_full(oldtnode, inode)) { -- node_set_parent(inode, tn); -- continue; -- } -- -- /* drop the node in the old tnode free list */ -- tnode_free_append(oldtnode, inode); -- -- /* fetch new nodes */ -- node1 = tnode_get_child(tn, 2 * i + 1); -- node0 = tnode_get_child(tn, 2 * i); -- -- /* bits == 1 then node0 and node1 represent inode's children */ -- if (inode->bits == 1) { -- node_set_parent(node1, tn); -- node_set_parent(node0, tn); -- continue; -- } -- -- /* update parent pointers in child node's children */ -- for (k = tnode_child_length(inode), j = k / 2; j;) { -- node_set_parent(tnode_get_child(inode, --k), node1); -- node_set_parent(tnode_get_child(inode, --j), node0); -- node_set_parent(tnode_get_child(inode, --k), node1); -- node_set_parent(tnode_get_child(inode, --j), node0); -- } -- -- /* resize child nodes */ -- resize(t, node1); -- resize(t, node0); -- } -- -- /* we completed without error, prepare to free old node */ -- tnode_free(oldtnode); - return 0; - nomem: - /* all pointers should be clean so we are done */ -@@ -568,7 +579,7 @@ nomem: - - static int halve(struct trie *t, struct tnode *oldtnode) - { -- struct tnode *tn, *tp, *inode, *node0, *node1; -+ struct tnode *tn; - unsigned long i; - - pr_debug("In halve\n"); -@@ -577,14 +588,18 @@ static int halve(struct trie *t, struct - if (!tn) - return -ENOMEM; - -+ /* prepare oldtnode to be freed */ -+ tnode_free_init(oldtnode); -+ - /* Assemble all of the pointers in our cluster, in this case that - * represents all of the pointers out of our allocated nodes that - * point to existing tnodes and the links between our allocated - * nodes. - */ - for (i = tnode_child_length(oldtnode); i;) { -- node1 = tnode_get_child(oldtnode, --i); -- node0 = tnode_get_child(oldtnode, --i); -+ struct tnode *node1 = tnode_get_child(oldtnode, --i); -+ struct tnode *node0 = tnode_get_child(oldtnode, --i); -+ struct tnode *inode; - - /* At least one of the children is empty */ - if (!node1 || !node0) { -@@ -609,34 +624,8 @@ static int halve(struct trie *t, struct - put_child(tn, i / 2, inode); - } - -- /* setup the parent pointer out of and back into this node */ -- tp = node_parent(oldtnode); -- NODE_INIT_PARENT(tn, tp); -- put_child_root(tp, t, tn->key, tn); -- -- /* prepare oldtnode to be freed */ -- tnode_free_init(oldtnode); -- -- /* update all of the child parent pointers */ -- for (i = tnode_child_length(tn); i;) { -- inode = tnode_get_child(tn, --i); -- -- /* only new tnodes will be considered "full" nodes */ -- if (!tnode_full(tn, inode)) { -- node_set_parent(inode, tn); -- continue; -- } -- -- /* Two nonempty children */ -- node_set_parent(tnode_get_child(inode, 1), inode); -- node_set_parent(tnode_get_child(inode, 0), inode); -- -- /* resize child node */ -- resize(t, inode); -- } -- -- /* all pointers should be clean so we are done */ -- tnode_free(oldtnode); -+ /* setup the parent pointers into and out of this node */ -+ replace(t, oldtnode, tn); - - return 0; - } diff --git a/target/linux/generic/pending-3.18/080-21-fib_trie-Fall-back-to-slen-update-on-inflate-halve-f.patch b/target/linux/generic/pending-3.18/080-21-fib_trie-Fall-back-to-slen-update-on-inflate-halve-f.patch deleted file mode 100644 index 058b33bf9d..0000000000 --- a/target/linux/generic/pending-3.18/080-21-fib_trie-Fall-back-to-slen-update-on-inflate-halve-f.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:20 -0800 -Subject: [PATCH] fib_trie: Fall back to slen update on inflate/halve failure - -This change corrects an issue where if inflate or halve fails we were -exiting the resize function without at least updating the slen for the -node. To correct this I have moved the update of max_size into the while -loop so that it is only decremented on a successful call to either inflate -or halve. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -752,7 +752,7 @@ static void resize(struct trie *t, struc - { - struct tnode *tp = node_parent(tn), *n = NULL; - struct tnode __rcu **cptr; -- int max_work; -+ int max_work = MAX_WORK; - - pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", - tn, inflate_threshold, halve_threshold); -@@ -775,8 +775,7 @@ static void resize(struct trie *t, struc - /* Double as long as the resulting node has a number of - * nonempty nodes that are above the threshold. - */ -- max_work = MAX_WORK; -- while (should_inflate(tp, tn) && max_work--) { -+ while (should_inflate(tp, tn) && max_work) { - if (inflate(t, tn)) { - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); -@@ -784,6 +783,7 @@ static void resize(struct trie *t, struc - break; - } - -+ max_work--; - tn = rtnl_dereference(*cptr); - } - -@@ -794,8 +794,7 @@ static void resize(struct trie *t, struc - /* Halve as long as the number of empty children in this - * node is above threshold. - */ -- max_work = MAX_WORK; -- while (should_halve(tp, tn) && max_work--) { -+ while (should_halve(tp, tn) && max_work) { - if (halve(t, tn)) { - #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); -@@ -803,6 +802,7 @@ static void resize(struct trie *t, struc - break; - } - -+ max_work--; - tn = rtnl_dereference(*cptr); - } - diff --git a/target/linux/generic/pending-3.18/080-22-fib_trie-Add-collapse-and-should_collapse-to-resize.patch b/target/linux/generic/pending-3.18/080-22-fib_trie-Add-collapse-and-should_collapse-to-resize.patch deleted file mode 100644 index 19b7db7f94..0000000000 --- a/target/linux/generic/pending-3.18/080-22-fib_trie-Add-collapse-and-should_collapse-to-resize.patch +++ /dev/null @@ -1,206 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:26 -0800 -Subject: [PATCH] fib_trie: Add collapse() and should_collapse() to resize - -This patch really does two things. - -First it pulls the logic for determining if we should collapse one node out -of the tree and the actual code doing the collapse into a separate pair of -functions. This helps to make the changes to these areas more readable. - -Second it encodes the upper 32b of the empty_children value onto the -full_children value in the case of bits == KEYLENGTH. By doing this we are -able to handle the case of a 32b node where empty_children would appear to -be 0 when it was actually 1ul << 32. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -83,7 +83,8 @@ - - #define MAX_STAT_DEPTH 32 - --#define KEYLENGTH (8*sizeof(t_key)) -+#define KEYLENGTH (8*sizeof(t_key)) -+#define KEY_MAX ((t_key)~0) - - typedef unsigned int t_key; - -@@ -102,8 +103,8 @@ struct tnode { - union { - /* The fields in this struct are valid if bits > 0 (TNODE) */ - struct { -- unsigned int full_children; /* KEYLENGTH bits needed */ -- unsigned int empty_children; /* KEYLENGTH bits needed */ -+ t_key empty_children; /* KEYLENGTH bits needed */ -+ t_key full_children; /* KEYLENGTH bits needed */ - struct tnode __rcu *child[0]; - }; - /* This list pointer if valid if bits == 0 (LEAF) */ -@@ -302,6 +303,16 @@ static struct tnode *tnode_alloc(size_t - return vzalloc(size); - } - -+static inline void empty_child_inc(struct tnode *n) -+{ -+ ++n->empty_children ? : ++n->full_children; -+} -+ -+static inline void empty_child_dec(struct tnode *n) -+{ -+ n->empty_children-- ? : n->full_children--; -+} -+ - static struct tnode *leaf_new(t_key key) - { - struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); -@@ -335,7 +346,7 @@ static struct leaf_info *leaf_info_new(i - - static struct tnode *tnode_new(t_key key, int pos, int bits) - { -- size_t sz = offsetof(struct tnode, child[1 << bits]); -+ size_t sz = offsetof(struct tnode, child[1ul << bits]); - struct tnode *tn = tnode_alloc(sz); - unsigned int shift = pos + bits; - -@@ -348,8 +359,10 @@ static struct tnode *tnode_new(t_key key - tn->pos = pos; - tn->bits = bits; - tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; -- tn->full_children = 0; -- tn->empty_children = 1<<bits; -+ if (bits == KEYLENGTH) -+ tn->full_children = 1; -+ else -+ tn->empty_children = 1ul << bits; - } - - pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), -@@ -375,11 +388,11 @@ static void put_child(struct tnode *tn, - - BUG_ON(i >= tnode_child_length(tn)); - -- /* update emptyChildren */ -+ /* update emptyChildren, overflow into fullChildren */ - if (n == NULL && chi != NULL) -- tn->empty_children++; -- else if (n != NULL && chi == NULL) -- tn->empty_children--; -+ empty_child_inc(tn); -+ if (n != NULL && chi == NULL) -+ empty_child_dec(tn); - - /* update fullChildren */ - wasfull = tnode_full(tn, chi); -@@ -630,6 +643,24 @@ static int halve(struct trie *t, struct - return 0; - } - -+static void collapse(struct trie *t, struct tnode *oldtnode) -+{ -+ struct tnode *n, *tp; -+ unsigned long i; -+ -+ /* scan the tnode looking for that one child that might still exist */ -+ for (n = NULL, i = tnode_child_length(oldtnode); !n && i;) -+ n = tnode_get_child(oldtnode, --i); -+ -+ /* compress one level */ -+ tp = node_parent(oldtnode); -+ put_child_root(tp, t, oldtnode->key, n); -+ node_set_parent(n, tp); -+ -+ /* drop dead node */ -+ node_free(oldtnode); -+} -+ - static unsigned char update_suffix(struct tnode *tn) - { - unsigned char slen = tn->pos; -@@ -729,10 +760,12 @@ static bool should_inflate(const struct - - /* Keep root node larger */ - threshold *= tp ? inflate_threshold : inflate_threshold_root; -- used += tn->full_children; - used -= tn->empty_children; -+ used += tn->full_children; - -- return tn->pos && ((50 * used) >= threshold); -+ /* if bits == KEYLENGTH then pos = 0, and will fail below */ -+ -+ return (used > 1) && tn->pos && ((50 * used) >= threshold); - } - - static bool should_halve(const struct tnode *tp, const struct tnode *tn) -@@ -744,13 +777,29 @@ static bool should_halve(const struct tn - threshold *= tp ? halve_threshold : halve_threshold_root; - used -= tn->empty_children; - -- return (tn->bits > 1) && ((100 * used) < threshold); -+ /* if bits == KEYLENGTH then used = 100% on wrap, and will fail below */ -+ -+ return (used > 1) && (tn->bits > 1) && ((100 * used) < threshold); -+} -+ -+static bool should_collapse(const struct tnode *tn) -+{ -+ unsigned long used = tnode_child_length(tn); -+ -+ used -= tn->empty_children; -+ -+ /* account for bits == KEYLENGTH case */ -+ if ((tn->bits == KEYLENGTH) && tn->full_children) -+ used -= KEY_MAX; -+ -+ /* One child or none, time to drop us from the trie */ -+ return used < 2; - } - - #define MAX_WORK 10 - static void resize(struct trie *t, struct tnode *tn) - { -- struct tnode *tp = node_parent(tn), *n = NULL; -+ struct tnode *tp = node_parent(tn); - struct tnode __rcu **cptr; - int max_work = MAX_WORK; - -@@ -764,14 +813,6 @@ static void resize(struct trie *t, struc - cptr = tp ? &tp->child[get_index(tn->key, tp)] : &t->trie; - BUG_ON(tn != rtnl_dereference(*cptr)); - -- /* No children */ -- if (tn->empty_children > (tnode_child_length(tn) - 1)) -- goto no_children; -- -- /* One child */ -- if (tn->empty_children == (tnode_child_length(tn) - 1)) -- goto one_child; -- - /* Double as long as the resulting node has a number of - * nonempty nodes that are above the threshold. - */ -@@ -807,19 +848,8 @@ static void resize(struct trie *t, struc - } - - /* Only one child remains */ -- if (tn->empty_children == (tnode_child_length(tn) - 1)) { -- unsigned long i; --one_child: -- for (i = tnode_child_length(tn); !n && i;) -- n = tnode_get_child(tn, --i); --no_children: -- /* compress one level */ -- put_child_root(tp, t, tn->key, n); -- node_set_parent(n, tp); -- -- /* drop dead node */ -- tnode_free_init(tn); -- tnode_free(tn); -+ if (should_collapse(tn)) { -+ collapse(t, tn); - return; - } - diff --git a/target/linux/generic/pending-3.18/080-23-fib_trie-Use-empty_children-instead-of-counting-empt.patch b/target/linux/generic/pending-3.18/080-23-fib_trie-Use-empty_children-instead-of-counting-empt.patch deleted file mode 100644 index 160fbe1f3e..0000000000 --- a/target/linux/generic/pending-3.18/080-23-fib_trie-Use-empty_children-instead-of-counting-empt.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:33 -0800 -Subject: [PATCH] fib_trie: Use empty_children instead of counting empty nodes - in stats collection - -It doesn't make much sense to count the pointers ourselves when -empty_children already has a count for the number of NULL pointers stored -in the tnode. As such save ourselves the cycles and just use -empty_children. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1954,16 +1954,10 @@ static void trie_collect_stats(struct tr - hlist_for_each_entry_rcu(li, &n->list, hlist) - ++s->prefixes; - } else { -- unsigned long i; -- - s->tnodes++; - if (n->bits < MAX_STAT_DEPTH) - s->nodesizes[n->bits]++; -- -- for (i = tnode_child_length(n); i--;) { -- if (!rcu_access_pointer(n->child[i])) -- s->nullpointers++; -- } -+ s->nullpointers += n->empty_children; - } - } - rcu_read_unlock(); diff --git a/target/linux/generic/pending-3.18/080-24-fib_trie-Move-fib_find_alias-to-file-where-it-is-use.patch b/target/linux/generic/pending-3.18/080-24-fib_trie-Move-fib_find_alias-to-file-where-it-is-use.patch deleted file mode 100644 index 5eba700caa..0000000000 --- a/target/linux/generic/pending-3.18/080-24-fib_trie-Move-fib_find_alias-to-file-where-it-is-use.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:39 -0800 -Subject: [PATCH] fib_trie: Move fib_find_alias to file where it is used - -The function fib_find_alias is only accessed by functions in fib_trie.c as -such it makes sense to relocate it and cast it as static so that the -compiler can take advantage of optimizations it can do to it as a local -function. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_lookup.h -+++ b/net/ipv4/fib_lookup.h -@@ -32,7 +32,6 @@ int fib_dump_info(struct sk_buff *skb, u - unsigned int); - void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, int dst_len, - u32 tb_id, const struct nl_info *info, unsigned int nlm_flags); --struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio); - - static inline void fib_result_assign(struct fib_result *res, - struct fib_info *fi) ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -410,24 +410,6 @@ errout: - rtnl_set_sk_err(info->nl_net, RTNLGRP_IPV4_ROUTE, err); - } - --/* Return the first fib alias matching TOS with -- * priority less than or equal to PRIO. -- */ --struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio) --{ -- if (fah) { -- struct fib_alias *fa; -- list_for_each_entry(fa, fah, fa_list) { -- if (fa->fa_tos > tos) -- continue; -- if (fa->fa_info->fib_priority >= prio || -- fa->fa_tos < tos) -- return fa; -- } -- } -- return NULL; --} -- - static int fib_detect_death(struct fib_info *fi, int order, - struct fib_info **last_resort, int *last_idx, - int dflt) ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -998,6 +998,26 @@ static struct tnode *fib_find_node(struc - return n; - } - -+/* Return the first fib alias matching TOS with -+ * priority less than or equal to PRIO. -+ */ -+static struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio) -+{ -+ struct fib_alias *fa; -+ -+ if (!fah) -+ return NULL; -+ -+ list_for_each_entry(fa, fah, fa_list) { -+ if (fa->fa_tos > tos) -+ continue; -+ if (fa->fa_info->fib_priority >= prio || fa->fa_tos < tos) -+ return fa; -+ } -+ -+ return NULL; -+} -+ - static void trie_rebalance(struct trie *t, struct tnode *tn) - { - struct tnode *tp; diff --git a/target/linux/generic/pending-3.18/080-25-fib_trie-Various-clean-ups-for-handling-slen.patch b/target/linux/generic/pending-3.18/080-25-fib_trie-Various-clean-ups-for-handling-slen.patch deleted file mode 100644 index c7739d0323..0000000000 --- a/target/linux/generic/pending-3.18/080-25-fib_trie-Various-clean-ups-for-handling-slen.patch +++ /dev/null @@ -1,116 +0,0 @@ -From: Alexander Duyck <alexander.h.duyck@redhat.com> -Date: Thu, 22 Jan 2015 15:51:45 -0800 -Subject: [PATCH] fib_trie: Various clean-ups for handling slen - -While doing further work on the fib_trie I noted a few items. - -First I was using calls that were far more complicated than they needed to -be for determining when to push/pull the suffix length. I have updated the -code to reflect the simplier logic. - -The second issue is that I realised we weren't necessarily handling the -case of a leaf_info struct surviving a flush. I have updated the logic so -that now we will call pull_suffix in the event of having a leaf info value -left in the leaf after flushing it. - -Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -917,27 +917,20 @@ static void leaf_push_suffix(struct tnod - - static void remove_leaf_info(struct tnode *l, struct leaf_info *old) - { -- struct hlist_node *prev; -- -- /* record the location of the pointer to this object */ -- prev = rtnl_dereference(hlist_pprev_rcu(&old->hlist)); -+ /* record the location of the previous list_info entry */ -+ struct hlist_node **pprev = old->hlist.pprev; -+ struct leaf_info *li = hlist_entry(pprev, typeof(*li), hlist.next); - - /* remove the leaf info from the list */ - hlist_del_rcu(&old->hlist); - -- /* if we emptied the list this leaf will be freed and we can sort -- * out parent suffix lengths as a part of trie_rebalance -- */ -- if (hlist_empty(&l->list)) -+ /* only access li if it is pointing at the last valid hlist_node */ -+ if (hlist_empty(&l->list) || (*pprev)) - return; - -- /* if we removed the tail then we need to update slen */ -- if (!rcu_access_pointer(hlist_next_rcu(prev))) { -- struct leaf_info *li = hlist_entry(prev, typeof(*li), hlist); -- -- l->slen = KEYLENGTH - li->plen; -- leaf_pull_suffix(l); -- } -+ /* update the trie with the latest suffix length */ -+ l->slen = KEYLENGTH - li->plen; -+ leaf_pull_suffix(l); - } - - static void insert_leaf_info(struct tnode *l, struct leaf_info *new) -@@ -961,7 +954,7 @@ static void insert_leaf_info(struct tnod - } - - /* if we added to the tail node then we need to update slen */ -- if (!rcu_access_pointer(hlist_next_rcu(&new->hlist))) { -+ if (l->slen < (KEYLENGTH - new->plen)) { - l->slen = KEYLENGTH - new->plen; - leaf_push_suffix(l); - } -@@ -1613,6 +1606,7 @@ static int trie_flush_leaf(struct tnode - struct hlist_head *lih = &l->list; - struct hlist_node *tmp; - struct leaf_info *li = NULL; -+ unsigned char plen = KEYLENGTH; - - hlist_for_each_entry_safe(li, tmp, lih, hlist) { - found += trie_flush_list(&li->falh); -@@ -1620,8 +1614,14 @@ static int trie_flush_leaf(struct tnode - if (list_empty(&li->falh)) { - hlist_del_rcu(&li->hlist); - free_leaf_info(li); -+ continue; - } -+ -+ plen = li->plen; - } -+ -+ l->slen = KEYLENGTH - plen; -+ - return found; - } - -@@ -1700,13 +1700,22 @@ int fib_table_flush(struct fib_table *tb - for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { - found += trie_flush_leaf(l); - -- if (ll && hlist_empty(&ll->list)) -- trie_leaf_remove(t, ll); -+ if (ll) { -+ if (hlist_empty(&ll->list)) -+ trie_leaf_remove(t, ll); -+ else -+ leaf_pull_suffix(ll); -+ } -+ - ll = l; - } - -- if (ll && hlist_empty(&ll->list)) -- trie_leaf_remove(t, ll); -+ if (ll) { -+ if (hlist_empty(&ll->list)) -+ trie_leaf_remove(t, ll); -+ else -+ leaf_pull_suffix(ll); -+ } - - pr_debug("trie_flush found=%d\n", found); - return found; diff --git a/target/linux/generic/pending-3.18/081-01-pppoe-Use-workqueue-to-die-properly-when-a-PADT-is-r.patch b/target/linux/generic/pending-3.18/081-01-pppoe-Use-workqueue-to-die-properly-when-a-PADT-is-r.patch deleted file mode 100644 index fb44df97e9..0000000000 --- a/target/linux/generic/pending-3.18/081-01-pppoe-Use-workqueue-to-die-properly-when-a-PADT-is-r.patch +++ /dev/null @@ -1,89 +0,0 @@ -From: Simon Farnsworth <simon@farnz.org.uk> -Date: Sun, 1 Mar 2015 10:54:39 +0000 -Subject: [PATCH] pppoe: Use workqueue to die properly when a PADT is received - -When a PADT frame is received, the socket may not be in a good state to -close down the PPP interface. The current implementation handles this by -simply blocking all further PPP traffic, and hoping that the lack of traffic -will trigger the user to investigate. - -Use schedule_work to get to a process context from which we clear down the -PPP interface, in a fashion analogous to hangup on a TTY-based PPP -interface. This causes pppd to disconnect immediately, and allows tools to -take immediate corrective action. - -Note that pppd's rp_pppoe.so plugin has code in it to disable the session -when it disconnects; however, as a consequence of this patch, the session is -already disabled before rp_pppoe.so is asked to disable the session. The -result is a harmless error message: - -Failed to disconnect PPPoE socket: 114 Operation already in progress - -This message is safe to ignore, as long as the error is 114 Operation -already in progress; in that specific case, it means that the PPPoE session -has already been disabled before pppd tried to disable it. - -Signed-off-by: Simon Farnsworth <simon@farnz.org.uk> -Tested-by: Dan Williams <dcbw@redhat.com> -Tested-by: Christoph Schulz <develop@kristov.de> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -454,6 +454,18 @@ out: - return NET_RX_DROP; - } - -+static void pppoe_unbind_sock_work(struct work_struct *work) -+{ -+ struct pppox_sock *po = container_of(work, struct pppox_sock, -+ proto.pppoe.padt_work); -+ struct sock *sk = sk_pppox(po); -+ -+ lock_sock(sk); -+ pppox_unbind_sock(sk); -+ release_sock(sk); -+ sock_put(sk); -+} -+ - /************************************************************************ - * - * Receive a PPPoE Discovery frame. -@@ -499,7 +511,8 @@ static int pppoe_disc_rcv(struct sk_buff - } - - bh_unlock_sock(sk); -- sock_put(sk); -+ if (!schedule_work(&po->proto.pppoe.padt_work)) -+ sock_put(sk); - } - - abort: -@@ -612,6 +625,8 @@ static int pppoe_connect(struct socket * - - lock_sock(sk); - -+ INIT_WORK(&po->proto.pppoe.padt_work, pppoe_unbind_sock_work); -+ - error = -EINVAL; - - if (sockaddr_len != sizeof(struct sockaddr_pppox)) ---- a/include/linux/if_pppox.h -+++ b/include/linux/if_pppox.h -@@ -19,6 +19,7 @@ - #include <linux/netdevice.h> - #include <linux/ppp_channel.h> - #include <linux/skbuff.h> -+#include <linux/workqueue.h> - #include <uapi/linux/if_pppox.h> - - static inline struct pppoe_hdr *pppoe_hdr(const struct sk_buff *skb) -@@ -32,6 +33,7 @@ struct pppoe_opt { - struct pppoe_addr pa; /* what this socket is bound to*/ - struct sockaddr_pppox relay; /* what socket data will be - relayed to (PPPoE relaying) */ -+ struct work_struct padt_work;/* Work item for handling PADT */ - }; - - struct pptp_opt { diff --git a/target/linux/generic/pending-3.18/081-02-pppoe-Lacks-DST-MAC-address-check.patch b/target/linux/generic/pending-3.18/081-02-pppoe-Lacks-DST-MAC-address-check.patch deleted file mode 100644 index f592929b3e..0000000000 --- a/target/linux/generic/pending-3.18/081-02-pppoe-Lacks-DST-MAC-address-check.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se> -Date: Mon, 20 Apr 2015 21:07:48 +0200 -Subject: [PATCH] pppoe: Lacks DST MAC address check - -A pppoe session is identified by its session ID and MAC address. -Currently pppoe does not check if the received pkg has the correct -MAC address. This is a problem when the eth I/F is in promisc mode -as then any DST MAC address is accepted. - -Signed-off-by: Joakim Tjernlund <joakim.tjernlund@transmode.se> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -379,6 +379,9 @@ static int pppoe_rcv_core(struct sock *s - * can't change. - */ - -+ if (skb->pkt_type == PACKET_OTHERHOST) -+ goto abort_kfree; -+ - if (sk->sk_state & PPPOX_BOUND) { - ppp_input(&po->chan, skb); - } else if (sk->sk_state & PPPOX_RELAY) { diff --git a/target/linux/generic/pending-3.18/081-03-pppoe-drop-pppoe-device-in-pppoe_unbind_sock_work.patch b/target/linux/generic/pending-3.18/081-03-pppoe-drop-pppoe-device-in-pppoe_unbind_sock_work.patch deleted file mode 100644 index 07d64359ce..0000000000 --- a/target/linux/generic/pending-3.18/081-03-pppoe-drop-pppoe-device-in-pppoe_unbind_sock_work.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sat, 9 May 2015 23:08:38 +0200 -Subject: [PATCH] pppoe: drop pppoe device in pppoe_unbind_sock_work - -After receiving a PADT and the socket is closed, user space will no -longer drop the reference to the pppoe device. -This leads to errors like this: - -[ 488.570000] unregister_netdevice: waiting for eth0.2 to become free. Usage count = 2 - -Fixes: 287f3a943fe ("pppoe: Use workqueue to die properly when a PADT is received") -Signed-off-by: Felix Fietkau <nbd@nbd.name> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -464,6 +464,10 @@ static void pppoe_unbind_sock_work(struc - struct sock *sk = sk_pppox(po); - - lock_sock(sk); -+ if (po->pppoe_dev) { -+ dev_put(po->pppoe_dev); -+ po->pppoe_dev = NULL; -+ } - pppox_unbind_sock(sk); - release_sock(sk); - sock_put(sk); diff --git a/target/linux/generic/pending-3.18/081-06-ppp-don-t-set-sk_state-to-PPPOX_ZOMBIE-in-pppoe_disc.patch b/target/linux/generic/pending-3.18/081-06-ppp-don-t-set-sk_state-to-PPPOX_ZOMBIE-in-pppoe_disc.patch deleted file mode 100644 index 8d155eba1d..0000000000 --- a/target/linux/generic/pending-3.18/081-06-ppp-don-t-set-sk_state-to-PPPOX_ZOMBIE-in-pppoe_disc.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Guillaume Nault <g.nault@alphalink.fr> -Date: Thu, 19 Nov 2015 12:52:56 +0100 -Subject: [PATCH] ppp: don't set sk_state to PPPOX_ZOMBIE in pppoe_disc_rcv() - -Since 287f3a943fef ("pppoe: Use workqueue to die properly when a PADT -is received"), pppoe_disc_rcv() disconnects the socket by scheduling -pppoe_unbind_sock_work(). This is enough to stop socket transmission -and makes the PPPOX_ZOMBIE state uncessary. - -Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -500,27 +500,9 @@ static int pppoe_disc_rcv(struct sk_buff - - pn = pppoe_pernet(dev_net(dev)); - po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex); -- if (po) { -- struct sock *sk = sk_pppox(po); -- -- bh_lock_sock(sk); -- -- /* If the user has locked the socket, just ignore -- * the packet. With the way two rcv protocols hook into -- * one socket family type, we cannot (easily) distinguish -- * what kind of SKB it is during backlog rcv. -- */ -- if (sock_owned_by_user(sk) == 0) { -- /* We're no longer connect at the PPPOE layer, -- * and must wait for ppp channel to disconnect us. -- */ -- sk->sk_state = PPPOX_ZOMBIE; -- } -- -- bh_unlock_sock(sk); -+ if (po) - if (!schedule_work(&po->proto.pppoe.padt_work)) -- sock_put(sk); -- } -+ sock_put(sk_pppox(po)); - - abort: - kfree_skb(skb); diff --git a/target/linux/generic/pending-3.18/081-07-ppp-remove-PPPOX_ZOMBIE-socket-state.patch b/target/linux/generic/pending-3.18/081-07-ppp-remove-PPPOX_ZOMBIE-socket-state.patch deleted file mode 100644 index 28ec03b410..0000000000 --- a/target/linux/generic/pending-3.18/081-07-ppp-remove-PPPOX_ZOMBIE-socket-state.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Guillaume Nault <g.nault@alphalink.fr> -Date: Thu, 19 Nov 2015 12:53:21 +0100 -Subject: [PATCH] ppp: remove PPPOX_ZOMBIE socket state - -PPPOX_ZOMBIE is never set anymore. - -Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -311,7 +311,7 @@ static void pppoe_flush_dev(struct net_d - lock_sock(sk); - - if (po->pppoe_dev == dev && -- sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) { -+ sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { - pppox_unbind_sock(sk); - sk->sk_state_change(sk); - po->pppoe_dev = NULL; -@@ -779,7 +779,7 @@ static int pppoe_ioctl(struct socket *so - struct pppox_sock *relay_po; - - err = -EBUSY; -- if (sk->sk_state & (PPPOX_BOUND | PPPOX_ZOMBIE | PPPOX_DEAD)) -+ if (sk->sk_state & (PPPOX_BOUND | PPPOX_DEAD)) - break; - - err = -ENOTCONN; ---- a/drivers/net/ppp/pppox.c -+++ b/drivers/net/ppp/pppox.c -@@ -58,7 +58,7 @@ void pppox_unbind_sock(struct sock *sk) - { - /* Clear connection to ppp device, if attached. */ - -- if (sk->sk_state & (PPPOX_BOUND | PPPOX_CONNECTED | PPPOX_ZOMBIE)) { -+ if (sk->sk_state & (PPPOX_BOUND | PPPOX_CONNECTED)) { - ppp_unregister_channel(&pppox_sk(sk)->chan); - sk->sk_state = PPPOX_DEAD; - } ---- a/include/linux/if_pppox.h -+++ b/include/linux/if_pppox.h -@@ -91,7 +91,6 @@ enum { - PPPOX_CONNECTED = 1, /* connection established ==TCP_ESTABLISHED */ - PPPOX_BOUND = 2, /* bound to ppp device */ - PPPOX_RELAY = 4, /* forwarding is enabled */ -- PPPOX_ZOMBIE = 8, /* dead, but still bound to ppp device */ - PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ - }; - diff --git a/target/linux/generic/pending-3.18/081-08-pppoe-fix-memory-corruption-in-padt-work-structure.patch b/target/linux/generic/pending-3.18/081-08-pppoe-fix-memory-corruption-in-padt-work-structure.patch deleted file mode 100644 index 8637746b5b..0000000000 --- a/target/linux/generic/pending-3.18/081-08-pppoe-fix-memory-corruption-in-padt-work-structure.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Guillaume Nault <g.nault@alphalink.fr> -Date: Thu, 3 Dec 2015 16:49:32 +0100 -Subject: [PATCH] pppoe: fix memory corruption in padt work structure - -pppoe_connect() mustn't touch the padt_work field of pppoe sockets -because that work could be already pending. - -[ 21.473147] BUG: unable to handle kernel NULL pointer dereference at 00000004 -[ 21.474523] IP: [<c1043177>] process_one_work+0x29/0x31c -[ 21.475164] *pde = 00000000 -[ 21.475513] Oops: 0000 [#1] SMP -[ 21.475910] Modules linked in: pppoe pppox ppp_generic slhc crc32c_intel aesni_intel virtio_net xts aes_i586 lrw gf128mul ablk_helper cryptd evdev acpi_cpufreq processor serio_raw button ext4 crc16 mbcache jbd2 virtio_blk virtio_pci virtio_ring virtio -[ 21.476168] CPU: 2 PID: 164 Comm: kworker/2:2 Not tainted 4.4.0-rc1 #1 -[ 21.476168] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014 -[ 21.476168] task: f5f83c00 ti: f5e28000 task.ti: f5e28000 -[ 21.476168] EIP: 0060:[<c1043177>] EFLAGS: 00010046 CPU: 2 -[ 21.476168] EIP is at process_one_work+0x29/0x31c -[ 21.484082] EAX: 00000000 EBX: f678b2a0 ECX: 00000004 EDX: 00000000 -[ 21.484082] ESI: f6c69940 EDI: f5e29ef0 EBP: f5e29f0c ESP: f5e29edc -[ 21.484082] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 -[ 21.484082] CR0: 80050033 CR2: 000000a4 CR3: 317ad000 CR4: 00040690 -[ 21.484082] Stack: -[ 21.484082] 00000000 f6c69950 00000000 f6c69940 c0042338 f5e29f0c c1327945 00000000 -[ 21.484082] 00000008 f678b2a0 f6c69940 f678b2b8 f5e29f30 c1043984 f5f83c00 f6c69970 -[ 21.484082] f678b2a0 c10437d3 f6775e80 f678b2a0 c10437d3 f5e29fac c1047059 f5e29f74 -[ 21.484082] Call Trace: -[ 21.484082] [<c1327945>] ? _raw_spin_lock_irq+0x28/0x30 -[ 21.484082] [<c1043984>] worker_thread+0x1b1/0x244 -[ 21.484082] [<c10437d3>] ? rescuer_thread+0x229/0x229 -[ 21.484082] [<c10437d3>] ? rescuer_thread+0x229/0x229 -[ 21.484082] [<c1047059>] kthread+0x8f/0x94 -[ 21.484082] [<c1327a32>] ? _raw_spin_unlock_irq+0x22/0x26 -[ 21.484082] [<c1327ee9>] ret_from_kernel_thread+0x21/0x38 -[ 21.484082] [<c1046fca>] ? kthread_parkme+0x19/0x19 -[ 21.496082] Code: 5d c3 55 89 e5 57 56 53 89 c3 83 ec 24 89 d0 89 55 e0 8d 7d e4 e8 6c d8 ff ff b9 04 00 00 00 89 45 d8 8b 43 24 89 45 dc 8b 45 d8 <8b> 40 04 8b 80 e0 00 00 00 c1 e8 05 24 01 88 45 d7 8b 45 e0 8d -[ 21.496082] EIP: [<c1043177>] process_one_work+0x29/0x31c SS:ESP 0068:f5e29edc -[ 21.496082] CR2: 0000000000000004 -[ 21.496082] ---[ end trace e362cc9cf10dae89 ]--- - -Reported-by: Andrew <nitr0@seti.kr.ua> -Fixes: 287f3a943fef ("pppoe: Use workqueue to die properly when a PADT is received") -Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -550,6 +550,9 @@ static int pppoe_create(struct net *net, - sk->sk_family = PF_PPPOX; - sk->sk_protocol = PX_PROTO_OE; - -+ INIT_WORK(&pppox_sk(sk)->proto.pppoe.padt_work, -+ pppoe_unbind_sock_work); -+ - return 0; - } - -@@ -614,8 +617,6 @@ static int pppoe_connect(struct socket * - - lock_sock(sk); - -- INIT_WORK(&po->proto.pppoe.padt_work, pppoe_unbind_sock_work); -- - error = -EINVAL; - - if (sockaddr_len != sizeof(struct sockaddr_pppox)) -@@ -649,8 +650,13 @@ static int pppoe_connect(struct socket * - po->pppoe_dev = NULL; - } - -- memset(sk_pppox(po) + 1, 0, -- sizeof(struct pppox_sock) - sizeof(struct sock)); -+ po->pppoe_ifindex = 0; -+ memset(&po->pppoe_pa, 0, sizeof(po->pppoe_pa)); -+ memset(&po->pppoe_relay, 0, sizeof(po->pppoe_relay)); -+ memset(&po->chan, 0, sizeof(po->chan)); -+ po->next = NULL; -+ po->num = 0; -+ - sk->sk_state = PPPOX_NONE; - } - diff --git a/target/linux/generic/pending-3.18/082-ipv6-ip6_fragment-fix-headroom-tests-and-skb-leak.patch b/target/linux/generic/pending-3.18/082-ipv6-ip6_fragment-fix-headroom-tests-and-skb-leak.patch deleted file mode 100644 index 8990061303..0000000000 --- a/target/linux/generic/pending-3.18/082-ipv6-ip6_fragment-fix-headroom-tests-and-skb-leak.patch +++ /dev/null @@ -1,101 +0,0 @@ -From: Florian Westphal <fw@strlen.de> -Date: Thu, 17 Sep 2015 11:24:48 +0100 -Subject: [PATCH] ipv6: ip6_fragment: fix headroom tests and skb leak - -David Woodhouse reports skb_under_panic when we try to push ethernet -header to fragmented ipv6 skbs: - - skbuff: skb_under_panic: text:c1277f1e len:1294 put:14 head:dec98000 - data:dec97ffc tail:0xdec9850a end:0xdec98f40 dev:br-lan -[..] -ip6_finish_output2+0x196/0x4da - -David further debugged this: - [..] offending fragments were arriving here with skb_headroom(skb)==10. - Which is reasonable, being the Solos ADSL card's header of 8 bytes - followed by 2 bytes of PPP frame type. - -The problem is that if netfilter ipv6 defragmentation is used, skb_cow() -in ip6_forward will only see reassembled skb. - -Therefore, headroom is overestimated by 8 bytes (we pulled fragment -header) and we don't check the skbs in the frag_list either. - -We can't do these checks in netfilter defrag since outdev isn't known yet. - -Furthermore, existing tests in ip6_fragment did not consider the fragment -or ipv6 header size when checking headroom of the fraglist skbs. - -While at it, also fix a skb leak on memory allocation -- ip6_fragment -must consume the skb. - -I tested this e1000 driver hacked to not allocate additional headroom -(we end up in slowpath, since LL_RESERVED_SPACE is 16). - -If 2 bytes of headroom are allocated, fastpath is taken (14 byte -ethernet header was pulled, so 16 byte headroom available in all -fragments). - -Reported-by: David Woodhouse <dwmw2@infradead.org> -Diagnosed-by: David Woodhouse <dwmw2@infradead.org> -Signed-off-by: Florian Westphal <fw@strlen.de> -Closes 20532 ---- - ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -603,20 +603,22 @@ int ip6_fragment(struct sk_buff *skb, in - } - mtu -= hlen + sizeof(struct frag_hdr); - -+ hroom = LL_RESERVED_SPACE(rt->dst.dev); - if (skb_has_frag_list(skb)) { - int first_len = skb_pagelen(skb); - struct sk_buff *frag2; - - if (first_len - hlen > mtu || - ((first_len - hlen) & 7) || -- skb_cloned(skb)) -+ skb_cloned(skb) || -+ skb_headroom(skb) < (hroom + sizeof(struct frag_hdr))) - goto slow_path; - - skb_walk_frags(skb, frag) { - /* Correct geometry. */ - if (frag->len > mtu || - ((frag->len & 7) && frag->next) || -- skb_headroom(frag) < hlen) -+ skb_headroom(frag) < (hlen + hroom + sizeof(struct frag_hdr))) - goto slow_path_clean; - - /* Partially cloned skb? */ -@@ -633,8 +635,6 @@ int ip6_fragment(struct sk_buff *skb, in - - err = 0; - offset = 0; -- frag = skb_shinfo(skb)->frag_list; -- skb_frag_list_init(skb); - /* BUILD HEADER */ - - *prevhdr = NEXTHDR_FRAGMENT; -@@ -642,8 +642,11 @@ int ip6_fragment(struct sk_buff *skb, in - if (!tmp_hdr) { - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), - IPSTATS_MIB_FRAGFAILS); -- return -ENOMEM; -+ err = -ENOMEM; -+ goto fail; - } -+ frag = skb_shinfo(skb)->frag_list; -+ skb_frag_list_init(skb); - - __skb_pull(skb, hlen); - fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr)); -@@ -741,7 +744,6 @@ slow_path: - */ - - *prevhdr = NEXTHDR_FRAGMENT; -- hroom = LL_RESERVED_SPACE(rt->dst.dev); - troom = rt->dst.dev->needed_tailroom; - - /* diff --git a/target/linux/generic/pending-3.18/083-solos-pci-Increase-headroom-on-received-packets.patch b/target/linux/generic/pending-3.18/083-solos-pci-Increase-headroom-on-received-packets.patch deleted file mode 100644 index 7f9f9266c6..0000000000 --- a/target/linux/generic/pending-3.18/083-solos-pci-Increase-headroom-on-received-packets.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: David Woodhouse <dwmw2@infradead.org> -Date: Thu, 17 Sep 2015 11:19:53 +0100 -Subject: [PATCH] solos-pci: Increase headroom on received packets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A comment in include/linux/skbuff.h says that: - - * Various parts of the networking layer expect at least 32 bytes of - * headroom, you should not reduce this. - -This was demonstrated by a panic when handling fragmented IPv6 packets: -http://marc.info/?l=linux-netdev&m=144236093519172&w=2 - -It's not entirely clear if that comment is still valid — and if it is, -perhaps netif_rx() ought to be enforcing it with a warning. - -But either way, it is rather stupid from a performance point of view -for us to be receiving packets into a buffer which doesn't have enough -room to prepend an Ethernet header — it means that *every* incoming -packet is going to be need to be reallocated. So let's fix that. - -Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> ---- - ---- a/drivers/atm/solos-pci.c -+++ b/drivers/atm/solos-pci.c -@@ -805,7 +805,12 @@ static void solos_bh(unsigned long card_ - continue; - } - -- skb = alloc_skb(size + 1, GFP_ATOMIC); -+ /* Use netdev_alloc_skb() because it adds NET_SKB_PAD of -+ * headroom, and ensures we can route packets back out an -+ * Ethernet interface (for example) without having to -+ * reallocate. Adding NET_IP_ALIGN also ensures that both -+ * PPPoATM and PPPoEoBR2684 packets end up aligned. */ -+ skb = netdev_alloc_skb_ip_align(NULL, size + 1); - if (!skb) { - if (net_ratelimit()) - dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n"); -@@ -869,7 +874,10 @@ static void solos_bh(unsigned long card_ - /* Allocate RX skbs for any ports which need them */ - if (card->using_dma && card->atmdev[port] && - !card->rx_skb[port]) { -- struct sk_buff *skb = alloc_skb(RX_DMA_SIZE, GFP_ATOMIC); -+ /* Unlike the MMIO case (qv) we can't add NET_IP_ALIGN -+ * here; the FPGA can only DMA to addresses which are -+ * aligned to 4 bytes. */ -+ struct sk_buff *skb = dev_alloc_skb(RX_DMA_SIZE); - if (skb) { - SKB_CB(skb)->dma_addr = - pci_map_single(card->dev, skb->data, diff --git a/target/linux/generic/pending-3.18/087-regmap-make-LZO-cache-optional.patch b/target/linux/generic/pending-3.18/087-regmap-make-LZO-cache-optional.patch deleted file mode 100644 index 94b61fdab4..0000000000 --- a/target/linux/generic/pending-3.18/087-regmap-make-LZO-cache-optional.patch +++ /dev/null @@ -1,67 +0,0 @@ -From de88e9b0354c2e3ff8eae3f97afe43a34f5ed239 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski <jonas.gorski@gmail.com> -Date: Sat, 13 May 2017 13:03:21 +0200 -Subject: [PATCH] regmap: make LZO cache optional - -Commit 2cbbb579bcbe3 ("regmap: Add the LZO cache support") added support -for LZO compression in regcache, but there were never any users added -afterwards. Since LZO support itself has its own size, it currently is -rather a deoptimization. - -So make it optional by introducing a symbol that can be selected by -drivers wanting to make use of it. - -Saves e.g. ~46 kB on MIPS (size of LZO support + regcache LZO code). - -Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> ---- -I tried using google to find any users (even out-of-tree ones), but at -best I found a single driver submission that was switched to RBTREE in -subsequent resubmissions (MFD_SMSC). - -One could maybe also just drop the code because of no users for 5 years, -but that would be up to the maintainer(s) to decide. - - drivers/base/regmap/Kconfig | 5 ++++- - drivers/base/regmap/Makefile | 3 ++- - drivers/base/regmap/regcache.c | 2 ++ - 3 files changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/base/regmap/Kconfig -+++ b/drivers/base/regmap/Kconfig -@@ -4,9 +4,12 @@ - - config REGMAP - default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_MMIO || REGMAP_IRQ) -+ select IRQ_DOMAIN if REGMAP_IRQ -+ bool -+ -+config REGCACHE_COMPRESSED - select LZO_COMPRESS - select LZO_DECOMPRESS -- select IRQ_DOMAIN if REGMAP_IRQ - bool - - config REGMAP_I2C ---- a/drivers/base/regmap/Makefile -+++ b/drivers/base/regmap/Makefile -@@ -1,5 +1,6 @@ - obj-$(CONFIG_REGMAP) += regmap.o regcache.o --obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.o -+obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o -+obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o - obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o - obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o - obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o ---- a/drivers/base/regmap/regcache.c -+++ b/drivers/base/regmap/regcache.c -@@ -21,7 +21,9 @@ - - static const struct regcache_ops *cache_types[] = { - ®cache_rbtree_ops, -+#if IS_ENABLED(CONFIG_REGCACHE_COMPRESSED) - ®cache_lzo_ops, -+#endif - ®cache_flat_ops, - }; - diff --git a/target/linux/generic/pending-3.18/090-overlayfs-fallback-to-readonly-when-full.patch b/target/linux/generic/pending-3.18/090-overlayfs-fallback-to-readonly-when-full.patch deleted file mode 100644 index 6c26a47c5f..0000000000 --- a/target/linux/generic/pending-3.18/090-overlayfs-fallback-to-readonly-when-full.patch +++ /dev/null @@ -1,109 +0,0 @@ -[linux-unionfs added to Cc] - -On Tue, May 19, 2015 at 09:51:20AM +0200, Bastian Bittorf wrote: -> Hi Miklos, -> -> sorry for writing directly to you, feel free to forward -> this to the appropriate mailinglist. -> -> we have a problem with mainline overlay filesystem on kernel 3.18: -> https://dev.openwrt.org/ticket/19564 -> -> 2 things are odd: -> when the working filesystem is full, overlays fails with: -> -> overlayfs: failed to create directory /overlay/work/work -> -> what is strange, that we call it with: -> -> mount(overlay, "/mnt", "overlay", MS_NOATIME, lowerdir) -> -> see here: -> http://nbd.name/gitweb.cgi?p=fstools.git;a=blob;f=libfstools/mount.c;h=81176ce399b4cd8e2d347c0008c13dec92407f55;hb=e6004000ff15d7bd32cf5663e8690fc94d7ec747#l125 -> -> do you have an idea whats wrong? -> 1) is it really needed, that we need space for creating dir "/overlay/work"? -> 2) why does overlay need "/overlay/work/work"? - -The work directory is needed for atomic copy-up and similar. It is not actually -necessary to mount a read-only overlay. Post 4.0 it is possible to mount the -overlay without workdir (but even then it won't happen automatically in case the -upper fs is full, so this should be fixed in the latest kernel too). - -Could you please try the following patch? If the workdir can't be created it -will fall back to mounting the overlay read-only. - -Thanks, -Miklos - ---- - fs/overlayfs/copy_up.c | 3 +++ - fs/overlayfs/dir.c | 9 +++++++++ - fs/overlayfs/super.c | 12 +++++++++--- - 3 files changed, 21 insertions(+), 3 deletions(-) - ---- a/fs/overlayfs/copy_up.c -+++ b/fs/overlayfs/copy_up.c -@@ -315,6 +315,9 @@ int ovl_copy_up_one(struct dentry *paren - struct cred *override_cred; - char *link = NULL; - -+ if (WARN_ON(!workdir)) -+ return -EROFS; -+ - ovl_path_upper(parent, &parentpath); - upperdir = parentpath.dentry; - ---- a/fs/overlayfs/dir.c -+++ b/fs/overlayfs/dir.c -@@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(st - struct kstat stat; - int err; - -+ if (WARN_ON(!workdir)) -+ return ERR_PTR(-EROFS); -+ - err = ovl_lock_rename_workdir(workdir, upperdir); - if (err) - goto out; -@@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(stru - struct dentry *newdentry; - int err; - -+ if (WARN_ON(!workdir)) -+ return -EROFS; -+ - err = ovl_lock_rename_workdir(workdir, upperdir); - if (err) - goto out; -@@ -507,6 +513,9 @@ static int ovl_remove_and_whiteout(struc - int err; - int flags = 0; - -+ if (WARN_ON(!workdir)) -+ return -EROFS; -+ - if (is_dir) { - opaquedir = ovl_check_empty_and_clear(dentry); - err = PTR_ERR(opaquedir); ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -760,9 +760,15 @@ static int ovl_fill_super(struct super_b - ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); - err = PTR_ERR(ufs->workdir); - if (IS_ERR(ufs->workdir)) { -- pr_err("overlayfs: failed to create directory %s/%s\n", -- ufs->config.workdir, OVL_WORKDIR_NAME); -- goto out_put_lower_mnt; -+ if (err == -ENOSPC || err == -EROFS) { -+ pr_warning("overlayfs: failed to create work directory (%s), mounting read-only\n", err == ENOSPC ? "ENOSPC" : "EROFS"); -+ sb->s_flags |= MS_RDONLY; -+ ufs->workdir = NULL; -+ } else { -+ pr_err("overlayfs: failed to create directory %s/%s\n", -+ ufs->config.workdir, OVL_WORKDIR_NAME); -+ goto out_put_lower_mnt; -+ } - } - - /* diff --git a/target/linux/generic/pending-3.18/091-mtd-spi-nor-add-support-Spansion_S25FL164K.patch b/target/linux/generic/pending-3.18/091-mtd-spi-nor-add-support-Spansion_S25FL164K.patch deleted file mode 100644 index 24aa0752d8..0000000000 --- a/target/linux/generic/pending-3.18/091-mtd-spi-nor-add-support-Spansion_S25FL164K.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -567,6 +567,7 @@ static const struct spi_device_id spi_no - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) }, - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, - - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, diff --git a/target/linux/generic/pending-3.18/092-01-spi-Check-to-see-if-the-device-is-processing-a-messa.patch b/target/linux/generic/pending-3.18/092-01-spi-Check-to-see-if-the-device-is-processing-a-messa.patch deleted file mode 100644 index fa3ab6a638..0000000000 --- a/target/linux/generic/pending-3.18/092-01-spi-Check-to-see-if-the-device-is-processing-a-messa.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Mark Brown <broonie@kernel.org> -Date: Tue, 9 Dec 2014 19:46:56 +0000 -Subject: [PATCH] spi: Check to see if the device is processing a message - before we idle - -cur_msg is updated under the queue lock and holds the message we are -currently processing. Since currently we only ever do removals in the -pump kthread it doesn't matter in what order we do things but we want -to be able to push things out from the submitting thread so pull the -check to see if we're currently handling a message before we check to -see if the queue is idle. - -Signed-off-by: Mark Brown <broonie@kernel.org> ---- - ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -891,8 +891,16 @@ static void spi_pump_messages(struct kth - bool was_busy = false; - int ret; - -- /* Lock queue and check for queue work */ -+ /* Lock queue */ - spin_lock_irqsave(&master->queue_lock, flags); -+ -+ /* Make sure we are not already running a message */ -+ if (master->cur_msg) { -+ spin_unlock_irqrestore(&master->queue_lock, flags); -+ return; -+ } -+ -+ /* Check if the queue is idle */ - if (list_empty(&master->queue) || !master->running) { - if (!master->busy) { - spin_unlock_irqrestore(&master->queue_lock, flags); -@@ -916,11 +924,6 @@ static void spi_pump_messages(struct kth - return; - } - -- /* Make sure we are not already running a message */ -- if (master->cur_msg) { -- spin_unlock_irqrestore(&master->queue_lock, flags); -- return; -- } - /* Extract head of queue */ - master->cur_msg = - list_first_entry(&master->queue, struct spi_message, queue); diff --git a/target/linux/generic/pending-3.18/092-02-spi-Pump-transfers-inside-calling-context-for-spi_sy.patch b/target/linux/generic/pending-3.18/092-02-spi-Pump-transfers-inside-calling-context-for-spi_sy.patch deleted file mode 100644 index b74b4cb93b..0000000000 --- a/target/linux/generic/pending-3.18/092-02-spi-Pump-transfers-inside-calling-context-for-spi_sy.patch +++ /dev/null @@ -1,184 +0,0 @@ -From: Mark Brown <broonie@kernel.org> -Date: Tue, 9 Dec 2014 21:38:05 +0000 -Subject: [PATCH] spi: Pump transfers inside calling context for spi_sync() - -If we are using the standard SPI message pump (which all drivers should be -transitioning over to) then special case the message enqueue and instead of -starting the worker thread to push messages to the hardware do so in the -context of the caller if the controller is idle. This avoids a context -switch in the common case where the controller has a single user in a -single thread, for short PIO transfers there may be no need to context -switch away from the calling context to complete the transfer. - -The code is a bit more complex than is desirable in part due to the need -to handle drivers not using the standard queue and in part due to handling -the various combinations of bus locking and asynchronous submission in -interrupt context. - -It is still suboptimal since it will still wake the message pump for each -transfer in order to schedule idling of the hardware and if multiple -contexts are using the controller simultaneously a caller may end up -pumping a message for some random other thread rather than for itself, -and if the thread ends up deferring due to another context idling the -hardware then it will just busy wait. It can, however, have the benefit -of aggregating power up and down of the hardware when a caller performs -a series of transfers back to back without any need for the use of -spi_async(). - -Signed-off-by: Mark Brown <broonie@kernel.org> ---- - ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -882,6 +882,9 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_t - * needs processing and if so call out to the driver to initialize hardware - * and transfer each message. - * -+ * Note that it is called both from the kthread itself and also from -+ * inside spi_sync(); the queue extraction handling at the top of the -+ * function should deal with this safely. - */ - static void spi_pump_messages(struct kthread_work *work) - { -@@ -900,6 +903,13 @@ static void spi_pump_messages(struct kth - return; - } - -+ /* If another context is idling the device then defer */ -+ if (master->idling) { -+ queue_kthread_work(&master->kworker, &master->pump_messages); -+ spin_unlock_irqrestore(&master->queue_lock, flags); -+ return; -+ } -+ - /* Check if the queue is idle */ - if (list_empty(&master->queue) || !master->running) { - if (!master->busy) { -@@ -907,7 +917,9 @@ static void spi_pump_messages(struct kth - return; - } - master->busy = false; -+ master->idling = true; - spin_unlock_irqrestore(&master->queue_lock, flags); -+ - kfree(master->dummy_rx); - master->dummy_rx = NULL; - kfree(master->dummy_tx); -@@ -921,6 +933,10 @@ static void spi_pump_messages(struct kth - pm_runtime_put_autosuspend(master->dev.parent); - } - trace_spi_master_idle(master); -+ -+ spin_lock_irqsave(&master->queue_lock, flags); -+ master->idling = false; -+ spin_unlock_irqrestore(&master->queue_lock, flags); - return; - } - -@@ -1166,12 +1182,9 @@ static int spi_destroy_queue(struct spi_ - return 0; - } - --/** -- * spi_queued_transfer - transfer function for queued transfers -- * @spi: spi device which is requesting transfer -- * @msg: spi message which is to handled is queued to driver queue -- */ --static int spi_queued_transfer(struct spi_device *spi, struct spi_message *msg) -+static int __spi_queued_transfer(struct spi_device *spi, -+ struct spi_message *msg, -+ bool need_pump) - { - struct spi_master *master = spi->master; - unsigned long flags; -@@ -1186,13 +1199,23 @@ static int spi_queued_transfer(struct sp - msg->status = -EINPROGRESS; - - list_add_tail(&msg->queue, &master->queue); -- if (!master->busy) -+ if (!master->busy && need_pump) - queue_kthread_work(&master->kworker, &master->pump_messages); - - spin_unlock_irqrestore(&master->queue_lock, flags); - return 0; - } - -+/** -+ * spi_queued_transfer - transfer function for queued transfers -+ * @spi: spi device which is requesting transfer -+ * @msg: spi message which is to handled is queued to driver queue -+ */ -+static int spi_queued_transfer(struct spi_device *spi, struct spi_message *msg) -+{ -+ return __spi_queued_transfer(spi, msg, true); -+} -+ - static int spi_master_initialize_queue(struct spi_master *master) - { - int ret; -@@ -2104,19 +2127,46 @@ static int __spi_sync(struct spi_device - DECLARE_COMPLETION_ONSTACK(done); - int status; - struct spi_master *master = spi->master; -+ unsigned long flags; -+ -+ status = __spi_validate(spi, message); -+ if (status != 0) -+ return status; - - message->complete = spi_complete; - message->context = &done; -+ message->spi = spi; - - if (!bus_locked) - mutex_lock(&master->bus_lock_mutex); - -- status = spi_async_locked(spi, message); -+ /* If we're not using the legacy transfer method then we will -+ * try to transfer in the calling context so special case. -+ * This code would be less tricky if we could remove the -+ * support for driver implemented message queues. -+ */ -+ if (master->transfer == spi_queued_transfer) { -+ spin_lock_irqsave(&master->bus_lock_spinlock, flags); -+ -+ trace_spi_message_submit(message); -+ -+ status = __spi_queued_transfer(spi, message, false); -+ -+ spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); -+ } else { -+ status = spi_async_locked(spi, message); -+ } - - if (!bus_locked) - mutex_unlock(&master->bus_lock_mutex); - - if (status == 0) { -+ /* Push out the messages in the calling context if we -+ * can. -+ */ -+ if (master->transfer == spi_queued_transfer) -+ spi_pump_messages(&master->pump_messages); -+ - wait_for_completion(&done); - status = message->status; - } ---- a/include/linux/spi/spi.h -+++ b/include/linux/spi/spi.h -@@ -260,6 +260,7 @@ static inline void spi_unregister_driver - * @pump_messages: work struct for scheduling work to the message pump - * @queue_lock: spinlock to syncronise access to message queue - * @queue: message queue -+ * @idling: the device is entering idle state - * @cur_msg: the currently in-flight message - * @cur_msg_prepared: spi_prepare_message was called for the currently - * in-flight message -@@ -425,6 +426,7 @@ struct spi_master { - spinlock_t queue_lock; - struct list_head queue; - struct spi_message *cur_msg; -+ bool idling; - bool busy; - bool running; - bool rt; diff --git a/target/linux/generic/pending-3.18/092-03-spi-Only-idle-the-message-pump-in-the-worker-kthread.patch b/target/linux/generic/pending-3.18/092-03-spi-Only-idle-the-message-pump-in-the-worker-kthread.patch deleted file mode 100644 index a5d85be2b4..0000000000 --- a/target/linux/generic/pending-3.18/092-03-spi-Only-idle-the-message-pump-in-the-worker-kthread.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Mark Brown <broonie@kernel.org> -Date: Wed, 10 Dec 2014 13:46:33 +0000 -Subject: [PATCH] spi: Only idle the message pump in the worker kthread - -In order to avoid the situation where the kthread is waiting for another -context to make the hardware idle let the message pump know if it's being -called from the worker thread context and if it isn't then defer to the -worker thread instead of idling the hardware immediately. This will ensure -that if this situation happens we block rather than busy waiting. - -Signed-off-by: Mark Brown <broonie@kernel.org> ---- - ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -875,8 +875,9 @@ void spi_finalize_current_transfer(struc - EXPORT_SYMBOL_GPL(spi_finalize_current_transfer); - - /** -- * spi_pump_messages - kthread work function which processes spi message queue -- * @work: pointer to kthread work struct contained in the master struct -+ * __spi_pump_messages - function which processes spi message queue -+ * @master: master to process queue for -+ * @in_kthread: true if we are in the context of the message pump thread - * - * This function checks if there is any spi message in the queue that - * needs processing and if so call out to the driver to initialize hardware -@@ -886,10 +887,8 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_t - * inside spi_sync(); the queue extraction handling at the top of the - * function should deal with this safely. - */ --static void spi_pump_messages(struct kthread_work *work) -+static void __spi_pump_messages(struct spi_master *master, bool in_kthread) - { -- struct spi_master *master = -- container_of(work, struct spi_master, pump_messages); - unsigned long flags; - bool was_busy = false; - int ret; -@@ -916,6 +915,15 @@ static void spi_pump_messages(struct kth - spin_unlock_irqrestore(&master->queue_lock, flags); - return; - } -+ -+ /* Only do teardown in the thread */ -+ if (!in_kthread) { -+ queue_kthread_work(&master->kworker, -+ &master->pump_messages); -+ spin_unlock_irqrestore(&master->queue_lock, flags); -+ return; -+ } -+ - master->busy = false; - master->idling = true; - spin_unlock_irqrestore(&master->queue_lock, flags); -@@ -1004,6 +1012,18 @@ static void spi_pump_messages(struct kth - } - } - -+/** -+ * spi_pump_messages - kthread work function which processes spi message queue -+ * @work: pointer to kthread work struct contained in the master struct -+ */ -+static void spi_pump_messages(struct kthread_work *work) -+{ -+ struct spi_master *master = -+ container_of(work, struct spi_master, pump_messages); -+ -+ __spi_pump_messages(master, true); -+} -+ - static int spi_init_queue(struct spi_master *master) - { - struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; -@@ -2165,7 +2185,7 @@ static int __spi_sync(struct spi_device - * can. - */ - if (master->transfer == spi_queued_transfer) -- spi_pump_messages(&master->pump_messages); -+ __spi_pump_messages(master, false); - - wait_for_completion(&done); - status = message->status; diff --git a/target/linux/generic/pending-3.18/095-api-fix-compatibility-of-linux-in.h-with-netinet-in..patch b/target/linux/generic/pending-3.18/095-api-fix-compatibility-of-linux-in.h-with-netinet-in..patch deleted file mode 100644 index 4c5cd596f7..0000000000 --- a/target/linux/generic/pending-3.18/095-api-fix-compatibility-of-linux-in.h-with-netinet-in..patch +++ /dev/null @@ -1,146 +0,0 @@ -From 279c6c7fa64f5763e6b9f05e7ab3840092e702e7 Mon Sep 17 00:00:00 2001 -From: Stephen Hemminger <stephen@networkplumber.org> -Date: Mon, 29 Jun 2015 14:57:48 -1000 -Subject: [PATCH] api: fix compatibility of linux/in.h with netinet/in.h - -u -This fixes breakage to iproute2 build with recent kernel headers -caused by: - commit a263653ed798216c0069922d7b5237ca49436007 - Author: Pablo Neira Ayuso <pablo@netfilter.org> - Date: Wed Jun 17 10:28:27 2015 -0500 - - netfilter: don't pull include/linux/netfilter.h from netns headers - -The issue is that definitions in linux/in.h overlap with those -in netinet/in.h. This patch solves this by introducing the same -mechanism as was used to solve the same problem with linux/in6.h - -Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - include/uapi/linux/in.h | 16 +++++++++++++--- - include/uapi/linux/libc-compat.h | 22 ++++++++++++++++++++++ - 2 files changed, 35 insertions(+), 3 deletions(-) - ---- a/include/uapi/linux/in.h -+++ b/include/uapi/linux/in.h -@@ -19,8 +19,10 @@ - #define _UAPI_LINUX_IN_H - - #include <linux/types.h> -+#include <linux/libc-compat.h> - #include <linux/socket.h> - -+#if __UAPI_DEF_IN_IPPROTO - /* Standard well-defined IP protocols. */ - enum { - IPPROTO_IP = 0, /* Dummy protocol for TCP */ -@@ -73,12 +75,14 @@ enum { - #define IPPROTO_RAW IPPROTO_RAW - IPPROTO_MAX - }; -+#endif - -- -+#if __UAPI_DEF_IN_ADDR - /* Internet address. */ - struct in_addr { - __be32 s_addr; - }; -+#endif - - #define IP_TOS 1 - #define IP_TTL 2 -@@ -154,6 +158,7 @@ struct in_addr { - - /* Request struct for multicast socket ops */ - -+#if __UAPI_DEF_IP_MREQ - struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -@@ -205,14 +210,18 @@ struct group_filter { - #define GROUP_FILTER_SIZE(numsrc) \ - (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \ - + (numsrc) * sizeof(struct __kernel_sockaddr_storage)) -+#endif - -+#if __UAPI_DEF_IN_PKTINFO - struct in_pktinfo { - int ipi_ifindex; - struct in_addr ipi_spec_dst; - struct in_addr ipi_addr; - }; -+#endif - - /* Structure describing an Internet (IP) socket address. */ -+#if __UAPI_DEF_SOCKADDR_IN - #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ - struct sockaddr_in { - __kernel_sa_family_t sin_family; /* Address family */ -@@ -224,8 +233,9 @@ struct sockaddr_in { - sizeof(unsigned short int) - sizeof(struct in_addr)]; - }; - #define sin_zero __pad /* for BSD UNIX comp. -FvK */ -+#endif - -- -+#if __UAPI_DEF_IN_CLASS - /* - * Definitions of the bits in an Internet address integer. - * On subnets, host and network parts are found according -@@ -276,7 +286,7 @@ struct sockaddr_in { - #define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */ - #define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */ - #define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */ -- -+#endif - - /* <asm/byteorder.h> contains the htonl type stuff.. */ - #include <asm/byteorder.h> ---- a/include/uapi/linux/libc-compat.h -+++ b/include/uapi/linux/libc-compat.h -@@ -56,6 +56,13 @@ - - /* GLIBC headers included first so don't define anything - * that would already be defined. */ -+#define __UAPI_DEF_IN_ADDR 0 -+#define __UAPI_DEF_IN_IPPROTO 0 -+#define __UAPI_DEF_IN_PKTINFO 0 -+#define __UAPI_DEF_IP_MREQ 0 -+#define __UAPI_DEF_SOCKADDR_IN 0 -+#define __UAPI_DEF_IN_CLASS 0 -+ - #define __UAPI_DEF_IN6_ADDR 0 - /* The exception is the in6_addr macros which must be defined - * if the glibc code didn't define them. This guard matches -@@ -76,6 +83,13 @@ - /* Linux headers included first, and we must define everything - * we need. The expectation is that glibc will check the - * __UAPI_DEF_* defines and adjust appropriately. */ -+#define __UAPI_DEF_IN_ADDR 1 -+#define __UAPI_DEF_IN_IPPROTO 1 -+#define __UAPI_DEF_IN_PKTINFO 1 -+#define __UAPI_DEF_IP_MREQ 1 -+#define __UAPI_DEF_SOCKADDR_IN 1 -+#define __UAPI_DEF_IN_CLASS 1 -+ - #define __UAPI_DEF_IN6_ADDR 1 - /* We unconditionally define the in6_addr macros and glibc must - * coordinate. */ -@@ -99,6 +113,14 @@ - * that we need. */ - #else /* !defined(__GLIBC__) */ - -+/* Definitions for in.h */ -+#define __UAPI_DEF_IN_ADDR 1 -+#define __UAPI_DEF_IN_IPPROTO 1 -+#define __UAPI_DEF_IN_PKTINFO 1 -+#define __UAPI_DEF_IP_MREQ 1 -+#define __UAPI_DEF_SOCKADDR_IN 1 -+#define __UAPI_DEF_IN_CLASS 1 -+ - /* Definitions for in6.h */ - #define __UAPI_DEF_IN6_ADDR 1 - #define __UAPI_DEF_IN6_ADDR_ALT 1 diff --git a/target/linux/generic/pending-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch b/target/linux/generic/pending-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch deleted file mode 100644 index 352bf6de15..0000000000 --- a/target/linux/generic/pending-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch +++ /dev/null @@ -1,182 +0,0 @@ -From: Rusty Russell <rusty@rustcorp.com.au> -Date: Tue, 20 Jan 2015 09:07:04 +1030 -Subject: [PATCH] module_arch_freeing_init(): new hook for archs before module->module_init freed. - -Archs have been abusing module_free() to clean up their arch-specific -allocations. Since module_free() is also (ab)used by BPF and trace code, -let's keep it to simple allocations, and provide a hook called before -that. - -This means that avr32, ia64, parisc and s390 no longer need to implement -their own module_free() at all. avr32 doesn't need module_finalize() -either. - -Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> -Cc: Chris Metcalf <cmetcalf@ezchip.com> -Cc: Haavard Skinnemoen <hskinnemoen@gmail.com> -Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: "James E.J. Bottomley" <jejb@parisc-linux.org> -Cc: Helge Deller <deller@gmx.de> -Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> -Cc: Heiko Carstens <heiko.carstens@de.ibm.com> -Cc: linux-kernel@vger.kernel.org -Cc: linux-ia64@vger.kernel.org -Cc: linux-parisc@vger.kernel.org -Cc: linux-s390@vger.kernel.org - -Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d453cded05ee219b77815ea194dc36efa5398bca ---- - arch/avr32/kernel/module.c | 13 +------------ - arch/ia64/kernel/module.c | 6 ++---- - arch/parisc/kernel/module.c | 6 +----- - arch/s390/kernel/module.c | 10 +++------- - arch/tile/kernel/module.c | 2 +- - include/linux/moduleloader.h | 2 ++ - kernel/module.c | 7 +++++++ - 7 files changed, 17 insertions(+), 29 deletions(-) - ---- a/arch/avr32/kernel/module.c -+++ b/arch/avr32/kernel/module.c -@@ -19,12 +19,10 @@ - #include <linux/moduleloader.h> - #include <linux/vmalloc.h> - --void module_free(struct module *mod, void *module_region) -+void module_arch_freeing_init(struct module *mod) - { - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; -- -- vfree(module_region); - } - - static inline int check_rela(Elf32_Rela *rela, struct module *module, -@@ -291,12 +289,3 @@ int apply_relocate_add(Elf32_Shdr *sechd - - return ret; - } -- --int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -- struct module *module) --{ -- vfree(module->arch.syminfo); -- module->arch.syminfo = NULL; -- -- return 0; --} ---- a/arch/ia64/kernel/module.c -+++ b/arch/ia64/kernel/module.c -@@ -305,14 +305,12 @@ plt_target (struct plt_entry *plt) - #endif /* !USE_BRL */ - - void --module_free (struct module *mod, void *module_region) -+module_arch_freeing_init (struct module *mod) - { -- if (mod && mod->arch.init_unw_table && -- module_region == mod->module_init) { -+ if (mod->arch.init_unw_table) { - unw_remove_unwind_table(mod->arch.init_unw_table); - mod->arch.init_unw_table = NULL; - } -- vfree(module_region); - } - - /* Have we already seen one of these relocations? */ ---- a/arch/parisc/kernel/module.c -+++ b/arch/parisc/kernel/module.c -@@ -298,14 +298,10 @@ static inline unsigned long count_stubs( - } - #endif - -- --/* Free memory returned from module_alloc */ --void module_free(struct module *mod, void *module_region) -+void module_arch_freeing_init(struct module *mod) - { - kfree(mod->arch.section); - mod->arch.section = NULL; -- -- vfree(module_region); - } - - /* Additional bytes needed in front of individual sections */ ---- a/arch/s390/kernel/module.c -+++ b/arch/s390/kernel/module.c -@@ -55,14 +55,10 @@ void *module_alloc(unsigned long size) - } - #endif - --/* Free memory returned from module_alloc */ --void module_free(struct module *mod, void *module_region) -+void module_arch_freeing_init(struct module *mod) - { -- if (mod) { -- vfree(mod->arch.syminfo); -- mod->arch.syminfo = NULL; -- } -- vfree(module_region); -+ vfree(mod->arch.syminfo); -+ mod->arch.syminfo = NULL; - } - - static void check_rela(Elf_Rela *rela, struct module *me) ---- a/arch/tile/kernel/module.c -+++ b/arch/tile/kernel/module.c -@@ -83,7 +83,7 @@ void module_free(struct module *mod, voi - 0, 0, 0, NULL, NULL, 0); - - /* -- * FIXME: If module_region == mod->module_init, trim exception -+ * FIXME: Add module_arch_freeing_init to trim exception - * table entries. - */ - } ---- a/include/linux/moduleloader.h -+++ b/include/linux/moduleloader.h -@@ -82,4 +82,6 @@ int module_finalize(const Elf_Ehdr *hdr, - /* Any cleanup needed when module leaves. */ - void module_arch_cleanup(struct module *mod); - -+/* Any cleanup before freeing mod->module_init */ -+void module_arch_freeing_init(struct module *mod); - #endif ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -1840,6 +1840,10 @@ void __weak module_arch_cleanup(struct m - { - } - -+void __weak module_arch_freeing_init(struct module *mod) -+{ -+} -+ - /* Free a module, remove from lists, etc. */ - static void free_module(struct module *mod) - { -@@ -1872,6 +1876,7 @@ static void free_module(struct module *m - - /* This may be NULL, but that's OK */ - unset_module_init_ro_nx(mod); -+ module_arch_freeing_init(mod); - module_free(mod, mod->module_init); - kfree(mod->args); - percpu_modfree(mod); -@@ -2983,6 +2988,7 @@ static struct module *layout_and_allocat - static void module_deallocate(struct module *mod, struct load_info *info) - { - percpu_modfree(mod); -+ module_arch_freeing_init(mod); - module_free(mod, mod->module_init); - module_free(mod, mod->module_core); - } -@@ -3105,6 +3111,7 @@ static int do_init_module(struct module - rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); - #endif - unset_module_init_ro_nx(mod); -+ module_arch_freeing_init(mod); - module_free(mod, mod->module_init); - mod->module_init = NULL; - mod->init_size = 0; diff --git a/target/linux/generic/pending-3.18/102-ehci_hcd_ignore_oc.patch b/target/linux/generic/pending-3.18/102-ehci_hcd_ignore_oc.patch deleted file mode 100644 index a5645596f9..0000000000 --- a/target/linux/generic/pending-3.18/102-ehci_hcd_ignore_oc.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 1e311820ec3055e3f08e687de6564692a7cec675 Mon Sep 17 00:00:00 2001 -From: Florian Fainelli <florian@openwrt.org> -Date: Mon, 28 Jan 2013 20:06:29 +0100 -Subject: [PATCH 11/12] USB: EHCI: add ignore_oc flag to disable overcurrent - checking - -This patch adds an ignore_oc flag which can be set by EHCI controller -not supporting or wanting to disable overcurrent checking. The EHCI -platform data in include/linux/usb/ehci_pdriver.h is also augmented to -take advantage of this new flag. - -Signed-off-by: Florian Fainelli <florian@openwrt.org> ---- - drivers/usb/host/ehci-hcd.c | 2 +- - drivers/usb/host/ehci-hub.c | 4 ++-- - drivers/usb/host/ehci-platform.c | 1 + - drivers/usb/host/ehci.h | 1 + - include/linux/usb/ehci_pdriver.h | 1 + - 5 files changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/usb/host/ehci-hcd.c -+++ b/drivers/usb/host/ehci-hcd.c -@@ -633,7 +633,7 @@ static int ehci_run (struct usb_hcd *hcd - "USB %x.%x started, EHCI %x.%02x%s\n", - ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), - temp >> 8, temp & 0xff, -- ignore_oc ? ", overcurrent ignored" : ""); -+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); - - ehci_writel(ehci, INTR_MASK, - &ehci->regs->intr_enable); /* Turn On Interrupts */ ---- a/drivers/usb/host/ehci-hub.c -+++ b/drivers/usb/host/ehci-hub.c -@@ -635,7 +635,7 @@ ehci_hub_status_data (struct usb_hcd *hc - * always set, seem to clear PORT_OCC and PORT_CSC when writing to - * PORT_POWER; that's surprising, but maybe within-spec. - */ -- if (!ignore_oc) -+ if (!ignore_oc && !ehci->ignore_oc) - mask = PORT_CSC | PORT_PEC | PORT_OCC; - else - mask = PORT_CSC | PORT_PEC; -@@ -995,7 +995,7 @@ int ehci_hub_control( - if (temp & PORT_PEC) - status |= USB_PORT_STAT_C_ENABLE << 16; - -- if ((temp & PORT_OCC) && !ignore_oc){ -+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ - status |= USB_PORT_STAT_C_OVERCURRENT << 16; - - /* ---- a/drivers/usb/host/ehci-platform.c -+++ b/drivers/usb/host/ehci-platform.c -@@ -226,6 +226,8 @@ static int ehci_platform_probe(struct pl - ehci->big_endian_desc = 1; - if (pdata->big_endian_mmio) - ehci->big_endian_mmio = 1; -+ if (pdata->ignore_oc) -+ ehci->ignore_oc = 1; - - #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO - if (ehci->big_endian_mmio) { ---- a/drivers/usb/host/ehci.h -+++ b/drivers/usb/host/ehci.h -@@ -226,6 +226,7 @@ struct ehci_hcd { /* one per controlle - unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ - unsigned need_oc_pp_cycle:1; /* MPC834X port power */ - unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ -+ unsigned ignore_oc:1; - - /* required for usb32 quirk */ - #define OHCI_CTRL_HCFS (3 << 6) ---- a/include/linux/usb/ehci_pdriver.h -+++ b/include/linux/usb/ehci_pdriver.h -@@ -45,6 +45,7 @@ struct usb_ehci_pdata { - unsigned big_endian_desc:1; - unsigned big_endian_mmio:1; - unsigned no_io_watchdog:1; -+ unsigned ignore_oc:1; - - /* Turn on all power and clocks */ - int (*power_on)(struct platform_device *pdev); diff --git a/target/linux/generic/pending-3.18/110-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-3.18/110-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch deleted file mode 100644 index 6bbeb93cfa..0000000000 --- a/target/linux/generic/pending-3.18/110-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Fri, 10 Apr 2015 13:35:29 +0200 -Subject: [PATCH] jffs2: use .rename2 and add RENAME_WHITEOUT support - -It is required for renames on overlayfs - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -35,7 +35,7 @@ static int jffs2_mkdir (struct inode *,s - static int jffs2_rmdir (struct inode *,struct dentry *); - static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t); - static int jffs2_rename (struct inode *, struct dentry *, -- struct inode *, struct dentry *); -+ struct inode *, struct dentry *, unsigned int); - - const struct file_operations jffs2_dir_operations = - { -@@ -57,7 +57,7 @@ const struct inode_operations jffs2_dir_ - .mkdir = jffs2_mkdir, - .rmdir = jffs2_rmdir, - .mknod = jffs2_mknod, -- .rename = jffs2_rename, -+ .rename2 = jffs2_rename, - .get_acl = jffs2_get_acl, - .set_acl = jffs2_set_acl, - .setattr = jffs2_setattr, -@@ -752,8 +752,27 @@ static int jffs2_mknod (struct inode *di - return ret; - } - -+static int jffs2_whiteout(struct inode *old_dir, struct dentry *old_dentry) -+{ -+ struct dentry *wh; -+ int err; -+ -+ wh = d_alloc(old_dentry->d_parent, &old_dentry->d_name); -+ if (!wh) -+ return -ENOMEM; -+ -+ err = jffs2_mknod(old_dir, wh, S_IFCHR | WHITEOUT_MODE, -+ WHITEOUT_DEV); -+ if (err) -+ return err; -+ -+ d_rehash(wh); -+ return 0; -+} -+ - static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, -- struct inode *new_dir_i, struct dentry *new_dentry) -+ struct inode *new_dir_i, struct dentry *new_dentry, -+ unsigned int flags) - { - int ret; - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); -@@ -761,6 +780,9 @@ static int jffs2_rename (struct inode *o - uint8_t type; - uint32_t now; - -+ if (flags & ~RENAME_WHITEOUT) -+ return -EINVAL; -+ - /* The VFS will check for us and prevent trying to rename a - * file over a directory and vice versa, but if it's a directory, - * the VFS can't check whether the victim is empty. The filesystem -@@ -824,9 +846,14 @@ static int jffs2_rename (struct inode *o - if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) - inc_nlink(new_dir_i); - -- /* Unlink the original */ -- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); -+ if (flags & RENAME_WHITEOUT) -+ /* Replace with whiteout */ -+ ret = jffs2_whiteout(old_dir_i, old_dentry); -+ else -+ /* Unlink the original */ -+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+ old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, now); - - /* We don't touch inode->i_nlink */ - diff --git a/target/linux/generic/pending-3.18/111-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-3.18/111-jffs2-add-RENAME_EXCHANGE-support.patch deleted file mode 100644 index e0ed3312a2..0000000000 --- a/target/linux/generic/pending-3.18/111-jffs2-add-RENAME_EXCHANGE-support.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sat, 25 Apr 2015 12:41:32 +0200 -Subject: [PATCH] jffs2: add RENAME_EXCHANGE support - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -780,7 +780,7 @@ static int jffs2_rename (struct inode *o - uint8_t type; - uint32_t now; - -- if (flags & ~RENAME_WHITEOUT) -+ if (flags & ~(RENAME_WHITEOUT | RENAME_EXCHANGE)) - return -EINVAL; - - /* The VFS will check for us and prevent trying to rename a -@@ -788,7 +788,7 @@ static int jffs2_rename (struct inode *o - * the VFS can't check whether the victim is empty. The filesystem - * needs to do that for itself. - */ -- if (new_dentry->d_inode) { -+ if (new_dentry->d_inode && !(flags & RENAME_EXCHANGE)) { - victim_f = JFFS2_INODE_INFO(new_dentry->d_inode); - if (S_ISDIR(new_dentry->d_inode->i_mode)) { - struct jffs2_full_dirent *fd; -@@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *o - if (ret) - return ret; - -- if (victim_f) { -+ if (victim_f && !(flags & RENAME_EXCHANGE)) { - /* There was a victim. Kill it off nicely */ - if (S_ISDIR(new_dentry->d_inode->i_mode)) - clear_nlink(new_dentry->d_inode); -@@ -849,6 +849,12 @@ static int jffs2_rename (struct inode *o - if (flags & RENAME_WHITEOUT) - /* Replace with whiteout */ - ret = jffs2_whiteout(old_dir_i, old_dentry); -+ else if (flags & RENAME_EXCHANGE) -+ /* Replace the original */ -+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), -+ new_dentry->d_inode->i_ino, type, -+ old_dentry->d_name.name, old_dentry->d_name.len, -+ now); - else - /* Unlink the original */ - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -@@ -875,7 +881,7 @@ static int jffs2_rename (struct inode *o - return ret; - } - -- if (S_ISDIR(old_dentry->d_inode->i_mode)) -+ if (S_ISDIR(old_dentry->d_inode->i_mode) && !(flags & RENAME_EXCHANGE)) - drop_nlink(old_dir_i); - - new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); diff --git a/target/linux/generic/pending-3.18/120-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-3.18/120-bridge_allow_receiption_on_disabled_port.patch deleted file mode 100644 index 909611403c..0000000000 --- a/target/linux/generic/pending-3.18/120-bridge_allow_receiption_on_disabled_port.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Stephen Hemminger <stephen@networkplumber.org> -Subject: bridge: allow receiption on disabled port - -When an ethernet device is enslaved to a bridge, and the bridge STP -detects loss of carrier (or operational state down), then normally -packet receiption is blocked. - -This breaks control applications like WPA which maybe expecting to -receive packets to negotiate to bring link up. The bridge needs to -block forwarding packets from these disabled ports, but there is no -hard requirement to not allow local packet delivery. - -Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> -Signed-off-by: Felix Fietkau <nbd@nbd.name> - ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -146,11 +146,13 @@ EXPORT_SYMBOL_GPL(br_handle_frame_finish - static int br_handle_local_finish(struct sk_buff *skb) - { - struct net_bridge_port *p = br_port_get_rcu(skb->dev); -- u16 vid = 0; -+ if (p->state != BR_STATE_DISABLED) { -+ u16 vid = 0; - -- /* check if vlan is allowed, to avoid spoofing */ -- if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid)) -- br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); -+ /* check if vlan is allowed, to avoid spoofing */ -+ if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid)) -+ br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); -+ } - return 0; /* process further */ - } - -@@ -224,6 +226,18 @@ rx_handler_result_t br_handle_frame(stru - - forward: - switch (p->state) { -+ case BR_STATE_DISABLED: -+ if (ether_addr_equal(p->br->dev->dev_addr, dest)) -+ skb->pkt_type = PACKET_HOST; -+ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, -+ br_handle_local_finish)) -+ break; -+ -+ BR_INPUT_SKB_CB(skb)->brdev = p->br->dev; -+ br_pass_frame_up(skb); -+ break; -+ - case BR_STATE_FORWARDING: - rhook = rcu_dereference(br_should_route_hook); - if (rhook) { diff --git a/target/linux/generic/pending-3.18/132-mips_inline_dma_ops.patch b/target/linux/generic/pending-3.18/132-mips_inline_dma_ops.patch deleted file mode 100644 index 7a64ae7994..0000000000 --- a/target/linux/generic/pending-3.18/132-mips_inline_dma_ops.patch +++ /dev/null @@ -1,688 +0,0 @@ -From 2c58080407554e1bac8fd50d23cb02420524caed Mon Sep 17 00:00:00 2001 -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 12 Aug 2013 12:50:22 +0200 -Subject: [PATCH] MIPS: partially inline dma ops - -Several DMA ops are no-op on many platforms, and the indirection through -the mips_dma_map_ops function table is causing the compiler to emit -unnecessary code. - -Inlining visibly improves network performance in my tests (on a 24Kc -based system), and also slightly reduces code size of a few drivers. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - arch/mips/Kconfig | 4 + - arch/mips/include/asm/dma-mapping.h | 360 +++++++++++++++++++++++++++++++++++- - arch/mips/mm/dma-default.c | 163 ++-------------- - 3 files changed, 373 insertions(+), 154 deletions(-) - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1453,6 +1453,7 @@ config CPU_CAVIUM_OCTEON - select CPU_SUPPORTS_HUGEPAGES - select USB_EHCI_BIG_ENDIAN_MMIO - select MIPS_L1_CACHE_SHIFT_7 -+ select SYS_HAS_DMA_OPS - help - The Cavium Octeon processor is a highly integrated chip containing - many ethernet hardware widgets for networking tasks. The processor -@@ -1708,6 +1709,9 @@ config MIPS_MALTA_PM - bool - default y - -+config SYS_HAS_DMA_OPS -+ bool -+ - # - # CPU may reorder R->R, R->W, W->R, W->W - # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC ---- a/arch/mips/include/asm/dma-mapping.h -+++ b/arch/mips/include/asm/dma-mapping.h -@@ -1,9 +1,16 @@ - #ifndef _ASM_DMA_MAPPING_H - #define _ASM_DMA_MAPPING_H - -+#include <linux/kmemcheck.h> -+#include <linux/bug.h> -+#include <linux/scatterlist.h> -+#include <linux/dma-debug.h> -+#include <linux/dma-attrs.h> -+ - #include <asm/scatterlist.h> - #include <asm/dma-coherence.h> - #include <asm/cache.h> -+#include <asm/cpu-type.h> - #include <asm-generic/dma-coherent.h> - - #ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */ -@@ -12,12 +19,48 @@ - - extern struct dma_map_ops *mips_dma_map_ops; - -+void __dma_sync(struct page *page, unsigned long offset, size_t size, -+ enum dma_data_direction direction); -+void *mips_dma_alloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, gfp_t gfp, -+ struct dma_attrs *attrs); -+void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, -+ dma_addr_t dma_handle, struct dma_attrs *attrs); -+ - static inline struct dma_map_ops *get_dma_ops(struct device *dev) - { -+#ifdef CONFIG_SYS_HAS_DMA_OPS - if (dev && dev->archdata.dma_ops) - return dev->archdata.dma_ops; - else - return mips_dma_map_ops; -+#else -+ return NULL; -+#endif -+} -+ -+/* -+ * Warning on the terminology - Linux calls an uncached area coherent; -+ * MIPS terminology calls memory areas with hardware maintained coherency -+ * coherent. -+ */ -+ -+static inline int cpu_needs_post_dma_flush(struct device *dev) -+{ -+#ifndef CONFIG_SYS_HAS_CPU_R10000 -+ return 0; -+#endif -+ return !plat_device_is_coherent(dev) && -+ (boot_cpu_type() == CPU_R10000 || -+ boot_cpu_type() == CPU_R12000 || -+ boot_cpu_type() == CPU_BMIPS5000); -+} -+ -+static inline struct page *dma_addr_to_page(struct device *dev, -+ dma_addr_t dma_addr) -+{ -+ return pfn_to_page( -+ plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT); - } - - static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) -@@ -30,12 +73,304 @@ static inline bool dma_capable(struct de - - static inline void dma_mark_clean(void *addr, size_t size) {} - --#include <asm-generic/dma-mapping-common.h> -+static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, -+ size_t size, -+ enum dma_data_direction dir, -+ struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ unsigned long offset = (unsigned long)ptr & ~PAGE_MASK; -+ struct page *page = virt_to_page(ptr); -+ dma_addr_t addr; -+ -+ kmemcheck_mark_initialized(ptr, size); -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) { -+ addr = ops->map_page(dev, page, offset, size, dir, attrs); -+ } else { -+ if (!plat_device_is_coherent(dev)) -+ __dma_sync(page, offset, size, dir); -+ -+ addr = plat_map_dma_mem_page(dev, page) + offset; -+ } -+ debug_dma_map_page(dev, page, offset, size, dir, addr, true); -+ return addr; -+} -+ -+static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, -+ size_t size, -+ enum dma_data_direction dir, -+ struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) { -+ ops->unmap_page(dev, addr, size, dir, attrs); -+ } else { -+ if (cpu_needs_post_dma_flush(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr), -+ addr & ~PAGE_MASK, size, dir); -+ -+ plat_unmap_dma_mem(dev, addr, size, dir); -+ } -+ debug_dma_unmap_page(dev, addr, size, dir, true); -+} -+ -+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, -+ int nents, enum dma_data_direction dir, -+ struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ int i, ents; -+ struct scatterlist *s; -+ -+ for_each_sg(sg, s, nents, i) -+ kmemcheck_mark_initialized(sg_virt(s), s->length); -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) { -+ ents = ops->map_sg(dev, sg, nents, dir, attrs); -+ } else { -+ for_each_sg(sg, s, nents, i) { -+ struct page *page = sg_page(s); -+ -+ if (!plat_device_is_coherent(dev)) -+ __dma_sync(page, s->offset, s->length, dir); -+#ifdef CONFIG_NEED_SG_DMA_LENGTH -+ s->dma_length = s->length; -+#endif -+ s->dma_address = -+ plat_map_dma_mem_page(dev, page) + s->offset; -+ } -+ ents = nents; -+ } -+ debug_dma_map_sg(dev, sg, nents, ents, dir); -+ -+ return ents; -+} -+ -+static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, -+ int nents, enum dma_data_direction dir, -+ struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ struct scatterlist *s; -+ int i; -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ debug_dma_unmap_sg(dev, sg, nents, dir); -+ if (ops) { -+ ops->unmap_sg(dev, sg, nents, dir, attrs); -+ return; -+ } -+ -+ for_each_sg(sg, s, nents, i) { -+ if (!plat_device_is_coherent(dev) && dir != DMA_TO_DEVICE) -+ __dma_sync(sg_page(s), s->offset, s->length, dir); -+ plat_unmap_dma_mem(dev, s->dma_address, s->length, dir); -+ } -+} -+ -+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, -+ size_t offset, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ dma_addr_t addr; -+ -+ kmemcheck_mark_initialized(page_address(page) + offset, size); -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) { -+ addr = ops->map_page(dev, page, offset, size, dir, NULL); -+ } else { -+ if (!plat_device_is_coherent(dev)) -+ __dma_sync(page, offset, size, dir); -+ -+ addr = plat_map_dma_mem_page(dev, page) + offset; -+ } -+ debug_dma_map_page(dev, page, offset, size, dir, addr, false); -+ -+ return addr; -+} -+ -+static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, -+ size_t size, enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) { -+ ops->unmap_page(dev, addr, size, dir, NULL); -+ } else { -+ if (cpu_needs_post_dma_flush(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr), -+ addr & ~PAGE_MASK, size, dir); -+ -+ plat_unmap_dma_mem(dev, addr, size, dir); -+ } -+ debug_dma_unmap_page(dev, addr, size, dir, false); -+} -+ -+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, -+ size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_single_for_cpu(dev, addr, size, dir); -+ else if (cpu_needs_post_dma_flush(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr), -+ addr & ~PAGE_MASK, size, dir); -+ debug_dma_sync_single_for_cpu(dev, addr, size, dir); -+} -+ -+static inline void dma_sync_single_for_device(struct device *dev, -+ dma_addr_t addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_single_for_device(dev, addr, size, dir); -+ else if (!plat_device_is_coherent(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr), -+ addr & ~PAGE_MASK, size, dir); -+ debug_dma_sync_single_for_device(dev, addr, size, dir); -+} -+ -+static inline void dma_sync_single_range_for_cpu(struct device *dev, -+ dma_addr_t addr, -+ unsigned long offset, -+ size_t size, -+ enum dma_data_direction dir) -+{ -+ const struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_single_for_cpu(dev, addr + offset, size, dir); -+ else if (cpu_needs_post_dma_flush(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr + offset), -+ (addr + offset) & ~PAGE_MASK, size, dir); -+ debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir); -+} -+ -+static inline void dma_sync_single_range_for_device(struct device *dev, -+ dma_addr_t addr, -+ unsigned long offset, -+ size_t size, -+ enum dma_data_direction dir) -+{ -+ const struct dma_map_ops *ops = get_dma_ops(dev); -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_single_for_device(dev, addr + offset, size, dir); -+ else if (!plat_device_is_coherent(dev)) -+ __dma_sync(dma_addr_to_page(dev, addr + offset), -+ (addr + offset) & ~PAGE_MASK, size, dir); -+ debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir); -+} -+ -+static inline void -+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, -+ int nelems, enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ struct scatterlist *s; -+ int i; -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_sg_for_cpu(dev, sg, nelems, dir); -+ else if (cpu_needs_post_dma_flush(dev)) { -+ for_each_sg(sg, s, nelems, i) -+ __dma_sync(sg_page(s), s->offset, s->length, dir); -+ } -+ debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); -+} -+ -+static inline void -+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, -+ int nelems, enum dma_data_direction dir) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ struct scatterlist *s; -+ int i; -+ -+ BUG_ON(!valid_dma_direction(dir)); -+ if (ops) -+ ops->sync_sg_for_device(dev, sg, nelems, dir); -+ else if (!plat_device_is_coherent(dev)) { -+ for_each_sg(sg, s, nelems, i) -+ __dma_sync(sg_page(s), s->offset, s->length, dir); -+ } -+ debug_dma_sync_sg_for_device(dev, sg, nelems, dir); -+ -+} -+ -+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) -+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL) -+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) -+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) -+ -+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size); -+ -+/** -+ * dma_mmap_attrs - map a coherent DMA allocation into user space -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @vma: vm_area_struct describing requested user mapping -+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_attrs -+ * @handle: device-view address returned from dma_alloc_attrs -+ * @size: size of memory originally requested in dma_alloc_attrs -+ * @attrs: attributes of mapping properties requested in dma_alloc_attrs -+ * -+ * Map a coherent DMA buffer previously allocated by dma_alloc_attrs -+ * into user space. The coherent DMA buffer must not be freed by the -+ * driver until the user space mapping has been released. -+ */ -+static inline int -+dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, -+ dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ BUG_ON(!ops); -+ if (ops && ops->mmap) -+ return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); -+ return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); -+} -+ -+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) -+ -+int -+dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size); -+ -+static inline int -+dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, -+ dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) -+{ -+ struct dma_map_ops *ops = get_dma_ops(dev); -+ BUG_ON(!ops); -+ if (ops && ops->get_sgtable) -+ return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, -+ attrs); -+ return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); -+} -+ -+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL) -+ - - static inline int dma_supported(struct device *dev, u64 mask) - { - struct dma_map_ops *ops = get_dma_ops(dev); -- return ops->dma_supported(dev, mask); -+ if (ops) -+ return ops->dma_supported(dev, mask); -+ return plat_dma_supported(dev, mask); - } - - static inline int dma_mapping_error(struct device *dev, u64 mask) -@@ -43,7 +378,9 @@ static inline int dma_mapping_error(stru - struct dma_map_ops *ops = get_dma_ops(dev); - - debug_dma_mapping_error(dev, mask); -- return ops->mapping_error(dev, mask); -+ if (ops) -+ return ops->mapping_error(dev, mask); -+ return 0; - } - - static inline int -@@ -54,7 +391,7 @@ dma_set_mask(struct device *dev, u64 mas - if(!dev->dma_mask || !dma_supported(dev, mask)) - return -EIO; - -- if (ops->set_dma_mask) -+ if (ops && ops->set_dma_mask) - return ops->set_dma_mask(dev, mask); - - *dev->dma_mask = mask; -@@ -74,7 +411,11 @@ static inline void *dma_alloc_attrs(stru - void *ret; - struct dma_map_ops *ops = get_dma_ops(dev); - -- ret = ops->alloc(dev, size, dma_handle, gfp, attrs); -+ if (ops) -+ ret = ops->alloc(dev, size, dma_handle, gfp, attrs); -+ else -+ ret = mips_dma_alloc_coherent(dev, size, dma_handle, gfp, -+ attrs); - - debug_dma_alloc_coherent(dev, size, *dma_handle, ret); - -@@ -89,7 +430,10 @@ static inline void dma_free_attrs(struct - { - struct dma_map_ops *ops = get_dma_ops(dev); - -- ops->free(dev, size, vaddr, dma_handle, attrs); -+ if (ops) -+ ops->free(dev, size, vaddr, dma_handle, attrs); -+ else -+ mips_dma_free_coherent(dev, size, vaddr, dma_handle, attrs); - - debug_dma_free_coherent(dev, size, vaddr, dma_handle); - } ---- a/arch/mips/mm/dma-default.c -+++ b/arch/mips/mm/dma-default.c -@@ -26,7 +26,7 @@ - - #ifdef CONFIG_DMA_MAYBE_COHERENT - int coherentio = 0; /* User defined DMA coherency from command line. */ --EXPORT_SYMBOL_GPL(coherentio); -+EXPORT_SYMBOL(coherentio); - int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ - - static int __init setcoherentio(char *str) -@@ -46,30 +46,6 @@ static int __init setnocoherentio(char * - early_param("nocoherentio", setnocoherentio); - #endif - --static inline struct page *dma_addr_to_page(struct device *dev, -- dma_addr_t dma_addr) --{ -- return pfn_to_page( -- plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT); --} -- --/* -- * The affected CPUs below in 'cpu_needs_post_dma_flush()' can -- * speculatively fill random cachelines with stale data at any time, -- * requiring an extra flush post-DMA. -- * -- * Warning on the terminology - Linux calls an uncached area coherent; -- * MIPS terminology calls memory areas with hardware maintained coherency -- * coherent. -- */ --static inline int cpu_needs_post_dma_flush(struct device *dev) --{ -- return !plat_device_is_coherent(dev) && -- (boot_cpu_type() == CPU_R10000 || -- boot_cpu_type() == CPU_R12000 || -- boot_cpu_type() == CPU_BMIPS5000); --} -- - static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) - { - gfp_t dma_flag; -@@ -125,8 +101,9 @@ void *dma_alloc_noncoherent(struct devic - } - EXPORT_SYMBOL(dma_alloc_noncoherent); - --static void *mips_dma_alloc_coherent(struct device *dev, size_t size, -- dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) -+void *mips_dma_alloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, gfp_t gfp, -+ struct dma_attrs *attrs) - { - void *ret; - struct page *page = NULL; -@@ -157,6 +134,7 @@ static void *mips_dma_alloc_coherent(str - - return ret; - } -+EXPORT_SYMBOL(mips_dma_alloc_coherent); - - - void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, -@@ -167,8 +145,8 @@ void dma_free_noncoherent(struct device - } - EXPORT_SYMBOL(dma_free_noncoherent); - --static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, -- dma_addr_t dma_handle, struct dma_attrs *attrs) -+void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, -+ dma_addr_t dma_handle, struct dma_attrs *attrs) - { - unsigned long addr = (unsigned long) vaddr; - int order = get_order(size); -@@ -188,6 +166,7 @@ static void mips_dma_free_coherent(struc - if (!dma_release_from_contiguous(dev, page, count)) - __free_pages(page, get_order(size)); - } -+EXPORT_SYMBOL(mips_dma_free_coherent); - - static inline void __dma_sync_virtual(void *addr, size_t size, - enum dma_data_direction direction) -@@ -216,8 +195,8 @@ static inline void __dma_sync_virtual(vo - * If highmem is not configured then the bulk of this loop gets - * optimized out. - */ --static inline void __dma_sync(struct page *page, -- unsigned long offset, size_t size, enum dma_data_direction direction) -+void __dma_sync(struct page *page, unsigned long offset, size_t size, -+ enum dma_data_direction direction) - { - size_t left = size; - -@@ -246,108 +225,7 @@ static inline void __dma_sync(struct pag - left -= len; - } while (left); - } -- --static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, -- size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) --{ -- if (cpu_needs_post_dma_flush(dev)) -- __dma_sync(dma_addr_to_page(dev, dma_addr), -- dma_addr & ~PAGE_MASK, size, direction); -- -- plat_unmap_dma_mem(dev, dma_addr, size, direction); --} -- --static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, -- int nents, enum dma_data_direction direction, struct dma_attrs *attrs) --{ -- int i; -- -- for (i = 0; i < nents; i++, sg++) { -- if (!plat_device_is_coherent(dev)) -- __dma_sync(sg_page(sg), sg->offset, sg->length, -- direction); --#ifdef CONFIG_NEED_SG_DMA_LENGTH -- sg->dma_length = sg->length; --#endif -- sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) + -- sg->offset; -- } -- -- return nents; --} -- --static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page, -- unsigned long offset, size_t size, enum dma_data_direction direction, -- struct dma_attrs *attrs) --{ -- if (!plat_device_is_coherent(dev)) -- __dma_sync(page, offset, size, direction); -- -- return plat_map_dma_mem_page(dev, page) + offset; --} -- --static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, -- int nhwentries, enum dma_data_direction direction, -- struct dma_attrs *attrs) --{ -- int i; -- -- for (i = 0; i < nhwentries; i++, sg++) { -- if (!plat_device_is_coherent(dev) && -- direction != DMA_TO_DEVICE) -- __dma_sync(sg_page(sg), sg->offset, sg->length, -- direction); -- plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction); -- } --} -- --static void mips_dma_sync_single_for_cpu(struct device *dev, -- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) --{ -- if (cpu_needs_post_dma_flush(dev)) -- __dma_sync(dma_addr_to_page(dev, dma_handle), -- dma_handle & ~PAGE_MASK, size, direction); --} -- --static void mips_dma_sync_single_for_device(struct device *dev, -- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) --{ -- if (!plat_device_is_coherent(dev)) -- __dma_sync(dma_addr_to_page(dev, dma_handle), -- dma_handle & ~PAGE_MASK, size, direction); --} -- --static void mips_dma_sync_sg_for_cpu(struct device *dev, -- struct scatterlist *sg, int nelems, enum dma_data_direction direction) --{ -- int i; -- -- if (cpu_needs_post_dma_flush(dev)) -- for (i = 0; i < nelems; i++, sg++) -- __dma_sync(sg_page(sg), sg->offset, sg->length, -- direction); --} -- --static void mips_dma_sync_sg_for_device(struct device *dev, -- struct scatterlist *sg, int nelems, enum dma_data_direction direction) --{ -- int i; -- -- if (!plat_device_is_coherent(dev)) -- for (i = 0; i < nelems; i++, sg++) -- __dma_sync(sg_page(sg), sg->offset, sg->length, -- direction); --} -- --int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) --{ -- return 0; --} -- --int mips_dma_supported(struct device *dev, u64 mask) --{ -- return plat_dma_supported(dev, mask); --} -+EXPORT_SYMBOL(__dma_sync); - - void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) -@@ -360,23 +238,10 @@ void dma_cache_sync(struct device *dev, - - EXPORT_SYMBOL(dma_cache_sync); - --static struct dma_map_ops mips_default_dma_map_ops = { -- .alloc = mips_dma_alloc_coherent, -- .free = mips_dma_free_coherent, -- .map_page = mips_dma_map_page, -- .unmap_page = mips_dma_unmap_page, -- .map_sg = mips_dma_map_sg, -- .unmap_sg = mips_dma_unmap_sg, -- .sync_single_for_cpu = mips_dma_sync_single_for_cpu, -- .sync_single_for_device = mips_dma_sync_single_for_device, -- .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, -- .sync_sg_for_device = mips_dma_sync_sg_for_device, -- .mapping_error = mips_dma_mapping_error, -- .dma_supported = mips_dma_supported --}; -- --struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops; -+#ifdef CONFIG_SYS_HAS_DMA_OPS -+struct dma_map_ops *mips_dma_map_ops = NULL; - EXPORT_SYMBOL(mips_dma_map_ops); -+#endif - - #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) - diff --git a/target/linux/generic/pending-3.18/140-mtd-part-add-generic-parsing-of-linux-part-probe.patch b/target/linux/generic/pending-3.18/140-mtd-part-add-generic-parsing-of-linux-part-probe.patch deleted file mode 100644 index bd34f9698a..0000000000 --- a/target/linux/generic/pending-3.18/140-mtd-part-add-generic-parsing-of-linux-part-probe.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 173b0add0cff6558f950c0cb1eacfb729d482711 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Sun, 17 May 2015 18:48:38 +0200 -Subject: [PATCH 4/8] mtd: part: add generic parsing of linux,part-probe - -This moves the linux,part-probe device tree parsing code from -physmap_of.c to mtdpart.c. Now all drivers can use this feature by just -providing a reference to their device tree node in struct -mtd_part_parser_data. - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - Documentation/devicetree/bindings/mtd/nand.txt | 16 ++++++++++ - drivers/mtd/maps/physmap_of.c | 40 +----------------------- - drivers/mtd/mtdpart.c | 43 ++++++++++++++++++++++++++ - 3 files changed, 60 insertions(+), 39 deletions(-) - ---- a/Documentation/devicetree/bindings/mtd/nand.txt -+++ b/Documentation/devicetree/bindings/mtd/nand.txt -@@ -12,6 +12,22 @@ - - nand-ecc-step-size: integer representing the number of data bytes - that are covered by a single ECC step. - -+- linux,part-probe: list of name as strings of the partition parser -+ which should be used to parse the partition table. -+ They will be tried in the specified ordering and -+ the next one will be used if the previous one -+ failed. -+ -+ Example: linux,part-probe = "cmdlinepart", "ofpart"; -+ -+ This is also the default value, which will be used -+ if this attribute is not specified. It could be -+ that the flash driver in use overwrote the default -+ value and uses some other default. -+ -+ Possible values are: bcm47xxpart, afs, ar7part, -+ ofoldpart, ofpart, bcm63xxpart, RedBoot, cmdlinepart -+ - The ECC strength and ECC step size properties define the correction capability - of a controller. Together, they say a controller can correct "{strength} bit - errors per {size} bytes". ---- a/drivers/mtd/maps/physmap_of.c -+++ b/drivers/mtd/maps/physmap_of.c -@@ -114,45 +114,9 @@ static struct mtd_info *obsolete_probe(s - static const char * const part_probe_types_def[] = { - "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; - --static const char * const *of_get_probes(struct device_node *dp) --{ -- const char *cp; -- int cplen; -- unsigned int l; -- unsigned int count; -- const char **res; -- -- cp = of_get_property(dp, "linux,part-probe", &cplen); -- if (cp == NULL) -- return part_probe_types_def; -- -- count = 0; -- for (l = 0; l != cplen; l++) -- if (cp[l] == 0) -- count++; -- -- res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL); -- count = 0; -- while (cplen > 0) { -- res[count] = cp; -- l = strlen(cp) + 1; -- cp += l; -- cplen -= l; -- count++; -- } -- return res; --} -- --static void of_free_probes(const char * const *probes) --{ -- if (probes != part_probe_types_def) -- kfree(probes); --} -- - static struct of_device_id of_flash_match[]; - static int of_flash_probe(struct platform_device *dev) - { -- const char * const *part_probe_types; - const struct of_device_id *match; - struct device_node *dp = dev->dev.of_node; - struct resource res; -@@ -302,10 +266,8 @@ static int of_flash_probe(struct platfor - goto err_out; - - ppdata.of_node = dp; -- part_probe_types = of_get_probes(dp); -- mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata, -+ mtd_device_parse_register(info->cmtd, part_probe_types_def, &ppdata, - NULL, 0); -- of_free_probes(part_probe_types); - - kfree(mtd_list); - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -29,6 +29,7 @@ - #include <linux/kmod.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -+#include <linux/of.h> - #include <linux/err.h> - - #include "mtdcore.h" -@@ -702,6 +703,40 @@ void deregister_mtd_parser(struct mtd_pa - EXPORT_SYMBOL_GPL(deregister_mtd_parser); - - /* -+ * Parses the linux,part-probe device tree property. -+ * When a non null value is returned it has to be freed with kfree() by -+ * the caller. -+ */ -+static const char * const *of_get_probes(struct device_node *dp) -+{ -+ const char *cp; -+ int cplen; -+ unsigned int l; -+ unsigned int count; -+ const char **res; -+ -+ cp = of_get_property(dp, "linux,part-probe", &cplen); -+ if (cp == NULL) -+ return NULL; -+ -+ count = 0; -+ for (l = 0; l != cplen; l++) -+ if (cp[l] == 0) -+ count++; -+ -+ res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); -+ count = 0; -+ while (cplen > 0) { -+ res[count] = cp; -+ l = strlen(cp) + 1; -+ cp += l; -+ cplen -= l; -+ count++; -+ } -+ return res; -+} -+ -+/* - * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you - * are changing this array! - */ -@@ -737,6 +772,13 @@ int parse_mtd_partitions(struct mtd_info - { - struct mtd_part_parser *parser; - int ret = 0; -+ const char *const *types_of = NULL; -+ -+ if (data && data->of_node) { -+ types_of = of_get_probes(data->of_node); -+ if (types_of != NULL) -+ types = types_of; -+ } - - if (!types) - types = default_mtd_part_types; -@@ -755,6 +797,7 @@ int parse_mtd_partitions(struct mtd_info - break; - } - } -+ kfree(types_of); - return ret; - } - diff --git a/target/linux/generic/pending-3.18/142-mtd-bcm47xxpart-don-t-fail-because-of-bit-flips.patch b/target/linux/generic/pending-3.18/142-mtd-bcm47xxpart-don-t-fail-because-of-bit-flips.patch deleted file mode 100644 index 926de5fef7..0000000000 --- a/target/linux/generic/pending-3.18/142-mtd-bcm47xxpart-don-t-fail-because-of-bit-flips.patch +++ /dev/null @@ -1,92 +0,0 @@ -From dfe4b4c732365fc1d83c2d2fd9cc18054ae850b7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Sun, 6 Dec 2015 11:24:05 +0100 -Subject: [PATCH] mtd: bcm47xxpart: don't fail because of bit-flips -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Bit-flip errors may occur on NAND flashes and are harmless. Handle them -gracefully as read content is still reliable and can be parsed. - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> ---- - drivers/mtd/bcm47xxpart.c | 38 ++++++++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 16 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -66,11 +66,13 @@ static const char *bcm47xxpart_trx_data_ - { - uint32_t buf; - size_t bytes_read; -+ int err; - -- if (mtd_read(master, offset, sizeof(buf), &bytes_read, -- (uint8_t *)&buf) < 0) { -- pr_err("mtd_read error while parsing (offset: 0x%X)!\n", -- offset); -+ err = mtd_read(master, offset, sizeof(buf), &bytes_read, -+ (uint8_t *)&buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", -+ offset, err); - goto out_default; - } - -@@ -95,6 +97,7 @@ static int bcm47xxpart_parse(struct mtd_ - int trx_part = -1; - int last_trx_part = -1; - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; -+ int err; - - /* - * Some really old flashes (like AT45DB*) had smaller erasesize-s, but -@@ -128,10 +131,11 @@ static int bcm47xxpart_parse(struct mtd_ - } - - /* Read beginning of the block */ -- if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, -- &bytes_read, (uint8_t *)buf) < 0) { -- pr_err("mtd_read error while parsing (offset: 0x%X)!\n", -- offset); -+ err = mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, -+ &bytes_read, (uint8_t *)buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", -+ offset, err); - continue; - } - -@@ -252,10 +256,11 @@ static int bcm47xxpart_parse(struct mtd_ - } - - /* Read middle of the block */ -- if (mtd_read(master, offset + 0x8000, 0x4, -- &bytes_read, (uint8_t *)buf) < 0) { -- pr_err("mtd_read error while parsing (offset: 0x%X)!\n", -- offset); -+ err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read, -+ (uint8_t *)buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", -+ offset, err); - continue; - } - -@@ -275,10 +280,11 @@ static int bcm47xxpart_parse(struct mtd_ - } - - offset = master->size - possible_nvram_sizes[i]; -- if (mtd_read(master, offset, 0x4, &bytes_read, -- (uint8_t *)buf) < 0) { -- pr_err("mtd_read error while reading at offset 0x%X!\n", -- offset); -+ err = mtd_read(master, offset, 0x4, &bytes_read, -+ (uint8_t *)buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("mtd_read error while reading (offset 0x%X): %d\n", -+ offset, err); - continue; - } - diff --git a/target/linux/generic/pending-3.18/180-usb-xhci-make-USB_XHCI_PLATFORM-selectable.patch b/target/linux/generic/pending-3.18/180-usb-xhci-make-USB_XHCI_PLATFORM-selectable.patch deleted file mode 100644 index a17e39800c..0000000000 --- a/target/linux/generic/pending-3.18/180-usb-xhci-make-USB_XHCI_PLATFORM-selectable.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 9612e686b235dc9e33c8dfb5e6d2ff2b2140fb9d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Tue, 16 Jun 2015 21:01:30 +0200 -Subject: [PATCH V2] usb: xhci: make USB_XHCI_PLATFORM selectable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Right now xhci-plat-hcd can be built when using one of platform specific -drivers only (mvebu/rcar). There shouldn't be such limitation as some -platforms may not require any quirks and may want to just use a generic -driver ("generic-xhci" / "xhci-hcd"). - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> ---- -Greg/Mathias: I'm not sure if it's more like USB subsystem stuff or xHCI -Could you decide which one of you could pick that, please? - -V2: Drop useless "default n", thanks Sergei :) ---- - drivers/usb/host/Kconfig | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/usb/host/Kconfig -+++ b/drivers/usb/host/Kconfig -@@ -32,7 +32,14 @@ config USB_XHCI_PCI - default y - - config USB_XHCI_PLATFORM -- tristate -+ tristate "Generic xHCI driver for a platform device" -+ ---help--- -+ Adds an xHCI host driver for a generic platform device, which -+ provides a memory space and an irq. -+ It is also a prerequisite for platform specific drivers that -+ implement some extra quirks. -+ -+ If unsure, say N. - - config USB_XHCI_MVEBU - tristate "xHCI support for Marvell Armada 375/38x" diff --git a/target/linux/generic/pending-3.18/190-cdc_ncm_add_support_for_moving_ndp_to_end_of_ncm_frame.patch b/target/linux/generic/pending-3.18/190-cdc_ncm_add_support_for_moving_ndp_to_end_of_ncm_frame.patch deleted file mode 100644 index 632384d56f..0000000000 --- a/target/linux/generic/pending-3.18/190-cdc_ncm_add_support_for_moving_ndp_to_end_of_ncm_frame.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 4a0e3e989d66bb7204b163d9cfaa7fa96d0f2023 Mon Sep 17 00:00:00 2001 -From: Enrico Mioso <mrkiko.rs@gmail.com> -Date: Wed, 8 Jul 2015 13:05:57 +0200 -Subject: [PATCH] cdc_ncm: Add support for moving NDP to end of NCM frame - -NCM specs are not actually mandating a specific position in the frame for -the NDP (Network Datagram Pointer). However, some Huawei devices will -ignore our aggregates if it is not placed after the datagrams it points -to. Add support for doing just this, in a per-device configurable way. -While at it, update NCM subdrivers, disabling this functionality in all of -them, except in huawei_cdc_ncm where it is enabled instead. -We aren't making any distinction between different Huawei NCM devices, -based on what the vendor driver does. Standard NCM devices are left -unaffected: if they are compliant, they should be always usable, still -stay on the safe side. - -This change has been tested and working with a Huawei E3131 device (which -works regardless of NDP position), a Huawei E3531 (also working both -ways) and an E3372 (which mandates NDP to be after indexed datagrams). - -V1->V2: -- corrected wrong NDP acronym definition -- fixed possible NULL pointer dereference -- patch cleanup -V2->V3: -- Properly account for the NDP size when writing new packets to SKB - -Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - drivers/net/usb/cdc_mbim.c | 2 +- - drivers/net/usb/cdc_ncm.c | 61 ++++++++++++++++++++++++++++++++++++---- - drivers/net/usb/huawei_cdc_ncm.c | 7 +++-- - include/linux/usb/cdc_ncm.h | 7 ++++- - 4 files changed, 67 insertions(+), 10 deletions(-) - ---- a/drivers/net/usb/cdc_mbim.c -+++ b/drivers/net/usb/cdc_mbim.c -@@ -158,7 +158,7 @@ static int cdc_mbim_bind(struct usbnet * - if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) - goto err; - -- ret = cdc_ncm_bind_common(dev, intf, data_altsetting); -+ ret = cdc_ncm_bind_common(dev, intf, data_altsetting, 0); - if (ret) - goto err; - ---- a/drivers/net/usb/cdc_ncm.c -+++ b/drivers/net/usb/cdc_ncm.c -@@ -684,10 +684,12 @@ static void cdc_ncm_free(struct cdc_ncm_ - ctx->tx_curr_skb = NULL; - } - -+ kfree(ctx->delayed_ndp16); -+ - kfree(ctx); - } - --int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting) -+int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags) - { - const struct usb_cdc_union_desc *union_desc = NULL; - struct cdc_ncm_ctx *ctx; -@@ -859,6 +861,17 @@ advance: - /* finish setting up the device specific data */ - cdc_ncm_setup(dev); - -+ /* Device-specific flags */ -+ ctx->drvflags = drvflags; -+ -+ /* Allocate the delayed NDP if needed. */ -+ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { -+ ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); -+ if (!ctx->delayed_ndp16) -+ goto error2; -+ dev_info(&intf->dev, "NDP will be placed at end of frame for this device."); -+ } -+ - /* override ethtool_ops */ - dev->net->ethtool_ops = &cdc_ncm_ethtool_ops; - -@@ -956,8 +969,11 @@ static int cdc_ncm_bind(struct usbnet *d - if (cdc_ncm_select_altsetting(intf) != CDC_NCM_COMM_ALTSETTING_NCM) - return -ENODEV; - -- /* The NCM data altsetting is fixed */ -- return cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM); -+ /* The NCM data altsetting is fixed, so we hard-coded it. -+ * Additionally, generic NCM devices are assumed to accept arbitrarily -+ * placed NDP. -+ */ -+ return cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM, 0); - } - - static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max) -@@ -979,6 +995,14 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm - struct usb_cdc_ncm_nth16 *nth16 = (void *)skb->data; - size_t ndpoffset = le16_to_cpu(nth16->wNdpIndex); - -+ /* If NDP should be moved to the end of the NCM package, we can't follow the -+ * NTH16 header as we would normally do. NDP isn't written to the SKB yet, and -+ * the wNdpIndex field in the header is actually not consistent with reality. It will be later. -+ */ -+ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) -+ if (ctx->delayed_ndp16->dwSignature == sign) -+ return ctx->delayed_ndp16; -+ - /* follow the chain of NDPs, looking for a match */ - while (ndpoffset) { - ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset); -@@ -988,7 +1012,8 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm - } - - /* align new NDP */ -- cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_max); -+ if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) -+ cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_max); - - /* verify that there is room for the NDP and the datagram (reserve) */ - if ((ctx->tx_max - skb->len - reserve) < ctx->max_ndp_size) -@@ -1001,7 +1026,11 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm - nth16->wNdpIndex = cpu_to_le16(skb->len); - - /* push a new empty NDP */ -- ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, ctx->max_ndp_size), 0, ctx->max_ndp_size); -+ if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) -+ ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, ctx->max_ndp_size), 0, ctx->max_ndp_size); -+ else -+ ndp16 = ctx->delayed_ndp16; -+ - ndp16->dwSignature = sign; - ndp16->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp16) + sizeof(struct usb_cdc_ncm_dpe16)); - return ndp16; -@@ -1016,6 +1045,15 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev - struct sk_buff *skb_out; - u16 n = 0, index, ndplen; - u8 ready2send = 0; -+ u32 delayed_ndp_size; -+ -+ /* When our NDP gets written in cdc_ncm_ndp(), then skb_out->len gets updated -+ * accordingly. Otherwise, we should check here. -+ */ -+ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) -+ delayed_ndp_size = ctx->max_ndp_size; -+ else -+ delayed_ndp_size = 0; - - /* if there is a remaining skb, it gets priority */ - if (skb != NULL) { -@@ -1070,7 +1108,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev - cdc_ncm_align_tail(skb_out, ctx->tx_modulus, ctx->tx_remainder, ctx->tx_max); - - /* check if we had enough room left for both NDP and frame */ -- if (!ndp16 || skb_out->len + skb->len > ctx->tx_max) { -+ if (!ndp16 || skb_out->len + skb->len + delayed_ndp_size > ctx->tx_max) { - if (n == 0) { - /* won't fit, MTU problem? */ - dev_kfree_skb_any(skb); -@@ -1143,6 +1181,17 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev - /* variables will be reset at next call */ - } - -+ /* If requested, put NDP at end of frame. */ -+ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { -+ nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; -+ cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_max); -+ nth16->wNdpIndex = cpu_to_le16(skb_out->len); -+ memcpy(skb_put(skb_out, ctx->max_ndp_size), ctx->delayed_ndp16, ctx->max_ndp_size); -+ -+ /* Zero out delayed NDP - signature checking will naturally fail. */ -+ ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); -+ } -+ - /* If collected data size is less or equal ctx->min_tx_pkt - * bytes, we send buffers as it is. If we get more data, it - * would be more efficient for USB HS mobile device with DMA ---- a/drivers/net/usb/huawei_cdc_ncm.c -+++ b/drivers/net/usb/huawei_cdc_ncm.c -@@ -73,11 +73,14 @@ static int huawei_cdc_ncm_bind(struct us - struct usb_driver *subdriver = ERR_PTR(-ENODEV); - int ret = -ENODEV; - struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; -+ int drvflags = 0; - - /* altsetting should always be 1 for NCM devices - so we hard-coded -- * it here -+ * it here. Some huawei devices will need the NDP part of the NCM package to -+ * be at the end of the frame. - */ -- ret = cdc_ncm_bind_common(usbnet_dev, intf, 1); -+ drvflags |= CDC_NCM_FLAG_NDP_TO_END; -+ ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags); - if (ret) - goto err; - ---- a/include/linux/usb/cdc_ncm.h -+++ b/include/linux/usb/cdc_ncm.h -@@ -80,6 +80,9 @@ - #define CDC_NCM_TIMER_INTERVAL_MIN 5UL - #define CDC_NCM_TIMER_INTERVAL_MAX (U32_MAX / NSEC_PER_USEC) - -+/* Driver flags */ -+#define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */ -+ - #define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \ - (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) - #define cdc_ncm_data_intf_is_mbim(x) ((x)->desc.bInterfaceProtocol == USB_CDC_MBIM_PROTO_NTB) -@@ -103,9 +106,11 @@ struct cdc_ncm_ctx { - - spinlock_t mtx; - atomic_t stop; -+ int drvflags; - - u32 timer_interval; - u32 max_ndp_size; -+ struct usb_cdc_ncm_ndp16 *delayed_ndp16; - - u32 tx_timer_pending; - u32 tx_curr_frame_num; -@@ -133,7 +138,7 @@ struct cdc_ncm_ctx { - }; - - u8 cdc_ncm_select_altsetting(struct usb_interface *intf); --int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); -+int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags); - void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); - struct sk_buff *cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign); - int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in); diff --git a/target/linux/generic/pending-3.18/192-USB-qcserial-Add-support-for-Quectel-EC20-Mini-PCIe-.patch b/target/linux/generic/pending-3.18/192-USB-qcserial-Add-support-for-Quectel-EC20-Mini-PCIe-.patch deleted file mode 100644 index 02133e4b5e..0000000000 --- a/target/linux/generic/pending-3.18/192-USB-qcserial-Add-support-for-Quectel-EC20-Mini-PCIe-.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 128524b9db3e4f4245226852bee771bd03db75be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz> -Date: Tue, 3 Nov 2015 11:01:42 +0100 -Subject: [PATCH 1/2] USB: qcserial: Add support for Quectel EC20 Mini PCIe - module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It seems like this device has same vendor and product IDs as G2K -devices, but it has different number of interfaces(4 vs 5) and also -different interface layout which makes it currently unusable: - - usbcore: registered new interface driver qcserial - usbserial: USB Serial support registered for Qualcomm USB modem - usb 2-1.2: unknown number of interfaces: 5 - -lsusb output: - - Bus 002 Device 003: ID 05c6:9215 Qualcomm, Inc. Acer Gobi 2000 Wireless - Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x05c6 Qualcomm, Inc. - idProduct 0x9215 Acer Gobi 2000 Wireless Modem - bcdDevice 2.32 - iManufacturer 1 Quectel - iProduct 2 Quectel LTE Module - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 209 - bNumInterfaces 5 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xa0 - (Bus Powered) - Remote Wakeup - MaxPower 500mA - -Signed-off-by: Petr Å tetiar <ynezz@true.cz> ---- - drivers/usb/serial/qcserial.c | 39 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - ---- a/drivers/usb/serial/qcserial.c -+++ b/drivers/usb/serial/qcserial.c -@@ -22,6 +22,8 @@ - #define DRIVER_AUTHOR "Qualcomm Inc" - #define DRIVER_DESC "Qualcomm USB Serial driver" - -+#define QUECTEL_EC20_IDPRODUCT 0x9215 -+ - /* standard device layouts supported by this driver */ - enum qcserial_layouts { - QCSERIAL_G2K = 0, /* Gobi 2000 */ -@@ -181,6 +183,38 @@ static const struct usb_device_id id_tab - }; - MODULE_DEVICE_TABLE(usb, id_table); - -+static int handle_quectel_ec20(struct device *dev, int ifnum) -+{ -+ int altsetting = 0; -+ -+ /* -+ * Quectel EC20 Mini PCIe LTE module layout: -+ * 0: DM/DIAG (use libqcdm from ModemManager for communication) -+ * 1: NMEA -+ * 2: AT-capable modem port -+ * 3: Modem interface -+ * 4: NDIS -+ */ -+ switch (ifnum) { -+ case 0: -+ dev_dbg(dev, "Quectel EC20 DM/DIAG interface found\n"); -+ break; -+ case 1: -+ dev_dbg(dev, "Quectel EC20 NMEA GPS interface found\n"); -+ break; -+ case 2: -+ case 3: -+ dev_dbg(dev, "Quectel EC20 Modem port found\n"); -+ break; -+ case 4: -+ /* Don't claim the QMI/net interface */ -+ altsetting = -1; -+ break; -+ } -+ -+ return altsetting; -+} -+ - static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) - { - struct usb_host_interface *intf = serial->interface->cur_altsetting; -@@ -253,6 +287,11 @@ static int qcprobe(struct usb_serial *se - altsetting = -1; - break; - case QCSERIAL_G2K: -+ if (nintf == 5 && id->idProduct == QUECTEL_EC20_IDPRODUCT) { -+ altsetting = handle_quectel_ec20(dev, ifnum); -+ goto done; -+ } -+ - /* - * Gobi 2K+ USB layout: - * 0: QMI/net diff --git a/target/linux/generic/pending-3.18/193-USB-qmi_wwan-Add-quirk-for-Quectel-EC20-Mini-PCIe-mo.patch b/target/linux/generic/pending-3.18/193-USB-qmi_wwan-Add-quirk-for-Quectel-EC20-Mini-PCIe-mo.patch deleted file mode 100644 index ae3533db19..0000000000 --- a/target/linux/generic/pending-3.18/193-USB-qmi_wwan-Add-quirk-for-Quectel-EC20-Mini-PCIe-mo.patch +++ /dev/null @@ -1,91 +0,0 @@ -From fe29727caa7fe434fcb3166df2a62672bc516b54 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz> -Date: Wed, 4 Nov 2015 16:23:37 +0100 -Subject: [PATCH 2/2] USB: qmi_wwan: Add quirk for Quectel EC20 Mini PCIe - module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This device has same vendor and product IDs as G2K devices, but it has -different number of interfaces(4 vs 5) and also different interface -layout where EC20 has QMI on interface 4 instead of 0. - -lsusb output: - - Bus 002 Device 003: ID 05c6:9215 Qualcomm, Inc. Acer Gobi 2000 - Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x05c6 Qualcomm, Inc. - idProduct 0x9215 Acer Gobi 2000 Wireless Modem - bcdDevice 2.32 - iManufacturer 1 Quectel - iProduct 2 Quectel LTE Module - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 209 - bNumInterfaces 5 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xa0 - (Bus Powered) - Remote Wakeup - MaxPower 500mA - -Signed-off-by: Petr Å tetiar <ynezz@true.cz> ---- - drivers/net/usb/qmi_wwan.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -836,6 +836,7 @@ static const struct usb_device_id produc - {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ - {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ - {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ -+ {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */ - {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ - {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ - {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ -@@ -867,6 +868,19 @@ static const struct usb_device_id produc - }; - MODULE_DEVICE_TABLE(usb, products); - -+static bool quectel_ec20_detected(struct usb_interface *intf) -+{ -+ struct usb_device *dev = interface_to_usbdev(intf); -+ -+ if (dev->actconfig && -+ le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 && -+ le16_to_cpu(dev->descriptor.idProduct) == 0x9215 && -+ dev->actconfig->desc.bNumInterfaces == 5) -+ return true; -+ -+ return false; -+} -+ - static int qmi_wwan_probe(struct usb_interface *intf, - const struct usb_device_id *prod) - { -@@ -895,6 +909,12 @@ static int qmi_wwan_probe(struct usb_int - return -ENODEV; - } - -+ /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ -+ if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { -+ dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); -+ return -ENODEV; -+ } -+ - return usbnet_probe(intf, id); - } - diff --git a/target/linux/generic/pending-3.18/200-fix_localversion.patch b/target/linux/generic/pending-3.18/200-fix_localversion.patch deleted file mode 100644 index 70228bb5f4..0000000000 --- a/target/linux/generic/pending-3.18/200-fix_localversion.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/scripts/setlocalversion -+++ b/scripts/setlocalversion -@@ -165,7 +165,7 @@ else - # annotated or signed tagged state (as git describe only - # looks at signed or annotated tags - git tag -a/-s) and - # LOCALVERSION= is not specified -- if test "${LOCALVERSION+set}" != "set"; then -+ if test "${CONFIG_LOCALVERSION+set}" != "set"; then - scm=$(scm_version --short) - res="$res${scm:++}" - fi diff --git a/target/linux/generic/pending-3.18/201-extra_optimization.patch b/target/linux/generic/pending-3.18/201-extra_optimization.patch deleted file mode 100644 index 5a2396cfa3..0000000000 --- a/target/linux/generic/pending-3.18/201-extra_optimization.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -618,9 +618,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-P - KBUILD_AFLAGS += $(call cc-option,-fno-PIE) - - ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE --KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) -+KBUILD_CFLAGS += -Os $(EXTRA_OPTIMIZATION) $(call cc-disable-warning,maybe-uninitialized,) - else --KBUILD_CFLAGS += -O2 -+KBUILD_CFLAGS += -O2 -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION) - endif - - # Tell gcc to never replace conditional load with a non-conditional one diff --git a/target/linux/generic/pending-3.18/202-reduce_module_size.patch b/target/linux/generic/pending-3.18/202-reduce_module_size.patch deleted file mode 100644 index 60ea5c2085..0000000000 --- a/target/linux/generic/pending-3.18/202-reduce_module_size.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -408,7 +408,7 @@ KBUILD_CFLAGS_KERNEL := - KBUILD_AFLAGS := -D__ASSEMBLY__ - KBUILD_AFLAGS_MODULE := -DMODULE - KBUILD_CFLAGS_MODULE := -DMODULE --KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds -+KBUILD_LDFLAGS_MODULE = -T $(srctree)/scripts/module-common.lds $(if $(CONFIG_PROFILING),,-s) - - # Read KERNELRELEASE from include/config/kernel.release (if it exists) - KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) diff --git a/target/linux/generic/pending-3.18/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-3.18/203-kallsyms_uncompressed.patch deleted file mode 100644 index b9d82207a0..0000000000 --- a/target/linux/generic/pending-3.18/203-kallsyms_uncompressed.patch +++ /dev/null @@ -1,108 +0,0 @@ ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -58,6 +58,7 @@ static struct addr_range percpu_range = - static struct sym_entry *table; - static unsigned int table_size, table_cnt; - static int all_symbols = 0; -+static int uncompressed = 0; - static int absolute_percpu = 0; - static char symbol_prefix_char = '\0'; - static unsigned long long kernel_start_addr = 0; -@@ -392,6 +393,9 @@ static void write_src(void) - - free(markers); - -+ if (uncompressed) -+ return; -+ - output_label("kallsyms_token_table"); - off = 0; - for (i = 0; i < 256; i++) { -@@ -450,6 +454,9 @@ static void *find_token(unsigned char *s - { - int i; - -+ if (uncompressed) -+ return NULL; -+ - for (i = 0; i < len - 1; i++) { - if (str[i] == token[0] && str[i+1] == token[1]) - return &str[i]; -@@ -522,6 +529,9 @@ static void optimize_result(void) - { - int i, best; - -+ if (uncompressed) -+ return; -+ - /* using the '\0' symbol last allows compress_symbols to use standard - * fast string functions */ - for (i = 255; i >= 0; i--) { -@@ -692,7 +702,9 @@ int main(int argc, char **argv) - } else if (strncmp(argv[i], "--page-offset=", 14) == 0) { - const char *p = &argv[i][14]; - kernel_start_addr = strtoull(p, NULL, 16); -- } else -+ } else if (strcmp(argv[i], "--uncompressed") == 0) -+ uncompressed = 1; -+ else - usage(); - } - } else if (argc != 1) ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1338,6 +1338,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW - the unaligned access emulation. - see arch/parisc/kernel/unaligned.c for reference - -+config KALLSYMS_UNCOMPRESSED -+ bool "Keep kallsyms uncompressed" -+ depends on KALLSYMS -+ help -+ Normally kallsyms contains compressed symbols (using a token table), -+ reducing the uncompressed kernel image size. Keeping the symbol table -+ uncompressed significantly improves the size of this part in compressed -+ kernel images. -+ -+ Say N unless you need compressed kernel images to be small. -+ - config HAVE_PCSPKR_PLATFORM - bool - ---- a/scripts/link-vmlinux.sh -+++ b/scripts/link-vmlinux.sh -@@ -90,6 +90,10 @@ kallsyms() - kallsymopt="${kallsymopt} --absolute-percpu" - fi - -+ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then -+ kallsymopt="${kallsymopt} --uncompressed" -+ fi -+ - local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ - ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" - ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -109,6 +109,11 @@ static unsigned int kallsyms_expand_symb - * For every byte on the compressed symbol data, copy the table - * entry for that byte. - */ -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ memcpy(result, data + 1, len - 1); -+ result += len - 1; -+ len = 0; -+#endif - while (len) { - tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; - data++; -@@ -141,6 +146,9 @@ tail: - */ - static char kallsyms_get_symbol_type(unsigned int off) - { -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ return kallsyms_names[off + 1]; -+#endif - /* - * Get just the first code, look it up in the token table, - * and return the first char from this token. diff --git a/target/linux/generic/pending-3.18/204-module_strip.patch b/target/linux/generic/pending-3.18/204-module_strip.patch deleted file mode 100644 index dcad148792..0000000000 --- a/target/linux/generic/pending-3.18/204-module_strip.patch +++ /dev/null @@ -1,190 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Subject: [PATCH] build: add a hack for removing non-essential module info - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -84,6 +84,7 @@ void trim_init_extable(struct module *m) - - /* Generic info of form tag = "info" */ - #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) -+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) - - /* For userspace: you can also call me... */ - #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -@@ -127,12 +128,12 @@ void trim_init_extable(struct module *m) - * Author(s), use "Name <email>" or just "Name", for multiple - * authors use multiple MODULE_AUTHOR() statements/lines. - */ --#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) -+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) - - /* What your module does. */ --#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) - --#ifdef MODULE -+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) - /* Creates an alias so file2alias.c can find device table. */ - #define MODULE_DEVICE_TABLE(type, name) \ - extern const typeof(name) __mod_##type##__##name##_device_table \ -@@ -159,7 +160,9 @@ extern const typeof(name) __mod_##type## - */ - - #if defined(MODULE) || !defined(CONFIG_SYSFS) --#define MODULE_VERSION(_version) MODULE_INFO(version, _version) -+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) -+#elif defined(CONFIG_MODULE_STRIPPED) -+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) - #else - #define MODULE_VERSION(_version) \ - static struct module_version_attribute ___modver_attr = { \ -@@ -181,7 +184,7 @@ extern const typeof(name) __mod_##type## - /* Optional firmware file (or files) needed by the module - * format is simply firmware file name. Multiple firmware - * files require multiple MODULE_FIRMWARE() specifiers */ --#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) - - /* Given an address, look for it in the exception tables */ - const struct exception_table_entry *search_exception_tables(unsigned long add); ---- a/include/linux/moduleparam.h -+++ b/include/linux/moduleparam.h -@@ -16,6 +16,16 @@ - /* Chosen so that structs with an unsigned long line up. */ - #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) - -+/* This struct is here for syntactic coherency, it is not used */ -+#define __MODULE_INFO_DISABLED(name) \ -+ struct __UNIQUE_ID(name) {} -+ -+#ifdef CONFIG_MODULE_STRIPPED -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) -+#else -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) -+#endif -+ - #ifdef MODULE - #define __MODULE_INFO(tag, name, info) \ - static const char __UNIQUE_ID(name)[] \ -@@ -23,8 +33,7 @@ static const char __UNIQUE_ID(name)[] - = __stringify(tag) "=" info - #else /* !MODULE */ - /* This struct is here for syntactic coherency, it is not used */ --#define __MODULE_INFO(tag, name, info) \ -- struct __UNIQUE_ID(name) {} -+#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name) - #endif - #define __MODULE_PARM_TYPE(name, _type) \ - __MODULE_INFO(parmtype, name##type, #name ":" _type) -@@ -32,7 +41,7 @@ static const char __UNIQUE_ID(name)[] - /* One for each parameter, describing how to use it. Some files do - multiple of these per line, so can't just use MODULE_INFO. */ - #define MODULE_PARM_DESC(_parm, desc) \ -- __MODULE_INFO(parm, _parm, #_parm ":" desc) -+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) - - struct kernel_param; - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1987,6 +1987,13 @@ config MODULE_COMPRESS_XZ - - endchoice - -+config MODULE_STRIPPED -+ bool "Reduce module size" -+ depends on MODULES -+ help -+ Remove module parameter descriptions, author info, version, aliases, -+ device tables, etc. -+ - endif # MODULES - - config INIT_ALL_POSSIBLE ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -2699,6 +2699,7 @@ static struct module *setup_load_info(st - - static int check_modinfo(struct module *mod, struct load_info *info, int flags) - { -+#ifndef CONFIG_MODULE_STRIPPED - const char *modmagic = get_modinfo(info, "vermagic"); - int err; - -@@ -2724,6 +2725,7 @@ static int check_modinfo(struct module * - pr_warn("%s: module is from the staging directory, the quality " - "is unknown, you have been warned.\n", mod->name); - } -+#endif - - /* Set up license info based on the info section */ - set_license(mod, get_modinfo(info, "license")); ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -1760,7 +1760,9 @@ static void read_symbols(char *modname) - symname = remove_dot(info.strtab + sym->st_name); - - handle_modversions(mod, &info, sym, symname); -+#ifndef CONFIG_MODULE_STRIPPED - handle_moddevtable(mod, &info, sym, symname); -+#endif - } - if (!is_vmlinux(modname) || - (is_vmlinux(modname) && vmlinux_section_warnings)) -@@ -1904,7 +1906,9 @@ static void add_header(struct buffer *b, - buf_printf(b, "#include <linux/vermagic.h>\n"); - buf_printf(b, "#include <linux/compiler.h>\n"); - buf_printf(b, "\n"); -+#ifndef CONFIG_MODULE_STRIPPED - buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); -+#endif - buf_printf(b, "\n"); - buf_printf(b, "__visible struct module __this_module\n"); - buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); -@@ -1921,16 +1925,20 @@ static void add_header(struct buffer *b, - - static void add_intree_flag(struct buffer *b, int is_intree) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (is_intree) - buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); -+#endif - } - - static void add_staging_flag(struct buffer *b, const char *name) - { -+#ifndef CONFIG_MODULE_STRIPPED - static const char *staging_dir = "drivers/staging"; - - if (strncmp(staging_dir, name, strlen(staging_dir)) == 0) - buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); -+#endif - } - - /** -@@ -2023,11 +2031,13 @@ static void add_depends(struct buffer *b - - static void add_srcversion(struct buffer *b, struct module *mod) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (mod->srcversion[0]) { - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", - mod->srcversion); - } -+#endif - } - - static void write_if_changed(struct buffer *b, const char *fname) -@@ -2258,7 +2268,9 @@ int main(int argc, char **argv) - add_staging_flag(&buf, mod->name); - err |= add_versions(&buf, mod); - add_depends(&buf, mod, modules); -+#ifndef CONFIG_MODULE_STRIPPED - add_moddevtable(&buf, mod); -+#endif - add_srcversion(&buf, mod); - - sprintf(fname, "%s.mod.c", mod->name); diff --git a/target/linux/generic/pending-3.18/205-backtrace_module_info.patch b/target/linux/generic/pending-3.18/205-backtrace_module_info.patch deleted file mode 100644 index f83b21ebc8..0000000000 --- a/target/linux/generic/pending-3.18/205-backtrace_module_info.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -614,8 +614,10 @@ char *symbol_string(char *buf, char *end - struct printf_spec spec, const char *fmt) - { - unsigned long value; --#ifdef CONFIG_KALLSYMS - char sym[KSYM_SYMBOL_LEN]; -+#ifndef CONFIG_KALLSYMS -+ struct module *mod; -+ int len; - #endif - - if (fmt[1] == 'R') -@@ -629,15 +631,15 @@ char *symbol_string(char *buf, char *end - sprint_symbol(sym, value); - else - sprint_symbol_no_offset(sym, value); -- -- return string(buf, end, sym, spec); - #else -- spec.field_width = 2 * sizeof(void *); -- spec.flags |= SPECIAL | SMALL | ZEROPAD; -- spec.base = 16; -+ len = snprintf(sym, sizeof(sym), "0x%lx", value); - -- return number(buf, end, value, spec); -+ mod = __module_address(value); -+ if (mod) -+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", -+ mod->name, mod->module_core, mod->core_size); - #endif -+ return string(buf, end, sym, spec); - } - - static noinline_for_stack diff --git a/target/linux/generic/pending-3.18/210-darwin_scripts_include.patch b/target/linux/generic/pending-3.18/210-darwin_scripts_include.patch deleted file mode 100644 index dc554de247..0000000000 --- a/target/linux/generic/pending-3.18/210-darwin_scripts_include.patch +++ /dev/null @@ -1,3088 +0,0 @@ ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -22,6 +22,35 @@ - #include <stdlib.h> - #include <string.h> - #include <ctype.h> -+#ifdef __APPLE__ -+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */ -+void *memmem (const void *haystack, size_t haystack_len, -+ const void *needle, size_t needle_len) -+{ -+ const char *begin; -+ const char *const last_possible -+ = (const char *) haystack + haystack_len - needle_len; -+ -+ if (needle_len == 0) -+ /* The first occurrence of the empty string is deemed to occur at -+ the beginning of the string. */ -+ return (void *) haystack; -+ -+ /* Sanity check, otherwise the loop might search through the whole -+ memory. */ -+ if (__builtin_expect (haystack_len < needle_len, 0)) -+ return NULL; -+ -+ for (begin = (const char *) haystack; begin <= last_possible; ++begin) -+ if (begin[0] == ((const char *) needle)[0] && -+ !memcmp ((const void *) &begin[1], -+ (const void *) ((const char *) needle + 1), -+ needle_len - 1)) -+ return (void *) begin; -+ -+ return NULL; -+} -+#endif - - #ifndef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) ---- a/scripts/kconfig/Makefile -+++ b/scripts/kconfig/Makefile -@@ -151,6 +151,9 @@ check-lxdialog := $(srctree)/$(src)/lxd - # we really need to do so. (Do not call gcc as part of make mrproper) - HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ - -DLOCALE -+ifeq ($(shell uname -s),Darwin) -+HOST_LOADLIBES += -lncurses -+endif - - # =========================================================================== - # Shared Makefile for the various kconfig executables: ---- a/scripts/mod/mk_elfconfig.c -+++ b/scripts/mod/mk_elfconfig.c -@@ -1,7 +1,11 @@ - #include <stdio.h> - #include <stdlib.h> - #include <string.h> -+#ifndef __APPLE__ - #include <elf.h> -+#else -+#include "elf.h" -+#endif - - int - main(int argc, char **argv) ---- a/scripts/mod/modpost.h -+++ b/scripts/mod/modpost.h -@@ -7,7 +7,11 @@ - #include <sys/mman.h> - #include <fcntl.h> - #include <unistd.h> -+#if !(defined(__APPLE__) || defined(__CYGWIN__)) - #include <elf.h> -+#else -+#include "elf.h" -+#endif - - #include "elfconfig.h" - ---- /dev/null -+++ b/scripts/mod/elf.h -@@ -0,0 +1,3007 @@ -+/* This file defines standard ELF types, structures, and macros. -+ Copyright (C) 1995-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ <http://www.gnu.org/licenses/>. */ -+ -+#ifndef _ELF_H -+#define _ELF_H 1 -+ -+/* Standard ELF types. */ -+ -+#include <stdint.h> -+ -+/* Type for a 16-bit quantity. */ -+typedef uint16_t Elf32_Half; -+typedef uint16_t Elf64_Half; -+ -+/* Types for signed and unsigned 32-bit quantities. */ -+typedef uint32_t Elf32_Word; -+typedef int32_t Elf32_Sword; -+typedef uint32_t Elf64_Word; -+typedef int32_t Elf64_Sword; -+ -+/* Types for signed and unsigned 64-bit quantities. */ -+typedef uint64_t Elf32_Xword; -+typedef int64_t Elf32_Sxword; -+typedef uint64_t Elf64_Xword; -+typedef int64_t Elf64_Sxword; -+ -+/* Type of addresses. */ -+typedef uint32_t Elf32_Addr; -+typedef uint64_t Elf64_Addr; -+ -+/* Type of file offsets. */ -+typedef uint32_t Elf32_Off; -+typedef uint64_t Elf64_Off; -+ -+/* Type for section indices, which are 16-bit quantities. */ -+typedef uint16_t Elf32_Section; -+typedef uint16_t Elf64_Section; -+ -+/* Type for version symbol information. */ -+typedef Elf32_Half Elf32_Versym; -+typedef Elf64_Half Elf64_Versym; -+ -+ -+/* The ELF file header. This appears at the start of every ELF file. */ -+ -+#define EI_NIDENT (16) -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf32_Half e_type; /* Object file type */ -+ Elf32_Half e_machine; /* Architecture */ -+ Elf32_Word e_version; /* Object file version */ -+ Elf32_Addr e_entry; /* Entry point virtual address */ -+ Elf32_Off e_phoff; /* Program header table file offset */ -+ Elf32_Off e_shoff; /* Section header table file offset */ -+ Elf32_Word e_flags; /* Processor-specific flags */ -+ Elf32_Half e_ehsize; /* ELF header size in bytes */ -+ Elf32_Half e_phentsize; /* Program header table entry size */ -+ Elf32_Half e_phnum; /* Program header table entry count */ -+ Elf32_Half e_shentsize; /* Section header table entry size */ -+ Elf32_Half e_shnum; /* Section header table entry count */ -+ Elf32_Half e_shstrndx; /* Section header string table index */ -+} Elf32_Ehdr; -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf64_Half e_type; /* Object file type */ -+ Elf64_Half e_machine; /* Architecture */ -+ Elf64_Word e_version; /* Object file version */ -+ Elf64_Addr e_entry; /* Entry point virtual address */ -+ Elf64_Off e_phoff; /* Program header table file offset */ -+ Elf64_Off e_shoff; /* Section header table file offset */ -+ Elf64_Word e_flags; /* Processor-specific flags */ -+ Elf64_Half e_ehsize; /* ELF header size in bytes */ -+ Elf64_Half e_phentsize; /* Program header table entry size */ -+ Elf64_Half e_phnum; /* Program header table entry count */ -+ Elf64_Half e_shentsize; /* Section header table entry size */ -+ Elf64_Half e_shnum; /* Section header table entry count */ -+ Elf64_Half e_shstrndx; /* Section header string table index */ -+} Elf64_Ehdr; -+ -+/* Fields in the e_ident array. The EI_* macros are indices into the -+ array. The macros under each EI_* macro are the values the byte -+ may have. */ -+ -+#define EI_MAG0 0 /* File identification byte 0 index */ -+#define ELFMAG0 0x7f /* Magic number byte 0 */ -+ -+#define EI_MAG1 1 /* File identification byte 1 index */ -+#define ELFMAG1 'E' /* Magic number byte 1 */ -+ -+#define EI_MAG2 2 /* File identification byte 2 index */ -+#define ELFMAG2 'L' /* Magic number byte 2 */ -+ -+#define EI_MAG3 3 /* File identification byte 3 index */ -+#define ELFMAG3 'F' /* Magic number byte 3 */ -+ -+/* Conglomeration of the identification bytes, for easy testing as a word. */ -+#define ELFMAG "\177ELF" -+#define SELFMAG 4 -+ -+#define EI_CLASS 4 /* File class byte index */ -+#define ELFCLASSNONE 0 /* Invalid class */ -+#define ELFCLASS32 1 /* 32-bit objects */ -+#define ELFCLASS64 2 /* 64-bit objects */ -+#define ELFCLASSNUM 3 -+ -+#define EI_DATA 5 /* Data encoding byte index */ -+#define ELFDATANONE 0 /* Invalid data encoding */ -+#define ELFDATA2LSB 1 /* 2's complement, little endian */ -+#define ELFDATA2MSB 2 /* 2's complement, big endian */ -+#define ELFDATANUM 3 -+ -+#define EI_VERSION 6 /* File version byte index */ -+ /* Value must be EV_CURRENT */ -+ -+#define EI_OSABI 7 /* OS ABI identification */ -+#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -+#define ELFOSABI_SYSV 0 /* Alias. */ -+#define ELFOSABI_HPUX 1 /* HP-UX */ -+#define ELFOSABI_NETBSD 2 /* NetBSD. */ -+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -+#define ELFOSABI_AIX 7 /* IBM AIX. */ -+#define ELFOSABI_IRIX 8 /* SGI Irix. */ -+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -+#define ELFOSABI_ARM 97 /* ARM */ -+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -+ -+#define EI_ABIVERSION 8 /* ABI version */ -+ -+#define EI_PAD 9 /* Byte index of padding bytes */ -+ -+/* Legal values for e_type (object file type). */ -+ -+#define ET_NONE 0 /* No file type */ -+#define ET_REL 1 /* Relocatable file */ -+#define ET_EXEC 2 /* Executable file */ -+#define ET_DYN 3 /* Shared object file */ -+#define ET_CORE 4 /* Core file */ -+#define ET_NUM 5 /* Number of defined types */ -+#define ET_LOOS 0xfe00 /* OS-specific range start */ -+#define ET_HIOS 0xfeff /* OS-specific range end */ -+#define ET_LOPROC 0xff00 /* Processor-specific range start */ -+#define ET_HIPROC 0xffff /* Processor-specific range end */ -+ -+/* Legal values for e_machine (architecture). */ -+ -+#define EM_NONE 0 /* No machine */ -+#define EM_M32 1 /* AT&T WE 32100 */ -+#define EM_SPARC 2 /* SUN SPARC */ -+#define EM_386 3 /* Intel 80386 */ -+#define EM_68K 4 /* Motorola m68k family */ -+#define EM_88K 5 /* Motorola m88k family */ -+#define EM_860 7 /* Intel 80860 */ -+#define EM_MIPS 8 /* MIPS R3000 big-endian */ -+#define EM_S370 9 /* IBM System/370 */ -+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -+ -+#define EM_PARISC 15 /* HPPA */ -+#define EM_VPP500 17 /* Fujitsu VPP500 */ -+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -+#define EM_960 19 /* Intel 80960 */ -+#define EM_PPC 20 /* PowerPC */ -+#define EM_PPC64 21 /* PowerPC 64-bit */ -+#define EM_S390 22 /* IBM S390 */ -+ -+#define EM_V800 36 /* NEC V800 series */ -+#define EM_FR20 37 /* Fujitsu FR20 */ -+#define EM_RH32 38 /* TRW RH-32 */ -+#define EM_RCE 39 /* Motorola RCE */ -+#define EM_ARM 40 /* ARM */ -+#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -+#define EM_SH 42 /* Hitachi SH */ -+#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -+#define EM_TRICORE 44 /* Siemens Tricore */ -+#define EM_ARC 45 /* Argonaut RISC Core */ -+#define EM_H8_300 46 /* Hitachi H8/300 */ -+#define EM_H8_300H 47 /* Hitachi H8/300H */ -+#define EM_H8S 48 /* Hitachi H8S */ -+#define EM_H8_500 49 /* Hitachi H8/500 */ -+#define EM_IA_64 50 /* Intel Merced */ -+#define EM_MIPS_X 51 /* Stanford MIPS-X */ -+#define EM_COLDFIRE 52 /* Motorola Coldfire */ -+#define EM_68HC12 53 /* Motorola M68HC12 */ -+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -+#define EM_PCP 55 /* Siemens PCP */ -+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -+#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -+#define EM_STARCORE 58 /* Motorola Start*Core processor */ -+#define EM_ME16 59 /* Toyota ME16 processor */ -+#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -+#define EM_X86_64 62 /* AMD x86-64 architecture */ -+#define EM_PDSP 63 /* Sony DSP Processor */ -+ -+#define EM_FX66 66 /* Siemens FX66 microcontroller */ -+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -+#define EM_SVX 73 /* Silicon Graphics SVx */ -+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -+#define EM_VAX 75 /* Digital VAX */ -+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -+#define EM_HUANY 81 /* Harvard University machine-independent object files */ -+#define EM_PRISM 82 /* SiTera Prism */ -+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -+#define EM_FR30 84 /* Fujitsu FR30 */ -+#define EM_D10V 85 /* Mitsubishi D10V */ -+#define EM_D30V 86 /* Mitsubishi D30V */ -+#define EM_V850 87 /* NEC v850 */ -+#define EM_M32R 88 /* Mitsubishi M32R */ -+#define EM_MN10300 89 /* Matsushita MN10300 */ -+#define EM_MN10200 90 /* Matsushita MN10200 */ -+#define EM_PJ 91 /* picoJava */ -+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -+#define EM_TILEPRO 188 /* Tilera TILEPro */ -+#define EM_TILEGX 191 /* Tilera TILE-Gx */ -+#define EM_NUM 192 -+ -+/* If it is necessary to assign new unofficial EM_* values, please -+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -+ chances of collision with official or non-GNU unofficial values. */ -+ -+#define EM_ALPHA 0x9026 -+ -+/* Legal values for e_version (version). */ -+ -+#define EV_NONE 0 /* Invalid ELF version */ -+#define EV_CURRENT 1 /* Current version */ -+#define EV_NUM 2 -+ -+/* Section header. */ -+ -+typedef struct -+{ -+ Elf32_Word sh_name; /* Section name (string tbl index) */ -+ Elf32_Word sh_type; /* Section type */ -+ Elf32_Word sh_flags; /* Section flags */ -+ Elf32_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf32_Off sh_offset; /* Section file offset */ -+ Elf32_Word sh_size; /* Section size in bytes */ -+ Elf32_Word sh_link; /* Link to another section */ -+ Elf32_Word sh_info; /* Additional section information */ -+ Elf32_Word sh_addralign; /* Section alignment */ -+ Elf32_Word sh_entsize; /* Entry size if section holds table */ -+} Elf32_Shdr; -+ -+typedef struct -+{ -+ Elf64_Word sh_name; /* Section name (string tbl index) */ -+ Elf64_Word sh_type; /* Section type */ -+ Elf64_Xword sh_flags; /* Section flags */ -+ Elf64_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf64_Off sh_offset; /* Section file offset */ -+ Elf64_Xword sh_size; /* Section size in bytes */ -+ Elf64_Word sh_link; /* Link to another section */ -+ Elf64_Word sh_info; /* Additional section information */ -+ Elf64_Xword sh_addralign; /* Section alignment */ -+ Elf64_Xword sh_entsize; /* Entry size if section holds table */ -+} Elf64_Shdr; -+ -+/* Special section indices. */ -+ -+#define SHN_UNDEF 0 /* Undefined section */ -+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -+#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -+#define SHN_BEFORE 0xff00 /* Order section before all others -+ (Solaris). */ -+#define SHN_AFTER 0xff01 /* Order section after all others -+ (Solaris). */ -+#define SHN_HIPROC 0xff1f /* End of processor-specific */ -+#define SHN_LOOS 0xff20 /* Start of OS-specific */ -+#define SHN_HIOS 0xff3f /* End of OS-specific */ -+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -+#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -+#define SHN_XINDEX 0xffff /* Index is in extra table. */ -+#define SHN_HIRESERVE 0xffff /* End of reserved indices */ -+ -+/* Legal values for sh_type (section type). */ -+ -+#define SHT_NULL 0 /* Section header table entry unused */ -+#define SHT_PROGBITS 1 /* Program data */ -+#define SHT_SYMTAB 2 /* Symbol table */ -+#define SHT_STRTAB 3 /* String table */ -+#define SHT_RELA 4 /* Relocation entries with addends */ -+#define SHT_HASH 5 /* Symbol hash table */ -+#define SHT_DYNAMIC 6 /* Dynamic linking information */ -+#define SHT_NOTE 7 /* Notes */ -+#define SHT_NOBITS 8 /* Program space with no data (bss) */ -+#define SHT_REL 9 /* Relocation entries, no addends */ -+#define SHT_SHLIB 10 /* Reserved */ -+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -+#define SHT_INIT_ARRAY 14 /* Array of constructors */ -+#define SHT_FINI_ARRAY 15 /* Array of destructors */ -+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -+#define SHT_GROUP 17 /* Section group */ -+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -+#define SHT_NUM 19 /* Number of defined types. */ -+#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -+#define SHT_SUNW_move 0x6ffffffa -+#define SHT_SUNW_COMDAT 0x6ffffffb -+#define SHT_SUNW_syminfo 0x6ffffffc -+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -+#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -+#define SHT_HIUSER 0x8fffffff /* End of application-specific */ -+ -+/* Legal values for sh_flags (section flags). */ -+ -+#define SHF_WRITE (1 << 0) /* Writable */ -+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -+#define SHF_EXECINSTR (1 << 2) /* Executable */ -+#define SHF_MERGE (1 << 4) /* Might be merged */ -+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling -+ required */ -+#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -+#define SHF_ORDERED (1 << 30) /* Special ordering requirement -+ (Solaris). */ -+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless -+ referenced or allocated (Solaris).*/ -+ -+/* Section group handling. */ -+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ -+ -+/* Symbol table entry. */ -+ -+typedef struct -+{ -+ Elf32_Word st_name; /* Symbol name (string tbl index) */ -+ Elf32_Addr st_value; /* Symbol value */ -+ Elf32_Word st_size; /* Symbol size */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf32_Section st_shndx; /* Section index */ -+} Elf32_Sym; -+ -+typedef struct -+{ -+ Elf64_Word st_name; /* Symbol name (string tbl index) */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf64_Section st_shndx; /* Section index */ -+ Elf64_Addr st_value; /* Symbol value */ -+ Elf64_Xword st_size; /* Symbol size */ -+} Elf64_Sym; -+ -+/* The syminfo section if available contains additional information about -+ every dynamic symbol. */ -+ -+typedef struct -+{ -+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf32_Half si_flags; /* Per symbol flags */ -+} Elf32_Syminfo; -+ -+typedef struct -+{ -+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf64_Half si_flags; /* Per symbol flags */ -+} Elf64_Syminfo; -+ -+/* Possible values for si_boundto. */ -+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ -+ -+/* Possible bitmasks for si_flags. */ -+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy -+ loaded */ -+/* Syminfo version values. */ -+#define SYMINFO_NONE 0 -+#define SYMINFO_CURRENT 1 -+#define SYMINFO_NUM 2 -+ -+ -+/* How to extract and insert information held in the st_info field. */ -+ -+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -+#define ELF32_ST_TYPE(val) ((val) & 0xf) -+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -+ -+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) -+ -+/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -+ -+#define STB_LOCAL 0 /* Local symbol */ -+#define STB_GLOBAL 1 /* Global symbol */ -+#define STB_WEAK 2 /* Weak symbol */ -+#define STB_NUM 3 /* Number of defined types. */ -+#define STB_LOOS 10 /* Start of OS-specific */ -+#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -+#define STB_HIOS 12 /* End of OS-specific */ -+#define STB_LOPROC 13 /* Start of processor-specific */ -+#define STB_HIPROC 15 /* End of processor-specific */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_NOTYPE 0 /* Symbol type is unspecified */ -+#define STT_OBJECT 1 /* Symbol is a data object */ -+#define STT_FUNC 2 /* Symbol is a code object */ -+#define STT_SECTION 3 /* Symbol associated with a section */ -+#define STT_FILE 4 /* Symbol's name is file name */ -+#define STT_COMMON 5 /* Symbol is a common data object */ -+#define STT_TLS 6 /* Symbol is thread-local data object*/ -+#define STT_NUM 7 /* Number of defined types. */ -+#define STT_LOOS 10 /* Start of OS-specific */ -+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -+#define STT_HIOS 12 /* End of OS-specific */ -+#define STT_LOPROC 13 /* Start of processor-specific */ -+#define STT_HIPROC 15 /* End of processor-specific */ -+ -+ -+/* Symbol table indices are found in the hash buckets and chain table -+ of a symbol hash table section. This special index value indicates -+ the end of a chain, meaning no further symbols are found in that bucket. */ -+ -+#define STN_UNDEF 0 /* End of a chain. */ -+ -+ -+/* How to extract and insert information held in the st_other field. */ -+ -+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -+ -+/* For ELF64 the definitions are the same. */ -+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) -+ -+/* Symbol visibility specification encoded in the st_other field. */ -+#define STV_DEFAULT 0 /* Default symbol visibility rules */ -+#define STV_INTERNAL 1 /* Processor specific hidden class */ -+#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -+#define STV_PROTECTED 3 /* Not preemptible, not exported */ -+ -+ -+/* Relocation table entry without addend (in section of type SHT_REL). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+} Elf32_Rel; -+ -+/* I have seen two different definitions of the Elf64_Rel and -+ Elf64_Rela structures, so we'll leave them out until Novell (or -+ whoever) gets their act together. */ -+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+} Elf64_Rel; -+ -+/* Relocation table entry with addend (in section of type SHT_RELA). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+ Elf32_Sword r_addend; /* Addend */ -+} Elf32_Rela; -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+ Elf64_Sxword r_addend; /* Addend */ -+} Elf64_Rela; -+ -+/* How to extract and insert information held in the r_info field. */ -+ -+#define ELF32_R_SYM(val) ((val) >> 8) -+#define ELF32_R_TYPE(val) ((val) & 0xff) -+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -+ -+#define ELF64_R_SYM(i) ((i) >> 32) -+#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) -+ -+/* Program segment header. */ -+ -+typedef struct -+{ -+ Elf32_Word p_type; /* Segment type */ -+ Elf32_Off p_offset; /* Segment file offset */ -+ Elf32_Addr p_vaddr; /* Segment virtual address */ -+ Elf32_Addr p_paddr; /* Segment physical address */ -+ Elf32_Word p_filesz; /* Segment size in file */ -+ Elf32_Word p_memsz; /* Segment size in memory */ -+ Elf32_Word p_flags; /* Segment flags */ -+ Elf32_Word p_align; /* Segment alignment */ -+} Elf32_Phdr; -+ -+typedef struct -+{ -+ Elf64_Word p_type; /* Segment type */ -+ Elf64_Word p_flags; /* Segment flags */ -+ Elf64_Off p_offset; /* Segment file offset */ -+ Elf64_Addr p_vaddr; /* Segment virtual address */ -+ Elf64_Addr p_paddr; /* Segment physical address */ -+ Elf64_Xword p_filesz; /* Segment size in file */ -+ Elf64_Xword p_memsz; /* Segment size in memory */ -+ Elf64_Xword p_align; /* Segment alignment */ -+} Elf64_Phdr; -+ -+/* Special value for e_phnum. This indicates that the real number of -+ program headers is too large to fit into e_phnum. Instead the real -+ value is in the field sh_info of section 0. */ -+ -+#define PN_XNUM 0xffff -+ -+/* Legal values for p_type (segment type). */ -+ -+#define PT_NULL 0 /* Program header table entry unused */ -+#define PT_LOAD 1 /* Loadable program segment */ -+#define PT_DYNAMIC 2 /* Dynamic linking information */ -+#define PT_INTERP 3 /* Program interpreter */ -+#define PT_NOTE 4 /* Auxiliary information */ -+#define PT_SHLIB 5 /* Reserved */ -+#define PT_PHDR 6 /* Entry for header table itself */ -+#define PT_TLS 7 /* Thread-local storage segment */ -+#define PT_NUM 8 /* Number of defined types */ -+#define PT_LOOS 0x60000000 /* Start of OS-specific */ -+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -+#define PT_LOSUNW 0x6ffffffa -+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -+#define PT_HISUNW 0x6fffffff -+#define PT_HIOS 0x6fffffff /* End of OS-specific */ -+#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define PT_HIPROC 0x7fffffff /* End of processor-specific */ -+ -+/* Legal values for p_flags (segment flags). */ -+ -+#define PF_X (1 << 0) /* Segment is executable */ -+#define PF_W (1 << 1) /* Segment is writable */ -+#define PF_R (1 << 2) /* Segment is readable */ -+#define PF_MASKOS 0x0ff00000 /* OS-specific */ -+#define PF_MASKPROC 0xf0000000 /* Processor-specific */ -+ -+/* Legal values for note segment descriptor types for core files. */ -+ -+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -+#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -+#define NT_AUXV 6 /* Contains copy of auxv array */ -+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -+#define NT_ASRS 8 /* Contains copy of asrset struct */ -+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -+#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -+#define NT_PRCRED 14 /* Contains copy of prcred struct */ -+#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -+ -+/* Legal values for the note segment descriptor types for object files. */ -+ -+#define NT_VERSION 1 /* Contains a version string. */ -+ -+ -+/* Dynamic section entry. */ -+ -+typedef struct -+{ -+ Elf32_Sword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf32_Word d_val; /* Integer value */ -+ Elf32_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf32_Dyn; -+ -+typedef struct -+{ -+ Elf64_Sxword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf64_Xword d_val; /* Integer value */ -+ Elf64_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf64_Dyn; -+ -+/* Legal values for d_tag (dynamic entry type). */ -+ -+#define DT_NULL 0 /* Marks end of dynamic section */ -+#define DT_NEEDED 1 /* Name of needed library */ -+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -+#define DT_PLTGOT 3 /* Processor defined value */ -+#define DT_HASH 4 /* Address of symbol hash table */ -+#define DT_STRTAB 5 /* Address of string table */ -+#define DT_SYMTAB 6 /* Address of symbol table */ -+#define DT_RELA 7 /* Address of Rela relocs */ -+#define DT_RELASZ 8 /* Total size of Rela relocs */ -+#define DT_RELAENT 9 /* Size of one Rela reloc */ -+#define DT_STRSZ 10 /* Size of string table */ -+#define DT_SYMENT 11 /* Size of one symbol table entry */ -+#define DT_INIT 12 /* Address of init function */ -+#define DT_FINI 13 /* Address of termination function */ -+#define DT_SONAME 14 /* Name of shared object */ -+#define DT_RPATH 15 /* Library search path (deprecated) */ -+#define DT_SYMBOLIC 16 /* Start symbol search here */ -+#define DT_REL 17 /* Address of Rel relocs */ -+#define DT_RELSZ 18 /* Total size of Rel relocs */ -+#define DT_RELENT 19 /* Size of one Rel reloc */ -+#define DT_PLTREL 20 /* Type of reloc in PLT */ -+#define DT_DEBUG 21 /* For debugging; unspecified */ -+#define DT_TEXTREL 22 /* Reloc might modify .text */ -+#define DT_JMPREL 23 /* Address of PLT relocs */ -+#define DT_BIND_NOW 24 /* Process relocations of object */ -+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -+#define DT_RUNPATH 29 /* Library search path */ -+#define DT_FLAGS 30 /* Flags for the object being loaded */ -+#define DT_ENCODING 32 /* Start of encoded range */ -+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -+#define DT_NUM 34 /* Number used */ -+#define DT_LOOS 0x6000000d /* Start of OS-specific */ -+#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -+#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -+ -+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -+ approach. */ -+#define DT_VALRNGLO 0x6ffffd00 -+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -+#define DT_CHECKSUM 0x6ffffdf8 -+#define DT_PLTPADSZ 0x6ffffdf9 -+#define DT_MOVEENT 0x6ffffdfa -+#define DT_MOVESZ 0x6ffffdfb -+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting -+ the following DT_* entry. */ -+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -+#define DT_VALRNGHI 0x6ffffdff -+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -+#define DT_VALNUM 12 -+ -+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -+ -+ If any adjustment is made to the ELF object after it has been -+ built these entries will need to be adjusted. */ -+#define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -+#define DT_TLSDESC_PLT 0x6ffffef6 -+#define DT_TLSDESC_GOT 0x6ffffef7 -+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -+#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -+#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -+#define DT_MOVETAB 0x6ffffefe /* Move table. */ -+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -+#define DT_ADDRRNGHI 0x6ffffeff -+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -+#define DT_ADDRNUM 11 -+ -+/* The versioning entry types. The next are defined as part of the -+ GNU extension. */ -+#define DT_VERSYM 0x6ffffff0 -+ -+#define DT_RELACOUNT 0x6ffffff9 -+#define DT_RELCOUNT 0x6ffffffa -+ -+/* These were chosen by Sun. */ -+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -+#define DT_VERDEF 0x6ffffffc /* Address of version definition -+ table */ -+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -+#define DT_VERNEED 0x6ffffffe /* Address of table with needed -+ versions */ -+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -+#define DT_VERSIONTAGNUM 16 -+ -+/* Sun added these machine-independent extensions in the "processor-specific" -+ range. Be compatible. */ -+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -+#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -+#define DT_EXTRANUM 3 -+ -+/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ -+ -+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -+ entry in the dynamic section. */ -+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -+#define DF_1_TRANS 0x00000200 -+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -+ -+/* Flags for the feature selection in DT_FEATURE_1. */ -+#define DTF_1_PARINIT 0x00000001 -+#define DTF_1_CONFEXP 0x00000002 -+ -+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not -+ generally available. */ -+ -+/* Version definition sections. */ -+ -+typedef struct -+{ -+ Elf32_Half vd_version; /* Version revision */ -+ Elf32_Half vd_flags; /* Version information */ -+ Elf32_Half vd_ndx; /* Version Index */ -+ Elf32_Half vd_cnt; /* Number of associated aux entries */ -+ Elf32_Word vd_hash; /* Version name hash value */ -+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf32_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf32_Verdef; -+ -+typedef struct -+{ -+ Elf64_Half vd_version; /* Version revision */ -+ Elf64_Half vd_flags; /* Version information */ -+ Elf64_Half vd_ndx; /* Version Index */ -+ Elf64_Half vd_cnt; /* Number of associated aux entries */ -+ Elf64_Word vd_hash; /* Version name hash value */ -+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf64_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf64_Verdef; -+ -+ -+/* Legal values for vd_version (version revision). */ -+#define VER_DEF_NONE 0 /* No version */ -+#define VER_DEF_CURRENT 1 /* Current version */ -+#define VER_DEF_NUM 2 /* Given version number */ -+ -+/* Legal values for vd_flags (version information flags). */ -+#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+/* Versym symbol index values. */ -+#define VER_NDX_LOCAL 0 /* Symbol is local. */ -+#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -+ -+/* Auxialiary version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vda_name; /* Version or dependency names */ -+ Elf32_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf32_Verdaux; -+ -+typedef struct -+{ -+ Elf64_Word vda_name; /* Version or dependency names */ -+ Elf64_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf64_Verdaux; -+ -+ -+/* Version dependency section. */ -+ -+typedef struct -+{ -+ Elf32_Half vn_version; /* Version of structure */ -+ Elf32_Half vn_cnt; /* Number of associated aux entries */ -+ Elf32_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf32_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf32_Verneed; -+ -+typedef struct -+{ -+ Elf64_Half vn_version; /* Version of structure */ -+ Elf64_Half vn_cnt; /* Number of associated aux entries */ -+ Elf64_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf64_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf64_Verneed; -+ -+ -+/* Legal values for vn_version (version revision). */ -+#define VER_NEED_NONE 0 /* No version */ -+#define VER_NEED_CURRENT 1 /* Current version */ -+#define VER_NEED_NUM 2 /* Given version number */ -+ -+/* Auxiliary needed version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vna_hash; /* Hash value of dependency name */ -+ Elf32_Half vna_flags; /* Dependency specific information */ -+ Elf32_Half vna_other; /* Unused */ -+ Elf32_Word vna_name; /* Dependency name string offset */ -+ Elf32_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf32_Vernaux; -+ -+typedef struct -+{ -+ Elf64_Word vna_hash; /* Hash value of dependency name */ -+ Elf64_Half vna_flags; /* Dependency specific information */ -+ Elf64_Half vna_other; /* Unused */ -+ Elf64_Word vna_name; /* Dependency name string offset */ -+ Elf64_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf64_Vernaux; -+ -+ -+/* Legal values for vna_flags. */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+ -+/* Auxiliary vector. */ -+ -+/* This vector is normally only used by the program interpreter. The -+ usual definition in an ABI supplement uses the name auxv_t. The -+ vector is not usually defined in a standard <elf.h> file, but it -+ can't hurt. We rename it to avoid conflicts. The sizes of these -+ types are an arrangement between the exec server and the program -+ interpreter, so we don't fully specify them here. */ -+ -+typedef struct -+{ -+ uint32_t a_type; /* Entry type */ -+ union -+ { -+ uint32_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf32_auxv_t; -+ -+typedef struct -+{ -+ uint64_t a_type; /* Entry type */ -+ union -+ { -+ uint64_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf64_auxv_t; -+ -+/* Legal values for a_type (entry type). */ -+ -+#define AT_NULL 0 /* End of vector */ -+#define AT_IGNORE 1 /* Entry should be ignored */ -+#define AT_EXECFD 2 /* File descriptor of program */ -+#define AT_PHDR 3 /* Program headers for program */ -+#define AT_PHENT 4 /* Size of program header entry */ -+#define AT_PHNUM 5 /* Number of program headers */ -+#define AT_PAGESZ 6 /* System page size */ -+#define AT_BASE 7 /* Base address of interpreter */ -+#define AT_FLAGS 8 /* Flags */ -+#define AT_ENTRY 9 /* Entry point of program */ -+#define AT_NOTELF 10 /* Program is not ELF */ -+#define AT_UID 11 /* Real uid */ -+#define AT_EUID 12 /* Effective uid */ -+#define AT_GID 13 /* Real gid */ -+#define AT_EGID 14 /* Effective gid */ -+#define AT_CLKTCK 17 /* Frequency of times() */ -+ -+/* Some more special a_type values describing the hardware. */ -+#define AT_PLATFORM 15 /* String identifying platform. */ -+#define AT_HWCAP 16 /* Machine dependent hints about -+ processor capabilities. */ -+ -+/* This entry gives some information about the FPU initialization -+ performed by the kernel. */ -+#define AT_FPUCW 18 /* Used FPU control word. */ -+ -+/* Cache block sizes. */ -+#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ -+ -+/* A special ignored value for PPC, used by the kernel to control the -+ interpretation of the AUXV. Must be > 16. */ -+#define AT_IGNOREPPC 22 /* Entry should be ignored. */ -+ -+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ -+ -+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ -+ -+#define AT_RANDOM 25 /* Address of 16 random bytes. */ -+ -+#define AT_EXECFN 31 /* Filename of executable. */ -+ -+/* Pointer to the global system page used for system calls and other -+ nice things. */ -+#define AT_SYSINFO 32 -+#define AT_SYSINFO_EHDR 33 -+ -+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains -+ log2 of line size; mask those to get cache size. */ -+#define AT_L1I_CACHESHAPE 34 -+#define AT_L1D_CACHESHAPE 35 -+#define AT_L2_CACHESHAPE 36 -+#define AT_L3_CACHESHAPE 37 -+ -+/* Note section contents. Each entry in the note section begins with -+ a header of a fixed form. */ -+ -+typedef struct -+{ -+ Elf32_Word n_namesz; /* Length of the note's name. */ -+ Elf32_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf32_Word n_type; /* Type of the note. */ -+} Elf32_Nhdr; -+ -+typedef struct -+{ -+ Elf64_Word n_namesz; /* Length of the note's name. */ -+ Elf64_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf64_Word n_type; /* Type of the note. */ -+} Elf64_Nhdr; -+ -+/* Known names of notes. */ -+ -+/* Solaris entries in the note section have this name. */ -+#define ELF_NOTE_SOLARIS "SUNW Solaris" -+ -+/* Note entries for GNU systems have this name. */ -+#define ELF_NOTE_GNU "GNU" -+ -+ -+/* Defined types of notes for Solaris. */ -+ -+/* Value of descriptor (one word) is desired pagesize for the binary. */ -+#define ELF_NOTE_PAGESIZE_HINT 1 -+ -+ -+/* Defined note types for GNU systems. */ -+ -+/* ABI information. The descriptor consists of words: -+ word 0: OS descriptor -+ word 1: major version of the ABI -+ word 2: minor version of the ABI -+ word 3: subminor version of the ABI -+*/ -+#define NT_GNU_ABI_TAG 1 -+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -+ -+/* Known OSes. These values can appear in word 0 of an -+ NT_GNU_ABI_TAG note section entry. */ -+#define ELF_NOTE_OS_LINUX 0 -+#define ELF_NOTE_OS_GNU 1 -+#define ELF_NOTE_OS_SOLARIS2 2 -+#define ELF_NOTE_OS_FREEBSD 3 -+ -+/* Synthetic hwcap information. The descriptor begins with two words: -+ word 0: number of entries -+ word 1: bitmask of enabled entries -+ Then follow variable-length entries, one byte followed by a -+ '\0'-terminated hwcap name string. The byte gives the bit -+ number to test if enabled, (1U << bit) & bitmask. */ -+#define NT_GNU_HWCAP 2 -+ -+/* Build ID bits as generated by ld --build-id. -+ The descriptor consists of any nonzero number of bytes. */ -+#define NT_GNU_BUILD_ID 3 -+ -+/* Version note generated by GNU gold containing a version string. */ -+#define NT_GNU_GOLD_VERSION 4 -+ -+ -+/* Move records. */ -+typedef struct -+{ -+ Elf32_Xword m_value; /* Symbol value. */ -+ Elf32_Word m_info; /* Size and index. */ -+ Elf32_Word m_poffset; /* Symbol offset. */ -+ Elf32_Half m_repeat; /* Repeat count. */ -+ Elf32_Half m_stride; /* Stride info. */ -+} Elf32_Move; -+ -+typedef struct -+{ -+ Elf64_Xword m_value; /* Symbol value. */ -+ Elf64_Xword m_info; /* Size and index. */ -+ Elf64_Xword m_poffset; /* Symbol offset. */ -+ Elf64_Half m_repeat; /* Repeat count. */ -+ Elf64_Half m_stride; /* Stride info. */ -+} Elf64_Move; -+ -+/* Macro to construct move records. */ -+#define ELF32_M_SYM(info) ((info) >> 8) -+#define ELF32_M_SIZE(info) ((unsigned char) (info)) -+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) -+ -+#define ELF64_M_SYM(info) ELF32_M_SYM (info) -+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) -+ -+ -+/* Motorola 68k specific definitions. */ -+ -+/* Values for Elf32_Ehdr.e_flags. */ -+#define EF_CPU32 0x00810000 -+ -+/* m68k relocs. */ -+ -+#define R_68K_NONE 0 /* No reloc */ -+#define R_68K_32 1 /* Direct 32 bit */ -+#define R_68K_16 2 /* Direct 16 bit */ -+#define R_68K_8 3 /* Direct 8 bit */ -+#define R_68K_PC32 4 /* PC relative 32 bit */ -+#define R_68K_PC16 5 /* PC relative 16 bit */ -+#define R_68K_PC8 6 /* PC relative 8 bit */ -+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -+#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -+#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -+#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -+#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -+#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -+#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -+#define R_68K_COPY 19 /* Copy symbol at runtime */ -+#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -+#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -+#define R_68K_RELATIVE 22 /* Adjust by program base */ -+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -+/* Keep this the last entry. */ -+#define R_68K_NUM 43 -+ -+/* Intel 80386 specific definitions. */ -+ -+/* i386 relocs. */ -+ -+#define R_386_NONE 0 /* No reloc */ -+#define R_386_32 1 /* Direct 32 bit */ -+#define R_386_PC32 2 /* PC relative 32 bit */ -+#define R_386_GOT32 3 /* 32 bit GOT entry */ -+#define R_386_PLT32 4 /* 32 bit PLT address */ -+#define R_386_COPY 5 /* Copy symbol at runtime */ -+#define R_386_GLOB_DAT 6 /* Create GOT entry */ -+#define R_386_JMP_SLOT 7 /* Create PLT entry */ -+#define R_386_RELATIVE 8 /* Adjust by program base */ -+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -+#define R_386_32PLT 11 -+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS -+ block offset */ -+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block -+ offset */ -+#define R_386_TLS_LE 17 /* Offset relative to static TLS -+ block */ -+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of -+ general dynamic thread local data */ -+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of -+ local dynamic thread local data -+ in LE code */ -+#define R_386_16 20 -+#define R_386_PC16 21 -+#define R_386_8 22 -+#define R_386_PC8 23 -+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic -+ thread local data */ -+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -+#define R_386_TLS_GD_CALL 26 /* Relocation for call to -+ __tls_get_addr() */ -+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic -+ thread local data in LE code */ -+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to -+ __tls_get_addr() in LDM code */ -+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS -+ block offset */ -+#define R_386_TLS_LE_32 34 /* Negated offset relative to static -+ TLS block */ -+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -+/* 38? */ -+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS -+ descriptor for -+ relaxation. */ -+#define R_386_TLS_DESC 41 /* TLS descriptor containing -+ pointer to code and to -+ argument, returning the TLS -+ offset for the symbol. */ -+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -+/* Keep this the last entry. */ -+#define R_386_NUM 43 -+ -+/* SUN SPARC specific definitions. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ -+ -+/* Values for Elf64_Ehdr.e_flags. */ -+ -+#define EF_SPARCV9_MM 3 -+#define EF_SPARCV9_TSO 0 -+#define EF_SPARCV9_PSO 1 -+#define EF_SPARCV9_RMO 2 -+#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -+#define EF_SPARC_EXT_MASK 0xFFFF00 -+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ -+ -+/* SPARC relocs. */ -+ -+#define R_SPARC_NONE 0 /* No reloc */ -+#define R_SPARC_8 1 /* Direct 8 bit */ -+#define R_SPARC_16 2 /* Direct 16 bit */ -+#define R_SPARC_32 3 /* Direct 32 bit */ -+#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -+#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -+#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -+#define R_SPARC_HI22 9 /* High 22 bit */ -+#define R_SPARC_22 10 /* Direct 22 bit */ -+#define R_SPARC_13 11 /* Direct 13 bit */ -+#define R_SPARC_LO10 12 /* Truncated 10 bit */ -+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -+#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -+#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ -+ -+/* Additional Sparc64 relocs. */ -+ -+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -+#define R_SPARC_10 30 /* Direct 10 bit */ -+#define R_SPARC_11 31 /* Direct 11 bit */ -+#define R_SPARC_64 32 /* Direct 64 bit */ -+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -+#define R_SPARC_7 43 /* Direct 7 bit */ -+#define R_SPARC_5 44 /* Direct 5 bit */ -+#define R_SPARC_6 45 /* Direct 6 bit */ -+#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -+#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -+#define R_SPARC_REGISTER 53 /* Global register usage */ -+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -+#define R_SPARC_TLS_GD_HI22 56 -+#define R_SPARC_TLS_GD_LO10 57 -+#define R_SPARC_TLS_GD_ADD 58 -+#define R_SPARC_TLS_GD_CALL 59 -+#define R_SPARC_TLS_LDM_HI22 60 -+#define R_SPARC_TLS_LDM_LO10 61 -+#define R_SPARC_TLS_LDM_ADD 62 -+#define R_SPARC_TLS_LDM_CALL 63 -+#define R_SPARC_TLS_LDO_HIX22 64 -+#define R_SPARC_TLS_LDO_LOX10 65 -+#define R_SPARC_TLS_LDO_ADD 66 -+#define R_SPARC_TLS_IE_HI22 67 -+#define R_SPARC_TLS_IE_LO10 68 -+#define R_SPARC_TLS_IE_LD 69 -+#define R_SPARC_TLS_IE_LDX 70 -+#define R_SPARC_TLS_IE_ADD 71 -+#define R_SPARC_TLS_LE_HIX22 72 -+#define R_SPARC_TLS_LE_LOX10 73 -+#define R_SPARC_TLS_DTPMOD32 74 -+#define R_SPARC_TLS_DTPMOD64 75 -+#define R_SPARC_TLS_DTPOFF32 76 -+#define R_SPARC_TLS_DTPOFF64 77 -+#define R_SPARC_TLS_TPOFF32 78 -+#define R_SPARC_TLS_TPOFF64 79 -+#define R_SPARC_GOTDATA_HIX22 80 -+#define R_SPARC_GOTDATA_LOX10 81 -+#define R_SPARC_GOTDATA_OP_HIX22 82 -+#define R_SPARC_GOTDATA_OP_LOX10 83 -+#define R_SPARC_GOTDATA_OP 84 -+#define R_SPARC_H34 85 -+#define R_SPARC_SIZE32 86 -+#define R_SPARC_SIZE64 87 -+#define R_SPARC_WDISP10 88 -+#define R_SPARC_JMP_IREL 248 -+#define R_SPARC_IRELATIVE 249 -+#define R_SPARC_GNU_VTINHERIT 250 -+#define R_SPARC_GNU_VTENTRY 251 -+#define R_SPARC_REV32 252 -+/* Keep this the last entry. */ -+#define R_SPARC_NUM 253 -+ -+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ -+ -+#define DT_SPARC_REGISTER 0x70000001 -+#define DT_SPARC_NUM 2 -+ -+/* MIPS R3000 specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -+#define EF_MIPS_PIC 2 /* Contains PIC code */ -+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -+#define EF_MIPS_XGOT 8 -+#define EF_MIPS_64BIT_WHIRL 16 -+#define EF_MIPS_ABI2 32 -+#define EF_MIPS_ABI_ON32 64 -+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ -+ -+/* Legal values for MIPS architecture level. */ -+ -+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* The following are non-official names and should not be used. */ -+ -+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* Special section indices. */ -+ -+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -+#define SHT_MIPS_MSYM 0x70000001 -+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -+#define SHT_MIPS_PACKAGE 0x70000007 -+#define SHT_MIPS_PACKSYM 0x70000008 -+#define SHT_MIPS_RELD 0x70000009 -+#define SHT_MIPS_IFACE 0x7000000b -+#define SHT_MIPS_CONTENT 0x7000000c -+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -+#define SHT_MIPS_SHDR 0x70000010 -+#define SHT_MIPS_FDESC 0x70000011 -+#define SHT_MIPS_EXTSYM 0x70000012 -+#define SHT_MIPS_DENSE 0x70000013 -+#define SHT_MIPS_PDESC 0x70000014 -+#define SHT_MIPS_LOCSYM 0x70000015 -+#define SHT_MIPS_AUXSYM 0x70000016 -+#define SHT_MIPS_OPTSYM 0x70000017 -+#define SHT_MIPS_LOCSTR 0x70000018 -+#define SHT_MIPS_LINE 0x70000019 -+#define SHT_MIPS_RFDESC 0x7000001a -+#define SHT_MIPS_DELTASYM 0x7000001b -+#define SHT_MIPS_DELTAINST 0x7000001c -+#define SHT_MIPS_DELTACLASS 0x7000001d -+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -+#define SHT_MIPS_DELTADECL 0x7000001f -+#define SHT_MIPS_SYMBOL_LIB 0x70000020 -+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -+#define SHT_MIPS_TRANSLATE 0x70000022 -+#define SHT_MIPS_PIXIE 0x70000023 -+#define SHT_MIPS_XLATE 0x70000024 -+#define SHT_MIPS_XLATE_DEBUG 0x70000025 -+#define SHT_MIPS_WHIRL 0x70000026 -+#define SHT_MIPS_EH_REGION 0x70000027 -+#define SHT_MIPS_XLATE_OLD 0x70000028 -+#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -+#define SHF_MIPS_MERGE 0x20000000 -+#define SHF_MIPS_ADDR 0x40000000 -+#define SHF_MIPS_STRINGS 0x80000000 -+#define SHF_MIPS_NOSTRIP 0x08000000 -+#define SHF_MIPS_LOCAL 0x04000000 -+#define SHF_MIPS_NAMES 0x02000000 -+#define SHF_MIPS_NODUPE 0x01000000 -+ -+ -+/* Symbol tables. */ -+ -+/* MIPS specific values for `st_other'. */ -+#define STO_MIPS_DEFAULT 0x0 -+#define STO_MIPS_INTERNAL 0x1 -+#define STO_MIPS_HIDDEN 0x2 -+#define STO_MIPS_PROTECTED 0x3 -+#define STO_MIPS_PLT 0x8 -+#define STO_MIPS_SC_ALIGN_UNUSED 0xff -+ -+/* MIPS specific values for `st_info'. */ -+#define STB_MIPS_SPLIT_COMMON 13 -+ -+/* Entries found in sections of type SHT_MIPS_GPTAB. */ -+ -+typedef union -+{ -+ struct -+ { -+ Elf32_Word gt_current_g_value; /* -G value used for compilation */ -+ Elf32_Word gt_unused; /* Not used */ -+ } gt_header; /* First entry in section */ -+ struct -+ { -+ Elf32_Word gt_g_value; /* If this value were used for -G */ -+ Elf32_Word gt_bytes; /* This many bytes would be used */ -+ } gt_entry; /* Subsequent entries in section */ -+} Elf32_gptab; -+ -+/* Entry found in sections of type SHT_MIPS_REGINFO. */ -+ -+typedef struct -+{ -+ Elf32_Word ri_gprmask; /* General registers used */ -+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ -+ Elf32_Sword ri_gp_value; /* $gp register value */ -+} Elf32_RegInfo; -+ -+/* Entries found in sections of type SHT_MIPS_OPTIONS. */ -+ -+typedef struct -+{ -+ unsigned char kind; /* Determines interpretation of the -+ variable part of descriptor. */ -+ unsigned char size; /* Size of descriptor, including header. */ -+ Elf32_Section section; /* Section header index of section affected, -+ 0 for global options. */ -+ Elf32_Word info; /* Kind-specific information. */ -+} Elf_Options; -+ -+/* Values for `kind' field in Elf_Options. */ -+ -+#define ODK_NULL 0 /* Undefined. */ -+#define ODK_REGINFO 1 /* Register usage information. */ -+#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -+#define ODK_PAD 3 /* Section padding options. */ -+#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -+#define ODK_FILL 5 /* record the fill value used by the linker. */ -+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ -+ -+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -+ -+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -+#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -+#define OEX_PRECISEFP OEX_FPDBUG -+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -+ -+#define OEX_FPU_INVAL 0x10 -+#define OEX_FPU_DIV0 0x08 -+#define OEX_FPU_OFLO 0x04 -+#define OEX_FPU_UFLO 0x02 -+#define OEX_FPU_INEX 0x01 -+ -+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -+ -+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -+ -+#define OPAD_PREFIX 0x1 -+#define OPAD_POSTFIX 0x2 -+#define OPAD_SYMBOL 0x4 -+ -+/* Entry found in `.options' section. */ -+ -+typedef struct -+{ -+ Elf32_Word hwp_flags1; /* Extra flags. */ -+ Elf32_Word hwp_flags2; /* Extra flags. */ -+} Elf_Options_Hw; -+ -+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -+ -+#define OHWA0_R4KEOP_CHECKED 0x00000001 -+#define OHWA1_R4KEOP_CLEAN 0x00000002 -+ -+/* MIPS relocs. */ -+ -+#define R_MIPS_NONE 0 /* No reloc */ -+#define R_MIPS_16 1 /* Direct 16 bit */ -+#define R_MIPS_32 2 /* Direct 32 bit */ -+#define R_MIPS_REL32 3 /* PC relative 32 bit */ -+#define R_MIPS_26 4 /* Direct 26 bit shifted */ -+#define R_MIPS_HI16 5 /* High 16 bit */ -+#define R_MIPS_LO16 6 /* Low 16 bit */ -+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -+#define R_MIPS_PC16 10 /* PC relative 16 bit */ -+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -+ -+#define R_MIPS_SHIFT5 16 -+#define R_MIPS_SHIFT6 17 -+#define R_MIPS_64 18 -+#define R_MIPS_GOT_DISP 19 -+#define R_MIPS_GOT_PAGE 20 -+#define R_MIPS_GOT_OFST 21 -+#define R_MIPS_GOT_HI16 22 -+#define R_MIPS_GOT_LO16 23 -+#define R_MIPS_SUB 24 -+#define R_MIPS_INSERT_A 25 -+#define R_MIPS_INSERT_B 26 -+#define R_MIPS_DELETE 27 -+#define R_MIPS_HIGHER 28 -+#define R_MIPS_HIGHEST 29 -+#define R_MIPS_CALL_HI16 30 -+#define R_MIPS_CALL_LO16 31 -+#define R_MIPS_SCN_DISP 32 -+#define R_MIPS_REL16 33 -+#define R_MIPS_ADD_IMMEDIATE 34 -+#define R_MIPS_PJUMP 35 -+#define R_MIPS_RELGOT 36 -+#define R_MIPS_JALR 37 -+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -+#define R_MIPS_GLOB_DAT 51 -+#define R_MIPS_COPY 126 -+#define R_MIPS_JUMP_SLOT 127 -+/* Keep this the last entry. */ -+#define R_MIPS_NUM 128 -+ -+/* Legal values for p_type field of Elf32_Phdr. */ -+ -+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -+#define PT_MIPS_OPTIONS 0x70000002 -+ -+/* Special program header types. */ -+ -+#define PF_MIPS_LOCAL 0x10000000 -+ -+/* Legal values for d_tag field of Elf32_Dyn. */ -+ -+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -+#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -+#define DT_MIPS_MSYM 0x70000007 -+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in -+ DT_MIPS_DELTA_CLASS. */ -+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in -+ DT_MIPS_DELTA_INSTANCE. */ -+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in -+ DT_MIPS_DELTA_RELOC. */ -+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta -+ relocations refer to. */ -+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in -+ DT_MIPS_DELTA_SYM. */ -+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the -+ class declaration. */ -+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in -+ DT_MIPS_DELTA_CLASSSYM. */ -+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -+#define DT_MIPS_PIXIE_INIT 0x70000023 -+#define DT_MIPS_SYMBOL_LIB 0x70000024 -+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -+#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve -+ function stored in GOT. */ -+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added -+ by rld on dlopen() calls. */ -+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -+/* The address of .got.plt in an executable using the new non-PIC ABI. */ -+#define DT_MIPS_PLTGOT 0x70000032 -+/* The base of the PLT in an executable using the new non-PIC ABI if that -+ PLT is writable. For a non-writable PLT, this is omitted or has a zero -+ value. */ -+#define DT_MIPS_RWPLT 0x70000034 -+#define DT_MIPS_NUM 0x35 -+ -+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -+ -+#define RHF_NONE 0 /* No flags */ -+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -+#define RHF_NO_MOVE (1 << 3) -+#define RHF_SGI_ONLY (1 << 4) -+#define RHF_GUARANTEE_INIT (1 << 5) -+#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -+#define RHF_GUARANTEE_START_INIT (1 << 7) -+#define RHF_PIXIE (1 << 8) -+#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -+#define RHF_REQUICKSTART (1 << 10) -+#define RHF_REQUICKSTARTED (1 << 11) -+#define RHF_CORD (1 << 12) -+#define RHF_NO_UNRES_UNDEF (1 << 13) -+#define RHF_RLD_ORDER_SAFE (1 << 14) -+ -+/* Entries found in sections of type SHT_MIPS_LIBLIST. */ -+ -+typedef struct -+{ -+ Elf32_Word l_name; /* Name (string table index) */ -+ Elf32_Word l_time_stamp; /* Timestamp */ -+ Elf32_Word l_checksum; /* Checksum */ -+ Elf32_Word l_version; /* Interface version */ -+ Elf32_Word l_flags; /* Flags */ -+} Elf32_Lib; -+ -+typedef struct -+{ -+ Elf64_Word l_name; /* Name (string table index) */ -+ Elf64_Word l_time_stamp; /* Timestamp */ -+ Elf64_Word l_checksum; /* Checksum */ -+ Elf64_Word l_version; /* Interface version */ -+ Elf64_Word l_flags; /* Flags */ -+} Elf64_Lib; -+ -+ -+/* Legal values for l_flags. */ -+ -+#define LL_NONE 0 -+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -+#define LL_REQUIRE_MINOR (1 << 2) -+#define LL_EXPORTS (1 << 3) -+#define LL_DELAY_LOAD (1 << 4) -+#define LL_DELTA (1 << 5) -+ -+/* Entries found in sections of type SHT_MIPS_CONFLICT. */ -+ -+typedef Elf32_Addr Elf32_Conflict; -+ -+ -+/* HPPA specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch -+ prediction. */ -+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ -+ -+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ -+ -+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -+ -+/* Additional section indeces. */ -+ -+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared -+ symbols in ANSI C. */ -+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ -+ -+#define STT_HP_OPAQUE (STT_LOOS + 0x1) -+#define STT_HP_STUB (STT_LOOS + 0x2) -+ -+/* HPPA relocs. */ -+ -+#define R_PARISC_NONE 0 /* No reloc. */ -+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -+#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LORESERVE 128 -+#define R_PARISC_COPY 128 /* Copy relocation. */ -+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_GNU_VTENTRY 232 -+#define R_PARISC_GNU_VTINHERIT 233 -+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -+#define R_PARISC_HIRESERVE 255 -+ -+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PT_HP_TLS (PT_LOOS + 0x0) -+#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -+#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -+#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -+#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -+#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -+#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -+#define PT_HP_PARALLEL (PT_LOOS + 0x10) -+#define PT_HP_FASTBIND (PT_LOOS + 0x11) -+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -+#define PT_HP_STACK (PT_LOOS + 0x14) -+ -+#define PT_PARISC_ARCHEXT 0x70000000 -+#define PT_PARISC_UNWIND 0x70000001 -+ -+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PF_PARISC_SBP 0x08000000 -+ -+#define PF_HP_PAGE_SIZE 0x00100000 -+#define PF_HP_FAR_SHARED 0x00200000 -+#define PF_HP_NEAR_SHARED 0x00400000 -+#define PF_HP_CODE 0x01000000 -+#define PF_HP_MODIFY 0x02000000 -+#define PF_HP_LAZYSWAP 0x04000000 -+#define PF_HP_SBP 0x08000000 -+ -+ -+/* Alpha specific definitions. */ -+ -+/* Legal values for e_flags field of Elf64_Ehdr. */ -+ -+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ -+ -+/* Legal values for sh_type field of Elf64_Shdr. */ -+ -+/* These two are primerily concerned with ECOFF debugging info. */ -+#define SHT_ALPHA_DEBUG 0x70000001 -+#define SHT_ALPHA_REGINFO 0x70000002 -+ -+/* Legal values for sh_flags field of Elf64_Shdr. */ -+ -+#define SHF_ALPHA_GPREL 0x10000000 -+ -+/* Legal values for st_other field of Elf64_Sym. */ -+#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ -+ -+/* Alpha relocs. */ -+ -+#define R_ALPHA_NONE 0 /* No reloc */ -+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -+#define R_ALPHA_TLS_GD_HI 28 -+#define R_ALPHA_TLSGD 29 -+#define R_ALPHA_TLS_LDM 30 -+#define R_ALPHA_DTPMOD64 31 -+#define R_ALPHA_GOTDTPREL 32 -+#define R_ALPHA_DTPREL64 33 -+#define R_ALPHA_DTPRELHI 34 -+#define R_ALPHA_DTPRELLO 35 -+#define R_ALPHA_DTPREL16 36 -+#define R_ALPHA_GOTTPREL 37 -+#define R_ALPHA_TPREL64 38 -+#define R_ALPHA_TPRELHI 39 -+#define R_ALPHA_TPRELLO 40 -+#define R_ALPHA_TPREL16 41 -+/* Keep this the last entry. */ -+#define R_ALPHA_NUM 46 -+ -+/* Magic values of the LITUSE relocation addend. */ -+#define LITUSE_ALPHA_ADDR 0 -+#define LITUSE_ALPHA_BASE 1 -+#define LITUSE_ALPHA_BYTOFF 2 -+#define LITUSE_ALPHA_JSR 3 -+#define LITUSE_ALPHA_TLS_GD 4 -+#define LITUSE_ALPHA_TLS_LDM 5 -+ -+/* Legal values for d_tag of Elf64_Dyn. */ -+#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -+#define DT_ALPHA_NUM 1 -+ -+/* PowerPC specific declarations */ -+ -+/* Values for Elf32/64_Ehdr.e_flags. */ -+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ -+ -+/* Cygnus local bits below */ -+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib -+ flag */ -+ -+/* PowerPC relocations defined by the ABIs */ -+#define R_PPC_NONE 0 -+#define R_PPC_ADDR32 1 /* 32bit absolute address */ -+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -+#define R_PPC_ADDR16 3 /* 16bit absolute address */ -+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -+#define R_PPC_ADDR14_BRTAKEN 8 -+#define R_PPC_ADDR14_BRNTAKEN 9 -+#define R_PPC_REL24 10 /* PC relative 26 bit */ -+#define R_PPC_REL14 11 /* PC relative 16 bit */ -+#define R_PPC_REL14_BRTAKEN 12 -+#define R_PPC_REL14_BRNTAKEN 13 -+#define R_PPC_GOT16 14 -+#define R_PPC_GOT16_LO 15 -+#define R_PPC_GOT16_HI 16 -+#define R_PPC_GOT16_HA 17 -+#define R_PPC_PLTREL24 18 -+#define R_PPC_COPY 19 -+#define R_PPC_GLOB_DAT 20 -+#define R_PPC_JMP_SLOT 21 -+#define R_PPC_RELATIVE 22 -+#define R_PPC_LOCAL24PC 23 -+#define R_PPC_UADDR32 24 -+#define R_PPC_UADDR16 25 -+#define R_PPC_REL32 26 -+#define R_PPC_PLT32 27 -+#define R_PPC_PLTREL32 28 -+#define R_PPC_PLT16_LO 29 -+#define R_PPC_PLT16_HI 30 -+#define R_PPC_PLT16_HA 31 -+#define R_PPC_SDAREL16 32 -+#define R_PPC_SECTOFF 33 -+#define R_PPC_SECTOFF_LO 34 -+#define R_PPC_SECTOFF_HI 35 -+#define R_PPC_SECTOFF_HA 36 -+ -+/* PowerPC relocations defined for the TLS access ABI. */ -+#define R_PPC_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -+ -+/* The remaining relocs are from the Embedded ELF ABI, and are not -+ in the SVR4 ELF ABI. */ -+#define R_PPC_EMB_NADDR32 101 -+#define R_PPC_EMB_NADDR16 102 -+#define R_PPC_EMB_NADDR16_LO 103 -+#define R_PPC_EMB_NADDR16_HI 104 -+#define R_PPC_EMB_NADDR16_HA 105 -+#define R_PPC_EMB_SDAI16 106 -+#define R_PPC_EMB_SDA2I16 107 -+#define R_PPC_EMB_SDA2REL 108 -+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -+#define R_PPC_EMB_MRKREF 110 -+#define R_PPC_EMB_RELSEC16 111 -+#define R_PPC_EMB_RELST_LO 112 -+#define R_PPC_EMB_RELST_HI 113 -+#define R_PPC_EMB_RELST_HA 114 -+#define R_PPC_EMB_BIT_FLD 115 -+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ -+ -+/* Diab tool relocations. */ -+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC_IRELATIVE 248 -+ -+/* GNU relocs used in PIC code sequences. */ -+#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* This is a phony reloc to handle any old fashioned TOC16 references -+ that may still be in object files. */ -+#define R_PPC_TOC16 255 -+ -+/* PowerPC specific values for the Dyn d_tag field. */ -+#define DT_PPC_GOT (DT_LOPROC + 0) -+#define DT_PPC_NUM 1 -+ -+/* PowerPC64 relocations defined by the ABIs */ -+#define R_PPC64_NONE R_PPC_NONE -+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -+#define R_PPC64_GOT16 R_PPC_GOT16 -+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA -+ -+#define R_PPC64_COPY R_PPC_COPY -+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -+#define R_PPC64_RELATIVE R_PPC_RELATIVE -+ -+#define R_PPC64_UADDR32 R_PPC_UADDR32 -+#define R_PPC64_UADDR16 R_PPC_UADDR16 -+#define R_PPC64_REL32 R_PPC_REL32 -+#define R_PPC64_PLT32 R_PPC_PLT32 -+#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA -+ -+#define R_PPC64_SECTOFF R_PPC_SECTOFF -+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -+#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -+#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -+#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ -+ -+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ -+ -+/* PowerPC64 relocations defined for the TLS access ABI. */ -+#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC64_JMP_IREL 247 -+#define R_PPC64_IRELATIVE 248 -+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* PowerPC64 specific values for the Dyn d_tag field. */ -+#define DT_PPC64_GLINK (DT_LOPROC + 0) -+#define DT_PPC64_OPD (DT_LOPROC + 1) -+#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -+#define DT_PPC64_NUM 3 -+ -+ -+/* ARM specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_ARM_RELEXEC 0x01 -+#define EF_ARM_HASENTRY 0x02 -+#define EF_ARM_INTERWORK 0x04 -+#define EF_ARM_APCS_26 0x08 -+#define EF_ARM_APCS_FLOAT 0x10 -+#define EF_ARM_PIC 0x20 -+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -+#define EF_ARM_NEW_ABI 0x80 -+#define EF_ARM_OLD_ABI 0x100 -+#define EF_ARM_SOFT_FLOAT 0x200 -+#define EF_ARM_VFP_FLOAT 0x400 -+#define EF_ARM_MAVERICK_FLOAT 0x800 -+ -+ -+/* Other constants defined in the ARM ELF spec. version B-01. */ -+/* NB. These conflict with values defined above. */ -+#define EF_ARM_SYMSARESORTED 0x04 -+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -+#define EF_ARM_MAPSYMSFIRST 0x10 -+#define EF_ARM_EABIMASK 0XFF000000 -+ -+/* Constants defined in AAELF. */ -+#define EF_ARM_BE8 0x00800000 -+#define EF_ARM_LE8 0x00400000 -+ -+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -+#define EF_ARM_EABI_UNKNOWN 0x00000000 -+#define EF_ARM_EABI_VER1 0x01000000 -+#define EF_ARM_EABI_VER2 0x02000000 -+#define EF_ARM_EABI_VER3 0x03000000 -+#define EF_ARM_EABI_VER4 0x04000000 -+#define EF_ARM_EABI_VER5 0x05000000 -+ -+/* Additional symbol types for Thumb. */ -+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ -+ -+/* ARM-specific values for sh_flags */ -+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined -+ in the input to a link step. */ -+ -+/* ARM-specific program header flags */ -+#define PF_ARM_SB 0x10000000 /* Segment contains the location -+ addressed by the static base. */ -+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ -+ -+ -+/* ARM relocs. */ -+ -+#define R_ARM_NONE 0 /* No reloc */ -+#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -+#define R_ARM_ABS32 2 /* Direct 32 bit */ -+#define R_ARM_REL32 3 /* PC relative 32 bit */ -+#define R_ARM_PC13 4 -+#define R_ARM_ABS16 5 /* Direct 16 bit */ -+#define R_ARM_ABS12 6 /* Direct 12 bit */ -+#define R_ARM_THM_ABS5 7 -+#define R_ARM_ABS8 8 /* Direct 8 bit */ -+#define R_ARM_SBREL32 9 -+#define R_ARM_THM_PC22 10 -+#define R_ARM_THM_PC8 11 -+#define R_ARM_AMP_VCALL9 12 -+#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -+#define R_ARM_THM_SWI8 14 -+#define R_ARM_XPC25 15 -+#define R_ARM_THM_XPC22 16 -+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -+#define R_ARM_COPY 20 /* Copy symbol at runtime */ -+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -+#define R_ARM_RELATIVE 23 /* Adjust by program base */ -+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -+#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -+#define R_ARM_PLT32 27 /* 32 bit PLT address */ -+#define R_ARM_ALU_PCREL_7_0 32 -+#define R_ARM_ALU_PCREL_15_8 33 -+#define R_ARM_ALU_PCREL_23_15 34 -+#define R_ARM_LDR_SBREL_11_0 35 -+#define R_ARM_ALU_SBREL_19_12 36 -+#define R_ARM_ALU_SBREL_27_20 37 -+#define R_ARM_TLS_GOTDESC 90 -+#define R_ARM_TLS_CALL 91 -+#define R_ARM_TLS_DESCSEQ 92 -+#define R_ARM_THM_TLS_CALL 93 -+#define R_ARM_GNU_VTENTRY 100 -+#define R_ARM_GNU_VTINHERIT 101 -+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -+#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic -+ thread local data */ -+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic -+ thread local data */ -+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS -+ block */ -+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of -+ static TLS block offset */ -+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static -+ TLS block */ -+#define R_ARM_THM_TLS_DESCSEQ 129 -+#define R_ARM_IRELATIVE 160 -+#define R_ARM_RXPC25 249 -+#define R_ARM_RSBREL32 250 -+#define R_ARM_THM_RPC22 251 -+#define R_ARM_RREL32 252 -+#define R_ARM_RABS22 253 -+#define R_ARM_RPC24 254 -+#define R_ARM_RBASE 255 -+/* Keep this the last entry. */ -+#define R_ARM_NUM 256 -+ -+/* IA-64 specific declarations. */ -+ -+/* Processor specific flags for the Ehdr e_flags field. */ -+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) -+ -+/* Processor specific flags for the Phdr p_flags field. */ -+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ -+ -+/* Processor specific flags for the Shdr sh_flags field. */ -+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Dyn d_tag field. */ -+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -+#define DT_IA_64_NUM 1 -+ -+/* IA-64 relocations. */ -+#define R_IA64_NONE 0x00 /* none */ -+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -+#define R_IA64_COPY 0x84 /* copy relocation */ -+#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ -+ -+/* SH specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_SH_MACH_MASK 0x1f -+#define EF_SH_UNKNOWN 0x0 -+#define EF_SH1 0x1 -+#define EF_SH2 0x2 -+#define EF_SH3 0x3 -+#define EF_SH_DSP 0x4 -+#define EF_SH3_DSP 0x5 -+#define EF_SH4AL_DSP 0x6 -+#define EF_SH3E 0x8 -+#define EF_SH4 0x9 -+#define EF_SH2E 0xb -+#define EF_SH4A 0xc -+#define EF_SH2A 0xd -+#define EF_SH4_NOFPU 0x10 -+#define EF_SH4A_NOFPU 0x11 -+#define EF_SH4_NOMMU_NOFPU 0x12 -+#define EF_SH2A_NOFPU 0x13 -+#define EF_SH3_NOMMU 0x14 -+#define EF_SH2A_SH4_NOFPU 0x15 -+#define EF_SH2A_SH3_NOFPU 0x16 -+#define EF_SH2A_SH4 0x17 -+#define EF_SH2A_SH3E 0x18 -+ -+/* SH relocs. */ -+#define R_SH_NONE 0 -+#define R_SH_DIR32 1 -+#define R_SH_REL32 2 -+#define R_SH_DIR8WPN 3 -+#define R_SH_IND12W 4 -+#define R_SH_DIR8WPL 5 -+#define R_SH_DIR8WPZ 6 -+#define R_SH_DIR8BP 7 -+#define R_SH_DIR8W 8 -+#define R_SH_DIR8L 9 -+#define R_SH_SWITCH16 25 -+#define R_SH_SWITCH32 26 -+#define R_SH_USES 27 -+#define R_SH_COUNT 28 -+#define R_SH_ALIGN 29 -+#define R_SH_CODE 30 -+#define R_SH_DATA 31 -+#define R_SH_LABEL 32 -+#define R_SH_SWITCH8 33 -+#define R_SH_GNU_VTINHERIT 34 -+#define R_SH_GNU_VTENTRY 35 -+#define R_SH_TLS_GD_32 144 -+#define R_SH_TLS_LD_32 145 -+#define R_SH_TLS_LDO_32 146 -+#define R_SH_TLS_IE_32 147 -+#define R_SH_TLS_LE_32 148 -+#define R_SH_TLS_DTPMOD32 149 -+#define R_SH_TLS_DTPOFF32 150 -+#define R_SH_TLS_TPOFF32 151 -+#define R_SH_GOT32 160 -+#define R_SH_PLT32 161 -+#define R_SH_COPY 162 -+#define R_SH_GLOB_DAT 163 -+#define R_SH_JMP_SLOT 164 -+#define R_SH_RELATIVE 165 -+#define R_SH_GOTOFF 166 -+#define R_SH_GOTPC 167 -+/* Keep this the last entry. */ -+#define R_SH_NUM 256 -+ -+/* S/390 specific definitions. */ -+ -+/* Valid values for the e_flags field. */ -+ -+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ -+ -+/* Additional s390 relocs */ -+ -+#define R_390_NONE 0 /* No reloc. */ -+#define R_390_8 1 /* Direct 8 bit. */ -+#define R_390_12 2 /* Direct 12 bit. */ -+#define R_390_16 3 /* Direct 16 bit. */ -+#define R_390_32 4 /* Direct 32 bit. */ -+#define R_390_PC32 5 /* PC relative 32 bit. */ -+#define R_390_GOT12 6 /* 12 bit GOT offset. */ -+#define R_390_GOT32 7 /* 32 bit GOT offset. */ -+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -+#define R_390_COPY 9 /* Copy symbol at runtime. */ -+#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -+#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -+#define R_390_RELATIVE 12 /* Adjust by program base. */ -+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -+#define R_390_GOT16 15 /* 16 bit GOT offset. */ -+#define R_390_PC16 16 /* PC relative 16 bit. */ -+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -+#define R_390_64 22 /* Direct 64 bit. */ -+#define R_390_PC64 23 /* PC relative 64 bit. */ -+#define R_390_GOT64 24 /* 64 bit GOT offset. */ -+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -+#define R_390_TLS_GDCALL 38 /* Tag for function call in general -+ dynamic TLS code. */ -+#define R_390_TLS_LDCALL 39 /* Tag for function call in local -+ dynamic TLS code. */ -+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS -+ block. */ -+#define R_390_20 57 /* Direct 20 bit. */ -+#define R_390_GOT20 58 /* 20 bit GOT offset. */ -+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -+/* Keep this the last entry. */ -+#define R_390_NUM 62 -+ -+ -+/* CRIS relocations. */ -+#define R_CRIS_NONE 0 -+#define R_CRIS_8 1 -+#define R_CRIS_16 2 -+#define R_CRIS_32 3 -+#define R_CRIS_8_PCREL 4 -+#define R_CRIS_16_PCREL 5 -+#define R_CRIS_32_PCREL 6 -+#define R_CRIS_GNU_VTINHERIT 7 -+#define R_CRIS_GNU_VTENTRY 8 -+#define R_CRIS_COPY 9 -+#define R_CRIS_GLOB_DAT 10 -+#define R_CRIS_JUMP_SLOT 11 -+#define R_CRIS_RELATIVE 12 -+#define R_CRIS_16_GOT 13 -+#define R_CRIS_32_GOT 14 -+#define R_CRIS_16_GOTPLT 15 -+#define R_CRIS_32_GOTPLT 16 -+#define R_CRIS_32_GOTREL 17 -+#define R_CRIS_32_PLT_GOTREL 18 -+#define R_CRIS_32_PLT_PCREL 19 -+ -+#define R_CRIS_NUM 20 -+ -+ -+/* AMD x86-64 relocations. */ -+#define R_X86_64_NONE 0 /* No reloc */ -+#define R_X86_64_64 1 /* Direct 64 bit */ -+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -+#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -+#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -+#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative -+ offset to GOT */ -+#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -+#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -+#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset -+ to two GOT entries for GD symbol */ -+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset -+ to two GOT entries for LD symbol */ -+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset -+ to GOT entry for IE symbol */ -+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -+#define R_X86_64_PC64 24 /* PC relative 64 bit */ -+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative -+ offset to GOT */ -+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset -+ to GOT entry */ -+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset -+ to PLT entry */ -+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS -+ descriptor. */ -+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -+ -+#define R_X86_64_NUM 39 -+ -+ -+/* AM33 relocations. */ -+#define R_MN10300_NONE 0 /* No reloc. */ -+#define R_MN10300_32 1 /* Direct 32 bit. */ -+#define R_MN10300_16 2 /* Direct 16 bit. */ -+#define R_MN10300_8 3 /* Direct 8 bit. */ -+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -+#define R_MN10300_24 9 /* Direct 24 bit. */ -+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -+ -+#define R_MN10300_NUM 24 -+ -+ -+/* M32R relocs. */ -+#define R_M32R_NONE 0 /* No reloc. */ -+#define R_M32R_16 1 /* Direct 16 bit. */ -+#define R_M32R_32 2 /* Direct 32 bit. */ -+#define R_M32R_24 3 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -+#define R_M32R_LO16 9 /* Low 16 bit. */ -+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -+#define R_M32R_GNU_VTINHERIT 11 -+#define R_M32R_GNU_VTENTRY 12 -+/* M32R relocs use SHT_RELA. */ -+#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -+#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -+#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -+#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -+#define R_M32R_RELA_GNU_VTINHERIT 43 -+#define R_M32R_RELA_GNU_VTENTRY 44 -+#define R_M32R_REL32 45 /* PC relative 32 bit. */ -+ -+#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -+#define R_M32R_COPY 50 /* Copy symbol at runtime */ -+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -+#define R_M32R_RELATIVE 53 /* Adjust by program base */ -+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned -+ low */ -+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed -+ low */ -+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to -+ GOT with unsigned low */ -+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to -+ GOT with signed low */ -+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to -+ GOT */ -+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT -+ with unsigned low */ -+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT -+ with signed low */ -+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -+#define R_M32R_NUM 256 /* Keep this the last entry. */ -+ -+ -+/* TILEPro relocations. */ -+#define R_TILEPRO_NONE 0 /* No reloc */ -+#define R_TILEPRO_32 1 /* Direct 32 bit */ -+#define R_TILEPRO_16 2 /* Direct 16 bit */ -+#define R_TILEPRO_8 3 /* Direct 8 bit */ -+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -+#define R_TILEPRO_LO16 7 /* Low 16 bit */ -+#define R_TILEPRO_HI16 8 /* High 16 bit */ -+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -+#define R_TILEPRO_COPY 10 /* Copy relocation */ -+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -+/* Relocs 56-59 are currently not defined. */ -+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ -+ -+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEPRO_NUM 130 -+ -+ -+/* TILE-Gx relocations. */ -+#define R_TILEGX_NONE 0 /* No reloc */ -+#define R_TILEGX_64 1 /* Direct 64 bit */ -+#define R_TILEGX_32 2 /* Direct 32 bit */ -+#define R_TILEGX_16 3 /* Direct 16 bit */ -+#define R_TILEGX_8 4 /* Direct 8 bit */ -+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -+#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -+#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -+#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -+#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -+#define R_TILEGX_COPY 16 /* Copy relocation */ -+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -+/* Relocs 66-71 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -+/* Relocs 76-77 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -+/* Relocs 90-91 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -+/* Relocs 94-99 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -+/* Relocs 104-105 are currently not defined. */ -+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ -+ -+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEGX_NUM 130 -+ -+#endif /* elf.h */ diff --git a/target/linux/generic/pending-3.18/212-byteshift_portability.patch b/target/linux/generic/pending-3.18/212-byteshift_portability.patch deleted file mode 100644 index 0f23ba9be9..0000000000 --- a/target/linux/generic/pending-3.18/212-byteshift_portability.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/tools/include/tools/be_byteshift.h -+++ b/tools/include/tools/be_byteshift.h -@@ -1,6 +1,10 @@ - #ifndef _TOOLS_BE_BYTESHIFT_H - #define _TOOLS_BE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include <stdint.h> - - static inline uint16_t __get_unaligned_be16(const uint8_t *p) ---- a/tools/include/tools/le_byteshift.h -+++ b/tools/include/tools/le_byteshift.h -@@ -1,6 +1,10 @@ - #ifndef _TOOLS_LE_BYTESHIFT_H - #define _TOOLS_LE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include <stdint.h> - - static inline uint16_t __get_unaligned_le16(const uint8_t *p) ---- /dev/null -+++ b/tools/include/tools/linux_types.h -@@ -0,0 +1,22 @@ -+#ifndef __LINUX_TYPES_H -+#define __LINUX_TYPES_H -+ -+#include <stdint.h> -+ -+typedef uint8_t __u8; -+typedef uint8_t __be8; -+typedef uint8_t __le8; -+ -+typedef uint16_t __u16; -+typedef uint16_t __be16; -+typedef uint16_t __le16; -+ -+typedef uint32_t __u32; -+typedef uint32_t __be32; -+typedef uint32_t __le32; -+ -+typedef uint64_t __u64; -+typedef uint64_t __be64; -+typedef uint64_t __le64; -+ -+#endif diff --git a/target/linux/generic/pending-3.18/213-x86_vdso_portability.patch b/target/linux/generic/pending-3.18/213-x86_vdso_portability.patch deleted file mode 100644 index 937ab9054d..0000000000 --- a/target/linux/generic/pending-3.18/213-x86_vdso_portability.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/arch/x86/vdso/vdso2c.c -+++ b/arch/x86/vdso/vdso2c.c -@@ -63,8 +63,8 @@ - - #include <tools/le_byteshift.h> - --#include <linux/elf.h> --#include <linux/types.h> -+#include <elf.h> -+#include <stdbool.h> - - const char *outfilename; - diff --git a/target/linux/generic/pending-3.18/214-spidev_h_portability.patch b/target/linux/generic/pending-3.18/214-spidev_h_portability.patch deleted file mode 100644 index 39fa32ffa2..0000000000 --- a/target/linux/generic/pending-3.18/214-spidev_h_portability.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/uapi/linux/spi/spidev.h -+++ b/include/uapi/linux/spi/spidev.h -@@ -112,7 +112,7 @@ struct spi_ioc_transfer { - - /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */ - #define SPI_MSGSIZE(N) \ -- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ - ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) - #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) - diff --git a/target/linux/generic/pending-3.18/220-gc_sections.patch b/target/linux/generic/pending-3.18/220-gc_sections.patch deleted file mode 100644 index d872949f8d..0000000000 --- a/target/linux/generic/pending-3.18/220-gc_sections.patch +++ /dev/null @@ -1,531 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> - -use -ffunction-sections, -fdata-sections and --gc-sections - -In combination with kernel symbol export stripping this significantly reduces -the kernel image size. Used on both ARM and MIPS architectures. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> -Signed-off-by: Jonas Gorski <jogo@openwrt.org> -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> ---- - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -89,10 +89,14 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - # - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe - cflags-y += -msoft-float --LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -+LDFLAGS_vmlinux += -G 0 -static -n -nostdlib --gc-sections - KBUILD_AFLAGS_MODULE += -mlong-calls - KBUILD_CFLAGS_MODULE += -mlong-calls - -+ifndef CONFIG_FUNCTION_TRACER -+KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections -+endif -+ - # - # pass -msoft-float to GAS if it supports it. However on newer binutils - # (specifically newer than 2.24.51.20140728) we then also need to explicitly ---- a/arch/mips/kernel/vmlinux.lds.S -+++ b/arch/mips/kernel/vmlinux.lds.S -@@ -67,7 +67,7 @@ SECTIONS - /* Exception table for data bus errors */ - __dbe_table : { - __start___dbe_table = .; -- *(__dbe_table) -+ KEEP(*(__dbe_table)) - __stop___dbe_table = .; - } - -@@ -112,7 +112,7 @@ SECTIONS - . = ALIGN(4); - .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) { - __mips_machines_start = .; -- *(.mips.machines.init) -+ KEEP(*(.mips.machines.init)) - __mips_machines_end = .; - } - ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -89,7 +89,7 @@ - #ifdef CONFIG_FTRACE_MCOUNT_RECORD - #define MCOUNT_REC() . = ALIGN(8); \ - VMLINUX_SYMBOL(__start_mcount_loc) = .; \ -- *(__mcount_loc) \ -+ KEEP(*(__mcount_loc)) \ - VMLINUX_SYMBOL(__stop_mcount_loc) = .; - #else - #define MCOUNT_REC() -@@ -97,7 +97,7 @@ - - #ifdef CONFIG_TRACE_BRANCH_PROFILING - #define LIKELY_PROFILE() VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \ -- *(_ftrace_annotated_branch) \ -+ KEEP(*(_ftrace_annotated_branch)) \ - VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .; - #else - #define LIKELY_PROFILE() -@@ -105,7 +105,7 @@ - - #ifdef CONFIG_PROFILE_ALL_BRANCHES - #define BRANCH_PROFILE() VMLINUX_SYMBOL(__start_branch_profile) = .; \ -- *(_ftrace_branch) \ -+ KEEP(*(_ftrace_branch)) \ - VMLINUX_SYMBOL(__stop_branch_profile) = .; - #else - #define BRANCH_PROFILE() -@@ -114,7 +114,7 @@ - #ifdef CONFIG_KPROBES - #define KPROBE_BLACKLIST() . = ALIGN(8); \ - VMLINUX_SYMBOL(__start_kprobe_blacklist) = .; \ -- *(_kprobe_blacklist) \ -+ KEEP(*(_kprobe_blacklist)) \ - VMLINUX_SYMBOL(__stop_kprobe_blacklist) = .; - #else - #define KPROBE_BLACKLIST() -@@ -123,7 +123,7 @@ - #ifdef CONFIG_EVENT_TRACING - #define FTRACE_EVENTS() . = ALIGN(8); \ - VMLINUX_SYMBOL(__start_ftrace_events) = .; \ -- *(_ftrace_events) \ -+ KEEP(*(_ftrace_events)) \ - VMLINUX_SYMBOL(__stop_ftrace_events) = .; - #else - #define FTRACE_EVENTS() -@@ -131,7 +131,7 @@ - - #ifdef CONFIG_TRACING - #define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .; \ -- *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \ -+ KEEP(*(__trace_printk_fmt)) /* Trace_printk fmt' pointer */ \ - VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .; - #define TRACEPOINT_STR() VMLINUX_SYMBOL(__start___tracepoint_str) = .; \ - *(__tracepoint_str) /* Trace_printk fmt' pointer */ \ -@@ -144,7 +144,7 @@ - #ifdef CONFIG_FTRACE_SYSCALLS - #define TRACE_SYSCALLS() . = ALIGN(8); \ - VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ -- *(__syscalls_metadata) \ -+ KEEP(*(__syscalls_metadata)) \ - VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; - #else - #define TRACE_SYSCALLS() -@@ -158,8 +158,8 @@ - #define _OF_TABLE_1(name) \ - . = ALIGN(8); \ - VMLINUX_SYMBOL(__##name##_of_table) = .; \ -- *(__##name##_of_table) \ -- *(__##name##_of_table_end) -+ KEEP(*(__##name##_of_table)) \ -+ KEEP(*(__##name##_of_table_end)) - - #define CLKSRC_OF_TABLES() OF_TABLE(CONFIG_CLKSRC_OF, clksrc) - #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip) -@@ -171,7 +171,7 @@ - #define KERNEL_DTB() \ - STRUCT_ALIGN(); \ - VMLINUX_SYMBOL(__dtb_start) = .; \ -- *(.dtb.init.rodata) \ -+ KEEP(*(.dtb.init.rodata)) \ - VMLINUX_SYMBOL(__dtb_end) = .; - - /* .data section */ -@@ -187,16 +187,17 @@ - /* implement dynamic printk debug */ \ - . = ALIGN(8); \ - VMLINUX_SYMBOL(__start___jump_table) = .; \ -- *(__jump_table) \ -+ KEEP(*(__jump_table)) \ - VMLINUX_SYMBOL(__stop___jump_table) = .; \ - . = ALIGN(8); \ - VMLINUX_SYMBOL(__start___verbose) = .; \ -- *(__verbose) \ -+ KEEP(*(__verbose)) \ - VMLINUX_SYMBOL(__stop___verbose) = .; \ - LIKELY_PROFILE() \ - BRANCH_PROFILE() \ - TRACE_PRINTKS() \ -- TRACEPOINT_STR() -+ TRACEPOINT_STR() \ -+ *(.data.[a-zA-Z_]*) - - /* - * Data section helpers -@@ -250,35 +251,35 @@ - /* PCI quirks */ \ - .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ -- *(.pci_fixup_early) \ -+ KEEP(*(.pci_fixup_early)) \ - VMLINUX_SYMBOL(__end_pci_fixups_early) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_header) = .; \ -- *(.pci_fixup_header) \ -+ KEEP(*(.pci_fixup_header)) \ - VMLINUX_SYMBOL(__end_pci_fixups_header) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \ -- *(.pci_fixup_final) \ -+ KEEP(*(.pci_fixup_final)) \ - VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \ -- *(.pci_fixup_enable) \ -+ KEEP(*(.pci_fixup_enable)) \ - VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \ -- *(.pci_fixup_resume) \ -+ KEEP(*(.pci_fixup_resume)) \ - VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .; \ -- *(.pci_fixup_resume_early) \ -+ KEEP(*(.pci_fixup_resume_early)) \ - VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \ -- *(.pci_fixup_suspend) \ -+ KEEP(*(.pci_fixup_suspend)) \ - VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \ - VMLINUX_SYMBOL(__start_pci_fixups_suspend_late) = .; \ -- *(.pci_fixup_suspend_late) \ -+ KEEP(*(.pci_fixup_suspend_late)) \ - VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \ - } \ - \ - /* Built-in firmware blobs */ \ - .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_builtin_fw) = .; \ -- *(.builtin_fw) \ -+ KEEP(*(.builtin_fw)) \ - VMLINUX_SYMBOL(__end_builtin_fw) = .; \ - } \ - \ -@@ -287,49 +288,49 @@ - /* Kernel symbol table: Normal symbols */ \ - __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab) = .; \ -- *(SORT(___ksymtab+*)) \ -+ KEEP(*(SORT(___ksymtab+*))) \ - VMLINUX_SYMBOL(__stop___ksymtab) = .; \ - } \ - \ - /* Kernel symbol table: GPL-only symbols */ \ - __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ -- *(SORT(___ksymtab_gpl+*)) \ -+ KEEP(*(SORT(___ksymtab_gpl+*))) \ - VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ - } \ - \ - /* Kernel symbol table: Normal unused symbols */ \ - __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ -- *(SORT(___ksymtab_unused+*)) \ -+ KEEP(*(SORT(___ksymtab_unused+*))) \ - VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ - } \ - \ - /* Kernel symbol table: GPL-only unused symbols */ \ - __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ -- *(SORT(___ksymtab_unused_gpl+*)) \ -+ KEEP(*(SORT(___ksymtab_unused_gpl+*))) \ - VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ - } \ - \ - /* Kernel symbol table: GPL-future-only symbols */ \ - __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ -- *(SORT(___ksymtab_gpl_future+*)) \ -+ KEEP(*(SORT(___ksymtab_gpl_future+*))) \ - VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ - } \ - \ - /* Kernel symbol table: Normal symbols */ \ - __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___kcrctab) = .; \ -- *(SORT(___kcrctab+*)) \ -+ KEEP(*(SORT(___kcrctab+*))) \ - VMLINUX_SYMBOL(__stop___kcrctab) = .; \ - } \ - \ - /* Kernel symbol table: GPL-only symbols */ \ - __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ -- *(SORT(___kcrctab_gpl+*)) \ -+ KEEP(*(SORT(___kcrctab_gpl+*))) \ - VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ - } \ - \ -@@ -343,14 +344,14 @@ - /* Kernel symbol table: GPL-only unused symbols */ \ - __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ -- *(SORT(___kcrctab_unused_gpl+*)) \ -+ KEEP(*(SORT(___kcrctab_unused_gpl+*))) \ - VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ - } \ - \ - /* Kernel symbol table: GPL-future-only symbols */ \ - __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ -- *(SORT(___kcrctab_gpl_future+*)) \ -+ KEEP(*(SORT(___kcrctab_gpl_future+*))) \ - VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ - } \ - \ -@@ -369,14 +370,14 @@ - /* Built-in module parameters. */ \ - __param : AT(ADDR(__param) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___param) = .; \ -- *(__param) \ -+ KEEP(*(__param)) \ - VMLINUX_SYMBOL(__stop___param) = .; \ - } \ - \ - /* Built-in module versions. */ \ - __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___modver) = .; \ -- *(__modver) \ -+ KEEP(*(__modver)) \ - VMLINUX_SYMBOL(__stop___modver) = .; \ - . = ALIGN((align)); \ - VMLINUX_SYMBOL(__end_rodata) = .; \ -@@ -432,7 +433,7 @@ - #define ENTRY_TEXT \ - ALIGN_FUNCTION(); \ - VMLINUX_SYMBOL(__entry_text_start) = .; \ -- *(.entry.text) \ -+ KEEP(*(.entry.text)) \ - VMLINUX_SYMBOL(__entry_text_end) = .; - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -@@ -460,7 +461,7 @@ - . = ALIGN(align); \ - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ex_table) = .; \ -- *(__ex_table) \ -+ KEEP(*(__ex_table)) \ - VMLINUX_SYMBOL(__stop___ex_table) = .; \ - } - -@@ -476,8 +477,8 @@ - #ifdef CONFIG_CONSTRUCTORS - #define KERNEL_CTORS() . = ALIGN(8); \ - VMLINUX_SYMBOL(__ctors_start) = .; \ -- *(.ctors) \ -- *(.init_array) \ -+ KEEP(*(.ctors)) \ -+ KEEP(*(.init_array)) \ - VMLINUX_SYMBOL(__ctors_end) = .; - #else - #define KERNEL_CTORS() -@@ -525,7 +526,7 @@ - #define SBSS(sbss_align) \ - . = ALIGN(sbss_align); \ - .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ -- *(.sbss) \ -+ *(.sbss .sbss.*) \ - *(.scommon) \ - } - -@@ -543,7 +544,7 @@ - BSS_FIRST_SECTIONS \ - *(.bss..page_aligned) \ - *(.dynbss) \ -- *(.bss) \ -+ *(.bss .bss.*) \ - *(COMMON) \ - } - -@@ -592,7 +593,7 @@ - . = ALIGN(8); \ - __bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___bug_table) = .; \ -- *(__bug_table) \ -+ KEEP(*(__bug_table)) \ - VMLINUX_SYMBOL(__stop___bug_table) = .; \ - } - #else -@@ -604,7 +605,7 @@ - . = ALIGN(4); \ - .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__tracedata_start) = .; \ -- *(.tracedata) \ -+ KEEP(*(.tracedata)) \ - VMLINUX_SYMBOL(__tracedata_end) = .; \ - } - #else -@@ -621,17 +622,17 @@ - #define INIT_SETUP(initsetup_align) \ - . = ALIGN(initsetup_align); \ - VMLINUX_SYMBOL(__setup_start) = .; \ -- *(.init.setup) \ -+ KEEP(*(.init.setup)) \ - VMLINUX_SYMBOL(__setup_end) = .; - - #define INIT_CALLS_LEVEL(level) \ - VMLINUX_SYMBOL(__initcall##level##_start) = .; \ -- *(.initcall##level##.init) \ -- *(.initcall##level##s.init) \ -+ KEEP(*(.initcall##level##.init)) \ -+ KEEP(*(.initcall##level##s.init)) \ - - #define INIT_CALLS \ - VMLINUX_SYMBOL(__initcall_start) = .; \ -- *(.initcallearly.init) \ -+ KEEP(*(.initcallearly.init)) \ - INIT_CALLS_LEVEL(0) \ - INIT_CALLS_LEVEL(1) \ - INIT_CALLS_LEVEL(2) \ -@@ -645,21 +646,21 @@ - - #define CON_INITCALL \ - VMLINUX_SYMBOL(__con_initcall_start) = .; \ -- *(.con_initcall.init) \ -+ KEEP(*(.con_initcall.init)) \ - VMLINUX_SYMBOL(__con_initcall_end) = .; - - #define SECURITY_INITCALL \ - VMLINUX_SYMBOL(__security_initcall_start) = .; \ -- *(.security_initcall.init) \ -+ KEEP(*(.security_initcall.init)) \ - VMLINUX_SYMBOL(__security_initcall_end) = .; - - #ifdef CONFIG_BLK_DEV_INITRD - #define INIT_RAM_FS \ - . = ALIGN(4); \ - VMLINUX_SYMBOL(__initramfs_start) = .; \ -- *(.init.ramfs) \ -+ KEEP(*(.init.ramfs)) \ - . = ALIGN(8); \ -- *(.init.ramfs.info) -+ KEEP(*(.init.ramfs.info)) - #else - #define INIT_RAM_FS - #endif ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -18,11 +18,16 @@ ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) - LDFLAGS_vmlinux += --be8 - LDFLAGS_MODULE += --be8 - endif -+LDFLAGS_vmlinux += --gc-sections - - OBJCOPYFLAGS :=-O binary -R .comment -S - GZFLAGS :=-9 - #KBUILD_CFLAGS +=-pipe - -+ifndef CONFIG_FUNCTION_TRACER -+KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections -+endif -+ - # Never generate .eh_frame - KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) - ---- a/arch/arm/kernel/vmlinux.lds.S -+++ b/arch/arm/kernel/vmlinux.lds.S -@@ -12,13 +12,13 @@ - #define PROC_INFO \ - . = ALIGN(4); \ - VMLINUX_SYMBOL(__proc_info_begin) = .; \ -- *(.proc.info.init) \ -+ KEEP(*(.proc.info.init)) \ - VMLINUX_SYMBOL(__proc_info_end) = .; - - #define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - VMLINUX_SYMBOL(__idmap_text_start) = .; \ -- *(.idmap.text) \ -+ KEEP(*(.idmap.text)) \ - VMLINUX_SYMBOL(__idmap_text_end) = .; \ - . = ALIGN(32); \ - VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ -@@ -93,7 +93,7 @@ SECTIONS - .text : { /* Real text segment */ - _stext = .; /* Text and read-only data */ - __exception_text_start = .; -- *(.exception.text) -+ KEEP(*(.exception.text)) - __exception_text_end = .; - IRQENTRY_TEXT - TEXT_TEXT -@@ -118,7 +118,7 @@ SECTIONS - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { - __start___ex_table = .; - #ifdef CONFIG_MMU -- *(__ex_table) -+ KEEP(*(__ex_table)) - #endif - __stop___ex_table = .; - } -@@ -130,12 +130,12 @@ SECTIONS - . = ALIGN(8); - .ARM.unwind_idx : { - __start_unwind_idx = .; -- *(.ARM.exidx*) -+ KEEP(*(.ARM.exidx*)) - __stop_unwind_idx = .; - } - .ARM.unwind_tab : { - __start_unwind_tab = .; -- *(.ARM.extab*) -+ KEEP(*(.ARM.extab*)) - __stop_unwind_tab = .; - } - #endif -@@ -154,14 +154,14 @@ SECTIONS - */ - __vectors_start = .; - .vectors 0 : AT(__vectors_start) { -- *(.vectors) -+ KEEP(*(.vectors)) - } - . = __vectors_start + SIZEOF(.vectors); - __vectors_end = .; - - __stubs_start = .; - .stubs 0x1000 : AT(__stubs_start) { -- *(.stubs) -+ KEEP(*(.stubs)) - } - . = __stubs_start + SIZEOF(.stubs); - __stubs_end = .; -@@ -175,24 +175,24 @@ SECTIONS - } - .init.arch.info : { - __arch_info_begin = .; -- *(.arch.info.init) -+ KEEP(*(.arch.info.init)) - __arch_info_end = .; - } - .init.tagtable : { - __tagtable_begin = .; -- *(.taglist.init) -+ KEEP(*(.taglist.init)) - __tagtable_end = .; - } - #ifdef CONFIG_SMP_ON_UP - .init.smpalt : { - __smpalt_begin = .; -- *(.alt.smp.init) -+ KEEP(*(.alt.smp.init)) - __smpalt_end = .; - } - #endif - .init.pv_table : { - __pv_table_begin = .; -- *(.pv_table) -+ KEEP(*(.pv_table)) - __pv_table_end = .; - } - .init.data : { ---- a/arch/arm/boot/compressed/Makefile -+++ b/arch/arm/boot/compressed/Makefile -@@ -122,6 +122,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y) - ORIG_CFLAGS := $(KBUILD_CFLAGS) - KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) - endif -+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) - - ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) - asflags-y := -DZIMAGE diff --git a/target/linux/generic/pending-3.18/221-module_exports.patch b/target/linux/generic/pending-3.18/221-module_exports.patch deleted file mode 100644 index f2cad7a028..0000000000 --- a/target/linux/generic/pending-3.18/221-module_exports.patch +++ /dev/null @@ -1,88 +0,0 @@ ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -54,6 +54,16 @@ - #define LOAD_OFFSET 0 - #endif - -+#ifndef SYMTAB_KEEP -+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) -+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) -+#endif -+ -+#ifndef SYMTAB_DISCARD -+#define SYMTAB_DISCARD -+#define SYMTAB_DISCARD_GPL -+#endif -+ - #include <linux/export.h> - - /* Align . to a 8 byte boundary equals to maximum function alignment. */ -@@ -288,14 +298,14 @@ - /* Kernel symbol table: Normal symbols */ \ - __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab) = .; \ -- KEEP(*(SORT(___ksymtab+*))) \ -+ SYMTAB_KEEP \ - VMLINUX_SYMBOL(__stop___ksymtab) = .; \ - } \ - \ - /* Kernel symbol table: GPL-only symbols */ \ - __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ -- KEEP(*(SORT(___ksymtab_gpl+*))) \ -+ SYMTAB_KEEP_GPL \ - VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ - } \ - \ -@@ -357,7 +367,7 @@ - \ - /* Kernel symbol table: strings */ \ - __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ -- *(__ksymtab_strings) \ -+ *(__ksymtab_strings+*) \ - } \ - \ - /* __*init sections */ \ -@@ -679,6 +689,8 @@ - EXIT_TEXT \ - EXIT_DATA \ - EXIT_CALL \ -+ SYMTAB_DISCARD \ -+ SYMTAB_DISCARD_GPL \ - *(.discard) \ - *(.discard.*) \ - } ---- a/scripts/Makefile.build -+++ b/scripts/Makefile.build -@@ -298,7 +298,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $( - # Linker scripts preprocessor (.lds.S -> .lds) - # --------------------------------------------------------------------------- - quiet_cmd_cpp_lds_S = LDS $@ -- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \ -+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -C -U$(ARCH) \ - -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< - - $(obj)/%.lds: $(src)/%.lds.S FORCE ---- a/include/linux/export.h -+++ b/include/linux/export.h -@@ -52,12 +52,19 @@ extern struct module __this_module; - #define __CRC_SYMBOL(sym, sec) - #endif - -+#ifdef MODULE -+#define __EXPORT_SUFFIX(sym) -+#else -+#define __EXPORT_SUFFIX(sym) "+" #sym -+#endif -+ - /* For every exported symbol, place a struct in the __ksymtab section */ - #define __EXPORT_SYMBOL(sym, sec) \ - extern typeof(sym) sym; \ - __CRC_SYMBOL(sym, sec) \ - static const char __kstrtab_##sym[] \ -- __attribute__((section("__ksymtab_strings"), aligned(1))) \ -+ __attribute__((section("__ksymtab_strings" \ -+ __EXPORT_SUFFIX(sym)), aligned(1))) \ - = VMLINUX_SYMBOL_STR(sym); \ - extern const struct kernel_symbol __ksymtab_##sym; \ - __visible const struct kernel_symbol __ksymtab_##sym \ diff --git a/target/linux/generic/pending-3.18/230-openwrt_lzma_options.patch b/target/linux/generic/pending-3.18/230-openwrt_lzma_options.patch deleted file mode 100644 index e59fdcd2e0..0000000000 --- a/target/linux/generic/pending-3.18/230-openwrt_lzma_options.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -325,7 +325,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) - - quiet_cmd_lzma = LZMA $@ - cmd_lzma = (cat $(filter-out FORCE,$^) | \ -- lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ -+ lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ - (rm -f $@ ; false) - - quiet_cmd_lzo = LZO $@ ---- a/scripts/gen_initramfs_list.sh -+++ b/scripts/gen_initramfs_list.sh -@@ -226,7 +226,7 @@ cpio_list= - output="/dev/stdout" - output_file="" - is_cpio_compressed= --compr="gzip -n -9 -f" -+compr="gzip -n -9 -f -" - - arg="$1" - case "$arg" in -@@ -242,13 +242,13 @@ case "$arg" in - output=${cpio_list} - echo "$output_file" | grep -q "\.gz$" \ - && [ -x "`which gzip 2> /dev/null`" ] \ -- && compr="gzip -n -9 -f" -+ && compr="gzip -n -9 -f -" - echo "$output_file" | grep -q "\.bz2$" \ - && [ -x "`which bzip2 2> /dev/null`" ] \ -- && compr="bzip2 -9 -f" -+ && compr="bzip2 -9 -f -" - echo "$output_file" | grep -q "\.lzma$" \ - && [ -x "`which lzma 2> /dev/null`" ] \ -- && compr="lzma -9 -f" -+ && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so" - echo "$output_file" | grep -q "\.xz$" \ - && [ -x "`which xz 2> /dev/null`" ] \ - && compr="xz --check=crc32 --lzma2=dict=1MiB" -@@ -315,7 +315,7 @@ if [ ! -z ${output_file} ]; then - if [ "${is_cpio_compressed}" = "compressed" ]; then - cat ${cpio_tfile} > ${output_file} - else -- (cat ${cpio_tfile} | ${compr} - > ${output_file}) \ -+ (cat ${cpio_tfile} | ${compr} > ${output_file}) \ - || (rm -f ${output_file} ; false) - fi - [ -z ${cpio_file} ] && rm ${cpio_tfile} ---- a/lib/decompress.c -+++ b/lib/decompress.c -@@ -48,6 +48,7 @@ static const struct compress_format comp - { {037, 0236}, "gzip", gunzip }, - { {0x42, 0x5a}, "bzip2", bunzip2 }, - { {0x5d, 0x00}, "lzma", unlzma }, -+ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, - { {0xfd, 0x37}, "xz", unxz }, - { {0x89, 0x4c}, "lzo", unlzo }, - { {0x02, 0x21}, "lz4", unlz4 }, diff --git a/target/linux/generic/pending-3.18/250-netfilter_depends.patch b/target/linux/generic/pending-3.18/250-netfilter_depends.patch deleted file mode 100644 index 47be4a0197..0000000000 --- a/target/linux/generic/pending-3.18/250-netfilter_depends.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -210,7 +210,6 @@ config NF_CONNTRACK_FTP - - config NF_CONNTRACK_H323 - tristate "H.323 protocol support" -- depends on (IPV6 || IPV6=n) - depends on NETFILTER_ADVANCED - help - H.323 is a VoIP signalling protocol from ITU-T. As one of the most -@@ -907,7 +906,6 @@ config NETFILTER_XT_TARGET_SECMARK - - config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' -- depends on (IPV6 || IPV6=n) - default m if NETFILTER_ADVANCED=n - ---help--- - This option adds a `TCPMSS' target, which allows you to alter the diff --git a/target/linux/generic/pending-3.18/251-sound_kconfig.patch b/target/linux/generic/pending-3.18/251-sound_kconfig.patch deleted file mode 100644 index c2ebacecd1..0000000000 --- a/target/linux/generic/pending-3.18/251-sound_kconfig.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/sound/core/Kconfig -+++ b/sound/core/Kconfig -@@ -10,13 +10,13 @@ config SND_DMAENGINE_PCM - tristate - - config SND_HWDEP -- tristate -+ tristate "Sound hardware support" - - config SND_RAWMIDI - tristate - - config SND_COMPRESS_OFFLOAD -- tristate -+ tristate "Compression offloading support" - - # To be effective this also requires INPUT - users should say: - # select SND_JACK if INPUT=y || INPUT=SND diff --git a/target/linux/generic/pending-3.18/252-mv_cesa_depends.patch b/target/linux/generic/pending-3.18/252-mv_cesa_depends.patch deleted file mode 100644 index fee28db120..0000000000 --- a/target/linux/generic/pending-3.18/252-mv_cesa_depends.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -164,6 +164,7 @@ config CRYPTO_DEV_MV_CESA - depends on PLAT_ORION - select CRYPTO_ALGAPI - select CRYPTO_AES -+ select CRYPTO_HASH2 - select CRYPTO_BLKCIPHER2 - select CRYPTO_HASH - help diff --git a/target/linux/generic/pending-3.18/253-ssb_b43_default_on.patch b/target/linux/generic/pending-3.18/253-ssb_b43_default_on.patch deleted file mode 100644 index 29d2a41a3b..0000000000 --- a/target/linux/generic/pending-3.18/253-ssb_b43_default_on.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -29,6 +29,7 @@ config SSB_SPROM - config SSB_BLOCKIO - bool - depends on SSB -+ default y - - config SSB_PCIHOST_POSSIBLE - bool -@@ -49,7 +50,7 @@ config SSB_PCIHOST - config SSB_B43_PCI_BRIDGE - bool - depends on SSB_PCIHOST -- default n -+ default y - - config SSB_PCMCIAHOST_POSSIBLE - bool ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -17,6 +17,7 @@ config BCMA - config BCMA_BLOCKIO - bool - depends on BCMA -+ default y - - config BCMA_HOST_PCI_POSSIBLE - bool diff --git a/target/linux/generic/pending-3.18/254-textsearch_kconfig_hacks.patch b/target/linux/generic/pending-3.18/254-textsearch_kconfig_hacks.patch deleted file mode 100644 index 3c3b1e1b53..0000000000 --- a/target/linux/generic/pending-3.18/254-textsearch_kconfig_hacks.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -320,16 +320,16 @@ config BCH_CONST_T - # Textsearch support is select'ed if needed - # - config TEXTSEARCH -- boolean -+ boolean "Textsearch support" - - config TEXTSEARCH_KMP -- tristate -+ tristate "Textsearch KMP" - - config TEXTSEARCH_BM -- tristate -+ tristate "Textsearch BM" - - config TEXTSEARCH_FSM -- tristate -+ tristate "Textsearch FSM" - - config BTREE - boolean diff --git a/target/linux/generic/pending-3.18/255-lib80211_kconfig_hacks.patch b/target/linux/generic/pending-3.18/255-lib80211_kconfig_hacks.patch deleted file mode 100644 index d8752359c7..0000000000 --- a/target/linux/generic/pending-3.18/255-lib80211_kconfig_hacks.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/wireless/Kconfig -+++ b/net/wireless/Kconfig -@@ -183,7 +183,7 @@ config CFG80211_WEXT - extensions with cfg80211-based drivers. - - config LIB80211 -- tristate -+ tristate "LIB80211" - default n - help - This options enables a library of common routines used -@@ -192,13 +192,16 @@ config LIB80211 - Drivers should select this themselves if needed. - - config LIB80211_CRYPT_WEP -- tristate -+ tristate "LIB80211_CRYPT_WEP" -+ select LIB80211 - - config LIB80211_CRYPT_CCMP -- tristate -+ tristate "LIB80211_CRYPT_CCMP" -+ select LIB80211 - - config LIB80211_CRYPT_TKIP -- tristate -+ tristate "LIB80211_CRYPT_TKIP" -+ select LIB80211 - - config LIB80211_DEBUG - bool "lib80211 debugging messages" diff --git a/target/linux/generic/pending-3.18/256-crypto_add_kconfig_prompts.patch b/target/linux/generic/pending-3.18/256-crypto_add_kconfig_prompts.patch deleted file mode 100644 index f9f6c0ea7b..0000000000 --- a/target/linux/generic/pending-3.18/256-crypto_add_kconfig_prompts.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -32,7 +32,7 @@ config CRYPTO_FIPS - this is. - - config CRYPTO_ALGAPI -- tristate -+ tristate "ALGAPI" - select CRYPTO_ALGAPI2 - help - This option provides the API for cryptographic algorithms. -@@ -41,7 +41,7 @@ config CRYPTO_ALGAPI2 - tristate - - config CRYPTO_AEAD -- tristate -+ tristate "AEAD" - select CRYPTO_AEAD2 - select CRYPTO_ALGAPI - -@@ -50,7 +50,7 @@ config CRYPTO_AEAD2 - select CRYPTO_ALGAPI2 - - config CRYPTO_BLKCIPHER -- tristate -+ tristate "BLKCIPHER" - select CRYPTO_BLKCIPHER2 - select CRYPTO_ALGAPI - -@@ -61,7 +61,7 @@ config CRYPTO_BLKCIPHER2 - select CRYPTO_WORKQUEUE - - config CRYPTO_HASH -- tristate -+ tristate "HASH" - select CRYPTO_HASH2 - select CRYPTO_ALGAPI - -@@ -70,7 +70,7 @@ config CRYPTO_HASH2 - select CRYPTO_ALGAPI2 - - config CRYPTO_RNG -- tristate -+ tristate "RNG" - select CRYPTO_RNG2 - select CRYPTO_ALGAPI - diff --git a/target/linux/generic/pending-3.18/257-wireless_ext_kconfig_hack.patch b/target/linux/generic/pending-3.18/257-wireless_ext_kconfig_hack.patch deleted file mode 100644 index daac5898ae..0000000000 --- a/target/linux/generic/pending-3.18/257-wireless_ext_kconfig_hack.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/net/wireless/Kconfig -+++ b/net/wireless/Kconfig -@@ -1,5 +1,5 @@ - config WIRELESS_EXT -- bool -+ bool "Wireless extensions" - - config WEXT_CORE - def_bool y -@@ -11,10 +11,10 @@ config WEXT_PROC - depends on WEXT_CORE - - config WEXT_SPY -- bool -+ bool "WEXT_SPY" - - config WEXT_PRIV -- bool -+ bool "WEXT_PRIV" - - config CFG80211 - tristate "cfg80211 - wireless configuration API" diff --git a/target/linux/generic/pending-3.18/258-netfilter_netlink_kconfig_hack.patch b/target/linux/generic/pending-3.18/258-netfilter_netlink_kconfig_hack.patch deleted file mode 100644 index 9d827c253b..0000000000 --- a/target/linux/generic/pending-3.18/258-netfilter_netlink_kconfig_hack.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -2,7 +2,7 @@ menu "Core Netfilter Configuration" - depends on NET && INET && NETFILTER - - config NETFILTER_NETLINK -- tristate -+ tristate "Netfilter NFNETLINK interface" - - config NETFILTER_NETLINK_ACCT - tristate "Netfilter NFACCT over NFNETLINK interface" diff --git a/target/linux/generic/pending-3.18/259-regmap_dynamic.patch b/target/linux/generic/pending-3.18/259-regmap_dynamic.patch deleted file mode 100644 index 0748919e66..0000000000 --- a/target/linux/generic/pending-3.18/259-regmap_dynamic.patch +++ /dev/null @@ -1,83 +0,0 @@ ---- a/drivers/base/regmap/Kconfig -+++ b/drivers/base/regmap/Kconfig -@@ -3,9 +3,8 @@ - # subsystems should select the appropriate symbols. - - config REGMAP -- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_MMIO || REGMAP_IRQ) - select IRQ_DOMAIN if REGMAP_IRQ -- bool -+ tristate - - config REGCACHE_COMPRESSED - select LZO_COMPRESS -@@ -14,18 +13,24 @@ config REGCACHE_COMPRESSED - - config REGMAP_I2C - tristate -+ select REGMAP - depends on I2C - - config REGMAP_SPI - tristate -+ select REGMAP -+ depends on SPI_MASTER - depends on SPI - - config REGMAP_SPMI -+ select REGMAP - tristate - depends on SPMI - - config REGMAP_MMIO - tristate -+ select REGMAP - - config REGMAP_IRQ -+ select REGMAP - bool ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -49,7 +49,7 @@ struct reg_default { - unsigned int def; - }; - --#ifdef CONFIG_REGMAP -+#if IS_ENABLED(CONFIG_REGMAP) - - enum regmap_endian { - /* Unspecified -> 0 -> Backwards compatible default */ ---- a/drivers/base/regmap/Makefile -+++ b/drivers/base/regmap/Makefile -@@ -1,7 +1,11 @@ --obj-$(CONFIG_REGMAP) += regmap.o regcache.o --obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o --obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o --obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o -+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o -+ifdef CONFIG_DEBUG_FS -+regmap-core-objs += regmap-debugfs.o -+endif -+ifdef CONFIG_REGCACHE_COMPRESSED -+regmap-core-objs += regcache-lzo.o -+endif -+obj-$(CONFIG_REGMAP) += regmap-core.o - obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o - obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o - obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -13,6 +13,7 @@ - #include <linux/device.h> - #include <linux/slab.h> - #include <linux/export.h> -+#include <linux/module.h> - #include <linux/mutex.h> - #include <linux/err.h> - #include <linux/of.h> -@@ -2630,3 +2631,5 @@ static int __init regmap_initcall(void) - return 0; - } - postcore_initcall(regmap_initcall); -+ -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-3.18/260-crypto_test_dependencies.patch b/target/linux/generic/pending-3.18/260-crypto_test_dependencies.patch deleted file mode 100644 index 8a96fd9da7..0000000000 --- a/target/linux/generic/pending-3.18/260-crypto_test_dependencies.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -96,10 +96,10 @@ config CRYPTO_MANAGER - - config CRYPTO_MANAGER2 - def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) -- select CRYPTO_AEAD2 -- select CRYPTO_HASH2 -- select CRYPTO_BLKCIPHER2 -- select CRYPTO_PCOMP2 -+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_BLKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_PCOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS - - config CRYPTO_USER - tristate "Userspace cryptographic algorithm configuration" ---- a/crypto/algboss.c -+++ b/crypto/algboss.c -@@ -248,6 +248,9 @@ static int cryptomgr_schedule_test(struc - type = alg->cra_flags; - - /* This piece of crap needs to disappear into per-type test hooks. */ -+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS -+ type |= CRYPTO_ALG_TESTED; -+#else - if ((!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & - CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV) && - ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == -@@ -256,6 +259,7 @@ static int cryptomgr_schedule_test(struc - (!((type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) && - alg->cra_type == &crypto_nivaead_type && alg->cra_aead.ivsize)) - type |= CRYPTO_ALG_TESTED; -+#endif - - param->type = type; - diff --git a/target/linux/generic/pending-3.18/270-uapi-libc-compat-add-fallback-for-unsupported-libcs.patch b/target/linux/generic/pending-3.18/270-uapi-libc-compat-add-fallback-for-unsupported-libcs.patch deleted file mode 100644 index 67895995b2..0000000000 --- a/target/linux/generic/pending-3.18/270-uapi-libc-compat-add-fallback-for-unsupported-libcs.patch +++ /dev/null @@ -1,102 +0,0 @@ -From c6bdd0d302119819de72439972d0462c26ef9eda Mon Sep 17 00:00:00 2001 -From: Felix Janda <felix.janda@posteo.de> -Date: Sun, 12 Nov 2017 13:30:17 -0500 -Subject: uapi libc compat: add fallback for unsupported libcs - -libc-compat.h aims to prevent symbol collisions between uapi and libc -headers for each supported libc. This requires continuous coordination -between them. - -The goal of this commit is to improve the situation for libcs (such as -musl) which are not yet supported and/or do not wish to be explicitly -supported, while not affecting supported libcs. More precisely, with -this commit, unsupported libcs can request the suppression of any -specific uapi definition by defining the correspondings _UAPI_DEF_* -macro as 0. This can fix symbol collisions for them, as long as the -libc headers are included before the uapi headers. Inclusion in the -other order is outside the scope of this commit. - -All infrastructure in order to enable this fallback for unsupported -libcs is already in place, except that libc-compat.h unconditionally -defines all _UAPI_DEF_* macros to 1 for all unsupported libcs so that -any previous definitions are ignored. In order to fix this, this commit -merely makes these definitions conditional. - -This commit together with the musl libc commit - -http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258 - -fixes for example the following compiler errors when <linux/in6.h> is -included after musl's <netinet/in.h>: - -./linux/in6.h:32:8: error: redefinition of 'struct in6_addr' -./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6' -./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq' - -The comments referencing glibc are still correct, but this file is not -only used for glibc any more. - -Signed-off-by: Felix Janda <felix.janda@posteo.de> -Reviewed-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - include/uapi/linux/libc-compat.h | 55 +++++++++++++++++++++++++++++++++++++++- - 1 file changed, 54 insertions(+), 1 deletion(-) - ---- a/include/uapi/linux/libc-compat.h -+++ b/include/uapi/linux/libc-compat.h -@@ -110,27 +110,54 @@ - - /* If we did not see any headers from any supported C libraries, - * or we are being included in the kernel, then define everything -- * that we need. */ -+ * that we need. Check for previous __UAPI_* definitions to give -+ * unsupported C libraries a way to opt out of any kernel definition. */ - #else /* !defined(__GLIBC__) */ - - /* Definitions for in.h */ -+#ifndef __UAPI_DEF_IN_ADDR - #define __UAPI_DEF_IN_ADDR 1 -+#endif -+#ifndef __UAPI_DEF_IN_IPPROTO - #define __UAPI_DEF_IN_IPPROTO 1 -+#endif -+#ifndef __UAPI_DEF_IN_PKTINFO - #define __UAPI_DEF_IN_PKTINFO 1 -+#endif -+#ifndef __UAPI_DEF_IP_MREQ - #define __UAPI_DEF_IP_MREQ 1 -+#endif -+#ifndef __UAPI_DEF_SOCKADDR_IN - #define __UAPI_DEF_SOCKADDR_IN 1 -+#endif -+#ifndef __UAPI_DEF_IN_CLASS - #define __UAPI_DEF_IN_CLASS 1 -+#endif - - /* Definitions for in6.h */ -+#ifndef __UAPI_DEF_IN6_ADDR - #define __UAPI_DEF_IN6_ADDR 1 -+#endif -+#ifndef __UAPI_DEF_IN6_ADDR_ALT - #define __UAPI_DEF_IN6_ADDR_ALT 1 -+#endif -+#ifndef __UAPI_DEF_SOCKADDR_IN6 - #define __UAPI_DEF_SOCKADDR_IN6 1 -+#endif -+#ifndef __UAPI_DEF_IPV6_MREQ - #define __UAPI_DEF_IPV6_MREQ 1 -+#endif -+#ifndef __UAPI_DEF_IPPROTO_V6 - #define __UAPI_DEF_IPPROTO_V6 1 -+#endif -+#ifndef __UAPI_DEF_IPV6_OPTIONS - #define __UAPI_DEF_IPV6_OPTIONS 1 -+#endif - - /* Definitions for xattr.h */ -+#ifndef __UAPI_DEF_XATTR - #define __UAPI_DEF_XATTR 1 -+#endif - - #endif /* __GLIBC__ */ - diff --git a/target/linux/generic/pending-3.18/272-uapi-if_ether.h-prevent-redefinition-of-struct-ethhd.patch b/target/linux/generic/pending-3.18/272-uapi-if_ether.h-prevent-redefinition-of-struct-ethhd.patch deleted file mode 100644 index 6f7ba681c1..0000000000 --- a/target/linux/generic/pending-3.18/272-uapi-if_ether.h-prevent-redefinition-of-struct-ethhd.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 649affd04813c43e0a72886517fcfccd63230981 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Mon, 29 Jun 2015 16:53:03 +0200 -Subject: uapi/if_ether.h: prevent redefinition of struct ethhdr - -Musl provides its own ethhdr struct definition. Add a guard to prevent -its definition of the appropriate musl header has already been included. - -glibc does not implement this header, but when glibc will implement this -they can just define __UAPI_DEF_ETHHDR 0 to make it work with the -kernel. - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - include/uapi/linux/if_ether.h | 3 +++ - include/uapi/linux/libc-compat.h | 6 ++++++ - 2 files changed, 9 insertions(+) - ---- a/include/uapi/linux/if_ether.h -+++ b/include/uapi/linux/if_ether.h -@@ -22,6 +22,7 @@ - #define _UAPI_LINUX_IF_ETHER_H - - #include <linux/types.h> -+#include <linux/libc-compat.h> - - /* - * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble -@@ -135,11 +136,13 @@ - * This is an Ethernet frame header. - */ - -+#if __UAPI_DEF_ETHHDR - struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - __be16 h_proto; /* packet type ID field */ - } __attribute__((packed)); -+#endif - - - #endif /* _UAPI_LINUX_IF_ETHER_H */ ---- a/include/uapi/linux/libc-compat.h -+++ b/include/uapi/linux/libc-compat.h -@@ -161,4 +161,10 @@ - - #endif /* __GLIBC__ */ - -+/* Definitions for if_ether.h */ -+/* allow libcs like musl to deactivate this, glibc does not implement this. */ -+#ifndef __UAPI_DEF_ETHHDR -+#define __UAPI_DEF_ETHHDR 1 -+#endif -+ - #endif /* _UAPI_LIBC_COMPAT_H */ diff --git a/target/linux/generic/pending-3.18/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-3.18/300-mips_expose_boot_raw.patch deleted file mode 100644 index ab7c46f087..0000000000 --- a/target/linux/generic/pending-3.18/300-mips_expose_boot_raw.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Mark Miller <mark@mirell.org> - -This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on -certain Broadcom chipsets running CFE in order to load the kernel. - -Signed-off-by: Mark Miller <mark@mirell.org> -Acked-by: Rob Landley <rob@landley.net> ---- ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -895,9 +895,6 @@ config FW_ARC - config ARCH_MAY_HAVE_PC_FDC - bool - --config BOOT_RAW -- bool -- - config CEVT_BCM1480 - bool - -@@ -2506,6 +2503,18 @@ config USE_OF - config BUILTIN_DTB - bool - -+config BOOT_RAW -+ bool "Enable the kernel to be executed from the load address" -+ default n -+ help -+ Allow the kernel to be executed from the load address for -+ bootloaders which cannot read the ELF format. This places -+ a jump to start_kernel at the load address. -+ -+ If unsure, say N. -+ -+ -+ - endmenu - - config LOCKDEP_SUPPORT diff --git a/target/linux/generic/pending-3.18/301-mips_image_cmdline_hack.patch b/target/linux/generic/pending-3.18/301-mips_image_cmdline_hack.patch deleted file mode 100644 index 993363c30f..0000000000 --- a/target/linux/generic/pending-3.18/301-mips_image_cmdline_hack.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -991,6 +991,10 @@ config SYNC_R4K - config MIPS_MACHINE - def_bool n - -+config IMAGE_CMDLINE_HACK -+ bool "OpenWrt specific image command line hack" -+ default n -+ - config NO_IOPORT_MAP - def_bool n - ---- a/arch/mips/kernel/head.S -+++ b/arch/mips/kernel/head.S -@@ -80,6 +80,12 @@ FEXPORT(__kernel_entry) - j kernel_entry - #endif - -+#ifdef CONFIG_IMAGE_CMDLINE_HACK -+ .ascii "CMDLINE:" -+EXPORT(__image_cmdline) -+ .fill 0x400 -+#endif /* CONFIG_IMAGE_CMDLINE_HACK */ -+ - __REF - - NESTED(kernel_entry, 16, sp) # kernel entry point diff --git a/target/linux/generic/pending-3.18/302-mips_no_branch_likely.patch b/target/linux/generic/pending-3.18/302-mips_no_branch_likely.patch deleted file mode 100644 index 44c6b04fcf..0000000000 --- a/target/linux/generic/pending-3.18/302-mips_no_branch_likely.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -87,7 +87,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - # machines may also. Since BFD is incredibly buggy with respect to - # crossformat linking we rely on the elf2ecoff tool for format conversion. - # --cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib --gc-sections - KBUILD_AFLAGS_MODULE += -mlong-calls diff --git a/target/linux/generic/pending-3.18/304-mips_disable_fpu.patch b/target/linux/generic/pending-3.18/304-mips_disable_fpu.patch deleted file mode 100644 index a28ca3ebe2..0000000000 --- a/target/linux/generic/pending-3.18/304-mips_disable_fpu.patch +++ /dev/null @@ -1,105 +0,0 @@ -From: Manuel Lauss <manuel.lauss@gmail.com> -Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional -Date: Mon, 7 Apr 2014 12:57:04 +0200 -Message-Id: <1396868224-252888-2-git-send-email-manuel.lauss@gmail.com> - -This small patch makes the MIPS FPU emulator optional. The kernel -kills float-users on systems without a hardware FPU by sending a SIGILL. - -Disabling the emulator shrinks vmlinux by about 54kBytes (32bit, -optimizing for size). - -Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> ---- -v4: rediffed because of patch 1/2, should now work with micromips as well -v3: updated patch description with size savings. -v2: incorporated changes suggested by Jonas Gorski - force the fpu emulator on for micromips: relocating the parts - of the mmips code in the emulator to other areas would be a - much larger change; I went the cheap route instead with this. - - arch/mips/Kbuild | 2 +- - arch/mips/Kconfig | 14 ++++++++++++++ - arch/mips/include/asm/fpu.h | 5 +++-- - arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++ - 4 files changed, 33 insertions(+), 3 deletions(-) - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -2498,6 +2498,20 @@ config MIPS_O32_FP64_SUPPORT - - If unsure, say N. - -+config MIPS_FPU_EMULATOR -+ bool "MIPS FPU Emulator" -+ default y -+ help -+ This option lets you disable the built-in MIPS FPU (Coprocessor 1) -+ emulator, which handles floating-point instructions on processors -+ without a hardware FPU. It is generally a good idea to keep the -+ emulator built-in, unless you are perfectly sure you have a -+ complete soft-float environment. With the emulator disabled, all -+ users of float operations will be killed with an illegal instr- -+ uction exception. -+ -+ Say Y, please. -+ - config USE_OF - bool - select OF ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -275,7 +275,7 @@ OBJCOPYFLAGS += --remove-section=.regin - head-y := arch/mips/kernel/head.o - - libs-y += arch/mips/lib/ --libs-y += arch/mips/math-emu/ -+libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/ - - # See arch/mips/Kbuild for content of core part of the kernel - core-y += arch/mips/ ---- a/arch/mips/include/asm/fpu.h -+++ b/arch/mips/include/asm/fpu.h -@@ -169,8 +169,10 @@ static inline int init_fpu(void) - ret = __own_fpu(); - if (!ret) - _init_fpu(); -- } else -+ } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) - fpu_emulator_init_fpu(); -+ else -+ ret = SIGILL; - - return ret; - } ---- a/arch/mips/include/asm/fpu_emulator.h -+++ b/arch/mips/include/asm/fpu_emulator.h -@@ -30,6 +30,7 @@ - #include <asm/local.h> - #include <asm/processor.h> - -+#ifdef CONFIG_MIPS_FPU_EMULATOR - #ifdef CONFIG_DEBUG_FS - - struct mips_fpu_emulator_stats { -@@ -65,6 +66,20 @@ extern int do_dsemulret(struct pt_regs * - extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, - struct mips_fpu_struct *ctx, int has_fpu, - void *__user *fault_addr); -+#else /* no CONFIG_MIPS_FPU_EMULATOR */ -+static inline int do_dsemulret(struct pt_regs *xcp) -+{ -+ return 0; /* 0 means error, should never get here anyway */ -+} -+ -+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp, -+ struct mips_fpu_struct *ctx, int has_fpu, -+ void *__user *fault_addr) -+{ -+ return SIGILL; /* we don't speak MIPS FPU */ -+} -+#endif /* CONFIG_MIPS_FPU_EMULATOR */ -+ - int process_fpemu_return(int sig, void __user *fault_addr); - int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, - unsigned long *contpc); diff --git a/target/linux/generic/pending-3.18/305-mips_module_reloc.patch b/target/linux/generic/pending-3.18/305-mips_module_reloc.patch deleted file mode 100644 index 6fe73178f6..0000000000 --- a/target/linux/generic/pending-3.18/305-mips_module_reloc.patch +++ /dev/null @@ -1,361 +0,0 @@ ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -90,8 +90,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib --gc-sections -+ifdef CONFIG_64BIT - KBUILD_AFLAGS_MODULE += -mlong-calls - KBUILD_CFLAGS_MODULE += -mlong-calls -+else -+ ifdef CONFIG_DYNAMIC_FTRACE -+ KBUILD_AFLAGS_MODULE += -mlong-calls -+ KBUILD_CFLAGS_MODULE += -mlong-calls -+ else -+ KBUILD_AFLAGS_MODULE += -mno-long-calls -+ KBUILD_CFLAGS_MODULE += -mno-long-calls -+ endif -+endif - - ifndef CONFIG_FUNCTION_TRACER - KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections ---- a/arch/mips/include/asm/module.h -+++ b/arch/mips/include/asm/module.h -@@ -11,6 +11,11 @@ struct mod_arch_specific { - const struct exception_table_entry *dbe_start; - const struct exception_table_entry *dbe_end; - struct mips_hi16 *r_mips_hi16_list; -+ -+ void *phys_plt_tbl; -+ void *virt_plt_tbl; -+ unsigned int phys_plt_offset; -+ unsigned int virt_plt_offset; - }; - - typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ ---- a/arch/mips/kernel/module.c -+++ b/arch/mips/kernel/module.c -@@ -43,14 +43,222 @@ struct mips_hi16 { - static LIST_HEAD(dbe_list); - static DEFINE_SPINLOCK(dbe_lock); - --#ifdef MODULE_START -+/* -+ * Get the potential max trampolines size required of the init and -+ * non-init sections. Only used if we cannot find enough contiguous -+ * physically mapped memory to put the module into. -+ */ -+static unsigned int -+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -+ const char *secstrings, unsigned int symindex, bool is_init) -+{ -+ unsigned long ret = 0; -+ unsigned int i, j; -+ Elf_Sym *syms; -+ -+ /* Everything marked ALLOC (this includes the exported symbols) */ -+ for (i = 1; i < hdr->e_shnum; ++i) { -+ unsigned int info = sechdrs[i].sh_info; -+ -+ if (sechdrs[i].sh_type != SHT_REL -+ && sechdrs[i].sh_type != SHT_RELA) -+ continue; -+ -+ /* Not a valid relocation section? */ -+ if (info >= hdr->e_shnum) -+ continue; -+ -+ /* Don't bother with non-allocated sections */ -+ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -+ continue; -+ -+ /* If it's called *.init*, and we're not init, we're -+ not interested */ -+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -+ != is_init) -+ continue; -+ -+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -+ if (sechdrs[i].sh_type == SHT_REL) { -+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rel[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } else { -+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rela[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+#ifndef MODULE_START -+static void *alloc_phys(unsigned long size) -+{ -+ unsigned order; -+ struct page *page; -+ struct page *p; -+ -+ size = PAGE_ALIGN(size); -+ order = get_order(size); -+ -+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -+ __GFP_THISNODE, order); -+ if (!page) -+ return NULL; -+ -+ split_page(page, order); -+ -+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -+ __free_page(p); -+ -+ return page_address(page); -+} -+#endif -+ -+static void free_phys(void *ptr, unsigned long size) -+{ -+ struct page *page; -+ struct page *end; -+ -+ page = virt_to_page(ptr); -+ end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT); -+ -+ for (; page < end; ++page) -+ __free_page(page); -+} -+ -+ - void *module_alloc(unsigned long size) - { -+#ifdef MODULE_START - return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, - GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, - __builtin_return_address(0)); -+#else -+ void *ptr; -+ -+ if (size == 0) -+ return NULL; -+ -+ ptr = alloc_phys(size); -+ -+ /* If we failed to allocate physically contiguous memory, -+ * fall back to regular vmalloc. The module loader code will -+ * create jump tables to handle long jumps */ -+ if (!ptr) -+ return vmalloc(size); -+ -+ return ptr; -+#endif - } -+ -+static inline bool is_phys_addr(void *ptr) -+{ -+#ifdef CONFIG_64BIT -+ return (KSEGX((unsigned long)ptr) == CKSEG0); -+#else -+ return (KSEGX(ptr) == KSEG0); - #endif -+} -+ -+/* Free memory returned from module_alloc */ -+void module_free(struct module *mod, void *module_region) -+{ -+ if (is_phys_addr(module_region)) { -+ if (mod->module_init == module_region) -+ free_phys(module_region, mod->init_size); -+ else if (mod->module_core == module_region) -+ free_phys(module_region, mod->core_size); -+ else -+ BUG(); -+ } else { -+ vfree(module_region); -+ } -+} -+ -+static void *__module_alloc(int size, bool phys) -+{ -+ void *ptr; -+ -+ if (phys) -+ ptr = kmalloc(size, GFP_KERNEL); -+ else -+ ptr = vmalloc(size); -+ return ptr; -+} -+ -+static void __module_free(void *ptr) -+{ -+ if (is_phys_addr(ptr)) -+ kfree(ptr); -+ else -+ vfree(ptr); -+} -+ -+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -+ char *secstrings, struct module *mod) -+{ -+ unsigned int symindex = 0; -+ unsigned int core_size, init_size; -+ int i; -+ -+ mod->arch.phys_plt_offset = 0; -+ mod->arch.virt_plt_offset = 0; -+ mod->arch.phys_plt_tbl = NULL; -+ mod->arch.virt_plt_tbl = NULL; -+ -+ if (IS_ENABLED(CONFIG_64BIT)) -+ return 0; -+ -+ for (i = 1; i < hdr->e_shnum; i++) -+ if (sechdrs[i].sh_type == SHT_SYMTAB) -+ symindex = i; -+ -+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -+ -+ if ((core_size + init_size) == 0) -+ return 0; -+ -+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -+ if (!mod->arch.phys_plt_tbl) -+ return -ENOMEM; -+ -+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -+ if (!mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ return -ENOMEM; -+ } -+ -+ return 0; -+} - - int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) - { -@@ -64,8 +272,39 @@ static int apply_r_mips_32_rel(struct mo - return 0; - } - -+static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -+ void *start, Elf_Addr v) -+{ -+ unsigned *tramp = start + *plt_offset; -+ *plt_offset += 4 * sizeof(int); -+ -+ /* adjust carry for addiu */ -+ if (v & 0x00008000) -+ v += 0x10000; -+ -+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -+ tramp[2] = 0x03200008; /* jr t9 */ -+ tramp[3] = 0x00000000; /* nop */ -+ -+ return (Elf_Addr) tramp; -+} -+ -+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) -+{ -+ if (is_phys_addr(location)) -+ return add_plt_entry_to(&me->arch.phys_plt_offset, -+ me->arch.phys_plt_tbl, v); -+ else -+ return add_plt_entry_to(&me->arch.virt_plt_offset, -+ me->arch.virt_plt_tbl, v); -+ -+} -+ - static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) - { -+ u32 ofs = *location & 0x03ffffff; -+ - if (v % 4) { - pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", - me->name); -@@ -73,14 +312,17 @@ static int apply_r_mips_26_rel(struct mo - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -- printk(KERN_ERR -- "module %s: relocation overflow\n", -- me->name); -- return -ENOEXEC; -+ v = add_plt_entry(me, location, v + (ofs << 2)); -+ if (!v) { -+ printk(KERN_ERR -+ "module %s: relocation overflow\n", me->name); -+ return -ENOEXEC; -+ } -+ ofs = 0; - } - - *location = (*location & ~0x03ffffff) | -- ((*location + (v >> 2)) & 0x03ffffff); -+ ((ofs + (v >> 2)) & 0x03ffffff); - - return 0; - } -@@ -287,9 +529,36 @@ int module_finalize(const Elf_Ehdr *hdr, - list_add(&me->arch.dbe_list, &dbe_list); - spin_unlock_irq(&dbe_lock); - } -+ -+ /* Get rid of the fixup trampoline if we're running the module -+ * from physically mapped address space */ -+ if (me->arch.phys_plt_offset == 0) { -+ __module_free(me->arch.phys_plt_tbl); -+ me->arch.phys_plt_tbl = NULL; -+ } -+ if (me->arch.virt_plt_offset == 0) { -+ __module_free(me->arch.virt_plt_tbl); -+ me->arch.virt_plt_tbl = NULL; -+ } -+ - return 0; - } - -+void module_arch_freeing_init(struct module *mod) -+{ -+ if (mod->state == MODULE_STATE_LIVE) -+ return; -+ -+ if (mod->arch.phys_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ } -+ if (mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.virt_plt_tbl); -+ mod->arch.virt_plt_tbl = NULL; -+ } -+} -+ - void module_arch_cleanup(struct module *mod) - { - spin_lock_irq(&dbe_lock); diff --git a/target/linux/generic/pending-3.18/306-mips_mem_functions_performance.patch b/target/linux/generic/pending-3.18/306-mips_mem_functions_performance.patch deleted file mode 100644 index 9818677425..0000000000 --- a/target/linux/generic/pending-3.18/306-mips_mem_functions_performance.patch +++ /dev/null @@ -1,83 +0,0 @@ ---- a/arch/mips/include/asm/string.h -+++ b/arch/mips/include/asm/string.h -@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ - - #define __HAVE_ARCH_MEMSET - extern void *memset(void *__s, int __c, size_t __count); -+#define memset(__s, __c, len) \ -+({ \ -+ size_t __len = (len); \ -+ void *__ret; \ -+ if (__builtin_constant_p(len) && __len >= 64) \ -+ __ret = memset((__s), (__c), __len); \ -+ else \ -+ __ret = __builtin_memset((__s), (__c), __len); \ -+ __ret; \ -+}) - - #define __HAVE_ARCH_MEMCPY - extern void *memcpy(void *__to, __const__ void *__from, size_t __n); -+#define memcpy(dst, src, len) \ -+({ \ -+ size_t __len = (len); \ -+ void *__ret; \ -+ if (__builtin_constant_p(len) && __len >= 64) \ -+ __ret = memcpy((dst), (src), __len); \ -+ else \ -+ __ret = __builtin_memcpy((dst), (src), __len); \ -+ __ret; \ -+}) - - #define __HAVE_ARCH_MEMMOVE - extern void *memmove(void *__dest, __const__ void *__src, size_t __n); -+#define memmove(dst, src, len) \ -+({ \ -+ size_t __len = (len); \ -+ void *__ret; \ -+ if (__builtin_constant_p(len) && __len >= 64) \ -+ __ret = memmove((dst), (src), __len); \ -+ else \ -+ __ret = __builtin_memmove((dst), (src), __len); \ -+ __ret; \ -+}) -+ -+#define __HAVE_ARCH_MEMCMP -+#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len)) - - #endif /* _ASM_STRING_H */ ---- a/arch/mips/lib/Makefile -+++ b/arch/mips/lib/Makefile -@@ -4,7 +4,7 @@ - - lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ - mips-atomic.o strlen_user.o strncpy_user.o \ -- strnlen_user.o uncached.o -+ strnlen_user.o uncached.o memcmp.o - - obj-y += iomap.o - obj-$(CONFIG_PCI) += iomap-pci.o ---- /dev/null -+++ b/arch/mips/lib/memcmp.c -@@ -0,0 +1,22 @@ -+/* -+ * copied from linux/lib/string.c -+ * -+ * Copyright (C) 1991, 1992 Linus Torvalds -+ */ -+ -+#include <linux/module.h> -+#include <linux/string.h> -+ -+#undef memcmp -+int memcmp(const void *cs, const void *ct, size_t count) -+{ -+ const unsigned char *su1, *su2; -+ int res = 0; -+ -+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) -+ if ((res = *su1 - *su2) != 0) -+ break; -+ return res; -+} -+EXPORT_SYMBOL(memcmp); -+ diff --git a/target/linux/generic/pending-3.18/307-mips_highmem_offset.patch b/target/linux/generic/pending-3.18/307-mips_highmem_offset.patch deleted file mode 100644 index 5a7dc9cee9..0000000000 --- a/target/linux/generic/pending-3.18/307-mips_highmem_offset.patch +++ /dev/null @@ -1,17 +0,0 @@ -Adjust highmem offset to 0x10000000 to ensure that all kmalloc allocations -stay within the same 256M boundary. This ensures that -mlong-calls is not -needed on systems with more than 256M RAM. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- ---- a/arch/mips/include/asm/mach-generic/spaces.h -+++ b/arch/mips/include/asm/mach-generic/spaces.h -@@ -44,7 +44,7 @@ - * Memory above this physical address will be considered highmem. - */ - #ifndef HIGHMEM_START --#define HIGHMEM_START _AC(0x20000000, UL) -+#define HIGHMEM_START _AC(0x10000000, UL) - #endif - - #endif /* CONFIG_32BIT */ diff --git a/target/linux/generic/pending-3.18/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-3.18/310-arm_module_unresolved_weak_sym.patch deleted file mode 100644 index 9210c1d2d3..0000000000 --- a/target/linux/generic/pending-3.18/310-arm_module_unresolved_weak_sym.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/arch/arm/kernel/module.c -+++ b/arch/arm/kernel/module.c -@@ -83,6 +83,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons - return -ENOEXEC; - } - -+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && -+ ELF_ST_BIND(sym->st_info) == STB_WEAK) -+ continue; -+ - loc = dstsec->sh_addr + rel->r_offset; - - switch (ELF32_R_TYPE(rel->r_info)) { diff --git a/target/linux/generic/pending-3.18/320-ppc4xx_optimization.patch b/target/linux/generic/pending-3.18/320-ppc4xx_optimization.patch deleted file mode 100644 index 8673de4df2..0000000000 --- a/target/linux/generic/pending-3.18/320-ppc4xx_optimization.patch +++ /dev/null @@ -1,31 +0,0 @@ -Upstream doesn't optimize the kernel and bootwrappers for ppc44x because -they still want to support gcc 3.3 -- well, we don't. - ---- a/arch/powerpc/Makefile -+++ b/arch/powerpc/Makefile -@@ -203,7 +203,8 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y) - KBUILD_CFLAGS += -mno-sched-epilog - endif - --cpu-as-$(CONFIG_4xx) += -Wa,-m405 -+cpu-as-$(CONFIG_40x) += -Wa,-m405 -+cpu-as-$(CONFIG_44x) += -Wa,-m440 - cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec - cpu-as-$(CONFIG_E200) += -Wa,-me200 - ---- a/arch/powerpc/boot/Makefile -+++ b/arch/powerpc/boot/Makefile -@@ -45,10 +45,10 @@ BOOTCFLAGS += -I$(obj) -I$(srctree)/$(ob - DTC_FLAGS ?= -p 1024 - - $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 --$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 -+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 - $(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405 --$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 --$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 -+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440 -+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440 - $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 - $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 - $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 diff --git a/target/linux/generic/pending-3.18/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/pending-3.18/321-powerpc_crtsavres_prereq.patch deleted file mode 100644 index ab6ea7beb2..0000000000 --- a/target/linux/generic/pending-3.18/321-powerpc_crtsavres_prereq.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/powerpc/Makefile -+++ b/arch/powerpc/Makefile -@@ -165,7 +165,6 @@ CPP = $(CC) -E $(KBUILD_CFLAGS) - - CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__ - --KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o - - ifeq ($(CONFIG_476FPE_ERR46),y) - KBUILD_LDFLAGS_MODULE += --ppc476-workaround \ diff --git a/target/linux/generic/pending-3.18/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-3.18/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch deleted file mode 100644 index 3a09572bde..0000000000 --- a/target/linux/generic/pending-3.18/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +++ /dev/null @@ -1,298 +0,0 @@ -From d8582dcf1ed66eee88a11e4760f42c0d6c8822be Mon Sep 17 00:00:00 2001 -From: Yousong Zhou <yszhou4tech@gmail.com> -Date: Sat, 31 Jan 2015 22:26:03 +0800 -Subject: [PATCH 331/331] MIPS: kexec: Accept command line parameters from - userspace. - -Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> ---- - arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++----- - arch/mips/kernel/machine_kexec.h | 20 +++++ - arch/mips/kernel/relocate_kernel.S | 21 +++-- - 3 files changed, 167 insertions(+), 27 deletions(-) - create mode 100644 arch/mips/kernel/machine_kexec.h - ---- a/arch/mips/kernel/machine_kexec.c -+++ b/arch/mips/kernel/machine_kexec.c -@@ -10,45 +10,145 @@ - #include <linux/mm.h> - #include <linux/delay.h> - -+#include <asm/bootinfo.h> - #include <asm/cacheflush.h> - #include <asm/page.h> -- --extern const unsigned char relocate_new_kernel[]; --extern const size_t relocate_new_kernel_size; -- --extern unsigned long kexec_start_address; --extern unsigned long kexec_indirection_page; -+#include <asm/uaccess.h> -+#include "machine_kexec.h" - - int (*_machine_kexec_prepare)(struct kimage *) = NULL; - void (*_machine_kexec_shutdown)(void) = NULL; - void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; -+ - #ifdef CONFIG_SMP - void (*relocated_kexec_smp_wait) (void *); - atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0); - #endif - --int --machine_kexec_prepare(struct kimage *kimage) -+static void machine_kexec_print_args(void) - { -+ unsigned long argc = (int)kexec_args[0]; -+ int i; -+ -+ pr_info("kexec_args[0] (argc): %lu\n", argc); -+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); -+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); -+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); -+ -+ for (i = 0; i < argc; i++) { -+ pr_info("kexec_argv[%d] = %p, %s\n", -+ i, kexec_argv[i], kexec_argv[i]); -+ } -+} -+ -+static void machine_kexec_init_argv(struct kimage *image) -+{ -+ void __user *buf = NULL; -+ size_t bufsz; -+ size_t size; -+ int i; -+ -+ bufsz = 0; -+ for (i = 0; i < image->nr_segments; i++) { -+ struct kexec_segment *seg; -+ -+ seg = &image->segment[i]; -+ if (seg->bufsz < 6) -+ continue; -+ -+ if (strncmp((char *) seg->buf, "kexec ", 6)) -+ continue; -+ -+ buf = seg->buf; -+ bufsz = seg->bufsz; -+ break; -+ } -+ -+ if (!buf) -+ return; -+ -+ size = KEXEC_COMMAND_LINE_SIZE; -+ size = min(size, bufsz); -+ if (size < bufsz) -+ pr_warn("kexec command line truncated to %zd bytes\n", size); -+ -+ /* Copy to kernel space */ -+ copy_from_user(kexec_argv_buf, buf, size); -+ kexec_argv_buf[size - 1] = 0; -+} -+ -+static void machine_kexec_parse_argv(struct kimage *image) -+{ -+ char *reboot_code_buffer; -+ int reloc_delta; -+ char *ptr; -+ int argc; -+ int i; -+ -+ ptr = kexec_argv_buf; -+ argc = 0; -+ -+ /* -+ * convert command line string to array of parameters -+ * (as bootloader does). -+ */ -+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { -+ if (*ptr == ' ') { -+ *ptr++ = '\0'; -+ continue; -+ } -+ -+ kexec_argv[argc++] = ptr; -+ ptr = strchr(ptr, ' '); -+ } -+ -+ if (!argc) -+ return; -+ -+ kexec_args[0] = argc; -+ kexec_args[1] = (unsigned long)kexec_argv; -+ kexec_args[2] = 0; -+ kexec_args[3] = 0; -+ -+ reboot_code_buffer = page_address(image->control_code_page); -+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; -+ -+ kexec_args[1] += reloc_delta; -+ for (i = 0; i < argc; i++) -+ kexec_argv[i] += reloc_delta; -+} -+ -+int machine_kexec_prepare(struct kimage *kimage) -+{ -+ /* -+ * Whenever arguments passed from kexec-tools, Init the arguments as -+ * the original ones to try avoiding booting failure. -+ */ -+ -+ kexec_args[0] = fw_arg0; -+ kexec_args[1] = fw_arg1; -+ kexec_args[2] = fw_arg2; -+ kexec_args[3] = fw_arg3; -+ -+ machine_kexec_init_argv(kimage); -+ machine_kexec_parse_argv(kimage); -+ - if (_machine_kexec_prepare) - return _machine_kexec_prepare(kimage); - return 0; - } - --void --machine_kexec_cleanup(struct kimage *kimage) -+void machine_kexec_cleanup(struct kimage *kimage) - { - } - --void --machine_shutdown(void) -+void machine_shutdown(void) - { - if (_machine_kexec_shutdown) - _machine_kexec_shutdown(); - } - --void --machine_crash_shutdown(struct pt_regs *regs) -+void machine_crash_shutdown(struct pt_regs *regs) - { - if (_machine_crash_shutdown) - _machine_crash_shutdown(regs); -@@ -66,10 +166,12 @@ machine_kexec(struct kimage *image) - unsigned long *ptr; - - reboot_code_buffer = -- (unsigned long)page_address(image->control_code_page); -+ (unsigned long)page_address(image->control_code_page); -+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); - - kexec_start_address = - (unsigned long) phys_to_virt(image->start); -+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); - - if (image->type == KEXEC_TYPE_DEFAULT) { - kexec_indirection_page = -@@ -77,9 +179,19 @@ machine_kexec(struct kimage *image) - } else { - kexec_indirection_page = (unsigned long)&image->head; - } -+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); - -- memcpy((void*)reboot_code_buffer, relocate_new_kernel, -- relocate_new_kernel_size); -+ pr_info("Where is memcpy: %p\n", memcpy); -+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", -+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); -+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, -+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); -+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, -+ KEXEC_RELOCATE_NEW_KERNEL_SIZE); -+ -+ pr_info("Before _print_args().\n"); -+ machine_kexec_print_args(); -+ pr_info("Before eval loop.\n"); - - /* - * The generic kexec code builds a page list with physical -@@ -101,15 +213,16 @@ machine_kexec(struct kimage *image) - /* - * we do not want to be bothered. - */ -+ pr_info("Before irq_disable.\n"); - local_irq_disable(); - -- printk("Will call new kernel at %08lx\n", image->start); -- printk("Bye ...\n"); -+ pr_info("Will call new kernel at %08lx\n", image->start); -+ pr_info("Bye ...\n"); - __flush_cache_all(); - #ifdef CONFIG_SMP - /* All secondary cpus now may jump to kexec_wait cycle */ - relocated_kexec_smp_wait = reboot_code_buffer + -- (void *)(kexec_smp_wait - relocate_new_kernel); -+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); - smp_wmb(); - atomic_set(&kexec_ready_to_reboot, 1); - #endif ---- /dev/null -+++ b/arch/mips/kernel/machine_kexec.h -@@ -0,0 +1,20 @@ -+#ifndef _MACHINE_KEXEC_H -+#define _MACHINE_KEXEC_H -+ -+#ifndef __ASSEMBLY__ -+extern const unsigned char kexec_relocate_new_kernel[]; -+extern unsigned long kexec_relocate_new_kernel_end; -+extern unsigned long kexec_start_address; -+extern unsigned long kexec_indirection_page; -+ -+extern char kexec_argv_buf[]; -+extern char *kexec_argv[]; -+ -+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) -+#endif /* !__ASSEMBLY__ */ -+ -+#define KEXEC_COMMAND_LINE_SIZE 256 -+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) -+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) -+ -+#endif ---- a/arch/mips/kernel/relocate_kernel.S -+++ b/arch/mips/kernel/relocate_kernel.S -@@ -12,8 +12,9 @@ - #include <asm/mipsregs.h> - #include <asm/stackframe.h> - #include <asm/addrspace.h> -+#include "machine_kexec.h" - --LEAF(relocate_new_kernel) -+LEAF(kexec_relocate_new_kernel) - PTR_L a0, arg0 - PTR_L a1, arg1 - PTR_L a2, arg2 -@@ -98,7 +99,7 @@ done: - #endif - /* jump to kexec_start_address */ - j s1 -- END(relocate_new_kernel) -+ END(kexec_relocate_new_kernel) - - #ifdef CONFIG_SMP - /* -@@ -184,9 +185,15 @@ kexec_indirection_page: - PTR 0 - .size kexec_indirection_page, PTRSIZE - --relocate_new_kernel_end: -+kexec_argv_buf: -+ EXPORT(kexec_argv_buf) -+ .skip KEXEC_COMMAND_LINE_SIZE -+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE -+ -+kexec_argv: -+ EXPORT(kexec_argv) -+ .skip KEXEC_ARGV_SIZE -+ .size kexec_argv, KEXEC_ARGV_SIZE - --relocate_new_kernel_size: -- EXPORT(relocate_new_kernel_size) -- PTR relocate_new_kernel_end - relocate_new_kernel -- .size relocate_new_kernel_size, PTRSIZE -+kexec_relocate_new_kernel_end: -+ EXPORT(kexec_relocate_new_kernel_end) diff --git a/target/linux/generic/pending-3.18/400-mtd-add-rootfs-split-support.patch b/target/linux/generic/pending-3.18/400-mtd-add-rootfs-split-support.patch deleted file mode 100644 index 0a6e134ed5..0000000000 --- a/target/linux/generic/pending-3.18/400-mtd-add-rootfs-split-support.patch +++ /dev/null @@ -1,171 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,23 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -30,9 +30,11 @@ - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> - #include <linux/of.h> -+#include <linux/magic.h> - #include <linux/err.h> - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* Our partition linked list */ - static LIST_HEAD(mtd_partitions); -@@ -46,13 +48,14 @@ struct mtd_part { - struct list_head list; - }; - -+static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); -+ - /* - * Given a pointer to the MTD object in the mtd_part structure, we can retrieve - * the pointer to that structure with this macro. - */ - #define PART(x) ((struct mtd_part *)(x)) - -- - /* - * MTD methods which simply translate the effective address and pass through - * to the _real_ device. -@@ -548,8 +551,10 @@ out_register: - return slave; - } - --int mtd_add_partition(struct mtd_info *master, const char *name, -- long long offset, long long length) -+ -+static int -+__mtd_add_partition(struct mtd_info *master, const char *name, -+ long long offset, long long length, bool dup_check) - { - struct mtd_partition part; - struct mtd_part *p, *new; -@@ -581,21 +586,24 @@ int mtd_add_partition(struct mtd_info *m - end = offset + length; - - mutex_lock(&mtd_partitions_mutex); -- list_for_each_entry(p, &mtd_partitions, list) -- if (p->master == master) { -- if ((start >= p->offset) && -- (start < (p->offset + p->mtd.size))) -- goto err_inv; -- -- if ((end >= p->offset) && -- (end < (p->offset + p->mtd.size))) -- goto err_inv; -- } -+ if (dup_check) { -+ list_for_each_entry(p, &mtd_partitions, list) -+ if (p->master == master) { -+ if ((start >= p->offset) && -+ (start < (p->offset + p->mtd.size))) -+ goto err_inv; -+ -+ if ((end >= p->offset) && -+ (end < (p->offset + p->mtd.size))) -+ goto err_inv; -+ } -+ } - - list_add(&new->list, &mtd_partitions); - mutex_unlock(&mtd_partitions_mutex); - - add_mtd_device(&new->mtd); -+ mtd_partition_split(master, new); - - return ret; - err_inv: -@@ -605,6 +613,12 @@ err_inv: - } - EXPORT_SYMBOL_GPL(mtd_add_partition); - -+int mtd_add_partition(struct mtd_info *master, const char *name, -+ long long offset, long long length) -+{ -+ return __mtd_add_partition(master, name, offset, length, true); -+} -+ - int mtd_del_partition(struct mtd_info *master, int partno) - { - struct mtd_part *slave, *next; -@@ -628,6 +642,35 @@ int mtd_del_partition(struct mtd_info *m - } - EXPORT_SYMBOL_GPL(mtd_del_partition); - -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_part *part) -+{ -+} -+ -+void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, -+ int offset, int size) -+{ -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && -+ config_enabled(CONFIG_MTD_SPLIT_FIRMWARE)) -+ split_firmware(master, part); -+ -+ arch_split_mtd_part(master, part->mtd.name, part->offset, -+ part->mtd.size); -+} - /* - * This function, given a master MTD object and a partition table, creates - * and registers slave MTD objects which are bound to the master according to -@@ -657,6 +700,7 @@ int add_mtd_partitions(struct mtd_info * - mutex_unlock(&mtd_partitions_mutex); - - add_mtd_device(&slave->mtd); -+ mtd_partition_split(master, slave); - - cur_offset = slave->offset + slave->mtd.size; - } ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -84,5 +84,7 @@ int mtd_add_partition(struct mtd_info *m - long long offset, long long length); - int mtd_del_partition(struct mtd_info *master, int partno); - uint64_t mtd_get_device_size(const struct mtd_info *mtd); -+extern void __weak arch_split_mtd_part(struct mtd_info *master, -+ const char *name, int offset, int size); - - #endif diff --git a/target/linux/generic/pending-3.18/401-mtd-add-support-for-different-partition-parser-types.patch b/target/linux/generic/pending-3.18/401-mtd-add-support-for-different-partition-parser-types.patch deleted file mode 100644 index 684234161a..0000000000 --- a/target/linux/generic/pending-3.18/401-mtd-add-support-for-different-partition-parser-types.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 02cff0ccaa6d364f5c1eeea83f47ac80ccc967d4 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos <juhosg@openwrt.org> -Date: Tue, 3 Sep 2013 18:11:50 +0200 -Subject: [PATCH] mtd: add support for different partition parser types - -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> ---- - drivers/mtd/mtdpart.c | 56 ++++++++++++++++++++++++++++++++++++++++ - include/linux/mtd/partitions.h | 11 ++++++++ - 2 files changed, 67 insertions(+) - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -730,6 +730,30 @@ static struct mtd_part_parser *get_parti - - #define put_partition_parser(p) do { module_put((p)->owner); } while (0) - -+static struct mtd_part_parser * -+get_partition_parser_by_type(enum mtd_parser_type type, -+ struct mtd_part_parser *start) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ p = list_prepare_entry(start, &part_parsers, list); -+ if (start) -+ put_partition_parser(start); -+ -+ list_for_each_entry_continue(p, &part_parsers, list) { -+ if (p->type == type && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ - void register_mtd_parser(struct mtd_part_parser *p) - { - spin_lock(&part_parser_lock); -@@ -845,6 +869,38 @@ int parse_mtd_partitions(struct mtd_info - return ret; - } - -+int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_part_parser *prev = NULL; -+ int ret = 0; -+ -+ while (1) { -+ struct mtd_part_parser *parser; -+ -+ parser = get_partition_parser_by_type(type, prev); -+ if (!parser) -+ break; -+ -+ ret = (*parser->parse_fn)(master, pparts, data); -+ -+ if (ret > 0) { -+ put_partition_parser(parser); -+ printk(KERN_NOTICE -+ "%d %s partitions found on MTD device %s\n", -+ ret, parser->name, master->name); -+ break; -+ } -+ -+ prev = parser; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type); -+ - int mtd_is_partition(const struct mtd_info *mtd) - { - struct mtd_part *part; ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -68,12 +68,17 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; - const char *name; - int (*parse_fn)(struct mtd_info *, struct mtd_partition **, - struct mtd_part_parser_data *); -+ enum mtd_parser_type type; - }; - - extern void register_mtd_parser(struct mtd_part_parser *parser); -@@ -87,4 +92,9 @@ uint64_t mtd_get_device_size(const struc - extern void __weak arch_split_mtd_part(struct mtd_info *master, - const char *name, int offset, int size); - -+int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data); -+ - #endif diff --git a/target/linux/generic/pending-3.18/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch b/target/linux/generic/pending-3.18/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch deleted file mode 100644 index dead0fbf5f..0000000000 --- a/target/linux/generic/pending-3.18/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -642,6 +642,37 @@ int mtd_del_partition(struct mtd_info *m - } - EXPORT_SYMBOL_GPL(mtd_del_partition); - -+static int -+run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type) -+{ -+ struct mtd_partition *parts; -+ int nr_parts; -+ int i; -+ -+ nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, &parts, -+ NULL); -+ if (nr_parts <= 0) -+ return nr_parts; -+ -+ if (WARN_ON(!parts)) -+ return 0; -+ -+ for (i = 0; i < nr_parts; i++) { -+ /* adjust partition offsets */ -+ parts[i].offset += slave->offset; -+ -+ __mtd_add_partition(slave->master, -+ parts[i].name, -+ parts[i].offset, -+ parts[i].size, -+ false); -+ } -+ -+ kfree(parts); -+ -+ return nr_parts; -+} -+ - #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME - #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME - #else -@@ -650,6 +681,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition); - - static void split_firmware(struct mtd_info *master, struct mtd_part *part) - { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); - } - - void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, -@@ -664,6 +696,12 @@ static void mtd_partition_split(struct m - if (rootfs_found) - return; - -+ if (!strcmp(part->mtd.name, "rootfs")) { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ rootfs_found = 1; -+ } -+ - if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && - config_enabled(CONFIG_MTD_SPLIT_FIRMWARE)) - split_firmware(master, part); ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -70,6 +70,8 @@ struct mtd_part_parser_data { - - enum mtd_parser_type { - MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, - }; - - struct mtd_part_parser { diff --git a/target/linux/generic/pending-3.18/403-mtd-hook-mtdsplit-to-Kbuild.patch b/target/linux/generic/pending-3.18/403-mtd-hook-mtdsplit-to-Kbuild.patch deleted file mode 100644 index 0cf1c38555..0000000000 --- a/target/linux/generic/pending-3.18/403-mtd-hook-mtdsplit-to-Kbuild.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -27,6 +27,8 @@ config MTD_SPLIT_FIRMWARE_NAME - depends on MTD_SPLIT_FIRMWARE - default "firmware" - -+source "drivers/mtd/mtdsplit/Kconfig" -+ - endmenu - - config MTD_TESTS ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -6,6 +6,8 @@ - obj-$(CONFIG_MTD) += mtd.o - mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o - obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o diff --git a/target/linux/generic/pending-3.18/404-mtd-add-more-helper-functions.patch b/target/linux/generic/pending-3.18/404-mtd-add-more-helper-functions.patch deleted file mode 100644 index b2f62c115d..0000000000 --- a/target/linux/generic/pending-3.18/404-mtd-add-more-helper-functions.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -446,14 +446,12 @@ static struct mtd_part *allocate_partiti - if (slave->offset == MTDPART_OFS_APPEND) - slave->offset = cur_offset; - if (slave->offset == MTDPART_OFS_NXTBLK) { -- slave->offset = cur_offset; -- if (mtd_mod_by_eb(cur_offset, master) != 0) { -- /* Round up to next erasesize */ -- slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; -+ /* Round up to next erasesize */ -+ slave->offset = mtd_roundup_to_eb(cur_offset, master); -+ if (slave->offset != cur_offset) - printk(KERN_NOTICE "Moving partition %d: " - "0x%012llx -> 0x%012llx\n", partno, - (unsigned long long)cur_offset, (unsigned long long)slave->offset); -- } - } - if (slave->offset == MTDPART_OFS_RETAIN) { - slave->offset = cur_offset; -@@ -673,6 +671,17 @@ run_parsers_by_type(struct mtd_part *sla - return nr_parts; - } - -+static inline unsigned long -+mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len) -+{ -+ unsigned long mask = mtd->erasesize - 1; -+ -+ len += offset & mask; -+ len = (len + mask) & ~mask; -+ len -= offset & mask; -+ return len; -+} -+ - #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME - #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME - #else -@@ -956,6 +965,24 @@ int mtd_is_partition(const struct mtd_in - } - EXPORT_SYMBOL_GPL(mtd_is_partition); - -+struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return (struct mtd_info *)mtd; -+ -+ return PART(mtd)->master; -+} -+EXPORT_SYMBOL_GPL(mtdpart_get_master); -+ -+uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return 0; -+ -+ return PART(mtd)->offset; -+} -+EXPORT_SYMBOL_GPL(mtdpart_get_offset); -+ - /* Returns the size of the entire flash chip */ - uint64_t mtd_get_device_size(const struct mtd_info *mtd) - { ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -90,6 +90,8 @@ int mtd_is_partition(const struct mtd_in - int mtd_add_partition(struct mtd_info *master, const char *name, - long long offset, long long length); - int mtd_del_partition(struct mtd_info *master, int partno); -+struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd); -+uint64_t mtdpart_get_offset(const struct mtd_info *mtd); - uint64_t mtd_get_device_size(const struct mtd_info *mtd); - extern void __weak arch_split_mtd_part(struct mtd_info *master, - const char *name, int offset, int size); ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -333,6 +333,24 @@ static inline uint32_t mtd_mod_by_eb(uin - return do_div(sz, mtd->erasesize); - } - -+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round up to next erase block */ -+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -+} -+ -+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round down to the start of the current erase block */ -+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -+} -+ - static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) - { - if (mtd->writesize_shift) diff --git a/target/linux/generic/pending-3.18/405-mtd-old-firmware-uimage-splitter.patch b/target/linux/generic/pending-3.18/405-mtd-old-firmware-uimage-splitter.patch deleted file mode 100644 index 7e74c4e538..0000000000 --- a/target/linux/generic/pending-3.18/405-mtd-old-firmware-uimage-splitter.patch +++ /dev/null @@ -1,70 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -27,6 +27,11 @@ config MTD_SPLIT_FIRMWARE_NAME - depends on MTD_SPLIT_FIRMWARE - default "firmware" - -+config MTD_UIMAGE_SPLIT -+ bool "Enable split support for firmware partitions containing a uImage" -+ depends on MTD_SPLIT_FIRMWARE -+ default y -+ - source "drivers/mtd/mtdsplit/Kconfig" - - endmenu ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -682,6 +682,37 @@ mtd_pad_erasesize(struct mtd_info *mtd, - return len; - } - -+#define UBOOT_MAGIC 0x27051956 -+ -+static void split_uimage(struct mtd_info *master, struct mtd_part *part) -+{ -+ struct { -+ __be32 magic; -+ __be32 pad[2]; -+ __be32 size; -+ } hdr; -+ size_t len; -+ -+ if (mtd_read(master, part->offset, sizeof(hdr), &len, (void *) &hdr)) -+ return; -+ -+ if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC)) -+ return; -+ -+ len = be32_to_cpu(hdr.size) + 0x40; -+ len = mtd_pad_erasesize(master, part->offset, len); -+ if (len + master->erasesize > part->mtd.size) -+ return; -+ -+ if (config_enabled(CONFIG_MTD_SPLIT_UIMAGE_FW)) -+ pr_err("Dedicated partitioner didn't split firmware partition, please fill a bug report!\n"); -+ else -+ pr_warn("Support for built-in firmware splitter will be removed, please use CONFIG_MTD_SPLIT_UIMAGE_FW\n"); -+ -+ __mtd_add_partition(master, "rootfs", part->offset + len, -+ part->mtd.size - len, false); -+} -+ - #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME - #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME - #else -@@ -690,7 +721,14 @@ mtd_pad_erasesize(struct mtd_info *mtd, - - static void split_firmware(struct mtd_info *master, struct mtd_part *part) - { -- run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+ int ret; -+ -+ ret = run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+ if (ret > 0) -+ return; -+ -+ if (config_enabled(CONFIG_MTD_UIMAGE_SPLIT)) -+ split_uimage(master, part); - } - - void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, diff --git a/target/linux/generic/pending-3.18/406-mtd-old-rootfs-squashfs-splitter.patch b/target/linux/generic/pending-3.18/406-mtd-old-rootfs-squashfs-splitter.patch deleted file mode 100644 index cc548efb60..0000000000 --- a/target/linux/generic/pending-3.18/406-mtd-old-rootfs-squashfs-splitter.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -18,6 +18,11 @@ config MTD_ROOTFS_ROOT_DEV - bool "Automatically set 'rootfs' partition to be root filesystem" - default y - -+config MTD_ROOTFS_SPLIT -+ bool "Automatically split 'rootfs' partition for squashfs" -+ select MTD_SPLIT -+ default y -+ - config MTD_SPLIT_FIRMWARE - bool "Automatically split firmware partition for kernel+rootfs" - default y ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -682,6 +682,47 @@ mtd_pad_erasesize(struct mtd_info *mtd, - return len; - } - -+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) -+{ -+ size_t squashfs_len; -+ int len, ret; -+ -+ ret = mtd_get_squashfs_len(master, offset, &squashfs_len); -+ if (ret) -+ return ret; -+ -+ len = mtd_pad_erasesize(master, offset, squashfs_len); -+ *split_offset = offset + len; -+ -+ return 0; -+} -+ -+static void split_rootfs_data(struct mtd_info *master, struct mtd_part *part) -+{ -+ unsigned int split_offset = 0; -+ unsigned int split_size; -+ int ret; -+ -+ ret = split_squashfs(master, part->offset, &split_offset); -+ if (ret) -+ return; -+ -+ if (split_offset <= 0) -+ return; -+ -+ if (config_enabled(CONFIG_MTD_SPLIT_SQUASHFS_ROOT)) -+ pr_err("Dedicated partitioner didn't create \"rootfs_data\" partition, please fill a bug report!\n"); -+ else -+ pr_warn("Support for built-in \"rootfs_data\" splitter will be removed, please use CONFIG_MTD_SPLIT_SQUASHFS_ROOT\n"); -+ -+ split_size = part->mtd.size - (split_offset - part->offset); -+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=0x%x, len=0x%x\n", -+ ROOTFS_SPLIT_NAME, split_offset, split_size); -+ -+ __mtd_add_partition(master, ROOTFS_SPLIT_NAME, split_offset, -+ split_size, false); -+} -+ - #define UBOOT_MAGIC 0x27051956 - - static void split_uimage(struct mtd_info *master, struct mtd_part *part) -@@ -744,7 +785,10 @@ static void mtd_partition_split(struct m - return; - - if (!strcmp(part->mtd.name, "rootfs")) { -- run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ int num = run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ if (num <= 0 && config_enabled(CONFIG_MTD_ROOTFS_SPLIT)) -+ split_rootfs_data(master, part); - - rootfs_found = 1; - } diff --git a/target/linux/generic/pending-3.18/410-mtd-move-forward-declaration-of-struct-mtd_info.patch b/target/linux/generic/pending-3.18/410-mtd-move-forward-declaration-of-struct-mtd_info.patch deleted file mode 100644 index 78ebbf88ca..0000000000 --- a/target/linux/generic/pending-3.18/410-mtd-move-forward-declaration-of-struct-mtd_info.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -35,6 +35,7 @@ - * Note: writeable partitions require their size and offset be - * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). - */ -+struct mtd_info; - - struct mtd_partition { - const char *name; /* identifier string */ -@@ -50,7 +51,6 @@ struct mtd_partition { - #define MTDPART_SIZ_FULL (0) - - --struct mtd_info; - struct device_node; - - /** diff --git a/target/linux/generic/pending-3.18/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/pending-3.18/411-mtd-partial_eraseblock_write.patch deleted file mode 100644 index 5d5c6ed5d3..0000000000 --- a/target/linux/generic/pending-3.18/411-mtd-partial_eraseblock_write.patch +++ /dev/null @@ -1,142 +0,0 @@ ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -36,6 +36,8 @@ - #include "mtdcore.h" - #include "mtdsplit/mtdsplit.h" - -+#define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */ -+ - /* Our partition linked list */ - static LIST_HEAD(mtd_partitions); - static DEFINE_MUTEX(mtd_partitions_mutex); -@@ -234,13 +236,61 @@ static int part_erase(struct mtd_info *m - struct mtd_part *part = PART(mtd); - int ret; - -+ -+ instr->partial_start = false; -+ if (mtd->flags & MTD_ERASE_PARTIAL) { -+ size_t readlen = 0; -+ u64 mtd_ofs; -+ -+ instr->erase_buf = kmalloc(part->master->erasesize, GFP_ATOMIC); -+ if (!instr->erase_buf) -+ return -ENOMEM; -+ -+ mtd_ofs = part->offset + instr->addr; -+ instr->erase_buf_ofs = do_div(mtd_ofs, part->master->erasesize); -+ -+ if (instr->erase_buf_ofs > 0) { -+ instr->addr -= instr->erase_buf_ofs; -+ ret = mtd_read(part->master, -+ instr->addr + part->offset, -+ part->master->erasesize, -+ &readlen, instr->erase_buf); -+ -+ instr->len += instr->erase_buf_ofs; -+ instr->partial_start = true; -+ } else { -+ mtd_ofs = part->offset + part->mtd.size; -+ instr->erase_buf_ofs = part->master->erasesize - -+ do_div(mtd_ofs, part->master->erasesize); -+ -+ if (instr->erase_buf_ofs > 0) { -+ instr->len += instr->erase_buf_ofs; -+ ret = mtd_read(part->master, -+ part->offset + instr->addr + -+ instr->len - part->master->erasesize, -+ part->master->erasesize, &readlen, -+ instr->erase_buf); -+ } else { -+ ret = 0; -+ } -+ } -+ if (ret < 0) { -+ kfree(instr->erase_buf); -+ return ret; -+ } -+ -+ } -+ - instr->addr += part->offset; - ret = part->master->_erase(part->master, instr); - if (ret) { - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_addr -= part->offset; - instr->addr -= part->offset; -+ if (mtd->flags & MTD_ERASE_PARTIAL) -+ kfree(instr->erase_buf); - } -+ - return ret; - } - -@@ -248,7 +298,25 @@ void mtd_erase_callback(struct erase_inf - { - if (instr->mtd->_erase == part_erase) { - struct mtd_part *part = PART(instr->mtd); -+ size_t wrlen = 0; - -+ if (instr->mtd->flags & MTD_ERASE_PARTIAL) { -+ if (instr->partial_start) { -+ part->master->_write(part->master, -+ instr->addr, instr->erase_buf_ofs, -+ &wrlen, instr->erase_buf); -+ instr->addr += instr->erase_buf_ofs; -+ } else { -+ instr->len -= instr->erase_buf_ofs; -+ part->master->_write(part->master, -+ instr->addr + instr->len, -+ instr->erase_buf_ofs, &wrlen, -+ instr->erase_buf + -+ part->master->erasesize - -+ instr->erase_buf_ofs); -+ } -+ kfree(instr->erase_buf); -+ } - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_addr -= part->offset; - instr->addr -= part->offset; -@@ -515,17 +583,20 @@ static struct mtd_part *allocate_partiti - if ((slave->mtd.flags & MTD_WRITEABLE) && - mtd_mod_by_eb(slave->offset, &slave->mtd)) { - /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of -- * _minor_ erase size though */ -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", -- part->name); -+ slave->mtd.flags |= MTD_ERASE_PARTIAL; -+ if (((u32) slave->mtd.size) > master->erasesize) -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ else -+ slave->mtd.erasesize = slave->mtd.size; - } - if ((slave->mtd.flags & MTD_WRITEABLE) && -- mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) { -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", -- part->name); -+ mtd_mod_by_eb(slave->offset + slave->mtd.size, &slave->mtd)) { -+ slave->mtd.flags |= MTD_ERASE_PARTIAL; -+ -+ if ((u32) slave->mtd.size > master->erasesize) -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ else -+ slave->mtd.erasesize = slave->mtd.size; - } - - slave->mtd.ecclayout = master->ecclayout; ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -55,6 +55,10 @@ struct erase_info { - u_long priv; - u_char state; - struct erase_info *next; -+ -+ u8 *erase_buf; -+ u32 erase_buf_ofs; -+ bool partial_start; - }; - - struct mtd_erase_region_info { diff --git a/target/linux/generic/pending-3.18/412-mtd-partial_eraseblock_unlock.patch b/target/linux/generic/pending-3.18/412-mtd-partial_eraseblock_unlock.patch deleted file mode 100644 index 62f9d5bad0..0000000000 --- a/target/linux/generic/pending-3.18/412-mtd-partial_eraseblock_unlock.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -335,7 +335,14 @@ static int part_lock(struct mtd_info *mt - static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) - { - struct mtd_part *part = PART(mtd); -- return part->master->_unlock(part->master, ofs + part->offset, len); -+ -+ ofs += part->offset; -+ if (mtd->flags & MTD_ERASE_PARTIAL) { -+ /* round up len to next erasesize and round down offset to prev block */ -+ len = (mtd_div_by_eb(len, part->master) + 1) * part->master->erasesize; -+ ofs &= ~(part->master->erasesize - 1); -+ } -+ return part->master->_unlock(part->master, ofs, len); - } - - static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) diff --git a/target/linux/generic/pending-3.18/420-mtd-redboot_space.patch b/target/linux/generic/pending-3.18/420-mtd-redboot_space.patch deleted file mode 100644 index f74affcef7..0000000000 --- a/target/linux/generic/pending-3.18/420-mtd-redboot_space.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/drivers/mtd/redboot.c -+++ b/drivers/mtd/redboot.c -@@ -265,14 +265,21 @@ static int parse_redboot_partitions(stru - #endif - names += strlen(names)+1; - --#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED - if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { -- i++; -- parts[i].offset = parts[i-1].size + parts[i-1].offset; -- parts[i].size = fl->next->img->flash_base - parts[i].offset; -- parts[i].name = nullname; -- } -+ if (!strcmp(parts[i].name, "rootfs")) { -+ parts[i].size = fl->next->img->flash_base; -+ parts[i].size &= ~(master->erasesize - 1); -+ parts[i].size -= parts[i].offset; -+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ nrparts--; -+ } else { -+ i++; -+ parts[i].offset = parts[i-1].size + parts[i-1].offset; -+ parts[i].size = fl->next->img->flash_base - parts[i].offset; -+ parts[i].name = nullname; - #endif -+ } -+ } - tmp_fl = fl; - fl = fl->next; - kfree(tmp_fl); diff --git a/target/linux/generic/pending-3.18/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-3.18/430-mtd-add-myloader-partition-parser.patch deleted file mode 100644 index 25e0ecd048..0000000000 --- a/target/linux/generic/pending-3.18/430-mtd-add-myloader-partition-parser.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -184,6 +184,22 @@ config MTD_BCM47XX_PARTS - This provides partitions parser for devices based on BCM47xx - boards. - -+config MTD_MYLOADER_PARTS -+ tristate "MyLoader partition parsing" -+ depends on ADM5120 || ATH25 || ATH79 -+ ---help--- -+ MyLoader is a bootloader which allows the user to define partitions -+ in flash devices, by putting a table in the second erase block -+ on the device, similar to a partition table. This table gives the -+ offsets and lengths of the user defined partitions. -+ -+ If you need code which can detect and parse these tables, and -+ register MTD 'partitions' corresponding to each image detected, -+ enable this option. -+ -+ 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/Makefile -+++ b/drivers/mtd/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o - obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o - obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o - obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o -+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o - - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o diff --git a/target/linux/generic/pending-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch deleted file mode 100644 index 5ad82f1f51..0000000000 --- a/target/linux/generic/pending-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch +++ /dev/null @@ -1,100 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Sat, 2 Jan 2016 01:04:52 +0100 -Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating - offsets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> ---- - drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 40 insertions(+), 10 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct - part->mask_flags = mask_flags; - } - -+/* -+ * Calculate real end offset (address) for a given amount of data. It checks -+ * all blocks skipping bad ones. -+ */ -+static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset, -+ size_t bytes) -+{ -+ size_t real_offset = offset; -+ -+ if (mtd_block_isbad(master, real_offset)) -+ pr_warn("Base offset shouldn't be at bad block"); -+ -+ while (bytes >= master->erasesize) { -+ bytes -= master->erasesize; -+ real_offset += master->erasesize; -+ while (mtd_block_isbad(master, real_offset)) { -+ real_offset += master->erasesize; -+ -+ if (real_offset >= master->size) -+ return real_offset - master->erasesize; -+ } -+ } -+ -+ real_offset += bytes; -+ -+ return real_offset; -+} -+ - static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, - size_t offset) - { -@@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_ - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { -+ uint32_t tmp; -+ - if (BCM47XXPART_MAX_PARTS - curr_part < 4) { - pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); - break; -@@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_ - i = 0; - /* We have LZMA loader if offset[2] points to sth */ - if (trx->offset[2]) { -+ tmp = bcm47xxpart_real_offset(master, offset, -+ trx->offset[i]); - bcm47xxpart_add_part(&parts[curr_part++], -- "loader", -- offset + trx->offset[i], -- 0); -+ "loader", tmp, 0); - i++; - } - - if (trx->offset[i]) { -+ tmp = bcm47xxpart_real_offset(master, offset, -+ trx->offset[i]); - bcm47xxpart_add_part(&parts[curr_part++], -- "linux", -- offset + trx->offset[i], -- 0); -+ "linux", tmp, 0); - i++; - } - -@@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_ - if (trx->offset[i]) { - const char *name; - -- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); -+ tmp = bcm47xxpart_real_offset(master, offset, -+ trx->offset[i]); -+ name = bcm47xxpart_trx_data_part_name(master, tmp); - bcm47xxpart_add_part(&parts[curr_part++], -- name, -- offset + trx->offset[i], -- 0); -+ name, tmp, 0); - i++; - } - diff --git a/target/linux/generic/pending-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch deleted file mode 100644 index 9e5ca91e55..0000000000 --- a/target/linux/generic/pending-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ /dev/null @@ -1,42 +0,0 @@ -From fd54aa583296f9adfb1f519affbc10ba521eb809 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> -Date: Wed, 28 Jan 2015 22:14:41 +0100 -Subject: [PATCH] mtd: bcm47xxpart: detect T_Meter partition -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It can be found on many Netgear devices. It consists of many 0x30 blocks -starting with 4D 54. - -Signed-off-by: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com> ---- - drivers/mtd/bcm47xxpart.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -38,6 +38,7 @@ - #define NVRAM_HEADER 0x48534C46 /* FLSH */ - #define POT_MAGIC1 0x54544f50 /* POTT */ - #define POT_MAGIC2 0x504f /* OP */ -+#define T_METER_MAGIC 0x4D540000 /* MT */ - #define ML_MAGIC1 0x39685a42 - #define ML_MAGIC2 0x26594131 - #define TRX_MAGIC 0x30524448 -@@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ - MTD_WRITEABLE); - continue; - } -+ -+ /* T_Meter */ -+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { -+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, -+ MTD_WRITEABLE); -+ continue; -+ } - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { diff --git a/target/linux/generic/pending-3.18/440-block2mtd_init.patch b/target/linux/generic/pending-3.18/440-block2mtd_init.patch deleted file mode 100644 index 5ab60265a3..0000000000 --- a/target/linux/generic/pending-3.18/440-block2mtd_init.patch +++ /dev/null @@ -1,107 +0,0 @@ ---- a/drivers/mtd/devices/block2mtd.c -+++ b/drivers/mtd/devices/block2mtd.c -@@ -17,6 +17,7 @@ - #include <linux/list.h> - #include <linux/init.h> - #include <linux/mtd/mtd.h> -+#include <linux/mtd/partitions.h> - #include <linux/mutex.h> - #include <linux/mount.h> - #include <linux/slab.h> -@@ -209,11 +210,12 @@ static void block2mtd_free_device(struct - } - - --static struct block2mtd_dev *add_device(char *devname, int erase_size) -+static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) - { - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; - struct block_device *bdev; - struct block2mtd_dev *dev; -+ struct mtd_partition *part; - char *name; - - if (!devname) -@@ -257,13 +259,16 @@ static struct block2mtd_dev *add_device( - - /* Setup the MTD structure */ - /* make the name contain the block device in */ -- name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname); -+ if (!mtdname) -+ mtdname = devname; -+ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); - if (!name) - goto err_destroy_mutex; - -+ strcpy(name, mtdname); - dev->mtd.name = name; - -- dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; -+ dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1); - dev->mtd.erasesize = erase_size; - dev->mtd.writesize = 1; - dev->mtd.writebufsize = PAGE_SIZE; -@@ -276,15 +281,18 @@ static struct block2mtd_dev *add_device( - dev->mtd.priv = dev; - dev->mtd.owner = THIS_MODULE; - -- if (mtd_device_register(&dev->mtd, NULL, 0)) { -+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); -+ part->name = name; -+ part->offset = 0; -+ part->size = dev->mtd.size; -+ if (mtd_device_register(&dev->mtd, part, 1)) { - /* Device didn't get added, so free the entry */ - goto err_destroy_mutex; - } - list_add(&dev->list, &blkmtd_device_list); - pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", - dev->mtd.index, -- dev->mtd.name + strlen("block2mtd: "), -- dev->mtd.erasesize >> 10, dev->mtd.erasesize); -+ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); - return dev; - - err_destroy_mutex: -@@ -353,9 +361,9 @@ static char block2mtd_paramline[80 + 12] - - static int block2mtd_setup2(const char *val) - { -- char buf[80 + 12]; /* 80 for device, 12 for erase size */ -+ char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ - char *str = buf; -- char *token[2]; -+ char *token[3]; - char *name; - size_t erase_size = PAGE_SIZE; - int i, ret; -@@ -368,7 +376,7 @@ static int block2mtd_setup2(const char * - strcpy(str, val); - kill_final_newline(str); - -- for (i = 0; i < 2; i++) -+ for (i = 0; i < 3; i++) - token[i] = strsep(&str, ","); - - if (str) { -@@ -394,8 +402,10 @@ static int block2mtd_setup2(const char * - return 0; - } - } -+ if (token[2] && (strlen(token[2]) + 1 > 80)) -+ pr_err("mtd device name too long\n"); - -- add_device(name, erase_size); -+ add_device(name, erase_size, token[2]); - - return 0; - } -@@ -429,7 +439,7 @@ static int block2mtd_setup(const char *v - - - module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); --MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); -+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\""); - - static int __init block2mtd_init(void) - { diff --git a/target/linux/generic/pending-3.18/441-block2mtd_probe.patch b/target/linux/generic/pending-3.18/441-block2mtd_probe.patch deleted file mode 100644 index 6836a48e39..0000000000 --- a/target/linux/generic/pending-3.18/441-block2mtd_probe.patch +++ /dev/null @@ -1,110 +0,0 @@ ---- a/drivers/mtd/devices/block2mtd.c -+++ b/drivers/mtd/devices/block2mtd.c -@@ -10,6 +10,7 @@ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - - #include <linux/module.h> -+#include <linux/delay.h> - #include <linux/fs.h> - #include <linux/blkdev.h> - #include <linux/bio.h> -@@ -210,13 +211,16 @@ static void block2mtd_free_device(struct - } - - --static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) -+static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname, int timeout) - { - const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; -- struct block_device *bdev; -+ struct block_device *bdev = ERR_PTR(-ENODEV); - struct block2mtd_dev *dev; - struct mtd_partition *part; - char *name; -+#ifndef MODULE -+ int i; -+#endif - - if (!devname) - return NULL; -@@ -227,15 +231,20 @@ static struct block2mtd_dev *add_device( - - /* Get a handle on the device */ - bdev = blkdev_get_by_path(devname, mode, dev); -+ - #ifndef MODULE -- if (IS_ERR(bdev)) { -+ for (i = 0; IS_ERR(bdev) && i <= timeout; i++) { -+ dev_t devt; - -- /* We might not have rootfs mounted at this point. Try -- to resolve the device name by other means. */ -+ if (i) -+ msleep(1000); -+ wait_for_device_probe(); -+ -+ devt = name_to_dev_t(devname); -+ if (!devt) -+ continue; - -- dev_t devt = name_to_dev_t(devname); -- if (devt) -- bdev = blkdev_get_by_dev(devt, mode, dev); -+ bdev = blkdev_get_by_dev(devt, mode, dev); - } - #endif - -@@ -361,11 +370,12 @@ static char block2mtd_paramline[80 + 12] - - static int block2mtd_setup2(const char *val) - { -- char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ -+ char buf[80 + 12 + 80 + 8]; /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ - char *str = buf; -- char *token[3]; -+ char *token[4]; - char *name; - size_t erase_size = PAGE_SIZE; -+ unsigned long timeout = 0; - int i, ret; - - if (strnlen(val, sizeof(buf)) >= sizeof(buf)) { -@@ -376,7 +386,7 @@ static int block2mtd_setup2(const char * - strcpy(str, val); - kill_final_newline(str); - -- for (i = 0; i < 3; i++) -+ for (i = 0; i < 4; i++) - token[i] = strsep(&str, ","); - - if (str) { -@@ -405,7 +415,10 @@ static int block2mtd_setup2(const char * - if (token[2] && (strlen(token[2]) + 1 > 80)) - pr_err("mtd device name too long\n"); - -- add_device(name, erase_size, token[2]); -+ if (token[3] && kstrtoul(token[3], 0, &timeout)) -+ pr_err("invalid timeout\n"); -+ -+ add_device(name, erase_size, token[2], timeout); - - return 0; - } -@@ -439,7 +452,7 @@ static int block2mtd_setup(const char *v - - - module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); --MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\""); -+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>[,<timeout>]]]\""); - - static int __init block2mtd_init(void) - { -@@ -474,7 +487,7 @@ static void block2mtd_exit(void) - } - - --module_init(block2mtd_init); -+late_initcall(block2mtd_init); - module_exit(block2mtd_exit); - - MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-3.18/450-mtd-nand-allow-to-use-platform-specific-chip-fixup.patch b/target/linux/generic/pending-3.18/450-mtd-nand-allow-to-use-platform-specific-chip-fixup.patch deleted file mode 100644 index 0f5abaa723..0000000000 --- a/target/linux/generic/pending-3.18/450-mtd-nand-allow-to-use-platform-specific-chip-fixup.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- - drivers/mtd/nand/plat_nand.c | 13 ++++++++++++- - include/linux/mtd/nand.h | 1 + - 2 files changed, 13 insertions(+), 1 deletion(-) - ---- a/include/linux/mtd/nand.h -+++ b/include/linux/mtd/nand.h -@@ -851,6 +851,7 @@ struct platform_nand_chip { - unsigned int options; - unsigned int bbt_options; - const char **part_probe_types; -+ int (*chip_fixup)(struct mtd_info *mtd); - }; - - /* Keep gcc happy */ ---- a/drivers/mtd/nand/plat_nand.c -+++ b/drivers/mtd/nand/plat_nand.c -@@ -90,7 +90,18 @@ static int plat_nand_probe(struct platfo - } - - /* Scan to find existence of the device */ -- if (nand_scan(&data->mtd, pdata->chip.nr_chips)) { -+ if (nand_scan_ident(&data->mtd, pdata->chip.nr_chips, NULL)) { -+ err = -ENXIO; -+ goto out; -+ } -+ -+ if (pdata->chip.chip_fixup) { -+ err = pdata->chip.chip_fixup(&data->mtd); -+ if (err) -+ goto out; -+ } -+ -+ if (nand_scan_tail(&data->mtd)) { - err = -ENXIO; - goto out; - } diff --git a/target/linux/generic/pending-3.18/451-mtd-nand-fix-return-code-of-nand_correct_data-function.patch b/target/linux/generic/pending-3.18/451-mtd-nand-fix-return-code-of-nand_correct_data-function.patch deleted file mode 100644 index 6a2092ce20..0000000000 --- a/target/linux/generic/pending-3.18/451-mtd-nand-fix-return-code-of-nand_correct_data-function.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/mtd/nand/nand_ecc.c -+++ b/drivers/mtd/nand/nand_ecc.c -@@ -507,7 +507,7 @@ int __nand_correct_data(unsigned char *b - return 1; /* error in ECC data; no action needed */ - - pr_err("%s: uncorrectable ECC error\n", __func__); -- return -1; -+ return -EBADMSG; - } - EXPORT_SYMBOL(__nand_correct_data); - diff --git a/target/linux/generic/pending-3.18/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-3.18/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch deleted file mode 100644 index 68fbd12466..0000000000 --- a/target/linux/generic/pending-3.18/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -809,7 +809,7 @@ static int get_chip(struct map_info *map - return 0; - - case FL_ERASING: -- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || - !(mode == FL_READY || mode == FL_POINT || - (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) - goto sleep; diff --git a/target/linux/generic/pending-3.18/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-3.18/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch deleted file mode 100644 index 382b44a939..0000000000 --- a/target/linux/generic/pending-3.18/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch +++ /dev/null @@ -1,18 +0,0 @@ -From: George Kashperko <george@znau.edu.ua> - -Issue map read after Write Buffer Load command to ensure chip is ready -to receive data. -Signed-off-by: George Kashperko <george@znau.edu.ua> ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 1 + - 1 file changed, 1 insertion(+) ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -1831,6 +1831,7 @@ static int __xipram do_write_buffer(stru - - /* Write Buffer Load */ - map_write(map, CMD(0x25), cmd_adr); -+ (void) map_read(map, cmd_adr); - - chip->state = FL_WRITING_TO_BUFFER; - diff --git a/target/linux/generic/pending-3.18/472-mtd-m25p80-add-support-for-Winbond-W25X05-flash.patch b/target/linux/generic/pending-3.18/472-mtd-m25p80-add-support-for-Winbond-W25X05-flash.patch deleted file mode 100644 index f059aa777e..0000000000 --- a/target/linux/generic/pending-3.18/472-mtd-m25p80-add-support-for-Winbond-W25X05-flash.patch +++ /dev/null @@ -1,20 +0,0 @@ -From eef9dfc4e821408af1af13aa0cc707fc496fb7c6 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos <juhosg@openwrt.org> -Date: Wed, 11 Dec 2013 19:05:59 +0100 -Subject: [PATCH] m25p80: add support for the Winbond W25X05 flash - -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> ---- - drivers/mtd/devices/m25p80.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -618,6 +618,7 @@ static const struct spi_device_id spi_no - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, - - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ -+ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, diff --git a/target/linux/generic/pending-3.18/473-mtd-spi-nor-add-support-for-the-Macronix-MX25L512E-S.patch b/target/linux/generic/pending-3.18/473-mtd-spi-nor-add-support-for-the-Macronix-MX25L512E-S.patch deleted file mode 100644 index 9ba7a4ab2f..0000000000 --- a/target/linux/generic/pending-3.18/473-mtd-spi-nor-add-support-for-the-Macronix-MX25L512E-S.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0d7388de0911c1a4fc4a8a3898ef9d0ab818ca08 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos <juhosg@openwrt.org> -Date: Tue, 7 Apr 2015 18:35:15 +0200 -Subject: [PATCH] mtd: spi-nor: add support for the Macronix MX25L512E SPI - flash chip - -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -518,6 +518,7 @@ static const struct spi_device_id spi_no - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, - - /* Macronix */ -+ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, diff --git a/target/linux/generic/pending-3.18/474-mtd-spi-nor-add-support-for-the-ISSI-SI25CD512-SPI-f.patch b/target/linux/generic/pending-3.18/474-mtd-spi-nor-add-support-for-the-ISSI-SI25CD512-SPI-f.patch deleted file mode 100644 index b06ac73fae..0000000000 --- a/target/linux/generic/pending-3.18/474-mtd-spi-nor-add-support-for-the-ISSI-SI25CD512-SPI-f.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 34e2b403040a2f9d3ba071d95a7f42457e2950f9 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos <juhosg@openwrt.org> -Date: Tue, 7 Apr 2015 18:35:15 +0200 -Subject: [PATCH] mtd: spi-nor: add support for the ISSI SI25CD512 SPI flash - -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> ---- - drivers/mtd/spi-nor/spi-nor.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -517,6 +517,9 @@ static const struct spi_device_id spi_no - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, - -+ /* ISSI */ -+ { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, -+ - /* Macronix */ - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, diff --git a/target/linux/generic/pending-3.18/475-mtd-spi-nor-add-macronix-mx25u25635f.patch b/target/linux/generic/pending-3.18/475-mtd-spi-nor-add-macronix-mx25u25635f.patch deleted file mode 100644 index 72c083232e..0000000000 --- a/target/linux/generic/pending-3.18/475-mtd-spi-nor-add-macronix-mx25u25635f.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -532,6 +532,7 @@ static const struct spi_device_id spi_no - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, -+ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, 0) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, diff --git a/target/linux/generic/pending-3.18/476-mtd-spi-nor-add-eon-en25qh32.patch b/target/linux/generic/pending-3.18/476-mtd-spi-nor-add-eon-en25qh32.patch deleted file mode 100644 index 950970dbc9..0000000000 --- a/target/linux/generic/pending-3.18/476-mtd-spi-nor-add-eon-en25qh32.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -497,6 +497,7 @@ static const struct spi_device_id spi_no - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, - diff --git a/target/linux/generic/pending-3.18/480-mtd-set-rootfs-to-be-root-dev.patch b/target/linux/generic/pending-3.18/480-mtd-set-rootfs-to-be-root-dev.patch deleted file mode 100644 index 8fc3578a66..0000000000 --- a/target/linux/generic/pending-3.18/480-mtd-set-rootfs-to-be-root-dev.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -37,6 +37,7 @@ - #include <linux/backing-dev.h> - #include <linux/gfp.h> - #include <linux/slab.h> -+#include <linux/root_dev.h> - - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -@@ -456,6 +457,15 @@ int add_mtd_device(struct mtd_info *mtd) - of this try_ nonsense, and no bitching about it - either. :) */ - __module_get(THIS_MODULE); -+ -+ if (!strcmp(mtd->name, "rootfs") && -+ config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ pr_notice("mtd: device %d (%s) set to be root filesystem\n", -+ mtd->index, mtd->name); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); -+ } -+ - return 0; - - fail_added: diff --git a/target/linux/generic/pending-3.18/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-3.18/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch deleted file mode 100644 index b2b46ac6aa..0000000000 --- a/target/linux/generic/pending-3.18/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 8a52e4100d7c3a4a1dfddfa02b8864a9b0068c13 Mon Sep 17 00:00:00 2001 -From: Daniel Golle <daniel@makrotopia.org> -Date: Sat, 17 May 2014 03:36:18 +0200 -Subject: [PATCH 1/5] ubi: auto-attach mtd device named "ubi" or "data" on boot -To: openwrt-devel@lists.openwrt.org - -Signed-off-by: Daniel Golle <daniel@makrotopia.org> ---- - drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -1223,6 +1223,49 @@ static struct mtd_info * __init open_mtd - return mtd; - } - -+/* -+ * This function tries attaching mtd partitions named either "ubi" or "data" -+ * during boot. -+ */ -+static void __init ubi_auto_attach(void) -+{ -+ int err; -+ struct mtd_info *mtd; -+ -+ /* try attaching mtd device named "ubi" or "data" */ -+ mtd = open_mtd_device("ubi"); -+ if (IS_ERR(mtd)) -+ mtd = open_mtd_device("data"); -+ -+ if (!IS_ERR(mtd)) { -+ size_t len; -+ char magic[4]; -+ -+ /* check for a valid ubi magic */ -+ err = mtd_read(mtd, 0, 4, &len, (void *) magic); -+ if (!err && len == 4 && strncmp(magic, "UBI#", 4)) { -+ ubi_err("no valid UBI magic found inside mtd%d", mtd->index); -+ put_mtd_device(mtd); -+ return; -+ } -+ -+ /* auto-add only media types where UBI makes sense */ -+ if (mtd->type == MTD_NANDFLASH || -+ mtd->type == MTD_NORFLASH || -+ mtd->type == MTD_DATAFLASH || -+ mtd->type == MTD_MLCNANDFLASH) { -+ mutex_lock(&ubi_devices_mutex); -+ ubi_msg("auto-attach mtd%d", mtd->index); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); -+ mutex_unlock(&ubi_devices_mutex); -+ if (err < 0) { -+ ubi_err("cannot attach mtd%d", mtd->index); -+ put_mtd_device(mtd); -+ } -+ } -+ } -+} -+ - static int __init ubi_init(void) - { - int err, i, k; -@@ -1312,6 +1355,12 @@ static int __init ubi_init(void) - } - } - -+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd -+ * parameter was given */ -+ if (config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ !ubi_is_module() && !mtd_devs) -+ ubi_auto_attach(); -+ - err = ubiblock_init(); - if (err) { - ubi_err("block: cannot initialize, error %d", err); diff --git a/target/linux/generic/pending-3.18/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-3.18/491-ubi-auto-create-ubiblock-device-for-rootfs.patch deleted file mode 100644 index b152fba1b3..0000000000 --- a/target/linux/generic/pending-3.18/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0f3966579815f889bb2fcb4846152c35f65e79c4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle <daniel@makrotopia.org> -Date: Thu, 15 May 2014 21:06:33 +0200 -Subject: [PATCH 2/5] ubi: auto-create ubiblock device for rootfs -To: openwrt-devel@lists.openwrt.org - -Signed-off-by: Daniel Golle <daniel@makrotopia.org> ---- - drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -615,6 +615,44 @@ static int __init ubiblock_create_from_p - return ret; - } - -+#define UBIFS_NODE_MAGIC 0x06101831 -+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) -+{ -+ int ret; -+ uint32_t magic_of, magic; -+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); -+ if (ret) -+ return 0; -+ magic = le32_to_cpu(magic_of); -+ return magic == UBIFS_NODE_MAGIC; -+} -+ -+static void __init ubiblock_create_auto_rootfs(void) -+{ -+ int ubi_num, ret, is_ubifs; -+ struct ubi_volume_desc *desc; -+ struct ubi_volume_info vi; -+ -+ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { -+ desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); -+ if (IS_ERR(desc)) -+ continue; -+ -+ ubi_get_volume_info(desc, &vi); -+ is_ubifs = ubi_vol_is_ubifs(desc); -+ ubi_close_volume(desc); -+ if (is_ubifs) -+ break; -+ -+ ret = ubiblock_create(&vi); -+ if (ret) -+ ubi_err("block: can't add '%s' volume, err=%d\n", -+ vi.name, ret); -+ /* always break if we get here */ -+ break; -+ } -+} -+ - static void ubiblock_remove_all(void) - { - struct ubiblock *next; -@@ -645,6 +683,10 @@ int __init ubiblock_init(void) - if (ret) - goto err_remove; - -+ /* auto-attach "rootfs" volume if existing and non-ubifs */ -+ if (config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV)) -+ ubiblock_create_auto_rootfs(); -+ - /* - * Block devices are only created upon user requests, so we ignore - * existing volumes. diff --git a/target/linux/generic/pending-3.18/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-3.18/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch deleted file mode 100644 index 54a2f8259c..0000000000 --- a/target/linux/generic/pending-3.18/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +++ /dev/null @@ -1,54 +0,0 @@ -From eea9e1785e4c05c2a3444506aabafa0ae958538f Mon Sep 17 00:00:00 2001 -From: Daniel Golle <daniel@makrotopia.org> -Date: Sat, 17 May 2014 03:35:02 +0200 -Subject: [PATCH 4/5] try auto-mounting ubi0:rootfs in init/do_mounts.c -To: openwrt-devel@lists.openwrt.org - -Signed-off-by: Daniel Golle <daniel@makrotopia.org> ---- - init/do_mounts.c | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -433,7 +433,28 @@ retry: - out: - put_page(page); - } -- -+ -+static int __init mount_ubi_rootfs(void) -+{ -+ int flags = MS_SILENT; -+ int err, tried = 0; -+ -+ while (tried < 2) { -+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ -+ root_mount_data); -+ switch (err) { -+ case -EACCES: -+ flags |= MS_RDONLY; -+ tried++; -+ break; -+ default: -+ return err; -+ } -+ } -+ -+ return -EINVAL; -+} -+ - #ifdef CONFIG_ROOT_NFS - - #define NFSROOT_TIMEOUT_MIN 5 -@@ -527,6 +548,10 @@ void __init mount_root(void) - change_floppy("root floppy"); - } - #endif -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (!mount_ubi_rootfs()) -+ return; -+#endif - #ifdef CONFIG_BLOCK - create_dev("/dev/root", ROOT_DEV); - mount_block_root("/dev/root", root_mountflags); diff --git a/target/linux/generic/pending-3.18/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-3.18/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch deleted file mode 100644 index 46917d12d2..0000000000 --- a/target/linux/generic/pending-3.18/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch +++ /dev/null @@ -1,37 +0,0 @@ -From cd68d1b12b5ea4c01a664c064179ada42bf55d3d Mon Sep 17 00:00:00 2001 -From: Daniel Golle <daniel@makrotopia.org> -Date: Thu, 15 May 2014 20:55:42 +0200 -Subject: [PATCH 5/5] ubi: set ROOT_DEV to ubiblock "rootfs" if unset -To: openwrt-devel@lists.openwrt.org - -Signed-off-by: Daniel Golle <daniel@makrotopia.org> ---- - drivers/mtd/ubi/block.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -48,6 +48,7 @@ - #include <linux/blkdev.h> - #include <linux/hdreg.h> - #include <asm/div64.h> -+#include <linux/root_dev.h> - - #include "ubi-media.h" - #include "ubi.h" -@@ -448,6 +449,15 @@ int ubiblock_create(struct ubi_volume_in - add_disk(dev->gd); - ubi_msg("%s created from ubi%d:%d(%s)", - dev->gd->disk_name, dev->ubi_num, dev->vol_id, vi->name); -+ -+ if (!strcmp(vi->name, "rootfs") && -+ config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", -+ dev->ubi_num, dev->vol_id, vi->name); -+ ROOT_DEV = MKDEV(gd->major, gd->first_minor); -+ } -+ - return 0; - - out_free_queue: diff --git a/target/linux/generic/pending-3.18/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-3.18/494-mtd-ubi-add-EOF-marker-support.patch deleted file mode 100644 index 4b5eb4568d..0000000000 --- a/target/linux/generic/pending-3.18/494-mtd-ubi-add-EOF-marker-support.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/drivers/mtd/ubi/attach.c -+++ b/drivers/mtd/ubi/attach.c -@@ -800,6 +800,13 @@ out_unlock: - return err; - } - -+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) -+{ -+ return ech->padding1[0] == 'E' && -+ ech->padding1[1] == 'O' && -+ ech->padding1[2] == 'F'; -+} -+ - /** - * scan_peb - scan and process UBI headers of a PEB. - * @ubi: UBI device description object -@@ -830,9 +837,21 @@ static int scan_peb(struct ubi_device *u - return 0; - } - -- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -- if (err < 0) -- return err; -+ if (!ai->eof_found) { -+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -+ if (err < 0) -+ return err; -+ -+ if (ec_hdr_has_eof(ech)) { -+ ubi_msg("EOF marker found, PEBs from %d will be erased", -+ pnum); -+ ai->eof_found = true; -+ } -+ } -+ -+ if (ai->eof_found) -+ err = UBI_IO_FF_BITFLIPS; -+ - switch (err) { - case 0: - break; ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -705,6 +705,7 @@ struct ubi_attach_info { - int mean_ec; - uint64_t ec_sum; - int ec_count; -+ bool eof_found; - struct kmem_cache *aeb_slab_cache; - }; - diff --git a/target/linux/generic/pending-3.18/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-3.18/530-jffs2_make_lzma_available.patch deleted file mode 100644 index b68238c937..0000000000 --- a/target/linux/generic/pending-3.18/530-jffs2_make_lzma_available.patch +++ /dev/null @@ -1,5142 +0,0 @@ ---- a/fs/jffs2/Kconfig -+++ b/fs/jffs2/Kconfig -@@ -139,6 +139,15 @@ config JFFS2_LZO - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. - -+config JFFS2_LZMA -+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZMA_COMPRESS -+ select LZMA_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ JFFS2 wrapper to the LZMA C SDK -+ - config JFFS2_RTIME - bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS - depends on JFFS2_FS ---- a/fs/jffs2/Makefile -+++ b/fs/jffs2/Makefile -@@ -18,4 +18,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub - jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o - jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o - jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o - jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -+ -+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma ---- a/fs/jffs2/compr.c -+++ b/fs/jffs2/compr.c -@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void) - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_init(); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_init(); -+#endif - /* Setting default compression mode */ - #ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void) - int jffs2_compressors_exit(void) - { - /* Unregistering compressors */ -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_exit(); -+#endif - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_exit(); - #endif ---- a/fs/jffs2/compr.h -+++ b/fs/jffs2/compr.h -@@ -29,9 +29,9 @@ - #define JFFS2_DYNRUBIN_PRIORITY 20 - #define JFFS2_LZARI_PRIORITY 30 - #define JFFS2_RTIME_PRIORITY 50 --#define JFFS2_ZLIB_PRIORITY 60 --#define JFFS2_LZO_PRIORITY 80 -- -+#define JFFS2_LZMA_PRIORITY 70 -+#define JFFS2_ZLIB_PRIORITY 80 -+#define JFFS2_LZO_PRIORITY 90 - - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ - #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void); - int jffs2_lzo_init(void); - void jffs2_lzo_exit(void); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+int jffs2_lzma_init(void); -+void jffs2_lzma_exit(void); -+#endif - - #endif /* __JFFS2_COMPR_H__ */ ---- /dev/null -+++ b/fs/jffs2/compr_lzma.c -@@ -0,0 +1,128 @@ -+/* -+ * JFFS2 -- Journalling Flash File System, Version 2. -+ * -+ * For licensing information, see the file 'LICENCE' in this directory. -+ * -+ * JFFS2 wrapper to the LZMA C SDK -+ * -+ */ -+ -+#include <linux/lzma.h> -+#include "compr.h" -+ -+#ifdef __KERNEL__ -+ static DEFINE_MUTEX(deflate_mutex); -+#endif -+ -+CLzmaEncHandle *p; -+Byte propsEncoded[LZMA_PROPS_SIZE]; -+SizeT propsSize = sizeof(propsEncoded); -+ -+STATIC void lzma_free_workspace(void) -+{ -+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -+} -+ -+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -+{ -+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) -+ { -+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -+ return -ENOMEM; -+ } -+ -+ if (LzmaEnc_SetProps(p, props) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen) -+{ -+ SizeT compress_size = (SizeT)(*dstlen); -+ int ret; -+ -+ #ifdef __KERNEL__ -+ mutex_lock(&deflate_mutex); -+ #endif -+ -+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -+ 0, NULL, &lzma_alloc, &lzma_alloc); -+ -+ #ifdef __KERNEL__ -+ mutex_unlock(&deflate_mutex); -+ #endif -+ -+ if (ret != SZ_OK) -+ return -1; -+ -+ *dstlen = (uint32_t)compress_size; -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen) -+{ -+ int ret; -+ SizeT dl = (SizeT)destlen; -+ SizeT sl = (SizeT)srclen; -+ ELzmaStatus status; -+ -+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -+ -+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -+ return -1; -+ -+ return 0; -+} -+ -+static struct jffs2_compressor jffs2_lzma_comp = { -+ .priority = JFFS2_LZMA_PRIORITY, -+ .name = "lzma", -+ .compr = JFFS2_COMPR_LZMA, -+ .compress = &jffs2_lzma_compress, -+ .decompress = &jffs2_lzma_decompress, -+ .disabled = 0, -+}; -+ -+int INIT jffs2_lzma_init(void) -+{ -+ int ret; -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; -+ -+ ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; -+ -+ ret = jffs2_register_compressor(&jffs2_lzma_comp); -+ if (ret) -+ lzma_free_workspace(); -+ -+ return ret; -+} -+ -+void jffs2_lzma_exit(void) -+{ -+ jffs2_unregister_compressor(&jffs2_lzma_comp); -+ lzma_free_workspace(); -+} ---- a/fs/jffs2/super.c -+++ b/fs/jffs2/super.c -@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void) - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - -- pr_info("version 2.2." -+ pr_info("version 2.2" - #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - " (NAND)" - #endif - #ifdef CONFIG_JFFS2_SUMMARY -- " (SUMMARY) " -+ " (SUMMARY)" - #endif -- " © 2001-2006 Red Hat, Inc.\n"); -+#ifdef CONFIG_JFFS2_ZLIB -+ " (ZLIB)" -+#endif -+#ifdef CONFIG_JFFS2_LZO -+ " (LZO)" -+#endif -+#ifdef CONFIG_JFFS2_LZMA -+ " (LZMA)" -+#endif -+#ifdef CONFIG_JFFS2_RTIME -+ " (RTIME)" -+#endif -+#ifdef CONFIG_JFFS2_RUBIN -+ " (RUBIN)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_NONE -+ " (CMODE_NONE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_PRIORITY -+ " (CMODE_PRIORITY)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_SIZE -+ " (CMODE_SIZE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -+ " (CMODE_FAVOURLZO)" -+#endif -+ " (c) 2001-2006 Red Hat, Inc.\n"); - - jffs2_inode_cachep = kmem_cache_create("jffs2_i", - sizeof(struct jffs2_inode_info), ---- a/include/uapi/linux/jffs2.h -+++ b/include/uapi/linux/jffs2.h -@@ -46,6 +46,7 @@ - #define JFFS2_COMPR_DYNRUBIN 0x05 - #define JFFS2_COMPR_ZLIB 0x06 - #define JFFS2_COMPR_LZO 0x07 -+#define JFFS2_COMPR_LZMA 0x08 - /* Compatibility flags. */ - #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ - #define JFFS2_NODE_ACCURATE 0x2000 ---- /dev/null -+++ b/include/linux/lzma.h -@@ -0,0 +1,62 @@ -+#ifndef __LZMA_H__ -+#define __LZMA_H__ -+ -+#ifdef __KERNEL__ -+ #include <linux/kernel.h> -+ #include <linux/sched.h> -+ #include <linux/slab.h> -+ #include <linux/vmalloc.h> -+ #include <linux/init.h> -+ #define LZMA_MALLOC vmalloc -+ #define LZMA_FREE vfree -+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -+ #define INIT __init -+ #define STATIC static -+#else -+ #include <stdint.h> -+ #include <stdlib.h> -+ #include <stdio.h> -+ #include <unistd.h> -+ #include <string.h> -+ #include <asm/types.h> -+ #include <errno.h> -+ #include <linux/jffs2.h> -+ #ifndef PAGE_SIZE -+ extern int page_size; -+ #define PAGE_SIZE page_size -+ #endif -+ #define LZMA_MALLOC malloc -+ #define LZMA_FREE free -+ #define PRINT_ERROR(msg) fprintf(stderr, msg) -+ #define INIT -+ #define STATIC -+#endif -+ -+#include "lzma/LzmaDec.h" -+#include "lzma/LzmaEnc.h" -+ -+#define LZMA_BEST_LEVEL (9) -+#define LZMA_BEST_LC (0) -+#define LZMA_BEST_LP (0) -+#define LZMA_BEST_PB (0) -+#define LZMA_BEST_FB (273) -+ -+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -+ -+static void *p_lzma_malloc(void *p, size_t size) -+{ -+ if (size == 0) -+ return NULL; -+ -+ return LZMA_MALLOC(size); -+} -+ -+static void p_lzma_free(void *p, void *address) -+{ -+ if (address != NULL) -+ LZMA_FREE(address); -+} -+ -+static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzFind.h -@@ -0,0 +1,115 @@ -+/* LzFind.h -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_FIND_H -+#define __LZ_FIND_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef UInt32 CLzRef; -+ -+typedef struct _CMatchFinder -+{ -+ Byte *buffer; -+ UInt32 pos; -+ UInt32 posLimit; -+ UInt32 streamPos; -+ UInt32 lenLimit; -+ -+ UInt32 cyclicBufferPos; -+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -+ -+ UInt32 matchMaxLen; -+ CLzRef *hash; -+ CLzRef *son; -+ UInt32 hashMask; -+ UInt32 cutValue; -+ -+ Byte *bufferBase; -+ ISeqInStream *stream; -+ int streamEndWasReached; -+ -+ UInt32 blockSize; -+ UInt32 keepSizeBefore; -+ UInt32 keepSizeAfter; -+ -+ UInt32 numHashBytes; -+ int directInput; -+ size_t directInputRem; -+ int btMode; -+ int bigHash; -+ UInt32 historySize; -+ UInt32 fixedHashSize; -+ UInt32 hashSizeSum; -+ UInt32 numSons; -+ SRes result; -+ UInt32 crc[256]; -+} CMatchFinder; -+ -+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -+ -+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+int MatchFinder_NeedMove(CMatchFinder *p); -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -+void MatchFinder_MoveBlock(CMatchFinder *p); -+void MatchFinder_ReadIfRequired(CMatchFinder *p); -+ -+void MatchFinder_Construct(CMatchFinder *p); -+ -+/* Conditions: -+ historySize <= 3 GB -+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -+*/ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -+ UInt32 *distances, UInt32 maxLen); -+ -+/* -+Conditions: -+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -+*/ -+ -+typedef void (*Mf_Init_Func)(void *object); -+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -+typedef void (*Mf_Skip_Func)(void *object, UInt32); -+ -+typedef struct _IMatchFinder -+{ -+ Mf_Init_Func Init; -+ Mf_GetIndexByte_Func GetIndexByte; -+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -+ Mf_GetMatches_Func GetMatches; -+ Mf_Skip_Func Skip; -+} IMatchFinder; -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+void MatchFinder_Init(CMatchFinder *p); -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzHash.h -@@ -0,0 +1,54 @@ -+/* LzHash.h -- HASH functions for LZ algorithms -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_HASH_H -+#define __LZ_HASH_H -+ -+#define kHash2Size (1 << 10) -+#define kHash3Size (1 << 16) -+#define kHash4Size (1 << 20) -+ -+#define kFix3HashSize (kHash2Size) -+#define kFix4HashSize (kHash2Size + kHash3Size) -+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -+ -+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -+ -+#define HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -+ -+#define HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -+ -+#define HASH5_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -+ hash4Value &= (kHash4Size - 1); } -+ -+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -+ -+ -+#define MT_HASH2_CALC \ -+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -+ -+#define MT_HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -+ -+#define MT_HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaDec.h -@@ -0,0 +1,231 @@ -+/* LzmaDec.h -- LZMA Decoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_DEC_H -+#define __LZMA_DEC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* #define _LZMA_PROB32 */ -+/* _LZMA_PROB32 can increase the speed on some CPUs, -+ but memory usage for CLzmaDec::probs will be doubled in that case */ -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+ -+/* ---------- LZMA Properties ---------- */ -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaProps -+{ -+ unsigned lc, lp, pb; -+ UInt32 dicSize; -+} CLzmaProps; -+ -+/* LzmaProps_Decode - decodes properties -+Returns: -+ SZ_OK -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -+ -+ -+/* ---------- LZMA Decoder state ---------- */ -+ -+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -+ -+#define LZMA_REQUIRED_INPUT_MAX 20 -+ -+typedef struct -+{ -+ CLzmaProps prop; -+ CLzmaProb *probs; -+ Byte *dic; -+ const Byte *buf; -+ UInt32 range, code; -+ SizeT dicPos; -+ SizeT dicBufSize; -+ UInt32 processedPos; -+ UInt32 checkDicSize; -+ unsigned state; -+ UInt32 reps[4]; -+ unsigned remainLen; -+ int needFlush; -+ int needInitState; -+ UInt32 numProbs; -+ unsigned tempBufSize; -+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -+} CLzmaDec; -+ -+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+void LzmaDec_Init(CLzmaDec *p); -+ -+/* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+ -+typedef enum -+{ -+ LZMA_FINISH_ANY, /* finish at any point */ -+ LZMA_FINISH_END /* block must be finished at the end */ -+} ELzmaFinishMode; -+ -+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -+ -+ You must use LZMA_FINISH_END, when you know that current output buffer -+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -+ -+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -+ and output value of destLen will be less than output buffer size limit. -+ You can check status result also. -+ -+ You can use multiple checks to test data integrity after full decompression: -+ 1) Check Result and "status" variable. -+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -+ You must use correct finish mode in that case. */ -+ -+typedef enum -+{ -+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -+} ELzmaStatus; -+ -+/* ELzmaStatus is used only as output value for function call */ -+ -+ -+/* ---------- Interfaces ---------- */ -+ -+/* There are 3 levels of interfaces: -+ 1) Dictionary Interface -+ 2) Buffer Interface -+ 3) One Call Interface -+ You can select any of these interfaces, but don't mix functions from different -+ groups for same object. */ -+ -+ -+/* There are two variants to allocate state for Dictionary Interface: -+ 1) LzmaDec_Allocate / LzmaDec_Free -+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -+ You can use variant 2, if you set dictionary buffer manually. -+ For Buffer Interface you must always use variant 1. -+ -+LzmaDec_Allocate* can return: -+ SZ_OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -+ -+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -+ -+/* ---------- Dictionary Interface ---------- */ -+ -+/* You can use it, if you want to eliminate the overhead for data copying from -+ dictionary to some other external buffer. -+ You must work with CLzmaDec variables directly in this interface. -+ -+ STEPS: -+ LzmaDec_Constr() -+ LzmaDec_Allocate() -+ for (each new stream) -+ { -+ LzmaDec_Init() -+ while (it needs more decompression) -+ { -+ LzmaDec_DecodeToDic() -+ use data from CLzmaDec::dic and update CLzmaDec::dicPos -+ } -+ } -+ LzmaDec_Free() -+*/ -+ -+/* LzmaDec_DecodeToDic -+ -+ The decoding to internal dictionary buffer (CLzmaDec::dic). -+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (dicLimit). -+ LZMA_FINISH_ANY - Decode just dicLimit bytes. -+ LZMA_FINISH_END - Stream must be finished after dicLimit. -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_NEEDS_MORE_INPUT -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+*/ -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- Buffer Interface ---------- */ -+ -+/* It's zlib-like interface. -+ See LzmaDec_DecodeToDic description for information about STEPS and return results, -+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -+ to work with CLzmaDec variables manually. -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+*/ -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaDecode -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -+*/ -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaEnc.h -@@ -0,0 +1,80 @@ -+/* LzmaEnc.h -- LZMA Encoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_ENC_H -+#define __LZMA_ENC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaEncProps -+{ -+ int level; /* 0 <= level <= 9 */ -+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -+ default = (1 << 24) */ -+ int lc; /* 0 <= lc <= 8, default = 3 */ -+ int lp; /* 0 <= lp <= 4, default = 0 */ -+ int pb; /* 0 <= pb <= 4, default = 2 */ -+ int algo; /* 0 - fast, 1 - normal, default = 1 */ -+ int fb; /* 5 <= fb <= 273, default = 32 */ -+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -+ int numHashBytes; /* 2, 3 or 4, default = 4 */ -+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -+ int numThreads; /* 1 or 2, default = 2 */ -+} CLzmaEncProps; -+ -+void LzmaEncProps_Init(CLzmaEncProps *p); -+void LzmaEncProps_Normalize(CLzmaEncProps *p); -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -+ -+ -+/* ---------- CLzmaEncHandle Interface ---------- */ -+ -+/* LzmaEnc_* functions can return the following exit codes: -+Returns: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater in props -+ SZ_ERROR_WRITE - Write callback error. -+ SZ_ERROR_PROGRESS - some break from progress callback -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+typedef void * CLzmaEncHandle; -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaEncode -+Return code: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater -+ SZ_ERROR_OUTPUT_EOF - output buffer overflow -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/Types.h -@@ -0,0 +1,226 @@ -+/* Types.h -- Basic types -+2009-11-23 : Igor Pavlov : Public domain */ -+ -+#ifndef __7Z_TYPES_H -+#define __7Z_TYPES_H -+ -+#include <stddef.h> -+ -+#ifdef _WIN32 -+#include <windows.h> -+#endif -+ -+#ifndef EXTERN_C_BEGIN -+#ifdef __cplusplus -+#define EXTERN_C_BEGIN extern "C" { -+#define EXTERN_C_END } -+#else -+#define EXTERN_C_BEGIN -+#define EXTERN_C_END -+#endif -+#endif -+ -+EXTERN_C_BEGIN -+ -+#define SZ_OK 0 -+ -+#define SZ_ERROR_DATA 1 -+#define SZ_ERROR_MEM 2 -+#define SZ_ERROR_CRC 3 -+#define SZ_ERROR_UNSUPPORTED 4 -+#define SZ_ERROR_PARAM 5 -+#define SZ_ERROR_INPUT_EOF 6 -+#define SZ_ERROR_OUTPUT_EOF 7 -+#define SZ_ERROR_READ 8 -+#define SZ_ERROR_WRITE 9 -+#define SZ_ERROR_PROGRESS 10 -+#define SZ_ERROR_FAIL 11 -+#define SZ_ERROR_THREAD 12 -+ -+#define SZ_ERROR_ARCHIVE 16 -+#define SZ_ERROR_NO_ARCHIVE 17 -+ -+typedef int SRes; -+ -+#ifdef _WIN32 -+typedef DWORD WRes; -+#else -+typedef int WRes; -+#endif -+ -+#ifndef RINOK -+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -+#endif -+ -+typedef unsigned char Byte; -+typedef short Int16; -+typedef unsigned short UInt16; -+ -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef long Int32; -+typedef unsigned long UInt32; -+#else -+typedef int Int32; -+typedef unsigned int UInt32; -+#endif -+ -+#ifdef _SZ_NO_INT_64 -+ -+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -+ NOTES: Some code will work incorrectly in that case! */ -+ -+typedef long Int64; -+typedef unsigned long UInt64; -+ -+#else -+ -+#if defined(_MSC_VER) || defined(__BORLANDC__) -+typedef __int64 Int64; -+typedef unsigned __int64 UInt64; -+#else -+typedef long long int Int64; -+typedef unsigned long long int UInt64; -+#endif -+ -+#endif -+ -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+typedef size_t SizeT; -+#endif -+ -+typedef int Bool; -+#define True 1 -+#define False 0 -+ -+ -+#ifdef _WIN32 -+#define MY_STD_CALL __stdcall -+#else -+#define MY_STD_CALL -+#endif -+ -+#ifdef _MSC_VER -+ -+#if _MSC_VER >= 1300 -+#define MY_NO_INLINE __declspec(noinline) -+#else -+#define MY_NO_INLINE -+#endif -+ -+#define MY_CDECL __cdecl -+#define MY_FAST_CALL __fastcall -+ -+#else -+ -+#define MY_CDECL -+#define MY_FAST_CALL -+ -+#endif -+ -+ -+/* The following interfaces use first parameter as pointer to structure */ -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) < input(*size)) is allowed */ -+} ISeqInStream; -+ -+/* it can return SZ_ERROR_INPUT_EOF */ -+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -+ -+typedef struct -+{ -+ size_t (*Write)(void *p, const void *buf, size_t size); -+ /* Returns: result - the number of actually written bytes. -+ (result < size) means error */ -+} ISeqOutStream; -+ -+typedef enum -+{ -+ SZ_SEEK_SET = 0, -+ SZ_SEEK_CUR = 1, -+ SZ_SEEK_END = 2 -+} ESzSeek; -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ISeekInStream; -+ -+typedef struct -+{ -+ SRes (*Look)(void *p, void **buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) > input(*size)) is not allowed -+ (output(*size) < input(*size)) is allowed */ -+ SRes (*Skip)(void *p, size_t offset); -+ /* offset must be <= output(*size) of Look */ -+ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ILookInStream; -+ -+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -+ -+/* reads via ILookInStream::Read */ -+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -+ -+#define LookToRead_BUF_SIZE (1 << 14) -+ -+typedef struct -+{ -+ ILookInStream s; -+ ISeekInStream *realStream; -+ size_t pos; -+ size_t size; -+ Byte buf[LookToRead_BUF_SIZE]; -+} CLookToRead; -+ -+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -+void LookToRead_Init(CLookToRead *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToLook; -+ -+void SecToLook_CreateVTable(CSecToLook *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToRead; -+ -+void SecToRead_CreateVTable(CSecToRead *p); -+ -+typedef struct -+{ -+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -+ /* Returns: result. (result != SZ_OK) means break. -+ Value (UInt64)(Int64)-1 for size means unknown value. */ -+} ICompressProgress; -+ -+typedef struct -+{ -+ void *(*Alloc)(void *p, size_t size); -+ void (*Free)(void *p, void *address); /* address can be 0 */ -+} ISzAlloc; -+ -+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -+#define IAlloc_Free(p, a) (p)->Free((p), a) -+ -+EXTERN_C_END -+ -+#endif ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -227,6 +227,12 @@ config LZ4_DECOMPRESS - - source "lib/xz/Kconfig" - -+config LZMA_COMPRESS -+ tristate -+ -+config LZMA_DECOMPRESS -+ tristate -+ - # - # These all provide a common interface (hence the apparent duplication with - # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -2,6 +2,16 @@ - # Makefile for some libs needed in the kernel. - # - -+ifdef CONFIG_JFFS2_ZLIB -+ CONFIG_ZLIB_INFLATE:=y -+ CONFIG_ZLIB_DEFLATE:=y -+endif -+ -+ifdef CONFIG_JFFS2_LZMA -+ CONFIG_LZMA_DECOMPRESS:=y -+ CONFIG_LZMA_COMPRESS:=y -+endif -+ - ifdef CONFIG_FUNCTION_TRACER - ORIG_CFLAGS := $(KBUILD_CFLAGS) - KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) -@@ -85,6 +95,8 @@ obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ - obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ - obj-$(CONFIG_XZ_DEC) += xz/ - obj-$(CONFIG_RAID6_PQ) += raid6/ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ - - lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o - lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o ---- /dev/null -+++ b/lib/lzma/LzFind.c -@@ -0,0 +1,761 @@ -+/* LzFind.c -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#include <string.h> -+ -+#include "LzFind.h" -+#include "LzHash.h" -+ -+#define kEmptyHashValue 0 -+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -+#define kNormalizeMask (~(kNormalizeStepMin - 1)) -+#define kMaxHistorySize ((UInt32)3 << 30) -+ -+#define kStartMaxLen 3 -+ -+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ if (!p->directInput) -+ { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+ } -+} -+ -+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -+ -+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+{ -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+ if (p->directInput) -+ { -+ p->blockSize = blockSize; -+ return 1; -+ } -+ if (p->bufferBase == 0 || p->blockSize != blockSize) -+ { -+ LzInWindow_Free(p, alloc); -+ p->blockSize = blockSize; -+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -+ } -+ return (p->bufferBase != 0); -+} -+ -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+ -+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+ -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+{ -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+ p->streamPos -= subValue; -+} -+ -+static void MatchFinder_ReadBlock(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+ if (p->directInput) -+ { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+ curSize = (UInt32)p->directInputRem; -+ p->directInputRem -= curSize; -+ p->streamPos += curSize; -+ if (p->directInputRem == 0) -+ p->streamEndWasReached = 1; -+ return; -+ } -+ for (;;) -+ { -+ Byte *dest = p->buffer + (p->streamPos - p->pos); -+ size_t size = (p->bufferBase + p->blockSize - dest); -+ if (size == 0) -+ return; -+ p->result = p->stream->Read(p->stream, dest, &size); -+ if (p->result != SZ_OK) -+ return; -+ if (size == 0) -+ { -+ p->streamEndWasReached = 1; -+ return; -+ } -+ p->streamPos += (UInt32)size; -+ if (p->streamPos - p->pos > p->keepSizeAfter) -+ return; -+ } -+} -+ -+void MatchFinder_MoveBlock(CMatchFinder *p) -+{ -+ memmove(p->bufferBase, -+ p->buffer - p->keepSizeBefore, -+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+} -+ -+int MatchFinder_NeedMove(CMatchFinder *p) -+{ -+ if (p->directInput) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+} -+ -+void MatchFinder_ReadIfRequired(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached) -+ return; -+ if (p->keepSizeAfter >= p->streamPos - p->pos) -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+{ -+ if (MatchFinder_NeedMove(p)) -+ MatchFinder_MoveBlock(p); -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -+{ -+ p->cutValue = 32; -+ p->btMode = 1; -+ p->numHashBytes = 4; -+ p->bigHash = 0; -+} -+ -+#define kCrcPoly 0xEDB88320 -+ -+void MatchFinder_Construct(CMatchFinder *p) -+{ -+ UInt32 i; -+ p->bufferBase = 0; -+ p->directInput = 0; -+ p->hash = 0; -+ MatchFinder_SetDefaultSettings(p); -+ -+ for (i = 0; i < 256; i++) -+ { -+ UInt32 r = i; -+ int j; -+ for (j = 0; j < 8; j++) -+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -+ p->crc[i] = r; -+ } -+} -+ -+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->hash); -+ p->hash = 0; -+} -+ -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ LzInWindow_Free(p, alloc); -+} -+ -+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -+{ -+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -+ if (sizeInBytes / sizeof(CLzRef) != num) -+ return 0; -+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -+} -+ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc) -+{ -+ UInt32 sizeReserv; -+ if (historySize > kMaxHistorySize) -+ { -+ MatchFinder_Free(p, alloc); -+ return 0; -+ } -+ sizeReserv = historySize >> 1; -+ if (historySize > ((UInt32)2 << 30)) -+ sizeReserv = historySize >> 2; -+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -+ -+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -+ if (LzInWindow_Create(p, sizeReserv, alloc)) -+ { -+ UInt32 newCyclicBufferSize = historySize + 1; -+ UInt32 hs; -+ p->matchMaxLen = matchMaxLen; -+ { -+ p->fixedHashSize = 0; -+ if (p->numHashBytes == 2) -+ hs = (1 << 16) - 1; -+ else -+ { -+ hs = historySize - 1; -+ hs |= (hs >> 1); -+ hs |= (hs >> 2); -+ hs |= (hs >> 4); -+ hs |= (hs >> 8); -+ hs >>= 1; -+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -+ if (hs > (1 << 24)) -+ { -+ if (p->numHashBytes == 3) -+ hs = (1 << 24) - 1; -+ else -+ hs >>= 1; -+ } -+ } -+ p->hashMask = hs; -+ hs++; -+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; -+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; -+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; -+ hs += p->fixedHashSize; -+ } -+ -+ { -+ UInt32 prevSize = p->hashSizeSum + p->numSons; -+ UInt32 newSize; -+ p->historySize = historySize; -+ p->hashSizeSum = hs; -+ p->cyclicBufferSize = newCyclicBufferSize; -+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -+ newSize = p->hashSizeSum + p->numSons; -+ if (p->hash != 0 && prevSize == newSize) -+ return 1; -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ p->hash = AllocRefs(newSize, alloc); -+ if (p->hash != 0) -+ { -+ p->son = p->hash + p->hashSizeSum; -+ return 1; -+ } -+ } -+ } -+ MatchFinder_Free(p, alloc); -+ return 0; -+} -+ -+static void MatchFinder_SetLimits(CMatchFinder *p) -+{ -+ UInt32 limit = kMaxValForNormalize - p->pos; -+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -+ if (limit2 < limit) -+ limit = limit2; -+ limit2 = p->streamPos - p->pos; -+ if (limit2 <= p->keepSizeAfter) -+ { -+ if (limit2 > 0) -+ limit2 = 1; -+ } -+ else -+ limit2 -= p->keepSizeAfter; -+ if (limit2 < limit) -+ limit = limit2; -+ { -+ UInt32 lenLimit = p->streamPos - p->pos; -+ if (lenLimit > p->matchMaxLen) -+ lenLimit = p->matchMaxLen; -+ p->lenLimit = lenLimit; -+ } -+ p->posLimit = p->pos + limit; -+} -+ -+void MatchFinder_Init(CMatchFinder *p) -+{ -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+ p->hash[i] = kEmptyHashValue; -+ p->cyclicBufferPos = 0; -+ p->buffer = p->bufferBase; -+ p->pos = p->streamPos = p->cyclicBufferSize; -+ p->result = SZ_OK; -+ p->streamEndWasReached = 0; -+ MatchFinder_ReadBlock(p); -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -+{ -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+} -+ -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+{ -+ UInt32 i; -+ for (i = 0; i < numItems; i++) -+ { -+ UInt32 value = items[i]; -+ if (value <= subValue) -+ value = kEmptyHashValue; -+ else -+ value -= subValue; -+ items[i] = value; -+ } -+} -+ -+static void MatchFinder_Normalize(CMatchFinder *p) -+{ -+ UInt32 subValue = MatchFinder_GetSubValue(p); -+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -+ MatchFinder_ReduceOffsets(p, subValue); -+} -+ -+static void MatchFinder_CheckLimits(CMatchFinder *p) -+{ -+ if (p->pos == kMaxValForNormalize) -+ MatchFinder_Normalize(p); -+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -+ MatchFinder_CheckAndMoveAndRead(p); -+ if (p->cyclicBufferPos == p->cyclicBufferSize) -+ p->cyclicBufferPos = 0; -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ son[_cyclicBufferPos] = curMatch; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ return distances; -+ { -+ const Byte *pb = cur - delta; -+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -+ if (pb[maxLen] == cur[maxLen] && *pb == *cur) -+ { -+ UInt32 len = 0; -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ return distances; -+ } -+ } -+ } -+ } -+} -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return distances; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ if (++len != lenLimit && pb[len] == cur[len]) -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return distances; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ { -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+#define MOVE_POS \ -+ ++p->cyclicBufferPos; \ -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+#define MOVE_POS_RET MOVE_POS return offset; -+ -+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -+#define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+ cur = p->buffer; -+ -+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -+ -+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -+ -+#define GET_MATCHES_FOOTER(offset, maxLen) \ -+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+#define SKIP_FOOTER \ -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -+ -+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 1) -+} -+ -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 2) -+} -+ -+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, delta2, maxLen, offset; -+ GET_MATCHES_HEADER(3) -+ -+ HASH3_CALC; -+ -+ delta2 = p->pos - p->hash[hash2Value]; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ -+ -+ maxLen = 2; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[0] = maxLen; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances + offset, maxLen) - (distances)); -+ MOVE_POS_RET -+} -+ -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances, 2) - (distances)); -+ MOVE_POS_RET -+} -+ -+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value; -+ SKIP_HEADER(3) -+ HASH3_CALC; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = p->pos; -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+{ -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+ if (!p->btMode) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 2) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 3) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -+ } -+ else -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+ } -+} ---- /dev/null -+++ b/lib/lzma/LzmaDec.c -@@ -0,0 +1,999 @@ -+/* LzmaDec.c -- LZMA Decoder -+2009-09-20 : Igor Pavlov : Public domain */ -+ -+#include "LzmaDec.h" -+ -+#include <string.h> -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_INIT_SIZE 5 -+ -+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -+ { UPDATE_0(p); i = (i + i); A0; } else \ -+ { UPDATE_1(p); i = (i + i) + 1; A1; } -+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -+ -+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -+#define TREE_DECODE(probs, limit, i) \ -+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -+ -+/* #define _LZMA_SIZE_OPT */ -+ -+#ifdef _LZMA_SIZE_OPT -+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -+#else -+#define TREE_6_DECODE(probs, i) \ -+ { i = 1; \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ i -= 0x40; } -+#endif -+ -+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0_CHECK range = bound; -+#define UPDATE_1_CHECK range -= bound; code -= bound; -+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -+#define TREE_DECODE_CHECK(probs, limit, i) \ -+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#define LZMA_DIC_MIN (1 << 12) -+ -+/* First LZMA-symbol is always decoded. -+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -+Out: -+ Result: -+ SZ_OK - OK -+ SZ_ERROR_DATA - Error -+ p->remainLen: -+ < kMatchSpecLenStart : normal remain -+ = kMatchSpecLenStart : finished -+ = kMatchSpecLenStart + 1 : Flush marker -+ = kMatchSpecLenStart + 2 : State Init Marker -+*/ -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ CLzmaProb *probs = p->probs; -+ -+ unsigned state = p->state; -+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -+ unsigned lc = p->prop.lc; -+ -+ Byte *dic = p->dic; -+ SizeT dicBufSize = p->dicBufSize; -+ SizeT dicPos = p->dicPos; -+ -+ UInt32 processedPos = p->processedPos; -+ UInt32 checkDicSize = p->checkDicSize; -+ unsigned len = 0; -+ -+ const Byte *buf = p->buf; -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ -+ do -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = processedPos & pbMask; -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ unsigned symbol; -+ UPDATE_0(prob); -+ prob = probs + Literal; -+ if (checkDicSize != 0 || processedPos != 0) -+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ state -= (state < 4) ? state : 3; -+ symbol = 1; -+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ state -= (state < 10) ? 3 : 6; -+ symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ dic[dicPos++] = (Byte)symbol; -+ processedPos++; -+ continue; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRep + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ state += kNumStates; -+ prob = probs + LenCoder; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ if (checkDicSize == 0 && processedPos == 0) -+ return SZ_ERROR_DATA; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ processedPos++; -+ state = state < kNumLitStates ? 9 : 11; -+ continue; -+ } -+ UPDATE_1(prob); -+ } -+ else -+ { -+ UInt32 distance; -+ UPDATE_1(prob); -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = (1 << kLenNumLowBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenChoice2; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = (1 << kLenNumMidBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = (1 << kLenNumHighBits); -+ } -+ } -+ TREE_DECODE(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state >= kNumStates) -+ { -+ UInt32 distance; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -+ TREE_6_DECODE(prob, distance); -+ if (distance >= kStartPosModelIndex) -+ { -+ unsigned posSlot = (unsigned)distance; -+ int numDirectBits = (int)(((distance >> 1) - 1)); -+ distance = (2 | (distance & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ distance <<= numDirectBits; -+ prob = probs + SpecPos + distance - posSlot - 1; -+ { -+ UInt32 mask = 1; -+ unsigned i = 1; -+ do -+ { -+ GET_BIT2(prob + i, i, ; , distance |= mask); -+ mask <<= 1; -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE -+ range >>= 1; -+ -+ { -+ UInt32 t; -+ code -= range; -+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -+ distance = (distance << 1) + (t + 1); -+ code += range & t; -+ } -+ /* -+ distance <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ distance |= 1; -+ } -+ */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ distance <<= kNumAlignBits; -+ { -+ unsigned i = 1; -+ GET_BIT2(prob + i, i, ; , distance |= 1); -+ GET_BIT2(prob + i, i, ; , distance |= 2); -+ GET_BIT2(prob + i, i, ; , distance |= 4); -+ GET_BIT2(prob + i, i, ; , distance |= 8); -+ } -+ if (distance == (UInt32)0xFFFFFFFF) -+ { -+ len += kMatchSpecLenStart; -+ state -= kNumStates; -+ break; -+ } -+ } -+ } -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ rep0 = distance + 1; -+ if (checkDicSize == 0) -+ { -+ if (distance >= processedPos) -+ return SZ_ERROR_DATA; -+ } -+ else if (distance >= checkDicSize) -+ return SZ_ERROR_DATA; -+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -+ } -+ -+ len += kMatchMinLen; -+ -+ if (limit == dicPos) -+ return SZ_ERROR_DATA; -+ { -+ SizeT rem = limit - dicPos; -+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -+ -+ processedPos += curLen; -+ -+ len -= curLen; -+ if (pos + curLen <= dicBufSize) -+ { -+ Byte *dest = dic + dicPos; -+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -+ const Byte *lim = dest + curLen; -+ dicPos += curLen; -+ do -+ *(dest) = (Byte)*(dest + src); -+ while (++dest != lim); -+ } -+ else -+ { -+ do -+ { -+ dic[dicPos++] = dic[pos]; -+ if (++pos == dicBufSize) -+ pos = 0; -+ } -+ while (--curLen != 0); -+ } -+ } -+ } -+ } -+ while (dicPos < limit && buf < bufLimit); -+ NORMALIZE; -+ p->buf = buf; -+ p->range = range; -+ p->code = code; -+ p->remainLen = len; -+ p->dicPos = dicPos; -+ p->processedPos = processedPos; -+ p->reps[0] = rep0; -+ p->reps[1] = rep1; -+ p->reps[2] = rep2; -+ p->reps[3] = rep3; -+ p->state = state; -+ -+ return SZ_OK; -+} -+ -+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -+{ -+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -+ { -+ Byte *dic = p->dic; -+ SizeT dicPos = p->dicPos; -+ SizeT dicBufSize = p->dicBufSize; -+ unsigned len = p->remainLen; -+ UInt32 rep0 = p->reps[0]; -+ if (limit - dicPos < len) -+ len = (unsigned)(limit - dicPos); -+ -+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -+ p->checkDicSize = p->prop.dicSize; -+ -+ p->processedPos += len; -+ p->remainLen -= len; -+ while (len-- != 0) -+ { -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ } -+ p->dicPos = dicPos; -+ } -+} -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ do -+ { -+ SizeT limit2 = limit; -+ if (p->checkDicSize == 0) -+ { -+ UInt32 rem = p->prop.dicSize - p->processedPos; -+ if (limit - p->dicPos > rem) -+ limit2 = p->dicPos + rem; -+ } -+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -+ if (p->processedPos >= p->prop.dicSize) -+ p->checkDicSize = p->prop.dicSize; -+ LzmaDec_WriteRem(p, limit); -+ } -+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -+ -+ if (p->remainLen > kMatchSpecLenStart) -+ { -+ p->remainLen = kMatchSpecLenStart; -+ } -+ return 0; -+} -+ -+typedef enum -+{ -+ DUMMY_ERROR, /* unexpected end of input stream */ -+ DUMMY_LIT, -+ DUMMY_MATCH, -+ DUMMY_REP -+} ELzmaDummy; -+ -+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -+{ -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ const Byte *bufLimit = buf + inSize; -+ CLzmaProb *probs = p->probs; -+ unsigned state = p->state; -+ ELzmaDummy res; -+ -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK -+ -+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -+ -+ prob = probs + Literal; -+ if (p->checkDicSize != 0 || p->processedPos != 0) -+ prob += (LZMA_LIT_SIZE * -+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ unsigned symbol = 1; -+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ unsigned symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ res = DUMMY_LIT; -+ } -+ else -+ { -+ unsigned len; -+ UPDATE_1_CHECK; -+ -+ prob = probs + IsRep + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ state = 0; -+ prob = probs + LenCoder; -+ res = DUMMY_MATCH; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ res = DUMMY_REP; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ NORMALIZE_CHECK; -+ return DUMMY_REP; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ } -+ state = kNumStates; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = 1 << kLenNumLowBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenChoice2; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = 1 << kLenNumMidBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = 1 << kLenNumHighBits; -+ } -+ } -+ TREE_DECODE_CHECK(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ unsigned posSlot; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ -+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -+ -+ if (posSlot < kEndPosModelIndex) -+ { -+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE_CHECK -+ range >>= 1; -+ code -= range & (((code - range) >> 31) - 1); -+ /* if (code >= range) code -= range; */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ unsigned i = 1; -+ do -+ { -+ GET_BIT_CHECK(prob + i, i); -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ } -+ } -+ } -+ NORMALIZE_CHECK; -+ return res; -+} -+ -+ -+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -+{ -+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -+ p->range = 0xFFFFFFFF; -+ p->needFlush = 0; -+} -+ -+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+{ -+ p->needFlush = 1; -+ p->remainLen = 0; -+ p->tempBufSize = 0; -+ -+ if (initDic) -+ { -+ p->processedPos = 0; -+ p->checkDicSize = 0; -+ p->needInitState = 1; -+ } -+ if (initState) -+ p->needInitState = 1; -+} -+ -+void LzmaDec_Init(CLzmaDec *p) -+{ -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+} -+ -+static void LzmaDec_InitStateReal(CLzmaDec *p) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -+ UInt32 i; -+ CLzmaProb *probs = p->probs; -+ for (i = 0; i < numProbs; i++) -+ probs[i] = kBitModelTotal >> 1; -+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -+ p->state = 0; -+ p->needInitState = 0; -+} -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT inSize = *srcLen; -+ (*srcLen) = 0; -+ LzmaDec_WriteRem(p, dicLimit); -+ -+ *status = LZMA_STATUS_NOT_SPECIFIED; -+ -+ while (p->remainLen != kMatchSpecLenStart) -+ { -+ int checkEndMarkNow; -+ -+ if (p->needFlush != 0) -+ { -+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -+ p->tempBuf[p->tempBufSize++] = *src++; -+ if (p->tempBufSize < RC_INIT_SIZE) -+ { -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (p->tempBuf[0] != 0) -+ return SZ_ERROR_DATA; -+ -+ LzmaDec_InitRc(p, p->tempBuf); -+ p->tempBufSize = 0; -+ } -+ -+ checkEndMarkNow = 0; -+ if (p->dicPos >= dicLimit) -+ { -+ if (p->remainLen == 0 && p->code == 0) -+ { -+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -+ return SZ_OK; -+ } -+ if (finishMode == LZMA_FINISH_ANY) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_OK; -+ } -+ if (p->remainLen != 0) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ checkEndMarkNow = 1; -+ } -+ -+ if (p->needInitState) -+ LzmaDec_InitStateReal(p); -+ -+ if (p->tempBufSize == 0) -+ { -+ SizeT processed; -+ const Byte *bufLimit; -+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ memcpy(p->tempBuf, src, inSize); -+ p->tempBufSize = (unsigned)inSize; -+ (*srcLen) += inSize; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ bufLimit = src; -+ } -+ else -+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -+ p->buf = src; -+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -+ return SZ_ERROR_DATA; -+ processed = (SizeT)(p->buf - src); -+ (*srcLen) += processed; -+ src += processed; -+ inSize -= processed; -+ } -+ else -+ { -+ unsigned rem = p->tempBufSize, lookAhead = 0; -+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -+ p->tempBuf[rem++] = src[lookAhead++]; -+ p->tempBufSize = rem; -+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ (*srcLen) += lookAhead; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ } -+ p->buf = p->tempBuf; -+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -+ return SZ_ERROR_DATA; -+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -+ (*srcLen) += lookAhead; -+ src += lookAhead; -+ inSize -= lookAhead; -+ p->tempBufSize = 0; -+ } -+ } -+ if (p->code == 0) -+ *status = LZMA_STATUS_FINISHED_WITH_MARK; -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+} -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT outSize = *destLen; -+ SizeT inSize = *srcLen; -+ *srcLen = *destLen = 0; -+ for (;;) -+ { -+ SizeT inSizeCur = inSize, outSizeCur, dicPos; -+ ELzmaFinishMode curFinishMode; -+ SRes res; -+ if (p->dicPos == p->dicBufSize) -+ p->dicPos = 0; -+ dicPos = p->dicPos; -+ if (outSize > p->dicBufSize - dicPos) -+ { -+ outSizeCur = p->dicBufSize; -+ curFinishMode = LZMA_FINISH_ANY; -+ } -+ else -+ { -+ outSizeCur = dicPos + outSize; -+ curFinishMode = finishMode; -+ } -+ -+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -+ src += inSizeCur; -+ inSize -= inSizeCur; -+ *srcLen += inSizeCur; -+ outSizeCur = p->dicPos - dicPos; -+ memcpy(dest, p->dic + dicPos, outSizeCur); -+ dest += outSizeCur; -+ outSize -= outSizeCur; -+ *destLen += outSizeCur; -+ if (res != 0) -+ return res; -+ if (outSizeCur == 0 || outSize == 0) -+ return SZ_OK; -+ } -+} -+ -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+} -+ -+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->dic); -+ p->dic = 0; -+} -+ -+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ LzmaDec_FreeProbs(p, alloc); -+ LzmaDec_FreeDict(p, alloc); -+} -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+{ -+ UInt32 dicSize; -+ Byte d; -+ -+ if (size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_UNSUPPORTED; -+ else -+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -+ -+ if (dicSize < LZMA_DIC_MIN) -+ dicSize = LZMA_DIC_MIN; -+ p->dicSize = dicSize; -+ -+ d = data[0]; -+ if (d >= (9 * 5 * 5)) -+ return SZ_ERROR_UNSUPPORTED; -+ -+ p->lc = d % 9; -+ d /= 9; -+ p->pb = d / 5; -+ p->lp = d % 5; -+ -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -+{ -+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -+ if (p->probs == 0 || numProbs != p->numProbs) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -+ p->numProbs = numProbs; -+ if (p->probs == 0) -+ return SZ_ERROR_MEM; -+ } -+ return SZ_OK; -+} -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ SizeT dicBufSize; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ dicBufSize = propNew.dicSize; -+ if (p->dic == 0 || dicBufSize != p->dicBufSize) -+ { -+ LzmaDec_FreeDict(p, alloc); -+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -+ if (p->dic == 0) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ } -+ p->dicBufSize = dicBufSize; -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc) -+{ -+ CLzmaDec p; -+ SRes res; -+ SizeT inSize = *srcLen; -+ SizeT outSize = *destLen; -+ *srcLen = *destLen = 0; -+ if (inSize < RC_INIT_SIZE) -+ return SZ_ERROR_INPUT_EOF; -+ -+ LzmaDec_Construct(&p); -+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -+ if (res != 0) -+ return res; -+ p.dic = dest; -+ p.dicBufSize = outSize; -+ -+ LzmaDec_Init(&p); -+ -+ *srcLen = inSize; -+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -+ -+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -+ res = SZ_ERROR_INPUT_EOF; -+ -+ (*destLen) = p.dicPos; -+ LzmaDec_FreeProbs(&p, alloc); -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/LzmaEnc.c -@@ -0,0 +1,2271 @@ -+/* LzmaEnc.c -- LZMA Encoder -+2009-11-24 : Igor Pavlov : Public domain */ -+ -+#include <string.h> -+ -+/* #define SHOW_STAT */ -+/* #define SHOW_STAT2 */ -+ -+#if defined(SHOW_STAT) || defined(SHOW_STAT2) -+#include <stdio.h> -+#endif -+ -+#include "LzmaEnc.h" -+ -+/* disable MT */ -+#define _7ZIP_ST -+ -+#include "LzFind.h" -+#ifndef _7ZIP_ST -+#include "LzFindMt.h" -+#endif -+ -+#ifdef SHOW_STAT -+static int ttt = 0; -+#endif -+ -+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -+ -+#define kBlockSize (9 << 10) -+#define kUnpackBlockSize (1 << 18) -+#define kMatchArraySize (1 << 21) -+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -+ -+#define kNumMaxDirectBits (31) -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+#define kProbInitValue (kBitModelTotal >> 1) -+ -+#define kNumMoveReducingBits 4 -+#define kNumBitPriceShiftBits 4 -+#define kBitPrice (1 << kNumBitPriceShiftBits) -+ -+void LzmaEncProps_Init(CLzmaEncProps *p) -+{ -+ p->level = 5; -+ p->dictSize = p->mc = 0; -+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -+ p->writeEndMark = 0; -+} -+ -+void LzmaEncProps_Normalize(CLzmaEncProps *p) -+{ -+ int level = p->level; -+ if (level < 0) level = 5; -+ p->level = level; -+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -+ if (p->lc < 0) p->lc = 3; -+ if (p->lp < 0) p->lp = 0; -+ if (p->pb < 0) p->pb = 2; -+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -+ if (p->numHashBytes < 0) p->numHashBytes = 4; -+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -+ if (p->numThreads < 0) -+ p->numThreads = -+ #ifndef _7ZIP_ST -+ ((p->btMode && p->algo) ? 2 : 1); -+ #else -+ 1; -+ #endif -+} -+ -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+{ -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ return props.dictSize; -+} -+ -+/* #define LZMA_LOG_BSR */ -+/* Define it for Intel's CPU */ -+ -+ -+#ifdef LZMA_LOG_BSR -+ -+#define kDicLogSizeMaxCompress 30 -+ -+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+UInt32 GetPosSlot1(UInt32 pos) -+{ -+ UInt32 res; -+ BSR2_RET(pos, res); -+ return res; -+} -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -+ -+#else -+ -+#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+void LzmaEnc_FastPosInit(Byte *g_FastPos) -+{ -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+ g_FastPos[1] = 1; -+ -+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -+ { -+ UInt32 k = (1 << ((slotFast >> 1) - 1)); -+ UInt32 j; -+ for (j = 0; j < k; j++, c++) -+ g_FastPos[c] = (Byte)slotFast; -+ } -+} -+ -+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -+ res = p->g_FastPos[pos >> i] + (i * 2); } -+/* -+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -+ p->g_FastPos[pos >> 6] + 12 : \ -+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -+*/ -+ -+#define GetPosSlot1(pos) p->g_FastPos[pos] -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -+ -+#endif -+ -+ -+#define LZMA_NUM_REPS 4 -+ -+typedef unsigned CState; -+ -+typedef struct -+{ -+ UInt32 price; -+ -+ CState state; -+ int prev1IsChar; -+ int prev2; -+ -+ UInt32 posPrev2; -+ UInt32 backPrev2; -+ -+ UInt32 posPrev; -+ UInt32 backPrev; -+ UInt32 backs[LZMA_NUM_REPS]; -+} COptimal; -+ -+#define kNumOpts (1 << 12) -+ -+#define kNumLenToPosStates 4 -+#define kNumPosSlotBits 6 -+#define kDicLogSizeMin 0 -+#define kDicLogSizeMax 32 -+#define kDistTableSizeMax (kDicLogSizeMax * 2) -+ -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+#define kAlignMask (kAlignTableSize - 1) -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -+ -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+#define LZMA_PB_MAX 4 -+#define LZMA_LC_MAX 8 -+#define LZMA_LP_MAX 4 -+ -+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -+ -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define LZMA_MATCH_LEN_MIN 2 -+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -+ -+#define kNumStates 12 -+ -+typedef struct -+{ -+ CLzmaProb choice; -+ CLzmaProb choice2; -+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -+ CLzmaProb high[kLenNumHighSymbols]; -+} CLenEnc; -+ -+typedef struct -+{ -+ CLenEnc p; -+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -+ UInt32 tableSize; -+ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -+} CLenPriceEnc; -+ -+typedef struct -+{ -+ UInt32 range; -+ Byte cache; -+ UInt64 low; -+ UInt64 cacheSize; -+ Byte *buf; -+ Byte *bufLim; -+ Byte *bufBase; -+ ISeqOutStream *outStream; -+ UInt64 processed; -+ SRes res; -+} CRangeEnc; -+ -+typedef struct -+{ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+} CSaveState; -+ -+typedef struct -+{ -+ IMatchFinder matchFinder; -+ void *matchFinderObj; -+ -+ #ifndef _7ZIP_ST -+ Bool mtMode; -+ CMatchFinderMt matchFinderMt; -+ #endif -+ -+ CMatchFinder matchFinderBase; -+ -+ #ifndef _7ZIP_ST -+ Byte pad[128]; -+ #endif -+ -+ UInt32 optimumEndIndex; -+ UInt32 optimumCurrentIndex; -+ -+ UInt32 longestMatchLength; -+ UInt32 numPairs; -+ UInt32 numAvail; -+ COptimal opt[kNumOpts]; -+ -+ #ifndef LZMA_LOG_BSR -+ Byte g_FastPos[1 << kNumLogBits]; -+ #endif -+ -+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -+ UInt32 numFastBytes; -+ UInt32 additionalOffset; -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+ -+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -+ UInt32 alignPrices[kAlignTableSize]; -+ UInt32 alignPriceCount; -+ -+ UInt32 distTableSize; -+ -+ unsigned lc, lp, pb; -+ unsigned lpMask, pbMask; -+ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ unsigned lclp; -+ -+ Bool fastMode; -+ -+ CRangeEnc rc; -+ -+ Bool writeEndMark; -+ UInt64 nowPos64; -+ UInt32 matchPriceCount; -+ Bool finished; -+ Bool multiThread; -+ -+ SRes result; -+ UInt32 dictSize; -+ UInt32 matchFinderCycles; -+ -+ int needInit; -+ -+ CSaveState saveState; -+} CLzmaEnc; -+ -+void LzmaEnc_SaveState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CSaveState *dest = &p->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -+} -+ -+void LzmaEnc_RestoreState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *dest = (CLzmaEnc *)pp; -+ const CSaveState *p = &dest->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -+} -+ -+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ -+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -+ return SZ_ERROR_PARAM; -+ p->dictSize = props.dictSize; -+ p->matchFinderCycles = props.mc; -+ { -+ unsigned fb = props.fb; -+ if (fb < 5) -+ fb = 5; -+ if (fb > LZMA_MATCH_LEN_MAX) -+ fb = LZMA_MATCH_LEN_MAX; -+ p->numFastBytes = fb; -+ } -+ p->lc = props.lc; -+ p->lp = props.lp; -+ p->pb = props.pb; -+ p->fastMode = (props.algo == 0); -+ p->matchFinderBase.btMode = props.btMode; -+ { -+ UInt32 numHashBytes = 4; -+ if (props.btMode) -+ { -+ if (props.numHashBytes < 2) -+ numHashBytes = 2; -+ else if (props.numHashBytes < 4) -+ numHashBytes = props.numHashBytes; -+ } -+ p->matchFinderBase.numHashBytes = numHashBytes; -+ } -+ -+ p->matchFinderBase.cutValue = props.mc; -+ -+ p->writeEndMark = props.writeEndMark; -+ -+ #ifndef _7ZIP_ST -+ /* -+ if (newMultiThread != _multiThread) -+ { -+ ReleaseMatchFinder(); -+ _multiThread = newMultiThread; -+ } -+ */ -+ p->multiThread = (props.numThreads > 1); -+ #endif -+ -+ return SZ_OK; -+} -+ -+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -+ -+#define IsCharState(s) ((s) < 7) -+ -+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -+ -+#define kInfinityPrice (1 << 30) -+ -+static void RangeEnc_Construct(CRangeEnc *p) -+{ -+ p->outStream = 0; -+ p->bufBase = 0; -+} -+ -+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -+ -+#define RC_BUF_SIZE (1 << 16) -+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ if (p->bufBase == 0) -+ { -+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -+ if (p->bufBase == 0) -+ return 0; -+ p->bufLim = p->bufBase + RC_BUF_SIZE; -+ } -+ return 1; -+} -+ -+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->bufBase); -+ p->bufBase = 0; -+} -+ -+static void RangeEnc_Init(CRangeEnc *p) -+{ -+ /* Stream.Init(); */ -+ p->low = 0; -+ p->range = 0xFFFFFFFF; -+ p->cacheSize = 1; -+ p->cache = 0; -+ -+ p->buf = p->bufBase; -+ -+ p->processed = 0; -+ p->res = SZ_OK; -+} -+ -+static void RangeEnc_FlushStream(CRangeEnc *p) -+{ -+ size_t num; -+ if (p->res != SZ_OK) -+ return; -+ num = p->buf - p->bufBase; -+ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -+ p->res = SZ_ERROR_WRITE; -+ p->processed += num; -+ p->buf = p->bufBase; -+} -+ -+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -+{ -+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -+ { -+ Byte temp = p->cache; -+ do -+ { -+ Byte *buf = p->buf; -+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -+ p->buf = buf; -+ if (buf == p->bufLim) -+ RangeEnc_FlushStream(p); -+ temp = 0xFF; -+ } -+ while (--p->cacheSize != 0); -+ p->cache = (Byte)((UInt32)p->low >> 24); -+ } -+ p->cacheSize++; -+ p->low = (UInt32)p->low << 8; -+} -+ -+static void RangeEnc_FlushData(CRangeEnc *p) -+{ -+ int i; -+ for (i = 0; i < 5; i++) -+ RangeEnc_ShiftLow(p); -+} -+ -+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -+{ -+ do -+ { -+ p->range >>= 1; -+ p->low += p->range & (0 - ((value >> --numBits) & 1)); -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+ } -+ while (numBits != 0); -+} -+ -+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -+{ -+ UInt32 ttt = *prob; -+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -+ if (symbol == 0) -+ { -+ p->range = newBound; -+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -+ } -+ else -+ { -+ p->low += newBound; -+ p->range -= newBound; -+ ttt -= ttt >> kNumMoveBits; -+ } -+ *prob = (CLzmaProb)ttt; -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+} -+ -+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -+{ -+ symbol |= 0x100; -+ do -+ { -+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -+{ -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+} -+ -+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+{ -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+ { -+ const int kCyclesBits = kNumBitPriceShiftBits; -+ UInt32 w = i; -+ UInt32 bitCount = 0; -+ int j; -+ for (j = 0; j < kCyclesBits; j++) -+ { -+ w = w * w; -+ bitCount <<= 1; -+ while (w >= ((UInt32)1 << 16)) -+ { -+ w >>= 1; -+ bitCount++; -+ } -+ } -+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -+ } -+} -+ -+ -+#define GET_PRICE(prob, symbol) \ -+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICEa(prob, symbol) \ -+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= 0x100; -+ do -+ { -+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+ -+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0;) -+ { -+ UInt32 bit; -+ i--; -+ bit = (symbol >> i) & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ } -+} -+ -+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = 0; i < numBitLevels; i++) -+ { -+ UInt32 bit = symbol & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ symbol >>= 1; -+ } -+} -+ -+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= (1 << numBitLevels); -+ while (symbol != 1) -+ { -+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -+ symbol >>= 1; -+ } -+ return price; -+} -+ -+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0; i--) -+ { -+ UInt32 bit = symbol & 1; -+ symbol >>= 1; -+ price += GET_PRICEa(probs[m], bit); -+ m = (m << 1) | bit; -+ } -+ return price; -+} -+ -+ -+static void LenEnc_Init(CLenEnc *p) -+{ -+ unsigned i; -+ p->choice = p->choice2 = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -+ p->low[i] = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -+ p->mid[i] = kProbInitValue; -+ for (i = 0; i < kLenNumHighSymbols; i++) -+ p->high[i] = kProbInitValue; -+} -+ -+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -+{ -+ if (symbol < kLenNumLowSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 0); -+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 1); -+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 0); -+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 1); -+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -+ } -+ } -+} -+ -+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -+{ -+ UInt32 a0 = GET_PRICE_0a(p->choice); -+ UInt32 a1 = GET_PRICE_1a(p->choice); -+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -+ UInt32 i = 0; -+ for (i = 0; i < kLenNumLowSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -+ } -+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -+ } -+ for (; i < numSymbols; i++) -+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -+} -+ -+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -+{ -+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -+ p->counters[posState] = p->tableSize; -+} -+ -+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -+{ -+ UInt32 posState; -+ for (posState = 0; posState < numPosStates; posState++) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -+{ -+ LenEnc_Encode(&p->p, rc, symbol, posState); -+ if (updatePrice) -+ if (--p->counters[posState] == 0) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+ -+ -+ -+static void MovePos(CLzmaEnc *p, UInt32 num) -+{ -+ #ifdef SHOW_STAT -+ ttt += num; -+ printf("\n MovePos %d", num); -+ #endif -+ if (num != 0) -+ { -+ p->additionalOffset += num; -+ p->matchFinder.Skip(p->matchFinderObj, num); -+ } -+} -+ -+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -+{ -+ UInt32 lenRes = 0, numPairs; -+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -+ #ifdef SHOW_STAT -+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -+ ttt++; -+ { -+ UInt32 i; -+ for (i = 0; i < numPairs; i += 2) -+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -+ } -+ #endif -+ if (numPairs > 0) -+ { -+ lenRes = p->matches[numPairs - 2]; -+ if (lenRes == p->numFastBytes) -+ { -+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ UInt32 distance = p->matches[numPairs - 1] + 1; -+ UInt32 numAvail = p->numAvail; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ { -+ const Byte *pby2 = pby - distance; -+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -+ } -+ } -+ } -+ p->additionalOffset++; -+ *numDistancePairsRes = numPairs; -+ return lenRes; -+} -+ -+ -+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -+#define IsShortRep(p) ((p)->backPrev == 0) -+ -+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -+{ -+ return -+ GET_PRICE_0(p->isRepG0[state]) + -+ GET_PRICE_0(p->isRep0Long[state][posState]); -+} -+ -+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -+{ -+ UInt32 price; -+ if (repIndex == 0) -+ { -+ price = GET_PRICE_0(p->isRepG0[state]); -+ price += GET_PRICE_1(p->isRep0Long[state][posState]); -+ } -+ else -+ { -+ price = GET_PRICE_1(p->isRepG0[state]); -+ if (repIndex == 1) -+ price += GET_PRICE_0(p->isRepG1[state]); -+ else -+ { -+ price += GET_PRICE_1(p->isRepG1[state]); -+ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -+ } -+ } -+ return price; -+} -+ -+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -+{ -+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -+ GetPureRepPrice(p, repIndex, state, posState); -+} -+ -+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -+{ -+ UInt32 posMem = p->opt[cur].posPrev; -+ UInt32 backMem = p->opt[cur].backPrev; -+ p->optimumEndIndex = cur; -+ do -+ { -+ if (p->opt[cur].prev1IsChar) -+ { -+ MakeAsChar(&p->opt[posMem]) -+ p->opt[posMem].posPrev = posMem - 1; -+ if (p->opt[cur].prev2) -+ { -+ p->opt[posMem - 1].prev1IsChar = False; -+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -+ } -+ } -+ { -+ UInt32 posPrev = posMem; -+ UInt32 backCur = backMem; -+ -+ backMem = p->opt[posPrev].backPrev; -+ posMem = p->opt[posPrev].posPrev; -+ -+ p->opt[posPrev].backPrev = backCur; -+ p->opt[posPrev].posPrev = cur; -+ cur = posPrev; -+ } -+ } -+ while (cur != 0); -+ *backRes = p->opt[0].backPrev; -+ p->optimumCurrentIndex = p->opt[0].posPrev; -+ return p->optimumCurrentIndex; -+} -+ -+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -+ -+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -+ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -+ UInt32 *matches; -+ const Byte *data; -+ Byte curByte, matchByte; -+ if (p->optimumEndIndex != p->optimumCurrentIndex) -+ { -+ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -+ *backRes = opt->backPrev; -+ p->optimumCurrentIndex = opt->posPrev; -+ return lenRes; -+ } -+ p->optimumCurrentIndex = p->optimumEndIndex = 0; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ if (numAvail < 2) -+ { -+ *backRes = (UInt32)(-1); -+ return 1; -+ } -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ repMaxIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 lenTest; -+ const Byte *data2; -+ reps[i] = p->reps[i]; -+ data2 = data - (reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ { -+ repLens[i] = 0; -+ continue; -+ } -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ repLens[i] = lenTest; -+ if (lenTest > repLens[repMaxIndex]) -+ repMaxIndex = i; -+ } -+ if (repLens[repMaxIndex] >= p->numFastBytes) -+ { -+ UInt32 lenRes; -+ *backRes = repMaxIndex; -+ lenRes = repLens[repMaxIndex]; -+ MovePos(p, lenRes - 1); -+ return lenRes; -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -+ { -+ *backRes = (UInt32)-1; -+ return 1; -+ } -+ -+ p->opt[0].state = (CState)p->state; -+ -+ posState = (position & p->pbMask); -+ -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -+ (!IsCharState(p->state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ MakeAsChar(&p->opt[1]); -+ -+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -+ -+ if (matchByte == curByte) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -+ if (shortRepPrice < p->opt[1].price) -+ { -+ p->opt[1].price = shortRepPrice; -+ MakeAsShortRep(&p->opt[1]); -+ } -+ } -+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -+ -+ if (lenEnd < 2) -+ { -+ *backRes = p->opt[1].backPrev; -+ return 1; -+ } -+ -+ p->opt[1].posPrev = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ p->opt[0].backs[i] = reps[i]; -+ -+ len = lenEnd; -+ do -+ p->opt[len--].price = kInfinityPrice; -+ while (len >= 2); -+ -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 repLen = repLens[i]; -+ UInt32 price; -+ if (repLen < 2) -+ continue; -+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -+ COptimal *opt = &p->opt[repLen]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = i; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--repLen >= 2); -+ } -+ -+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -+ -+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -+ if (len <= mainLen) -+ { -+ UInt32 offs = 0; -+ while (len > matches[offs]) -+ offs += 2; -+ for (; ; len++) -+ { -+ COptimal *opt; -+ UInt32 distance = matches[offs + 1]; -+ -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(len); -+ if (distance < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -+ else -+ { -+ UInt32 slot; -+ GetPosSlot2(distance, slot); -+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -+ } -+ opt = &p->opt[len]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = distance + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ if (len == matches[offs]) -+ { -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ } -+ } -+ } -+ -+ cur = 0; -+ -+ #ifdef SHOW_STAT2 -+ if (position >= 0) -+ { -+ unsigned i; -+ printf("\n pos = %4X", position); -+ for (i = cur; i <= lenEnd; i++) -+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -+ } -+ #endif -+ -+ for (;;) -+ { -+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -+ Bool nextIsChar; -+ Byte curByte, matchByte; -+ const Byte *data; -+ COptimal *curOpt; -+ COptimal *nextOpt; -+ -+ cur++; -+ if (cur == lenEnd) -+ return Backward(p, backRes, cur); -+ -+ newLen = ReadMatchDistances(p, &numPairs); -+ if (newLen >= p->numFastBytes) -+ { -+ p->numPairs = numPairs; -+ p->longestMatchLength = newLen; -+ return Backward(p, backRes, cur); -+ } -+ position++; -+ curOpt = &p->opt[cur]; -+ posPrev = curOpt->posPrev; -+ if (curOpt->prev1IsChar) -+ { -+ posPrev--; -+ if (curOpt->prev2) -+ { -+ state = p->opt[curOpt->posPrev2].state; -+ if (curOpt->backPrev2 < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ state = kLiteralNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ if (posPrev == cur - 1) -+ { -+ if (IsShortRep(curOpt)) -+ state = kShortRepNextStates[state]; -+ else -+ state = kLiteralNextStates[state]; -+ } -+ else -+ { -+ UInt32 pos; -+ const COptimal *prevOpt; -+ if (curOpt->prev1IsChar && curOpt->prev2) -+ { -+ posPrev = curOpt->posPrev2; -+ pos = curOpt->backPrev2; -+ state = kRepNextStates[state]; -+ } -+ else -+ { -+ pos = curOpt->backPrev; -+ if (pos < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ prevOpt = &p->opt[posPrev]; -+ if (pos < LZMA_NUM_REPS) -+ { -+ UInt32 i; -+ reps[0] = prevOpt->backs[pos]; -+ for (i = 1; i <= pos; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ for (; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i]; -+ } -+ else -+ { -+ UInt32 i; -+ reps[0] = (pos - LZMA_NUM_REPS); -+ for (i = 1; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ } -+ } -+ curOpt->state = (CState)state; -+ -+ curOpt->backs[0] = reps[0]; -+ curOpt->backs[1] = reps[1]; -+ curOpt->backs[2] = reps[2]; -+ curOpt->backs[3] = reps[3]; -+ -+ curPrice = curOpt->price; -+ nextIsChar = False; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ posState = (position & p->pbMask); -+ -+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ curAnd1Price += -+ (!IsCharState(state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ nextOpt = &p->opt[cur + 1]; -+ -+ if (curAnd1Price < nextOpt->price) -+ { -+ nextOpt->price = curAnd1Price; -+ nextOpt->posPrev = cur; -+ MakeAsChar(nextOpt); -+ nextIsChar = True; -+ } -+ -+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -+ -+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -+ if (shortRepPrice <= nextOpt->price) -+ { -+ nextOpt->price = shortRepPrice; -+ nextOpt->posPrev = cur; -+ MakeAsShortRep(nextOpt); -+ nextIsChar = True; -+ } -+ } -+ numAvailFull = p->numAvail; -+ { -+ UInt32 temp = kNumOpts - 1 - cur; -+ if (temp < numAvailFull) -+ numAvailFull = temp; -+ } -+ -+ if (numAvailFull < 2) -+ continue; -+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -+ -+ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -+ { -+ /* try Literal + rep0 */ -+ UInt32 temp; -+ UInt32 lenTest2; -+ const Byte *data2 = data - (reps[0] + 1); -+ UInt32 limit = p->numFastBytes + 1; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ -+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -+ lenTest2 = temp - 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kLiteralNextStates[state]; -+ UInt32 posStateNext = (position + 1) & p->pbMask; -+ UInt32 nextRepMatchPrice = curAnd1Price + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = False; -+ } -+ } -+ } -+ } -+ -+ startLen = 2; /* speed optimization */ -+ { -+ UInt32 repIndex; -+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -+ { -+ UInt32 lenTest; -+ UInt32 lenTestTemp; -+ UInt32 price; -+ const Byte *data2 = data - (reps[repIndex] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ while (lenEnd < cur + lenTest) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ lenTestTemp = lenTest; -+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -+ COptimal *opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = repIndex; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--lenTest >= 2); -+ lenTest = lenTestTemp; -+ -+ if (repIndex == 0) -+ startLen = lenTest + 1; -+ -+ /* if (_maxMode) */ -+ { -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kRepNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = -+ price + p->repLenEnc.prices[posState][lenTest - 2] + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (position + lenTest + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = repIndex; -+ } -+ } -+ } -+ } -+ } -+ } -+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -+ if (newLen > numAvail) -+ { -+ newLen = numAvail; -+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -+ matches[numPairs] = newLen; -+ numPairs += 2; -+ } -+ if (newLen >= startLen) -+ { -+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -+ UInt32 offs, curBack, posSlot; -+ UInt32 lenTest; -+ while (lenEnd < cur + newLen) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ -+ offs = 0; -+ while (startLen > matches[offs]) -+ offs += 2; -+ curBack = matches[offs + 1]; -+ GetPosSlot2(curBack, posSlot); -+ for (lenTest = /*2*/ startLen; ; lenTest++) -+ { -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(lenTest); -+ COptimal *opt; -+ if (curBack < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -+ else -+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -+ -+ opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = curBack + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ -+ if (/*_maxMode && */lenTest == matches[offs]) -+ { -+ /* Try Match + Literal + Rep0 */ -+ const Byte *data2 = data - (curBack + 1); -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kMatchNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = curAndLenPrice + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (posStateNext + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = curBack + LZMA_NUM_REPS; -+ } -+ } -+ } -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ curBack = matches[offs + 1]; -+ if (curBack >= kNumFullDistances) -+ GetPosSlot2(curBack, posSlot); -+ } -+ } -+ } -+ } -+} -+ -+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -+ -+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -+ const Byte *data; -+ const UInt32 *matches; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ *backRes = (UInt32)-1; -+ if (numAvail < 2) -+ return 1; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ -+ repLen = repIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -+ if (len >= p->numFastBytes) -+ { -+ *backRes = i; -+ MovePos(p, len - 1); -+ return len; -+ } -+ if (len > repLen) -+ { -+ repIndex = i; -+ repLen = len; -+ } -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ -+ mainDist = 0; /* for GCC */ -+ if (mainLen >= 2) -+ { -+ mainDist = matches[numPairs - 1]; -+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -+ { -+ if (!ChangePair(matches[numPairs - 3], mainDist)) -+ break; -+ numPairs -= 2; -+ mainLen = matches[numPairs - 2]; -+ mainDist = matches[numPairs - 1]; -+ } -+ if (mainLen == 2 && mainDist >= 0x80) -+ mainLen = 1; -+ } -+ -+ if (repLen >= 2 && ( -+ (repLen + 1 >= mainLen) || -+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -+ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -+ { -+ *backRes = repIndex; -+ MovePos(p, repLen - 1); -+ return repLen; -+ } -+ -+ if (mainLen < 2 || numAvail <= 2) -+ return 1; -+ -+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -+ if (p->longestMatchLength >= 2) -+ { -+ UInt32 newDistance = matches[p->numPairs - 1]; -+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -+ (p->longestMatchLength > mainLen + 1) || -+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -+ return 1; -+ } -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len, limit; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ limit = mainLen - 1; -+ for (len = 2; len < limit && data[len] == data2[len]; len++); -+ if (len >= limit) -+ return 1; -+ } -+ *backRes = mainDist + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 2); -+ return mainLen; -+} -+ -+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -+{ -+ UInt32 len; -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ len = LZMA_MATCH_LEN_MIN; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -+} -+ -+static SRes CheckErrors(CLzmaEnc *p) -+{ -+ if (p->result != SZ_OK) -+ return p->result; -+ if (p->rc.res != SZ_OK) -+ p->result = SZ_ERROR_WRITE; -+ if (p->matchFinderBase.result != SZ_OK) -+ p->result = SZ_ERROR_READ; -+ if (p->result != SZ_OK) -+ p->finished = True; -+ return p->result; -+} -+ -+static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -+{ -+ /* ReleaseMFStream(); */ -+ p->finished = True; -+ if (p->writeEndMark) -+ WriteEndMarker(p, nowPos & p->pbMask); -+ RangeEnc_FlushData(&p->rc); -+ RangeEnc_FlushStream(&p->rc); -+ return CheckErrors(p); -+} -+ -+static void FillAlignPrices(CLzmaEnc *p) -+{ -+ UInt32 i; -+ for (i = 0; i < kAlignTableSize; i++) -+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -+ p->alignPriceCount = 0; -+} -+ -+static void FillDistancesPrices(CLzmaEnc *p) -+{ -+ UInt32 tempPrices[kNumFullDistances]; -+ UInt32 i, lenToPosState; -+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -+ { -+ UInt32 posSlot = GetPosSlot1(i); -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -+ } -+ -+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -+ { -+ UInt32 posSlot; -+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -+ -+ { -+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -+ UInt32 i; -+ for (i = 0; i < kStartPosModelIndex; i++) -+ distancesPrices[i] = posSlotPrices[i]; -+ for (; i < kNumFullDistances; i++) -+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -+ } -+ } -+ p->matchPriceCount = 0; -+} -+ -+void LzmaEnc_Construct(CLzmaEnc *p) -+{ -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Construct(&p->matchFinderMt); -+ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -+ #endif -+ -+ { -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ LzmaEnc_SetProps(p, &props); -+ } -+ -+ #ifndef LZMA_LOG_BSR -+ LzmaEnc_FastPosInit(p->g_FastPos); -+ #endif -+ -+ LzmaEnc_InitPriceTables(p->ProbPrices); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -+{ -+ void *p; -+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -+ if (p != 0) -+ LzmaEnc_Construct((CLzmaEnc *)p); -+ return p; -+} -+ -+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+ #endif -+ MatchFinder_Free(&p->matchFinderBase, allocBig); -+ LzmaEnc_FreeLits(p, alloc); -+ RangeEnc_Free(&p->rc, alloc); -+} -+ -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -+ alloc->Free(alloc, p); -+} -+ -+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -+{ -+ UInt32 nowPos32, startPos32; -+ if (p->needInit) -+ { -+ p->matchFinder.Init(p->matchFinderObj); -+ p->needInit = 0; -+ } -+ -+ if (p->finished) -+ return p->result; -+ RINOK(CheckErrors(p)); -+ -+ nowPos32 = (UInt32)p->nowPos64; -+ startPos32 = nowPos32; -+ -+ if (p->nowPos64 == 0) -+ { -+ UInt32 numPairs; -+ Byte curByte; -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ return Flush(p, nowPos32); -+ ReadMatchDistances(p, &numPairs); -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -+ p->state = kLiteralNextStates[p->state]; -+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -+ LitEnc_Encode(&p->rc, p->litProbs, curByte); -+ p->additionalOffset--; -+ nowPos32++; -+ } -+ -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -+ for (;;) -+ { -+ UInt32 pos, len, posState; -+ -+ if (p->fastMode) -+ len = GetOptimumFast(p, &pos); -+ else -+ len = GetOptimum(p, nowPos32, &pos); -+ -+ #ifdef SHOW_STAT2 -+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -+ #endif -+ -+ posState = nowPos32 & p->pbMask; -+ if (len == 1 && pos == (UInt32)-1) -+ { -+ Byte curByte; -+ CLzmaProb *probs; -+ const Byte *data; -+ -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+ curByte = *data; -+ probs = LIT_PROBS(nowPos32, *(data - 1)); -+ if (IsCharState(p->state)) -+ LitEnc_Encode(&p->rc, probs, curByte); -+ else -+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -+ p->state = kLiteralNextStates[p->state]; -+ } -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ if (pos < LZMA_NUM_REPS) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -+ if (pos == 0) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -+ } -+ else -+ { -+ UInt32 distance = p->reps[pos]; -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -+ if (pos == 1) -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -+ if (pos == 3) -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ } -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = distance; -+ } -+ if (len == 1) -+ p->state = kShortRepNextStates[p->state]; -+ else -+ { -+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ p->state = kRepNextStates[p->state]; -+ } -+ } -+ else -+ { -+ UInt32 posSlot; -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ pos -= LZMA_NUM_REPS; -+ GetPosSlot(pos, posSlot); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -+ -+ if (posSlot >= kStartPosModelIndex) -+ { -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ UInt32 posReduced = pos - base; -+ -+ if (posSlot < kEndPosModelIndex) -+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -+ else -+ { -+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -+ p->alignPriceCount++; -+ } -+ } -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = pos; -+ p->matchPriceCount++; -+ } -+ } -+ p->additionalOffset -= len; -+ nowPos32 += len; -+ if (p->additionalOffset == 0) -+ { -+ UInt32 processed; -+ if (!p->fastMode) -+ { -+ if (p->matchPriceCount >= (1 << 7)) -+ FillDistancesPrices(p); -+ if (p->alignPriceCount >= kAlignTableSize) -+ FillAlignPrices(p); -+ } -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ break; -+ processed = nowPos32 - startPos32; -+ if (useLimits) -+ { -+ if (processed + kNumOpts + 300 >= maxUnpackSize || -+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -+ break; -+ } -+ else if (processed >= (1 << 15)) -+ { -+ p->nowPos64 += nowPos32 - startPos32; -+ return CheckErrors(p); -+ } -+ } -+ } -+ p->nowPos64 += nowPos32 - startPos32; -+ return Flush(p, nowPos32); -+} -+ -+#define kBigHashDicLimit ((UInt32)1 << 24) -+ -+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 beforeSize = kNumOpts; -+ Bool btMode; -+ if (!RangeEnc_Alloc(&p->rc, alloc)) -+ return SZ_ERROR_MEM; -+ btMode = (p->matchFinderBase.btMode != 0); -+ #ifndef _7ZIP_ST -+ p->mtMode = (p->multiThread && !p->fastMode && btMode); -+ #endif -+ -+ { -+ unsigned lclp = p->lc + p->lp; -+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ if (p->litProbs == 0 || p->saveState.litProbs == 0) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ p->lclp = lclp; -+ } -+ } -+ -+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -+ -+ if (beforeSize + p->dictSize < keepWindowSize) -+ beforeSize = keepWindowSize - p->dictSize; -+ -+ #ifndef _7ZIP_ST -+ if (p->mtMode) -+ { -+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -+ p->matchFinderObj = &p->matchFinderMt; -+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -+ } -+ else -+ #endif -+ { -+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -+ return SZ_ERROR_MEM; -+ p->matchFinderObj = &p->matchFinderBase; -+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -+ } -+ return SZ_OK; -+} -+ -+void LzmaEnc_Init(CLzmaEnc *p) -+{ -+ UInt32 i; -+ p->state = 0; -+ for (i = 0 ; i < LZMA_NUM_REPS; i++) -+ p->reps[i] = 0; -+ -+ RangeEnc_Init(&p->rc); -+ -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ UInt32 j; -+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -+ { -+ p->isMatch[i][j] = kProbInitValue; -+ p->isRep0Long[i][j] = kProbInitValue; -+ } -+ p->isRep[i] = kProbInitValue; -+ p->isRepG0[i] = kProbInitValue; -+ p->isRepG1[i] = kProbInitValue; -+ p->isRepG2[i] = kProbInitValue; -+ } -+ -+ { -+ UInt32 num = 0x300 << (p->lp + p->lc); -+ for (i = 0; i < num; i++) -+ p->litProbs[i] = kProbInitValue; -+ } -+ -+ { -+ for (i = 0; i < kNumLenToPosStates; i++) -+ { -+ CLzmaProb *probs = p->posSlotEncoder[i]; -+ UInt32 j; -+ for (j = 0; j < (1 << kNumPosSlotBits); j++) -+ probs[j] = kProbInitValue; -+ } -+ } -+ { -+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -+ p->posEncoders[i] = kProbInitValue; -+ } -+ -+ LenEnc_Init(&p->lenEnc.p); -+ LenEnc_Init(&p->repLenEnc.p); -+ -+ for (i = 0; i < (1 << kNumAlignBits); i++) -+ p->posAlignEncoder[i] = kProbInitValue; -+ -+ p->optimumEndIndex = 0; -+ p->optimumCurrentIndex = 0; -+ p->additionalOffset = 0; -+ -+ p->pbMask = (1 << p->pb) - 1; -+ p->lpMask = (1 << p->lp) - 1; -+} -+ -+void LzmaEnc_InitPrices(CLzmaEnc *p) -+{ -+ if (!p->fastMode) -+ { -+ FillDistancesPrices(p); -+ FillAlignPrices(p); -+ } -+ -+ p->lenEnc.tableSize = -+ p->repLenEnc.tableSize = -+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -+} -+ -+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 i; -+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -+ if (p->dictSize <= ((UInt32)1 << i)) -+ break; -+ p->distTableSize = i * 2; -+ -+ p->finished = False; -+ p->result = SZ_OK; -+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ p->nowPos64 = 0; -+ return SZ_OK; -+} -+ -+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ p->rc.outStream = outStream; -+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -+} -+ -+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -+ ISeqInStream *inStream, UInt32 keepWindowSize, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+{ -+ p->matchFinderBase.directInput = 1; -+ p->matchFinderBase.bufferBase = (Byte *)src; -+ p->matchFinderBase.directInputRem = srcLen; -+} -+ -+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ p->needInit = 1; -+ -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+void LzmaEnc_Finish(CLzmaEncHandle pp) -+{ -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ if (p->mtMode) -+ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -+ #else -+ pp = pp; -+ #endif -+} -+ -+typedef struct -+{ -+ ISeqOutStream funcTable; -+ Byte *data; -+ SizeT rem; -+ Bool overflow; -+} CSeqOutStreamBuf; -+ -+static size_t MyWrite(void *pp, const void *data, size_t size) -+{ -+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -+ if (p->rem < size) -+ { -+ size = p->rem; -+ p->overflow = True; -+ } -+ memcpy(p->data, data, size); -+ p->rem -= size; -+ p->data += size; -+ return size; -+} -+ -+ -+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+} -+ -+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+} -+ -+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ UInt64 nowPos64; -+ SRes res; -+ CSeqOutStreamBuf outStream; -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = False; -+ p->finished = False; -+ p->result = SZ_OK; -+ -+ if (reInit) -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ nowPos64 = p->nowPos64; -+ RangeEnc_Init(&p->rc); -+ p->rc.outStream = &outStream.funcTable; -+ -+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -+ -+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ -+ return res; -+} -+ -+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+{ -+ SRes res = SZ_OK; -+ -+ #ifndef _7ZIP_ST -+ Byte allocaDummy[0x300]; -+ int i = 0; -+ for (i = 0; i < 16; i++) -+ allocaDummy[i] = (Byte)i; -+ #endif -+ -+ for (;;) -+ { -+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -+ if (res != SZ_OK || p->finished != 0) -+ break; -+ if (progress != 0) -+ { -+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -+ if (res != SZ_OK) -+ { -+ res = SZ_ERROR_PROGRESS; -+ break; -+ } -+ } -+ } -+ LzmaEnc_Finish(p); -+ return res; -+} -+ -+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -+} -+ -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ int i; -+ UInt32 dictSize = p->dictSize; -+ if (*size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_PARAM; -+ *size = LZMA_PROPS_SIZE; -+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -+ -+ for (i = 11; i <= 30; i++) -+ { -+ if (dictSize <= ((UInt32)2 << i)) -+ { -+ dictSize = (2 << i); -+ break; -+ } -+ if (dictSize <= ((UInt32)3 << i)) -+ { -+ dictSize = (3 << i); -+ break; -+ } -+ } -+ -+ for (i = 0; i < 4; i++) -+ props[1 + i] = (Byte)(dictSize >> (8 * i)); -+ return SZ_OK; -+} -+ -+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ SRes res; -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ -+ CSeqOutStreamBuf outStream; -+ -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = writeEndMark; -+ -+ p->rc.outStream = &outStream.funcTable; -+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -+ if (res == SZ_OK) -+ res = LzmaEnc_Encode2(p, progress); -+ -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+} -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -+ SRes res; -+ if (p == 0) -+ return SZ_ERROR_MEM; -+ -+ res = LzmaEnc_SetProps(p, props); -+ if (res == SZ_OK) -+ { -+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -+ if (res == SZ_OK) -+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -+ writeEndMark, progress, alloc, allocBig); -+ } -+ -+ LzmaEnc_Destroy(p, alloc, allocBig); -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/Makefile -@@ -0,0 +1,7 @@ -+lzma_compress-objs := LzFind.o LzmaEnc.o -+lzma_decompress-objs := LzmaDec.o -+ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -+ -+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h diff --git a/target/linux/generic/pending-3.18/531-debloat_lzma.patch b/target/linux/generic/pending-3.18/531-debloat_lzma.patch deleted file mode 100644 index aa3c498016..0000000000 --- a/target/linux/generic/pending-3.18/531-debloat_lzma.patch +++ /dev/null @@ -1,1024 +0,0 @@ ---- a/include/linux/lzma/LzmaDec.h -+++ b/include/linux/lzma/LzmaDec.h -@@ -31,14 +31,6 @@ typedef struct _CLzmaProps - UInt32 dicSize; - } CLzmaProps; - --/* LzmaProps_Decode - decodes properties --Returns: -- SZ_OK -- SZ_ERROR_UNSUPPORTED - Unsupported properties --*/ -- --SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -- - - /* ---------- LZMA Decoder state ---------- */ - -@@ -70,8 +62,6 @@ typedef struct - - #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - --void LzmaDec_Init(CLzmaDec *p); -- - /* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -@@ -108,97 +98,6 @@ typedef enum - - /* ELzmaStatus is used only as output value for function call */ - -- --/* ---------- Interfaces ---------- */ -- --/* There are 3 levels of interfaces: -- 1) Dictionary Interface -- 2) Buffer Interface -- 3) One Call Interface -- You can select any of these interfaces, but don't mix functions from different -- groups for same object. */ -- -- --/* There are two variants to allocate state for Dictionary Interface: -- 1) LzmaDec_Allocate / LzmaDec_Free -- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -- You can use variant 2, if you set dictionary buffer manually. -- For Buffer Interface you must always use variant 1. -- --LzmaDec_Allocate* can return: -- SZ_OK -- SZ_ERROR_MEM - Memory allocation error -- SZ_ERROR_UNSUPPORTED - Unsupported properties --*/ -- --SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); --void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -- --SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); --void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -- --/* ---------- Dictionary Interface ---------- */ -- --/* You can use it, if you want to eliminate the overhead for data copying from -- dictionary to some other external buffer. -- You must work with CLzmaDec variables directly in this interface. -- -- STEPS: -- LzmaDec_Constr() -- LzmaDec_Allocate() -- for (each new stream) -- { -- LzmaDec_Init() -- while (it needs more decompression) -- { -- LzmaDec_DecodeToDic() -- use data from CLzmaDec::dic and update CLzmaDec::dicPos -- } -- } -- LzmaDec_Free() --*/ -- --/* LzmaDec_DecodeToDic -- -- The decoding to internal dictionary buffer (CLzmaDec::dic). -- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -- --finishMode: -- It has meaning only if the decoding reaches output limit (dicLimit). -- LZMA_FINISH_ANY - Decode just dicLimit bytes. -- LZMA_FINISH_END - Stream must be finished after dicLimit. -- --Returns: -- SZ_OK -- status: -- LZMA_STATUS_FINISHED_WITH_MARK -- LZMA_STATUS_NOT_FINISHED -- LZMA_STATUS_NEEDS_MORE_INPUT -- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -- SZ_ERROR_DATA - Data error --*/ -- --SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -- -- --/* ---------- Buffer Interface ---------- */ -- --/* It's zlib-like interface. -- See LzmaDec_DecodeToDic description for information about STEPS and return results, -- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -- to work with CLzmaDec variables manually. -- --finishMode: -- It has meaning only if the decoding reaches output limit (*destLen). -- LZMA_FINISH_ANY - Decode just destLen bytes. -- LZMA_FINISH_END - Stream must be finished after (*destLen). --*/ -- --SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -- -- - /* ---------- One Call Interface ---------- */ - - /* LzmaDecode ---- a/lib/lzma/LzmaDec.c -+++ b/lib/lzma/LzmaDec.c -@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, - p->needFlush = 0; - } - --void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) - { - p->needFlush = 1; - p->remainLen = 0; -@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p - p->needInitState = 1; - } - --void LzmaDec_Init(CLzmaDec *p) -+static void LzmaDec_Init(CLzmaDec *p) - { - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); -@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD - p->needInitState = 0; - } - --SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) - { - SizeT inSize = *srcLen; -@@ -837,65 +837,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; - } - --SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) --{ -- SizeT outSize = *destLen; -- SizeT inSize = *srcLen; -- *srcLen = *destLen = 0; -- for (;;) -- { -- SizeT inSizeCur = inSize, outSizeCur, dicPos; -- ELzmaFinishMode curFinishMode; -- SRes res; -- if (p->dicPos == p->dicBufSize) -- p->dicPos = 0; -- dicPos = p->dicPos; -- if (outSize > p->dicBufSize - dicPos) -- { -- outSizeCur = p->dicBufSize; -- curFinishMode = LZMA_FINISH_ANY; -- } -- else -- { -- outSizeCur = dicPos + outSize; -- curFinishMode = finishMode; -- } -- -- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -- src += inSizeCur; -- inSize -= inSizeCur; -- *srcLen += inSizeCur; -- outSizeCur = p->dicPos - dicPos; -- memcpy(dest, p->dic + dicPos, outSizeCur); -- dest += outSizeCur; -- outSize -= outSizeCur; -- *destLen += outSizeCur; -- if (res != 0) -- return res; -- if (outSizeCur == 0 || outSize == 0) -- return SZ_OK; -- } --} -- --void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) - { - alloc->Free(alloc, p->probs); - p->probs = 0; - } - --static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) --{ -- alloc->Free(alloc, p->dic); -- p->dic = 0; --} -- --void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) --{ -- LzmaDec_FreeProbs(p, alloc); -- LzmaDec_FreeDict(p, alloc); --} -- --SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) - { - UInt32 dicSize; - Byte d; -@@ -935,7 +883,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma - return SZ_OK; - } - --SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) - { - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -@@ -943,28 +891,6 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, - p->prop = propNew; - return SZ_OK; - } -- --SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) --{ -- CLzmaProps propNew; -- SizeT dicBufSize; -- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -- dicBufSize = propNew.dicSize; -- if (p->dic == 0 || dicBufSize != p->dicBufSize) -- { -- LzmaDec_FreeDict(p, alloc); -- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -- if (p->dic == 0) -- { -- LzmaDec_FreeProbs(p, alloc); -- return SZ_ERROR_MEM; -- } -- } -- p->dicBufSize = dicBufSize; -- p->prop = propNew; -- return SZ_OK; --} - - SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ---- a/include/linux/lzma/LzmaEnc.h -+++ b/include/linux/lzma/LzmaEnc.h -@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps - } CLzmaEncProps; - - void LzmaEncProps_Init(CLzmaEncProps *p); --void LzmaEncProps_Normalize(CLzmaEncProps *p); --UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -- - - /* ---------- CLzmaEncHandle Interface ---------- */ - -@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * - void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); - SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); - SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); --SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - --/* ---------- One Call Interface ---------- */ -- --/* LzmaEncode --Return code: -- SZ_OK - OK -- SZ_ERROR_MEM - Memory allocation error -- SZ_ERROR_PARAM - Incorrect paramater -- SZ_ERROR_OUTPUT_EOF - output buffer overflow -- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) --*/ -- --SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -- - #ifdef __cplusplus - } - #endif ---- a/lib/lzma/LzmaEnc.c -+++ b/lib/lzma/LzmaEnc.c -@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) - p->writeEndMark = 0; - } - --void LzmaEncProps_Normalize(CLzmaEncProps *p) -+static void LzmaEncProps_Normalize(CLzmaEncProps *p) - { - int level = p->level; - if (level < 0) level = 5; -@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp - #endif - } - --UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) - { - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); -@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL - - #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } - --UInt32 GetPosSlot1(UInt32 pos) -+static UInt32 GetPosSlot1(UInt32 pos) - { - UInt32 res; - BSR2_RET(pos, res); -@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos) - #define kNumLogBits (9 + (int)sizeof(size_t) / 2) - #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) - --void LzmaEnc_FastPosInit(Byte *g_FastPos) -+static void LzmaEnc_FastPosInit(Byte *g_FastPos) - { - int c = 2, slotFast; - g_FastPos[0] = 0; -@@ -339,58 +339,6 @@ typedef struct - CSaveState saveState; - } CLzmaEnc; - --void LzmaEnc_SaveState(CLzmaEncHandle pp) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- CSaveState *dest = &p->saveState; -- int i; -- dest->lenEnc = p->lenEnc; -- dest->repLenEnc = p->repLenEnc; -- dest->state = p->state; -- -- for (i = 0; i < kNumStates; i++) -- { -- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -- } -- for (i = 0; i < kNumLenToPosStates; i++) -- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -- memcpy(dest->reps, p->reps, sizeof(p->reps)); -- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); --} -- --void LzmaEnc_RestoreState(CLzmaEncHandle pp) --{ -- CLzmaEnc *dest = (CLzmaEnc *)pp; -- const CSaveState *p = &dest->saveState; -- int i; -- dest->lenEnc = p->lenEnc; -- dest->repLenEnc = p->repLenEnc; -- dest->state = p->state; -- -- for (i = 0; i < kNumStates; i++) -- { -- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -- } -- for (i = 0; i < kNumLenToPosStates; i++) -- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -- memcpy(dest->reps, p->reps, sizeof(p->reps)); -- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); --} -- - SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -600,7 +548,7 @@ static void LitEnc_EncodeMatched(CRangeE - while (symbol < 0x10000); - } - --void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) - { - UInt32 i; - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -@@ -1676,7 +1624,7 @@ static void FillDistancesPrices(CLzmaEnc - p->matchPriceCount = 0; - } - --void LzmaEnc_Construct(CLzmaEnc *p) -+static void LzmaEnc_Construct(CLzmaEnc *p) - { - RangeEnc_Construct(&p->rc); - MatchFinder_Construct(&p->matchFinderBase); -@@ -1709,7 +1657,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * - return p; - } - --void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) - { - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); -@@ -1717,7 +1665,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAl - p->saveState.litProbs = 0; - } - --void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) - { - #ifndef _7ZIP_ST - MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -@@ -1947,7 +1895,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, U - return SZ_OK; - } - --void LzmaEnc_Init(CLzmaEnc *p) -+static void LzmaEnc_Init(CLzmaEnc *p) - { - UInt32 i; - p->state = 0; -@@ -2005,7 +1953,7 @@ void LzmaEnc_Init(CLzmaEnc *p) - p->lpMask = (1 << p->lp) - 1; - } - --void LzmaEnc_InitPrices(CLzmaEnc *p) -+static void LzmaEnc_InitPrices(CLzmaEnc *p) - { - if (!p->fastMode) - { -@@ -2037,26 +1985,6 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEn - return SZ_OK; - } - --static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- p->matchFinderBase.stream = inStream; -- p->needInit = 1; -- p->rc.outStream = outStream; -- return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); --} -- --SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -- ISeqInStream *inStream, UInt32 keepWindowSize, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- p->matchFinderBase.stream = inStream; -- p->needInit = 1; -- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); --} -- - static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) - { - p->matchFinderBase.directInput = 1; -@@ -2064,7 +1992,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc - p->matchFinderBase.directInputRem = srcLen; - } - --SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2074,7 +2002,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); - } - --void LzmaEnc_Finish(CLzmaEncHandle pp) -+static void LzmaEnc_Finish(CLzmaEncHandle pp) - { - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2107,53 +2035,6 @@ static size_t MyWrite(void *pp, const vo - return size; - } - -- --UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) --{ -- const CLzmaEnc *p = (CLzmaEnc *)pp; -- return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); --} -- --const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) --{ -- const CLzmaEnc *p = (CLzmaEnc *)pp; -- return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; --} -- --SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- UInt64 nowPos64; -- SRes res; -- CSeqOutStreamBuf outStream; -- -- outStream.funcTable.Write = MyWrite; -- outStream.data = dest; -- outStream.rem = *destLen; -- outStream.overflow = False; -- -- p->writeEndMark = False; -- p->finished = False; -- p->result = SZ_OK; -- -- if (reInit) -- LzmaEnc_Init(p); -- LzmaEnc_InitPrices(p); -- nowPos64 = p->nowPos64; -- RangeEnc_Init(&p->rc); -- p->rc.outStream = &outStream.funcTable; -- -- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -- -- *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -- *destLen -= outStream.rem; -- if (outStream.overflow) -- return SZ_ERROR_OUTPUT_EOF; -- -- return res; --} -- - static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) - { - SRes res = SZ_OK; -@@ -2184,13 +2065,6 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, - return res; - } - --SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -- return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); --} -- - SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2247,25 +2121,3 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp - return SZ_ERROR_OUTPUT_EOF; - return res; - } -- --SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -- SRes res; -- if (p == 0) -- return SZ_ERROR_MEM; -- -- res = LzmaEnc_SetProps(p, props); -- if (res == SZ_OK) -- { -- res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -- if (res == SZ_OK) -- res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -- writeEndMark, progress, alloc, allocBig); -- } -- -- LzmaEnc_Destroy(p, alloc, allocBig); -- return res; --} ---- a/include/linux/lzma/LzFind.h -+++ b/include/linux/lzma/LzFind.h -@@ -55,11 +55,6 @@ typedef struct _CMatchFinder - - #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) - --int MatchFinder_NeedMove(CMatchFinder *p); --Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); --void MatchFinder_MoveBlock(CMatchFinder *p); --void MatchFinder_ReadIfRequired(CMatchFinder *p); -- - void MatchFinder_Construct(CMatchFinder *p); - - /* Conditions: -@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); - void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); --void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); --void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -- --UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -- UInt32 *distances, UInt32 maxLen); - - /* - Conditions: -@@ -102,12 +91,6 @@ typedef struct _IMatchFinder - - void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); - --void MatchFinder_Init(CMatchFinder *p); --UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); --UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); --void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); --void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -- - #ifdef __cplusplus - } - #endif ---- a/lib/lzma/LzFind.c -+++ b/lib/lzma/LzFind.c -@@ -14,9 +14,15 @@ - - #define kStartMaxLen 3 - -+#if 0 -+#define DIRECT_INPUT p->directInput -+#else -+#define DIRECT_INPUT 1 -+#endif -+ - static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) - { -- if (!p->directInput) -+ if (!DIRECT_INPUT) - { - alloc->Free(alloc, p->bufferBase); - p->bufferBase = 0; -@@ -28,7 +34,7 @@ static void LzInWindow_Free(CMatchFinder - static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) - { - UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -- if (p->directInput) -+ if (DIRECT_INPUT) - { - p->blockSize = blockSize; - return 1; -@@ -42,12 +48,12 @@ static int LzInWindow_Create(CMatchFinde - return (p->bufferBase != 0); - } - --Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } --Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } - --UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } - --void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) - { - p->posLimit -= subValue; - p->pos -= subValue; -@@ -58,7 +64,7 @@ static void MatchFinder_ReadBlock(CMatch - { - if (p->streamEndWasReached || p->result != SZ_OK) - return; -- if (p->directInput) -+ if (DIRECT_INPUT) - { - UInt32 curSize = 0xFFFFFFFF - p->streamPos; - if (curSize > p->directInputRem) -@@ -89,7 +95,7 @@ static void MatchFinder_ReadBlock(CMatch - } - } - --void MatchFinder_MoveBlock(CMatchFinder *p) -+static void MatchFinder_MoveBlock(CMatchFinder *p) - { - memmove(p->bufferBase, - p->buffer - p->keepSizeBefore, -@@ -97,22 +103,14 @@ void MatchFinder_MoveBlock(CMatchFinder - p->buffer = p->bufferBase + p->keepSizeBefore; - } - --int MatchFinder_NeedMove(CMatchFinder *p) -+static int MatchFinder_NeedMove(CMatchFinder *p) - { -- if (p->directInput) -+ if (DIRECT_INPUT) - return 0; - /* if (p->streamEndWasReached) return 0; */ - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); - } - --void MatchFinder_ReadIfRequired(CMatchFinder *p) --{ -- if (p->streamEndWasReached) -- return; -- if (p->keepSizeAfter >= p->streamPos - p->pos) -- MatchFinder_ReadBlock(p); --} -- - static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) - { - if (MatchFinder_NeedMove(p)) -@@ -268,7 +266,7 @@ static void MatchFinder_SetLimits(CMatch - p->posLimit = p->pos + limit; - } - --void MatchFinder_Init(CMatchFinder *p) -+static void MatchFinder_Init(CMatchFinder *p) - { - UInt32 i; - for (i = 0; i < p->hashSizeSum; i++) -@@ -287,7 +285,7 @@ static UInt32 MatchFinder_GetSubValue(CM - return (p->pos - p->historySize - 1) & kNormalizeMask; - } - --void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) - { - UInt32 i; - for (i = 0; i < numItems; i++) -@@ -319,38 +317,7 @@ static void MatchFinder_CheckLimits(CMat - MatchFinder_SetLimits(p); - } - --static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -- UInt32 *distances, UInt32 maxLen) --{ -- son[_cyclicBufferPos] = curMatch; -- for (;;) -- { -- UInt32 delta = pos - curMatch; -- if (cutValue-- == 0 || delta >= _cyclicBufferSize) -- return distances; -- { -- const Byte *pb = cur - delta; -- curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -- if (pb[maxLen] == cur[maxLen] && *pb == *cur) -- { -- UInt32 len = 0; -- while (++len != lenLimit) -- if (pb[len] != cur[len]) -- break; -- if (maxLen < len) -- { -- *distances++ = maxLen = len; -- *distances++ = delta - 1; -- if (len == lenLimit) -- return distances; -- } -- } -- } -- } --} -- --UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) - { -@@ -460,10 +427,10 @@ static void SkipMatchesSpec(UInt32 lenLi - p->buffer++; \ - if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); - --#define MOVE_POS_RET MOVE_POS return offset; -- - static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } - -+#define MOVE_POS_RET MatchFinder_MovePos(p); return offset; -+ - #define GET_MATCHES_HEADER2(minLen, ret_op) \ - UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ - lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -@@ -479,62 +446,7 @@ static void MatchFinder_MovePos(CMatchFi - distances + offset, maxLen) - distances); MOVE_POS_RET; - - #define SKIP_FOOTER \ -- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -- --static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(2) -- HASH2_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = 0; -- GET_MATCHES_FOOTER(offset, 1) --} -- --UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = 0; -- GET_MATCHES_FOOTER(offset, 2) --} -- --static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 hash2Value, delta2, maxLen, offset; -- GET_MATCHES_HEADER(3) -- -- HASH3_CALC; -- -- delta2 = p->pos - p->hash[hash2Value]; -- curMatch = p->hash[kFix3HashSize + hashValue]; -- -- p->hash[hash2Value] = -- p->hash[kFix3HashSize + hashValue] = p->pos; -- -- -- maxLen = 2; -- offset = 0; -- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -- { -- for (; maxLen != lenLimit; maxLen++) -- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -- break; -- distances[0] = maxLen; -- distances[1] = delta2 - 1; -- offset = 2; -- if (maxLen == lenLimit) -- { -- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -- MOVE_POS_RET; -- } -- } -- GET_MATCHES_FOOTER(offset, maxLen) --} -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p); - - static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) - { -@@ -583,108 +495,6 @@ static UInt32 Bt4_MatchFinder_GetMatches - GET_MATCHES_FOOTER(offset, maxLen) - } - --static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -- GET_MATCHES_HEADER(4) -- -- HASH4_CALC; -- -- delta2 = p->pos - p->hash[ hash2Value]; -- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -- curMatch = p->hash[kFix4HashSize + hashValue]; -- -- p->hash[ hash2Value] = -- p->hash[kFix3HashSize + hash3Value] = -- p->hash[kFix4HashSize + hashValue] = p->pos; -- -- maxLen = 1; -- offset = 0; -- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -- { -- distances[0] = maxLen = 2; -- distances[1] = delta2 - 1; -- offset = 2; -- } -- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -- { -- maxLen = 3; -- distances[offset + 1] = delta3 - 1; -- offset += 2; -- delta2 = delta3; -- } -- if (offset != 0) -- { -- for (; maxLen != lenLimit; maxLen++) -- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -- break; -- distances[offset - 2] = maxLen; -- if (maxLen == lenLimit) -- { -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS_RET; -- } -- } -- if (maxLen < 3) -- maxLen = 3; -- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -- distances + offset, maxLen) - (distances)); -- MOVE_POS_RET --} -- --UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -- distances, 2) - (distances)); -- MOVE_POS_RET --} -- --static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(2) -- HASH2_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- --void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- --static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- UInt32 hash2Value; -- SKIP_HEADER(3) -- HASH3_CALC; -- curMatch = p->hash[kFix3HashSize + hashValue]; -- p->hash[hash2Value] = -- p->hash[kFix3HashSize + hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- - static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) - { - do -@@ -701,61 +511,12 @@ static void Bt4_MatchFinder_Skip(CMatchF - while (--num != 0); - } - --static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- UInt32 hash2Value, hash3Value; -- SKIP_HEADER(4) -- HASH4_CALC; -- curMatch = p->hash[kFix4HashSize + hashValue]; -- p->hash[ hash2Value] = -- p->hash[kFix3HashSize + hash3Value] = -- p->hash[kFix4HashSize + hashValue] = p->pos; -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS -- } -- while (--num != 0); --} -- --void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS -- } -- while (--num != 0); --} -- - void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) - { - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -- if (!p->btMode) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -- } -- else if (p->numHashBytes == 2) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -- } -- else if (p->numHashBytes == 3) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -- } -- else -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -- } -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; - } diff --git a/target/linux/generic/pending-3.18/532-jffs2_eofdetect.patch b/target/linux/generic/pending-3.18/532-jffs2_eofdetect.patch deleted file mode 100644 index 8ce53d8bed..0000000000 --- a/target/linux/generic/pending-3.18/532-jffs2_eofdetect.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/fs/jffs2/build.c -+++ b/fs/jffs2/build.c -@@ -116,6 +116,16 @@ static int jffs2_build_filesystem(struct - dbg_fsbuild("scanned flash completely\n"); - jffs2_dbg_dump_block_lists_nolock(c); - -+ if (c->flags & (1 << 7)) { -+ printk("%s(): unlocking the mtd device... ", __func__); -+ mtd_unlock(c->mtd, 0, c->mtd->size); -+ printk("done.\n"); -+ -+ printk("%s(): erasing all blocks after the end marker... ", __func__); -+ jffs2_erase_pending_blocks(c, -1); -+ printk("done.\n"); -+ } -+ - dbg_fsbuild("pass 1 starting\n"); - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ ---- a/fs/jffs2/scan.c -+++ b/fs/jffs2/scan.c -@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in - /* reset summary info for next eraseblock scan */ - jffs2_sum_reset_collected(s); - -- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -- buf_size, s); -+ if (c->flags & (1 << 7)) { -+ if (mtd_block_isbad(c->mtd, jeb->offset)) -+ ret = BLK_STATE_BADBLOCK; -+ else -+ ret = BLK_STATE_ALLFF; -+ } else -+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+ buf_size, s); - - if (ret < 0) - goto out; -@@ -561,6 +567,17 @@ full_scan: - return err; - } - -+ if ((buf[0] == 0xde) && -+ (buf[1] == 0xad) && -+ (buf[2] == 0xc0) && -+ (buf[3] == 0xde)) { -+ /* end of filesystem. erase everything after this point */ -+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -+ c->flags |= (1 << 7); -+ -+ return BLK_STATE_ALLFF; -+ } -+ - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - max_ofs = EMPTY_SCAN_SIZE(c->sector_size); diff --git a/target/linux/generic/pending-3.18/550-ubifs-symlink-xattr-support.patch b/target/linux/generic/pending-3.18/550-ubifs-symlink-xattr-support.patch deleted file mode 100644 index 6e08ca302e..0000000000 --- a/target/linux/generic/pending-3.18/550-ubifs-symlink-xattr-support.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- a/fs/ubifs/file.c -+++ b/fs/ubifs/file.c -@@ -1597,6 +1597,10 @@ const struct inode_operations ubifs_syml - .follow_link = ubifs_follow_link, - .setattr = ubifs_setattr, - .getattr = ubifs_getattr, -+ .setxattr = ubifs_setxattr, -+ .getxattr = ubifs_getxattr, -+ .listxattr = ubifs_listxattr, -+ .removexattr = ubifs_removexattr, - }; - - const struct file_operations ubifs_file_operations = { ---- a/fs/ubifs/journal.c -+++ b/fs/ubifs/journal.c -@@ -572,6 +572,13 @@ int ubifs_jnl_update(struct ubifs_info * - aligned_dlen = ALIGN(dlen, 8); - aligned_ilen = ALIGN(ilen, 8); - len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; -+ if (xent) { -+ /* -+ * Make sure to account for host_ui->data_len in -+ * length calculation in case there is extended attribute. -+ */ -+ len += host_ui->data_len; -+ } - dent = kmalloc(len, GFP_NOFS); - if (!dent) - return -ENOMEM; -@@ -648,7 +655,8 @@ int ubifs_jnl_update(struct ubifs_info * - - ino_key_init(c, &ino_key, dir->i_ino); - ino_offs += aligned_ilen; -- err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ); -+ err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, -+ UBIFS_INO_NODE_SZ + host_ui->data_len); - if (err) - goto out_ro; - ---- a/fs/ubifs/xattr.c -+++ b/fs/ubifs/xattr.c -@@ -210,12 +210,12 @@ static int change_xattr(struct ubifs_inf - goto out_free; - } - inode->i_size = ui->ui_size = size; -- ui->data_len = size; - - mutex_lock(&host_ui->ui_mutex); - host->i_ctime = ubifs_current_time(host); - host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); - host_ui->xattr_size += CALC_XATTR_BYTES(size); -+ ui->data_len = size; - - /* - * It is important to write the host inode after the xattr inode diff --git a/target/linux/generic/pending-3.18/551-ubifs-fix-default-compression-selection.patch b/target/linux/generic/pending-3.18/551-ubifs-fix-default-compression-selection.patch deleted file mode 100644 index 1b0f30718c..0000000000 --- a/target/linux/generic/pending-3.18/551-ubifs-fix-default-compression-selection.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/fs/ubifs/sb.c -+++ b/fs/ubifs/sb.c -@@ -63,6 +63,17 @@ - /* Default time granularity in nanoseconds */ - #define DEFAULT_TIME_GRAN 1000000000 - -+static int get_default_compressor(void) -+{ -+ if (ubifs_compr_present(UBIFS_COMPR_LZO)) -+ return UBIFS_COMPR_LZO; -+ -+ if (ubifs_compr_present(UBIFS_COMPR_ZLIB)) -+ return UBIFS_COMPR_ZLIB; -+ -+ return UBIFS_COMPR_NONE; -+} -+ - /** - * create_default_filesystem - format empty UBI volume. - * @c: UBIFS file-system description object -@@ -183,7 +194,7 @@ static int create_default_filesystem(str - if (c->mount_opts.override_compr) - sup->default_compr = cpu_to_le16(c->mount_opts.compr_type); - else -- sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO); -+ sup->default_compr = cpu_to_le16(get_default_compressor()); - - generate_random_uuid(sup->uuid); - diff --git a/target/linux/generic/pending-3.18/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-3.18/600-netfilter_conntrack_flush.patch deleted file mode 100644 index bc6ed3e5d7..0000000000 --- a/target/linux/generic/pending-3.18/600-netfilter_conntrack_flush.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -17,6 +17,7 @@ - #include <linux/percpu.h> - #include <linux/netdevice.h> - #include <linux/security.h> -+#include <linux/inet.h> - #include <net/net_namespace.h> - #ifdef CONFIG_SYSCTL - #include <linux/sysctl.h> -@@ -262,10 +263,66 @@ static int ct_open(struct inode *inode, - sizeof(struct ct_iter_state)); - } - -+struct kill_request { -+ u16 family; -+ union nf_inet_addr addr; -+}; -+ -+static int kill_matching(struct nf_conn *i, void *data) -+{ -+ struct kill_request *kr = data; -+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; -+ -+ if (!kr->family) -+ return 1; -+ -+ if (t1->src.l3num != kr->family) -+ return 0; -+ -+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); -+} -+ -+static ssize_t ct_file_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct seq_file *seq = file->private_data; -+ struct net *net = seq_file_net(seq); -+ struct kill_request kr = { }; -+ char req[INET6_ADDRSTRLEN] = { }; -+ -+ if (count == 0) -+ return 0; -+ -+ if (count >= INET6_ADDRSTRLEN) -+ count = INET6_ADDRSTRLEN - 1; -+ -+ if (copy_from_user(req, buf, count)) -+ return -EFAULT; -+ -+ if (strnchr(req, count, ':')) { -+ kr.family = AF_INET6; -+ if (!in6_pton(req, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } else if (strnchr(req, count, '.')) { -+ kr.family = AF_INET; -+ if (!in4_pton(req, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } -+ -+ nf_ct_iterate_cleanup(net, kill_matching, &kr, 0, 0); -+ -+ return count; -+} -+ - static const struct file_operations ct_file_ops = { - .owner = THIS_MODULE, - .open = ct_open, - .read = seq_read, -+ .write = ct_file_write, - .llseek = seq_lseek, - .release = seq_release_net, - }; -@@ -367,7 +424,7 @@ static int nf_conntrack_standalone_init_ - { - struct proc_dir_entry *pde; - -- pde = proc_create("nf_conntrack", 0440, net->proc_net, &ct_file_ops); -+ pde = proc_create("nf_conntrack", 0660, net->proc_net, &ct_file_ops); - if (!pde) - goto out_nf_conntrack; - diff --git a/target/linux/generic/pending-3.18/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-3.18/610-netfilter_match_bypass_default_checks.patch deleted file mode 100644 index b96402fd3e..0000000000 --- a/target/linux/generic/pending-3.18/610-netfilter_match_bypass_default_checks.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -@@ -87,6 +87,7 @@ struct ipt_ip { - #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ - #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ - #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ -+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ - - /* Values for "inv" field in struct ipt_ip. */ - #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -82,6 +82,9 @@ ip_packet_match(const struct iphdr *ip, - - #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) - -+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -+ return true; -+ - if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, - IPT_INV_SRCIP) || - FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, -@@ -135,6 +138,29 @@ ip_packet_match(const struct iphdr *ip, - return true; - } - -+static void -+ip_checkdefault(struct ipt_ip *ip) -+{ -+ static const char iface_mask[IFNAMSIZ] = {}; -+ -+ if (ip->invflags || ip->flags & IPT_F_FRAG) -+ return; -+ -+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (ip->smsk.s_addr || ip->dmsk.s_addr) -+ return; -+ -+ if (ip->proto) -+ return; -+ -+ ip->flags |= IPT_F_NO_DEF_MATCH; -+} -+ - static bool - ip_checkentry(const struct ipt_ip *ip) - { -@@ -650,6 +676,8 @@ find_check_entry(struct ipt_entry *e, st - struct xt_mtchk_param mtpar; - struct xt_entry_match *ematch; - -+ ip_checkdefault(&e->ip); -+ - j = 0; - memset(&mtpar, 0, sizeof(mtpar)); - mtpar.net = net; -@@ -943,6 +971,7 @@ copy_entries_to_user(unsigned int total_ - const struct xt_table_info *private = table->private; - int ret = 0; - const void *loc_cpu_entry; -+ u8 flags; - - counters = alloc_counters(table); - if (IS_ERR(counters)) -@@ -974,6 +1003,14 @@ copy_entries_to_user(unsigned int total_ - goto free_counters; - } - -+ flags = e->ip.flags & IPT_F_MASK; -+ if (copy_to_user(userptr + off -+ + offsetof(struct ipt_entry, ip.flags), -+ &flags, sizeof(flags)) != 0) { -+ ret = -EFAULT; -+ goto free_counters; -+ } -+ - for (i = sizeof(struct ipt_entry); - i < e->target_offset; - i += m->u.match_size) { -@@ -1380,12 +1417,15 @@ compat_copy_entry_to_user(struct ipt_ent - compat_uint_t origsize; - const struct xt_entry_match *ematch; - int ret = 0; -+ u8 flags = e->ip.flags & IPT_F_MASK; - - origsize = *size; - ce = (struct compat_ipt_entry __user *)*dstptr; - if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || - copy_to_user(&ce->counters, &counters[i], -- sizeof(counters[i])) != 0) -+ sizeof(counters[i])) != 0 || -+ copy_to_user(&ce->ip.flags, &flags, -+ sizeof(flags)) != 0) - return -EFAULT; - - *dstptr += sizeof(struct compat_ipt_entry); diff --git a/target/linux/generic/pending-3.18/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-3.18/611-netfilter_match_bypass_default_table.patch deleted file mode 100644 index ef993c864b..0000000000 --- a/target/linux/generic/pending-3.18/611-netfilter_match_bypass_default_table.patch +++ /dev/null @@ -1,94 +0,0 @@ ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -310,6 +310,33 @@ struct ipt_entry *ipt_next_entry(const s - return (void *)entry + entry->next_offset; - } - -+static bool -+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) -+{ -+ struct xt_entry_target *t; -+ struct xt_standard_target *st; -+ -+ if (e->target_offset != sizeof(struct ipt_entry)) -+ return false; -+ -+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) -+ return false; -+ -+ t = ipt_get_target(e); -+ if (t->u.kernel.target->target) -+ return false; -+ -+ st = (struct xt_standard_target *) t; -+ if (st->verdict == XT_RETURN) -+ return false; -+ -+ if (st->verdict >= 0) -+ return false; -+ -+ *verdict = (unsigned)(-st->verdict) - 1; -+ return true; -+} -+ - /* Returns one of the generic firewall policies, like NF_ACCEPT. */ - unsigned int - ipt_do_table(struct sk_buff *skb, -@@ -331,9 +358,33 @@ ipt_do_table(struct sk_buff *skb, - unsigned int addend; - - /* Initialization */ -+ IP_NF_ASSERT(table->valid_hooks & (1 << hook)); -+ local_bh_disable(); -+ private = table->private; -+ cpu = smp_processor_id(); -+ /* -+ * Ensure we load private-> members after we've fetched the base -+ * pointer. -+ */ -+ smp_read_barrier_depends(); -+ table_base = private->entries[cpu]; -+ -+ e = get_entry(table_base, private->hook_entry[hook]); -+ if (ipt_handle_default_rule(e, &verdict)) { -+ ADD_COUNTER(e->counters, skb->len, 1); -+ local_bh_enable(); -+ return verdict; -+ } -+ - ip = ip_hdr(skb); - indev = in ? in->name : nulldevname; - outdev = out ? out->name : nulldevname; -+ -+ addend = xt_write_recseq_begin(); -+ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; -+ stackptr = per_cpu_ptr(private->stackptr, cpu); -+ origptr = *stackptr; -+ - /* We handle fragments by dealing with the first fragment as - * if it was a normal packet. All other fragments are treated - * normally, except that they will NEVER match rules that ask -@@ -348,23 +399,6 @@ ipt_do_table(struct sk_buff *skb, - acpar.family = NFPROTO_IPV4; - acpar.hooknum = hook; - -- IP_NF_ASSERT(table->valid_hooks & (1 << hook)); -- local_bh_disable(); -- addend = xt_write_recseq_begin(); -- private = table->private; -- cpu = smp_processor_id(); -- /* -- * Ensure we load private-> members after we've fetched the base -- * pointer. -- */ -- smp_read_barrier_depends(); -- table_base = private->entries[cpu]; -- jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; -- stackptr = per_cpu_ptr(private->stackptr, cpu); -- origptr = *stackptr; -- -- e = get_entry(table_base, private->hook_entry[hook]); -- - pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n", - table->name, hook, origptr, - get_entry(table_base, private->underflow[hook])); diff --git a/target/linux/generic/pending-3.18/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-3.18/612-netfilter_match_reduce_memory_access.patch deleted file mode 100644 index 72172d8bb4..0000000000 --- a/target/linux/generic/pending-3.18/612-netfilter_match_reduce_memory_access.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -85,9 +85,11 @@ ip_packet_match(const struct iphdr *ip, - if (ipinfo->flags & IPT_F_NO_DEF_MATCH) - return true; - -- if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, -+ if (FWINV(ipinfo->smsk.s_addr && -+ (ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, - IPT_INV_SRCIP) || -- FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, -+ FWINV(ipinfo->dmsk.s_addr && -+ (ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, - IPT_INV_DSTIP)) { - dprintf("Source or dest mismatch.\n"); - diff --git a/target/linux/generic/pending-3.18/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-3.18/613-netfilter_optional_tcp_window_check.patch deleted file mode 100644 index 1d3b37cc10..0000000000 --- a/target/linux/generic/pending-3.18/613-netfilter_optional_tcp_window_check.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -33,6 +33,9 @@ - #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> - #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> - -+/* Do not check the TCP window for incoming packets */ -+static int nf_ct_tcp_no_window_check __read_mostly = 1; -+ - /* "Be conservative in what you do, - be liberal in what you accept from others." - If it's non-zero, we mark only out of window RST segments as INVALID. */ -@@ -515,6 +518,9 @@ static bool tcp_in_window(const struct n - s32 receiver_offset; - bool res, in_recv_win; - -+ if (nf_ct_tcp_no_window_check) -+ return true; -+ - /* - * Get the required data from the packet. - */ -@@ -1452,6 +1458,13 @@ static struct ctl_table tcp_sysctl_table - .mode = 0644, - .proc_handler = proc_dointvec, - }, -+ { -+ .procname = "nf_conntrack_tcp_no_window_check", -+ .data = &nf_ct_tcp_no_window_check, -+ .maxlen = sizeof(unsigned int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec, -+ }, - { } - }; - diff --git a/target/linux/generic/pending-3.18/616-net_optimize_xfrm_calls.patch b/target/linux/generic/pending-3.18/616-net_optimize_xfrm_calls.patch deleted file mode 100644 index 2a64d5420a..0000000000 --- a/target/linux/generic/pending-3.18/616-net_optimize_xfrm_calls.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/net/netfilter/nf_nat_core.c -+++ b/net/netfilter/nf_nat_core.c -@@ -90,6 +90,9 @@ int nf_xfrm_me_harder(struct sk_buff *sk - struct dst_entry *dst; - int err; - -+ if (skb->dev && !dev_net(skb->dev)->xfrm.policy_count[XFRM_POLICY_OUT]) -+ return 0; -+ - err = xfrm_decode_session(skb, &fl, family); - if (err < 0) - return err; diff --git a/target/linux/generic/pending-3.18/621-sched_act_connmark.patch b/target/linux/generic/pending-3.18/621-sched_act_connmark.patch deleted file mode 100644 index 72d8e53433..0000000000 --- a/target/linux/generic/pending-3.18/621-sched_act_connmark.patch +++ /dev/null @@ -1,161 +0,0 @@ ---- /dev/null -+++ b/net/sched/act_connmark.c -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (c) 2011 Felix Fietkau <nbd@nbd.name> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple -+ * Place - Suite 330, Boston, MA 02111-1307 USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/skbuff.h> -+#include <linux/rtnetlink.h> -+#include <linux/pkt_cls.h> -+#include <linux/ip.h> -+#include <linux/ipv6.h> -+#include <net/netlink.h> -+#include <net/pkt_sched.h> -+#include <net/act_api.h> -+ -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_core.h> -+ -+#define TCA_ACT_CONNMARK 20 -+ -+#define CONNMARK_TAB_MASK 3 -+ -+static int tcf_connmark(struct sk_buff *skb, const struct tc_action *a, -+ struct tcf_result *res) -+{ -+ struct nf_conn *c; -+ enum ip_conntrack_info ctinfo; -+ int proto; -+ int r; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ if (skb->len < sizeof(struct iphdr)) -+ goto out; -+ proto = PF_INET; -+ } else if (skb->protocol == htons(ETH_P_IPV6)) { -+ if (skb->len < sizeof(struct ipv6hdr)) -+ goto out; -+ proto = PF_INET6; -+ } else -+ goto out; -+ -+ r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); -+ if (r != NF_ACCEPT) -+ goto out; -+ -+ c = nf_ct_get(skb, &ctinfo); -+ if (!c) -+ goto out; -+ -+ skb->mark = c->mark; -+ nf_conntrack_put(skb->nfct); -+ skb->nfct = NULL; -+ -+out: -+ return TC_ACT_PIPE; -+} -+ -+static int tcf_connmark_init(struct net *net, struct nlattr *nla, -+ struct nlattr *est, struct tc_action *a, -+ int ovr, int bind) -+{ -+ int ret = 0; -+ -+ if (!tcf_hash_check(0, a, bind)) { -+ ret = tcf_hash_create(0, est, a, sizeof(struct tcf_common), bind); -+ if (ret) -+ return ret; -+ -+ tcf_hash_insert(a); -+ ret = ACT_P_CREATED; -+ } else { -+ if (!ovr) { -+ tcf_hash_release(a, bind); -+ return -EEXIST; -+ } -+ } -+ -+ return ret; -+} -+ -+static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, -+ int bind, int ref) -+{ -+ return skb->len; -+} -+ -+static struct tc_action_ops act_connmark_ops = { -+ .kind = "connmark", -+ .type = TCA_ACT_CONNMARK, -+ .owner = THIS_MODULE, -+ .act = tcf_connmark, -+ .dump = tcf_connmark_dump, -+ .init = tcf_connmark_init, -+}; -+ -+MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>"); -+MODULE_DESCRIPTION("Connection tracking mark restoring"); -+MODULE_LICENSE("GPL"); -+ -+static int __init connmark_init_module(void) -+{ -+ -+ return tcf_register_action(&act_connmark_ops, CONNMARK_TAB_MASK); -+} -+ -+static void __exit connmark_cleanup_module(void) -+{ -+ tcf_unregister_action(&act_connmark_ops); -+} -+ -+module_init(connmark_init_module); -+module_exit(connmark_cleanup_module); ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -686,6 +686,19 @@ config NET_ACT_CSUM - To compile this code as a module, choose M here: the - module will be called act_csum. - -+config NET_ACT_CONNMARK -+ tristate "Connection Tracking Marking" -+ depends on NET_CLS_ACT -+ depends on NF_CONNTRACK -+ depends on NF_CONNTRACK_MARK -+ ---help--- -+ Say Y here to restore the connmark from a scheduler action -+ -+ If unsure, say N. -+ -+ To compile this code as a module, choose M here: the -+ module will be called act_connmark. -+ - config NET_CLS_IND - bool "Incoming device classification" - depends on NET_CLS_U32 || NET_CLS_FW ---- a/net/sched/Makefile -+++ b/net/sched/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit - obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o - obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o - obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o -+obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o - obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o - obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o - obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o diff --git a/target/linux/generic/pending-3.18/630-packet_socket_type.patch b/target/linux/generic/pending-3.18/630-packet_socket_type.patch deleted file mode 100644 index 21f3732167..0000000000 --- a/target/linux/generic/pending-3.18/630-packet_socket_type.patch +++ /dev/null @@ -1,134 +0,0 @@ -This patch allows the user to specify desired packet types (outgoing, -broadcast, unicast, etc.) on packet sockets via setsockopt. -This can reduce the load in situations where only a limited number -of packet types are necessary - -Signed-off-by: Felix Fietkau <nbd@nbd.name> - ---- a/include/uapi/linux/if_packet.h -+++ b/include/uapi/linux/if_packet.h -@@ -31,6 +31,8 @@ struct sockaddr_ll { - #define PACKET_KERNEL 7 /* To kernel space */ - /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ - #define PACKET_FASTROUTE 6 /* Fastrouted frame */ -+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ -+ - - /* Packet socket options */ - -@@ -54,6 +56,7 @@ struct sockaddr_ll { - #define PACKET_FANOUT 18 - #define PACKET_TX_HAS_OFF 19 - #define PACKET_QDISC_BYPASS 20 -+#define PACKET_RECV_TYPE 21 - - #define PACKET_FANOUT_HASH 0 - #define PACKET_FANOUT_LB 1 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -1551,6 +1551,7 @@ static int packet_rcv_spkt(struct sk_buf - { - struct sock *sk; - struct sockaddr_pkt *spkt; -+ struct packet_sock *po; - - /* - * When we registered the protocol we saved the socket in the data -@@ -1558,6 +1559,7 @@ static int packet_rcv_spkt(struct sk_buf - */ - - sk = pt->af_packet_priv; -+ po = pkt_sk(sk); - - /* - * Yank back the headers [hope the device set this -@@ -1570,7 +1572,7 @@ static int packet_rcv_spkt(struct sk_buf - * so that this procedure is noop. - */ - -- if (skb->pkt_type == PACKET_LOOPBACK) -+ if (!(po->pkt_type & (1 << skb->pkt_type))) - goto out; - - if (!net_eq(dev_net(dev), sock_net(sk))) -@@ -1769,12 +1771,12 @@ static int packet_rcv(struct sk_buff *sk - int skb_len = skb->len; - unsigned int snaplen, res; - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -1894,12 +1896,12 @@ static int tpacket_rcv(struct sk_buff *s - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -2866,6 +2868,7 @@ static int packet_create(struct net *net - spin_lock_init(&po->bind_lock); - mutex_init(&po->pg_vec_lock); - po->prot_hook.func = packet_rcv; -+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); - - if (sock->type == SOCK_PACKET) - po->prot_hook.func = packet_rcv_spkt; -@@ -3489,6 +3492,16 @@ packet_setsockopt(struct socket *sock, i - po->xmit = val ? packet_direct_xmit : dev_queue_xmit; - return 0; - } -+ case PACKET_RECV_TYPE: -+ { -+ unsigned int val; -+ if (optlen != sizeof(val)) -+ return -EINVAL; -+ if (copy_from_user(&val, optval, sizeof(val))) -+ return -EFAULT; -+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); -+ return 0; -+ } - default: - return -ENOPROTOOPT; - } -@@ -3540,6 +3553,13 @@ static int packet_getsockopt(struct sock - case PACKET_VNET_HDR: - val = po->has_vnet_hdr; - break; -+ case PACKET_RECV_TYPE: -+ if (len > sizeof(unsigned int)) -+ len = sizeof(unsigned int); -+ val = po->pkt_type; -+ -+ data = &val; -+ break; - case PACKET_VERSION: - val = po->tp_version; - break; ---- a/net/packet/internal.h -+++ b/net/packet/internal.h -@@ -117,6 +117,7 @@ struct packet_sock { - struct net_device __rcu *cached_dev; - int (*xmit)(struct sk_buff *skb); - struct packet_type prot_hook ____cacheline_aligned_in_smp; -+ unsigned int pkt_type; - }; - - static struct packet_sock *pkt_sk(struct sock *sk) diff --git a/target/linux/generic/pending-3.18/640-bridge_no_eap_forward.patch b/target/linux/generic/pending-3.18/640-bridge_no_eap_forward.patch deleted file mode 100644 index 35802d63dc..0000000000 --- a/target/linux/generic/pending-3.18/640-bridge_no_eap_forward.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Subject: [PATCH] bridge: no EAP forward - -When bridging, do not forward EAP frames to other ports, only deliver -them locally. -Fixes WPA authentication issues with multiples APs that are connected to -each other via bridges. ---- ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -97,7 +97,11 @@ int br_handle_frame_finish(struct sk_buf - - dst = NULL; - -- if (is_broadcast_ether_addr(dest)) { -+ if (skb->protocol == htons(ETH_P_PAE)) { -+ skb2 = skb; -+ /* Do not forward 802.1x/EAP frames */ -+ skb = NULL; -+ } else if (is_broadcast_ether_addr(dest)) { - skb2 = skb; - unicast = false; - } else if (is_multicast_ether_addr(dest)) { diff --git a/target/linux/generic/pending-3.18/641-bridge_always_accept_eap.patch b/target/linux/generic/pending-3.18/641-bridge_always_accept_eap.patch deleted file mode 100644 index a822fb0dc9..0000000000 --- a/target/linux/generic/pending-3.18/641-bridge_always_accept_eap.patch +++ /dev/null @@ -1,17 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Subject: [PATCH] bridge: always accept EAP - -Allow EAP frames to pass through bridges even in learning state. Fixes -issues with WDS. ---- ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -84,7 +84,7 @@ int br_handle_frame_finish(struct sk_buf - br_multicast_rcv(br, p, skb, vid)) - goto drop; - -- if (p->state == BR_STATE_LEARNING) -+ if ((p->state == BR_STATE_LEARNING) && skb->protocol != htons(ETH_P_PAE)) - goto drop; - - BR_INPUT_SKB_CB(skb)->brdev = br->dev; diff --git a/target/linux/generic/pending-3.18/642-bridge_port_isolate.patch b/target/linux/generic/pending-3.18/642-bridge_port_isolate.patch deleted file mode 100644 index 47f8eb160b..0000000000 --- a/target/linux/generic/pending-3.18/642-bridge_port_isolate.patch +++ /dev/null @@ -1,92 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Subject: [PATCH] bridge: port isolate - -Isolating individual bridge ports ---- ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -172,6 +172,7 @@ struct net_bridge_port - #define BR_FLOOD 0x00000040 - #define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING) - #define BR_PROMISC 0x00000080 -+#define BR_ISOLATE_MODE 0x00000100 - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - struct bridge_mcast_own_query ip4_own_query; ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -170,6 +170,7 @@ BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUA - BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); - BRPORT_ATTR_FLAG(learning, BR_LEARNING); - BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); -+BRPORT_ATTR_FLAG(isolated, BR_ISOLATE_MODE); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -213,6 +214,7 @@ static const struct brport_attribute *br - &brport_attr_multicast_router, - &brport_attr_multicast_fast_leave, - #endif -+ &brport_attr_isolated, - NULL - }; - ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -120,8 +120,8 @@ int br_handle_frame_finish(struct sk_buf - - unicast = false; - br->dev->stats.multicast++; -- } else if ((dst = __br_fdb_get(br, dest, vid)) && -- dst->is_local) { -+ } else if ((p->flags & BR_ISOLATE_MODE) || -+ ((dst = __br_fdb_get(br, dest, vid)) && dst->is_local)) { - skb2 = skb; - /* Do not forward the packet since it's local. */ - skb = NULL; ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -117,7 +117,7 @@ EXPORT_SYMBOL_GPL(br_deliver); - /* called with rcu_read_lock */ - void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0) - { -- if (should_deliver(to, skb)) { -+ if (should_deliver(to, skb) && !(to->flags & BR_ISOLATE_MODE)) { - if (skb0) - deliver_clone(to, skb, __br_forward); - else -@@ -173,7 +173,7 @@ static void br_flood(struct net_bridge * - struct sk_buff *skb0, - void (*__packet_hook)(const struct net_bridge_port *p, - struct sk_buff *skb), -- bool unicast) -+ bool unicast, bool forward) - { - struct net_bridge_port *p; - struct net_bridge_port *prev; -@@ -181,6 +181,8 @@ static void br_flood(struct net_bridge * - prev = NULL; - - list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (forward && (p->flags & BR_ISOLATE_MODE)) -+ continue; - /* Do not flood unicast traffic to ports that turn it off */ - if (unicast && !(p->flags & BR_FLOOD)) - continue; -@@ -207,14 +209,14 @@ out: - /* called with rcu_read_lock */ - void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast) - { -- br_flood(br, skb, NULL, __br_deliver, unicast); -+ br_flood(br, skb, NULL, __br_deliver, unicast, false); - } - - /* called under bridge lock */ - void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, - struct sk_buff *skb2, bool unicast) - { -- br_flood(br, skb, skb2, __br_forward, unicast); -+ br_flood(br, skb, skb2, __br_forward, unicast, true); - } - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING diff --git a/target/linux/generic/pending-3.18/645-bridge_multicast_to_unicast.patch b/target/linux/generic/pending-3.18/645-bridge_multicast_to_unicast.patch deleted file mode 100644 index 642cf03d33..0000000000 --- a/target/linux/generic/pending-3.18/645-bridge_multicast_to_unicast.patch +++ /dev/null @@ -1,390 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Subject: [PATCH] bridge: multicast to unicast - -Implement optinal multicast->unicast conversion for igmp snooping ---- ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -635,7 +635,8 @@ struct net_bridge_port_group *br_multica - struct net_bridge_port *port, - struct br_ip *group, - struct net_bridge_port_group __rcu *next, -- unsigned char state) -+ unsigned char state, -+ const unsigned char *src) - { - struct net_bridge_port_group *p; - -@@ -650,12 +651,33 @@ struct net_bridge_port_group *br_multica - hlist_add_head(&p->mglist, &port->mglist); - setup_timer(&p->timer, br_multicast_port_group_expired, - (unsigned long)p); -+ if ((port->flags & BR_MULTICAST_TO_UCAST) && src) { -+ memcpy(p->eth_addr, src, ETH_ALEN); -+ p->unicast = true; -+ } - return p; - } - -+static bool br_port_group_equal(struct net_bridge_port_group *p, -+ struct net_bridge_port *port, -+ const unsigned char *src) -+{ -+ if (p->port != port) -+ return false; -+ -+ if (!p->unicast) -+ return true; -+ -+ if (!src) -+ return false; -+ -+ return ether_addr_equal(src, p->eth_addr); -+} -+ - static int br_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, -- struct br_ip *group) -+ struct br_ip *group, -+ const unsigned char *src) - { - struct net_bridge_mdb_entry *mp; - struct net_bridge_port_group *p; -@@ -682,13 +704,13 @@ static int br_multicast_add_group(struct - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { -- if (p->port == port) -+ if (br_port_group_equal(p, port, src)) - goto found; - if ((unsigned long)p->port < (unsigned long)port) - break; - } - -- p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY); -+ p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY, src); - if (unlikely(!p)) - goto err; - rcu_assign_pointer(*pp, p); -@@ -707,7 +729,7 @@ err: - static int br_ip4_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, - __be32 group, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - -@@ -718,14 +740,14 @@ static int br_ip4_multicast_add_group(st - br_group.proto = htons(ETH_P_IP); - br_group.vid = vid; - -- return br_multicast_add_group(br, port, &br_group); -+ return br_multicast_add_group(br, port, &br_group, src); - } - - #if IS_ENABLED(CONFIG_IPV6) - static int br_ip6_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, - const struct in6_addr *group, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - -@@ -736,7 +758,7 @@ static int br_ip6_multicast_add_group(st - br_group.proto = htons(ETH_P_IPV6); - br_group.vid = vid; - -- return br_multicast_add_group(br, port, &br_group); -+ return br_multicast_add_group(br, port, &br_group, src); - } - #endif - -@@ -965,6 +987,7 @@ static int br_ip4_multicast_igmp3_report - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src; - struct igmpv3_report *ih; - struct igmpv3_grec *grec; - int i; -@@ -1008,7 +1031,8 @@ static int br_ip4_multicast_igmp3_report - continue; - } - -- err = br_ip4_multicast_add_group(br, port, group, vid); -+ src = eth_hdr(skb)->h_source; -+ err = br_ip4_multicast_add_group(br, port, group, vid, src); - if (err) - break; - } -@@ -1022,6 +1046,7 @@ static int br_ip6_multicast_mld2_report( - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src; - struct icmp6hdr *icmp6h; - struct mld2_grec *grec; - int i; -@@ -1069,8 +1094,9 @@ static int br_ip6_multicast_mld2_report( - continue; - } - -+ src = eth_hdr(skb)->h_source; - err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, -- vid); -+ vid, src); - if (err) - break; - } -@@ -1406,7 +1432,8 @@ br_multicast_leave_group(struct net_brid - struct net_bridge_port *port, - struct br_ip *group, - struct bridge_mcast_other_query *other_query, -- struct bridge_mcast_own_query *own_query) -+ struct bridge_mcast_own_query *own_query, -+ const unsigned char *src) - { - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; -@@ -1456,7 +1483,7 @@ br_multicast_leave_group(struct net_brid - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { -- if (p->port != port) -+ if (!br_port_group_equal(p, port, src)) - continue; - - rcu_assign_pointer(*pp, p->next); -@@ -1490,7 +1517,7 @@ br_multicast_leave_group(struct net_brid - for (p = mlock_dereference(mp->ports, br); - p != NULL; - p = mlock_dereference(p->next, br)) { -- if (p->port != port) -+ if (!br_port_group_equal(p, port, src)) - continue; - - if (!hlist_unhashed(&p->mglist) && -@@ -1508,8 +1535,8 @@ out: - - static void br_ip4_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, -- __be32 group, -- __u16 vid) -+ __be32 group, __u16 vid, -+ const unsigned char *src) - { - struct br_ip br_group; - struct bridge_mcast_own_query *own_query; -@@ -1524,14 +1551,14 @@ static void br_ip4_multicast_leave_group - br_group.vid = vid; - - br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query, -- own_query); -+ own_query, src); - } - - #if IS_ENABLED(CONFIG_IPV6) - static void br_ip6_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, - const struct in6_addr *group, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - struct bridge_mcast_own_query *own_query; -@@ -1546,7 +1573,7 @@ static void br_ip6_multicast_leave_group - br_group.vid = vid; - - br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query, -- own_query); -+ own_query, src); - } - #endif - -@@ -1555,6 +1582,7 @@ static int br_multicast_ipv4_rcv(struct - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src; - struct sk_buff *skb2 = skb; - const struct iphdr *iph; - struct igmphdr *ih; -@@ -1628,7 +1656,8 @@ static int br_multicast_ipv4_rcv(struct - case IGMP_HOST_MEMBERSHIP_REPORT: - case IGMPV2_HOST_MEMBERSHIP_REPORT: - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -- err = br_ip4_multicast_add_group(br, port, ih->group, vid); -+ src = eth_hdr(skb)->h_source; -+ err = br_ip4_multicast_add_group(br, port, ih->group, vid, src); - break; - case IGMPV3_HOST_MEMBERSHIP_REPORT: - err = br_ip4_multicast_igmp3_report(br, port, skb2, vid); -@@ -1637,7 +1666,8 @@ static int br_multicast_ipv4_rcv(struct - err = br_ip4_multicast_query(br, port, skb2, vid); - break; - case IGMP_HOST_LEAVE_MESSAGE: -- br_ip4_multicast_leave_group(br, port, ih->group, vid); -+ src = eth_hdr(skb)->h_source; -+ br_ip4_multicast_leave_group(br, port, ih->group, vid, src); - break; - } - -@@ -1655,6 +1685,7 @@ static int br_multicast_ipv6_rcv(struct - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src; - struct sk_buff *skb2; - const struct ipv6hdr *ip6h; - u8 icmp6_type; -@@ -1764,7 +1795,9 @@ static int br_multicast_ipv6_rcv(struct - } - mld = (struct mld_msg *)skb_transport_header(skb2); - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -- err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid); -+ src = eth_hdr(skb)->h_source; -+ err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid, -+ src); - break; - } - case ICMPV6_MLD2_REPORT: -@@ -1781,7 +1814,8 @@ static int br_multicast_ipv6_rcv(struct - goto out; - } - mld = (struct mld_msg *)skb_transport_header(skb2); -- br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid); -+ src = eth_hdr(skb)->h_source; -+ br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src); - } - } - ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -112,6 +112,9 @@ struct net_bridge_port_group { - struct timer_list timer; - struct br_ip addr; - unsigned char state; -+ -+ unsigned char eth_addr[ETH_ALEN]; -+ bool unicast; - }; - - struct net_bridge_mdb_entry -@@ -173,6 +176,7 @@ struct net_bridge_port - #define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING) - #define BR_PROMISC 0x00000080 - #define BR_ISOLATE_MODE 0x00000100 -+#define BR_MULTICAST_TO_UCAST 0x00000200 - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - struct bridge_mcast_own_query ip4_own_query; -@@ -485,7 +489,8 @@ void br_multicast_free_pg(struct rcu_hea - struct net_bridge_port_group * - br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, - struct net_bridge_port_group __rcu *next, -- unsigned char state); -+ unsigned char state, -+ const unsigned char *src); - void br_mdb_init(void); - void br_mdb_uninit(void); - void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -342,7 +342,7 @@ static int br_mdb_add_group(struct net_b - break; - } - -- p = br_multicast_new_port_group(port, group, *pp, state); -+ p = br_multicast_new_port_group(port, group, *pp, state, NULL); - if (unlikely(!p)) - return -ENOMEM; - rcu_assign_pointer(*pp, p); ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -168,6 +168,34 @@ out: - return p; - } - -+static struct net_bridge_port *maybe_deliver_addr( -+ struct net_bridge_port *prev, struct net_bridge_port *p, -+ struct sk_buff *skb, const unsigned char *addr, -+ void (*__packet_hook)(const struct net_bridge_port *p, -+ struct sk_buff *skb)) -+{ -+ struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; -+ const unsigned char *src = eth_hdr(skb)->h_source; -+ -+ if (!should_deliver(p, skb)) -+ return prev; -+ -+ /* Even with hairpin, no soliloquies - prevent breaking IPv6 DAD */ -+ if (skb->dev == p->dev && ether_addr_equal(src, addr)) -+ return prev; -+ -+ skb = skb_copy(skb, GFP_ATOMIC); -+ if (!skb) { -+ dev->stats.tx_dropped++; -+ return prev; -+ } -+ -+ memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN); -+ __packet_hook(p, skb); -+ -+ return prev; -+} -+ - /* called under bridge lock */ - static void br_flood(struct net_bridge *br, struct sk_buff *skb, - struct sk_buff *skb0, -@@ -232,6 +260,7 @@ static void br_multicast_flood(struct ne - struct net_bridge_port *prev = NULL; - struct net_bridge_port_group *p; - struct hlist_node *rp; -+ const unsigned char *addr; - - rp = rcu_dereference(hlist_first_rcu(&br->router_list)); - p = mdst ? rcu_dereference(mdst->ports) : NULL; -@@ -242,10 +271,19 @@ static void br_multicast_flood(struct ne - rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) : - NULL; - -- port = (unsigned long)lport > (unsigned long)rport ? -- lport : rport; -- -- prev = maybe_deliver(prev, port, skb, __packet_hook); -+ if ((unsigned long)lport > (unsigned long)rport) { -+ port = lport; -+ addr = p->unicast ? p->eth_addr : NULL; -+ } else { -+ port = rport; -+ addr = NULL; -+ } -+ -+ if (addr) -+ prev = maybe_deliver_addr(prev, port, skb, addr, -+ __packet_hook); -+ else -+ prev = maybe_deliver(prev, port, skb, __packet_hook); - if (IS_ERR(prev)) - goto out; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -187,6 +187,7 @@ static BRPORT_ATTR(multicast_router, S_I - store_multicast_router); - - BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); -+BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UCAST); - #endif - - static const struct brport_attribute *brport_attrs[] = { -@@ -213,6 +214,7 @@ static const struct brport_attribute *br - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - &brport_attr_multicast_router, - &brport_attr_multicast_fast_leave, -+ &brport_attr_multicast_to_unicast, - #endif - &brport_attr_isolated, - NULL diff --git a/target/linux/generic/pending-3.18/650-pppoe_header_pad.patch b/target/linux/generic/pending-3.18/650-pppoe_header_pad.patch deleted file mode 100644 index e69de29bb2..0000000000 --- a/target/linux/generic/pending-3.18/650-pppoe_header_pad.patch +++ /dev/null diff --git a/target/linux/generic/pending-3.18/651-wireless_mesh_header.patch b/target/linux/generic/pending-3.18/651-wireless_mesh_header.patch deleted file mode 100644 index 16da5cd66f..0000000000 --- a/target/linux/generic/pending-3.18/651-wireless_mesh_header.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -130,7 +130,7 @@ static inline bool dev_xmit_complete(int - */ - - #if defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) --# if defined(CONFIG_MAC80211_MESH) -+# if 1 || defined(CONFIG_MAC80211_MESH) - # define LL_MAX_HEADER 128 - # else - # define LL_MAX_HEADER 96 diff --git a/target/linux/generic/pending-3.18/653-disable_netlink_trim.patch b/target/linux/generic/pending-3.18/653-disable_netlink_trim.patch deleted file mode 100644 index ebe5da4ec0..0000000000 --- a/target/linux/generic/pending-3.18/653-disable_netlink_trim.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -1154,23 +1154,7 @@ void netlink_detachskb(struct sock *sk, - - static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation) - { -- int delta; -- - WARN_ON(skb->sk != NULL); -- delta = skb->end - skb->tail; -- if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize) -- return skb; -- -- if (skb_shared(skb)) { -- struct sk_buff *nskb = skb_clone(skb, allocation); -- if (!nskb) -- return skb; -- consume_skb(skb); -- skb = nskb; -- } -- -- if (!pskb_expand_head(skb, 0, -delta, allocation)) -- skb->truesize -= delta; - - return skb; - } diff --git a/target/linux/generic/pending-3.18/655-increase_skb_pad.patch b/target/linux/generic/pending-3.18/655-increase_skb_pad.patch deleted file mode 100644 index 96f81e9aa7..0000000000 --- a/target/linux/generic/pending-3.18/655-increase_skb_pad.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2024,7 +2024,7 @@ static inline int pskb_network_may_pull( - * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) - */ - #ifndef NET_SKB_PAD --#define NET_SKB_PAD max(32, L1_CACHE_BYTES) -+#define NET_SKB_PAD max(64, L1_CACHE_BYTES) - #endif - - int ___pskb_trim(struct sk_buff *skb, unsigned int len); diff --git a/target/linux/generic/pending-3.18/656-skb_reduce_truesize-helper.patch b/target/linux/generic/pending-3.18/656-skb_reduce_truesize-helper.patch deleted file mode 100644 index 0fde9f6e62..0000000000 --- a/target/linux/generic/pending-3.18/656-skb_reduce_truesize-helper.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4593a806e31119c5bd3faa00c7210ad862d515af Mon Sep 17 00:00:00 2001 -From: Dave Taht <dave.taht@bufferbloat.net> -Date: Mon, 31 Dec 2012 10:02:21 -0800 -Subject: [PATCH 3/7] skb_reduce_truesize: helper function for shrinking skbs - whenever needed - -On embedded devices in particular, large queues of small packets from the rx -path with a large truesize can exist. Reducing their size can reduce -memory pressure. skb_reduce_truesize is a helper function for doing this, -when needed. ---- - include/linux/skbuff.h | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2069,6 +2069,24 @@ static inline void pskb_trim_unique(stru - BUG_ON(err); - } - -+/* -+ * Caller wants to reduce memory needs before queueing skb -+ * The (expensive) copy should not be be done in fast path. -+ */ -+static inline struct sk_buff *skb_reduce_truesize(struct sk_buff *skb) -+{ -+ if (skb->truesize > 2 * SKB_TRUESIZE(skb->len)) { -+ struct sk_buff *nskb; -+ nskb = skb_copy_expand(skb, skb_headroom(skb), 0, -+ GFP_ATOMIC | __GFP_NOWARN); -+ if (nskb) { -+ __kfree_skb(skb); -+ skb = nskb; -+ } -+ } -+ return skb; -+} -+ - /** - * skb_orphan - orphan a buffer - * @skb: buffer to orphan diff --git a/target/linux/generic/pending-3.18/657-qdisc_reduce_truesize.patch b/target/linux/generic/pending-3.18/657-qdisc_reduce_truesize.patch deleted file mode 100644 index 410e0b763d..0000000000 --- a/target/linux/generic/pending-3.18/657-qdisc_reduce_truesize.patch +++ /dev/null @@ -1,63 +0,0 @@ -From bc9fec2f87d57bdbff30d296605e24504513f65c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dave=20T=C3=A4ht?= <dave.taht@bufferbloat.net> -Date: Mon, 17 Sep 2012 19:20:22 -0700 -Subject: [PATCH 4/7] net: add skb_reduce_truesize support to common qdiscs - -Reduce skb size under load when queues begin to fill on the -commont qdiscs. ---- - net/sched/sch_codel.c | 2 ++ - net/sched/sch_fifo.c | 12 ++++++++---- - net/sched/sch_fq_codel.c | 2 ++ - 3 files changed, 12 insertions(+), 4 deletions(-) - ---- a/net/sched/sch_codel.c -+++ b/net/sched/sch_codel.c -@@ -97,6 +97,8 @@ static int codel_qdisc_enqueue(struct sk - struct codel_sched_data *q; - - if (likely(qdisc_qlen(sch) < sch->limit)) { -+ if(qdisc_qlen(sch) > 128) -+ skb = skb_reduce_truesize(skb); - codel_set_enqueue_time(skb); - return qdisc_enqueue_tail(skb, sch); - } ---- a/net/sched/sch_fifo.c -+++ b/net/sched/sch_fifo.c -@@ -29,17 +29,21 @@ static int bfifo_enqueue(struct sk_buff - - static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch) - { -- if (likely(skb_queue_len(&sch->q) < sch->limit)) -+ if (likely(skb_queue_len(&sch->q) < sch->limit)) { -+ if (skb_queue_len(&sch->q) > 128) -+ skb = skb_reduce_truesize(skb); - return qdisc_enqueue_tail(skb, sch); -- -+ } - return qdisc_reshape_fail(skb, sch); - } - - static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch) - { -- if (likely(skb_queue_len(&sch->q) < sch->limit)) -+ if (likely(skb_queue_len(&sch->q) < sch->limit)) { -+ if (skb_queue_len(&sch->q) > 128) -+ skb = skb_reduce_truesize(skb); - return qdisc_enqueue_tail(skb, sch); -- -+ } - /* queue full, remove one skb to fulfill the limit */ - __qdisc_queue_drop_head(sch, &sch->q); - qdisc_qstats_drop(sch); ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -185,6 +185,8 @@ static int fq_codel_enqueue(struct sk_bu - return ret; - } - idx--; -+ if (sch->q.qlen > 128) -+ skb = skb_reduce_truesize(skb); - - codel_set_enqueue_time(skb); - flow = &q->flows[idx]; diff --git a/target/linux/generic/pending-3.18/660-fq_codel_defaults.patch b/target/linux/generic/pending-3.18/660-fq_codel_defaults.patch deleted file mode 100644 index 8a870cccc1..0000000000 --- a/target/linux/generic/pending-3.18/660-fq_codel_defaults.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -394,8 +394,8 @@ static int fq_codel_init(struct Qdisc *s - struct fq_codel_sched_data *q = qdisc_priv(sch); - int i; - -- sch->limit = 10*1024; -- q->flows_cnt = 1024; -+ sch->limit = 1024; -+ q->flows_cnt = 128; - q->quantum = psched_mtu(qdisc_dev(sch)); - q->perturbation = prandom_u32(); - INIT_LIST_HEAD(&q->new_flows); diff --git a/target/linux/generic/pending-3.18/661-fq_codel_keep_dropped_stats.patch b/target/linux/generic/pending-3.18/661-fq_codel_keep_dropped_stats.patch deleted file mode 100644 index 45a8d68367..0000000000 --- a/target/linux/generic/pending-3.18/661-fq_codel_keep_dropped_stats.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -198,7 +198,6 @@ static int fq_codel_enqueue(struct sk_bu - list_add_tail(&flow->flowchain, &q->new_flows); - q->new_flow_count++; - flow->deficit = q->quantum; -- flow->dropped = 0; - } - if (++sch->q.qlen <= sch->limit) - return NET_XMIT_SUCCESS; diff --git a/target/linux/generic/pending-3.18/662-use_fq_codel_by_default.patch b/target/linux/generic/pending-3.18/662-use_fq_codel_by_default.patch deleted file mode 100644 index 39abfaabea..0000000000 --- a/target/linux/generic/pending-3.18/662-use_fq_codel_by_default.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -3,8 +3,9 @@ - # - - menuconfig NET_SCHED -- bool "QoS and/or fair queueing" -+ def_bool y - select NET_SCH_FIFO -+ select NET_SCH_FQ_CODEL - ---help--- - When the kernel has several packets to send out over a network - device, it has to decide which ones to send first, which ones to ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -599,7 +599,7 @@ static const struct Qdisc_class_ops fq_c - .walk = fq_codel_walk, - }; - --static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { -+struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { - .cl_ops = &fq_codel_class_ops, - .id = "fq_codel", - .priv_size = sizeof(struct fq_codel_sched_data), -@@ -615,6 +615,7 @@ static struct Qdisc_ops fq_codel_qdisc_o - .dump_stats = fq_codel_dump_stats, - .owner = THIS_MODULE, - }; -+EXPORT_SYMBOL(fq_codel_qdisc_ops); - - static int __init fq_codel_module_init(void) - { ---- a/include/net/sch_generic.h -+++ b/include/net/sch_generic.h -@@ -341,6 +341,7 @@ extern struct Qdisc noop_qdisc; - extern struct Qdisc_ops noop_qdisc_ops; - extern struct Qdisc_ops pfifo_fast_ops; - extern struct Qdisc_ops mq_qdisc_ops; -+extern struct Qdisc_ops fq_codel_qdisc_ops; - extern const struct Qdisc_ops *default_qdisc_ops; - - struct Qdisc_class_common { ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -31,7 +31,7 @@ - #include <net/dst.h> - - /* Qdisc to use by default */ --const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; -+const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops; - EXPORT_SYMBOL(default_qdisc_ops); - - /* Main transmission queue. */ -@@ -742,7 +742,7 @@ static void attach_one_default_qdisc(str - - if (dev->tx_queue_len) { - qdisc = qdisc_create_dflt(dev_queue, -- default_qdisc_ops, TC_H_ROOT); -+ &fq_codel_qdisc_ops, TC_H_ROOT); - if (!qdisc) { - netdev_info(dev, "activation failed\n"); - return; ---- a/net/sched/sch_mq.c -+++ b/net/sched/sch_mq.c -@@ -57,7 +57,7 @@ static int mq_init(struct Qdisc *sch, st - - for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { - dev_queue = netdev_get_tx_queue(dev, ntx); -- qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops, -+ qdisc = qdisc_create_dflt(dev_queue, &fq_codel_qdisc_ops, - TC_H_MAKE(TC_H_MAJ(sch->handle), - TC_H_MIN(ntx + 1))); - if (qdisc == NULL) ---- a/net/sched/sch_mqprio.c -+++ b/net/sched/sch_mqprio.c -@@ -124,7 +124,7 @@ static int mqprio_init(struct Qdisc *sch - - for (i = 0; i < dev->num_tx_queues; i++) { - dev_queue = netdev_get_tx_queue(dev, i); -- qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops, -+ qdisc = qdisc_create_dflt(dev_queue, &fq_codel_qdisc_ops, - TC_H_MAKE(TC_H_MAJ(sch->handle), - TC_H_MIN(i + 1))); - if (qdisc == NULL) { ---- a/net/sched/sch_api.c -+++ b/net/sched/sch_api.c -@@ -1949,7 +1949,7 @@ static int __init pktsched_init(void) - return err; - } - -- register_qdisc(&pfifo_fast_ops); -+ register_qdisc(&fq_codel_qdisc_ops); - register_qdisc(&pfifo_qdisc_ops); - register_qdisc(&bfifo_qdisc_ops); - register_qdisc(&pfifo_head_drop_qdisc_ops); diff --git a/target/linux/generic/pending-3.18/663-remove_pfifo_fast.patch b/target/linux/generic/pending-3.18/663-remove_pfifo_fast.patch deleted file mode 100644 index 50b90b375f..0000000000 --- a/target/linux/generic/pending-3.18/663-remove_pfifo_fast.patch +++ /dev/null @@ -1,143 +0,0 @@ ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -445,140 +445,6 @@ static struct Qdisc noqueue_qdisc = { - .busylock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.busylock), - }; - -- --static const u8 prio2band[TC_PRIO_MAX + 1] = { -- 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 --}; -- --/* 3-band FIFO queue: old style, but should be a bit faster than -- generic prio+fifo combination. -- */ -- --#define PFIFO_FAST_BANDS 3 -- --/* -- * Private data for a pfifo_fast scheduler containing: -- * - queues for the three band -- * - bitmap indicating which of the bands contain skbs -- */ --struct pfifo_fast_priv { -- u32 bitmap; -- struct sk_buff_head q[PFIFO_FAST_BANDS]; --}; -- --/* -- * Convert a bitmap to the first band number where an skb is queued, where: -- * bitmap=0 means there are no skbs on any band. -- * bitmap=1 means there is an skb on band 0. -- * bitmap=7 means there are skbs on all 3 bands, etc. -- */ --static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0}; -- --static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv, -- int band) --{ -- return priv->q + band; --} -- --static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc) --{ -- if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) { -- int band = prio2band[skb->priority & TC_PRIO_MAX]; -- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -- struct sk_buff_head *list = band2list(priv, band); -- -- priv->bitmap |= (1 << band); -- qdisc->q.qlen++; -- return __qdisc_enqueue_tail(skb, qdisc, list); -- } -- -- return qdisc_drop(skb, qdisc); --} -- --static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) --{ -- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -- int band = bitmap2band[priv->bitmap]; -- -- if (likely(band >= 0)) { -- struct sk_buff_head *list = band2list(priv, band); -- struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list); -- -- qdisc->q.qlen--; -- if (skb_queue_empty(list)) -- priv->bitmap &= ~(1 << band); -- -- return skb; -- } -- -- return NULL; --} -- --static struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc) --{ -- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -- int band = bitmap2band[priv->bitmap]; -- -- if (band >= 0) { -- struct sk_buff_head *list = band2list(priv, band); -- -- return skb_peek(list); -- } -- -- return NULL; --} -- --static void pfifo_fast_reset(struct Qdisc *qdisc) --{ -- int prio; -- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -- -- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) -- __qdisc_reset_queue(qdisc, band2list(priv, prio)); -- -- priv->bitmap = 0; -- qdisc->qstats.backlog = 0; -- qdisc->q.qlen = 0; --} -- --static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) --{ -- struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS }; -- -- memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1); -- if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) -- goto nla_put_failure; -- return skb->len; -- --nla_put_failure: -- return -1; --} -- --static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt) --{ -- int prio; -- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -- -- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) -- __skb_queue_head_init(band2list(priv, prio)); -- -- /* Can by-pass the queue discipline */ -- qdisc->flags |= TCQ_F_CAN_BYPASS; -- return 0; --} -- --struct Qdisc_ops pfifo_fast_ops __read_mostly = { -- .id = "pfifo_fast", -- .priv_size = sizeof(struct pfifo_fast_priv), -- .enqueue = pfifo_fast_enqueue, -- .dequeue = pfifo_fast_dequeue, -- .peek = pfifo_fast_peek, -- .init = pfifo_fast_init, -- .reset = pfifo_fast_reset, -- .dump = pfifo_fast_dump, -- .owner = THIS_MODULE, --}; -- - static struct lock_class_key qdisc_tx_busylock; - - struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, diff --git a/target/linux/generic/pending-3.18/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-3.18/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch deleted file mode 100644 index 9a2808acd5..0000000000 --- a/target/linux/generic/pending-3.18/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +++ /dev/null @@ -1,481 +0,0 @@ -From 775d6fe74d1eaec2ba387535b068dde2dc89de9e Mon Sep 17 00:00:00 2001 -From: Steven Barth <steven@midlink.org> -Date: Thu, 22 May 2014 09:49:05 +0200 -Subject: [PATCH] Add support for MAP-E FMRs (mesh mode) - -MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication -between MAP CEs (mesh mode) without the need to forward such data to a -border relay. This is similar to how 6rd works but for IPv4 over IPv6. - -Signed-off-by: Steven Barth <cyrus@openwrt.org> ---- - include/net/ip6_tunnel.h | 13 ++ - include/uapi/linux/if_tunnel.h | 13 ++ - net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 291 insertions(+), 11 deletions(-) - ---- a/include/net/ip6_tunnel.h -+++ b/include/net/ip6_tunnel.h -@@ -15,6 +15,18 @@ - /* determine capability on a per-packet basis */ - #define IP6_TNL_F_CAP_PER_PACKET 0x40000 - -+/* IPv6 tunnel FMR */ -+struct __ip6_tnl_fmr { -+ struct __ip6_tnl_fmr *next; /* next fmr in list */ -+ struct in6_addr ip6_prefix; -+ struct in_addr ip4_prefix; -+ -+ __u8 ip6_prefix_len; -+ __u8 ip4_prefix_len; -+ __u8 ea_len; -+ __u8 offset; -+}; -+ - struct __ip6_tnl_parm { - char name[IFNAMSIZ]; /* name of tunnel device */ - int link; /* ifindex of underlying L2 interface */ -@@ -25,6 +37,7 @@ struct __ip6_tnl_parm { - __u32 flags; /* tunnel flags */ - struct in6_addr laddr; /* local tunnel end-point address */ - struct in6_addr raddr; /* remote tunnel end-point address */ -+ struct __ip6_tnl_fmr *fmrs; /* FMRs */ - - __be16 i_flags; - __be16 o_flags; ---- a/include/uapi/linux/if_tunnel.h -+++ b/include/uapi/linux/if_tunnel.h -@@ -57,10 +57,23 @@ enum { - IFLA_IPTUN_ENCAP_FLAGS, - IFLA_IPTUN_ENCAP_SPORT, - IFLA_IPTUN_ENCAP_DPORT, -+ IFLA_IPTUN_FMRS, - __IFLA_IPTUN_MAX, - }; - #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) - -+enum { -+ IFLA_IPTUN_FMR_UNSPEC, -+ IFLA_IPTUN_FMR_IP6_PREFIX, -+ IFLA_IPTUN_FMR_IP4_PREFIX, -+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, -+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, -+ IFLA_IPTUN_FMR_EA_LEN, -+ IFLA_IPTUN_FMR_OFFSET, -+ __IFLA_IPTUN_FMR_MAX, -+}; -+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) -+ - enum tunnel_encap_types { - TUNNEL_ENCAP_NONE, - TUNNEL_ENCAP_FOU, ---- a/net/ipv6/ip6_tunnel.c -+++ b/net/ipv6/ip6_tunnel.c -@@ -16,6 +16,8 @@ - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * -+ * Changes: -+ * Steven Barth <cyrus@openwrt.org>: MAP-E FMR support - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -77,11 +79,9 @@ static bool log_ecn_error = true; - module_param(log_ecn_error, bool, 0644); - MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); - --static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) -+static u32 HASH(const struct in6_addr *addr) - { -- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); -- -- return hash_32(hash, HASH_SIZE_SHIFT); -+ return hash_32(ipv6_addr_hash(addr), HASH_SIZE_SHIFT); - } - - static int ip6_tnl_dev_init(struct net_device *dev); -@@ -180,15 +180,24 @@ EXPORT_SYMBOL_GPL(ip6_tnl_dst_store); - static struct ip6_tnl * - ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_addr *local) - { -- unsigned int hash = HASH(remote, local); -+ unsigned int hash = HASH(local); - struct ip6_tnl *t; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); -+ struct __ip6_tnl_fmr *fmr; - - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { -- if (ipv6_addr_equal(local, &t->parms.laddr) && -- ipv6_addr_equal(remote, &t->parms.raddr) && -- (t->dev->flags & IFF_UP)) -+ if (!ipv6_addr_equal(local, &t->parms.laddr) || -+ !(t->dev->flags & IFF_UP)) -+ continue; -+ -+ if (ipv6_addr_equal(remote, &t->parms.raddr)) - return t; -+ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ if (ipv6_prefix_equal(remote, &fmr->ip6_prefix, -+ fmr->ip6_prefix_len)) -+ return t; -+ } - } - t = rcu_dereference(ip6n->tnls_wc[0]); - if (t && (t->dev->flags & IFF_UP)) -@@ -218,7 +227,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, - - if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { - prio = 1; -- h = HASH(remote, local); -+ h = HASH(local); - } - return &ip6n->tnls[prio][h]; - } -@@ -391,6 +400,12 @@ ip6_tnl_dev_uninit(struct net_device *de - struct net *net = t->net; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ - if (dev == ip6n->fb_tnl_dev) - RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); - else -@@ -784,6 +799,108 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, - } - EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); - -+ -+/** -+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR -+ * @dest: destination IPv6 address buffer -+ * @skb: received socket buffer -+ * @fmr: MAP FMR -+ * @xmit: Calculate for xmit or rcv -+ **/ -+static void ip4ip6_fmr_calc(struct in6_addr *dest, -+ const struct iphdr *iph, const uint8_t *end, -+ const struct __ip6_tnl_fmr *fmr, bool xmit) -+{ -+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); -+ u8 *portp = NULL; -+ bool use_dest_addr; -+ const struct iphdr *dsth = iph; -+ -+ if ((u8*)dsth >= end) -+ return; -+ -+ /* find significant IP header */ -+ if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ if (ih && ((u8*)&ih[1]) <= end && ( -+ ih->type == ICMP_DEST_UNREACH || -+ ih->type == ICMP_SOURCE_QUENCH || -+ ih->type == ICMP_TIME_EXCEEDED || -+ ih->type == ICMP_PARAMETERPROB || -+ ih->type == ICMP_REDIRECT)) -+ dsth = (const struct iphdr*)&ih[1]; -+ } -+ -+ /* in xmit-path use dest port by default and source port only if -+ this is an ICMP reply to something else; vice versa in rcv-path */ -+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); -+ -+ /* get dst port */ -+ if (((u8*)&dsth[1]) <= end && ( -+ dsth->protocol == IPPROTO_UDP || -+ dsth->protocol == IPPROTO_TCP || -+ dsth->protocol == IPPROTO_SCTP || -+ dsth->protocol == IPPROTO_DCCP)) { -+ /* for UDP, TCP, SCTP and DCCP source and dest port -+ follow IPv4 header directly */ -+ portp = ((u8*)dsth) + dsth->ihl * 4; -+ -+ if (use_dest_addr) -+ portp += sizeof(u16); -+ } else if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ -+ /* use icmp identifier as port */ -+ if (((u8*)&ih) <= end && ( -+ (use_dest_addr && ( -+ ih->type == ICMP_ECHOREPLY || -+ ih->type == ICMP_TIMESTAMPREPLY || -+ ih->type == ICMP_INFO_REPLY || -+ ih->type == ICMP_ADDRESSREPLY)) || -+ (!use_dest_addr && ( -+ ih->type == ICMP_ECHO || -+ ih->type == ICMP_TIMESTAMP || -+ ih->type == ICMP_INFO_REQUEST || -+ ih->type == ICMP_ADDRESS) -+ ))) -+ portp = (u8*)&ih->un.echo.id; -+ } -+ -+ if ((portp && &portp[2] <= end) || psidlen == 0) { -+ int frombyte = fmr->ip6_prefix_len / 8; -+ int fromrem = fmr->ip6_prefix_len % 8; -+ int bytes = sizeof(struct in6_addr) - frombyte; -+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; -+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); -+ u64 t = 0; -+ -+ /* extract PSID from port and add it to eabits */ -+ u16 psidbits = 0; -+ if (psidlen > 0) { -+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); -+ psidbits >>= 16 - psidlen - fmr->offset; -+ psidbits = (u16)(psidbits << (16 - psidlen)); -+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); -+ } -+ -+ /* rewrite destination address */ -+ *dest = fmr->ip6_prefix; -+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); -+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); -+ -+ if (bytes > sizeof(u64)) -+ bytes = sizeof(u64); -+ -+ /* insert eabits */ -+ memcpy(&t, &dest->s6_addr[frombyte], bytes); -+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) -+ << (64 - fmr->ea_len - fromrem)); -+ t = cpu_to_be64(t | (eabits >> fromrem)); -+ memcpy(&dest->s6_addr[frombyte], &t, bytes); -+ } -+} -+ -+ - /** - * ip6_tnl_rcv - decapsulate IPv6 packet and retransmit it locally - * @skb: received socket buffer -@@ -828,6 +945,26 @@ static int ip6_tnl_rcv(struct sk_buff *s - skb_reset_network_header(skb); - skb->protocol = htons(protocol); - memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); -+ if (protocol == ETH_P_IP && t->parms.fmrs && -+ !ipv6_addr_equal(&ipv6h->saddr, &t->parms.raddr)) { -+ /* Packet didn't come from BR, so lookup FMR */ -+ struct __ip6_tnl_fmr *fmr; -+ struct in6_addr expected = t->parms.raddr; -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) -+ if (ipv6_prefix_equal(&ipv6h->saddr, -+ &fmr->ip6_prefix, fmr->ip6_prefix_len)) -+ break; -+ -+ /* Check that IPv6 matches IPv4 source to prevent spoofing */ -+ if (fmr) -+ ip4ip6_fmr_calc(&expected, ip_hdr(skb), -+ skb_tail_pointer(skb), fmr, false); -+ -+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { -+ rcu_read_unlock(); -+ goto discard; -+ } -+ } - - __skb_tunnel_rx(skb, t->dev, t->net); - -@@ -1089,6 +1226,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str - __u8 dsfield; - __u32 mtu; - int err; -+ struct __ip6_tnl_fmr *fmr; - - /* ensure we can access the full inner ip header */ - if (!pskb_may_pull(skb, sizeof(struct iphdr))) -@@ -1114,6 +1252,18 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str - if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) - fl6.flowi6_mark = skb->mark; - -+ /* try to find matching FMR */ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ unsigned mshift = 32 - fmr->ip4_prefix_len; -+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == -+ ntohl(iph->daddr) >> mshift) -+ break; -+ } -+ -+ /* change dstaddr according to FMR */ -+ if (fmr) -+ ip4ip6_fmr_calc(&fl6.daddr, iph, skb_tail_pointer(skb), fmr, true); -+ - err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); - if (err != 0) { - /* XXX: send ICMP error even if DF is not set. */ -@@ -1286,6 +1436,14 @@ ip6_tnl_change(struct ip6_tnl *t, const - t->parms.flowinfo = p->flowinfo; - t->parms.link = p->link; - t->parms.proto = p->proto; -+ -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ t->parms.fmrs = p->fmrs; -+ - ip6_tnl_dst_reset(t); - ip6_tnl_link_config(t); - return 0; -@@ -1316,6 +1474,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ - p->flowinfo = u->flowinfo; - p->link = u->link; - p->proto = u->proto; -+ p->fmrs = NULL; - memcpy(p->name, u->name, sizeof(u->name)); - } - -@@ -1591,6 +1750,15 @@ static int ip6_tnl_validate(struct nlatt - return 0; - } - -+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { -+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, -+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } -+}; -+ - static void ip6_tnl_netlink_parms(struct nlattr *data[], - struct __ip6_tnl_parm *parms) - { -@@ -1624,6 +1792,46 @@ static void ip6_tnl_netlink_parms(struct - - if (data[IFLA_IPTUN_PROTO]) - parms->proto = nla_get_u8(data[IFLA_IPTUN_PROTO]); -+ -+ if (data[IFLA_IPTUN_FMRS]) { -+ unsigned rem; -+ struct nlattr *fmr; -+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { -+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; -+ struct __ip6_tnl_fmr *nfmr; -+ -+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, -+ fmr, ip6_tnl_fmr_policy); -+ -+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) -+ continue; -+ -+ nfmr->offset = 6; -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) -+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], -+ sizeof(nfmr->ip6_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) -+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], -+ sizeof(nfmr->ip4_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) -+ nfmr->ip6_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) -+ nfmr->ip4_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) -+ nfmr->ea_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) -+ nfmr->offset = nla_get_u8(c); -+ -+ nfmr->next = parms->fmrs; -+ parms->fmrs = nfmr; -+ } -+ } - } - - static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, -@@ -1676,6 +1884,12 @@ static void ip6_tnl_dellink(struct net_d - - static size_t ip6_tnl_get_size(const struct net_device *dev) - { -+ const struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *c; -+ int fmrs = 0; -+ for (c = t->parms.fmrs; c; c = c->next) -+ ++fmrs; -+ - return - /* IFLA_IPTUN_LINK */ - nla_total_size(4) + -@@ -1693,6 +1907,24 @@ static size_t ip6_tnl_get_size(const str - nla_total_size(4) + - /* IFLA_IPTUN_PROTO */ - nla_total_size(1) + -+ /* IFLA_IPTUN_FMRS */ -+ nla_total_size(0) + -+ ( -+ /* nest */ -+ nla_total_size(0) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX */ -+ nla_total_size(sizeof(struct in6_addr)) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX */ -+ nla_total_size(sizeof(struct in_addr)) + -+ /* IFLA_IPTUN_FMR_EA_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_OFFSET */ -+ nla_total_size(1) -+ ) * fmrs + - 0; - } - -@@ -1700,6 +1932,9 @@ static int ip6_tnl_fill_info(struct sk_b - { - struct ip6_tnl *tunnel = netdev_priv(dev); - struct __ip6_tnl_parm *parm = &tunnel->parms; -+ struct __ip6_tnl_fmr *c; -+ int fmrcnt = 0; -+ struct nlattr *fmrs; - - if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || - nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), -@@ -1710,8 +1945,27 @@ static int ip6_tnl_fill_info(struct sk_b - nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || - nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || - nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || -- nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto)) -+ nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || -+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) - goto nla_put_failure; -+ -+ for (c = parm->fmrs; c; c = c->next) { -+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); -+ if (!fmr || -+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, -+ sizeof(c->ip6_prefix), &c->ip6_prefix) || -+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, -+ sizeof(c->ip4_prefix), &c->ip4_prefix) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, fmr); -+ } -+ nla_nest_end(skb, fmrs); -+ - return 0; - - nla_put_failure: -@@ -1727,6 +1981,7 @@ static const struct nla_policy ip6_tnl_p - [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 }, - [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 }, - [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, - }; - - static struct rtnl_link_ops ip6_link_ops __read_mostly = { diff --git a/target/linux/generic/pending-3.18/667-ipv6-Fixed-source-specific-default-route-handling.patch b/target/linux/generic/pending-3.18/667-ipv6-Fixed-source-specific-default-route-handling.patch deleted file mode 100644 index 61612cecb8..0000000000 --- a/target/linux/generic/pending-3.18/667-ipv6-Fixed-source-specific-default-route-handling.patch +++ /dev/null @@ -1,96 +0,0 @@ -From e16e888b525503be05b3aea64190e8b3bdef44d0 Mon Sep 17 00:00:00 2001 -From: Markus Stenberg <markus.stenberg@iki.fi> -Date: Tue, 5 May 2015 13:36:59 +0300 -Subject: [PATCH] ipv6: Fixed source specific default route handling. - -If there are only IPv6 source specific default routes present, the -host gets -ENETUNREACH on e.g. connect() because ip6_dst_lookup_tail -calls ip6_route_output first, and given source address any, it fails, -and ip6_route_get_saddr is never called. - -The change is to use the ip6_route_get_saddr, even if the initial -ip6_route_output fails, and then doing ip6_route_output _again_ after -we have appropriate source address available. - -Note that this is '99% fix' to the problem; a correct fix would be to -do route lookups only within addrconf.c when picking a source address, -and never call ip6_route_output before source address has been -populated. - -Signed-off-by: Markus Stenberg <markus.stenberg@iki.fi> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/ipv6/ip6_output.c | 39 +++++++++++++++++++++++++++++++-------- - net/ipv6/route.c | 5 +++-- - 2 files changed, 34 insertions(+), 10 deletions(-) - ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -909,21 +909,45 @@ static int ip6_dst_lookup_tail(struct so - #endif - int err; - -- if (*dst == NULL) -- *dst = ip6_route_output(net, sk, fl6); -- -- if ((err = (*dst)->error)) -- goto out_err_release; -+ /* The correct way to handle this would be to do -+ * ip6_route_get_saddr, and then ip6_route_output; however, -+ * the route-specific preferred source forces the -+ * ip6_route_output call _before_ ip6_route_get_saddr. -+ * -+ * In source specific routing (no src=any default route), -+ * ip6_route_output will fail given src=any saddr, though, so -+ * that's why we try it again later. -+ */ -+ if (ipv6_addr_any(&fl6->saddr) && (!*dst || !(*dst)->error)) { -+ struct rt6_info *rt; -+ bool had_dst = *dst != NULL; - -- if (ipv6_addr_any(&fl6->saddr)) { -- struct rt6_info *rt = (struct rt6_info *) *dst; -+ if (!had_dst) -+ *dst = ip6_route_output(net, sk, fl6); -+ rt = (*dst)->error ? NULL : (struct rt6_info *)*dst; - err = ip6_route_get_saddr(net, rt, &fl6->daddr, - sk ? inet6_sk(sk)->srcprefs : 0, - &fl6->saddr); - if (err) - goto out_err_release; -+ -+ /* If we had an erroneous initial result, pretend it -+ * never existed and let the SA-enabled version take -+ * over. -+ */ -+ if (!had_dst && (*dst)->error) { -+ dst_release(*dst); -+ *dst = NULL; -+ } - } - -+ if (!*dst) -+ *dst = ip6_route_output(net, sk, fl6); -+ -+ err = (*dst)->error; -+ if (err) -+ goto out_err_release; -+ - #ifdef CONFIG_IPV6_OPTIMISTIC_DAD - /* - * Here if the dst entry we've looked up ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -2185,9 +2185,10 @@ int ip6_route_get_saddr(struct net *net, - unsigned int prefs, - struct in6_addr *saddr) - { -- struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt); -+ struct inet6_dev *idev = -+ rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL; - int err = 0; -- if (rt->rt6i_prefsrc.plen) -+ if (rt && rt->rt6i_prefsrc.plen) - *saddr = rt->rt6i_prefsrc.addr; - else - err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, diff --git a/target/linux/generic/pending-3.18/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-3.18/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch deleted file mode 100644 index ac4a0a6bf9..0000000000 --- a/target/linux/generic/pending-3.18/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 1b5aaa4b16f6e6471ab1c07b38068197a1b4c395 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski <jogo@openwrt.org> -Date: Fri, 24 May 2013 14:40:54 +0200 -Subject: [PATCH 1/2] ipv6: allow rejecting with "source address failed policy" - -RFC6204 L-14 requires rejecting traffic from invalid addresses with -ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ -egress policy) on the LAN side, so add an appropriate rule for that. - -Signed-off-by: Jonas Gorski <jogo@openwrt.org> ---- - include/net/netns/ipv6.h | 1 + - include/uapi/linux/fib_rules.h | 4 +++ - include/uapi/linux/rtnetlink.h | 1 + - net/ipv4/fib_semantics.c | 4 +++ - net/ipv4/fib_trie.c | 1 + - net/ipv4/ipmr.c | 1 + - net/ipv6/fib6_rules.c | 4 +++ - net/ipv6/ip6mr.c | 2 ++ - net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- - 9 files changed, 75 insertions(+), 1 deletion(-) - ---- a/include/net/netns/ipv6.h -+++ b/include/net/netns/ipv6.h -@@ -59,6 +59,7 @@ struct netns_ipv6 { - unsigned long ip6_rt_last_gc; - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - struct rt6_info *ip6_prohibit_entry; -+ struct rt6_info *ip6_policy_failed_entry; - struct rt6_info *ip6_blk_hole_entry; - struct fib6_table *fib6_local_tbl; - struct fib_rules_ops *fib6_rules_ops; ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -64,6 +64,10 @@ enum { - FR_ACT_BLACKHOLE, /* Drop without notification */ - FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT, /* Drop with EACCES */ -+ FR_ACT_RES9, -+ FR_ACT_RES10, -+ FR_ACT_RES11, -+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ - __FR_ACT_MAX, - }; - ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -203,6 +203,7 @@ enum { - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ -+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ - __RTN_MAX - }; - ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -138,6 +138,10 @@ const struct fib_prop fib_props[RTN_MAX - .error = -EINVAL, - .scope = RT_SCOPE_NOWHERE, - }, -+ [RTN_POLICY_FAILED] = { -+ .error = -EACCES, -+ .scope = RT_SCOPE_UNIVERSE, -+ }, - }; - - static void rt_fibinfo_free(struct rtable __rcu **rtp) ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2236,6 +2236,7 @@ static const char *const rtn_type_names[ - [RTN_THROW] = "THROW", - [RTN_NAT] = "NAT", - [RTN_XRESOLVE] = "XRESOLVE", -+ [RTN_POLICY_FAILED] = "POLICY_FAILED", - }; - - static inline const char *rtn_type(char *buf, size_t len, unsigned int t) ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -184,6 +184,7 @@ static int ipmr_rule_action(struct fib_r - case FR_ACT_UNREACHABLE: - return -ENETUNREACH; - case FR_ACT_PROHIBIT: -+ case FR_ACT_POLICY_FAILED: - return -EACCES; - case FR_ACT_BLACKHOLE: - default: ---- a/net/ipv6/fib6_rules.c -+++ b/net/ipv6/fib6_rules.c -@@ -73,6 +73,10 @@ static int fib6_rule_action(struct fib_r - err = -EACCES; - rt = net->ipv6.ip6_prohibit_entry; - goto discard_pkt; -+ case FR_ACT_POLICY_FAILED: -+ err = -EACCES; -+ rt = net->ipv6.ip6_policy_failed_entry; -+ goto discard_pkt; - } - - table = fib6_get_table(net, rule->table); ---- a/net/ipv6/ip6mr.c -+++ b/net/ipv6/ip6mr.c -@@ -169,6 +169,8 @@ static int ip6mr_rule_action(struct fib_ - return -ENETUNREACH; - case FR_ACT_PROHIBIT: - return -EACCES; -+ case FR_ACT_POLICY_FAILED: -+ return -EACCES; - case FR_ACT_BLACKHOLE: - default: - return -EINVAL; ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -87,6 +87,8 @@ static int ip6_pkt_discard(struct sk_bu - static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb); - static int ip6_pkt_prohibit(struct sk_buff *skb); - static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb); -+static int ip6_pkt_policy_failed(struct sk_buff *skb); -+static int ip6_pkt_policy_failed_out(struct sock *sk, struct sk_buff *skb); - static void ip6_link_failure(struct sk_buff *skb); - static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, - struct sk_buff *skb, u32 mtu); -@@ -283,6 +285,21 @@ static const struct rt6_info ip6_prohibi - .rt6i_ref = ATOMIC_INIT(1), - }; - -+static const struct rt6_info ip6_policy_failed_entry_template = { -+ .dst = { -+ .__refcnt = ATOMIC_INIT(1), -+ .__use = 1, -+ .obsolete = DST_OBSOLETE_FORCE_CHK, -+ .error = -EACCES, -+ .input = ip6_pkt_policy_failed, -+ .output = ip6_pkt_policy_failed_out, -+ }, -+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), -+ .rt6i_protocol = RTPROT_KERNEL, -+ .rt6i_metric = ~(u32) 0, -+ .rt6i_ref = ATOMIC_INIT(1), -+}; -+ - static const struct rt6_info ip6_blk_hole_entry_template = { - .dst = { - .__refcnt = ATOMIC_INIT(1), -@@ -1579,6 +1596,11 @@ int ip6_route_add(struct fib6_config *cf - rt->dst.output = ip6_pkt_prohibit_out; - rt->dst.input = ip6_pkt_prohibit; - break; -+ case RTN_POLICY_FAILED: -+ rt->dst.error = -EACCES; -+ rt->dst.output = ip6_pkt_policy_failed_out; -+ rt->dst.input = ip6_pkt_policy_failed; -+ break; - case RTN_THROW: - default: - rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN -@@ -2142,6 +2164,17 @@ static int ip6_pkt_prohibit_out(struct s - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); - } - -+static int ip6_pkt_policy_failed(struct sk_buff *skb) -+{ -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); -+} -+ -+static int ip6_pkt_policy_failed_out(struct sock *sk, struct sk_buff *skb) -+{ -+ skb->dev = skb_dst(skb)->dev; -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); -+} -+ - /* - * Allocate a dst for local (unicast / anycast) address. - */ -@@ -2368,7 +2401,8 @@ static int rtm_to_fib6_config(struct sk_ - if (rtm->rtm_type == RTN_UNREACHABLE || - rtm->rtm_type == RTN_BLACKHOLE || - rtm->rtm_type == RTN_PROHIBIT || -- rtm->rtm_type == RTN_THROW) -+ rtm->rtm_type == RTN_THROW || -+ rtm->rtm_type == RTN_POLICY_FAILED) - cfg->fc_flags |= RTF_REJECT; - - if (rtm->rtm_type == RTN_LOCAL) -@@ -2570,6 +2604,9 @@ static int rt6_fill_node(struct net *net - case -EACCES: - rtm->rtm_type = RTN_PROHIBIT; - break; -+ case -EPERM: -+ rtm->rtm_type = RTN_POLICY_FAILED; -+ break; - case -EAGAIN: - rtm->rtm_type = RTN_THROW; - break; -@@ -2828,6 +2865,8 @@ static int ip6_route_dev_notify(struct n - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.ip6_prohibit_entry->dst.dev = dev; - net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); -+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; -+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); - net->ipv6.ip6_blk_hole_entry->dst.dev = dev; - net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); - #endif -@@ -3054,6 +3093,17 @@ static int __net_init ip6_route_net_init - net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; - dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, - ip6_template_metrics, true); -+ -+ net->ipv6.ip6_policy_failed_entry = -+ kmemdup(&ip6_policy_failed_entry_template, -+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); -+ if (!net->ipv6.ip6_policy_failed_entry) -+ goto out_ip6_blk_hole_entry; -+ net->ipv6.ip6_policy_failed_entry->dst.path = -+ (struct dst_entry *)net->ipv6.ip6_policy_failed_entry; -+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; -+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, -+ ip6_template_metrics, true); - #endif - - net->ipv6.sysctl.flush_delay = 0; -@@ -3072,6 +3122,8 @@ out: - return ret; - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+out_ip6_blk_hole_entry: -+ kfree(net->ipv6.ip6_blk_hole_entry); - out_ip6_prohibit_entry: - kfree(net->ipv6.ip6_prohibit_entry); - out_ip6_null_entry: -@@ -3089,6 +3141,7 @@ static void __net_exit ip6_route_net_exi - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(net->ipv6.ip6_prohibit_entry); - kfree(net->ipv6.ip6_blk_hole_entry); -+ kfree(net->ipv6.ip6_policy_failed_entry); - #endif - dst_entries_destroy(&net->ipv6.ip6_dst_ops); - } -@@ -3162,6 +3215,9 @@ void __init ip6_route_init_special_entri - init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); - init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; - init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -+ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; -+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = -+ in6_dev_get(init_net.loopback_dev); - #endif - } - diff --git a/target/linux/generic/pending-3.18/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-3.18/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch deleted file mode 100644 index 25a8639397..0000000000 --- a/target/linux/generic/pending-3.18/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 7749b481ce5d7e232b1f7da5e6b2c44816f51681 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski <jogo@openwrt.org> -Date: Sun, 19 Jan 2014 20:45:51 +0100 -Subject: [PATCH 2/2] net: provide defines for _POLICY_FAILED until all code is - updated - -Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination -unreachable, conflicting with our name. - -Add appropriate defines to allow our code to build with the new -name until we have updated our local patches for older kernels -and userspace packages. - -Signed-off-by: Jonas Gorski <jogo@openwrt.org> ---- - include/uapi/linux/fib_rules.h | 2 ++ - include/uapi/linux/icmpv6.h | 2 ++ - include/uapi/linux/rtnetlink.h | 2 ++ - 3 files changed, 6 insertions(+) - ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -71,6 +71,8 @@ enum { - __FR_ACT_MAX, - }; - -+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED -+ - #define FR_ACT_MAX (__FR_ACT_MAX - 1) - - #endif ---- a/include/uapi/linux/icmpv6.h -+++ b/include/uapi/linux/icmpv6.h -@@ -118,6 +118,8 @@ struct icmp6hdr { - #define ICMPV6_POLICY_FAIL 5 - #define ICMPV6_REJECT_ROUTE 6 - -+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL -+ - /* - * Codes for Time Exceeded - */ ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -207,6 +207,8 @@ enum { - __RTN_MAX - }; - -+#define RTN_FAILED_POLICY RTN_POLICY_FAILED -+ - #define RTN_MAX (__RTN_MAX - 1) - - diff --git a/target/linux/generic/pending-3.18/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-3.18/680-NET-skip-GRO-for-foreign-MAC-addresses.patch deleted file mode 100644 index 038c75b680..0000000000 --- a/target/linux/generic/pending-3.18/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ /dev/null @@ -1,160 +0,0 @@ -Subject: NET: skip GRO for foreign MAC addresses - -For network drivers using napi_gro_receive, packets are run through GRO, -even when the destination MAC address does not match, and they're supposed -to be delivered to another host behind a different bridge port. - -This can be very expensive, because for drivers without TSO or scatter- -gather, this can only be undone by copying the skb and checksumming it -again. - -To be able to track foreign MAC addresses in an inexpensive way, create -a mask of changed bits in MAC addresses of upper devices. This allows -handling VLANs and bridge devices with different addresses (as long as -they are not too different). - -Signed-off-by: Felix Fietkau <nbd@nbd.name> - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4028,6 +4028,9 @@ static enum gro_result dev_gro_receive(s - enum gro_result ret; - int grow; - -+ if (skb->gro_skip) -+ goto normal; -+ - if (!(skb->dev->features & NETIF_F_GRO)) - goto normal; - -@@ -5103,6 +5106,48 @@ static void __netdev_adjacent_dev_unlink - &upper_dev->adj_list.lower); - } - -+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, -+ struct net_device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < dev->addr_len; i++) -+ mask[i] |= addr[i] ^ dev->dev_addr[i]; -+} -+ -+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, -+ struct net_device *lower) -+{ -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ netdev_for_each_upper_dev_rcu(dev, cur, iter) { -+ __netdev_addr_mask(mask, cur->dev_addr, lower); -+ __netdev_upper_mask(mask, cur, lower); -+ } -+} -+ -+static void __netdev_update_addr_mask(struct net_device *dev) -+{ -+ unsigned char mask[MAX_ADDR_LEN]; -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ memset(mask, 0, sizeof(mask)); -+ __netdev_upper_mask(mask, dev, dev); -+ memcpy(dev->local_addr_mask, mask, dev->addr_len); -+ -+ netdev_for_each_lower_dev(dev, cur, iter) -+ __netdev_update_addr_mask(cur); -+} -+ -+static void netdev_update_addr_mask(struct net_device *dev) -+{ -+ rcu_read_lock(); -+ __netdev_update_addr_mask(dev); -+ rcu_read_unlock(); -+} -+ - static int __netdev_upper_dev_link(struct net_device *dev, - struct net_device *upper_dev, bool master, - void *private) -@@ -5163,6 +5208,7 @@ static int __netdev_upper_dev_link(struc - goto rollback_lower_mesh; - } - -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); - return 0; - -@@ -5280,6 +5326,7 @@ void netdev_upper_dev_unlink(struct net_ - list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) - __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); - -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); - } - EXPORT_SYMBOL(netdev_upper_dev_unlink); -@@ -5799,6 +5846,7 @@ int dev_set_mac_address(struct net_devic - if (err) - return err; - dev->addr_assign_type = NET_ADDR_SET; -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - add_device_randomness(dev->dev_addr, dev->addr_len); - return 0; ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1556,6 +1556,8 @@ struct net_device { - struct netdev_hw_addr_list mc; - struct netdev_hw_addr_list dev_addrs; - -+ unsigned char local_addr_mask[MAX_ADDR_LEN]; -+ - #ifdef CONFIG_SYSFS - struct kset *queues_kset; - #endif ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -598,7 +598,8 @@ struct sk_buff { - __u8 ipvs_property:1; - - __u8 inner_protocol_type:1; -- /* 4 or 6 bit hole */ -+ __u8 gro_skip:1; -+ /* 3 or 5 bit hole */ - - #ifdef CONFIG_NET_SCHED - __u16 tc_index; /* traffic control index */ ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -172,6 +172,18 @@ u32 eth_get_headlen(void *data, unsigned - } - EXPORT_SYMBOL(eth_get_headlen); - -+static inline bool -+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) -+{ -+ const u16 *a1 = addr1; -+ const u16 *a2 = addr2; -+ const u16 *m = mask; -+ -+ return (((a1[0] ^ a2[0]) & ~m[0]) | -+ ((a1[1] ^ a2[1]) & ~m[1]) | -+ ((a1[2] ^ a2[2]) & ~m[2])); -+} -+ - /** - * eth_type_trans - determine the packet's protocol ID. - * @skb: received socket data -@@ -199,8 +211,12 @@ __be16 eth_type_trans(struct sk_buff *sk - skb->pkt_type = PACKET_MULTICAST; - } - else if (unlikely(!ether_addr_equal_64bits(eth->h_dest, -- dev->dev_addr))) -+ dev->dev_addr))) { - skb->pkt_type = PACKET_OTHERHOST; -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; -+ } - - /* - * Some variants of DSA tagging don't have an ethertype field diff --git a/target/linux/generic/pending-3.18/681-NET-add-of_get_mac_address_mtd.patch b/target/linux/generic/pending-3.18/681-NET-add-of_get_mac_address_mtd.patch deleted file mode 100644 index a836eed867..0000000000 --- a/target/linux/generic/pending-3.18/681-NET-add-of_get_mac_address_mtd.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: John Crispin <blogic@openwrt.org> -Date: Sun, 27 Jul 2014 09:40:01 +0100 -Subject: NET: add of_get_mac_address_mtd() - -Many embedded devices have information such as mac addresses stored inside mtd -devices. This patch allows us to add a property inside a node describing a -network interface. The new property points at a mtd partition with an offset -where the mac address can be found. - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++ - include/linux/of_net.h | 1 + - 2 files changed, 38 insertions(+) - ---- a/drivers/of/of_net.c -+++ b/drivers/of/of_net.c -@@ -10,6 +10,7 @@ - #include <linux/of_net.h> - #include <linux/phy.h> - #include <linux/export.h> -+#include <linux/mtd/mtd.h> - - /** - * of_get_phy_mode - Get phy mode for given device_node -@@ -75,3 +76,45 @@ const void *of_get_mac_address(struct de - return NULL; - } - EXPORT_SYMBOL(of_get_mac_address); -+ -+#ifdef CONFIG_MTD -+int of_get_mac_address_mtd(struct device_node *np, unsigned char *mac) -+{ -+ struct device_node *mtd_np = NULL; -+ size_t retlen; -+ int size, ret; -+ struct mtd_info *mtd; -+ const char *part; -+ const __be32 *list; -+ phandle phandle; -+ u32 mac_inc = 0; -+ -+ list = of_get_property(np, "mtd-mac-address", &size); -+ if (!list || (size != (2 * sizeof(*list)))) -+ return -ENOENT; -+ -+ phandle = be32_to_cpup(list++); -+ if (phandle) -+ mtd_np = of_find_node_by_phandle(phandle); -+ -+ if (!mtd_np) -+ return -ENOENT; -+ -+ part = of_get_property(mtd_np, "label", NULL); -+ if (!part) -+ part = mtd_np->name; -+ -+ mtd = get_mtd_device_nm(part); -+ if (IS_ERR(mtd)) -+ return PTR_ERR(mtd); -+ -+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac); -+ put_mtd_device(mtd); -+ -+ if (!of_property_read_u32(np, "mtd-mac-address-increment", &mac_inc)) -+ mac[5] += mac_inc; -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_get_mac_address_mtd); -+#endif ---- a/include/linux/of_net.h -+++ b/include/linux/of_net.h -@@ -11,6 +11,14 @@ - #include <linux/of.h> - extern int of_get_phy_mode(struct device_node *np); - extern const void *of_get_mac_address(struct device_node *np); -+#ifdef CONFIG_MTD -+extern int of_get_mac_address_mtd(struct device_node *np, unsigned char *mac); -+#else -+static inline int of_get_mac_address_mtd(struct device_node *np, unsigned char *mac) -+{ -+ return -ENOENT; -+} -+#endif - #else - static inline int of_get_phy_mode(struct device_node *np) - { diff --git a/target/linux/generic/pending-3.18/700-swconfig.patch b/target/linux/generic/pending-3.18/700-swconfig.patch deleted file mode 100644 index 7cf525a509..0000000000 --- a/target/linux/generic/pending-3.18/700-swconfig.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -12,6 +12,16 @@ menuconfig PHYLIB - - if PHYLIB - -+config SWCONFIG -+ tristate "Switch configuration API" -+ ---help--- -+ Switch configuration API using netlink. This allows -+ you to configure the VLAN features of certain switches. -+ -+config SWCONFIG_LEDS -+ bool "Switch LED trigger support" -+ depends on (SWCONFIG && LEDS_TRIGGERS) -+ - comment "MII PHY device drivers" - - config AT803X_PHY ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -3,6 +3,7 @@ - libphy-objs := phy.o phy_device.o mdio_bus.o - - obj-$(CONFIG_PHYLIB) += libphy.o -+obj-$(CONFIG_SWCONFIG) += swconfig.o - obj-$(CONFIG_MARVELL_PHY) += marvell.o - obj-$(CONFIG_DAVICOM_PHY) += davicom.o - obj-$(CONFIG_CICADA_PHY) += cicada.o ---- a/include/uapi/linux/Kbuild -+++ b/include/uapi/linux/Kbuild -@@ -374,6 +374,7 @@ header-y += stddef.h - header-y += string.h - header-y += suspend_ioctls.h - header-y += swab.h -+header-y += switch.h - header-y += synclink.h - header-y += sysctl.h - header-y += sysinfo.h diff --git a/target/linux/generic/pending-3.18/701-phy_extension.patch b/target/linux/generic/pending-3.18/701-phy_extension.patch deleted file mode 100644 index ffc310a134..0000000000 --- a/target/linux/generic/pending-3.18/701-phy_extension.patch +++ /dev/null @@ -1,63 +0,0 @@ ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -363,6 +363,50 @@ int phy_ethtool_gset(struct phy_device * - } - EXPORT_SYMBOL(phy_ethtool_gset); - -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) -+{ -+ u32 cmd; -+ int tmp; -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ struct ethtool_value edata = { ETHTOOL_GLINK }; -+ -+ if (get_user(cmd, (u32 *) useraddr)) -+ return -EFAULT; -+ -+ switch (cmd) { -+ case ETHTOOL_GSET: -+ phy_ethtool_gset(phydev, &ecmd); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; -+ -+ case ETHTOOL_SSET: -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ return phy_ethtool_sset(phydev, &ecmd); -+ -+ case ETHTOOL_NWAY_RST: -+ /* if autoneg is off, it's an error */ -+ tmp = phy_read(phydev, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ phy_write(phydev, MII_BMCR, tmp); -+ return 0; -+ } -+ return -EINVAL; -+ -+ case ETHTOOL_GLINK: -+ edata.data = (phy_read(phydev, -+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; -+ } -+ -+ return -EOPNOTSUPP; -+} -+EXPORT_SYMBOL(phy_ethtool_ioctl); -+ - /** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -759,6 +759,7 @@ void phy_start_machine(struct phy_device - void phy_stop_machine(struct phy_device *phydev); - int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); - int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); - int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd); - int phy_start_interrupts(struct phy_device *phydev); - void phy_print_status(struct phy_device *phydev); diff --git a/target/linux/generic/pending-3.18/702-phy_add_aneg_done_function.patch b/target/linux/generic/pending-3.18/702-phy_add_aneg_done_function.patch deleted file mode 100644 index 49ffd27814..0000000000 --- a/target/linux/generic/pending-3.18/702-phy_add_aneg_done_function.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -480,6 +480,12 @@ struct phy_driver { - /* Determines the negotiated speed and duplex */ - int (*read_status)(struct phy_device *phydev); - -+ /* -+ * Update the value in phydev->link to reflect the -+ * current link value -+ */ -+ int (*update_link)(struct phy_device *phydev); -+ - /* Clears any pending interrupts */ - int (*ack_interrupt)(struct phy_device *phydev); - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -915,6 +915,9 @@ int genphy_update_link(struct phy_device - { - int status; - -+ if (phydev->drv && phydev->drv->update_link) -+ return phydev->drv->update_link(phydev); -+ - /* Do a fake read */ - status = phy_read(phydev, MII_BMSR); - if (status < 0) diff --git a/target/linux/generic/pending-3.18/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-3.18/703-phy-add-detach-callback-to-struct-phy_driver.patch deleted file mode 100644 index ca8e455833..0000000000 --- a/target/linux/generic/pending-3.18/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -674,6 +674,9 @@ void phy_detach(struct phy_device *phyde - { - int i; - -+ if (phydev->drv && phydev->drv->detach) -+ phydev->drv->detach(phydev); -+ - if (phydev->bus->dev.driver) - module_put(phydev->bus->dev.driver->owner); - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -498,6 +498,12 @@ struct phy_driver { - */ - int (*did_interrupt)(struct phy_device *phydev); - -+ /* -+ * Called before an ethernet device is detached -+ * from the PHY. -+ */ -+ void (*detach)(struct phy_device *phydev); -+ - /* Clears up any memory if needed */ - void (*remove)(struct phy_device *phydev); - diff --git a/target/linux/generic/pending-3.18/710-phy-add-mdio_register_board_info.patch b/target/linux/generic/pending-3.18/710-phy-add-mdio_register_board_info.patch deleted file mode 100644 index 60026b474c..0000000000 --- a/target/linux/generic/pending-3.18/710-phy-add-mdio_register_board_info.patch +++ /dev/null @@ -1,192 +0,0 @@ ---- a/drivers/net/phy/mdio_bus.c -+++ b/drivers/net/phy/mdio_bus.c -@@ -38,6 +38,8 @@ - - #include <asm/irq.h> - -+#include "mdio-boardinfo.h" -+ - /** - * mdiobus_alloc_size - allocate a mii_bus structure - * @size: extra amount of memory to allocate for private storage. -@@ -335,9 +337,21 @@ void mdiobus_free(struct mii_bus *bus) - } - EXPORT_SYMBOL(mdiobus_free); - -+static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus, -+ struct phy_device *phydev, -+ struct mdio_board_info *bi) -+{ -+ if (strcmp(bus->id, bi->bus_id) || -+ bi->phy_addr != phydev->addr) -+ return; -+ -+ phydev->dev.platform_data = (void *) bi->platform_data; -+} -+ - struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) - { - struct phy_device *phydev; -+ struct mdio_board_entry *be; - int err; - - phydev = get_phy_device(bus, addr, false); -@@ -350,6 +364,12 @@ struct phy_device *mdiobus_scan(struct m - */ - of_mdiobus_link_phydev(bus, phydev); - -+ mutex_lock(&__mdio_board_lock); -+ list_for_each_entry(be, &__mdio_board_list, list) -+ mdiobus_setup_phydev_from_boardinfo(bus, phydev, -+ &be->board_info); -+ mutex_unlock(&__mdio_board_lock); -+ - err = phy_device_register(phydev); - if (err) { - phy_device_free(phydev); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -796,4 +796,22 @@ int __init mdio_bus_init(void); - void mdio_bus_exit(void); - - extern struct bus_type mdio_bus_type; -+ -+struct mdio_board_info { -+ const char *bus_id; -+ int phy_addr; -+ -+ const void *platform_data; -+}; -+ -+#ifdef CONFIG_MDIO_BOARDINFO -+int mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n); -+#else -+static inline int -+mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n) -+{ -+ return 0; -+} -+#endif -+ - #endif /* __PHY_H */ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -12,6 +12,10 @@ menuconfig PHYLIB - - if PHYLIB - -+config MDIO_BOARDINFO -+ bool -+ default y -+ - config SWCONFIG - tristate "Switch configuration API" - ---help--- ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -2,6 +2,8 @@ - - libphy-objs := phy.o phy_device.o mdio_bus.o - -+obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o -+ - obj-$(CONFIG_PHYLIB) += libphy.o - obj-$(CONFIG_SWCONFIG) += swconfig.o - obj-$(CONFIG_MARVELL_PHY) += marvell.o ---- /dev/null -+++ b/drivers/net/phy/mdio-boardinfo.c -@@ -0,0 +1,58 @@ -+/* -+ * mdio-boardinfo.c - collect pre-declarations of PHY devices -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/phy.h> -+#include <linux/slab.h> -+#include <linux/export.h> -+#include <linux/mutex.h> -+#include <linux/phy.h> -+ -+#include "mdio-boardinfo.h" -+ -+/* -+ * These symbols are exported ONLY FOR the mdio_bus component. -+ * No other users will be supported. -+ */ -+ -+LIST_HEAD(__mdio_board_list); -+EXPORT_SYMBOL_GPL(__mdio_board_list); -+ -+DEFINE_MUTEX(__mdio_board_lock); -+EXPORT_SYMBOL_GPL(__mdio_board_lock); -+ -+/** -+ * mdio_register_board_info - register PHY devices for a given board -+ * @info: array of chip descriptors -+ * @n: how many descriptors are provided -+ * Context: can sleep -+ * -+ * The board info passed can safely be __initdata ... but be careful of -+ * any embedded pointers (platform_data, etc), they're copied as-is. -+ */ -+int __init -+mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n) -+{ -+ struct mdio_board_entry *be; -+ int i; -+ -+ be = kzalloc(n * sizeof(*be), GFP_KERNEL); -+ if (!be) -+ return -ENOMEM; -+ -+ for (i = 0; i < n; i++, be++, info++) { -+ memcpy(&be->board_info, info, sizeof(*info)); -+ mutex_lock(&__mdio_board_lock); -+ list_add_tail(&be->list, &__mdio_board_list); -+ mutex_unlock(&__mdio_board_lock); -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/phy/mdio-boardinfo.h -@@ -0,0 +1,22 @@ -+/* -+ * mdio-boardinfo.h - boardinfo interface internal to the mdio_bus component -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ */ -+ -+#include <linux/mutex.h> -+ -+struct mdio_board_entry { -+ struct list_head list; -+ struct mdio_board_info board_info; -+}; -+ -+/* __mdio_board_lock protects __mdio_board_list -+ * only mdio_bus components are allowed to use these symbols. -+ */ -+extern struct mutex __mdio_board_lock; -+extern struct list_head __mdio_board_list; ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -15,7 +15,7 @@ obj-$(CONFIG_MII) += mii.o - obj-$(CONFIG_MDIO) += mdio.o - obj-$(CONFIG_NET) += Space.o loopback.o - obj-$(CONFIG_NETCONSOLE) += netconsole.o --obj-$(CONFIG_PHYLIB) += phy/ -+obj-y += phy/ - obj-$(CONFIG_RIONET) += rionet.o - obj-$(CONFIG_NET_TEAM) += team/ - obj-$(CONFIG_TUN) += tun.o diff --git a/target/linux/generic/pending-3.18/720-phy_adm6996.patch b/target/linux/generic/pending-3.18/720-phy_adm6996.patch deleted file mode 100644 index b0b8db4e5d..0000000000 --- a/target/linux/generic/pending-3.18/720-phy_adm6996.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -132,6 +132,13 @@ config MICREL_PHY - ---help--- - Supports the KSZ9021, VSC8201, KS8001 PHYs. - -+config ADM6996_PHY -+ tristate "Driver for ADM6996 switches" -+ select SWCONFIG -+ ---help--- -+ Currently supports the ADM6996FC and ADM6996M switches. -+ Support for FC is very limited. -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o - obj-$(CONFIG_BCM7XXX_PHY) += bcm7xxx.o - obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o - obj-$(CONFIG_ICPLUS_PHY) += icplus.o -+obj-$(CONFIG_ADM6996_PHY) += adm6996.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/target/linux/generic/pending-3.18/721-phy_packets.patch b/target/linux/generic/pending-3.18/721-phy_packets.patch deleted file mode 100644 index ed51bb1d2d..0000000000 --- a/target/linux/generic/pending-3.18/721-phy_packets.patch +++ /dev/null @@ -1,161 +0,0 @@ ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1228,6 +1228,7 @@ enum netdev_priv_flags { - IFF_LIVE_ADDR_CHANGE = 1<<20, - IFF_MACVLAN = 1<<21, - IFF_XMIT_DST_RELEASE_PERM = 1<<22, -+ IFF_NO_IP_ALIGN = 1<<23, - }; - - #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN -@@ -1253,6 +1254,7 @@ enum netdev_priv_flags { - #define IFF_LIVE_ADDR_CHANGE IFF_LIVE_ADDR_CHANGE - #define IFF_MACVLAN IFF_MACVLAN - #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM -+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN - - /** - * struct net_device - The DEVICE structure. -@@ -1523,6 +1525,11 @@ struct net_device { - const struct ethtool_ops *ethtool_ops; - const struct forwarding_accel_ops *fwd_ops; - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); -+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); -+#endif -+ - const struct header_ops *header_ops; - - unsigned int flags; -@@ -1587,6 +1594,10 @@ struct net_device { - void *ax25_ptr; - struct wireless_dev *ieee80211_ptr; - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void *phy_ptr; /* PHY device specific data */ -+#endif -+ - /* - * Cache lines mostly used on receive path (including eth_type_trans()) - */ ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2055,6 +2055,10 @@ static inline int pskb_trim(struct sk_bu - return (len < skb->len) ? __pskb_trim(skb, len) : 0; - } - -+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp); -+ -+ - /** - * pskb_trim_unique - remove end from a paged unique (not cloned) buffer - * @skb: buffer to alter -@@ -2181,16 +2185,6 @@ static inline struct sk_buff *dev_alloc_ - } - - --static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -- unsigned int length, gfp_t gfp) --{ -- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -- -- if (NET_IP_ALIGN && skb) -- skb_reserve(skb, NET_IP_ALIGN); -- return skb; --} -- - static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, - unsigned int length) - { ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -25,6 +25,12 @@ menuconfig NET - - if NET - -+config ETHERNET_PACKET_MANGLE -+ bool -+ help -+ This option can be selected by phy drivers that need to mangle -+ packets going in or out of an ethernet device. -+ - config WANT_COMPAT_NETLINK_MESSAGES - bool - help ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2637,10 +2637,20 @@ static int xmit_one(struct sk_buff *skb, - if (!list_empty(&ptype_all)) - dev_queue_xmit_nit(skb, dev); - -- len = skb->len; -- trace_net_dev_start_xmit(skb, dev); -- rc = netdev_start_xmit(skb, dev, txq, more); -- trace_net_dev_xmit(skb, rc, dev, len); -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (!dev->eth_mangle_tx || -+ (skb = dev->eth_mangle_tx(dev, skb)) != NULL) -+#else -+ if (1) -+#endif -+ { -+ len = skb->len; -+ trace_net_dev_start_xmit(skb, dev); -+ rc = netdev_start_xmit(skb, dev, txq, more); -+ trace_net_dev_xmit(skb, rc, dev, len); -+ } else { -+ rc = NETDEV_TX_OK; -+ } - - return rc; - } ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -63,6 +63,7 @@ - #include <linux/errqueue.h> - #include <linux/prefetch.h> - #include <linux/if_vlan.h> -+#include <linux/if.h> - - #include <net/protocol.h> - #include <net/dst.h> -@@ -471,6 +472,22 @@ struct sk_buff *__netdev_alloc_skb(struc - } - EXPORT_SYMBOL(__netdev_alloc_skb); - -+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp) -+{ -+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) -+ return skb; -+#endif -+ -+ if (NET_IP_ALIGN && skb) -+ skb_reserve(skb, NET_IP_ALIGN); -+ return skb; -+} -+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); -+ - void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, - int size, unsigned int truesize) - { ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -200,6 +200,12 @@ __be16 eth_type_trans(struct sk_buff *sk - const struct ethhdr *eth; - - skb->dev = dev; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_rx) -+ dev->eth_mangle_rx(dev, skb); -+#endif -+ - skb_reset_mac_header(skb); - skb_pull_inline(skb, ETH_HLEN); - eth = eth_hdr(skb); diff --git a/target/linux/generic/pending-3.18/722-phy_mvswitch.patch b/target/linux/generic/pending-3.18/722-phy_mvswitch.patch deleted file mode 100644 index f577a9f684..0000000000 --- a/target/linux/generic/pending-3.18/722-phy_mvswitch.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -139,6 +139,10 @@ config ADM6996_PHY - Currently supports the ADM6996FC and ADM6996M switches. - Support for FC is very limited. - -+config MVSWITCH_PHY -+ tristate "Driver for Marvell 88E6060 switches" -+ select ETHERNET_PACKET_MANGLE -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM7XXX_PHY) += bcm7xxx.o - obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o - obj-$(CONFIG_ICPLUS_PHY) += icplus.o - obj-$(CONFIG_ADM6996_PHY) += adm6996.o -+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/target/linux/generic/pending-3.18/723-phy_ip175c.patch b/target/linux/generic/pending-3.18/723-phy_ip175c.patch deleted file mode 100644 index c7c4f99eec..0000000000 --- a/target/linux/generic/pending-3.18/723-phy_ip175c.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -143,6 +143,10 @@ config MVSWITCH_PHY - tristate "Driver for Marvell 88E6060 switches" - select ETHERNET_PACKET_MANGLE - -+config IP17XX_PHY -+ tristate "Driver for IC+ IP17xx switches" -+ select SWCONFIG -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o - obj-$(CONFIG_ICPLUS_PHY) += icplus.o - obj-$(CONFIG_ADM6996_PHY) += adm6996.o - obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o -+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/target/linux/generic/pending-3.18/724-phy_ar8216.patch b/target/linux/generic/pending-3.18/724-phy_ar8216.patch deleted file mode 100644 index acb2df8f83..0000000000 --- a/target/linux/generic/pending-3.18/724-phy_ar8216.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -147,6 +147,11 @@ config IP17XX_PHY - tristate "Driver for IC+ IP17xx switches" - select SWCONFIG - -+config AR8216_PHY -+ tristate "Driver for Atheros AR8216 switches" -+ select ETHERNET_PACKET_MANGLE -+ select SWCONFIG -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -22,6 +22,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o - obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o - obj-$(CONFIG_IP17XX_PHY) += ip17xx.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o -+obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/generic/pending-3.18/725-phy_rtl8306.patch b/target/linux/generic/pending-3.18/725-phy_rtl8306.patch deleted file mode 100644 index 78ac6ce98a..0000000000 --- a/target/linux/generic/pending-3.18/725-phy_rtl8306.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -152,6 +152,10 @@ config AR8216_PHY - select ETHERNET_PACKET_MANGLE - select SWCONFIG - -+config RTL8306_PHY -+ tristate "Driver for Realtek RTL8306S switches" -+ select SWCONFIG -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o - obj-$(CONFIG_IP17XX_PHY) += ip17xx.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o -+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/generic/pending-3.18/726-phy_rtl8366.patch b/target/linux/generic/pending-3.18/726-phy_rtl8366.patch deleted file mode 100644 index 4a4a4acee0..0000000000 --- a/target/linux/generic/pending-3.18/726-phy_rtl8366.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -250,6 +250,30 @@ config MDIO_BCM_UNIMAC - controllers as well as some Broadcom Ethernet switches such as the - Starfighter 2 switches. - -+config RTL8366_SMI -+ tristate "Driver for the RTL8366 SMI interface" -+ depends on GPIOLIB -+ ---help--- -+ This module implements the SMI interface protocol which is used -+ by some RTL8366 ethernet switch devices via the generic GPIO API. -+ -+if RTL8366_SMI -+ -+config RTL8366_SMI_DEBUG_FS -+ bool "RTL8366 SMI interface debugfs support" -+ depends on DEBUG_FS -+ default n -+ -+config RTL8366S_PHY -+ tristate "Driver for the Realtek RTL8366S switch" -+ select SWCONFIG -+ -+config RTL8366RB_PHY -+ tristate "Driver for the Realtek RTL8366RB switch" -+ select SWCONFIG -+ -+endif # RTL8366_SMI -+ - endif # PHYLIB - - config MICREL_KS8995MA ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -24,6 +24,9 @@ obj-$(CONFIG_IP17XX_PHY) += ip17xx.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o - obj-$(CONFIG_RTL8306_PHY) += rtl8306.o -+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o -+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o -+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/generic/pending-3.18/727-phy-rtl8367.patch b/target/linux/generic/pending-3.18/727-phy-rtl8367.patch deleted file mode 100644 index 8481b589d9..0000000000 --- a/target/linux/generic/pending-3.18/727-phy-rtl8367.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -272,6 +272,10 @@ config RTL8366RB_PHY - tristate "Driver for the Realtek RTL8366RB switch" - select SWCONFIG - -+config RTL8367_PHY -+ tristate "Driver for the Realtek RTL8367R/M switches" -+ select SWCONFIG -+ - endif # RTL8366_SMI - - endif # PHYLIB ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -27,6 +27,7 @@ obj-$(CONFIG_RTL8306_PHY) += rtl8306.o - obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o - obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o - obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o -+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/generic/pending-3.18/728-phy-rtl8367b.patch b/target/linux/generic/pending-3.18/728-phy-rtl8367b.patch deleted file mode 100644 index 958ff58907..0000000000 --- a/target/linux/generic/pending-3.18/728-phy-rtl8367b.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -276,6 +276,10 @@ config RTL8367_PHY - tristate "Driver for the Realtek RTL8367R/M switches" - select SWCONFIG - -+config RTL8367B_PHY -+ tristate "Driver fot the Realtek RTL8367R-VB switch" -+ select SWCONFIG -+ - endif # RTL8366_SMI - - endif # PHYLIB ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -28,6 +28,7 @@ obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi - obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o - obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o - obj-$(CONFIG_RTL8367_PHY) += rtl8367.o -+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/generic/pending-3.18/729-phy-tantos.patch b/target/linux/generic/pending-3.18/729-phy-tantos.patch deleted file mode 100644 index 019f919492..0000000000 --- a/target/linux/generic/pending-3.18/729-phy-tantos.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -287,3 +287,8 @@ endif # PHYLIB - config MICREL_KS8995MA - tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch" - depends on SPI -+ -+config PSB6970_PHY -+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" -+ select SWCONFIG -+ select ETHERNET_PACKET_MANGLE ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -30,6 +30,7 @@ obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb - obj-$(CONFIG_RTL8367_PHY) += rtl8367.o - obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o -+obj-$(CONFIG_PSB6970_PHY) += psb6970.o - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o - obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o diff --git a/target/linux/generic/pending-3.18/730-phy_b53.patch b/target/linux/generic/pending-3.18/730-phy_b53.patch deleted file mode 100644 index 8137693b3c..0000000000 --- a/target/linux/generic/pending-3.18/730-phy_b53.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -282,6 +282,8 @@ config RTL8367B_PHY - - endif # RTL8366_SMI - -+source "drivers/net/phy/b53/Kconfig" -+ - endif # PHYLIB - - config MICREL_KS8995MA ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -31,6 +31,7 @@ obj-$(CONFIG_RTL8367_PHY) += rtl8367.o - obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_PSB6970_PHY) += psb6970.o -+obj-$(CONFIG_SWCONFIG_B53) += b53/ - obj-$(CONFIG_FIXED_PHY) += fixed.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o - obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o ---- /dev/null -+++ b/linux/platform_data/b53.h -@@ -0,0 +1,36 @@ -+/* -+ * B53 platform data -+ * -+ * Copyright (C) 2013 Jonas Gorski <jogo@openwrt.org> -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef __B53_H -+#define __B53_H -+ -+#include <linux/kernel.h> -+ -+struct b53_platform_data { -+ u32 chip_id; -+ u16 enabled_ports; -+ -+ /* allow to specify an ethX alias */ -+ const char *alias; -+ -+ /* only used by MMAP'd driver */ -+ unsigned big_endian:1; -+ void __iomem *regs; -+}; -+ -+#endif diff --git a/target/linux/generic/pending-3.18/732-phy-ar8216-led-support.patch b/target/linux/generic/pending-3.18/732-phy-ar8216-led-support.patch deleted file mode 100644 index c753967572..0000000000 --- a/target/linux/generic/pending-3.18/732-phy-ar8216-led-support.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -152,6 +152,10 @@ config AR8216_PHY - select ETHERNET_PACKET_MANGLE - select SWCONFIG - -+config AR8216_PHY_LEDS -+ bool "Atheros AR8216 switch LED support" -+ depends on (AR8216_PHY && LEDS_CLASS) -+ - config RTL8306_PHY - tristate "Driver for Realtek RTL8306S switches" - select SWCONFIG diff --git a/target/linux/generic/pending-3.18/733-phy_mvsw61xx.patch b/target/linux/generic/pending-3.18/733-phy_mvsw61xx.patch deleted file mode 100644 index 041d168b65..0000000000 --- a/target/linux/generic/pending-3.18/733-phy_mvsw61xx.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -143,6 +143,10 @@ config MVSWITCH_PHY - tristate "Driver for Marvell 88E6060 switches" - select ETHERNET_PACKET_MANGLE - -+config MVSW61XX_PHY -+ tristate "Driver for Marvell 88E6171/6172 switches" -+ select SWCONFIG -+ - config IP17XX_PHY - tristate "Driver for IC+ IP17xx switches" - select SWCONFIG ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o - obj-$(CONFIG_ICPLUS_PHY) += icplus.o - obj-$(CONFIG_ADM6996_PHY) += adm6996.o - obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o -+obj-$(CONFIG_MVSW61XX_PHY) += mvsw61xx.o - obj-$(CONFIG_IP17XX_PHY) += ip17xx.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o diff --git a/target/linux/generic/pending-3.18/734-net-phy-at803x-allow-to-configure-via-pdata.patch b/target/linux/generic/pending-3.18/734-net-phy-at803x-allow-to-configure-via-pdata.patch deleted file mode 100644 index 0d021ac7bd..0000000000 --- a/target/linux/generic/pending-3.18/734-net-phy-at803x-allow-to-configure-via-pdata.patch +++ /dev/null @@ -1,180 +0,0 @@ ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -12,12 +12,14 @@ - */ - - #include <linux/phy.h> -+#include <linux/mdio.h> - #include <linux/module.h> - #include <linux/string.h> - #include <linux/netdevice.h> - #include <linux/etherdevice.h> - #include <linux/of_gpio.h> - #include <linux/gpio/consumer.h> -+#include <linux/platform_data/phy-at803x.h> - - #define AT803X_INTR_ENABLE 0x12 - #define AT803X_INTR_STATUS 0x13 -@@ -34,8 +36,16 @@ - #define AT803X_INER 0x0012 - #define AT803X_INER_INIT 0xec00 - #define AT803X_INSR 0x0013 -+ -+#define AT803X_PCS_SMART_EEE_CTRL3 0x805D -+#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3 -+#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12 -+#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8) -+ - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E -+#define AT803X_DBG0_REG 0x00 -+#define AT803X_DEBUG_RGMII_RX_CLK_DLY BIT(8) - #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05 - #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8) - -@@ -50,6 +60,7 @@ MODULE_LICENSE("GPL"); - struct at803x_priv { - bool phy_reset:1; - struct gpio_desc *gpiod_reset; -+ int prev_speed; - }; - - struct at803x_context { -@@ -61,6 +72,43 @@ struct at803x_context { - u16 led_control; - }; - -+static u16 -+at803x_dbg_reg_rmw(struct phy_device *phydev, u16 reg, u16 clear, u16 set) -+{ -+ struct mii_bus *bus = phydev->bus; -+ int val; -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ bus->write(bus, phydev->addr, AT803X_DEBUG_ADDR, reg); -+ val = bus->read(bus, phydev->addr, AT803X_DEBUG_DATA); -+ if (val < 0) { -+ val = 0xffff; -+ goto out; -+ } -+ -+ val &= ~clear; -+ val |= set; -+ bus->write(bus, phydev->addr, AT803X_DEBUG_DATA, val); -+ -+out: -+ mutex_unlock(&bus->mdio_lock); -+ return val; -+} -+ -+static inline void -+at803x_dbg_reg_set(struct phy_device *phydev, u16 reg, u16 set) -+{ -+ at803x_dbg_reg_rmw(phydev, reg, 0, set); -+} -+ -+static inline void -+at803x_dbg_reg_clr(struct phy_device *phydev, u16 reg, u16 clear) -+{ -+ at803x_dbg_reg_rmw(phydev, reg, clear, 0); -+} -+ -+ - /* save relevant PHY registers to private copy */ - static void at803x_context_save(struct phy_device *phydev, - struct at803x_context *context) -@@ -208,8 +256,16 @@ static int at803x_probe(struct phy_devic - return 0; - } - -+static void at803x_disable_smarteee(struct phy_device *phydev) -+{ -+ phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3, -+ 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT); -+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -+} -+ - static int at803x_config_init(struct phy_device *phydev) - { -+ struct at803x_platform_data *pdata; - int ret; - - ret = genphy_config_init(phydev); -@@ -227,6 +283,26 @@ static int at803x_config_init(struct phy - return ret; - } - -+ pdata = dev_get_platdata(&phydev->dev); -+ if (pdata) { -+ if (pdata->disable_smarteee) -+ at803x_disable_smarteee(phydev); -+ -+ if (pdata->enable_rgmii_rx_delay) -+ at803x_dbg_reg_set(phydev, AT803X_DBG0_REG, -+ AT803X_DEBUG_RGMII_RX_CLK_DLY); -+ else -+ at803x_dbg_reg_clr(phydev, AT803X_DBG0_REG, -+ AT803X_DEBUG_RGMII_RX_CLK_DLY); -+ -+ if (pdata->enable_rgmii_tx_delay) -+ at803x_dbg_reg_set(phydev, AT803X_DEBUG_SYSTEM_MODE_CTRL, -+ AT803X_DEBUG_RGMII_TX_CLK_DLY); -+ else -+ at803x_dbg_reg_clr(phydev, AT803X_DEBUG_SYSTEM_MODE_CTRL, -+ AT803X_DEBUG_RGMII_TX_CLK_DLY); -+ } -+ - return 0; - } - -@@ -258,6 +334,8 @@ static int at803x_config_intr(struct phy - static void at803x_link_change_notify(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; -+ struct at803x_platform_data *pdata; -+ pdata = dev_get_platdata(&phydev->dev); - - /* - * Conduct a hardware reset for AT8030 every time a link loss is -@@ -288,6 +366,26 @@ static void at803x_link_change_notify(st - priv->phy_reset = false; - } - } -+ if (pdata && pdata->fixup_rgmii_tx_delay && -+ phydev->speed != priv->prev_speed) { -+ switch (phydev->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ at803x_dbg_reg_set(phydev, -+ AT803X_DEBUG_SYSTEM_MODE_CTRL, -+ AT803X_DEBUG_RGMII_TX_CLK_DLY); -+ break; -+ case SPEED_1000: -+ at803x_dbg_reg_clr(phydev, -+ AT803X_DEBUG_SYSTEM_MODE_CTRL, -+ AT803X_DEBUG_RGMII_TX_CLK_DLY); -+ break; -+ default: -+ break; -+ } -+ -+ priv->prev_speed = phydev->speed; -+ } - } - - static struct phy_driver at803x_driver[] = { ---- /dev/null -+++ b/include/linux/platform_data/phy-at803x.h -@@ -0,0 +1,11 @@ -+#ifndef _PHY_AT803X_PDATA_H -+#define _PHY_AT803X_PDATA_H -+ -+struct at803x_platform_data { -+ int disable_smarteee:1; -+ int enable_rgmii_tx_delay:1; -+ int enable_rgmii_rx_delay:1; -+ int fixup_rgmii_tx_delay:1; -+}; -+ -+#endif /* _PHY_AT803X_PDATA_H */ diff --git a/target/linux/generic/pending-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch deleted file mode 100644 index 4a8f532aa3..0000000000 --- a/target/linux/generic/pending-3.18/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -36,6 +36,9 @@ - #define AT803X_INER 0x0012 - #define AT803X_INER_INIT 0xec00 - #define AT803X_INSR 0x0013 -+#define AT803X_REG_CHIP_CONFIG 0x1f -+#define AT803X_BT_BX_REG_SEL 0x8000 -+#define AT803X_SGMII_ANEG_EN 0x1000 - - #define AT803X_PCS_SMART_EEE_CTRL3 0x805D - #define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3 -@@ -49,9 +52,10 @@ - #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05 - #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8) - --#define ATH8030_PHY_ID 0x004dd076 --#define ATH8031_PHY_ID 0x004dd074 --#define ATH8035_PHY_ID 0x004dd072 -+#define AT803X_PHY_ID_MASK 0xffffffef -+#define ATH8030_PHY_ID 0x004dd076 -+#define ATH8031_PHY_ID 0x004dd074 -+#define ATH8035_PHY_ID 0x004dd072 - - MODULE_DESCRIPTION("Atheros 803x PHY driver"); - MODULE_AUTHOR("Matus Ujhelyi"); -@@ -267,6 +271,27 @@ static int at803x_config_init(struct phy - { - struct at803x_platform_data *pdata; - int ret; -+ u32 v; -+ -+ if (phydev->drv->phy_id == ATH8031_PHY_ID && -+ phydev->interface == PHY_INTERFACE_MODE_SGMII) -+ { -+ v = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ /* select SGMII/fiber page */ -+ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -+ v & ~AT803X_BT_BX_REG_SEL); -+ if (ret) -+ return ret; -+ /* enable SGMII autonegotiation */ -+ ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN); -+ if (ret) -+ return ret; -+ /* select copper page */ -+ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -+ v | AT803X_BT_BX_REG_SEL); -+ if (ret) -+ return ret; -+ } - - ret = genphy_config_init(phydev); - if (ret < 0) -@@ -393,7 +418,7 @@ static struct phy_driver at803x_driver[] - /* ATHEROS 8035 */ - .phy_id = ATH8035_PHY_ID, - .name = "Atheros 8035 ethernet", -- .phy_id_mask = 0xffffffef, -+ .phy_id_mask = AT803X_PHY_ID_MASK, - .probe = at803x_probe, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, -@@ -412,7 +437,7 @@ static struct phy_driver at803x_driver[] - /* ATHEROS 8030 */ - .phy_id = ATH8030_PHY_ID, - .name = "Atheros 8030 ethernet", -- .phy_id_mask = 0xffffffef, -+ .phy_id_mask = AT803X_PHY_ID_MASK, - .probe = at803x_probe, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, -@@ -430,8 +455,8 @@ static struct phy_driver at803x_driver[] - }, { - /* ATHEROS 8031 */ - .phy_id = ATH8031_PHY_ID, -- .name = "Atheros 8031 ethernet", -- .phy_id_mask = 0xffffffef, -+ .name = "Atheros 8031/8033 ethernet", -+ .phy_id_mask = AT803X_PHY_ID_MASK, - .probe = at803x_probe, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, -@@ -465,9 +490,9 @@ module_init(atheros_init); - module_exit(atheros_exit); - - static struct mdio_device_id __maybe_unused atheros_tbl[] = { -- { ATH8030_PHY_ID, 0xffffffef }, -- { ATH8031_PHY_ID, 0xffffffef }, -- { ATH8035_PHY_ID, 0xffffffef }, -+ { ATH8030_PHY_ID, AT803X_PHY_ID_MASK }, -+ { ATH8031_PHY_ID, AT803X_PHY_ID_MASK }, -+ { ATH8035_PHY_ID, AT803X_PHY_ID_MASK }, - { } - }; - diff --git a/target/linux/generic/pending-3.18/760-8139cp-fixes-from-4.3.patch b/target/linux/generic/pending-3.18/760-8139cp-fixes-from-4.3.patch deleted file mode 100644 index 79bbcc74e4..0000000000 --- a/target/linux/generic/pending-3.18/760-8139cp-fixes-from-4.3.patch +++ /dev/null @@ -1,365 +0,0 @@ -commit 41b976414c88016e2c9d9b2f6667ee67a998d388 -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:45:31 2015 +0100 - - 8139cp: Dump contents of descriptor ring on TX timeout - - We are seeing unexplained TX timeouts under heavy load. Let's try to get - a better idea of what's going on. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit 7f4c685633e2df9ba10d49a31dda13715745db37 -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:45:16 2015 +0100 - - 8139cp: Fix DMA unmapping of transmitted buffers - - The low 16 bits of the 'opts1' field in the TX descriptor are supposed - to still contain the buffer length when the descriptor is handed back to - us. In practice, at least on my hardware, they don't. So stash the - original value of the opts1 field and get the length to unmap from - there. - - There are other ways we could have worked out the length, but I actually - want a stash of the opts1 field anyway so that I can dump it alongside - the contents of the descriptor ring when we suffer a TX timeout. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit 0a5aeee0b79fa99d8e04c98dd4e87d4f52aa497b -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:44:57 2015 +0100 - - 8139cp: Reduce duplicate csum/tso code in cp_start_xmit() - - We calculate the value of the opts1 descriptor field in three different - places. With two different behaviours when given an invalid packet to - be checksummed — none of them correct. Sort that out. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit a3b804043f490aeec57d8ca5baccdd35e6250857 -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:44:38 2015 +0100 - - 8139cp: Fix TSO/scatter-gather descriptor setup - - When sending a TSO frame in multiple buffers, we were neglecting to set - the first descriptor up in TSO mode. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit 26b0bad6ac3a0167792dc4ffb276c29bc597d239 -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:44:06 2015 +0100 - - 8139cp: Fix tx_queued debug message to print correct slot numbers - - After a certain amount of staring at the debug output of this driver, I - realised it was lying to me. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit aaa0062ecf4877a26dea66bee1039c6eaf906c94 -Author: David Woodhouse <David.Woodhouse@intel.com> -Date: Wed Sep 23 09:43:41 2015 +0100 - - 8139cp: Do not re-enable RX interrupts in cp_tx_timeout() - - If an RX interrupt was already received but NAPI has not yet run when - the RX timeout happens, we end up in cp_tx_timeout() with RX interrupts - already disabled. Blindly re-enabling them will cause an IRQ storm. - - (This is made particularly horrid by the fact that cp_interrupt() always - returns that it's handled the interrupt, even when it hasn't actually - done anything. If it didn't do that, the core IRQ code would have - detected the storm and handled it, I'd have had a clear smoking gun - backtrace instead of just a spontaneously resetting router, and I'd have - at *least* two days of my life back. Changing the return value of - cp_interrupt() will be argued about under separate cover.) - - Unconditionally leave RX interrupts disabled after the reset, and - schedule NAPI to check the receive ring and re-enable them. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit 7a8a8e75d505147358b225173e890ada43a267e2 -Author: David Woodhouse <dwmw2@infradead.org> -Date: Fri Sep 18 00:21:54 2015 +0100 - - 8139cp: Call __cp_set_rx_mode() from cp_tx_timeout() - - Unless we reset the RX config, on real hardware I don't seem to receive - any packets after a TX timeout. - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> - -commit fc27bd115b334e3ebdc682a42a47c3aea2566dcc -Author: David Woodhouse <dwmw2@infradead.org> -Date: Fri Sep 18 00:19:08 2015 +0100 - - 8139cp: Use dev_kfree_skb_any() instead of dev_kfree_skb() in cp_clean_rings() - - This can be called from cp_tx_timeout() with interrupts disabled. - Spotted by Francois Romieu <romieu@fr.zoreil.com> - - Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> - Signed-off-by: David S. Miller <davem@davemloft.net> ---- a/drivers/net/ethernet/realtek/8139cp.c -+++ b/drivers/net/ethernet/realtek/8139cp.c -@@ -157,6 +157,7 @@ enum { - NWayAdvert = 0x66, /* MII ADVERTISE */ - NWayLPAR = 0x68, /* MII LPA */ - NWayExpansion = 0x6A, /* MII Expansion */ -+ TxDmaOkLowDesc = 0x82, /* Low 16 bit address of a Tx descriptor. */ - Config5 = 0xD8, /* Config5 */ - TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */ - RxMaxSize = 0xDA, /* Max size of an Rx packet (8169 only) */ -@@ -341,6 +342,7 @@ struct cp_private { - unsigned tx_tail; - struct cp_desc *tx_ring; - struct sk_buff *tx_skb[CP_TX_RING_SIZE]; -+ u32 tx_opts[CP_TX_RING_SIZE]; - - unsigned rx_buf_sz; - unsigned wol_enabled : 1; /* Is Wake-on-LAN enabled? */ -@@ -670,7 +672,7 @@ static void cp_tx (struct cp_private *cp - BUG_ON(!skb); - - dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr), -- le32_to_cpu(txd->opts1) & 0xffff, -+ cp->tx_opts[tx_tail] & 0xffff, - PCI_DMA_TODEVICE); - - if (status & LastFrag) { -@@ -738,7 +740,7 @@ static netdev_tx_t cp_start_xmit (struct - { - struct cp_private *cp = netdev_priv(dev); - unsigned entry; -- u32 eor, flags; -+ u32 eor, opts1; - unsigned long intr_flags; - __le32 opts2; - int mss = 0; -@@ -758,6 +760,21 @@ static netdev_tx_t cp_start_xmit (struct - mss = skb_shinfo(skb)->gso_size; - - opts2 = cpu_to_le32(cp_tx_vlan_tag(skb)); -+ opts1 = DescOwn; -+ if (mss) -+ opts1 |= LargeSend | ((mss & MSSMask) << MSSShift); -+ else if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ const struct iphdr *ip = ip_hdr(skb); -+ if (ip->protocol == IPPROTO_TCP) -+ opts1 |= IPCS | TCPCS; -+ else if (ip->protocol == IPPROTO_UDP) -+ opts1 |= IPCS | UDPCS; -+ else { -+ WARN_ONCE(1, -+ "Net bug: asked to checksum invalid Legacy IP packet\n"); -+ goto out_dma_error; -+ } -+ } - - if (skb_shinfo(skb)->nr_frags == 0) { - struct cp_desc *txd = &cp->tx_ring[entry]; -@@ -773,31 +790,20 @@ static netdev_tx_t cp_start_xmit (struct - txd->addr = cpu_to_le64(mapping); - wmb(); - -- flags = eor | len | DescOwn | FirstFrag | LastFrag; -- -- if (mss) -- flags |= LargeSend | ((mss & MSSMask) << MSSShift); -- else if (skb->ip_summed == CHECKSUM_PARTIAL) { -- const struct iphdr *ip = ip_hdr(skb); -- if (ip->protocol == IPPROTO_TCP) -- flags |= IPCS | TCPCS; -- else if (ip->protocol == IPPROTO_UDP) -- flags |= IPCS | UDPCS; -- else -- WARN_ON(1); /* we need a WARN() */ -- } -+ opts1 |= eor | len | FirstFrag | LastFrag; - -- txd->opts1 = cpu_to_le32(flags); -+ txd->opts1 = cpu_to_le32(opts1); - wmb(); - - cp->tx_skb[entry] = skb; -- entry = NEXT_TX(entry); -+ cp->tx_opts[entry] = opts1; -+ netif_dbg(cp, tx_queued, cp->dev, "tx queued, slot %d, skblen %d\n", -+ entry, skb->len); - } else { - struct cp_desc *txd; -- u32 first_len, first_eor; -+ u32 first_len, first_eor, ctrl; - dma_addr_t first_mapping; - int frag, first_entry = entry; -- const struct iphdr *ip = ip_hdr(skb); - - /* We must give this initial chunk to the device last. - * Otherwise we could race with the device. -@@ -810,14 +816,14 @@ static netdev_tx_t cp_start_xmit (struct - goto out_dma_error; - - cp->tx_skb[entry] = skb; -- entry = NEXT_TX(entry); - - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; - u32 len; -- u32 ctrl; - dma_addr_t mapping; - -+ entry = NEXT_TX(entry); -+ - len = skb_frag_size(this_frag); - mapping = dma_map_single(&cp->pdev->dev, - skb_frag_address(this_frag), -@@ -829,19 +835,7 @@ static netdev_tx_t cp_start_xmit (struct - - eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; - -- ctrl = eor | len | DescOwn; -- -- if (mss) -- ctrl |= LargeSend | -- ((mss & MSSMask) << MSSShift); -- else if (skb->ip_summed == CHECKSUM_PARTIAL) { -- if (ip->protocol == IPPROTO_TCP) -- ctrl |= IPCS | TCPCS; -- else if (ip->protocol == IPPROTO_UDP) -- ctrl |= IPCS | UDPCS; -- else -- BUG(); -- } -+ ctrl = opts1 | eor | len; - - if (frag == skb_shinfo(skb)->nr_frags - 1) - ctrl |= LastFrag; -@@ -854,8 +848,8 @@ static netdev_tx_t cp_start_xmit (struct - txd->opts1 = cpu_to_le32(ctrl); - wmb(); - -+ cp->tx_opts[entry] = ctrl; - cp->tx_skb[entry] = skb; -- entry = NEXT_TX(entry); - } - - txd = &cp->tx_ring[first_entry]; -@@ -863,27 +857,17 @@ static netdev_tx_t cp_start_xmit (struct - txd->addr = cpu_to_le64(first_mapping); - wmb(); - -- if (skb->ip_summed == CHECKSUM_PARTIAL) { -- if (ip->protocol == IPPROTO_TCP) -- txd->opts1 = cpu_to_le32(first_eor | first_len | -- FirstFrag | DescOwn | -- IPCS | TCPCS); -- else if (ip->protocol == IPPROTO_UDP) -- txd->opts1 = cpu_to_le32(first_eor | first_len | -- FirstFrag | DescOwn | -- IPCS | UDPCS); -- else -- BUG(); -- } else -- txd->opts1 = cpu_to_le32(first_eor | first_len | -- FirstFrag | DescOwn); -+ ctrl = opts1 | first_eor | first_len | FirstFrag; -+ txd->opts1 = cpu_to_le32(ctrl); - wmb(); -+ -+ cp->tx_opts[first_entry] = ctrl; -+ netif_dbg(cp, tx_queued, cp->dev, "tx queued, slots %d-%d, skblen %d\n", -+ first_entry, entry, skb->len); - } -- cp->tx_head = entry; -+ cp->tx_head = NEXT_TX(entry); - - netdev_sent_queue(dev, skb->len); -- netif_dbg(cp, tx_queued, cp->dev, "tx queued, slot %d, skblen %d\n", -- entry, skb->len); - if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1)) - netif_stop_queue(dev); - -@@ -1120,6 +1104,7 @@ static int cp_init_rings (struct cp_priv - { - memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); - cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd); -+ memset(cp->tx_opts, 0, sizeof(cp->tx_opts)); - - cp_init_rings_index(cp); - -@@ -1156,7 +1141,7 @@ static void cp_clean_rings (struct cp_pr - desc = cp->rx_ring + i; - dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr), - cp->rx_buf_sz, PCI_DMA_FROMDEVICE); -- dev_kfree_skb(cp->rx_skb[i]); -+ dev_kfree_skb_any(cp->rx_skb[i]); - } - } - -@@ -1169,7 +1154,7 @@ static void cp_clean_rings (struct cp_pr - le32_to_cpu(desc->opts1) & 0xffff, - PCI_DMA_TODEVICE); - if (le32_to_cpu(desc->opts1) & LastFrag) -- dev_kfree_skb(skb); -+ dev_kfree_skb_any(skb); - cp->dev->stats.tx_dropped++; - } - } -@@ -1177,6 +1162,7 @@ static void cp_clean_rings (struct cp_pr - - memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); - memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); -+ memset(cp->tx_opts, 0, sizeof(cp->tx_opts)); - - memset(cp->rx_skb, 0, sizeof(struct sk_buff *) * CP_RX_RING_SIZE); - memset(cp->tx_skb, 0, sizeof(struct sk_buff *) * CP_TX_RING_SIZE); -@@ -1254,7 +1240,7 @@ static void cp_tx_timeout(struct net_dev - { - struct cp_private *cp = netdev_priv(dev); - unsigned long flags; -- int rc; -+ int rc, i; - - netdev_warn(dev, "Transmit timeout, status %2x %4x %4x %4x\n", - cpr8(Cmd), cpr16(CpCmd), -@@ -1262,13 +1248,26 @@ static void cp_tx_timeout(struct net_dev - - spin_lock_irqsave(&cp->lock, flags); - -+ netif_dbg(cp, tx_err, cp->dev, "TX ring head %d tail %d desc %x\n", -+ cp->tx_head, cp->tx_tail, cpr16(TxDmaOkLowDesc)); -+ for (i = 0; i < CP_TX_RING_SIZE; i++) { -+ netif_dbg(cp, tx_err, cp->dev, -+ "TX slot %d @%p: %08x (%08x) %08x %llx %p\n", -+ i, &cp->tx_ring[i], le32_to_cpu(cp->tx_ring[i].opts1), -+ cp->tx_opts[i], le32_to_cpu(cp->tx_ring[i].opts2), -+ le64_to_cpu(cp->tx_ring[i].addr), -+ cp->tx_skb[i]); -+ } -+ - cp_stop_hw(cp); - cp_clean_rings(cp); - rc = cp_init_rings(cp); - cp_start_hw(cp); -- cp_enable_irq(cp); -+ __cp_set_rx_mode(dev); -+ cpw16_f(IntrMask, cp_norx_intr_mask); - - netif_wake_queue(dev); -+ napi_schedule(&cp->napi); - - spin_unlock_irqrestore(&cp->lock, flags); - } diff --git a/target/linux/generic/pending-3.18/773-bgmac-add-srab-switch.patch b/target/linux/generic/pending-3.18/773-bgmac-add-srab-switch.patch deleted file mode 100644 index a93877b69e..0000000000 --- a/target/linux/generic/pending-3.18/773-bgmac-add-srab-switch.patch +++ /dev/null @@ -1,72 +0,0 @@ -Register switch connected to srab - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> - ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -17,6 +17,7 @@ - #include <linux/phy_fixed.h> - #include <linux/interrupt.h> - #include <linux/dma-mapping.h> -+#include <linux/platform_data/b53.h> - #include <bcm47xx_nvram.h> - - static const struct bcma_device_id bgmac_bcma_tbl[] = { -@@ -1538,6 +1539,17 @@ static void bgmac_mii_unregister(struct - mdiobus_free(mii_bus); - } - -+static struct b53_platform_data bgmac_b53_pdata = { -+}; -+ -+static struct platform_device bgmac_b53_dev = { -+ .name = "b53-srab-switch", -+ .id = -1, -+ .dev = { -+ .platform_data = &bgmac_b53_pdata, -+ }, -+}; -+ - /************************************************** - * BCMA bus ops - **************************************************/ -@@ -1671,6 +1683,16 @@ static int bgmac_probe(struct bcma_devic - net_dev->hw_features = net_dev->features; - net_dev->vlan_features = net_dev->features; - -+ if ((ci->id == BCMA_CHIP_ID_BCM4707 || -+ ci->id == BCMA_CHIP_ID_BCM53018) && -+ !bgmac_b53_pdata.regs) { -+ bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000); -+ -+ err = platform_device_register(&bgmac_b53_dev); -+ if (!err) -+ bgmac->b53_device = &bgmac_b53_dev; -+ } -+ - err = register_netdev(bgmac->net_dev); - if (err) { - bgmac_err(bgmac, "Cannot register net device\n"); -@@ -1697,6 +1719,10 @@ static void bgmac_remove(struct bcma_dev - { - struct bgmac *bgmac = bcma_get_drvdata(core); - -+ if (bgmac->b53_device) -+ platform_device_unregister(&bgmac_b53_dev); -+ bgmac->b53_device = NULL; -+ - unregister_netdev(bgmac->net_dev); - bgmac_mii_unregister(bgmac); - netif_napi_del(&bgmac->napi); ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -462,6 +462,9 @@ struct bgmac { - bool has_robosw; - - bool loopback; -+ -+ /* platform device for associated switch */ -+ struct platform_device *b53_device; - }; - - static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset) diff --git a/target/linux/generic/pending-3.18/785-hso-support-0af0-9300.patch b/target/linux/generic/pending-3.18/785-hso-support-0af0-9300.patch deleted file mode 100644 index 50bccc4df5..0000000000 --- a/target/linux/generic/pending-3.18/785-hso-support-0af0-9300.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/drivers/net/usb/hso.c -+++ b/drivers/net/usb/hso.c -@@ -468,6 +468,7 @@ static const struct usb_device_id hso_id - {USB_DEVICE(0x0af0, 0x8900)}, - {USB_DEVICE(0x0af0, 0x9000)}, - {USB_DEVICE(0x0af0, 0x9200)}, /* Option GTM671WFS */ -+ {USB_DEVICE(0x0af0, 0x9300)}, /* GTM 66xxWFS */ - {USB_DEVICE(0x0af0, 0xd035)}, - {USB_DEVICE(0x0af0, 0xd055)}, - {USB_DEVICE(0x0af0, 0xd155)}, ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -1330,6 +1330,12 @@ UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0 - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - 0 ), - -+UNUSUAL_DEV( 0x0af0, 0x9300, 0x0000, 0x0000, -+ "Option", -+ "Globetrotter 66xxWFS SD-Card", -+ USB_SC_DEVICE, USB_PR_DEVICE, NULL, -+ 0 ), -+ - UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000, - "Option", - "GI 070x SD-Card", diff --git a/target/linux/generic/pending-3.18/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-3.18/810-pci_disable_common_quirks.patch deleted file mode 100644 index 5155bcdadf..0000000000 --- a/target/linux/generic/pending-3.18/810-pci_disable_common_quirks.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -58,6 +58,12 @@ config XEN_PCIDEV_FRONTEND - The PCI device frontend driver allows the kernel to import arbitrary - PCI devices from a PCI backend to support PCI driver domains. - -+config PCI_DISABLE_COMMON_QUIRKS -+ bool "PCI disable common quirks" -+ depends on PCI -+ help -+ If you don't know what to do here, say N. -+ - config HT_IRQ - bool "Interrupts on hypertransport devices" - default y ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -41,6 +41,7 @@ static void quirk_mmio_always_on(struct - DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - /* The Mellanox Tavor device gives false positive parity errors - * Mark this device with a broken_parity_status, to allow - * PCI scanning code to "skip" this now blacklisted device. -@@ -2929,6 +2930,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ - - /* - * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. To -@@ -2985,6 +2987,8 @@ static void fixup_debug_report(struct pc - } - } - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - /* - * Some BIOS implementations leave the Intel GPU interrupts enabled, - * even though no one is handling them (f.e. i915 driver is never loaded). -@@ -3019,6 +3023,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * PCI devices which are on Intel chips can skip the 10ms delay - * before entering D3 mode. diff --git a/target/linux/generic/pending-3.18/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-3.18/811-pci_disable_usb_common_quirks.patch deleted file mode 100644 index ddc8549634..0000000000 --- a/target/linux/generic/pending-3.18/811-pci_disable_usb_common_quirks.patch +++ /dev/null @@ -1,101 +0,0 @@ - ---- a/drivers/usb/host/pci-quirks.c -+++ b/drivers/usb/host/pci-quirks.c -@@ -98,6 +98,8 @@ struct amd_chipset_type { - u8 rev; - }; - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static struct amd_chipset_info { - struct pci_dev *nb_dev; - struct pci_dev *smbus_dev; -@@ -462,6 +464,10 @@ void usb_amd_dev_put(void) - } - EXPORT_SYMBOL_GPL(usb_amd_dev_put); - -+#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ -+#if IS_ENABLED(CONFIG_USB_UHCI_HCD) -+ - /* - * Make sure the controller is completely inactive, unable to - * generate interrupts or do DMA. -@@ -541,8 +547,17 @@ reset_needed: - uhci_reset_hc(pdev, base); - return 1; - } -+#else -+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) -+{ -+ return 0; -+} -+ -+#endif - EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) - { - u16 cmd; -@@ -1103,3 +1118,4 @@ static void quirk_usb_early_handoff(stru - } - DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); -+#endif ---- a/drivers/usb/host/pci-quirks.h -+++ b/drivers/usb/host/pci-quirks.h -@@ -4,6 +4,9 @@ - #ifdef CONFIG_PCI - void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); - int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -+#endif /* CONFIG_PCI */ -+ -+#if defined(CONFIG_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) - int usb_amd_find_chipset_info(void); - int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); - bool usb_amd_hang_symptom_quirk(void); -@@ -16,11 +19,24 @@ void usb_disable_xhci_ports(struct pci_d - void sb800_prefetch(struct device *dev, int on); - #else - struct pci_dev; -+static inline int usb_amd_find_chipset_info(void) -+{ -+ return 0; -+} -+static inline bool usb_amd_hang_symptom_quirk(void) -+{ -+ return false; -+} -+static inline bool usb_amd_prefetch_quirk(void) -+{ -+ return false; -+} - static inline void usb_amd_quirk_pll_disable(void) {} - static inline void usb_amd_quirk_pll_enable(void) {} - static inline void usb_amd_dev_put(void) {} - static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} - static inline void sb800_prefetch(struct device *dev, int on) {} --#endif /* CONFIG_PCI */ -+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} -+#endif - - #endif /* __LINUX_USB_PCI_QUIRKS_H */ ---- a/include/linux/usb/hcd.h -+++ b/include/linux/usb/hcd.h -@@ -445,7 +445,14 @@ extern int usb_hcd_pci_probe(struct pci_ - extern void usb_hcd_pci_remove(struct pci_dev *dev); - extern void usb_hcd_pci_shutdown(struct pci_dev *dev); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); -+#else -+static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev) -+{ -+ return 0; -+} -+#endif - - #ifdef CONFIG_PM - extern const struct dev_pm_ops usb_hcd_pci_pm_ops; diff --git a/target/linux/generic/pending-3.18/821-usb-dwc2-dualrole.patch b/target/linux/generic/pending-3.18/821-usb-dwc2-dualrole.patch deleted file mode 100644 index 9e841cb642..0000000000 --- a/target/linux/generic/pending-3.18/821-usb-dwc2-dualrole.patch +++ /dev/null @@ -1,146 +0,0 @@ ---- a/drivers/usb/dwc2/Kconfig -+++ b/drivers/usb/dwc2/Kconfig -@@ -1,6 +1,6 @@ - config USB_DWC2 -- bool "DesignWare USB2 DRD Core Support" -- depends on USB -+ tristate "DesignWare USB2 DRD Core Support" -+ depends on USB || USB_GADGET - help - Say Y here if your system has a Dual Role Hi-Speed USB - controller based on the DesignWare HSOTG IP Core. -@@ -10,49 +10,61 @@ config USB_DWC2 - bus interface module (if you have a PCI bus system) will be - called dwc2_pci.ko, and the platform interface module (for - controllers directly connected to the CPU) will be called -- dwc2_platform.ko. For gadget mode, there will be a single -- module called dwc2_gadget.ko. -- -- NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The -- host and gadget drivers are still currently separate drivers. -- There are plans to merge the dwc2_gadget driver with the dwc2 -- host driver in the near future to create a dual-role driver. -+ dwc2_platform.ko. For all modes(host, gadget and dual-role), there -+ will be an additional module named dwc2.ko. - - if USB_DWC2 - -+choice -+ bool "DWC2 Mode Selection" -+ default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET) -+ default USB_DWC2_HOST if (USB && !USB_GADGET) -+ default USB_DWC2_PERIPHERAL if (!USB && USB_GADGET) -+ - config USB_DWC2_HOST -- tristate "Host only mode" -+ bool "Host only mode" - depends on USB - help - The Designware USB2.0 high-speed host controller -- integrated into many SoCs. -+ integrated into many SoCs. Select this option if you want the -+ driver to operate in Host-only mode. - --config USB_DWC2_PLATFORM -- bool "DWC2 Platform" -- depends on USB_DWC2_HOST -- default USB_DWC2_HOST -+comment "Gadget/Dual-role mode requires USB Gadget support to be enabled" -+ -+config USB_DWC2_PERIPHERAL -+ bool "Gadget only mode" -+ depends on USB_GADGET=y || USB_GADGET=USB_DWC2 -+ help -+ The Designware USB2.0 high-speed gadget controller -+ integrated into many SoCs. Select this option if you want the -+ driver to operate in Peripheral-only mode. This option requires -+ USB_GADGET to be enabled. -+ -+config USB_DWC2_DUAL_ROLE -+ bool "Dual Role mode" -+ depends on (USB=y || USB=USB_DWC2) && (USB_GADGET=y || USB_GADGET=USB_DWC2) - help -- The Designware USB2.0 platform interface module for -- controllers directly connected to the CPU. This is only -- used for host mode. -+ Select this option if you want the driver to work in a dual-role -+ mode. In this mode both host and gadget features are enabled, and -+ the role will be determined by the cable that gets plugged-in. This -+ option requires USB_GADGET to be enabled. -+endchoice -+ -+config USB_DWC2_PLATFORM -+ tristate "DWC2 Platform" -+ default USB_DWC2_HOST || USB_DWC2_PERIPHERAL -+ help -+ The Designware USB2.0 platform interface module for -+ controllers directly connected to the CPU. - - config USB_DWC2_PCI -- bool "DWC2 PCI" -+ tristate "DWC2 PCI" - depends on USB_DWC2_HOST && PCI - default USB_DWC2_HOST - help - The Designware USB2.0 PCI interface module for controllers - connected to a PCI bus. This is only used for host mode. - --comment "Gadget mode requires USB Gadget support to be enabled" -- --config USB_DWC2_PERIPHERAL -- tristate "Gadget only mode" -- depends on USB_GADGET -- help -- The Designware USB2.0 high-speed gadget controller -- integrated into many SoCs. -- - config USB_DWC2_DEBUG - bool "Enable Debugging Messages" - help ---- a/drivers/usb/dwc2/Makefile -+++ b/drivers/usb/dwc2/Makefile -@@ -1,28 +1,28 @@ - ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG - ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG - --obj-$(CONFIG_USB_DWC2_HOST) += dwc2.o -+obj-$(CONFIG_USB_DWC2) += dwc2.o - dwc2-y := core.o core_intr.o --dwc2-y += hcd.o hcd_intr.o --dwc2-y += hcd_queue.o hcd_ddma.o -+ -+ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) -+ dwc2-y += hcd.o hcd_intr.o -+ dwc2-y += hcd_queue.o hcd_ddma.o -+endif -+ -+ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),) -+ dwc2-y += gadget.o -+endif - - # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to - # this location and renamed gadget.c. When building for dynamically linked --# modules, dwc2_gadget.ko will get built for peripheral mode. For host mode, --# the core module will be dwc2.ko, the PCI bus interface module will called --# dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. --# At present the host and gadget driver will be separate drivers, but there --# are plans in the near future to create a dual-role driver. -+# modules, dwc2.ko will get built for host mode, peripheral mode, and dual-role -+# mode. The PCI bus interface module will called dwc2_pci.ko and the platform -+# interface module will be called dwc2_platform.ko. - - ifneq ($(CONFIG_USB_DWC2_PCI),) -- obj-$(CONFIG_USB_DWC2_HOST) += dwc2_pci.o -+ obj-$(CONFIG_USB_DWC2) += dwc2_pci.o - dwc2_pci-y := pci.o - endif - --ifneq ($(CONFIG_USB_DWC2_PLATFORM),) -- obj-$(CONFIG_USB_DWC2_HOST) += dwc2_platform.o -- dwc2_platform-y := platform.o --endif -- --obj-$(CONFIG_USB_DWC2_PERIPHERAL) += dwc2_gadget.o --dwc2_gadget-y := gadget.o -+obj-$(CONFIG_USB_DWC2_PLATFORM) += dwc2_platform.o -+dwc2_platform-y := platform.o diff --git a/target/linux/generic/pending-3.18/834-ledtrig-libata.patch b/target/linux/generic/pending-3.18/834-ledtrig-libata.patch deleted file mode 100644 index b956dedcce..0000000000 --- a/target/linux/generic/pending-3.18/834-ledtrig-libata.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 52cfd51cdf6a6e14d4fb270c6343abac3bac00f4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle <daniel@makrotopia.org> -Date: Fri, 12 Dec 2014 13:38:33 +0100 -Subject: [PATCH] libata: add ledtrig support -To: linux-ide@vger.kernel.org, - Tejun Heo <tj@kernel.org> - -This adds a LED trigger for each ATA port indicating disk activity. - -As this is needed only on specific platforms (NAS SoCs and such), -these platforms should define ARCH_WANTS_LIBATA_LEDS if there -are boards with LED(s) intended to indicate ATA disk activity and -need the OS to take care of that. -In that way, if not selected, LED trigger support not will be -included in libata-core and both, codepaths and structures remain -untouched. - -Signed-off-by: Daniel Golle <daniel@makrotopia.org> ---- - drivers/ata/Kconfig | 16 ++++++++++++++++ - drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++ - include/linux/libata.h | 9 +++++++++ - 3 files changed, 66 insertions(+) - ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR - - If unsure, say Y. - -+config ARCH_WANT_LIBATA_LEDS -+ bool -+ -+config ATA_LEDS -+ bool "support ATA port LED triggers" -+ depends on ARCH_WANT_LIBATA_LEDS -+ select NEW_LEDS -+ select LEDS_CLASS -+ select LEDS_TRIGGERS -+ default y -+ help -+ This option adds a LED trigger for each registered ATA port. -+ It is used to drive disk activity leds connected via GPIO. -+ -+ If unsure, say N. -+ - config ATA_ACPI - bool "ATA ACPI Support" - depends on ACPI && PCI ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -725,6 +725,19 @@ u64 ata_tf_read_block(struct ata_taskfil - return block; - } - -+#ifdef CONFIG_ATA_LEDS -+#define LIBATA_BLINK_DELAY 20 /* ms */ -+static inline void ata_led_act(struct ata_port *ap) -+{ -+ unsigned long led_delay = LIBATA_BLINK_DELAY; -+ -+ if (unlikely(!ap->ledtrig)) -+ return; -+ -+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); -+} -+#endif -+ - /** - * ata_build_rw_tf - Build ATA taskfile for given read/write request - * @tf: Target ATA taskfile -@@ -4828,6 +4841,9 @@ static struct ata_queued_cmd *ata_qc_new - break; - } - } -+#ifdef CONFIG_ATA_LEDS -+ ata_led_act(ap); -+#endif - - return qc; - } -@@ -5737,6 +5753,9 @@ struct ata_port *ata_port_alloc(struct a - ap->stats.unhandled_irq = 1; - ap->stats.idle_irq = 1; - #endif -+#ifdef CONFIG_ATA_LEDS -+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -+#endif - ata_sff_port_init(ap); - - return ap; -@@ -5758,6 +5777,12 @@ static void ata_host_release(struct devi - - kfree(ap->pmp_link); - kfree(ap->slave_link); -+#ifdef CONFIG_ATA_LEDS -+ if (ap->ledtrig) { -+ led_trigger_unregister(ap->ledtrig); -+ kfree(ap->ledtrig); -+ }; -+#endif - kfree(ap); - host->ports[i] = NULL; - } -@@ -6204,7 +6229,23 @@ int ata_host_register(struct ata_host *h - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); - host->ports[i]->local_port_no = i + 1; - } -+#ifdef CONFIG_ATA_LEDS -+ for (i = 0; i < host->n_ports; i++) { -+ if (unlikely(!host->ports[i]->ledtrig)) -+ continue; - -+ snprintf(host->ports[i]->ledtrig_name, -+ sizeof(host->ports[i]->ledtrig_name), "ata%u", -+ host->ports[i]->print_id); -+ -+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; -+ -+ if (led_trigger_register(host->ports[i]->ledtrig)) { -+ kfree(host->ports[i]->ledtrig); -+ host->ports[i]->ledtrig = NULL; -+ } -+ } -+#endif - /* Create associated sysfs transport objects */ - for (i = 0; i < host->n_ports; i++) { - rc = ata_tport_add(host->dev,host->ports[i]); ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -38,6 +38,9 @@ - #include <linux/acpi.h> - #include <linux/cdrom.h> - #include <linux/sched.h> -+#ifdef CONFIG_ATA_LEDS -+#include <linux/leds.h> -+#endif - - /* - * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -874,6 +877,12 @@ struct ata_port { - #ifdef CONFIG_ATA_ACPI - struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ - #endif -+ -+#ifdef CONFIG_ATA_LEDS -+ struct led_trigger *ledtrig; -+ char ledtrig_name[8]; -+#endif -+ - /* owned by EH */ - u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; - }; diff --git a/target/linux/generic/pending-3.18/840-rtc7301.patch b/target/linux/generic/pending-3.18/840-rtc7301.patch deleted file mode 100644 index 2134d87476..0000000000 --- a/target/linux/generic/pending-3.18/840-rtc7301.patch +++ /dev/null @@ -1,250 +0,0 @@ ---- a/drivers/rtc/Kconfig -+++ b/drivers/rtc/Kconfig -@@ -979,6 +979,15 @@ config RTC_DRV_NUC900 - If you say yes here you get support for the RTC subsystem of the - NUC910/NUC920 used in embedded systems. - -+config RTC_DRV_RTC7301 -+ tristate "Epson RTC-7301 SF/DG" -+ help -+ If you say Y here you will get support for the -+ Epson RTC-7301 SF/DG RTC chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-7301. -+ - comment "on-CPU RTC drivers" - - config RTC_DRV_DAVINCI ---- a/drivers/rtc/Makefile -+++ b/drivers/rtc/Makefile -@@ -115,6 +115,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c - obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o - obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o - obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o -+obj-$(CONFIG_RTC_DRV_RTC7301) += rtc-rtc7301.o - obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o - obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o - obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o ---- /dev/null -+++ b/drivers/rtc/rtc-rtc7301.c -@@ -0,0 +1,219 @@ -+/* -+ * Driver for Epson RTC-7301SF/DG -+ * -+ * Copyright (C) 2009 Jose Vasconcellos -+ * -+ * 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/module.h> -+#include <linux/rtc.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/delay.h> -+#include <linux/bcd.h> -+ -+#define RTC_NAME "rtc7301" -+#define RTC_VERSION "0.1" -+ -+/* Epson RTC-7301 register addresses */ -+#define RTC7301_SEC 0x00 -+#define RTC7301_SEC10 0x01 -+#define RTC7301_MIN 0x02 -+#define RTC7301_MIN10 0x03 -+#define RTC7301_HOUR 0x04 -+#define RTC7301_HOUR10 0x05 -+#define RTC7301_WEEKDAY 0x06 -+#define RTC7301_DAY 0x07 -+#define RTC7301_DAY10 0x08 -+#define RTC7301_MON 0x09 -+#define RTC7301_MON10 0x0A -+#define RTC7301_YEAR 0x0B -+#define RTC7301_YEAR10 0x0C -+#define RTC7301_YEAR100 0x0D -+#define RTC7301_YEAR1000 0x0E -+#define RTC7301_CTRLREG 0x0F -+ -+static uint8_t __iomem *rtc7301_base; -+ -+#define read_reg(offset) (readb(rtc7301_base + offset) & 0xf) -+#define write_reg(offset, data) writeb(data, rtc7301_base + (offset)) -+ -+#define rtc7301_isbusy() (read_reg(RTC7301_CTRLREG) & 1) -+ -+static void rtc7301_init_settings(void) -+{ -+ int i; -+ -+ write_reg(RTC7301_CTRLREG, 2); -+ write_reg(RTC7301_YEAR1000, 2); -+ udelay(122); -+ -+ /* bank 1 */ -+ write_reg(RTC7301_CTRLREG, 6); -+ for (i=0; i<15; i++) -+ write_reg(i, 0); -+ -+ /* bank 2 */ -+ write_reg(RTC7301_CTRLREG, 14); -+ for (i=0; i<15; i++) -+ write_reg(i, 0); -+ write_reg(RTC7301_CTRLREG, 0); -+} -+ -+static int rtc7301_get_datetime(struct device *dev, struct rtc_time *dt) -+{ -+ int cnt; -+ uint8_t buf[16]; -+ -+ cnt = 0; -+ while (rtc7301_isbusy()) { -+ udelay(244); -+ if (cnt++ > 100) { -+ dev_err(dev, "%s: timeout error %x\n", __func__, rtc7301_base[RTC7301_CTRLREG]); -+ return -EIO; -+ } -+ } -+ -+ for (cnt=0; cnt<16; cnt++) -+ buf[cnt] = read_reg(cnt); -+ -+ if (buf[RTC7301_SEC10] & 8) { -+ dev_err(dev, "%s: RTC not set\n", __func__); -+ return -EINVAL; -+ } -+ -+ memset(dt, 0, sizeof(*dt)); -+ -+ dt->tm_sec = buf[RTC7301_SEC] + buf[RTC7301_SEC10]*10; -+ dt->tm_min = buf[RTC7301_MIN] + buf[RTC7301_MIN10]*10; -+ dt->tm_hour = buf[RTC7301_HOUR] + buf[RTC7301_HOUR10]*10; -+ -+ dt->tm_mday = buf[RTC7301_DAY] + buf[RTC7301_DAY10]*10; -+ dt->tm_mon = buf[RTC7301_MON] + buf[RTC7301_MON10]*10 - 1; -+ dt->tm_year = buf[RTC7301_YEAR] + buf[RTC7301_YEAR10]*10 + -+ buf[RTC7301_YEAR100]*100 + -+ ((buf[RTC7301_YEAR1000] & 3)*1000) - 1900; -+ -+ /* the rtc device may contain illegal values on power up -+ * according to the data sheet. make sure they are valid. -+ */ -+ -+ return rtc_valid_tm(dt); -+} -+ -+static int rtc7301_set_datetime(struct device *dev, struct rtc_time *dt) -+{ -+ int data; -+ -+ data = dt->tm_year + 1900; -+ if (data >= 2100 || data < 1900) -+ return -EINVAL; -+ -+ write_reg(RTC7301_CTRLREG, 2); -+ udelay(122); -+ -+ data = bin2bcd(dt->tm_sec); -+ write_reg(RTC7301_SEC, data); -+ write_reg(RTC7301_SEC10, (data >> 4)); -+ -+ data = bin2bcd(dt->tm_min); -+ write_reg(RTC7301_MIN, data ); -+ write_reg(RTC7301_MIN10, (data >> 4)); -+ -+ data = bin2bcd(dt->tm_hour); -+ write_reg(RTC7301_HOUR, data); -+ write_reg(RTC7301_HOUR10, (data >> 4)); -+ -+ data = bin2bcd(dt->tm_mday); -+ write_reg(RTC7301_DAY, data); -+ write_reg(RTC7301_DAY10, (data>> 4)); -+ -+ data = bin2bcd(dt->tm_mon + 1); -+ write_reg(RTC7301_MON, data); -+ write_reg(RTC7301_MON10, (data >> 4)); -+ -+ data = bin2bcd(dt->tm_year % 100); -+ write_reg(RTC7301_YEAR, data); -+ write_reg(RTC7301_YEAR10, (data >> 4)); -+ data = bin2bcd((1900 + dt->tm_year) / 100); -+ write_reg(RTC7301_YEAR100, data); -+ -+ data = bin2bcd(dt->tm_wday); -+ write_reg(RTC7301_WEEKDAY, data); -+ -+ write_reg(RTC7301_CTRLREG, 0); -+ -+ return 0; -+} -+ -+static const struct rtc_class_ops rtc7301_rtc_ops = { -+ .read_time = rtc7301_get_datetime, -+ .set_time = rtc7301_set_datetime, -+}; -+ -+static int rtc7301_probe(struct platform_device *pdev) -+{ -+ struct rtc_device *rtc; -+ struct resource *res; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENOENT; -+ -+ rtc7301_base = ioremap_nocache(res->start, 0x1000 /*res->end - res->start + 1*/); -+ if (!rtc7301_base) -+ return -EINVAL; -+ -+ rtc = rtc_device_register(RTC_NAME, &pdev->dev, -+ &rtc7301_rtc_ops, THIS_MODULE); -+ if (IS_ERR(rtc)) { -+ iounmap(rtc7301_base); -+ return PTR_ERR(rtc); -+ } -+ -+ platform_set_drvdata(pdev, rtc); -+ -+ rtc7301_init_settings(); -+ return 0; -+} -+ -+static int rtc7301_remove(struct platform_device *pdev) -+{ -+ struct rtc_device *rtc = platform_get_drvdata(pdev); -+ -+ if (rtc) -+ rtc_device_unregister(rtc); -+ if (rtc7301_base) -+ iounmap(rtc7301_base); -+ return 0; -+} -+ -+static struct platform_driver rtc7301_driver = { -+ .driver = { -+ .name = RTC_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = rtc7301_probe, -+ .remove = rtc7301_remove, -+}; -+ -+static __init int rtc7301_init(void) -+{ -+ return platform_driver_register(&rtc7301_driver); -+} -+module_init(rtc7301_init); -+ -+static __exit void rtc7301_exit(void) -+{ -+ platform_driver_unregister(&rtc7301_driver); -+} -+module_exit(rtc7301_exit); -+ -+MODULE_DESCRIPTION("Epson 7301 RTC driver"); -+MODULE_AUTHOR("Jose Vasconcellos <jvasco@verizon.net>"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:" RTC_NAME); -+MODULE_VERSION(RTC_VERSION); diff --git a/target/linux/generic/pending-3.18/841-rtc_pt7c4338.patch b/target/linux/generic/pending-3.18/841-rtc_pt7c4338.patch deleted file mode 100644 index 83b0232e13..0000000000 --- a/target/linux/generic/pending-3.18/841-rtc_pt7c4338.patch +++ /dev/null @@ -1,247 +0,0 @@ ---- a/drivers/rtc/Kconfig -+++ b/drivers/rtc/Kconfig -@@ -567,6 +567,15 @@ config RTC_DRV_S5M - This driver can also be built as a module. If so, the module - will be called rtc-s5m. - -+config RTC_DRV_PT7C4338 -+ tristate "Pericom Technology Inc. PT7C4338 RTC" -+ help -+ If you say yes here you get support for the Pericom Technology -+ Inc. PT7C4338 RTC chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-pt7c4338. -+ - endif # I2C - - comment "SPI RTC drivers" ---- a/drivers/rtc/Makefile -+++ b/drivers/rtc/Makefile -@@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030 - obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o - obj-$(CONFIG_RTC_DRV_PM8XXX) += rtc-pm8xxx.o - obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o -+obj-$(CONFIG_RTC_DRV_PT7C4338) += rtc-pt7c4338.o - obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o - obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o - obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o ---- /dev/null -+++ b/drivers/rtc/rtc-pt7c4338.c -@@ -0,0 +1,216 @@ -+/* -+ * Copyright 2010 Freescale Semiconductor, Inc. -+ * -+ * Author: Priyanka Jain <Priyanka.Jain@freescale.com> -+ * -+ * See file CREDITS for list of people who contributed to this -+ * project. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+/* -+ * This file provides Date & Time support (no alarms) for PT7C4338 chip. -+ * -+ * This file is based on drivers/rtc/rtc-ds1307.c -+ * -+ * PT7C4338 chip is manufactured by Pericom Technology Inc. -+ * It is a serial real-time clock which provides -+ * 1)Low-power clock/calendar. -+ * 2)Programmable square-wave output. -+ * It has 56 bytes of nonvolatile RAM. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/rtc.h> -+#include <linux/bcd.h> -+ -+/* RTC register addresses */ -+#define PT7C4338_REG_SECONDS 0x00 -+#define PT7C4338_REG_MINUTES 0x01 -+#define PT7C4338_REG_HOURS 0x02 -+#define PT7C4338_REG_AMPM 0x02 -+#define PT7C4338_REG_DAY 0x03 -+#define PT7C4338_REG_DATE 0x04 -+#define PT7C4338_REG_MONTH 0x05 -+#define PT7C4338_REG_YEAR 0x06 -+#define PT7C4338_REG_CTRL_STAT 0x07 -+ -+/* RTC second register address bit */ -+#define PT7C4338_SEC_BIT_CH 0x80 /*Clock Halt (in Register 0)*/ -+ -+/* RTC control and status register bits */ -+#define PT7C4338_CTRL_STAT_BIT_RS0 0x1 /*Rate select 0*/ -+#define PT7C4338_CTRL_STAT_BIT_RS1 0x2 /*Rate select 1*/ -+#define PT7C4338_CTRL_STAT_BIT_SQWE 0x10 /*Square Wave Enable*/ -+#define PT7C4338_CTRL_STAT_BIT_OSF 0x20 /*Oscillator Stop Flag*/ -+#define PT7C4338_CTRL_STAT_BIT_OUT 0x80 /*Output Level Control*/ -+ -+static const struct i2c_device_id pt7c4338_id[] = { -+ { "pt7c4338", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, pt7c4338_id); -+ -+struct pt7c4338{ -+ struct i2c_client *client; -+ struct rtc_device *rtc; -+}; -+ -+static int pt7c4338_read_time(struct device *dev, struct rtc_time *time) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int ret; -+ u8 buf[7]; -+ u8 year, month, day, hour, minute, second; -+ u8 week, twelve_hr, am_pm; -+ -+ ret = i2c_smbus_read_i2c_block_data(client, -+ PT7C4338_REG_SECONDS, 7, buf); -+ if (ret < 0) -+ return ret; -+ if (ret < 7) -+ return -EIO; -+ -+ second = buf[0]; -+ minute = buf[1]; -+ hour = buf[2]; -+ week = buf[3]; -+ day = buf[4]; -+ month = buf[5]; -+ year = buf[6]; -+ -+ /* Extract additional information for AM/PM */ -+ twelve_hr = hour & 0x40; -+ am_pm = hour & 0x20; -+ -+ /* Write to rtc_time structure */ -+ time->tm_sec = bcd2bin(second & 0x7f); -+ time->tm_min = bcd2bin(minute & 0x7f); -+ if (twelve_hr) { -+ /* Convert to 24 hr */ -+ if (am_pm) -+ time->tm_hour = bcd2bin(hour & 0x10) + 12; -+ else -+ time->tm_hour = bcd2bin(hour & 0xBF); -+ } else { -+ time->tm_hour = bcd2bin(hour); -+ } -+ -+ time->tm_wday = bcd2bin(week & 0x07) - 1; -+ time->tm_mday = bcd2bin(day & 0x3f); -+ time->tm_mon = bcd2bin(month & 0x1F) - 1; -+ /* assume 20YY not 19YY */ -+ time->tm_year = bcd2bin(year) + 100; -+ -+ return 0; -+} -+ -+static int pt7c4338_set_time(struct device *dev, struct rtc_time *time) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ u8 buf[7]; -+ -+ /* Extract time from rtc_time and load into pt7c4338*/ -+ buf[0] = bin2bcd(time->tm_sec); -+ buf[1] = bin2bcd(time->tm_min); -+ buf[2] = bin2bcd(time->tm_hour); -+ buf[3] = bin2bcd(time->tm_wday + 1); /* Day of the week */ -+ buf[4] = bin2bcd(time->tm_mday); /* Date */ -+ buf[5] = bin2bcd(time->tm_mon + 1); -+ -+ /* assume 20YY not 19YY */ -+ if (time->tm_year >= 100) -+ buf[6] = bin2bcd(time->tm_year - 100); -+ else -+ buf[6] = bin2bcd(time->tm_year); -+ -+ return i2c_smbus_write_i2c_block_data(client, -+ PT7C4338_REG_SECONDS, 7, buf); -+} -+ -+static const struct rtc_class_ops pt7c4338_rtc_ops = { -+ .read_time = pt7c4338_read_time, -+ .set_time = pt7c4338_set_time, -+}; -+ -+static int pt7c4338_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct pt7c4338 *pt7c4338; -+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); -+ int ret; -+ -+ pt7c4338 = kzalloc(sizeof(struct pt7c4338), GFP_KERNEL); -+ if (!pt7c4338) -+ return -ENOMEM; -+ -+ pt7c4338->client = client; -+ i2c_set_clientdata(client, pt7c4338); -+ pt7c4338->rtc = rtc_device_register(client->name, &client->dev, -+ &pt7c4338_rtc_ops, THIS_MODULE); -+ if (IS_ERR(pt7c4338->rtc)) { -+ ret = PTR_ERR(pt7c4338->rtc); -+ dev_err(&client->dev, "unable to register the class device\n"); -+ goto out_free; -+ } -+ -+ return 0; -+out_free: -+ i2c_set_clientdata(client, NULL); -+ kfree(pt7c4338); -+ return ret; -+} -+ -+static int pt7c4338_remove(struct i2c_client *client) -+{ -+ struct pt7c4338 *pt7c4338 = i2c_get_clientdata(client); -+ -+ rtc_device_unregister(pt7c4338->rtc); -+ i2c_set_clientdata(client, NULL); -+ kfree(pt7c4338); -+ return 0; -+} -+ -+static struct i2c_driver pt7c4338_driver = { -+ .driver = { -+ .name = "rtc-pt7c4338", -+ .owner = THIS_MODULE, -+ }, -+ .probe = pt7c4338_probe, -+ .remove = pt7c4338_remove, -+ .id_table = pt7c4338_id, -+}; -+ -+static int __init pt7c4338_init(void) -+{ -+ return i2c_add_driver(&pt7c4338_driver); -+} -+ -+static void __exit pt7c4338_exit(void) -+{ -+ i2c_del_driver(&pt7c4338_driver); -+} -+ -+module_init(pt7c4338_init); -+module_exit(pt7c4338_exit); -+ -+MODULE_AUTHOR("Priyanka Jain <Priyanka.Jain@freescale.com>"); -+MODULE_DESCRIPTION("pericom Technology Inc. PT7C4338 RTC Driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-3.18/861-04_spi_gpio_implement_spi_delay.patch b/target/linux/generic/pending-3.18/861-04_spi_gpio_implement_spi_delay.patch deleted file mode 100644 index e7b32a50bc..0000000000 --- a/target/linux/generic/pending-3.18/861-04_spi_gpio_implement_spi_delay.patch +++ /dev/null @@ -1,58 +0,0 @@ -Implement the SPI-GPIO delay function for busses that need speed limitation. - ---mb - - - ---- a/drivers/spi/spi-gpio.c -+++ b/drivers/spi/spi-gpio.c -@@ -21,6 +21,7 @@ - #include <linux/module.h> - #include <linux/platform_device.h> - #include <linux/gpio.h> -+#include <linux/delay.h> - #include <linux/of.h> - #include <linux/of_device.h> - #include <linux/of_gpio.h> -@@ -73,6 +74,7 @@ struct spi_gpio { - * #define SPI_MOSI_GPIO 120 - * #define SPI_SCK_GPIO 121 - * #define SPI_N_CHIPSEL 4 -+ * #undef NEED_SPIDELAY - * #include "spi-gpio.c" - */ - -@@ -80,6 +82,7 @@ struct spi_gpio { - #define DRIVER_NAME "spi_gpio" - - #define GENERIC_BITBANG /* vs tight inlines */ -+#define NEED_SPIDELAY 1 - - /* all functions referencing these symbols must define pdata */ - #define SPI_MISO_GPIO ((pdata)->miso) -@@ -130,12 +133,20 @@ static inline int getmiso(const struct s - #undef pdata - - /* -- * NOTE: this clocks "as fast as we can". It "should" be a function of the -- * requested device clock. Software overhead means we usually have trouble -- * reaching even one Mbit/sec (except when we can inline bitops), so for now -- * we'll just assume we never need additional per-bit slowdowns. -+ * NOTE: to clock "as fast as we can", set spi_device.max_speed_hz -+ * and spi_transfer.speed_hz to 0. -+ * Otherwise this is a function of the requested device clock. -+ * Software overhead means we usually have trouble -+ * reaching even one Mbit/sec (except when we can inline bitops). So on small -+ * embedded devices with fast SPI slaves you usually don't need a delay. - */ --#define spidelay(nsecs) do {} while (0) -+static inline void spidelay(unsigned nsecs) -+{ -+#ifdef NEED_SPIDELAY -+ if (unlikely(nsecs)) -+ ndelay(nsecs); -+#endif /* NEED_SPIDELAY */ -+} - - #include "spi-bitbang-txrx.h" - diff --git a/target/linux/generic/pending-3.18/862-gpio_spi_driver.patch b/target/linux/generic/pending-3.18/862-gpio_spi_driver.patch deleted file mode 100644 index 70bf11f8f5..0000000000 --- a/target/linux/generic/pending-3.18/862-gpio_spi_driver.patch +++ /dev/null @@ -1,373 +0,0 @@ -THIS CODE IS DEPRECATED. - -Please use the new mainline SPI-GPIO driver, as of 2.6.29. - ---mb - - - ---- - drivers/spi/Kconfig | 9 + - drivers/spi/Makefile | 1 - drivers/spi/spi_gpio_old.c | 251 +++++++++++++++++++++++++++++++++++++++ - include/linux/spi/spi_gpio_old.h | 73 +++++++++++ - 4 files changed, 334 insertions(+) - ---- /dev/null -+++ b/include/linux/spi/spi_gpio_old.h -@@ -0,0 +1,73 @@ -+/* -+ * spi_gpio interface to platform code -+ * -+ * Copyright (c) 2008 Piotr Skamruk -+ * Copyright (c) 2008 Michael Buesch -+ * -+ * 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. -+ */ -+#ifndef _LINUX_SPI_SPI_GPIO -+#define _LINUX_SPI_SPI_GPIO -+ -+#include <linux/types.h> -+#include <linux/spi/spi.h> -+ -+ -+/** -+ * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device. -+ * -+ * This structure holds information about a GPIO-based SPI device. -+ * -+ * @pin_clk: The GPIO pin number of the CLOCK pin. -+ * -+ * @pin_miso: The GPIO pin number of the MISO pin. -+ * -+ * @pin_mosi: The GPIO pin number of the MOSI pin. -+ * -+ * @pin_cs: The GPIO pin number of the CHIPSELECT pin. -+ * -+ * @cs_activelow: If true, the chip is selected when the CS line is low. -+ * -+ * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging. -+ * Note that doing no delay is not standards compliant, -+ * but it might be needed to speed up transfers on some -+ * slow embedded machines. -+ * -+ * @boardinfo_setup: This callback is called after the -+ * SPI master device was registered, but before the -+ * device is registered. -+ * @boardinfo_setup_data: Data argument passed to boardinfo_setup(). -+ */ -+struct spi_gpio_platform_data { -+ unsigned int pin_clk; -+ unsigned int pin_miso; -+ unsigned int pin_mosi; -+ unsigned int pin_cs; -+ bool cs_activelow; -+ bool no_spi_delay; -+ int (*boardinfo_setup)(struct spi_board_info *bi, -+ struct spi_master *master, -+ void *data); -+ void *boardinfo_setup_data; -+}; -+ -+/** -+ * SPI_GPIO_PLATDEV_NAME - The platform device name string. -+ * -+ * The name string that has to be used for platform_device_alloc -+ * when allocating a spi-gpio device. -+ */ -+#define SPI_GPIO_PLATDEV_NAME "spi-gpio" -+ -+/** -+ * spi_gpio_next_id - Get another platform device ID number. -+ * -+ * This returns the next platform device ID number that has to be used -+ * for platform_device_alloc. The ID is opaque and should not be used for -+ * anything else. -+ */ -+int spi_gpio_next_id(void); -+ -+#endif /* _LINUX_SPI_SPI_GPIO */ ---- /dev/null -+++ b/drivers/spi/spi_gpio_old.c -@@ -0,0 +1,251 @@ -+/* -+ * Bitbanging SPI bus driver using GPIO API -+ * -+ * Copyright (c) 2008 Piotr Skamruk -+ * Copyright (c) 2008 Michael Buesch -+ * -+ * based on spi_s3c2410_gpio.c -+ * Copyright (c) 2006 Ben Dooks -+ * Copyright (c) 2006 Simtec Electronics -+ * and on i2c-gpio.c -+ * Copyright (C) 2007 Atmel Corporation -+ * -+ * 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/init.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> -+#include <linux/workqueue.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/spi/spi.h> -+#include <linux/spi/spi_bitbang.h> -+#include <linux/spi/spi_gpio_old.h> -+#include <linux/gpio.h> -+#include <asm/atomic.h> -+ -+ -+struct spi_gpio { -+ struct spi_bitbang bitbang; -+ struct spi_gpio_platform_data *info; -+ struct platform_device *pdev; -+ struct spi_board_info bi; -+}; -+ -+ -+static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev) -+{ -+ return dev->controller_data; -+} -+ -+static inline void setsck(struct spi_device *dev, int val) -+{ -+ struct spi_gpio *sp = spidev_to_sg(dev); -+ gpio_set_value(sp->info->pin_clk, val ? 1 : 0); -+} -+ -+static inline void setmosi(struct spi_device *dev, int val) -+{ -+ struct spi_gpio *sp = spidev_to_sg(dev); -+ gpio_set_value(sp->info->pin_mosi, val ? 1 : 0); -+} -+ -+static inline u32 getmiso(struct spi_device *dev) -+{ -+ struct spi_gpio *sp = spidev_to_sg(dev); -+ return gpio_get_value(sp->info->pin_miso) ? 1 : 0; -+} -+ -+static inline void do_spidelay(struct spi_device *dev, unsigned nsecs) -+{ -+ struct spi_gpio *sp = spidev_to_sg(dev); -+ -+ if (!sp->info->no_spi_delay) -+ ndelay(nsecs); -+} -+ -+#define spidelay(nsecs) do { \ -+ /* Steal the spi_device pointer from our caller. \ -+ * The bitbang-API should probably get fixed here... */ \ -+ do_spidelay(spi, nsecs); \ -+ } while (0) -+ -+#define EXPAND_BITBANG_TXRX -+#include "spi-bitbang-txrx.h" -+ -+static u32 spi_gpio_txrx_mode0(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); -+} -+ -+static u32 spi_gpio_txrx_mode1(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); -+} -+ -+static u32 spi_gpio_txrx_mode2(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); -+} -+ -+static u32 spi_gpio_txrx_mode3(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); -+} -+ -+static void spi_gpio_chipselect(struct spi_device *dev, int on) -+{ -+ struct spi_gpio *sp = spidev_to_sg(dev); -+ -+ if (sp->info->cs_activelow) -+ on = !on; -+ gpio_set_value(sp->info->pin_cs, on ? 1 : 0); -+} -+ -+static int spi_gpio_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct spi_gpio_platform_data *pdata; -+ struct spi_gpio *sp; -+ struct spi_device *spidev; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -ENXIO; -+ -+ err = -ENOMEM; -+ master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio)); -+ if (!master) -+ goto err_alloc_master; -+ -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); -+ sp->info = pdata; -+ -+ err = gpio_request(pdata->pin_clk, "spi_clock"); -+ if (err) -+ goto err_request_clk; -+ err = gpio_request(pdata->pin_mosi, "spi_mosi"); -+ if (err) -+ goto err_request_mosi; -+ err = gpio_request(pdata->pin_miso, "spi_miso"); -+ if (err) -+ goto err_request_miso; -+ err = gpio_request(pdata->pin_cs, "spi_cs"); -+ if (err) -+ goto err_request_cs; -+ -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.master->bus_num = -1; -+ sp->bitbang.master->num_chipselect = 1; -+ sp->bitbang.chipselect = spi_gpio_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0; -+ sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1; -+ sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2; -+ sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3; -+ -+ gpio_direction_output(pdata->pin_clk, 0); -+ gpio_direction_output(pdata->pin_mosi, 0); -+ gpio_direction_output(pdata->pin_cs, -+ pdata->cs_activelow ? 1 : 0); -+ gpio_direction_input(pdata->pin_miso); -+ -+ err = spi_bitbang_start(&sp->bitbang); -+ if (err) -+ goto err_no_bitbang; -+ err = pdata->boardinfo_setup(&sp->bi, master, -+ pdata->boardinfo_setup_data); -+ if (err) -+ goto err_bi_setup; -+ sp->bi.controller_data = sp; -+ spidev = spi_new_device(master, &sp->bi); -+ if (!spidev) -+ goto err_new_dev; -+ -+ return 0; -+ -+err_new_dev: -+err_bi_setup: -+ spi_bitbang_stop(&sp->bitbang); -+err_no_bitbang: -+ spi_master_put(sp->bitbang.master); -+ gpio_free(pdata->pin_cs); -+err_request_cs: -+ gpio_free(pdata->pin_miso); -+err_request_miso: -+ gpio_free(pdata->pin_mosi); -+err_request_mosi: -+ gpio_free(pdata->pin_clk); -+err_request_clk: -+ kfree(master); -+ -+err_alloc_master: -+ return err; -+} -+ -+static int spi_gpio_remove(struct platform_device *pdev) -+{ -+ struct spi_gpio *sp; -+ struct spi_gpio_platform_data *pdata; -+ -+ pdata = pdev->dev.platform_data; -+ sp = platform_get_drvdata(pdev); -+ -+ gpio_free(pdata->pin_clk); -+ gpio_free(pdata->pin_mosi); -+ gpio_free(pdata->pin_miso); -+ gpio_free(pdata->pin_cs); -+ spi_bitbang_stop(&sp->bitbang); -+ spi_master_put(sp->bitbang.master); -+ -+ return 0; -+} -+ -+static struct platform_driver spi_gpio_driver = { -+ .driver = { -+ .name = SPI_GPIO_PLATDEV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = spi_gpio_probe, -+ .remove = spi_gpio_remove, -+}; -+ -+int spi_gpio_next_id(void) -+{ -+ static atomic_t counter = ATOMIC_INIT(-1); -+ -+ return atomic_inc_return(&counter); -+} -+EXPORT_SYMBOL(spi_gpio_next_id); -+ -+static int __init spi_gpio_init(void) -+{ -+ int err; -+ -+ err = platform_driver_register(&spi_gpio_driver); -+ if (err) -+ printk(KERN_ERR "spi-gpio: register failed: %d\n", err); -+ -+ return err; -+} -+module_init(spi_gpio_init); -+ -+static void __exit spi_gpio_exit(void) -+{ -+ platform_driver_unregister(&spi_gpio_driver); -+} -+module_exit(spi_gpio_exit); -+ -+MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>"); -+MODULE_AUTHOR("Michael Buesch"); -+MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -225,6 +225,15 @@ config SPI_GPIO - GPIO operations, you should be able to leverage that for better - speed with a custom version of this driver; see the source code. - -+config SPI_GPIO_OLD -+ tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)" -+ depends on SPI_MASTER && GPIOLIB -+ select SPI_BITBANG -+ help -+ This code is deprecated. Please use the new mainline SPI-GPIO driver. -+ -+ If unsure, say N. -+ - config SPI_IMX - tristate "Freescale i.MX SPI controllers" - depends on ARCH_MXC || COMPILE_TEST ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-li - obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o - obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o - obj-$(CONFIG_SPI_GPIO) += spi-gpio.o -+obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o - obj-$(CONFIG_SPI_IMX) += spi-imx.o - obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o - obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o diff --git a/target/linux/generic/pending-3.18/870-hifn795x_byteswap.patch b/target/linux/generic/pending-3.18/870-hifn795x_byteswap.patch deleted file mode 100644 index 3a37c951ec..0000000000 --- a/target/linux/generic/pending-3.18/870-hifn795x_byteswap.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/drivers/crypto/hifn_795x.c -+++ b/drivers/crypto/hifn_795x.c -@@ -682,12 +682,12 @@ static inline u32 hifn_read_1(struct hif - - static inline void hifn_write_0(struct hifn_device *dev, u32 reg, u32 val) - { -- writel((__force u32)cpu_to_le32(val), dev->bar[0] + reg); -+ writel(val, dev->bar[0] + reg); - } - - static inline void hifn_write_1(struct hifn_device *dev, u32 reg, u32 val) - { -- writel((__force u32)cpu_to_le32(val), dev->bar[1] + reg); -+ writel(val, dev->bar[1] + reg); - } - - static void hifn_wait_puc(struct hifn_device *dev) diff --git a/target/linux/generic/pending-3.18/890-8250_optional_sysrq.patch b/target/linux/generic/pending-3.18/890-8250_optional_sysrq.patch deleted file mode 100644 index 8815e4c644..0000000000 --- a/target/linux/generic/pending-3.18/890-8250_optional_sysrq.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/drivers/tty/serial/8250/8250_core.c -+++ b/drivers/tty/serial/8250/8250_core.c -@@ -16,7 +16,7 @@ - * membase is an 'ioremapped' cookie. - */ - --#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -+#if defined(CONFIG_SERIAL_8250_SYSRQ) && defined(CONFIG_MAGIC_SYSRQ) - #define SUPPORT_SYSRQ - #endif - ---- a/drivers/tty/serial/8250/Kconfig -+++ b/drivers/tty/serial/8250/Kconfig -@@ -91,6 +91,10 @@ config SERIAL_8250_CONSOLE - - If unsure, say N. - -+config SERIAL_8250_SYSRQ -+ bool "Magic sysrq support on 8250/16550 devices" -+ depends on SERIAL_8250_CONSOLE -+ - config SERIAL_8250_GSC - tristate - depends on SERIAL_8250 && GSC diff --git a/target/linux/generic/pending-3.18/901-debloat_sock_diag.patch b/target/linux/generic/pending-3.18/901-debloat_sock_diag.patch deleted file mode 100644 index 41c9220a60..0000000000 --- a/target/linux/generic/pending-3.18/901-debloat_sock_diag.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -89,6 +89,9 @@ source "net/netlabel/Kconfig" - - endif # if INET - -+config SOCK_DIAG -+ bool -+ - config NETWORK_SECMARK - bool "Security Marking" - help ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -9,8 +9,9 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. - - obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ -- sock_diag.o dev_ioctl.o tso.o -+ dev_ioctl.o tso.o - -+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o - obj-$(CONFIG_XFRM) += flow.o - obj-y += net-sysfs.o - obj-$(CONFIG_PROC_FS) += net-procfs.o ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -419,6 +419,7 @@ config INET_LRO - - config INET_DIAG - tristate "INET: socket monitoring interface" -+ select SOCK_DIAG - default y - ---help--- - Support for INET (TCP, DCCP, etc) socket monitoring interface used by ---- a/net/unix/Kconfig -+++ b/net/unix/Kconfig -@@ -22,6 +22,7 @@ config UNIX - config UNIX_DIAG - tristate "UNIX: socket monitoring interface" - depends on UNIX -+ select SOCK_DIAG - default n - ---help--- - Support for UNIX socket monitoring interface used by the ss tool. ---- a/net/netlink/Kconfig -+++ b/net/netlink/Kconfig -@@ -4,6 +4,7 @@ - - config NETLINK_DIAG - tristate "NETLINK: socket monitoring interface" -+ select SOCK_DIAG - default n - ---help--- - Support for NETLINK socket monitoring interface used by the ss tool. ---- a/net/packet/Kconfig -+++ b/net/packet/Kconfig -@@ -18,6 +18,7 @@ config PACKET - config PACKET_DIAG - tristate "Packet: sockets monitoring interface" - depends on PACKET -+ select SOCK_DIAG - default n - ---help--- - Support for PF_PACKET sockets monitoring interface used by the ss tool. diff --git a/target/linux/generic/pending-3.18/902-debloat_proc.patch b/target/linux/generic/pending-3.18/902-debloat_proc.patch deleted file mode 100644 index 8b68cd36fa..0000000000 --- a/target/linux/generic/pending-3.18/902-debloat_proc.patch +++ /dev/null @@ -1,342 +0,0 @@ ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -2620,6 +2620,8 @@ static const struct file_operations proc - - static int __init proc_locks_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create("locks", 0, NULL, &proc_locks_operations); - return 0; - } ---- a/fs/proc/Kconfig -+++ b/fs/proc/Kconfig -@@ -71,3 +71,8 @@ config PROC_PAGE_MONITOR - /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap, - /proc/kpagecount, and /proc/kpageflags. Disabling these - interfaces will reduce the size of the kernel by approximately 4kb. -+ -+config PROC_STRIPPED -+ default n -+ depends on EXPERT -+ bool "Strip non-essential /proc functionality to reduce code size" ---- a/fs/proc/consoles.c -+++ b/fs/proc/consoles.c -@@ -106,6 +106,9 @@ static const struct file_operations proc - - static int __init proc_consoles_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - proc_create("consoles", 0, NULL, &proc_consoles_operations); - return 0; - } ---- a/fs/proc/proc_tty.c -+++ b/fs/proc/proc_tty.c -@@ -144,7 +144,10 @@ static const struct file_operations proc - void proc_tty_register_driver(struct tty_driver *driver) - { - struct proc_dir_entry *ent; -- -+ -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!driver->driver_name || driver->proc_entry || - !driver->ops->proc_fops) - return; -@@ -161,6 +164,9 @@ void proc_tty_unregister_driver(struct t - { - struct proc_dir_entry *ent; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ent = driver->proc_entry; - if (!ent) - return; -@@ -175,6 +181,9 @@ void proc_tty_unregister_driver(struct t - */ - void __init proc_tty_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!proc_mkdir("tty", NULL)) - return; - proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ ---- a/kernel/exec_domain.c -+++ b/kernel/exec_domain.c -@@ -176,6 +176,8 @@ static const struct file_operations exec - - static int __init proc_execdomains_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create("execdomains", 0, NULL, &execdomains_proc_fops); - return 0; - } ---- a/kernel/irq/proc.c -+++ b/kernel/irq/proc.c -@@ -330,6 +330,9 @@ void register_irq_proc(unsigned int irq, - static DEFINE_MUTEX(register_lock); - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) - return; - -@@ -379,6 +382,9 @@ void unregister_irq_proc(unsigned int ir - { - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || !desc->dir) - return; - #ifdef CONFIG_SMP -@@ -414,6 +420,9 @@ void init_irq_proc(void) - unsigned int irq; - struct irq_desc *desc; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - /* create /proc/irq */ - root_irq_dir = proc_mkdir("irq", NULL); - if (!root_irq_dir) ---- a/kernel/time/timer_list.c -+++ b/kernel/time/timer_list.c -@@ -362,6 +362,9 @@ static int __init init_timer_list_procfs - { - struct proc_dir_entry *pe; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - pe = proc_create("timer_list", 0400, NULL, &timer_list_fops); - if (!pe) - return -ENOMEM; ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -2663,6 +2663,8 @@ static const struct file_operations proc - - static int __init proc_vmalloc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations); - return 0; - } ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -1424,10 +1424,12 @@ static int __init setup_vmstat(void) - cpu_notifier_register_done(); - #endif - #ifdef CONFIG_PROC_FS -- proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); -- proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); -+ proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops); -+ proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations); -+ } - proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations); -- proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations); - #endif - return 0; - } ---- a/net/8021q/vlanproc.c -+++ b/net/8021q/vlanproc.c -@@ -127,6 +127,9 @@ void vlan_proc_cleanup(struct net *net) - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (vn->proc_vlan_conf) - remove_proc_entry(name_conf, vn->proc_vlan_dir); - -@@ -146,6 +149,9 @@ int __net_init vlan_proc_init(struct net - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); - if (!vn->proc_vlan_dir) - goto err; ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -2945,6 +2945,8 @@ static __net_initdata struct pernet_oper - - static int __init proto_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - return register_pernet_subsys(&proto_net_ops); - } - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2490,10 +2490,12 @@ static const struct file_operations fib_ - - int __net_init fib_proc_init(struct net *net) - { -- if (!proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) - goto out1; - -- if (!proc_create("fib_triestat", S_IRUGO, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create("fib_triestat", S_IRUGO, net->proc_net, - &fib_triestat_fops)) - goto out2; - -@@ -2503,17 +2505,21 @@ int __net_init fib_proc_init(struct net - return 0; - - out3: -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_triestat", net->proc_net); - out2: -- remove_proc_entry("fib_trie", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_trie", net->proc_net); - out1: - return -ENOMEM; - } - - void __net_exit fib_proc_exit(struct net *net) - { -- remove_proc_entry("fib_trie", net->proc_net); -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("fib_trie", net->proc_net); -+ remove_proc_entry("fib_triestat", net->proc_net); -+ } - remove_proc_entry("route", net->proc_net); - } - ---- a/net/ipv4/proc.c -+++ b/net/ipv4/proc.c -@@ -524,6 +524,9 @@ static __net_initdata struct pernet_oper - - int __init ip_misc_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_proc_ops); - } - ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -418,6 +418,9 @@ static struct pernet_operations ip_rt_pr - - static int __init ip_rt_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_rt_proc_ops); - } - ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -1075,6 +1075,9 @@ void __init msg_init(void) - printk(KERN_INFO "msgmni has been set to %d\n", - init_ipc_ns.msg_ctlmni); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ipc_init_proc_interface("sysvipc/msg", - " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", - IPC_MSG_IDS, sysvipc_msg_proc_show); ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -191,6 +191,8 @@ void sem_exit_ns(struct ipc_namespace *n - void __init sem_init(void) - { - sem_init_ns(&init_ipc_ns); -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/sem", - " key semid perms nsems uid gid cuid cgid otime ctime\n", - IPC_SEM_IDS, sysvipc_sem_proc_show); ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -118,6 +118,8 @@ pure_initcall(ipc_ns_init); - - void __init shm_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/shm", - #if BITS_PER_LONG <= 32 - " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -161,6 +161,9 @@ void __init ipc_init_proc_interface(cons - struct proc_dir_entry *pde; - struct ipc_proc_iface *iface; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - iface = kmalloc(sizeof(*iface), GFP_KERNEL); - if (!iface) - return; ---- a/net/core/net-procfs.c -+++ b/net/core/net-procfs.c -@@ -318,10 +318,12 @@ static int __net_init dev_proc_net_init( - - if (!proc_create("dev", S_IRUGO, net->proc_net, &dev_seq_fops)) - goto out; -- if (!proc_create("softnet_stat", S_IRUGO, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create("softnet_stat", S_IRUGO, net->proc_net, - &softnet_seq_fops)) - goto out_dev; -- if (!proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) - goto out_softnet; - - if (wext_proc_init(net)) -@@ -330,9 +332,11 @@ static int __net_init dev_proc_net_init( - out: - return rc; - out_ptype: -- remove_proc_entry("ptype", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("ptype", net->proc_net); - out_softnet: -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("softnet_stat", net->proc_net); - out_dev: - remove_proc_entry("dev", net->proc_net); - goto out; -@@ -342,8 +346,10 @@ static void __net_exit dev_proc_net_exit - { - wext_proc_exit(net); - -- remove_proc_entry("ptype", net->proc_net); -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("ptype", net->proc_net); -+ remove_proc_entry("softnet_stat", net->proc_net); -+ } - remove_proc_entry("dev", net->proc_net); - } - diff --git a/target/linux/generic/pending-3.18/904-debloat_dma_buf.patch b/target/linux/generic/pending-3.18/904-debloat_dma_buf.patch deleted file mode 100644 index a5e0be2496..0000000000 --- a/target/linux/generic/pending-3.18/904-debloat_dma_buf.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- a/drivers/base/Kconfig -+++ b/drivers/base/Kconfig -@@ -229,7 +229,7 @@ config SOC_BUS - source "drivers/base/regmap/Kconfig" - - config DMA_SHARED_BUFFER -- bool -+ tristate - default n - select ANON_INODES - help ---- a/drivers/dma-buf/Makefile -+++ b/drivers/dma-buf/Makefile -@@ -1 +1,2 @@ --obj-y := dma-buf.o fence.o reservation.o seqno-fence.o -+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o -+dma-shared-buffer-objs := dma-buf.o fence.o reservation.o seqno-fence.o ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -32,6 +32,7 @@ - #include <linux/seq_file.h> - #include <linux/poll.h> - #include <linux/reservation.h> -+#include <linux/module.h> - - static inline int is_dma_buf_file(struct file *); - -@@ -904,4 +905,5 @@ static void __exit dma_buf_deinit(void) - { - dma_buf_uninit_debugfs(); - } --__exitcall(dma_buf_deinit); -+module_exit(dma_buf_deinit); -+MODULE_LICENSE("GPL"); ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -1823,6 +1823,7 @@ int wake_up_state(struct task_struct *p, - { - return try_to_wake_up(p, state, 0); - } -+EXPORT_SYMBOL_GPL(wake_up_state); - - /* - * This function clears the sched_dl_entity static params. diff --git a/target/linux/generic/pending-3.18/910-kobject_uevent.patch b/target/linux/generic/pending-3.18/910-kobject_uevent.patch deleted file mode 100644 index f69294b4fe..0000000000 --- a/target/linux/generic/pending-3.18/910-kobject_uevent.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -53,6 +53,18 @@ static const char *kobject_actions[] = { - [KOBJ_OFFLINE] = "offline", - }; - -+u64 uevent_next_seqnum(void) -+{ -+ u64 seq; -+ -+ mutex_lock(&uevent_sock_mutex); -+ seq = ++uevent_seqnum; -+ mutex_unlock(&uevent_sock_mutex); -+ -+ return seq; -+} -+EXPORT_SYMBOL_GPL(uevent_next_seqnum); -+ - /** - * kobject_action_type - translate action string to numeric type - * diff --git a/target/linux/generic/pending-3.18/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/pending-3.18/911-kobject_add_broadcast_uevent.patch deleted file mode 100644 index 6e4c140291..0000000000 --- a/target/linux/generic/pending-3.18/911-kobject_add_broadcast_uevent.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -32,6 +32,8 @@ - #define UEVENT_NUM_ENVP 32 /* number of env pointers */ - #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ - -+struct sk_buff; -+ - #ifdef CONFIG_UEVENT_HELPER - /* path to the userspace helper executed on an event */ - extern char uevent_helper[]; -@@ -221,4 +223,7 @@ int add_uevent_var(struct kobj_uevent_en - int kobject_action_type(const char *buf, size_t count, - enum kobject_action *type); - -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation); -+ - #endif /* _KOBJECT_H_ */ ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -424,6 +424,43 @@ int add_uevent_var(struct kobj_uevent_en - EXPORT_SYMBOL_GPL(add_uevent_var); - - #if defined(CONFIG_NET) -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ struct uevent_sock *ue_sk; -+ int err = 0; -+ -+ /* send netlink message */ -+ mutex_lock(&uevent_sock_mutex); -+ list_for_each_entry(ue_sk, &uevent_sock_list, list) { -+ struct sock *uevent_sock = ue_sk->sk; -+ struct sk_buff *skb2; -+ -+ skb2 = skb_clone(skb, allocation); -+ if (!skb2) -+ break; -+ -+ err = netlink_broadcast(uevent_sock, skb2, pid, group, -+ allocation); -+ if (err) -+ break; -+ } -+ mutex_unlock(&uevent_sock_mutex); -+ -+ kfree_skb(skb); -+ return err; -+} -+#else -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ kfree_skb(skb); -+ return 0; -+} -+#endif -+EXPORT_SYMBOL_GPL(broadcast_uevent); -+ -+#if defined(CONFIG_NET) - static int uevent_net_init(struct net *net) - { - struct uevent_sock *ue_sk; diff --git a/target/linux/generic/pending-3.18/921-use_preinit_as_init.patch b/target/linux/generic/pending-3.18/921-use_preinit_as_init.patch deleted file mode 100644 index 57c2fe27be..0000000000 --- a/target/linux/generic/pending-3.18/921-use_preinit_as_init.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/init/main.c -+++ b/init/main.c -@@ -963,7 +963,8 @@ static int __ref kernel_init(void *unuse - pr_err("Failed to execute %s (error %d). Attempting defaults...\n", - execute_command, ret); - } -- if (!try_to_run_init_process("/sbin/init") || -+ if (!try_to_run_init_process("/etc/preinit") || -+ !try_to_run_init_process("/sbin/init") || - !try_to_run_init_process("/etc/init") || - !try_to_run_init_process("/bin/init") || - !try_to_run_init_process("/bin/sh")) diff --git a/target/linux/generic/pending-3.18/922-always-create-console-node-in-initramfs.patch b/target/linux/generic/pending-3.18/922-always-create-console-node-in-initramfs.patch deleted file mode 100644 index 988de35ce0..0000000000 --- a/target/linux/generic/pending-3.18/922-always-create-console-node-in-initramfs.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/scripts/gen_initramfs_list.sh -+++ b/scripts/gen_initramfs_list.sh -@@ -59,6 +59,18 @@ default_initramfs() { - EOF - } - -+list_openwrt_initramfs() { -+ : -+} -+ -+openwrt_initramfs() { -+ # make sure that /dev/console exists -+ cat <<-EOF >> ${output} -+ dir /dev 0755 0 0 -+ nod /dev/console 0600 0 0 c 5 1 -+ EOF -+} -+ - filetype() { - local argv1="$1" - -@@ -177,6 +189,8 @@ dir_filelist() { - if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then - ${dep_list}print_mtime "$1" - -+ ${dep_list}openwrt_initramfs -+ - echo "${dirlist}" | \ - while read x; do - ${dep_list}parse ${x} diff --git a/target/linux/generic/pending-3.18/930-crashlog.patch b/target/linux/generic/pending-3.18/930-crashlog.patch deleted file mode 100644 index 9b0eb732df..0000000000 --- a/target/linux/generic/pending-3.18/930-crashlog.patch +++ /dev/null @@ -1,276 +0,0 @@ ---- /dev/null -+++ b/include/linux/crashlog.h -@@ -0,0 +1,17 @@ -+#ifndef __CRASHLOG_H -+#define __CRASHLOG_H -+ -+#ifdef CONFIG_CRASHLOG -+void crashlog_init_bootmem(struct bootmem_data *bdata); -+void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size); -+#else -+static inline void crashlog_init_bootmem(struct bootmem_data *bdata) -+{ -+} -+ -+static inline void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) -+{ -+} -+#endif -+ -+#endif ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1279,6 +1279,10 @@ config RELAY - - If unsure, say N. - -+config CRASHLOG -+ bool "Crash logging" -+ depends on (!NO_BOOTMEM || HAVE_MEMBLOCK) && !(ARM || SPARC || PPC) -+ - config BLK_DEV_INITRD - bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" - depends on BROKEN || !FRV ---- a/kernel/Makefile -+++ b/kernel/Makefile -@@ -96,6 +96,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o - obj-$(CONFIG_JUMP_LABEL) += jump_label.o - obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o - obj-$(CONFIG_TORTURE_TEST) += torture.o -+obj-$(CONFIG_CRASHLOG) += crashlog.o - - $(obj)/configs.o: $(obj)/config_data.h - ---- /dev/null -+++ b/kernel/crashlog.c -@@ -0,0 +1,181 @@ -+/* -+ * Crash information logger -+ * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name> -+ * -+ * Based on ramoops.c -+ * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/bootmem.h> -+#include <linux/memblock.h> -+#include <linux/debugfs.h> -+#include <linux/crashlog.h> -+#include <linux/kmsg_dump.h> -+#include <linux/module.h> -+#include <linux/pfn.h> -+#include <asm/io.h> -+ -+#define CRASHLOG_PAGES 4 -+#define CRASHLOG_SIZE (CRASHLOG_PAGES * PAGE_SIZE) -+#define CRASHLOG_MAGIC 0xa1eedead -+ -+/* -+ * Start the log at 1M before the end of RAM, as some boot loaders like -+ * to use the end of the RAM for stack usage and other things -+ * If this fails, fall back to using the last part. -+ */ -+#define CRASHLOG_OFFSET (1024 * 1024) -+ -+struct crashlog_data { -+ u32 magic; -+ u32 len; -+ u8 data[]; -+}; -+ -+static struct debugfs_blob_wrapper crashlog_blob; -+static unsigned long crashlog_addr = 0; -+static struct crashlog_data *crashlog_buf; -+static struct kmsg_dumper dump; -+static bool first = true; -+ -+extern struct list_head *crashlog_modules; -+ -+#ifndef CONFIG_NO_BOOTMEM -+void __init crashlog_init_bootmem(bootmem_data_t *bdata) -+{ -+ unsigned long addr; -+ -+ if (crashlog_addr) -+ return; -+ -+ addr = PFN_PHYS(bdata->node_low_pfn) - CRASHLOG_OFFSET; -+ if (reserve_bootmem(addr, CRASHLOG_SIZE, BOOTMEM_EXCLUSIVE) < 0) { -+ printk("Crashlog failed to allocate RAM at address 0x%lx\n", addr); -+ bdata->node_low_pfn -= CRASHLOG_PAGES; -+ addr = PFN_PHYS(bdata->node_low_pfn); -+ } -+ crashlog_addr = addr; -+} -+#endif -+ -+#ifdef CONFIG_HAVE_MEMBLOCK -+void __init_memblock crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) -+{ -+ if (crashlog_addr) -+ return; -+ -+ addr += size - CRASHLOG_OFFSET; -+ if (memblock_reserve(addr, CRASHLOG_SIZE)) { -+ printk("Crashlog failed to allocate RAM at address 0x%lx\n", (unsigned long) addr); -+ return; -+ } -+ -+ crashlog_addr = addr; -+} -+#endif -+ -+static void __init crashlog_copy(void) -+{ -+ if (crashlog_buf->magic != CRASHLOG_MAGIC) -+ return; -+ -+ if (!crashlog_buf->len || crashlog_buf->len > -+ CRASHLOG_SIZE - sizeof(*crashlog_buf)) -+ return; -+ -+ crashlog_blob.size = crashlog_buf->len; -+ crashlog_blob.data = kmemdup(crashlog_buf->data, -+ crashlog_buf->len, GFP_KERNEL); -+ -+ debugfs_create_blob("crashlog", 0700, NULL, &crashlog_blob); -+} -+ -+static int get_maxlen(void) -+{ -+ return CRASHLOG_SIZE - sizeof(*crashlog_buf) - crashlog_buf->len; -+} -+ -+static void crashlog_printf(const char *fmt, ...) -+{ -+ va_list args; -+ int len = get_maxlen(); -+ -+ if (!len) -+ return; -+ -+ va_start(args, fmt); -+ crashlog_buf->len += vscnprintf( -+ &crashlog_buf->data[crashlog_buf->len], -+ len, fmt, args); -+ va_end(args); -+} -+ -+static void crashlog_do_dump(struct kmsg_dumper *dumper, -+ enum kmsg_dump_reason reason) -+{ -+ struct timeval tv; -+ struct module *m; -+ char *buf; -+ size_t len; -+ -+ if (!first) -+ crashlog_printf("\n===================================\n"); -+ -+ do_gettimeofday(&tv); -+ crashlog_printf("Time: %lu.%lu\n", -+ (long)tv.tv_sec, (long)tv.tv_usec); -+ -+ if (first) { -+ crashlog_printf("Modules:"); -+ list_for_each_entry(m, crashlog_modules, list) { -+ crashlog_printf("\t%s@%p+%x", m->name, -+ m->module_core, m->core_size, -+ m->module_init, m->init_size); -+ } -+ crashlog_printf("\n"); -+ first = false; -+ } -+ -+ buf = (char *)&crashlog_buf->data[crashlog_buf->len]; -+ -+ kmsg_dump_get_buffer(dumper, true, buf, get_maxlen(), &len); -+ -+ crashlog_buf->len += len; -+} -+ -+ -+int __init crashlog_init_fs(void) -+{ -+ if (!crashlog_addr) -+ return -ENOMEM; -+ -+ crashlog_buf = ioremap(crashlog_addr, CRASHLOG_SIZE); -+ -+ crashlog_copy(); -+ -+ crashlog_buf->magic = CRASHLOG_MAGIC; -+ crashlog_buf->len = 0; -+ -+ dump.max_reason = KMSG_DUMP_OOPS; -+ dump.dump = crashlog_do_dump; -+ kmsg_dump_register(&dump); -+ -+ return 0; -+} -+module_init(crashlog_init_fs); ---- a/mm/bootmem.c -+++ b/mm/bootmem.c -@@ -15,6 +15,7 @@ - #include <linux/export.h> - #include <linux/kmemleak.h> - #include <linux/range.h> -+#include <linux/crashlog.h> - #include <linux/memblock.h> - #include <linux/bug.h> - #include <linux/io.h> -@@ -177,6 +178,7 @@ static unsigned long __init free_all_boo - if (!bdata->node_bootmem_map) - return 0; - -+ crashlog_init_bootmem(bdata); - map = bdata->node_bootmem_map; - start = bdata->node_min_pfn; - end = bdata->node_low_pfn; ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -105,6 +105,9 @@ static LIST_HEAD(modules); - #ifdef CONFIG_KGDB_KDB - struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ - #endif /* CONFIG_KGDB_KDB */ -+#ifdef CONFIG_CRASHLOG -+struct list_head *crashlog_modules = &modules; -+#endif - - #ifdef CONFIG_MODULE_SIG - #ifdef CONFIG_MODULE_SIG_FORCE ---- a/mm/memblock.c -+++ b/mm/memblock.c -@@ -19,6 +19,7 @@ - #include <linux/debugfs.h> - #include <linux/seq_file.h> - #include <linux/memblock.h> -+#include <linux/crashlog.h> - - #include <asm-generic/sections.h> - #include <linux/io.h> -@@ -477,6 +478,8 @@ static void __init_memblock memblock_ins - memblock_set_region_node(rgn, nid); - type->cnt++; - type->total_size += size; -+ if (type == &memblock.memory && idx == 0) -+ crashlog_init_memblock(base, size); - } - - /** diff --git a/target/linux/generic/pending-3.18/970-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-3.18/970-remove-unsane-filenames-from-deps_initramfs-list.patch deleted file mode 100644 index ac13c9e673..0000000000 --- a/target/linux/generic/pending-3.18/970-remove-unsane-filenames-from-deps_initramfs-list.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/usr/Makefile -+++ b/usr/Makefile -@@ -53,6 +53,8 @@ ifneq ($(wildcard $(obj)/.initramfs_data - include $(obj)/.initramfs_data.cpio.d - endif - -+deps_initramfs_sane := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) -+ - quiet_cmd_initfs = GEN $@ - cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) - -@@ -61,14 +63,14 @@ targets := initramfs_data.cpio.gz initra - initramfs_data.cpio.lzo initramfs_data.cpio.lz4 \ - initramfs_data.cpio - # do not try to update files included in initramfs --$(deps_initramfs): ; -+$(deps_initramfs_sane): ; - --$(deps_initramfs): klibcdirs -+$(deps_initramfs_sane): klibcdirs - # We rebuild initramfs_data.cpio if: - # 1) Any included file is newer then initramfs_data.cpio - # 2) There are changes in which files are included (added or deleted) - # 3) If gen_init_cpio are newer than initramfs_data.cpio - # 4) arguments to gen_initramfs.sh changes --$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs -+$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs_sane) klibcdirs - $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d - $(call if_changed,initfs) diff --git a/target/linux/generic/pending-3.18/980-arm_openwrt_machtypes.patch b/target/linux/generic/pending-3.18/980-arm_openwrt_machtypes.patch deleted file mode 100644 index 5e9718b61d..0000000000 --- a/target/linux/generic/pending-3.18/980-arm_openwrt_machtypes.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/arch/arm/tools/mach-types -+++ b/arch/arm/tools/mach-types -@@ -1007,3 +1007,29 @@ eco5_bx2 MACH_ECO5_BX2 ECO5_BX2 4572 - eukrea_cpuimx28sd MACH_EUKREA_CPUIMX28SD EUKREA_CPUIMX28SD 4573 - domotab MACH_DOMOTAB DOMOTAB 4574 - pfla03 MACH_PFLA03 PFLA03 4575 -+# -+# Additional mach-types supported by OpenWrt -+# -+wg302v1 MACH_WG302V1 WG302V1 889 -+pronghorn MACH_PRONGHORN PRONGHORN 928 -+pronghorn_metro MACH_PRONGHORNMETRO PRONGHORNMETRO 1040 -+sidewinder MACH_SIDEWINDER SIDEWINDER 1041 -+wrt300nv2 MACH_WRT300NV2 WRT300NV2 1077 -+compex42x MACH_COMPEXWP18 COMPEXWP18 1273 -+goldfish MACH_GOLDFISH GOLDFISH 1441 -+cambria MACH_CAMBRIA CAMBRIA 1468 -+dt2 MACH_DT2 DT2 1514 -+ap1000 MACH_AP1000 AP1000 1543 -+tw2662 MACH_TW2662 TW2662 1658 -+tw5334 MACH_TW5334 TW5334 1664 -+usr8200 MACH_USR8200 USR8200 1762 -+mi424wr MACH_MI424WR MI424WR 1778 -+gw2388 MACH_GW2388 GW2388 2635 -+iconnect MACH_ICONNECT ICONNECT 2870 -+nsb3ast MACH_NSB3AST NSB3AST 2917 -+goflexnet MACH_GOFLEXNET GOFLEXNET 3089 -+nas6210 MACH_NAS6210 NAS6210 3104 -+ns_k330 MACH_NS_K330 NS_K330 3108 -+bcm2708 MACH_BCM2708 BCM2708 3138 -+wn802t MACH_WN802T WN802T 3306 -+nsa310 MACH_NSA310 NSA310 4022 diff --git a/target/linux/generic/pending-3.18/990-gpio_wdt.patch b/target/linux/generic/pending-3.18/990-gpio_wdt.patch deleted file mode 100644 index 47422734f3..0000000000 --- a/target/linux/generic/pending-3.18/990-gpio_wdt.patch +++ /dev/null @@ -1,360 +0,0 @@ -This generic GPIO watchdog is used on Huawei E970 (brcm47xx) - -Signed-off-by: Mathias Adam <m.adam--openwrt@adamis.de> - ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -1139,6 +1139,15 @@ config WDT_MTX1 - Hardware driver for the MTX-1 boards. This is a watchdog timer that - will reboot the machine after a 100 seconds timer expired. - -+config GPIO_WDT -+ tristate "GPIO Hardware Watchdog" -+ help -+ Hardware driver for GPIO-controlled watchdogs. GPIO pin and -+ toggle interval settings are platform-specific. The driver -+ will stop toggling the GPIO (i.e. machine reboots) after a -+ 100 second timer expired and no process has written to -+ /dev/watchdog during that time. -+ - config PNX833X_WDT - tristate "PNX833x Hardware Watchdog" - depends on SOC_PNX8335 ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -134,6 +134,7 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt - obj-$(CONFIG_INDYDOG) += indydog.o - obj-$(CONFIG_JZ4740_WDT) += jz4740_wdt.o - obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o -+obj-$(CONFIG_GPIO_WDT) += old_gpio_wdt.o - obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o - obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o - obj-$(CONFIG_AR7_WDT) += ar7_wdt.o ---- /dev/null -+++ b/drivers/watchdog/old_gpio_wdt.c -@@ -0,0 +1,301 @@ -+/* -+ * Driver for GPIO-controlled Hardware Watchdogs. -+ * -+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de> -+ * -+ * Replaces mtx1_wdt (driver for the MTX-1 Watchdog): -+ * -+ * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, -+ * All Rights Reserved. -+ * http://www.4g-systems.biz -+ * -+ * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Neither Michael Stickel nor 4G Systems admit liability nor provide -+ * warranty for any of this software. This material is provided -+ * "AS-IS" and at no charge. -+ * -+ * (c) Copyright 2005 4G Systems <info@4g-systems.biz> -+ * -+ * Release 0.01. -+ * Author: Michael Stickel michael.stickel@4g-systems.biz -+ * -+ * Release 0.02. -+ * Author: Florian Fainelli florian@openwrt.org -+ * use the Linux watchdog/timer APIs -+ * -+ * Release 0.03. -+ * Author: Mathias Adam <m.adam--linux@adamis.de> -+ * make it a generic gpio watchdog driver -+ * -+ * The Watchdog is configured to reset the MTX-1 -+ * if it is not triggered for 100 seconds. -+ * It should not be triggered more often than 1.6 seconds. -+ * -+ * A timer triggers the watchdog every 5 seconds, until -+ * it is opened for the first time. After the first open -+ * it MUST be triggered every 2..95 seconds. -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/types.h> -+#include <linux/errno.h> -+#include <linux/miscdevice.h> -+#include <linux/fs.h> -+#include <linux/init.h> -+#include <linux/ioport.h> -+#include <linux/timer.h> -+#include <linux/completion.h> -+#include <linux/jiffies.h> -+#include <linux/watchdog.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/uaccess.h> -+#include <linux/gpio.h> -+#include <linux/old_gpio_wdt.h> -+ -+static int ticks = 100 * HZ; -+ -+static struct { -+ struct completion stop; -+ spinlock_t lock; -+ int running; -+ struct timer_list timer; -+ int queue; -+ int default_ticks; -+ unsigned long inuse; -+ unsigned gpio; -+ unsigned int gstate; -+ int interval; -+ int first_interval; -+} gpio_wdt_device; -+ -+static void gpio_wdt_trigger(unsigned long unused) -+{ -+ spin_lock(&gpio_wdt_device.lock); -+ if (gpio_wdt_device.running && ticks > 0) -+ ticks -= gpio_wdt_device.interval; -+ -+ /* toggle wdt gpio */ -+ gpio_wdt_device.gstate = !gpio_wdt_device.gstate; -+ gpio_set_value(gpio_wdt_device.gpio, gpio_wdt_device.gstate); -+ -+ if (gpio_wdt_device.queue && ticks > 0) -+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.interval); -+ else -+ complete(&gpio_wdt_device.stop); -+ spin_unlock(&gpio_wdt_device.lock); -+} -+ -+static void gpio_wdt_reset(void) -+{ -+ ticks = gpio_wdt_device.default_ticks; -+} -+ -+ -+static void gpio_wdt_start(void) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&gpio_wdt_device.lock, flags); -+ if (!gpio_wdt_device.queue) { -+ gpio_wdt_device.queue = 1; -+ gpio_wdt_device.gstate = 1; -+ gpio_set_value(gpio_wdt_device.gpio, 1); -+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.first_interval); -+ } -+ gpio_wdt_device.running++; -+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags); -+} -+ -+static int gpio_wdt_stop(void) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&gpio_wdt_device.lock, flags); -+ if (gpio_wdt_device.queue) { -+ gpio_wdt_device.queue = 0; -+ gpio_wdt_device.gstate = 0; -+ gpio_set_value(gpio_wdt_device.gpio, 0); -+ } -+ ticks = gpio_wdt_device.default_ticks; -+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags); -+ return 0; -+} -+ -+/* Filesystem functions */ -+ -+static int gpio_wdt_open(struct inode *inode, struct file *file) -+{ -+ if (test_and_set_bit(0, &gpio_wdt_device.inuse)) -+ return -EBUSY; -+ return nonseekable_open(inode, file); -+} -+ -+ -+static int gpio_wdt_release(struct inode *inode, struct file *file) -+{ -+ clear_bit(0, &gpio_wdt_device.inuse); -+ return 0; -+} -+ -+static long gpio_wdt_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ void __user *argp = (void __user *)arg; -+ int __user *p = (int __user *)argp; -+ unsigned int value; -+ static const struct watchdog_info ident = { -+ .options = WDIOF_CARDRESET, -+ .identity = "GPIO WDT", -+ }; -+ -+ switch (cmd) { -+ case WDIOC_GETSUPPORT: -+ if (copy_to_user(argp, &ident, sizeof(ident))) -+ return -EFAULT; -+ break; -+ case WDIOC_GETSTATUS: -+ case WDIOC_GETBOOTSTATUS: -+ put_user(0, p); -+ break; -+ case WDIOC_SETOPTIONS: -+ if (get_user(value, p)) -+ return -EFAULT; -+ if (value & WDIOS_ENABLECARD) -+ gpio_wdt_start(); -+ else if (value & WDIOS_DISABLECARD) -+ gpio_wdt_stop(); -+ else -+ return -EINVAL; -+ return 0; -+ case WDIOC_KEEPALIVE: -+ gpio_wdt_reset(); -+ break; -+ default: -+ return -ENOTTY; -+ } -+ return 0; -+} -+ -+ -+static ssize_t gpio_wdt_write(struct file *file, const char *buf, -+ size_t count, loff_t *ppos) -+{ -+ if (!count) -+ return -EIO; -+ gpio_wdt_reset(); -+ return count; -+} -+ -+static const struct file_operations gpio_wdt_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .unlocked_ioctl = gpio_wdt_ioctl, -+ .open = gpio_wdt_open, -+ .write = gpio_wdt_write, -+ .release = gpio_wdt_release, -+}; -+ -+ -+static struct miscdevice gpio_wdt_misc = { -+ .minor = WATCHDOG_MINOR, -+ .name = "watchdog", -+ .fops = &gpio_wdt_fops, -+}; -+ -+ -+static int gpio_wdt_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct gpio_wdt_platform_data *gpio_wdt_data = pdev->dev.platform_data; -+ -+ gpio_wdt_device.gpio = gpio_wdt_data->gpio; -+ gpio_wdt_device.interval = gpio_wdt_data->interval; -+ gpio_wdt_device.first_interval = gpio_wdt_data->first_interval; -+ if (gpio_wdt_device.first_interval <= 0) { -+ gpio_wdt_device.first_interval = gpio_wdt_device.interval; -+ } -+ -+ ret = gpio_request(gpio_wdt_device.gpio, "gpio-wdt"); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "failed to request gpio"); -+ return ret; -+ } -+ -+ spin_lock_init(&gpio_wdt_device.lock); -+ init_completion(&gpio_wdt_device.stop); -+ gpio_wdt_device.queue = 0; -+ clear_bit(0, &gpio_wdt_device.inuse); -+ setup_timer(&gpio_wdt_device.timer, gpio_wdt_trigger, 0L); -+ gpio_wdt_device.default_ticks = ticks; -+ -+ gpio_wdt_start(); -+ dev_info(&pdev->dev, "GPIO Hardware Watchdog driver (gpio=%i interval=%i/%i)\n", -+ gpio_wdt_data->gpio, gpio_wdt_data->first_interval, gpio_wdt_data->interval); -+ return 0; -+} -+ -+static int gpio_wdt_remove(struct platform_device *pdev) -+{ -+ /* FIXME: do we need to lock this test ? */ -+ if (gpio_wdt_device.queue) { -+ gpio_wdt_device.queue = 0; -+ wait_for_completion(&gpio_wdt_device.stop); -+ } -+ -+ gpio_free(gpio_wdt_device.gpio); -+ misc_deregister(&gpio_wdt_misc); -+ return 0; -+} -+ -+static struct platform_driver gpio_wdt_driver = { -+ .probe = gpio_wdt_probe, -+ .remove = gpio_wdt_remove, -+ .driver.name = "gpio-wdt", -+ .driver.owner = THIS_MODULE, -+}; -+ -+static int __init gpio_wdt_init(void) -+{ -+ return platform_driver_register(&gpio_wdt_driver); -+} -+arch_initcall(gpio_wdt_init); -+ -+/* -+ * We do wdt initialization in two steps: arch_initcall probes the wdt -+ * very early to start pinging the watchdog (misc devices are not yet -+ * available), and later module_init() just registers the misc device. -+ */ -+static int gpio_wdt_init_late(void) -+{ -+ int ret; -+ -+ ret = misc_register(&gpio_wdt_misc); -+ if (ret < 0) { -+ pr_err("GPIO_WDT: failed to register misc device\n"); -+ return ret; -+ } -+ return 0; -+} -+#ifndef MODULE -+module_init(gpio_wdt_init_late); -+#endif -+ -+static void __exit gpio_wdt_exit(void) -+{ -+ platform_driver_unregister(&gpio_wdt_driver); -+} -+module_exit(gpio_wdt_exit); -+ -+MODULE_AUTHOR("Michael Stickel, Florian Fainelli, Mathias Adam"); -+MODULE_DESCRIPTION("Driver for GPIO hardware watchdogs"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -+MODULE_ALIAS("platform:gpio-wdt"); ---- /dev/null -+++ b/include/linux/old_gpio_wdt.h -@@ -0,0 +1,21 @@ -+/* -+ * Definitions for the GPIO watchdog driver -+ * -+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de> -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _GPIO_WDT_H_ -+#define _GPIO_WDT_H_ -+ -+struct gpio_wdt_platform_data { -+ int gpio; /* GPIO line number */ -+ int interval; /* watchdog reset interval in system ticks */ -+ int first_interval; /* first wd reset interval in system ticks */ -+}; -+ -+#endif /* _GPIO_WDT_H_ */ diff --git a/target/linux/generic/pending-3.18/995-mangle_bootargs.patch b/target/linux/generic/pending-3.18/995-mangle_bootargs.patch deleted file mode 100644 index 0029e90822..0000000000 --- a/target/linux/generic/pending-3.18/995-mangle_bootargs.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- a/init/main.c -+++ b/init/main.c -@@ -362,6 +362,29 @@ static inline void setup_nr_cpu_ids(void - static inline void smp_prepare_cpus(unsigned int maxcpus) { } - #endif - -+#ifdef CONFIG_MANGLE_BOOTARGS -+static void __init mangle_bootargs(char *command_line) -+{ -+ char *rootdev; -+ char *rootfs; -+ -+ rootdev = strstr(command_line, "root=/dev/mtdblock"); -+ -+ if (rootdev) -+ strncpy(rootdev, "mangled_rootblock=", 18); -+ -+ rootfs = strstr(command_line, "rootfstype"); -+ -+ if (rootfs) -+ strncpy(rootfs, "mangled_fs", 10); -+ -+} -+#else -+static void __init mangle_bootargs(char *command_line) -+{ -+} -+#endif -+ - /* - * We need to store the untouched command line for future reference. - * We also need to store the touched command line since the parameter -@@ -530,6 +553,7 @@ asmlinkage __visible void __init start_k - pr_notice("%s", linux_banner); - setup_arch(&command_line); - mm_init_cpumask(&init_mm); -+ mangle_bootargs(command_line); - setup_command_line(command_line); - setup_nr_cpu_ids(); - setup_per_cpu_areas(); ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1597,6 +1597,15 @@ config EMBEDDED - an embedded system so certain expert options are available - for configuration. - -+config MANGLE_BOOTARGS -+ bool "Rename offending bootargs" -+ depends on EXPERT -+ help -+ Sometimes the bootloader passed bogus root= and rootfstype= -+ parameters to the kernel, and while you want to ignore them, -+ you need to know the values f.e. to support dual firmware -+ layouts on the flash. -+ - config HAVE_PERF_EVENTS - bool - help diff --git a/target/linux/generic/pending-3.18/997-device_tree_cmdline.patch b/target/linux/generic/pending-3.18/997-device_tree_cmdline.patch deleted file mode 100644 index 61fe71b784..0000000000 --- a/target/linux/generic/pending-3.18/997-device_tree_cmdline.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -909,6 +909,9 @@ int __init early_init_dt_scan_chosen(uns - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); -+ p = of_get_flat_dt_prop(node, "bootargs-append", &l); -+ if (p != NULL && l > 0) -+ strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE)); - - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else ---- a/arch/mips/kernel/prom.c -+++ b/arch/mips/kernel/prom.c -@@ -49,6 +49,9 @@ void * __init early_init_dt_alloc_memory - - void __init __dt_setup_arch(void *bph) - { -+ if (boot_command_line[0] == '\0') -+ strcpy(boot_command_line, arcs_cmdline); -+ - if (!early_init_dt_scan(bph)) - return; - diff --git a/target/linux/generic/pending-3.18/998-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-3.18/998-enable_wilink_platform_without_drivers.patch deleted file mode 100644 index d317de1102..0000000000 --- a/target/linux/generic/pending-3.18/998-enable_wilink_platform_without_drivers.patch +++ /dev/null @@ -1,15 +0,0 @@ -We use backports for driver updates - make sure we can compile in the glue code regardless - -Signed-off-by: Imre Kaloz <kaloz@openwrt.org> - ---- a/drivers/net/wireless/ti/Kconfig -+++ b/drivers/net/wireless/ti/Kconfig -@@ -15,7 +15,7 @@ source "drivers/net/wireless/ti/wlcore/K - - config WILINK_PLATFORM_DATA - bool "TI WiLink platform data" -- depends on WLCORE_SDIO || WL1251_SDIO -+ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS - default y - ---help--- - Small platform data bit needed to pass data to the sdio modules. diff --git a/target/linux/generic/pending-3.18/999-seccomp_log.patch b/target/linux/generic/pending-3.18/999-seccomp_log.patch deleted file mode 100644 index 1db6b18d4e..0000000000 --- a/target/linux/generic/pending-3.18/999-seccomp_log.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/kernel/seccomp.c -+++ b/kernel/seccomp.c -@@ -614,6 +614,7 @@ int __secure_computing(void) - #ifdef CONFIG_SECCOMP_FILTER - static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd) - { -+ char name[sizeof(current->comm)]; - u32 filter_ret, action; - int data; - -@@ -644,6 +645,13 @@ static u32 __seccomp_phase1_filter(int t - case SECCOMP_RET_TRACE: - return filter_ret; /* Save the rest for phase 2. */ - -+ case SECCOMP_RET_LOG: -+ get_task_comm(name, current); -+ pr_err_ratelimited("seccomp: %s [%u] tried to call non-whitelisted syscall: %d\n", name, current->pid, this_syscall); -+ syscall_set_return_value(current, task_pt_regs(current), -+ -data, 0); -+ goto skip; -+ - case SECCOMP_RET_ALLOW: - return SECCOMP_PHASE1_OK; - ---- a/include/uapi/linux/seccomp.h -+++ b/include/uapi/linux/seccomp.h -@@ -28,6 +28,7 @@ - #define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ - #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ - #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ -+#define SECCOMP_RET_LOG 0x00070000U /* allow + logline */ - #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ - #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ - |